/* Redesign 44 — complete stylesheet for the 'home' route (all design-system + page style blocks, in cascade order). */

/* Rev 08F FINAL COMPOSITE — approved section sources: A shell rhythm + B opening alternation;
       B rail shell (+C contextual hierarchy, see state sheet); B cats/featured; A services;
       A audience index; A/B horizontal steps; new flat Why-Boomax SVG; B/C review hierarchy;
       approved CTA + one quiet C facet. Hero, trust strip, header, footer LOCKED.
       All arrows/chevrons are the Rev 08F inline-SVG control family — no raw Unicode glyphs. */
    html {
      --bx-gutter: clamp(18px, 3vw, 48px);
      --bx-measure: 1360px;
      --bx-vw: 100vw;
      --bx-side: max(var(--bx-gutter), calc((var(--bx-vw) - var(--bx-measure)) / 2 + var(--bx-gutter)));
      /* Rev 18.4-R1 §6 — rail-aware side inset for content INSIDE the shell.
         `--bx-side` is derived from the full viewport (--bx-vw: 100vw), which is correct for the
         full-bleed hero and trust strip. It was ALSO used as the main column's padding-right, but
         the main column is only `100vw − rail` wide, so the inset was measured against the wrong
         containing block and over-reserved as the viewport grew: at 1920px it claimed ~280px of
         right padding inside a ~1608px column. That is the unexplained internal whitespace on the
         wide shell. This value subtracts the rail, so the cap applies to the column that is
         actually being padded. Below 1200 the rail is 0px and this equals --bx-side. */
      --bx-side-main: max(var(--bx-gutter), calc((var(--bx-vw) - var(--bx-rail) - var(--bx-measure)) / 2 + var(--bx-gutter)));
      --bx-rail: 0px;
    }
    @media (min-width: 1200px) { html { --bx-rail: clamp(300px, 21.5vw, 312px); } }
    body { margin: 0; font-family: var(--bm-font-body); background: var(--bm-canvas); }
    /* Rev 10 link boundary: the generic content-link rule is zero-specificity and unclassed-only
       (:where(scope) a:where(:not([class]))); classed/component links (.bm-rail-*, Button variants,
       .bxf2-name, .bxr-*) own their own states. text-decoration comes from the DS :where(a) rule. */
    :where(#bx-main .bx-shell-main) a:where(:not([class])) { color: var(--bm-blue); }
    :where(#bx-main .bx-shell-main) a:where(:not([class]):hover) { color: var(--bm-blue-hover); }
    :where(#bx-main .bx-shell-main) a:where(:not([class]):active) { color: var(--bm-blue-active); }
    #bx-main a:focus-visible, #bx-main button:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: 3px; border-radius: 10px; }
    .bx-link { font: var(--bm-button); min-height: 44px; display: inline-flex; align-items: center; gap: 8px; }
    .bx-i { display: inline-flex; flex: none; transition: transform 220ms cubic-bezier(0.2,0.8,0.2,1); }
    .bx-link:hover .bx-i--fwd { transform: translateX(3px); }
    .bx-link:hover .bx-i--ext { transform: translate(2px, -2px); }
    .bx-sec { max-width: 1200px; margin: 0 auto; padding: clamp(64px, 7vw, 104px) var(--bx-gutter); box-sizing: border-box; container-type: inline-size; }
    .bx-sec-tight { padding-top: clamp(40px, 4.6vw, 64px); padding-bottom: clamp(40px, 4.6vw, 64px); } /* R4.19: was 32–52px */
    .bx-stack { display: flex; flex-direction: column; }
    .bx-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; }
    .bx-eyebrow { font: var(--bm-eyebrow); letter-spacing: 0.1em; text-transform: uppercase; color: var(--bm-blue); display: inline-flex; align-items: center; gap: 10px; }
    .bx-eyebrow::before { content: ""; width: 8px; height: 8px; border-radius: 9999px; background: var(--bm-blue); flex: none; }
    .bx-h2 { font: var(--bm-heading-1); font-family: var(--bm-font-display); color: var(--bm-navy); margin: 0; letter-spacing: -0.03em; text-wrap: pretty; }
    .bx-h3 { font: var(--bm-heading-3); font-family: var(--bm-font-display); color: var(--bm-navy); margin: 0; letter-spacing: -0.02em; text-wrap: pretty; }
    .bx-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
    .bx-path { display: block; overflow: visible; }
    .bx-path .rt { fill: none; stroke: var(--bm-blue); stroke-width: 2; stroke-linecap: round; opacity: 0.45; stroke-dasharray: 1000; stroke-dashoffset: 1000; transition: stroke-dashoffset 900ms cubic-bezier(0.2,0.8,0.2,1); }
    .bx-path .rt-dark { stroke: #6f86d6; opacity: 0.75; }
    .is-in .bx-path .rt { stroke-dashoffset: 0; }
    .bx-path .nd { fill: var(--bm-blue); }
    .bx-path .nd-hot { fill: var(--bm-yellow); stroke: var(--bm-blue); stroke-width: 1.5; }

    /* Round 39 title-link contract at ID strength — beats the #bx-main global anchor rule. */
    #bx-main .bxf2-name, #bx-main .bxf2-name:link, #bx-main .bxf2-name:visited { color: var(--bm-ink); text-decoration: none; }
    #bx-main .bxf2-name:hover, #bx-main .bxf2-name:active { color: var(--bm-blue); text-decoration: none; }
    #bx-main .bxf2-name:focus-visible { color: var(--bm-blue); text-decoration: none; outline: 3px solid var(--bm-blue); outline-offset: 3px; border-radius: 6px; }

    /* ---- LOCKED hero: Version B — Pin-Imprinted S8 ---- */
    .bx-hero-vb { position: relative; background: #000047; overflow: hidden; height: 610px; }
    .bx-hero-vb-art { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
    /* Rev 18.1 field model: the hero art is a full-bleed BACKGROUND FIELD (navy→cobalt, painted by
       the SVG itself), never a boxed picture beside the copy. Matches .bm-hero__art in the shared Hero. */
    /* Rev 18.4-R1 — the field is authored with sc-camel-preserve-aspect-ratio="none" to stretch to the band,
       so cover was clipping its bottom edge. fill shows the whole field, no crop. */
    .bx-hero-vb-art img { display: block; width: 100%; height: 100%; object-fit: fill; object-position: center; }
    /* Rev 18.4-R1 — hero copy centred vertically in the band (was top-aligned with a 0 bottom
       padding, which left a large dead area below the actions). */
    .bx-hero-vb-inner { position: relative; z-index: 1; height: 100%; box-sizing: border-box; padding: 36px var(--bx-side); display: flex; align-items: center; }
    .bx-hero-vb-copy { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; max-width: 100%; }
    .bx-hero-vb .bx-eyebrow { color: #C9D8FA; }
    .bx-hero-vb .bx-eyebrow::before { background: #C9D8FA; }
    .bx-hero-vb-h1 { font-family: var(--bm-font-display); font-weight: 700; font-size: clamp(34px, 2.6vw + 16px, 58px); line-height: 1.06; color: #FFFFFF; margin: 0; letter-spacing: -0.04em; max-width: 16ch; text-wrap: balance; }
    .bx-hero-vb-sub { font: var(--bm-body-lg); color: var(--bm-on-dark-muted); margin: 0; max-width: 40ch; text-wrap: pretty; }
    #bx-main .bx-hero-vb a:focus-visible { outline-color: #FFFFFF; }
    @media (max-width: 359px) { .bx-hero-vb { height: 600px; } }
    @media (min-width: 600px) { .bx-hero-vb { height: 520px; } .bx-hero-vb-inner { align-items: center; padding-top: 0; } .bx-hero-vb-copy { max-width: min(340px, 46vw); gap: 15px; } }
    @media (min-width: 992px) { .bx-hero-vb { height: 564px; } .bx-hero-vb-copy { max-width: min(520px, 42vw); gap: 18px; } }
    @media (min-width: 1100px) { .bx-hero-vb { height: 620px; } }

    /* ---- LOCKED trust strip ---- */
    .bx-trust { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 24px; }
    .bx-trust-item { display: flex; align-items: center; gap: 12px; color: #fff; font: var(--bm-title-md); }
    .bx-trust-plate { width: 34px; height: 34px; border-radius: 10px; background: rgba(255,255,255,0.14); display: flex; align-items: center; justify-content: center; flex: none; }
    @media (max-width: 1179px) { .bx-trust { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
    @media (max-width: 359px) { .bx-trust { grid-template-columns: minmax(0, 1fr); } }


    /* ---- Shell: rail ≥1200 only, gutter fully removed below ---- */
    .bx-shell { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; }
    .bx-shell-side { display: none; }
    .bx-shell-main { display: flex; flex-direction: column; min-width: 0; }
    @media (min-width: 1200px) {
      .bx-shell { grid-template-columns: var(--bx-rail) minmax(0, 1fr); position: relative; align-items: start; }
      /* Rev 18.8 — the rail boundary gains a light shadow so the sidebar reads as a separate plane
         from the page content. It is applied to the EXISTING 1px divider rather than as a
         box-shadow on the rail itself: the rail is a sticky, internally-scrolling box, so a shadow
         on it would be clipped by its own overflow, while this pseudo-element already spans exactly
         the shell's height and stops before the footer — which the DS requires ("no sidebar divider
         continues through or misaligns with the footer").
         Shadow colour and alpha are the DS's single shadow family (rgba(0,0,71,0.06)), turned onto
         the horizontal axis. */
      .bx-shell::before { content: ""; position: absolute; top: 0; bottom: 0; left: var(--bx-rail); width: 1px; background: var(--bm-border-soft); pointer-events: none; box-shadow: 6px 0 18px rgba(0,0,71,0.06); }
      .bx-shell-side { display: flex; flex-direction: column; position: sticky; top: var(--bm-header-visible-h, 76px); align-self: start; height: calc(100dvh - var(--bm-header-visible-h, 76px)); overflow: hidden; background: #fff; }
      /* R81: bound the sidebar mount to the sticky rail box so the quote zone scrolls internally and the CTA stays pinned */
      .bx-shell-side > * { flex: 1 1 auto; min-height: 0; min-width: 0; height: 100%; }
      .bx-sec { max-width: none; margin: 0; padding-left: var(--bx-gutter); padding-right: var(--bx-side-main); }
    }

    /* Rev 12: the quote rail is the shared ContextSidebar DC (contract-rail.html) — no page-local rail CSS or logic. */

    /* ---- B signal-led heading tail (cats + featured only) ---- */
    .bxb-sig { flex: 1 1 60px; min-width: 60px; align-self: center; height: 10px; margin-bottom: 8px; }
    @media (max-width: 699px) { .bxb-sig { display: none; } }

    /* Rev 18.3: the page-level .bx-cat* category-card CSS is DELETED — it was dead after the
       PlanningGrid rollback and its grid-template-columns / thumbnail-background rules conflicted with the
       DS planning contract (outer-wrapper container query, 2×2 at ≥44rem, white 152px contain well). The
       shared PlanningGrid + RentalCategoryCard variant="planning" now own that layout entirely. */

    /* ---- Services (A): flush navy band ---- */
    .bxa-svc-sec { background: var(--bm-navy); }
    .bxa-svc-sec .bx-eyebrow { color: #C9D8FA; }
    .bxa-svc-sec .bx-eyebrow::before { background: #C9D8FA; }
    .bxa-svc-sec .bx-h2 { color: #fff; }
    .bxa-svc { display: grid; grid-template-columns: 1fr; }
    .bxa-svc-col { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; padding: 24px 0; border-top: 1px solid rgba(255,255,255,0.16); }
    .bxa-svc-col:first-child { border-top: 0; padding-top: 0; }
    .bx-svc-plate { width: 62px; height: 62px; border-radius: 16px; background: #fff; display: flex; align-items: center; justify-content: center; overflow: hidden; transition: transform 220ms cubic-bezier(0.2,0.8,0.2,1); }
    .bx-svc-plate img { width: 78%; height: 78%; object-fit: contain; }
    .bxa-svc-col:hover .bx-svc-plate { transform: translateY(-2px); }
    .bx-svc-title { font: var(--bm-heading-4); color: #fff; margin: 0; }
    .bx-svc-copy { font: var(--bm-body-sm); color: var(--bm-on-dark-muted); margin: 0; }
    #bx-main .bx-svc-act, #bx-main .bx-svc-act:link, #bx-main .bx-svc-act:visited { margin-top: auto; white-space: nowrap; display: inline-flex; align-items: center; justify-content: center; height: 46px; padding: 0 22px; border-radius: 9999px; background: #fff; border: 1.5px solid #fff; color: var(--bm-navy); font: var(--bm-button); box-sizing: border-box; transition: background 220ms cubic-bezier(0.2,0.8,0.2,1); }
    #bx-main .bx-svc-act:hover { background: var(--bm-blue-soft); border-color: var(--bm-blue-soft); color: var(--bm-navy); }
    #bx-main .bx-svc-act:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
    @container (min-width: 45rem) {
      .bxa-svc { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
      .bxa-svc-col { padding: 0 0 0 32px; border-top: 0; border-left: 1px solid rgba(255,255,255,0.16); }
      .bxa-svc-col:first-child { padding-left: 0; border-left: 0; }
    }

    /* ---- Who we work with (A): numbered editorial index ---- */
    .bxa-aud { display: grid; grid-template-columns: 1fr; gap: 0 52px; }
    .bxa-aud-row { display: grid; grid-template-columns: 54px minmax(0, 1fr); gap: 14px; padding: 18px 0; border-top: 1px solid var(--bm-border-soft); align-items: start; }
    .bxa-aud-num { font: 700 28px/1.15 var(--bm-font-display); letter-spacing: -0.02em; color: var(--bm-blue-border); }
    .bx-aud-title { font: var(--bm-title-lg); color: var(--bm-ink); }
    .bx-aud-copy { font: var(--bm-body-sm); color: var(--bm-body); margin-top: 3px; }
    @container (min-width: 40rem) { .bxa-aud { grid-template-columns: repeat(2, minmax(0, 1fr)); } .bxa-aud-row:nth-child(-n+2) { border-top: 0; } }

    /* ---- How it works (A/B): horizontal signal path ---- */
    .bx-steps { display: grid; grid-template-columns: 1fr; gap: 0; position: relative; }
    .bx-step { display: flex; flex-direction: column; gap: 8px; padding: 20px 0; border-top: 1px solid var(--bm-border); }
    .bx-step:first-child { border-top: 0; padding-top: 0; }
    .bx-step-head { display: flex; align-items: center; gap: 12px; }
    .bx-step-num { width: 40px; height: 40px; border-radius: 9999px; background: var(--bm-yellow); color: var(--bm-on-yellow); display: flex; align-items: center; justify-content: center; font: var(--bm-title-md); flex: none; }
    .bx-step-icon { width: 34px; height: 34px; border-radius: 9999px; background: #fff; display: flex; align-items: center; justify-content: center; flex: none; }
    .bx-step-title { font: var(--bm-heading-4); color: var(--bm-ink); margin: 0; }
    .bx-step-copy { font: var(--bm-body-sm); color: var(--bm-body); margin: 0; max-width: 44ch; }
    .bx-steps-line { display: none; }
    @container (min-width: 44rem) { .bx-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 26px; } .bx-step { padding: 0; border-top: 0; } .bx-steps-line { display: block; position: absolute; top: 19px; left: 46px; width: calc(100% - 92px); height: 2px; } }

    /* ---- Why Boomax: editorial two-text split (no artwork) ---- */
    .bx-story { display: grid; grid-template-columns: 1fr; gap: 28px; align-items: center; }
    .bx-chips { display: flex; flex-wrap: wrap; gap: 8px; }
    .bx-chip { display: inline-flex; white-space: nowrap; align-items: center; gap: 7px; padding: 7px 14px; border-radius: 9999px; background: var(--bm-blue-soft); border: 1px solid var(--bm-blue-border); font: var(--bm-caption); font-weight: 700; color: var(--bm-navy); }
    /* The 58fr/42fr split was authored when the right column held the illustration (max-width
       430px of art). With body copy in that slot the ratio was inverted against its content: the
       short heading took the wide column and the sentence was squeezed to 29 characters a line —
       under half this page's own 46-62ch measure. The text column is now the wide one, and the
       two-column form only applies from 60rem, where both columns can actually hold their content;
       below that the section stacks and the sentence gets the full measure. */
    @container (min-width: 60rem) { .bx-story { grid-template-columns: 42fr 58fr; gap: clamp(32px,3.6vw,56px); } }

    /* ---- Reviews (B/C identity band) on mist, white cards ---- */
    .bx-rev-rail { display: flex; gap: 18px; min-width: 0; max-width: 100%; overflow-x: auto; contain: paint; scroll-snap-type: x mandatory; scroll-padding-inline: 4px; scroll-behavior: smooth; padding: 4px 4px 14px; margin: -4px -4px 0; scrollbar-width: thin; }
    .bx-rev-card { flex: 0 0 calc(50% - 9px); min-width: min(86%, 344px); max-width: 520px; scroll-snap-align: start; background: #fff; border: 1px solid var(--bm-border); border-radius: 22px; padding: 0 20px 18px; display: flex; flex-direction: column; gap: 14px; margin: 0; box-sizing: border-box; overflow: hidden; }
    .bx-rev-top { display: flex; align-items: center; gap: 12px; margin: 0 -20px; padding: 16px 20px; background: var(--bm-blue-mist); border-bottom: 1px solid var(--bm-border-soft); }
    .bx-avatar { width: 42px; height: 42px; border-radius: 9999px; background: var(--bm-navy); color: #fff; display: flex; align-items: center; justify-content: center; font: 800 15px/1 var(--bm-font-body); letter-spacing: 0.04em; flex: none; }
    .bx-rev-name { font: var(--bm-title-md); color: var(--bm-ink); }
    .bx-rev-src { font: var(--bm-caption); color: var(--bm-muted); }
    .bx-stars { margin-left: auto; display: inline-flex; align-items: center; background: var(--bm-yellow-soft); border: 1px solid var(--bm-yellow-border); color: var(--bm-navy); border-radius: 9999px; padding: 4px 10px; font-size: 12px; letter-spacing: 1.5px; flex: none; }
    .bx-rev-text { font: 400 16px/1.6 var(--bm-font-body); color: var(--bm-body); margin: 0; max-width: 46ch; text-wrap: pretty; }
    .bx-rev-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--bm-border-soft); }
    @media (max-width: 479px) { .bx-rev-top { flex-wrap: wrap; } .bx-stars { margin-left: 54px; } }
    .bx-rev-bar { display: flex; align-items: center; gap: 12px; }
    /* Round 75 — CarouselNavButton: true circle, grid-centered chevron, quiet outline at rest */
    .bx-rev-btn { width: 48px; height: 48px; border-radius: 50%; border: 1.5px solid var(--bm-border); background: #fff; color: var(--bm-navy); display: grid; place-items: center; line-height: 0; padding: 0; box-sizing: border-box; cursor: pointer; transition: background 180ms cubic-bezier(0.2,0.8,0.2,1); }
    .bx-rev-btn:hover:enabled { background: var(--bm-blue-soft); }
    .bx-rev-btn:disabled { border-color: var(--bm-border-soft); color: var(--bm-border); cursor: default; }
    .bx-rev-pos { font: var(--bm-caption); color: var(--bm-muted); font-variant-numeric: tabular-nums; }

    /* ---- Final CTA (approved) + one quiet C facet ---- */
    .bx-cta-panel { background: var(--bm-navy); border-radius: 28px; padding: clamp(26px, 3.2vw, 42px); box-sizing: border-box; box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); position: relative; overflow: hidden; }
    .bx-cta-facet { position: absolute; top: 0; bottom: 0; right: -5%; width: 30%; background: linear-gradient(112deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.06) 55%, rgba(255,255,255,0) 100%); transform: skewX(-12deg); pointer-events: none; }
    .bx-cta-grid { display: grid; grid-template-columns: 1fr; gap: 26px; align-items: center; position: relative; }
    .bx-cta-copy { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
    .bx-cta-heading { font-family: var(--bm-font-display); font-weight: 700; font-size: clamp(26px, 2.2vw + 10px, 38px); line-height: 1.12; letter-spacing: -0.03em; color: #fff; margin: 0; text-wrap: pretty; }
    .bx-flow-panel { background: var(--bm-navy-soft); border: 1px solid rgba(255,255,255,0.13); border-radius: 20px; padding: 22px 18px; box-sizing: border-box; box-shadow: inset 0 1px 0 rgba(255,255,255,0.12); }
    .bx-flow-cap { font: var(--bm-caption); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--bm-on-dark-muted); margin: 0 0 16px; }
    .bx-flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; position: relative; }
    .bx-flow-line { position: absolute; top: 25px; left: 12.5%; width: 75%; height: 2px; }
    .bx-flow-item { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; position: relative; z-index: 1; }
    .bx-flow-plate { width: 50px; height: 50px; border-radius: 15px; background: rgba(255,255,255,0.18); border: 1px solid rgba(255,255,255,0.22); display: flex; align-items: center; justify-content: center; box-shadow: inset 0 1px 0 rgba(255,255,255,0.14); }
    .bx-flow-plate--hot { background: var(--bm-yellow); border-color: var(--bm-yellow); box-shadow: 0 0 0 6px rgba(255,255,169,0.12); }
    .bx-flow-label { font: var(--bm-caption); font-weight: 700; color: #fff; text-wrap: balance; }
    @container (min-width: 46rem) { .bx-cta-grid { grid-template-columns: 55fr 45fr; gap: 36px; } }
    @media (max-width: 359px) { .bx-flow { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 10px; } .bx-flow-line { display: none; } }

    .bx-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; width: fit-content; max-width: 100%; }
    .bx-pair > a { white-space: nowrap; }
    @media (max-width: 479px) { .bx-pair { grid-template-columns: 1fr; width: min(100%, 320px); } }

    .bx-motion .bx-reveal { opacity: 0; transform: translateY(10px); }
    .bx-motion .bx-reveal.is-in { opacity: 1; transform: none; transition: opacity 240ms cubic-bezier(0.2,0.8,0.2,1), transform 240ms cubic-bezier(0.2,0.8,0.2,1); }
    @supports not (container-type: inline-size) {
      @media (min-width: 1024px) {
        .bxa-aud { grid-template-columns: repeat(2, minmax(0, 1fr)); }
        .bxa-svc, .bx-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
        .bx-story, .bx-cta-grid { grid-template-columns: 1fr 1fr; }
      }
    }
    @media (prefers-reduced-motion: reduce) {
      * { transition: none !important; animation: none !important; }
      .bx-rev-rail { scroll-behavior: auto; }
      .bx-path .rt { stroke-dashoffset: 0; }
      .bx-motion .bx-reveal { opacity: 1; transform: none; }
    }
    /* Rev 18.4-R1 — product price a step lighter than navy, so the product NAME stays the focal
       point of the card/row. The DS sets the price inline in priceRow(), so this needs !important;
       the selector matches that one inline font/colour pair and nothing else. */
    #bx-main span[style*="--bm-navy"][style*="/1.2"] { color: var(--bm-body) !important; }
    /* Rev 18.4-R1 — the four planning-card CTAs are one consistent, full-width action.
       They were solid cobalt pills sized to their own label, so the four cards showed four
       different button widths and the saturated fill fought the pale section behind it. They now
       span the card's body column (identical width on all four, starting where the copy starts and
       ending at the card's inner edge) and use the DS add-to-quote action family, which is the
       lighter treatment already used for product actions elsewhere on the page.
       Class-based DS rules, so #bx-main specificity is enough — no !important. */
    #bx-main .bm-plan-card__action {
      width: 100%;
      background: var(--bm-add-bg);
      color: var(--bm-add-text);
      border: 1px solid var(--bm-add-border);
      box-sizing: border-box;
    }
    #bx-main .bm-plan-card:hover .bm-plan-card__action { background: var(--bm-add-hover); }
    /* Rev 18.4-R1 — centred headers on three sections, for rhythm variety. Eight identically
       left-aligned headers was a large part of why the page read flat. Only the three sections
       whose header is a plain eyebrow+heading block are centred; Categories, Featured rentals and
       Reviews keep their left-aligned headers because those share a row with a "browse" link. */
    .bx-sec > div:has(> #svc-h),
    .bx-sec > div:has(> #ind-h),
    .bx-sec > div:has(> #how-h) {
      align-items: center; text-align: center;
      max-width: 640px; margin-left: auto; margin-right: auto;
    }
    .bx-sec > div:has(> #how-h) .bx-h2,
    .bx-sec > div:has(> #svc-h) .bx-h2,
    .bx-sec > div:has(> #ind-h) .bx-h2 { text-wrap: balance; }
    /* SHAPED BACKGROUNDS — restrained set. No section borders anywhere, and no shape that spans
       two sections: each shape belongs to exactly one section and stops at its edge. Categories,
       Featured rentals, How it works and the final CTA carry NO shape, so the three that do land
       as moments rather than a pattern. Flat brand tokens only — no gradients, no glow, no blobs.
       Shapes are pseudo-elements: invisible to assistive tech, always behind content.
       SELECTORS: descendant combinator inside :has() — headings sit at different depths (#ind-h is
       .bx-sec > div > h2; #reviews-h is .bx-sec > .bx-head > div > h2 because that row also
       carries a "browse" link). A child chain silently matches nothing. */
    .bx-shell-main > section:has(> .bx-sec #ind-h),
    .bx-shell-main > section:has(> .bx-sec #reviews-h) { position: relative; overflow: hidden; }
    .bx-shell-main > section.bxa-svc-sec,
    .bx-shell-main > section.bxh-field { position: relative; overflow: hidden; }
    .bx-shell-main > section::before,
    .bx-shell-main > section.bxa-svc-sec::after,
    .bx-shell-main > section.bxh-field::after { pointer-events: none; z-index: 0; }

    /* Services — angled band edge only; the navy already carries the section. */
    .bx-shell-main > section.bxa-svc-sec {
      clip-path: url(#bxa-svc-wave);
      margin-top: calc(-1 * var(--bxc));
      margin-bottom: calc(-1 * var(--bxc));
      padding-top: calc(var(--bxc) * 1.75 + 12px);
      padding-bottom: calc(var(--bxc) * 1.75 + 12px);
      z-index: 1;
    }
    /* R4.9: the R4.5 edge strips were removed — the bottom one read as a stray lavender band against the
       cut. Services now uses the same neighbour-overlap treatment as How it works, so the sections above
       and below fill the wedges. */
    /* R4.12–R4.15 (owner-directed): both dark bands carry soft wave edges in their own colour (white at
       low alpha), behind content. --bxc = the neighbour-overlap height. */
    .bx-shell-main { --bxc: clamp(44px, 6vw, 80px); } /* shared by the bands AND their neighbours */
    /* R4.17: the bands pull into their neighbours by --bxc, so give each neighbour that much back on the
       shared edge — restores the pre-R4.8 clearance between neighbour content and the wave trough. */
    /* R4.19: neighbours get the overlap back PLUS breathing room, so content never crowds a wave crest. */
    .bx-shell-main > section:has(+ section.bxa-svc-sec),
    .bx-shell-main > section:has(+ section.bxh-field) { padding-bottom: calc(var(--bxc) + clamp(20px, 2.4vw, 36px)); }
    .bx-shell-main > section.bxa-svc-sec + section,
    .bx-shell-main > section.bxh-field + section { padding-top: calc(var(--bxc) + clamp(20px, 2.4vw, 36px)); }
    /* R4.14/R4.18: Services edges are soft waves — the approved R4.14 curve. R4.18: the clipPaths are
       userSpaceOnUse and re-drawn by the logic class (ResizeObserver) from the band's real width/height
       with a FIXED pixel depth (--bxc), so the curve reads identically on a phone and a desktop and never
       grows into the cards. ::before is the offset translucent wave layer along both edges. */
    .bx-shell-main > section.bxa-svc-sec::before {
      content: ""; position: absolute; inset: 0; background: rgba(255,255,255,0.12);
      clip-path: url(#bxa-svc-wave-2);
    }
    .bx-shell-main > section.bxa-svc-sec::after { content: none; }
    /* R4.15: How it works edges match the Services wave treatment, horizontally mirrored so the two bands
       do not stamp the same curve. ::before is the offset translucent wave layer; the R4.12 dot band is gone. */
    .bx-shell-main > section.bxh-field::before {
      content: ""; position: absolute; inset: 0; background: rgba(255,255,255,0.14);
      clip-path: url(#bxh-wave-2);
    }
    .bx-shell-main > section.bxh-field::after { content: none; }
    /* Who we work with — plane entering from the left. */
    .bx-shell-main > section:has(> .bx-sec #ind-h)::before {
      content: ""; position: absolute; inset: 0 auto 0 0; width: min(46%, 520px);
      background: var(--bm-surface-blue);
      clip-path: polygon(0 0, 100% 0, calc(100% - clamp(56px, 9vw, 132px)) 100%, 0 100%);
    }
    /* Reviews — mirrored from the right, in the deeper tone. */
    .bx-shell-main > section:has(> .bx-sec #reviews-h)::before {
      content: ""; position: absolute; inset: 0 0 0 auto; width: min(46%, 520px);
      background: var(--bm-hero-surface);
      clip-path: polygon(clamp(56px, 9vw, 132px) 0, 100% 0, 100% 100%, 0 100%);
    }

    .bx-shell-main > section > .bx-sec { position: relative; z-index: 1; }
    /* Rev 18.4-R1 — planning-card media at narrow widths and 200% zoom.
       The DS sizes the well image with width:auto/height:auto + max-*:100%, so the image renders at
       its INTRINSIC size capped to the well. When the well is wider than the artwork (the stacked
       mobile/tablet state gives it 100% width) the image sits small inside a large empty box, which
       is the "doesn't fill" symptom. Switching to width/height 100% + object-fit:contain makes the
       image use the whole well box while still never being cropped or distorted — contain preserves
       aspect ratio, so this is a fit fix, not an upscale-and-crop.
       The stacked well also loses a little height so there is less empty area around a contained
       product shot. DELETABLE once the DS ships a responsive planning well. */
    #bx-main .bm-plan-card__well img {
      width: 100% !important; height: 100% !important;
      object-fit: contain !important; object-position: center !important;
    }
    /* Stacked state: the DS gives the well 100% width and a FIXED 160px height, so a square
       product photo contains to 160x160 and floats in a much wider empty box — the "image doesn't
       fill / can't see it properly" symptom. A square well removes the wasted axis entirely, so
       the contained artwork uses nearly the whole box at a legible size, still uncropped. */
    @container bm-plan (max-width: 30rem) {
      #bx-main .bm-plan-card__well {
        /* Full card width, not capped — a 240px cap left the well sitting against the left
           edge of a wider card, which read as misalignment. Square keeps the square catalog art
           filling nearly the whole box with no side voids. */
        width: 100% !important; max-width: none !important; height: auto !important;
        aspect-ratio: 1 / 1 !important; padding: 16px !important;
      }
    }
    @supports not (container-type: inline-size) {
      @media (max-width: 479px) {
        #bx-main .bm-plan-card__well {
          width: 100% !important; max-width: 240px; height: auto !important;
          aspect-ratio: 1 / 1 !important; padding: 14px !important;
        }
      }
    }
    /* Rev 18.4-R1 — Services section, stacked state. Below the 3-column breakpoint each service
       was an icon stacked above left-aligned text, separated by hard 1px rules: cramped, dated, and
       all the weight pinned to the left edge. Each service is now its own soft panel on the navy
       (translucent white fill + hairline, so it stays on-brand without a new colour), with the icon
       sitting ON the title line and the copy and action spanning the full panel width. Desktop's
       three-column composition is untouched. */
    @media (max-width: 1023px) {
      #bx-main .bxa-svc { gap: 14px; }
      #bx-main .bxa-svc-col {
        border-top: 0; padding: 20px; box-sizing: border-box;
        background: rgba(255,255,255,0.055);
        border: 1px solid rgba(255,255,255,0.14);
        border-radius: 18px;
        display: grid; grid-template-columns: 52px minmax(0, 1fr);
        column-gap: 14px; row-gap: 12px; align-items: center;
      }
      #bx-main .bxa-svc-col .bx-svc-plate {
        width: 52px; height: 52px; border-radius: 14px;
        grid-column: 1; grid-row: 1;
      }
      #bx-main .bxa-svc-col .bx-svc-title { grid-column: 2; grid-row: 1; }
      #bx-main .bxa-svc-col .bx-svc-copy { grid-column: 1 / -1; }
      #bx-main .bxa-svc-col > a { grid-column: 1 / -1; justify-self: start; }
    }
    /* Rev 18.4-R1 — "How it works" as a real signal path, at every width.
       It was three text blocks separated by hairlines, with a small number and a small icon stacked
       in a head row: informative but flat. Now each step is a white card on the deep band, the
       numbered node is large and sits on a connector, and the LAST node is the soft-yellow
       "confirmed" node — the design system's own signal-path motif, which it permits specifically
       in the hero, How it works, and the final CTA.
       Desktop/tablet: horizontal connector through the three nodes.
       Mobile: the connector becomes a short vertical segment between stacked cards, aligned to the
       node centre, so the path still reads top-to-bottom. */
    #bx-main .bx-step {
      background: #fff; border: 1px solid var(--bm-border); border-radius: 18px;
      padding: 20px; box-sizing: border-box; position: relative;
    }
    #bx-main .bx-step-head { gap: 10px; align-items: center; }
    #bx-main .bx-step-num {
      width: 52px; height: 52px; font: 700 20px/1 var(--bm-font-display);
      background: #fff; color: var(--bm-navy);
      border: 2px solid var(--bm-border-strong); box-sizing: border-box;
    }
    /* One confirmed node, in soft yellow — never more than one. */
    #bx-main .bx-step:last-child .bx-step-num {
      background: var(--bm-yellow); color: var(--bm-on-yellow); border-color: var(--bm-yellow-border);
    }
    /* Rev 18.8 — each step card carries its own surface, so the row reads as three distinct moments
       rather than three identical boxes. The three fills are all existing palette tokens and they
       progress toward the confirmation accent the last step already owns (its numeral disc has been
       soft yellow since Rev 08): white → pale blue → soft yellow. No new colours; the yellow stays
       tied to the one "confirmed" moment rather than becoming decoration. Each border comes from
       the same family as its fill so the cards keep an even weight.
       nth-of-type, NOT nth-child: the first child of .bx-steps is the connector &lt;svg>, so
       nth-child(2) would have coloured step ONE. nth-of-type counts only the div siblings. */
    #bx-main .bx-step:nth-of-type(2) { background: var(--bm-blue-soft); border-color: var(--bm-blue-border); }
    #bx-main .bx-step:nth-of-type(3) { background: var(--bm-yellow-soft); border-color: var(--bm-yellow-border); }
    /* The icon disc stays white on every card so it reads against all three fills. */
    #bx-main .bx-step:nth-of-type(2) .bx-step-icon,
    #bx-main .bx-step:nth-of-type(3) .bx-step-icon { background: #fff; }
    #bx-main .bx-step-icon {
      width: 40px; height: 40px; border: 1px solid var(--bm-border); box-sizing: border-box;
    }
    #bx-main .bx-step-title { margin-top: 4px; }
    /* Horizontal path — line sits at the node centre (20px card padding + half of the 52px node)
       and STOPS at the third node rather than running on to the section edge. */
    @container (min-width: 44rem) {
      #bx-main .bx-steps-line { top: 46px; left: 4%; right: 30%; }
    }
    /* Vertical path between stacked cards. */
    @container (max-width: 43.9rem) {
      #bx-main .bx-steps { gap: 0; }
      #bx-main .bx-step { border-top: 1px solid var(--bm-border); margin-bottom: 18px; }
      #bx-main .bx-step:not(:last-child)::after {
        content: ""; position: absolute; left: 45px; top: 100%;
        width: 2px; height: 18px; background: var(--bm-border);
      }
    }
    /* Rev 18.4-R1 — MOBILE HERO SAFE AREA (home's hand-authored band). Same contract as the DS
       hero pages: a vertical navy veil between the art field and the copy, opaque through the copy
       and buttons, clearing before the bottom edge. .bx-hero-vb already has a solid navy ground,
       so the veil can never leave a gap. */
    @media (max-width: 767px) {
      .bx-hero-vb::after {
        content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
        background: linear-gradient(180deg, #000047 0%, #000047 60%, rgba(0,0,71,0.62) 78%, rgba(0,0,71,0) 95%);
      }
    }
    /* Rev 18.4-R1 — planning-card media is a DARK PHOTOGRAPH, filled edge to edge, instead of a
       contained product photo on white. Owner-approved Higgsfield generations (8 credits), shipped
       as 800/480 WebP in assets/generated/ at ~7-32 KB each (the source PNGs were ~1.5 MB).
       Prompted as realistic EQUIPMENT DETAIL in low light — mixer faders, a projector lens and
       beam, a display bezel, uplights in haze — deliberately NOT identifiable catalog products and
       NOT venue/stage/crowd scenes, both of which the design system forbids.
       These are now PHOTOGRAPHS, not stretch-fields, so object-fit: cover is correct — and because
       both the image and the well are square nothing is actually cropped. fill would distort a
       photograph, and the earlier stretch-field reasoning no longer applies.
       DEPARTURE FROM THE DESIGN SYSTEM, deliberate and owner-requested: the guide specifies real
       verified product photography in "strictly white or pale-blue padded contain wells" for
       category-browsing cards, so customers see what Boomax actually rents. These cards no longer
       show a product. Delete this block and restore the four photo-src bindings to revert. */
    #bx-main .bm-plan-card__well {
      background: var(--bm-navy) !important; padding: 0 !important;
      border-color: transparent !important; overflow: hidden !important;
    }
    #bx-main .bm-plan-card__well img {
      width: 100% !important; height: 100% !important;
      object-fit: cover !important; object-position: center !important;
    }
    /* Rev 18.8 — CARD BORDER RUNS INTO THE BUTTON.
       The card's stroke is thicker (2.5px) and a connector of the same weight and colour travels
       from the card's left border, across the empty space under the image well, and into the
       button's left cap — so the outline reads as one continuous path that leaves the frame, meets
       the action, and carries on. The button stays INSIDE the card (no straddling) as asked.
       Geometry is derived, not guessed: the connector's width is the distance from the card's
       border inner edge to the body column's left edge = card padding + the DS well (152px) + the
       DS column gap (18px); its centre matches the action's centre = card padding + half the pill.
       The connector is switched off in the stacked state, where the well becomes a full-width
       square and the line would cross the photograph instead of empty space. */
    #bx-main #bx-plan-grid { --bx-plan-pad: clamp(20px,2cqi,26px); --bx-pill-h: 54px; --bx-stroke: 2.5px; }
    #bx-main #bx-plan-grid .bm-plan-card {
      position: relative; align-items: stretch;
      border: var(--bx-stroke) solid var(--bm-add-border);
      /* Guarantees the connector always runs below the image well instead of vanishing behind it.
         The well is 152px and top-aligned, so its bottom is pad + 152; the action's centre is
         cardHeight - pad - pill/2. Requiring the latter to clear the former gives a minimum content
         height of 2*pad + 152 + pill/2 + a 12px breathing gap. Without it the shorter TV/Lighting
         row showed the line interrupted while the taller row showed it whole. */
      min-height: calc(2 * var(--bx-plan-pad) + 152px + var(--bx-pill-h) / 2 + 12px);
    }
    #bx-main #bx-plan-grid .bm-plan-card::before {
      content: ""; position: absolute; z-index: 0;
      /* BX PLAN CARD FIX 2026-09-09: the rule used to start at left:0, which is the card's
         border edge, so it visibly ran into the card border. It now starts at the padding edge,
         flush with the image well, and still ends exactly where the action pill begins. */
      left: var(--bx-plan-pad); width: 152px;
      bottom: calc(var(--bx-plan-pad) + var(--bx-pill-h) / 2 - var(--bx-stroke) / 2);
      height: var(--bx-stroke);
      background: var(--bm-add-border);
      transition: background var(--bm-duration-base) var(--bm-ease);
    }
    #bx-main #bx-plan-grid .bm-plan-card:hover::before { background: var(--bm-blue); }
    @container bm-plan (max-width: 30rem) {
      #bx-main #bx-plan-grid .bm-plan-card::before { display: none; }
    }
    @supports not (container-type: inline-size) {
      @media (max-width: 767px) {
        #bx-main #bx-plan-grid .bm-plan-card::before { display: none; }
      }
    }
    #bx-main #bx-plan-grid .bm-plan-card__well { align-self: start; position: relative; z-index: 1; }
    #bx-main #bx-plan-grid .bm-plan-card__body { display: flex; flex-direction: column; height: 100%; position: relative; z-index: 1; }
    #bx-main #bx-plan-grid .bm-plan-card__action {
      /* BX PILL FIT FIX 2026-09-09: the pill is width:100% of a minmax(0,1fr) column, so a long
         label ("Projectors") could exceed it and shove the arrow disc outside the pill border.
         It now reclaims the 18px column gap, starting flush with the image, and min-width:0 lets
         the label ellipsize as a last resort so the disc can never be pushed out again. */
      margin: auto 0 0 -18px; width: calc(100% + 18px); min-width: 0; box-sizing: border-box;
      display: flex; align-items: center; justify-content: space-between; gap: 14px;
      /* Height is a floor, not a cap: a fixed height clips a label that wraps to two lines,
         which is what the approved design system avoids with min-height + auto height. */
      height: auto; min-height: var(--bx-pill-h);
      /* Right padding is set so the disc's gap to the cap matches its gap to the top and bottom:
         (54 - 2*2.5 - 40) / 2 = 4.5px of vertical clearance, so 5px reads even against the curve. */
      padding: 0 5px 0 22px;
      background: var(--bm-add-bg);
      border: var(--bx-stroke) solid var(--bm-add-border);
      border-radius: 9999px;
      color: var(--bm-add-text); font: var(--bm-button);
      transition: background var(--bm-duration-base) var(--bm-ease), border-color var(--bm-duration-base) var(--bm-ease);
    }
    #bx-main #bx-plan-grid .bm-plan-card__action-label {
      min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    #bx-main #bx-plan-grid .bm-plan-card__action::after {
      content: ""; flex: none; width: 40px; height: 40px; border-radius: 9999px;
      background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' sc-camel-view-box='0 0 16 16' fill='none'%3E%3Cpath d='M2.5 8H13M9 3.5L13.5 8L9 12.5' stroke='%230849C7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center;
      border: 1px solid var(--bm-add-border);
      transition: transform var(--bm-duration-base) var(--bm-ease);
    }
    /* Rev 18.8 — the WHOLE CARD carries the hover state, not just the pill: the surface tints, the
       stroke and its connector go cobalt, and the pill fills solid cobalt with a white label — so
       the card reads as one interactive object. Focus-visible mirrors hover, since the card is a
       single link and keyboard users must get the same signal (the DS focus ring still draws on
       top). Tokens verified present in tokens/colors.css: --bm-blue, --bm-blue-soft.
       The tint is --bm-blue-soft (#edf3ff), NOT --bm-blue-mist (#f5f8ff): the section band behind
       these cards is #f4f7ff, so the mist tint was within 1/1/0 of it — on hover the card's
       interior went the same colour as the band and the surface receded instead of responding.
       A full dark-navy surface would match the wording better, but the card's title and
       description are inline-styled by the DS with no classes, so the on-dark text swap it needs
       could only be forced with !important on structural selectors. Raised as a DS request instead
       (an invert/on-dark hover option on the card) rather than forked here. */
    #bx-main #bx-plan-grid .bm-plan-card:hover,
    #bx-main #bx-plan-grid .bm-plan-card:focus-visible {
      background: var(--bm-blue-soft);
      border-color: var(--bm-blue);
    }
    #bx-main #bx-plan-grid .bm-plan-card:hover::before,
    #bx-main #bx-plan-grid .bm-plan-card:focus-visible::before { background: var(--bm-blue); }
    #bx-main #bx-plan-grid .bm-plan-card:hover .bm-plan-card__action,
    #bx-main #bx-plan-grid .bm-plan-card:focus-visible .bm-plan-card__action {
      background: var(--bm-blue); border-color: var(--bm-blue); color: #fff;
    }
    /* Narrow columns: the pill's minimum content width is border+padding+the longest word+gap+disc.
       Below roughly 50rem of grid the body column is narrower than that, and because a text node's
       min-width floors at min-content the label cannot shrink — so it pushed the disc out through
       the pill's right edge. Only "Projectors" showed it, being the longest label; the others had
       just enough room. Tightening the paddings, gap and disc lowers the requirement to ~143px so
       every label fits inside its own outline. */
    @container bm-plan (max-width: 50rem) {
      #bx-main #bx-plan-grid .bm-plan-card__action { padding: 0 4px 0 14px; gap: 8px; }
      #bx-main #bx-plan-grid .bm-plan-card__action::after { width: 34px; height: 34px; }
    }
    @supports not (container-type: inline-size) {
      @media (max-width: 900px) {
        #bx-main #bx-plan-grid .bm-plan-card__action { padding: 0 4px 0 14px; gap: 8px; }
        #bx-main #bx-plan-grid .bm-plan-card__action::after { width: 34px; height: 34px; }
      }
    }
    #bx-main #bx-plan-grid .bm-plan-card:hover .bm-plan-card__action::after { transform: translateX(3px); }
    @media (prefers-reduced-motion: reduce) {
      #bx-main #bx-plan-grid .bm-plan-card:hover .bm-plan-card__action::after { transform: none; }
    }
    /* Rev 18.8 — breathing room in the Categories header. Three things shared one line — the
       heading, the decorative signal-path rule and the "View all rentals" link — with a 16px gap
       between them, so the row read as crowded and the 34px stack gap put the cards right under it.
       The row gap is widened, the stack gap raised, and the decorative rule is dropped at the
       widths where it is what makes the row tight (it carries no information). */
    #bx-main section[data-screen-label="Categories"] .bx-head { gap: 22px 36px; }
    @container (max-width: 68rem) {
      #bx-main section[data-screen-label="Categories"] .bx-head .bxb-sig { display: none; }
    }
    /* ---- "Start here" cards. The action is deliberately NOT the category cards' filled pill +
         disc: that treatment belongs to the category group, and repeating it here would make two
         adjacent sections look like the same component. This is a quiet full-width text action on a
         hairline instead — same cobalt, same 44px+ target, different weight. ---- */
    .bxc-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 20px; }
    #bx-main .bxc-card, #bx-main .bxc-card:visited {
      display: flex; flex-direction: column; align-items: flex-start; gap: 12px;
      padding: clamp(20px,2.2vw,28px);
      background: #fff; border: 1.5px solid var(--bm-add-border); border-radius: 22px;
      color: inherit; min-width: 0; height: 100%; box-sizing: border-box;
      transition: background var(--bm-duration-base) var(--bm-ease), border-color var(--bm-duration-base) var(--bm-ease);
    }
    #bx-main .bxc-card:hover, #bx-main .bxc-card:focus-visible { background: var(--bm-blue-soft); border-color: var(--bm-blue); color: inherit; }
    .bxc-ico { width: 48px; height: 48px; flex: none; border-radius: 14px; background: var(--bm-add-bg); display: flex; align-items: center; justify-content: center; }
    .bxc-ico img { width: 28px; height: 28px; display: block; }
    .bxc-t { font: var(--bm-title-lg); color: var(--bm-ink); }
    .bxc-c { font: var(--bm-body-sm); color: var(--bm-body); text-wrap: pretty; }
    .bxc-act {
      margin-top: auto; width: 100%; box-sizing: border-box;
      display: flex; align-items: center; justify-content: space-between; gap: 12px;
      min-height: 48px; padding: 14px 0 0;
      border-top: 1px solid var(--bm-border-soft);
      color: var(--bm-blue); font: var(--bm-button);
      transition: color var(--bm-duration-base) var(--bm-ease), border-top-color var(--bm-duration-base) var(--bm-ease);
    }
    .bxc-arrow { flex: none; display: inline-flex; transition: transform var(--bm-duration-base) var(--bm-ease); }
    #bx-main .bxc-card:hover .bxc-act { color: var(--bm-blue-hover); border-top-color: var(--bm-blue-border); }
    #bx-main .bxc-card:hover .bxc-arrow { transform: translateX(4px); }
    @container (max-width: 46rem) { .bxc-grid { grid-template-columns: minmax(0,1fr); } }

    @media (prefers-reduced-motion: reduce) {
      #bx-main .bxc-card:hover .bxc-arrow { transform: none; }
    }
    /* Rev 18.8 — the audience index was a plain two-column text list and read as empty. It gains a
       real graphic layer without any new asset or colour: the index numerals become large OUTLINED
       display figures (transparent fill, cobalt-tint stroke), each row sits on a tinted panel, and
       the panels alternate white / pale blue down the two columns so the block has texture.
       Outlined numerals need a fallback — with color:transparent and no text-stroke support the
       figures would vanish entirely, so the solid colour is the base and the stroke is applied only
       inside @supports. Tokens verified in tokens/colors.css: --bm-blue-border #c9d8fa,
       --bm-blue-soft #edf3ff, --bm-border-soft #e7ecf5. */
    #bx-main .bxa-aud { gap: 14px 20px; }
    #bx-main .bxa-aud-row {
      grid-template-columns: auto minmax(0, 1fr);
      gap: 18px; align-items: center;
      padding: 20px 22px;
      border-top: 0;
      border: 1px solid var(--bm-border-soft);
      border-radius: 18px;
      background: #fff;
      box-sizing: border-box;
    }
    /* Tint by GRID ROW, not by item: 4n+3 / 4n+4 tints the third and fourth items, which are the
       two cards on the second row of the two-column grid. Tinting 4n+2 / 4n+3 instead scattered the
       fills diagonally (items 2, 3 and 6), which read as a mistake rather than a pattern. */
    #bx-main .bxa-aud-row:nth-of-type(4n+3),
    #bx-main .bxa-aud-row:nth-of-type(4n+4) { background: var(--bm-blue-soft); border-color: var(--bm-blue-border); }
    #bx-main .bxa-aud-num {
      font: 700 clamp(34px, 3.4vw, 52px)/1 var(--bm-font-display);
      letter-spacing: -0.03em;
      color: var(--bm-muted-soft);
      flex: none;
    }
    /* Stroked in --bm-muted-soft (~2.5:1 on white), not --bm-blue-border (1.43:1 on white and
       1.28:1 on the tinted rows, where it was also the SAME value as the row's own border, so the
       figure merged into the frame). A 1.5px hairline at that contrast was invisible at 34px, which
       left the section reading as the plain list it was meant to fix — the same mistake already
       corrected on the navy option's numerals, at a fainter value. */
    @supports (-webkit-text-stroke: 1px currentColor) {
      #bx-main .bxa-aud-num { color: transparent; -webkit-text-stroke: 1.75px var(--bm-muted-soft); }
    }
    /* On the tinted rows the numeral goes cobalt so it separates from both the fill and the frame. */
    #bx-main .bxa-aud-row:nth-of-type(4n+3) .bxa-aud-num,
    #bx-main .bxa-aud-row:nth-of-type(4n+4) .bxa-aud-num { color: var(--bm-blue); }
    @supports (-webkit-text-stroke: 1px currentColor) {
      #bx-main .bxa-aud-row:nth-of-type(4n+3) .bxa-aud-num,
      #bx-main .bxa-aud-row:nth-of-type(4n+4) .bxa-aud-num { color: transparent; -webkit-text-stroke: 1.75px var(--bm-blue); }
    }
    /* Rev 18.8 — the banding pattern must CHANGE with the layout. 4n+3 / 4n+4 tints the second row
       of a two-column grid; in the single-column state those same selectors tint items 3 and 4,
       i.e. an arbitrary pair in the middle of the list. Stacked, the pattern alternates every other
       item instead, which is the only reading that makes sense in one column.
       The two-column rules are reset first, since they still match here. */
    @container (max-width: 39.9rem) {
      #bx-main .bxa-aud-row:nth-of-type(4n+3),
      #bx-main .bxa-aud-row:nth-of-type(4n+4) { background: #fff; border-color: var(--bm-border-soft); }
      #bx-main .bxa-aud-row:nth-of-type(4n+3) .bxa-aud-num,
      #bx-main .bxa-aud-row:nth-of-type(4n+4) .bxa-aud-num { color: var(--bm-muted-soft); }
      #bx-main .bxa-aud-row:nth-of-type(even) { background: var(--bm-blue-soft); border-color: var(--bm-blue-border); }
      #bx-main .bxa-aud-row:nth-of-type(even) .bxa-aud-num { color: var(--bm-blue); }
    }
    @supports (-webkit-text-stroke: 1px currentColor) {
      @container (max-width: 39.9rem) {
        #bx-main .bxa-aud-row:nth-of-type(4n+3) .bxa-aud-num,
        #bx-main .bxa-aud-row:nth-of-type(4n+4) .bxa-aud-num { color: transparent; -webkit-text-stroke: 1.75px var(--bm-muted-soft); }
        #bx-main .bxa-aud-row:nth-of-type(even) .bxa-aud-num { color: transparent; -webkit-text-stroke: 1.75px var(--bm-blue); }
      }
    }
    /* Same pattern for engines without container queries, keyed to the width where this grid is
       still one column (its two-column fallback starts at 1024px). */
    @supports not (container-type: inline-size) {
      @media (max-width: 1023px) {
        #bx-main .bxa-aud-row:nth-of-type(4n+3),
        #bx-main .bxa-aud-row:nth-of-type(4n+4) { background: #fff; border-color: var(--bm-border-soft); }
        #bx-main .bxa-aud-row:nth-of-type(even) { background: var(--bm-blue-soft); border-color: var(--bm-blue-border); }
      }
    }
    /* Rev 18.8 — Reviews sits on a light blue FIELD rather than a flat tint. It is the wordiest
       block at the bottom of the page (four verified reviews, all body copy), so it gets the visual
       interest instead of the copy being cut.
       The pattern is a sparse dot grid in the pale-blue border token — a calm technical texture that
       suits the brand's AV personality, not a decorative wash: no blobs, no glow, no colour outside
       the palette. It fades out down the section so the band resolves into the white CTA below
       rather than stopping at a hard edge, and the white review cards sit on top of it unchanged.
       The background moved from an inline style to this class so it can be layered at all.
       Tokens verified in tokens/colors.css: --bm-surface-blue #f4f7ff, --bm-blue-border #c9d8fa. */
    /* Two background layers on the section itself, no pseudo-element and no mask: the dot grid,
       with a top-to-bottom wash of the section's own colour laid OVER it so the dots fade out
       before the white CTA below. An earlier version put the dots on a ::before with a mask-image;
       measured live, that pseudo-element resolved with the mask applied but background-image:none,
       so the pattern never painted. Layering in one shorthand removes the moving parts. */
    .bxr-field {
      background-color: var(--bm-surface-blue);
      background-image:
        linear-gradient(to bottom, rgba(244,247,255,0) 0%, rgba(244,247,255,0) 46%, var(--bm-surface-blue) 100%),
        radial-gradient(var(--bm-blue-border) 1.4px, transparent 1.5px);
      background-size: 100% 100%, 24px 24px;
      background-position: 0 0, 12px 12px;
      background-repeat: no-repeat, repeat;
    }
    /* Rev 18.8 — "How it works" becomes a full cobalt field instead of a pale tint: the blue is used
       at full strength across the whole band, which is the boldest moment on the page after the
       hero. The three step cards keep their white / pale-blue / soft-yellow fills, so the colour
       variation asked for earlier survives and now reads much harder against the saturated ground.
       Copy inside the cards is unchanged — the cards are light, so their navy text is untouched.
       Only the section's own heading, eyebrow and connector switch to on-dark values.
       bm-on-dark is the DS class that also moves the focus ring to soft yellow inside this band.
       Contrast: white heading on #0041c4 = 8.59:1, soft-yellow eyebrow = 7.4:1. */
    .bxh-field .bx-eyebrow { color: var(--bm-yellow); }
    /* How it works edges (R4.7/R4.8, owner-directed) — angled cuts (Services vocabulary, opposite slope).
       R4.8: the band overlaps each neighbour by the cut height (negative margins, compensated in padding,
       lifted with z-index) so the neighbours' backgrounds run into the wedges instead of a white gap. */
    .bx-shell-main > section.bxh-field {
      clip-path: url(#bxh-wave);
      margin-top: calc(-1 * var(--bxc));
      margin-bottom: calc(-1 * var(--bxc));
      padding-top: calc(var(--bxc) * 1.75 + 12px);
      padding-bottom: calc(var(--bxc) * 1.75 + 12px);
      z-index: 1;
    }
    .bxh-field .bx-eyebrow::before { background: var(--bm-yellow); }
    .bxh-field .bx-h2 { color: #fff; }
    /* The connector runs between cards on the cobalt ground, so it lightens. */
    .bxh-field .bx-path .rt { stroke: #fff; opacity: 0.5; }
    .bxh-field .bx-path .nd { fill: #fff; }
    /* Card borders lift slightly so each fill still has an edge against the strong ground. */
    #bx-main .bxh-field .bx-step { border-color: var(--bm-blue-border); }
    /* bm-on-dark switches heading colours to white for the whole band — correct for the section's
       own H2, WRONG inside the cards, which are light. Measured: card 1's title rendered white on
       white and disappeared entirely. Card text is re-asserted to its normal ink/body values; only
       the section header stays on-dark. */
    #bx-main .bxh-field .bx-step-title { color: var(--bm-ink); }
    #bx-main .bxh-field .bx-step-copy { color: var(--bm-body); }
    #bx-main .bxh-field .bx-step-num { color: var(--bm-navy); }
    #bx-main .bxh-field .bx-step:last-child .bx-step-num { color: var(--bm-on-yellow); }

:root { --bm-header-h: 76px; --bm-header-visible-h: 76px; }
    body { margin: 0; padding-top: var(--bm-header-h); }
    [id] { scroll-margin-top: calc(var(--bm-header-h) + 16px); }
    /* R4.27 (owner-directed): catalog search in the header bar, in the slot the phone number used to occupy.
       The DS Header has no search slot, so the website adapter overlays the shared SiteSearch on the bar,
       aligned to the actions group (measured, re-measured on resize), and follows the bar's hide-on-scroll.
       Below 768px (where the phone link was already hidden) it becomes a 44px search button that opens a
       full-width search row under the bar. */
    /* The DS phone link is removed from the bar (owner). Its display/padding are inline (React-owned), so the
       page rule takes it out of flow and sight instead of fighting display — no !important. */
    .bxh-bar a[href="tel:8454997499"].bxh-hide-md { position: absolute; width: 0; height: 0; overflow: hidden; opacity: 0; visibility: hidden; pointer-events: none; margin: 0; }
    .bxh-search-slot { position: fixed; top: 14px; z-index: 201; height: 48px; display: flex; align-items: center; transition: opacity var(--bm-duration-base, 220ms) var(--bm-ease, ease), transform var(--bm-duration-base, 220ms) var(--bm-ease, ease); }
    .bxh-search-slot[data-hidden="true"] { opacity: 0; transform: translateY(-90px); pointer-events: none; }
    .bxh-search-btn { width: 44px; height: 44px; display: grid; place-items: center; background: transparent; border: 1px solid var(--bm-border); border-radius: 12px; cursor: pointer; color: var(--bm-navy); padding: 0; box-sizing: border-box; }
    .bxh-search-btn:hover { background: var(--bm-blue-mist, #F1F5FC); }
    .bxh-search-btn:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: 2px; }
    .bxh-search-sheet { position: fixed; top: var(--bm-header-visible-h, 76px); left: 0; right: 0; z-index: 199; background: rgba(255,255,255,0.98); border-bottom: 1px solid var(--bm-border-soft); padding: 10px clamp(18px,3vw,40px) 14px; box-sizing: border-box; box-shadow: 0 12px 32px rgba(0,0,71,0.10); }
    @media (prefers-reduced-motion: reduce) { .bxh-search-slot { transition: none; } }

body { margin: 0; }
    /* Rev 12 rail scroll contract (contract-rail.html): the rail shell owns height; the nav yields
       (flex 0 1 auto, own scroll); the quote module is a min-height:0 flex column; ONLY the quote
       row list scrolls; the Review CTA is a non-scrolling sibling. No page-level clones, no
       competing overflow ancestors, no !important overflow workarounds, no trapped wheel. */
    .bxr { display: flex; flex-direction: column; height: 100%; min-height: 0; box-sizing: border-box; background: #fff; }
    .bxr-nav { flex: 0 1 auto; min-height: 0; overflow-y: auto; padding: 24px 20px 12px 20px; box-sizing: border-box; display: flex; flex-direction: column; }
    .bxr-cap { font: var(--bm-eyebrow); letter-spacing: 0.1em; text-transform: uppercase; color: var(--bm-muted); padding: 0 12px 12px; flex: none; }
    .bxr-back { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 12px; border-radius: 12px; color: var(--bm-blue); font: var(--bm-body-sm); font-weight: 700; text-decoration: none; transition: background 160ms; flex: none; }
    .bxr-back:hover { background: var(--bm-blue-mist, #F1F5FC); color: var(--bm-blue); }
    /* Rev 14: the redundant scope-heading path (.bxr-level/levelLabel/hasLevel) is REMOVED. */
    /* Rev 09/12 link boundary: row colours/current state come from the DS .bm-rail-link classed
       states (tokens/base.css — pale-blue current surface + 3px inset cobalt indicator, never
       yellow); local rules are layout-only. Light inset dividers between actionable rows. */
    .bxr-sep { border-top: 1px solid var(--bm-border-soft); margin: 0 12px; flex: none; }
    .bxr-item { display: flex; align-items: center; gap: 12px; min-height: 50px; padding: 0 12px; border-radius: 14px; font: var(--bm-title-md); transition: background 180ms cubic-bezier(0.2,0.8,0.2,1), color 180ms cubic-bezier(0.2,0.8,0.2,1); }
    .bxr-item[aria-current="true"] { color: var(--bm-blue); box-shadow: inset 3px 0 0 var(--bm-blue); }
    .bxr-plate { width: 34px; height: 34px; border-radius: 10px; background: var(--bm-blue-soft); border: 1px solid var(--bm-blue-border); display: grid; place-items: center; flex: none; color: var(--bm-blue); }
    .bxr-plate svg { width: 18px; height: 18px; display: block; }
    .bxq-mod { margin-top: auto; display: flex; flex-direction: column; min-height: 0; border-top: 1px solid var(--bm-border-soft); background: #fff; }
    /* Owner request (Sept 2026): the quote module anchors to the BOTTOM of the rail — heading and items sit
       directly above the Review quote CTA and grow upward as items are added, instead of hanging from the top. */
    .bxq-head { display: flex; align-items: center; gap: 4px; padding: 10px 14px 2px 14px; flex: none; margin-top: auto; }
    .bxq-toggle { flex: 1 1 auto; display: flex; align-items: center; gap: 10px; min-height: 44px; min-width: 0; padding: 0 10px; background: transparent; border: none; border-radius: 12px; cursor: pointer; text-align: left; transition: background 180ms cubic-bezier(0.2,0.8,0.2,1); }
    .bxq-toggle:hover { background: var(--bm-blue-mist, #F1F5FC); }
    .bxq-title { font: 700 14px/1.3 var(--bm-font-body); color: var(--bm-navy); }
    .bxq-chev { font-size: 10px; color: var(--bm-muted); transition: transform 220ms cubic-bezier(0.2,0.8,0.2,1); display: inline-block; }
    .bxq-preview { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 0 14px 0 20px; box-sizing: border-box; }
    /* Only this list scrolls; wheel at its boundaries resumes page scroll (no overscroll trap). */
    .bxq-view { flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-gutter: stable; }
    .bxq-list { display: flex; flex-direction: column; }
    .bxq-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding: 9px 4px 9px 12px; border-top: 1px solid var(--bm-border-soft); }
    .bxq-list > .bxq-row:first-child { border-top: 0; }
    .bxq-thumb { width: 42px; height: 42px; display: flex; align-items: center; justify-content: center; flex: none; }
    .bxq-thumb img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
    .bxq-name { font: 600 14px/1.3 var(--bm-font-body); color: inherit; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-width: 0; }
    /* Rev 18.3: the P6 overlay-anchor bridge is DELETED. QuotePreviewRow now ships `productHref`, so the
       shared component owns the combined thumbnail+title anchor, its no-underline blue hover/focus band,
       the pure-white image well and the controls-outside-the-link structure. No page-level override. */
    /* Rev 18.4-R1 — the rail deliberately shows NO price. Per-unit prices live on the product
       cards, the product page and the Request Quote review; in a 300px rail they crowded the row
       and forced the controls to wrap. Removing them also retires the wrap/gap workarounds the
       price line needed, so the row returns to the DS geometry: name, then stepper + remove. */
    /* removed (Rev 18.8): QuotePreviewRow's remove control now owns its destructive hover,
       so the page no longer needs !important to reach past the component's inline styles. */

    /* Rev 17.3 row detail link: thumbnail + name are one 44px-tall focusable target. Colour/hover/current
       states come from the shared .bm-rail-link contract in tokens/base.css — no local link restyling. */
    .bxq-detail { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 120px; min-height: 44px; padding: 2px 4px 2px 0; border-radius: 10px; text-decoration: none; }
    .bxq-detail:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: 2px; }
    /* QuantityStepper: DS component (Rev 10) per row; stepper + remove clustered right. */
    .bxq-ctl { display: flex; align-items: center; gap: 2px; flex-wrap: nowrap; flex-shrink: 0; margin-left: auto; }
    .bxq-x { width: 44px; height: 44px; margin: 0; border-radius: 12px; background: transparent; border: none; color: var(--bm-muted); display: grid; place-items: center; line-height: 0; padding: 0; cursor: pointer; align-self: center; transition: background 180ms cubic-bezier(0.2,0.8,0.2,1), color 180ms cubic-bezier(0.2,0.8,0.2,1); }
    .bxq-x:hover { background: #FFF1F1; color: #B42318; }
    .bxq-x:active { background: #FFE4E4; color: #B42318; }
    .bxq-x:focus-visible { background: #FFF1F1; color: #B42318; outline: 3px solid var(--bm-blue); outline-offset: -3px; }
    .bxq-x svg { width: 12px; height: 12px; flex: none; pointer-events: none; display: block; }
    .bxq-close { flex: none; }
    .bxq-close:hover { background: var(--bm-blue-mist, #F1F5FC); color: var(--bm-navy); }
    .bxq-close:active { background: var(--bm-blue-soft); color: var(--bm-navy); }
    .bxq-close:focus-visible { background: var(--bm-blue-mist, #F1F5FC); color: var(--bm-navy); outline: 3px solid var(--bm-blue); outline-offset: -3px; }
    .bxr-cta-region { flex: none; background: #fff; padding: 12px 20px 16px; box-sizing: border-box; display: flex; flex-direction: column; gap: 8px; }
    /* Rev 09 link boundary: CTA colours/states come from the DS .bm-rail-cta (tokens/base.css). */
    .bxr-cta { display: inline-flex; align-items: center; justify-content: center; text-align: center; gap: 10px; width: 100%; min-height: 48px; padding: 0 18px; border-radius: 9999px; border: 1.5px solid transparent; font: var(--bm-button); box-sizing: border-box; transition: background 220ms cubic-bezier(0.2,0.8,0.2,1), border-color 220ms cubic-bezier(0.2,0.8,0.2,1); }
    .bxr-qsum { font: var(--bm-body-sm); color: var(--bm-body); display: flex; align-items: center; gap: 8px; min-height: 24px; }
    .bxr-spacer { flex: 1 1 auto; }
    a:focus-visible, button:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: 2px; }
    @media (prefers-reduced-motion: reduce) { .bxr * { transition: none !important; } }

/* Rev 08F carousel V5 (round 39): card-contained actions via container query (responds to the
       component's own width, not the viewport), min-width:0 shrink path, uncovered focus rings
       (padding instead of overflow clipping), and the full title-link state contract
       (ink default/visited → cobalt hover/focus/active, never underlined). */
    body { margin: 0; }
    .bxf2-root { outline: none; }
    .bxf2-root:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: 4px; }
    .bxf2-copy { display: flex; flex-direction: column; gap: 10px; min-width: 0; container-type: inline-size; }
    /* Rev 18.4-R1 — the action row is raised above any decorative layer on the host page. A
       programmatic click on Add to quote registers (verified: units 57->58 on home at 430px), so
       the handler is sound; this guards against a page-level pseudo-element or overlay ever
       intercepting the real pointer event, which is the only way a working handler can look dead. */
    .bxf2-act { display: flex; align-items: center; gap: 12px; padding: 6px 4px 4px 4px; min-height: 46px; min-width: 0; flex-wrap: wrap; position: relative; z-index: 2; }
    .bxf2-stp { display: flex; align-items: center; gap: 4px; flex: none; }
    /* R75 shared QuantityStepper capsule */
    /* QuantityStepper: DS component (Rev 10) mounted via x-import — no page-local stepper CSS */
    .bxf2-qty-lbl { font: var(--bm-caption); font-weight: 700; color: var(--bm-muted); text-transform: uppercase; letter-spacing: 0.06em; margin-right: 4px; }
    /* Rev 18.4-R1 — quantity stepper matched to the other product cards: ONE pill with a single
       rounded outline around [− n +] and light dividers between the segments, instead of three
       separate glyph rings. Height is 46px here to sit level with .bxf2-add beside it. The DS
       QuantityStepper inline-styles each ring, so the per-glyph rings are overridden off and the
       group becomes the affordance. Hit targets stay 46×46. */
    .bxf2-stp [role="group"][aria-label^="Quantity for"] {
      height: 46px; box-sizing: border-box; background: #fff;
      border: 1px solid var(--bm-border); border-radius: 9999px;
      width: fit-content; flex: 0 0 auto;
    }
    .bxf2-stp [role="group"][aria-label^="Quantity for"] > button { height: 100% !important; width: 46px !important; }
    .bxf2-stp [role="group"][aria-label^="Quantity for"] > button > span {
      width: 100% !important; height: 100% !important;
      border: 0 !important; background: transparent !important; border-radius: 0 !important;
      font-size: 18px !important; color: var(--bm-navy) !important;
    }
    .bxf2-stp [role="group"][aria-label^="Quantity for"] > button:first-of-type > span { border-radius: 9999px 0 0 9999px !important; }
    .bxf2-stp [role="group"][aria-label^="Quantity for"] > button:last-of-type > span { border-radius: 0 9999px 9999px 0 !important; }
    .bxf2-stp [role="group"][aria-label^="Quantity for"] > button:not(:disabled):hover > span { background: var(--bm-blue-soft) !important; }
    .bxf2-stp [role="group"][aria-label^="Quantity for"] > .bm-qs-input {
      height: 100% !important; width: 46px !important; margin: 0 !important;
      border-radius: 0 !important; border-top: 0 !important; border-bottom: 0 !important;
      border-left: 1px solid var(--bm-border-soft) !important;
      border-right: 1px solid var(--bm-border-soft) !important;
    }
    .bxf2-add { flex: 1 1 140px; min-width: 0; max-width: 300px; min-height: 46px; padding: 0 16px; border-radius: 9999px; font: var(--bm-button); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; box-sizing: border-box; transition: background 220ms cubic-bezier(0.2,0.8,0.2,1); }
    /* Card-width (container) stacking: when the copy column itself is narrow — even on a wide
       viewport — the Add button drops to a clean full-width second row. */
    @container (max-width: 379px) { .bxf2-add { flex: 1 1 100%; max-width: none; } }
    .bxf2-grid { display: grid; grid-template-columns: 44fr 56fr; gap: clamp(24px, 3.5vw, 44px); align-items: center; }
    /* Rev 18.4-R1 — square well so square catalog art actually fills it. This was a 336x240 box
       holding 1024x1024 artwork: contain capped on the short axis and left ~130px of dead width
       beside the product (measured area fill 0.53). A square well removes the wasted axis, and the
       image is given the full well box instead of an intrinsic size so it uses the short axis too.
       Still object-fit: contain, so nothing is cropped or distorted. */
    .bxf2-img { display: flex; align-items: center; justify-content: center; width: 100%; max-width: 320px; aspect-ratio: 1 / 1; height: auto; margin-inline: auto; padding: 10px; box-sizing: border-box; border-radius: 12px; }
    .bxf2-img img, .bxf2-img picture, .bxf2-img picture img {
      width: 100%; height: 100%; object-fit: contain; object-position: center; display: block;
    }
    .bxf2-name, .bxf2-name:link, .bxf2-name:visited { font: var(--bm-heading-3); font-family: var(--bm-font-display); color: var(--bm-ink); letter-spacing: -0.018em; line-height: 1.18; text-decoration: none; text-wrap: pretty; display: block; min-height: 3.6em; transition: color 180ms cubic-bezier(0.2,0.8,0.2,1); }
    .bxf2-name:hover, .bxf2-name:active { color: var(--bm-blue); text-decoration: none; }
    .bxf2-name:focus-visible { color: var(--bm-blue); text-decoration: none; outline: 3px solid var(--bm-blue); outline-offset: 3px; border-radius: 6px; }
    .bxf2-desc { font: var(--bm-body-md); color: var(--bm-body); margin: 0; line-height: 1.55; height: 4.68em; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; text-wrap: pretty; }
    /* R75 CarouselNavButton — true circle, grid-centered chevron, quiet outline */
    .bxf2-btn { width: 48px; height: 48px; border-radius: 50%; background: #fff; display: grid; place-items: center; line-height: 0; padding: 0; box-sizing: border-box; transition: background 220ms cubic-bezier(0.2,0.8,0.2,1), border-color 220ms cubic-bezier(0.2,0.8,0.2,1); }
    .bxf2-btn:enabled { cursor: pointer; }
    .bxf2-btn:hover:enabled { background: var(--bm-blue-soft); }
    .bxf2-btn:active:enabled { background: var(--bm-blue-border); }
    .bxf2-seg { width: 44px; height: 44px; background: transparent; border: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
    .bxf2-seg span { width: 22px; height: 4px; border-radius: 2px; display: block; transition: background 220ms cubic-bezier(0.2,0.8,0.2,1); }
    @media (max-width: 899px) { .bxf2-grid { grid-template-columns: 1fr; gap: 14px; } .bxf2-img { height: 230px; } }
    @media (max-width: 599px) { .bxf2-name { min-height: 4.8em; } }
    @media (max-width: 479px) { .bxf2-desc { height: 6.24em; -webkit-line-clamp: 4; } }
    @media (prefers-reduced-motion: reduce) { .bxf2-btn, .bxf2-seg span { transition: none !important; } }

body { margin: 0; }
    /* Rev 10 link boundary: content-link colours come from the DS :where(a) rules; no bare a{} rules. Classed header/footer links own their states. */
    .bxf-grid { display: grid; grid-template-columns: minmax(110px, 0.7fr) minmax(130px, 1fr) minmax(130px, 0.9fr) minmax(110px, 0.8fr) minmax(300px, 1.2fr); gap: clamp(20px, 2.4vw, 32px); }
    /* Actions: compact group after the hours, side by side whenever the Contact track is ≥300px. */
    .bxf-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.14); max-width: 380px; }
    .bxf-contact { container: bxfc / inline-size; }
    /* Rev 07 — tablet/narrow desktop: named areas, no auto-placement. Brand row, balanced
       three-column navigation row, then Contact as a compact full-width row. */
    @media (max-width: 1179px) {
      .bxf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-areas: "brand brand brand" "browse services company" "contact contact contact"; row-gap: 36px; }
      .bxf-brand { grid-area: brand; }
      .bxf-browse { grid-area: browse; }
      .bxf-services { grid-area: services; }
      .bxf-company { grid-area: company; }
      .bxf-contact { grid-area: contact; }
    }
    /* Rev 07 — mobile: brand, two-column nav subgrid (Browse tall left; Services + Company right), contact. */
    @media (max-width: 599px) {
      .bxf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-areas: "brand brand" "browse services" "browse company" "contact contact"; column-gap: 24px; row-gap: 28px; }
    }
    @media (max-width: 419px) {
      .bxf-grid { grid-template-columns: 1fr; grid-template-areas: "brand" "browse" "services" "company" "contact"; row-gap: 26px; }
    }
    /* Stack equal full width only where two buttons genuinely can't fit; cap so pills don't oversize. */
    @media (max-width: 479px) { .bxf-actions { grid-template-columns: 1fr; max-width: 320px; } }
    /* Rev 08D — the footer stays full width; only its inner container follows the page measure.
       Defaults reproduce the previous centred 1360px container exactly; a page that publishes the
       --bx-footer-* hooks (home) aligns the inner grid to its main content column instead. */
    .bxf-inner { max-width: 1360px; margin: 0 auto; padding: 52px clamp(18px,3vw,48px) 28px; box-sizing: border-box; }
    @media (min-width: 1200px) {
      .bxf-inner {
        max-width: var(--bx-footer-max, 1360px);
        margin-left: var(--bx-footer-ml, auto);
        margin-right: var(--bx-footer-mr, auto);
        padding-left: var(--bx-footer-pl, clamp(18px,3vw,48px));
        padding-right: var(--bx-footer-pr, clamp(18px,3vw,48px));
      }
    }

.bm-qs{display:inline-flex;align-items:center;width:fit-content;flex:0 0 auto;box-sizing:border-box}.bm-qs--discs{gap:0}.bm-qs--segmented{border:1px solid var(--bm-border);border-radius:9999px;background:#fff;overflow:hidden}.bm-qs--segmented .bm-qs__btn{border-radius:0}.bm-qs--segmented .bm-qs__btn:hover:not(:disabled){background:var(--bm-surface-blue)}.bm-qs__btn:focus-visible{outline:2px solid var(--bm-blue);outline-offset:-2px}

body { margin: 0; }
    address { font-style: normal; }
    .bxcd { display: flex; flex-direction: column; }
    .bxcd-group { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
    /* footer variant: compact groups, subtle dividers */
    .bxcd-f { gap: 11px; }
    .bxcd-f .bxcd-group + .bxcd-group { border-top: 1px solid rgba(255,255,255,0.14); padding-top: 11px; }
    /* page variant: more air, light dividers */
    .bxcd-p { gap: 18px; }
    .bxcd-p .bxcd-group + .bxcd-group { border-top: 1px solid var(--bm-border-soft); padding-top: 18px; }
    /* hours grids — rows can never wrap internally */
    .bxcd-hours { margin: 0; }
    .bxcd-hours dt, .bxcd-hours dd { margin: 0; white-space: nowrap; }
    .bxcd-hours-f { display: grid; grid-template-columns: max-content max-content; justify-content: start; column-gap: 12px; row-gap: 5px; }
    .bxcd-hours-p { display: grid; grid-template-columns: minmax(0, 1fr) max-content; column-gap: 16px; row-gap: 6px; max-width: 340px; }
    @media (max-width: 379px) {
      .bxcd-hours-p { grid-template-columns: 1fr; row-gap: 2px; }
      .bxcd-hours-p dd { margin-bottom: 6px; }
    }
    /* Rev 07 — when the footer Contact block spans a full-width row (container ≥ 40rem),
       the three groups form a compact horizontal subgrid instead of one tall column. */
    @container bxfc (min-width: 40rem) {
      .bxcd-f { display: grid; grid-template-columns: repeat(3, minmax(0, max-content)); column-gap: clamp(32px, 8cqw, 88px); row-gap: 12px; align-items: start; }
      .bxcd-f > div:first-child { grid-column: 1 / -1; }
      .bxcd-f .bxcd-group + .bxcd-group { border-top: none; padding-top: 0; }
    }

body { margin: 0; }
    .bxs-input::placeholder { color: var(--bm-muted); }
    .bxs-input:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: 2px; }
    .bxs-opt:hover, .bxs-opt[aria-selected="true"] { background: var(--bm-blue-mist, #F1F5FC); }
    .bxs-opt:focus-visible, .bxs-all:focus-visible { outline: 3px solid var(--bm-blue); outline-offset: -3px; }
    .bxs-all:hover { background: var(--bm-blue-mist, #F1F5FC); }

.bxh-nav-desktop{display:flex}.bxh-burger,.bxh-mobile-quote{display:none !important}.bxh-iconbtn{width:44px;height:44px;place-items:center;line-height:0;background:transparent;border:1px solid var(--bm-border);border-radius:12px;cursor:pointer;color:var(--bm-navy);padding:0;box-sizing:border-box}.bxh-iconbtn svg{display:block}.bxh-toast{position:fixed;left:50%;transform:translateX(-50%);bottom:14px;z-index:240;display:flex;align-items:center;gap:10px;background:#fff;color:var(--bm-ink);border:1px solid var(--bm-border);border-radius:16px;padding:5px 5px 5px 14px;box-shadow:0 10px 30px rgba(0,0,71,.16);max-width:min(420px,calc(100vw - 24px));box-sizing:border-box}.bxh-toast__text{overflow:hidden}.bxh-toast__text>span:first-child{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:1199px){.bxh-nav-desktop{display:none !important}.bxh-burger{display:grid !important}}@media(max-width:767px){.bxh-hide-md{display:none !important}}@media(max-width:479px){.bxh-hide-narrow{display:none !important}.bxh-mobile-quote{display:grid !important}}@media(prefers-reduced-motion:reduce){.bxh-bar{transition:none !important}}

/* The container element cannot query ITSELF — @container only matches descendants — so the
   container-type lives on an OUTER wrapper and the grid inside it is what responds. This was the
   real cause of the homepage regression: with container-type on .bm-plan, the old
   `@container (min-width:58rem)` rule could never apply, leaving the grid pinned to its base
   single-column value at every width. */.bm-plan-outer{container-type:inline-size;container-name:bm-plan}.bm-plan{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:26px 28px}@container bm-plan (max-width:44rem){.bm-plan{grid-template-columns:minmax(0,1fr);gap:22px}}@supports not (container-type:inline-size){@media (max-width:767px){.bm-plan{grid-template-columns:minmax(0,1fr);gap:22px}}}.bm-plan-card{display:grid;grid-template-columns:152px minmax(0,1fr);gap:18px;align-items:start;border-radius:22px;padding:clamp(20px,2cqi,26px);background:#fff;border:1px solid var(--bm-border);text-decoration:none;box-sizing:border-box;height:100%;transition:border var(--bm-duration-base) var(--bm-ease),box-shadow var(--bm-duration-base) var(--bm-ease)}.bm-plan-card:hover{border-color:var(--bm-blue);box-shadow:var(--bm-shadow-low)}.bm-plan-card__well{width:152px;height:152px;display:grid;place-items:center;background:#fff;border:1px solid var(--bm-border-soft);border-radius:16px;overflow:hidden;padding:10px;box-sizing:border-box}.bm-plan-card__well img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;display:block}.bm-plan-card__body{display:flex;flex-direction:column;gap:8px;min-width:0;height:100%;text-align:left;align-items:flex-start}.bm-plan-card__action{margin-top:auto;display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 20px;border-radius:9999px;font:var(--bm-button);background:var(--bm-blue);color:#fff}.bm-plan-card:hover .bm-plan-card__action{background:var(--bm-blue-hover)}.bm-plan-card--action-full .bm-plan-card__action{width:100%}.bm-plan-card--action-add .bm-plan-card__action{background:var(--bm-add-bg);color:var(--bm-add-text);border:1.5px solid var(--bm-add-border)}.bm-plan-card--action-add:hover .bm-plan-card__action{background:var(--bm-add-bg-hover,var(--bm-surface-blue))}@container bm-plan (max-width:30rem){.bm-plan-card{grid-template-columns:minmax(0,1fr)}.bm-plan-card__well{width:100%;height:auto;aspect-ratio:1/1}.bm-plan-card__action{width:100%}}@supports not (container-type:inline-size){@media(max-width:479px){.bm-plan-card{grid-template-columns:minmax(0,1fr)}.bm-plan-card__well{width:100%;height:auto;aspect-ratio:1/1}.bm-plan-card__action{width:100%}}}

/* BX PILL STACK RESET (ordered) --------------------------------------------------------------
   Must come AFTER the base .bm-plan-card__action rule: both have the same specificity, so the
   later declaration wins. When the card stacks the decorative rule is hidden and the pill spans
   the full width, so the -18px pull has to be undone or the pill hangs off the card's left edge.
   -------------------------------------------------------------------------------------------- */
@container bm-plan (max-width: 30rem) {
  #bx-main #bx-plan-grid .bm-plan-card__action { margin-left: 0; width: 100%; }
}
@supports not (container-type: inline-size) {
  @media (max-width: 479px) {
    #bx-main #bx-plan-grid .bm-plan-card__action { margin-left: 0; width: 100%; }
  }
}
