/*
 * Mosqity : socle graphique du thème enfant mosqitychild (parent Hummingbird 2.1.2).
 *
 * Déclarée dans config/theme.yml (id « mosqitychild-socle », priorité 200) :
 * chargée après theme.css de Hummingbird (priorité 50).
 *
 * Sources des valeurs : brand book Mosqity v1.0 et thème WordPress sentinel 1.2.3
 * (mosqity.fr), avec les arbitrages d'Aurélien du 25/09/2026 (voir GUIDE.md).
 *
 * Règles de rangement (détaillées dans GUIDE.md) :
 * - Polices et jetons hors couche : c'est le seul endroit qui l'emporte sur le
 *   :root de Hummingbird.
 * - Une valeur écrite en dur par Bootstrap ou Hummingbird est redéclarée avec le
 *   MÊME sélecteur, dans la MÊME couche (@layer) que l'original. Notre règle
 *   arrive après et gagne, comme si Hummingbird avait été compilé avec nos
 *   valeurs ; ses propres ajustements des couches supérieures restent actifs.
 * - Jamais de sélecteur d'élément hors couche, jamais de nouvelle couche,
 *   jamais de !important.
 *
 * Sommaire
 *    1. Polices
 *    2. Jetons Mosqity (--mq-*)
 *    3. Correspondance Bootstrap / Hummingbird (--bs-*)
 *    4. Base : titres, liens, sélection, focus, largeur utile
 *    5. Boutons
 *    6. Champs de formulaire
 *    7. Autres composants : bleu de Hummingbird remplacé
 *    8. En-tête Creative Elements (modèle « En-tête Mosqity ») : en-tête
 *       moderne du 02/10/2026, deux états (opaque, posé sur la photo)
 *    9. Pied de page Creative Elements (modèle « Pied de page Mosqity »)
 *   10. Accueil Creative Elements (modèle « Accueil Mosqity ») : héro
 *       pleine largeur, bouton pause du diaporama
 *   11. Sections Creative Elements : gouttière et cartes
 *   12. Fiche produit, vignette et listes (étape 6, 01/10/2026)
 *       12.1  Largeur utile et gouttière unique
 *       12.2  Vignette produit
 *       12.3  Sélecteur de quantité
 *       12.4  Déclinaisons : légendes et pastilles de couleur
 *       12.5  Fiche produit : mise en page
 *       12.6  Fiche produit : sections, prix, description
 *       12.7  Fiche produit : modules, rythme et cibles tactiles
 *       12.8  Aperçu rapide
 *       12.9  Fil d'Ariane
 *       12.10 Listes : composants natifs
 *       12.11 Surcharges de Creative Elements (hors couche) : listes, grilles,
 *             accueil, pied, en-tête et recherche AJAX Search, panneaux du
 *             menu (bord à bord, étape 2a ; soulignés et photo, étape 2b),
 *             surtitre à puce et fonds marine (lot G)
 *       12.12 Options retenues par Aurélien (01/10/2026)
 *   13. Panier et tunnel (lot E du 01/10/2026, étape 7 du 02/10/2026)
 *       13.1 Panier
 *       13.2 Fenêtre d'ajout
 *       13.3 Tunnel
 *       13.4 Fenêtre des CGV et confirmation
 *       13.5 Suivi de commande invité
 *   14. Pages de contenu, erreurs et contact (lot G du 03/10/2026)
 *       14.1 Pages CMS de lecture
 *       14.2 Contact
 *       14.3 Plan du site
 */

/* Ordre des couches de Hummingbird, répété à l'identique (sans effet si
   theme.css est déjà chargé ; protège l'ordre dans le cas contraire). */
@layer vendors, bs-base, bs-components, bs-custom-components, ps-base, ps-components, ps-pages, ps-modules, utilities;


/* ============================================================
   1. POLICES
   Galano Grotesque (René Bieder), licence confirmée par Aurélien le
   25/09/2026. Fichiers complets convertis en woff2, préchargés par
   assets/preload.html. Toute autre graisse demandée se rabat sur la plus
   proche : 400 → Medium, 600 → Bold.
   ============================================================ */

@font-face {
  font-family: "Galano Grotesque";
  src: url("../fonts/galano-grotesque-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Galano Grotesque";
  src: url("../fonts/galano-grotesque-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}


/* ============================================================
   2. JETONS MOSQITY
   Préfixe --mq-, un nom distinct par famille (couleur, taille, rayon…).
   Mêmes valeurs dans les couleurs globales du « Style du thème » de
   Creative Elements (saisie en double, voir GUIDE.md).
   ============================================================ */

:root {
  /* Couleurs de la charte (brand book v1.0, HEX écran) */
  --mq-marine: #173b4f;
  --mq-jaune: #f0ff00;
  --mq-turquoise: #6dd8d6;

  /* Neutres et déclinaisons (thème WordPress) */
  --mq-blanc: #ffffff;
  --mq-blanc-casse: #f6f5f1;
  --mq-noir: #000000;
  --mq-gris: #bebebe;            /* éléments inactifs seulement : 1,86:1 sur blanc */
  --mq-marine-700: #122f3f;      /* survol des aplats marine */
  --mq-marine-100: #e2e9ed;      /* surface marine très claire */
  --mq-turquoise-100: #e5f8f7;   /* surface turquoise très claire */
  --mq-jaune-survol: #e2f000;    /* hors charte, repris du WordPress (validé le 25/09/2026) */
  --mq-jaune-100: #fcffcc;       /* jaune à 20 % sur blanc : fond des alertes d'avertissement (O3 B, 02/10/2026) */
  --mq-texte-attenue: #587280;   /* 5,1:1 sur blanc, 4,7:1 sur blanc cassé */
  --mq-bordure: #dce1e5;         /* séparateurs décoratifs ; les champs sont bordés de marine */
  --mq-erreur: #b3261e;          /* hors charte (aucune couleur d'état), valeur du WordPress */

  /* Rôles. Texte courant noir, titres, liens et interface en marine,
     comme sur mosqity.fr (arbitrage du 25/09/2026). */
  --mq-couleur-texte: var(--mq-noir);
  --mq-couleur-titre: var(--mq-marine);
  --mq-couleur-lien: var(--mq-marine);
  --mq-couleur-lien-survol: var(--mq-marine-700);
  --mq-couleur-focus: var(--mq-marine);   /* jaune sur les fonds sombres, voir §4 */

  /* Typographie */
  --mq-police: "Galano Grotesque", "Poppins", "Century Gothic", sans-serif;
  --mq-graisse-texte: 500;       /* Medium : texte courant (charte) */
  --mq-graisse-titre: 700;       /* Bold : titres (charte) */
  --mq-taille-hero: clamp(3.5rem, 6.8vw, 6.125rem);      /* 56 à 98px ; non employé : le héro CE garde 72 / 56 / 40px (B3) */
  --mq-taille-titre: clamp(2.25rem, 3.5vw, 3.1875rem);   /* 36 à 51px : h1, h2 */
  --mq-taille-h3: 1.6875rem;     /* 27px */
  --mq-taille-h4: 1.4375rem;     /* 23px */
  --mq-taille-h5: 1.3125rem;     /* 21px */
  --mq-taille-h6: 1.125rem;      /* 18px */
  --mq-taille-label: 0.75rem;    /* 12px : boutons, navigation, étiquettes */
  --mq-taille-surtitre: 0.6875rem; /* 11px */
  --mq-interligne-titre: 1.02;
  --mq-interligne-sous-titre: 1.15;
  --mq-approche-capitales: 0.08em;
  --mq-approche-surtitre: 0.14em;

  /* Formes */
  --mq-rayon-carte: 19px;
  --mq-rayon-photo: 30px;
  --mq-rayon-champ: 14px;
  --mq-rayon-pilule: 999px;
  --mq-trait: 1.5px;             /* bordure des boutons et des champs */

  /* Espacements (base 4) */
  --mq-espace-1: 4px;
  --mq-espace-2: 8px;
  --mq-espace-3: 12px;
  --mq-espace-4: 16px;
  --mq-espace-5: 24px;           /* gouttière */
  --mq-espace-6: 32px;
  --mq-espace-7: 48px;
  --mq-espace-8: 64px;
  --mq-espace-9: 96px;           /* respiration de section */
  --mq-espace-10: 128px;

  /* Largeur utile, ombre, mouvement */
  --mq-largeur-contenu: 1240px;
  --mq-ombre-douce: 0 8px 28px rgba(23, 59, 79, 0.1);
  --mq-courbe: cubic-bezier(0.22, 1, 0.36, 1);
  --mq-duree-rapide: 150ms;
  --mq-duree-base: 250ms;
}


/* ============================================================
   3. CORRESPONDANCE BOOTSTRAP / HUMMINGBIRD
   Même sélecteur que Bootstrap (hors couche, déclaré après) : nos valeurs
   gagnent. Les variantes « -rgb » sont écrites en chiffres, Bootstrap les
   combine avec une opacité.
   ============================================================ */

:root,
[data-bs-theme=light] {
  /* Primaire = marine : Hummingbird écrit du blanc sur la primaire
     (badges produit, pastille du panier) ; le jaune est porté par .btn-primary. */
  --bs-primary: var(--mq-marine);
  --bs-primary-rgb: 23, 59, 79;
  --bs-primary-text-emphasis: var(--mq-marine);
  --bs-primary-bg-subtle: var(--mq-marine-100);
  --bs-primary-border-subtle: #a2b1b9;

  --bs-secondary: var(--mq-texte-attenue);
  --bs-secondary-rgb: 88, 114, 128;
  --bs-secondary-text-emphasis: var(--mq-marine-700);
  --bs-secondary-bg-subtle: var(--mq-marine-100);
  --bs-secondary-border-subtle: #a2b1b9;

  --bs-danger: var(--mq-erreur);
  --bs-danger-rgb: 179, 38, 30;
  --bs-danger-text-emphasis: #480f0c;
  --bs-danger-bg-subtle: #f0d4d2;
  --bs-danger-border-subtle: #e1a8a5;

  /* Couleurs d'état (option O3 B, décision d'Aurélien du 02/10/2026,
     valeurs du cadrage de l'étape 7, 4.12). Déclarées ici sur :root,
     exception voulue à la règle 6 du GUIDE (§5.2) : alertes, toasts,
     cercle du tunnel, « + » de la quantité, coche de la fenêtre d'ajout et
     classes posées par le JavaScript (jauge du mot de passe, icônes)
     suivent d'eux-mêmes. Succès en marine, sa surface en turquoise très
     clair (texte marine, 10,7:1) ; information sur blanc cassé (10,8:1) ;
     avertissement sur jaune à 20 % (11,4:1), bord jaune, jamais de texte
     jaune. Les couleurs de base --bs-info et --bs-warning ne sont pas
     redéclarées : le cadrage ne leur donne pas de valeur et seule la
     disponibilité les emploie en texte, déjà réglée sur l'élément (§12.5).
     Le rouge reste celui de Mosqity (ci-dessus). */
  --bs-success: var(--mq-marine);
  --bs-success-rgb: 23, 59, 79;
  --bs-success-text-emphasis: var(--mq-marine);
  --bs-success-bg-subtle: var(--mq-turquoise-100);
  --bs-success-border-subtle: var(--mq-turquoise);

  --bs-info-text-emphasis: var(--mq-marine);
  --bs-info-bg-subtle: var(--mq-blanc-casse);
  --bs-info-border-subtle: var(--mq-bordure);

  --bs-warning-text-emphasis: var(--mq-marine);
  --bs-warning-bg-subtle: var(--mq-jaune-100);
  --bs-warning-border-subtle: var(--mq-jaune);

  --bs-light: var(--mq-blanc-casse);
  --bs-light-rgb: 246, 245, 241;

  --bs-dark: var(--mq-marine);
  --bs-dark-rgb: 23, 59, 79;
  --bs-dark-text-emphasis: var(--mq-marine);
  --bs-dark-bg-subtle: var(--mq-marine-100);
  --bs-dark-border-subtle: #a2b1b9;

  /* Texte et fonds */
  --bs-font-sans-serif: var(--mq-police);
  --bs-body-font-family: var(--mq-police);
  --bs-body-font-weight: var(--mq-graisse-texte);
  /* Taille (1rem) et interligne (1.5) : valeurs standard de Hummingbird, conservées. */
  --bs-body-color: var(--mq-couleur-texte);
  --bs-body-color-rgb: 0, 0, 0;
  --bs-secondary-color: var(--mq-texte-attenue);
  --bs-secondary-color-rgb: 88, 114, 128;
  --bs-secondary-bg: var(--mq-marine-100);
  --bs-secondary-bg-rgb: 226, 233, 237;
  --bs-tertiary-color: var(--mq-texte-attenue);
  --bs-tertiary-color-rgb: 88, 114, 128;
  --bs-tertiary-bg: var(--mq-blanc-casse);
  --bs-tertiary-bg-rgb: 246, 245, 241;
  --bs-heading-color: var(--mq-couleur-titre);
  --bs-highlight-color: var(--mq-marine);
  --bs-highlight-bg: var(--mq-jaune);

  /* Liens : les quatre variables, Bootstrap recolore via la version -rgb. */
  --bs-link-color: var(--mq-couleur-lien);
  --bs-link-color-rgb: 23, 59, 79;
  --bs-link-hover-color: var(--mq-couleur-lien-survol);
  --bs-link-hover-color-rgb: 18, 47, 63;

  /* Bordures et rayons */
  --bs-border-color: var(--mq-bordure);
  --bs-border-radius: var(--mq-rayon-carte);
  --bs-border-radius-sm: var(--mq-rayon-champ);
  --bs-border-radius-lg: var(--mq-rayon-carte);
  --bs-border-radius-xl: var(--mq-rayon-photo);
  --bs-border-radius-xxl: var(--mq-rayon-photo);
  --bs-border-radius-pill: var(--mq-rayon-pilule);

  /* Ombres : la marque n'en use presque pas ; ombre douce marine. */
  --bs-box-shadow: var(--mq-ombre-douce);
  --bs-box-shadow-sm: 0 2px 8px rgba(23, 59, 79, 0.08);
  --bs-box-shadow-lg: 0 16px 48px rgba(23, 59, 79, 0.14);
  --bs-box-shadow-md: var(--mq-ombre-douce);   /* variable propre à Hummingbird (survol des miniatures) */

  /* Focus et validation. --bs-focus-ring-* ne sert qu'à .focus-ring
     (miniatures de la fiche produit) et aux pastilles de couleur. */
  --bs-focus-ring-width: 2px;
  --bs-focus-ring-color: var(--mq-marine);
  --bs-form-invalid-color: var(--mq-erreur);
  --bs-form-invalid-border-color: var(--mq-erreur);

  /* État valide neutralisé (O3 B) : un champ valide garde le bord marine
     d'un champ normal ; coche, halo et libellé coloré sont retirés au §6. */
  --bs-form-valid-color: var(--mq-marine);
  --bs-form-valid-border-color: var(--mq-marine);

  /* Mouvement (variable propre à Hummingbird) */
  --bs-transition-default: all var(--mq-duree-rapide) var(--mq-courbe);

  /* Crochets lus par Hummingbird mais jamais déclarés (liens du bandeau
     supérieur de l'en-tête). */
  --header-top-color: var(--mq-couleur-lien);
  --header-top-color-hover: var(--mq-couleur-lien-survol);
}

/* Réduction des animations demandée par le système : plus de transition
   sur les composants de Hummingbird (Bootstrap coupe déjà les siennes). */
@media (prefers-reduced-motion: reduce) {
  :root,
  [data-bs-theme=light] {
    --bs-transition-default: none;
  }
}


/* ============================================================
   4. BASE
   ============================================================ */

@layer bs-base {
  /* Titres : Bold, approche 0 (charte), marine via --bs-heading-color.
     Interligne 1.02, sauf h3 et h4 à 1.15 (comme sur le WordPress). */
  .h1, .h2, .h3, .h4, .h5, .h6, .left-block__title, .right-block__title, h1, h2, h3, h4, h5, h6 {
    font-weight: var(--mq-graisse-titre);
    letter-spacing: 0;
    line-height: var(--mq-interligne-titre);
  }

  .h1, h1 {
    font-size: var(--mq-taille-titre);
  }

  .h2, h2 {
    font-size: var(--mq-taille-titre);
  }

  .h3, .left-block__title, .right-block__title, h3 {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
  }

  .h4, h4 {
    font-size: var(--mq-taille-h4);
    line-height: var(--mq-interligne-sous-titre);
  }

  .h5, h5 {
    font-size: var(--mq-taille-h5);
  }

  .h6, h6 {
    font-size: var(--mq-taille-h6);
  }

  ::selection {
    background-color: var(--mq-jaune);
    color: var(--mq-marine);
  }

  /* Focus : anneau marine de 2px décalé de 2px (le turquoise du WordPress
     n'atteint que 1,69:1 sur blanc). Les composants qui le suppriment sont
     traités plus bas. */
  :focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  /* Largeur utile de 1240px au-delà de 1400px, comme mosqity.fr
     (1320px chez Bootstrap). */
  @media (min-width: 1400px) {
    .checkout-steps__mobile, .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xs, .container-xxl {
      max-width: calc(var(--mq-largeur-contenu) + var(--bs-gutter-x));
    }
  }
}

@layer ps-base {
  /* Sur les fonds sombres, l'anneau de focus passe en jaune. */
  .footer__main,
  .copyright {
    --mq-couleur-focus: var(--mq-jaune);
  }

  /* Logo d'en-tête : un SVG n'a pas de dimensions pour PrestaShop,
     la hauteur est fixée ici (40px, comme sur mosqity.fr). */
  .header-bottom .navbar-brand .logo {
    height: 2.5rem;
    object-fit: contain;
  }
}

@layer ps-components {
  /* Titres de page natifs (panier, pages CMS, compte, contact, étape en
     cours du tunnel) à l'échelle h1 du thème, comme les listes et
     l'accueil (décision B1 du 01/10/2026). */
  .page-title-section {
    font-size: var(--mq-taille-titre);
    font-weight: var(--mq-graisse-titre);
    line-height: var(--mq-interligne-titre);
  }

  /* Titres des modules (produits phares, même catégorie, déjà vus, ventes
     croisées, produits associés, avis) au jeton h3, sous le H1. */
  .section-title {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* Liens soulignés dans les textes courants de PrestaShop (descriptions,
     pages CMS), pas dans l'interface. Pour les textes Creative Elements, le
     réglage se fait dans son Style du thème (sa CSS est hors couche). */
  .rich-text a:not(.btn) {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  /* Hummingbird 2.1.2 souligne .rich-text a : pas les boutons.
     :not(.btn-basic) garde le soulignement voulu des boutons texte. */
  .rich-text a.btn:not(.btn-basic) {
    text-decoration: none;
  }

  /* Liens d'interface de Hummingbird écrits avec la couleur du texte
     courant (noir) : passés en marine. Les survols (:hover) de Hummingbird,
     plus spécifiques, restent actifs. */
  .left-block__title-link, .right-block__title-link {
    color: var(--mq-couleur-titre);
  }

  .left-block__link, .right-block__link {
    color: var(--mq-couleur-lien);
  }

  .category-tree__title-link {
    color: var(--mq-couleur-titre);
  }

  .category-tree__item-link {
    color: var(--mq-couleur-lien);
  }

  .subcategory__link {
    color: var(--mq-couleur-lien);
  }

  .account-menu__link {
    color: var(--mq-couleur-lien);
  }

  /* Reposé après .account-menu__link (même spécificité). */
  .account-menu__link--signout, .account-menu__link--signout:hover {
    color: var(--bs-danger);
  }

  @media (min-width: 992px) {
    /* Menu latéral défilant (Hummingbird 2.1.2) : anneau tracé à
       l'intérieur pour ne pas être rogné. */
    .account-menu--sidebar .account-menu__link:focus-visible {
      outline-offset: -2px;
    }
  }

  .product-line__title {
    color: var(--mq-couleur-lien);
  }

  .sitemap__link {
    color: var(--mq-couleur-lien);
  }

  .header-block__action-btn {
    color: var(--mq-couleur-lien);
  }

  .checkout-steps__btn {
    color: var(--mq-couleur-lien);
  }

  .checkout-steps__step--current .checkout-steps__btn {
    color: var(--mq-couleur-lien);
  }

  /* Pastilles des étapes du tunnel : voir §13.3. */

  /* Champ de quantité : marge réduite, sinon trois chiffres ne tiennent
     pas dans les 4rem prévus par Hummingbird. */
  .quantity-button input {
    padding-inline: 0.5rem;
  }
}

@layer ps-modules {
  #header .ps-contactinfo a {
    color: var(--mq-couleur-lien);
  }

  .search-filters__link {
    color: var(--mq-couleur-lien);
  }

  /* Réassurance, version sombre (fond marine) : focus et survol en jaune. */
  .blockreassurance--dark {
    --mq-couleur-focus: var(--mq-jaune);
  }

  .blockreassurance--dark .reassurance--link:hover .reassurance__title {
    color: var(--mq-jaune);
  }

  /* Légende du carrousel (voile marine) : les titres prennent la couleur
     claire de la légende au lieu du marine des titres. */
  .ps-imageslider__figcaption {
    --bs-heading-color: currentColor;
  }
}


/* ============================================================
   5. BOUTONS
   Pilules du WordPress : 12px en capitales, approche 0.08em, Medium,
   bordure 1.5px. Couche bs-components, comme l'original de Bootstrap.
   ============================================================ */

@layer bs-components {
  .btn {
    --bs-btn-padding-x: 1.75rem;   /* 28px */
    --bs-btn-padding-y: 0.875rem;  /* 14px */
    --bs-btn-font-size: var(--mq-taille-label);
    --bs-btn-font-weight: var(--mq-graisse-texte);
    --bs-btn-line-height: 1.45;
    --bs-btn-color: var(--mq-marine);
    --bs-btn-border-width: var(--mq-trait);
    --bs-btn-border-radius: var(--mq-rayon-pilule);
    --bs-btn-disabled-opacity: 0.4;
    --bs-btn-focus-box-shadow: none;
    letter-spacing: var(--mq-approche-capitales);
    text-transform: uppercase;

    /* Capitales de Galano recentrées : 1px de plus en haut, 1px de moins
       en bas, hauteur inchangée (B9, contrôle entete-accueil-pied-28). */
    padding-block: calc(var(--bs-btn-padding-y) + 1px) calc(var(--bs-btn-padding-y) - 1px);
  }

  /* La règle .btn ci-dessus arrive après les variantes de Bootstrap (même
     couche, même spécificité) : on leur rend leur couleur de texte d'origine. */
  .btn-success {
    --bs-btn-color: #fff;
  }

  .btn-info {
    --bs-btn-color: #000;
  }

  .btn-warning {
    --bs-btn-color: #000;
  }

  .btn-light {
    --bs-btn-color: #000;
  }

  .btn-dark {
    --bs-btn-color: #fff;
  }

  .btn-outline-secondary {
    --bs-btn-color: #6c757d;
  }

  .btn-outline-success {
    --bs-btn-color: #188251;
  }

  .btn-outline-info {
    --bs-btn-color: #0dcaf0;
  }

  .btn-outline-warning {
    --bs-btn-color: #ffc107;
  }

  .btn-outline-light {
    --bs-btn-color: #f8f9fa;
  }

  .btn-outline-dark {
    --bs-btn-color: #212529;
  }

  .btn:focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  .btn-check:focus-visible + .btn {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  .btn-group-sm > .btn, .btn-sm {
    --bs-btn-padding-y: 0.625rem;  /* 10px */
    --bs-btn-padding-x: 1.25rem;   /* 20px */
    --bs-btn-font-size: var(--mq-taille-surtitre);
    --bs-btn-border-radius: var(--mq-rayon-pilule);
  }

  .btn-group-lg > .btn, .btn-lg {
    --bs-btn-padding-y: 1.125rem;  /* 18px */
    --bs-btn-padding-x: 2.25rem;   /* 36px */
    --bs-btn-font-size: var(--mq-taille-label);
    --bs-btn-border-radius: var(--mq-rayon-pilule);
  }

  /* Bouton principal : pilule jaune, texte marine (Ajouter au panier,
     Commander, S'abonner…). */
  .btn-primary {
    --bs-btn-color: var(--mq-marine);
    --bs-btn-bg: var(--mq-jaune);
    --bs-btn-border-color: var(--mq-jaune);
    --bs-btn-hover-color: var(--mq-marine);
    --bs-btn-hover-bg: var(--mq-jaune-survol);
    --bs-btn-hover-border-color: var(--mq-jaune-survol);
    --bs-btn-focus-shadow-rgb: 23, 59, 79;
    --bs-btn-active-color: var(--mq-marine);
    --bs-btn-active-bg: var(--mq-jaune-survol);
    --bs-btn-active-border-color: var(--mq-jaune-survol);
    --bs-btn-disabled-color: var(--mq-marine);
    --bs-btn-disabled-bg: var(--mq-jaune);
    --bs-btn-disabled-border-color: var(--mq-jaune);
  }

  /* Pilule marine, texte blanc. */
  .btn-secondary {
    --bs-btn-color: var(--mq-blanc);
    --bs-btn-bg: var(--mq-marine);
    --bs-btn-border-color: var(--mq-marine);
    --bs-btn-hover-color: var(--mq-blanc);
    --bs-btn-hover-bg: var(--mq-marine-700);
    --bs-btn-hover-border-color: var(--mq-marine-700);
    --bs-btn-focus-shadow-rgb: 23, 59, 79;
    --bs-btn-active-color: var(--mq-blanc);
    --bs-btn-active-bg: var(--mq-marine-700);
    --bs-btn-active-border-color: var(--mq-marine-700);
    --bs-btn-disabled-color: var(--mq-blanc);
    --bs-btn-disabled-bg: var(--mq-marine);
    --bs-btn-disabled-border-color: var(--mq-marine);
  }

  /* Pilule contour marine. */
  .btn-outline-primary {
    --bs-btn-color: var(--mq-marine);
    --bs-btn-border-color: var(--mq-marine);
    --bs-btn-hover-color: var(--mq-marine);
    --bs-btn-hover-bg: var(--mq-marine-100);
    --bs-btn-hover-border-color: var(--mq-marine);
    --bs-btn-focus-shadow-rgb: 23, 59, 79;
    --bs-btn-active-color: var(--mq-marine);
    --bs-btn-active-bg: var(--mq-marine-100);
    --bs-btn-active-border-color: var(--mq-marine);
    --bs-btn-disabled-color: var(--mq-marine);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--mq-marine);
  }

  .btn-link {
    --bs-btn-color: var(--bs-link-color);
    --bs-btn-focus-shadow-rgb: 23, 59, 79;
  }

  .btn-danger {
    --bs-btn-color: var(--mq-blanc);
    --bs-btn-hover-color: var(--mq-blanc);
    --bs-btn-active-color: var(--mq-blanc);
    --bs-btn-disabled-color: var(--mq-blanc);
    --bs-btn-bg: var(--mq-erreur);
    --bs-btn-border-color: var(--mq-erreur);
    --bs-btn-hover-bg: #98201a;
    --bs-btn-hover-border-color: #8f1f18;
    --bs-btn-focus-shadow-rgb: 179, 38, 30;
    --bs-btn-active-bg: #8f1f18;
    --bs-btn-active-border-color: #861d17;
    --bs-btn-disabled-bg: var(--mq-erreur);
    --bs-btn-disabled-border-color: var(--mq-erreur);
  }

  .btn-outline-danger {
    --bs-btn-color: var(--mq-erreur);
    --bs-btn-border-color: var(--mq-erreur);
    --bs-btn-hover-color: var(--mq-blanc);
    --bs-btn-hover-bg: var(--mq-erreur);
    --bs-btn-hover-border-color: var(--mq-erreur);
    --bs-btn-focus-shadow-rgb: 179, 38, 30;
    --bs-btn-active-color: var(--mq-blanc);
    --bs-btn-active-bg: var(--mq-erreur);
    --bs-btn-active-border-color: var(--mq-erreur);
    --bs-btn-disabled-color: var(--mq-erreur);
    --bs-btn-disabled-border-color: var(--mq-erreur);
  }

  /* Boutons contour posés sur le .btn-primary d'un gabarit : une seule
     liste de variables (étape 7). Contour marine, comme
     .btn-outline-primary ; ces variables battent celles de .btn-primary
     par la spécificité (0,2,0), survol marine très clair (9,64:1).
     - Œil du mot de passe (tunnel, connexion, inscription, nouveau mot de
       passe) : au lieu d'un second jaune collé au champ (cadrage 4.15). Le
       rayon du champ vient de `.input-group .btn` (§6).
     - « Appliquer » du code promo (T3.1) : « Commander », juste dessous,
       reste le seul jaune. Écart assumé au 4.7, qui plaçait cette règle au
       §13 en ps-components : une liste unique. Le bouton d'étape de
       l'étape 2 (T3.12, E13) a sa propre règle, juste dessous. */
  .password-field .btn, .cart-voucher__form .btn {
    --bs-btn-color: var(--mq-marine);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--mq-marine);
    --bs-btn-hover-color: var(--mq-marine);
    --bs-btn-hover-bg: var(--mq-marine-100);
    --bs-btn-hover-border-color: var(--mq-marine);
    --bs-btn-focus-shadow-rgb: 23, 59, 79;
    --bs-btn-active-color: var(--mq-marine);
    --bs-btn-active-bg: var(--mq-marine-100);
    --bs-btn-active-border-color: var(--mq-marine);
    --bs-btn-disabled-color: var(--mq-marine);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--mq-marine);
  }

  /* Étape 2, état « Enregistrer » (T3.12, E13 ; relevé du 12/10/2026,
     séance 3) : formulaire de livraison ouvert, facturation différente,
     deux adresses au moins. Le gabarit montre deux jaunes, « Enregistrer »
     et le bouton d'étape (checkout-step-buttons.tpl, Hummingbird 2.1),
     rattaché par l'attribut form au formulaire vide de l'étape. Le bouton
     d'étape passe en contour : un seul jaune. Règle séparée : un :has()
     inconnu ferait abandonner toute la liste ci-dessus (œil du mot de
     passe, code promo). Sans :has(), deux jaunes, rendu natif. État
     désactivé laissé au §12.12. */
  #checkout-addresses-step:has(#delivery-address, #invoice-address) .btn-primary[name="confirm-addresses"]:not([data-ps-action]) {
    --bs-btn-color: var(--mq-marine);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--mq-marine);
    --bs-btn-hover-color: var(--mq-marine);
    --bs-btn-hover-bg: var(--mq-marine-100);
    --bs-btn-hover-border-color: var(--mq-marine);
    --bs-btn-focus-shadow-rgb: 23, 59, 79;
    --bs-btn-active-color: var(--mq-marine);
    --bs-btn-active-bg: var(--mq-marine-100);
    --bs-btn-active-border-color: var(--mq-marine);
  }

  /* Déclinaisons en radio (Hummingbird 2.1.2 : .btn-check +
     .btn-outline-primary) : option cochée en pilule marine pleine, texte
     blanc (11,8:1), au lieu de 1,2:1 sans reprise (WCAG 1.4.11). Capitales
     de 12px gardées, comme les boutons (Q7 du rapport de migration). */
  .product-variant__radio .btn-outline-primary {
    --bs-btn-active-color: var(--mq-blanc);
    --bs-btn-active-bg: var(--mq-marine);
    --bs-btn-active-border-color: var(--mq-marine);
  }
}

@layer bs-custom-components {
  /* Boutons icône de Hummingbird (quantité, ajout rapide, zoom) : ils
     tirent leur marge de --bs-btn-padding-y et la taille de l'icône de celle
     du texte (1.25em) ; on leur rend leurs dimensions d'origine. */
  .btn-square-icon {
    --bs-btn-padding-y: 0.375rem;

    /* Boutons à icône seule : remplissage symétrique, le recentrage de B9 ne
       vaut que pour les capitales. */
    padding-block: var(--bs-btn-padding-y);
  }

  .btn-square-icon .material-icons {
    font-size: 1.25rem;
  }

  /* Œil du mot de passe (icône seule, form-fields.tpl) : remplissage
     symétrique, comme les boutons à icône (B9). */
  [data-ps-action="toggle-password"] {
    padding-block: var(--bs-btn-padding-y);
  }

  /* Boutons tertiaires de Hummingbird (tri, filtres actifs, retour) :
     éléments d'interface, donc marine plutôt que la couleur du texte. */
  .btn-tertiary {
    --bs-btn-color: var(--mq-marine);
  }

  .btn-outline-tertiary {
    --bs-btn-color: var(--mq-marine);
  }

  /* Boutons texte (.btn-basic : « Annuler » et « L'adresse de facturation
     est différente… » au tunnel, « Mot de passe oublié ? », « Retour à la
     connexion ») soulignés, trait épaissi au survol (T3.12, décision 5 du
     02/10/2026) : en 12px capitales marine sans bord, ils avaient le style
     exact d'une étiquette de champ. Sept emplois dans six gabarits, tous
     des actions texte. */
  .btn-basic {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  .btn-basic:hover {
    text-decoration-thickness: var(--mq-trait);
  }

  .modal-title {
    color: var(--mq-couleur-titre);
  }
}


/* ============================================================
   6. CHAMPS DE FORMULAIRE
   Bordure marine 1.5px, rayon 14px, champs et listes de 48px, comme les
   boutons (B9, 01/10/2026). Étiquettes en capitales de 12px.
   ============================================================ */

@layer bs-components {
  .form-label {
    color: var(--mq-marine);
    font-size: var(--mq-taille-label);
    font-weight: var(--mq-graisse-texte);
    letter-spacing: var(--mq-approche-capitales);
    margin-bottom: 0.5rem;
    text-transform: uppercase;
  }

  .form-control {
    border: var(--mq-trait) solid var(--mq-marine);
    border-radius: var(--mq-rayon-champ);
    color: var(--mq-marine);
    font-weight: var(--mq-graisse-texte);
    padding: 0.65rem 1.125rem;
  }

  .form-control:focus {
    border-color: var(--mq-marine);
    box-shadow: none;
    color: var(--mq-marine);
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  /* Tailles -sm et -lg et bouton de fichier : marges d'origine reposées
     après notre .form-control (même couche, même spécificité). */
  .form-control::file-selector-button {
    margin: -0.65rem -1.125rem;
    margin-inline-end: 1.125rem;
    padding: 0.65rem 1.125rem;
  }

  .form-control-sm {
    border-radius: var(--mq-rayon-champ);
    padding: 0.25rem 0.5rem;
  }

  .form-control-sm::file-selector-button {
    margin: -0.25rem -0.5rem;
    margin-inline-end: 0.5rem;
    padding: 0.25rem 0.5rem;
  }

  .form-control-lg {
    border-radius: var(--mq-rayon-champ);
    padding: 0.5rem 1rem;
  }

  .form-control-lg::file-selector-button {
    margin: -0.5rem -1rem;
    margin-inline-end: 1rem;
    padding: 0.5rem 1rem;
  }

  /* Bouton « Choisir un fichier » (pièce jointe du contact et tout champ de
     fichier du site ; lot G, cadrage 4.4, décision d'Aurélien du
     03/10/2026) : marine très clair, texte marine (9,64:1), 12px en
     capitales Medium, comme les étiquettes ; au survol, --mq-bordure
     (8,98:1). Bootstrap le peint en --bs-tertiary-bg (blanc cassé, §3), puis
     --bs-secondary-bg au survol : mêmes sélecteurs, même couche, redéclarés
     après lui. Le trait qui le sépare du nom du fichier garde la couleur du
     bord du champ (marine). Interligne de 24px, celui du texte du champ, et
     calage en haut de la ligne : en 12px, le bouton remplit toute la hauteur
     du champ sans le grandir (aligné sur la ligne de base, il le grandissait
     de 1px ; mesuré en local, 46,8px comme les autres champs). */
  .form-control::file-selector-button {
    background-color: var(--mq-marine-100);
    color: var(--mq-marine);
    font-size: var(--mq-taille-label);
    font-weight: var(--mq-graisse-texte);
    letter-spacing: var(--mq-approche-capitales);
    line-height: 1.5rem;
    text-transform: uppercase;
    vertical-align: top;
  }

  .form-control:hover:not(:disabled):not([readonly])::file-selector-button {
    background-color: var(--mq-bordure);
  }

  textarea.form-control {
    border-radius: var(--mq-rayon-carte);
  }

  .form-select {
    --bs-form-select-bg-img: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23173b4f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
    border: var(--mq-trait) solid var(--mq-marine);
    border-radius: var(--mq-rayon-champ);
    color: var(--mq-marine);
    cursor: pointer;
    font-weight: var(--mq-graisse-texte);
    padding: 0.65rem 2.75rem 0.65rem 1.125rem;
    background-position: right 1.125rem center;
  }

  .form-select:focus {
    border-color: var(--mq-marine);
    box-shadow: none;
  }

  .form-select:focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  .form-select-sm {
    border-radius: var(--mq-rayon-champ);
    padding-bottom: 0.25rem;
    padding-left: 0.5rem;
    padding-top: 0.25rem;
  }

  .form-select-lg {
    border-radius: var(--mq-rayon-champ);
    padding-bottom: 0.5rem;
    padding-left: 1rem;
    padding-top: 0.5rem;
  }

  /* Dans un groupe de saisie (mot de passe, quantité), le bouton prend le
     rayon du champ plutôt que la pilule. */
  .input-group .btn {
    --bs-btn-border-radius: var(--mq-rayon-champ);
  }

  .form-check-input {
    border: var(--mq-trait) solid var(--mq-marine);
  }

  /* Anneau de focus au clavier seulement (:focus-visible), pas au clic. */
  .form-check-input:focus {
    border-color: var(--mq-marine);
    box-shadow: none;
  }

  .form-check-input:focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  .form-check-input:checked {
    background-color: var(--mq-marine);
    border-color: var(--mq-marine);
  }

  /* Coche, point et tiret jaunes sur fond marine (design system, 10,7:1). */
  .form-check-input:checked[type=checkbox] {
    --bs-form-check-bg-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23f0ff00' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E");
  }

  .form-check-input:checked[type=radio] {
    --bs-form-check-bg-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='2' fill='%23f0ff00'/%3E%3C/svg%3E");
  }

  .form-check-input[type=checkbox]:indeterminate {
    --bs-form-check-bg-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23f0ff00' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E");
    background-color: var(--mq-marine);
    border-color: var(--mq-marine);
  }

  /* Champs et cases désactivés (design system) : fond blanc cassé,
     transparence, curseur « interdit ». */
  .form-control:disabled {
    background-color: var(--mq-blanc-casse);
    cursor: not-allowed;
    opacity: 0.55;
  }

  .form-select:disabled {
    background-color: var(--mq-blanc-casse);
    cursor: not-allowed;
    opacity: 0.55;
  }

  .form-check-input:disabled {
    opacity: 0.45;
  }

  .form-check-input:disabled ~ .form-check-label, .form-check-input[disabled] ~ .form-check-label {
    cursor: not-allowed;
    opacity: 0.45;
  }

  .form-check-label {
    cursor: pointer;
  }

  .form-switch .form-check-input:focus {
    --bs-form-switch-bg: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23a2b1b9'/%3E%3C/svg%3E");
  }

  .form-range::-webkit-slider-thumb {
    background-color: var(--mq-marine);
  }

  .form-range::-moz-range-thumb {
    background-color: var(--mq-marine);
  }

  .form-range::-webkit-slider-thumb:active {
    background-color: var(--mq-marine-100);
  }

  .form-range::-moz-range-thumb:active {
    background-color: var(--mq-marine-100);
  }

  .form-range:focus::-webkit-slider-thumb {
    box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(23, 59, 79, 0.25);
  }

  .form-range:focus::-moz-range-thumb {
    box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(23, 59, 79, 0.25);
  }

  /* Pictogramme d'erreur dans le rouge Mosqity (#b3261e). Mêmes listes de
     sélecteurs que Hummingbird (validation serveur .is-invalid, validation
     du navigateur .was-validated, champs .error des avis produit).
     Étape 7, tranche 3 (T3.8) : picto à 18px du bord, comme le chevron des
     listes (Bootstrap : 9px), texte arrêté 12px avant lui ; dans une liste,
     chevron gardé à 18px et picto à 44px. Hummingbird 2.1.2 : les champs
     .error des avis ne reçoivent plus les règles de Bootstrap (@extend
     remplacé par un mixin en ps-modules) ; leurs no-repeat, taille du
     picto et halos sont repris au §12.7. Les variantes .form-select et
     .form-check-input nées de l'@extend, sans cible, sont retirées des
     listes du §6 (ce paragraphe, état valide et halo). */
  .form-control.is-invalid, .product-comment-modal input.form-control[name=comment_title].error, .product-comment-modal input.form-control[name=customer_name].error, .product-comment-modal textarea.form-control.error, .was-validated .form-control:invalid {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23b3261e' viewBox='0 0 12 12'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23b3261e' stroke='none'/%3E%3C/svg%3E");
    background-position: right 1.125rem center;
    padding-right: 3rem;
  }

  /* Zones de texte : picto en haut à droite, comme chez Bootstrap. Règle
     reposée après la précédente : pour la zone de texte des avis produit,
     les deux sélecteurs ont la même spécificité (0,3,1) et la règle
     ci-dessus l'aurait emporté. */
  .product-comment-modal textarea.form-control.error, .was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {
    background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
    padding-right: calc(1.5em + 0.75rem);
  }

  .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"], .was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"] {
    --bs-form-select-bg-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23b3261e' viewBox='0 0 12 12'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23b3261e' stroke='none'/%3E%3C/svg%3E");
    background-position: right 1.125rem center, center right 2.75rem;
    padding-right: 4.5rem;
  }

  /* Étape 7, tranche 1 (cadrage 4.15, 02/10/2026). Règles valables pour
     tout le site : tunnel, connexion, inscription, adresses, contact. */

  /* Aides des champs lisibles : 14px, en bloc (sur le span du noyau, la
     marge haute de 4px de Bootstrap restait sans effet). */
  .form-text {
    display: block;
    font-size: 0.875rem;
    line-height: 1.4;
  }

  /* Liens dans les libellés de case (consentement, CGV) soulignés : marine
     dans du texte noir ne fait que 1,8:1, le trait distingue le lien
     (WCAG 1.4.1). Les libellés des facettes natives de ps_facetedsearch
     (a.search-filters__link, facets.tpl) ne sont pas des liens de texte :
     exclus. */
  .form-check-label a:not(.search-filters__link) {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  /* Cases et boutons radio de 20px, à 12px de leur libellé (au lieu de
     8px), centrés sur la première ligne de 24px. L'interrupteur garde ses
     proportions (2em sur 1em) ; les cases inversées (.form-check-reverse)
     gardent le retrait de Bootstrap, à droite. Vaut pour tout le site :
     aussi les facettes et les retours produit du compte. Les déclinaisons
     en radio de la fiche sont des pilules depuis Hummingbird 2.1.2 (§5). */
  .form-check-input {
    width: 1.25rem;
    height: 1.25rem;
  }

  .form-check:not(.form-switch, .form-check-reverse) {
    padding-left: 2rem;
  }

  .form-check:not(.form-switch, .form-check-reverse) .form-check-input {
    margin-left: -2rem;
    margin-top: 0.125rem;
  }

  .form-switch .form-check-input {
    height: 1em;
  }

  /* État valide neutralisé (O3 B, 02/10/2026) : après un premier envoi
     (`was-validated`) ou une validation du noyau (`is-valid`), un champ
     valide garde l'aspect d'un champ normal. Mêmes listes de sélecteurs que
     Bootstrap, comme le pictogramme d'erreur ci-dessus : coche verte écrite
     en dur retirée, remplissage droit et chevron des listes rendus, halo
     vert du focus retiré (l'anneau du focus reste), libellé des cases dans
     sa couleur normale. Le bord vient de --bs-form-valid-border-color (§3).
     Champs .valid des avis produit retirés de ces listes (Hummingbird
     2.1.2 : plus de coche, halo repris au §12.7). */
  .form-control.is-valid, .was-validated .form-control:valid {
    background-image: none;
    padding-right: 1.125rem;
  }

  .form-control.is-valid:focus, .was-validated .form-control:valid:focus {
    box-shadow: none;
  }

  .was-validated textarea.form-control:valid, textarea.form-control.is-valid {
    padding-right: 1.125rem;
  }

  .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"], .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"] {
    --bs-form-select-bg-icon: none;
    background-position: right 1.125rem center;
    background-size: 16px 12px;
    padding-right: 2.75rem;
  }

  .form-select.is-valid:focus, .was-validated .form-select:valid:focus {
    box-shadow: none;
  }

  .form-check-input.is-valid:focus, .was-validated .form-check-input:valid:focus {
    box-shadow: none;
  }

  .form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label {
    color: inherit;
  }

  /* Étape 7, tranche 3 (T3.8, cadrage 4.15, 02/10/2026) : état d'erreur
     des champs, pour tout le site (tunnel, inscription, identité, adresses
     du compte). Pictogramme : voir plus haut.

     Erreur du serveur : le noyau pose .has-error sur le conteneur du champ,
     sans règle chez Hummingbird ; le bord passe au rouge (6,54:1). Placé
     après les :focus et :checked de ce paragraphe, à spécificité égale
     (0,2,0) : le bord reste rouge au focus. Après un clic sur
     « Continuer », un champ que le navigateur juge valide reprend le bord
     marine (.was-validated, 0,3,0), l'alerte restant affichée : limite
     connue. Cases : libellé rouge, comme à la validation du navigateur. */
  .has-error .form-control,
  .has-error .form-select,
  .has-error .form-check-input {
    border-color: var(--bs-form-invalid-border-color);
  }

  .has-error .form-check-input ~ .form-check-label {
    color: var(--bs-form-invalid-color);
  }

  /* Alerte du serveur sous le champ, compacte : 14px, 45px de haut au lieu
     de 58px (plus haute que le champ), rayon du champ. Croix de 44 x 44px
     (icône de 14px), alignée sur l'alerte. Couleurs natives (#480f0c sur
     #f0d4d2, 11,16:1), marge haute (mt-3) et marge droite de la croix
     gardées. Limitée aux erreurs de champ (.has-error) : les erreurs
     globales en tête des formulaires de connexion, d'inscription et
     d'adresse (form-errors.tpl) gardent l'alerte native. Écart au 4.15,
     qui visait .help-block .alert-danger en ps-components. */
  .has-error .help-block .alert {
    --bs-alert-padding-y: 0.6875rem;
    --bs-alert-padding-x: 0.75rem;
    --bs-alert-margin-bottom: 0;
    --bs-alert-border-radius: var(--mq-rayon-champ);
    font-size: 0.875rem;
  }

  .has-error .help-block .btn-close {
    padding: 0.9375rem;
  }

  /* Halo rose de Bootstrap retiré au focus d'un champ en erreur (mêmes
     listes que Bootstrap, venues après) : on voyait trois traits, bord
     rouge, halo et anneau. Le bord reste rouge et l'anneau marine du focus
     reste (au clavier seulement pour les cases, GUIDE §5.3). Avis produit
     sous Hummingbird 2.1.2 : halo en ps-modules, retiré au §12.7. */
  .form-control.is-invalid:focus, .product-comment-modal input.form-control[name=comment_title].error:focus, .product-comment-modal input.form-control[name=customer_name].error:focus, .product-comment-modal textarea.form-control.error:focus, .was-validated .form-control:invalid:focus {
    box-shadow: none;
  }

  .form-select.is-invalid:focus, .was-validated .form-select:invalid:focus {
    box-shadow: none;
  }

  .form-check-input.is-invalid:focus, .was-validated .form-check-input:invalid:focus {
    box-shadow: none;
  }

  /* Case obligatoire non cochée, après un envoi : pictogramme d'erreur
     après le libellé, qui signale la case sans la seule couleur une fois
     la bulle du navigateur fermée (élément visuel, rien n'est lu). Sur
     customer_privacy, dont le libellé finit par un paragraphe, il tombe
     sous ce paragraphe : limite connue, jusqu'au réglage n° 5. */
  .was-validated .form-check-input:invalid ~ .form-check-label::after {
    content: "";
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-inline-start: 0.375rem;
    vertical-align: -0.125em;
    background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23b3261e' viewBox='0 0 12 12'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23b3261e' stroke='none'/%3E%3C/svg%3E") center / contain no-repeat;
  }
}


/* ============================================================
   7. AUTRES COMPOSANTS : BLEU DE HUMMINGBIRD REMPLACÉ
   Liste fermée des valeurs du bleu #0b69f6 écrites en dur dans le
   theme.css compilé de Hummingbird 2.0.0 (inventaire du 25/09/2026). À
   refaire sur le theme.css compilé de Hummingbird 2.1.2 après la montée
   (date à reporter ici), puis à chaque mise à jour de Hummingbird : voir
   GUIDE.md.
   ============================================================ */

@layer bs-components {
  /* Titres d'accordéon (onglets de la fiche produit, filtres, arbre des
     catégories, tunnel) : marine comme tous les titres, fermés comme ouverts ;
     chevron marine au lieu du gris #363a41. */
  .accordion {
    --bs-accordion-btn-color: var(--mq-couleur-titre);
    --bs-accordion-active-color: var(--mq-couleur-titre);
    --bs-accordion-btn-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23173b4f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
    --bs-accordion-btn-active-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23173b4f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
    --bs-accordion-btn-focus-box-shadow: none;
  }

  .btn-close {
    --bs-btn-close-focus-shadow: none;
  }

  .btn-close:focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  .dropdown-menu {
    --bs-dropdown-link-active-bg: var(--mq-marine);
  }

  .dropdown-menu-dark {
    --bs-dropdown-link-active-bg: var(--mq-marine);
  }

  .list-group {
    --bs-list-group-active-bg: var(--mq-marine);
    --bs-list-group-active-border-color: var(--mq-marine);
  }

  .nav-link:focus-visible {
    box-shadow: none;
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  .nav-pills {
    --bs-nav-pills-link-active-bg: var(--mq-marine);
  }

  .pagination {
    --bs-pagination-focus-box-shadow: none;
  }

  .page-link:focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }

  /* Pagination des avis (.page-link.btn) : le remplissage vertical de .btn
     (§5, B9) arrive après celui de .page-link ; on lui rend le sien. */
  .page-link {
    padding-block: var(--bs-pagination-padding-y);
  }

  .progress, .progress-stacked {
    --bs-progress-bar-bg: var(--mq-marine);
  }

  .table-primary {
    --bs-table-bg: var(--mq-marine-100);
    --bs-table-border-color: #a2b1b9;
    --bs-table-striped-bg: #d7dfe3;
    --bs-table-active-bg: #cbd5da;
    --bs-table-hover-bg: #d1dadf;
  }

  /* Fil d'Ariane comme sur mosqity.fr : 11px en capitales, séparateur ›,
     liens en texte atténué, page courante en marine et en gras. */
  .breadcrumb {
    --bs-breadcrumb-font-size: var(--mq-taille-surtitre);
    --bs-breadcrumb-divider: "›";
    --bs-breadcrumb-divider-color: var(--mq-texte-attenue);
    --bs-breadcrumb-item-active-color: var(--mq-marine);
    color: var(--mq-marine);
    letter-spacing: var(--mq-approche-capitales);
    text-transform: uppercase;
  }

  /* Pastilles (produit « Neuf », « −20 % », statuts de commande) en pilule,
     11px en capitales, comme les badges de mosqity.fr. Couleurs inchangées :
     blanc sur marine (primaire) pour les drapeaux produit. */
  .badge {
    --bs-badge-font-size: var(--mq-taille-surtitre);
    --bs-badge-font-weight: var(--mq-graisse-texte);
    --bs-badge-padding-y: 0.4375rem;
    --bs-badge-padding-x: 0.875rem;
    --bs-badge-border-radius: var(--mq-rayon-pilule);
    letter-spacing: var(--mq-approche-capitales);
    text-transform: uppercase;
  }

  /* Hummingbird écrit Inter en dur sur les infobulles. */
  .tooltip {
    font-family: var(--bs-body-font-family);
  }

  .popover {
    font-family: var(--bs-body-font-family);
  }

  /* Toasts (panier, quantité indisponible ; étape 7, cadrage 4.23) : texte
     de 16px au lieu de 14px, rayon de 14px au lieu de 19px. Leurs couleurs
     (bg-*-subtle, posées par le JavaScript) suivent les jetons d'état du §3
     (O3 B). Le délai de 3s ne se règle qu'en JavaScript : limite connue
     (WCAG 2.2.1). */
  .toast {
    --bs-toast-font-size: 1rem;
    --bs-toast-border-radius: var(--bs-border-radius-sm);
  }
}

@layer bs-custom-components {
  .accordion-button:focus-visible {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: -2px;
  }

  /* Fil d'Ariane sans le bandeau blanc cassé de Hummingbird (mosqity.fr
     n'en a pas). */
  .breadcrumb__wrapper {
    background-color: transparent;
  }

  .breadcrumb-link {
    color: var(--mq-texte-attenue);
  }

  .breadcrumb-link:hover {
    color: var(--mq-marine);
  }

  .breadcrumb-item:last-child {
    font-weight: var(--mq-graisse-titre);
  }
}

/* Halo des pastilles des facettes natives (ps-components sous Hummingbird
   2.0.0) : déplacé au §12.4, en ps-modules comme chez Hummingbird 2.1.2. */

@layer ps-modules {
  .stars-selector:has(.stars-selector__input:focus-visible) {
    box-shadow: 0 0 0 0.25rem rgba(23, 59, 79, 0.25);
  }
}

@layer utilities {
  /* Lien « Se déconnecter » du pied de page Hummingbird : jaune sur marine
     (charte) au lieu du rouge clair #ff4657 (arbitrage du 25/09/2026). */
  .text-danger-on-dark {
    color: var(--mq-jaune);
  }
}

/* ============================================================
   8. EN-TÊTE CREATIVE ELEMENTS (modèle « En-tête Mosqity »)
   En-tête moderne (conception validée le 02/10/2026 :
   analyses/entete-moderne/entete-moderne-options.md de l'espace de
   travail ; ses numéros §2.1 à §2.14 et ses tests du §10 sont cités
   ci-dessous). Deux sections CE de bord à bord portent la classe
   « mq-entete » :
   - « mq-entete--rangee1 » : bouton du tiroir, logo, recherche, compte,
     panier ; collante sur tous les appareils ;
   - « mq-entete--rangee2 » : menu ps_mainmenu et tiroir ; collante au
     bureau seulement, fixée sous la rangée 1 par le décalage dynamique de
     CE, dont la valeur est « .mq-entete--rangee1:not(.elementor-sticky__spacer) »
     (ne pas renommer cette classe). Les deux rangées restent affichées au
     défilement, en descendant comme en remontant : « Hide on Scroll »
     désactivé dans CE le 07/10/2026 (conception du 06/10/2026).
   États, portés par les jetons --mq-entete-* :
   - par défaut, sur toutes les pages : fond blanc, marine ;
   - défilé (dès 1px) : rangée 1 en dégradé quasi opaque et flou, porté
     par son ::before (06/10/2026) ; rangée 2 blanche ;
   - posé sur la photo, en haut de l'accueil seulement : fond
     transparent, blanc, champ de recherche « verre marine ».
   Menu, compte et panier sont les modules natifs rendus par le widget
   Module de CE, avec leurs gabarits Hummingbird. La recherche est le
   widget AJAX Search de CE : sa feuille est hors couche, ses règles sont
   au §12.11 avec les autres corrections de CE. La disposition (ordre,
   largeur, écarts, fixation, visibilité) se règle dans CE (GUIDE §6.3),
   sauf dans le tunnel allégé (E6, 12/10/2026, tranche4-conception.md
   T4.1) : sur #checkout, rangée 2, bouton du tiroir, recherches et compte
   sont masqués au §12.11 (hors couche) ; Panier poussé à droite, filet et
   ombre sous la rangée 1 au bureau, toasts à 5rem : règles « Tunnel
   allégé » de ce §8.

   Conditions, écrites une fois ici et reprises telles quelles :
   - HÉRO = .mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"])
     Le héro pleine largeur, première section du modèle Accueil, affiché
     sur tous les appareils (sans classe de masquage responsive de CE).
     Pleine largeur et première section sont deux garde-fous ajoutés à la
     condition du §2.1 (contrat du §2.14) : un héro encadré, ou une
     section posée au-dessus, laisse l'en-tête opaque et dans le flux.
   - POSÉ = body#index:has(HÉRO):not(:has(#notifications .alert))
     L'en-tête sort du flux et se pose sur le héro (§2.10).
   - ACCUEIL-HAUT = body#index:has(HÉRO):not(:has(#notifications .alert,
       .mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer),
       .mq-entete--rangee2:not(.elementor-sticky__spacer) .ps-mainmenu__tree-dropdown-toggle[aria-expanded="true"]))
     POSÉ, moins de 1 px défilé et aucun panneau du menu ouvert : la classe
     d'effets de CE (réglage Effects Offset = 1) est absente de la rangée 1,
     copie « spacer » exclue (§2.1, test n° 1 du §10) ; un panneau ouvert
     rend l'en-tête blanc d'un coup (conception du 06/10/2026, §2.5). La
     copie « spacer » est exclue : refaite à chaque redimensionnement, elle
     peut garder un aria-expanded="true" périmé.
   - DÉFILÉ = .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer))
   - DANS-LE-FLUX = :where(body:not(#index), body:not(:has(HÉRO)),
       body:has(#notifications .alert))
     Le complément de POSÉ ; :where() lui laisse une spécificité nulle.
   L'état « posé sur la photo » (encre blanche, champ verre) n'est écrit
   qu'une fois, dans le bloc de jetons ACCUEIL-HAUT ; l'état défilé ne rend
   transparent que le fond de la rangée 1, couvert par son ::before. Le champ de recherche (§12.11) lit ces jetons : il a la
   même condition par construction (§2.1 : une condition plus étroite
   laissait le texte du champ blanc sur un en-tête redevenu blanc).
   Aucune transition de couleur dans l'en-tête (§2.1, états
   intermédiaires) : liens et boutons ici, sections et recherche au §12.11.
   ============================================================ */

@layer ps-base {
  /* L'en-tête CE gère sa fixation (deux sections collantes, §2.5) : la
     fixation native de Hummingbird (.header { position: sticky }) est
     neutralisée quand il est là. */
  .header:has(.mq-entete) {
    position: relative;
  }

  /* POSÉ : à l'accueil, l'en-tête sort du flux et se pose sur le héro, qui
     commence ainsi à y = 0 (§2.10, voie V2 du rapport CE) : aucune marge
     négative à tenir à jour. Hummingbird donne à .header le blanc de la page :
     fond transparent ici. Les copies « spacer » des sections collantes
     restent dans #header, sans effet sur le héro ; le z-index de 1021 de
     Hummingbird garde l'en-tête au-dessus. Sans héro affiché, ou avec une
     alerte, l'en-tête reste dans le flux (contrôle de la contre-vérification :
     contenu à 128px, pas sous l'en-tête). */
  body#index:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"])):not(:has(#notifications .alert)) .header:has(.mq-entete) {
    position: absolute;
    inset-inline: 0;
    top: 0;
    background-color: transparent;
  }

  /* DANS-LE-FLUX : l'écart avec le contenu, qui était le remplissage bas de
     la section B (12px au bureau, 8px dessous), passe en marge sous
     l'en-tête : le fond blanc des rangées fixées s'arrête au menu (§2.12). */
  :where(body:not(#index), body:not(:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"]))), body:has(#notifications .alert)) .header:has(.mq-entete) {
    margin-block-end: 0.75rem;
  }

  @media (max-width: 1199.98px) {
    :where(body:not(#index), body:not(:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"]))), body:has(#notifications .alert)) .header:has(.mq-entete) {
      margin-block-end: 0.5rem;
    }
  }

  /* Défilement vers une ancre ou un élément qui prend le focus : les rangées
     collantes, toujours affichées (06/10/2026), ne doivent pas le masquer. Au
     bureau, les deux rangées (80 + 48px, §2.12) ; dessous, la rangée 1 seule
     (64px) ; plus 16px d'air, comme Hummingbird. Ne vaut qu'à l'accueil :
     sur les autres pages, l'en-tête porte data-ps-ref="header" (Hummingbird
     2.1.2 ; .js-sticky-header en 2.0.0) et Hummingbird pose en ligne sur
     <html> sa propre valeur (hauteur des copies « spacer » + 16px, soit
     144px au bureau et 81px dessous ; dans le tunnel allégé, 96px au
     bureau et 80px dessous ; scrollPadding.ts, GUIDE §5.2 point 7),
     gardée telle quelle. */
  :root:has(.mq-entete--rangee1) {
    scroll-padding-top: 9rem;
  }

  @media (max-width: 1199.98px) {
    :root:has(.mq-entete--rangee1) {
      scroll-padding-top: 5rem;
    }
  }

  /* Rebond élastique en haut de page (Safari) sous l'en-tête fixé : le fond
     marine du document est déjà posé au §9 (html, toutes les pages), rien à
     ajouter ici (§2.1, test 17). */
}

@layer ps-components {
  /* Jetons d'état (§2.1) : opaque par défaut, sur toutes les pages. Le fond
     est porté par le thème (champ de couleur des sections vide dans CE,
     geste S.1). Pastille du panier marine à texte blanc ; champ de recherche
     blanc à contour marine, texte noir, indication #587280 (5,1:1). */
  .mq-entete {
    --mq-entete-fond: var(--mq-blanc);
    --mq-entete-encre: var(--mq-couleur-lien);
    --mq-entete-encre-survol: var(--mq-couleur-lien-survol);
    --mq-entete-pastille-fond: var(--mq-marine);
    --mq-entete-pastille-texte: var(--mq-blanc);
    --mq-entete-champ-fond: var(--mq-blanc);
    --mq-entete-champ-bord: var(--mq-marine);
    --mq-entete-champ-texte: var(--mq-noir);
    --mq-entete-champ-indication: var(--mq-texte-attenue);
    --mq-entete-champ-icone: var(--mq-marine);
    --mq-entete-champ-flou: none;
    --mq-entete-ombre: 0 6px 18px rgb(23 59 79 / 0.1), 0 1px 0 rgb(23 59 79 / 0.06);
    background-color: var(--mq-entete-fond);
  }

  /* DÉFILÉ : fond quasi opaque, toujours visible (conception du 06/10/2026,
     analyses/entete-moderne/entete-collant-et-sous-menu.md §1.3 de l'espace
     de travail ; relevé de Tikamoon). Rangée 1 : 85 % de blanc en haut, blanc
     plein à 55 % de l'en-tête (70px des 128px au bureau, 35px des 64px
     dessous) ; dans le tunnel allégé (E6), à 70px des 80px de la rangée 1
     seule ; flou de 20px de ce qui passe dessous. Rangée 2 : blanc plein du
     jeton par défaut, la jonction à 80px est invisible. Dégradé et flou sont
     portés par un pseudo-élément, jamais par la section : backdrop-filter
     ferait de la rangée le cadre de ses descendants fixes (recherche Topbar ;
     même règle pour la rangée 2, qui porte le tiroir ; §12.11). z-index -1 :
     sous les widgets, dans le contexte
     d'empilement de la rangée fixée. Contraste au pire cas (fond noir
     derrière) : marine à 8,4:1 au sommet. Aucune transition : la bascule
     reste immédiate. */
  .mq-entete--rangee1 {
    --mq-entete-degrade: none;
    --mq-entete-flou: none;
    --mq-entete-degrade-fin: 2.1875rem;
  }

  @media (min-width: 1200px) {
    .mq-entete--rangee1 {
      --mq-entete-degrade-fin: 4.375rem;
    }
  }

  .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer)) .mq-entete--rangee1 {
    --mq-entete-fond: transparent;
    --mq-entete-degrade: linear-gradient(rgb(255 255 255 / 0.85), var(--mq-blanc) var(--mq-entete-degrade-fin));
    --mq-entete-flou: blur(20px);
  }

  .mq-entete--rangee1::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: var(--mq-entete-degrade);
    -webkit-backdrop-filter: var(--mq-entete-flou);
    backdrop-filter: var(--mq-entete-flou);
  }

  /* Navigateur sans flou : départ plus opaque (95 %, 10,6:1 au sommet). */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer)) .mq-entete--rangee1 {
      --mq-entete-degrade: linear-gradient(rgb(255 255 255 / 0.95), var(--mq-blanc) var(--mq-entete-degrade-fin));
    }
  }

  /* Transparence réduite, contraste renforcé, couleurs forcées : blanc
     plein, sans dégradé ni flou. */
  @media (prefers-reduced-transparency: reduce), (prefers-contrast: more), (forced-colors: active) {
    .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer)) .mq-entete--rangee1 {
      --mq-entete-fond: var(--mq-blanc);
      --mq-entete-degrade: none;
      --mq-entete-flou: none;
    }
  }

  /* Messages (toasts de Hummingbird, fixes en haut à droite, z-index 1090) :
     sous l'en-tête toujours visible, pour ne pas couvrir compte et panier.
     L'utilitaire top-0 du gabarit est gardé ; la marge s'y ajoute. */
  :root:has(.mq-entete--rangee1) #js-toast-container {
    margin-block-start: 8rem;
  }

  @media (max-width: 1199.98px) {
    :root:has(.mq-entete--rangee1) #js-toast-container {
      margin-block-start: 4rem;
    }
  }

  /* Tunnel allégé (E6, tranche4-conception.md T4.1) : la rangée 2 est
     masquée (§12.11), l'en-tête ne fait plus que 80px au bureau. Sous
     1200px, les 4rem ci-dessus restent justes. (2,1,1) bat (1,2,0). */
  @media (min-width: 1200px) {
    body#checkout:has(.mq-entete--rangee1) #js-toast-container {
      margin-block-start: 5rem;
    }
  }

  /* ACCUEIL-HAUT : posé sur la photo. Texte, pictos et menu blancs, pastille
     jaune à texte marine, anneau de focus jaune ; champ « verre marine »
     (marine à 35 %, contour blanc, flou de 8px posé sur le champ seulement,
     jamais sur une section : décision Q3, §2.6). Pire cas mesuré, photo
     remplacée par un blanc pur et deux couches de voile : pictos à 5,3:1,
     texte du champ à 8,4:1 (§2.11). Dès 1px de défilement, ou dès qu'un
     panneau du menu s'ouvre, la condition tombe d'un coup. Seul endroit où
     l'état « posé sur la photo » est écrit. */
  body#index:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"])):not(:has(#notifications .alert, .mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer), .mq-entete--rangee2:not(.elementor-sticky__spacer) .ps-mainmenu__tree-dropdown-toggle[aria-expanded="true"])) .mq-entete {
    --mq-entete-fond: transparent;
    --mq-entete-encre: var(--mq-blanc);
    --mq-entete-encre-survol: var(--mq-blanc);
    --mq-entete-pastille-fond: var(--mq-jaune);
    --mq-entete-pastille-texte: var(--mq-marine);
    --mq-entete-champ-fond: rgb(23 59 79 / 0.35);
    --mq-entete-champ-bord: var(--mq-blanc);
    --mq-entete-champ-texte: var(--mq-blanc);
    --mq-entete-champ-indication: var(--mq-blanc);
    --mq-entete-champ-icone: var(--mq-blanc);
    --mq-entete-champ-flou: blur(8px);
    --mq-couleur-focus: var(--mq-jaune);
  }

  /* Panneaux blancs ouverts depuis l'en-tête : tiroir, sous-menus du bureau,
     menu du compte, suggestions d'AJAX Search (liste ajoutée dans le widget,
     classe lue dans le gestionnaire du widget) et barre de recherche mobile
     (habillage Topbar). Couleurs de page, même en haut de l'accueil (§2.1). */
  .mq-entete :is(.offcanvas, .submenu, .dropdown-menu, .elementor-search__products, .elementor-search--skin-topbar .elementor-search__container) {
    --mq-entete-encre: var(--mq-couleur-lien);
    --mq-entete-encre-survol: var(--mq-couleur-lien-survol);
    --mq-entete-champ-fond: var(--mq-blanc);
    --mq-entete-champ-bord: var(--mq-marine);
    --mq-entete-champ-texte: var(--mq-noir);
    --mq-entete-champ-indication: var(--mq-texte-attenue);
    --mq-entete-champ-icone: var(--mq-marine);
    --mq-entete-champ-flou: none;
    --mq-couleur-focus: var(--mq-marine);
  }

  /* Aucune transition de couleur (§2.1) : Hummingbird écrit
     a { transition: var(--bs-transition-default) } (couche ps-base ; jeton du
     thème : all 150ms, §3). Au passage à 1px, le fond deviendrait blanc d'un
     coup et le texte des liens resterait blanc un instant (2,4:1 mesuré à la
     contre-vérification). Les transitions que CE écrit sur les sections et
     sur la recherche sont coupées au §12.11. */
  .mq-entete :is(a, button) {
    transition: none;
  }

  /* Logo : SVG marine du back-office, rendu blanc sur la photo (variante
     blanche officielle, monochrome ; §2.8). Sans transition : la durée de
     transition du widget Logo reste vide dans CE (test 17). */
  body#index:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"])):not(:has(#notifications .alert, .mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer), .mq-entete--rangee2:not(.elementor-sticky__spacer) .ps-mainmenu__tree-dropdown-toggle[aria-expanded="true"])) .mq-entete__logo img {
    filter: brightness(0) invert(1);
  }

  /* Logo : ne rétrécit jamais (45px d'encre au minimum, brand book), même
     quand la rangée est serrée (écran de 320px). */
  .mq-entete__logo {
    flex-shrink: 0;
  }

  /* Rangée 1, disposition de la maquette (§2.3, §2.4) : la recherche suit le
     logo, compte et panier sont poussés à droite (le logo ne grandit plus :
     geste 3.4 de analyses/entete-moderne/realisation/plan-ce.md). Au bureau,
     48px entre le logo et le champ (l'écart de 24px de la colonne, plus
     24px). Sous 768px, c'est la loupe (recherche Topbar) qui ouvre le groupe
     de droite. */
  .mq-entete__compte {
    margin-inline-start: auto;
  }

  @media (min-width: 1200px) {
    .mq-entete__recherche {
      margin-inline-start: var(--mq-espace-5);
    }
  }

  @media (max-width: 767.98px) {
    .mq-entete__recherche--mobile {
      margin-inline-start: auto;
    }

    .mq-entete__compte {
      margin-inline-start: 0;
    }
  }

  /* Tunnel allégé (E6) : compte et loupe, qui poussaient le Panier à
     droite, sont masqués (§12.11) ; le Panier se pousse lui-même. */
  body#checkout .mq-entete__panier {
    margin-inline-start: auto;
  }

  /* Bord bas, sous la rangée du bas (rangée 2 au bureau, rangée 1 dessous) :
     filet de 1px au repos dans le flux (hors accueil, accueil sans héro ou
     avec une alerte), ombre légère dès que la page défile, sur toutes les
     pages (capture de Tikamoon, quatrième écart au SiteNav du design system,
     décision Q2). Les filets #DCE1E5 du widget menu sont retirés de CE
     (geste S.5). Spécificité : DÉFILÉ suivi de la classe de la rangée vaut
     (0,5,0), le filet (0,1,0) grâce à :where() : l'ombre l'emporte. */
  @media (max-width: 1199.98px) {
    :where(body:not(#index), body:not(:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"]))), body:has(#notifications .alert)) .mq-entete--rangee1 {
      box-shadow: 0 1px 0 var(--mq-bordure);
    }

    .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer)) .mq-entete--rangee1 {
      box-shadow: var(--mq-entete-ombre);
    }
  }

  @media (min-width: 1200px) {
    :where(body:not(#index), body:not(:has(.mq-heros.elementor-section-full_width:first-child:not([class*="hidden-"]))), body:has(#notifications .alert)) .mq-entete--rangee2 {
      box-shadow: 0 1px 0 var(--mq-bordure);
    }

    .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer)) .mq-entete--rangee2 {
      box-shadow: var(--mq-entete-ombre);
    }
  }

  /* Tunnel allégé (E6) : la rangée 2 est masquée (§12.11) ; au bureau,
     filet puis ombre passent sous la rangée 1, comme sous 1200px. En
     couleurs forcées, le navigateur retire ces box-shadow : aucun bord sous
     l'en-tête, sur tout le site (limite du GUIDE §6.3). */
  @media (min-width: 1200px) {
    body#checkout .mq-entete--rangee1 {
      box-shadow: 0 1px 0 var(--mq-bordure);
    }

    body#checkout .header:has(.mq-entete--rangee1.elementor-sticky--effects:not(.elementor-sticky__spacer)) .mq-entete--rangee1 {
      box-shadow: var(--mq-entete-ombre);
    }
  }

  /* Voile sous les panneaux du menu (bureau, conception du 06/10/2026,
     §2.5) : marine à 40 % sur la page, pendant qu'un panneau est ouvert. Un
     seul voile pour tous les panneaux, porté par la rangée 2 fixée : il
     reste en place quand on passe d'une entrée à l'autre (Hummingbird ferme
     un panneau et en ouvre un autre). Il apparaît après 100ms, pour ne pas
     assombrir la page quand on traverse le menu. Position absolue sous la
     rangée, qui est fixée : pas de hauteur d'en-tête en dur, pas de
     défilement créé. .elementor-sticky--active réserve la règle à la rangée
     fixée, jamais à la copie « spacer » (dans l'aperçu de l'éditeur de CE,
     la fixation tourne aussi : voile possible sous un panneau ouvert, sans
     effet sur le modèle). z-index -1 dans le
     contexte de la rangée (99, CE) : sous le panneau, au-dessus de la page ;
     aucun z-index sur la section (§6.3 du GUIDE). Visible, il capte le
     pointeur : toucher la page voilée ferme le panneau (clic hors de la
     navigation, Hummingbird) sans ouvrir le lien du dessous. */
  @media (min-width: 1200px) {
    .mq-entete--rangee2.elementor-sticky--active::after {
      content: "";
      position: absolute;
      inset-inline: 0;
      top: 100%;
      height: 100vh;
      z-index: -1;
      pointer-events: none;
      visibility: hidden;
      opacity: 0;
      background-color: rgb(23 59 79 / 0.4);
      transition: opacity 150ms ease, visibility 0s 150ms;
    }

    .mq-entete--rangee2.elementor-sticky--active:has(.ps-mainmenu__tree-dropdown-toggle[aria-expanded="true"])::after {
      pointer-events: auto;
      visibility: visible;
      opacity: 1;
      transition: opacity 150ms ease 100ms, visibility 0s 100ms;
    }
  }

  /* Mouvement réduit : l'attente reste, sans fondu. */
  @media (min-width: 1200px) and (prefers-reduced-motion: reduce) {
    .mq-entete--rangee2.elementor-sticky--active::after {
      transition: none;
    }

    .mq-entete--rangee2.elementor-sticky--active:has(.ps-mainmenu__tree-dropdown-toggle[aria-expanded="true"])::after {
      transition: opacity 0s 100ms, visibility 0s 100ms;
    }
  }

  /* Transparence réduite, couleurs forcées : pas de voile ; le panneau garde
     l'ombre de Hummingbird. */
  @media (prefers-reduced-transparency: reduce), (forced-colors: active) {
    .mq-entete--rangee2.elementor-sticky--active::after {
      content: none;
    }
  }

  /* Sections fixées (A, et B au bureau) : toujours la largeur de la fenêtre,
     même si le plugin de fixation a écrit une largeur en ligne périmée
     (min-width et max-width l'emportent sur width, sans !important ; point
     ouvert « largeur figée », §2.13). */
  .mq-entete.elementor-sticky--active {
    min-width: 100%;
    max-width: 100%;
  }

  /* Copies « spacer » du plugin : jamais de panneau visible. Une copie faite
     tiroir ouvert le montrerait (.offcanvas.show impose visibility: visible).
     Le tiroir est hors du flux : la hauteur de la copie ne change pas (§2.5,
     garde-fou ; sous 1200px, B n'est pas collante et n'a pas de copie). */
  .elementor-sticky__spacer :is(.offcanvas, .offcanvas-backdrop) {
    display: none;
  }

  /* Bouton du tiroir de menu (widget HTML de la rangée 1, tablette et
     mobile) : zone de 44px, picto de 24px calé sur la grille (marge de
     -10px). Le bouton natif du module, dans la rangée 2, est masqué plus
     bas. */
  .mq-entete__burger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-inline-start: -0.625rem;
    padding: 0;
    color: var(--mq-entete-encre);
    cursor: pointer;
    background: transparent;
    border: 0;
    border-radius: var(--bs-border-radius-sm);
  }

  .mq-entete__burger:hover {
    color: var(--mq-entete-encre-survol);
  }

  /* Compte, panier : zone de 44px (picto de 24px et 10px autour), de 48px au
     bureau où le libellé est visible. Au bureau le retrait latéral est nul :
     l'écart visible entre blocs est celui de la colonne CE. Couleur de l'état
     (jeton), survol et focus compris : Hummingbird passe sinon les liens en
     marine foncé (.header-block__action-btn[href]:hover, 0,3,0), invisible
     sur la photo. */
  .mq-entete .header-block__action-btn {
    justify-content: center;
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding: 0.625rem;
    font-size: var(--mq-taille-label);
    color: var(--mq-entete-encre);
    text-transform: uppercase;
    letter-spacing: var(--mq-approche-capitales);
  }

  .mq-entete .header-block__action-btn[href]:is(:hover, :focus) {
    color: var(--mq-entete-encre-survol);
  }

  @media (min-width: 1200px) {
    .mq-entete .header-block__action-btn {
      min-height: 3rem;
      padding-inline: 0;
    }
  }

  .mq-entete .header-block__icon {
    font-size: 1.5rem;
  }

  /* Compte aligné sur la loupe et le panier (07/10/2026) : le gabarit de
     Hummingbird pose le lien (inline-flex) dans un bloc ordinaire, dont la
     ligne de texte ajoutait 7px sous lui et le décalait de 3,5px vers le bas.
     Le panier a déjà ce conteneur en flex (d-flex align-items-center). Même
     correction pour le bouton du tiroir, passé en flex plus haut. */
  .mq-entete .ps-customersignin .header-block {
    display: flex;
    align-items: center;
  }

  /* Pictos au trait (§2.7) : le glyphe plein de Material Icons des modules
     natifs et du bouton du tiroir est remplacé par un SVG au trait posé en
     masque, dans la couleur du texte. Aucun gabarit surchargé. color: inherit
     annule le marine que Hummingbird donne à l'icône d'un panier rempli
     (.header-block--active .header-block__icon, dès 768px). Fichiers :
     assets/img/pictos/interface/, dessins des maquettes, provisoires tant que
     le jeu définitif n'est pas choisi (Lucide proposé, §2.7). Propriétés
     longues : le raccourci mask remettrait l'image à none et battrait les
     règles d'image, moins spécifiques. Test 8. */
  .mq-entete :is(.mq-entete__compte, .mq-entete__panier) .header-block__icon,
  .mq-entete__burger .material-icons {
    width: 1.5rem;
    height: 1.5rem;
    font-size: 0;
    color: inherit;
    background-color: currentColor;
    mask-position: center;
    mask-size: contain;
    mask-repeat: no-repeat;
  }

  .mq-entete__compte .header-block__icon {
    mask-image: url("../img/pictos/interface/compte.svg");
  }

  .mq-entete__panier .header-block__icon {
    mask-image: url("../img/pictos/interface/panier.svg");
  }

  .mq-entete__burger .material-icons {
    mask-image: url("../img/pictos/interface/menu.svg");
  }

  /* Pastille du panier (couleurs de l'état) : marine à texte blanc, jaune à
     texte marine sur la photo (§2.1) ; de 20px sur mobile (chiffre de 12px)
     et de 22px dès 768px. */
  .mq-entete .header-block__badge {
    min-width: 1.25rem;
    height: 1.25rem;
    font-size: var(--mq-taille-label);
    color: var(--mq-entete-pastille-texte);
    background: var(--mq-entete-pastille-fond);
  }

  @media (min-width: 768px) {
    .mq-entete .header-block__badge {
      min-width: 1.375rem;
      height: 1.375rem;
    }
  }

  /* Sous 1200px, les libellés « Connexion » et « Panier » sont masqués à
     l'écran mais restent lus (les liens ont aussi un aria-label). Pas de
     display:none : Hummingbird les affiche avec une classe utilitaire. */
  @media (max-width: 1199.98px) {
    .mq-entete .header-block__title {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      white-space: nowrap;
      clip: rect(0, 0, 0, 0);
      border: 0;
    }
  }

  /* Retirées le 02/10/2026 (en-tête moderne) :
     - filet sous la rangée 1 après défilement (.mq-entete--rangee1.
       elementor-sticky--effects) : remplacé par l'ombre ci-dessus ; au
       bureau il aurait tracé un trait entre les deux rangées ;
     - hauteur de 48px des pilules « Mon diagnostic » et « Faire mon
       diagnostic » (.mq-entete__diagnostic) : les deux widgets sont
       supprimés (décision Q5), la pilule est une entrée du menu, plus bas. */
}

@layer ps-modules {
  /* Recherche : widget AJAX Search de CE (décision Q6), habillé au §12.11.
     En tablette, le bloc prend jusqu'à 240px et cède la place (200px au
     moins) au bouton de menu, au logo, au compte et au panier : la rangée
     reste sur une ligne, barre de défilement comprise. Le widget Topbar
     (loupe mobile) est masqué en tablette par CE : la règle ne le touche
     pas. */
  @media (min-width: 768px) and (max-width: 1199.98px) {
    .mq-entete__recherche {
      flex: 0 1 15rem;
      min-width: 12.5rem;
    }
  }

  /* REPLI de la recherche (§2.6) : module natif ps_searchbar, à n'employer
     qu'avec le script spacer-fix.js (copie « spacer » de la rangée
     collante), si les tests 5 à 7 du §10 échouent avec AJAX Search. Sans
     objet tant qu'AJAX Search est en place ; à retirer une fois ces tests
     passés. Champ en pilule de 320 x 48px ; sous 768px, le champ déplacé dans
     le volet de recherche prend toute sa largeur (bouton « Annuler »
     resserré). */
  .mq-entete .ps-searchbar {
    width: 20rem;
    min-width: 0;
    margin-block: 0;
  }

  @media (min-width: 768px) and (max-width: 1199.98px) {
    .mq-entete .ps-searchbar {
      width: 100%;
    }
  }

  @media (max-width: 767.98px) {
    .mq-entete .ps-searchbar {
      width: 100%;
    }

    .mq-entete .ps-searchbar__offcanvas .offcanvas-header .btn-link {
      padding-inline: 0.75rem;
    }
  }

  .mq-entete .ps-searchbar__input {
    min-height: 3rem;
    border-radius: var(--mq-rayon-pilule);
  }

  .mq-entete .ps-searchbar__magnifier,
  .mq-entete .ps-searchbar__clear {
    color: var(--mq-couleur-lien);
  }

  /* Menu du bureau (§2.9) : centré, 14px capitales, Medium, couleur de l'état
     (blanc sur la photo, marine ailleurs) ; page active en gras ; soulignement
     au survol (§12.11). Rangée de 48px : les filets du widget, qui faisaient
     2px, sont retirés de CE (geste S.5). 32px entre les entrées, portés par
     leur remplissage (06/10/2026) et non par un écart : les zones de survol
     se touchent, la souris ne passe plus par un vide qui fermerait panneau,
     voile et atténuation entre deux entrées. */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree {
    justify-content: center;
    gap: 0;
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li {
    padding-inline: calc(var(--mq-espace-6) / 2);
  }

  /* Panneaux de sous-menu (étape 2a de la conception du 06/10/2026, §2.5 ;
     bureau seulement, le tiroir n'est jamais visé). Bord à bord (enveloppes
     de CE rendues statiques au §12.11). Hauteur au plus celle de la fenêtre
     sous l'en-tête. Sélecteurs de Hummingbird préfixés par .mq-entete : le
     filet haut de 1px de Hummingbird (0,4,1) est battu. display est écrit en
     ligne par le script : jamais visé sur .submenu.
     Depuis l'étape 2b (07/10/2026), la surcharge du gabarit ne garde la
     structure en onglets de Hummingbird que pour un univers à niveau 3 :
     les règles de .submenu__row, __left et __right ne servent qu'à lui (un
     univers sans niveau 3 a sa liste simple, règles plus bas). La colonne
     d'onglets épouse ses libellés (280px au plus) et reste calée à gauche :
     la partie droite (niveaux 3) prend toute la place restante, pas 75 %, et
     la rangée remplit le conteneur. Remplissage
     de 32 / 48px porté par la rangée (celui de la colonne, 24px, est remis
     à 0). margin-inline: 0 sur la rangée : la gouttière .gx-5 la ferait
     déborder de 12px, d'où une barre horizontale avec overflow-y. Onglet
     sans enfant : plus de fond beige à l'ouverture (initializeSubMenuTabs
     active l'index 0). La règle 2a qui masquait une partie droite sans
     lien (.submenu__right:not(:has(.menu-item))) est retirée : le gabarit
     ne rend plus cette partie que si un niveau 3 existe. */
  @media (min-width: 1200px) {
    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .submenu {
      max-height: calc(100vh - 8rem);
      max-height: calc(100dvh - 8rem);
      overflow-y: auto;
      border-top: 0;
    }

    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__row {
      justify-content: center;
      margin-inline: 0;
      padding-block: var(--mq-espace-6) var(--mq-espace-7);
    }

    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__left {
      flex: 0 1 auto;
      width: max-content;
      max-width: 17.5rem;
      padding: 0;
      border-right: 0;
    }

    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__right {
      flex: 1 1 0;
      width: auto;
    }

    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__left-item.active[data-ps-has-child="false"]:not(:hover, :focus) {
      background-color: transparent;
    }

    /* Tous les liens de la colonne en marine (navigation, §5.3 du GUIDE) :
       Hummingbird met les liens en noir et l'actif en marine, le premier se
       distinguait sans raison. Survol et focus de Hummingbird gardés. */
    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__left-item:not(:hover, :focus) {
      color: var(--mq-couleur-lien);
    }

    /* Liens de niveau 3 (univers à niveau 3 seulement ; aucun dans le
       catalogue de démonstration) en marine eux aussi : Hummingbird les met
       en couleur de texte (.submenu__right-items .menu-item, 0,4,0, même
       couche). Survol de Hummingbird gardé. Taille et graisse du premier
       lien de chaque groupe (1.25rem, 600), titre, « Voir tout » et photo
       dans ce mode : à décider avec le vrai catalogue (Q24). */
    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__right-items .menu-item:not(:hover) {
      color: var(--mq-couleur-lien);
    }
  }

  /* Pendant l'ouverture d'un panneau : les autres entrées en texte atténué
     (#587280, 5,1:1 ; l'opacité de 0,5 de Tikamoon ferait tomber le marine
     à 2,8:1). Jamais l'entrée qui a le focus clavier, ni la pilule « Mon
     diagnostic », ni rien sous « contraste renforcé ». Changement immédiat :
     aucune transition de couleur dans l'en-tête. */
  @media (min-width: 1200px) and (prefers-contrast: no-preference) {
    .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree:has(.ps-mainmenu__tree-dropdown-toggle[aria-expanded="true"]) > li:not(:has([aria-expanded="true"])):not(:focus-within):not([data-id="cms-page-11"]) {
      --mq-entete-encre: var(--mq-texte-attenue);
    }
  }

  /* Panneaux de sous-menu, étape 2b (07/10/2026) : univers sans niveau 3
     (tout le catalogue de démonstration), rendu en liste simple par la
     surcharge modules/ps_mainmenu/ps_mainmenu.tpl (conception du
     06/10/2026, §2.2 et §2.6 ; maquette, mode « cible »). Titre de
     l'univers (Bold 23px), liens des sous-catégories (Medium 16px, zones de
     44px), « Voir tout » (capitales 12px, flèche), puis la photo posée par
     un contenu CE sur le greffon displayMqSousMenu<Identifiant>. Groupe
     centré sur l'axe de la page : colonne de 280px, écart de 64px, photo de
     520 x 390px, soit 864px ; colonne centrée en hauteur sur la photo tant
     qu'un univers a peu de liens (calage à revoir avec le vrai catalogue,
     Q24). Sans contenu CE sur le greffon, le gabarit ne rend pas
     l'emplacement et marque le groupe « --sans-visuel » : la colonne épouse
     alors ses libellés (280px au plus), comme en 2a, pour que le texte soit
     centré à l'œil. Filet si le greffon rend quelque chose sans image
     (contenu enregistré avant d'y poser le widget, contenu vide) :
     l'emplacement est masqué et la colonne traitée comme sans visuel.
     Remplissage de 32 / 48px porté par le groupe. Couleurs
     de page dans le panneau (jetons réinitialisés sur .submenu, plus haut).
     Hors de cette couche, au §12.11 : les soulignements (`.elementor a` les
     retire ici) et la photo (`.elementor img` lui ôte son rayon). */
  @media (min-width: 1200px) {
    .mq-entete .mq-sous-menu__groupe {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: var(--mq-espace-8);
      padding-block: var(--mq-espace-6) var(--mq-espace-7);
    }

    .mq-entete .mq-sous-menu__colonne {
      flex: 0 0 17.5rem;
      min-width: 0;
    }

    .mq-entete .mq-sous-menu__groupe--sans-visuel .mq-sous-menu__colonne,
    .mq-entete .mq-sous-menu__groupe:not(:has(.mq-sous-menu__visuel img)) .mq-sous-menu__colonne {
      flex: 0 1 auto;
      width: max-content;
      max-width: 17.5rem;
    }

    .mq-entete .mq-sous-menu__liens {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
    }

    .mq-entete .mq-sous-menu__titre {
      margin: 0 0 var(--mq-espace-3);
      font-size: var(--mq-taille-h4);
      font-weight: var(--mq-graisse-titre);
      line-height: var(--mq-interligne-sous-titre);
      color: var(--mq-couleur-titre);
    }

    .mq-entete .mq-sous-menu__liste {
      align-self: stretch;
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .mq-entete .mq-sous-menu__lien {
      display: flex;
      align-items: center;
      min-height: 2.75rem;
      font-size: 1rem;
      font-weight: var(--mq-graisse-texte);
      color: var(--mq-couleur-lien);
    }

    /* Sous-catégorie de la page en cours : en gras, comme l'entrée de premier
       niveau (décision d'Aurélien du 07/10/2026). */
    .mq-entete .mq-sous-menu__lien[aria-current="page"] {
      font-weight: var(--mq-graisse-titre);
    }

    .mq-entete .mq-sous-menu__tout {
      display: inline-flex;
      align-items: center;
      gap: var(--mq-espace-2);
      min-height: 2.75rem;
      margin-block-start: var(--mq-espace-4);
      font-size: var(--mq-taille-label);
      font-weight: var(--mq-graisse-texte);
      color: var(--mq-couleur-lien);
      text-transform: uppercase;
      letter-spacing: var(--mq-approche-capitales);
    }

    .mq-entete .mq-sous-menu__fleche {
      flex-shrink: 0;
      width: 1.125rem;
      height: 1.125rem;
    }

    /* Emplacement de la photo : 520px, réductible si la place manque. Sa
       hauteur suit la photo (§12.11 : 4:3, plafonnée sur un écran bas). */
    .mq-entete .mq-sous-menu__visuel {
      position: relative;
      flex: 0 1 32.5rem;
      min-width: 0;
    }

    .mq-entete .mq-sous-menu__visuel:not(:has(img)) {
      display: none;
    }

    /* Photos de démonstration (décision d'Aurélien du 07/10/2026) : pastille
       « Photo de démonstration » en bas à gauche, tant que le widget Image
       du contenu CE porte la classe mq-photo-demo (Avancé > Classes CSS) ;
       retirer la classe avec la vraie photo (Q24, choix d'Anaïs et Florence).
       Seul marquage : pas de légende dans CE (elle serait affichée en double
       et lue dans la navigation).
       Texte décoratif : masqué aux lecteurs d'écran par la syntaxe « / "" »
       (Chrome 77, Safari 17.4, Firefox 128 ; en deçà, la première
       déclaration reste et le texte est lu). Blanc sur marine plein : 11,8:1. */
    .mq-entete .mq-sous-menu__visuel:has(.mq-photo-demo)::after {
      content: "Photo de démonstration";
      content: "Photo de démonstration" / "";
      position: absolute;
      inset-inline-start: var(--mq-espace-4);
      inset-block-end: var(--mq-espace-4);
      padding: var(--mq-espace-1) 0.625rem;
      font-size: var(--mq-taille-surtitre);
      line-height: 1.5;
      color: var(--mq-blanc);
      text-transform: uppercase;
      letter-spacing: var(--mq-approche-surtitre);
      pointer-events: none;
      background-color: var(--mq-marine);
      border-radius: var(--mq-rayon-pilule);
    }
  }

  /* Centrage : Hummingbird fait du module un conteneur flex, où la navigation
     ne prend que la largeur de ses entrées (elle restait calée à gauche) ;
     elle occupe ici toute la rangée, et la liste centre ses entrées. */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__desktop {
    flex-grow: 1;
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li {
    min-height: 3rem;
  }

  /* Après une entrée à chevron, le bouton du chevron (22px + 2 x 2px) ajoute
     6px à l'écart visible : retirés pour avoir 32px partout. */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li:has(.ps-mainmenu__tree-dropdown-toggle) {
    margin-inline-end: -0.375rem;
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .ps-mainmenu__tree-item-wrapper {
    align-self: stretch;
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .ps-mainmenu__tree-link {
    display: flex;
    align-items: center;
    align-self: stretch;
    padding: 0;
    font-size: 0.875rem;
    font-weight: var(--mq-graisse-texte);
    color: var(--mq-entete-encre);
    text-transform: uppercase;
    letter-spacing: var(--mq-approche-capitales);
  }

  /* Souligné au survol : §12.11 (hors couche, `.elementor a` le retire ici). */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .ps-mainmenu__tree-link:hover {
    color: var(--mq-entete-encre);
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li.current .ps-mainmenu__tree-link {
    font-weight: var(--mq-graisse-titre);
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .ps-mainmenu__tree-dropdown-toggle {
    padding-block: 0;
    color: var(--mq-entete-encre);
  }

  /* Chevron : Hummingbird anime toutes ses propriétés (::after, all 150ms),
     couleur comprise, qui passerait du blanc au marine sur un fond déjà blanc.
     Seule la rotation reste animée (coupée en mouvement réduit par le
     jeton du §3). */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .ps-mainmenu__tree-dropdown-toggle::after {
    transition-property: transform;
  }

  /* Anneau de focus des entrées et des chevrons : Hummingbird le trace avec
     --bs-link-color (marine), invisible sur la photo ; il suit ici l'anneau
     du thème, jaune en haut de l'accueil (§3 de la conception, Accessibilité). */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li :is(.ps-mainmenu__tree-link, .ps-mainmenu__tree-dropdown-toggle):focus {
    outline-color: var(--mq-couleur-focus);
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__mobile-toggle .menu-toggle {
    color: var(--mq-entete-encre);
  }

  /* Le bouton de menu natif du module est remplacé par celui de la rangée 1
     (.mq-entete__burger) : masqué seulement quand ce bouton existe (la
     rangée 2 ne garde alors que le menu du bureau ; le tiroir reste dans le
     widget Module). Sans le bouton CE, le bouton natif reste affiché. Au
     bureau, le sélecteur ~ trouve aussi la copie « spacer » de B : sans
     effet. */
  .mq-entete--rangee1:has(.mq-entete__burger) ~ .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__mobile-toggle {
    display: none;
  }

  /* « Mon diagnostic » (page CMS n° 11, entrée de ps_mainmenu placée après
     les catégories et avant « Le magazine », décision Q3) : pilule jaune à
     texte marine au bureau, à sa place dans la liste, sur la photo comme sur
     le blanc (décision Q5, variante boutique du design system). Repère du
     contrat (§2.14) : data-id="cms-page-11" au bureau, #cms-page-11 dans le
     tiroir ; changer de page impose de changer ces sélecteurs. Test 9. */
  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li[data-id="cms-page-11"] .ps-mainmenu__tree-link {
    align-self: center;
    min-height: 2.5rem;
    padding-inline: 1.25rem;
    color: var(--mq-marine);
    background-color: var(--mq-jaune);
    border-radius: var(--mq-rayon-pilule);
  }

  .mq-entete .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li[data-id="cms-page-11"] .ps-mainmenu__tree-link:hover {
    color: var(--mq-marine);
    background-color: var(--mq-jaune-survol);
  }

  /* Tiroir du menu mobile : entrées en marine (Hummingbird : texte
     atténué), de 48px, chevron dans une zone de 44px, marge de 12px comme le
     contenu de la page, croix marine pleine de 44px, sans liseré sur les
     écrans de 400px et moins (le tiroir couvre l'écran). Panneau blanc : il
     garde ses couleurs de page en haut de l'accueil (jetons réinitialisés
     plus haut). */
  .ps-mainmenu:is(.ps-mainmenu--mobile) .menu a,
  .ps-mainmenu:is(.ps-mainmenu--mobile) .menu__title {
    color: var(--mq-couleur-lien);
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) .menu {
    padding-inline: 0.75rem;
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) .menu a {
    padding-block: 0.75rem;
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) .menu__toggle-child {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 2.75rem;
    min-height: 2.75rem;
    padding: 0;
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) .menu__toggle-child .material-icons {
    font-size: 1.5rem;
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) .btn-close {
    --bs-btn-close-opacity: 1;
    --bs-btn-close-bg: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23173b4f'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3E%3C/svg%3E");
    box-sizing: border-box;
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
  }

  @media (max-width: 400px) {
    .ps-mainmenu:is(.ps-mainmenu--mobile) {
      --bs-offcanvas-border-width: 0;
    }
  }

  /* « Mon diagnostic » dans le tiroir (tablette et mobile, décision Q5) :
     pilule jaune pleine largeur de 48px, placée en dernier par order, comme
     le panneau mobile du design system ; 12px capitales, comme les boutons.
     L'ordre de lecture suit l'affichage : seul le premier niveau du menu est
     concerné. Test 9. */
  .ps-mainmenu:is(.ps-mainmenu--mobile) #menu-mobile > .menu__list {
    display: flex;
    flex-direction: column;
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) #cms-page-11 {
    order: 1;
    margin-block-start: 1rem;
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) #cms-page-11 > .menu__link {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 3rem;
    padding-block: 0;
    font-size: var(--mq-taille-label);
    color: var(--mq-marine);
    text-transform: uppercase;
    letter-spacing: var(--mq-approche-capitales);
    background-color: var(--mq-jaune);
    border-radius: var(--mq-rayon-pilule);
  }

  .ps-mainmenu:is(.ps-mainmenu--mobile) #cms-page-11 > .menu__link:hover {
    color: var(--mq-marine);
    background-color: var(--mq-jaune-survol);
  }
}

/* ============================================================
   9. PIED DE PAGE CREATIVE ELEMENTS (modèle « Pied de page Mosqity »)
   En tête, la rangée « Besoin d'aide ? » sur turquoise très clair (bloc
   natif ps_linklist du greffon displayFooterBefore, classe mq-pied__aide),
   puis trois bandes marine de bord à bord : liens et newsletter séparés
   par un filet (vertical au bureau, horizontal une fois empilés), ligne
   signature, ligne basse. Le fond est posé sur chaque section (classe
   mq-pied--marine) ; le contenu reste sur la grille de 1240px.
   Newsletter, réseaux et blocs de liens sont les modules natifs
   (ps_emailsubscription, ps_socialfollow, ps_linklist) rendus par le
   widget Module avec leurs gabarits Hummingbird. Plusieurs de ces
   gabarits portent des classes utilitaires en !important (bg-*, py-*,
   justify-content-*, text-body-secondary) : on passe par leurs
   variables ou on compense, sans !important.
   ============================================================ */

@layer ps-base {
  /* Pages courtes (panier vide, 404) : sous le pied, le canevas prend le
     fond de html, donc le marine. Le body garde son fond blanc. */
  html {
    background-color: var(--mq-marine);
  }
}

@layer ps-modules {
  /* Sur le marine du pied (les trois sections), l'anneau de focus passe en
     jaune. */
  .mq-pied--marine {
    --mq-couleur-focus: var(--mq-jaune);
  }

  /* Rangée « Besoin d'aide ? » : bloc ps_linklist « Besoin d'aide ? »
     (greffon displayFooterBefore), rendu par le widget Module de la section
     mq-pied--aide, fond turquoise très clair posé dans CE. Titre et liens
     sur une ligne dès 1200px ; titre au-dessus des liens en dessous ; deux
     colonnes de 576 à 767px, une sous 576px. Liens de 44px partout. */
  .mq-pied__aide .ps-linklist {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 3rem;
    width: 100%;
    max-width: none;
    padding: 0;
    margin: 0;
  }

  .mq-pied__aide .footer-block__title {
    justify-content: flex-start;   /* était space-between (titre à bascule) */
    gap: 0.25rem;
    margin: 0;
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    line-height: 1.2;
    color: var(--mq-marine);
  }

  /* Picto officiel « bulle » en couleur du titre. Le dessin occupe 58 % de
     la hauteur du fichier : boîte de 40px pour un dessin de 23px, retrait
     de 10px pour aligner le dessin sur la grille. */
  .mq-pied__aide .footer-block__title::before {
    flex: none;
    width: 2.5rem;
    height: 2.5rem;
    margin-inline-start: -0.625rem;
    content: "";
    background-color: currentColor;
    mask: url("../img/pictos/avis-de-lexpert.svg") center / contain no-repeat;
  }

  /* Bouton d'accordéon de Hummingbird : masqué (sa classe stretched-link
     couvrirait toute la rangée sous 768px) ; la liste reste ouverte. */
  .mq-pied__aide .footer-block__title button {
    display: none;
  }

  .mq-pied__aide .footer-block__content.collapse {
    display: block;
    flex: 1 1 auto;
  }

  .mq-pied__aide .footer-block__list {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    column-gap: 1.5rem;
    padding: 0;
    list-style: none;
  }

  /* li en flex : pas de ligne de texte autour du lien (sinon 5px de
     jambage s'ajoutent sous un lien à picto). */
  .mq-pied__aide .footer-block__list li {
    display: flex;
    min-width: 0;
  }

  .mq-pied__aide .footer-block__list a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding-block: 0;
    font-size: 1rem;
    line-height: 1.25;
    color: var(--mq-marine);
  }

  .mq-pied__aide .footer-block__list a:hover {
    color: var(--mq-marine-700);
  }

  @media (max-width: 1199.98px) {
    .mq-pied__aide .ps-linklist {
      flex-direction: column;
      align-items: flex-start;
    }

    .mq-pied__aide .footer-block__content.collapse {
      width: 100%;
    }

    .mq-pied__aide .footer-block__list {
      justify-content: flex-start;
      column-gap: 2rem;
    }
  }

  @media (max-width: 767.98px) {
    .mq-pied__aide .footer-block__list {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      column-gap: 1.5rem;
    }
  }

  @media (max-width: 575.98px) {
    .mq-pied__aide .footer-block__list {
      grid-template-columns: minmax(0, 1fr);
    }
  }

  /* Newsletter sur marine : le fond du gabarit (bg-body-tertiary, importance
     forcée) prend le marine. Le titre est celui du widget Titre de CE. */
  .mq-pied__formulaire {
    --bs-tertiary-bg-rgb: 23, 59, 79;
  }

  /* Texte légal sous le champ : clair sur marine (9,2:1). La variable ne vaut
     que pour lui : posée sur tout le formulaire, elle donnait aussi sa couleur
     au texte d'exemple du champ (placeholder), qui se lisait comme une valeur
     saisie. */
  .mq-pied__formulaire .ps-emailsubscription p {
    --bs-secondary-color: #dde4e8;
  }

  /* Compense le py-3 / py-lg-4 (!important) de Hummingbird quand le
     formulaire est à côté du texte ; empilé (mobile), on le garde. */
  @media (min-width: 768px) {
    .mq-pied__formulaire .ps-emailsubscription {
      margin-block: -1rem;
    }
  }

  @media (min-width: 992px) {
    .mq-pied__formulaire .ps-emailsubscription {
      margin-block: -1.5rem;
    }
  }

  .mq-pied__formulaire .ps-emailsubscription .container {
    max-width: none;
    padding-inline: 0;
  }

  .mq-pied__formulaire .ps-emailsubscription .row {
    margin-inline: 0;
  }

  .mq-pied__formulaire .ps-emailsubscription .h3 {
    display: none;
  }

  .mq-pied__formulaire .ps-emailsubscription form {
    flex: 0 0 100%;
    width: 100%;
    max-width: 100%;
    padding-inline: 0;
  }

  /* Formulaire d'inscription : champ et bouton de 48px, retour à la ligne
     quand la place manque (le champ gardait 175px à 390px et tronquait
     l'adresse), bouton pleine largeur sous le champ sous 576px. */
  .mq-pied__formulaire .ps-emailsubscription form > .d-flex {
    flex-wrap: wrap;
  }

  .mq-pied__formulaire .ps-emailsubscription .form-control {
    flex-basis: 14rem;
    min-width: 0;
    min-height: 3rem;
    padding-block: 0.65rem;
    border-radius: var(--mq-rayon-pilule);
    background-color: var(--mq-blanc);
  }

  @media (max-width: 575.98px) {
    .mq-pied__formulaire .ps-emailsubscription .form-control {
      flex-basis: 100%;
    }

    .mq-pied__formulaire .ps-emailsubscription .btn-primary {
      flex-grow: 1;
    }
  }

  /* Réseaux : icônes jaunes, dans la ligne signature. */
  .mq-pied__reseaux .ps-socialfollow {
    margin-block: -1.5rem;
  }

  .mq-pied__reseaux .ps-socialfollow .container {
    display: flex;
    max-width: none;
    padding-inline: 0;
  }

  .mq-pied__reseaux .ps-socialfollow ul {
    width: fit-content;
    margin-inline-start: -0.625rem;
  }

  .mq-pied__reseaux .ps-socialfollow a {
    position: relative;
    display: inline-flex;
    color: var(--mq-jaune);
  }

  /* Zone tactile de 44px autour de la zone de 36px de Hummingbird (`.p-2`,
     importance forcée) : les zones se touchent, sans se recouvrir. */
  .mq-pied__reseaux .ps-socialfollow a::after {
    position: absolute;
    inset: -0.25rem;
    content: "";
  }

  /* Écart de 4px entre les icônes (Hummingbird) plus 2 x 2px de marge : les
     zones de 44px se touchent. */
  .mq-pied__reseaux .ps-socialfollow li {
    margin-inline: 0.125rem;
  }

  .mq-pied__reseaux .ps-socialfollow svg {
    width: 1.25rem;
    height: 1.25rem;
  }

  /* Courriel : zone de 44px de haut. */
  .mq-pied__courriel a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    font-size: 0.875rem;
    color: var(--mq-jaune);
  }

  /* Souligné au survol des liens du pied : §12.11 (hors couche). */

  /* Blocs de liens : trois colonnes côte à côte à partir de 768px (dans la
     moitié gauche du pied dès 1200px : 540px utiles à 1200px). En dessous,
     deux colonnes ouvertes, voir plus bas. */
  .mq-pied__liens .elementor-widget-container {
    display: flex;
    flex-wrap: wrap;
    column-gap: 1.5rem;
  }

  .mq-pied__liens .ps-linklist {
    flex: 1 1 0;
    width: auto;
    min-width: 9rem;
    max-width: none;
    padding-inline: 0;
  }

  .mq-pied__liens .footer-block__title {
    font-size: var(--mq-taille-surtitre);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-jaune);
    text-transform: uppercase;
    letter-spacing: var(--mq-approche-capitales);
  }

  .mq-pied__liens .footer-block a {
    font-size: 0.875rem;
    color: #dde4e8;
  }

  .mq-pied__liens .footer-block a:hover {
    color: var(--mq-blanc);
  }

  /* Mobile : blocs de liens ouverts, en deux colonnes, lignes de 44px. Le
     bouton d'accordéon est masqué, la liste reste visible. */
  @media (max-width: 767.98px) {
    .mq-pied__liens .elementor-widget-container {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 1.5rem;
    }

    .mq-pied__liens .ps-linklist {
      min-width: 0;
    }

    .mq-pied__liens .footer-block {
      margin-block-end: 0;
    }

    .mq-pied__liens .footer-block__title button {
      display: none;
    }

    .mq-pied__liens .footer-block__content.collapse {
      display: block;
    }

    .mq-pied__liens .footer-block__list a {
      display: flex;
      align-items: center;
      min-height: 2.75rem;
      padding-block: 0;
    }
  }

  /* Ligne légale (bloc « Informations légales », hook displayFooterAfter) :
     liens en ligne, toujours visibles ; le titre reste pour les lecteurs
     d'écran (il nomme la navigation). */
  .mq-pied__legal .ps-linklist {
    width: 100%;
    max-width: none;
    padding: 0;
    margin: 0;
  }

  .mq-pied__legal .footer-block__title {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    white-space: nowrap;
    clip: rect(0, 0, 0, 0);
    border: 0;
  }

  .mq-pied__legal .footer-block__title button {
    display: none;
  }

  .mq-pied__legal .footer-block__content.collapse {
    display: block;
  }

  .mq-pied__legal .footer-block__list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.375rem;
    padding: 0;
    list-style: none;
  }

  .mq-pied__legal .footer-block__list a {
    padding-block: 0.5rem;
    font-size: var(--mq-taille-label);
    color: #dde4e8;
    text-transform: uppercase;
    letter-spacing: var(--mq-approche-capitales);
  }

  /* Liens légaux : 34px au bureau, 44px sous 768px. */
  @media (max-width: 767.98px) {
    .mq-pied__legal .footer-block__list a {
      display: inline-flex;
      align-items: center;
      min-height: 2.75rem;
      padding-block: 0;
    }
  }

  .mq-pied__legal .footer-block__list a:hover {
    color: var(--mq-blanc);
  }
}

/* ============================================================
   10. ACCUEIL CREATIVE ELEMENTS (modèle « Accueil Mosqity »)
   Réglages de contenu dans CE ; ici seulement ce que CE ne sait pas
   exprimer proprement (liens d'action, arrondis de la grille), et le héro
   de l'en-tête moderne du 02/10/2026 (§2.10 et §4 de
   analyses/entete-moderne/entete-moderne-options.md) : section de bord à
   bord, première du modèle, sous l'en-tête posé (§8), voile marine en deux
   couches réglé dans CE ; option A (image fixe), puis option B (diaporama
   d'arrière-plan natif de CE et bouton pause, script
   assets/js/custom.js).
   ============================================================ */

@layer ps-components {
  /* Lien d'action (« Découvrir ») : 12px capitales, marine, souligné
     au survol, comme les liens d'action de mosqity.fr. */
  .mq-lien-action a {
    font-size: var(--mq-taille-label);
    font-weight: var(--mq-graisse-texte);
    color: var(--mq-couleur-lien);
    text-transform: uppercase;
    letter-spacing: var(--mq-approche-capitales);
    text-decoration-thickness: var(--mq-trait);
    text-underline-offset: 0.45em;
  }

  /* Souligné au survol : §12.11 (hors couche, `.elementor a` le retire ici). */

  /* Titres des cartes de pilier : liens marine sans soulignement. */
  .mq-carte-pilier .elementor-heading-title a {
    color: var(--mq-couleur-titre);
  }

  /* Héro : titre et accroche limités en largeur (17 et 32 caractères),
     comme sur mosqity.fr, pour rester sur la partie assombrie. */
  .mq-heros__titre .elementor-heading-title {
    max-width: 17ch;
    text-wrap: balance;
  }

  .mq-heros__accroche p {
    max-width: 32ch;
  }

  /* Héro : anneau de focus jaune sur la photo (boutons du héro, bouton
     pause), et déjà sur la carte sombre du héro encadré d'avant le geste 4.1. */
  .mq-heros {
    --mq-couleur-focus: var(--mq-jaune);
  }

  /* Héro pleine largeur (§2.10) : fond marine tant que la photo n'est pas
     affichée (photo lente ou absente, §2.1) ; le texte blanc de l'en-tête et
     du héro est alors posé sur du marine. Le champ de couleur de la section
     reste vide dans CE (geste S.7). Limité au héro pleine largeur, comme la
     condition HÉRO du §8 : le héro encadré d'aujourd'hui (section sans fond,
     carte arrondie dans la colonne) aurait sinon une bande marine de bord à
     bord autour de sa carte, entre la mise en ligne du CSS et le geste 4.1. */
  .mq-heros.elementor-section-full_width {
    background-color: var(--mq-marine);
  }

  /* Option B, bouton pause du diaporama (§4, geste B.3 ; WCAG 2.2.2). Posé
     par assets/js/custom.js en tête de la section, donc premier dans l'ordre
     de tabulation du héro. 44 x 44px, contour blanc de 1,5px, fond marine à
     60 %, picto au trait selon data-etat : « lecture » (le diaporama tourne :
     picto pause) ou « pause » (picto lecture). En bas à droite au bureau et
     en tablette ; masqué sur mobile, où rien ne défile tout seul (07/10/2026). Sans effet tant que le héro n'a pas de diaporama
     (option A) : le script ne pose alors aucun bouton. */
  .mq-heros__pause {
    position: absolute;
    z-index: 2;
    bottom: 4.5rem;
    inset-inline-end: 2.5rem;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    color: var(--mq-blanc);
    cursor: pointer;
    background-color: rgb(23 59 79 / 0.6);
    border: var(--mq-trait) solid var(--mq-blanc);
    border-radius: var(--mq-rayon-pilule);
  }

  .mq-heros__pause::before {
    width: 1.5rem;
    height: 1.5rem;
    content: "";
    background-color: currentColor;
    mask: url("../img/pictos/interface/pause.svg") center / contain no-repeat;
  }

  .mq-heros__pause[data-etat="pause"]::before {
    mask-image: url("../img/pictos/interface/lecture.svg");
  }

  .mq-heros__pause:hover {
    background-color: var(--mq-marine);
  }

  @media (max-width: 1199.98px) {
    .mq-heros__pause {
      bottom: 3.5rem;
      inset-inline-end: 1.5rem;
    }
  }

  /* Mobile (moins de 768px) : bouton masqué (décision d'Aurélien du
     07/10/2026). Le diaporama n'y défile pas tout seul (custom.js) : sans
     mouvement automatique, WCAG 2.2.2 n'exige aucun bouton, et le héro reste
     sur sa première photo. display: none le retire aussi de la tabulation. */
  @media (max-width: 767.98px) {
    .mq-heros__pause {
      display: none;
    }
  }

  /* Titres des widgets Titre de CE : lignes équilibrées (un seul mot ne reste
     pas seul à la ligne). Le titre du héro l'a déjà ci-dessus. */
  .elementor-widget-heading .elementor-heading-title {
    text-wrap: balance;
  }

  /* Arrondi des images de la grille des gammes : §12.11 (hors couche,
     `.elementor img` l'annule ici). */
}

/* ============================================================
   11. SECTIONS CREATIVE ELEMENTS : GOUTTIÈRE ET CARTES
   ============================================================ */

@layer ps-base {
  /* Sections CE de premier niveau en largeur limitée : même gouttière que
     les conteneurs de Hummingbird (12px de chaque côté). La largeur de
     contenu de CE est réglée à 1264px (1240px utiles, comme .container). */
  .elementor-top-section.elementor-section-boxed > .elementor-container {
    padding-inline: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
  }
}

@layer ps-components {
  /* Cartes posées sur des colonnes à fond (piliers, avis) : 24px entre elles
     (2 x 12px ; CE met la gouttière dans la même boîte que le fond). La rangée
     rentre de 12px de chaque côté pour que les cartes aillent jusqu'aux bords
     du contenu, comme titres et grilles (elles étaient en retrait de 8px). */
  .mq-carte-pilier > .elementor-element-populated,
  .mq-avis .elementor-inner-section .elementor-column > .elementor-element-populated {
    margin: 0.75rem;
  }

  .mq-entree-magazine .elementor-inner-section .elementor-row,
  .mq-avis .elementor-inner-section .elementor-row {
    min-width: calc(100% + 1.5rem);
    margin: -0.75rem;
  }

  @media (max-width: 767.98px) {
    .mq-carte-pilier > .elementor-element-populated,
    .mq-avis .elementor-inner-section .elementor-column > .elementor-element-populated {
      margin: 0 0 1rem;
    }

    .mq-entree-magazine .elementor-inner-section .elementor-row,
    .mq-avis .elementor-inner-section .elementor-row {
      min-width: 0;
      margin: 0;
    }
  }
}


/* ============================================================
   12. FICHE PRODUIT, VIGNETTE ET LISTES (étape 6, 01/10/2026)
   Rédigé, relu et corrigé sur copies locales du staging ; notes détaillées
   dans analyses/etape6-fiche-produit-listings/css-etape6-notes.md.

   Règles de rangement (GUIDE §5.2) :
   - Une valeur de Hummingbird se redéclare dans la MÊME couche que
     l'original : une règle de ps-components perd contre une règle de
     ps-pages ou de ps-modules, quelle que soit sa spécificité.
   - Exception (§12.11, section « surcharges de CE ») : les feuilles de Creative
     Elements sont HORS couche et passent devant toutes les couches. Ce
     qu'elles écrivent (fond du bouton, champs, largeur des articles, grille,
     pagination, filtres, liens, images) ne se corrige que par une règle
     hors couche de spécificité STRICTEMENT supérieure : une égalité ne se
     gagnerait que par l'ordre de chargement des feuilles, que CE peut changer.
     Les sélecteurs visent les classes « mq-* » du contrat avec CE, jamais
     les identifiants de widgets.
   - Aucune déclaration forcée : le mot-clé d'importance n'est jamais utilisé.
   - Les règles de la fiche visent « .page-product », classe aussi portée par
     le corps de l'aperçu rapide (« .page-product--quickview »).
   - Va avec les gabarits du thème enfant : product-details.tpl (sections
     et classe `mq-fiche-section--limites`) et miniatures/product.tpl (h3).

   Sommaire
     12.1  Largeur utile et gouttière unique
     12.2  Vignette produit
     12.3  Sélecteur de quantité
     12.4  Déclinaisons : légendes et pastilles de couleur
     12.5  Fiche produit : mise en page
     12.6  Fiche produit : sections, prix, description
     12.7  Fiche produit : modules, rythme et cibles tactiles
     12.8  Aperçu rapide
     12.9  Fil d'Ariane
     12.10 Listes : composants natifs
     12.11 Surcharges de Creative Elements (hors couche) : listes, grilles,
           accueil, pied, en-tête et recherche AJAX Search, surtitre à
           puce et fonds marine (lot G)
     12.12 Options retenues par Aurélien (01/10/2026)
   ============================================================ */


/* ------------------------------------------------------------
   12.1 LARGEUR UTILE ET GOUTTIÈRE UNIQUE
   ------------------------------------------------------------ */

@layer bs-base {
  /* Largeur utile à toutes les largeurs : le conteneur Bootstrap devient
     fluide sous 1264px et suit les blocs Creative Elements (en-tête, pied,
     accueil). Remplace la condition « min-width: 1400px » du §4 : si le §4
     est corrigé à la source, cette règle devient redondante. */
  .checkout-steps__mobile, .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xs, .container-xxl {
    max-width: calc(var(--mq-largeur-contenu) + var(--bs-gutter-x));
  }
}

@layer ps-base {
  /* Une section Creative Elements posée DANS un .container (listes, bas de
     fiche, modèles insérés) a déjà la gouttière du conteneur : on annule celle
     du §11. Hors .container (en-tête, pied, accueil), sans effet. */
  .container .elementor-top-section.elementor-section-boxed > .elementor-container {
    padding-inline: 0;
  }
}


/* ------------------------------------------------------------
   12.2 VIGNETTE PRODUIT (décision D4 B du 01/10/2026)
   Bouton texte pleine largeur, quantité masquée (le bouton ajoute 1), nom
   en Bold marine, ni zoom ni ombre au survol.
   ------------------------------------------------------------ */

@layer ps-components {
  /* Le champ garde sa valeur : l'ajout envoie qty=1 (ou la quantité
     minimale du produit). */
  .product-miniature .quantity-button {
    display: none;
  }

  .product-miniature__bottom {
    gap: 1rem;
    padding-inline: 0;
  }

  .product-miniature__form {
    align-items: stretch;
    flex-direction: column;
  }

  /* Bouton d'ajout et lien « Voir détails » : pilule pleine largeur. Le
     bouton d'ajout est un .btn-square-icon dont le remplissage est de 6px :
     on lui rend celui d'un bouton (14px, recentré à 15 / 13px plus bas, B9).
     Le libellé reste lu (aria-label) ; l'icône est masquée. */
  .product-miniature__add,
  .product-miniature__details {
    --bs-btn-padding-y: 0.875rem;
    padding-inline: 1rem;
    width: 100%;
    min-height: 2.75rem;
    text-wrap: balance;
  }

  @container product-miniature (width < 13.5rem) {
    .product-miniature__add,
    .product-miniature__details {
      padding-inline: 0.5rem;
    }
  }

  /* Le bouton d'ajout est un .btn-square-icon mais porte un texte : même
     recentrage que .btn (B9). */
  .product-miniature__add {
    padding-block: calc(var(--bs-btn-padding-y) + 1px) calc(var(--bs-btn-padding-y) - 1px);
  }

  .product-miniature__add .material-icons {
    display: none;
  }

  .product-miniature__add-text {
    display: block;
    line-height: inherit;
  }

  /* Nom du produit. Le gabarit enfant l'enveloppe d'un h3 : on lui retire la
     taille et la marge des titres (rendu identique avec ou sans le h3). */
  .product-miniature__heading {
    margin: 0;
    font-size: inherit;
    line-height: inherit;
  }

  .product-miniature__title {
    display: block;
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    line-height: 1.2;
  }

  .product-miniature__price {
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  /* 21px et 20px dès que la carte atteint 216px (13.5rem), le seuil
     qu'utilise déjà Hummingbird ; 18px en dessous (cartes mobiles de
     160 à 175px). */
  @container product-miniature (width >= 13.5rem) {
    .product-miniature__title {
      font-size: var(--mq-taille-h5);
    }

    .product-miniature__price {
      font-size: 1.25rem;
    }
  }

  /* Prix barré : 14px (R15). La couleur est déjà le texte atténué #587280
     par --bs-tertiary-color (§3). */
  .product-miniature__regular-price {
    font-size: 0.875rem;
  }

  /* Pastilles produit : une seule taille, celle du socle. Hummingbird les
     réduit à 12px et 2px sous 216px de carte. */
  .product-miniature .product-flags .badge {
    font-size: var(--mq-taille-surtitre);
    padding: 0.4375rem 0.875rem;
  }

  @container product-miniature (width < 13.5rem) {
    .product-miniature .product-flags .badge {
      padding-inline: 0.625rem;
    }
  }

  /* Cartes mobiles de 140 à 175px (écrans de 320 à 390px) : « Rupture de
     stock » (146px) dépassait de 14px à 320px et de 2px à 344px, rogné par la
     zone image. Remplissage et approche resserrés. */
  @container product-miniature (width < 11rem) {
    .product-miniature .product-flags .badge {
      padding-inline: 0.4375rem;
      letter-spacing: 0.03em;
    }
  }

  /* Bouton d'aperçu rapide des écrans tactiles, posé sur l'image : 44px
     (le remplissage de 6px des boutons carrés le laissait à 38px). */
  .product-miniature__quickview-touch {
    --bs-btn-padding-y: 0.5625rem;
  }

  /* Survol : plus de zoom ni d'ombre (le bandeau « Aperçu rapide » reste).
     Le souligné du nom, qui garde un signe de survol, est au §12.11 : dans
     une liste Creative Elements, `.elementor a` le retire. */
  @media (hover: hover) {
    .product-miniature__inner:hover .product-miniature__image {
      transform: none;
    }

    .product-miniature__inner:hover,
    .product-miniature__inner:has(:focus-visible) {
      box-shadow: none;
    }
  }
}


/* ------------------------------------------------------------
   12.3 SÉLECTEUR DE QUANTITÉ
   Un seul cadre : pilule à contour marine de 1.5px, boutons de 44px.
   Même composant sur la fiche, l'aperçu rapide et le panier.
   ------------------------------------------------------------ */

@layer ps-components {
  .quantity-button__group {
    height: 3rem;
    border: var(--mq-trait) solid var(--mq-marine);
    border-radius: var(--mq-rayon-pilule);
  }

  .quantity-button button {
    border: 0;
    min-width: 2.75rem;
  }

  .quantity-button button.decrement {
    border-radius: var(--mq-rayon-pilule) 0 0 var(--mq-rayon-pilule);
  }

  .quantity-button button.increment {
    border-radius: 0 var(--mq-rayon-pilule) var(--mq-rayon-pilule) 0;
  }

  .quantity-button input {
    max-width: 3.25rem;
    padding-block: 0;
    border: 0;
    border-radius: 0;
    font-weight: var(--mq-graisse-titre);
  }

  /* L'anneau de focus du champ entoure tout le groupe (un anneau
     rectangulaire dépasserait de la pilule). Les boutons gardent le leur. */
  .quantity-button input:focus {
    outline: 0;
  }

  .quantity-button__group:has(input:focus-visible) {
    outline: 2px solid var(--mq-couleur-focus);
    outline-offset: 2px;
  }
}


/* ------------------------------------------------------------
   12.4 DÉCLINAISONS : LÉGENDES ET PASTILLES DE COULEUR
   ------------------------------------------------------------ */

@layer ps-components {
  /* « TAILLE : S » sur une ligne, alignée sur la ligne de base. Hummingbird
     2.1.2 : plus d'enveloppe (.product-variant__label), légende et valeur
     enfants directs du fieldset. La légende flotte (Bootstrap) : elle n'est
     donc pas la « légende rendue » et devient un élément flex. Le choix
     passe à la ligne, 8px dessous (marge de .product-variant__attributes,
     Hummingbird). */
  .product-variant {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.25em;
  }

  .product-variant__attributes {
    flex-basis: 100%;
  }

  .product-variant__legend {
    font-size: var(--mq-taille-label);
    line-height: 1.45;
  }

  .product-variant__selected {
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-marine);
  }

  /* Pastilles : bordure de repos à 5.1:1 (le #dce1e5 de Hummingbird ne fait
     que 1.3:1 et la pastille blanche disparaît). */
  .product-miniature__variants .color,
  .product-variant__colors .color {
    border-color: var(--mq-texte-attenue);
  }

  /* Pastille choisie, survolée ou au clavier : anneau marine à l'extérieur
     (l'anneau intérieur de Hummingbird se perd sur une pastille foncée).
     Pastilles des facettes natives : en ps-modules, après ce paragraphe. */
  .product-miniature__variants .color.active,
  .product-miniature__variants .color:focus-visible,
  .product-miniature__variants .color:hover,
  .product-variant__colors .color.active,
  .product-variant__colors .color:focus-visible,
  .product-variant__colors .color:hover,
  .input-color__input:focus-visible + .input-color__label .color {
    outline: 2px solid var(--mq-marine);
    outline-offset: 2px;
  }

  /* Pastille cochée et au clavier : un seul anneau (celui de la pastille). */
  .input-color__input:checked:focus-visible + .input-color__label {
    box-shadow: none;
  }

  /* Vignette (Hummingbird 2.1.2, mixin color-swatch) : un seul anneau, le
     nôtre. */
  .product-miniature__variants .color:focus-visible {
    box-shadow: none;
  }

  /* Zone cliquable de 36px autour de la pastille de 24px, sans chevauchement
     avec les voisines (écart porté à 12px), sur la fiche et sur la vignette.
     Sur la vignette, la pastille est le lien lui-même et sa bordure de 1px
     réduit la zone de remplissage : le décalage est de 7px (36px au total). */
  .product-variant__colors,
  .product-miniature__variants {
    gap: 0.75rem;
  }

  .input-color__label,
  .product-miniature__variants .color {
    position: relative;
  }

  .input-color__label::after {
    content: "";
    position: absolute;
    inset: -0.375rem;
  }

  .product-miniature__variants .color::after {
    content: "";
    position: absolute;
    inset: -0.4375rem;
  }
}

@layer ps-modules {
  /* Facettes natives : Hummingbird 2.1.2 produit ces règles en ps-modules
     (mixins). Mêmes bordure et anneau que les pastilles ci-dessus. Seulement
     si la colonne native de ps_facetedsearch s'affiche : les listes passent
     par le widget Filtres de CE. */
  .search-filters__form-check--color .form-check-label .color {
    border-color: var(--mq-texte-attenue);
  }

  .search-filters__form-check--color .form-check-label .color.active,
  .search-filters__form-check--color .form-check-label .color:focus-visible,
  .search-filters__form-check--color .form-check-label .color:hover {
    outline: 2px solid var(--mq-marine);
    outline-offset: 2px;
  }

  .search-filters__form-check--color .color:focus-visible {
    box-shadow: 0 0 0 0.25rem rgba(23, 59, 79, 0.25);
  }
}


/* ------------------------------------------------------------
   12.5 FICHE PRODUIT : MISE EN PAGE
   ------------------------------------------------------------ */

@layer ps-pages {
  /* Bas de fiche en une colonne pleine largeur dès 992px : la colonne de
     droite ne reçoit plus rien depuis le retrait de la réassurance native
     (exception « product » dans Positions). À retirer si un module y
     revient. */
  @media (min-width: 992px) {
    .page-product .product__bottom {
      grid-template-columns: minmax(0, 1fr);
    }

    .page-product .product__bottom-right {
      display: none;
    }
  }

  /* Ordre d'affichage : description, sections (limites, sécurité, garantie,
     entretien, éco-conception), détails, fiche technique, documents. Le
     balisage ne change pas : l'ordre de tabulation reste celui de la
     lecture parce que les sections n'ont AUCUN élément focalisable.
     CONTRAINTE à respecter (GUIDE §6.4) : aucun lien ni bouton dans
     `.mq-fiche-section`. La lecture linéaire d'un lecteur d'écran suit le
     gabarit (détails avant sections). */
  .page-product .product__accordion {
    display: flex;
    flex-direction: column;
  }

  .page-product .js-product-details {
    display: contents;
  }

  .page-product .product__accordion > .accordion-item,
  .page-product .js-product-details > .accordion-item {
    order: 5;
  }

  .page-product #product_description {
    order: 1;
  }

  .page-product .mq-fiche-sections {
    order: 2;
  }

  .page-product #product_details {
    order: 3;
  }

  .page-product #product_features {
    order: 4;
  }

  .page-product .product__description {
    max-width: 75ch;
  }

  /* Quantité et bouton sur une ligne, y compris sous 576px (Hummingbird
     donne 100% à la quantité). */
  .page-product .product__quantity {
    width: auto;
  }

  .page-product .product__actions-qty-add {
    gap: 0.75rem;
  }

  /* Sous 576px, l'icône du bouton est retirée (le libellé suffit, comme sur
     la vignette) et le bouton prend la hauteur de la quantité (48px) : la
     place gagnée garde quantité et bouton sur une ligne dès 360px (375px dans
     l'aperçu rapide). Sous 344px environ, le bouton repasse dessous. */
  @media (max-width: 575.98px) {
    .page-product .product__add-to-cart-button {
      --bs-btn-padding-x: 1rem;
      min-height: 3rem;
    }

    .page-product .product__add-to-cart-button .material-icons {
      display: none;
    }
  }

  /* Une image : la bande de vignettes ne répète pas l'image principale. */
  .page-product .product__thumbnails:has(.product__thumbnails-list > :only-child) {
    display: none;
  }

  @media (min-width: 992px) {
    .page-product:not(.page-product--quickview) .product__carousel {
      border-radius: var(--mq-rayon-photo);
    }
  }

  .page-product .product__zoom {
    width: 2.75rem;
    height: 2.75rem;
  }

  /* Disponibilité : « en stock » et « stock faible » en marine (l'icône
     porte le sens), « rupture » reste en rouge Mosqity. Les variables sont
     redéclarées sur l'élément et non sur :root : le tunnel lit les mêmes
     variables (cercle de l'étape) et n'est pas touché. Même technique pour
     le libellé de stock d'une ligne du panier (`text-warning` jaune #ffc107
     sur blanc, 1.63:1, et vert #188251 sinon). Depuis O3 B (02/10/2026),
     --bs-success-rgb vaut aussi le marine sur :root (§3) ; la règle reste
     pour --bs-warning-rgb, que le §3 ne redéclare pas. */
  .page-product .product__availability-status,
  .product-line__item-availability-message {
    --bs-success-rgb: 23, 59, 79;
    --bs-warning-rgb: 23, 59, 79;
  }

  .page-product .product__bottom-left,
  .page-product .product__bottom-right {
    margin-block-end: 0;
  }
}


/* ------------------------------------------------------------
   12.6 FICHE PRODUIT : SECTIONS, PRIX, DESCRIPTION
   Les sections viennent de la surcharge product-details.tpl
   (caractéristiques repérées par leur nom).
   ------------------------------------------------------------ */

@layer ps-pages {
  .page-product .product__price {
    font-size: var(--mq-taille-h3);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .mq-fiche-sections {
    margin-block-start: var(--mq-espace-5);
  }

  .mq-fiche-section {
    padding-block: var(--mq-espace-5);
    border-bottom: 1px solid var(--bs-border-color);
  }

  /* « Les limites de ce produit » (exigence P1) : encart blanc cassé. Il suit
     le SENS et non la position : la classe `mq-fiche-section--limites` est
     posée par le gabarit product-details.tpl sur la section de ce titre (à
     livrer avec cette CSS, voir les notes). Si la caractéristique est vide, la
     section n'existe pas et aucune autre ne prend l'encart. */
  .mq-fiche-section--limites {
    padding: var(--mq-espace-5);
    border-bottom: 0;
    border-radius: var(--mq-rayon-carte);
    background-color: var(--mq-blanc-casse);
  }

  .mq-fiche-section__titre {
    margin-bottom: var(--mq-espace-2);
    font-size: 1.25rem;
  }

  .mq-fiche-section__texte {
    max-width: 75ch;
    margin-bottom: 0;
  }

  /* Titre à gauche, texte à droite dès 992px. Les colonnes viennent du
     conteneur (sous-grille) pour que les textes de l'encart et des lignes
     démarrent au même endroit ; sans sous-grille, repli sur les mêmes
     colonnes par section. */
  @media (min-width: 992px) {
    .mq-fiche-sections {
      display: grid;
      grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
      column-gap: var(--mq-espace-6);
    }

    .mq-fiche-section {
      display: grid;
      grid-column: 1 / -1;
      grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
      column-gap: var(--mq-espace-6);
    }

    .mq-fiche-section--limites {
      padding: var(--mq-espace-6);
    }

    .mq-fiche-section__titre {
      margin-bottom: 0;
    }
  }

  @supports (grid-template-columns: subgrid) {
    @media (min-width: 992px) {
      .mq-fiche-section {
        grid-template-columns: subgrid;
      }
    }
  }
}

@layer ps-components {
  /* Texte riche de la description (éditeur du back-office) : listes
     numérotées avec leurs numéros, intertitres à l'échelle de la fiche
     (sous le h2 « Description » de l'accordéon). */
  .rich-text ol {
    padding-left: 1.2rem;
    list-style: decimal;
  }

  .product__description h2 {
    font-size: var(--mq-taille-h5);
  }

  .product__description h3 {
    font-size: var(--mq-taille-h6);
  }

  .product__description h4 {
    font-size: 1rem;
  }

  .product__description :is(h2, h3, h4) {
    margin-block: 1.5rem 0.5rem;
  }

  .product__description > :first-child {
    margin-top: 0;
  }
}


/* ------------------------------------------------------------
   12.7 FICHE PRODUIT : MODULES, RYTHME ET CIBLES TACTILES
   ------------------------------------------------------------ */

@layer ps-modules {
  .ps-sharebuttons__link {
    color: var(--mq-couleur-lien);
  }

  .product__additional-info .ps-sharebuttons__link,
  .quickview__footer .ps-sharebuttons__link {
    width: 2.75rem;
    height: 2.75rem;
  }

  /* Un pas de 96px (64px sous 768px) entre les blocs sous la fiche ;
     les marges basses de Hummingbird (32 et 48px) sont retirées. */
  .page-product .product-comments-wrapper,
  .page-product .ps-categoryproducts,
  .page-product .ps-viewedproduct {
    margin-block: var(--mq-espace-9) 0;
  }

  @media (max-width: 767.98px) {
    .page-product .product-comments-wrapper,
    .page-product .ps-categoryproducts,
    .page-product .ps-viewedproduct {
      margin-block-start: var(--mq-espace-8);
    }
  }

  /* Bloc « Prévenez-moi » en rupture. */
  .ps-emailalerts__content {
    padding: var(--mq-espace-5);
  }

  .ps-emailalerts .btn {
    text-wrap: balance;
  }

  /* Avis produits, Hummingbird 2.1.2 : mixins en ps-modules au lieu de
     @extend. Le pictogramme (§6, champs .error des avis) perd le
     no-repeat et la taille de Bootstrap ; halos retirés (O3 B). Défaut
     latent : module désactivé depuis le 01/10/2026. */
  .product-comment-modal input[name="comment_title"].error,
  .product-comment-modal input[name="customer_name"].error,
  .product-comment-modal textarea.error {
    background-repeat: no-repeat;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
  }

  .product-comment-modal input[name="comment_title"].error:focus,
  .product-comment-modal input[name="customer_name"].error:focus,
  .product-comment-modal textarea.error:focus,
  .product-comment-modal input[name="comment_title"].valid:focus,
  .product-comment-modal input[name="customer_name"].valid:focus,
  .product-comment-modal textarea.valid:focus {
    box-shadow: none;
  }
}


/* ------------------------------------------------------------
   12.8 APERÇU RAPIDE
   Rayon 30 et ombre douce (seule ombre admise, sur les fenêtres). Sous
   768px, la fenêtre est compactée pour que le bouton d'ajout soit visible
   sans défilement dès environ 660px de hauteur utile (390 x 664 et
   375 x 667 compris, barres du navigateur déduites). En dessous, le
   défilement interne de la fenêtre reste acceptable.
   Gardé tant que le retrait de l'aperçu (GUIDE §6.4) n'est pas définitif.
   `.modal .btn-close` vaut pour toutes les fenêtres (zoom, panier, avis) :
   ne jamais la retirer avec le reste (B13).
   ------------------------------------------------------------ */

@layer ps-components {
  .quickview__content {
    border-radius: var(--mq-rayon-photo);
    box-shadow: var(--mq-ombre-douce);
  }

  /* Croix pleine (opacité 1) et marine, de 44px, dans toutes les fenêtres :
     aperçu rapide, zoom de la galerie, avis, panier. L'original (`.btn-close`,
     bs-components) est grise, à 50% d'opacité, sur une zone de 40px. */
  .modal .btn-close {
    --bs-btn-close-opacity: 1;
    --bs-btn-close-bg: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23173b4f'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3E%3C/svg%3E");
    box-sizing: border-box;
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
  }

  .quickview__details-link {
    min-height: 2.75rem;
  }

  @media (max-width: 767.98px) {
    .quickview {
      --bs-modal-padding: 1rem;
    }

    /* La croix flotte sur l'image au lieu de prendre une rangée de 68px. */
    .quickview__header {
      position: absolute;
      top: 1.25rem;
      right: 1.25rem;
      z-index: 2;
      padding: 0;
    }

    .quickview .btn-close {
      border-radius: 50%;
      background-color: var(--mq-blanc);
    }
  }
}

@layer ps-pages {
  .page-product--quickview .product__name {
    font-size: 2.25rem;
  }

  @media (max-width: 767.98px) {
    .page-product--quickview .product__thumbnails {
      display: none;
    }

    .page-product--quickview .product__images {
      margin-block-end: 1rem;
    }

    /* Hauteur fixe et photo entière (contain) : un recadrage en 16 / 9
       couperait le sommet ou le pied des photos carrées du catalogue. */
    .page-product--quickview .carousel-item img {
      aspect-ratio: auto;
      height: 9.5rem;
      object-fit: contain;
      background-color: var(--mq-blanc-casse);
    }

    .page-product--quickview .product__description-short {
      display: none;
    }

    /* Pas de marge basse ici : le gabarit pose `.mb-1` (utilitaire à
       l'importance forcée), une déclaration serait perdue. */
    .page-product--quickview .product__name {
      font-size: 1.75rem;
    }

    .page-product--quickview .product__manufacturer,
    .page-product--quickview .product__prices,
    .page-product--quickview .product__variants {
      margin-block-end: 1rem;
    }

    .page-product--quickview .product__actions,
    .page-product--quickview .product__actions-qty-add {
      margin-block-end: 0;
    }

    .page-product--quickview .product__add-to-cart-button {
      --bs-btn-padding-x: 0.75rem;
    }
  }
}

@layer ps-modules {
  /* Le partage ne sert pas à acheter : retiré de l'aperçu sous 768px. */
  @media (max-width: 767.98px) {
    .quickview__footer .ps-sharebuttons {
      display: none;
    }
  }
}


/* ------------------------------------------------------------
   12.9 FIL D'ARIANE
   ------------------------------------------------------------ */

@layer bs-custom-components {
  /* Sous 768px, Hummingbird garde le fil sur une ligne qui défile sans
     indice : la page courante sort du champ. Retour à la ligne à la place.
     Écart de 8px entre les lignes : les zones de lien (32px de haut) de deux
     lignes se chevauchent encore de 8px (12px avec 4px d'écart). Le séparateur
     « › » peut ouvrir la deuxième ligne : sans correction propre en CSS,
     accepté. */
  @media (max-width: 767.98px) {
    .breadcrumb {
      flex-wrap: wrap;
      overflow-x: visible;
      row-gap: 0.5rem;
    }
  }

  .breadcrumb-link {
    display: inline-block;
    padding-block: 0.5rem;
    margin-block: -0.5rem;
  }

  /* Fil à un seul maillon (panier, catégorie Accueil, toute page de premier
     niveau) : masqué. Hummingbird 2.1.2 ne masque plus ce fil (règle morte
     retirée) : cette règle est la seule. Le `nav` reste en place, invisible
     et hors de l'arbre d'accessibilité : sa marge basse (24px, 40px dès
     768px) garde l'écart sous l'en-tête (C1). */
  .breadcrumb__wrapper[data-depth="1"] {
    visibility: hidden;
  }

  .breadcrumb__wrapper[data-depth="1"] .breadcrumb {
    display: none;
  }
}


/* ------------------------------------------------------------
   12.10 LISTES : COMPOSANTS NATIFS
   ------------------------------------------------------------ */

@layer ps-pages {
  /* Texte de bas de catégorie : ligne limitée, sans marge basse (le rythme
     vient des sections). La règle de Hummingbird est dans ps-pages. */
  .page-category .category__additional-description {
    max-width: 70ch;
    margin-bottom: 0;
  }
}

@layer ps-components {
  /* Section de bas de liste sans texte (catégorie sans description
     additionnelle, ou page 2 et suivantes) : elle ne laisse plus de vide. */
  .mq-bas-de-liste:not(:has(.category__additional-description)) {
    display: none;
  }
}


/* ------------------------------------------------------------
   12.11 SURCHARGES DE CREATIVE ELEMENTS (HORS COUCHE)
   Seule section hors couche du §12 : les règles hors couche battent les couches et se
   départagent par la spécificité, puis par l'ordre de chargement. Elle rassemble les
   corrections de CE de tout le thème : listes et grilles (étape 6), accueil, en-tête
   et pied (soulignements), puis l'en-tête moderne du 02/10/2026 (transitions des
   sections, recherche AJAX Search), enfin les composants communs des pages de
   contenu du lot G (surtitre à puce, fonds marine), en fin de section.
   ------------------------------------------------------------ */

/* Grille de vignettes (listes, accueil) : même écart que la gouttière
   (24px, 16px en mobile) et cartes étirées, pour que les boutons soient au
   même niveau. CE écrit gap: 15px et align-self: flex-start. */
.elementor .ce-product-grid {
  gap: var(--mq-espace-4);
}

@media (min-width: 768px) {
  .elementor .ce-product-grid {
    gap: var(--mq-espace-5);
  }
}

.ce-product-grid > .product-miniature {
  align-self: stretch;
}

/* Nom de la vignette souligné au survol de la carte (liste CE ou native). */
@media (hover: hover) {
  .product-miniature__inner:hover .product-miniature__title {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }
}

/* Bouton Filtrer et filtres actifs : le type « par défaut » de CE n'a pas de
   fond (la base écrit #818a91). La variable est celle que CE règle au survol
   (#E2E9ED) ; elle est déclarée avec une valeur initiale transparente, le
   repos est donc transparent, soit blanc sur la page. Le fond blanc du Style
   du thème (C4) est à égalité de spécificité avec la base de CE : la règle
   reste. */
.mq-liste__filtres .elementor-button,
.mq-liste__filtres-actifs .elementor-button {
  background-color: var(--ce-btn-bg-color);
}

/* Sous-catégories en pilules contour marine de 44px, à la ligne (CE les
   pose en articles de 300px, sans retour à la ligne, avec défilement). */
.elementor .mq-sous-categories .elementor-widget .elementor-widget-container .ce-articles {
  gap: var(--mq-espace-2) var(--mq-espace-3);
  flex-wrap: wrap;
  overflow: visible;
  scroll-snap-type: none;
}

.elementor .mq-sous-categories .elementor-widget .elementor-widget-container .ce-articles .ce-article {
  width: auto;
  padding: 0;
  background: none;
}

.elementor .mq-sous-categories .elementor-widget .elementor-widget-container .ce-article__title a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-inline: 1.5rem;
  border: var(--mq-trait) solid var(--mq-marine);
  border-radius: var(--mq-rayon-pilule);
  font-size: var(--mq-taille-label);
  text-transform: uppercase;
  letter-spacing: var(--mq-approche-capitales);
}

.elementor .mq-sous-categories .elementor-widget .elementor-widget-container .ce-article__title a:hover {
  background-color: var(--mq-marine-100);
}

/* État vide (modèle n° 7 dans la grille) : le compteur « Il y a 0 produits. »
   est masqué à l'écran mais gardé pour les lecteurs d'écran (zone
   role="status" de CE, annoncée après un filtrage) (C5). PrestaShop n'a pas de
   forme au singulier pour 0 et le titre du modèle dit déjà qu'aucun produit ne
   correspond. Hors couche car CE écrit .elementor-widget { position: relative }
   hors couche ; 0,4,0 dépasse les règles de CE sur ce widget (0,3,0 au plus).
   Sorti du flux, le widget ne laisse aucun écart dans la rangée. */
.elementor .mq-liste:has(.mq-aucun-resultat) .mq-liste__nombre {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Tri : champ aux valeurs du socle (§6), anneau de focus au clavier (CE le
   supprime), étiquette et chevron marine. */
.mq-liste__tri {
  --ce-field-color: var(--mq-marine);
}

.mq-liste__tri .elementor-field-label {
  color: var(--mq-marine);
}

.mq-liste__tri .elementor-field-group .elementor-field-textual {
  min-height: 3rem;
  padding: 0.65rem 2.75rem 0.65rem 1.125rem;
  border: var(--mq-trait) solid var(--mq-marine);
  border-radius: var(--mq-rayon-champ);
  color: var(--mq-marine);
  font-size: 1rem;
  font-weight: var(--mq-graisse-texte);
}

.mq-liste__tri .elementor-field-group .elementor-select-wrapper:before {
  inset-inline-end: 1.125rem;
}

.mq-liste__tri .elementor-field-group .elementor-field-textual:focus-visible {
  outline: 2px solid var(--mq-couleur-focus);
  outline-offset: 2px;
  box-shadow: none;
}

/* Mobile : le tri prend toute la ligne, sous « Il y a N produits » et
   Filtrer. */
@media (max-width: 767.98px) {
  .mq-liste__tri {
    flex: 1 1 100%;
  }
}

/* Pagination : numéros et flèches groupés au centre, cibles de 44px, page
   courante en pastille marine (CE écrit un lien sans cadre à chaque bord).
   Sur mobile la liste complète passe sur deux rangées dès 5 pages à 390px
   (4 pages à 360px) : 24 produits par page (B5, 01/10/2026) ; la variante
   compacte listes-32 est écartée. */
.elementor .mq-liste__pagination .ce-pagination {
  gap: var(--mq-espace-2);
  justify-content: center;
}

.elementor .mq-liste__pagination .ce-pagination .elementor-row {
  width: auto;
}

.elementor .mq-liste__pagination .ce-pagination a,
.elementor .mq-liste__pagination .ce-pagination li > .elementor-icon-list-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  border-radius: var(--mq-rayon-pilule);
}

.elementor .mq-liste__pagination .ce-pagination a:hover {
  background-color: var(--mq-marine-100);
}

.elementor .mq-liste__pagination .ce-pagination li:not(:has(a)) > .elementor-icon-list-text {
  background-color: var(--mq-marine);
  color: var(--mq-blanc);
  font-weight: var(--mq-graisse-titre);
}

/* Panneau de filtres : croix de 44px dégagée du premier groupe, lignes et
   options de 44px, cases et curseur à la charte (CE écrit du bleu #0075ff).
   La croix est visée à l'état OUVERT (`.ce-filters--shown`, 0,4,0) : CE la
   cache panneau fermé par `.ce-filters__container:not(.ce-filters--shown)
   .dialog-lightbox-close-button { display: none }` (0,3,0), qu'une règle de
   même poids ne battrait que par l'ordre de chargement. */
.mq-liste__filtres .ce-filters__container.ce-filters--shown .dialog-lightbox-close-button {
  top: 0.5rem;
  inset-inline-end: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin: 0;
  font-size: 1.25rem;
  color: var(--mq-marine);
}

.mq-liste__filtres .ce-filters__container.ce-filters--shown .dialog-lightbox-close-button:hover,
.mq-liste__filtres .ce-filters__container.ce-filters--shown .dialog-lightbox-close-button:focus {
  color: var(--mq-marine);
}

.mq-liste__filtres .ce-filters__container.ce-filters--shown .ce-filters {
  padding: 4rem 1.5rem 1.5rem;
}

.mq-liste__filtres .ce-filters .ce-filters__tab,
.mq-liste__filtres .ce-filters .elementor-field-option {
  min-height: 2.75rem;
}

.mq-liste__filtres .ce-filters .elementor-field-subgroup {
  gap: 0;
}

.mq-liste__filtres .ce-filters .ce-checkbox,
.mq-liste__filtres .ce-filters .ce-radio {
  width: 1.25rem;
  height: 1.25rem;
  border: var(--mq-trait) solid var(--mq-marine);
}

.mq-liste__filtres .ce-filters input:checked ~ .ce-checkbox {
  border-color: var(--mq-marine);
  background: var(--mq-marine);
  color: var(--mq-jaune);
}

.mq-liste__filtres .ce-filters input:checked ~ .ce-radio {
  border-color: var(--mq-marine);
  background-color: var(--mq-marine);
  background-image: radial-gradient(circle, var(--mq-jaune) 44%, transparent 50%);
}

.mq-liste__filtres .ce-filters .ce-dual-range {
  --ce-range-active-color: var(--mq-marine);
}

/* Aucun résultat : le titre du modèle passe au jeton h3 (le h1 de la page
   garde la taille de titre). CE impose line-height: 1 aux titres. */
.elementor .mq-aucun-resultat .elementor-heading-title {
  font-size: var(--mq-taille-h3);
  line-height: var(--mq-interligne-sous-titre);
}

/* Image de catégorie du héro : cadrée (CE la sert à sa taille d'origine et
   `.elementor img` impose border-radius: 0). */
.elementor .mq-heros-categorie__image img {
  width: 100%;
  max-height: 280px;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--mq-rayon-carte);
}

/* Liens des textes de Creative Elements : `.elementor a` retire le
   soulignement, le lien n'est alors distingué du texte noir que par une
   couleur à 1.8:1. Texte de bas de liste souligné ; lien du héro blanc
   souligné, focus jaune sur le fond marine. */
.elementor .rich-text a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.mq-heros-categorie {
  --mq-couleur-focus: var(--mq-jaune);
}

.elementor .mq-heros-categorie__intro a {
  color: var(--mq-blanc);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Accueil : deux règles du §10 de mosqity.css sont sans effet (en couche, elles
   perdent contre `.elementor img` et `.elementor a`, hors couche) ; elles sont
   reprises ici et à RETIRER du §10 à la fusion. Images de la grille des gammes
   arrondies comme les cartes (mesuré : 0px au lieu de 19px) ; lien d'action
   souligné au survol (l'épaisseur et le décalage restent ceux du §10). */
.elementor .mq-gammes__grille img {
  border-radius: var(--mq-rayon-carte);
}

.elementor .mq-lien-action a:hover {
  text-decoration: underline;
}

/* En-tête et pied : soulignement au survol du menu du bureau et des liens du
   pied, retiré par `.elementor a` (0,1,1) quand la règle est en couche. */
.elementor .mq-entete .ps-mainmenu .ps-mainmenu__tree-link:hover,
.elementor .mq-pied__aide .footer-block__list a:hover,
.elementor .mq-pied__legal .footer-block__list a:hover,
.elementor .mq-pied__liens .footer-block a:hover,
.elementor .mq-pied__courriel a:hover {
  text-decoration: underline;
  text-decoration-thickness: var(--mq-trait);
}

.elementor .mq-entete .ps-mainmenu .ps-mainmenu__tree-link:hover {
  text-underline-offset: 0.45em;
}

/* « Mon diagnostic » (pilule du menu, §8) : pas de soulignement au survol,
   le fond change déjà. 0,6,1 dépasse la règle ci-dessus (0,5,0). */
.elementor .mq-entete .ps-mainmenu li[data-id="cms-page-11"] .ps-mainmenu__tree-link:hover {
  text-decoration: none;
}

/* En-tête moderne (02/10/2026, §8) : corrections de CE.
   Sections de l'en-tête sans transition. CE écrit sur chaque section
   transition: background 0.3s, border 0.3s, border-radius 0.3s, box-shadow
   0.3s (CSS généré du modèle n° 1, 0,3,0, relevé dans la feuille servie le
   01/10/2026). Au retour en haut de l'accueil, le fond passerait du blanc au
   transparent en 300ms sous un texte déjà blanc : le défaut que le §2.1
   exclut.
   Fond des sections : celui de l'état (jeton --mq-entete-fond du §8), même
   si un fond est rempli dans CE. CE écrit le fond d'une section avec
   « .elementor-1170101 .elementor-element.elementor-element-…:not(.elementor-
   motion-effects-element-type-background) » (0,4,0, hors couche) : ce
   #FFFFFF, que le geste 3.3 retire, battrait le jeton transparent en haut de
   l'accueil, sous un texte blanc. Garde-fou à 0,5,0, qui ne dépend plus de ce
   geste. */
.elementor .elementor-element.elementor-section.elementor-top-section.mq-entete {
  background-color: var(--mq-entete-fond);
  transition: none;
}

/* Panneaux du menu bord à bord (conception du 06/10/2026, §2.5) : au
   bureau, les enveloppes de CE de la rangée 2 (conteneur, colonne,
   column-wrap, widget-wrap, widget Module) sont en position: relative ; le
   panneau de Hummingbird (absolu, left et right à 0) se calait sur le widget
   (1 345px à 1 440px, à cause des 40px de remplissage de la section). Rendues
   statiques, c'est la section, pleine largeur, qui devient son bloc
   conteneur ; le top que le script écrit en ligne (offsetTop + offsetHeight
   du li) reste juste. .elementor-row n'est pas positionnée, la nav l'est déjà
   en static. Repli si l'éditeur de CE place mal ses poignées : inset-inline
   de -2.5rem sur le panneau, lié aux 40px de la section. */
@media (min-width: 1200px) {
  .elementor .mq-entete--rangee2 :is(.elementor-container, .elementor-column, .elementor-column-wrap, .elementor-widget-wrap, .elementor-widget.mq-entete__menu) {
    position: static;
  }
}

/* Panneaux du menu, étape 2b (07/10/2026, règles de mise en page au §8).
   Soulignés : liens des sous-catégories au survol, « Voir tout » toujours
   (`.elementor a`, 0,1,1, retire le soulignement d'une règle en couche).
   Photo du contenu CE posé sur le greffon de l'univers : `.elementor img`
   (0,1,1) remet son rayon à 0 ; règle à 0,3,1. Format 4:3 sur la largeur de
   l'emplacement (520px), recadrée (object-fit: cover) ; sur un écran bas, sa
   hauteur se réduit pour que le panneau tienne sans défiler : fenêtre moins
   l'en-tête (8rem, comme la hauteur maximale du panneau au §8) et le
   remplissage du groupe (32 + 48px), soit 208px ; effet visible sous 598px
   de hauteur de fenêtre (à 540px, photo de 332px). Fond blanc cassé pendant
   le chargement (chargement différé natif de CE).
   Contrat du contenu CE : un seul widget Image, sans lien, sans légende (la
   pastille « Photo de démonstration » vient du CSS, §8), texte alternatif
   vide, champs de style vides, section sans écart de colonnes ni classe ;
   une règle de style remplie dans CE (0,3,1 ou plus) pourrait l'emporter. */
@media (min-width: 1200px) {
  .elementor .mq-entete .mq-sous-menu__lien:hover,
  .elementor .mq-entete .mq-sous-menu__tout {
    text-decoration: underline;
    text-decoration-thickness: var(--mq-trait);
  }

  .elementor .mq-entete .mq-sous-menu__lien:hover {
    text-underline-offset: 0.3em;
  }

  .elementor .mq-entete .mq-sous-menu__tout {
    text-underline-offset: 0.45em;
  }

  .elementor .mq-entete .mq-sous-menu__visuel img {
    display: block;
    width: 100%;
    height: auto;
    max-height: calc(100vh - 8rem - var(--mq-espace-6) - var(--mq-espace-7));
    max-height: calc(100dvh - 8rem - var(--mq-espace-6) - var(--mq-espace-7));
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background-color: var(--mq-blanc-casse);
    border-radius: var(--mq-rayon-photo);
  }
}

/* Recherche, widget AJAX Search de CE (décision Q6, §2.6). Feuille du widget
   relevée sur la démonstration de WebshopWorks (02/10/2026) : le conteneur
   porte le fond (#eceeef) et une transition générale (.2s), le champ et le
   bouton des transitions de couleur, l'indication une opacité de 0,6, et le
   focus du champ est retiré (outline: 0). Les règles du CSS généré pour le
   widget, si un réglage de style est rempli dans CE, vont jusqu'à 0,5,0 :
   les sélecteurs ci-dessous valent 0,6,0 au moins. Les champs de couleur et
   de bordure du widget restent vides dans CE. Les couleurs viennent des
   jetons --mq-entete-champ-* du §8 : verre marine en haut de l'accueil
   (condition ACCUEIL-HAUT, écrite au §8 seulement), blanc à contour marine
   partout ailleurs et dans les panneaux. Aucune transition, pour que le
   verre marine bascule au blanc d'un coup (test 17). Classes et type du
   champ à confirmer dans le DOM de la boutique (tests 5 et 6). */

/* Habillage Classic (dès 768px) : pilule de 48px, loupe d'envoi à droite
   (bouton en icône du widget, loupe posée en masque plus bas). Le flou est
   posé sur le champ, jamais sur une section : sur un ancêtre du tiroir, il
   deviendrait le cadre de sa position fixe (§2.14). */
.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search,
.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__container,
.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__input,
.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__submit {
  transition: none;
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__container {
  min-height: 3rem;
  background-color: var(--mq-entete-champ-fond);
  border: var(--mq-trait) solid var(--mq-entete-champ-bord);
  border-radius: var(--mq-rayon-pilule);
  -webkit-backdrop-filter: var(--mq-entete-champ-flou);
  backdrop-filter: var(--mq-entete-champ-flou);
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__input {
  min-width: 0;
  padding-inline: 1.25rem 0.25rem;
  font-size: 1rem;
  color: var(--mq-entete-champ-texte);
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__input::placeholder {
  color: var(--mq-entete-champ-indication);
  opacity: 1;
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__submit {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  min-width: 3rem;
  padding: 0;
  font-size: 1.5rem;
  color: var(--mq-entete-champ-icone);
  background-color: transparent;
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__clear {
  color: var(--mq-entete-champ-icone);
  opacity: 1;
}

/* Loupe au trait des deux habillages. CE affiche dans l'éditeur l'icône SVG
   indiquée par son adresse, mais ne la rend pas côté boutique (bouton vide,
   relevé du 02/10/2026). Le picto est donc posé en masque, comme ceux du
   compte et du panier (§8) ; une icône que CE rendrait (éditeur, réglage
   futur) est masquée pour ne jamais doubler la loupe. */
.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__submit :is(svg, i),
.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__toggle :is(svg, i) {
  display: none;
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__submit::before,
.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__toggle::before {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
  content: "";
  background-color: currentColor;
  mask-image: url("../img/pictos/interface/loupe.svg");
  mask-position: center;
  mask-size: contain;
  mask-repeat: no-repeat;
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Focus : CE retire l'anneau du champ et le conteneur coupe ce qui déborde
   (overflow: hidden). L'anneau est donc tracé autour de la pilule, quand le
   widget pose elementor-search--focus sur le formulaire ; celui du bouton,
   à l'intérieur. */
.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search--focus .elementor-search__container {
  outline: 2px solid var(--mq-couleur-focus);
  outline-offset: 2px;
}

.elementor .mq-entete .mq-entete__recherche.elementor-widget-ajax-search:not(.elementor-search--skin-topbar) .elementor-search__submit:focus-visible {
  outline: 2px solid var(--mq-couleur-focus);
  outline-offset: -0.375rem;
}

/* Habillage Topbar (loupe mobile, sous 768px, décision Q4) : loupe de 24px
   dans une zone de 44px, couleur de la rangée (blanc sur la photo, marine
   ailleurs), sans transition. La barre s'ouvre en haut de l'écran : panneau
   blanc (jetons de page, §8), champ en pilule comme ceux de la boutique,
   étiquette en capitales de 12px, croix de 44px. L'ombre n'est posée que
   barre ouverte : fermée, la barre est translatée hors de l'écran et son
   ombre dépasserait en haut (défaut relevé sur la maquette). */
.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__toggle {
  --ce-search-toggle-icon-size: 1.5rem;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--mq-entete-encre);
  border-radius: var(--bs-border-radius-sm);
  transition: none;
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__toggle:hover {
  color: var(--mq-entete-encre-survol);
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__container {
  gap: var(--mq-espace-2);
  padding: var(--mq-espace-3) 4rem var(--mq-espace-3) var(--mq-espace-3);
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__container.elementor-search--topbar {
  box-shadow: 0 8px 28px rgb(23 59 79 / 0.15);
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__label {
  font-size: var(--mq-taille-label);
  color: var(--mq-marine);
  text-transform: uppercase;
  letter-spacing: var(--mq-approche-capitales);
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search input[type="search"].elementor-search__input {
  min-height: 3rem;
  padding-inline: 1.25rem 2.75rem;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--mq-entete-champ-texte);
  background-color: var(--mq-entete-champ-fond);
  border: var(--mq-trait) solid var(--mq-entete-champ-bord);
  border-radius: var(--mq-rayon-pilule);
  transition: none;
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__input::placeholder {
  color: var(--mq-entete-champ-indication);
  opacity: 1;
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__input:focus-visible {
  outline: 2px solid var(--mq-couleur-focus);
  outline-offset: 2px;
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__clear {
  justify-content: center;
  width: 2.75rem;
  color: var(--mq-entete-champ-icone);
  opacity: 1;
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .dialog-lightbox-close-button {
  top: var(--mq-espace-3);
  inset-inline-end: var(--mq-espace-3);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin: 0;
  font-size: 1.5rem;
  color: var(--mq-marine);
}

.elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .dialog-lightbox-close-button:focus-visible {
  outline: 2px solid var(--mq-couleur-focus);
  outline-offset: -2px;
}

/* Mouvement réduit : la barre Topbar s'ouvre sans glisser (CE : transform
   .3s) et sa croix apparaît sans fondu. */
@media (prefers-reduced-motion: reduce) {
  .elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .elementor-search__container,
  .elementor .mq-entete .mq-entete__recherche.elementor-search--skin-topbar .elementor-search .dialog-lightbox-close-button {
    transition: none;
  }
}

/* Pages de contenu (lot G, cadrage analyses/lot-g-pages/cadrage.md de
   l'espace de travail, 4.0 ; décisions d'Aurélien du 03/10/2026).
   Surtitre à puce : classe modificatrice `mq-surtitre--puce`, posée avec
   `mq-surtitre` sur le widget Titre des NOUVEAUX modèles seulement (404,
   contact, pages composées) ; l'accueil et les modèles n° 3 et n° 5 ne la
   portent pas et ne changent pas. Disque de 11px, comme le gabarit d'erreur
   du design system (son readme dit environ 18px), à 10px du texte, centré
   sur les capitales de 11px. Marine sur fond clair, jaune sur fond marine :
   sur blanc, une puce jaune serait presque invisible (écart assumé au design
   system, décision 1 du 03/10/2026). Décorative : rien n'est lu. Aucune règle
   de CE ne vise ce pseudo-élément ; 0,3,1 et 0,4,1. */
.elementor .mq-surtitre--puce .elementor-heading-title::before {
  content: "";
  display: inline-block;
  width: 0.6875rem;
  height: 0.6875rem;
  margin-inline-end: 0.625rem;
  vertical-align: -0.15em;
  border-radius: 50%;
  background-color: var(--mq-marine);
}

.elementor .mq-fond-marine .mq-surtitre--puce .elementor-heading-title::before {
  background-color: var(--mq-jaune);
}

/* Fonds marine des nouveaux modèles (`mq-fond-marine`, sur la section ou la
   colonne : panneau du contact, photo et panneau, citation marine) : anneau
   de focus jaune (10,71:1), comme le pied. */
.mq-fond-marine {
  --mq-couleur-focus: var(--mq-jaune);
}

/* Page 404 (lot G, 4.1, O1 A ; modèle CE « Page 404 Mosqity », section
   `mq-erreur`). Le h1 garde l'échelle du thème (§4, 36 à 51px), pas les
   98px du design system (écart validé le 03/10/2026) ; CE lui impose
   line-height: 1, ramené à l'interligne des titres. Titre et message
   centrés, à largeur de lecture. */
.elementor .mq-erreur .elementor-heading-title {
  line-height: var(--mq-interligne-titre);
  text-wrap: balance;
}

.elementor .mq-erreur h1.elementor-heading-title {
  max-width: 14ch;
  margin-inline: auto;
}

/* Le widget Éditeur de texte de CE 2.14 n'a pas de div.elementor-text-editor
   (relevé R3 du 05/10/2026). Largeur posée sur son conteneur intérieur : sur
   le widget, elle le ferait remonter à côté des boutons (colonne flex en
   ligne, retour à la ligne). Le paragraphe hérite la police du widget
   (`font: inherit` de CE). */
.elementor .mq-erreur .elementor-widget-text-editor > .elementor-widget-container {
  max-width: 44ch;
  margin-inline: auto;
}

@media (min-width: 768px) {
  .elementor .mq-erreur .elementor-widget-text-editor {
    font-size: var(--mq-taille-h6);
  }
}

/* Panneau « Nous écrire » du contact (lot G, 4.4, O4 B ; Contenu n'importe
   où « Contact » sur displayContactContent, section `mq-contact-panneau
   mq-fond-marine`) : l'adresse e-mail en jaune soulignée sur le marine
   (10,71:1). CE écrit `.elementor a { text-decoration: none }` (0,1,1). */
.elementor .mq-contact-panneau a {
  color: var(--mq-jaune);
  text-decoration: underline;
  text-decoration-thickness: var(--mq-trait);
  text-underline-offset: 0.2em;
}

/* FAQ (lot G, 4.8 ; page CMS 14 éditée avec CE, section `mq-faq`, modèle
   enregistré « FAQ » inséré par copie). Un h2 par thème, puis un Accordéon
   de CE : questions en h3 (réglage du widget), « FAQ Schema » activé,
   icône à droite. Tailles des h2 et h3 d'un contenu CE dans une page CMS :
   §14.4 ; interligne : règle des pages composées, plus bas.
   Dès 992px, 8 colonnes sur 12 alignées sous le h1 natif (4.16) : environ
   820px dans le conteneur de 1240px. 0,4,0 : la largeur boxed de CE et du
   Style du thème est en 0,3,0. */
@media (min-width: 992px) {
  .elementor .mq-faq.elementor-section-boxed > .elementor-container {
    max-width: calc((100% + var(--bs-gutter-x, 1.5rem)) * 8 / 12 - var(--bs-gutter-x, 1.5rem));
    margin-inline-start: 0;
  }
}

/* Titre d'un thème, après l'introduction ou le thème précédent : 48px
   au-dessus (24px d'espacement des widgets du Style du thème, plus 24px),
   24px en dessous, plus près de ses questions. */
.elementor .mq-faq .elementor-widget + .elementor-widget-heading {
  margin-top: var(--mq-espace-5);
}

/* Accordéon (classes relevées le 05/10/2026, R8). CE pose un cadre gris
   autour de chaque question, 15 x 20px de marge intérieure (12 x 15px en
   mobile), line-height: 1 et outline: none sur le titre (0,2,0 et 0,3,0,
   1-widget-accordion.css). Ici : filets fins entre les questions, sans bords
   latéraux (FaqItem du design system), question de 18px sur 48px de haut au
   moins, icône alignée à droite même sur deux lignes, réponse à largeur de
   lecture. Le lien de la question reçoit le focus : anneau du §4, rétabli
   aussi sur le titre. */
.elementor .mq-faq .elementor-accordion .elementor-accordion-item {
  border-width: 0 0 1px;
  border-color: var(--mq-bordure);
}

.elementor .mq-faq .elementor-accordion .elementor-accordion-item:first-child {
  border-top-width: 1px;
}

.elementor .mq-faq .elementor-accordion .elementor-tab-title {
  display: flex;
  align-items: center;
  gap: var(--mq-espace-4);
  min-height: 3rem;
  padding: var(--mq-espace-3) 0;
  color: var(--mq-couleur-titre);
  font-size: var(--mq-taille-h6);
  line-height: 1.2;
}

.elementor .mq-faq .elementor-accordion .elementor-accordion-title {
  flex: 1;
}

.elementor .mq-faq .elementor-accordion .elementor-tab-title .elementor-accordion-icon-right {
  order: 1;
}

.elementor .mq-faq .elementor-accordion .elementor-tab-title:focus-visible {
  outline: 2px solid var(--mq-couleur-focus);
  outline-offset: 2px;
}

.elementor .mq-faq .elementor-accordion .elementor-tab-content {
  max-width: 37rem;
  padding: 0 0 var(--mq-espace-5);
  border-top: 0;
  color: var(--mq-couleur-texte);
  font-size: 1rem;
  line-height: 1.5;
}

/* « Une autre question ? Écrivez-nous » : lien souligné, `.elementor a`
   retire le soulignement. */
.elementor .mq-faq .elementor-widget-text-editor a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Lien d'évitement de l'accueil (A11Y-3, décision d'Aurélien du 06/10/2026) :
   widget natif « Liens d'évitement » de CE, en tête de la rangée 1 de
   l'en-tête (classe `mq-entete__evitement`, position absolue, hors du flux),
   un seul lien « Aller au contenu principal » vers #content. Seule la mise en
   page « En-tête et pied » de CE (accueil, body.layout-header-footer) n'a pas
   le lien de Hummingbird (relevé R1 du 06/10, cadrage du lot G) : ailleurs,
   le widget est retiré pour ne pas doubler ce lien. Retiré aussi de la copie
   collante de la rangée 1 (pas de second lien). CE le masque lui-même tant
   qu'il n'a pas le focus (opacité 0, hors écran). */
body:not(.layout-header-footer) .elementor .mq-entete__evitement,
.elementor .elementor-sticky__spacer .mq-entete__evitement {
  display: none;
}

/* Tunnel allégé (E6 ; O5 B du cadrage de l'étape 7, 02/10/2026 ; « Mon
   diagnostic » absent du tunnel, écart confirmé le 06/10/2026 ; conception
   tranche4-conception.md T4.1, validée le 12/10/2026). Les quatre étapes
   seulement (#checkout, identifiant de body) : panier et confirmation
   restent complets. En-tête : logo (vers l'accueil) et Panier. La rangée 2
   (menu, entrée « Mon diagnostic », tiroir) et sa copie « spacer », qui
   porte les mêmes classes, sont retirées : #header passe à 80px au bureau et
   Hummingbird écrit 96px dans --scroll-padding-top (80px dessous). Retirés
   aussi, y compris de l'arbre d'accessibilité : bouton du tiroir,
   recherches, compte. Hors couche, car CE l'est ; (1,1,0) dépasse ses
   règles (0,4,0 au plus), sans sélecteur d'élément (GUIDE §5.2, point 3).
   Panier à droite, filet, ombre et toasts du tunnel : §8. */
#checkout .mq-entete--rangee2,
#checkout .mq-entete__menu-mobile,
#checkout .mq-entete__recherche,
#checkout .mq-entete__compte {
  display: none;
}

/* Pied du tunnel : « Besoin d'aide ? » et ligne légale seulement. Sections
   marine repérées par leur contenu, (1,3,0). Règle à part : un :has()
   inconnu ferait abandonner toute une liste. Sans :has(), pied complet. */
#checkout .mq-pied:not(.mq-pied--aide):not(:has(.mq-pied__legal, .mq-pied__copyright)) {
  display: none;
}

/* Pages composées avec CE (lot G, 4.7 ; modèles de section de la tranche 3 :
   En-tête de section, Panneau texte, Étapes, Cartes, Photo et panneau,
   Équipe, Citation ; modèle de page « Page de contenu », essayé sur la
   CMS 12). Tailles des h2 et h3 : §14.4.
   Interligne des titres d'un contenu CE dans une page CMS : CE impose
   line-height: 1 (0,2,0) ; un interligne réglé dans le widget (0,4,0) garde
   la main. FAQ comprise. */
.page-content--cms .elementor .elementor-heading-title {
  line-height: var(--mq-interligne-sous-titre);
}

/* Pastille numérotée des Étapes (titre `div`, classe `mq-etape__numero` sur
   le widget) : disque de 48px, chiffre Bold de 20px. Jaune, puis turquoise
   (7,0:1 avec le marine), puis marine à chiffre blanc (11,8:1). */
.elementor .mq-etape__numero .elementor-heading-title {
  display: inline-grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background-color: var(--mq-jaune);
  color: var(--mq-marine);
  font-size: 1.25rem;
  font-weight: var(--mq-graisse-titre);
  line-height: 1;
}

.elementor .mq-etape__numero--turquoise .elementor-heading-title {
  background-color: var(--mq-turquoise);
}

.elementor .mq-etape__numero--marine .elementor-heading-title {
  background-color: var(--mq-marine);
  color: var(--mq-blanc);
}

/* Citation (section `mq-citation`, panneau clair) : 27px Bold, interligne
   1.25 (QuoteBlock du design system). L'attribution garde les réglages de son
   widget (11px en capitales, 0,4,0). */
.elementor .mq-citation .elementor-heading-title {
  font-size: var(--mq-taille-h3);
  font-weight: var(--mq-graisse-titre);
  line-height: 1.25;
}


/* ------------------------------------------------------------
   12.12 OPTIONS RETENUES PAR AURÉLIEN (01/10/2026)
   Rédigées avec le §12 (options fiche-panier-21, 08 et 20 des notes de
   l'étape 6). Toutes en couche : la section hors couche reste le §12.11.
   ------------------------------------------------------------ */

/* Bouton principal désactivé lisible : marine sur marine très clair (9.64:1)
   au lieu de l'opacité 0.4 (texte marine sur jaune pâle, 2.1:1). Vaut pour
   tout bouton principal désactivé, dont « Commander » au panier. En rupture,
   la quantité disparaît (l'achat est impossible). */
@layer bs-components {
  .btn-primary {
    --bs-btn-disabled-bg: var(--mq-marine-100);
    --bs-btn-disabled-color: var(--mq-marine);
    --bs-btn-disabled-border-color: var(--mq-marine-100);
    --bs-btn-disabled-opacity: 1;
  }
}

@layer ps-pages {
  .page-product .product__actions-qty-add:has(.product__add-to-cart-button:disabled) .product__quantity {
    display: none;
  }

  /* Tablette portrait (768 à 991px) : zone d'achat à droite de la galerie,
     le bouton d'ajout remonte d'environ 600px. */
  @media (min-width: 768px) and (max-width: 991.98px) {
    .page-product .product__container {
      display: grid;
      grid-template-columns: minmax(0, 4fr) minmax(0, 5fr);
      column-gap: var(--mq-espace-5);
    }

    .page-product .product__container .product__images {
      margin-block-end: 0;
    }

    .page-product .product__container .product__thumbnails-list {
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: 1rem;
    }
  }

  /* Titre de la fiche plafonné à 40px et blocs resserrés dès 1200px : le
     bouton d'ajout reste visible sur un portable de 1366 x 768. */
  .page-product:not(.page-product--quickview) .product__name {
    font-size: clamp(2.25rem, 2.8vw, 2.5rem);
  }

  @media (min-width: 1200px) {
    .page-product:not(.page-product--quickview) .product__name,
    .page-product:not(.page-product--quickview) .product__manufacturer,
    .page-product:not(.page-product--quickview) .product__prices,
    .page-product:not(.page-product--quickview) .product__description-short,
    .page-product:not(.page-product--quickview) .product__variants {
      margin-block-end: 1.5rem;
    }
  }
}

/* Aperçu rapide : retiré des vignettes par le gabarit enfant
   miniatures/product-quickview.tpl (vide). La règle du bouton tactile au
   §12.2 est sans objet tant que ce gabarit est en place. */


/* ============================================================
   13. PANIER ET TUNNEL (lot E, décisions d'Aurélien du 01/10/2026 et
   du 02/10/2026)
   Gabarits natifs de Hummingbird (checkout/cart.tpl, checkout.tpl et
   leurs partiels, fenêtre d'ajout de ps_shoppingcart, confirmation et
   suivi de commande invité), habillés ici.
   Conception : cadrage de l'étape 7 (analyses/etape7-panier-tunnel/
   cadrage.md de l'espace de travail), dont les numéros (4.1, 4.12…) sont
   cités dans les commentaires. Tranche 1 réalisée le 02/10/2026, avec
   les options O2 B, O3 B et O6 B. Tranche 3 écrite le 02/10/2026
   (tranche3-conception.md du même dossier, dont les éléments T3.1 à
   T3.25 sont cités dans les commentaires, avec les décisions 1 à 8
   d'Aurélien du 02/10/2026), à contrôler en ligne.

   Ailleurs dans ce fichier, pour tout le site : couleurs d'état et de
   validation au §3 (O3 B), boutons contour posés sur un .btn-primary
   (œil du mot de passe, « Appliquer » du code promo) et boutons texte
   soulignés au §5, aides, cases, liens des libellés, état valide
   neutralisé et état d'erreur des champs au §6, toasts au §7.
   Va avec le gabarit enfant _partials/form-fields.tpl (O6 B :
   autocomplétion, aide reliée au champ ; O6 B+, tranche 3 : erreur du
   serveur reliée au champ, classe is-invalid habillée au §6).

   Tranche 4 écrite le 12/10/2026 (tranche4-conception.md, éléments T4.1
   à T4.7, validée le même jour) : récapitulatif collant (4.8, E5) et
   réassurance (4.10, E2a) au §13.1 ; en-tête et pied allégés du tunnel
   (O5 B, E6) au §12.11 et au §8 ; bouton d'étape en contour de l'étape 2
   (E13) poussé en séance seulement si le relevé montre deux jaunes.

   Pas encore réalisé : surcharge du bloc cart_voucher_form (étiquette du
   code promo), seulement si les codes promo ouvrent (décision 1).

     13.1 Panier
     13.2 Fenêtre d'ajout
     13.3 Tunnel
     13.4 Fenêtre des CGV et confirmation
     13.5 Suivi de commande invité
   ============================================================ */


/* ------------------------------------------------------------
   13.1 PANIER
   ------------------------------------------------------------ */

@layer ps-pages {
  /* « Récapitulatif de commande » en h4, sous le H1 « Panier » (B1, C2). */
  .cart-grid__aside h2 {
    font-size: var(--mq-taille-h4);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* Panier vide : ni récapitulatif à 0,00 €, ni colonne vide ; le message
     et « Continuer mes achats » prennent la largeur (fiche-panier-16).
     Suit aussi un panier vidé en AJAX (`.cart__empty` apparaît). */
  .cart-grid:has(.cart__empty) .cart-grid__aside {
    display: none;
  }

  .cart-grid:has(.cart__empty) .cart-grid__content {
    width: 100%;
  }

  /* Bloc diagnostic du panier vide (Contenu n'importe où « Panier vide »,
     section `mq-panier-vide`, greffon displayCrossSellingShoppingCart) :
     masqué dès que le panier contient un article. */
  .cart-grid:not(:has(.cart__empty)) + .cart-grid__footer .mq-panier-vide {
    display: none;
  }

  /* « Produits phares » masqués sur le panier rempli (O2 B, 4.11), même
     motif que la règle précédente : le bloc reproposait l'article déjà au
     panier et doublait ses identifiants. Ils restent sur le panier vide. */
  .cart-grid:not(:has(.cart__empty)) + .cart-grid__footer .ps-featuredproducts {
    display: none;
  }

  /* Tablette, de 768 à 991px (4.25) : la colonne du récapitulatif passe
     sous les lignes ; 30rem au plus, alignée à droite, pour que libellés et
     montants restent proches. Vaut aussi pour la colonne du tunnel. */
  @media (min-width: 768px) and (max-width: 991.98px) {
    .cart-grid__aside,
    .checkout-grid__aside {
      max-width: 30rem;
      margin-inline-start: auto;
    }
  }

  /* Récapitulatif collant du panier et du tunnel (4.8, 4.20, E5 ;
     tranche4-conception.md T4.2) : collant natif de Hummingbird gardé, sans
     règle sur top. --scroll-padding-top, posé en ligne par scrollPadding.ts
     (en-tête + 16px), vaut 144px au bureau, 81px de 992 à 1199px, 96px dans
     le tunnel allégé (O5 B). Écran bas : colonne dans le flux, sinon son bas
     resterait sous la fenêtre jusqu'à la fin de la rangée. Seuil : 144 +
     colonne du panier (470px mesurés en ligne le 12/10/2026 après E2a, avec
     les descriptions de la réassurance) + 16, plus une réserve de 96px (code
     promo, détails ouverts), arrondi au multiple de 16 supérieur : 736px
     (800px au cadrage, avec l'ancien en-tête et la colonne d'avant E2a ;
     règle de la question 5 du 12/10/2026). */
  @media (min-width: 992px) and (max-height: 735.98px) {
    .cart-grid__aside-wrapper,
    .checkout-grid__aside-wrapper {
      position: static;
    }
  }
}

@layer ps-components {
  /* Ligne produit (4.4) : total de ligne en Bold marine, comme les prix de
     la fiche et des vignettes ; le prix unitaire passe en Medium et
     s'efface devant lui. */
  .product-line__price {
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .product-line__item-price {
    font-weight: var(--mq-graisse-texte);
  }

  /* Pastille « -20% » à 11px comme les autres pastilles : les 14px de
     Hummingbird battaient le .badge du §7, en couche inférieure. */
  .product-line__item-discount {
    font-size: var(--mq-taille-surtitre);
  }

  /* Déclinaisons (« Taille: S ») en 14px atténué (5,1:1). Le deux-points
     collé est écrit en dur dans le gabarit : limite connue. */
  .product-line__item--info {
    font-size: 0.875rem;
    color: var(--mq-texte-attenue);
  }

  /* Sous 576px, quantité et total sur une rangée tant qu'elle tient
     (390px) ; à 360 et 320px, le total passe sous la quantité, aligné à
     droite. */
  @media (max-width: 575.98px) {
    .product-line__content-right {
      flex-direction: row;
      flex-wrap: wrap;
      gap: 0.5rem 1rem;
      justify-content: space-between;
      align-items: center;
    }

    .product-line__price {
      margin-inline-start: auto;
    }
  }

  /* « Retirer » (4.6), et tout lien qu'un module ajouterait par
     displayCartExtraProductActions : souligné, zone de 44px de haut, trait
     épaissi au survol. Le conteneur est visé, pas la classe js-*. */
  .product-line__actions a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  .product-line__actions a:hover {
    text-decoration-thickness: var(--mq-trait);
  }

  /* « Continuer mes achats » à la largeur de son texte à toutes les
     largeurs (4.8) : pleine largeur sous 768px, il passait avant le
     récapitulatif comme une action principale. */
  .cart__continue-shopping {
    width: auto;
  }

  /* Total TTC à 18px Bold marine (4.8), au panier comme dans le
     récapitulatif du tunnel (4.20). */
  .cart-summary__line--bold {
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  /* Code promo (T3.1, 4.7), au panier comme au récapitulatif du tunnel.
     Décision 1 du 02/10/2026 : CSS et traductions préparées, sans effet
     tant qu'aucune règle de panier n'est active ; la surcharge du bloc
     cart_voucher_form attend l'ouverture des codes. Le bouton passe en
     contour au §5. Titre de l'accordéon en Medium (action secondaire,
     « Total TTC » reste en Bold), sur 44px ; la couche l'emporte sur celle
     de .accordion--small (bs-custom-components). Taille et marine gardés. */
  .cart-voucher__accordion-button {
    font-weight: var(--mq-graisse-texte);
    min-height: 2.75rem;
  }

  /* Champ et bouton sur une rangée tant que le champ garde 10rem ; en
     dessous (vers 320px), le bouton passe sous le champ. */
  .cart-voucher__form {
    flex-wrap: wrap;
  }

  .cart-voucher__form .form-control {
    flex: 1 1 10rem;
    width: auto;
    min-width: 0;
  }

  /* Code faux : alerte à 14px, comme l'erreur sous un champ (T3.8, §6),
     avec un remplissage plus court (elle n'a pas de croix) et sans marge
     basse. Couleurs natives gardées (11,16:1) : le rouge Mosqity en texte
     n'y ferait que 4,69:1. */
  .cart-voucher__error {
    --bs-alert-padding-y: 0.5rem;
    --bs-alert-padding-x: 0.75rem;
    --bs-alert-margin-bottom: 0;
    font-size: 0.875rem;
  }

  .cart-voucher__error-icon {
    font-size: 1.25rem;
  }

  /* Bon ajouté (T3.7 a) : corbeille de 44px (24px auparavant), icône
     centrée. Les marges négatives gardent la hauteur de la ligne : la
     cible déborde de 10px en haut et en bas. */
  .cart-voucher__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.75rem;
    min-height: 2.75rem;
    margin-block: -0.625rem;
  }

  /* Produit indisponible (T3.7 b) : message de disponibilité d'une ligne à
     14px, comme les déclinaisons (4.4), icône à 16px. Couleurs : §12.5. */
  .product-line__item-availability-message {
    font-size: 0.875rem;
  }

  .product-line__item-availability-icon {
    font-size: 1rem;
  }
}

@layer ps-modules {
  /* Réassurance du panier et du tunnel (4.10, O1 A, E2a ;
     tranche4-conception.md T4.3) : module natif blockreassurance sur
     displayReassurance (displayBlockProduct.tpl de Hummingbird). La fiche
     produit en est exclue (exception « product ») : aucune règle ne la vise.
     Picto de 40px à toutes les largeurs (48 puis 64px chez Hummingbird) ; SVG
     posé en ligne par le JS du module (viewBox 0 0 70 70, relevé du
     12/10/2026), couleur réglée dans le module (#173b4f). Gardés natifs :
     écarts de 16px, marges de 32px, picto centré sur le texte. Rangées de
     42px avec la description, bloc de 158px au lieu de 224 (mesuré en ligne
     le 12/10/2026). */
  .blockreassurance:is(.blockreassurance--cart, .blockreassurance--checkout) .reassurance__image {
    width: 2.5rem;
    height: 2.5rem;
  }

  /* object-fit ne vaut que pour une icône en image ; un SVG en ligne se
     met à l'échelle par son viewBox. */
  .blockreassurance:is(.blockreassurance--cart, .blockreassurance--checkout) .reassurance__image > :is(svg, img) {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  /* Interligne sur le bloc de texte (élément flex) : posé sur le titre,
     en ligne, il ne descendrait pas sous les 24px hérités du corps. */
  .blockreassurance:is(.blockreassurance--cart, .blockreassurance--checkout) .reassurance__content {
    line-height: var(--mq-interligne-sous-titre);
  }

  /* Titre : règle des titres (Bold, marine, GUIDE §5.3), 11,83:1. */
  .blockreassurance:is(.blockreassurance--cart, .blockreassurance--checkout) .reassurance__title {
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  /* Description : 14px (<small>), #587280 (--bs-secondary-color, 5,1:1),
     sous le titre. Les trois blocs en ont une (lorem ipsum saisi le
     02/10/2026). */
  .blockreassurance:is(.blockreassurance--cart, .blockreassurance--checkout) .reassurance__desc {
    display: block;
    margin-block-start: 0.25rem;
    line-height: 1.4;
  }
}


/* ------------------------------------------------------------
   13.2 FENÊTRE D'AJOUT (« Ajouté à votre panier », ps_shoppingcart)
   ------------------------------------------------------------ */

@layer ps-modules {
  /* Titre en marine à toutes les largeurs (4.3). Hummingbird le met en vert
     sous 576px et en noir au-delà, dans un @media : cette règle, venue après
     à spécificité égale, gagne partout. */
  .blockcart-modal__title {
    color: var(--mq-couleur-titre);
  }

  /* Coche en marine (11,8:1). Les jetons d'état du §3 (O3 B) donnent déjà
     ce résultat ; la règle le garde s'ils changent. */
  .blockcart-modal__title-icon {
    color: var(--mq-marine);
  }

  /* Produit harmonisé avec la ligne du panier (T3.3, décision 5 du
     02/10/2026) : nom en Bold marine, déclinaisons et quantité en 14px
     atténué (5,08:1). Règles venues après celles de Hummingbird, même
     spécificité ; aucune copie de modal.tpl (O4 A). */
  .blockcart-modal__name {
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .blockcart-modal__property,
  .blockcart-modal__quantity {
    font-size: 0.875rem;
    color: var(--mq-texte-attenue);
  }
}


/* ------------------------------------------------------------
   13.3 TUNNEL (checkout.tpl : bande des étapes, étapes 1 à 4,
   récapitulatif final de l'étape 4, récapitulatif)
   Les règles des étapes écrivent leurs couleurs : elles ne dépendent pas
   des jetons d'état du §3. Seules les étapes à venir sont désactivées ;
   l'étape en cours porte .active. Total, total de ligne et prix unitaire
   du récapitulatif final : règles partagées avec la confirmation, au
   §13.4.
   ------------------------------------------------------------ */

@layer ps-components {
  /* Bande mobile (4.1) : titre de l'étape au jeton h5 (21px), en marine.
     Hummingbird : 20px puis 24px dès 576px, en noir. */
  .checkout-steps__title {
    font-size: var(--mq-taille-h5);
    color: var(--mq-couleur-titre);
  }

  /* Sous-titre « Étape suivante : … » à 16px, atténué, comme la maquette
     mobile validée le 02/10/2026 (4.1). Hummingbird : 14px sous 576px,
     16px au-delà ; cette règle, venue après à spécificité égale, gagne
     partout. La couleur atténuée reste celle de Hummingbird. */
  .checkout-steps__subtitle {
    font-size: 1rem;
  }

  /* Bande du bureau (4.13) : 60rem au lieu de 45rem, soit 240px par étape ;
     « Informations personnelles » tient sur une ligne au bureau. */
  .checkout-steps__desktop {
    max-width: 60rem;
  }

  /* Pastilles (4.12). Étapes à venir : pastille blanche bordée, chiffre en
     texte atténué (5,1:1 sur la pastille blanche). Remplace l'ancienne
     règle du §4 (fond #587280). */
  .checkout-steps__number {
    background: var(--mq-blanc);
    border: var(--mq-trait) solid var(--mq-texte-attenue);
    color: var(--mq-texte-attenue);
  }

  /* Étape en cours : pastille turquoise, chiffre marine (7,0:1). La pastille
     ne fait que 1,55:1 sur la bande : écart accepté le 02/10/2026, l'état
     est aussi porté par le libellé en gras, le h1 et aria-selected. */
  .checkout-steps__step--current .checkout-steps__number {
    background: var(--mq-turquoise);
    border-color: var(--mq-turquoise);
    color: var(--mq-marine);
  }

  /* Étapes faites : pastille marine, coche blanche. Le chiffre est masqué
     (taille 0) ; la coche est le point de code E5CA de Material Icons
     (police déjà préchargée), le même que &#xE5CA; dans modal.tpl : pas de
     ligature, donc pas de mot « check » si la police manque. La seconde
     déclaration ajoute un texte de remplacement vide (rien n'est lu) ; la
     première est le repli des navigateurs qui rejettent cette syntaxe
     (Safari 16 à 17.3, Firefox 121 à 127, promis au GUIDE §5.6). */
  .checkout-steps__step--success .checkout-steps__number {
    background: var(--mq-marine);
    border-color: var(--mq-marine);
    color: var(--mq-blanc);
    font-size: 0;
  }

  .checkout-steps__step--success .checkout-steps__number::after {
    content: "\e5ca";
    content: "\e5ca" / "";
    font-family: "Material Icons", sans-serif;
    font-size: 1rem;
    font-style: normal;
    font-weight: 400;
    font-feature-settings: "liga";
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
    direction: ltr;
    -webkit-font-smoothing: antialiased;
  }

  /* Connecteurs : filet clair vers les étapes à venir, marine sur le
     chemin fait (décoratifs). */
  .checkout-steps__step::before,
  .checkout-steps__step::after {
    background: var(--mq-bordure);
  }

  .checkout-steps__step--success::before,
  .checkout-steps__step--success::after,
  .checkout-steps__step--current::before {
    background: var(--mq-marine);
  }

  /* Libellés des étapes faites en marine (Hummingbird : vert, qui battait
     la règle du §4), soulignés au survol : ils ramènent à l'étape (4.13). */
  .checkout-steps__step--success .checkout-steps__btn {
    color: var(--mq-couleur-lien);
  }

  .checkout-steps__step--success .checkout-steps__btn:hover {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  /* Étapes à venir (boutons désactivés) : sans l'opacité de 0.4 du §5, et
     libellé en texte atténué écrit sur le bouton : la variable de couleur
     désactivée de .btn serait sans effet, la couleur de
     .checkout-steps__btn (§4, couche supérieure) la bat. */
  .checkout-steps__btn {
    --bs-btn-disabled-opacity: 1;
  }

  .checkout-steps__btn:disabled {
    color: var(--mq-texte-attenue);
  }

  /* Cercle de la bande mobile : piste gris-bleu (#a2b1b9, décorative),
     « 2 / 4 » en marine. L'arc suit l'utilitaire text-success, marine par
     les jetons d'état du §3 (O3 B). */
  .progress-ring__background-circle {
    stroke: var(--bs-primary-border-subtle);
  }

  .progress-ring__text {
    fill: var(--mq-marine);
  }

  /* Étape 1, client connecté (T3.10, 4.24) : nom du client et « Se
     déconnecter » soulignés, trait épaissi au survol. La couleur seule ne
     les distinguait pas du texte noir (1,77:1 et 3,21:1, WCAG 1.4.1). Le
     rouge de déconnexion vient d'un utilitaire : gardé. Sélecteur tiré du
     gabarit (personal-information.tpl), à confirmer au relevé d'Aurélien. */
  .step__account a {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  .step__account a:hover {
    text-decoration-thickness: var(--mq-trait);
  }

  /* Étape 2, adresse enregistrée (4.16) : nom de l'adresse en 18px Bold
     marine ; carte choisie bordée de 2px (1px de bord marine de Hummingbird
     et 1px d'ombre intérieure, sans décalage). Le nom et les actions
     valent aussi pour « Mes adresses » (block-address.tpl), le détail de
     commande du compte (h3 depuis Hummingbird 2.1.2, ramené à 18px) et le
     récapitulatif final de l'étape 4. */
  .address-card__alias {
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .address-card--radio.selected {
    box-shadow: inset 0 0 0 1px var(--mq-marine);
  }

  /* « Modifier » et « Supprimer » soulignés, zone de 44px de haut. Leurs
     couleurs (noir, rouge, survol rose) viennent d'utilitaires à
     l'importance forcée : écarts connus, acceptés (GUIDE §5.2). */
  .address-card__actions a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  /* Étape 3 (4.17) : transporteurs en cartes blanches bordées, espacées de
     8px ; la carte choisie et les rayons de la première et de la dernière
     sont réglés en ps-pages, plus bas. Nom du transporteur et prix en Bold. */
  .delivery-option__item {
    background-color: var(--mq-blanc);
    border: 1px solid var(--mq-bordure);
    border-radius: var(--mq-rayon-carte);
    margin-block-end: 0.5rem;
  }

  .delivery-option__carrier-name {
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .delivery-option__price {
    font-weight: var(--mq-graisse-titre);
  }

  /* Étape 4 (T3.13, 4.18, décision 5 du 02/10/2026) : moyens de paiement
     en cartes, calquées sur les transporteurs (4.17) : carte blanche
     bordée, rayon de 19px. Le remplissage est porté par le libellé et non
     par la carte : toute la rangée de 48px choisit le moyen, sans
     recouvrir le texte du module ni les champs qu'un futur prestataire
     poserait dans la carte. Aucune classe js-* visée. */
  .payment-option {
    background-color: var(--mq-blanc);
    border: 1px solid var(--mq-bordure);
    border-radius: var(--mq-rayon-carte);
    padding-inline: 1rem;
  }

  /* Carte choisie : fond blanc cassé, bord marine de 2px (1px de bord et
     1px d'ombre intérieure, comme 4.16 et 4.17). Dans un navigateur sans
     :has() (GUIDE §5.6), la carte reste blanche : le radio désigne seul le
     moyen choisi. */
  .payment-option:has(.payment-option__input:checked) {
    background-color: var(--mq-blanc-casse);
    border-color: var(--mq-marine);
    box-shadow: inset 0 0 0 1px var(--mq-marine);
  }

  .payment-option__form-check {
    margin-block-end: 0;
  }

  /* Libellé en Bold marine (11,83:1 sur blanc, 10,85:1 sur blanc cassé),
     sur une rangée de 48px ; radio de 20px centré sur sa première ligne,
     décalée de 12px. Le retrait de 2rem du §6 est gardé. */
  .payment-option__label {
    display: block;
    padding-block: 0.75rem;
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .payment-option__input {
    margin-top: 0.875rem;
  }

  /* Texte du module : le libellé porte déjà 12px dessus. */
  .payment-option__additional-information {
    padding-block: 0 1rem;
  }

  /* Paragraphe vide produit par payment_infos.tpl du chèque (un p ouvert
     autour du dl) : 16px de trop. Seul un p vide est masqué. */
  .payment-option__additional-information p:empty {
    display: none;
  }

  /* Coordonnées du chèque sur blanc, bordées, dans la carte (grille et
     rayon de Hummingbird gardés). */
  .payment-option dl {
    background-color: var(--mq-blanc);
    border: 1px solid var(--mq-bordure);
  }

  /* Récapitulatif final (T3.14, 4.18 ; réglage n° 10 gardé, décision 2 ;
     habillage, décision 5). Hiérarchie : h1 « Paiement » à 27px, titre
     du récapitulatif au jeton h4 (23px, au lieu de 36 à 51px), en-têtes
     de bloc en étiquette, noms des cartes à 18px. Écart au 4.18, qui
     proposait le jeton h5 : 23px est le palier juste sous le h1, la
     taille de l'accordéon mobile « Récapitulatif de commande » et celle
     des cartes de la confirmation (T3.20). */
  .final-summary > .h2 {
    font-size: var(--mq-taille-h4);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* En-têtes « Adresses », « Mode de livraison », « Articles commandés »
     en 12px capitales Bold marine (11,83:1), comme les étiquettes de champ
     et la bande des étapes. Flex et marge haute de Hummingbird gardés. */
  .final-summary__header {
    font-size: var(--mq-taille-label);
    font-weight: var(--mq-graisse-titre);
    letter-spacing: var(--mq-approche-capitales);
    text-transform: uppercase;
    color: var(--mq-couleur-titre);
  }

  /* Pilules « Modifier » à 44,5px de haut (38,5px avec .btn-sm) : la
     règle B9 de .btn (§5) lit la variable. */
  .final-summary__header .btn {
    --bs-btn-padding-y: 0.8125rem;
  }

  /* Liens « Modifier » et « Supprimer » des cartes d'adresse retirés
     (option A, décision 6) : une action par bloc, aucune suppression au
     dernier écran. La pilule « Adresses » ramène à l'étape 2, où modifier
     et supprimer restent possibles. */
  .final-summary .address-card__actions {
    display: none;
  }

  .final-summary .address-card__content {
    margin-block-end: 0;
  }

  /* Récapitulatif (4.20) : nombre d'articles en 18px Bold marine. Sous
     992px, titre de l'accordéon « Récapitulatif de commande » au jeton h4
     (23px), comme celui du panier (C2) ; Hummingbird : 20px. */
  .cart-summary__products-number {
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .checkout__summary-accordion-header .accordion-button {
    font-size: var(--mq-taille-h4);
    font-weight: var(--mq-graisse-titre);
    line-height: var(--mq-interligne-sous-titre);
    color: var(--mq-couleur-titre);
  }
}

@layer ps-pages {
  /* Titre de l'étape en cours (h1) au jeton h3, 27px (4.1) : la bande
     nomme déjà l'étape et la colonne ne fait que 819px. Écart assumé à B1,
     propre au tunnel (décision du 02/10/2026). */
  .checkout-grid .page-title-section {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* Sous 768px, la bande mobile répète ce titre juste au-dessus : il est
     masqué à l'écran mais reste dans l'arbre d'accessibilité (motif de
     .visually-hidden, sans l'importance forcée de l'utilitaire). */
  @media (max-width: 767.98px) {
    .checkout-grid .step--current .step__title {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
      border: 0;
    }
  }

  /* Étape 1 (4.14) : onglets « Commander en tant qu'invité » et
     « Connexion » en 12px capitales marine, zone de 44px, trait de 3px sous
     l'onglet actif, filet clair sous la rangée. Limité à l'étape : le
     composant peut servir ailleurs. */
  #checkout-personal-information-step .nav-underline {
    --bs-nav-underline-gap: 1.5rem;
    --bs-nav-underline-border-width: 3px;
    --bs-nav-underline-link-active-color: var(--mq-marine);
    border-block-end: 1px solid var(--mq-bordure);
  }

  #checkout-personal-information-step .nav-link {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    font-size: var(--mq-taille-label);
    letter-spacing: var(--mq-approche-capitales);
    text-transform: uppercase;
    color: var(--mq-marine);
  }

  /* Étape 2 (T3.12, décision 5 du 02/10/2026) : « Adresse de livraison »
     et « Votre adresse de facturation » (p.h3, 27px) au jeton h5 (21px) :
     ils égalaient le h1 au bureau et dépassaient la bande sur mobile.
     Échelle rétablie : 27 (h1), 21 (sections), 18 (nom de l'adresse).
     Marges (.mt-4 compris) gardées. */
  #checkout-addresses-step p.h3 {
    font-size: var(--mq-taille-h5);
  }

  /* Étape 3 (4.17) : la première et la dernière carte retrouvent un rayon
     complet et leur filet bas (Hummingbird, dans cette couche : rayons
     partiels, pas de filet sous la dernière). */
  .delivery-options__list > .delivery-option__item:is(:first-child, :last-child) {
    border-block-end: 1px solid var(--mq-bordure);
    border-radius: var(--mq-rayon-carte);
  }

  /* Carte choisie : fond blanc cassé, bord marine de 2px (1px de bord et
     1px d'ombre intérieure). Spécificité (0,4,0) : vaut aussi pour la
     première et la dernière carte. */
  .delivery-options__list > .delivery-option__item:has(.form-check-input:checked) {
    background-color: var(--mq-blanc-casse);
    border-color: var(--mq-marine);
    box-shadow: inset 0 0 0 1px var(--mq-marine);
  }

  /* Étape 4, consigne du récapitulatif final (T3.15, décision 2 : réglage
     n° 10 gardé). L'alerte rouge native, affichée avant toute action de
     l'acheteur, est habillée en consigne neutre aux couleurs d'une alerte
     d'information (jetons O3 B du §3) : marine sur blanc cassé (10,85:1),
     liens en Bold soulignés (.alert-link). Elle ne peut pas être masquée
     en CSS : core.js pose son display en ligne (règle 7 du GUIDE §5.2).
     Visée comme le frère qui suit .final-summary, pas par sa classe js-*. */
  .final-summary + .alert-danger {
    --bs-alert-color: var(--bs-info-text-emphasis);
    --bs-alert-bg: var(--bs-info-bg-subtle);
    --bs-alert-border-color: var(--bs-info-border-subtle);
    --bs-alert-link-color: var(--bs-info-text-emphasis);
    --bs-alert-padding-y: 0.75rem;
  }

  /* Étape 4 (T3.19) : de 992 à environ 1010px, le bouton final passe seul
     sur une seconde rangée ; il y reste à droite. Identifiant natif, stable
     (core.js s'en sert). Dès 768px seulement : en colonne, sur mobile, la
     marge automatique l'empêcherait d'occuper toute la largeur. */
  @media (min-width: 768px) {
    #payment-confirmation {
      margin-inline-start: auto;
    }
  }
}


/* ------------------------------------------------------------
   13.4 FENÊTRE DES CGV ET CONFIRMATION
   Confirmation de commande (T3.20, 4.21) : règles .order-confirmation__*
   en ps-components, partagées avec le récapitulatif final de l'étape 4
   (T3.14) et définies une seule fois ; titres, lien et colonne de la page
   en ps-pages. « Produits phares » retirés par la dissociation du module
   au back-office (T3.21 B1, décision 6 du 02/10/2026) : aucune CSS.
   ------------------------------------------------------------ */

@layer ps-components {
  /* Même gabarit (order-confirmation-table.tpl) au récapitulatif final et
     dans « Détails de la commande » de la confirmation. « Total TTC » et
     son montant à 18px Bold marine, comme au récapitulatif latéral (4.8,
     4.20) ; Hummingbird met 600 sur toutes les valeurs de ligne, seule la
     ligne --bold est visée ici. Si l'affichage des taxes est activé,
     « Taxes » et « Total HT » portent aussi --bold et prennent ce style,
     comme au panier. */
  .order-confirmation__line--bold .order-confirmation__line-label,
  .order-confirmation__line--bold .order-confirmation__line-value {
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  /* Total de ligne en Bold marine et prix unitaire en Medium, qui s'efface
     devant lui, comme la ligne du panier (4.4 ; ajouts au 4.21). Le prix
     unitaire reste masqué sous 768px (Hummingbird). */
  .order-confirmation__product-total {
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }

  .order-confirmation__product-price {
    font-weight: var(--mq-graisse-texte);
  }
}

@layer ps-pages {
  /* Fenêtre des CGV (#checkout-modal, 4.19) : le contenu de la page CMS y
     est copié sans la classe rich-text. Titres ramenés aux jetons h4, h5 et
     h6 (le contenu de démonstration commence par un h1 de 51px), puces et
     numéros rendus, liens soulignés, lignes d'environ 75 caractères au
     plus : 37rem, soit 592px pour 7,8px par caractère mesurés en Galano à
     16px (75ch vaudrait 800px, le zéro de Galano étant large, et serait
     sans effet dans la fenêtre de 800px). La largeur est posée sur les
     enfants : sur .modal-body, la barre de défilement interne se serait
     retrouvée au milieu de la fenêtre. */
  #checkout-modal .modal-body h1 {
    font-size: var(--mq-taille-h4);
    line-height: var(--mq-interligne-sous-titre);
  }

  #checkout-modal .modal-body h2 {
    font-size: var(--mq-taille-h5);
  }

  #checkout-modal .modal-body h3 {
    font-size: var(--mq-taille-h6);
    line-height: var(--mq-interligne-titre);
  }

  /* Titres plus bas du texte des CGV : 16px Bold, sous les h3 (sans cette
     règle, un h4 garderait 23px et passerait au-dessus des h2 et h3). Décision
     d'Aurélien du 02/10/2026. */
  #checkout-modal .modal-body :is(h4, h5, h6) {
    font-size: 1rem;
    font-weight: var(--mq-graisse-titre);
    line-height: var(--mq-interligne-titre);
  }

  #checkout-modal .modal-body ul {
    list-style: disc;
    padding-inline-start: 1.5rem;
  }

  #checkout-modal .modal-body ol {
    list-style: decimal;
    padding-inline-start: 1.5rem;
  }

  #checkout-modal .modal-body a:not(.btn) {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  #checkout-modal .modal-body > * {
    max-width: 37rem;
  }

  /* Confirmation de commande (T3.20, décision 5 du 02/10/2026) :
     hiérarchie 27 / 23 / 21px au lieu de 36 à 51px. Le h1 de l'encadré au
     jeton h3 (27px), comme le h1 d'étape du tunnel. */
  body#order-confirmation .alert-success .page-title-section {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* « Informations de paiement » (p.h2 des modules de paiement sous
     Hummingbird 2.0.0, h2 nu depuis la 2.1 ; C5 du rapport de migration) et
     « Détails de la commande » (h2.h2) au jeton h4 (23px). */
  body#order-confirmation .card :is(h2, .h2) {
    font-size: var(--mq-taille-h4);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* « Payer par chèque » (p.h3) au jeton h5 (21px) ; sa couleur atténuée
     vient de l'utilitaire text-secondary (5,08:1), gardée. */
  body#order-confirmation .card .h3 {
    font-size: var(--mq-taille-h5);
  }

  /* « Gagnez du temps… » (h3 sans classe, invité seulement) au niveau des
     autres cartes (23px). */
  body#order-confirmation .order-confirmation__account-transformation h3 {
    font-size: var(--mq-taille-h4);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* Liens de texte des cartes (« support client », lien du paiement à la
     livraison) soulignés : marine contre le texte noir ne fait que 1,77:1
     (WCAG 1.4.1). Comme .rich-text a (§4). */
  body#order-confirmation .card a:not(.btn) {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  /* Colonne de 820px au bureau, alignée à gauche sur le fil d'Ariane et le
     logo, comme la colonne du tunnel (au lieu de 1240px). Sans effet sous
     844px de fenêtre. Les alertes de #notifications restent hors de cette
     colonne. */
  body#order-confirmation #center-column {
    max-width: 51.25rem;
  }
}


/* ------------------------------------------------------------
   13.5 SUIVI DE COMMANDE INVITÉ (T3.24, T3.25)
   Formulaire (customer/guest-login.tpl) : aucune règle propre, il suit
   les règles globales du §6. Résultat (customer/guest-tracking.tpl, qui
   étend order-detail.tpl, partagé avec le détail de commande du compte,
   lot F) : la pastille d'état, son texte sur fond clair et la ligne de
   référence valent aussi au compte. Carte de création de compte : voir
   le §5 (œil) et le §6, aucune règle nouvelle (T3.23).
   ------------------------------------------------------------ */

@layer ps-components {
  /* Pastille d'état (T3.25) : elle passe à la ligne dans sa colonne au lieu
     de déborder (« En attente du paiement par chèque » : 279px pour 199px
     de colonne à 390px). Sa couleur de fond, posée en ligne par le noyau,
     reste celle du back-office (décision 7). */
  .order-status__badge {
    white-space: normal;
    text-align: start;
    line-height: 1.3;
  }

  /* « Commande … passée le … » en 18px Bold marine, comme les noms
     d'adresse (4.16). */
  .order-infos__reference {
    font-size: var(--mq-taille-h6);
    font-weight: var(--mq-graisse-titre);
    color: var(--mq-couleur-titre);
  }
}

@layer ps-pages {
  /* Pastilles que le noyau classe « foncées » (fond clair) : texte noir au
     lieu du marine de --bs-dark, meilleur contraste sur les fonds moyens et
     clairs (texte courant noir, charte). Même liste que Hummingbird,
     redéclarée après. Le blanc des pastilles --bright est inchangé. */
  .page-guest-tracking .order-status__badge--dark, .page-order-detail .order-status__badge--dark {
    color: var(--mq-noir);
  }

  /* Hummingbird 2.1.2 : titres de section en h2 nu (au lieu de .h3), soit
     36 à 51px, autant que le h1 ; ramenés au jeton h3 (27px), un cran sous
     le h1. Suivi invité et détail de commande du compte. « Messages du
     service client » (h3.h3) est déjà à 27px. */
  :is(.page-order-detail, .page-guest-tracking) :is(.order-status, .order-addresses, .order-products, .order-carriers, .order-message-form, .order-merchandise-return) h2 {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
  }

  /* « Commander à nouveau » retiré pour l'invité (décision 6) : le noyau ne
     recrée le panier que pour un client connecté, le lien ne faisait rien.
     Le réglage natif (PS_DISALLOW_HISTORY_REORDERING) l'ôterait aussi aux
     clients inscrits (réachat des recharges, cdc:344) : seul le suivi
     invité est visé, par le paramètre submitReorder du lien et non par sa
     classe de style. Retiré aussi de l'arbre d'accessibilité. */
  body#guest-tracking .order-infos__actions a[href*="submitReorder"] {
    display: none;
  }
}


/* ============================================================
   14. PAGES DE CONTENU, ERREURS ET CONTACT (lot G, décisions
   d'Aurélien du 03/10/2026)
   Gabarits natifs de Hummingbird (cms/page.tpl, contact.tpl,
   cms/sitemap.tpl), habillés ici. Conception : cadrage du lot G
   (analyses/lot-g-pages/cadrage.md de l'espace de travail), dont les
   numéros (4.5, 4.15, O6…) sont cités dans les commentaires. Tranche 1
   écrite le 05/10/2026 et contrôlée sur copies locales des relevés ; à
   contrôler en ligne.

   Ailleurs dans ce fichier, pour tout le site : bouton de fichier au §6
   (4.4) ; surtitre à puce et fonds marine des nouveaux modèles CE au
   §12.11 (4.0).

   Tranche 2 (05/10/2026) : page 404 (4.1), panneau « Nous écrire » (4.4)
   et FAQ (4.8) au §12.11, modèles CE ; grille du contact au 14.2 ; tailles
   des titres d'un contenu CE dans une page CMS au 14.4 (règle du 4.7, posée
   avec la FAQ).

   Tranche 3 (05/10/2026) : pages composées avec CE (4.7), pastilles,
   citation et interligne des titres au §12.11, grilles de cartes et nom de
   l'équipe au 14.4.

   Pas encore réalisé : page de maintenance (4.3, fichier error.css de
   l'enfant), tranche 4.

     14.1 Pages CMS de lecture
     14.2 Contact
     14.3 Plan du site
     14.4 Contenu Creative Elements dans une page CMS
   ============================================================ */


/* ------------------------------------------------------------
   14.1 PAGES CMS DE LECTURE (4.5, G4)
   Livraison, mentions légales, conditions, paiement sécurisé, retours,
   CGV : texte riche de l'éditeur du back-office (O6 A), sous le h1 natif
   (.page-title-section, échelle h1, §4). Règles posées sur les enfants
   DIRECTS de .page-content--cms : .rich-text sert aussi aux descriptions de
   produit, de catégorie et de marque, et un contenu Creative Elements
   arrive dans un div.elementor, laissé intact (ses titres : 4.7, tranche
   3). Couche ps-components, celle de .rich-text chez Hummingbird : elle
   bat l'échelle globale des titres (§4, bs-base).
   Échelle d'un cran net par niveau : h2 27, h3 21, h4 18px, h5 et h6 à
   16px, jamais au-dessus d'un h4. La description de la fiche fait de même
   un cran plus bas (§12.6) ; la fenêtre des CGV garde la sienne (§13.4).
   Aucune règle pour un h1 du contenu : il se retire du texte (règle de
   rédaction du 4.6, GUIDE §6.6), un filet CSS cacherait l'erreur.
   ------------------------------------------------------------ */

@layer ps-components {
  .page-content--cms > h2 {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
    margin-block: 2.75rem 0.75rem;
  }

  .page-content--cms > h3 {
    font-size: var(--mq-taille-h5);
    line-height: var(--mq-interligne-sous-titre);
    margin-block: 2rem 0.5rem;
  }

  /* Interligne de 1.15 déjà posé sur h4 par le §4. */
  .page-content--cms > h4 {
    font-size: var(--mq-taille-h6);
    margin-block: 1.5rem 0.5rem;
  }

  /* h5 et h6 : 16px, Bold comme tous les titres (§4). Interligne et marges
     du h4, en complément du cadrage : à 1.02 (§4), un titre de deux lignes
     serait serré, et sans marge haute il collerait au paragraphe. */
  .page-content--cms > :is(h5, h6) {
    font-size: 1rem;
    line-height: var(--mq-interligne-sous-titre);
    margin-block: 1.5rem 0.5rem;
  }

  /* Rien au-dessus du premier élément : .page-header pose déjà 2rem sous
     le h1. 0,2,0 bat les marges des titres ci-dessus (0,1,1). */
  .page-content--cms > :first-child {
    margin-top: 0;
  }

  /* Lignes d'environ 75 caractères au plus (largeur A) : 37rem, soit 592px
     pour 7,8px par caractère en Galano à 16px (mesure du §13.4). Colonne
     alignée sous le h1 ; au bureau, le reste de la grille reste vide.
     Tableaux, figures et images posés seuls gardent toute la largeur ; une
     image que l'éditeur range dans un paragraphe suit la colonne. */
  .page-content--cms > :is(p, ul, ol, dl, blockquote, h2, h3, h4, h5, h6) {
    max-width: 37rem;
  }

  /* Listes : retrait de 22px, 8px entre les points (design system). Même
     couche et même spécificité (0,1,1) que .rich-text ul de Hummingbird et
     .rich-text ol (§12.6) : la règle vient après et gagne. Puces et numéros
     restent les leurs. */
  .page-content--cms > :is(ul, ol) {
    padding-inline-start: 1.375rem;
  }

  .page-content--cms > :is(ul, ol) > li + li {
    margin-top: var(--mq-espace-2);
  }

  /* Citations (citations A) : panneau blanc cassé, rayon de 19px, 24 x 28px
     de marge intérieure, 21px Bold marine (10,85:1), interligne 1.25 : le
     QuoteBlock clair du design system, réduit. Le jaune reste réservé aux
     citations CE, une par page. Marge basse de Bootstrap (1rem) gardée ; le
     dernier paragraphe de la citation perd la sienne. */
  .page-content--cms > blockquote {
    padding: var(--mq-espace-5) 1.75rem;
    border-radius: var(--mq-rayon-carte);
    background-color: var(--mq-blanc-casse);
    color: var(--mq-couleur-titre);
    font-size: var(--mq-taille-h5);
    font-weight: var(--mq-graisse-titre);
    line-height: 1.25;
  }

  .page-content--cms > blockquote > :last-child {
    margin-bottom: 0;
  }

  /* Filet : couleur (--bs-border-color, donc --mq-bordure, §3) et opacité 1
     viennent déjà de Hummingbird (hr, bs-custom-components) ; seul l'espace
     change, celui d'un h2. */
  .page-content--cms > hr {
    margin-block: 2.75rem;
  }
}


/* ------------------------------------------------------------
   14.2 CONTACT (4.4)
   Tranche 1 : bouton de fichier seulement, au §6 (il vaut pour tout le
   site). Tranche 2 : grille de la page en pleine largeur et panneau
   « Nous écrire » (O4 B, réglages N8 et N10), ici et au §12.11.
   Sous 992px, panneau sous le formulaire, à 32px du bouton d'envoi (collé
   sans la grille, relevé R6 du 05/10). Dès 992px, formulaire et panneau
   côte à côte (1,3fr et 1fr, environ 670 et 500px à 1440px), panneau en
   haut. Couche ps-pages.
   ------------------------------------------------------------ */

@layer ps-pages {
  body#contact .page-content--general {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--mq-espace-6);
  }

  @media (min-width: 992px) {
    body#contact .page-content--general {
      grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
      gap: var(--mq-espace-7);
      align-items: start;
    }
  }
}


/* ------------------------------------------------------------
   14.3 PLAN DU SITE (4.15, O9 A)
   Gabarit cms/sitemap.tpl : quatre blocs à h2 (Nos offres, Catégories,
   Votre compte, Pages), deux colonnes dès 768px, quatre dès 992px. Couche
   ps-components, celle du composant sitemap de Hummingbird et de
   .sitemap__link (§4) : ps-pages gagnerait aussi, mais sortirait ces règles
   de la couche de leur composant (4.15). Déjà natifs, sans règle ici : marge
   de 1rem sous les h2 ; filet des blocs empilés sous 768px (hr) à la
   couleur --mq-bordure et à l'opacité 1 ; filet gris-bleu des listes
   imbriquées. Liens morts et pages de démonstration : réglages du
   back-office (G5, 4.14), pas la CSS.
   ------------------------------------------------------------ */

@layer ps-components {
  /* h2 des blocs au jeton h3 (27px), au lieu de 36 à 51px dans des colonnes
     de 286px. */
  .sitemap__block h2 {
    font-size: var(--mq-taille-h3);
    line-height: var(--mq-interligne-sous-titre);
  }

  .sitemap__block {
    margin-bottom: var(--mq-espace-6);
  }
}


/* ------------------------------------------------------------
   14.4 CONTENU CREATIVE ELEMENTS DANS UNE PAGE CMS (4.7, 4.8)
   Une page CMS éditée avec CE (FAQ, puis pages composées) rend son contenu
   dans un div.elementor, à l'intérieur de .page-content--cms (relevé R8 du
   05/10/2026). Sous le h1 natif (O7 A), un h2 sans taille réglée dans son
   widget prendrait les 36 à 51px de l'échelle globale (§4, bs-base) : il
   passe au jeton h3 (27px), un cran sous le h1, comme dans les pages de
   lecture (14.1) ; un h3, au jeton h5 (21px). Un titre réglé dans son widget
   garde sa taille (règle de CE, hors couche) : h2 du bloc diagnostic n° 3
   déjà à 27px. Interligne : CE impose line-height: 1 hors couche, repris
   au §12.11. Grilles de cartes des modèles de la tranche 3. Couche
   ps-components, celle de .rich-text.
   ------------------------------------------------------------ */

@layer ps-components {
  .page-content--cms .elementor h2 {
    font-size: var(--mq-taille-h3);
  }

  .page-content--cms .elementor h3 {
    font-size: var(--mq-taille-h5);
  }

  /* Nom d'un membre de l'équipe : 18px (TeamCard du design system). */
  .page-content--cms .elementor .mq-equipe h3 {
    font-size: var(--mq-taille-h6);
  }

  /* Cartes posées sur des colonnes à fond (Étapes, Cartes, Photo et
     panneau) et cartes de l'Équipe : 24px entre elles, cartes jusqu'aux
     bords du contenu. Même mécanique que le §11 (CE met la gouttière dans la
     boîte qui porte le fond) ; sections réglées « Sans espace » dans CE. */
  :is(.mq-etapes, .mq-cartes, .mq-panneau-photo, .mq-equipe) > .elementor-container > .elementor-row {
    min-width: calc(100% + 1.5rem);
    margin: -0.75rem;
  }

  :is(.mq-etapes, .mq-cartes, .mq-panneau-photo, .mq-equipe) > .elementor-container > .elementor-row > .elementor-column > .elementor-element-populated {
    margin: 0.75rem;
  }

  /* Mobile : cartes empilées à 16px d'écart ; l'Équipe reste en 2 x 2. */
  @media (max-width: 767.98px) {
    :is(.mq-etapes, .mq-cartes, .mq-panneau-photo) > .elementor-container > .elementor-row {
      min-width: 0;
      margin: 0;
    }

    :is(.mq-etapes, .mq-cartes, .mq-panneau-photo) > .elementor-container > .elementor-row > .elementor-column > .elementor-element-populated {
      margin: 0 0 1rem;
    }
  }
}
