/* =============================================================================
   MAREMBAL — FEUILLE DU SITE PUBLIC
   =============================================================================

   Écrite à la main. Aucune classe utilitaire, aucun framework, aucune
   dépendance. Elle habille toutes les pages de présentation — accueil, pôles,
   produits, secteurs, groupe — qui ne contiennent pas une seule ligne de React.

   Les couleurs, les fontes et les courbes viennent des jetons du design system
   (src/app/globals.css) : une seule source de vérité pour la marque, que la
   page soit rendue en HTML nu ou par l'application React.

   ── Trois règles tenues de bout en bout ────────────────────────────────────

   1. On n'anime que transform, opacity, clip-path et filter. Jamais une
      propriété qui déclenche une mise en page. C'est la seule discipline qui
      garantit 60 images par seconde sur une machine de bureau ordinaire.

   2. Aucune valeur de couleur, de fonte ou de courbe en dur. Tout passe par une
      variable. Changer la charte se fait à un seul endroit.

   3. Chaque composant est utilisable sur fond clair et sur fond sombre. Le
      basculement passe par un attribut sur un ancêtre — jamais par une
      duplication de règles.

   ── Sommaire ───────────────────────────────────────────────────────────────

    0. Racine, verrous et réglages globaux
    1. Conteneur, sections et primitives typographiques
    2. Primitives de révélation
    3. Calques d'atmosphère
    4. Préloader
    5. Navigation
    6. Boutons
    7. La plaque
    8. Blocs partagés
    9. Pied de page
   10. Accueil
   11. Page pôle
   12. Page produit
   13. Page secteur
   14. Pages groupe
   15. Accessibilité
   16. Mouvement réduit et impression
   ============================================================================= */

/* =============================================================================
   0. RACINE, VERROUS ET RÉGLAGES GLOBAUX
   ============================================================================= */

.mb {
  /* --- Rythme vertical ---------------------------------------------------- */
  --pas: clamp(64px, 9vw, 152px);
  --pas-court: clamp(44px, 6vw, 96px);
  --gouttiere: clamp(20px, 4vw, 56px);
  --largeur: 1440px;

  /* Hauteur de la barre. Fixe, et déclarée ici plutôt que déduite du contenu :
     tout ce qui doit passer dessous — ancres, méga-menu, menu plein écran,
     ouvertures de page — s'y réfère. Une seule valeur, redéfinie une fois pour
     le mobile, et tout suit. */
  --h-barre: 78px;

  /* --- Mouvement : alias courts sur les jetons ---------------------------- */
  --e-sortie: var(--ease-sortie, cubic-bezier(0.16, 1, 0.3, 1));
  --e-doux: var(--ease-doux, cubic-bezier(0.4, 0, 0.2, 1));
  --e-franc: var(--ease-franc, cubic-bezier(0.7, 0, 0.2, 1));
  --e-ressort: var(--ease-ressort, cubic-bezier(0.34, 1.56, 0.64, 1));

  /* --- Teintes de travail -------------------------------------------------
     Deux familles : `voile` sur fond sombre, `encre` sur fond clair. Chaque
     composant lit l'une ou l'autre selon le contexte, jamais une couleur
     absolue. C'est ce qui permet au même bouton d'exister sur les deux fonds. */
  --voile: color-mix(in srgb, var(--color-paper) 64%, transparent);
  --voile-faible: color-mix(in srgb, var(--color-paper) 34%, transparent);
  --trait-clair: color-mix(in srgb, var(--color-paper) 16%, transparent);
  --trait-sombre: color-mix(in srgb, var(--color-ink-900) 13%, transparent);
  --verre: color-mix(in srgb, var(--color-paper) 86%, transparent);
  --verre-sombre: color-mix(in srgb, var(--color-navy-900) 82%, transparent);

  position: relative;
  background: var(--color-paper);
  isolation: isolate;
}

/* Le défilement est confié au navigateur. Aucun smooth-scroll JavaScript : il
   désynchronise systématiquement la barre de progression sur trackpad, et il
   confisque à l'utilisateur le contrôle de sa propre molette. */
html {
  scroll-behavior: smooth;
  /* Les ancres ne se collent jamais sous la navigation fixe : hauteur de la
     barre, plus une respiration. */
  scroll-padding-top: 108px;
}

@media (width < 60rem) {
  html { scroll-padding-top: 92px; }
}

/* Verrou de défilement sans une ligne de JavaScript.
   Le script n'écrit jamais sur <body> : React possède cet élément, et toute
   classe posée avant l'hydratation produirait une divergence. La condition est
   lue directement dans le DOM rendu par le serveur. */
html:has(.pre:not([data-fini])),
html:has(.mb-menu[data-ouvert]),
html:has(.mb-mega[data-ouvert]) {
  overflow: hidden;
}

/* Le méga-menu ne verrouille le défilement qu'au-dessus de 60rem : en dessous
   c'est le menu plein écran qui prend le relais, et lui a son propre verrou. */
@media (width < 60rem) {
  html:has(.mb-mega[data-ouvert]) { overflow: visible; }
}

.mb ::selection {
  background: var(--color-gold-300);
  color: var(--color-navy-900);
}

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

/* `content-visibility: auto` a été retiré volontairement.

   L'idée était bonne sur le papier — ne pas mettre en page ce qui est hors
   écran — mais elle a un effet de bord qui se sent immédiatement : tant qu'une
   section n'a pas été rendue une première fois, le navigateur lui prête la
   taille de `contain-intrinsic-size`, jamais la vraie. La hauteur totale du
   document change donc à mesure qu'on descend, la barre de défilement se
   redimensionne sous le curseur, et la page part par à-coups — on croit
   défiler trop vite, puis trop lentement.

   Le gain était par ailleurs invisible ici : la mesure de fluidité donne
   16,7 ms d'image médiane sans lui. Une optimisation qui ne se mesure pas mais
   qui se sent n'est pas une optimisation. */

/* =============================================================================
   1. CONTENEUR, SECTIONS ET PRIMITIVES TYPOGRAPHIQUES
   ============================================================================= */

.mb-bloc {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

.mb-section {
  position: relative;
  padding-block: var(--pas);
}

.mb-section--court { padding-block: var(--pas-court); }
.mb-section--haut { padding-block: var(--pas) 0; }
.mb-section--bas { padding-block: 0 var(--pas); }

/* Les deux fonds du site. `--sur` porte la couleur de texte courante pour que
   les composants n'aient jamais à savoir sur lequel des deux ils sont posés. */
.mb-sombre {
  background: var(--color-navy-900);
  color: var(--color-paper);
  --sur: var(--color-paper);
  --sur-faible: var(--voile);
  --sur-tres-faible: var(--voile-faible);
  --filet: var(--color-navy-700);
  --filet-fort: var(--color-navy-500);
  --fond: var(--color-navy-900);
  --fond-creux: var(--color-navy-700);
}

.mb-clair {
  background: var(--color-paper);
  color: var(--color-ink-900);
  --sur: var(--color-navy-900);
  --sur-faible: var(--color-ink-500);
  --sur-tres-faible: var(--color-ink-500);
  --filet: var(--color-rule);
  --filet-fort: var(--color-navy-500);
  --fond: var(--color-paper);
  --fond-creux: color-mix(in srgb, var(--color-kraft-200) 40%, var(--color-paper));
}

.mb-kraft {
  background: color-mix(in srgb, var(--color-kraft-200) 46%, var(--color-paper));
  color: var(--color-ink-900);
  --sur: var(--color-navy-900);
  --sur-faible: var(--color-ink-500);
  --sur-tres-faible: var(--color-ink-500);
  --filet: var(--color-rule);
  --filet-fort: var(--color-navy-500);
  --fond: var(--color-paper);
  --fond-creux: color-mix(in srgb, var(--color-kraft-200) 62%, var(--color-paper));
}

/* Sur-titre technique : le seul style d'étiquette du site. */
.mb-sur {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-kraft-500);
}

.mb-sur::before {
  content: '';
  width: 22px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
  /* Le filet se trace au lieu d'apparaître : c'est le même geste que le sceau
     du préloader, répété à toutes les échelles du site. */
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 620ms var(--e-sortie) var(--retard, 0ms);
}

[data-vu] .mb-sur::before,
.mb-sur[data-vu]::before { transform: scaleX(1); }

.mb-sombre .mb-sur { color: var(--color-gold-300); }

/* --- Titres --------------------------------------------------------------
   L'axe de largeur d'Archivo donne aux grands titres leur présence de plaque
   gravée, sans recourir à une seconde fonte. */

/* ── Titres calés sur leur propre texte ───────────────────────────────────

   Tous les grands titres du site sont coupés à la main : chaque ligne vit dans
   son propre masque et se relève d'un seul bloc. Une ligne qui déborde et se
   coupe toute seule casse deux choses à la fois — la composition voulue, et la
   révélation, qui ne sait relever qu'une ligne.

   Plutôt que de rapetisser tous les titres du site jusqu'à ce que le plus long
   passe, chaque titre se dimensionne sur SA ligne la plus longue :

     `--n`  nombre de caractères de cette ligne, posé par le serveur — lui seul
            connaît le texte.
     `cqi`  1 % de la largeur du conteneur de mesure.

   Les deux constantes ci-dessous sont mesurées, pas estimées — sur un élément
   réel portant les styles calculés du titre, `white-space: nowrap`, et les
   lignes réellement écrites sur le site :

     H1  Archivo 700, axe de largeur à 112  →  0,545 em/caractère au pire
     H2  Archivo 600, largeur normale       →  0,472 em/caractère au pire

   L'axe de largeur compte : à `wdth 112`, Archivo est 12 % plus large qu'à sa
   largeur normale. Une mesure qui l'ignore sous-estime le H1 d'autant, et la
   ligne déborde exactement sur les écrans étroits.

   Une ligne de n caractères tient donc tant que la police reste sous
   100cqi / (0,545 × n) = 183cqi/n pour un H1, et 212cqi/n pour un H2. On retient
   176 et 200, soit 4 à 6 % de marge.

   Le repli est gratuit : un navigateur sans unités de conteneur ignore la
   déclaration et garde la taille de base déclarée juste au-dessus. */
.titre-mesure { container-type: inline-size; }

.mb-t1.titre-cale { font-size: clamp(1.55rem, calc(176cqi / var(--n, 22)), 4.6rem); }
.mb-t2.titre-cale { font-size: clamp(1.5rem, calc(200cqi / var(--n, 24)), 3.6rem); }

/* Titres issus du contenu, dont on ne maîtrise pas la longueur : la taille
   décroît par paliers. Un titre long à la taille d'un titre court remplit
   l'écran et repousse toute la page sous la ligne de flottaison. */
.mb-t1[data-echelle='xl'] { font-size: clamp(2.4rem, 1.2rem + 4.6vw, 4.6rem); }
.mb-t1[data-echelle='l'] { font-size: clamp(2.1rem, 1.2rem + 3.4vw, 3.7rem); }
.mb-t1[data-echelle='m'] { font-size: clamp(1.9rem, 1.2rem + 2.5vw, 3rem); line-height: 1.02; }
.mb-t1[data-echelle='s'] { font-size: clamp(1.7rem, 1.1rem + 1.9vw, 2.5rem); line-height: 1.06; }

.mb-t1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 112%;
  font-variation-settings: 'wdth' 112;
  font-size: clamp(2.6rem, 1.1rem + 6.4vw, 7rem);
  line-height: 0.94;
  letter-spacing: -0.03em;
  color: var(--sur, var(--color-navy-900));
  margin: 0;
}

.mb-t2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.9rem, 1.1rem + 2.9vw, 3.6rem);
  line-height: 1.04;
  letter-spacing: -0.022em;
  color: var(--sur, var(--color-navy-900));
  text-wrap: balance;
  margin: 0;
}

.mb-t3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.25rem, 1rem + 1.1vw, 1.85rem);
  line-height: 1.14;
  letter-spacing: -0.018em;
  color: var(--sur, var(--color-navy-900));
  text-wrap: balance;
  margin: 0;
}

.mb-t4 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.22rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--sur, var(--color-navy-900));
  margin: 0;
}

.mb-p {
  font-family: var(--font-sans);
  font-size: clamp(1rem, 0.96rem + 0.22vw, 1.15rem);
  line-height: 1.62;
  color: var(--sur-faible, var(--color-ink-500));
  max-width: 62ch;
  text-wrap: pretty;
  margin: 0;
}

.mb-p--court { max-width: 46ch; }
.mb-p--petit { font-size: 0.9375rem; line-height: 1.6; }

/* Deux respirations verticales nommées, pour ne pas avoir à écrire un style en
   ligne là où la valeur appartient à la maquette. */
.mt-20 { margin-top: 20px; }
.mt-titre { margin-top: 2px; }

/* Mot mis en valeur : le contour, jamais l'aplat. */
.mb-creux {
  color: transparent;
  -webkit-text-stroke: 1.4px var(--sur, var(--color-navy-900));
  paint-order: stroke fill;
}

.mb-or { color: var(--color-gold-500); }
.mb-sombre .mb-or { color: var(--color-gold-300); }

/* Toute valeur chiffrée en Plex Mono, chiffres tabulaires. Règle du design
   system : un nombre ne se lit pas comme un mot. */
.mb .val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'zero' 1;
}

/* =============================================================================
   2. PRIMITIVES DE RÉVÉLATION
   Cinq primitives. Toute la page s'anime avec ça, et rien d'autre.
   Le délai vient toujours de --retard, posé en ligne ou calculé par le script.
   ============================================================================= */

/* a. Masque de ligne — le texte monte de derrière un bord net. */
.masque {
  display: block;
  overflow: hidden;
  /* La descendante d'un « g » ou d'un « p » ne doit pas être rognée par le
     masque : on rend un peu de place en bas et on la reprend en marge. */
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}

.masque > * {
  display: block;
  transform: translateY(110%);
  transition: transform 1080ms var(--e-sortie) var(--retard, 0ms);
}

[data-vu] .masque > *,
.masque[data-vu] > * { transform: none; }

/* b. Montée simple — le cheval de bataille. */
.monte {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 900ms var(--e-sortie) var(--retard, 0ms),
    transform 900ms var(--e-sortie) var(--retard, 0ms);
}

[data-vu] .monte,
.monte[data-vu] { opacity: 1; transform: none; }

/* c. Volet — l'image se découvre derrière un rideau qui remonte, pendant que
   le cadrage se détend. Deux vitesses différentes : c'est l'écart entre les
   deux qui donne la profondeur. */
.volet {
  position: relative;
  overflow: hidden;
}

.volet::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--color-navy-900);
  transform-origin: bottom;
  transition: transform 1180ms var(--e-franc) var(--retard, 0ms);
  z-index: 2;
}

[data-vu] .volet::after,
.volet[data-vu]::after { transform: scaleY(0); }

.volet > img,
.volet > picture > img {
  transform: scale(1.16);
  transition: transform 1600ms var(--e-sortie) var(--retard, 0ms);
}

[data-vu] .volet > img,
[data-vu] .volet > picture > img,
.volet[data-vu] > img { transform: scale(1); }

/* d. Mots — révélation mot à mot. Le script découpe le texte et pose --rang.
   Réservé aux chapeaux : sur un paragraphe long, le décalage devient un défaut
   de lecture, pas un effet. */
.mots > i {
  display: inline-block;
  font-style: normal;
  opacity: 0;
  transform: translateY(0.5em);
  transition:
    opacity 720ms var(--e-sortie) calc(var(--retard, 0ms) + var(--rang, 0) * 26ms),
    transform 720ms var(--e-sortie) calc(var(--retard, 0ms) + var(--rang, 0) * 26ms);
}

[data-vu] .mots > i,
.mots[data-vu] > i { opacity: 1; transform: none; }

/* e. Filet — une règle horizontale qui se trace. */
.filet-anime {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 900ms var(--e-sortie) var(--retard, 0ms);
}

[data-vu] .filet-anime,
.filet-anime[data-vu] { transform: scaleX(1); }

/* Cascade automatique — le parent distribue le retard à ses enfants directs.
   Évite d'écrire un style en ligne par carte, et garde le pas de la cascade
   au même endroit que la maquette. */
[data-cascade] > * { --retard: calc(var(--rang, 0) * var(--pas-cascade, 110ms)); }
[data-cascade] > *:nth-child(1) { --rang: 0; }
[data-cascade] > *:nth-child(2) { --rang: 1; }
[data-cascade] > *:nth-child(3) { --rang: 2; }
[data-cascade] > *:nth-child(4) { --rang: 3; }
[data-cascade] > *:nth-child(5) { --rang: 4; }
[data-cascade] > *:nth-child(6) { --rang: 5; }
[data-cascade] > *:nth-child(7) { --rang: 6; }
[data-cascade] > *:nth-child(8) { --rang: 7; }
[data-cascade] > *:nth-child(9) { --rang: 8; }
[data-cascade] > *:nth-child(10) { --rang: 9; }
[data-cascade] > *:nth-child(11) { --rang: 10; }
[data-cascade] > *:nth-child(12) { --rang: 11; }

/* =============================================================================
   3. CALQUES D'ATMOSPHÈRE
   ============================================================================= */

/* Grain argentique. Il unifie photo et aplat, et retire au fond son côté
   « écran ». Volontairement très faible : on doit le remarquer en son absence,
   jamais en sa présence.

   La surface est calée au plus juste (12 % de débord pour un déplacement de
   1,5 %) : un calque fixe de la taille de l'écran est gratuit à composer, un
   calque de 2,2 fois l'écran ne l'est plus sur machine intégrée. */
.mb-grain {
  position: fixed;
  inset: -12%;
  z-index: 60;
  pointer-events: none;
  opacity: 0.042;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 700ms steps(3) infinite;
  will-change: transform;
}

@keyframes grain {
  0% { transform: translate3d(0, 0, 0); }
  33% { transform: translate3d(-1.4%, 1%, 0); }
  66% { transform: translate3d(1%, -1.4%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* Grille de dessin technique : quatre montants, comme un plan coté. Elle donne
   à la page son axe de lecture — tout se cale dessus. */
.mb-grille {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.mb-grille span {
  border-left: 1px solid var(--trait-sombre);
  opacity: 0.45;
}

.mb-grille span:first-child { border-left: none; }

@media (width < 60rem) {
  .mb-grille { display: none; }
}

/* Barre de progression de lecture. */
.mb-progres {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 100%;
  z-index: 70;
  background: var(--color-gold-500);
  transform: scaleX(var(--avance, 0));
  transform-origin: left;
  pointer-events: none;
}

/* Rideau de transition entre pages. Il couvre le seul moment du parcours où le
   chargement se voit : le passage de la vitrine à l'application React. */
.mb-rideau {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--color-navy-900);
  transform: translateY(100%);
  pointer-events: none;
  display: grid;
  place-items: center;
}

.mb-rideau[data-ferme] {
  transform: none;
  transition: transform 560ms var(--e-franc);
}

/* La marque au centre du rideau : la transition n'est pas un écran noir, c'est
   un plan de coupe. Elle n'apparaît qu'une fois le rideau en place. */
.mb-rideau .logo {
  --logo-l: clamp(200px, 34vw, 260px);
  opacity: 0;
  transform: translateY(8px);
}

.mb-rideau[data-ferme] .logo {
  opacity: 1;
  transform: none;
  transition: opacity 300ms var(--e-doux) 320ms, transform 460ms var(--e-sortie) 320ms;
}


/* =============================================================================
   4. PRÉLOADER — « LE PATRON »
   =============================================================================

   Une seule idée, tenue de bout en bout : avant d'être une boîte, un emballage
   est un dessin. Le patron de découpe est le premier document du métier — celui
   que tout le monde reconnaît dans cette maison, et que personne ne voit jamais
   sur un site web.

   Trois actes, deux secondes et demie :

     I.  LE TRAC É    Le patron se dessine en or sur le fond. Traits de coupe
                      pleins, traits de pli pointillés, encoches. C'est un vrai
                      patron de caisse américaine, pas une décoration.

     II. L'IMPRESSION Le nom se lève de derrière le pli central et se pose sur
                      le carton à plat — c'est exactement l'ordre des opérations
                      en atelier : on imprime la feuille avant de la plier.
                      La cote mesure la largeur du patron et porte l'année.

     III. L'OUVERTURE Le dessin se retire, le fond se sépare en deux le long du
                      pli central, et le site monte de derrière — déjà en place,
                      simplement révélé.

   Ni pourcentage, ni compteur, ni barre de chargement. Ce sont des indicateurs
   de patience : ils ne disent au visiteur qu'une chose, c'est qu'il attend.

   Tout est en `transform`, `opacity` et `stroke-dashoffset` — les trois seules
   propriétés qu'un navigateur anime sans jamais repasser par la mise en page.
   ============================================================================= */

/* Le conteneur n'a PAS de fond : ce sont les deux moitiés qui font l'opacité,
   et elles se recouvrent d'un demi-pour-cent pour qu'aucun liseré n'apparaisse
   au pli. Un fond ici resterait en place pendant que les moitiés s'écartent —
   on verrait le trait d'or se briser sur du navy, et rien s'ouvrir derrière. */
.pre {
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow: hidden;
}

.pre[data-fini] { display: none; }

/* --- Les deux moitiés du fond --------------------------------------------
   Elles se séparent le long du pli central. Une translation, pas une rotation :
   un rabat qui bascule à 84° laisse deux bandes fines et grises en fin de
   course, et on voit le truc. Deux plans qui s'écartent, on ne voit que
   l'ouverture. */

.pre-moitie {
  position: absolute;
  left: -1px;
  right: -1px;
  height: 50.5%; /* un demi-pixel de recouvrement : aucun liseré au pli */
  background: var(--color-navy-900);
  will-change: transform;
}

.pre-moitie--haut { top: 0; }
.pre-moitie--bas { bottom: 0; }

.pre[data-sortie] .pre-moitie {
  transition: transform 900ms cubic-bezier(0.72, 0, 0.16, 1) 170ms;
}

.pre[data-sortie] .pre-moitie--haut { transform: translate3d(0, -100%, 0); }
.pre[data-sortie] .pre-moitie--bas { transform: translate3d(0, 100%, 0); }

/* Le pli qui cède : un trait d'or sur la ligne de séparation, qui s'allume au
   moment de la rupture puis s'efface avec l'écartement. C'est ce détail qui
   fait lire l'ouverture comme un sceau qu'on brise. */
.pre-pli {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  z-index: 3;
  background: linear-gradient(
    90deg,
    transparent,
    var(--color-gold-500) 22%,
    var(--color-gold-300) 50%,
    var(--color-gold-500) 78%,
    transparent
  );
  transform: scaleX(0);
  opacity: 0;
}

.pre[data-sortie] .pre-pli {
  animation: pre-pli 820ms cubic-bezier(0.72, 0, 0.16, 1) 60ms forwards;
}

@keyframes pre-pli {
  0% { transform: scaleX(0); opacity: 0; }
  26% { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

/* --- La scène ------------------------------------------------------------- */

.pre-scene {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(26px, 4vh, 44px);
  padding: 24px;
  text-align: center;
}

/* À la sortie, le dessin recule d'un souffle avant que le fond ne s'ouvre.
   Sans ce retrait, le nom reste plaqué sur les deux moitiés qui s'écartent et
   se fait couper en deux. */
.pre[data-sortie] .pre-scene {
  opacity: 0;
  transform: scale(0.97);
  transition: opacity 260ms var(--e-doux), transform 520ms var(--e-sortie);
}

/* --- Acte I : le patron --------------------------------------------------- */

.pre-plan {
  position: relative;
  width: min(560px, 88vw);
  aspect-ratio: 560 / 340;
  /* Le patron mesure le nom : c'est la largeur du dessin qui décide de la
     taille de la typographie, jamais l'inverse. Un nom plus large que la
     feuille sur laquelle il est censé être imprimé ruine l'idée entière. */
  container-type: inline-size;
}

.pre-plan svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Traits de coupe : pleins, ils se tracent. `pathLength="1"` normalise la
   longueur de chaque tracé, ce qui permet d'écrire un seul jeu de valeurs de
   pointillé pour des segments de longueurs très différentes. */
.pre-coupe {
  fill: none;
  stroke: var(--color-gold-500);
  stroke-width: 1.25;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: pre-tracer 900ms cubic-bezier(0.5, 0, 0.2, 1) both;
}

.pre-encoche {
  fill: none;
  stroke: var(--color-gold-500);
  stroke-width: 1.25;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: pre-tracer 420ms cubic-bezier(0.5, 0, 0.2, 1) both;
  animation-delay: calc(560ms + var(--rang, 0) * 45ms);
}

@keyframes pre-tracer {
  to { stroke-dashoffset: 0; }
}

/* Traits de pli : pointillés. Ils ne peuvent pas se tracer par pointillé — la
   propriété est déjà prise — alors ils s'étirent depuis leur milieu. */
.pre-pli-trait {
  fill: none;
  stroke: color-mix(in srgb, var(--color-gold-500) 52%, transparent);
  stroke-width: 1;
  stroke-dasharray: 5 5;
  transform-box: fill-box;
  transform-origin: center;
  animation: pre-etirer 620ms var(--e-sortie) both;
  animation-delay: calc(360ms + var(--rang, 0) * 60ms);
}

.pre-pli-trait--h { transform: scaleX(0); }
.pre-pli-trait--v { transform: scaleY(0); }

@keyframes pre-etirer {
  to { transform: none; }
}

/* Le patron s'estompe une fois le nom posé : c'est le nom qu'on doit lire, pas
   le dessin. Il reste présent, en fond, comme l'encre sous l'impression. */
.pre-plan svg {
  animation: pre-estomper 700ms var(--e-doux) 1350ms both;
}

@keyframes pre-estomper {
  from { opacity: 1; }
  to { opacity: 0.34; }
}

/* --- Acte II : l'impression ----------------------------------------------- */

.pre-impression {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* MAREMBAL en Archivo 700 largeur 112, interlettré à 0,15 em, occupe 10,3 fois
   sa taille de police — mesuré au rendu, pas estimé.

   La référence n'est pas la largeur du cadre mais celle du PATRON, qui n'en
   occupe que 82 % (460 sur 560). Le nom doit lui-même tenir dans 82 % du
   patron pour garder ses marges d'impression :

       taille = 0,82 × 0,82 × largeurCadre / 10,3 ≈ 6,5 cqi                */
.pre-mot {
  display: flex;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 112%;
  font-variation-settings: 'wdth' 112;
  font-size: max(1.15rem, 6.5cqi);
  line-height: 1;
  letter-spacing: 0.15em;
  /* Compense l'interlettrage à droite : le mot reste optiquement centré. */
  text-indent: 0.15em;
  color: var(--color-paper);
}

/* Chaque lettre porte son propre masque : elle se lève de derrière le pli, elle
   n'apparaît pas. C'est une translation, jamais un fondu. */
.pre-l {
  display: inline-block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
}

.pre-l i {
  display: inline-block;
  font-style: normal;
  transform: translateY(106%);
  animation: pre-lettre 900ms var(--e-sortie) both;
  animation-delay: calc(560ms + var(--rang) * 42ms);
}

@keyframes pre-lettre {
  to { transform: none; }
}

/* Le sceau : il sépare le nom de la promesse. */
.pre-sceau {
  width: min(300px, 54vw);
  height: 1px;
  margin: clamp(16px, 2.4vh, 26px) 0 clamp(14px, 2vh, 22px);
  background: linear-gradient(
    90deg,
    transparent,
    var(--color-gold-500) 20%,
    var(--color-gold-300) 50%,
    var(--color-gold-500) 80%,
    transparent
  );
  transform: scaleX(0);
  animation: pre-etirer 760ms var(--e-sortie) 980ms both;
}

.pre-slogan {
  margin: 0;
  max-width: 26ch;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.85rem, 0.75rem + 0.45vw, 1.2rem);
  line-height: 1.3;
  text-wrap: balance;
  color: var(--color-gold-300);
  opacity: 0;
  animation: pre-monte 700ms var(--e-sortie) 1200ms both;
}

@keyframes pre-monte {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* --- La cote -------------------------------------------------------------
   Une vraie ligne de cote, comme sur un plan : deux repères d'extrémité, un
   trait qui se mesure, et la valeur posée dessus. Ici la valeur est l'année de
   fondation — le seul chiffre que cette maison ait à donner d'entrée.

   Elle est un élément de flux dans une colonne centrée, pas un absolu décalé de
   -50 % : une animation qui termine sur `transform: none` effacerait ce
   décalage et la ligne partirait sur le côté. Le centrage tient à la mise en
   page, jamais à une transformation. */

.pre-cote {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  opacity: 0;
  animation: pre-monte 620ms var(--e-sortie) 1400ms both;
}

.pre-cote-ligne {
  position: relative;
  display: flex;
  align-items: center;
  width: min(280px, 56vw);
  height: 9px;
}

/* Les deux repères d'extrémité. */
.pre-cote-ligne::before,
.pre-cote-ligne::after {
  content: '';
  position: absolute;
  top: 0;
  width: 1px;
  height: 9px;
  background: color-mix(in srgb, var(--color-paper) 34%, transparent);
}

.pre-cote-ligne::before { left: 0; }
.pre-cote-ligne::after { right: 0; }

/* Le trait qui se mesure, d'un repère à l'autre. */
.pre-cote-ligne i {
  display: block;
  width: 100%;
  height: 1px;
  background: var(--color-gold-500);
  transform: scaleX(0);
  transform-origin: left;
  animation: pre-etirer 900ms var(--e-doux) 1520ms both;
}

.pre-cote-valeur {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--voile-faible);
}

.pre-cote-valeur .val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  color: var(--color-paper);
}

.pre-pt {
  width: 3px;
  height: 3px;
  background: var(--color-gold-500);
  border-radius: 50%;
}

/* --- Passer --------------------------------------------------------------- */

.pre-passer {
  position: absolute;
  right: clamp(20px, 4vw, 48px);
  bottom: clamp(20px, 4vh, 44px);
  z-index: 4;
  padding: 9px 17px;
  border: 1px solid var(--trait-clair);
  border-radius: var(--radius-controle, 6px);
  background: transparent;
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--voile);
  cursor: pointer;
  opacity: 0;
  animation: pre-monte 500ms var(--e-sortie) 1500ms both;
  transition: color 160ms, background-color 160ms, border-color 160ms;
}

.pre-passer:hover {
  background: var(--color-gold-500);
  border-color: var(--color-gold-500);
  color: var(--color-navy-900);
}

.pre[data-sortie] .pre-passer {
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms;
}

/* --- Le site derrière ----------------------------------------------------
   L'ouverture ne peut pas être seulement l'affaire du rideau. Tant que la page
   reste rigoureusement immobile derrière, on lit « un cache se retire d'une
   image fixe » — pas « ça s'ouvre ». Il suffit que le contenu monte d'un
   quarante-cinquième de sa taille pour que les deux gestes n'en fassent plus
   qu'un.

   La condition est lue dans le DOM par `:has()`, jamais posée par le script :
   c'est React qui possède ces éléments, et rien ne doit y être écrit avant
   l'hydratation. */

.mb:has(.pre:not([data-fini])) main {
  transform: scale(1.045);
  opacity: 0;
}

.mb:has(.pre:not([data-fini])) .mb-nav {
  opacity: 0;
}

.mb:has(.pre[data-sortie]) main {
  transform: none;
  opacity: 1;
  transition:
    transform 1150ms cubic-bezier(0.16, 1, 0.3, 1) 150ms,
    opacity 700ms var(--e-doux) 150ms;
}

.mb:has(.pre[data-sortie]) .mb-nav {
  opacity: 1;
  transition: opacity 620ms var(--e-doux) 480ms;
}


/* =============================================================================
   5. NAVIGATION
   ============================================================================= */

/* La barre est un calque fixe, plein écran ; son CONTENU est calé sur la même
   grille que la page. Sans ce conteneur intérieur, le logo colle au bord de
   l'écran au-delà de 1440 px pendant que le contenu reste centré — et l'axe de
   lecture, qui est toute la tenue de cette maquette, se casse. */
.mb-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  transition:
    transform 520ms var(--e-sortie),
    background-color 380ms var(--e-doux),
    box-shadow 380ms var(--e-doux);
}

.mb-nav-inner {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
  height: var(--h-barre, 78px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(16px, 3vw, 40px);
}

/* Verre : le fond n'apparaît qu'une fois décollé du hero. Au repos la barre
   flotte au-dessus de l'image, sans filet ni voile — c'est ce qui laisse au
   grand titre toute sa hauteur. Sur les pages sans hero, le serveur pose
   directement `data-solide`.

   Le filet est un box-shadow et non une bordure : une bordure ajoute un pixel à
   la hauteur de l'élément, donc décale son contenu au moment précis où elle
   apparaît. L'ombre, elle, ne prend pas de place. */
.mb-nav[data-colle],
.mb-nav[data-solide] {
  background: color-mix(in srgb, var(--color-paper) 82%, transparent);
  backdrop-filter: blur(18px) saturate(1.8);
  -webkit-backdrop-filter: blur(18px) saturate(1.8);
  box-shadow: 0 1px 0 0 var(--color-rule);
}

/* La nav se retire au défilement descendant, revient au premier geste vers le
   haut. Jamais quand un menu est ouvert : le script s'en assure. */
.mb-nav[data-cache] { transform: translateY(-100%); }

/* Panneau ouvert : la barre bascule en sombre et se fond dans le méga-menu qui
   descend derrière elle. Sans cela, le verre clair laisse le logo navy sur le
   fond navy du panneau — c'est-à-dire invisible. */
.mb-nav[data-panneau] {
  background: var(--color-navy-900);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}

/* --- Logo -----------------------------------------------------------------
   Le fichier de marque, servi à la taille où il est vu.

   `--logo-l` est la largeur d'affichage, et la seule chose qu'un appelant ait
   à décider. La hauteur suit le rapport du fichier, réservée par les attributs
   `width`/`height` de la balise : la barre ne saute pas d'un pixel entre le
   HTML et l'arrivée de l'image.

   Deux encres. La variante `--auto` les empile et fond de l'une à l'autre —
   c'est la seule façon de suivre l'inversion de la barre quand un méga-menu
   s'ouvre sans qu'un script ait à réécrire un `src`, ce qui provoquerait un
   clignotement le temps du chargement. */

.logo {
  display: block;
  width: var(--logo-l, 148px);
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}

.logo--auto {
  position: relative;
  display: block;
  /* La hauteur vient de l'exemplaire en flux ; celui du dessus est absolu. */
  line-height: 0;
}

.logo--auto .logo-i {
  display: block;
  width: 100%;
  height: auto;
}

.logo--auto .logo-i--clair {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 320ms var(--e-doux);
}

.mb-logo {
  display: flex;
  align-items: center;
  line-height: 1;
  text-decoration: none;
  flex: 0 0 auto;
  /* Le logo s'enfonce à peine au clic — le seul retour tactile d'un lien qui
     ne change pas de couleur. */
  transition: transform 260ms var(--e-sortie);
}

.mb-logo:active { transform: scale(0.975); }

.mb-logo .logo--auto {
  width: clamp(122px, 12vw, 152px);
}

/* Barre inversée : l'encre papier passe devant. Les deux fichiers sont déjà
   chargés, la bascule ne coûte qu'une opacité. */
.mb-nav[data-panneau] .mb-logo .logo-i--sombre { opacity: 0; }
.mb-nav[data-panneau] .mb-logo .logo-i--clair { opacity: 1; }

.mb-nav[data-panneau] .mb-logo .logo-i--sombre {
  transition: opacity 320ms var(--e-doux);
}

/* Le logo du pied de page — encre papier, sur le navy du bloc de clôture. */
.mb-pied-logo { --logo-l: clamp(180px, 18vw, 220px); }

/* --- Liens --------------------------------------------------------------- */

.mb-liens {
  display: flex;
  align-items: center;
  gap: 2px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Pastille au survol plutôt qu'un simple soulignement : la cible est plus
   grande, le retour plus franc, et le trait d'or reste disponible pour dire
   « vous êtes ici » sans que les deux signaux se confondent. */
.mb-lien {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  border: none;
  border-radius: var(--radius-controle, 6px);
  background: transparent;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.005em;
  color: var(--color-navy-900);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 240ms var(--e-doux), color 240ms var(--e-doux);
}

.mb-lien:hover,
.mb-lien[aria-expanded='true'] {
  background: color-mix(in srgb, var(--color-navy-900) 6%, transparent);
}

/* Page courante : un trait d'or court sous le libellé. Il reste en place, et
   ne bouge pas au survol — c'est un repère, pas une réaction. */
.mb-lien[data-courant]::after {
  content: '';
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 4px;
  height: 1.5px;
  border-radius: 1px;
  background: var(--color-gold-500);
}

.mb-lien svg {
  width: 8px;
  height: 5px;
  opacity: 0.5;
  transition: transform 300ms var(--e-sortie), opacity 240ms var(--e-doux);
}

.mb-lien:hover svg { opacity: 1; }
.mb-lien[aria-expanded='true'] svg { transform: rotate(180deg); opacity: 1; }

/* --- Inversion quand un panneau est ouvert -------------------------------- */

.mb-nav[data-panneau] .mb-lien { color: var(--color-paper); }
.mb-nav[data-panneau] .mb-lien:hover,
.mb-nav[data-panneau] .mb-lien[aria-expanded='true'] {
  background: color-mix(in srgb, var(--color-paper) 12%, transparent);
}
.mb-nav[data-panneau] .mb-tel { color: var(--voile); }
.mb-nav[data-panneau] .mb-tel:hover { color: var(--color-paper); }
.mb-nav[data-panneau] .mb-burger { border-color: var(--color-navy-500); }
.mb-nav[data-panneau] .mb-burger i { background: var(--color-paper); }

/* --- Bloc de droite ------------------------------------------------------- */

.mb-nav-droite {
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.4vw, 18px);
  flex: 0 0 auto;
}

.mb-tel {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: var(--color-ink-500);
  text-decoration: none;
  transition: color 200ms var(--e-doux);
  white-space: nowrap;
}

.mb-tel:hover { color: var(--color-navy-900); }

/* Sous 72 rem le téléphone sort de la barre : il reste dans le menu plein
   écran et dans le pied de page, et le bouton de cotation prend le relais. */
@media (width < 72rem) {
  .mb-nav .mb-tel { display: none; }
}

/* --- Bouton hamburger ----------------------------------------------------- */

.mb-burger {
  display: none;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-technique, 2px);
  background: transparent;
  cursor: pointer;
  position: relative;
}

.mb-burger i {
  position: absolute;
  left: 12px;
  right: 12px;
  height: 1.5px;
  background: var(--color-navy-900);
  transition: transform 420ms var(--e-sortie), opacity 200ms;
}

.mb-burger i:nth-child(1) { top: 17px; }
.mb-burger i:nth-child(2) { bottom: 17px; }

.mb-burger[aria-expanded='true'] i:nth-child(1) { transform: translateY(4.5px) rotate(45deg); }
.mb-burger[aria-expanded='true'] i:nth-child(2) { transform: translateY(-4.5px) rotate(-45deg); }

/* =============================================================================
   5b. MÉGA-MENU
   Il descend derrière la barre, en clip-path : rien ne se redimensionne, rien
   ne repousse la page. Le contenu monte d'un cran par colonne.
   ============================================================================= */

.mb-mega {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 49;
  padding: calc(var(--h-barre, 78px) + 30px) var(--gouttiere) 44px;
  background: var(--color-navy-900);
  color: var(--color-paper);

  /* Le contexte de couleurs est déclaré EN ENTIER.

     Déclarer `--sur` sans `--fond` laisse les composants qui lisent les deux —
     la carte, la plaque — piocher leur fond dans la valeur de repli, c'est-à-dire
     le papier : on obtient alors du texte papier sur fond papier, invisible, au
     milieu d'un panneau sombre. Un contexte de couleurs se pose complet ou pas
     du tout. */
  --sur: var(--color-paper);
  --sur-faible: var(--voile);
  --sur-tres-faible: var(--voile-faible);
  --filet: var(--color-navy-700);
  --filet-fort: var(--color-navy-500);
  --fond: var(--color-navy-900);
  --fond-creux: var(--color-navy-700);

  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition: clip-path 640ms var(--e-franc), visibility 0s linear 640ms;
  box-shadow: 0 32px 64px -32px rgb(0 0 0 / 0.6);
  max-height: 100dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.mb-mega[data-ouvert] {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path 640ms var(--e-franc), visibility 0s;
}

.mb-mega-inner {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
}

.mb-mega-grille {
  display: grid;
  gap: clamp(24px, 3vw, 48px);
  margin-top: 34px;
}

@media (width >= 60rem) {
  .mb-mega-grille { grid-template-columns: repeat(4, 1fr); }
}

/* Chaque colonne monte à son tour. Le retard est porté par --rang, posé dans
   le balisage : le CSS ne compte pas les enfants, il lit un rang. */
.mb-mega-col {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 620ms var(--e-sortie),
    transform 620ms var(--e-sortie);
}

.mb-mega[data-ouvert] .mb-mega-col {
  opacity: 1;
  transform: none;
  transition-delay: calc(140ms + var(--rang, 0) * 70ms);
}

.mb-mega-tete {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--filet);
  text-decoration: none;
}

.mb-mega-tete i {
  display: block;
  width: 3px;
  height: 15px;
  flex: 0 0 auto;
  transform: translateY(2px);
  background: var(--teinte, var(--color-gold-500));
  transition: transform 300ms var(--e-ressort);
}

.mb-mega-tete:hover i { transform: translateY(2px) scaleY(1.4); }

.mb-mega-tete b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.015em;
  color: var(--color-paper);
  transition: color 200ms var(--e-doux);
}

.mb-mega-tete:hover b { color: var(--color-gold-300); }

.mb-mega-tete span {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  color: var(--voile-faible);
}

.mb-mega-liste {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 2px;
}

.mb-mega-liste a {
  display: block;
  padding: 9px 10px 9px 0;
  border-radius: var(--radius-technique, 2px);
  text-decoration: none;
  transition: padding-left 300ms var(--e-sortie), background-color 300ms var(--e-doux);
}

.mb-mega-liste a:hover {
  padding-left: 10px;
  background: var(--color-navy-700);
}

.mb-mega-liste b {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-paper);
  transition: color 200ms var(--e-doux);
}

.mb-mega-liste a:hover b { color: var(--color-gold-300); }

.mb-mega-liste span {
  display: block;
  margin-top: 2px;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--voile-faible);
}

/* --- Recherche produit ---------------------------------------------------- */

.mb-cherche { max-width: 42rem; }

.mb-cherche label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--voile-faible);
}

.mb-cherche-champ {
  position: relative;
  margin-top: 10px;
}

.mb-cherche input {
  width: 100%;
  padding: 14px 46px 14px 16px;
  border: 1px solid var(--color-navy-500);
  border-radius: var(--radius-controle, 6px);
  background: var(--color-navy-700);
  font-family: var(--font-sans);
  font-size: 1rem;
  color: var(--color-paper);
  transition: border-color 260ms var(--e-doux), background-color 260ms var(--e-doux);
  -webkit-appearance: none;
  appearance: none;
}

.mb-cherche input::placeholder { color: var(--voile-faible); }

.mb-cherche input:focus {
  outline: none;
  border-color: var(--color-gold-500);
  background: var(--color-navy-900);
}

.mb-cherche-champ svg {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--voile-faible);
  pointer-events: none;
}

/* Résultats. La hauteur n'est jamais animée : on montre ou on cache. Animer une
   hauteur, c'est repeindre la page à chaque frappe. */
.mb-resultats {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: none;
  border: 1px solid var(--color-navy-500);
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
}

.mb-resultats[data-ouvert] { display: block; }

.mb-resultats li + li { border-top: 1px solid var(--color-navy-700); }

.mb-resultats a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  text-decoration: none;
  transition: background-color 200ms var(--e-doux);
}

.mb-resultats a:hover,
.mb-resultats a:focus-visible { background: var(--color-navy-700); }

.mb-resultats i {
  display: block;
  width: 3px;
  height: 16px;
  flex: 0 0 auto;
  background: var(--teinte, var(--color-gold-500));
}

.mb-resultats b {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-paper);
}

.mb-resultats span {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  color: var(--voile-faible);
}

.mb-vide {
  display: none;
  margin: 12px 0 0;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--voile);
}

.mb-vide[data-ouvert] { display: block; }
.mb-vide a { color: var(--color-gold-300); text-underline-offset: 4px; }

/* --- Menu plein écran (mobile) -------------------------------------------- */

.mb-menu {
  position: fixed;
  inset: 0;
  z-index: 45;
  background: var(--color-navy-900);
  display: flex;
  flex-direction: column;
  padding: calc(var(--h-barre, 78px) + 24px) var(--gouttiere) 40px;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 720ms var(--e-franc), visibility 0s linear 720ms;
  visibility: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.mb-menu[data-ouvert] {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path 720ms var(--e-franc), visibility 0s;
}

.mb-menu ul { list-style: none; margin: 0; padding: 0; }
.mb-menu > ul > li { overflow: hidden; }

.mb-menu > ul > li > a {
  display: block;
  padding-block: 9px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.7rem, 1.2rem + 3.4vw, 3rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--color-paper);
  text-decoration: none;
  transform: translateY(110%);
  transition: transform 760ms var(--e-sortie) var(--retard, 0ms), color 200ms;
}

.mb-menu[data-ouvert] > ul > li > a { transform: none; }
.mb-menu > ul > li > a:hover { color: var(--color-gold-300); }

/* Sous-liste des produits dans le menu mobile : discrète, dépliée, sans
   accordéon. Un accordéon dans un menu plein écran ajoute un geste pour rien. */
.mb-menu-sous {
  display: grid;
  gap: 6px;
  margin: 4px 0 18px;
  padding-left: 2px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 600ms var(--e-sortie), transform 600ms var(--e-sortie);
  transition-delay: var(--retard, 0ms);
}

.mb-menu[data-ouvert] .mb-menu-sous { opacity: 1; transform: none; }

.mb-menu-sous a {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  color: var(--voile);
  text-decoration: none;
}

.mb-menu-sous a:hover { color: var(--color-gold-300); }

.mb-menu-pied {
  margin-top: auto;
  padding-top: 28px;
  border-top: 1px solid var(--color-navy-700);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  opacity: 0;
  transition: opacity 600ms var(--e-doux) 420ms;
}

.mb-menu[data-ouvert] .mb-menu-pied { opacity: 1; }

.mb-menu-pied a.mb-tel { color: var(--voile); font-size: 0.9375rem; }
.mb-menu-pied a.mb-tel:hover { color: var(--color-paper); }

@media (width < 60rem) {
  .mb-liens { display: none; }
  .mb-burger { display: block; }
  .mb-nav .mb-btn { display: none; }
  .mb-nav-droite { gap: 10px; }
  .mb-mega { display: none; }
  .mb { --h-barre: 68px; }
}

/* =============================================================================
   6. BOUTONS
   ============================================================================= */

.mb-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 15px 28px;
  border: none;
  border-radius: var(--radius-controle, 6px);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  background: var(--color-gold-500);
  color: var(--color-navy-900);
  transition: transform 320ms var(--e-sortie), color 300ms var(--e-doux);
  white-space: nowrap;
}

/* Remplissage qui monte au survol : la couleur vient du bas, comme une cuve. */
.mb-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-navy-900);
  transform: translateY(101%);
  transition: transform 520ms var(--e-franc);
}

.mb-btn:hover::before { transform: translateY(0); }
.mb-btn:hover { color: var(--color-paper); }

.mb-btn:active { transform: scale(0.98); }

.mb-btn svg { transition: transform 420ms var(--e-sortie); flex: 0 0 auto; }
.mb-btn:hover svg { transform: translateX(5px); }

/* Contour. Sur fond clair comme sur fond sombre : le trait lit --filet. */
.mb-btn--vide {
  background: transparent;
  color: var(--sur, var(--color-navy-900));
  box-shadow: inset 0 0 0 1px var(--filet, var(--color-rule));
}

.mb-btn--vide::before { background: var(--sur, var(--color-navy-900)); }
.mb-btn--vide:hover { color: var(--fond, var(--color-paper)); }

/* Or sur fond sombre : le remplissage vient en papier. */
.mb-btn--clair::before { background: var(--color-paper); }
.mb-btn--clair:hover { color: var(--color-navy-900); }

.mb-btn--petit { padding: 11px 20px; font-size: 0.875rem; }
.mb-btn--large { width: 100%; }

/* --- Lien fléché : la micro-action du site -------------------------------- */

.mb-fleche {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--color-gold-500);
  text-decoration: none;
  padding-block: 3px;
  position: relative;
}

.mb-sombre .mb-fleche,
.mb-mega .mb-fleche { color: var(--color-gold-300); }

.mb-fleche svg { transition: transform 420ms var(--e-sortie); }
.mb-fleche:hover svg { transform: translateX(5px); }

/* Le trait n'existe qu'au survol, et il part du texte, pas du bloc. */
.mb-fleche::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 420ms var(--e-sortie);
}

.mb-fleche:hover::after { transform: scaleX(1); transform-origin: left; }

/* =============================================================================
   7. LA PLAQUE
   =============================================================================
   LE composant du design system. Une plaque d'identification industrielle :
   code de pôle gravé dans l'angle, liseré de matière sur la tranche, trame de
   points, spécifications en monospace tabulaire.

   Elle existe en React pour l'application (components/plaque) et ici en CSS pur
   pour les pages de présentation. Même ADN, deux rendus, une seule maquette.
   ============================================================================= */

.plaque {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--fond, var(--color-paper));
  border: 1px solid var(--filet, var(--color-rule));
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
  text-decoration: none;
  transition:
    transform 620ms var(--e-sortie),
    border-color 420ms var(--e-doux),
    box-shadow 620ms var(--e-sortie);
}

/* Le liseré de matière, sur la tranche gauche. C'est le seul usage autorisé de
   la couleur de pôle par la charte : jamais un aplat, jamais un fond. */
.plaque::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--teinte, var(--color-gold-500));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 620ms var(--e-sortie) var(--retard, 0ms);
  z-index: 2;
}

[data-vu] .plaque::before,
.plaque[data-vu]::before { transform: scaleY(1); }

a.plaque:hover {
  transform: translateY(-4px);
  border-color: var(--filet-fort, var(--color-navy-500));
  box-shadow: var(--ombre-levee);
}

/* `flex: 1` absorbe la hauteur excédentaire : dans une rangée de plaques, les
   accroches ne font pas toutes le même nombre de lignes, et sans cela les
   grilles de spécifications se décalent de quelques pixels d'une plaque à
   l'autre. Alignées, elles se lisent en colonnes. */
.plaque-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex: 1;
  padding: 22px 24px;
  padding-left: 27px;
}

.plaque-tete h3,
.plaque-tete .plaque-titre {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.16rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--sur, var(--color-navy-900));
  transition: color 260ms var(--e-doux);
}

a.plaque:hover .plaque-titre,
a.plaque:hover h3 { color: var(--color-navy-500); }

.mb-sombre a.plaque:hover .plaque-titre,
.mb-sombre a.plaque:hover h3 { color: var(--color-gold-300); }

.plaque-tete p {
  margin: 8px 0 0;
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--sur-faible, var(--color-ink-500));
  max-width: 40ch;
}

/* Le code de pôle, gravé — une encoche assombrie, pas une pastille de couleur.

   La charte réserve la couleur de pôle au liseré de 3 px et à lui seul : jamais
   d'aplat. Un badge coloré ici mettrait quatre teintes différentes en
   concurrence sur une même grille de produits, et ferait lire la couleur comme
   une catégorie de statut plutôt que comme une matière.

   C'est aussi le rendu du même code dans la plaque React de l'application :
   les deux moitiés du projet gravent le code de la même façon. */
.plaque-code {
  flex: 0 0 auto;
  padding: 4px 9px;
  border-radius: var(--radius-technique, 2px);
  background: color-mix(in srgb, var(--color-ink-900) 6%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--color-ink-900) 12%, transparent);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sur-faible, var(--color-ink-500));
}

.mb-sombre .plaque-code {
  background: color-mix(in srgb, var(--color-paper) 10%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--color-paper) 16%, transparent);
}

.plaque-specs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  margin: 0;
  background: var(--filet, var(--color-rule));
  border-top: 1px solid var(--filet, var(--color-rule));
}

.plaque-specs--une { grid-template-columns: 1fr; }

.plaque-spec {
  background: var(--fond, var(--color-paper));
  padding: 14px 24px;
}

/* Nombre impair de spécifications : la dernière prend toute la largeur.
   Sans cela, la cellule manquante laisse voir le fond de la grille — un carré
   gris qu'on lit comme une donnée absente plutôt que comme un vide de
   composition. */
.plaque-spec:last-child:nth-child(odd) { grid-column: 1 / -1; }

.plaque-spec dt,
.plaque-spec .plaque-label {
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sur-faible, var(--color-ink-500));
}

.plaque-spec dd,
.plaque-spec .plaque-valeur {
  margin: 6px 0 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.9375rem;
  color: var(--sur, var(--color-navy-900));
}

/* La spécification clé : celle que l'acheteur cherche en premier. */
.plaque-spec[data-cle] {
  background: color-mix(in srgb, var(--color-gold-300) 15%, var(--fond, var(--color-paper)));
}

.mb-sombre .plaque-spec[data-cle] {
  background: color-mix(in srgb, var(--color-gold-500) 12%, var(--fond));
}

.plaque-pied {
  margin-top: auto;
  padding: 16px 24px;
  padding-left: 27px;
  border-top: 1px solid var(--filet, var(--color-rule));
}

/* Trame de points, en fond de la zone de titre. Très basse densité. */
.plaque--trame .plaque-tete {
  background-image: radial-gradient(var(--trait-sombre) 0.5px, transparent 0.5px);
  background-size: 4px 4px;
}

.mb-sombre .plaque--trame .plaque-tete {
  background-image: radial-gradient(var(--trait-clair) 0.5px, transparent 0.5px);
}

/* =============================================================================
   8. BLOCS PARTAGÉS
   ============================================================================= */

/* --- Fil d'Ariane --------------------------------------------------------- */

.mb-fil {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  color: var(--sur-faible, var(--color-ink-500));
}

.mb-fil a {
  color: inherit;
  text-decoration: none;
  transition: color 200ms var(--e-doux);
}

.mb-fil a:hover { color: var(--sur, var(--color-navy-900)); }

.mb-fil li:not(:last-child)::after {
  content: '/';
  margin-left: 8px;
  opacity: 0.5;
}

.mb-fil [aria-current] { color: var(--sur, var(--color-navy-900)); }

/* --- En-tête de section --------------------------------------------------- */

/* Deux colonnes explicites plutôt qu'une largeur en `ch`.

   Le `ch` se mesure sur le chiffre zéro, qui dans Archivo est plus large que la
   moyenne des lettres : une contrainte en `ch` est donc systématiquement plus
   serrée qu'elle n'en a l'air, et elle coupe les titres composés à la main.
   Une fraction de grille, elle, se raisonne à la règle et se vérifie. */
.mb-tete {
  display: grid;
  gap: clamp(20px, 3vw, 48px);
  align-items: end;
  padding-bottom: clamp(28px, 3.4vw, 52px);
  border-bottom: 1px solid var(--filet, var(--color-rule));
}

@media (width >= 60rem) {
  .mb-tete { grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.6fr); }
}

.mb-tete-titre { min-width: 0; }
.mb-tete .mb-t2 { margin-top: 18px; }
.mb-tete .mb-p { max-width: 44ch; }

/* --- Tableau technique ---------------------------------------------------- */

.mb-tableau-boite {
  margin-top: clamp(22px, 2.6vw, 34px);
  border: 1px solid var(--filet, var(--color-rule));
  border-radius: var(--radius-technique, 2px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background: var(--fond, var(--color-paper));
}

.mb-tableau {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  text-align: left;
}

.mb-tableau th {
  padding: 13px 18px;
  background: var(--fond-creux);
  border-bottom: 1px solid var(--filet, var(--color-rule));
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sur-faible, var(--color-ink-500));
  white-space: nowrap;
}

.mb-tableau td {
  padding: 13px 18px;
  border-bottom: 1px solid var(--filet, var(--color-rule));
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.875rem;
  color: var(--sur, var(--color-navy-900));
  vertical-align: baseline;
}

.mb-tableau tr:last-child td { border-bottom: none; }

/* La première colonne est un intitulé, pas une valeur : elle repasse en sans. */
.mb-tableau td:first-child {
  font-family: var(--font-sans);
  font-size: 0.875rem;
}

.mb-tableau tbody tr { transition: background-color 200ms var(--e-doux); }
.mb-tableau tbody tr:hover { background: var(--fond-creux); }

/* La colonne « le plus demandé » est la réponse que l'acheteur cherche : elle
   est la seule en or, et elle l'est sur toute la hauteur. */
.mb-tableau td[data-fort] { color: var(--color-navy-900); font-weight: 500; }
.mb-sombre .mb-tableau td[data-fort] { color: var(--color-gold-300); }

.mb-note {
  margin: 16px 0 0;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--sur-faible, var(--color-ink-500));
  max-width: 68ch;
}

/* --- Liste de spécifications en chips ------------------------------------- */

.mb-specs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mb-specs li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 13px;
  border: 1px solid var(--filet, var(--color-rule));
  border-radius: var(--radius-technique, 2px);
  transition: border-color 300ms var(--e-doux);
}

.mb-specs li:hover { border-color: var(--filet-fort); }

.mb-specs b {
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sur-tres-faible, var(--color-ink-500));
}

.mb-specs span {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: var(--sur, var(--color-navy-900));
}

/* --- Liste à puce carrée -------------------------------------------------- */

.mb-liste {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: grid;
  gap: 11px;
}

.mb-liste li {
  display: flex;
  gap: 13px;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--sur, var(--color-ink-900));
}

.mb-liste li::before {
  content: '';
  flex: 0 0 auto;
  width: 12px;
  height: 3px;
  margin-top: 0.6em;
  background: var(--teinte, var(--color-gold-500));
}

/* --- Définitions en colonnes ---------------------------------------------- */

.mb-dl {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 26px 32px;
  margin: 0;
  padding-top: 28px;
  border-top: 1px solid var(--filet, var(--color-rule));
}

.mb-dl dt {
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sur-tres-faible, var(--color-ink-500));
}

.mb-dl dd {
  margin: 9px 0 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.3rem, 1rem + 1.2vw, 1.9rem);
  line-height: 1.1;
  color: var(--sur, var(--color-navy-900));
}

.mb-dl dd.est-texte {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--sur-faible, var(--color-ink-500));
}

/* --- Encart d'avertissement ----------------------------------------------- */

.mb-encart {
  display: flex;
  gap: 14px;
  padding: 18px 20px;
  border: 1px solid var(--filet, var(--color-rule));
  border-left: 3px solid var(--color-gold-500);
  border-radius: var(--radius-technique, 2px);
  background: var(--fond-creux);
}

.mb-encart p {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--sur-faible, var(--color-ink-500));
  max-width: 68ch;
}

.mb-encart b { color: var(--sur, var(--color-navy-900)); font-weight: 500; }

/* --- Figure --------------------------------------------------------------- */

.mb-figure {
  position: relative;
  margin: 0;
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
  background: var(--color-kraft-200);
}

.mb-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mb-figure figcaption {
  margin-top: 12px;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--sur-faible, var(--color-ink-500));
}

/* Plaque de cote posée sur une image, comme un repère de plan coté. */
.mb-cote {
  position: absolute;
  right: 0;
  bottom: 26px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 14px 18px;
  margin: 0;
  background: var(--color-navy-900);
  color: var(--color-paper);
  border-radius: var(--radius-technique, 2px) 0 0 var(--radius-technique, 2px);
}

.mb-cote b {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1;
  color: var(--color-gold-300);
}

.mb-cote span {
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--voile);
}

/* --- Appel final ---------------------------------------------------------- */

.mb-final {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 38px;
}

/* La base de 32rem laisse le bloc de texte se replier sous le bouton en dessous
   d'environ 62 rem, plutôt que de rétrécir jusqu'à l'illisible. */
.mb-final-texte { flex: 1 1 32rem; min-width: 0; }
.mb-final .mb-p { max-width: 52ch; margin-top: 20px; }

/* =============================================================================
   9. PIED DE PAGE
   ============================================================================= */

.mb-pied {
  background: var(--color-navy-900);
  color: var(--voile);
  --sur: var(--color-paper);
  --sur-faible: var(--voile);
  --filet: var(--color-navy-700);
  padding-block: clamp(48px, 6vw, 84px) 34px;
  border-top: 1px solid var(--color-navy-700);
  position: relative;
  z-index: 2;
}

.mb-pied-grille {
  display: grid;
  gap: 38px;
}

@media (width >= 48rem) {
  .mb-pied-grille { grid-template-columns: 1.5fr 1fr 1fr 1fr; }
}

.mb-pied-marque > span {
  display: block;
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-kraft-500);
}

.mb-pied-marque address {
  margin-top: 20px;
  font-style: normal;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.65;
}

.mb-pied-marque a { color: var(--voile); text-decoration: none; transition: color 200ms; }
.mb-pied-marque a:hover { color: var(--color-gold-300); }

.mb-pied-col h3 {
  margin: 0 0 16px;
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--voile-faible);
}

.mb-pied-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.mb-pied-col a {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  color: var(--voile);
  text-decoration: none;
  transition: color 220ms var(--e-doux);
}

.mb-pied-col a:hover { color: var(--color-paper); }

.mb-pied-bas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: clamp(40px, 5vw, 66px);
  padding-top: 24px;
  border-top: 1px solid var(--color-navy-700);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--voile-faible);
}

/* =============================================================================
   10. ACCUEIL
   ============================================================================= */

/* --- Hero ----------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: 132px;
  padding-bottom: clamp(80px, 10vh, 140px);
  overflow: hidden;
}

.hero-grille {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(40px, 5vw, 72px);
  align-items: center;
  width: 100%;
}

@media (width >= 60rem) {
  .hero-grille { grid-template-columns: 1.04fr 0.96fr; }
}

.hero-titre { margin: 22px 0 0; }
.hero-titre em { font-style: normal; display: block; }

.hero-p { margin-top: 30px; max-width: 54ch; }

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 38px;
}

/* Colonne image : ratio 4/5, volet de révélation, parallaxe douce. */
.hero-visuel {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-technique, 2px);
  background: var(--color-kraft-200);
}

.hero-visuel img { width: 100%; height: 100%; object-fit: cover; }

/* Rail vertical : la mention du lieu, à la verticale, dans la marge.
   Il n'apparaît qu'au-delà de 100rem — en dessous, la marge extérieure n'existe
   pas et le rail viendrait mordre sur le texte. Une décoration qui chevauche le
   contenu n'est pas une décoration, c'est un défaut. */
.hero-rail { display: none; }

@media (width >= 100rem) {
  .hero-rail {
    position: absolute;
    left: max(20px, calc((100vw - var(--largeur)) / 2 - 34px));
    bottom: clamp(80px, 12vh, 150px);
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0;
    transform: rotate(180deg);
    writing-mode: vertical-rl;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 0.6875rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--color-ink-500);
  }

  .hero-rail::after {
    content: '';
    width: 1px;
    height: 64px;
    background: linear-gradient(to bottom, var(--color-kraft-500), transparent);
  }
}

/* Invite au défilement. Elle disparaît dès que la page a bougé : une invite qui
   reste après le geste qu'elle demandait est un défaut d'attention. */
.hero-defile {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-ink-500);
  transition: opacity 420ms var(--e-doux), transform 620ms var(--e-sortie);
}

.hero-defile[data-parti] {
  opacity: 0;
  transform: translateX(-50%) translateY(14px);
  pointer-events: none;
}

.hero-defile i {
  width: 1px;
  height: 46px;
  background: var(--color-rule);
  position: relative;
  overflow: hidden;
}

.hero-defile i::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--color-navy-900);
  animation: defile 2000ms var(--e-doux) infinite;
}

@keyframes defile {
  0% { transform: translateY(-100%); }
  60%, 100% { transform: translateY(100%); }
}

@media (width < 60rem) { .hero-defile { display: none; } }

/* --- Barre de preuve ------------------------------------------------------ */

.preuves {
  border-block: 1px solid var(--color-rule);
  background: var(--color-paper);
  position: relative;
  z-index: 2;
}

.preuves-l {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--color-rule);
}

@media (width >= 48rem) {
  .preuves-l { grid-template-columns: repeat(5, 1fr); }
}

.preuve {
  background: var(--color-paper);
  padding: clamp(26px, 3.4vw, 44px) clamp(16px, 2vw, 28px);
  text-align: center;
  position: relative;
  overflow: hidden;
}

/* Le survol allume la cellule par le bas : le geste de la cuve du bouton,
   répété à l'échelle du tableau de bord. */
.preuve::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--color-gold-500);
  transform: scaleX(0);
  transition: transform 520ms var(--e-sortie);
}

.preuve:hover::after { transform: scaleX(1); }

.preuve b {
  display: block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.7rem, 1.1rem + 2.1vw, 3rem);
  font-weight: 400;
  line-height: 1;
  color: var(--color-navy-900);
}

.preuve span {
  display: block;
  margin-top: 11px;
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-ink-500);
}

/* --- Bandeau défilant ----------------------------------------------------- */

.ruban {
  overflow: hidden;
  background: var(--color-navy-900);
  padding-block: clamp(20px, 2.4vw, 34px);
  border-block: 1px solid var(--color-navy-700);
  position: relative;
  z-index: 2;
}

.ruban-piste {
  display: flex;
  width: max-content;
  animation: ruban 46s linear infinite;
  will-change: transform;
}

.ruban:hover .ruban-piste { animation-play-state: paused; }

@keyframes ruban {
  to { transform: translate3d(-50%, 0, 0); }
}

.ruban-piste > span {
  display: flex;
  align-items: center;
  gap: clamp(28px, 4vw, 62px);
  padding-right: clamp(28px, 4vw, 62px);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.4rem, 0.9rem + 2vw, 2.6rem);
  letter-spacing: -0.01em;
  color: transparent;
  -webkit-text-stroke: 1px color-mix(in srgb, var(--color-paper) 42%, transparent);
  white-space: nowrap;
}

.ruban-piste b {
  font-weight: 600;
  color: var(--color-gold-500);
  -webkit-text-stroke: 0;
}

.ruban-pt { color: var(--color-gold-500); -webkit-text-stroke: 0; }

/* --- Manifeste ------------------------------------------------------------
   Le titre est coupé à la main, ligne par ligne : c'est une composition, pas un
   paragraphe. Il faut donc lui garantir la largeur de ses lignes, sinon le
   masque de révélation révèle deux lignes au lieu d'une et la coupe éditoriale
   part en morceaux. D'où la taille indexée sur la largeur, et pas l'inverse. */

/* La taille est calée sur la largeur de la colonne, et pas l'inverse : les
   trois lignes du titre sont coupées à la main, et une quatrième ligne née d'un
   retour automatique détruirait à la fois la composition et le masque de
   révélation, qui ne sait relever qu'une ligne à la fois. La borne haute a été
   mesurée sur la ligne la plus longue, pas estimée. */
.manifeste-t {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.3rem, 0.62rem + 2.6vw, 2.7rem);
  line-height: 1.16;
  letter-spacing: -0.022em;
  color: var(--color-navy-900);
  margin: 22px 0 0;
}

/* Le portrait tient la colonne de droite. Sans lui, le bloc s'arrête au milieu
   de la page et le vide se lit comme un oubli plutôt que comme une respiration.
   Il dit aussi la troisième affirmation du manifeste — la maison est restée
   familiale — mieux que le paragraphe qui la porte. */
/* Même règle que les ouvertures : le texte part du haut. Aligné en bas, le
   sur-titre « Le métier » se retrouvait décollé de son titre par la hauteur du
   portrait. */
.manifeste-haut {
  display: grid;
  gap: clamp(30px, 4vw, 64px);
  align-items: start;
}

@media (width >= 60rem) {
  .manifeste-haut { grid-template-columns: 1.3fr 0.7fr; }
}

.manifeste-portrait {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-technique, 2px);
  background: var(--color-kraft-200);
}

.manifeste-portrait img { width: 100%; height: 100%; object-fit: cover; }

.manifeste-portrait figcaption {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 3;
  margin: 0;
  padding: 11px 16px;
  background: var(--color-navy-900);
  color: var(--voile);
  border-radius: 0 var(--radius-technique, 2px) 0 0;
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.manifeste-bas {
  display: grid;
  gap: clamp(30px, 4vw, 64px);
  margin-top: clamp(38px, 5vw, 72px);
}

@media (width >= 60rem) {
  .manifeste-bas { grid-template-columns: repeat(3, 1fr); }
}

.manifeste-item h3 {
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-kraft-500);
  margin: 0 0 12px;
}

.manifeste-item p {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--color-ink-500);
  margin: 0;
  max-width: 42ch;
}

/* Le numéro de l'item, en filigrane. Il donne au bloc son rythme de fiche. */
.manifeste-item {
  position: relative;
  padding-top: 26px;
  border-top: 1px solid var(--color-rule);
}

.manifeste-item::before {
  content: attr(data-num);
  position: absolute;
  top: 22px;
  right: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  color: var(--color-rule);
}

/* --- Les quatre pôles ----------------------------------------------------- */

.poles { padding-block: var(--pas); }

.poles-grille {
  display: grid;
  gap: clamp(30px, 4vw, 70px);
  margin-top: clamp(34px, 4vw, 62px);
}

@media (width >= 60rem) {
  .poles-grille { grid-template-columns: 0.92fr 1.08fr; align-items: start; }
}

/* Colonne visuelle épinglée : elle reste, la liste défile devant elle. */
.poles-visuel {
  position: relative;
  aspect-ratio: 3 / 2;
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
  background: var(--color-navy-700);
}

@media (width >= 60rem) {
  .poles-visuel {
    position: sticky;
    top: 118px;
    aspect-ratio: 4 / 5;
  }
}

.poles-visuel figure {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 760ms var(--e-doux), transform 1100ms var(--e-sortie);
}

.poles-visuel figure[data-actif] { opacity: 1; transform: none; }

.poles-visuel img { width: 100%; height: 100%; object-fit: cover; }

/* Compteur d'index posé sur l'image. */
.poles-index {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 3;
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin: 0;
  padding: 13px 19px;
  background: var(--color-gold-500);
  color: var(--color-navy-900);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  border-radius: 0 var(--radius-technique, 2px) 0 0;
}

.poles-index b { font-size: 1.35rem; font-weight: 400; line-height: 1; }
.poles-index span { font-size: 0.75rem; opacity: 0.62; }

.pole-item {
  position: relative;
  padding-block: clamp(30px, 3.6vw, 54px);
  border-bottom: 1px solid var(--color-navy-700);
  transition: opacity 520ms var(--e-doux);
}

@media (width >= 60rem) {
  .pole-item { opacity: 0.32; }
  .pole-item[data-actif] { opacity: 1; }
}

.pole-item:first-child { padding-top: 0; }
.pole-item:last-child { border-bottom: none; }

.pole-tete { display: flex; align-items: baseline; gap: 16px; }

.pole-code {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  color: var(--color-gold-500);
}

.pole-nom {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.5rem, 1rem + 1.9vw, 2.5rem);
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: var(--color-paper);
  margin: 0;
  flex: 1;
}

.pole-accroche {
  margin: 14px 0 0;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--voile);
  max-width: 52ch;
}

.pole-item .mb-specs { margin-top: 20px; }
.pole-item .mb-specs li { border-color: var(--color-navy-500); }
.pole-item .mb-fleche { margin-top: 22px; }

/* Liseré de matière : la seule couleur de pôle autorisée par la charte. */
.pole-item::before {
  content: '';
  position: absolute;
  left: -18px;
  top: clamp(30px, 3.6vw, 54px);
  width: 3px;
  height: 0;
  background: var(--teinte);
  transition: height 620ms var(--e-sortie);
}

.pole-item[data-actif]::before { height: 42px; }
.pole-item:first-child::before { top: 0; }

@media (width < 60rem) { .pole-item::before { display: none; } }

/* --- Savoir-faire --------------------------------------------------------- */

.savoir-grille {
  display: grid;
  gap: clamp(34px, 4vw, 70px);
  align-items: center;
}

@media (width >= 60rem) {
  .savoir-grille { grid-template-columns: 1.05fr 0.95fr; }
}

/* --- Capacité ------------------------------------------------------------- */

.capacite-grille {
  display: grid;
  gap: clamp(34px, 4vw, 70px);
  align-items: center;
}

@media (width >= 60rem) {
  .capacite-grille { grid-template-columns: 1fr 1fr; }
}

.capacite-grille .mb-dl { margin-top: 38px; }
.capacite-grille .mb-dl > div:last-child { grid-column: 1 / -1; }

.capacite-visuel {
  position: relative;
  aspect-ratio: 3 / 2;
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
  background: var(--color-navy-700);
}

.capacite-visuel img { width: 100%; height: 100%; object-fit: cover; }

/* --- Secteurs ------------------------------------------------------------- */

.secteurs-l {
  display: grid;
  gap: 20px;
  margin-top: clamp(34px, 4vw, 60px);
}

@media (width >= 48rem) {
  .secteurs-l { grid-template-columns: repeat(3, 1fr); }
}

.secteur {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
  background: var(--color-paper);
  text-decoration: none;
  transition: border-color 420ms var(--e-doux), transform 620ms var(--e-sortie),
    box-shadow 620ms var(--e-sortie);
}

.secteur:hover {
  border-color: var(--color-navy-500);
  transform: translateY(-5px);
  box-shadow: var(--ombre-levee);
}

.secteur-img {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--color-kraft-200);
}

/* Le noir et blanc au repos, la couleur au survol : la photo répond au geste
   plutôt que de crier avant qu'on l'ait regardée. */
.secteur-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.04);
  transform: scale(1.02);
  transition: filter 720ms var(--e-doux), transform 900ms var(--e-sortie);
}

.secteur:hover .secteur-img img {
  filter: grayscale(0);
  transform: scale(1.06);
}

.secteur-corps {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 24px;
}

.secteur-corps h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.22rem;
  letter-spacing: -0.015em;
  color: var(--color-navy-900);
  transition: color 300ms var(--e-doux);
}

.secteur:hover .secteur-corps h3 { color: var(--color-navy-500); }

.secteur-corps p {
  margin: 13px 0 0;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.58;
  color: var(--color-ink-500);
}

.secteur-besoin { margin-top: auto; padding-top: 18px; }

.secteur-besoin span {
  display: block;
  padding-top: 16px;
  border-top: 1px solid var(--color-rule);
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--color-ink-900);
}

/* =============================================================================
   11. PAGE PÔLE
   ============================================================================= */

/* Bandeau d'ouverture des pages intérieures. Toujours la même structure : fil
   d'Ariane, sur-titre, titre, chapeau, chiffres, action. Le visiteur qui a vu
   une page les a toutes vues — c'est ce qui rend un site lisible. */
.ouverture {
  position: relative;
  padding-top: calc(var(--h-barre, 78px) + clamp(38px, 5vw, 76px));
  padding-bottom: clamp(44px, 5vw, 84px);
  overflow: hidden;
}

/* Alignement en haut, jamais en bas.

   Avec `align-items: end`, la colonne de texte descend se caler sur le bas de
   l'image — et comme l'image est plus haute qu'elle, il se creuse au-dessus du
   sur-titre un vide qui n'a aucune raison d'être et qu'on lit comme un oubli de
   mise en page. Le texte commence en haut, l'image occupe la hauteur qu'elle
   veut. */
.ouverture-grille {
  display: grid;
  gap: clamp(34px, 4vw, 64px);
  align-items: start;
  margin-top: clamp(26px, 3vw, 44px);
}

@media (width >= 60rem) {
  .ouverture-grille { grid-template-columns: 1.1fr 0.9fr; }
}

/* Le liseré de pôle à l'échelle du titre : même signal que sur la plaque, mais
   à la taille du bloc. */
.ouverture-titre {
  display: flex;
  align-items: stretch;
  gap: 20px;
}

/* Le bloc de texte prend toute la place restante, explicitement.

   Sans cela il serait dimensionné par son contenu — or le titre porte
   `container-type: inline-size`, qui retire justement au titre le droit de
   participer à la largeur de son parent. La colonne se réglait alors sur le
   sur-titre (« Pôle PPL », une centaine de pixels) et le H1 se repliait au
   milieu d'une page vide. `flex: 1` coupe la circularité à la racine. */
.ouverture-titre > div {
  flex: 1 1 auto;
  min-width: 0;
}

.ouverture-titre > i {
  flex: 0 0 auto;
  width: 4px;
  background: var(--teinte, var(--color-gold-500));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 820ms var(--e-sortie) 120ms;
}

[data-vu] .ouverture-titre > i { transform: scaleY(1); }

.ouverture .mb-t1 { margin-top: 12px; }
.ouverture .titre-mesure { margin-top: 12px; }
.ouverture .mt-titre { margin-top: 2px; }
.ouverture .mb-p { margin-top: 24px; max-width: 58ch; }

/* Les gouttières sont volontairement plus serrées que le rythme général : avec
   56 px, quatre spécifications en monospace dépassent la colonne d'une
   quinzaine de pixels à 1440 px et la dernière part seule à la ligne. Mesuré,
   pas supposé. */
.ouverture-chiffres {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(20px, 2.6vw, 38px);
  margin: clamp(28px, 3vw, 44px) 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--filet, var(--color-rule));
}

.ouverture-chiffres dt {
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sur-tres-faible, var(--color-ink-500));
}

.ouverture-chiffres dd {
  margin: 8px 0 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.3rem, 1rem + 1.1vw, 1.85rem);
  line-height: 1;
  color: var(--sur, var(--color-navy-900));
}

.ouverture-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: clamp(28px, 3vw, 40px);
}

.ouverture-visuel {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-technique, 2px);
  overflow: hidden;
  background: var(--color-kraft-200);
}

.ouverture-visuel img { width: 100%; height: 100%; object-fit: cover; }

/* Grille de plaques — produits d'un pôle, configurations d'un produit. */
.grille-plaques {
  display: grid;
  gap: 20px;
  margin-top: clamp(30px, 3.4vw, 48px);
}

@media (width >= 40rem) { .grille-plaques { grid-template-columns: repeat(2, 1fr); } }
@media (width >= 68rem) { .grille-plaques--3 { grid-template-columns: repeat(3, 1fr); } }

/* =============================================================================
   12. PAGE PRODUIT
   ============================================================================= */

.produit-corps {
  display: grid;
  gap: clamp(34px, 4vw, 64px);
  align-items: start;
}

@media (width >= 68rem) {
  .produit-corps { grid-template-columns: 1.15fr 0.85fr; }
}

.produit-section + .produit-section {
  margin-top: clamp(34px, 4vw, 56px);
  padding-top: clamp(30px, 3.4vw, 48px);
  border-top: 1px solid var(--filet, var(--color-rule));
}

.produit-section .mb-p { margin-top: 16px; max-width: 66ch; }

.produit-visuels {
  display: grid;
  gap: 16px;
  position: sticky;
  top: calc(var(--h-barre, 78px) + 24px);
}

@media (width < 68rem) {
  .produit-visuels { position: static; grid-template-columns: repeat(2, 1fr); }
}

/* Liste « ce que nous vous demanderons » : une ligne de bordereau, avec le
   filet pointillé qui relie l'intitulé à sa valeur. */
.bordereau {
  margin: 0;
  border: 1px solid var(--filet, var(--color-rule));
  border-radius: var(--radius-technique, 2px);
  background: var(--fond, var(--color-paper));
}

.bordereau > div {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 12px 20px;
}

.bordereau > div + div { border-top: 1px solid var(--filet, var(--color-rule)); }

.bordereau dt {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  color: var(--sur, var(--color-ink-900));
}

.bordereau i {
  flex: 1;
  min-width: 16px;
  transform: translateY(-3px);
  border-bottom: 1px dotted var(--filet, var(--color-rule));
}

.bordereau dd {
  flex: 0 0 auto;
  margin: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: var(--sur-faible, var(--color-ink-500));
}

/* =============================================================================
   13. PAGE SECTEUR — 14. PAGES GROUPE
   ============================================================================= */

/* Grille de cartes de contenu, utilisée par les secteurs et par le groupe. */
.grille-cartes {
  display: grid;
  gap: 20px;
  margin-top: clamp(30px, 3.4vw, 48px);
}

@media (width >= 48rem) { .grille-cartes { grid-template-columns: repeat(2, 1fr); } }
@media (width >= 68rem) { .grille-cartes--3 { grid-template-columns: repeat(3, 1fr); } }

.carte {
  display: flex;
  flex-direction: column;
  padding: clamp(22px, 2.4vw, 32px);
  border: 1px solid var(--filet, var(--color-rule));
  border-radius: var(--radius-technique, 2px);
  background: var(--fond, var(--color-paper));
  text-decoration: none;
  transition: border-color 420ms var(--e-doux), transform 620ms var(--e-sortie),
    box-shadow 620ms var(--e-sortie);
}

a.carte:hover {
  border-color: var(--filet-fort);
  transform: translateY(-4px);
  box-shadow: var(--ombre-levee);
}

.carte-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  color: var(--color-kraft-500);
}

.carte h3 { margin: 14px 0 0; }

.carte p {
  margin: 12px 0 0;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--sur-faible, var(--color-ink-500));
}

.carte .mb-fleche { margin-top: auto; padding-top: 20px; }

/* Frise chronologique du groupe. Une colonne, un filet, des jalons. */
.frise {
  list-style: none;
  margin: clamp(30px, 3.4vw, 48px) 0 0;
  padding: 0 0 0 30px;
  position: relative;
}

.frise::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--filet, var(--color-rule));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 1200ms var(--e-sortie);
}

[data-vu] .frise::before { transform: scaleY(1); }

.frise li { position: relative; padding-bottom: clamp(26px, 3vw, 42px); }
.frise li:last-child { padding-bottom: 0; }

.frise li::before {
  content: '';
  position: absolute;
  left: -30px;
  top: 7px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-gold-500);
}

.frise b {
  display: block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.875rem;
  letter-spacing: 0.1em;
  color: var(--color-gold-500);
}

.frise strong {
  display: block;
  margin-top: 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.16rem;
  letter-spacing: -0.015em;
  color: var(--sur, var(--color-navy-900));
}

.frise p {
  margin: 8px 0 0;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--sur-faible, var(--color-ink-500));
  max-width: 56ch;
}

/* Bloc de certification. */
.norme {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  padding: clamp(20px, 2.2vw, 28px);
  border: 1px solid var(--filet, var(--color-rule));
  border-radius: var(--radius-technique, 2px);
  background: var(--fond, var(--color-paper));
}

.norme-sceau {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid var(--color-gold-500);
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  color: var(--color-gold-500);
}

.norme b {
  display: block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.0625rem;
  letter-spacing: 0.04em;
  color: var(--sur, var(--color-navy-900));
}

.norme span {
  display: block;
  margin-top: 6px;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--sur-faible, var(--color-ink-500));
}

/* Ligne de site industriel. */
.site-ligne {
  display: grid;
  gap: 6px 24px;
  padding: clamp(18px, 2vw, 26px) 0;
  border-top: 1px solid var(--filet, var(--color-rule));
}

@media (width >= 60rem) {
  .site-ligne { grid-template-columns: 0.8fr 1.2fr 1fr; align-items: baseline; }
}

.site-ligne b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  color: var(--sur, var(--color-navy-900));
}

.site-ligne p {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--sur-faible, var(--color-ink-500));
}

.site-ligne .mb-specs { justify-content: flex-start; }

/* Mention « à confirmer » : elle doit se voir, sans crier. Le prototype ne
   présente jamais une hypothèse comme un fait. */
.a-confirmer {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 3px 9px;
  border: 1px dashed var(--color-kraft-500);
  border-radius: var(--radius-technique, 2px);
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-kraft-500);
}

/* =============================================================================
   15. ACCESSIBILITÉ
   ============================================================================= */

.mb-saut {
  position: absolute;
  left: -9999px;
  z-index: 200;
  padding: 12px 20px;
  background: var(--color-navy-900);
  color: var(--color-paper);
  border-radius: var(--radius-technique, 2px);
  font-family: var(--font-sans);
  font-size: 0.875rem;
  text-decoration: none;
}

.mb-saut:focus { left: var(--gouttiere); top: 12px; }

.mb :where(a, button, input, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--color-gold-500);
  outline-offset: 3px;
  border-radius: var(--radius-technique, 2px);
}

.mb-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* =============================================================================
   16. MOUVEMENT RÉDUIT ET IMPRESSION
   =============================================================================

   Tout ce qui bouge s'arrête. Rien ne disparaît : le contenu reste intégralement
   lisible, il est simplement déjà en place. C'est la règle — un site qui devient
   vide quand on coupe le mouvement n'a pas un problème d'animation, il a un
   problème de contenu.
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* L'intro ne joue pas du tout. Une animation purement décorative n'a pas de
     version dégradée qui vaille : on la retire en CSS, pour que le script n'ait
     aucun attribut à écrire avant l'hydratation. */
  .pre { display: none !important; }
  html:has(.pre:not([data-fini])) { overflow: visible; }

  /* `display: none` retire l'intro de l'affichage, PAS du document : le
     sélecteur `:has(.pre:not([data-fini]))` qui met le contenu en attente
     continue donc de s'appliquer, et la page resterait invisible pour
     exactement les personnes qui ont demandé moins de mouvement. On le
     neutralise explicitement. */
  .mb:has(.pre:not([data-fini])) main,
  .mb:has(.pre:not([data-fini])) .mb-nav {
    transform: none !important;
    opacity: 1 !important;
  }

  .mb *,
  .mb *::before,
  .mb *::after,
  .pre *,
  .pre *::before {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .masque > *,
  .monte,
  .mots > i,
  .volet > img,
  .mb-menu > ul > li > a,
  .mb-menu-sous,
  .mb-mega-col {
    transform: none !important;
    opacity: 1 !important;
  }

  .filet-anime,
  .mb-sur::before,
  .plaque::before,
  .ouverture-titre > i,
  .frise::before { transform: none !important; }

  .volet::after { transform: scaleY(0) !important; }

  .mb-grain,
  .hero-defile i::after,
  .ruban-piste { animation: none !important; }

  .ruban-piste { transform: none !important; }
  .poles-visuel figure { transition: none; }

  /* Le survol continue de répondre : ce n'est pas du mouvement décoratif, c'est
     le retour d'un geste. Il passe simplement en instantané. */
  a.plaque:hover,
  a.carte:hover,
  .secteur:hover { transform: none; }
}

@media print {
  .mb-nav, .mb-mega, .mb-menu, .mb-grain, .mb-grille, .mb-progres,
  .mb-rideau, .pre, .hero-defile, .hero-rail, .ruban,
  .mb-saut { display: none !important; }

  .mb, .mb-sombre, .mb-kraft {
    background: #fff !important;
    color: #000 !important;
  }

  .mb-section { content-visibility: visible; padding-block: 18mm 0; }

  .masque > *, .monte, .mots > i, .volet > img {
    transform: none !important;
    opacity: 1 !important;
  }

  .volet::after { display: none; }
  .plaque, .carte, .norme { break-inside: avoid; }
}
