/* ============================================================
   mze-vitrine.css — Composants de la vitrine
   Mobile-first : base < 576px, surcharges à 576 / 992 / 1200px.
   Aucune valeur d'axe en dur : tout passe par var(--mze-*).

   Porte les 7 primitives absentes du design system d’origine :
   hero, sections à fond alterné, carrousel, galerie produit,
   fil d'Ariane, pagination, avis.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--mze-bg);
  color: var(--mze-text);
  font-family: var(--mze-font-body);
  font-size: var(--mze-body-size);
  font-weight: var(--mze-weight-body);
  line-height: var(--mze-lh-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--mze-font-heading);
  font-weight: var(--mze-weight-heading);
  line-height: var(--mze-lh-heading);
  letter-spacing: var(--mze-ls-heading);
  margin: 0 0 .5em;
}
h1 { font-size: var(--mze-h1); }
h2 { font-size: var(--mze-h2); }
h3 { font-size: var(--mze-h3); }
h4 { font-size: var(--mze-h4); }
h5 { font-size: var(--mze-h5); }
h6 { font-size: var(--mze-h6); }
p  { margin: 0 0 1em; }

a { color: var(--mze-accent-contrast); text-underline-offset: .22em; }
img { max-width: 100%; display: block; }

.mze-wrap { width: 100%; max-width: var(--mze-wrap-max); margin: 0 auto; padding: 0 var(--mze-wrap-pad); }
.mze-tagline {
  font-family: var(--mze-font-tagline);
  font-size: var(--mze-tagline-size);
  letter-spacing: var(--mze-tagline-ls);
  text-transform: var(--mze-tagline-transform);
  color: var(--mze-accent-contrast);
  line-height: 1.25;
  margin: 0 0 .3em;
}
.mze-visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- Bandeau de bascule de thème (maquette uniquement) ---------- */
.mze-themebar {
  position: sticky; top: 0; z-index: 100;
  background: #1b1b1b; color: #fff;
  font-family: system-ui, sans-serif; font-size: 12px;
  padding: 8px 14px; display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
}
.mze-themebar strong { letter-spacing: .06em; margin-right: 4px; }
.mze-themebar button {
  font: inherit; cursor: pointer; padding: 5px 10px;
  background: transparent; color: #fff; border: 1px solid #555; border-radius: 2px;
}
.mze-themebar button[aria-pressed="true"] { background: #fff; color: #1b1b1b; font-weight: 600; }
.mze-themebar .sep { margin-left: auto; opacity: .5; }
.mze-themebar a { color: #fff; }

/* ---------- Bandeau supérieur ----------
   Passé en CSS scopé de MzeTopbar, seul consommateur. */

/* ---------- En-tête ----------
   Barre, sélecteur de langue, navigation, recherche, suggestions et menu de collections :
   passés en CSS scopé de MzeHeader, seul consommateur. Restent ici les primitives partagées
   ci-dessous (.mze-logo, .mze-iconbtn, .mze-cartcount). */

/* Logo — partagé par MzeHeader, MzeFooter (`.mze-logo mze-footer__brand`) et le shell
   d'administration (MzeAppHeader, MzeAppLayoutWithSidebar) : reste global.

   `min-width: 0` autorise l'élément flex à passer sous sa largeur min-content, et l'ellipse
   absorbe le résidu en deçà de 320 px — le débordement de page devient impossible (BUG-SITE-001). */
.mze-logo {
  font-family: var(--mze-font-heading);
  font-size: var(--mze-h6); line-height: 1.1;
  letter-spacing: var(--mze-ls-heading);
  color: var(--mze-text); text-decoration: none; white-space: nowrap;
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
/* La ligne de sous-titre disparaît au palier mobile : elle n'apporte rien et allonge le bloc. */
.mze-logo span { display: none; font-family: var(--mze-font-body); font-size: .58rem; letter-spacing: .18em; text-transform: uppercase; color: var(--mze-text-muted); }

/* Logo de l'en-tête précédé de la couronne du logo d'origine (décision du 2026-11-06). La couronne
   (44 px) est plus haute que le nom sur une ligne : le rognage vertical de `overflow: hidden` la
   coupait en deux taches de fleurs. `overflow-x: clip` garde l'ellipse du nom sans rogner en hauteur. */
.mze-logo--couronne {
  position: relative;
  padding-left: calc(44px + var(--mze-space-2));
  overflow: visible; overflow-x: clip; overflow-clip-margin: 0;
}
.mze-logo__couronne {
  position: absolute; left: 0; top: 50%;
  width: 44px; height: auto;
  transform: translateY(-50%);
}

/* Cibles tactiles de 44 px — recommandation WCAG 2.5.5 */
.mze-iconbtn {
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--mze-text); border-radius: var(--mze-radius-sm);
  width: 44px; height: 44px; flex: none;
  display: inline-grid; place-items: center; position: relative;
  font-size: 1.25rem; line-height: 1; text-decoration: none;
  transition: background var(--mze-duration), color var(--mze-duration);
}
.mze-iconbtn:hover { background: var(--mze-accent-soft); color: var(--mze-accent-contrast); }
.mze-iconbtn:focus-visible { outline: 2px solid var(--mze-accent-contrast); outline-offset: 1px; }
.mze-cartcount {
  position: absolute; top: 5px; right: 4px;
  background: var(--mze-accent); color: var(--mze-text-on-accent);
  font-family: var(--mze-font-body); font-size: .62rem; font-weight: 700; line-height: 1;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--mze-radius-pill); display: grid; place-items: center;
}

/* ---------- Menu mobile (tiroir) ----------
   Passé en CSS scopé de MzeDrawer, seul consommateur. `body.mze-noscroll` reste ici :
   <body> n'appartient à aucun composant, la règle est posée par mze-vitrine.js. */
body.mze-noscroll { overflow: hidden; }

/* ---------- Registre visuel éditorial ----------
   Redéfinition des tokens de forme des composants du design system pour la vitrine. Le même
   MzeButton rend ici le bouton capitales-espacées des maquettes, et le bouton applicatif dans
   l'administration : un seul composant, deux registres, aucune classe parallèle.

   Porté par `.mze-vitrine` (MzeVitrineLayout), pendant symétrique de `.mze-admin`.
   Ne redéfinir ici que des tokens — aucune règle de composant. */
.mze-vitrine {
  --mze-btn-radius:       var(--mze-radius);
  --mze-btn-weight:       600;
  --mze-btn-transform:    uppercase;
  --mze-btn-tracking:     .09em;
  --mze-btn-height-md:    48px;
  --mze-btn-padding-x-md: 26px;
  --mze-btn-font-size-md: .82rem;
  /* Les aplats d'accent sont saturés : les éclaircir au survol les délave. */
  --mze-btn-hover-filter: brightness(.92);
}

/* ---------- Sections à fond alterné ---------- */
/* Déplacé en CSS scopé du composant MzeSection (Mze.FrontEnd/Vitrine/MzeSection.razor.css). */

/* ---------- Hero ---------- */
/* Déplacé en CSS scopé du composant MzeHero (Mze.FrontEnd/Vitrine/MzeHero.razor.css). */

/* Sélecteur de dates d'évènement — état global de session (relève de SITE-005) */
.mze-datepick {
  background: var(--mze-bg); color: var(--mze-text);
  border-radius: var(--mze-radius); padding: 14px;
  display: grid; gap: 10px; max-width: 460px; margin-top: 22px;
  box-shadow: 0 10px 30px rgba(0,0,0,.13);
}
.mze-datepick__label { font-size: .66rem; letter-spacing: .14em; text-transform: uppercase; color: var(--mze-text-muted); }
/* .mze-datepick__fields : retiré — structure absente de toute maquette validée (cf. BUG-SITE-003). */
.mze-datepick__period { margin: 2px 0 0; font-size: .84rem; color: var(--mze-text-muted); }
.mze-datepick__period strong { color: var(--mze-text); font-weight: 600; white-space: nowrap; }
.mze-datepick__adjust { display: grid; grid-template-columns: 1fr; gap: 8px; padding-top: 4px; }
.mze-datepick__adjust[hidden] { display: none; }
.mze-linkaction {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: inherit; color: var(--mze-accent-contrast);
  text-decoration: underline; text-underline-offset: .22em;
}
@media (min-width: 576px) {
  .mze-datepick__adjust { grid-template-columns: 1fr 1fr; }
}
.mze-field { display: grid; gap: 4px; }
.mze-field label { font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--mze-text-muted); }
.mze-field input, .mze-field select {
  font: inherit; font-size: .9rem; color: var(--mze-text); background: var(--mze-bg);
  padding: 10px 11px; border: 1px solid var(--mze-border-strong); border-radius: var(--mze-radius-sm);
}
.mze-field input:focus, .mze-field select:focus { outline: 2px solid var(--mze-accent-contrast); outline-offset: 1px; }

/* ---------- Grilles ---------- */
.mze-grid { display: grid; gap: var(--mze-gutter); }
.mze-grid--2 { grid-template-columns: repeat(2, 1fr); }
.mze-grid--3 { grid-template-columns: 1fr; }
.mze-grid--4 { grid-template-columns: repeat(2, 1fr); }

/* ---------- Carte produit ---------- */
/* Déplacé en CSS scopé du composant MzeCarteProduit (Mze.Vitrine.FrontEnd/MzeCarteProduit.razor.css).
   `.mze-card` est aussi la classe racine du composant générique MzeCard : une règle GLOBALE
   portant ce nom s'appliquait donc aussi à lui, partout où il apparaît. Le scope l'empêche. */

/* ---------- Placeholder photo ---------- */
/* Déplacé dans la feuille partagée du domaine vitrine
   (_content/Mze.Vitrine.FrontEnd/css/mze-vitrine-composants.css) : sept fichiers l'émettent,
   dans les deux projets — la règle a plusieurs consommateurs, elle ne peut pas être scopée. */

/* ---------- Badges ---------- */
/* Déplacé dans la même feuille partagée, et RENOMMÉ en `.mze-vitrine-pastille`.
   L'ancien nom `.mze-badge` entrait en collision avec le composant générique MzeBadge. */

/* ---------- Carrousel ---------- */
/* La PISTE est en CSS scopé du composant MzeCarrousel. Les FLÈCHES sont rendues par la page
   /atelier, seule émettrice : déplacées dans AtelierVitrine.razor.css. */

/* ---------- Collections ----------
   Le gabarit .mze-coll est passé en CSS scopé de MzeTuileCollection, seul consommateur. */

/* ---------- Fil d'Ariane ---------- */
/* Déplacé en CSS scopé du composant MzeFilAriane (Mze.FrontEnd/Vitrine/MzeFilAriane.razor.css). */

/* ---------- Galerie produit ---------- */
/* Déplacé en CSS scopé du composant MzeGalerie (Mze.FrontEnd/Vitrine/MzeGalerie.razor.css). */

/* ---------- Avis ---------- */
/* Déplacé en CSS scopé du composant MzeAvis (Mze.FrontEnd/Vitrine/MzeAvis.razor.css). */

/* ---------- Pagination ---------- */
/* Déplacé en CSS scopé du composant MzePagination (Mze.FrontEnd/Vitrine/MzePagination.razor.css). */

/* ---------- Réassurance ---------- */
.mze-reassure { display: grid; gap: 22px; grid-template-columns: 1fr; text-align: center; }
.mze-reassure h4 { margin: 0 0 .3em; font-size: 1.02rem; }
.mze-reassure p { color: var(--mze-text-muted); font-size: .86rem; margin: 0; }

/* ---------- Instagram ---------- */
.mze-insta { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.mze-insta a { aspect-ratio: 1/1; display: block; }

/* ---------- Panier ---------- */
.mze-cartline { display: grid; grid-template-columns: 74px 1fr; gap: 13px; padding: 16px 0; border-bottom: 1px solid var(--mze-border); align-items: start; }
.mze-cartline__media { aspect-ratio: 1/1; border-radius: var(--mze-radius-sm); overflow: hidden; }
.mze-cartline__title { font-family: var(--mze-font-heading); font-size: 1rem; margin: 0 0 3px; }
.mze-cartline__meta { font-size: .78rem; color: var(--mze-text-muted); margin: 0 0 9px; }
.mze-cartline__ctrl { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.mze-qty { display: inline-flex; align-items: center; border: 1px solid var(--mze-border-strong); border-radius: var(--mze-radius-sm); overflow: hidden; }
.mze-qty button { width: 32px; height: 34px; border: 0; background: transparent; cursor: pointer; color: var(--mze-text); font-size: 1rem; }
.mze-qty input { width: 40px; height: 34px; border: 0; text-align: center; font: inherit; font-size: .9rem; color: var(--mze-text); background: transparent; }
.mze-cartline__total { font-family: var(--mze-font-heading); font-size: 1.05rem; margin-left: auto; }
.mze-linkremove { background: none; border: 0; cursor: pointer; color: var(--mze-text-muted); font: inherit; font-size: .78rem; text-decoration: underline; padding: 0; }

.mze-summary { background: var(--mze-bg-alt); border-radius: var(--mze-radius); padding: 20px; }
.mze-summary__row { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; font-size: .92rem; }
.mze-summary__row--total { border-top: 1px solid var(--mze-border-strong); margin-top: 8px; padding-top: 14px; font-family: var(--mze-font-heading); font-size: 1.2rem; }

.mze-switchrow { display: flex; align-items: flex-start; gap: 11px; padding: 11px 0; border-bottom: 1px solid var(--mze-border); }
.mze-switchrow:last-child { border-bottom: 0; }
.mze-switch { position: relative; width: 44px; height: 25px; flex: none; margin-top: 2px; }
.mze-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.mze-switch span { position: absolute; inset: 0; border-radius: var(--mze-radius-pill); background: var(--mze-border-strong); transition: background var(--mze-duration); pointer-events: none; }
.mze-switch span::after { content: ""; position: absolute; top: 3px; left: 3px; width: 19px; height: 19px; border-radius: var(--mze-radius-pill); background: var(--mze-bg); transition: transform var(--mze-duration); }
.mze-switch input:checked + span { background: var(--mze-accent); }
.mze-switch input:checked + span::after { transform: translateX(19px); }
.mze-switch input:focus-visible + span { outline: 2px solid var(--mze-accent-contrast); outline-offset: 2px; }
.mze-switchrow__txt strong { display: block; font-size: .93rem; }
.mze-switchrow__txt span { font-size: .8rem; color: var(--mze-text-muted); }

.mze-notice { background: var(--mze-accent-soft); border-left: 3px solid var(--mze-accent-contrast); padding: 13px 15px; border-radius: var(--mze-radius-sm); font-size: .87rem; }
.mze-notice strong { color: var(--mze-accent-contrast); }

/* ---------- Pied de page ----------
   Le gabarit .mze-footer est passé en CSS scopé de MzeFooter, seul consommateur —
   surcharges responsive comprises. */


/* ============================================================
   Composants remontés depuis les maquettes — mutualisés
   (rail de navigation, indicateur d'étapes, champs de formulaire)
   ============================================================ */
.mze-check input { margin: 0; flex: none; accent-color: var(--mze-accent); }
.mze-check:last-child { margin-bottom: 0; }
.mze-chip:hover { background: var(--mze-accent-soft); }
.mze-formrow { display: grid; gap: 12px; margin-bottom: 12px; }
.mze-formrow:last-child { margin-bottom: 0; }
/* Le gabarit .mze-rail est passé en CSS scopé de MzeRailCollections, seul consommateur. */
.mze-req { color: var(--mze-accent-contrast); font-weight: 700; }
.mze-request { border: 1px solid var(--mze-border); border-radius: var(--mze-radius); padding: 16px; background: var(--mze-bg); }
.mze-request__actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.mze-request__actions .mze-button { padding: 0 18px; }
.mze-request__amount { font-family: var(--mze-font-heading); font-size: 1.12rem; }
.mze-request__date { font-size: .78rem; color: var(--mze-text-muted); }
.mze-request__facts { display: grid; gap: 8px; font-size: .86rem; margin-bottom: 14px; }
.mze-request__facts dd { margin: 0; }
.mze-request__facts dt { font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--mze-text-muted); margin: 0; }
.mze-request__ref { font-family: var(--mze-font-heading); font-size: 1.05rem; }
.mze-request__top { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; margin-bottom: 10px; }
.mze-steps li {
    counter-increment: mzestep;
    display: flex; align-items: center; gap: 10px;
    font-size: .84rem; color: var(--mze-text-muted);
  }
.mze-steps li::before {
    content: counter(mzestep);
    flex: none; width: 28px; height: 28px; border-radius: var(--mze-radius-pill);
    display: grid; place-items: center;
    font-family: var(--mze-font-body); font-size: .8rem; font-weight: 700;
    background: var(--mze-bg-alt); color: var(--mze-text-muted);
    border: 1px solid var(--mze-border-strong);
  }
.mze-steps li[aria-current="step"] { color: var(--mze-text); font-weight: 600; }
.mze-steps li[aria-current="step"]::before {
    background: var(--mze-accent); color: var(--mze-text-on-accent); border-color: transparent;
  }
.mze-steps li[data-done="true"]::before { content: "✓"; background: var(--mze-accent-soft); color: var(--mze-accent-contrast); }

/* ============================================================
   Gabarits d'écran portés des maquettes (FEAT-SITE-003, UX §4.3)
   Sources : mockup-04-collections, mockup-05-collection, mockup-14-cles-en-main.
   Portage verbatim, à trois exceptions près :
   1. breakpoints normalisés (640 → 576, 1100 → 992) ;
   2. valeurs d'axe remplacées par les tokens du lot A ;
   3. .mze-rail n'est pas redéclaré ici — son gabarit vit dans le CSS scopé de MzeRailCollections.
   Tokens --mze-* uniquement — le lot A est livré par la piste 3 dans mze-tokens.css.
   ============================================================ */

/* En-tête de section écrit DANS UNE PAGE (`.mze-pagehead`, `.mze-collhead`).
   Les règles de `.mze-sectionhead` vivent dans le CSS scopé de MzeSection : elles ne s'appliquent
   qu'au markup rendu par le composant. Un en-tête écrit dans une page n'en reçoit donc AUCUNE.
   Ces règles globales couvrent ce cas ; elles s'appliquent aussi au markup du composant, ce qui
   rend le bloc scopé redondant. ⚠️ Consolidation à arbitrer : retirer le bloc de
   MzeSection.razor.css serait une modification non additive d'une zone partagée. */
.mze-sectionhead { margin-bottom: var(--mze-space-4); }
.mze-sectionhead--center { text-align: center; }
.mze-sectionhead h1, .mze-sectionhead h2, .mze-sectionhead h3 { margin-bottom: .18em; }
.mze-sectionhead p { color: var(--mze-text-muted); margin: 0; }
.mze-sectionhead .mze-tagline { color: var(--mze-accent-contrast); }

/* Chapeau de page et en-tête de collection : longueur de ligne maîtrisée. */
.mze-pagehead, .mze-collhead { max-width: 62ch; }
.mze-pagehead p, .mze-collhead p { color: var(--mze-text-muted); }

/* Gabarit catalogue : rail de navigation + grille de résultats.
   Mobile-first — le rail est au-dessus de la grille sous 992px. */
.mze-catalog {
  display: grid;
  gap: var(--mze-gutter-catalog);
  align-items: start;
  padding-bottom: var(--mze-space-4);
}

/* Barre d'outils : compteur de résultats et formulaire de tri. */
.mze-toolbar {
  display: flex; flex-wrap: wrap; gap: var(--mze-space-3);
  align-items: flex-end; justify-content: space-between;
  padding-bottom: var(--mze-space-3); margin-bottom: var(--mze-space-4);
  border-bottom: 1px solid var(--mze-border);
}
.mze-toolbar__count { color: var(--mze-text-muted); margin: 0 0 var(--mze-space-1); }
.mze-toolbar__count b { color: var(--mze-text); }
/* Le tri est un îlot MzeSelectUrl, plus un formulaire. `.mze-input-field` porte `width: 100%` —
   dans une barre en `flex-wrap`, il occupait donc toute la largeur et passait à la ligne sous le
   compteur. Largeur ramenée au contenu pour qu'il reste à droite, sur la ligne du compteur ;
   `margin-left: auto` le tient à droite même quand la barre n'a qu'un seul enfant visible. */
.mze-toolbar__form { width: auto; min-width: 190px; margin-left: auto; }

/* Rappel du sélecteur de dates, centré dans sa section. */
.mze-daterecall { display: grid; gap: var(--mze-space-3); justify-items: center; text-align: center; }
.mze-daterecall .mze-datepick { text-align: left; width: 100%; }
.mze-daterecall .mze-notice { max-width: 62ch; text-align: left; }

/* Décors clés en main : conteneur de grille et barre de filtres.
   Les cartes elles-mêmes sont en CSS scopé de MzeCartePack. */
.mze-pk { display: grid; gap: var(--mze-gutter-lg); grid-template-columns: 1fr; }
.mze-pkfilter {
  background: var(--mze-bg-alt); border-radius: var(--mze-radius);
  padding: var(--mze-space-3);
  display: flex; gap: var(--mze-space-3); align-items: flex-end; flex-wrap: wrap;
  margin-bottom: var(--mze-space-5);
}
/* Le filtre est un îlot MzeSelectUrl : sa racine est `.mze-input-field`, plus le `.mze-field`
   du formulaire natif qu'il a remplacé. */
.mze-pkfilter .mze-input-field { min-width: 190px; }
.mze-pkfilter__note { margin: 0 0 var(--mze-space-2); font-size: .84rem; color: var(--mze-text-muted); }

/* ============================================================
   Blocs propres aux écrans du sprint 2
   ============================================================ */

/* Lien d'évitement : hors flux, révélé au focus clavier. */
.mze-skiplink {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--mze-bg); color: var(--mze-accent-contrast);
  padding: var(--mze-space-2) var(--mze-space-3);
  border: 1px solid var(--mze-border-strong); border-radius: var(--mze-radius-sm);
}
.mze-skiplink:focus { left: var(--mze-space-2); top: var(--mze-space-2); }
#contenu:focus { outline: none; }

/* Reste des règles de carte produit : déplacé en CSS scopé du composant
   (Mze.Vitrine.FrontEnd/MzeCarteProduit.razor.css). */

/* Bloc texte + média des sections éditoriales.
   Le placeholder est la couche de base, l'image se pose dessus : un média absent du disque ne
   laisse jamais un cadre vide. Même motif sur .mze-card__media, .mze-pk__media, .mze-coll,
   .mze-hero__media et .mze-insta a. */
.mze-splitblock { display: grid; gap: var(--mze-space-4); align-items: center; }
.mze-splitblock__media { aspect-ratio: 4/3; position: relative; }
.mze-splitblock__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mze-splitblock__media .ph { width: 100%; height: 100%; }

/* Vignettes de la galerie et du flux : même motif de superposition. */
.mze-insta a { position: relative; }
.mze-insta a img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mze-prose > :last-child { margin-bottom: 0; }

/* ---------- Surfaces claires imbriquées dans une section inversée ----------
   Cause générique d'une famille de défauts de contraste : une section `--dark` ou `--accent`
   reteinte son contenu, mais un bloc qui pose SON PROPRE fond clair à l'intérieur reste clair — le
   texte y devenait clair sur clair (témoignages : blanc sur blanc, rapport 1,09).

   Le mécanisme n'est pas une exception par classe mais une réassignation locale des tokens de
   surface. Les propriétés personnalisées se résolvent sur l'élément qui les consomme : la
   déclaration la plus proche l'emporte, sans avoir à battre la spécificité des règles `::deep` de
   la section, ce qui serait impossible. Toute nouvelle surface claire s'ajoute à cette liste, ou
   porte simplement `.mze-surface--clair`. */
.mze-surface--clair,
/* .mze-card vise ici DEUX composants — MzeCarteProduit et le générique MzeCard — et c'est
   voulu : une surface claire posée dans une section inversée doit réassigner ses tokens,
   quel que soit le composant qui la porte. C'est le seul endroit où le nom reste global. */
.mze-card,
.mze-review,
.mze-datepick,
.mze-pk__card,
.mze-empty,
.mze-notice,
.mze-summary,
.mze-request {
  color: var(--mze-text);
  --mze-surface-texte: var(--mze-text);
  --mze-surface-accent: var(--mze-accent-contrast);
  --mze-focus-color: var(--mze-accent-contrast);
}

/* Pied de section : lien « voir tout » sous la liste, visible à tous les paliers. */
.mze-sectionfoot { display: flex; justify-content: center; margin: var(--mze-space-4) 0 0; }

/* Garde de réduction des éléments de grille : `min-width: auto` par défaut empêche une piste `1fr`
   de descendre sous la largeur min-content de son contenu, ce qui fait déborder la ligne dès qu'une
   référence produit porte un mot long. Même mécanisme que .mze-datepick__fields. */
.mze-grid > * { min-width: 0; }

/* Appel à action centré. */
.mze-cta { display: grid; justify-items: center; gap: var(--mze-space-2); max-width: 62ch; margin: 0 auto; }
.mze-cta p { margin: 0; }

/* Icône de réassurance. */
.mze-reassure__icon { font-size: 1.6rem; color: var(--mze-accent-contrast); display: block; margin-bottom: .4em; }
.mze-section--dark .mze-reassure__icon,
.mze-section--accent .mze-reassure__icon { color: inherit; }

/* Coordonnées de la section contact. */
.mze-coords { display: grid; gap: var(--mze-space-1); margin: 0; }
.mze-coords dt { font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--mze-text-muted); }
.mze-coords dd { margin: 0 0 var(--mze-space-2); }

/* Rail de collections de l'accueil : une seule structure, deux comportements.
   Sous 576px la piste défile ; au-delà elle redevient une grille de trois colonnes.
   Le sélecteur porte le nom d'élément pour l'emporter sur le CSS scopé de MzeCarrousel,
   de même spécificité mais chargé après cette feuille. */
div.mze-collrail .mze-carousel__track { grid-auto-columns: 78%; }

/* ---------- Utilitaires ---------- */
.mze-hint { font-size: .8rem; color: var(--mze-text-muted); margin: 0; }
.mze-hint--tight { margin-top: 10px; }
.mze-hint--spaced { margin: 12px 0 18px; }
.mze-hint--center { text-align: center; margin: 14px 0 0; }

/* ============================================================
   Surcharges — l'ordre suit la logique mobile-first
   ============================================================ */
@media (min-width: 576px) {
  /* L'en-tête retrouve sa composition complète : la largeur disponible le permet à nouveau. */
  .mze-logo { font-size: var(--mze-h5); }
  .mze-logo span { display: block; }

  .mze-grid--3 { grid-template-columns: repeat(3, 1fr); }
  .mze-reassure { grid-template-columns: repeat(2, 1fr); }

  .mze-cartline { grid-template-columns: 100px 1fr; }
  .mze-pk { grid-template-columns: repeat(2, 1fr); }
  /* Le rail de collections cesse de défiler et devient une grille : plus rien n'est masqué. */
  div.mze-collrail .mze-carousel__track {
    grid-auto-flow: row;
    grid-template-columns: repeat(3, 1fr);
    overflow-x: visible;
    padding-bottom: 0;
  }
  /* .mze-carousel__track / .mze-hero__inner / .mze-section : déplacés en CSS scopé des composants. */
}

@media (min-width: 992px) {
  .mze-wrap { padding: 0 var(--mze-wrap-pad-lg); }
  .mze-grid--4 { grid-template-columns: repeat(4, 1fr); }
  .mze-reassure { grid-template-columns: repeat(4, 1fr); }

  .mze-insta { grid-template-columns: repeat(6, 1fr); }
  .mze-pk { grid-template-columns: repeat(3, 1fr); }
  /* Rail de navigation à gauche, résultats à droite. */
  .mze-catalog { grid-template-columns: 258px 1fr; gap: var(--mze-gutter-catalog-lg); }
  .mze-splitblock { grid-template-columns: 1fr 1fr; }
  /* Image à gauche : on inverse l'ordre visuel, jamais l'ordre du document. */
  .mze-splitblock--reverse .mze-splitblock__texte { order: 2; }
  /* Flèches du carrousel (rendues dans l'en-tête de section) : visibles à partir du desktop. */
  .mze-carousel__nav { display: flex; }
  /* Piste, section, hero, galerie : overrides desktop en CSS scopé des composants. */
}

/* Le palier 1280 px (navigation éditoriale, hamburger, tiroir) vit désormais dans le CSS
   scopé de MzeHeader et de MzeDrawer. */

/* Palier 4K : on élargit le conteneur et rien d'autre. Pas de cinquième colonne — au-delà de quatre
   cartes par ligne, un catalogue de décoration se lit comme un tableur (arbitrage UX §2.2).
   Les blocs de texte restent plafonnés à 62ch par leur propre règle. */
@media (min-width: 1800px) {
  .mze-wrap { max-width: var(--mze-wrap-max-xl); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; scroll-behavior: auto !important; animation: none !important; }
}

/* Focus visible sur tout ce qui est atteignable au clavier. `:where()` a une spécificité nulle :
   la règle ne prend jamais le pas sur les règles de focus plus ciblées déjà en place, et couvre
   tout le reste — boutons, cartes, tuiles, rail, pagination, pied de page (UX §12). */
:where(a, button, [tabindex]):focus-visible {
  outline: var(--mze-focus-width) solid var(--mze-focus-color);
  outline-offset: var(--mze-focus-offset);
}
/* Les variantes de section déclarent elles-mêmes --mze-focus-color avec leur jeu de tokens de
   surface (MzeSection.razor.css) : rien à redéclarer ici. */

/* EXCEPTION — titres focalisés par programme.
   <FocusOnNavigate Selector="h1"> (Routes.razor) pose tabindex="-1" sur le titre de chaque page et
   lui donne le focus à la navigation : c'est ce qui annonce le changement de page à un lecteur
   d'écran. Mais [tabindex] fait alors matcher la règle ci-dessus, et le titre s'encadre à l'arrivée
   sur la page — un cadre que le visiteur n'a pas demandé, sur un élément qu'il ne peut pas activer.

   L'anneau est donc masqué là, et LÀ SEULEMENT : un titre focalisé par programme n'est pas un
   contrôle atteignable au clavier, il ne relève pas de l'exigence d'indicateur de focus. Ne pas
   élargir ce sélecteur — le masquer sur un lien ou un bouton rendrait la vitrine inutilisable au
   clavier. */
:where(h1, h2, h3, h4, h5, h6)[tabindex="-1"]:focus-visible { outline: none; }

/* ==========================================================================
   Fiche produit (FEAT-SITE-004)

   RIEN ICI, ET C'EST VOULU. Les trois blocs de la page — .mze-pdp, .mze-dl et
   .mze-avail — n'ont qu'un consommateur : ils vivent dans
   Components/Pages/FicheProduit.razor.css. Le fil d'Ariane et la galerie
   appartiennent à MzeFilAriane et MzeGalerie, qui portent leur CSS scopé dans
   Mze.FrontEnd. Les redéclarer ici les ferait fuir sur ces composants : une règle
   globale n'a pas d'attribut de scope, elle s'applique partout où la classe
   apparaît et écrase le scopé.
   ========================================================================== */
