/* ===========================================================================
   Symbio3D — thème public.
   Direction : charte historique du site WordPress (relevée le 21/07/2026 sur
   www.symbio3d.com). Vert #60B339 sur alternance de fonds clairs et sombres,
   Montserrat pour les titres, titres verts en graisse moyenne.

   La direction précédente (« atelier technique », signature de strates) a été
   remplacée sur décision de Florian — motif esthétique. Voir
   docs/superpowers/specs/2026-07-21-theme-public-charte-historique-design.md
   ======================================================================== */

:root {
  /* Variables globales du kit Elementor de l'ancien site. Le kit les definissait
     sur le selecteur `.elementor-kit-12406` — classe que notre <body> ne porte
     pas — et uniquement dans legacy-pages.css, absente des pages non-legacy.
     Toutes les regles de la coquille (chargee partout) qui font `var(--e-global-*)`
     resolvaient donc dans le vide, et l'en-tete changeait d'aspect selon que
     legacy-pages.css etait chargee ou non. On redeclare le kit ici, sur :root
     et donc sur tout le site, pour un rendu identique partout. Les @font-face
     (Montserrat, Lato) sont deja dans legacy-shell.css, elle aussi partout. */
  --e-global-color-primary: #3D3D3D;
  --e-global-color-secondary: #3D3D3D;
  --e-global-color-text: #3D3D3D;
  --e-global-color-accent: #61CE70;
  --e-global-color-d970559: #3D3D3D;
  --e-global-color-3611b5c: #60B339;
  --e-global-color-eab9c9f: #E5E5E5;
  --e-global-typography-primary-font-family: "Montserrat";
  --e-global-typography-primary-font-weight: 600;
  --e-global-typography-secondary-font-family: "Montserrat Alternates";
  --e-global-typography-secondary-font-weight: 400;
  --e-global-typography-text-font-family: "Lato";
  --e-global-typography-text-font-weight: 400;
  --e-global-typography-accent-font-family: "Montserrat";
  --e-global-typography-accent-font-weight: 500;

  /* Couleurs */
  --green: #60B339;
  --green-bright: #7ECB4F;
  /* #3d7a26 : 5,24:1 avec du blanc ET sur du blanc. Une seule valeur couvre
     donc le fond des boutons (texte blanc dessus) et la couleur des titres sur
     fond clair. Valeur deja retenue par l'admin au lot 1 (--btn-primary-bg),
     ou #60B339 sous du blanc ne donnait que 2,62:1. */
  --green-deep: #3d7a26;
  --ink: #141414;
  --ink-soft: #1e1e1e;
  --paper: #ffffff;
  --surface-alt: #fafafa;
  --text: #2b2b2b;
  /* #6f6f6f = 5,0:1 sur blanc. L'ancien site utilise #777 (4,48:1), sous le
     seuil AA de 4,5:1 : l'écart est invisible, la conformité ne l'est pas. */
  --muted: #6f6f6f;
  --line: #e4e7e2;
  --danger: #c0392b;

  /* Conserves de la charte precedente : ~24 regles du tunnel de commande, du
     panier et de l'espace client les referencent encore, et ces ecrans sont
     hors du perimetre de ce lot. Un var() non resolu sur une propriete heritee
     (color, font-family) retombe sur la valeur du parent : sans ces deux
     lignes, les textes secondaires perdent leur gris et .mono sa chasse fixe. */
  --steel: #5f6b60;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* Typo */
  --font-brand: Montserrat, system-ui, sans-serif;
  --font-body: Lato, system-ui, sans-serif;

  /* Rythme */
  --container: 1120px;
  --radius: 3px;
  --section-pad: clamp(3rem, 7vw, 5.5rem);
}

/* --- Coquille importee (en-tete / pied WordPress) ------------------------ */
/* La coquille est chargee sur TOUTES les pages, mais le menu et le corps du
   pied heritaient leur police du <body> : sur les pages importees, theme.css
   (bare `body{font-family}`) la fixait ; ailleurs (configurateur, tunnel), non,
   et l'en-tete changeait d'aspect. theme.css reste volontairement hors des
   ecrans de l'app (selecteurs nus). On fixe donc la police de la coquille
   explicitement, sur des selecteurs de classe, pour un rendu identique partout :
   Montserrat pour la navigation et les titres, Lato pour le texte du pied. */
.elementor-location-header,
.elementor-location-header .elementor-item,
.elementor-location-header .elementor-sub-item,
.elementor-location-footer h1,
.elementor-location-footer h2,
.elementor-location-footer h3,
.elementor-location-footer h4 { font-family: "Montserrat", sans-serif; }
.elementor-location-footer { font-family: "Lato", sans-serif; }

/* Sous-menus deroulants. Elementor ouvrait ses menus via SmartMenus (jQuery),
   que l'application n'embarque pas : le sous-menu (deja stylé et positionne par
   le CSS Elementor) restait en display:none. On l'ouvre en CSS pur, au survol
   ET au focus clavier (accessibilite : le sous-menu s'ouvre a la tabulation,
   ce que l'ancien site ne permettait pas). */
.elementor-location-header .menu-item-has-children:hover > .sub-menu,
.elementor-location-header .menu-item-has-children:focus-within > .sub-menu {
  display: block;
}
/* Elementor impose width: var(--width) = 100% (soit la largeur de l'item
   parent, 156px) au deroulant, alors que ses entrees sont en nowrap
   (« Impression 3D – PEEK PEI ULTEM » fait 239px) : le texte debordait du fond
   gris. On laisse le sous-menu prendre la largeur de son contenu. !important
   car la regle d'Elementor est plus specifique (verifie au navigateur : 156px
   sans, 267px avec). */
.elementor-location-header .sub-menu { width: max-content !important; }

/* Bouton « Imprimer en ligne » de l'en-tete : son conteneur Elementor
   (.elementor-element-51f41680, colonne flex, hauteur auto) porte un
   padding-top:10px / padding-bottom:0 : la boite (55px) colle exactement au
   bouton (45px) plus ce padding, donc justify-content n'a aucun espace libre
   a redistribuer — la 1re passe (justify-content seul) n'avait donc rien
   change (verifie au navigateur). En retirant le padding-top asymetrique, la
   boite se resserre exactement sur le bouton (45px) et l'alignement du header
   (align-items:center) le recentre alors sur le meme axe que le logo (mesure :
   centre du bouton = centre du logo, 120.2px des deux cotes). justify-content
   garde en filet si un autre ecran laissait un residu d'espace libre. Fait
   dans site.css (dernier mot sur la coquille), jamais dans legacy-shell.css
   (regenere par l'import, la regle serait perdue). */
.elementor-element-51f41680 { padding-top: 0; justify-content: center; }

/* Mobile (<=767px) : bouton « Imprimer en ligne » en haut a droite, hamburger
   juste en dessous (demande Florian, 31/07/2026). Par defaut (legacy-shell.css,
   regenere par l'import) le conteneur du bouton (.elementor-element-51f41680)
   porte width:100% et un order de flex par defaut (0), donc il retombe seul sur
   une 2e ligne PLEINE LARGEUR sous logo+hamburger (qui, eux, ont order:-99999).
   On lui donne un order intermediaire (-99998) et une largeur au contenu pour
   qu'il rejoigne la 1re ligne, colle a droite (margin-left:auto) ; le widget du
   hamburger (.elementor-element-bfb5314, order:-99997) passe alors seul sur la
   2e ligne (flex-basis:100% force le retour a la ligne) ou son icone reste
   collee au meme bord droit (regle heritee elementor-nav-menu__text-align-aside).
   Verifie au navigateur (Claude in Chrome sur preprod) : bords droits du bouton
   et du hamburger alignes au pixel pres, tiroir de menu toujours fonctionnel. */
@media (max-width: 767px) {
  .elementor-element-51f41680 {
    order: -99998;
    width: auto;
    flex-grow: 0;
    margin-left: auto;
    /* Espace demande au-dessus du bouton (31/07/2026) : padding-top plutot
       que margin-top pour agrandir la boite du conteneur (justify-content:
       center du bloc precedent centre alors le bouton dans cet espace en plus,
       au lieu de le pousser hors du flex). */
    padding-top: 15px;
    /* Bouton colle au bord droit complet (meme demande) : le conteneur
       heritait 28px de padding-right (legacy-shell.css, pousse le bouton
       depuis son propre bord) PLUS le padding-right:3% du bloc-ligne parent
       .elementor-element-3abb80a8 (.e-con-inner, garde-fou d'ecart general
       du header) : on annule les deux — 28px localement, -3% pour compenser
       le parent (meme pourcentage que legacy-shell.css, a garder synchrone
       si Elementor le change lors d'un reimport). Le hamburger juste en
       dessous garde lui son propre retrait : seul le bouton etait demande. */
    padding-right: 0;
    margin-right: -3%;
  }
  .elementor-element-bfb5314 {
    order: -99997;
    flex-basis: 100%;
    width: 100%;
    max-width: 100%;
  }
}

/* Etapes numerotees (widget Unlimited Elements "Shape Bullets", pages
   /services : accompagnement, a-la-demande, prototypage, en-serie, stocks) :
   l'icone (loupe, camion...) se superposait au titre de l'etape. Cause :
   Elementor genere le CSS de mise en page de ce greffon en <style> INLINE,
   un bloc par instance de widget (scope a un id genere, #uc_uc_diamond_
   bullets_elementor_XXXXXXX), jamais dans une feuille liee <link> — la seule
   forme que capte l'import (AssetCollector::stylesheets()). Sans
   `.ue_item_icon{position:relative}`, l'icone (`position:absolute` dans le
   CSS d'origine, retrouve dans le cache local de l'import) se positionne
   par rapport au premier ancetre positionne trouve plus haut dans le
   document au lieu de son cercle - d'ou le chevauchement avec le texte.
   Regles reconstruites depuis le <style> inline d'origine (var/legacy-cache),
   generiques (sans l'id par instance) pour couvrir les cinq pages a la fois.
   Verifie au navigateur sur les cinq pages de services. */
.ue_item { display: flex; }
.ue_item .ue_item_icon_holder { display: flex; flex-direction: column; }
.ue_item_icon { flex-shrink: 0; flex-grow: 0; position: relative; }
.ue_item_content { flex-grow: 1; }
.ue_item_icon .ue_icon_output_wrapper { line-height: 1em; }
.ue_item_icon .ue_icon_output_wrapper svg { height: 1em; width: 1em; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.ue_item_icon i { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.ue_item_icon > svg path { stroke-linecap: round; }
.ue_item_icon_line { height: 100%; margin-left: auto; margin-right: auto; }
.ue_item:last-child .ue_item_icon_line { display: none; }

/* Cartes retournables (widget Unlimited Elements "Flip Box", page
   impression-3d-a-la-demande : Dépôt de filament / Résine / Filaments HT).
   Même cause que les etapes ci-dessus : la mise en page (positionnement des
   deux faces, rotation 3D) vit dans un fichier externe non capte par
   l'import — `ue-flipbox-styles.css`, servi depuis /wp-content/uploads/
   ac_assets/... et absent de la liste blanche d'AssetCollector (elle ne
   couvre que /uploads/elementor/), pas dans un <style> inline cette fois.
   Sans elle, face avant et face arriere s'empilaient l'une sous l'autre en
   flux normal au lieu de se superposer : la face arriere (fond noir) restait
   en permanence visible sous l'image, comme une bande grise. Le fichier
   d'origine est perdu (l'ancien site WordPress ne repond plus sur ce nom de
   domaine, remplace par cette application) ; a defaut, retournement 3D
   classique reconstruit ici (perspective + rotateY + backface-visibility),
   au survol (le gabarit porte deja la classe `ue-flip-box__container--hover`
   posee par Elementor). Verifie au navigateur : etat repos propre (plus de
   bande grise), face arriere accessible au survol. */
.ue-flip-box__container { position: relative; perspective: 1200px; }
.ue-flip-box__panel { backface-visibility: hidden; -webkit-backface-visibility: hidden; transition: transform .6s; }
.ue-flip-box__panel--front { position: relative; transform: rotateY(0deg); z-index: 2; }
.ue-flip-box__panel--back { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotateY(-180deg); }
.ue-flip-box__container--hover:hover .ue-flip-box__panel--front { transform: rotateY(180deg); }
.ue-flip-box__container--hover:hover .ue-flip-box__panel--back { transform: rotateY(0deg); }
.ue-flip-box__panel--front-overlay, .ue-flip-box__panel--back-overlay { position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: -1; }

/* Colonne « Notre savoir-faire au service de vos projets » du pied de page :
   seule des quatre colonnes a porter un paragraphe de prose (les trois autres
   n'ont que des lignes courtes), elle heritait du line-height/margin-bottom
   generique des <p> (1.8 / 16px) et depassait les autres de 90 a 150px de
   haut, largement au-dela du texte qu'elle contient. Resserre localement
   (.elementor-element-5ed6b51e, ce widget precisement), jamais sur `p` nu
   qui reglerait aussi le corps des pages legacy. Demande Florian, 31/07/2026.
   Verifie au navigateur : colonne ramenee a la hauteur des « Mentions
   legales » (~264px contre 314px), texte toujours lisible. */
.elementor-element-5ed6b51e .elementor-widget-container p { line-height: 1.5; margin-bottom: 10px; }

/* Bouton « retour en haut » du pied de page (fleche cerclee) : le style
   exact des boutons du site (--green, meme fond que .btn-primary/« Imprimer
   en ligne »), pas le fond pastel par defaut d'Elementor
   (--e-global-color-accent, rgb(97,206,112) - une troisieme nuance de vert,
   ni celle du site ni celle du 31/07 au matin) ni le gris par defaut
   (fill:#33373d, legacy-shell.css). Icone --ink comme le texte de
   .btn-primary : meme fond clair, meme geste de contraste. Demande Florian,
   31/07/2026 (soir). Dans site.css, jamais dans legacy-shell.css (regenere
   par l'import). */
.elementor-element-c7a48d8 .elementor-button {
  background-color: var(--green);
  border-radius: 5px;
}
.elementor-element-c7a48d8 .elementor-button:hover { background-color: var(--green-bright); }
.elementor-element-c7a48d8 .e-font-icon-svg { fill: var(--ink); }

/* Accueil, bloc « Délais rapides / Données sécurisées / Entreprise Française /
   Travail soigné » du hero (.elementor-element-3be68bf) : Elementor le sort du
   flux normal et le remonte devant le hero par une marge negative enorme
   (--margin-top), technique fragile qui ne visait qu'un seul gabarit d'ecran.
   Demande Florian, 31/07/2026.
   - Desktop (>767px) : le bloc retombait ~34px plus bas que les boutons
     « Imprimer en ligne »/« Contact » au lieu d'etre en face a face avec eux
     (mesure au navigateur : sommet du 1er badge a 601px contre 563px pour le
     bouton). --margin-top ajuste de -120px a -154px pour recentrer chaque
     ligne de badges sur son bouton (ecart residuel de la moitie de la
     difference de hauteur bouton/badge, 4-5px, cosmetique).
   - Mobile (<=767px) : --margin-top:-385px le faisait chevaucher le sous-titre
     « Vos Idées, Notre Priorité » (bloc mesure a 306px de haut, remonte de
     385px) ; --margin-left:180px etait un decalage fixe pense pour une seule
     largeur d'ecran, pas aligne au bord sur les autres. Remonte moins
     (-346px : juste sous le sous-titre, mesure au navigateur) et collee au
     bord droit (--margin-left:auto, fonctionne ici comme pour un bloc
     classique puisque son parent n'est pas un conteneur flex — 3be68bf est
     un frere du bloc hero, pas son enfant, sorti du flux par la marge
     negative). Le bloc garde sa hauteur totale (306px) mais tient desormais
     entierement dans la zone sombre du hero (verifie : bas du bloc a 471px,
     bas du hero a 511px) — necessaire car son texte est clair (#e5e5e5),
     illisible sur fond blanc s'il debordait sous le hero. */
@media (min-width: 768px) {
  .elementor-12056 .elementor-element.elementor-element-3be68bf { --margin-top: -154px; }
}
@media (max-width: 767px) {
  .elementor-12056 .elementor-element.elementor-element-3be68bf {
    --margin-top: -346px;
    --margin-left: auto;
    /* 5px de respiration avant le bord droit plutot que colle dessus
       (demande Florian, 31/07/2026 suite). */
    margin-right: 5px;
  }
}

/* Tiroir du menu mobile : recouvrait le bas de l'icone de fermeture (X) du
   bouton hamburger. Cause : `top:0` (regle Elementor, propre a l'origine
   quand toggle+tiroir partageaient la meme ligne) positionne le tiroir au
   sommet de son widget porteur (.elementor-element-bfb5314), alors que ce
   widget est desormais SEUL sur sa propre ligne, sous le bouton « Imprimer
   en ligne » (cf. la regle mobile plus haut) : le tiroir demarrait donc au
   sommet du bouton hamburger au lieu d'en dessous, chevauchant ses 23
   derniers pixels (mesure au navigateur : tiroir a 206px, bas du bouton a
   230px). `top:100%` le fait demarrer a la hauteur du widget porteur, donc
   juste sous l'icone quel que soit son etat (hamburger ou X). Demande
   Florian, 31/07/2026. Verifie au navigateur : icone X entierement visible,
   tiroir juste en dessous. */
@media (max-width: 767px) {
  .elementor-element-bfb5314 nav.elementor-nav-menu--dropdown { top: 100%; }
}

/* Accueil mobile : marge a gauche du titre du hero et des boutons, tenus
   colles au bord gauche (0). Demande Florian, 31/07/2026.
   - Texte « L'impression 3D en ligne / au service de vos projets » et
     « Vos Idées, Notre Priorité » (elementor-element-86a0c32 et -ca66e8e) :
     +5px.
   - Boutons « Imprimer en ligne » et « Contact » (elementor-element-5b06672
     et -d60779d) : +15px.
   Cible le meme `.elementor-widget-container` que les regles de marge
   d'origine (legacy-pages.css) pour n'ecraser QUE margin-left, jamais tout
   le raccourci `margin`, qui effacerait le haut/bas deja regles. */
@media (max-width: 767px) {
  .elementor-12056 .elementor-element.elementor-element-86a0c32 > .elementor-widget-container,
  .elementor-12056 .elementor-element.elementor-element-ca66e8e > .elementor-widget-container {
    margin-left: 5px;
  }
  .elementor-12056 .elementor-element.elementor-element-5b06672 > .elementor-widget-container,
  .elementor-12056 .elementor-element.elementor-element-d60779d > .elementor-widget-container {
    margin-left: 15px;
  }
}

/* Accueil mobile : 20px (au lieu de 84px) au-dessus de la section
   « Bienvenue chez Symbio3D... ». Le gabarit empile deux sources d'espace
   avant ce texte : la marge du bloc qui le porte (elementor-element-cf22dfa,
   54px sur mobile) et un widget "spacer" dedie juste avant lui
   (elementor-element-8b2a7d1, 30px) — 84px au total. Neutralise le spacer
   (hauteur 0) et ramene la marge a 20px directement, plutot que de laisser
   les deux s'additionner. Demande Florian, 31/07/2026. */
@media (max-width: 767px) {
  .elementor-12056 .elementor-element.elementor-element-cf22dfa { --margin-top: 20px; }
  .elementor-12056 .elementor-element.elementor-element-8b2a7d1 { --spacer-size: 0px; }
}

/* Accueil mobile : les boutons « Imprimer en ligne »/« Contact » du hero
   passaient AU-DESSUS du tiroir du menu ouvert au lieu de rester dessous,
   qu'importe le scroll (verifie au navigateur : le rectangle vert du bouton
   se voit par-dessus « Technologies »/« Blog »/etc.). Cause : ces widgets
   portent position:relative + z-index:999 (regle d'origine, pour rester
   au-dessus de l'image du hero — masquee sur mobile par elementor-hidden-
   mobile, donc ce z-index n'y sert plus a rien). z-index cree un contexte
   d'empilement propre a l'element quand aucun ancetre n'en a deja un : ici
   aucun ancetre entre le bouton et la racine n'en pose (tous position:
   relative mais z-index:auto), donc ses 999 se comparent au document
   entier. Le tiroir (z-index:9997) est lui enferme dans le contexte de
   l'en-tete (position:sticky, qui EN CREE un a lui seul, meme sans
   z-index) : ses 9997 ne comptent qu'a l'interieur de ce contexte, pas face
   au reste du document. Resultat, malgre 999 < 9997, le bouton (hors de ce
   contexte) passe devant le tiroir (enferme dedans). Neutralise sur mobile
   uniquement (le z-index reste utile sur desktop, image visible). Demande
   Florian, 31/07/2026. Verifie au navigateur : boutons ne recouvrent plus
   le tiroir en defilant menu ouvert. */
@media (max-width: 767px) {
  .elementor-12056 .elementor-element.elementor-element-5b06672,
  .elementor-12056 .elementor-element.elementor-element-d60779d {
    z-index: auto;
  }
}

/* Selecteur de langue a cote du hamburger (mobile). Les deux copies
   existantes (templates/layouts/site.php, injectees apres « Panier » dans
   chaque <ul> du menu) restent invisibles hors tiroir ouvert sur mobile :
   la nav principale est masquee (legacy-shell.css), le tiroir n'apparait
   qu'au clic. site.php en injecte donc une troisieme, sans enveloppe <li>
   (.lang-switch-header), juste avant le bouton hamburger — visible en
   permanence. Cachee par defaut : ne s'affiche qu'en dessous de 768px, sur
   la meme ligne que le hamburger, a sa gauche (ordre naturel du flux, le
   marqueur est injecte AVANT le bouton dans le HTML).
   Hors d'un <nav class="elementor-nav-menu">, elle echappe aux regles de
   specificite qu'il avait fallu ecrire pour les copies en liste (`.elementor-
   nav-menu ul{display:none}` de legacy-shell.css, `.lang-switch-item` comme
   parade) : le natif <details> geree seul son etat ouvert/ferme ici, les
   regles de base (.lang-flag/.lang-menu/.lang-list, plus haut) suffisent
   sans variante `.lang-switch-item ...`. Demande Florian, 31/07/2026.
   Premiere version repartie au centre de l'en-tete plutot qu'a cote du
   hamburger (constate par Florian) : `.elementor-widget-container` porte
   `--flex-direction:column` (regle Elementor du widget nav-menu, jamais
   touchee ici), donc `justify-content:flex-end` poussait les elements vers
   le BAS (axe principal en colonne), et `align-items:center` les centrait
   a l'HORIZONTALE (axe transverse) — inversion complete par rapport a
   l'intention. `flex-direction:row` force la ligne attendue. Ensuite, le
   bouton hamburger porte deja `margin-left:auto` (regle Elementor, pour se
   plaquer seul a droite quand il etait l'unique element visible de la
   ligne) : une marge auto absorbe tout l'espace libre et neutralise
   `justify-content`, laissant le drapeau retomber tout a gauche de la
   ligne au lieu de coller au bouton. Neutralisee ici (`margin-left:0`) au
   profit du `justify-content:flex-end` + `gap` du conteneur, qui placent
   maintenant le couple drapeau+bouton ensemble — selecteur `.elementor-12473
   .elementor-element.elementor-element-bfb5314 .elementor-menu-toggle`
   (4 classes) copie a l'identique celui de la regle d'origine
   (legacy-shell.css) : un essai a 2 classes seulement s'etait fait battre
   en specificite malgre site.css charge en dernier (constate au
   navigateur - la regle d'origine gagnait toujours, gap mesure a plus de
   400px au lieu de 40). Ecart porte a 40px (demande Florian, 31/07/2026
   suite - etait 30px). Verifie au navigateur : drapeau et hamburger
   alignes sur le meme axe horizontal, exactement 40px d'ecart. */
.lang-switch-header { display: none; }
@media (max-width: 767px) {
  .elementor-element-bfb5314 > .elementor-widget-container {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    gap: 40px;
  }
  .elementor-12473 .elementor-element.elementor-element-bfb5314 .elementor-menu-toggle {
    margin-left: 0;
  }
  .lang-switch-header { display: block; }
}

/* --- Base ---------------------------------------------------------------- */
* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--muted);
  background: var(--paper);
}
/* --green (#60B339) sur blanc = 2,62:1, illisible. Les titres sur fond clair
   prennent --green-deep (5,24:1), au-dessus du seuil texte normal : tous les
   niveaux sont couverts, y compris h4. Sur fond sombre, --green donne 7,02:1
   et reste la couleur d'accent (voir le récap noir du panier). */
h1, h2, h3, h4 { font-family: var(--font-brand); font-weight: 500; color: var(--green-deep); margin: 0 0 .6em; }
h1 { font-size: 40px; line-height: 1.2; }
h2 { font-size: 32px; line-height: 1.25; }
h3 { font-size: 24px; }
p { margin: 0 0 1em; }
a { color: var(--green-deep); }
img { max-width: 100%; height: auto; display: block; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 1.5rem; }
.mono { font-family: var(--font-mono); }

/* Eyebrow : surtitre court au-dessus d'un titre de section.
   --green-deep sur fond clair (--green n'y donne que 2,62:1) ; le hero,
   sombre, reprend --green plus bas. */
.eyebrow {
  font-family: var(--font-brand);
  font-size: .8rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--green-deep);
  margin: 0 0 .8rem;
}

/* Texte fonce et non blanc, comme .btn-primary : c'est le lien d'evitement du
   clavier, il serait malvenu qu'une aide a l'accessibilite soit justement ce
   qu'on lit le moins bien (blanc sur --green : 2,62:1). */
.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 100;
  background: var(--green); color: var(--ink); padding: .5rem 1rem;
}
.skip-link:focus { left: 0; }

/* Bandeau d'environnement (préprod uniquement) : rayures ambre/noir, jamais
   confondu avec le vert de marque ni le bandeau promo WP. Sticky pour rester
   visible en scrollant (le header WP n'est pas fixed, donc pas de collision). */
.env-banner {
  position: sticky; top: 0; z-index: 200;
  background: repeating-linear-gradient(45deg,
    #f5a623 0 14px, #1a1a1a 14px 28px);
  color: #fff; text-align: center;
  font-family: var(--font-brand); font-weight: 700; font-size: .8rem;
  letter-spacing: .04em; text-transform: uppercase;
  padding: .5rem 1rem;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}

:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

/* --- Header ----------------------------------------------------------------
   La coquille « charte historique » (.site-header, .site-banner, .logo,
   .main-nav, .nav-list/-item/-sub, .header-actions, .account-link) a été
   retirée le 31/07/2026 (audit) : remplacée depuis le 22-23/07 par la copie
   fidèle WordPress (legacy-header.html + legacy-shell.css), plus rien ne
   l'émettait. */
/* Sélecteur de langue - liste dépliable (details natif, utilisable sans JS).
   Injecté DANS le menu de l'en-tête, juste après « Panier » (templates/
   layouts/site.php, demande Florian 31/07/2026) : un petit drapeau rond,
   sans texte — le déroulé, lui, garde le nom de chaque langue. Fond clair
   semi-transparent sur le drapeau : l'en-tête est sur fond noir
   (elementor-element-3abb80a8), --surface-alt (pensé pour un fond blanc)
   y disparaîtrait. */
.lang-switch-item { display: flex; align-items: center; margin-inline-start: .6rem; }
.lang-menu { position: relative; }
/* Le bouton lui-même (<summary class="lang-flag">) : un rond, le drapeau
   centré dedans, pas de texte — le nom de la langue reste dans .lang-list. */
.lang-flag {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  /* Noir comme l'en-tete (elementor-element-3abb80a8, #000000), demande
     Florian 31/07/2026 (soir) : le rond blanc translucide d'avant tranchait
     sur le fond noir au lieu de s'y fondre. */
  background: #000;
  font-size: 1rem;
  line-height: 1;
  user-select: none;
}
.lang-flag::-webkit-details-marker { display: none; }
.lang-flag:hover,
.lang-menu[open] .lang-flag { background: rgba(255, 255, 255, .18); }
/* Icônes icons8 rondes (fr.png/en.png) : déjà circulaires côté fichier,
   border-radius en filet + object-fit pour un rendu net quel que soit le
   PNG fourni plus tard pour une autre langue. */
.lang-flag-img { display: block; width: 20px; height: 20px; border-radius: 50%; object-fit: cover; }
.lang-list {
  position: absolute;
  /* Centré dans l'AXE du drapeau (demande Marc, 31/07/2026, photo à l'appui :
     calé right:0, le déroulé s'étalait vers la gauche jusque sous « Panier »).
     left 50% + translateX(-50%) : le milieu de la liste sous le milieu du
     rond, quelle que soit sa largeur. */
  left: 50%;
  transform: translateX(-50%);
  top: 100%;
  z-index: 60; /* au-dessus du contenu, sous la modale de consentement */
  margin: .4rem 0 0;
  padding: .25rem;
  list-style: none;
  width: max-content;
  min-width: 0;
  /* Noir comme l'en-tête (elementor-element-3abb80a8, #000000), demande
     Florian 31/07/2026 : texte clair plutot que --muted (illisible sur ce
     fond). Bordure et ombre adaptees, --line disparaissait aussi sur noir. */
  background: #000;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
  /* .elementor-nav-menu ul{display:none} (legacy-shell.css) masque TOUT <ul>
     niche dans le menu — y compris celui-ci, qui n'a rien a voir avec les
     sous-menus Services/Technologies qu'elle vise. Sans cette regle, le
     natif <details> avait beau passer "open", la liste restait display:none
     (constate en direct sur preprod, 31/07/2026) : specificite superieure
     (3 classes/attribut) plutot qu'!important. */
}
.lang-menu[open] .lang-list { display: block; }
.lang-list a {
  display: flex;
  align-items: center;
  gap: .45rem;
  color: #f2f2f2;
  text-decoration: none;
  font-size: .8rem;
  padding: .3rem .6rem;
  border-radius: var(--radius);
  white-space: nowrap;
}
/* Specificite superieure a .elementor-nav-menu--main .elementor-nav-menu a
   (legacy-shell.css, padding:13px 20px) qui, sans ca, ecrasait silencieusement
   le padding ci-dessus : la case grossissait (46px de haut, 192px de large
   pour "English") et son bord gauche s'etalait jusque sous "Contact" - lu par
   Florian comme "les drapeaux ne sont pas alignes" (31/07/2026 soir). Meme
   defaut que le display:none du meme fichier plus haut : specificite, pas
   !important. */
.lang-switch-item .lang-menu .lang-list a { padding: .3rem .6rem; }
/* Même bataille de spécificité pour la LARGEUR : les règles de menu
   d'Elementor (min-width sur les ul nichés) regonflaient la boîte — d'où le
   déroulé « large » que montre la photo de Marc. La liste fait la largeur de
   son contenu, point. */
.lang-switch-item .lang-menu .lang-list { width: max-content; min-width: 0; }
.lang-list a:hover { color: #fff; background: rgba(255, 255, 255, .14); }
/* Langue existante sur le site, mais pas pour cette page-ci : montrée, pas
   cliquable. Un lien qui mènerait à une 404 serait pire que rien. */
.lang-list .is-unavailable {
  display: flex;
  align-items: center;
  gap: .45rem;
  color: #f2f2f2;
  opacity: .5;
  font-size: .8rem;
  padding: .3rem .6rem;
  cursor: default;
  white-space: nowrap;
}

.page-flash { margin: 0; padding: .8rem 1.5rem; text-align: center; }

/* Le bloc Hero de la maquette « charte historique » (.blk-hero, .hero-*) a
   été retiré le 31/07/2026 (audit) : home.php avait disparu avec le CMS par
   blocs (migration 037), plus rien ne l'émettait. */

/* --- Boutons ------------------------------------------------------------- */
.btn {
  display: inline-block; border: 0; border-radius: var(--radius); cursor: pointer;
  padding: 12px 24px; font-family: var(--font-brand); font-size: 15px; font-weight: 500;
  text-decoration: none; text-align: center; background: #ececea; color: var(--ink);
  transition: background .15s, transform .1s;
}
.btn:active { transform: translateY(1px); }
/* Bouton vert de l'app, aligne sur « Imprimer en ligne » de l'en-tete : meme
   vert de marque (--green, #60B339), meme forme (majuscules, Montserrat 14px,
   letter-spacing .19px, radius 5px). Il en differait par un vert plus sombre,
   ce qui sautait aux yeux d'un ecran a l'autre.

   Le TEXTE, lui, est fonce la ou l'en-tete met du blanc : blanc sur #60B339 ne
   donne que 2,62:1, sous le minimum WCAG AA de 4,5:1. C'est le defaut de
   l'ancien site, qu'on ne reproduit pas ici. --ink sur ce meme vert donne
   7,02:1 (niveau AAA) sans toucher ni a la couleur ni a la forme - c'est ce qui
   permet de garder le vert de marque, la ou le lot 1 avait du l'assombrir.
   L'en-tete garde son texte blanc : elle reste une copie fidele du fragment
   WordPress (arbitrage de Florian, 27/07/2026).

   Survol : on eclaircit au lieu d'inverser en blanc comme le fait la reference.
   Un bouton blanc sans bordure disparaitrait sur les pages de l'app, qui sont
   sur fond blanc - la ou l'en-tete, elle, est sur fond colore. */
.btn-primary {
  background: var(--green); color: var(--ink);
  text-transform: uppercase; font-size: 14px; letter-spacing: .19px; border-radius: 5px;
}
.btn-primary:hover { background: var(--green-bright); }
.btn-ghost { background: transparent; color: #fff; box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.35); }
.btn-ghost:hover { box-shadow: inset 0 0 0 1.5px var(--green-bright); color: var(--green-bright); }
.btn-lg { padding: 14px 32px; font-size: 16px; }

/* --- Sections / blocs ------------------------------------------------------ */
section[class^="blk-"] { padding: var(--section-pad) 0; }
/* Seule .blk-columns survit du mécanisme de blocs CMS (elle habille la page
   publique des avis) ; ses sœurs (.blk-hero, .blk-cta, .blk-faq, .blk-raw…)
   sont parties avec lui (migration 037, ménage du 31/07/2026). Le sélecteur
   litéral reste exigé par le contrat de classes. */
.blk-columns {
  padding: var(--section-pad) 0;
}
.section-intro { color: var(--steel); max-width: 40em; margin-top: -.4rem; }

.prose { max-width: 46em; }
.prose p { margin: 0 0 1em; }
.prose ul { padding-left: 1.2em; }

/* Cartes (.cards-2 et .cards-4, sans emploi depuis la migration 037, sont
   parties au ménage du 31/07/2026) */
.cards { display: grid; gap: 1.25rem; margin-top: 2rem; }
.cards-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .cards-3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 580px) { .cards, .cards-3 { grid-template-columns: 1fr; } }

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-top: 3px solid transparent;
  border-radius: var(--radius);
  padding: 1.4rem 1.4rem 1.2rem;
  transition: border-top-color .15s, transform .15s;
}
.card:hover { border-top-color: var(--green); transform: translateY(-2px); }
.card-icon { font-size: 1.6rem; display: block; margin-bottom: .6rem; }
.card p { color: var(--steel); font-size: .95rem; margin: .4rem 0 .8rem; }
.card-link { font-weight: 600; text-decoration: none; font-size: .92rem; }

/* Les blocs Texte+image (.blk-text-image, .ti-*), CTA (.blk-cta), FAQ
   (.faq-*) et Réassurance (.blk-reassurance, .reassurance-*, .r-icon) de la
   maquette CMS sont partis avec le mécanisme (migration 037) — retirés au
   ménage du 31/07/2026, plus rien ne les émettait. */

/* Avis */
.reviews-avg { font-size: 1.4rem; color: var(--green-deep); margin-top: -0.6rem; }
.reviews-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
@media (max-width: 900px) { .reviews-row { grid-template-columns: 1fr; } }
.review-card {
  margin: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem;
  font-size: .95rem;
}
.review-stars { color: var(--green); letter-spacing: .1em; margin: 0 0 .5rem; }

/* Photos jointes à un avis.
   Sans cette règle elles se suivaient EN COLONNE, y compris sur grand écran :
   la ligne 149 pose `img { display: block }` pour tout le site, et rien ne
   remettait celles-ci en ligne. Le flex les aligne et les fait passer à la
   ligne quand il y en a beaucoup.
   Vignettes carrées avec object-fit plutôt que largeur seule : les photos
   envoyées par les clients ont des proportions quelconques, et une simple
   largeur commune donnait une rangée de hauteurs inégales. */
.review-photos {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: .8rem 0 0;
}
.review-photos a {
  display: block;
  line-height: 0;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
}
.review-photos img {
  width: 90px;
  height: 90px;
  object-fit: cover;
  transition: transform .15s ease;
}
.review-photos a:hover img,
.review-photos a:focus-visible img { transform: scale(1.06); }
@media (max-width: 480px) {
  .review-photos img { width: 72px; height: 72px; }
}

/* Blog */
.post-date { color: var(--steel); font-size: .82rem; }
.post-card h2 { font-size: 1.1rem; }
.post-card h2 a { color: var(--ink); text-decoration: none; }
.post-card h2 a:hover { color: var(--green-deep); }
/* Les visuels d'article viennent de la mediatheque WordPress en pleine
   resolution (2560 px de large) : sans plafond de hauteur, la couverture
   occupe deux ecrans avant le premier paragraphe. */
.post-cover {
  border-radius: var(--radius); margin-bottom: 1.5rem;
  width: 100%; max-height: 420px; object-fit: cover;
}
.post-card img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius); margin-bottom: .9rem; }
.blog-post { padding: var(--section-pad) 1.25rem; }
.blog-list { padding: var(--section-pad) 1.25rem; }

/* Corps d'article. Les 10 articles importes de WordPress (bin/import_blog.php)
   apportent des intertitres, des listes, des citations et surtout des TABLEAUX
   comparatifs — sans regle dediee, un <table> s'affiche colonnes collees et sans
   filet, ce qui rend les comparatifs materiaux/procedes illisibles. */
.blog-post .prose { max-width: 46em; }
.blog-post .prose h2 {
  font-family: var(--font-brand); font-size: 1.5rem; font-weight: 700;
  color: var(--ink); margin: 2.2rem 0 .8rem; line-height: 1.25;
}
.blog-post .prose h3 { font-family: var(--font-brand); font-size: 1.15rem; font-weight: 700; margin: 1.8rem 0 .6rem; }
.blog-post .prose h4 { font-family: var(--font-brand); font-size: 1rem; font-weight: 700; margin: 1.4rem 0 .5rem; }
.blog-post .prose li { margin: 0 0 .45em; }
.blog-post .prose ol { padding-left: 1.2em; }
.blog-post .prose a { color: var(--green-deep); }
.blog-post .prose img { border-radius: var(--radius); margin: 1.6rem 0; }
.blog-post .prose figure { margin: 1.6rem 0; }
.blog-post .prose figcaption { color: var(--muted); font-size: .85rem; margin-top: .4rem; }
.blog-post .prose hr { border: 0; border-top: 1px solid var(--line); margin: 2.2rem 0; }
.blog-post .prose blockquote {
  margin: 1.6rem 0; padding: 1rem 1.2rem;
  background: var(--surface-alt); border-left: 3px solid var(--green);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.blog-post .prose blockquote p:last-child { margin-bottom: 0; }

/* Le tableau deborde sur mobile : il defile dans son propre conteneur plutot
   que d'elargir la page (regle du projet : jamais de scroll horizontal du body). */
.blog-post .prose table {
  border-collapse: collapse; margin: 1.6rem 0; font-size: .92rem;
  /* display:block + max-content : le tableau prend la largeur de son contenu
     dans la limite de la colonne, et defile dans sa propre boite au-dela. */
  display: block; overflow-x: auto; width: max-content; max-width: 100%;
}
.blog-post .prose th,
.blog-post .prose td { border: 1px solid var(--line); padding: .6rem .75rem; text-align: left; vertical-align: top; }
.blog-post .prose th { background: var(--surface-alt); font-weight: 700; color: var(--ink); }
.blog-post .prose tbody tr:nth-child(even) { background: rgba(0, 0, 0, .015); }

/* --- Formulaires ------------------------------------------------------------ */
label { display: block; margin: .95rem 0 .3rem; font-weight: 600; font-size: .92rem; }
label .optional { font-weight: 400; color: var(--steel); }
input[type=text], input[type=email], input[type=password], input[type=tel],
select, textarea {
  width: 100%;
  padding: .6rem .75rem;
  border: 1px solid #d4d8d2;
  border-radius: var(--radius);
  font-size: 1rem;
  font-family: var(--font-brand);
  background: #fff;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--green); outline-offset: 1px; border-color: var(--green); }
.hint { color: var(--steel); font-size: .85rem; margin: .25rem 0 0; }
.field-error { color: var(--danger); font-size: .85rem; margin: .25rem 0 0; }
.form-row { display: flex; gap: 1rem; }
.form-row > div { flex: 1; }
@media (max-width: 580px) { .form-row { flex-direction: column; gap: 0; } }
fieldset {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem 1.4rem;
  margin: 0 0 1.5rem;
  background: #fff;
}
legend { font-weight: 700; padding: 0 .5rem; font-size: .95rem; }
label.checkbox, label.radio { font-weight: 400; display: flex; gap: .5rem; align-items: baseline; }

/* Formulaire d'avis : l'échelle se lit d'un coup d'œil. Même grille pour
   l'en-tête (« Très bien » au-dessus du 5★, « Très mauvais » au-dessus du 1★)
   et pour chaque rangée de cases, afin que les colonnes s'alignent ; sous
   chaque case, son nuancier (liseré vert → rouge, .v5 à .v1). */
.stars-scale, .stars-input { display: grid; grid-template-columns: repeat(5, minmax(3.4rem, 4.6rem)); gap: .4rem; }
.stars-input { margin-bottom: .9rem; }
.stars-scale { font-size: .78rem; font-weight: 700; margin-bottom: .35rem; }
.stars-scale span:first-child { color: var(--green-deep); }
.stars-scale span:last-child { color: var(--danger); text-align: right; }
label.radio.star-cell {
  display: flex; justify-content: center; align-items: center; gap: .35rem;
  padding: .45rem 0 .55rem; border: 1px solid var(--line); border-radius: 8px;
  cursor: pointer; position: relative;
}
label.radio.star-cell::after {
  content: ""; position: absolute; left: .5rem; right: .5rem; bottom: .28rem;
  height: 4px; border-radius: 2px;
}
/* Par position, pas par classe : le gabarit boucle de 5★ (1re case) à 1★. */
.stars-input .star-cell:nth-child(1)::after { background: #3d7a26; }
.stars-input .star-cell:nth-child(2)::after { background: #7ecb4f; }
.stars-input .star-cell:nth-child(3)::after { background: #e0b400; }
.stars-input .star-cell:nth-child(4)::after { background: #e07b00; }
.stars-input .star-cell:nth-child(5)::after { background: #c0392b; }
.star-cell:has(input:checked) { border-color: var(--ink); background: #f4f8f1; }
@media (max-width: 480px) { .stars-scale, .stars-input { grid-template-columns: repeat(5, 1fr); } }

.alert { padding: .75rem 1rem; border-radius: var(--radius); margin: .8rem 0; }
.alert-error { background: #fdecea; color: var(--danger); }
.alert-success { background: #eaf7e6; color: var(--green-deep); }

/* Pages compte */
.auth-card { max-width: 430px; margin: 0 auto; padding: var(--section-pad) 1.25rem; }
.auth-links { margin-top: 1.2rem; font-size: .92rem; }
.auth-card .btn-primary, .contact-form .btn-primary { width: 100%; margin-top: 1.3rem; }

.account-dashboard {
  max-width: none;
  padding: var(--section-pad) 1.25rem;
}
.account-profile {
  padding: var(--section-pad) 1.25rem;
}
.account-hello {
  font-size: 1.1rem; color: var(--ink); margin: 0 0 2rem;
}
.account-nav-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0 2.5rem;
}
.account-nav-cards .card {
  text-decoration: none; color: var(--ink);
}
.account-nav-cards .card h2 {
  font-size: 1.15rem; margin: .4rem 0 .3rem;
}
.account-nav-cards .card p {
  color: var(--steel); margin: 0 0 .8rem;
}
.account-recent {
  margin: 2rem 0;
}
.account-recent h2 {
  font-size: 1.3rem; margin-bottom: 1rem;
}
.account-empty {
  color: var(--steel); margin: 1rem 0;
}
.account-logout {
  margin-top: 2.5rem;
}

/* Assistance client : le formulaire, puis l'historique des demandes. */
.account-support {
  max-width: 780px;
  padding: var(--section-pad) 1.25rem;
}
.support-form {
  margin: 1.5rem 0 1rem;
  padding: 1.5rem;
}
/* .card se soulève au survol : juste pour une tuile cliquable, désagréable
   sous un formulaire qu'on est en train de remplir. */
.support-form:hover {
  transform: none;
  border-top-color: var(--line);
}
.support-form label {
  display: block;
  margin-top: 1.2rem;
  font-weight: 600;
}
.support-form select,
.support-form textarea {
  width: 100%;
}
.support-form textarea {
  resize: vertical;
  min-height: 8rem;
}
.field-hint {
  color: var(--steel);
  font-size: .88rem;
  margin: .35rem 0 0;
}
.support-list {
  display: flex;
  flex-direction: column;
  gap: .8rem;
  margin-top: 1.5rem;
}
.support-list-item {
  padding: 1.1rem 1.25rem;
}
.support-list-item:hover {
  transform: none;
  border-top-color: var(--line);
}
.support-list-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.support-list-subject {
  font-weight: 600;
}
.support-list-meta {
  color: var(--steel);
  font-size: .88rem;
  margin: .3rem 0 .6rem;
  display: flex;
  gap: .8rem;
  flex-wrap: wrap;
}
/* Le message est du texte écrit par le client : il peut être long, et il porte
   ses propres retours à la ligne (nl2br). */
.support-list-message {
  margin: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Pastille de couleur du panier.
   Elle existait dans admin.css, employée par les écrans du catalogue — mais
   le panier est une page PUBLIQUE, qui ne charge que site.css. Posée sans sa
   règle, elle se rendait sans dimension : invisible, sans rien pour le
   signaler.
   La bordure n'est pas décorative : la première couleur du catalogue est
   « Blanc » (#FFFFFF). Sans elle, la pastille de blanc n'affiche rien du tout
   sur le fond clair de la page. */
.swatch {
  display: inline-block;
  width: .85em;
  height: .85em;
  border-radius: 50%;
  border: 1px solid var(--line);
  vertical-align: -1px;
  margin-right: .35em;
}
/* Notre réponse, sous le message du client. Le liseré vert la détache : le
   client doit voir d'un coup d'oeil qu'on lui a répondu, sans lire. */
.support-reply {
  border-left: 3px solid var(--green);
  padding-left: 1rem;
  margin-top: 1rem;
}
.support-reply-head {
  color: var(--steel);
  font-size: .85rem;
  font-weight: 600;
  margin: 0 0 .3rem;
}

.account-profile {
  max-width: 680px;
  margin: 0 auto;
}
.account-form fieldset {
  margin-bottom: 1.5rem;
}
.account-actions {
  display: flex; gap: 1rem; align-items: center; flex-wrap: wrap;
}
.quotes-list {
  display: flex; flex-direction: column; gap: .8rem; margin-top: 1.5rem;
}
.quotes-list-item {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: 1rem;
  align-items: center;
}
.btn-small { padding: .45rem .9rem; font-size: .85rem; }

/* Contact */
.contact-page { max-width: 620px; margin: 0 auto; padding: var(--section-pad) 1.25rem; }

/* Le pied de page « charte historique » (.site-footer, .footer-*) a été
   retiré le 31/07/2026 (audit) : remplacé par la copie fidèle WordPress
   (legacy-footer.html), plus rien ne l'émettait. */

/* Le champ leurre anti-robots (AntiBot::champs) : hors écran, jamais display:none
   — certains robots sautent ce qui est explicitement caché. */
.form-piege { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* --- Bannière de consentement ------------------------------------------------ */
.consent-banner {
  position: fixed;
  inset: auto 1rem 1rem 1rem;
  /* Au-dessus du chatbot (bulle 9999, fenêtre 10000) : le consentement est un
     préalable légal, rien ne doit le recouvrir (demande Marc, 29/07/2026). */
  z-index: 10001;
  max-width: 480px;
  margin-left: auto;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 30px rgba(0,0,0,.18);
  padding: 1.3rem 1.4rem;
}
.consent-banner h2 { font-size: 1.05rem; margin-bottom: .5rem; }
.consent-banner p { font-size: .9rem; color: var(--steel); margin: 0 0 1rem; }
.consent-choices label.checkbox { font-size: .92rem; margin: .3rem 0; }
.consent-actions { display: flex; gap: .7rem; margin-top: 1rem; flex-wrap: wrap; }
.consent-actions .btn { padding: .5rem 1rem; font-size: .92rem; flex: 1; }

/* Page 404 */
.error-page { padding: var(--section-pad) 1.25rem; text-align: center; }

/* L'apparition au défilement des blocs CMS (.will-appear/.is-in, posées par
   site.js sur les .blk-* de la maquette) est partie avec eux — chaîne
   entièrement inerte depuis la migration 037, retirée le 31/07/2026 des deux
   côtés (CSS + observer de site.js). Les animations des pages importées
   passent, elles, par elementor-invisible (site.js, IntersectionObserver). */

/* ===========================================================================
   --- Tunnel de commande (P4) --------------------------------------------
   Panier, checkout, paiement, confirmation, espace client commandes/devis.
   Réutilise les tokens et classes existants (.card, .btn, .alert, fieldset).
   ======================================================================== */

.cart-page, .checkout-page, .payment-page, .confirmation-page,
.account-orders, .account-order-detail, .account-quotes {
  padding: var(--section-pad) 0;
}
.cart-empty { color: var(--steel); margin: 1.5rem 0; }

/* --- Barre de progression vers le minimum de commande ----------------------
   (.cart-progress-label et .progress-fill.is-complete, sans émetteur — le
   bandeau actuel parle en .cart-fs-* et shop.js ne pose plus is-complete
   depuis la migration 087 — retirées le 31/07/2026) */
.cart-progress { margin: 1.5rem 0 2rem; }
.progress-track {
  height: 8px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: var(--green);
  border-radius: 999px;
  transition: width .3s ease;
}

/* --- Panier ------------------------------------------------------------------ */
.cart-layout {
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: 2rem;
  align-items: start;
}
@media (max-width: 900px) { .cart-layout { grid-template-columns: 1fr; } }

.cart-list { display: flex; flex-direction: column; gap: 1rem; }
.cart-item {
  display: grid;
  grid-template-columns: 84px 1fr auto;
  gap: 1rem;
  align-items: start;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
}
.cart-thumb {
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--paper);
}
.cart-item-name { margin: 0 0 .3rem; font-size: 1.02rem; }
.cart-item-specs { color: var(--steel); font-size: .85rem; margin: 0 0 .4rem; }
.cart-item-comment { color: var(--steel); font-size: .85rem; font-style: italic; margin: 0 0 .4rem; }
.cart-item-unit { font-size: .85rem; color: var(--steel); margin: 0 0 .6rem; }
.cart-item-qty-locked { font-size: .85rem; color: var(--steel); }

.qty-selector { display: inline-flex; align-items: center; border: 1px solid #d4d8d2; border-radius: var(--radius); overflow: hidden; }
.qty-btn {
  width: 32px; height: 32px;
  border: 0; background: var(--paper); cursor: pointer;
  font-size: 1.1rem; line-height: 1; color: var(--ink);
}
.qty-btn:hover { background: var(--line); }
.qty-input {
  width: 48px; height: 32px;
  border: 0; border-left: 1px solid #d4d8d2; border-right: 1px solid #d4d8d2;
  text-align: center; font-family: var(--font-mono); font-size: .9rem;
  -moz-appearance: textfield;
}
.qty-input::-webkit-outer-spin-button, .qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.cart-item-aside { display: flex; flex-direction: column; align-items: flex-end; gap: .6rem; text-align: right; }
.cart-item-total { font-size: 1.05rem; font-weight: 700; }
.cart-item-remove {
  border: 0; background: none; color: var(--danger); cursor: pointer;
  font-size: .82rem; text-decoration: underline; padding: 0;
}

.cart-summary { position: sticky; top: 5.5rem; }
.cart-summary h2 { font-size: 1.1rem; }
.cart-summary-row { display: flex; justify-content: space-between; align-items: baseline; margin: .6rem 0; }
.cart-summary .hint { margin-bottom: 1rem; }
.cart-checkout-btn { display: block; width: 100%; text-align: center; }
.cart-checkout-btn.is-disabled { background: #b9bdb6; color: #fff; cursor: not-allowed; pointer-events: none; }
.cart-quote-form { margin-top: .8rem; }
.cart-quote-btn { width: 100%; }
.cart-quote-locked { margin-top: .8rem; text-align: center; }
.cart-quote-locked .btn[disabled] { opacity: .5; cursor: not-allowed; width: 100%; }
.cart-quote-locked .hint { display: block; margin-top: .4rem; }

/* --- Checkout : 2 colonnes, récap sombre sticky ------------------------------ */
.checkout-grid {
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: 2rem;
  align-items: start;
}
@media (max-width: 992px) { .checkout-grid { grid-template-columns: 1fr; } }

.vat-check-row { display: flex; gap: .6rem; align-items: center; }
.vat-check-row input { flex: 1; }
.vat-check-row .btn { flex-shrink: 0; padding: .6rem 1rem; }

.shipping-address-card {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px dashed var(--line);
}

.shipping-options { margin-top: 1rem; display: flex; flex-direction: column; gap: .6rem; }
.shipping-option {
  display: flex;
  align-items: center;
  gap: .7rem;
  border: 1px solid #d4d8d2;
  border-radius: var(--radius);
  padding: .7rem .9rem;
  font-weight: 400;
  cursor: pointer;
}
.shipping-option:has(input:checked) { border-color: var(--green); background: #f3faf0; }
.shipping-option input { width: auto; margin: 0; }
.shipping-option-name { flex: 1; }
.shipping-option-name small { color: var(--steel); font-weight: 400; }
.shipping-option-price { font-weight: 700; }
.dropoff-pick-btn { margin: -.3rem 0 .4rem; align-self: flex-start; padding: .45rem .9rem; font-size: .88rem; }
.dropoff-chosen { font-size: .88rem; color: var(--green-deep); font-weight: 600; }

.checkout-summary {
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius);
  padding: 1.5rem 1.4rem;
  position: sticky;
  top: 5.5rem;
}
.checkout-summary h2 { color: #fff; font-size: 1.1rem; }
.checkout-summary-items { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.checkout-summary-items li { display: flex; align-items: center; gap: .7rem; font-size: .88rem; }
.checkout-summary-items img { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; flex-shrink: 0; }
.checkout-summary-item-name { flex: 1; color: #d8dcd6; }
.checkout-summary-item-name small { display: block; color: #9aa397; }
.checkout-summary-row { display: flex; justify-content: space-between; padding: .5rem 0; border-top: 1px solid rgba(255,255,255,.12); font-size: .92rem; color: #d8dcd6; }
.checkout-summary-total { font-size: 1.05rem; color: #fff; }
.checkout-summary-total strong { color: var(--green-bright); }
.checkout-summary-tax { color: #9aa397; margin: .4rem 0 1.2rem; }
.checkout-submit { display: block; width: 100%; text-align: center; }

/* --- Modale point relais ------------------------------------------------------ */
.dropoff-modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(20, 20, 20, .6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.dropoff-modal[hidden] { display: none; }
.dropoff-modal-inner {
  background: #fff;
  border-radius: var(--radius);
  padding: 1.5rem;
  max-width: 480px;
  width: 100%;
  max-height: 80vh;
  overflow-y: auto;
  position: relative;
}
.dropoff-modal-close {
  position: absolute; top: .8rem; right: .8rem;
  width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: var(--paper); font-size: 1.3rem; line-height: 1; cursor: pointer;
}
.dropoff-list { display: flex; flex-direction: column; gap: .6rem; margin-top: 1rem; }
.dropoff-item {
  display: flex; flex-direction: column; gap: .2rem;
  text-align: left; border: 1px solid var(--line); border-radius: var(--radius);
  padding: .7rem .9rem; background: #fff; cursor: pointer; font-family: var(--font-brand);
}
.dropoff-item:hover { border-color: var(--green); }
.dropoff-item span { color: var(--steel); font-size: .85rem; }
/* La carte des points (Leaflet). Une hauteur FIXE est requise : Leaflet ne
   sait pas se dimensionner dans un conteneur à hauteur auto. */
.dropoff-map { height: 260px; border-radius: var(--radius); margin-top: 1rem; overflow: hidden; }
.dropoff-item.is-active { border-color: var(--green); box-shadow: 0 0 0 1px var(--green); }

/* --- Paiement ------------------------------------------------------------------
   L'ancienne mouture (.payment-layout/-recap/-order-number/-items/-total-row/
   -methods/-card) a été retirée le 31/07/2026 (audit) : la page actuelle
   parle le vocabulaire de shop.css (payment-grid, checkout-card…). Seul
   .payment-divider survit — payment.php:39 l'emploie. */
.payment-divider { text-align: center; color: var(--steel); font-size: .85rem; margin: 0; text-transform: uppercase; letter-spacing: .08em; }

/* --- Confirmation ---------------------------------------------------------------
   Même ménage : .confirmation-pending/-success/-check/-overview/
   -payment-method/-addresses/-reassurance appartenaient à l'ancienne page
   (l'actuelle parle en confirmation-*-card, shop.css). Les .confirmation-items*
   ci-dessous VIVENT : le détail de commande de l'espace client les emploie. */

.confirmation-items-recap { background: var(--ink); color: #fff; border-radius: var(--radius); padding: 1.5rem 1.4rem; margin-bottom: 2rem; }
.confirmation-items-recap h2 { color: #fff; font-size: 1.1rem; }
.confirmation-items { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.confirmation-items li { display: flex; align-items: center; gap: 1rem; }
.confirmation-items img { width: 52px; height: 52px; object-fit: cover; border-radius: 4px; flex-shrink: 0; }
.confirmation-item-details { flex: 1; }
.confirmation-item-name { margin: 0; color: #fff; }
.confirmation-item-specs { margin: .2rem 0 0; color: #9aa397; font-size: .8rem; }
.confirmation-item-total { font-weight: 700; }
.confirmation-totals { border-top: 1px solid rgba(255,255,255,.12); padding-top: .8rem; }
.confirmation-totals > div { display: flex; justify-content: space-between; font-size: .9rem; color: #d8dcd6; padding: .25rem 0; }
.confirmation-total-ttc { font-size: 1.1rem; color: #fff; padding-top: .5rem !important; border-top: 1px solid rgba(255,255,255,.12); margin-top: .3rem; }
.confirmation-total-ttc strong { color: var(--green-bright); }

/* --- Espace client : commandes & devis ------------------------------------------ */
.orders-list { display: flex; flex-direction: column; gap: .8rem; margin-top: 1.5rem; }
.orders-list-item {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: 1rem;
  align-items: center;
  text-decoration: none;
  color: var(--ink);
}
.orders-list-item:hover { border-top-color: var(--green); }
.orders-list-date { color: var(--steel); font-size: .9rem; }
.orders-list-total { font-weight: 700; }

.quotes-list-item {
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  gap: 1rem;
  align-items: center;
}
.quotes-list-date { color: var(--steel); font-size: .9rem; }
.quotes-list-total { font-weight: 700; }
.quotes-list-actions { display: flex; gap: .6rem; }
.quotes-list-actions .btn { padding: .45rem .9rem; font-size: .85rem; }

@media (max-width: 700px) {
  .orders-list-item, .quotes-list-item { grid-template-columns: 1fr; text-align: left; }
}

.account-shipment { margin: 1.5rem 0; }
.account-back { margin-top: 2rem; }
.account-back a { font-weight: 600; }

/* Badges de statut (commandes / devis) */
.badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: .25rem .6rem;
  border-radius: 999px;
  background: var(--line);
  color: var(--steel);
}
.badge-paid, .badge-completed, .badge-active, .badge-resolved { background: #eaf7e6; color: var(--green-deep); }
.badge-pending, .badge-processing, .badge-in_progress { background: #fdf3e3; color: #b5730a; }
/* Une demande d'assistance « reçue » n'est ni en attente ni terminée : le bleu
   dit « c'est arrivé chez nous », l'ambre est réservé à ce qui est en cours. */
.badge-shipped, .badge-new { background: #e6f0fd; color: #2b5fa8; }
.badge-cancelled, .badge-refunded, .badge-failed, .badge-expired { background: #fdecea; color: var(--danger); }

/* =========================================================================
   Mini-panier — apercu du panier depuis l'en-tete (toutes les pages).
   Tiroir lateral droit + overlay ; badge de comptage sur le lien « Panier ».
   Charte boutique (noir premium / vert). Voir public/assets/js/site.js.
   ========================================================================= */
:root { --mc-vert: #60B339; --mc-vert-clair: #7ECB4F; --mc-noir: #141414; }

/* Badge de comptage sur le lien Panier de l'en-tete */
.mc-count {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 6px;
  border-radius: 999px; background: var(--mc-vert); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1; vertical-align: middle;
  font-family: "Montserrat", sans-serif;
}
.mc-count[hidden] { display: none; }

/* Overlay */
.mc-overlay {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(20, 20, 20, .5);
  opacity: 0; visibility: hidden; transition: opacity .25s ease, visibility .25s;
}
.mc-overlay.is-open { opacity: 1; visibility: visible; }

/* Tiroir */
.mc-drawer {
  position: fixed; top: 0; right: 0; z-index: 1201;
  width: 400px; max-width: 92vw; height: 100%;
  background: #fff; box-shadow: -12px 0 40px -18px rgba(20, 20, 20, .5);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .3s cubic-bezier(.4, 0, .2, 1);
  font-family: "Montserrat", sans-serif; color: var(--mc-noir);
}
.mc-overlay.is-open .mc-drawer { transform: translateX(0); }

.mc-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 22px; border-bottom: 1px solid #e5e8e1; flex: none;
}
.mc-head h2 { font-size: 16px; font-weight: 700; margin: 0; letter-spacing: -.01em; }
.mc-close {
  width: 34px; height: 34px; border: 0; background: #f6f7f4; border-radius: 50%;
  cursor: pointer; font-size: 20px; line-height: 1; color: #6b7269;
  display: grid; place-items: center;
}
.mc-close:hover { background: #ececec; color: #141414; }

.mc-body { flex: 1; overflow-y: auto; padding: 8px 0; }

/* Ligne article */
.mc-item {
  display: grid; grid-template-columns: 56px 1fr auto; gap: 14px;
  align-items: center; padding: 14px 22px; border-bottom: 1px solid #f0f1ee;
}
.mc-item img {
  width: 56px; height: 56px; object-fit: cover; border-radius: 8px;
  background: var(--mc-noir); display: block;
}
.mc-item-name { font-weight: 700; font-size: 14px; margin: 0 0 2px; overflow-wrap: anywhere; }
.mc-item-specs { color: #6b7269; font-size: 12px; margin: 0 0 3px; overflow-wrap: anywhere; }
.mc-item-qty { color: #6b7269; font-size: 12px; margin: 0; }
.mc-item-total { font-weight: 800; font-size: 14px; white-space: nowrap; }
.mc-item-total .s3d-ht { font-size: .72em; font-weight: 600; opacity: .55; margin-left: 2px; }

/* Etat vide */
.mc-empty { text-align: center; padding: 60px 24px; color: #6b7269; }
.mc-empty p { margin: 0 0 18px; font-size: 14px; }
.mc-empty .btn { display: inline-block; }

/* Pied : sous-total + actions */
.mc-foot {
  flex: none; padding: 20px 22px;
  border-top: 1px solid #e5e8e1; background: #fff;
}
.mc-subtotal {
  display: flex; justify-content: space-between; align-items: baseline;
  margin: 0 0 16px;
}
.mc-subtotal span { color: #6b7269; font-size: 13px; font-weight: 600; }
.mc-subtotal strong { font-size: 22px; font-weight: 800; }
.mc-subtotal strong .s3d-ht { font-size: .55em; font-weight: 600; opacity: .55; margin-left: 3px; }
.mc-actions { display: flex; flex-direction: column; gap: 10px; }
.mc-btn {
  display: block; width: 100%; text-align: center; border-radius: 10px;
  padding: 14px; font-family: "Montserrat", sans-serif; font-size: 14px;
  font-weight: 700; cursor: pointer; text-decoration: none; border: 0;
  transition: background .2s, border-color .2s, color .2s;
}
.mc-btn-primary {
  background: var(--mc-vert); color: #fff;
  text-transform: uppercase; letter-spacing: .04em;
}
.mc-btn-primary:hover { background: var(--mc-vert-clair); }
.mc-btn-ghost {
  background: transparent; color: var(--mc-noir); border: 1px solid #e5e8e1;
}
.mc-btn-ghost:hover { border-color: var(--mc-vert); color: #4d9a2b; }

@media (prefers-reduced-motion: reduce) {
  .mc-overlay, .mc-drawer { transition: none; }
}

/* --- Pages legacy (.wp-legacy) : pas de scroll horizontal ------------------- */
/* Le CSS Elementor capturé n'a pas de variantes mobiles pour ses effets
   décoratifs (ex. --e-transform-scale:2 + margin fixe sur /accompagnement) :
   c'est identique sur l'ancien site, dont le THÈME clippe le débordement au
   niveau du body. On reproduit ce clip ici, au niveau du wrapper legacy. */
.wp-legacy { overflow-x: hidden; overflow-x: clip; }

/* Tableaux plus larges que l'écran (filament-fdm, resine-sla, filament-ht…) :
   sans cette règle, le clip ci-dessus rendrait leurs colonnes inaccessibles.
   Même solution que le blog : le tableau défile dans sa propre boîte. */
@media (max-width: 1024px) {
  .wp-legacy table {
    display: block;
    overflow-x: auto;
    width: auto !important;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
  }
}

/* --- Tiroir de navigation mobile ------------------------------------------- */
/* L'ouverture est portée par la feuille importée (.elementor-active sur le
   bouton, cf. site.js) ; le fond gris et les couleurs des liens en viennent
   aussi. Ne manquent que les sous-menus : `.elementor-nav-menu ul {display:none}`
   les réserve au survol, geste qui n'existe pas au doigt (Elementor les dépliait
   en JS derrière un chevron). On les affiche dépliés et indentés — tout est
   atteignable d'un seul geste, et le tiroir défile déjà de lui-même
   (overflow-y: auto, max-height: 100vh) s'il dépasse la hauteur de l'écran. */
nav.elementor-nav-menu--dropdown .elementor-nav-menu ul { display: block; }
nav.elementor-nav-menu--dropdown .elementor-sub-item { padding-left: 2.4em; }

/* --- Encart de synthèse des avis (accueil) ---------------------------------- */
/* Mise en forme portée de mon-module-stl/css/avis.css : cette feuille n'entrait
   pas dans la liste blanche de l'import (elle n'est ni Elementor ni du thème),
   le bloc laissé par le greffon dans la page d'accueil se retrouvait donc sans
   aucun style — en plus de ne jamais recevoir ses données.
   Le contenu est désormais rendu côté serveur : templates/partials/reviews_summary.php. */
.sym-avis-stats-wrapper { margin: 1.5rem 0; }

.sym-avis-stats-card {
  display: block;
  max-width: 480px;
  padding: 16px 18px;
  border: 1px solid #e5e5e5;
  border-radius: 8px;
  background: #fafafa;
  color: inherit;
  text-decoration: none;
}
/* L'original était un <div role="link"> rendu cliquable en JavaScript. C'est un
   vrai lien : il fonctionne au clavier et sans script, il lui faut donc un état
   de survol et un anneau de focus visibles. */
.sym-avis-stats-card:hover { border-color: #cfcfcf; background: #f5f5f5; }
.sym-avis-stats-card:focus-visible { outline: 2px solid var(--green-deep); outline-offset: 2px; }

.sym-avis-stats-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}
.sym-avis-stats-score {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 140px;
}
.sym-avis-stats-score-criteria { margin-left: 18px; }
.sym-avis-stats-label { font-size: 12px; opacity: .8; margin-bottom: 4px; }
.sym-avis-stats-score-number { font-size: 2rem; font-weight: 700; margin-right: 8px; }
.sym-avis-stats-score-stars { font-size: 1.4rem; letter-spacing: 1px; }
.sym-avis-stats-meta { font-size: .9rem; color: #555; }
.sym-avis-stats-count { font-weight: 500; }
.sym-avis-stats-sub {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 4px 16px;
  font-size: .9rem;
  color: #333;
}

@media (max-width: 480px) {
  .sym-avis-stats-score-criteria { margin-left: 0; }
}

/* --- Pied de page importé : pas de scroll horizontal ------------------------ */
/* Même dispositif que `.wp-legacy` plus haut, étendu au pied de page.
   La règle existante ne couvrait que le CORPS des pages importées ; le pied,
   lui, appartient à la coquille et sort donc de ce périmètre. L'ancien site,
   dont le thème clippe au niveau du body, couvre les deux — d'où un
   débordement visible en préproduction et pas sur la référence.

   Mesuré sur www.symbio3d.com ET sur la préprod : à 642 px, 796 px de contenu
   pour 642 px de fenêtre. Ce n'est donc PAS une régression de la refonte, mais
   un défaut de l'original que la copie a fidèlement repris. */
.elementor-location-footer { overflow-x: hidden; overflow-x: clip; }

/* Le clip seul ferait disparaître le bouton « Contact » sous 768 px, exactement
   comme sur la référence : son conteneur est en `flex-direction: column` AVEC
   `flex-wrap: wrap` et `gap: 10%`, si bien que le bouton bascule dans une
   SECONDE COLONNE, hors écran (mesuré : left 668 px pour une fenêtre de 642).
   En interdisant ce retour à la ligne, il se replace sous le titre.
   Écart assumé avec la référence : un bouton d'appel à l'action invisible sur
   tablette n'est pas une intention de conception. */
.elementor-12754 .elementor-element-3fd8f369 > .e-con-inner { flex-wrap: nowrap; }

/* --- Espace client : suivi de commande et recommande ------------------------ */

/* Texte réservé aux lecteurs d'écran. Retiré du flux sans display:none ni
   visibility:hidden, qui le rendraient invisible aux lecteurs d'écran aussi. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Reprise du paiement d'une commande en attente : le bouton doit se détacher
   du badge de statut qui le précède. */
.order-pay-pending {
  margin: 1.5rem 0;
}

/* Frise d'avancement. Le badge de statut seul ne situe pas la commande dans le
   parcours ; la frise montre l'étape atteinte ET celles qui restent. */
.order-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  list-style: none;
  margin: 1.5rem 0;
  padding: 0;
}
.order-step {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .9rem;
  color: var(--muted);
}
/* La pastille porte l'étape ; la graisse du libellé double l'information, pour
   ne pas dépendre de la seule couleur. */
.order-step-dot {
  width: .7rem; height: .7rem;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--paper);
  flex: none;
}
.order-step.is-done { color: var(--text); }
.order-step.is-done .order-step-dot {
  background: var(--green-deep);
  border-color: var(--green-deep);
}
.order-step.is-current .order-step-label { font-weight: 600; }

.order-reorder-all { margin: 1.2rem 0; display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.order-reorder-line { margin-top: .4rem; }
.order-reorder-why { margin: .4rem 0 0; font-size: .85rem; }

/* Annonce du site (congés, délais exceptionnels…).
   En tête de page, refermable, et rendue côté serveur : posée par JavaScript
   elle apparaîtrait après coup, en décalant la page sous les yeux du visiteur.
   Elle n'est pas `position: fixed` — elle pousse le contenu plutôt que de le
   recouvrir, parce qu'on la lit une fois puis on la ferme. */
.annonce {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: var(--ink);
  color: #f0efea;
  padding: .7rem 1.25rem;
  font-size: .95rem;
}
.annonce-texte {
  margin: 0;
  flex: 1;
  min-width: 0;
}
.annonce-fermer {
  flex: none;
  background: transparent;
  border: 0;
  color: #f0efea;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 .3rem;
}
.annonce-fermer:hover { color: var(--green-bright); }
