/* =============================================================================
   BMW BRAND LAYER
   Loaded additively after theme.css when brand_make = "bmw".
   EVERY selector MUST be scoped under .brand-bmw so it can never affect other
   brands or the generic look. Ported from the former brand-bmw.css "skin",
   rewritten as scoped layers on top of the base theme (no global reset, no
   stylesheet swap). Her global reset is intentionally dropped — the base
   theme.css owns normalize/box-sizing.

   Box style variants combine here as:  .brand-bmw .box-style-luxury { … }
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. TOKENS
   BMW design tokens (her names, so ported component CSS works unchanged) PLUS
   mappings onto the theme's tokens (so base theme components render BMW-styled).
   ----------------------------------------------------------------------------- */
.brand-bmw {
    /* ---- BMW CI palette ---- */
    --white: #ffffff;
    --black: #1a1a1a;
    --grey-900: #262626;
    --grey-700: #494949;   /* CI dark grey — primary text */
    --grey-500: #6f6f6f;
    --grey-400: #929292;
    --grey-300: #c7c7c7;
    --grey-200: #d6d6d6;   /* hairlines */
    --grey-100: #ededee;
    --grey-50: #f4f5f7;

    --blue: #0066b1;       /* BMW Blue */
    --blue-dark: #003d78;
    --blue-700: #00518f;
    /* BMW M tricolor — light blue, dark blue, red. Values are the official BMW
       symbol colours from BMW Group CI "The Basics and Principles of the BMW
       Brand Design" v2.0 (March 2020), §3 Colours, p.9 — see
       docs/brand_guidelines/bmw/Design_Basics_and_Principles_March_2020.pdf.
       The middle band is a DARK BLUE (symbol C), not violet. */
    --m-red: #e22718;      /* M red — CI symbol D (Pantone 7626C, sRGB 226/39/24) */
    --m-blue: #0066b1;     /* M light blue — CI symbol B (Pantone 2144C, sRGB 0/102/177) */
    --m-navy: #003d78;     /* M dark blue — CI symbol C (Pantone 294C, sRGB 0/61/120) */
    --m-stripe: linear-gradient(90deg, var(--m-blue) 0 33.3%, var(--m-navy) 33.3% 66.6%, var(--m-red) 66.6% 100%);

    /* ---- Semantic (her component CSS reads these) ---- */
    --ink: var(--grey-700);
    --ink-strong: var(--black);
    --ink-soft: var(--grey-500);
    --line: var(--grey-200);
    --bg: var(--white);
    --bg-alt: var(--grey-50);
    --accent: var(--blue);

    /* ---- Type scale ---- */
    --font: "BMW Type Next", "Helvetica Neue", Arial, sans-serif;
    --fs-display: clamp(2.9rem, 6.6vw, 6rem);
    --fs-h1: clamp(2.3rem, 4.6vw, 4.1rem);
    --fs-h2: clamp(1.85rem, 3.3vw, 3rem);
    --fs-h3: clamp(1.3rem, 1.9vw, 1.85rem);
    --fs-lead: clamp(1.05rem, 1.35vw, 1.3rem);
    --fs-body: 1.0625rem;
    --fs-small: 0.875rem;
    --fs-eyebrow: 0.78rem;

    /* ---- Layout ---- */
    --maxw: 1440px;
    --gutter: clamp(20px, 5vw, 88px);
    --section-y: clamp(64px, 8vw, 132px);
    --radius: 0px;          /* sharp corners — CI architectural */
    --radius-ui: 0px;
    --shadow-card: 0 1px 2px rgba(26,26,26,.04), 0 18px 40px -24px rgba(26,26,26,.22);
    --shadow-float: 0 24px 60px -28px rgba(0,61,120,.35);
    --ease: cubic-bezier(.2,.7,.2,1);
    --header-h: 76px;

    /* QA1-checkup-5 « réduire la hauteur du header » — scopé BMW EXPRÈS :
       --header-height vit sur :root dans theme.css et pilote les 9 marques.
       brands/bmw.css est chargé APRÈS theme.css (layouts/default.htm:146) et
       .brand-bmw (0,1,0) égale :root (0,1,0) → l'ordre de source tranche, et la
       classe est aussi posée sur <body>, donc tout le sous-arbre suit.
       ⚠️ le total au repos reste 34px de top-bar + 72px : le seuil maison <80px
       n'est atteignable au repos qu'en masquant le top-bar (réglage show_top_bar).
       Détail : reference_header_80px_gate_vs_top_bar. */
    --header-height: 72px;
    --header-height-scrolled: 60px;

    /* ---- Mappings onto the THEME tokens (base components inherit the BMW look) ---- */
    --brand-primary: var(--blue);
    --brand-primary-rgb: 0, 102, 177;
    --brand-accent: var(--blue);
    --brand-accent-hover: var(--blue-700);
    --brand-accent-rgb: 0, 102, 177;
    --brand-secondary: var(--black);

    --brand-text: var(--ink-strong);
    --brand-text-secondary: var(--ink);
    --brand-text-muted: var(--ink-soft);
    --brand-border: var(--line);

    --brand-dark: var(--black);
    --brand-dark-rgb: 26, 26, 26;
    --brand-bg-alt: var(--bg-alt);

    --font-heading: var(--font);
    --font-body: var(--font);

    /* Sharp, architectural radii across the base UI */
    --radius-sm: 0px;
    --radius-md: 0px;
    --radius-lg: 0px;
    --radius-xl: 0px;
    --radius-full: 0px;        /* pills/chips — BMW is square, not rounded */
    --fb-input-radius: 0px;    /* FormBuilder inputs */
    --bs-border-radius: 0px;   /* Bootstrap components */

    /* BMW button treatment */
    --btn-letter-spacing: 0.5px;
    --btn-font-size: 14px;
    --btn-border-radius: 0px;
}

/* Force the sharp radii to win even over later/higher-specificity var blocks
   (e.g. theme-variables' html[class] overrides). :root.brand-bmw = (0,2,0). */
:root.brand-bmw {
    --radius-sm: 0px; --radius-md: 0px; --radius-lg: 0px; --radius-xl: 0px; --radius-full: 0px;
    --btn-border-radius: 0px; --fb-input-radius: 0px; --bs-border-radius: 0px;
}

/* -----------------------------------------------------------------------------
   2. COMPONENT REFINEMENTS
   BMW-specific component/layout treatments (hero, cards, etc.) are ported here
   incrementally, each scoped under .brand-bmw, as the box style variants land.
   ----------------------------------------------------------------------------- */

/* Box heading weight default (QA #86a8, decision 2). Jade wants 300 without
   touching the backend dropdown, on all 8 heading classes theme.css's
   heading-weight-* mixin recognizes. NOT scoped to .box-style-luxury: the box
   partials don't gate these classes on that variable consistently (e.g.
   text-image.htm renders .text-image__title unconditionally, luxury or not)
   -- a project pitfall already paid once on the Models page grid. Two of the
   eight (.financing-form__title, .lead-form__title) have zero live instances
   on this site; .dloc__heading and the non-luxury .value-props__heading
   (sr-only even where used) are unreachable too, since dealer-location and
   value-props both render .h2 instead once boxStyle resolves to luxury
   (always true for BMW). Kept in the list anyway: harmless when unmatched,
   and correct the day any of those variants gets used. .h2 already computes
   to 300 via the more specific `.box-style-luxury .h2` rule below (kept, not
   redundant to remove -- it also carries size/case/color).
   No !important: theme.css's dropdown rules (.section.heading-weight-*) carry
   !important, so an explicit backend choice keeps winning over this default. */
.brand-bmw :is(.section-title, .text-image__title, .financing-form__title, .lead-form__title,
  .dloc__heading, .value-props__heading, .cta-banner__title, .h2) { font-weight: 300; }

/* --- Shared maquette primitives (only inside luxury boxes) --- */
.brand-bmw .box-style-luxury .eyebrow {
    font-size: var(--fs-eyebrow);
    font-weight: 400;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--accent);
    display: inline-flex;
    align-items: center;
    gap: .7em;
}
.brand-bmw .box-style-luxury .eyebrow.muted { color: var(--ink-soft); }
.brand-bmw .box-style-luxury .eyebrow::before {
    content: "";
    width: 26px;
    height: 2px;
    background: currentColor;
    display: inline-block;
}
.brand-bmw .box-style-luxury .h2 {
    font-size: var(--fs-h2);
    text-transform: uppercase;
    font-weight: 300;
    line-height: 1.04;
    color: var(--ink-strong);
    letter-spacing: -0.01em;
}
.brand-bmw .box-style-luxury .lead { font-size: var(--fs-lead); color: var(--ink); font-weight: 300; line-height: 1.5; }
.brand-bmw .box-style-luxury .muted { color: var(--ink-soft); }

.brand-bmw .box-style-luxury .section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 32px;
    flex-wrap: wrap;
    margin-bottom: clamp(28px, 4vw, 56px);
}
.brand-bmw .box-style-luxury .section-head .titles { max-width: 760px; }
.brand-bmw .box-style-luxury .section-head .eyebrow { margin-bottom: 18px; }
.brand-bmw .box-style-luxury .section-head .sub { margin-top: 16px; max-width: 56ch; }

/* --- value-props (luxury): feature strip --- */
.brand-bmw .box-style-luxury .feat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.brand-bmw .box-style-luxury .feat-grid .feat { background: var(--white); border: 1px solid var(--line); padding: 26px; }
.brand-bmw .box-style-luxury .feat-grid .feat .ico { width: 38px; height: 38px; color: var(--accent); margin-bottom: 14px; }
.brand-bmw .box-style-luxury .feat-grid .feat b { display: block; color: var(--ink-strong); font-weight: 400; margin-bottom: 6px; }
.brand-bmw .box-style-luxury .feat-grid .feat p { font-size: .9rem; color: var(--ink-soft); margin: 0; }
@media (max-width: 760px) {
    .brand-bmw .box-style-luxury .feat-grid { grid-template-columns: 1fr; }
}

/* --- services-grid (luxury): image variant + optional link, reuses .feat-grid --- */
.brand-bmw .box-style-luxury .feat-grid .feat__image { margin-bottom: 14px; border-radius: 2px; overflow: hidden; }
.brand-bmw .box-style-luxury .feat-grid .feat__image img { width: 100%; height: auto; display: block; }
.brand-bmw .box-style-luxury .feat-grid .feat__link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    font-size: .85rem;
    font-weight: 400;
    color: var(--accent);
    text-decoration: none;
    transition: gap 200ms ease;
}
.brand-bmw .box-style-luxury .feat-grid .feat__link:hover { gap: 10px; }

/* --- Shared: buttons --- */
.brand-bmw .box-style-luxury .btn {
    --bg: var(--accent); --fg: var(--white);
    display: inline-flex; align-items: center; justify-content: center; gap: .85em;
    padding: 1em 1.9em; background: var(--bg); color: var(--fg);
    font-size: .82rem; font-weight: 400; letter-spacing: .14em; text-transform: uppercase;
    border-radius: var(--radius-ui); position: relative; overflow: hidden;
    transition: transform .35s var(--ease), background .3s var(--ease), color .3s var(--ease), box-shadow .35s var(--ease);
    isolation: isolate; white-space: nowrap;
}
.brand-bmw .box-style-luxury .btn .ico { width: 1.05em; height: 1.05em; transition: transform .4s var(--ease); }
.brand-bmw .box-style-luxury .btn::after { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--blue-dark); transform: translateY(101%); transition: transform .42s var(--ease); }
.brand-bmw .box-style-luxury .btn:hover::after { transform: translateY(0); }
.brand-bmw .box-style-luxury .btn:hover { box-shadow: var(--shadow-float); }
.brand-bmw .box-style-luxury .btn:hover .ico { transform: translateX(5px); }
.brand-bmw .box-style-luxury .btn--ghost { --bg: transparent; --fg: var(--ink-strong); border: 1.5px solid var(--ink-strong); }

/* #32bc — les boutons de /promotions viennent du composant plugin
   `nerd/marketing/promotionslist`, rendu HORS de tout conteneur `.box-style-luxury` :
   ils gardaient donc le `.btn` de base du thème au lieu du contrat BMW ci-dessus.
   Mesuré le 2026-08-25, 1440 px, FR et EN :
     filtres      11.2px / 600 / AUCUNE bordure
     « Voir l offre » 14px / 600
     référence du site 13.12px / 400 / bordure 1px
   ⛔ On ne réécrit pas des valeurs à la main : on rattache ces boutons au MÊME
   contrat typographique que tous les autres. `html.brand-bmw` et non `.brand-bmw` :
   les deux classes sont posées sur le MÊME <body>, seul le <html> est un ancêtre. */
html.brand-bmw .page-promotions .btn,
html.brand-bmw .page-promotions .category-filter {
    font-size: .82rem;
    font-weight: 400;
    letter-spacing: .14em;
    text-transform: uppercase;
}
/* La variante contour du site porte une bordure ; celle du plugin n en avait pas. */
html.brand-bmw .page-promotions .category-filter { border: 1px solid var(--accent); }
.brand-bmw .box-style-luxury .btn--ghost::after { background: var(--ink-strong); }
.brand-bmw .box-style-luxury .btn--ghost:hover { color: var(--white); }
.brand-bmw .box-style-luxury .btn--sm { padding: .8em 1.3em; font-size: .74rem; }
.brand-bmw .box-style-luxury .btn--on-dark.btn--ghost { --fg: var(--white); border-color: rgba(255,255,255,.55); }
.brand-bmw .box-style-luxury .btn--on-dark.btn--ghost::after { background: var(--white); }
.brand-bmw .box-style-luxury .btn--on-dark.btn--ghost:hover { color: var(--ink-strong); }

/* --- Shared: M-stripe rule, section tones, badges --- */
.brand-bmw .box-style-luxury .m-rule { height: 4px; width: 64px; background: var(--m-stripe); }
.brand-bmw .box-style-luxury .section--alt { background: var(--bg-alt); }
.brand-bmw .box-style-luxury .badge { display: inline-flex; align-items: center; gap: .5em; font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; padding: .45em .8em; background: var(--ink-strong); color: var(--white); }
.brand-bmw .box-style-luxury .badge--new { background: var(--blue-dark); }
.brand-bmw .box-style-luxury .badge--used { background: var(--grey-700); }
.brand-bmw .box-style-luxury .badge--m { background: var(--ink-strong); position: relative; padding-left: 1.5em; }
.brand-bmw .box-style-luxury .badge--m::before { content: ""; position: absolute; left: .5em; top: 50%; transform: translateY(-50%); width: .55em; height: .9em; background: var(--m-stripe); }

/* --- testimonials (luxury): review cards --- */
.brand-bmw .box-style-luxury .bmw-reviews { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2.5vw, 28px); }
.brand-bmw .box-style-luxury .bmw-rv { background: var(--white); border: 1px solid var(--line); padding: 26px 24px 24px; display: flex; flex-direction: column; gap: 14px; transition: box-shadow .35s, transform .35s, border-color .3s; }
.brand-bmw .box-style-luxury .bmw-rv:hover { box-shadow: var(--shadow-card); transform: translateY(-3px); border-color: transparent; }
.brand-bmw .box-style-luxury .bmw-rv__top { display: flex; align-items: center; justify-content: space-between; }
.brand-bmw .box-style-luxury .bmw-rv__stars { display: flex; gap: 2px; }
.brand-bmw .box-style-luxury .bmw-rv__source { display: flex; align-items: center; opacity: .7; }
.brand-bmw .box-style-luxury .bmw-rv__quote { font-size: .96rem; color: var(--ink-soft); line-height: 1.65; margin: 0; flex: 1; }
.brand-bmw .box-style-luxury .bmw-rv__quote::before { content: '\201C'; font-size: 1.4rem; color: var(--accent); line-height: 0; vertical-align: -.3em; margin-right: 3px; }
.brand-bmw .box-style-luxury .bmw-rv__author { display: flex; align-items: center; gap: 12px; padding-top: 14px; border-top: 1px solid var(--line); }
.brand-bmw .box-style-luxury .bmw-rv__avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.brand-bmw .box-style-luxury .bmw-rv__avatar--init { background: linear-gradient(150deg, var(--accent), #003d78); color: #fff; display: grid; place-items: center; font-size: 1rem; font-weight: 300; border-radius: 50%; }
.brand-bmw .box-style-luxury .bmw-rv__name { display: block; font-weight: 400; color: var(--ink-strong); font-size: .95rem; }
.brand-bmw .box-style-luxury .bmw-rv__role { font-size: .78rem; color: var(--accent); letter-spacing: .04em; margin-top: 2px; }
@media (max-width: 900px) { .brand-bmw .box-style-luxury .bmw-reviews { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .brand-bmw .box-style-luxury .bmw-reviews { grid-template-columns: 1fr; } }

/* --- cta-cards (luxury): culture/perk grid --- */
.brand-bmw .box-style-luxury .culture-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; margin-top: 4px; }
.brand-bmw .box-style-luxury .perk { background: var(--white); border: 1px solid var(--line); padding: 30px 26px; transition: box-shadow .35s, transform .35s, border-color .3s; }
.brand-bmw .box-style-luxury .perk:hover { box-shadow: var(--shadow-card); transform: translateY(-4px); border-color: transparent; }
.brand-bmw .box-style-luxury .perk .perk-ico { width: 44px; height: 44px; display: grid; place-items: center; background: var(--bg-alt); color: var(--accent); margin-bottom: 18px; }
.brand-bmw .box-style-luxury .perk h3 { font-size: 1.05rem; color: var(--ink-strong); margin-bottom: 8px; }
.brand-bmw .box-style-luxury .perk p { font-size: .9rem; color: var(--ink-soft); }
@media (max-width: 900px) { .brand-bmw .box-style-luxury .culture-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .brand-bmw .box-style-luxury .culture-grid { grid-template-columns: 1fr; } }

/* --- split-cta (luxury): intro band --- */
.brand-bmw .box-style-luxury .intro-band { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px,4vw,64px); align-items: center; }
.brand-bmw .box-style-luxury .intro-band .intro-media { aspect-ratio: 5/4; position: relative; }
.brand-bmw .box-style-luxury .intro-band .intro-media img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 820px) { .brand-bmw .box-style-luxury .intro-band { grid-template-columns: 1fr; } }

/* --- accordion (luxury): FAQ --- */
.brand-bmw .box-style-luxury .bmw-faq__item { border-bottom: 1px solid var(--line); }
.brand-bmw .box-style-luxury .bmw-faq__item:first-child { border-top: 1px solid var(--line); }
.brand-bmw .box-style-luxury .bmw-faq__q { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1.3rem 0; cursor: pointer; list-style: none; font-size: var(--fs-body); font-weight: 400; color: var(--ink-strong); letter-spacing: .01em; user-select: none; transition: color .2s; }
.brand-bmw .box-style-luxury .bmw-faq__q::-webkit-details-marker { display: none; }
.brand-bmw .box-style-luxury .bmw-faq__q:hover { color: var(--accent); }
.brand-bmw .box-style-luxury .bmw-faq__chevron { flex-shrink: 0; color: var(--accent); transition: transform .3s var(--ease); }
.brand-bmw .box-style-luxury .bmw-faq__item[open] .bmw-faq__chevron { transform: rotate(180deg); }
.brand-bmw .box-style-luxury .bmw-faq__a { padding: 0 0 1.4rem; color: var(--ink-soft); line-height: 1.75; font-weight: 300; font-size: var(--fs-body); }
.brand-bmw .box-style-luxury .bmw-faq__a p:last-child { margin-bottom: 0; }
.brand-bmw .box-style-luxury .bmw-faq__a strong { font-weight: 400; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .bmw-faq__a ul, .brand-bmw .box-style-luxury .bmw-faq__a ol { padding-left: 1.5rem; margin-bottom: 1em; }
.brand-bmw .box-style-luxury .bmw-faq__a li { margin-bottom: .4em; }

/* --- geo-stats (luxury): trust figures --- */
.brand-bmw .box-style-luxury .lead-trust { display: flex; gap: 28px; margin-top: 30px; flex-wrap: wrap; }
.brand-bmw .box-style-luxury .lead-trust .t .n { font-size: 2rem; font-weight: 300; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .lead-trust .t .l { font-size: .78rem; color: var(--ink-soft); letter-spacing: .04em; }

/* --- geo-takeaways (luxury): SEO two-column block --- */
.brand-bmw .box-style-luxury .seo-block .seo-grid2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(28px, 4vw, 64px); }
.brand-bmw .box-style-luxury .seo-block .seo-grid2 .seo-item h3 { font-size: var(--fs-h3); color: var(--ink-strong); margin-bottom: 10px; letter-spacing: -.01em; }
.brand-bmw .box-style-luxury .seo-block .seo-grid2 .seo-item p { color: var(--ink-soft); line-height: 1.75; max-width: 52ch; }
.brand-bmw .box-style-luxury .seo-block .seo-grid2 .seo-more { display: none; }
.brand-bmw .box-style-luxury .seo-block .seo-grid2.expanded .seo-more { display: block; }
/* Inline text link with the maquette's left-to-right underline reveal on hover. */
.brand-bmw .box-style-luxury .link { display: inline-flex; align-items: center; gap: .55em; font-size: .82rem; letter-spacing: .13em; text-transform: uppercase; text-decoration: none; color: var(--ink-strong); position: relative; padding-bottom: 4px; }
/* Override base theme's `.brand-bmw a:not(.btn):hover { text-decoration: underline }`
   (specificity 0,3,1) so only the animated ::after line shows, never the UA underline. */
.brand-bmw .box-style-luxury .link:hover,
.brand-bmw .box-style-luxury .link:focus { text-decoration: none; }
.brand-bmw .box-style-luxury .link::after { content: ""; position: absolute; left: 0; bottom: 0; height: 1.5px; width: 100%; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform .4s var(--ease); }
.brand-bmw .box-style-luxury .link:hover::after { transform: scaleX(1); }
.brand-bmw .box-style-luxury .link .ico { width: 1em; height: 1em; transition: transform .35s var(--ease); }
.brand-bmw .box-style-luxury .link:hover .ico { transform: translateX(4px); }
.brand-bmw .box-style-luxury .link.on-dark { color: var(--white); }
@media (max-width: 720px) { .brand-bmw .box-style-luxury .seo-block .seo-grid2 { grid-template-columns: 1fr; } }

/* --- dealer-location (luxury): dark section + hours card --- */
.brand-bmw .box-style-luxury.dloc { background: var(--ink-strong); color: var(--grey-200); }
.brand-bmw .box-style-luxury.dloc .h2, .brand-bmw .box-style-luxury.dloc h2, .brand-bmw .box-style-luxury.dloc h3 { color: var(--white); }
.brand-bmw .box-style-luxury .bmw-dloc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
.brand-bmw .box-style-luxury .bmw-dloc-name { font-size: var(--fs-h3); font-weight: 300; color: var(--white); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 22px; }
.brand-bmw .box-style-luxury .bmw-dloc-info .footer-contact { display: grid; gap: 12px; margin-top: 0; margin-bottom: 28px; font-size: .92rem; }
.brand-bmw .box-style-luxury .bmw-dloc-info .footer-contact a { display: flex; gap: .7em; color: var(--grey-300); transition: color .25s; }
.brand-bmw .box-style-luxury .bmw-dloc-info .footer-contact a:hover { color: var(--white); }
.brand-bmw .box-style-luxury .bmw-dloc-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.brand-bmw .box-style-luxury .bmw-hours-card { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.1); padding: 26px 28px; }
.brand-bmw .box-style-luxury .bmw-hours-head { display: flex; align-items: center; gap: 10px; color: var(--accent); font-size: var(--fs-small); letter-spacing: .12em; text-transform: uppercase; margin-bottom: 18px; }
.brand-bmw .box-style-luxury .bmw-hours-tabs { display: flex; border-bottom: 1px solid rgba(255,255,255,.12); margin-bottom: 16px; }
/* ⭐ `all: unset` d'abord : sans lui le navigateur peint sa propre chrome de <button> — fond
   `buttonface` #efefef et bordure noire de 2 px (mesuré le 2026-08-27 sur /fr/contactez-nous).
   Ça donnait des pastilles grises au lieu d'onglets, « pas comme les autres » (Jade). L'autre
   composant d'onglets du thème, `.hours-tabs__btn` (theme.css:10161), fait exactement ça — on
   s'aligne sur lui au lieu d'inventer un second vocabulaire. */
.brand-bmw .box-style-luxury .bmw-hours-tab { all: unset; cursor: pointer; padding: 8px 16px; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.5); border-bottom: 2px solid transparent; transition: color .25s, border-color .25s; }
.brand-bmw .box-style-luxury .bmw-hours-tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.brand-bmw .box-style-luxury .bmw-hours-tab:hover { color: rgba(255,255,255,.85); }
.brand-bmw .box-style-luxury .bmw-hours-panel { display: none; }
.brand-bmw .box-style-luxury .bmw-hours-panel.is-active { display: block; }
.brand-bmw .box-style-luxury .bmw-hours-panel ul { list-style: none; padding: 0; margin: 0; }
.brand-bmw .box-style-luxury .bmw-hours-panel li { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,.06); font-size: var(--fs-small); }
.brand-bmw .box-style-luxury .bmw-hours-panel li:last-child { border-bottom: none; padding-bottom: 0; }
.brand-bmw .box-style-luxury .bmw-hours-panel li span:first-child { color: var(--grey-200); font-weight: 400; }
.brand-bmw .box-style-luxury .bmw-hours-panel li span:last-child { color: var(--accent); }
.brand-bmw .box-style-luxury .bmw-hours-note { font-size: .8rem; color: rgba(255,255,255,.45); font-style: italic; margin-top: 12px; }
.brand-bmw .box-style-luxury .bmw-dloc-map { margin-top: clamp(2rem, 4vw, 3.5rem); overflow: hidden; border: 1px solid rgba(255,255,255,.1); }
@media (max-width: 900px) { .brand-bmw .box-style-luxury .bmw-dloc-grid { grid-template-columns: 1fr; gap: 2.5rem; } }
@media (max-width: 560px) { .brand-bmw .box-style-luxury .bmw-dloc-ctas { flex-direction: column; } .brand-bmw .box-style-luxury .bmw-dloc-ctas .btn { width: 100%; justify-content: center; } .brand-bmw .box-style-luxury .bmw-hours-card { padding: 20px 18px; } }

/* --- vehicle-carousel (luxury): inventory card grid --- */
.brand-bmw .box-style-luxury .inv-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 28px); }
.brand-bmw .box-style-luxury .veh-card { background: var(--white); border: 1px solid var(--line); display: flex; flex-direction: column; transition: box-shadow .4s var(--ease), transform .4s var(--ease), border-color .3s; }
.brand-bmw .box-style-luxury .veh-card:hover { box-shadow: var(--shadow-card); transform: translateY(-5px); border-color: transparent; }
.brand-bmw .box-style-luxury .veh-media { position: relative; aspect-ratio: 4/3; background: var(--grey-100); overflow: hidden; }
.brand-bmw .box-style-luxury .veh-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease); }
.brand-bmw .box-style-luxury .veh-card:hover .veh-media img { transform: scale(1.05); }
/* QA3-19: label shown over the placeholder image when a vehicle has no photos yet. */
/* ⭐ GALERIE DANS LA CARTE (Jade, 2026-08-27 : « on devrait pouvoir changer les images comme sur
   le site live »). Les vignettes sont EMPILEES en absolu et `.is-active` decide laquelle se voit ;
   c'est ce qui evite de recalculer une largeur de piste et de gerer un debordement.
   ⛔ `.veh-media` reste `position: relative; overflow: hidden` (bmw.css:380) : rien a changer la.
   ⛔ Le lien couvre toute la zone et passe SOUS les fleches (z-index 1 contre 2) — sinon le clic
   sur une fleche suivrait le lien de la fiche. */
.brand-bmw .box-style-luxury .veh-media__link {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: block;
}

.brand-bmw .box-style-luxury .veh-media__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity .35s var(--ease);
}

.brand-bmw .box-style-luxury .veh-media__slide.is-active {
    opacity: 1;
}

/* Les fleches : discretes au repos, revelees au survol de la carte — et TOUJOURS visibles au
   doigt, ou il n'y a pas de survol (`hover: none`). */
.brand-bmw .box-style-luxury .veh-media__nav {
    all: unset;
    cursor: pointer;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-strong, #1a1a1a);
    background: rgba(255, 255, 255, .88);
    border: 1px solid var(--line, rgba(0,0,0,.12));
    opacity: 0;
    transition: opacity .25s var(--ease), background-color .2s ease;
}

.brand-bmw .box-style-luxury .veh-media__nav svg { width: 18px; height: 18px; }
.brand-bmw .box-style-luxury .veh-media__nav--prev { left: 10px; }
.brand-bmw .box-style-luxury .veh-media__nav--next { right: 10px; }

.brand-bmw .box-style-luxury .veh-card:hover .veh-media__nav,
.brand-bmw .box-style-luxury .veh-media__nav:focus-visible {
    opacity: 1;
}

.brand-bmw .box-style-luxury .veh-media__nav:hover {
    background: #fff;
}

@media (hover: none) {
    .brand-bmw .box-style-luxury .veh-media__nav { opacity: 1; }
}

/* Le compteur « 1/6 » : meme discretion que les fleches. */
.brand-bmw .box-style-luxury .veh-media__count {
    position: absolute;
    right: 10px;
    bottom: 10px;
    z-index: 2;
    padding: 2px 8px;
    font-size: .68rem;
    letter-spacing: .06em;
    color: var(--ink-strong, #1a1a1a);
    background: rgba(255, 255, 255, .88);
    border: 1px solid var(--line, rgba(0,0,0,.12));
    opacity: 0;
    transition: opacity .25s var(--ease);
}

.brand-bmw .box-style-luxury .veh-card:hover .veh-media__count { opacity: 1; }
@media (hover: none) { .brand-bmw .box-style-luxury .veh-media__count { opacity: 1; } }

.brand-bmw .box-style-luxury .veh-media__coming-soon { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--grey-700); text-align: center; padding: 0 1em; }
.brand-bmw .box-style-luxury .veh-tags { position: absolute; top: 14px; left: 14px; display: flex; gap: 6px; }
.brand-bmw .box-style-luxury .veh-body { padding: 20px 22px 22px; display: flex; flex-direction: column; gap: 14px; flex: 1; }
.brand-bmw .box-style-luxury .veh-head .yr { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .veh-head .nm { font-size: 1.3rem; font-weight: 300; color: var(--ink-strong); line-height: 1.1; margin-top: 2px; }
.brand-bmw .box-style-luxury .veh-head .trim { font-size: .9rem; color: var(--ink-soft); margin-top: 2px; }
.brand-bmw .box-style-luxury .veh-specs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 14px; padding: 14px 0; border-block: 1px solid var(--line); }
.brand-bmw .box-style-luxury .veh-specs .sp { display: flex; align-items: center; gap: 9px; font-size: .85rem; color: var(--grey-700); }
.brand-bmw .box-style-luxury .veh-specs .sp .ico { width: 17px; height: 17px; color: var(--ink-soft); flex: none; }
.brand-bmw .box-style-luxury .veh-price { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-top: auto; }
.brand-bmw .box-style-luxury .veh-price .pay { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .veh-price .pay b { font-size: 1.05rem; color: var(--ink-strong); font-weight: 400; letter-spacing: 0; }
.brand-bmw .box-style-luxury .veh-price .total { text-align: right; }
.brand-bmw .box-style-luxury .veh-price .total .lbl { font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); display: block; }
.brand-bmw .box-style-luxury .veh-price .total .amt { font-size: 1.5rem; font-weight: 300; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .veh-price .total .was { display: block; font-size: .9rem; color: var(--ink-soft); text-decoration: line-through; line-height: 1.2; }
.brand-bmw .box-style-luxury .veh-price .total--sale .amt { color: var(--accent); }
/* --grey-400 (#929292) ne fait que 3.11:1 sur blanc — sous les 4.5:1 requis pour du
   texte (Lighthouse, sur chaque carte d'inventaire). --grey-500 est le cran suivant de
   la même échelle, déjà utilisé pour du texte tertiaire ailleurs : 5.02:1. */
.brand-bmw .box-style-luxury .veh-stock { font-size: .72rem; color: var(--grey-500); letter-spacing: .04em; }
.brand-bmw .box-style-luxury .veh-actions { display: grid; grid-template-columns: 1fr auto; gap: 8px; margin-top: auto; }
/* ⚠️ mesuré le 2026-08-20 sur le rendu local, 1440 px : « Vérifier la disponibilité »
   sortait rogné en « rifier la disponibili ». Cause : la règle .btn de cette couche
   (ligne ~209) pose `white-space: nowrap` ET `overflow: hidden` (nécessaire au ::after
   qui glisse), et elle bat par spécificité l'exception de theme.css. La colonne `1fr`
   fait ~165 px pour un libellé qui en demande ~200. Le libellé enroule donc ici, où la
   spécificité est la même et l'ordre de source tranche. `min-width: 0` empêche en plus
   la piste `1fr` de refuser de se réduire. */
.brand-bmw .box-style-luxury .veh-actions { grid-template-columns: minmax(0, 1fr) auto; }
.brand-bmw .box-style-luxury .veh-actions .btn { white-space: normal; overflow-wrap: break-word; min-width: 0; }
@media (max-width: 980px) { .brand-bmw .box-style-luxury .inv-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) {
    .brand-bmw .box-style-luxury .inv-grid { grid-template-columns: 1fr; }
    /* Stack the card actions so the Test-drive label isn't clipped by the narrow 1fr column. */
    .brand-bmw .box-style-luxury .veh-actions { grid-template-columns: 1fr; }
}
/* Section-head "View all inventory" CTA: BMW blue outline (not the default black ghost). */
.brand-bmw .box-style-luxury.vehicle-showcase-section .section-head .btn--ghost { --fg: var(--accent); border-color: var(--accent); }
.brand-bmw .box-style-luxury.vehicle-showcase-section .section-head .btn--ghost::after { background: var(--accent); }

/* --- Scroll-reveal animations (driven by brands/bmw.js, which adds .in) --- */
.brand-bmw .box-style-luxury [data-reveal] { opacity: 0; transform: translateY(26px); transition: opacity .9s var(--ease), transform .9s var(--ease); }
.brand-bmw .box-style-luxury [data-reveal].in { opacity: 1; transform: none; }
.brand-bmw .box-style-luxury [data-reveal-stagger] > * { opacity: 0; transform: translateY(26px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.brand-bmw .box-style-luxury [data-reveal-stagger].in > * { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .brand-bmw .box-style-luxury [data-reveal],
    .brand-bmw .box-style-luxury [data-reveal-stagger] > * { opacity: 1 !important; transform: none !important; }
}

/* --- Full maquette shell: delegated bmw/* teaser boxes render their own <section>.
   Scoped to .lux-shell so it never touches the section-helper boxes (whose !important
   spacing classes would win anyway). --- */
.brand-bmw .lux-shell { padding-block: var(--section-y); }
.brand-bmw .lux-shell > .container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.brand-bmw .lux-shell.section--alt { background: var(--bg-alt); }
.brand-bmw .lux-shell.section--ink { background: var(--ink-strong); color: var(--grey-200); }
.brand-bmw .lux-shell.section--ink .h2 { color: var(--white); }

/* --- promotions-teaser (luxury): live promo banners --- */
.brand-bmw .box-style-luxury .promo-banner-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(18px, 2.4vw, 32px); }
.brand-bmw .box-style-luxury .promo-banner { background: var(--white); border: 1px solid var(--line); display: flex; flex-direction: column; transition: box-shadow .4s var(--ease), transform .4s var(--ease); }
.brand-bmw .box-style-luxury .promo-banner:hover { box-shadow: var(--shadow-card); transform: translateY(-4px); }
.brand-bmw .box-style-luxury .promo-banner__img { display: block; overflow: hidden; }
.brand-bmw .box-style-luxury .promo-banner__img img { width: 100%; height: auto; display: block; transition: transform 1s var(--ease); }
.brand-bmw .box-style-luxury .promo-banner:hover .promo-banner__img img { transform: scale(1.04); }
.brand-bmw .box-style-luxury .promo-banner__cap { padding: 18px 20px 22px; display: flex; flex-direction: column; gap: 10px; }
.brand-bmw .box-style-luxury .promo-banner__title { font-size: 1.05rem; font-weight: 400; color: var(--ink-strong); letter-spacing: -.01em; }
@media (max-width: 860px) { .brand-bmw .box-style-luxury .promo-banner-grid { grid-template-columns: 1fr; } }

/* --- lineup-teaser (luxury): catalog segmented filter + model cards --- */
.brand-bmw .box-style-luxury .catalog-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 36px; }
.brand-bmw .box-style-luxury .seg { display: inline-flex; background: var(--bg-alt); padding: 4px; }
/* Re-establish the maquette's button reset (her global `button{}` reset is not ported). */
.brand-bmw .box-style-luxury .seg button { font: inherit; background: none; border: 0; cursor: pointer; padding: 9px 18px; font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); transition: color .25s; position: relative; z-index: 0; }
.brand-bmw .box-style-luxury .seg button:hover { color: var(--ink-strong); }
.brand-bmw .box-style-luxury .seg button.active { color: var(--white); }
.brand-bmw .box-style-luxury .seg button.active:hover { color: var(--white); }
.brand-bmw .box-style-luxury .seg button.active::before { content: ""; position: absolute; inset: 0; background: var(--accent); z-index: -1; transition: background .25s var(--ease); }
.brand-bmw .box-style-luxury .badge--blue { background: var(--accent); }
.brand-bmw .box-style-luxury .lineup-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.brand-bmw .box-style-luxury .model-card { position: relative; background: var(--white); border: 1px solid var(--line); padding: 30px 30px 26px; display: flex; flex-direction: column; min-height: 360px; transition: box-shadow .4s var(--ease), transform .45s var(--ease), border-color .3s, opacity .45s var(--ease); overflow: hidden; }
.brand-bmw .box-style-luxury .model-card:hover { box-shadow: var(--shadow-card); transform: translateY(-4px); border-color: transparent; }
/* Filtering: fade + scale out before the grid reflows (JS toggles .is-filtering, then display:none). */
.brand-bmw .box-style-luxury .model-card.is-filtering { opacity: 0; transform: translateY(14px) scale(.96); pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
    .brand-bmw .box-style-luxury .model-card.is-filtering { transform: none; }
}
.brand-bmw .box-style-luxury .model-card .mc-top { display: flex; justify-content: space-between; align-items: flex-start; }
.brand-bmw .box-style-luxury .model-card .mc-name { font-size: 1.5rem; font-weight: 300; color: var(--ink-strong); letter-spacing: .01em; }
.brand-bmw .box-style-luxury .model-card .mc-type { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin-top: 4px; }
.brand-bmw .box-style-luxury .model-card .mc-media { flex: 1; display: grid; place-items: center; margin: 6px 0 16px; min-height: 150px; }
.brand-bmw .box-style-luxury .model-card .mc-media img { width: 100%; max-height: 200px; object-fit: contain; transition: transform .7s var(--ease); filter: drop-shadow(0 24px 30px rgba(26,26,26,.18)); }
.brand-bmw .box-style-luxury .model-card:hover .mc-media img { transform: scale(1.06) translateX(4px); }
.brand-bmw .box-style-luxury .model-card .mc-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.brand-bmw .box-style-luxury .model-card .mc-price .lbl { font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); display: block; }
.brand-bmw .box-style-luxury .model-card .mc-price .val { font-size: 1.15rem; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .model-card .mc-cta { width: 46px; height: 46px; background: var(--bg-alt); display: grid; place-items: center; transition: background .3s, color .3s; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .model-card:hover .mc-cta { background: var(--accent); color: #fff; }
.brand-bmw .box-style-luxury .model-card .mc-fuel { position: absolute; top: 30px; right: 30px; }
@media (max-width: 980px) { .brand-bmw .box-style-luxury .lineup-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .brand-bmw .box-style-luxury .lineup-grid { grid-template-columns: 1fr; } }
/* Mobile: the category filter can exceed the viewport — let it scroll horizontally
   inside its own track instead of overflowing the page. */
@media (max-width: 760px) {
    .brand-bmw .box-style-luxury .catalog-filters { max-width: 100%; }
    .brand-bmw .box-style-luxury .seg { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
    .brand-bmw .box-style-luxury .seg::-webkit-scrollbar { display: none; }
    .brand-bmw .box-style-luxury .seg button { flex: 0 0 auto; white-space: nowrap; }
}

/* --- blog-teaser (luxury): editorial post grid (1 lead + side cards) --- */
.brand-bmw .box-style-luxury .blog-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 4px; }
.brand-bmw .box-style-luxury .post { position: relative; background: var(--white); border: 1px solid var(--line); display: flex; flex-direction: column; transition: box-shadow .4s, transform .4s, border-color .3s; overflow: hidden; }
.brand-bmw .box-style-luxury .post:hover { box-shadow: var(--shadow-card); transform: translateY(-4px); border-color: transparent; }
.brand-bmw .box-style-luxury .post-media { aspect-ratio: 16/10; position: relative; background: var(--grey-100); overflow: hidden; display: block; }
.brand-bmw .box-style-luxury .post-media .media { width: 100%; height: 100%; }
.brand-bmw .box-style-luxury .post-media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease); }
.brand-bmw .box-style-luxury .post:hover .post-media img { transform: scale(1.05); }
.brand-bmw .box-style-luxury .post-cat { position: absolute; top: 16px; left: 16px; }
.brand-bmw .box-style-luxury .post-body { padding: 22px 24px 26px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.brand-bmw .box-style-luxury .post-meta { font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .post-title { font-size: 1.2rem; font-weight: 300; color: var(--ink-strong); line-height: 1.2; }
.brand-bmw .box-style-luxury .post-excerpt { color: var(--ink-soft); font-size: .95rem; }
.brand-bmw .box-style-luxury .post .link { margin-top: auto; }
.brand-bmw .box-style-luxury .post.lead-post { grid-row: span 2; }
.brand-bmw .box-style-luxury .post.lead-post .post-media { aspect-ratio: auto; flex: 1; min-height: 280px; }
.brand-bmw .box-style-luxury .post.lead-post .post-title { font-size: clamp(1.5rem, 2vw, 2rem); }
@media (max-width: 900px) { .brand-bmw .box-style-luxury .blog-grid { grid-template-columns: 1fr 1fr; } .brand-bmw .box-style-luxury .post.lead-post { grid-column: span 2; grid-row: span 1; } .brand-bmw .box-style-luxury .post.lead-post .post-media { min-height: 240px; } }
@media (max-width: 560px) { .brand-bmw .box-style-luxury .blog-grid { grid-template-columns: 1fr; } .brand-bmw .box-style-luxury .post.lead-post { grid-column: span 1; } }

/* --- quick-search (luxury): inventory search card that overlaps the hero --- */
.brand-bmw .box-style-luxury.quicksearch { position: relative; z-index: 6; margin-top: -46px; }
.brand-bmw .box-style-luxury.quicksearch > .container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.brand-bmw .box-style-luxury.quicksearch .qs-card { background: var(--white); box-shadow: var(--shadow-card); border-top: 4px solid var(--accent); padding: clamp(20px, 2.4vw, 30px); }
.brand-bmw .box-style-luxury .qs-grid { display: grid; grid-template-columns: repeat(4, 1fr) auto; gap: 0; align-items: stretch; }
.brand-bmw .box-style-luxury .qs-field { display: flex; flex-direction: column; gap: 6px; padding: 6px 22px; border-right: 1px solid var(--line); }
.brand-bmw .box-style-luxury .qs-field:first-child { padding-left: 4px; }
.brand-bmw .box-style-luxury .qs-field label { font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .qs-field select { font: inherit; border: none; background: none; font-size: 1rem; color: var(--ink-strong); padding: 4px 0; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23494949' stroke-width='1.5' fill='none'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right center; }
.brand-bmw .box-style-luxury .qs-submit { display: flex; align-items: stretch; padding-left: 22px; }
.brand-bmw .box-style-luxury .qs-submit .btn { height: 100%; }
.brand-bmw .box-style-luxury .qs-meta { display: flex; align-items: center; gap: 20px; margin-top: 16px; font-size: .82rem; color: var(--ink-soft); flex-wrap: wrap; }
.brand-bmw .box-style-luxury .qs-meta .chip { padding: 6px 12px; background: var(--bg-alt); color: var(--grey-700); letter-spacing: .04em; text-decoration: none; transition: background .25s, color .25s; }
.brand-bmw .box-style-luxury .qs-meta .chip:hover { background: var(--accent); color: #fff; }
@media (max-width: 920px) {
    .brand-bmw .box-style-luxury.quicksearch { margin-top: -30px; }
    .brand-bmw .box-style-luxury .qs-grid { grid-template-columns: 1fr 1fr; }
    .brand-bmw .box-style-luxury .qs-field { border-right: none; border-bottom: 1px solid var(--line); padding: 12px 6px; }
    .brand-bmw .box-style-luxury .qs-submit { grid-column: 1 / -1; padding-left: 0; padding-top: 14px; }
    .brand-bmw .box-style-luxury .qs-submit .btn { width: 100%; padding-block: 1.1em; }
}

/* --- text-block (luxury): editorial / SEO copy block (her .seo-block / .seo-cols) ---
   The text-block box uses the section helper, so its <section> already carries
   `box-style-luxury text-block-section`. Style its base classes to the maquette look.
   Background stays driven by the box's own bg setting (don't force it here).
   NOTE: content width is centralized in the text-block box (keyed on
   .box-style-luxury) so it honors the Content Width control — do not re-add a
   .text-block__content max-width here. */
.brand-bmw .box-style-luxury.text-block-section .section-eyebrow { font-size: var(--fs-eyebrow); font-weight: 400; letter-spacing: .22em; text-transform: uppercase; color: var(--accent); display: inline-flex; align-items: center; gap: .7em; }
.brand-bmw .box-style-luxury.text-block-section .section-eyebrow::before { content: ""; width: 26px; height: 2px; background: currentColor; display: inline-block; }
.brand-bmw .box-style-luxury.text-block-section .section-title { font-size: var(--fs-h2); text-transform: uppercase; font-weight: 300; line-height: 1.04; color: var(--ink-strong); letter-spacing: -.01em; }
.brand-bmw .box-style-luxury.text-block-section .section-subtitle { font-size: var(--fs-lead); color: var(--ink-soft); font-weight: 300; line-height: 1.5; }
/* Body prose — BMW editorial typography */
.brand-bmw .box-style-luxury.text-block-section .text-block__body { color: var(--grey-500); font-weight: 300; line-height: 1.8; }
.brand-bmw .box-style-luxury.text-block-section .text-block__body p { margin-bottom: 1em; break-inside: avoid; }
.brand-bmw .box-style-luxury.text-block-section .text-block__body h2,
.brand-bmw .box-style-luxury.text-block-section .text-block__body h3,
.brand-bmw .box-style-luxury.text-block-section .text-block__body h4 { font-size: 1.05rem; color: var(--ink-strong); letter-spacing: .02em; margin: 1.2em 0 .5em; text-transform: uppercase; font-weight: 400; break-inside: avoid; }
.brand-bmw .box-style-luxury.text-block-section .text-block__content.text-columns-2 .text-block__body,
.brand-bmw .box-style-luxury.text-block-section .text-block__content.text-columns-3 .text-block__body { column-gap: 56px; }
.brand-bmw .box-style-luxury.text-block-section .text-block__body a { color: var(--accent); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color .25s; }
.brand-bmw .box-style-luxury.text-block-section .text-block__body a:hover { text-decoration: none; border-color: var(--accent); }
.brand-bmw .box-style-luxury.text-block-section .text-block__body blockquote { border-left: 3px solid var(--accent); padding-left: 1.2em; margin: 1.5em 0; color: var(--ink); font-style: normal; }

/* =============================================================================
   FULL-PAGE LUXURY (VRP / VDP / forms)
   Full pages opt into the luxury look by wrapping their content in
   `.box-style-luxury` (a styling hook, not an actual Box), so they reuse every
   rule above (veh-card, inv-grid, badges, buttons, eyebrow, .link, …). Below are
   the page-only pieces that don't exist in any box.
   ============================================================================= */

/* --- Page hero banner (breadcrumbs, title, stat row) --- */
.brand-bmw .box-style-luxury .page-hero { background: var(--bg-alt); border-bottom: 1px solid var(--line); position: relative; overflow: hidden; }
.brand-bmw .box-style-luxury .page-hero .container { padding-block: clamp(28px, 3.2vw, 48px); position: relative; z-index: 2; }
.brand-bmw .box-style-luxury .page-hero .crumbs { display: flex; align-items: center; gap: 8px; font-size: .76rem; letter-spacing: .04em; color: var(--ink-soft); margin-bottom: 22px; flex-wrap: wrap; }
.brand-bmw .box-style-luxury .page-hero .crumbs a { color: inherit; text-decoration: none; transition: color .2s; }
.brand-bmw .box-style-luxury .page-hero .crumbs a:hover { color: var(--accent); }
.brand-bmw .box-style-luxury .page-hero .crumbs .sep { opacity: .5; }
.brand-bmw .box-style-luxury .page-hero .crumbs .cur { color: var(--ink-strong); }
.brand-bmw .box-style-luxury .page-hero h1 { font-size: clamp(1.6rem, 2.4vw, 2.4rem); text-transform: uppercase; font-weight: 300; line-height: 1.08; color: var(--ink-strong); letter-spacing: -.01em; margin: 0; max-width: none; overflow-wrap: break-word; }
.brand-bmw .box-style-luxury .page-hero .ph-sub { margin-top: 18px; max-width: 60ch; font-size: var(--fs-lead); color: var(--ink-soft); font-weight: 300; }
.brand-bmw .box-style-luxury .page-hero .ph-meta { margin-top: 26px; display: flex; gap: 30px; flex-wrap: wrap; }
/* Nombre et libelle SUR LA MEME LIGNE (« met le texte vehicules a cote du compte
   pas en dessou »). Ils etaient empiles, le libelle sous le chiffre.
   `align-items: baseline` et non `center` : les deux tailles sont tres inegales
   (1.9rem vs .76rem), un centrage vertical fait flotter le libelle au milieu du
   chiffre au lieu de l'asseoir sur sa ligne de base.
   ⚠️ Cette paire de regles sert AUSSI le compteur de /neufs — le page-hero de
   `partials/site/page-header.htm` reprend `.box-style-luxury .page-hero .ph-meta`,
   et le compteur de Filternew y rend le meme `.pm > .n + .l` justement pour
   partager cette typographie (demande de Jade : harmoniser les deux compteurs VRP).
   Les deux passent donc en ligne ensemble, ce qui est l'effet voulu. */
.brand-bmw .box-style-luxury .page-hero .ph-meta .pm { display: flex; align-items: baseline; gap: 9px; }
.brand-bmw .box-style-luxury .page-hero .ph-meta .pm .n { font-size: 1.9rem; font-weight: 300; color: var(--ink-strong); line-height: 1; }
.brand-bmw .box-style-luxury .page-hero .ph-meta .pm .l { font-size: .76rem; letter-spacing: .06em; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .page-hero .m-rule { margin-bottom: 22px; }

/* --- Inventory filter/sort toolbar (sticky under the header) --- */
.brand-bmw .box-style-luxury .inv-toolbar { position: sticky; top: var(--header-h); z-index: 40; background: rgba(255,255,255,.95); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
.brand-bmw .box-style-luxury .inv-toolbar .container { display: flex; align-items: center; gap: 14px; padding-block: 16px; flex-wrap: wrap; }
.brand-bmw .box-style-luxury .inv-toolbar .tb-field { display: flex; flex-direction: column; gap: 3px; }
.brand-bmw .box-style-luxury .inv-toolbar label { font-size: .64rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .inv-toolbar select { font: inherit; border: 1px solid var(--line); background: var(--white); padding: .55em 2em .55em .8em; font-size: .9rem; color: var(--ink-strong); cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23494949' stroke-width='1.5' fill='none'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right .7em center; }
.brand-bmw .box-style-luxury .inv-toolbar select:focus { outline: none; border-color: var(--accent); }
.brand-bmw .box-style-luxury .inv-toolbar .tb-count { margin-left: auto; font-size: .85rem; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .inv-toolbar .tb-count b { color: var(--ink-strong); font-weight: 400; }
.brand-bmw .box-style-luxury .inv-toolbar .tb-reset { font: inherit; background: none; border: 0; cursor: pointer; font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); padding: .5em; }
.brand-bmw .box-style-luxury .inv-toolbar .tb-reset:hover { text-decoration: underline; }
@media (max-width: 760px) {
    .brand-bmw .box-style-luxury .inv-toolbar { position: static; }
    .brand-bmw .box-style-luxury .inv-toolbar .tb-field { flex: 1 1 40%; }
    .brand-bmw .box-style-luxury .inv-toolbar select { width: 100%; }
    .brand-bmw .box-style-luxury .inv-toolbar .tb-count { width: 100%; margin-left: 0; }
}

/* Outline badge used by veh-card tags on light media */
.brand-bmw .box-style-luxury .badge--light { background: var(--white); color: var(--ink-strong); border: 1px solid var(--line); }

/* --- VRP filter sidebar — the plugin's functional form, BMW-styled (CSS only;
   markup + vehicles.js data-request contract untouched). Lives inside the VRP's
   .box-style-luxury wrapper. --- */
.brand-bmw .box-style-luxury .vehicle-filters h6 { font-size: var(--fs-h3); font-weight: 300; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .filter-group { padding-bottom: 22px; margin-bottom: 22px !important; border-bottom: 1px solid var(--line); }
.brand-bmw .box-style-luxury .filter-group:last-child { border-bottom: 0; }

/* ─────────────────────────────────────────────────────────────────────────────
   Accordéon des filtres (<details>/<summary>, partials/vehicles/partials/filters-content.htm)

   ⛔ On ANNULE ici le `max-height: calc(100vh - 100px); overflow-y: auto` que le
   plugin pose sur `.desktop-filters` (plugins/nerd/inventory/assets/css/filters.css:186).
   C'était la source du défilement dans le défilement : 2 666 px de contenu dans une
   boîte de 900 px, à l'intérieur du défilement de page. Avec l'accordéon (trois
   panneaux ouverts) et les options à zéro résultat retirées, le panneau tient sous la
   hauteur d'écran et n'a plus besoin d'être borné.

   Neutralisé depuis le thème et non retiré du plugin, à dessein : `filters.css` sert
   AUSSI les autres sites, qui n'ont pas encore l'accordéon et pour qui la boîte bornée
   reste le moindre mal. La règle est donc portée par `.brand-bmw .box-style-luxury`,
   plus spécifique (0,3,0 contre 0,1,0) et chargée après.
   ───────────────────────────────────────────────────────────────────────────── */
.brand-bmw .box-style-luxury .desktop-filters {
    max-height: none;
    overflow-y: visible;
    overflow-x: visible;
}

/* ─────────────────────────────────────────────────────────────────────────────
   Décalage collant de la colonne de filtres, accordé à l'en-tête escamotable.

   Le plugin fixe `top: 80px !important` sur `.col-lg-3` (filters.css:182). Mesuré
   sur /fr/inventaire/occasion à 1440x1000, une fois la page défilée :
     · l'en-tête rétrécit à 61 px (`.site-header.is-scrolled`, la barre du haut se
       replie) — 80 px lui laissent donc 19 px de garde, il ne recouvre RIEN ;
     · mais en défilement vers le BAS l'en-tête est escamoté (translaté hors écran,
       `bottom: 0`) et les filtres restent quand même à 80 px du haut, plus les 24 px
       de `padding` de `.vehicle-filters` : 104 px de vide au-dessus du titre pour
       une navbar qui n'occupe plus rien.

   On récupère donc ces 68 px pendant la descente, et on les rend dès la remontée :
   l'en-tête revient au premier geste vers le haut, et une colonne restée à 12 px
   passerait dessous.

   ⛔ Le crochet est `.site-header.is-hidden`, pas `.navbar-hidden`. Les deux classes
   sont posées ensemble sur la descente (par le script de partials/site/header.htm et
   par assets/js/theme.js respectivement), mais `navbar-hidden` n'a AUCUNE règle CSS
   dans ce thème — c'est `is-hidden` qui porte le `translateY(-100%)` (theme.css:2240),
   donc c'est elle qui dit la vérité sur l'état de l'en-tête.

   Repli sûr : `is-hidden` n'est posée que si les réglages « masquer au défilement »
   et « en-tête collant » sont actifs. Sur un site qui les désactive, la règle ne se
   déclenche jamais et la colonne garde ses 80 px — le comportement d'aujourd'hui.

   `transition` calée sur les 0,3 s de l'en-tête (theme.css:2213) pour que la colonne
   glisse avec lui au lieu de sauter. Il faut `!important` des deux côtés : on ne bat
   pas un `!important` sans en poser un, et la spécificité fait le reste.
   ───────────────────────────────────────────────────────────────────────────── */
@media (min-width: 992px) {
    html.brand-bmw .box-style-luxury .vehicles-container .col-lg-3 {
        transition: top .3s ease;
    }
    html.brand-bmw body:has(.site-header.is-hidden) .box-style-luxury .vehicles-container .col-lg-3 {
        top: 12px !important;
    }
}

/* Le <summary> est la zone cliquable du panneau. `list-style: none` + le pseudo
   ::-webkit-details-marker retirent le triangle natif, remplacé par un chevron dessiné
   en bordures pour rester net à toutes les tailles. */
/* ⛔ Les panneaux n'utilisent PAS `.filter-group`, à dessein. Cette classe est stylée
   par le plugin (plugins/nerd/inventory/assets/css/filters.css:23) en carte : fond,
   bordure, coin arrondi et `padding: 20px`. Ce padding est ce qui donnait un panneau
   FERMÉ de 86 px de haut, les cinq fermés pesant 430 px à eux seuls (mesuré
   1440x1000) — et le reste est un style de carte dont l'accordéon ne veut pas. On
   repart donc d'une boîte propre plutôt que d'annuler quatre propriétés.
   La règle responsive qui accompagnait `.filter-group` (champs Prix/Km sur une ligne
   chacun sous 1200 px) est redéclarée plus bas pour `.filter-panel`.

   ⛔ Même raison pour le libellé : `.filter-panel__label` et non `.filter-label`. Le
   plugin pose SEPT `!important` sur `.filter-label` (filters.css:12-20 — font-size,
   font-weight, color, text-transform, letter-spacing, margin-bottom, display), si
   bien que la typographie BMW des libellés de filtres déclarée plus haut dans ce
   fichier (`.68rem`, graisse 400) n'a JAMAIS pris : le calculé donne 14 px et 600,
   c'est-à-dire les valeurs du plugin. Constat pré-existant, signalé à part ; on ne
   surenchérit pas en `!important`, on prend un nom de classe à nous. */
.brand-bmw .box-style-luxury .filter-panel {
    border-bottom: 1px solid var(--line);
}
.brand-bmw .box-style-luxury .filter-panel:last-child { border-bottom: 0; }

.brand-bmw .box-style-luxury .filter-panel__label {
    display: block;
    /* ⛔ .75rem = 12 px, le plancher posé sur ce panneau. `.filter-label` du thème
       déclarait .68rem (10,88 px), mais cette règle n'a jamais pris — les sept
       `!important` du plugin forçaient 14 px — donc personne n'avait vu qu'elle était
       sous le plancher. En reprenant la main sur le libellé on hérite du problème :
       ne pas redescendre à .68rem. */
    font-size: .75rem;
    font-weight: 400;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--ink-strong);
    /* Filet de sécurité repris de `.filter-label` : en majuscules avec letter-spacing,
       « GROUPE MOTOPROPULSEUR » demande 139 px pour les 116 px de la colonne à 992 px.
       La césure d'abord, la coupure brute en dernier recours. */
    overflow-wrap: break-word;
    hyphens: auto;
}

/* Prix et Kilométrage à un champ par ligne sous 1200 px : dans une colonne de 206 px,
   deux colonnes ne laissent que 30 px de texte par champ alors que « Max km » en
   demande 51. Repris de la règle `.filter-group` d'origine, qui ne s'applique plus
   depuis que les panneaux ont quitté cette classe. */
@media (max-width: 1199.98px) {
    .brand-bmw .box-style-luxury .desktop-filters .filter-panel .row > .col-6 {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

.brand-bmw .box-style-luxury .filter-panel > .filter-panel__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    cursor: pointer;
    list-style: none;
    /* 13px de part et d'autre : la ligne fermée fait ~47 px, au-dessus du minimum de
       24 px de cible tactile (WCAG 2.2 SC 2.5.8) sans le vide d'avant. */
    padding: 13px 0;
    margin: 0;
}
.brand-bmw .box-style-luxury .filter-panel > .filter-panel__summary::-webkit-details-marker { display: none; }

/* Anneau de focus visible au clavier — un <summary> est focusable, et le retirer du
   flux visuel sans état de focus le rendrait inatteignable à l'œil (WCAG 2.2 SC 2.4.11). */
.brand-bmw .box-style-luxury .filter-panel > .filter-panel__summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Chevron : deux bordures d'un carré tourné à 45°. Pointe vers le bas fermé, vers le
   haut ouvert. `flex-shrink: 0` — sinon il se fait écraser par un libellé long, et les
   libellés de ce panneau sont longs en français (« GROUPE MOTOPROPULSEUR »). */
.brand-bmw .box-style-luxury .filter-panel > .filter-panel__summary::after {
    content: '';
    flex-shrink: 0;
    width: 7px;
    height: 7px;
    border-right: 1px solid var(--ink-soft);
    border-bottom: 1px solid var(--ink-soft);
    transform: rotate(45deg) translateY(-2px);
    transition: transform .18s var(--ease);
}
.brand-bmw .box-style-luxury .filter-panel[open] > .filter-panel__summary::after {
    transform: rotate(-135deg) translateY(-2px);
}

/* Dans un summary le libellé partage la ligne avec le chevron. */
.brand-bmw .box-style-luxury .filter-panel__summary .filter-panel__label { display: inline; margin: 0; }

.brand-bmw .box-style-luxury .filter-panel__body { padding: 2px 0 18px; }

/* Densité des listes d'options. Bootstrap donne ~37 px par `.form-check` une fois la
   typographie du panneau appliquée, ce qui faisait 299 px pour les 8 marques. On
   descend à ~28 px : assez pour rester au-dessus des 24 px de cible tactile
   verticale, et le libellé reste cliquable sur toute la largeur de la ligne. */
.brand-bmw .box-style-luxury .filter-options .form-check,
.brand-bmw .box-style-luxury .filter-dropdown-menu .form-check {
    margin-bottom: 0;
    padding-top: 3px;
    padding-bottom: 3px;
    min-height: 0;
}

/* Compteur de résultats à côté de chaque option. Volontairement discret : c'est une
   information secondaire qui ne doit pas concurrencer le libellé, tout en restant
   au-dessus du minimum de contraste (--grey-700 = #494949, 7,4:1 sur blanc — le
   --ink-soft #6f6f6f des libellés secondaires ne donne que 4,11:1 et échouerait sur
   du texte de cette taille). `tabular-nums` pour que les chiffres s'alignent d'une
   ligne à l'autre. */
.brand-bmw .box-style-luxury .facet-count {
    color: var(--grey-700);
    /* .86em de 14 px = 12,04 px : le compte reste secondaire à l'œil sans passer sous
       le plancher (.78em donnait 10,9 px). */
    font-size: .86em;
    font-variant-numeric: tabular-nums;
}
.brand-bmw .box-style-luxury .facet-count::before { content: '('; }
.brand-bmw .box-style-luxury .facet-count::after { content: ')'; }

/* Les listes d'options ne sont plus bornées en hauteur (`.filter-checkbox-scroll` a
   disparu du markup) : Marque tient en 8 lignes et Transmission en 2 une fois les
   zéros retirés. Seuls les deux menus déroulants Année/Modèle gardent une hauteur
   bornée, parce qu'ils flottent au-dessus de la page et non dans le flux. */
.brand-bmw .box-style-luxury .filter-dropdown-menu {
    max-height: 250px;
    overflow-y: auto;
}

/* Le lien « ville, province » du bloc localisation — largeur bornée pour ne pas
   pousser la ligne, remplace un style inline. */
.brand-bmw .box-style-luxury .location-indicator__link { max-width: 180px; }

/* ─────────────────────────────────────────────────────────────────────────────
   Sentinelle du défilement infini (partials/vehicles/partials/grid.htm →
   `.inv-pager`, pilotée par assets/js/vrp-load-more.js).

   Remplace les boutons « Voir plus » / « Voir moins ». Elle n'affiche RIEN au repos :
   un repère de défilement visible promettrait une action alors qu'il n'y en a aucune à
   faire. L'indicateur n'apparaît que pendant la requête, quand `.is-loading` est posée
   sur le pager — sans lui, la liste s'allonge sans que rien n'ait signalé qu'un
   chargement était en cours, ce qui est le reproche classique fait au défilement infini.
   ───────────────────────────────────────────────────────────────────────────── */
.brand-bmw .box-style-luxury .inv-pager {
    display: flex;
    justify-content: center;
}
.brand-bmw .box-style-luxury .inv-pager__sentinel {
    /* Une hauteur non nulle est nécessaire : un noeud de 0 px n'intersecte jamais de
       façon fiable selon les moteurs. 40 px suffisent et restent invisibles au repos. */
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.brand-bmw .box-style-luxury .inv-pager__spinner {
    width: 22px;
    height: 22px;
    border: 2px solid var(--line);
    border-top-color: var(--accent);
    border-radius: 50%;
    opacity: 0;
    transition: opacity .15s var(--ease);
}
.brand-bmw .box-style-luxury .inv-pager.is-loading .inv-pager__spinner {
    opacity: 1;
    animation: inv-pager-spin .7s linear infinite;
}
@keyframes inv-pager-spin { to { transform: rotate(360deg); } }

/* Respecte le réglage système : on garde le retour visuel, sans rotation. */
@media (prefers-reduced-motion: reduce) {
    .brand-bmw .box-style-luxury .inv-pager.is-loading .inv-pager__spinner {
        animation: none;
        border-top-color: var(--accent);
    }
}

/* ─────────────────────────────────────────────────────────────────────────────
   DENSITÉ du panneau de filtres

   Mesuré le 2026-09-09 à 1200x795 : la colonne faisait 1153 px pour 771 px
   utilisables. Tout ce qui suit rogne du VIDE — paddings, marges, gabarit des
   contrôles. Aucune taille de texte ne descend : le plancher de 12 px posé sur ce
   panneau est respecté, les sous-libellés y sont déjà (`.form-label`, 12 px) et les
   libellés d'option restent à 14 px. Les concurrents descendent en « pattes de
   mouches » parce qu'ils n'ont pas rogné le vide d'abord ; ce n'est pas la peine ici.

   Les deux plus gros postes étaient structurels, réglés dans le markup :
     · le bouton « Réinitialiser les filtres » s'enroulait sur 2 lignes (46 px) —
       surchargé en lien d'une ligne, voir partials/vehicles/partials/reset-button.htm ;
     · le groupe « TRIER PAR » + select s'empilait sur 2 lignes (69 px) — le libellé
       visible est passé en aria-label, le select seul suffit.
   ───────────────────────────────────────────────────────────────────────────── */

/* Encart du panneau : 24 px de retrait en haut ET en bas, pour un panneau dont le
   premier élément est déjà un titre. 14 px suffisent à l'aérer. */
.brand-bmw .box-style-luxury .vehicle-filters { padding: 12px !important; }

/* En-tête : titre + lien de réinitialisation sur une ligne, puis le tri. */
.brand-bmw .box-style-luxury .filters-head { margin-bottom: 10px; }
.brand-bmw .box-style-luxury .filters-head__row { margin-bottom: 10px; }
.brand-bmw .box-style-luxury .filters-head__title {
    font-size: .82rem;
    font-weight: 400;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--ink-strong);
}

/* Lien de réinitialisation — `.btn` du plugin remplacé par un lien de texte. Le
   point rouge devient un vrai point à côté du mot plutôt qu'une pastille en
   position absolue par-dessus le coin du bouton. */
.brand-bmw .box-style-luxury .filters-reset {
    border: 0;
    background: none;
    padding: 0;
    /* 12 px, plancher du panneau — pas .72rem (11,5 px). */
    font-size: .75rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--accent);
    cursor: pointer;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    line-height: 1.4;
}
.brand-bmw .box-style-luxury .filters-reset:hover { text-decoration: underline; }
.brand-bmw .box-style-luxury .filters-reset:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.brand-bmw .box-style-luxury .filters-reset__dot {
    width: 5px; height: 5px; border-radius: 50%;
    background: var(--accent); flex-shrink: 0;
}

/* Contrôles : `padding: .6em .8em` donnait 41 px de haut à chaque select et chaque
   champ. `.34em` les ramène à ~33 px sans toucher au texte, qui reste à 14 px.
   ⛔ Préfixé `html` (spécificité 0,4,1) et non `.brand-bmw` seul (0,4,0) : la règle
   `.6em` porte EXACTEMENT le même sélecteur et se trouve PLUS BAS dans ce fichier —
   le bloc accordéon inséré au-dessus l'a repoussée — donc à spécificité égale c'est
   elle qui gagnait. Mesuré : padding calculé resté à 8,4 px, hauteur à 41 px. */
html.brand-bmw .box-style-luxury .vehicle-filters .form-select,
html.brand-bmw .box-style-luxury .vehicle-filters .form-control {
    padding: .34em .7em;
}

/* Panneaux : la ligne fermée passe de 43 à 35 px. 35 px reste au-dessus des 24 px de
   cible tactile minimale (WCAG 2.2 SC 2.5.8), le <summary> occupant toute la largeur. */
/* 7px : la ligne fermée passe de 38 à 34 px. Toujours au-dessus des 24 px de cible
   tactile de SC 2.5.8, le <summary> couvrant toute la largeur de la colonne. */
.brand-bmw .box-style-luxury .filter-panel > .filter-panel__summary { padding: 7px 0; }

/* Listes d'options sur DEUX colonnes quand la place le permet — le poste le plus lourd
   du panneau était la liste Marque : 213 px pour 8 cases (mesuré 1366x768). En deux
   colonnes elle tient en 4 rangées.
   `auto-fill` + `minmax(120px, 1fr)` : deux colonnes dès ~250 px de largeur utile, une
   seule en dessous (colonne de 207 px à 992 px de viewport) — dégradation automatique,
   sans media query. Rien ne change pour la hauteur de ligne ni pour la cible tactile :
   c'est la même ligne de 24 px, il y en a juste deux par rangée. */
.brand-bmw .box-style-luxury .filter-options--grid {
    display: grid;
    /* ⛔ 120px, et NE PAS descendre. Essayé à 105 pour forcer deux colonnes dès la
       colonne de 279 px d'un viewport à 1200 px : ça gagne bien 62 px (861 -> 799),
       mais trois libellés des DEUX panneaux ouverts par défaut s'enroulent alors sur
       deux lignes — « Occasion (62) », « Hyundai (2) », « Porsche (1) ». Un défaut
       visible d'entrée contre 62 px : mauvais échange.
       À 120, deux colonnes à partir de ~250 px de largeur utile (viewport >= 1366) et
       une seule en dessous, sans un seul libellé enroulé à aucune largeur — vérifié
       tous panneaux ouverts. */
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    column-gap: 10px;
}
.brand-bmw .box-style-luxury .filter-panel__body { padding: 0 0 12px; }

/* Lignes d'option : 26 → 24 px. C'est EXACTEMENT le plancher de cible tactile de
   SC 2.5.8, pas en dessous — ne pas descendre plus bas. Le libellé est cliquable sur
   toute la largeur de la ligne, la cible est donc large même si elle est courte. */
.brand-bmw .box-style-luxury .filter-options .form-check,
.brand-bmw .box-style-luxury .filter-dropdown-menu .form-check {
    padding-top: 2px;
    padding-bottom: 2px;
}

/* Sous-libellés (ANNÉE, MARQUE, MODÈLE, Transmission…) : déjà à 12 px, seule la
   marge bouge. */
.brand-bmw .box-style-luxury .filter-panel__body .form-label { margin-bottom: 2px !important; }

/* Espacement entre les sous-blocs d'un même panneau (les 3 de « Véhicule »). */
.brand-bmw .box-style-luxury .filter-panel__body > .mb-3 { margin-bottom: 10px !important; }
.brand-bmw .box-style-luxury .filter-label { display: block; font-size: .68rem; font-weight: 400; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 12px; }
.brand-bmw .box-style-luxury .vehicle-filters .form-label { font-size: .75rem !important; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft) !important; font-weight: 400; }
/* Filet de sécurité des libellés du panneau de filtres (mesuré 2026-09-01, page FR, viewport 992
   px — la colonne col-lg-3 ne fait plus que 206 px) : en majuscules avec letter-spacing, un mot
   français long dépasse sa boîte et sort de la colonne — « GROUPE MOTOPROPULSEUR » demande 139 px
   pour 116 px disponibles (+23 px), « SPÉCIFICATIONS » 123 px pour 116 px (+7 px). Rétrécir le
   texte est exclu (plancher de 12 px posé sur le panneau), donc on laisse le mot se couper : la
   césure d'abord (hyphens, dictionnaire fr de Chrome via lang="fr-CA"), la coupure brute en
   dernier recours. Aucun effet à 1200 px et 1440 px, ni en EN : à ces largeurs rien ne déborde. */
.brand-bmw .box-style-luxury .filter-label,
.brand-bmw .box-style-luxury .vehicle-filters .form-label { overflow-wrap: break-word; hyphens: auto; }
/* Inputs & selects — sharp, hairline border, BMW focus */
.brand-bmw .box-style-luxury .vehicle-filters .form-select,
.brand-bmw .box-style-luxury .vehicle-filters .form-control {
    font: inherit; font-size: .9rem; color: var(--ink-strong);
    border: 1px solid var(--line); border-radius: 0; background-color: var(--white);
    padding: .6em .8em; box-shadow: none;
}
.brand-bmw .box-style-luxury .vehicle-filters .form-select {
    appearance: none; padding-right: 2em;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23494949' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right .7em center;
}
.brand-bmw .box-style-luxury .vehicle-filters .form-select:focus,
.brand-bmw .box-style-luxury .vehicle-filters .form-control:focus { border-color: var(--accent); box-shadow: none; outline: none; }
/* Checkboxes — BMW blue, sharp */
.brand-bmw .box-style-luxury .vehicle-filters .form-check-input { border-radius: 0; border-color: var(--grey-300); }
.brand-bmw .box-style-luxury .vehicle-filters .form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }
.brand-bmw .box-style-luxury .vehicle-filters .form-check-input:focus { box-shadow: none; border-color: var(--accent); }
.brand-bmw .box-style-luxury .vehicle-filters .form-check-label { color: var(--ink); font-size: .9rem; }
/* Sort input-group */
.brand-bmw .box-style-luxury .vehicle-filters .input-group-text { font-size: .75rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); background: var(--bg-alt); border: 1px solid var(--line); border-radius: 0; }
/* Multiselect dropdown panels */
.brand-bmw .box-style-luxury .vehicle-filters .dropdown-menu { border-radius: 0; border-color: var(--line); }
.brand-bmw .box-style-luxury .vehicle-filters .dropdown-menu .form-check-label { font-size: .85rem; }
/* Reset link */
.brand-bmw .box-style-luxury #resetFiltersContainer .btn,
.brand-bmw .box-style-luxury #resetFiltersContainer button,
.brand-bmw .box-style-luxury #resetFiltersContainer a { font: inherit; background: none; border: 0; cursor: pointer; font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); padding: 0; }
/* Le bouton « Réinitialiser les filtres » ne se comprime pas et sortait de la colonne en FR
   (mesuré 2026-09-01 : 214 px de bouton pour 206 px de colonne à 992 px). Son texte a le droit de
   se replier ; le passage à la ligne du bouton lui-même est géré par `flex-wrap` sur l'en-tête
   (filters-content.htm). */
.brand-bmw .box-style-luxury #resetFiltersContainer { min-width: 0; }
.brand-bmw .box-style-luxury #resetFiltersContainer .btn,
.brand-bmw .box-style-luxury #resetFiltersContainer button,
.brand-bmw .box-style-luxury #resetFiltersContainer a { white-space: normal; text-align: left; max-width: 100%; }

/* Tri — « TRIER PAR » occupe 94 px de la colonne `col-lg-3`, et les libellés de tri français sont
   longs : « Ajouté : Plus récent en premier » demande ~180 px. Côte à côte, il ne reste que 115 px
   au <select> à 1200 px et 63 px à 992 px (mesuré 2026-09-01 : on lisait « Ajo »). En dessous de
   1400 px le libellé passe donc sur sa propre ligne et le select prend toute la largeur — le seul
   agencement où les 9 options se lisent en entier. Ciblé sur `.desktop-filters` : le panneau
   mobile fait 350 px de large, il n'a jamais eu le problème et garde sa disposition. À partir de
   1400 px la disposition d'origine est conservée telle quelle — le select y fait 175 px, l'option
   affichée y est rognée de ~5 px en FR (invisible à l'œil), et la liste ouverte s'affiche de toute
   façon à sa largeur naturelle. */
/* ⛔ Règle retirée : elle empilait le libellé « TRIER PAR » au-dessus de son select
   sous 1400 px, parce que les deux ne tenaient pas côte à côte dans la colonne. Le
   libellé visible n'existe plus (passé en aria-label, voir filters-content.htm), il
   n'y a plus d'`input-group` à replier et le bloc de tri est passé de 69 à 35 px. */
/* Prix et Kilométrage — à deux colonnes dans une colonne de 206 px, il ne reste que 30 px de texte
   dans chaque champ alors que le gabarit « Max km » en demande 51 (on lisait « M( »). Un champ par
   ligne en dessous de 1200 px seulement : à 1200 px les 56 px disponibles suffisent déjà. Ciblé
   lui aussi sur `.desktop-filters`, pour ne rien changer au panneau mobile. */
@media (max-width: 1199.98px) {
    .brand-bmw .box-style-luxury .desktop-filters .filter-group .row > .col-6 { flex: 0 0 100%; max-width: 100%; }
}
/* Mobile condition tabs */
.brand-bmw .box-style-luxury .condition-tab { border-radius: 0; }

/* Estimated-payment disclaimer under the SRP grid (Jade, decision: "centré dans
   le bas"). theme.css's `.vrp-est-note` (shared by 7 brands, out of scope here)
   sets max-width:70ch but no text-align/margin, so the paragraph sits flush
   left under the grid instead of centered. Already at the bottom of the grid
   in the markup (partials/vehicles/default.htm renders it right after
   #vehiclesContainer) -- only the alignment needed fixing. */
.brand-bmw .box-style-luxury .vrp-est-note { text-align: center; margin-left: auto; margin-right: auto; }
/* ⭐ Et elle prend toute la largeur disponible (Jade, 2026-08-26 : « il est trop épais dans la
   page »). `theme.css` la bride à `max-width: 70ch`, soit 531 px dans un conteneur de 1440 :
   mesuré, ça donnait un pavé de 4 lignes. Sans la bride, le même texte tient sur 2 lignes et se
   lit comme une note de bas de page plutôt que comme un bloc. Le `padding` du conteneur
   (`.container-fluid px-lg-5`, 48 px) l'empêche de coller aux bords. */
.brand-bmw .box-style-luxury .vrp-est-note { max-width: none; }
/* ⭐ De l'air entre le bouton « Voir plus » et la note (Jade, 2026-08-26). Mesuré à 1440 px :
   28 px seulement séparaient le bas du bouton du haut de la note — les deux se lisaient comme
   un seul bloc. `theme.css` pose `margin: 28px 0 0` sur cette note ; on passe à 4rem (64 px) ici,
   côté marque, sans toucher aux 7 autres marques. ⚠️ `--space-8` ne vaut que 2rem sur ce thème :
   il n'aurait ajouté que 4 px. */
/* ⛔ Et de l'air EN DESSOUS aussi : mesuré le 2026-08-26, la note collait la bande
   « Contactez-nous » à 0 px — bas de la note 3950, haut de la bande 3950. Le paragraphe se
   lisait comme le début du pied de page au lieu d'être la note de la grille. */
/* ⛔ L'espace ne peut PAS vivre sur la note : elle n'existe pas sur toutes les pages. Mesuré le
   2026-08-26 — `estNoteUtile` (partials/vehicles/default.htm:111) la masque volontairement quand
   aucune carte ne porte d'estimation de paiement : /fr/inventaire/neuf, /demo et /fr/neufs n'ont
   donc AUCUNE note, et le bouton « Voir plus » se retrouvait collé à la bande Contactez-nous.
   L'air est donc porté par le PAGER, qui existe partout, et la note ne garde que sa marge du bas.
   Total constant : 64 px sous le bouton, 64 px avant la bande, avec ou sans note. */
.brand-bmw [data-role="vrp-pager"] { margin-bottom: 4rem; }
.brand-bmw .box-style-luxury .vrp-est-note { margin-top: 0; margin-bottom: 4rem; }

/* ⭐ CENTRÉE COMME UN BLOC dans sa bande blanche (Jade, 2026-08-27 : « devrait être centré dans
   la section blanche »). Elle était déjà `text-align: center`, mais sans bride de largeur le
   paragraphe remplissait la ligne d'un bord à l'autre : ça se lisait comme une bande, pas comme
   une note centrée. ⚠️ On ne revient PAS à `max-width: 70ch` de theme.css — mesuré le 2026-08-26,
   ça donnait un pavé de 4 lignes que Jade a refusé (« il est trop épais dans la page »). 1100 px
   est le compromis : le texte reste sur 2 lignes à 1440 et le bloc est visiblement centré.
   `.vrp-est-note-row` est la rangée blanche créée le 2026-08-27, hors du conteneur gris. */
/* ⛔ MEME AIR EN HAUT QU'EN BAS dans la bande blanche (Jade, 2026-08-27 : « il n'a pas le meme
   padding au top et au bottom »). Mesure avant : 0 px au-dessus de la note, 64 px en dessous — la
   bande commencait pile au ras du texte. La cause : la rangee n'avait AUCUN padding vertical
   (`container-fluid` n'en pose pas) et les 64 px du bas venaient du `margin-bottom` de la note
   elle-meme. On porte donc l'air sur la RANGEE, symetriquement, et on retire la marge de la note.
   ⚠️ `padding-top`/`padding-bottom` seulement : un `padding` complet ecraserait les gouttieres
   horizontales de `px-lg-5 px-3`. */
html.brand-bmw .vrp-est-note-row {
    padding-top: 3rem;
    padding-bottom: 3rem;
}

html.brand-bmw .vrp-est-note-row .vrp-est-note {
    margin-top: 0;
    margin-bottom: 0;
}

html.brand-bmw .vrp-est-note-row .vrp-est-note {
    /* ⛔ `1100px` seul ne centrait RIEN sous 1100 px de large : la note reprenait toute la
       ligne et Jade la voyait encore pleine largeur (« n'est toujours pas centré », 2026-08-27,
       fenêtre mesurée à 842 px). Il faut une bride qui morde à TOUTE largeur, d'où le
       pourcentage — et le plafond en pixels pour ne pas devenir un pavé sur un très grand écran.
       Mesuré à 842 px : 75 % = 608 px de large, 117 px de marge de chaque côté, et toujours
       3 lignes. 70 % en ferait 4 — la limite que Jade a refusée le 2026-08-26 (« trop épais »).
       Mesuré à 1512 px : le plafond de 1100 px s'applique, 206 px de marge, 2 lignes. */
    max-width: 1100px;
    max-width: min(1100px, 75%);
    margin-left: auto;
    margin-right: auto;
}

/* --- VDP (vehicle detail) — .vdu gallery+info, specs, finance calc, lead form --- */
.brand-bmw .box-style-luxury .btn--block { width: 100%; }
.brand-bmw .box-style-luxury .vdu { display: grid; grid-template-columns: 1.35fr 1fr; gap: clamp(28px, 4vw, 64px); align-items: start; }
.brand-bmw .box-style-luxury .vdu-gallery { position: sticky; top: calc(var(--header-h) + 24px); }
.brand-bmw .box-style-luxury .vdu-main { aspect-ratio: 4/3; background: var(--grey-100); border: 1px solid var(--line); position: relative; overflow: hidden; }
.brand-bmw .box-style-luxury .vdu-main img { width: 100%; height: 100%; object-fit: cover; }
.brand-bmw .box-style-luxury .vdu-main .veh-tags { position: absolute; top: 16px; left: 16px; display: flex; gap: 6px; z-index: 1; }
/* Fill the aspect-ratio box via absolute positioning — a percentage height does NOT
   resolve against an aspect-ratio-derived parent height in Firefox, which made the
   slides expand to the full natural image size. */
.brand-bmw .box-style-luxury .vdu-main .vdu-swiper { position: absolute; inset: 0; width: 100%; height: 100%; }
.brand-bmw .box-style-luxury .vdu-swiper .swiper-slide { background: var(--grey-100); height: 100%; }
.brand-bmw .box-style-luxury .vdu-swiper .swiper-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.brand-bmw .box-style-luxury .vdu-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 42px; height: 42px; display: grid; place-items: center; background: rgba(255,255,255,.9); border: 1px solid var(--line); color: var(--ink-strong); cursor: pointer; transition: background .25s, color .25s, border-color .25s; }
.brand-bmw .box-style-luxury .vdu-nav svg { width: 20px; height: 20px; }
.brand-bmw .box-style-luxury .vdu-nav--prev { left: 12px; }
.brand-bmw .box-style-luxury .vdu-nav--next { right: 12px; }
.brand-bmw .box-style-luxury .vdu-nav:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.brand-bmw .box-style-luxury .vdu-nav.swiper-button-disabled { opacity: .3; pointer-events: none; }
.brand-bmw .box-style-luxury .vdu-thumbs { margin-top: 6px; }
.brand-bmw .box-style-luxury .vdu-thumbs .th { aspect-ratio: 4/3; background: var(--grey-100); border: 1px solid var(--line); cursor: pointer; transition: border-color .25s; overflow: hidden; padding: 0; box-sizing: border-box; }
.brand-bmw .box-style-luxury .vdu-thumbs .th img { width: 100%; height: 100%; object-fit: cover; display: block; }
.brand-bmw .box-style-luxury .vdu-thumbs .th:hover,
.brand-bmw .box-style-luxury .vdu-thumbs .swiper-slide-thumb-active { border-color: var(--accent); }
.brand-bmw .box-style-luxury .vdu-info .vdu-yr { font-size: .8rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .vdu-info h1 { font-size: clamp(2rem, 3.2vw, 3rem); text-transform: uppercase; font-weight: 300; line-height: 1.04; color: var(--ink-strong); margin: 6px 0 4px; }
.brand-bmw .box-style-luxury .vdu-info .vdu-trim { color: var(--ink-soft); font-size: 1.05rem; }
.brand-bmw .box-style-luxury .vdu-tags-row { display: flex; gap: 8px; margin: 18px 0; flex-wrap: wrap; }
.brand-bmw .box-style-luxury .vdu-price-box { background: var(--bg-alt); padding: 24px; margin: 22px 0; border-left: 3px solid var(--accent); }
.brand-bmw .box-style-luxury .vdu-price-box .row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.brand-bmw .box-style-luxury .vdu-price-box .total { font-size: 2.2rem; font-weight: 300; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .vdu-price-box .pay { color: var(--ink-soft); font-size: .9rem; }
.brand-bmw .box-style-luxury .vdu-price-box .pay b { color: var(--accent); font-weight: 400; font-size: 1.1rem; }
.brand-bmw .box-style-luxury .vdu-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 22px 0; }
.brand-bmw .box-style-luxury .vdu-actions .btn--block { grid-column: 1 / -1; }
.brand-bmw .box-style-luxury .vdu-specs { display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(16px, 3vw, 40px); border-top: 1px solid var(--line); margin-top: 8px; }
.brand-bmw .box-style-luxury .vdu-specs .row { display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 10px; padding: 14px 4px; border-bottom: 1px solid var(--line); font-size: .92rem; }
.brand-bmw .box-style-luxury .vdu-specs .row .ico { width: 18px; height: 18px; color: var(--ink-soft); flex: none; }
.brand-bmw .box-style-luxury .vdu-specs .row .lbl { color: var(--ink-soft); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand-bmw .box-style-luxury .vdu-specs .row .v { color: var(--ink-strong); text-align: right; white-space: nowrap; }
.brand-bmw .box-style-luxury .fin-calc { background: var(--white); border: 1px solid var(--line); padding: 26px; margin-top: 28px; }
.brand-bmw .box-style-luxury .fin-calc h3 { font-size: 1rem; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 4px; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .fin-calc .fin-pay { display: flex; align-items: baseline; gap: 10px; margin: 14px 0 20px; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.brand-bmw .box-style-luxury .fin-calc .fin-pay .amt { font-size: 2.4rem; font-weight: 300; color: var(--accent); }
.brand-bmw .box-style-luxury .fin-calc .fin-pay .per { color: var(--ink-soft); font-size: .9rem; }
.brand-bmw .box-style-luxury .fin-calc .fin-field { margin-bottom: 16px; }
.brand-bmw .box-style-luxury .fin-calc .fin-field .top { display: flex; justify-content: space-between; font-size: .82rem; margin-bottom: 8px; }
.brand-bmw .box-style-luxury .fin-calc .fin-field .top .lbl { color: var(--ink-soft); letter-spacing: .04em; text-transform: uppercase; font-size: .7rem; }
.brand-bmw .box-style-luxury .fin-calc .fin-field .top .out { color: var(--ink-strong); }
.brand-bmw .box-style-luxury .fin-calc input[type=range] { width: 100%; accent-color: var(--accent); }
.brand-bmw .box-style-luxury .fin-calc select { font: inherit; width: 100%; padding: .7em 1em; border: 1px solid var(--line); border-radius: 0; background: var(--bg-alt); }
.brand-bmw .box-style-luxury .fin-calc .fin-note { font-size: .72rem; color: var(--ink-soft); margin-top: 6px; }
/* Restored multi-tab payment calculator (finance/lease, frequency, sliders, breakdown) */
.brand-bmw .box-style-luxury .inv-vdp-pricing__calc-tabs { display: flex; gap: 4px; margin: 14px 0 18px; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__calc-tab { font: inherit; background: var(--bg-alt); border: 0; cursor: pointer; flex: 1; padding: .7em 1em; font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); transition: color .25s, background .25s; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__calc-tab.is-active { background: var(--accent); color: #fff; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__calc-panel { display: none; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__calc-panel.is-active { display: block; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__payment-display { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 20px; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__payment-amount { font-size: 2.4rem; font-weight: 300; color: var(--accent); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__payment-frequency { display: flex; gap: 4px; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__freq-btn { font: inherit; background: none; border: 1px solid var(--line); cursor: pointer; padding: .4em .8em; font-size: .68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); transition: border-color .2s, color .2s; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__freq-btn.is-active { border-color: var(--accent); color: var(--accent); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__slider-group { margin-bottom: 18px; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__slider-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__slider-header label { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__slider-value { font-size: .92rem; color: var(--ink-strong); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__slider { width: 100%; accent-color: var(--accent); }
/* --grey-400 (#929292) ne fait que 3.11:1 sur blanc, sous le 4.5:1 requis pour du texte —
   ici les bornes min/max du curseur de paiement (calculette de financement, fiche véhicule),
   en .68rem donc pas "grand texte". --grey-500 est le cran suivant de la même échelle,
   déjà le choix retenu pour .veh-stock juste au-dessus : 5.02:1, mesuré. */
.brand-bmw .box-style-luxury .inv-vdp-pricing__slider-range { display: flex; justify-content: space-between; font-size: .68rem; color: var(--grey-500); margin-top: 4px; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__breakdown { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 14px; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__breakdown-row { display: flex; justify-content: space-between; font-size: .88rem; color: var(--ink-soft); padding: 6px 0; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__breakdown-row span:last-child { color: var(--ink-strong); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__breakdown-row--highlight { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 12px; font-weight: 400; }
.brand-bmw .box-style-luxury .inv-vdp-pricing__breakdown-row--highlight span:last-child { color: var(--accent); }
.brand-bmw .box-style-luxury .inv-vdp-pricing__lease-info { display: grid; gap: 14px; text-align: center; padding: 10px 0; }
@media (max-width: 880px) {
    .brand-bmw .box-style-luxury .vdu { grid-template-columns: 1fr; }
    .brand-bmw .box-style-luxury .vdu-gallery { position: static; }
}

/* --- Lead / contact form (VDP test-drive; also used by financing later) --- */
.brand-bmw .box-style-luxury .lead-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(30px, 5vw, 80px); align-items: center; }
.brand-bmw .box-style-luxury .lead-form { background: var(--white); padding: clamp(26px, 3vw, 42px); box-shadow: var(--shadow-card); border-top: 4px solid var(--accent); }
.brand-bmw .box-style-luxury .lead-form .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.brand-bmw .box-style-luxury .field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 16px; }
.brand-bmw .box-style-luxury .field label { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .field input, .brand-bmw .box-style-luxury .field select, .brand-bmw .box-style-luxury .field textarea { font: inherit; padding: .9em 1em; border: 1px solid var(--line); border-radius: 0; background: var(--bg-alt); font-size: .95rem; transition: border-color .25s, background .25s; }
.brand-bmw .box-style-luxury .field input:focus, .brand-bmw .box-style-luxury .field select:focus, .brand-bmw .box-style-luxury .field textarea:focus { outline: none; border-color: var(--accent); background: #fff; }
.brand-bmw .box-style-luxury .contact-pref { display: flex; gap: 10px; flex-wrap: wrap; }
.brand-bmw .box-style-luxury .contact-pref label { display: inline-flex; align-items: center; gap: .5em; padding: .7em 1em; border: 1px solid var(--line); cursor: pointer; font-size: .85rem; text-transform: none; letter-spacing: 0; color: var(--grey-700); transition: border-color .25s, background .25s; }
.brand-bmw .box-style-luxury .contact-pref input { accent-color: var(--accent); }
.brand-bmw .box-style-luxury .contact-pref label:has(input:checked) { border-color: var(--accent); background: rgba(0,102,177,.06); }
.brand-bmw .box-style-luxury .lead-copy .h2 { margin: 16px 0; }
.brand-bmw .box-style-luxury .tdf-error { color: var(--m-red); font-size: .76rem; margin: 2px 0 0; }
@media (max-width: 860px) {
    .brand-bmw .box-style-luxury .lead-grid { grid-template-columns: 1fr; }
    .brand-bmw .box-style-luxury .lead-form .form-row { grid-template-columns: 1fr; }
}

/* --- VDP restored sections: description, history, sticky CTA --- */
.brand-bmw .box-style-luxury .vdp-prose { color: var(--grey-500); font-weight: 300; line-height: 1.8; max-width: 72ch; }
.brand-bmw .box-style-luxury .vdp-prose p { margin-bottom: 1em; }
.brand-bmw .box-style-luxury .vdp-prose strong { color: var(--ink-strong); font-weight: 400; }
.brand-bmw .box-style-luxury .vdp-prose h2, .brand-bmw .box-style-luxury .vdp-prose h3 { font-size: 1.05rem; text-transform: uppercase; letter-spacing: .02em; color: var(--ink-strong); font-weight: 400; margin: 1.4em 0 .5em; }

.brand-bmw .box-style-luxury .vdp-hist-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.brand-bmw .box-style-luxury .vdp-hist-card { background: var(--white); border: 1px solid var(--line); padding: 24px; display: flex; gap: 14px; align-items: flex-start; }
.brand-bmw .box-style-luxury .vdp-hist-card .ico { width: 30px; height: 30px; color: var(--accent); flex: none; }
.brand-bmw .box-style-luxury .vdp-hist-card .val { display: block; color: var(--ink-strong); font-weight: 400; }
.brand-bmw .box-style-luxury .vdp-hist-card .lbl { font-size: .8rem; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .vdp-hist-carfax { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; background: var(--bg-alt); border: 1px solid var(--line); padding: 20px 24px; margin-top: 16px; }
.brand-bmw .box-style-luxury .vdp-hist-carfax .lbl { display: flex; align-items: center; gap: 10px; font-size: .82rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.brand-bmw .box-style-luxury .vdp-hist-warranty { display: flex; gap: 14px; padding: 20px 24px; border-left: 3px solid var(--accent); background: var(--bg-alt); margin-top: 16px; }
.brand-bmw .box-style-luxury .vdp-hist-warranty .ico { width: 24px; height: 24px; color: var(--accent); flex: none; }
.brand-bmw .box-style-luxury .vdp-hist-warranty h4 { font-size: .95rem; color: var(--ink-strong); font-weight: 400; margin-bottom: 4px; }
.brand-bmw .box-style-luxury .vdp-hist-warranty p { font-size: .9rem; color: var(--ink-soft); margin: 0; }
.brand-bmw .box-style-luxury .vdp-insp { margin-top: 28px; }
.brand-bmw .box-style-luxury .vdp-insp h3 { font-size: 1rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-strong); font-weight: 400; display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.brand-bmw .box-style-luxury .vdp-insp h3 svg { color: var(--accent); }
.brand-bmw .box-style-luxury .vdp-insp-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 24px; }
.brand-bmw .box-style-luxury .vdp-insp-item { display: flex; align-items: center; gap: 8px; font-size: .9rem; color: var(--grey-700); }
.brand-bmw .box-style-luxury .vdp-insp-item svg { color: var(--accent); flex: none; }
@media (max-width: 760px) {
    .brand-bmw .box-style-luxury .vdp-hist-grid { grid-template-columns: 1fr 1fr; }
    .brand-bmw .box-style-luxury .vdp-insp-list { grid-template-columns: 1fr 1fr; }
}

/* Mobile sticky CTA bar */
.brand-bmw .box-style-luxury .vdp-sticky { position: fixed; left: 0; right: 0; bottom: 0; z-index: 200; background: var(--white); border-top: 1px solid var(--line); box-shadow: 0 -8px 30px -18px rgba(26,26,26,.4); padding: 10px 16px; display: none; align-items: center; justify-content: space-between; gap: 12px; }
.brand-bmw .box-style-luxury .vdp-sticky__price { font-size: 1.1rem; font-weight: 400; color: var(--ink-strong); display: block; line-height: 1.1; }
.brand-bmw .box-style-luxury .vdp-sticky__veh { font-size: .68rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .06em; }
.brand-bmw .box-style-luxury .vdp-sticky__actions { display: flex; gap: 8px; flex: none; }
@media (max-width: 880px) {
    .brand-bmw .box-style-luxury .vdp-sticky { display: flex; }
    .brand-bmw .box-style-luxury .vdp-luxury { padding-bottom: 72px; }
}

/* =============================================================================
   BMW VDP — re-skin the standard inv-vdp-* page to the BMW aesthetic (CSS only,
   markup untouched). Page-level scope (.brand-bmw) — the VDP is not a Box.
   The photo gallery (.inv-vdp-gallery__*) is intentionally NOT re-skinned here
   — one exception below is a bug fix, not styling.
   ============================================================================= */

/* Gallery crop bug fix (QA #8e07). vdp-gallery.htm asks for
   image.thumb(960, 640, 'crop'), but the media disk is S3 and October's
   resizer can't touch it: .thumb() silently falls back to the RAW original
   file (measured: <img src> is the untouched S3 object, no resize params
   in the URL). Source ratios are also not uniform across vehicles — mostly
   800x450 (16:9), but e.g. vehicle 888 (BMW X5) ships 800x600 (4:3). A fixed
   aspect-ratio box + object-fit:cover can therefore never be crop-free (an
   earlier version of this fix assumed a 3:2 crop that doesn't exist and
   still lost 15.6% of width on the common 16:9 case). Switched to `contain`
   so nothing is ever cut regardless of source ratio; the letterbox falls on
   the existing --brand-bg-alt fill theme.css already sets on
   .inv-vdp-gallery__main. Container kept close to the dominant 16:9 ratio to
   minimize the letterbox on the common case. Same crop existed — worse — on
   the thumbnail strip's fixed 4:3 box (25% of width lost on 16:9 photos),
   fixed the same way. */
/* ⛔ Le fond du cadre, pas le cadrage (QA Jade 2026-09-01 : « des bandes blanches sur les
   coté »). Le `contain` ci-dessus est VOLONTAIRE et le reste : les sources n'ont pas toutes
   le meme ratio (800x450, 800x600, 960x640 mesures), donc aucun `cover` ne serait sans
   rognage. Ce qui n'allait pas, c'est le remplissage : `--brand-bg-alt` vaut #f4f5f7 sur
   une page #ffffff, soit un ecart de luminance quasi nul — le letterbox ne se lisait pas
   comme un cadre mais comme deux bandes blanches. Mesure sur la Kia EV6 : image 960x640
   dans une boite 754x424, 636 px peints, 59 px de vide par cote (15,7 % de la largeur).
   ⚠️ Mesure du 1er essai : `--grey-100` (#ededee) ne donne que 1,17:1 contre le blanc de la
   page — ca se lit encore comme du blanc. On prend `--grey-900` (#262626), le cadre sombre
   des galeries auto : il se lit comme un cadre voulu et fait ressortir la voiture. Les images
   restent entieres. Meme fond sur la bande de vignettes, qui a le meme letterbox. */
.brand-bmw .inv-vdp-gallery__main { aspect-ratio: 16 / 9; background: var(--grey-900, #262626); }
/* ⚠️ Le fond doit aussi etre pose sur la DIAPOSITIVE, pas seulement sur le cadre : c'est elle
   qui occupe les 754x424 derriere l'image, et un fond clair pose plus haut dans la cascade
   (ou par le swiper) repeignait par-dessus celui du cadre. Les deux sont poses, la bande ne
   peut plus retomber sur du blanc quel que soit l'element qui gagne. */
.brand-bmw .inv-vdp-gallery__slide,
.brand-bmw .inv-vdp-gallery__swiper { background: var(--grey-900, #262626); }
.brand-bmw .inv-vdp-gallery__image { object-fit: contain; }
.brand-bmw .inv-vdp-gallery__thumb img { object-fit: contain; background: var(--grey-900, #262626); }

/* Breadcrumb */
.brand-bmw .inv-vdp__breadcrumb { background: var(--bg-alt); border-bottom: 1px solid var(--line); }
.brand-bmw .inv-vdp__breadcrumb-list { font-size: .76rem; letter-spacing: .03em; }
.brand-bmw .inv-vdp__breadcrumb-list a { color: var(--ink-soft); text-decoration: none; transition: color .2s; }
.brand-bmw .inv-vdp__breadcrumb-list a:hover { color: var(--accent); }

/* Section headings */
.brand-bmw .inv-vdp-description__title,
.brand-bmw .inv-vdp-pricing__title,
.brand-bmw .inv-vdp-history__title,
.brand-bmw .inv-vdp-features__title {
    text-transform: uppercase; font-weight: 300; letter-spacing: .01em; color: var(--ink-strong);
}
/* Contact title sits on the blue gradient header — keep it white (matches theme.css) */
.brand-bmw .inv-vdp-contact__title {
    text-transform: uppercase; font-weight: 300; letter-spacing: .01em; color: #fff;
}
.brand-bmw .inv-vdp-description__title svg,
.brand-bmw .inv-vdp-pricing__title svg,
.brand-bmw .inv-vdp-history__title svg,
.brand-bmw .inv-vdp-features__title svg { color: var(--accent); }

/* Quick-facts bar */
.brand-bmw .inv-vdp__facts { background: var(--bg-alt); border-block: 1px solid var(--line); }
.brand-bmw .inv-vdp__fact-icon { color: var(--accent); }
.brand-bmw .inv-vdp__fact-value { color: var(--ink-strong); font-weight: 400; }
/* --ink-soft sur le gris des blocs de caractéristiques ne fait que 2.67:1 (Lighthouse). */
.brand-bmw .inv-vdp__fact-label { text-transform: uppercase; letter-spacing: .08em; color: var(--grey-700); font-size: .7rem; }

/* Description prose */
.brand-bmw .inv-vdp-description__text,
.brand-bmw .inv-vdp-description__auto { color: var(--ink-soft); font-weight: 300; line-height: 1.8; }
.brand-bmw .inv-vdp-description__intro strong { color: var(--ink-strong); font-weight: 400; }

/* Pricing card + price */
.brand-bmw .inv-vdp-pricing__price-card,
.brand-bmw .inv-vdp-pricing__calculator,
.brand-bmw .inv-vdp-pricing__cta { border-radius: 0; border-color: var(--line); }
.brand-bmw .inv-vdp-pricing__label,
.brand-bmw .inv-vdp-pricing__tax-note { text-transform: uppercase; letter-spacing: .1em; color: var(--ink-soft); }
.brand-bmw .inv-vdp-pricing__price-current { color: var(--ink-strong); font-weight: 300; }
.brand-bmw .inv-vdp-pricing__price-original { color: var(--ink-soft); }
.brand-bmw .inv-vdp-pricing__savings-tag { background: var(--accent); color: #fff; border-radius: 0; }
.brand-bmw .inv-vdp-pricing__price-asterisk,
.brand-bmw .inv-vdp-sidebar__price-asterisk { color: var(--ink-soft); font-weight: 400; }
.brand-bmw .inv-vdp-pricing__legal-note { margin-top: 6px; font-size: .74rem; line-height: 1.5; color: var(--ink-soft); }

/* Payment calculator (range inputs here are NOT the gallery slider) */
.brand-bmw .inv-vdp-pricing__calc-tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.brand-bmw .inv-vdp-pricing__freq-btn { border-radius: 0; }
.brand-bmw .inv-vdp-pricing__freq-btn.is-active { background: var(--accent); color: #fff; border-color: var(--accent); }
/* payment-amount sits on the blue gradient (.inv-vdp-pricing__payment-display,
   theme.css) — do NOT recolor it to --accent (BMW blue on BMW blue was
   unreadable, ~1:1 contrast). Inherit the white set by the parent instead. */
.brand-bmw .inv-vdp-pricing__payment-amount { font-weight: 300; }
.brand-bmw .inv-vdp-pricing__slider { accent-color: var(--accent); }
.brand-bmw .inv-vdp-pricing__breakdown-row--highlight { color: var(--accent); font-weight: 400; }

/* History */
.brand-bmw .inv-vdp-history__badge { color: var(--accent); }
.brand-bmw .inv-vdp-history__card,
.brand-bmw .inv-vdp-history__carfax,
.brand-bmw .inv-vdp-history__inspection { background: var(--white); border: 1px solid var(--line); border-radius: 0; }
.brand-bmw .inv-vdp-history__card-icon { color: var(--accent); }
.brand-bmw .inv-vdp-history__card-value { color: var(--ink-strong); font-weight: 400; }
.brand-bmw .inv-vdp-history__card-label,
.brand-bmw .inv-vdp-history__inspection-title { text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); }
.brand-bmw .inv-vdp-history__inspection-item svg { color: var(--accent); }
.brand-bmw .inv-vdp-history__warranty { background: var(--bg-alt); border: 0; border-left: 3px solid var(--accent); border-radius: 0; }
.brand-bmw .inv-vdp-history__warranty-icon { color: var(--accent); }

/* Features */
.brand-bmw .inv-vdp-features__tab.is-active { color: var(--accent); border-color: var(--accent); }
.brand-bmw .inv-vdp-features__highlight-card { background: var(--white); border: 1px solid var(--line); border-radius: 0; }
.brand-bmw .inv-vdp-features__highlight-icon,
.brand-bmw .inv-vdp-features__check { color: var(--accent); }
.brand-bmw .inv-vdp-features__highlights-title { text-transform: uppercase; letter-spacing: .06em; color: var(--ink-strong); font-weight: 400; }

/* Contact / dealer card */
.brand-bmw .inv-vdp-contact__form,
.brand-bmw .inv-vdp-contact__dealer { border-radius: 0; border-color: var(--line); }
/* ⛔ Le correctif précédent (var(--grey-700), gris foncé) partait de l'hypothèse que ce
   sous-titre est sur une carte BLANCHE — faux : .inv-vdp-contact__header (theme.css) porte
   son propre fond en dégradé bleu (var(--brand-accent) → var(--brand-accent-hover)),
   pas la carte blanche .inv-vdp-contact__form/__dealer visée par la règle du dessus.
   Gris foncé sur bleu foncé mesurait 1.10–1.52:1 (composé avec l'opacity:.9 du parent,
   theme.css) — Lighthouse ne l'a pas vu car son audit color-contrast ne sait pas résoudre
   un fond en linear-gradient() et écarte ces éléments au lieu de les faire échouer.
   Fix : rester blanc comme .inv-vdp-contact__title juste au-dessus (même fond) →
   5.14:1 mesuré (composé à 90% d'opacité sur le point le plus clair du dégradé). */
.brand-bmw .inv-vdp-contact__subtitle { color: var(--white); }
.brand-bmw .inv-vdp-contact__form input,
.brand-bmw .inv-vdp-contact__form select,
.brand-bmw .inv-vdp-contact__form textarea { border-radius: 0; }
.brand-bmw .inv-vdp-contact__form input:focus,
.brand-bmw .inv-vdp-contact__form select:focus,
.brand-bmw .inv-vdp-contact__form textarea:focus { border-color: var(--accent); box-shadow: none; }
.brand-bmw .inv-vdp-contact__dealer-phone { color: var(--accent); }

/* Buttons — sharp + uppercase (color already BMW-blue via token remap) */
.brand-bmw .inv-vdp-pricing__cta .btn,
.brand-bmw .inv-vdp-contact__form .btn,
.brand-bmw .inv-vdp-pricing__lease-info .btn { border-radius: 0; text-transform: uppercase; letter-spacing: .08em; font-weight: 400; }

/* Mobile CTA overflow fix: theme.css already declares a single-column
   .inv-vdp-sidebar__ctas at max-width:480px, but the outline buttons
   ("Nous contacter" / "Évaluer mon échange") keep rendering as two columns
   at real phone widths (measured 390×844: text-overflow, "Évaluer mon
   échange" clipped at the viewport edge). Re-declared here, scoped and
   !important, since theme.css is shared by 7 brands and out of scope here. */
@media (max-width: 480px) {
    .brand-bmw .inv-vdp-sidebar__ctas { grid-template-columns: 1fr !important; }
    .brand-bmw .inv-vdp-sidebar__cta--primary,
    .brand-bmw .inv-vdp-sidebar__cta--secondary,
    .brand-bmw .inv-vdp-sidebar__cta--outline { grid-column: span 1 !important; }
    .brand-bmw .inv-vdp-sidebar__cta-text strong { white-space: normal !important; }
}

/* Sticky mobile CTA bar */
.brand-bmw .inv-vdp-sticky { border-top: 1px solid var(--line); }
.brand-bmw .inv-vdp-sticky__price { color: var(--ink-strong); font-weight: 400; }
.brand-bmw .inv-vdp-sticky__btn--primary { border-radius: 0; }

/* -----------------------------------------------------------------------------
   FONTS — BMW Type Next (client-supplied)
   @font-face is global by nature (it only registers the family). The family is
   APPLIED within .brand-bmw via the --font / --font-heading / --font-body token
   mappings in the TOKENS block above, which the base theme consumes on body and
   headings — so this stays additive and never touches other brands.
   Supplied weights: Thin 100, Light 300, Regular 400, Bold 700.
   ----------------------------------------------------------------------------- */
@font-face {
    font-family: "BMW Type Next";
    src: url("../../fonts/bmw/BMWTypeNext-Thin.woff2") format("woff2"),
         url("../../fonts/bmw/BMWTypeNextTT-Thin.woff") format("woff");
    font-weight: 100; font-style: normal; font-display: swap;
}
@font-face {
    font-family: "BMW Type Next";
    src: url("../../fonts/bmw/BMWTypeNext-Light.woff2") format("woff2"),
         url("../../fonts/bmw/BMWTypeNextTT-Light.woff") format("woff");
    font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
    font-family: "BMW Type Next";
    src: url("../../fonts/bmw/BMWTypeNext-Regular.woff2") format("woff2"),
         url("../../fonts/bmw/BMWTypeNextTT-Regular.woff") format("woff");
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: "BMW Type Next";
    src: url("../../fonts/bmw/BMWTypeNext-Bold.woff2") format("woff2"),
         url("../../fonts/bmw/BMWTypeNextTT-Bold.woff") format("woff");
    font-weight: 700; font-style: normal; font-display: swap;
}

/* Form controls + buttons don't inherit font-family by default, and this theme
   dropped the maquette's global reset — so bare <button>/<input> (e.g. the
   financing wizard's step indicators and edit/next buttons) fall back to the
   system font. Pin them to the BMW face so every page's forms match. */
.brand-bmw button,
.brand-bmw input,
.brand-bmw select,
.brand-bmw textarea {
    font-family: var(--font);
}

/* -----------------------------------------------------------------------------
   3. SITE CHROME — header, top bar, nav, mega menu, mobile nav, footer
   Re-skins the shared site/header + site/footer partials to BMW CI. Adapted
   from the maquette's chrome onto this theme's BEM class names. Styling only —
   no markup changes. Each selector scoped under .brand-bmw.
   ----------------------------------------------------------------------------- */

/* ---- Header shell: translucent, blurred, hairline base ---- */
.brand-bmw .site-header {
    background: rgba(255, 255, 255, .92);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--line);
}
.brand-bmw .site-header.scrolled,
.brand-bmw .site-header.is-scrolled {
    box-shadow: 0 10px 30px -20px rgba(26, 26, 26, .4);
}

/* ---- Top bar: dark CI band, uppercase tracked claim ---- */
.brand-bmw .top-bar {
    background: var(--ink-strong);
    color: var(--grey-300);
    font-size: .76rem;
    letter-spacing: .04em;
}
.brand-bmw .top-bar__announcement,
.brand-bmw .top-bar__marquee {
    color: var(--white);
    letter-spacing: .16em;
    text-transform: uppercase;
    font-size: .72rem;
}
.brand-bmw .top-bar a { transition: color .25s; }
.brand-bmw .top-bar a:hover { color: var(--white); }
.brand-bmw .top-bar__divider { color: rgba(255, 255, 255, .25); }

/* ---- Logo lockup ---- */
.brand-bmw .header__logo-text {
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--ink-strong);
}

/* ---- Primary nav: uppercase, tracked, BMW-blue underline reveal ---- */
.brand-bmw .nav-link {
    text-transform: uppercase;
    letter-spacing: .08em;
    font-size: .82rem;
    color: var(--ink-strong);
}
.brand-bmw .nav-menu > .nav-item > .nav-link {
    position: relative;
}
.brand-bmw .nav-menu > .nav-item > .nav-link::after {
    content: "";
    position: absolute;
    left: 14px; right: 14px; bottom: 6px;
    height: 1.5px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .35s var(--ease);
}
.brand-bmw .nav-menu > .nav-item:hover > .nav-link::after,
.brand-bmw .nav-menu > .nav-item > .nav-link.active::after {
    transform: scaleX(1);
}
/* Keep only the animated blue ::after underline on nav links — suppress the base
   theme's UA underline (.brand-bmw a:not(.btn):hover, specificity 0,3,1). */
.brand-bmw .nav-menu .nav-link:hover,
.brand-bmw .nav-menu .nav-link:focus { text-decoration: none; }

/* ---- Mega menu + nav dropdowns: white panel, hairline top, blue hover ---- */
.brand-bmw .megamenu,
.brand-bmw .nav-dropdown {
    background: var(--white);
    border-top: 1px solid var(--line);
    box-shadow: 0 30px 50px -30px rgba(26, 26, 26, .4);
    border-radius: 0;
}
.brand-bmw .megamenu__section-header,
.brand-bmw .nav-dropdown__heading {
    text-transform: uppercase;
    letter-spacing: .18em;
    font-size: .74rem;
    color: var(--ink-soft);
}
.brand-bmw .megamenu__links-list a:hover,
.brand-bmw .megamenu__model-item:hover .megamenu__model-name { color: var(--accent); }
.brand-bmw .megamenu__count { color: var(--ink-soft); }
.brand-bmw .megamenu__inventory-btn {
    border-radius: 0;
    text-transform: uppercase;
    letter-spacing: .08em;
}

/* ---- Header CTA + mobile toggle ---- */
.brand-bmw .header__actions .btn { border-radius: 0; text-transform: uppercase; letter-spacing: .08em; }

/* ---- Mobile nav drawer ---- */
.brand-bmw .mobile-nav { background: var(--white); }
.brand-bmw .mobile-nav__heading {
    text-transform: uppercase;
    letter-spacing: .16em;
    font-size: .74rem;
    color: var(--ink-soft);
}
.brand-bmw .mobile-nav__cta-btn,
.brand-bmw .submenu-cta { border-radius: 0; text-transform: uppercase; letter-spacing: .08em; }

/* ---- Footer: dark CI ground ---- */
.brand-bmw .site-footer {
    background: var(--ink-strong);
    color: var(--grey-400);
}
.brand-bmw .footer__column h3,
.brand-bmw .footer__column h4,
.brand-bmw .footer__column h5 {
    color: #fff;
    text-transform: uppercase;
    letter-spacing: .16em;
    font-size: .74rem;
}
.brand-bmw .footer__description { color: var(--grey-400); }
.brand-bmw .footer__links a,
.brand-bmw .footer__contact-item a { color: var(--grey-300); transition: color .25s, padding .25s; }
.brand-bmw .footer__links a:hover { color: #fff; padding-left: 5px; }
.brand-bmw .footer__contact-item a:hover { color: #fff; }
.brand-bmw .footer__social a {
    border: 1px solid rgba(255, 255, 255, .18);
    color: var(--grey-300);
    border-radius: 0;
    transition: background .25s, color .25s, border-color .25s;
}
.brand-bmw .footer__social a:hover { background: #fff; color: var(--ink-strong); border-color: #fff; }
/* ⭐ Plus d'inversion : le logo du pied de page garde ses couleurs, comme celui de la
   barre de nav (demande de Jade, 2026-08-24). C'était la 3e des trois règles qui
   l'aplatissaient — les deux autres sont dans theme.css. Tant qu'elle restait, le logo
   blanc sur la plaque blanche ne faisait qu'un gros carré blanc. La plaque, elle, est
   nécessaire : le fichier est à 38 % de pixels sombres et le pied de page est sur #1a1a1a. */
.brand-bmw .footer__logo-invert { filter: none; }
.brand-bmw .footer__bottom { border-top: 1px solid rgba(255, 255, 255, .1); }
.brand-bmw .footer__bottom a:hover { color: #fff; }

/* -----------------------------------------------------------------------------
   CAREERS PAGE (nerd.jobs) — BMW luxury refinement.
   Base layout in theme.css (.careers-*, .job-card, .careers-form). Here we apply the
   CI treatment: sharp corners, M-accent top rule, uppercase tracked labels, BMW type
   (form controls already inherit --font via the global pin above). Scoped under
   .brand-bmw .box-style-luxury (the page wraps its content in .box-style-luxury for
   luxury brands). The page-hero-style header uses .page-header--careers.
   ----------------------------------------------------------------------------- */

/* Header — le traitement CI (capitales, graisse fine) s'applique à TOUTES les pages
   statiques, pas seulement à Carrières. C'est l'écart relevé en QA : Carrières avait le
   bon rendu et Promotions, Blogue et Notre équipe suivaient le réglage global (700), d'où
   quatre titres qui ne se ressemblaient pas. La graisse reste ajustable au backend via
   « Heading Weight » (l'option 300 y a été ajoutée le 2026-08-13). */
.brand-bmw .page-header--careers { background: var(--bg-alt); border-bottom: 1px solid var(--line); }
.brand-bmw .page-header .page-header__title { text-transform: uppercase; font-weight: 300; letter-spacing: -.01em; color: var(--ink-strong); }
/* --ink-soft (#6f6f6f) en graisse 300 ne fait que 4.11:1 sur le fond de l'entête
   (Lighthouse, /fr/blogue) — sous les 4.5:1. --grey-700 (#494949) donne de la marge
   sans changer le gris de l'identité. Les entêtes bleus (financement, reprise) gardent
   leur texte blanc, réglé plus bas par un sélecteur plus précis. */
.brand-bmw .page-header .page-header__subtitle { color: var(--grey-700); font-weight: 300; }

/* Intro + shared rule (the .box-style-luxury .m-rule tricolor rule wins over base) */
.brand-bmw .box-style-luxury .careers-intro__lead { color: var(--ink-soft); font-weight: 300; font-size: var(--fs-lead); }
.brand-bmw .box-style-luxury .careers-jobs__title,
.brand-bmw .box-style-luxury .careers-form__title { text-transform: uppercase; font-weight: 300; color: var(--ink-strong); letter-spacing: .01em; }

/* Job cards */
.brand-bmw .box-style-luxury .job-card { background: var(--white); border: 1px solid var(--line); border-top: 3px solid var(--accent); border-radius: 0; box-shadow: var(--shadow-card); }
.brand-bmw .box-style-luxury .job-card:hover { box-shadow: var(--shadow-float); transform: translateY(-3px); }
.brand-bmw .box-style-luxury .job-card__title { font-weight: 400; color: var(--ink-strong); text-transform: uppercase; letter-spacing: .01em; }
.brand-bmw .box-style-luxury .job-card__meta-label { text-transform: uppercase; letter-spacing: .08em; font-size: .72rem; color: var(--ink-soft); font-weight: 400; }
.brand-bmw .box-style-luxury .job-card__meta-item { color: var(--grey-700); }
.brand-bmw .box-style-luxury .job-card__date { color: var(--ink-soft); }
.brand-bmw .box-style-luxury .job-card__desc { color: var(--grey-500); font-weight: 300; line-height: 1.8; }

/* Application form */
.brand-bmw .box-style-luxury .careers-form { background: var(--white); border: 1px solid var(--line); border-top: 4px solid var(--accent); border-radius: 0; box-shadow: var(--shadow-card); }
.brand-bmw .box-style-luxury .careers-form .field label { text-transform: uppercase; letter-spacing: .1em; font-size: .72rem; color: var(--ink-soft); font-weight: 400; }
.brand-bmw .box-style-luxury .careers-form .form-control { border-radius: 0; border: 1px solid var(--line); background: var(--bg-alt); }
.brand-bmw .box-style-luxury .careers-form .form-control:focus { border-color: var(--accent); background: #fff; box-shadow: none; }

/* -----------------------------------------------------------------------------
   TEAM PAGE — luxury refinement (pages/notre-equipe.htm)
   Shared .team-* markup from the theme; BMW gives it the architectural,
   sharp-cornered CI treatment. Only styling changes — the markup is identical.
   ----------------------------------------------------------------------------- */
.brand-bmw .box-style-luxury.team-section { background: var(--bg-alt); }

.brand-bmw .box-style-luxury .team-group__eyebrow {
    color: var(--ink-soft);
    letter-spacing: .18em;
}

.brand-bmw .box-style-luxury .team-group__title {
    color: var(--ink-strong);
    font-weight: 300;
    letter-spacing: -0.01em;
}

.brand-bmw .box-style-luxury .team-grid { gap: 4px; }

.brand-bmw .box-style-luxury .team-member {
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: 0;
    box-shadow: none;
    padding: 40px 28px 32px;
    position: relative;
    transition: box-shadow .35s var(--ease), transform .35s var(--ease), border-color .3s;
}

.brand-bmw .box-style-luxury .team-member::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: var(--m-stripe);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .42s var(--ease);
}

.brand-bmw .box-style-luxury .team-member:hover {
    box-shadow: var(--shadow-card);
    transform: translateY(-3px);
    border-color: transparent;
}

.brand-bmw .box-style-luxury .team-member:hover::before { transform: scaleX(1); }

.brand-bmw .box-style-luxury .team-member__media {
    border-radius: 0;
    background: var(--grey-50);
}

.brand-bmw .box-style-luxury .team-member__initials { color: var(--blue); }

.brand-bmw .box-style-luxury .team-member__name {
    color: var(--ink-strong);
    font-weight: 400;
}

.brand-bmw .box-style-luxury .team-member__position {
    color: var(--blue);
    letter-spacing: .1em;
}

.brand-bmw .box-style-luxury .team-member__experience { color: var(--ink-soft); }
.brand-bmw .box-style-luxury .team-member__bio { color: var(--ink); }

.brand-bmw .box-style-luxury .team-member__contact { border-top-color: var(--line); }
.brand-bmw .box-style-luxury .team-member__contact svg { color: var(--blue); }
.brand-bmw .box-style-luxury .team-member__contact a { color: var(--ink); }
.brand-bmw .box-style-luxury .team-member__contact a:hover { color: var(--blue); }

/* -----------------------------------------------------------------------------
   LINEUP VRP — new-vehicles listing ("/neufs" page, nerd.lineup Filternew).
   The plugin injects a token-driven `.vrp` base (vrp_styles.htm) that already
   picks up the BMW palette/radii via the token mappings above. These rules add
   the luxury CI refinements the tokens can't express: BMW Type Next thin
   uppercase headings, the tricolor M-rule, square pills/buttons (the base
   hardcodes rounded radii, which the radius tokens can't reach), and a
   monochrome price treatment (blue is reserved for CTA, not text). `.vrp` is
   used only by this page, so scoping under `.brand-bmw .vrp` is safe.
   ----------------------------------------------------------------------------- */
/* Header — left-aligned page hero with a tricolor accent, matching the SRP */
.brand-bmw .vrp__header {
    text-align: left;
    padding: clamp(28px, 3.2vw, 48px) 0 24px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 28px;
}
.brand-bmw .vrp__header::before {
    content: "";
    display: block;
    width: 46px;
    height: 3px;
    background: var(--m-stripe);
    margin-bottom: 18px;
}
.brand-bmw .vrp__header-title {
    font-family: var(--font);
    font-weight: 300;
    text-transform: uppercase;
    letter-spacing: -.01em;
    color: var(--ink-strong);
}
.brand-bmw .vrp__header-count { color: var(--ink-soft); }
.brand-bmw .vrp__header-count strong { color: var(--accent); }

/* Category pills — square, uppercase CI chips (base forces border-radius:999px) */
.brand-bmw .vrp__pill {
    border-radius: 0;
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: .72rem;
    color: var(--ink-soft);
    border-color: var(--line);
}
.brand-bmw .vrp__pill:hover {
    border-color: var(--ink-strong);
    color: var(--ink-strong);
    background: transparent;
}
.brand-bmw .vrp__pill.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

/* Category headings + tricolor divider */
.brand-bmw .vrp__category-title {
    font-weight: 300;
    text-transform: uppercase;
    letter-spacing: .02em;
    color: var(--ink-strong);
}
.brand-bmw .vrp__category-divider {
    width: 46px;
    height: 3px;
    background: var(--m-stripe);
    border-radius: 0;
}

/* Cards — sharp corners, hairline border, refined hover */
.brand-bmw .vrp__card {
    border-radius: 0;
    border: 1px solid var(--line);
    box-shadow: none;
    transition: box-shadow .4s var(--ease), transform .45s var(--ease), border-color .3s, opacity .5s ease;
}
.brand-bmw .vrp__card:hover {
    box-shadow: var(--shadow-card);
    border-color: transparent;
    transform: translateY(-4px);
}
.brand-bmw .vrp__card-image { background: var(--bg-alt); }
.brand-bmw .vrp__card-finance-btn { border-radius: 0; }
.brand-bmw .vrp__card-make { color: var(--ink-soft); letter-spacing: .14em; }
.brand-bmw .vrp__card-model {
    font-weight: 300;
    color: var(--ink-strong);
    letter-spacing: .01em;
}
.brand-bmw .vrp__card-price-label { letter-spacing: .14em; color: var(--ink-soft); }
/* Blue is a CTA colour in the CI — the price reads in strong ink, not accent */
.brand-bmw .vrp__card-price { color: var(--ink-strong); font-weight: 400; }

/* Buttons — square, uppercase, letter-spaced (base hardcodes border-radius:8px) */
.brand-bmw .vrp__btn-primary,
.brand-bmw .vrp__btn-outline {
    border-radius: 0;
    text-transform: uppercase;
    letter-spacing: .08em;
    font-size: .76rem;
}
.brand-bmw .vrp__btn-primary {
    background: var(--accent);
    border-color: var(--accent);
}
.brand-bmw .vrp__btn-primary:hover {
    background: var(--blue-700);
    border-color: var(--blue-700);
    opacity: 1;
}
.brand-bmw .vrp__btn-outline {
    color: var(--ink-strong);
    border-color: var(--line);
}
.brand-bmw .vrp__btn-outline:hover {
    background: var(--bg-alt);
    color: var(--ink-strong);
    border-color: var(--ink-strong);
}

/* Filter/search controls (visible when the page unhides the filter) — sharp */
.brand-bmw .vrp__search-input,
.brand-bmw .vrp__sort,
.brand-bmw .vrp__filters-toggle,
.brand-bmw .vrp__filter-group .filterDropdown__btn,
.brand-bmw .vrp__filter-group .filterDropdown__content,
.brand-bmw .vrp__scroll-top { border-radius: 0; }

/* -----------------------------------------------------------------------------
   3. ACCESSIBILITÉ — corrections de contraste WCAG 2.2 AA (2026-08-24)
   Audit demandé par l'équipe : /fr/contactez-nous, /fr/financement,
   /fr/formulaire-devaluation (+ /en). Ratios mesurés à la main (luminance relative,
   formule WCAG) faute de navigateur outillé dans cette session — cible SC 1.4.3
   (texte : 4.5:1 normal / 3:1 grand) et SC 1.4.11 (bordures de champs, icônes
   porteuses de sens : 3:1).
   ----------------------------------------------------------------------------- */

/* --- Bug de spécificité : l'entête dégradé bleu de financement/reprise (fourni par
   le plugin nerd/nerdcrm, financing-form.css / tradein-form.css) est réécrit en texte
   sombre par la règle Carrières ci-dessus (`.brand-bmw .page-header .page-header__*`,
   pensée pour l'entête clair de cette page), qui gagne par spécificité ÉGALE (0,3,0)
   sur les règles blanches du plugin (0,2,0). Mesuré : titre #1a1a1a sur #0066b1 =
   2.93:1, sous-titre #6f6f6f sur #0066b1 = 1.18:1 — quasi illisible. Fix : même
   spécificité (0,3,0), placée APRÈS → l'ordre de source tranche (déjà le principe
   documenté plus haut pour --header-height). */
.brand-bmw .page-header--financing .page-header__title,
.brand-bmw .page-header--trade-in .page-header__title {
    color: #fff;
}
.brand-bmw .page-header--financing .page-header__subtitle,
.brand-bmw .page-header--trade-in .page-header__subtitle {
    color: #fff;
    opacity: .9;
}
/* Fil d'Ariane du même entête : rgba(255,255,255,.8) sur ce bleu ne fait que 4.38:1
   (sous 4.5:1). .92 -> 5.30:1, mesuré. */
.brand-bmw .page-header--financing .page-header__breadcrumb a,
.brand-bmw .page-header--financing .page-header__breadcrumb span,
.brand-bmw .page-header--trade-in .page-header__breadcrumb a,
.brand-bmw .page-header--trade-in .page-header__breadcrumb span {
    color: rgba(255, 255, 255, .92);
}

/* --- Rouge d'erreur : #ef4444 (theme.css --color-error, repris tel quel en dur par
   nerdcrm/{financing,tradein}-form.css sur .invalid-feedback, .required-indicator,
   .search-results__error, .selected-vehicle__remove) ne fait que 3.76:1 sur blanc —
   sous 4.5:1. On assombrit le rouge M déjà dans la palette CI (--m-red #e22718 ne
   fait lui-même que 4.63:1, trop juste) : #c11f0f = 6.05:1, mesuré. */
:root.brand-bmw {
    --color-error: #c11f0f;
    /* --- Vert de succès : --brand-success n'est défini nulle part (ni theme.css, ni
       plus haut dans ce fichier) ; nerdcrm/{financing,tradein}-form.css retombe sur
       son fallback codé en dur #22c55e = 2.28:1 sur blanc (icônes de bénéfices, icône
       de succès de l'assistant). #157347 = 5.87:1, mesuré. */
    --brand-success: #157347;
    /* --- Alias défensif : tradein-form.css lit --brand-text-primary pour les titres
       de section (jamais défini ailleurs) ; sans alias `color` est invalide et
       retombe sur l'héritage, un rendu non garanti plutôt qu'un vrai contraste. */
    --brand-text-primary: var(--ink-strong);
}
.brand-bmw .invalid-feedback,
.brand-bmw .required-indicator,
.brand-bmw .search-results__error,
.brand-bmw .selected-vehicle__remove { color: var(--color-error); }
.brand-bmw .selected-vehicle__remove:hover { color: #fff; background: var(--color-error); }

/* --- Placeholder d'upload photo (reprise) : #9ca3af sur #fafafa ne fait que 2.43:1.
   --ink-soft donne 4.81:1 sur ce même fond, mesuré. */
.brand-bmw .image-upload-placeholder { color: var(--ink-soft); }

/* --- Sous-étiquette de la note d'état du véhicule : #888 à 11px sur blanc = 3.54:1.
   --ink-soft donne 5.02:1, mesuré. */
.brand-bmw .condition-rating-sublabel { color: var(--ink-soft); }

/* --- Note d'état sélectionnée : le libellé passe en var(--rating-color) (posée en
   style inline par le composant, hors de portée ici) — 3 des 5 teintes échouent comme
   TEXTE une fois sélectionnées (jaune #ffc107 1.63:1, sarcelle #20c997 2.13:1, orange
   #fd7e14 2.57:1 sur blanc, mesurés ; seuls le vert #198754 et le rouge #dc3545
   passent de justesse à 4.53:1). Le code couleur reste porté par la barre et le fond
   teinté (color-mix 8%) ; le texte repasse en encre foncée, lisible dans tous les cas. */
.brand-bmw .condition-rating-input:checked ~ .condition-rating-card .condition-rating-label {
    color: var(--ink-strong);
}

/* --- Bordures de champs : var(--brand-border)/var(--brand-border-strong) valent
   grey-200/#cbd5e1 ici, 1.45:1 et 1.48:1 sur blanc — un champ ou une carte de
   sélection au repos n'a alors aucun contour perceptible (SC 1.4.11, 3:1 requis).
   --grey-400 (déjà dans la palette CI, déjà utilisé pour du texte tertiaire) donne
   3.11:1, mesuré. Scopé aux contrôles réels (champs texte/select, cases à cocher,
   puces radio, ET les cartes de sélection qui remplacent visuellement un input caché
   en opacity:0 sur financement/reprise) — pas aux traits de séparation décoratifs :
   on remonte la lisibilité, pas un repaint du skin. */
.brand-bmw .form-control,
.brand-bmw .form-select,
.brand-bmw .form-check-input,
.brand-bmw .checkbox-custom,
.brand-bmw .radio-list-indicator,
.brand-bmw .radio-list-card,
.brand-bmw .condition-rating-card,
.brand-bmw .brand-selector-card,
.brand-bmw .vehicle-type-option__card {
    border-color: var(--grey-400);
}


/* ⛔ Sous-titre des boutons de la colonne latérale : blanc sur un bouton devenu blanc
   (« Planifiez votre visite », 3.59:1 puis invisible selon la variante). On reprend
   l'encre du bouton lui-même plutôt qu'une couleur fixe : le CTA plein garde son texte
   clair, le CTA en contour reprend l'encre foncée. */
.brand-bmw .inv-vdp-sidebar__cta-text small {
    color: inherit;
    /* ⛔ Pas d'opacité : le thème en pose déjà 0.8 et elle DILUE la couleur — mesuré,
       le texte tombait à 3.72:1. Un sous-titre de bouton doit se lire, pas s'effacer. */
    opacity: 1;
}

/* Même cause sur l'étiquette des caractéristiques : une opacité héritée ramenait
   l'encre à ~#7c7d7d. On la remet à plein. */
.brand-bmw .inv-vdp__fact-label {
    opacity: 1;
}


/* =============================================================================
   MÉGA-MENU MODÈLES — règles RAPATRIÉES depuis `nerd/lineup` (2026-08-25)
   ⛔ Ce plugin appartient à Sean : on n'y pousse pas. Les règles ci-dessous
   vivaient dans son `assets/css/lineupmenu.css` et n'auraient donc jamais
   atteint le staging par notre MR. Elles sont ici pour partir avec nos commits,
   avec le gabarit correspondant (`partials/lineupmenu/default.htm`, surcharge
   de thème du composant).
   ⚠️ MESURÉ le 2026-08-25 : `lineupmenu.css` est chargée APRÈS `bmw.css` (elle est
   injectée par le composant, pas par le layout). À spécificité égale le PLUGIN
   gagnerait donc. Les sélecteurs qui entrent en collision avec lui sont préfixés
   `html.brand-bmw` (+1 type +1 classe) pour gagner quel que soit l'ordre.
   Les classes neuves (.lm__tab-all, .lm-drill__all) n'ont pas ce besoin.
   ⛔ À RETIRER quand Sean aura intégré les patches
   (~/Sites/_staging-export/patches-pour-sean-2026-08-25/) — sinon deux copies
   des mêmes règles divergeront.
   ============================================================================= */

/* Une 6e tuile (la carte « Voir tous les modèles ») faisait replier la rangée
   dès ~1315 px au lieu de ~1113 px : 156 px rétablit l'ancien seuil. */
html.brand-bmw .lm__tabs { grid-template-columns: repeat(auto-fit, minmax(156px, 1fr)); }

/* ---- Carte « Voir tous les modèles » (fin de la rangée d'onglets) ----
   Même boîte que .lm__tab pour garder la grille auto-fit régulière, mais un
   LIEN et non un onglet : barre d'accent noire (les catégories l'ont bleue),
   fond gris clair et chevron. Deux classes distinctes plutôt qu'un modifieur
   de .lm__tab, parce que le JS sélectionne `.lm__tab` pour mapper les
   panneaux — voir le commentaire du gabarit. */
.lm__tab-all { display: grid; grid-template-columns: 3px 1fr auto; column-gap: clamp(11px, 1vw, 16px); row-gap: 3px;
               align-content: center;
               padding: clamp(12px, 1.2vw, 18px) clamp(14px, 1.2vw, 20px) clamp(12px, 1.2vw, 18px) 0;
               border: 1px solid var(--grey-200, #d6d6d6); background: var(--grey-100, #ededee);
               position: relative; text-decoration: none; text-align: left; }
.lm__tab-all::before { content: ""; grid-column: 1; grid-row: 1 / -1; align-self: stretch; background: var(--black, #1a1a1a); }
.lm__tab-all .lm__tab-name { grid-column: 2; grid-row: 1; font-weight: 500; }
.lm__tab-all .lm__tab-count { grid-column: 2; grid-row: 2; }
.lm__tab-all-chev { grid-column: 3; grid-row: 1 / -1; align-self: center; display: grid; place-items: center;
                    color: var(--black, #1a1a1a); }
.lm__tab-all:hover,
.lm__tab-all:focus-visible { background: #fff; border-color: var(--grey-300, #c7c7c7); }
@media (prefers-reduced-motion: no-preference) {
    .lm__tab-all,
    .lm__tab-all-chev { transition: background-color .18s var(--ease, cubic-bezier(.2,.7,.2,1)),
                                    border-color .18s var(--ease, cubic-bezier(.2,.7,.2,1)),
                                    transform .18s var(--ease, cubic-bezier(.2,.7,.2,1)); }
    .lm__tab-all:hover .lm__tab-all-chev { transform: translateX(3px); }
}

/* Pendant mobile de .lm__tab-all : même rangée que .lm-drill__cat, barre d'accent
   noire pour la distinguer des catégories, et c'est un lien (pas un bouton de drill). */
.lm-drill__all { display: flex; align-items: center; gap: 12px; padding: 16px; border-bottom: 1px solid var(--grey-100,#ededee);
                 position: relative; width: 100%; text-decoration: none; background: var(--grey-100,#ededee); }
.lm-drill__all::before { content:""; position:absolute; left:0; top:13px; bottom:13px; width:3px; background: var(--black,#1a1a1a); }
.lm-drill__all .lm-drill__cat-name { font-weight: 500; }
.lm-drill__all .lm-drill__chev { color: var(--black,#1a1a1a); }


/* -----------------------------------------------------------------------------
   Grid Search — live filter box above the inventory (partials/vehicles/default.htm)
   and models (pages/models.htm → Filternew) grids. Markup: partials/site/grid-search.htm.
   Behaviour: assets/js/grid-search.js.
   Scoped to `.brand-bmw` alone, not `.box-style-luxury`: the models grid (Filternew,
   a Nerd.Lineup component) never gets that wrapper, same reason `.vrp__search-input`
   above is scoped the same way. Visual language borrowed from the existing quicksearch
   `.qs-card` (white card, top accent border, sharp corners) so it reads as the same
   family of control as the hero search and the VRP toolbar.
----------------------------------------------------------------------------- */
.brand-bmw .grid-search { margin-bottom: clamp(20px, 2.4vw, 32px); }
.brand-bmw .grid-search__field {
    position: relative;
    background: var(--white);
    border: 1px solid var(--line);
    border-top: 4px solid var(--accent);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 20px;
    transition: box-shadow .2s var(--ease);
}
/* Native `input:focus { outline: none }` is replaced by a visible ring on the whole
   field — required (WCAG 2.2 SC 2.4.11), and reads better than a browser outline
   sitting flush against the field's own border. */
.brand-bmw .grid-search__field:focus-within { box-shadow: 0 0 0 2px var(--accent) inset; }
.brand-bmw .grid-search__icon { width: 20px; height: 20px; color: var(--ink-soft); flex-shrink: 0; }
.brand-bmw .grid-search__input { flex: 1; border: none; background: none; font: inherit; font-size: 1rem; color: var(--ink-strong); padding: 4px 0; }
.brand-bmw .grid-search__input:focus { outline: none; }
.brand-bmw .grid-search__input::placeholder { color: var(--ink-soft); }
.brand-bmw .grid-search__input::-webkit-search-cancel-button { display: none; }
.brand-bmw .grid-search__clear {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; padding: 0; border: none; border-radius: 0;
    background: var(--bg-alt); color: var(--ink-soft); cursor: pointer; flex-shrink: 0;
    transition: background .2s, color .2s;
}
.brand-bmw .grid-search__clear svg { width: 14px; height: 14px; }
.brand-bmw .grid-search__clear:hover { background: var(--accent); color: var(--white); }
/* Spans every column of whichever grid it lands in (.inv-grid on inventory,
   .vrp__grid on models) — ignored harmlessly if that grid turns out to be flex. */
.brand-bmw .grid-search__empty { grid-column: 1 / -1; width: 100%; padding: 48px 20px; text-align: center; color: var(--ink-soft); font-size: .95rem; }

/* -----------------------------------------------------------------------------
   VRP lineup counter (pages/models.htm → Filternew, "/neufs" · "/new-vehicles")
   — restyled to match the inventory counter's typography (.page-hero .ph-meta
   .pm .n / .pm .l above), demande de Jade : « avec l'ecriture de la page
   inventaire ». Same rem values and CSS vars, not re-invented.
   Markup moved (not renamed) from @partials/filterResult into @partials/filter's
   .vrp__header — see the theme overrides in partials/Filternew/. Classes kept
   exactly as the plugin declared them (`.vrp__header-count`, `.vrp__count-number`)
   because plugins/nerd/lineup's own vrp_scripts.htm finds the counter by class to
   animate it on category-pill clicks; only its CSS and its parent in the DOM
   changed, never its class contract.
----------------------------------------------------------------------------- */
.vrp__header .vrp__header-count {
    display: flex;
    flex-direction: column;
    /* ⛔ flex-start, PAS center : le bloc occupe toute la largeur de l'en-tête, donc
       `align-items:center` posait le nombre au MILIEU de la page alors que le titre est
       à gauche (rapporté par Jade, 2026-08-25 : « il est centré dans la page »).
       ⚠️ Piège de mesure : `getBoundingClientRect()` du bloc donnait bien x=88, aligné
       sur le <h1> — c'est le CONTENU qui était centré à l'intérieur, pas la boîte. Une
       boîte alignée ne prouve pas un texte aligné. */
    align-items: flex-start;
    font-size: .76rem;
    letter-spacing: .06em;
    color: var(--ink-soft);
    margin-top: 5px;
}
.vrp__header .vrp__header-count .vrp__count-number {
    font-size: 1.9rem;
    font-weight: 300;
    letter-spacing: normal; /* .pm .n n'a pas le tracking du wrapper, contrairement à .pm .l */
    color: var(--ink-strong);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.vrp__header .vrp__header-count-label { display: block; }


/* ---- Méga-menu Modèles : survol = ouvre, clic = navigue (demande Jade 2026-08-25) ----
   Le CSS du plugin ANNULE explicitement la révélation au survol tant que `.is-open`
   n'est pas posée (`.nav-item.lm-nav.has-megamenu:not(.is-open):hover > .lm-megamenu
   { opacity:0; visibility:hidden }`), parce qu'il ouvrait au clic. On rétablit le
   comportement des autres méga-menus du thème, qui s'ouvrent déjà au survol
   (`theme.css:4849`). Spécificité montée d'un cran pour battre la règle du plugin,
   chargée APRÈS bmw.css. */
html.brand-bmw .nav-item.lm-nav.has-megamenu:hover > .lm-megamenu,
html.brand-bmw .nav-item.lm-nav.has-megamenu:focus-within > .lm-megamenu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}


/* ---- Méga-menu Modèles : hauteur ----
   ⛔ J'avais borné `.lm__body` à `calc(100dvh - 320px)` et mis `.lm__lists` à
   `max-height:100%` pour que le panneau ne déborde plus le bas de l'écran. Mauvais
   échange : dans une grille l'enfant vaut `min-height:auto`, la liste refusait donc
   de rétrécir, elle passait de 467 px à 820 px pour 825 px de contenu — **5 px
   défilables au lieu de 358**. Jade l'a vu tout de suite : « les scroll down dans le
   megamenu modeles ne fonctionne plus correctement ».
   On rend la main à la règle du plugin (`min(620px, 56vh)`), qui défilait bien. Le
   débordement de 90 px en bas d'écran redevient un défaut ouvert — mais un menu qui
   défile mal est pire qu'un menu 90 px trop long. */

/* ---- Page Modèles : la ligne de specs prend l'habillage des cartes d'inventaire ----
   Demande Jade 2026-08-25 : « devrait etre affiché comme dans les cartes de vehicules
   dans la page inventaire ». Le markup est passé en `.veh-specs`/`.sp`/`.ico` (mêmes
   icônes que `partials/vehicles/partials/grid.htm`), mais la règle d'origine est scopée
   `.brand-bmw .box-style-luxury .veh-specs` — or les cartes de la page Modèles ne sont
   PAS dans un conteneur `.box-style-luxury`. On rejoue donc les MÊMES valeurs pour ce
   contexte-ci, sans les réinventer (lignes 365-367 de ce fichier).
   Une seule colonne ici : la carte de gamme est plus étroite que celle de l'inventaire,
   deux colonnes y couperaient « Transmission intégrale ». */
html.brand-bmw .vrp__card .veh-specs {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px 14px;
    padding: 14px 0;
    border-block: 1px solid var(--line);
}
html.brand-bmw .vrp__card .veh-specs .sp {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: .85rem;
    color: var(--grey-700);
}
html.brand-bmw .vrp__card .veh-specs .sp .ico { width: 17px; height: 17px; color: var(--ink-soft); flex: none; }

/* ---- Fiche véhicule : specs de la barre "quick facts" alignées sur les cartes ----
   Demande Jade 2026-08-25 : le CTA "10 834 km / 35826 Stock #" de la VDP doit porter
   les mêmes badges que les cartes de la grille inventaire (partials/inventory/
   vdp-quick-facts.htm réutilise désormais les icônes `.ico` de grid.htm pour Moteur/
   Traction/Carburant). Ces SVG n'ont pas de width/height inline (contrairement aux
   icônes 24x24 déjà présentes dans ce bloc) : sans cette règle ils débordent la boîte
   44x44px de `.inv-vdp__fact-icon` (theme.css). Même gabarit que les icônes voisines. */
.brand-bmw .inv-vdp__fact-icon .ico { width: 24px; height: 24px; }

/* ---- Méga-menu « Concessionnaire » : même hauteur que « Inventaire » ----
   Demande Jade 2026-08-25 : « le dropdown de concessionnaire est un peu trop haut,
   il doit etre la meme hauteur que celui d'inventaire ».
   Mesuré : le panneau Concessionnaire ouvrait à y=93, celui de l'Inventaire à y=107.
   Cause — les deux <li> portent les MÊMES classes mais pas la même position :
     Inventaire      → position: static   → le panneau se cale sur le <header> (107 px)
     Concessionnaire → position: relative → il se cale sur son <li> (45 px)
   On aligne le second sur le premier. `:has()` cible le seul <li> concerné, sans
   toucher aux autres menus déroulants du thème. */
html.brand-bmw .nav-item.has-megamenu:has(> .megamenu--nav) {
    /* ⛔ On GARDE `position: relative` (valeur du thème) : le passer en `static`
       alignait bien la hauteur, mais le panneau se calait alors sur le <header> et
       débordait jusqu'au bord droit de la fenêtre au lieu de rester sous son onglet
       (rapporté par Jade : « il overflow vers la droite »).
       On corrige donc le seul défaut réel — le décalage VERTICAL — sans toucher à
       l'ancrage horizontal. */
    position: relative;
}
/* Le panneau ouvrait 14 px trop haut : `top: 100%` le cale sur le bas du <li> (y=93),
   alors que celui de l'Inventaire se cale sur le bas du <header> (y=107). Ces 14 px
   sont le rembourrage bas de l'en-tête. Mesuré le 2026-08-25 à 1440 px.
   ⚠️ Ce +14px ne suffit qu'à l'état de repos : re-mesuré (vrai survol CDP, pas un
   `.megamenu{opacity:0}` déclaratif) en comparant le `top` RENDU des deux panneaux
   (pas leur `top` CSS — ils n'ont pas le même référentiel, comparer les deux est ce
   qui a fait chercher un écart de 47 px qui n'existe pas). Écart réel :
     repos (`.site-header` sans `.is-scrolled`)  → 0.5 px encore
     défilé (`.site-header.is-scrolled`, header réduit par `--header-height-scrolled`)
       → 6.5 px, parce que la hauteur du <li> (fixe, 45px) ne réduit pas au même rythme
       que le rembourrage du <header> quand il rétrécit. D'où « encore trop haut »
       répété par Jade après le premier correctif : il ne couvrait pas l'état défilé. */
html.brand-bmw header.site-header:not(.is-scrolled) .megamenu--nav { top: calc(100% + 13.5px); }
html.brand-bmw header.site-header.is-scrolled .megamenu--nav { top: calc(100% + 7.5px); }

/* ⭐ « Financement » — le seul panneau de la barre de nav qui n'est PAS un `.megamenu` : il est
   rendu par `.nav-dropdown`, un petit panneau de 220 px. Mesuré le 2026-08-26, il divergeait des
   trois autres sur deux points, tous deux signalés par Jade :
     · il s'ouvrait à 102,5 px alors que Modèles, Inventaire et Concessionnaire s'ouvrent à 126 —
       il chevauchait donc le bas de l'en-tête (107 px). Même calage que `.megamenu--nav`, dans
       les deux états de l'en-tête ;
     · ses liens sortaient en 16 px avec 12/16 de rembourrage, soit des items de 50 à 75 px de
       haut, contre 14 px et 38 px dans les mégamenus. On aligne la typographie et la densité. */
/* ⚠️ Calibré sur l'état OUVERT, pas fermé. Les panneaux sont masqués avec un `transform`
   (translateY) : mesuré fermé, un panneau annonce une position qu'il n'aura pas à l'écran. Mon
   +23,5 px venait de cette confusion ; en ouvert il sortait à 116 contre 106 pour Concessionnaire.
   Valeurs vérifiées panneau OUVERT : les deux à 106 au repos. */
html.brand-bmw header.site-header:not(.is-scrolled) .nav-dropdown { top: calc(100% + 13.5px); }
html.brand-bmw header.site-header.is-scrolled .nav-dropdown { top: calc(100% + 7.5px); }

/* ⛔ CE QUI RESTE VISIBLEMENT DIFFÉRENT N'EST PAS DU CSS : le panneau Concessionnaire porte des
   en-têtes de section (« À PROPOS », « SERVICES ») soulignés de 2 px bleus, parce que ses entrées
   de nav contiennent des enfants de type `heading`. Financement n'en a AUCUN (mesuré :
   `.nav-dropdown__heading` absent du DOM), donc son panneau est une liste nue. Ça se règle au
   backend, pas ici. La règle ci-dessous prépare le terrain : le jour où un en-tête est ajouté
   sous Financement, il aura exactement l'allure de ceux du mégamenu. */
html.brand-bmw .nav-dropdown__heading span {
    display: block;
    font-size: 11.84px;
    letter-spacing: 2.13px;
    text-transform: uppercase;
    color: var(--grey-600, rgb(111, 111, 111));
    border-bottom: 2px solid var(--accent);
    padding-bottom: var(--space-2, 8px);
    margin-bottom: var(--space-4, 16px);
}

/* Même habillage intérieur que `.megamenu__inner` (20 px) et mêmes liens que
   `.megamenu__links-list a` (14 px, 8/0) — c'est ce qui restait différent à l'œil. */
/* ⭐ La ligne bleue, COLLÉE EN HAUT du panneau (choix de Jade, 2026-08-26). Première tentative :
   un `::before` tracé à l'intérieur du rembourrage, à la place du soulignement d'en-tête du
   mégamenu — vu au vrai survol, le trait flottait seul au-dessus d'une zone vide, parce que le
   titre qu'il est censé souligner n'existe pas dans le contenu de Financement. Ici c'est un liseré
   de marque sur le bord du panneau : pas d'espace mort, et le rappel visuel du bleu reste. */
html.brand-bmw .nav-dropdown {
    padding: 20px;
    /* Le mégamenu porte SA ligne en `::before` (theme.css:4821) : 3 px, dégradé
       primary → accent → primary. On reprend exactement la même, plutôt qu'un `border-top`
       approximatif de 2 px en aplat. */
    position: absolute;
}

html.brand-bmw .nav-dropdown::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    background: linear-gradient(90deg,
        var(--brand-primary) 0%,
        var(--brand-accent) 50%,
        var(--brand-primary) 100%);
}

/* ⛔ PONT DE SURVOL. Le panneau s'ouvre sur `.nav-item.has-dropdown:hover` (theme.css:2282),
   donc le pointeur doit rester DANS le `<li>`. Or le `<li>` s'arrête à 92 px et le panneau
   commence à 106 : ces 14 px de vide font perdre le survol, et le menu se referme dès qu'on
   descend vers lui (rapporté par Jade, 2026-08-26). Ce pseudo-élément transparent comble la
   bande. Il est enfant du panneau, donc du `<li>` : le survoler maintient le menu ouvert. */
html.brand-bmw .nav-dropdown::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -16px;
    height: 16px;
}
html.brand-bmw .nav-dropdown a {
    font-size: var(--text-sm);
    padding: var(--space-2, 8px) 0;
}

/* ---- Grille d'inventaire : état « aucun résultat » ----
   Demande Jade 2026-08-25 : « devrait etre centré dans la page et avoir une carte autour ».
   Ce bloc n'avait AUCUNE règle : ni `.inv-empty` ni ses enfants n'existaient dans
   theme.css ou bmw.css — d'où un texte brut aligné à gauche. On reprend le cadre des
   cartes de véhicule (fond blanc, filet `--line`, coins carrés) pour rester cohérent. */
html.brand-bmw .inv-empty {
    grid-column: 1 / -1;              /* la grille est en colonnes : on occupe toute la largeur */
    max-width: 640px;
    margin: clamp(24px, 4vw, 56px) auto;
    padding: clamp(28px, 4vw, 48px) clamp(20px, 3vw, 40px);
    background: #fff;
    border: 1px solid var(--line);
    text-align: center;
}
html.brand-bmw .inv-empty__title {
    font-size: clamp(19px, 1.5vw, 24px);
    font-weight: 400;
    color: var(--ink-strong);
    margin: 0 0 .6em;
}
html.brand-bmw .inv-empty__detail {
    font-size: .9rem;
    font-weight: 400;
    color: var(--grey-700);
    margin: 0;
    line-height: 1.6;
}

/* ---- « Réinitialiser les filtres » : état de survol ----
   Demande Jade 2026-08-25 : « contraste pas correctement quand on hover dessus ».
   Cause : le bouton porte les classes Bootstrap `btn btn-outline-secondary`, servies
   depuis le CDN. Au repos, notre règle (l. 613-615) le rend en lien bleu sans fond ;
   au SURVOL, c'est Bootstrap qui reprend la main et peint son fond gris `#6c757d`,
   pendant que notre `color: var(--accent)` (bleu #0066b1) reste — soit du bleu sur
   gris, ≈ 1,6:1. Notre règle de repos n'avait aucun pendant `:hover`, d'où le trou.
   On garde le parti pris « lien », sans fond, et on marque le survol par un bleu plus
   sombre + un soulignement : le contraste reste calculé contre le fond du panneau. */
html.brand-bmw #resetFiltersContainer .btn:hover,
html.brand-bmw #resetFiltersContainer button:hover,
html.brand-bmw #resetFiltersContainer a:hover,
html.brand-bmw #resetFiltersContainer .btn:focus-visible,
html.brand-bmw #resetFiltersContainer button:focus-visible {
    background: none;
    border: 0;
    color: var(--blue-dark, #00518f);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ⭐ « Voir plus de véhicules » — bouton BLEU PLEIN, identique sur les deux grilles et à
   toutes les largeurs (Jade, 2026-08-25 : « il devrait être bleu et avoir le même en mode
   mobile »). Les deux pages ne partaient pas du même habillage : l'inventaire rendait
   `btn btn--ghost` (262x46, contour), la page Modèles `vrp__btn-outline` (pleine largeur,
   1264x42). On cible le RÔLE, pas les classes, pour que les deux se rejoignent — et une
   seule règle, sans media query, garantit qu'il n'y a pas de variante mobile qui dérive. */
/* ⛔ DOUBLON : le plugin nerd/inventory rend SON propre bouton mobile
   (`#mobileLoadMoreBtn.mobile-load-more-btn.d-lg-none`, vehicles.js) — visible sous 992 px, en
   blanc, 468x48, juste sous le nôtre. Mesuré le 2026-08-26 : deux boutons « Voir plus de
   véhicules » empilés. Le nôtre couvre desktop ET mobile depuis `assets/js/vrp-load-more.js`,
   donc celui du plugin n'a plus de raison d'être. On le masque côté thème — le plugin n'est pas
   notre dépôt, on n'y touche pas. */
html.brand-bmw #mobileLoadMoreBtn,
html.brand-bmw .mobile-load-more-btn {
    display: none !important;
}

html.brand-bmw [data-role="vrp-load-more-btn"][data-role],
html.brand-bmw [data-role="vrp-load-less-btn"][data-role],
html.brand-bmw [data-role="lineup-more-btn"][data-role],
html.brand-bmw [data-role="lineup-less-btn"][data-role] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    min-width: 262px;
    min-height: 46px;
    padding: 0 var(--space-5, 1.75rem);
    /* ⛔ On pilote --bg / --fg, PAS `background` / `color` : le contrat de bouton BMW est
       `.brand-bmw .box-style-luxury .btn { background: var(--bg); color: var(--fg) }`
       (bmw.css:222), spécificité 3 classes — une déclaration `background` directe à
       2 classes perd contre lui, et le bouton restait transparent (mesuré). */
    --bg: var(--accent);
    --fg: #fff;
    background: var(--bg);
    border: 1px solid var(--accent);
    color: var(--fg);
    font-weight: 400;
    letter-spacing: .02em;
    text-transform: none;
    border-radius: 0;
    transition: background-color .2s ease, border-color .2s ease;
}

/* ⛔ `display: inline-flex` ci-dessus battrait le `hidden` du HTML (display:none a la
   specificite 0) : sans cette regle, « Voir moins » resterait visible en permanence. */
html.brand-bmw [data-role$="-btn"][hidden] {
    display: none !important;
}

html.brand-bmw [data-role="vrp-load-more-btn"][data-role]:hover,
html.brand-bmw [data-role="vrp-load-more-btn"][data-role]:focus-visible,
html.brand-bmw [data-role="vrp-load-less-btn"][data-role]:hover,
html.brand-bmw [data-role="vrp-load-less-btn"][data-role]:focus-visible,
html.brand-bmw [data-role="lineup-more-btn"][data-role]:hover,
html.brand-bmw [data-role="lineup-more-btn"][data-role]:focus-visible,
html.brand-bmw [data-role="lineup-less-btn"][data-role]:hover,
html.brand-bmw [data-role="lineup-less-btn"][data-role]:focus-visible {
    /* Bleu foncé : même valeur que le survol du bouton « réinitialiser les filtres »
       (contraste mesuré 7,48:1 sur le fond du panneau) — un seul bleu de survol sur le site. */
    --bg: #00518f;
    --fg: #fff;
    background: var(--bg);
    border-color: #00518f;
    color: var(--fg);
}

/* En mobile, le bouton prend la largeur disponible plutôt que de dépasser les 262px
   minimum sur un écran de 390px — même allure, jamais de débordement. */
@media (max-width: 480px) {
    html.brand-bmw [data-role="vrp-load-more-btn"][data-role],
    html.brand-bmw [data-role="vrp-load-less-btn"][data-role],
    html.brand-bmw [data-role="lineup-more-btn"][data-role],
    html.brand-bmw [data-role="lineup-less-btn"][data-role] {
        width: 100%;
        min-width: 0;
    }
}

/* ⛔ CONTRASTE — la box « Dealer Location » sur TOUT fond CLAIR. Première passe le 2026-08-26
   (Jade, sur /fr/essai-routier), REPRISE le 2026-08-27 : Jade a retrouvé le même texte blanc sur
   blanc sur /fr/contactez-nous, parce que la passe précédente ne visait que `.bg-default`. La box
   existe en 10 exemplaires, dont 4 en `bg_style = light` (/fr/contactez-nous, /en/contact-us,
   /fr/ix3, /en/ix3) : elles étaient toutes cassées.
   ⭐ La leçon : corriger la VARIANTE qu'on a sous les yeux laisse les autres cassées. On liste
   donc les trois fonds clairs du thème une seule fois, avec `:is()`.
       .bg-default → var(--brand-bg)     = #ffffff   (mesuré le 2026-08-27)
       .bg-light   → var(--brand-bg-alt) = #f4f5f7
       .bg-surface → var(--brand-surface)= #ffffff
   La cause : la section porte À LA FOIS `box-style-luxury` et un fond clair. La règle luxe
   (bmw.css:345) donne un fond SOMBRE avec une encre claire (`--grey-200`) ; la classe de fond
   repeint le fond en clair et l'encre claire reste. Mesuré sur /fr/contactez-nous AVANT :
       « BMW Ste-Agathe. » (.h2)   blanc sur #f4f5f7    1,09:1  ⛔ invisible
       adresse et téléphone        rgb(199,199,199)     1,55:1  ⛔
       jours de la semaine         rgb(214,214,214)     1,33:1  ⛔
       bouton fantôme              blanc                1,09:1  ⛔
       onglet « Service »          blanc à 50 %         1,15:1  ⛔
   APRÈS (mesuré dans Chrome, page entière) : **0 échec**, et 15,95:1 sur les titres.
   ⚠️ Les classes réelles de cette box sont `.bmw-hours-tab` et `.bmw-dloc-name` — pas
   `.hours-tabs__btn` comme dans la bande de contact du pied de page.
   ⛔ Ne JAMAIS reposer l'encre sur un `a` nu ici : le bouton plein « Appelez-nous » n'a pas de
   couleur propre, il héritait — le repeindre en encre sombre le mettait à 1,52:1 sur le bleu de
   marque. Les deux familles de boutons sont donc traitées séparément. */
html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) {
    color: var(--ink, #494949);
}

/* `!important` assumé, après trois tentatives de spécificité le 2026-08-26 : la règle luxe
   `.brand-bmw .box-style-luxury.dloc …` gagne à poids de classes égal et l'ordre de source rend
   la course illisible. Un texte invisible passe avant l'élégance de la cascade. */
html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) :is(.h2, h2, h3, .bmw-dloc-name, .dloc__heading) {
    color: var(--ink-strong, #1a1a1a) !important;
}

html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .footer-contact a {
    color: var(--ink, #494949);
}

/* Bouton plein : le bleu de marque garde son texte inversé (blanc sur #0066b1 = 4,68:1). */
html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .btn:not(.btn--ghost) {
    color: var(--brand-text-inverse, #fff) !important;
}

/* Bouton fantôme : le gabarit sort `btn--on-dark` sans condition, donc une bordure blanche à 55 %
   invisible sur fond clair. On repose texte ET bordure. */
html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .btn--ghost {
    color: var(--ink-strong, #1a1a1a) !important;
    border-color: var(--ink, #494949) !important;
}

html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-tab {
    color: var(--ink, #494949);
}

html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-card,
html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-card * {
    color: var(--ink, #494949) !important;
}

html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-card :is(.bmw-hours-tab.is-active, .bmw-hours-head) {
    color: var(--accent) !important;
}

html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-tab.is-active {
    color: var(--accent);
}

/* La carte des heures avait un fond blanc à 4 % et une bordure blanche à 10 % : invisible sur une
   section claire. On la repose sur une surface qui CONTRASTE avec le fond de sa section — sinon
   elle disparaît de nouveau. ⚠️ `--surface` n'est pas défini sur BMW (vérifié le 2026-08-27, la
   variable rend une chaîne vide) : on nomme les tokens de marque, pas un repli. */
html.brand-bmw .dloc:is(.bg-default, .bg-surface) .bmw-hours-card {
    background: var(--brand-bg-alt, #f4f5f7);
    border-color: var(--line, rgba(0,0,0,.12));
}

html.brand-bmw .dloc.bg-light .bmw-hours-card {
    background: var(--brand-surface, #fff);
    border-color: var(--line, rgba(0,0,0,.12));
}

html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-tabs {
    border-bottom-color: var(--line, rgba(0,0,0,.12));
}

/* Les séparateurs de jours étaient en blanc à 6 % : invisibles sur une carte claire. */
html.brand-bmw .dloc:is(.bg-default, .bg-light, .bg-surface) .bmw-hours-panel li {
    border-bottom-color: var(--line, rgba(0,0,0,.12));
}

/* ⭐ La bande « Contactez-nous » du pied de page ne s'affiche PAS sur une page qui porte déjà une
   box Dealer Location (Jade, 2026-08-26 : « le topfooter dans cette page ne devrait pas être
   affiché ») — les deux répètent la même adresse, le même téléphone et les mêmes heures.
   `:has()` évite de toucher au gabarit du pied de page, qui est global à toutes les pages. */
body:has(.dloc) .footer-contact-band {
    display: none;
}

/* ⛔ CONTRASTE — les « eyebrow » sur section SOMBRE. Relevé par l'audit d'accessibilité du
   2026-08-26 et re-mesuré par moi sur /fr/bmw-grand-klasse : 5 eyebrows en bleu de marque
   #0066b1 sur #1a1a1a → **2,93:1** à 12,48 px, alors que l'AA en demande 4,5:1.
   C'est exactement la même valeur, et la même cause, que « Powered by Nerd Auto » corrigé dans
   theme.css:10926 : le bleu de marque n'est pas lisible sur le sombre. On reprend donc la même
   réponse — la variante CLAIRE du bleu que le thème garde pour ce cas (4,9:1 mesuré là-bas). */
/* ⛔ CONTRASTE sur fond sombre. Les box en `box-style-luxury` posent leurs titres en
   `--ink-strong` (noir) et leur prose en gris : sur une section `bg-dark` (#1a1a1a) ca
   donne du noir sur noir. Mesure sur /fr/bmw-grand-klasse : « LE LUXE SELON BMW » a 1:1
   (invisible), les legendes d'image a 1,93 et 3,27:1, la note de prix a 3,46:1.
   ⚠️ Specificite : `.brand-bmw .box-style-luxury .h2` fait 3 classes et gagnait sur une
   regle a 2 classes ; et `.section.body-color-secondary :is(p, li, .prose…)` de theme.css
   est en `!important`. D'ou les 4 classes ici et le `!important` sur la prose. */
html.brand-bmw .box-style-luxury.bg-dark h2,
html.brand-bmw .box-style-luxury.bg-dark h3,
html.brand-bmw .box-style-luxury.bg-dark h4,
html.brand-bmw .box-style-luxury.bg-dark .h2,
html.brand-bmw .box-style-luxury.bg-dark .h3,
html.brand-bmw .box-style-luxury.bg-dark .h4,
html.brand-bmw .box-style-luxury.bg-inverse h2,
html.brand-bmw .box-style-luxury.bg-inverse h3,
html.brand-bmw .box-style-luxury.bg-inverse h4,
html.brand-bmw .box-style-luxury.bg-inverse .h2,
html.brand-bmw .box-style-luxury.bg-inverse .h3,
html.brand-bmw .box-style-luxury.bg-inverse .h4 {
    color: #fff;
}

/* ⚠️ Cible les corps de texte qui sont VRAIMENT sur le fond sombre, pas ceux des cartes
   posees dessus : `.feat` de value-props a un fond blanc, et une inversion en masse y
   mettait du blanc sur blanc (mesure : 3 textes a 1:1 apres un premier essai trop large). */
html.brand-bmw .bg-dark :is(.text-block__body, .text-image__body, .section-subtitle, .lead),
html.brand-bmw .bg-dark :is(.text-block__body, .text-image__body) :is(p, li),
html.brand-bmw .bg-inverse :is(.text-block__body, .text-image__body, .section-subtitle, .lead),
html.brand-bmw .bg-inverse :is(.text-block__body, .text-image__body) :is(p, li) {
    color: rgba(255, 255, 255, .82) !important;
}

html.brand-bmw .bg-dark .section-eyebrow,
html.brand-bmw .bg-dark .eyebrow,
html.brand-bmw .bg-inverse .section-eyebrow,
html.brand-bmw .bg-inverse .eyebrow,
html.brand-bmw .box-style-luxury.bg-dark [class*="eyebrow"],
html.brand-bmw .box-style-luxury.bg-inverse [class*="eyebrow"] {
    color: var(--brand-accent-light, #7fb9e6);
}

/* Avec `btn-style-outline`, `.btn-primary` perd son fond et laisse #0066b1 sur la photo
   sombre du héros : 3,53:1, sous l'AA. Le bleu clair des eyebrows donne 8,28:1. */
html.brand-bmw.btn-style-outline .hero-section.hero--text-light .btn-primary {
    border-color: var(--brand-accent-light, #7fb9e6);
    color: var(--brand-accent-light, #7fb9e6);
}

html.brand-bmw.btn-style-outline .hero-section.hero--text-light .btn-primary:focus-visible {
    outline-color: var(--brand-accent-light, #7fb9e6);
}

/* Boutons du héros centrés, titre laissé fer a gauche (Jade, 2026-09-02). */
html.brand-bmw .hero-section.hero--align-left .hero__actions {
    justify-content: center;
}

/* ⛔ VDP MODÈLE (luxe) — bandes blanches sur les côtés de la photo principale de la galerie.
   Mesuré : `plugins/nerd/lineup/.../vdp_luxury_styles.htm` cape `.vdp-lux__gallery-main` à
   max-width:720px (voulu : les photos VDM ne font que 640×480, un cap "près du natif" évite
   qu'elles soient agrandies et floues). Mais `.vdp-lux__gallery-thumbs-wrap`, juste en dessous,
   monte lui à 1200px — et la section `.vdp-lux__gallery` entière partage le même fond
   rgb(238,238,238) que la boîte de la photo, donc rien ne distingue visuellement la boîte de
   son fond. Sur un écran ≥1200px ça laisse ~240px de vide gris-quasi-blanc de CHAQUE côté de la
   grande photo contre ~120px pour la bande de vignettes — l'écart est visible et lu comme des
   « bandes blanches sur les côtés ». Ce n'est PAS `object-fit` : les photos sont déjà en 4:3
   natif (640×480 = 4:3 = le ratio du conteneur), `contain` et `cover` y rendent identiquement,
   sans letterbox. On aligne donc la bande de vignettes sur la largeur de la photo (720px) plutôt
   que d'élargir la photo (qui la flouterait, à l'encontre du choix déjà fait). Plugin non
   éditable (Sean, règle Jade 2026-08-25) → surcharge ici ; `!important` nécessaire car le
   <style> du plugin est injecté en ligne dans le <body>, après le <link> de ce fichier dans le
   <head> — à spécificité égale l'ordre de source le fait gagner. */
.brand-bmw .vdp-lux__gallery-thumbs-wrap {
    max-width: 720px !important;
}

/* PROMO DÉTAIL (« Plus d'informations », /fr/promotions/promotion-detail/... ) — la bande de
   titre et la ligne au-dessus du CTA n'ont pas la couleur de marque. Mesuré dans
   `plugins/nerd/marketing/assets/css/detail.css` :
     `.card__detail__header { background-color: var(--primary); }` — `--primary` (Bootstrap 4)
     n'est déclaré NULLE PART dans ce thème (grep theme.css/brands/*.css : 0 résultat), donc la
     bande de titre reste transparente au lieu du bleu BMW.
     `.hl { width: 100px; }` — proportionné à l'ancien thème `theme-nerd2` (article étroit) ;
     minuscule dans celui-ci où la colonne CTA fait ~470px (`col-lg-6`), d'où « la ligne devrait
     prendre toute la largeur ». Le bouton lui-même est déjà centré (flex `justify-content-around`
     à un seul enfant = centré) et déjà stylé marque (`.btn-primary` lit `--brand-accent` dans
     theme.css:1527, pas `--primary`) — seuls la bande et le trait avaient le bug.
   Plugin non éditable (Sean, règle Jade 2026-08-25) → surcharge ici. Spécificité
   `.brand-bmw #myTabContent` (ID) bat `.hl`/`.card__detail__header` seuls, même si
   detail.css charge après ce fichier ({% styles %} sort après le <link> brand dans <head>). */
.brand-bmw .card__detail__header {
    background-color: var(--brand-accent);
    color: var(--brand-text-inverse);
}

.brand-bmw #myTabContent .hl {
    width: 100%;
    margin-left: auto;
    margin-right: auto;
}

/* ==========================================================================
   MODE SOMBRE — remappage des tokens d'encre
   ==========================================================================
   ⛔ DEFAUT MESURE LE 2026-09-03. `.brand-bmw` (ci-dessus) definit `--ink`,
   `--ink-strong`, `--ink-soft` et `--brand-text*` avec la specificite (0,1,0) —
   exactement celle de `.dark-mode` dans theme.css:394. Et brands/bmw.css se
   charge APRES theme.css, donc BMW gagnait toujours : le FOND passait en sombre,
   le TEXTE restait en encre foncee.

   Mesure au style calcule sur /fr, mode sombre force :
       .h2   couleur rgb(26,26,26) sur fond rgb(15,17,23)  ->  1,08:1
       body  idem                                          ->  1,08:1
       .eyebrow rgb(0,102,177) sur le meme fond            ->  3,18:1
   Le seuil AA du texte normal est 4,5:1 (SC 1.4.3). Touchait titres,
   sous-titres, liens, libelles de formulaire et titres d'articles.

   ⭐ On remappe les tokens d'ENCRE, pas seulement `--brand-text*` : 82 regles
   lisent `var(--ink-strong)` et 76 `var(--ink-soft)` directement, donc corriger
   `--brand-text` seul en aurait laisse la majorite au sol.

   Specificite (0,2,0) : gagne sur `.brand-bmw` comme sur `.dark-mode`, sans
   `!important`. Valeurs reprises de `.dark-mode` de theme.css pour que les deux
   couches disent la meme chose.
   ========================================================================== */
.brand-bmw.dark-mode {
    --black: #e8eaf0;
    --ink-strong: #e8eaf0;
    --ink: #a0a6b8;
    --ink-soft: #8b93a7;
    --line: #2a2f3d;

    --brand-text: #e8eaf0;
    --brand-text-secondary: #a0a6b8;
    --brand-text-muted: #8b93a7;
    --brand-border: #2a2f3d;

    /* ⚠️ L'ACCENT AUSSI. Le bleu BMW #0066b1 ne donne que 3,18:1 sur le fond
       sombre #0f1117 — sous le seuil AA de 4,5:1, et `.eyebrow` l'utilise via
       `--brand-accent` (theme.css:803). On reprend le bleu clair DEJA employe
       par ce theme sur fond sombre (`--brand-accent-light`, #7fb9e6, present
       aux lignes 2266-2273 de ce fichier et theme.css:11594) plutot que d'en
       inventer un. ⛔ On ne touche PAS `--brand-primary` : il sert de FOND de
       bouton, l'eclaircir casserait le contraste du texte blanc dessus. */
    --brand-accent: var(--brand-accent-light, #7fb9e6);
}
