/* ==========================================================================
   Le Bidon Malin — Frontend public custom (L3)
   Source de vérité design : custom/Client/LBM/design/HANDOFF.md
   CSP stricte (G2) : zéro CDN, tout le CSS du site vit ici (zéro style inline).
   ========================================================================== */

/* ---------- 1. Design tokens (variables CSS) ---------- */
:root {
    /* Fonds */
    --lbm-paper: #F4F3EE;
    --lbm-surface: #FFFFFF;
    --lbm-surface-alt: #F7F6F1;

    /* Textes */
    --lbm-ink: #1B241F;
    --lbm-text-secondary: #5A6560;
    /* Correctif accessibilité (audit du 18/09/2026) : #6A746D ne tenait que
       4,36:1 sur le fond papier (--lbm-paper) — sous le seuil WCAG AA de
       4,5:1 pour du texte normal. Même teinte, assombrie au minimum
       nécessaire (homothétie RGB, hue inchangée) : 4,56:1 sur papier /
       5,06:1 sur blanc. */
    --lbm-text-muted: #67716A;
    /* Correctif accessibilité (audit du 18/09/2026) : #9AA39D ne tenait que
       2,59:1 sur une carte blanche (prix au litre/au kilo) — assombri sur le
       fond le plus défavorable (papier) pour garantir ≥4,5:1 partout où le
       jeton est utilisé : 4,56:1 sur papier / 5,06:1 sur blanc. */
    --lbm-text-disabled: #6A706C;

    /* Bordures */
    --lbm-border: #E7E6DE;
    --lbm-border-hover: #cdd4cf;

    /* Vert recharge (primaire) */
    --lbm-primary: #1E6B47;
    --lbm-primary-hover: #185A3C;

    /* Vert marque / foncé */
    --lbm-brand-dark: #14401f;
    --lbm-brand-aside: #22513D;
    --lbm-brand-darker: #163A2B;
    --lbm-brand-light-bg: #EAF1EC;
    /* ⚠️ VERT DE MARQUE — NE PAS « CORRIGER » POUR LE CONTRASTE.
       L'audit du 18/09/2026 a relevé que le « MALIN » du logo ne tient que
       2,01:1 sur le fond papier de l'en-tête, loin du seuil WCAG AA de 4,5:1.
       Il a été assombri, puis REMIS à sa valeur d'origine sur décision du
       gérant du 18/09 — et c'est fondé : le critère 1.4.3 de WCAG exempte
       explicitement le texte qui fait partie d'un LOGO ou d'un NOM DE MARQUE.
       « LE BIDON MALIN » à côté de la mascotte est précisément cela.
       Les deux autres écarts relevés par le même audit, eux, ne sont pas
       exemptés et RESTENT corrigés : --lbm-text-disabled (prix au litre) et
       --lbm-text-muted (texte secondaire). */
    --lbm-brand-vivid: #7cbf3f;
    --lbm-brand-text-on-dark: #C7DBCD;

    /* Terracotta */
    --lbm-terracotta: #C26B4A;
    --lbm-terracotta-bg: #FBE9DB;

    /* Rouge pastel — sous-ligne bidon « à résoudre » (question non répondue) */
    --lbm-pending-bg: #FBE3E0;
    --lbm-pending-border: #E8B4AC;
    --lbm-pending-text: #9A4034;
}

/* ---------- 2. Polices locales (zéro CDN, G2) ---------- */
@font-face {
    font-family: 'Bricolage Grotesque';
    src: url('/bundles/clientlbmmoduleboutique/fonts/bricolage-grotesque.woff2') format('woff2');
    font-weight: 500 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Hanken Grotesk';
    src: url('/bundles/clientlbmmoduleboutique/fonts/hanken-grotesk.woff2') format('woff2');
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

/* ---------- 3. Reset & base ---------- */
* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--lbm-paper);
    color: var(--lbm-ink);
    font-family: 'Hanken Grotesk', system-ui, sans-serif;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    margin: 0;
    letter-spacing: -.015em;
    line-height: 1.08;
}

p { margin: 0; }

a { color: inherit; text-decoration: none; }

button { font-family: inherit; }

img { max-width: 100%; display: block; }

/* L'attribut HTML `hidden` doit TOUJOURS l'emporter sur nos règles de mise en
   page. Le navigateur ne le pose qu'en feuille utilisateur-agent (`[hidden] {
   display: none }`, spécificité 0-1-0) : la moindre classe de layout d'auteur
   de même spécificité — `.lbm-auth-row { display: grid }` par exemple — la
   supplantait, et les champs conditionnels rendus `hidden` côté serveur
   (SIRET/TVA réservés aux professionnels) restaient visibles pour tout le
   monde. Le `!important` est ici le seul moyen de garantir cette priorité
   quelles que soient les règles de layout ajoutées ensuite. */
[hidden] { display: none !important; }

:focus-visible {
    outline: 2.5px solid var(--lbm-primary);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Page = colonne pleine hauteur, footer collé en bas (cf. layout.html.twig) */
.lbm-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.lbm-main { flex: 1; }

/* ── Messages flash (bandeau global, cf. layout.html.twig) ──
   Même vocabulaire de classes que l'admin (.lbm-flash / .lbm-flash--<type>)
   pour rester cohérent d'un back-office à l'autre, avec les tokens --lbm-*
   du site public. Zéro style inline (G2 CSP stricte). */
.lbm-flashes {
    max-width: 1180px;
    margin: 0 auto;
    padding: 18px 24px 0;
}

/* Rendu NEUTRE par défaut : sert de repli à tout type inattendu
   (warning, notice…) ajouté un jour par un controller. */
.lbm-flash {
    background: var(--lbm-surface-alt);
    color: var(--lbm-ink);
    border: 1px solid var(--lbm-border);
    border-radius: 10px;
    padding: 12px 16px;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.45;
}

.lbm-flash + .lbm-flash {
    margin-top: 10px;
}

/* Succès (ajout au panier, magic link envoyé, compte supprimé…) */
.lbm-flash--success {
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-primary);
    border-color: var(--lbm-primary);
}

/* Erreur (quota anti-abus dépassé, lien de connexion expiré…) */
.lbm-flash--error {
    background: var(--lbm-terracotta-bg);
    color: var(--lbm-terracotta);
    border-color: var(--lbm-terracotta);
}

/* Information non bloquante (panier vide…) */
.lbm-flash--info {
    background: var(--lbm-surface-alt);
    color: var(--lbm-text-secondary);
    border-color: var(--lbm-border);
}

/* Honeypot anti-spam (GUIDE_FRONTEND_CUSTOM.md §6) — répliqué car ce frontend
   custom n'inclut pas fondation.css. Ne JAMAIS remplacer par un style inline. */
.fondation-honeypot {
    position: absolute !important;
    left: -9999px !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Masquage visuel ACCESSIBLE — jamais `display:none`/`visibility:hidden`, qui
   retireraient le contenu à la fois de l'indexation et des lecteurs d'écran.
   Recherché dans toute la feuille avant création : aucun utilitaire de ce
   type n'existait (le frontend public n'inclut pas fondation.css/Bootstrap,
   ni lien d'évitement). Sert au H1 du catalogue (section 14, SEO). */
.lbm-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ---------- 4. Animation d'entrée (n'anime que la position — jamais l'opacité) ---------- */
@keyframes fadeUp {
    from { transform: translateY(8px); }
    to { transform: none; }
}

.lbm-anim-fadeup { animation: fadeUp .3s ease; }

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
}

/* ==========================================================================
   5. Header (persistant)
   ========================================================================== */
.lbm-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: rgba(244, 243, 238, .86);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--lbm-border);
}

.lbm-header__inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 24px;
    /* 88 px (au lieu de 68) — réglage du gérant du 19/09/2026 : la barre
       paraissait écrasée face au reste de la page. Les quatre valeurs de cette
       barre ont été relevées ENSEMBLE (logo 54, nom 23, menu et boutons 16) :
       n'en changer qu'une la déséquilibre à nouveau. */
    min-height: 88px;
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
}

.lbm-header__brand {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 0;
}

.lbm-header__badge {
    width: 54px;
    height: 54px;
    border-radius: 12px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    display: grid;
    place-items: center;
    flex: none;
    overflow: hidden;
}

.lbm-header__badge img { height: 48px; width: auto; }

.lbm-header__wordmark {
    display: block;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 800;
    font-size: 23px;
    letter-spacing: -.02em;
    line-height: 1;
}

.lbm-header__wordmark-bidon { color: var(--lbm-brand-dark); }
.lbm-header__wordmark-malin { color: var(--lbm-brand-vivid); }

.lbm-header__subtitle {
    display: block;
    font-size: 11px;
    color: var(--lbm-text-muted);
    font-weight: 500;
    margin-top: 1px;
}

.lbm-nav {
    display: flex;
    gap: 3px;
    margin-left: 6px;
    flex-wrap: wrap;
}

/* Rembourrage et rayon ALIGNÉS sur .lbm-btn-account / .lbm-btn-cart (13/15 px,
   rayon 11 px) : taille et graisse étaient déjà identiques, c'est la boîte qui
   différait et faisait paraître le menu rabougri à côté des deux boutons.
   Si l'un des trois change un jour, changer les trois — c'est une seule barre.
   Rembourrage vertical porté de 10 à 13 px (audit accessibilité du
   18/09/2026, cible tactile WCAG ≥44 px) : la boîte du menu ne faisait que
   ~42 px de haut ; celle du panier tombait à 38 px sous 640 px, une fois le
   libellé masqué et l'icône (18 px) seule visible. Rembourrage plutôt que
   texte agrandi, pour ne pas changer la lecture de la barre. */
.lbm-nav__item {
    padding: 13px 15px;
    border-radius: 11px;
    font-weight: 600;
    font-size: 16px;
    border: none;
    background: transparent;
    color: var(--lbm-text-muted);
    transition: .15s;
}

.lbm-nav__item:hover { background: #EFEEE8; }

.lbm-nav__item.is-active {
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-primary);
}

.lbm-header__actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 9px;
}

.lbm-btn-account {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 13px 15px;
    border-radius: 11px;
    font-weight: 600;
    font-size: 16px;
    background: var(--lbm-surface);
    color: var(--lbm-ink);
    border: 1px solid var(--lbm-border);
    transition: .15s;
}

.lbm-btn-account:hover { background: #EFEEE8; }

/* Icône « utilisateur » dessinée en CSS pur (pas d'image, pas de police icône) */
.lbm-btn-account__icon {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1.8px solid var(--lbm-ink);
    position: relative;
    display: inline-block;
    flex: none;
}

.lbm-btn-account__icon::before {
    content: "";
    position: absolute;
    top: 2.5px;
    left: 50%;
    transform: translateX(-50%);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--lbm-ink);
}

.lbm-btn-account__icon::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 12px;
    height: 6px;
    border-radius: 6px 6px 0 0;
    background: var(--lbm-ink);
}

.lbm-btn-cart {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 13px 16px;
    border-radius: 11px;
    font-weight: 600;
    font-size: 16px;
    background: var(--lbm-primary);
    color: #fff;
    border: none;
    transition: .15s;
}

.lbm-btn-cart:hover { background: var(--lbm-primary-hover); }

/* Icône « panier » : SVG écrit directement dans le gabarit (aucun CDN, aucune
   police d'icônes — G2). Le tracé hérite de la couleur du bouton via
   `currentColor`. `flex: none` l'empêche d'être écrasée par le libellé, et elle
   reste seule visible sous 560 px où le libellé est masqué. */
.lbm-btn-cart__icon {
    width: 18px;
    height: 18px;
    flex: none;
    display: block;
}

.lbm-btn-cart__badge {
    position: absolute;
    top: -7px;
    right: -7px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    border-radius: 10px;
    background: var(--lbm-terracotta);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    display: grid;
    place-items: center;
}

/* ==========================================================================
   6. Boutons & badges génériques
   ========================================================================== */
.lbm-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 14px 24px;
    border-radius: 12px;
    font-weight: 700;
    font-size: 16px;
    border: none;
    cursor: pointer;
    transition: .15s;
}

.lbm-btn--primary { background: var(--lbm-primary); color: #fff; }
.lbm-btn--primary:hover { background: var(--lbm-primary-hover); }

.lbm-btn--ghost {
    background: var(--lbm-surface);
    color: var(--lbm-ink);
    border: 1px solid var(--lbm-border);
}
.lbm-btn--ghost:hover { background: #EFEEE8; }

.lbm-btn--light { background: #fff; color: var(--lbm-brand-darker); }

.lbm-badge-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    font-size: 12.5px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--lbm-primary);
    background: var(--lbm-brand-light-bg);
    padding: 7px 13px;
    border-radius: 999px;
}

/* ==========================================================================
   7. Accueil — Hero
   ========================================================================== */
.lbm-hero {
    max-width: 1180px;
    margin: 0 auto;
    padding: 40px 24px 8px;
}

.lbm-hero__grid {
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    gap: 34px;
    align-items: center;
}

/* Accroche du héros : contrairement aux deux autres pastilles du site
   (« Notre démarche », « Questions fréquentes »), qui sont des ÉTIQUETTES et
   restent en capitales, celle-ci est une phrase écrite par le gérant. On lève
   donc la mise en capitales et l'interlettrage du style commun, et on rend
   quelques dixièmes de taille perdus par le passage en bas-de-casse. */
.lbm-hero__badge {
    margin-bottom: 20px;
    text-transform: none;
    letter-spacing: normal;
    font-size: 13.5px;
}

.lbm-hero__title { font-size: clamp(34px, 4.6vw, 54px); font-weight: 800; }

.lbm-hero__text {
    color: var(--lbm-text-secondary);
    font-size: 17.5px;
    margin: 18px 0 28px;
    max-width: 40ch;
}

.lbm-hero__actions { display: flex; gap: 12px; flex-wrap: wrap; }

.lbm-hero__args {
    display: flex;
    gap: 22px;
    margin-top: 30px;
    flex-wrap: wrap;
}

.lbm-hero__arg {
    font-size: 14px;
    color: var(--lbm-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.lbm-hero__arg-check { color: var(--lbm-primary); font-weight: 700; }

/* Cadre du bandeau — 3 / 2, LE FORMAT DES VISUELS DU GÉRANT.
   Le cadre suit la façon dont les images sont fabriquées, jamais l'inverse :
   le gérant dépose des visuels produit en paysage 3:2 (ex. 1024 × 683), dont
   la composition est pensée pour cette largeur — logo « FABRICATION
   FRANÇAISE » dans l'angle, produits au centre-droit, scène étalée.
   L'ancien cadre 4 / 3.4 (≈ 1,18, presque carré) faisait rogner à `cover`
   ~11 % de CHAQUE côté : le logo, qui est un argument commercial, y perdait
   ses premières lettres. En 3 / 2, une image 3:2 entre INTÉGRALEMENT.
   Contrepartie assumée : le bandeau est plus bas à largeur égale, et le
   contenu qui suit remonte d'autant. */
.lbm-hero__media {
    aspect-ratio: 3 / 2;
    border-radius: 22px;
    position: relative;
    overflow: hidden;
    box-shadow: 0 20px 50px rgba(22, 58, 43, .18);
    border: 1px solid var(--lbm-border);
}

/* `cover` garantit un cadre TOUJOURS rempli (jamais de bande vide, quel que
   soit le fichier déposé). Sur une image déjà en 3:2 il ne rogne rien, et
   `object-position` n'a alors aucun effet : ce réglage ne sert donc qu'aux
   images HORS format.
   Le cas concret est l'image livrée avec le code (bottles.png, 730 × 630,
   presque carrée) : plus haute que le cadre, elle perd ~23 % de sa hauteur.
   On ancre HAUT (15 %) parce que les visuels de cette marque placent en haut
   ce qui porte le message — logo « FABRICATION FRANÇAISE », bouchons et
   étiquettes des bidons — et en bas le seul décor (plan de travail, linge).
   Le 30 % hérité du cadre presque carré tranchait le logo en deux ; à 15 %
   il reste entier et les bidons vont du bouchon à la mention « 5 L ». */
.lbm-hero__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 15%;
}

/* ==========================================================================
   8. Accueil — Concept en 4 étapes
   ========================================================================== */
.lbm-steps-section {
    max-width: 1180px;
    margin: 0 auto;
    padding: 44px 24px;
}

.lbm-steps-card {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 20px;
    padding: 34px;
}

.lbm-steps-card h2 { font-size: 25px; text-align: center; }

.lbm-steps-card__intro {
    text-align: center;
    color: var(--lbm-text-muted);
    margin: 6px 0 28px;
}

.lbm-steps-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
}

/* Carte d'étape ILLUSTRÉE (lot 29, R7 — décision client D1 du 19/09/2026).
   L'image occupe le haut de la carte, le texte le bas, et un dégradé assure la
   transition de l'une à l'autre. Hauteur FIXE : les quatre illustrations n'ont
   pas exactement le même cadrage, et sans hauteur commune les quatre cartes
   d'une même rangée ne s'alignaient plus. */
.lbm-step {
    position: relative;
    height: 290px;
    border-radius: 14px;
    background: var(--lbm-surface-alt);
    overflow: hidden;
    text-align: center;
}

/* `contain` et NON `cover` : ces illustrations sont des objets détourés (un
   bidon, une main qui remplit). Les rogner pour remplir le cadre couperait le
   sujet lui-même — c'est tout ce qu'il y a à voir. Le léger débord par le haut
   (-6px) reprend le cadrage de la maquette et rattrape la marge blanche des
   fichiers fournis. */
.lbm-step__img {
    position: absolute;
    top: -6px;
    left: 0;
    width: 100%;
    height: 210px;
    object-fit: contain;
}

/* Le texte repose sur un dégradé qui part du fond de la carte : l'illustration
   se fond dedans au lieu d'être coupée net. La couleur de départ est la
   couleur de la carte RENDUE TRANSPARENTE (color-mix) — surtout pas un gris
   écrit en dur, qui trahirait le jeton au premier changement de charte. */
.lbm-step__body {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 44px 14px 18px;
    background: linear-gradient(
        to bottom,
        color-mix(in srgb, var(--lbm-surface-alt), transparent 100%) 0%,
        var(--lbm-surface-alt) 34%,
        var(--lbm-surface-alt) 100%
    );
}

.lbm-step__num {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--lbm-primary);
    color: #fff;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    display: grid;
    place-items: center;
    margin: 0 auto 9px;
    font-size: 14.5px;
}

.lbm-step__title {
    display: block;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-size: 15.5px;
    margin-bottom: 3px;
}

.lbm-step__sub { color: var(--lbm-text-muted); font-size: 13px; }

.lbm-step__price {
    margin-top: 7px;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    color: var(--lbm-terracotta);
    font-size: 14px;
}

/* ==========================================================================
   9. Accueil — Best-sellers
   ========================================================================== */
.lbm-bestsellers {
    max-width: 1180px;
    margin: 0 auto;
    padding: 8px 24px 50px;
}

.lbm-section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 20px;
    gap: 12px;
    flex-wrap: wrap;
}

.lbm-section-head h2 { font-size: 25px; }

.lbm-link-arrow {
    color: var(--lbm-primary);
    font-weight: 700;
    font-size: 15px;
}

.lbm-link-arrow:hover { text-decoration: underline; }

.lbm-product-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 18px;
}

/* ==========================================================================
   10. Composant — Carte produit (templates/site/_product_card.html.twig)
   ========================================================================== */
.lbm-product-card {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    padding: 16px;
    display: flex;
    flex-direction: column;
    /* Largeur pleine ET hauteur étirée (§12, correctif du 18/09/2026) : la
       carte est désormais l'enfant flex de `.lbm-catalogue__item` (ci-dessus),
       qui l'étire déjà en hauteur par défaut (align-items: stretch) — mais un
       enfant flex ne prend PAS sa pleine largeur par défaut (axe principal),
       d'où ce `width: 100%` explicite pour retrouver le plein format de
       cellule qu'avait la carte quand son parent était un bloc ordinaire. */
    width: 100%;
    transition: .15s;
}

.lbm-product-card:hover {
    border-color: var(--lbm-border-hover);
    transform: translateY(-2px);
}

.lbm-product-card__media {
    /* Format portrait 3/4 pour adapter le cadre aux photos produit réelles
       (bidons verticaux au format ~3:4 sur fond blanc, photos fournisseur standardisées).
       object-fit: contain préserve l'intégrité visuelle. */
    aspect-ratio: 3 / 4;
    border-radius: 11px;
    background: var(--lbm-surface);
    display: grid;
    place-items: center;
    margin-bottom: 13px;
    position: relative;
    overflow: hidden;
}

.lbm-product-card__media img {
    width: 100%;
    height: 100%;
    /* Produit visible en entier (contain) — vignette catalogue.
       Le gérant téléverse des photos aux proportions libres ;
       cover rognerait le bidon/flacon ; contain préserve l'intégrité visuelle. */
    object-fit: contain;
}

.lbm-product-card__tag {
    position: absolute;
    top: 9px;
    left: 9px;
    color: #fff;
    font-weight: 700;
    font-size: 10px;
    padding: 3px 8px;
    border-radius: 7px;
    letter-spacing: .03em;
    z-index: 1;
}

.lbm-product-card__tag--nouveau { background: var(--lbm-primary); }
.lbm-product-card__tag--premium { background: var(--lbm-terracotta); }

/* Bandeau « Recharge » (lot du 18/09/2026) : coin haut-droit de la vignette,
   en travers, produits `hasBidon` (contenant réutilisable proposé). Rogné par
   `.lbm-product-card__media` (overflow: hidden, ci-dessus) — jamais de
   débordement hors carte. Vert primaire volontairement (couleur "recharge"
   de la charte) ; la FORME (bandeau en travers) le distingue du tag NOUVEAU
   (pastille) au même vert, cf. tests/auto.md pour la validation à l'œil. */
.lbm-product-card__ribbon {
    position: absolute;
    top: 14px;
    right: -34px;
    transform: rotate(45deg);
    background: var(--lbm-primary);
    color: #fff;
    font-weight: 700;
    font-size: 10px;
    letter-spacing: .03em;
    padding: 3px 36px;
    text-align: center;
    z-index: 1;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
}

/* Placeholder « bidon » dessiné en CSS (vignette produit absente) */
.lbm-bottle {
    width: 50px;
    height: 70px;
    background: var(--lbm-surface);
    border: 2px solid #e3e6e2;
    border-radius: 7px 7px 8px 8px;
    position: relative;
}

.lbm-bottle__cap {
    position: absolute;
    top: -8px;
    left: 50%;
    transform: translateX(-50%);
    width: 18px;
    height: 9px;
    background: var(--lbm-surface);
    border: 2px solid #e3e6e2;
    border-bottom: none;
    border-radius: 4px 4px 0 0;
}

/* Couleur de fond posée en JS depuis data-label-color (cf. lbm-site.js) —
   jamais en style="" inline. Une couleur neutre de repli évite le flash FOUC. */
.lbm-bottle__label {
    position: absolute;
    left: 5px;
    right: 5px;
    bottom: 8px;
    height: 32px;
    border-radius: 4px;
    display: grid;
    place-items: center;
    font-size: 7.5px;
    font-weight: 700;
    color: #fff;
    text-align: center;
    line-height: 1.05;
    letter-spacing: .02em;
    background: var(--lbm-text-disabled);
}

.lbm-product-card__title { font-size: 15.5px; font-weight: 700; }

/* Hauteur STABLE (§12, correctif du 18/09/2026) : la troncature à 90
   caractères (cf. gabarit) limite déjà le TEXTE, mais un compte de caractères
   ne garantit pas un compte de LIGNES — deux descriptions à 90 caractères
   peuvent occuper 2 ou 3 lignes selon les mots. `line-clamp` fixe le nombre
   de lignes affichées ; une description absente ou courte ne raccourcit plus
   la carte (elle reste dans son emplacement, vide), une longue ne l'allonge
   plus (coupée avec une ellipse). */
.lbm-product-card__desc {
    color: var(--lbm-text-muted);
    font-size: 12.5px;
    margin: 3px 0 13px;
    flex: 1;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

/* Le média + titre + description mènent à la fiche (le pied en est exclu). */
.lbm-product-card__link {
    display: flex;
    flex-direction: column;
    flex: 1;
    color: inherit;
    text-decoration: none;
}

.lbm-product-card__foot {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
}

.lbm-product-card__pricing {
    display: flex;
    align-items: baseline;
    gap: 6px;
    /* nowrap (§12, correctif du 18/09/2026) : le prix catalogue barré d'un
       membre CE remisé doit rester sur la MÊME ligne que le prix net, sous
       peine d'ajouter une ligne — donc de la hauteur — aux seules cartes
       remisées, et de désaligner à nouveau leur pied par rapport à une carte
       non remisée de la même rangée. Le prix barré est réduit ci-dessous pour
       que le tout tienne large sur la largeur d'une carte (prix courts, deux
       à quatre chiffres). */
    flex-wrap: nowrap;
}

.lbm-product-card__pricing .lbm-price-old {
    font-size: 12.5px;
    white-space: nowrap;
}

/* Ligne quick-add : stepper quantité + bouton « Ajouter » (occupe le reste). */
.lbm-quick-add {
    display: flex;
    align-items: center;
    gap: 8px;
}

.lbm-qty {
    display: flex;
    align-items: center;
    border: 1px solid var(--lbm-border);
    border-radius: 9px;
    overflow: hidden;
    flex: none;
}

.lbm-qty__btn {
    width: 28px;
    height: 32px;
    border: none;
    background: var(--lbm-surface);
    color: var(--lbm-ink);
    font-size: 16px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.lbm-qty__btn:hover {
    background: var(--lbm-surface-alt);
}

.lbm-qty__input {
    width: 34px;
    height: 32px;
    border: none;
    border-left: 1px solid var(--lbm-border);
    border-right: 1px solid var(--lbm-border);
    text-align: center;
    font-size: 13px;
    color: var(--lbm-ink);
    background: var(--lbm-surface);
    -moz-appearance: textfield;
    appearance: textfield;
}

/* Masque les flèches natives du input number (Chrome/Safari). */
.lbm-qty__input::-webkit-outer-spin-button,
.lbm-qty__input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.lbm-product-card__price-from { font-size: 11px; color: var(--lbm-text-muted); }

.lbm-product-card__price {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-size: 18px;
}

.lbm-product-card__per-liter {
    display: block;
    font-size: 11px;
    color: var(--lbm-text-disabled);
    margin-top: 1px;
}

/* Rembourrage vertical porté de 9 à 13 px (audit accessibilité du
   18/09/2026, cible tactile WCAG ≥44 px) : le bouton ne faisait que ~36 px de
   haut. Rembourrage plutôt que texte agrandi (13,5 px conservé) pour ne pas
   déformer la ligne quick-add (stepper + bouton, alignés en `center`). */
.lbm-product-card__add {
    flex: 1;
    padding: 13px 13px;
    border-radius: 10px;
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-primary);
    font-weight: 700;
    font-size: 13.5px;
    border: none;
    cursor: pointer;
    transition: .15s;
}

.lbm-product-card__add:hover { background: var(--lbm-primary); color: #fff; }

/* ==========================================================================
   11. Concept (page /concept)
   ========================================================================== */
/* Largeur alignée sur le reste du site (1180 px : en-tête, accueil, boutique).
   Elle était seule à 900 px, ce qui se voyait en passant d'une page à l'autre —
   le contenu « sautait » en largeur. Ne pas la remettre à une valeur isolée :
   si un bloc de texte devient trop large à lire, c'est CE bloc qu'on borne
   (mesure de lecture), pas le conteneur de la page. */
.lbm-concept {
    max-width: 1180px;
    margin: 0 auto;
    padding: 48px 24px 60px;
}

.lbm-concept__badge { margin-bottom: 18px; }

.lbm-concept__title {
    font-size: clamp(30px, 4vw, 44px);
    font-weight: 800;
    max-width: 18ch;
}

.lbm-concept__intro {
    color: var(--lbm-text-secondary);
    font-size: 18px;
    margin: 18px 0 0;
    max-width: 60ch;
}

.lbm-stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin: 36px 0;
}

.lbm-stat-card {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    /* overflow: hidden fait épouser à l'image les angles arrondis de la
       carte (lot 31) ; le padding ne vaut plus que pour le texte, l'image
       allant jusqu'aux bords. */
    overflow: hidden;
    padding: 0 0 24px;
}

/* Visuel des trois cartes (lot 31, R2) : MÊME rapport et MÊME cadrage pour
   les trois, quelle que soit l'image que le gérant dépose plus tard depuis
   « Apparence » — c'est ce qui garantit que les cartes restent alignées. */
.lbm-stat-card__img {
    display: block;
    width: 100%;
    /* `height: auto` est INDISPENSABLE, ce n'est pas une précaution de style :
       les attributs `width`/`height` de la balise (posés pour réserver la place
       et éviter que la page ne saute) sont traduits par le navigateur en
       hauteur EFFECTIVE. Sans cette ligne, l'image gardait ses 292 px de haut,
       `aspect-ratio` était ignoré — il ne s'applique que si une dimension est
       `auto` — et `object-fit: cover` rognait les côtés : le drapeau perdait
       ses marges, les trois cartes n'avaient plus la bonne proportion.
       Le cas ne se pose PAS pour les autres cadres du site (.lbm-hero__media,
       .lbm-atelier__frame…) : là, le rapport est porté par le conteneur, qui
       n'a pas d'attribut de dimension. */
    height: auto;
    aspect-ratio: 2.4 / 1;
    object-fit: cover;
}

/* Chiffre et libellé sur la MÊME LIGNE (réglage du gérant du 19/09/2026) :
   empilés, ils laissaient un blanc au milieu de la carte et le regard
   décrochait entre les deux. Alignés sur la LIGNE DE BASE plutôt que centrés :
   le chiffre fait 34 px, le libellé 14,5 px — un centrage vertical ferait
   flotter le petit texte au milieu du grand. Le libellé prend la place
   restante et se replie sur deux ou trois lignes sans pousser le chiffre. */
.lbm-stat-card__text {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin-top: 18px;
    padding: 0 24px;
}

.lbm-stat-card__big {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 800;
    font-size: 29px;
    color: var(--lbm-primary);
    /* Le chiffre ne se replie jamais et ne rétrécit pas : c'est lui qu'on lit
       en premier, le libellé s'adapte autour. */
    flex: none;
    white-space: nowrap;
    /* Largeur PLANCHER commune aux trois cartes, pour que les libellés
       démarrent tous à la même distance du bord : « 62 » est deux fois plus
       court que « 100 % », et sans ce plancher son libellé partait seul vers
       la gauche — les trois cartes se lisant côte à côte, le décalage sautait
       aux yeux. Plancher et non largeur fixe : un compteur à trois chiffres
       pousse simplement le libellé, il ne déborde pas. */
    min-width: 94px;
}

.lbm-stat-card__sub {
    color: var(--lbm-text-secondary);
    font-size: 14.5px;
    line-height: 1.35;
}

/* Concept — écart avant la bannière CTA. Le bloc « 4 étapes » partagé
   (.lbm-steps-card, cf. section 8) n'a pas de marge propre : c'était
   .lbm-cycle-card qui la portait avant sa fusion avec l'accueil
   (lot du 18/09/2026). */
.lbm-cycle-wrap { margin-bottom: 30px; }

.lbm-cta-banner {
    display: flex;
    gap: 14px;
    align-items: center;
    background: var(--lbm-brand-aside);
    color: #fff;
    border-radius: 20px;
    padding: 28px 32px;
    flex-wrap: wrap;
}

.lbm-cta-banner__text { flex: 1; min-width: 240px; }
.lbm-cta-banner__text h3 { font-size: 21px; color: #fff; }
.lbm-cta-banner__text p { color: var(--lbm-brand-text-on-dark); margin-top: 6px; font-size: 15px; }

/* ==========================================================================
   12. Footer (persistant)
   ========================================================================== */
.lbm-footer {
    border-top: 1px solid var(--lbm-border);
    background: var(--lbm-surface);
    margin-top: auto;
}

.lbm-footer__inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 26px 24px;
    display: flex;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    color: var(--lbm-text-muted);
    font-size: 13.5px;
}

/* ==========================================================================
   14. Catalogue (/catalogue) — HANDOFF.md écran 3 « cat »
   ========================================================================== */
.lbm-catalogue {
    max-width: 1180px;
    margin: 0 auto;
    padding: 44px 24px 56px;
}

/* Bandeau CE (lot 26, §12, D12.3) : rouge pastel — réutilise les tokens
   --lbm-pending-* déjà posés pour la sous-ligne « bidon à résoudre » du
   panier plutôt qu'une teinte inventée (contraste déjà éprouvé, ~5.4:1). */
.lbm-ce-notice {
    margin-bottom: 20px;
    padding: 14px 18px;
    border: 1.5px solid var(--lbm-pending-border);
    border-radius: 13px;
    background: var(--lbm-pending-bg);
    color: var(--lbm-pending-text);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
}

.lbm-catalogue__title { font-size: 34px; font-weight: 800; }

/* Chips + recherche sur UNE ligne, alignées (retouche visuelle du 18/09/2026) :
   le H1 (masqué, cf. .lbm-sr-only) et le compte de références ne sont plus
   affichés, `.lbm-chips` prend l'espace disponible et `.lbm-search` reste à
   sa taille propre. `flex-wrap` fait passer la recherche sur sa propre ligne
   sous une largeur de téléphone plutôt que de déborder. */
.lbm-catalogue__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 26px;
}

.lbm-catalogue__toolbar .lbm-chips {
    flex: 1 1 auto;
    margin-bottom: 0;
}

.lbm-catalogue__toolbar .lbm-search {
    flex: 0 0 auto;
}

.lbm-search { position: relative; }

.lbm-search__icon {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--lbm-text-disabled);
    pointer-events: none;
}

.lbm-search__input {
    width: 280px;
    max-width: 60vw;
    padding: 12px 14px 12px 36px;
    border: 1px solid var(--lbm-border);
    border-radius: 12px;
    font-size: 14.5px;
    background: var(--lbm-surface);
    color: var(--lbm-ink);
}

.lbm-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 26px;
}

.lbm-chip {
    padding: 8px 15px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 13.5px;
    cursor: pointer;
    transition: .15s;
    border: 1px solid var(--lbm-border);
    background: var(--lbm-surface);
    color: var(--lbm-ink);
}

.lbm-chip:hover { border-color: var(--lbm-border-hover); }

.lbm-chip.is-active {
    background: var(--lbm-ink);
    color: #fff;
    border-color: var(--lbm-ink);
}

/* Wrapper de filtrage JS (data-name/data-desc/data-cat) autour de la carte produit */
/* Cellule de grille du catalogue (§12, correctif du 18/09/2026) : `display:
   flex` fait que la carte à l'intérieur (son unique enfant) s'étire sur toute
   la hauteur de la cellule — déjà étirée par le comportement PAR DÉFAUT de
   `.lbm-product-grid` (grid, align-items: stretch). Sans ce `flex`, la carte
   ne prenait que sa hauteur de contenu et « flottait » en haut d'une cellule
   pourtant déjà de la bonne hauteur : deux fiches de contenus différents dans
   la même rangée semblaient alors de hauteurs différentes. */
.lbm-catalogue__item {
    display: flex;
}

.lbm-catalogue__item[hidden] { display: none; }

.lbm-catalogue__empty {
    text-align: center;
    padding: 60px;
    color: var(--lbm-text-muted);
}

/* ==========================================================================
   15. Fiche produit (/produit/{slug}) — HANDOFF.md écran 4 « fiche »
   ========================================================================== */
.lbm-product {
    max-width: 1100px;
    margin: 0 auto;
    padding: 30px 24px 60px;
}

.lbm-product__breadcrumb {
    font-size: 13.5px;
    color: var(--lbm-text-muted);
    margin-bottom: 18px;
}

.lbm-product__breadcrumb a { text-decoration: underline; }

.lbm-product__grid {
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: 40px;
    align-items: start;
}

.lbm-product__media {
    /* Format portrait 3/4 pour adapter le cadre aux photos produit réelles
       (bidons verticaux au format ~3:4 sur fond blanc, photos fournisseur standardisées).
       object-fit: contain préserve l'intégrité visuelle. */
    aspect-ratio: 3 / 4;
    border-radius: 20px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    display: grid;
    place-items: center;
    position: relative;
    overflow: hidden;
}

/* Bandeau « Recharge » de la fiche produit — même principe que la carte
   (.lbm-product-card__ribbon), agrandi pour le visuel plus grand de la fiche.
   Rogné par `overflow: hidden` ci-dessus, jamais de débordement hors cadre. */
.lbm-product__ribbon {
    position: absolute;
    top: 20px;
    right: -46px;
    transform: rotate(45deg);
    background: var(--lbm-primary);
    color: #fff;
    font-weight: 700;
    font-size: 13px;
    letter-spacing: .03em;
    padding: 5px 54px;
    text-align: center;
    z-index: 1;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
}

.lbm-product__media img {
    width: 100%;
    height: 100%;
    /* Produit visible en entier (contain) — fiche produit.
       Le gérant téléverse des photos aux proportions libres ;
       cover rognerait le bidon/flacon ; contain préserve l'intégrité visuelle. */
    object-fit: contain;
}

/* Placeholder « bidon » agrandi pour la fiche (variante de .lbm-bottle) */
.lbm-bottle--large {
    width: 140px;
    height: 200px;
    border-width: 2.5px;
    border-radius: 11px 11px 13px 13px;
}

.lbm-bottle--large .lbm-bottle__cap {
    width: 42px;
    height: 17px;
    top: -15px;
    border-width: 2.5px;
    border-radius: 7px 7px 0 0;
}

.lbm-bottle__label--large {
    left: 14px;
    right: 14px;
    bottom: 26px;
    height: 80px;
    border-radius: 7px;
    font-size: 15px;
}

.lbm-product__tag {
    display: inline-block;
    color: #fff;
    font-weight: 700;
    font-size: 11px;
    padding: 4px 10px;
    border-radius: 7px;
    margin-bottom: 12px;
    letter-spacing: .03em;
}

.lbm-product__tag--nouveau { background: var(--lbm-primary); }
.lbm-product__tag--premium { background: var(--lbm-terracotta); }

.lbm-product__name { font-size: 32px; font-weight: 800; margin-bottom: 7px; }

.lbm-product__desc {
    color: var(--lbm-text-secondary);
    font-size: 16px;
    margin-bottom: 24px;
}

.lbm-option-group { margin-bottom: 22px; }

.lbm-option-group__label {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--lbm-text-muted);
    margin-bottom: 10px;
}

.lbm-option-group__values { display: flex; gap: 9px; flex-wrap: wrap; }

.lbm-variant-btn {
    padding: 11px 16px;
    border-radius: 11px;
    background: var(--lbm-surface);
    border: 1.5px solid var(--lbm-border);
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    text-align: left;
    transition: .12s;
    color: var(--lbm-ink);
}

.lbm-variant-btn small {
    display: block;
    font-weight: 500;
    color: var(--lbm-text-muted);
    font-size: 12px;
}

.lbm-variant-btn.is-selected {
    background: var(--lbm-brand-light-bg);
    border-color: var(--lbm-primary);
}

/* Mention « produit vendu en recharge » sur la fiche (le choix bidon se fait au panier) */
.lbm-product__recharge-note {
    padding: 12px 15px;
    border: 1.5px dashed var(--lbm-border-hover);
    border-radius: 12px;
    background: var(--lbm-surface-alt);
    color: var(--lbm-text-secondary);
    font-size: 13.5px;
    margin-bottom: 22px;
}

.lbm-qty { margin-bottom: 6px; }

.lbm-qty__label {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--lbm-text-muted);
    margin-bottom: 10px;
}

.lbm-qty__stepper {
    display: flex;
    align-items: center;
    border: 1.5px solid var(--lbm-border);
    border-radius: 12px;
    overflow: hidden;
    width: fit-content;
}

.lbm-qty__btn {
    width: 44px;
    height: 48px;
    font-size: 21px;
    font-weight: 700;
    color: var(--lbm-ink);
    background: var(--lbm-surface);
    border: none;
    cursor: pointer;
}

.lbm-qty__value {
    width: 56px;
    height: 48px;
    display: grid;
    place-items: center;
    border-left: 1.5px solid var(--lbm-border);
    border-right: 1.5px solid var(--lbm-border);
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 17px;
}

.lbm-product__total-row {
    display: flex;
    align-items: center;
    gap: 20px;
    margin-top: 26px;
    padding-top: 22px;
    border-top: 1px solid var(--lbm-border);
    flex-wrap: wrap;
}

.lbm-product__total { font-family: 'Bricolage Grotesque', system-ui, sans-serif; }

.lbm-product__total small {
    display: block;
    font-size: 12px;
    color: var(--lbm-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
}

.lbm-product__total b { font-size: 30px; font-weight: 800; }

/* Prix au litre de la variante sélectionnée (arrêté 16/11/1999) — discret. */
.lbm-product__per-litre {
    display: block;
    font-size: 12px;
    color: var(--lbm-text-muted);
    margin-top: 2px;
}

/* Mention « prix nets — franchise TVA 293 B » sous le total (discrète). */
.lbm-product__tva-note {
    font-size: 11.5px;
    color: var(--lbm-text-disabled);
    margin: 10px 0 0;
}

/* Bloc délai de récupération (retrait / livraison 48 h). */
.lbm-product__delivery-info {
    margin-top: 16px;
    padding: 12px 14px;
    border-radius: 12px;
    background: var(--lbm-surface-alt, #f4f6f2);
    font-size: 13px;
    color: var(--lbm-text-secondary);
}

.lbm-product__section {
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid var(--lbm-border);
}

.lbm-product__section h2 { font-size: 18px; margin-bottom: 10px; }

.lbm-product__section p {
    color: var(--lbm-text-secondary);
    font-size: 14.5px;
}

.lbm-product__fds-link {
    display: inline-block;
    margin-top: 22px;
    color: var(--lbm-primary);
    font-weight: 700;
    font-size: 14px;
    text-decoration: underline;
}

/* Section « Sécurité — Dangers (CLP) » — affichage obligatoire des dangers
   d'un mélange vendu en ligne (CLP art. 48 §2, LEGAL.md §4-N). */
.lbm-clp__signal {
    display: inline-block;
    margin-bottom: 12px;
    padding: 6px 14px;
    border-radius: 4px;
    font-weight: 800;
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* « Danger » : rouge terracotta soutenu (niveau de gravité le plus élevé). */
.lbm-clp__signal--danger {
    background: #9A2E22;
    color: #FFFFFF;
}

.lbm-clp__hazards {
    margin: 4px 0 14px;
    padding-left: 18px;
    list-style: disc;
}

.lbm-clp__hazard {
    margin-bottom: 6px;
    color: var(--lbm-text-secondary);
    font-size: 14.5px;
}

.lbm-clp__hazard b { color: var(--lbm-ink); }

.lbm-clp__note {
    color: var(--lbm-text-muted);
    font-size: 13.5px;
    font-style: italic;
}

.lbm-clp__unclassified {
    color: var(--lbm-text-secondary);
    font-size: 14.5px;
}

/* ==========================================================================
   17. Panier (/panier) — HANDOFF.md écran 5 « cart »
   ========================================================================== */
.lbm-cart {
    max-width: 1100px;
    margin: 0 auto;
    padding: 30px 24px 60px;
}

.lbm-cart__title {
    font-size: 32px;
    font-weight: 800;
    margin-bottom: 22px;
}

.lbm-cart__grid {
    display: grid;
    grid-template-columns: 1fr 330px;
    gap: 28px;
    align-items: start;
}

.lbm-cart__list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.lbm-cart-line {
    display: flex;
    align-items: center;
    gap: 16px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    padding: 14px 16px;
    flex-wrap: wrap;
}

.lbm-cart-line__media {
    width: 60px;
    height: 60px;
    flex: none;
    border-radius: 11px;
    background: var(--lbm-surface-alt);
    display: grid;
    place-items: center;
    overflow: hidden;
}

.lbm-cart-line__media img {
    width: 100%;
    height: 100%;
    /* Produit visible en entier (contain) — miniature panier.
       Le gérant téléverse des photos aux proportions libres ;
       cover rognerait le bidon/flacon ; contain préserve l'intégrité visuelle. */
    object-fit: contain;
}

.lbm-cart-line__media .lbm-bottle {
    width: 34px;
    height: 48px;
}

.lbm-cart-line__media .lbm-bottle__cap {
    width: 13px;
    height: 6px;
    top: -6px;
}

.lbm-cart-line__media .lbm-bottle__label {
    height: 22px;
    font-size: 6px;
    bottom: 5px;
}

.lbm-cart-line__info { flex: 1; min-width: 160px; }

.lbm-cart-line__name { font-weight: 700; font-size: 15px; }

.lbm-cart-line__variant {
    color: var(--lbm-text-muted);
    font-size: 13px;
    margin-top: 2px;
}

.lbm-cart-line__stepper-form { flex: none; }

.lbm-cart-line__total {
    flex: none;
    width: 90px;
    text-align: right;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 17px;
}

.lbm-cart-line__remove-form { flex: none; }

.lbm-cart-line__remove {
    background: none;
    border: none;
    color: var(--lbm-text-muted);
    font-size: 13px;
    font-weight: 600;
    text-decoration: underline;
    cursor: pointer;
    padding: 0;
}

.lbm-cart-line__remove:hover { color: var(--lbm-terracotta); }

/* ---------- Groupe « ligne produit + sous-ligne bidon » ---------- */
.lbm-cart-item {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Sous-ligne « Bidon réutilisable » (produits vendus en recharge) — L-bidon */
.lbm-cart-bidon {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-left: 24px;
    padding: 12px 16px;
    border: 1.5px solid var(--lbm-border);
    border-radius: 13px;
    background: var(--lbm-surface);
}

/* État « à résoudre » : fond rouge pastel tant que le client n'a pas répondu. */
.lbm-cart-bidon.is-pending {
    background: var(--lbm-pending-bg);
    border-color: var(--lbm-pending-border);
}

.lbm-cart-bidon.is-pending .lbm-cart-bidon__title { color: var(--lbm-pending-text); }

/* État « own » : neutre (aucun bidon facturé). */
.lbm-cart-bidon.is-own {
    background: var(--lbm-surface-alt);
    border-color: var(--lbm-border);
}

/* État « buy » : vert (réutilise les tokens de marque), surcoût affiché. */
.lbm-cart-bidon.is-buy {
    background: var(--lbm-brand-light-bg);
    border-color: var(--lbm-primary);
}

.lbm-cart-bidon__label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 180px;
}

.lbm-cart-bidon__title {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 14px;
}

.lbm-cart-bidon__question {
    color: var(--lbm-text-muted);
    font-size: 12.5px;
}

.lbm-cart-bidon__status {
    margin-top: 2px;
    font-weight: 700;
    font-size: 13px;
    color: var(--lbm-primary);
}

.lbm-cart-bidon__actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.lbm-cart-bidon__actions form { margin: 0; }

.lbm-cart-bidon__btn {
    padding: 9px 14px;
    border: 1.5px solid var(--lbm-border);
    border-radius: 10px;
    background: var(--lbm-surface);
    color: var(--lbm-ink);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: .12s;
}

.lbm-cart-bidon__btn:hover { border-color: var(--lbm-border-hover); }

.lbm-cart-bidon__btn.is-active {
    border-color: var(--lbm-primary);
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-primary-hover);
}

.lbm-cart-bidon__btn--buy {
    color: var(--lbm-primary-hover);
    border-color: var(--lbm-primary);
}

.lbm-cart-bidon__btn--buy.is-active {
    background: var(--lbm-primary);
    color: #fff;
}

/* Ligne agrégée « Bidons réutilisables » — somme de tous les bidons achetés */
.lbm-cart-bidon-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 4px;
    padding: 14px 16px;
    border: 1.5px solid var(--lbm-primary);
    border-radius: 16px;
    background: var(--lbm-brand-light-bg);
}

.lbm-cart-bidon-summary__label {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.lbm-cart-bidon-summary__title {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 15px;
}

.lbm-cart-bidon-summary__detail {
    color: var(--lbm-text-muted);
    font-size: 12.5px;
}

.lbm-cart-bidon-summary__total {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 700;
    font-size: 17px;
    color: var(--lbm-primary);
}

/* Bouton « Continuer mes achats », bas de colonne gauche (lot 23a) — réutilise
   .lbm-btn-cart telle quelle (C.12, zéro duplication) ; seul ajustement propre
   à ce contexte : la colonne .lbm-cart__list est un flex column qui stretch
   ses enfants par défaut, d'où cet align-self pour garder la largeur naturelle
   du bouton et l'aligner à gauche. .lbm-btn-cart (bouton panier de l'en-tête)
   n'est pas modifiée. */
.lbm-cart__continue-btn { align-self: flex-start; }

.lbm-cart__empty {
    text-align: center;
    padding: 60px 24px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    color: var(--lbm-text-muted);
}

.lbm-cart__empty p { margin-bottom: 18px; }

/* Aside récap — fond vert foncé, sticky (HANDOFF.md §Panier) */
.lbm-cart-aside {
    position: sticky;
    top: 88px;
    background: var(--lbm-brand-aside);
    color: #fff;
    border-radius: 18px;
    padding: 26px;
}

.lbm-cart-aside__row {
    display: flex;
    justify-content: space-between;
    font-size: 14.5px;
    margin-bottom: 12px;
    color: var(--lbm-brand-text-on-dark);
}

.lbm-cart-aside__row:nth-last-of-type(1) {
    color: #fff;
    font-weight: 700;
    font-size: 17px;
}

.lbm-cart-aside__note {
    font-size: 12.5px;
    color: var(--lbm-brand-text-on-dark);
    margin: 16px 0 20px;
}

/* Mention « prix nets — franchise TVA 293 B » dans le récap panier (fond sombre). */
.lbm-cart-aside__tva-note {
    font-size: 11.5px;
    color: var(--lbm-brand-text-on-dark);
    margin: 0 0 18px;
}

/* ---------- CTA clair des récaps sur fond vert foncé (panier + tunnel) -------
   Présentation de RÉFÉRENCE, celle que le client a validée sur le panier :
   pastille blanche pleine largeur, angles franchement arrondis, texte vert
   foncé centré et gras — le contraste sur le vert foncé du récap la rend
   immédiatement lisible comme « l'action à faire ».

   Elle est volontairement PARTAGÉE avec le bouton final du tunnel
   (.lbm-checkout-submit, §21) : les deux portent la même action de bout en
   bout du parcours et le client trouvait le second dissemblable — il était
   bien stylé (vert vif), mais son vert se fondait dans le vert foncé du récap.
   On la déclare donc UNE SEULE FOIS, ici, dans l'écran qui fixe l'apparence ;
   chaque écran n'ajoute ensuite que ce qui lui est propre, dans sa section.

   Les propriétés de remise à zéro (border, appearance, font-family) ne servent
   qu'au <button> du tunnel — sans effet sur le <a> du panier — et empêchent les
   styles par défaut du navigateur (bordure en relief, corps 13 px non gras) de
   reprendre la main sur une partie du rendu. */
.lbm-cart-aside__cta,
.lbm-checkout-submit {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 14px;
    border: none;
    border-radius: 12px;
    background: #fff;
    color: var(--lbm-brand-darker);
    font-family: inherit;
    font-weight: 700;
    font-size: 15.5px;
    line-height: 1.3;
    text-align: center;
    cursor: pointer;
    appearance: none;
    transition: .15s;
}

.lbm-cart-aside__cta:hover,
.lbm-checkout-submit:hover { background: var(--lbm-brand-light-bg); }

/* Anneau de focus blanc : l'anneau global (vert --lbm-primary, §2) est
   illisible sur le fond vert foncé des deux récaps. */
.lbm-cart-aside__cta:focus-visible,
.lbm-checkout-submit:focus-visible {
    outline: 2.5px solid #fff;
    outline-offset: 2px;
}

.lbm-cart-aside__cta.is-disabled {
    opacity: .5;
    pointer-events: none;
    cursor: not-allowed;
}

/* ==========================================================================
   19. Authentification (/inscription, /connexion) — HANDOFF.md écran 7 « auth »
   ========================================================================== */
.lbm-auth {
    max-width: 540px;
    margin: 0 auto;
    padding: 44px 24px 60px;
}

.lbm-auth-card {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 20px;
    padding: 30px;
}

.lbm-auth-tabs {
    display: flex;
    gap: 6px;
    background: var(--lbm-surface-alt);
    border-radius: 12px;
    padding: 5px;
    margin-bottom: 24px;
}

.lbm-auth-tab {
    flex: 1;
    text-align: center;
    padding: 10px 12px;
    border-radius: 9px;
    font-weight: 700;
    font-size: 14px;
    color: var(--lbm-text-muted);
}

.lbm-auth-tab.is-active {
    background: var(--lbm-surface);
    color: var(--lbm-ink);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}

/* (Les alertes de la carte d'authentification ont disparu : les flash sont
   désormais rendus une seule fois par le layout — cf. .lbm-flash plus haut.) */

.lbm-auth-form {
    display: flex;
    flex-direction: column;
}

.lbm-auth-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.lbm-auth-field {
    margin-bottom: 16px;
}

.lbm-auth-field label,
.lbm-auth-field__label {
    display: block;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--lbm-text-secondary);
    margin-bottom: 6px;
}

.lbm-auth-field input,
.lbm-auth-field select {
    width: 100%;
    padding: 12px 14px;
    border: 1.5px solid var(--lbm-border);
    border-radius: 11px;
    font-size: 14.5px;
    font-family: inherit;
    background: var(--lbm-surface);
    color: var(--lbm-ink);
}

.lbm-auth-field input:focus,
.lbm-auth-field select:focus {
    outline: none;
    border-color: var(--lbm-primary);
}

.lbm-auth-field__hint {
    display: block;
    margin-top: 5px;
    font-size: 12px;
    color: var(--lbm-text-disabled);
}

.lbm-auth-field .lbm-field-error,
.lbm-auth-field .form-error-message {
    display: block;
    color: var(--lbm-terracotta);
    font-size: 12.5px;
    margin-top: 5px;
}

/* Segment « Type de compte » — boutons radio stylés (Particulier/Pro/CE) */
.lbm-auth-segment {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.lbm-auth-segment__option {
    position: relative;
    flex: 1;
    min-width: 120px;
    /* Colonne : la pastille (<span>) remplit toute la hauteur du groupe, sinon
       une option portant une seconde ligne (« Bientôt ») dépasse ses voisines. */
    display: flex;
    flex-direction: column;
}

.lbm-auth-segment__option span {
    display: block;
    flex: 1;
    text-align: center;
    padding: 11px 10px;
    border: 1.5px solid var(--lbm-border);
    border-radius: 11px;
    font-weight: 600;
    font-size: 13.5px;
    color: var(--lbm-ink);
    background: var(--lbm-surface);
    cursor: pointer;
    transition: .12s;
}

/* Le radio natif reste dans le DOM (accessibilité/soumission) mais invisible :
   c'est le <span> voisin qui porte le style visuel du segment (:checked + span). */
.lbm-auth-segment__option input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.lbm-auth-segment__option input:checked + span {
    background: var(--lbm-brand-light-bg);
    border-color: var(--lbm-primary);
    color: var(--lbm-primary);
}

.lbm-auth-segment__option input:focus-visible + span {
    outline: 2.5px solid var(--lbm-primary);
    outline-offset: 2px;
}

/* Option annoncée mais pas encore ouverte (« Comité d'entreprise ») : le radio
   natif porte `disabled`, ce sélecteur grise le libellé visible qui lui sert de
   façade. Purement cosmétique — le refus réel est SERVEUR (contrainte Choice
   restreinte aux types réellement commercialisés, cf. LbmCustomer::TYPES_SELECTABLE). */
.lbm-auth-segment__option input:disabled + span {
    background: var(--lbm-surface-alt);
    border-color: var(--lbm-border);
    color: var(--lbm-text-disabled);
    cursor: not-allowed;
}

.lbm-auth-submit {
    width: 100%;
    margin-top: 6px;
}

/* Note explicative (connexion sans mot de passe) */
.lbm-auth-note {
    font-size: 13px;
    color: var(--lbm-text-secondary);
    background: var(--lbm-surface-alt);
    border-radius: 10px;
    padding: 11px 13px;
    margin: 0 0 18px;
    line-height: 1.5;
}

/* Page « Vérifiez votre email » (après inscription passwordless) */
.lbm-check-email {
    text-align: center;
}

.lbm-check-email__icon {
    display: block;
    width: 56px;
    height: 56px;
    margin: 4px auto 16px;
    border-radius: 50%;
    background: var(--lbm-brand-light-bg);
}

.lbm-check-email__title {
    font-size: 22px;
    font-weight: 800;
    color: var(--lbm-ink);
    margin: 0 0 12px;
}

.lbm-check-email__text {
    font-size: 15px;
    color: var(--lbm-text-secondary);
    line-height: 1.6;
    margin: 0 0 14px;
}

.lbm-check-email__hint {
    font-size: 13px;
    color: var(--lbm-text-muted);
    line-height: 1.6;
    margin: 0;
}

/* ==========================================================================
   20. Espace client (/compte) — HANDOFF.md écran 8 « account »
   ========================================================================== */
.lbm-account {
    max-width: 1100px;
    margin: 0 auto;
    padding: 40px 24px 60px;
}

.lbm-account__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 26px;
}

.lbm-account__title { font-size: clamp(26px, 4vw, 34px); font-weight: 800; }

.lbm-account__sub {
    color: var(--lbm-text-muted);
    margin-top: 6px;
    font-size: 15px;
    text-transform: capitalize;
}

.lbm-account-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-bottom: 32px;
}

.lbm-account-stat {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    padding: 22px;
}

.lbm-account-stat__value {
    display: block;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 800;
    font-size: 32px;
    color: var(--lbm-ink);
}

.lbm-account-stat--terracotta .lbm-account-stat__value { color: var(--lbm-terracotta); }
.lbm-account-stat--green .lbm-account-stat__value { color: var(--lbm-primary); }

.lbm-account-stat__label {
    display: block;
    color: var(--lbm-text-secondary);
    font-size: 13.5px;
    margin-top: 4px;
}

.lbm-account-section { margin-top: 8px; }

.lbm-account__placeholder {
    text-align: center;
    padding: 50px 24px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    color: var(--lbm-text-muted);
}

.lbm-account__placeholder p { margin-bottom: 16px; }

/* ==========================================================================
   18. Responsive — mobile : nav repliée sous la marque, grilles à 1/2 colonnes
   ========================================================================== */
@media (max-width: 860px) {
    .lbm-hero__grid { grid-template-columns: 1fr; }
    .lbm-steps-grid,
    .lbm-product-grid { grid-template-columns: repeat(2, 1fr); }
    .lbm-stats-grid { grid-template-columns: 1fr; }
    .lbm-product__grid { grid-template-columns: 1fr; }
    .lbm-cart__grid { grid-template-columns: 1fr; }
    .lbm-cart-aside { position: static; }
    .lbm-account-stats { grid-template-columns: 1fr; }
}

/* ==========================================================================
   21. Checkout / Paiement (/paiement) — HANDOFF.md écran 6 « pay »
   ========================================================================== */
.lbm-checkout {
    max-width: 1000px;
    margin: 0 auto;
    padding: 30px 24px 60px;
}

.lbm-checkout__back {
    display: inline-block;
    color: var(--lbm-text-muted);
    font-size: 13.5px;
    font-weight: 600;
    margin-bottom: 14px;
}

.lbm-checkout__back:hover { color: var(--lbm-ink); }

.lbm-checkout__title { font-size: 32px; font-weight: 800; margin-bottom: 22px; }

.lbm-checkout__grid {
    display: grid;
    grid-template-columns: 1fr 320px;
    gap: 28px;
    align-items: start;
}

.lbm-checkout__main {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.lbm-checkout-section {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 18px;
    padding: 24px;
}

.lbm-checkout-section__title {
    font-size: 18px;
    margin-bottom: 16px;
}

/* Sélecteur de mode de récupération — même mécanique que .lbm-auth-segment
   (radio natif invisible, <span> voisin porte le style, :checked le surligne) */
.lbm-delivery-grid {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.lbm-delivery-option {
    position: relative;
    flex: 1;
    min-width: 200px;
}

.lbm-delivery-option input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.lbm-delivery-option__card {
    display: block;
    padding: 14px 16px;
    border: 1.5px solid var(--lbm-border);
    border-radius: 13px;
    cursor: pointer;
    transition: .12s;
}

.lbm-delivery-option__card strong {
    display: block;
    font-size: 14.5px;
    margin-bottom: 3px;
}

.lbm-delivery-option__card small { color: var(--lbm-text-muted); font-size: 12.5px; }

.lbm-delivery-option input:checked + .lbm-delivery-option__card {
    background: var(--lbm-brand-light-bg);
    border-color: var(--lbm-primary);
}

.lbm-delivery-option input:focus-visible + .lbm-delivery-option__card {
    outline: 2.5px solid var(--lbm-primary);
    outline-offset: 2px;
}

.lbm-checkout-address {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--lbm-border);
}

/* Bouton par défaut du tunnel (lot 34) : invisible, hors parcours clavier, mais
   RENDU — c'est lui que la touche Entrée déclenche, et il commande la commande.
   Pas de `display:none` : tous les navigateurs ne retiennent pas un bouton non
   rendu comme bouton par défaut. Cf. le commentaire de checkout.html.twig. */
.lbm-checkout__default-submit {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ── Code comité d'entreprise dans le tunnel (lot 34, D1/D2) ──
   Champ + bouton « Appliquer » sur une ligne, le champ prenant la place
   restante. Le bloc entier est masqué par l'attribut `hidden` hors type
   « Particulier » (posé par le serveur, maintenu par initSegmentTypeCompte) :
   aucune règle d'affichage conditionnel n'est écrite ici. */
.lbm-checkout-ce-code__row {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.lbm-checkout-ce-code__row input {
    flex: 1 1 auto;
    min-width: 0;
}

.lbm-checkout-ce-code__apply {
    flex: 0 0 auto;
    padding: 0 18px;
    border: 1px solid var(--lbm-primary);
    border-radius: 10px;
    background: var(--lbm-surface);
    color: var(--lbm-primary);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.lbm-checkout-ce-code__apply:hover {
    background: var(--lbm-primary);
    color: #fff;
}

/* Réponse au code saisi : refus en terracotta (comme une erreur de champ),
   acceptation en vert. La FORMULATION des refus est volontairement identique
   dans les trois cas (R3) — seule la couleur distingue les deux issues. */
.lbm-checkout-ce-code__feedback {
    margin: 8px 0 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--lbm-terracotta);
}

.lbm-checkout-ce-code__feedback.is-accepted {
    color: var(--lbm-primary);
}

/* Note de paiement (checkout) — remplace l'ancien bloc carte STUB (L7) */
.lbm-checkout-pay-note {
    padding: 16px 18px;
    border: 1px solid var(--lbm-border);
    border-radius: 13px;
    background: var(--lbm-surface-alt);
    color: var(--lbm-text-secondary);
    font-size: 14px;
    line-height: 1.5;
}

/* Note « livraison sur devis » du tunnel : même encart que .lbm-checkout-pay-note
   mais en accent informatif (la livraison n'est pas commandable en ligne) */
.lbm-checkout-quote-note {
    margin-top: 14px;
    border-left: 3px solid var(--lbm-primary);
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-text-secondary);
}

/* Choix du moyen de paiement (carte en ligne / règlement à l'entrepôt) —
   réutilise intégralement la mécanique .lbm-delivery-option (radio masqué +
   carte stylée) ; ce modificateur ne fait qu'aérer le bloc. */
.lbm-payment-grid {
    margin-bottom: 10px;
}

/* Rappel des deux modalités sous le sélecteur (ton secondaire, pas d'accent) */
.lbm-checkout-pay-note--mode {
    margin-top: 12px;
}

/* Récap sticky — même habillage que .lbm-cart-aside (fond vert foncé) */
.lbm-checkout-aside {
    position: sticky;
    top: 88px;
    background: var(--lbm-brand-aside);
    color: #fff;
    border-radius: 18px;
    padding: 26px;
}

/* Récap détaillé obligatoire avant paiement (art. L221-14) — dans l'aside foncé */
.lbm-checkout-recap__title {
    font-size: 15px;
    font-weight: 700;
    color: #fff;
    margin-bottom: 14px;
}

.lbm-checkout-recap-lines {
    list-style: none;
    margin: 0 0 18px;
    padding: 0 0 14px;
    border-bottom: 1px solid rgba(255, 255, 255, .18);
}

.lbm-checkout-recap-line {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 10px;
    font-size: 13.5px;
}

.lbm-checkout-recap-line:last-child { margin-bottom: 0; }

.lbm-checkout-recap-line__label {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.lbm-checkout-recap-line__name { color: #fff; }

.lbm-checkout-recap-line__meta {
    color: var(--lbm-brand-text-on-dark);
    font-size: 12px;
}

.lbm-checkout-recap-line__total {
    color: #fff;
    font-weight: 600;
    white-space: nowrap;
}

.lbm-checkout-tva-note {
    font-size: 11.5px;
    color: var(--lbm-brand-text-on-dark);
    margin: 14px 0 16px;
}

/* Case d'acceptation des CGV (art. L221-5 / L221-14) */
.lbm-checkout-cgv {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 16px;
}

.lbm-checkout-cgv input[type="checkbox"] {
    margin-top: 2px;
    width: 17px;
    height: 17px;
    flex: 0 0 auto;
    accent-color: var(--lbm-brand-vivid);
}

.lbm-checkout-cgv__label {
    font-size: 13px;
    line-height: 1.4;
    color: var(--lbm-brand-text-on-dark);
    cursor: pointer;
}

.lbm-checkout-cgv__label a {
    color: #fff;
    text-decoration: underline;
}

/* ---------- Encart « Informations légales » du tunnel ----------
   Les mentions de prospection (art. L34-5 CPCE) et de rétractation (art.
   L221-5 / L221-28) vivaient dans le récap sombre, en petits pavés étroits :
   illisibles alors que leur portée est juridique (une exclusion de rétractation
   non lisible est inopposable). Elles occupent désormais une section pleine
   largeur SOUS les moyens de paiement, au même gabarit que les autres sections
   du tunnel (.lbm-checkout-section) : titre, sous-titres, texte à 15 px.

   Depuis la demande client d'harmonisation, chaque mention est posée dans le
   même encadré que les notes du haut de page (.lbm-checkout-pay-note, ajoutée
   dans le template). Le filet de séparation entre blocs ferait alors doublon
   avec la bordure de ces encadrés : seul l'espacement subsiste. */
.lbm-checkout-legal__block + .lbm-checkout-legal__block {
    margin-top: 18px;
}

.lbm-checkout-legal__subtitle {
    font-size: 15px;
    font-weight: 700;
    margin-bottom: 6px;
    color: var(--lbm-ink);
}

/* ⚠️ Doit rester APRÈS .lbm-checkout-pay-note dans ce fichier : les mentions
   portent les deux classes, la spécificité est identique (une classe chacune),
   c'est donc l'ordre de déclaration qui garantit la taille de lecture de 15 px
   plutôt que les 14 px de la note. Ne pas remonter ce bloc. */
.lbm-checkout-legal__text {
    font-size: 15px;
    line-height: 1.6;
    color: var(--lbm-text-secondary);
}

.lbm-checkout-legal__text + .lbm-checkout-legal__text { margin-top: 8px; }

.lbm-checkout-legal__text strong { color: var(--lbm-ink); }

.lbm-checkout-legal__text a {
    color: var(--lbm-primary);
    font-weight: 600;
    text-decoration: underline;
}

/* ---------- Bouton de validation du tunnel (art. L221-9) ----------
   Action principale de la page : la formule « avec obligation de paiement » est
   imposée par la loi et le montant doit rester visible. Les deux tenaient jadis
   sur une seule ligne dans un bouton de 320 px et se chevauchaient : ils
   restent donc EMPILÉS, formule légale au-dessus, montant en dessous.

   L'habillage (pastille blanche, angles arrondis, texte vert foncé, survol et
   anneau de focus) n'est PAS redéclaré ici : il est mutualisé §17 avec
   .lbm-cart-aside__cta, le bouton « Passer au paiement » du panier, pour que
   les deux étapes du même geste se ressemblent. Ne reste ci-dessous que ce qui
   est propre au tunnel — l'empilement des deux mentions obligatoires. */
.lbm-checkout-submit {
    flex-direction: column;
    gap: 3px;
}

/* Formule légale : jamais réduite ni tronquée, c'est elle qui informe le client
   qu'il s'engage à payer. Elle hérite volontairement du corps 15,5 px / 700 du
   CTA partagé — exactement la lisibilité de « Passer au paiement » — plutôt que
   de refixer une taille qui pourrait diverger. */
.lbm-checkout-submit__legal {
    line-height: 1.25;
}

/* Montant engagé : accentué pour rester repérable d'un coup d'œil, mais sans
   écraser la mention légale au-dessus (rapport de taille volontairement
   modeste, la loi exige que la formule reste explicite et lisible). */
.lbm-checkout-submit__amount {
    font-size: 18px;
    font-weight: 800;
    line-height: 1.2;
}

/* ==========================================================================
   22. Confirmation (/commande/confirmee/{reference}) — HANDOFF.md écran 10 « done »
   ========================================================================== */
.lbm-confirmation {
    max-width: 540px;
    margin: 0 auto;
    padding: 60px 24px;
}

.lbm-confirmation-card {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 20px;
    padding: 44px 32px;
    text-align: center;
}

.lbm-confirmation-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-primary);
    font-size: 28px;
    font-weight: 800;
    margin-bottom: 18px;
}

.lbm-confirmation-title { font-size: 28px; font-weight: 800; margin-bottom: 10px; }

.lbm-confirmation-text {
    color: var(--lbm-text-secondary);
    font-size: 15px;
    margin-bottom: 22px;
}

.lbm-confirmation-total {
    display: flex;
    justify-content: center;
    align-items: baseline;
    gap: 10px;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    margin-bottom: 26px;
}

.lbm-confirmation-total span { color: var(--lbm-text-muted); font-size: 14px; }
.lbm-confirmation-total strong { font-size: 26px; font-weight: 800; }

.lbm-confirmation-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}

/* États de paiement (L7) : confirmation payée, en attente, annulé, simulation */
.lbm-confirmation-paid {
    color: var(--lbm-primary);
    font-weight: 700;
    margin-bottom: 22px;
}

/* Commande à régler sur place au retrait : encart d'attente (à distinguer
   nettement de .lbm-confirmation-paid, qui annonce une commande déjà réglée) */
.lbm-confirmation-topay {
    padding: 14px 18px;
    margin-bottom: 22px;
    border: 1px solid var(--lbm-primary);
    border-radius: 13px;
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-text-secondary);
    font-size: 14.5px;
    line-height: 1.55;
}

.lbm-confirmation-check--pending {
    background: #FBF3DE;
    color: #B7860B;
}

.lbm-confirmation-check--cancel {
    background: #FBE4E4;
    color: #C0392B;
}

.lbm-sim-banner {
    padding: 10px 14px;
    border: 1px dashed var(--lbm-border);
    border-radius: 10px;
    background: var(--lbm-surface-alt);
    color: var(--lbm-text-secondary);
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 20px;
}

.lbm-sim-form {
    display: inline-flex;
    margin: 0;
}

/* ==========================================================================
   23. Espace client — recommande 1-clic / produits récurrents / historique
   (L6c, HANDOFF.md écrans 8 « account » et 9 « history »)
   ========================================================================== */

/* ---------- Carte commande réutilisable (_order_card.html.twig) ---------- */
.lbm-order-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 18px;
}

.lbm-order-card {
    display: flex;
    flex-direction: column;
    gap: 14px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    padding: 18px;
}

.lbm-order-card__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
}

.lbm-order-card__ident { display: flex; flex-direction: column; gap: 2px; }

.lbm-order-card__ref { font-weight: 800; font-size: 15.5px; }

.lbm-order-card__date { color: var(--lbm-text-muted); font-size: 12.5px; }

/* Couleurs du badge de statut décidées ICI (jamais dans l'enum OrderStatus, G3). */
.lbm-order-card__badge {
    flex: none;
    padding: 5px 11px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    white-space: nowrap;
}

.lbm-order-card__badge--pending { background: var(--lbm-terracotta-bg); color: var(--lbm-terracotta); }
.lbm-order-card__badge--ready { background: var(--lbm-brand-light-bg); color: var(--lbm-primary); }
.lbm-order-card__badge--done { background: var(--lbm-surface-alt); color: var(--lbm-text-secondary); }
.lbm-order-card__badge--cancelled { background: #F5E1DE; color: #A6402F; }
/* Paiement à finaliser : ambre. Signale au client qu'il lui reste un geste à
   faire, sans la dramatisation du rouge d'une commande annulée. */
.lbm-order-card__badge--waiting { background: #FAF0D6; color: #8A6410; }

.lbm-order-card__thumbs {
    display: flex;
    align-items: center;
    gap: 8px;
}

.lbm-order-card__thumb {
    width: 34px;
    height: 34px;
    flex: none;
    border-radius: 9px;
    background: var(--lbm-surface-alt);
}

.lbm-order-card__thumb-more {
    width: 34px;
    height: 34px;
    flex: none;
    border-radius: 9px;
    background: var(--lbm-surface-alt);
    color: var(--lbm-text-muted);
    display: grid;
    place-items: center;
    font-size: 12px;
    font-weight: 700;
}

.lbm-order-card__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.lbm-order-card__total {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 800;
    font-size: 18px;
}

.lbm-order-card__actions { display: flex; gap: 8px; flex: none; }

.lbm-order-card__reorder-form { flex: none; }

/* Variante compacte de .lbm-btn, boutons de carte commande (Détail / Recommander). */
.lbm-btn--sm {
    padding: 9px 14px;
    font-size: 13.5px;
    white-space: nowrap;
    flex: none;
}

/* ---------- Produits récurrents (grille compacte, vignette cliquable) ---------- */
.lbm-recurring-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
}

.lbm-recurring-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    padding: 18px 14px;
    transition: .15s;
}

.lbm-recurring-card:hover { border-color: var(--lbm-border-hover); transform: translateY(-2px); }

.lbm-recurring-card--unavailable { color: var(--lbm-text-disabled); cursor: default; }
.lbm-recurring-card--unavailable:hover { transform: none; border-color: var(--lbm-border); }

.lbm-recurring-card__thumb {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background: var(--lbm-surface-alt);
}

.lbm-recurring-card__name { font-size: 13.5px; font-weight: 700; }

.lbm-recurring-card__price {
    font-size: 12px;
    color: var(--lbm-text-muted);
    white-space: nowrap;
}

/* Prix catalogue barré : taille réduite pour rester sur la MÊME ligne que le
   prix net (§12, correctif du 18/09/2026 — même principe que la carte
   catalogue, cf. .lbm-product-card__pricing .lbm-price-old). */
.lbm-recurring-card__price .lbm-price-old {
    font-size: 10.5px;
}

.lbm-recurring-card__add {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--lbm-brand-light-bg);
    color: var(--lbm-primary);
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 14px;
}

/* ---------- Historique de commandes (/compte/commandes) — écran 9 « history » ---------- */
.lbm-history {
    max-width: 900px;
    margin: 0 auto;
    padding: 40px 24px 60px;
}

.lbm-history__head { margin-bottom: 26px; }

.lbm-history__back {
    display: inline-block;
    color: var(--lbm-text-muted);
    font-size: 13.5px;
    font-weight: 600;
    margin-bottom: 10px;
}

.lbm-history__back:hover { color: var(--lbm-ink); }

.lbm-history__title { font-size: clamp(24px, 4vw, 30px); font-weight: 800; }

.lbm-history__list {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.lbm-history__entry {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Ligne « Facture » (lot 7, DOLIBARR_CONTRATS.md §6bis.2) : lien de
   téléchargement si émise, mention discrète sinon. */
.lbm-history__invoice { margin-bottom: 2px; }

.lbm-history__invoice-pending {
    color: var(--lbm-text-muted);
    font-size: 13.5px;
    font-weight: 600;
}

.lbm-history__lines {
    display: flex;
    flex-direction: column;
    gap: 0;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 16px;
    padding: 4px 16px;
}

.lbm-history__line {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 0;
    border-bottom: 1px solid var(--lbm-border);
    flex-wrap: wrap;
}

.lbm-history__line:last-child { border-bottom: none; }

.lbm-history__line-name {
    flex: 1;
    min-width: 140px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 14.5px;
    font-weight: 700;
}

.lbm-history__line-variant {
    color: var(--lbm-text-muted);
    font-size: 12.5px;
    font-weight: 500;
}

.lbm-history__line-qty {
    flex: none;
    color: var(--lbm-text-muted);
    font-size: 13.5px;
}

.lbm-history__line-total {
    flex: none;
    width: 80px;
    text-align: right;
    font-weight: 700;
    font-size: 14.5px;
}

@media (max-width: 860px) {
    .lbm-checkout__grid { grid-template-columns: 1fr; }
    .lbm-checkout-aside { position: static; }
    .lbm-order-grid { grid-template-columns: 1fr; }
    .lbm-recurring-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
    /* ── LA BARRE REVIENT À SES PROPORTIONS D'ORIGINE SOUS 640 px ──────────
       Le relèvement du 19/09 (barre 88 px, logo 54, nom 23) a été calé sur un
       écran large. Sur un téléphone, marque + boutons ne tiennent plus sur une
       ligne : les boutons passaient en dessous, et le menu encore en dessous —
       trois lignes au lieu de deux. Constaté par le gérant le 21/09.
       Les valeurs ci-dessous sont celles qui tenaient avant, à peine relevées :
       la barre respire toujours, sans jamais se replier. Toucher à l'une des
       trois (pastille, image, nom) suppose de revérifier sur 360 px de large —
       c'est la largeur qui décide, pas l'esthétique de l'aperçu. */
    .lbm-header__inner { padding: 10px 16px; min-height: 72px; }
    .lbm-header__badge { width: 44px; height: 44px; }
    .lbm-header__badge img { height: 40px; }
    .lbm-header__wordmark { font-size: 19px; }
    .lbm-header__brand { gap: 9px; }
    /* Le bandeau flash s'aligne sur les gouttières du header en mobile. */
    .lbm-flashes { padding: 14px 16px 0; }
    .lbm-header__subtitle { display: none; }
    .lbm-nav {
        order: 3;
        width: 100%;
        margin-left: 0;
        justify-content: flex-start;
    }

    /* Les quatre entrées tiennent sur UNE ligne dès 360 px : rembourrage
       horizontal resserré et texte à 15 px. La hauteur de la cible tactile ne
       bouge pas (rembourrage VERTICAL inchangé à 13 px) — c'est elle qui compte
       pour l'accessibilité, pas la largeur. */
    .lbm-nav__item {
        padding: 13px 10px;
        font-size: 15px;
    }
    .lbm-header__actions { gap: 6px; }
    .lbm-btn-account__label,
    .lbm-btn-cart__label { display: none; }
    .lbm-steps-grid,
    .lbm-product-grid { grid-template-columns: repeat(1, 1fr); }
    /* Textes sous 14 px en mobile (audit accessibilité du 18/09/2026) :
       description de carte (12,5 px), prix à l'unité de mesure et « dès »
       (11 px), sous-titres des 4 étapes (13 px). Remontés à 14 px, le
       plancher lisible retenu par l'audit — inchangés en desktop (une seule
       colonne en dessous de 640 px, aucun risque de débordement). */
    .lbm-product-card__desc,
    .lbm-product-card__per-liter,
    .lbm-product-card__price-from,
    .lbm-step__sub { font-size: 14px; }
    .lbm-search__input { width: 100%; max-width: 100%; }
    /* Chips + recherche : la recherche passe sur sa propre ligne (flex-wrap
       du parent), pleine largeur, jamais de débordement horizontal. */
    .lbm-catalogue__toolbar .lbm-search { flex: 1 1 100%; width: 100%; }
    .lbm-cart-line { justify-content: space-between; }
    .lbm-cart-line__total { width: auto; }
    .lbm-cart-bidon { margin-left: 0; }
    .lbm-cart-bidon__actions { width: 100%; }
    .lbm-cart-bidon__btn { flex: 1; }
    .lbm-auth-row { grid-template-columns: 1fr; }
    .lbm-account__head { flex-direction: column; align-items: stretch; }
    .lbm-recurring-grid { grid-template-columns: repeat(1, 1fr); }
    .lbm-order-card__foot { flex-direction: column; align-items: stretch; }
    .lbm-order-card__actions { justify-content: stretch; }
    .lbm-order-card__actions .lbm-btn,
    .lbm-order-card__reorder-form { flex: 1; }
    .lbm-order-card__reorder { width: 100%; }
}

/* ============================================================
   RGPD — page « Mes données » (lot J6, art. 13/15/17/20)
   ============================================================ */

/* Actions groupées dans l'en-tête du dashboard (Mes données + déconnexion). */
.lbm-account__head-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* Bouton d'action destructrice (effacement du compte). */
.lbm-btn--danger {
    background: var(--lbm-pending-text);
    color: #fff;
}
.lbm-btn--danger:hover { background: #822f26; }

/* Tableau clé/valeur des données détenues (droit d'accès). */
.lbm-rgpd-data {
    margin: 0;
    border: 1px solid var(--lbm-border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--lbm-surface);
}
.lbm-rgpd-data__row {
    display: flex;
    gap: 1rem;
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--lbm-border);
}
.lbm-rgpd-data__row:last-child { border-bottom: 0; }
.lbm-rgpd-data__row dt {
    flex: 0 0 40%;
    margin: 0;
    color: var(--lbm-text-secondary);
    font-weight: 600;
}
.lbm-rgpd-data__row dd { margin: 0; color: var(--lbm-ink); word-break: break-word; }

.lbm-rgpd-note {
    margin-top: 0.8rem;
    color: var(--lbm-text-secondary);
    font-size: 0.92rem;
}

/* Mentions légales art. 13 (liste descriptive). */
.lbm-rgpd-legal__list { margin: 0; }
.lbm-rgpd-legal__list dt {
    margin-top: 1rem;
    font-weight: 700;
    color: var(--lbm-brand-darker);
}
.lbm-rgpd-legal__list dt:first-child { margin-top: 0; }
.lbm-rgpd-legal__list dd {
    margin: 0.2rem 0 0;
    color: var(--lbm-text-secondary);
    line-height: 1.5;
}

/* Marqueur visuel des données restant à fournir par le client (placeholders). */
.lbm-rgpd-placeholder {
    color: var(--lbm-text-muted);
    font-style: italic;
}

/* Zone d'effacement (danger) + confirmation native <details> (aucun JS, CSP self). */
.lbm-rgpd-danger {
    border: 1px solid var(--lbm-pending-border);
    background: var(--lbm-pending-bg);
    border-radius: 14px;
    padding: 1.2rem 1.4rem;
}
.lbm-rgpd-confirm { margin-top: 0.8rem; }
.lbm-rgpd-confirm > summary {
    display: inline-block;
    cursor: pointer;
    list-style: none;
}
.lbm-rgpd-confirm > summary::-webkit-details-marker { display: none; }
.lbm-rgpd-confirm__form {
    margin-top: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    max-width: 32rem;
}
.lbm-rgpd-confirm__check {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    color: var(--lbm-ink);
}
.lbm-rgpd-confirm__check input { margin-top: 0.2rem; }

/* ==========================================================================
   20. Liens légaux en footer (J8)
   ========================================================================== */
.lbm-footer__legal {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 24px 26px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
    border-top: 1px solid var(--lbm-border);
    padding-top: 18px;
}

/* Rembourrage ajouté (audit accessibilité du 18/09/2026, cible tactile WCAG
   ≥44 px) : un simple lien texte de 13 px ne faisait que ~20 px de haut.
   Rembourrage plutôt que texte agrandi ; les liens sont des éléments flex de
   `.lbm-footer__legal` (`display: flex`), le padding agit donc bien sur leur
   boîte cliquable — au prix d'un pied de page un peu plus haut, assumé. */
.lbm-footer__legal-link {
    display: inline-block;
    padding: 13px 4px;
    color: var(--lbm-text-muted);
    text-decoration: none;
    font-size: 13px;
}

.lbm-footer__legal-link:hover {
    color: var(--lbm-primary);
    text-decoration: underline;
}

/* ==========================================================================
   21. Pages légales (mentions, CGV, confidentialité, cookies, rétractation)
   Colonne de lecture ~800px, typographie confortable, encadrés réglementaires.
   ========================================================================== */
.lbm-legal {
    max-width: 820px;
    margin: 0 auto;
    padding: 44px 24px 72px;
}

.lbm-legal__doc {
    color: var(--lbm-ink);
    line-height: 1.65;
    font-size: 15.5px;
}

.lbm-legal__eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--lbm-primary);
    margin-bottom: 6px;
}

.lbm-legal__title {
    font-size: 34px;
    line-height: 1.15;
    margin-bottom: 10px;
}

.lbm-legal__updated {
    color: var(--lbm-text-muted);
    font-size: 14px;
    margin-bottom: 28px;
}

.lbm-legal__section {
    margin-bottom: 30px;
}

.lbm-legal__section h2 {
    font-size: 20px;
    margin-bottom: 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--lbm-border);
}

.lbm-legal__section p {
    margin-bottom: 12px;
}

.lbm-legal__list {
    margin: 0 0 12px;
    padding-left: 22px;
    list-style: disc;
}

.lbm-legal__list li {
    margin-bottom: 6px;
}

/* Variante « entrées longues » (modificateur, opt-in explicite dans le Twig).
   Les 6px ci-dessus ont été calibrés pour des puces d'UNE ligne. Dès qu'une
   entrée occupe plusieurs lignes (cf. politique de confidentialité §2, une
   catégorie de données = libellé + finalité + caractère obligatoire), cet
   interligne se confond avec le retour à la ligne interne : la liste se lit
   comme un pavé et la puce devient le seul repère. On aère donc l'ESPACE ENTRE
   ENTRÉES sans toucher au rythme interne d'une entrée.
   Portée : uniquement les <ul> qui portent le modificateur — les listes courtes
   des autres pages légales (mentions, CGV, cookies, rétractation) restent
   inchangées. */
.lbm-legal__list--detailed > li {
    margin-bottom: 18px;
}

/* Pas de blanc surnuméraire en fin de liste : le margin-bottom du <ul> suffit. */
.lbm-legal__list--detailed > li:last-child {
    margin-bottom: 0;
}

.lbm-legal__doc a {
    color: var(--lbm-primary);
    text-decoration: underline;
}

.lbm-legal__doc a:hover {
    color: var(--lbm-primary-hover);
}

/* Bandeau « brouillon » des CGV en cours de finalisation. */
.lbm-legal__draft {
    background: var(--lbm-pending-bg);
    border: 1px solid var(--lbm-pending-border);
    color: var(--lbm-pending-text);
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 28px;
    font-size: 14.5px;
}

/* Encadré de texte réglementaire reproduit à l'identique. */
.lbm-legal__section--regulatory .lbm-legal__box {
    background: var(--lbm-surface-alt);
    border: 1px solid var(--lbm-border);
    border-left: 4px solid var(--lbm-primary);
    border-radius: 8px;
    padding: 18px 20px;
    font-size: 14.5px;
}

.lbm-legal__note {
    color: var(--lbm-text-muted);
    font-size: 13.5px;
    font-style: italic;
    margin-bottom: 10px;
}

.lbm-legal__form-fields {
    margin: 12px 0;
    padding-left: 22px;
    list-style: none;
}

.lbm-legal__form-fields li {
    padding: 8px 0;
    border-bottom: 1px dashed var(--lbm-border);
}

/* ==========================================================================
   22. Page FAQ (/faq, lot 22 — SEO technique)
   Colonne de lecture ~760px ; accordéon en <details>/<summary> natif (zéro
   JS) ; façade vidéo au clic (vignette locale + bouton, iframe injectée en
   JS uniquement après clic — cf. lbm-site.js#initFaqVideoFacade).
   ========================================================================== */
.lbm-faq {
    max-width: 760px;
    margin: 0 auto;
    padding: 44px 24px 72px;
}

.lbm-faq__badge { margin-bottom: 14px; }

.lbm-faq__title {
    font-size: 34px;
    line-height: 1.15;
    margin-bottom: 10px;
}

.lbm-faq__intro {
    color: var(--lbm-text-muted);
    font-size: 15.5px;
    line-height: 1.6;
    margin-bottom: 30px;
}

.lbm-faq__list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 44px;
}

.lbm-faq__item {
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    border-radius: 12px;
    padding: 4px 18px;
}

/* Puce native du <summary> masquée : remplacée par un chevron dessiné en CSS
   (::after) qui pivote à l'ouverture — cohérent avec le reste du design,
   aucune police d'icônes ni image (G2). */
.lbm-faq__question {
    list-style: none;
    cursor: pointer;
    padding: 14px 0;
    font-weight: 700;
    font-size: 15.5px;
    color: var(--lbm-ink);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.lbm-faq__question::-webkit-details-marker { display: none; }

.lbm-faq__question::after {
    content: '';
    flex: none;
    width: 9px;
    height: 9px;
    border-right: 2px solid var(--lbm-primary);
    border-bottom: 2px solid var(--lbm-primary);
    transform: rotate(45deg);
    transition: transform .15s;
}

.lbm-faq__item[open] .lbm-faq__question::after {
    transform: rotate(-135deg);
}

.lbm-faq__answer {
    color: var(--lbm-text-secondary);
    font-size: 14.5px;
    line-height: 1.6;
    padding: 0 0 16px;
}

.lbm-faq__video-section { margin-bottom: 40px; }

.lbm-faq__video-section h2 {
    font-size: 20px;
    margin-bottom: 8px;
}

.lbm-faq__video-note {
    color: var(--lbm-text-muted);
    font-size: 13.5px;
    margin-bottom: 16px;
}

.lbm-faq__video-note a {
    color: var(--lbm-primary);
    text-decoration: underline;
}

.lbm-faq__video {
    aspect-ratio: 16 / 9;
    width: 100%;
    border-radius: 14px;
    overflow: hidden;
    background: var(--lbm-brand-darker);
}

.lbm-faq__video-play {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    cursor: pointer;
    background: none;
}

.lbm-faq__video-play img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Triangle « lecture » dessiné en CSS (bordures) — aucune police d'icônes, aucun CDN. */
.lbm-faq__video-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 62px;
    height: 62px;
    border-radius: 50%;
    background: rgba(27, 36, 31, .55);
    display: flex;
    align-items: center;
    justify-content: center;
}

.lbm-faq__video-icon::after {
    content: '';
    margin-left: 5px;
    border-style: solid;
    border-width: 11px 0 11px 18px;
    border-color: transparent transparent transparent #fff;
}

.lbm-faq__video-iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}


/* Concept — en-tête deux colonnes (discours + visuel de l'atelier de vrac).
   flex-wrap : le visuel repasse sous le texte sur petit écran. */
.lbm-concept__hero { display: flex; flex-wrap: wrap; gap: 32px; align-items: center; margin-bottom: 8px; }
.lbm-concept__hero-text { flex: 1 1 340px; min-width: 0; }
/* Cadre CARRÉ de la photo d'en-tête du concept (lot 29). Il est devenu
   nécessaire le jour où cette image est devenue remplaçable par le gérant : en
   `height: auto`, une photo d'un autre format aurait changé la hauteur de tout
   l'en-tête, et les attributs `width`/`height` du gabarit auraient menti — donc
   la page aurait sauté au chargement (R10). Le carré est le format du visuel
   livré (1000 × 1000) : rien n'est rogné tant que le gérant n'a rien déposé. */
.lbm-concept__hero-media {
    flex: 1 1 300px;
    aspect-ratio: 1 / 1;
    border-radius: 16px;
    overflow: hidden;
}
.lbm-concept__hero-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Remises CE (lot 25.5, D15) ──────────────────────────────────────────
   Affichées au seul client connecté, rattaché à un CE, sur une ligne remisée.
   Ajouts seuls : aucune règle existante n'est modifiée. */

/* Badge « −X % » en haut à GAUCHE de la vignette (lot du 18/09/2026) : le coin
   haut-droit est désormais pris par le bandeau « Recharge »
   (.lbm-product-card__ribbon, ci-dessus) — la remise ne doit pas disparaître
   pour autant, elle rejoint le tag NOUVEAU/PREMIUM côté gauche. Empilé SOUS
   le tag quand les deux sont présents (règle suivante, sélecteur de sibling) ;
   seul en haut à gauche sinon. */
.lbm-product-card__ce-badge {
    position: absolute;
    top: 9px;
    left: 9px;
    background: var(--lbm-terracotta);
    color: #fff;
    font-weight: 800;
    font-size: 11px;
    padding: 3px 8px;
    border-radius: 7px;
    letter-spacing: .02em;
    z-index: 1;
}

/* Tag + remise CE présents ensemble : la remise descend sous le tag au lieu
   de le chevaucher (même colonne gauche, empilement vertical). */
.lbm-product-card__tag + .lbm-product-card__ce-badge {
    top: 35px;
}

/* Prix catalogue barré : atténué, lisible sur fond clair comme sur le récap sombre. */
.lbm-price-old {
    opacity: .65;
    font-weight: 500;
    text-decoration: line-through;
}

/* Panier : prix unitaire barré / net et pourcentage sous la variante. */
.lbm-cart-line__ce {
    color: var(--lbm-terracotta);
    font-size: 13px;
    font-weight: 600;
    margin-top: 2px;
}

/* Panier : total catalogue barré, au-dessus du total net de la ligne. */
.lbm-cart-line__total-old {
    display: block;
    font-size: 13px;
}

/* Fiche produit : mention de la remise incluse dans le total. */
.lbm-product__ce-note {
    display: block;
    color: var(--lbm-terracotta);
    font-size: 13px;
    font-weight: 600;
}

/* ==========================================================================
   Lot 25.8 (D16) — contenants ajoutés d'office en livraison groupée CE
   --------------------------------------------------------------------------
   Le récapitulatif du paiement porte deux jeux de montants (retrait / livraison
   CE) ; le jeu visible suit le mode coché.

   Correctif (audit du 17/09/2026, lot 26.4) : la bascule reposait sur
   `:has()`, INCONNU de Firefox < 121 et Safari < 15.4 — sur ces navigateurs
   le jeu « retrait » restait affiché même en livraison CE cochée, alors que
   c'est bien le montant CE qui est débité (Stripe, lui, voit toujours le bon
   montant : seul CET affichage mentait). La bascule est désormais portée par
   la classe `.is-ce-selected`, posée sur `[data-checkout-recap]` par
   `initCheckoutDelivery()` (lbm-site.js, fichier séparé — CSP `script-src
   'self'`, zéro inline) : un mécanisme, pas deux à maintenir en double (C.12).
   Support universel (classe = CSS le plus basique qui soit), y compris sur
   les navigateurs sans `:has()`. Repli si JavaScript est désactivé : le jeu
   « retrait » reste affiché (c'est le mode PAR DÉFAUT du formulaire,
   cf. CheckoutType::deliveryMode 'data' => DeliveryMode::RETRAIT) — même
   dépendance à JS que le reste de cette page pour ses bascules d'affichage
   (ex. initSegmentTypeCompte, champs pro/CE).
   ========================================================================== */

/* Jeu « livraison CE » masqué par défaut… */
.lbm-checkout-recap--ce {
    display: none;
}

/* … et substitué au jeu « retrait » dès que le récapitulatif porte .is-ce-selected. */
[data-checkout-recap].is-ce-selected .lbm-checkout-recap--retrait {
    display: none;
}

[data-checkout-recap].is-ce-selected li.lbm-checkout-recap--ce,
[data-checkout-recap].is-ce-selected div.lbm-checkout-recap--ce {
    display: flex;
}

[data-checkout-recap].is-ce-selected p.lbm-checkout-recap--ce,
[data-checkout-recap].is-ce-selected span.lbm-checkout-recap--ce {
    display: block;
}

/* Panier : avis aux membres d'un CE ayant une date de livraison groupée ouverte. */
.lbm-cart-aside__ce-notice {
    color: #fff;
    font-weight: 600;
}

/* ==========================================================================
   Lot 25.9 (correction 2), durci §12 (18/09/2026) — paiement « à l'entrepôt »
   grisé quand la livraison groupée CE est cochée au checkout.
   --------------------------------------------------------------------------
   Comportement porté par la classe `.is-ce-selected` sur la carte « entrepôt »
   (`[data-payment-option-entrepot]`) — posée PAR LE SERVEUR au premier rendu
   (`cePreselected`, checkout.html.twig) et maintenue par `initCheckoutDelivery()`
   (lbm-site.js) au changement de mode, même principe que le récapitulatif D16
   ci-dessus. Simple confort visuel : la validation qui compte reste SERVEUR
   (CheckoutGroupDelivery::validatedDate refuse déjà la combinaison
   « livraison_ce + entrepot », inchangée par ce lot).
   Les règles `:has()` juste après restent en complément (navigateurs qui le
   supportent, y compris avant tout JS) mais rien n'en dépend plus : un
   navigateur sans `:has()` ET sans JavaScript actif reste sur le seul repli
   serveur (`cePreselected` au premier rendu).
   ========================================================================== */

/* La note « paiement requis en ligne » n'existe que pour l'annoncer quand la
   livraison CE est cochée ; masquée par défaut. */
.lbm-payment-option__note--ce-blocked {
    display: none;
}

/* Carte « à l'entrepôt » visuellement désactivée dès que la livraison CE est
   cochée. pointer-events: none évite qu'un clic ne coche un choix que le
   serveur refuse de toute façon — un confort honnête, pas une barrière. */
.lbm-payment-grid .lbm-delivery-option__card.is-ce-selected,
.lbm-checkout__grid:has(input[value="livraison_ce"]:checked) .lbm-payment-grid input[value="entrepot"] + .lbm-delivery-option__card {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}

.lbm-payment-grid .lbm-delivery-option__card.is-ce-selected .lbm-payment-option__note--default,
.lbm-checkout__grid:has(input[value="livraison_ce"]:checked) .lbm-payment-grid input[value="entrepot"] + .lbm-delivery-option__card .lbm-payment-option__note--default {
    display: none;
}

.lbm-payment-grid .lbm-delivery-option__card.is-ce-selected .lbm-payment-option__note--ce-blocked,
.lbm-checkout__grid:has(input[value="livraison_ce"]:checked) .lbm-payment-grid input[value="entrepot"] + .lbm-delivery-option__card .lbm-payment-option__note--ce-blocked {
    display: block;
    color: var(--lbm-terracotta);
    font-weight: 600;
}

/* ==========================================================================
   Accueil — « Chez nous, à Annecy » et « Et si on consommait autrement ? »
   (lot 29, R8 — nouvelle présentation du concept, 19/09/2026)

   Deux blocs AJOUTÉS : aucune règle existante n'est modifiée ici. Les images
   sont gérables depuis « Gestion → Apparence » ; leurs cadres portent donc un
   `aspect-ratio` FIXE, pour que la page garde exactement la même hauteur quel
   que soit le fichier déposé par le gérant (R10, stabilité d'affichage).
   ========================================================================== */

.lbm-atelier {
    max-width: 1180px;
    margin: 0 auto;
    padding: 10px 24px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 34px;
    align-items: center;
}

/* Mosaïque : une vue large sur toute la largeur, puis deux vignettes. */
.lbm-atelier__mosaic {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.lbm-atelier__frame {
    border-radius: 18px;
    overflow: hidden;
    border: 1px solid var(--lbm-border);
    /* 4 / 3 = le format des deux visuels livrés (600 × 450). */
    aspect-ratio: 4 / 3;
}

.lbm-atelier__frame--wide {
    grid-column: 1 / -1;
    /* 1200 / 645 — le format du panorama livré, exprimé tel quel plutôt
       qu'arrondi : c'est ce que le gabarit annonce en width/height. */
    aspect-ratio: 1200 / 645;
}

/* `cover` garantit un cadre TOUJOURS rempli, quel que soit le fichier déposé :
   jamais de bande vide au milieu de la mosaïque. */
.lbm-atelier__frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.lbm-atelier__title {
    font-size: 28px;
    margin-top: 18px;
}

.lbm-atelier__intro {
    color: var(--lbm-text-secondary);
    font-size: 16.5px;
    margin: 16px 0 0;
}

/* Liste d'arguments : une vraie <ul> (structure lue par les lecteurs d'écran),
   sans les puces du navigateur — la coche verte en tient lieu visuellement. */
.lbm-atelier__points {
    display: grid;
    gap: 10px;
    margin: 22px 0 0;
    padding: 0;
    list-style: none;
}

.lbm-atelier__points li {
    display: flex;
    gap: 11px;
    align-items: flex-start;
    font-size: 15px;
    color: var(--lbm-text-secondary);
}

.lbm-atelier__check {
    color: var(--lbm-primary);
    font-weight: 800;
}

.lbm-atelier__text .lbm-btn {
    margin-top: 26px;
}

.lbm-manifesto {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 24px 60px;
}

.lbm-manifesto__inner {
    display: grid;
    grid-template-columns: .85fr 1.15fr;
    border-radius: 22px;
    overflow: hidden;
    border: 1px solid var(--lbm-border);
    background: var(--lbm-surface);
}

/* L'image remplit sa colonne quelle que soit la hauteur prise par le texte à
   côté : `min-height` couvre le cas inverse, un texte plus court que l'image. */
.lbm-manifesto__media {
    position: relative;
    min-height: 260px;
}

.lbm-manifesto__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.lbm-manifesto__body {
    padding: 38px 40px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.lbm-manifesto__title {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-weight: 800;
    font-size: clamp(22px, 2.4vw, 30px);
    line-height: 1.2;
}

.lbm-manifesto__text {
    color: var(--lbm-text-secondary);
    font-size: 16px;
    margin: 14px 0 0;
    max-width: 46ch;
}

.lbm-manifesto__actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 24px;
    align-items: center;
}

.lbm-manifesto__note {
    font-size: 14px;
    color: var(--lbm-text-muted);
}

/* Mobile : les deux blocs repassent en une colonne, au même seuil que les
   autres grilles de l'accueil (cf. section 18). L'image du manifeste se place
   alors AU-DESSUS du texte, comme la mosaïque de l'atelier. */
@media (max-width: 860px) {
    .lbm-atelier,
    .lbm-manifesto__inner { grid-template-columns: 1fr; }
    .lbm-manifesto__media { min-height: 220px; }
    .lbm-manifesto__body { padding: 28px 24px; }
}

/* ── « La conscience » — rappel au personnel encore connecté ────────────────
   Affiché sur le site public quand un compte de gestion navigue en croyant
   être un client (cf. _staff_conscience.html.twig pour le pourquoi). En bas à
   GAUCHE : la droite porte déjà le panier et les boutons d'action, et la
   pastille ne doit jamais recouvrir ce sur quoi on clique. */
.lbm-conscience {
    position: fixed;
    left: 16px;
    bottom: 16px;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: min(420px, calc(100vw - 32px));
    padding: 10px 14px 10px 10px;
    border-radius: 16px;
    background: var(--lbm-surface);
    border: 1px solid var(--lbm-border);
    box-shadow: 0 14px 30px rgba(16, 58, 38, .22);
}

.lbm-conscience__img {
    width: 70px;
    height: 70px;
    border-radius: 12px;
    object-fit: cover;
    flex: none;
}

.lbm-conscience__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.lbm-conscience__title {
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    font-size: 14.5px;
    line-height: 1.25;
    color: var(--lbm-ink);
}

.lbm-conscience__text {
    font-size: 13px;
    line-height: 1.35;
    color: var(--lbm-text-secondary);
}

.lbm-conscience__link {
    align-self: flex-start;
    margin-top: 4px;
    font-size: 13px;
    font-weight: 700;
    color: var(--lbm-primary);
    text-decoration: underline;
}

/* Téléphone : le texte passe sous l'image plutôt que de l'écraser. */
@media (max-width: 520px) {
    .lbm-conscience { gap: 10px; padding: 9px 12px 9px 9px; }
    .lbm-conscience__img { width: 52px; height: 52px; }
    .lbm-conscience__text { font-size: 12.5px; }
}
