/* ============================================================
   GÉNÉRATION JEUX BOIS — feuille de style unique
   ------------------------------------------------------------
   Deux exigences tenues ensemble :

   PREMIUM     de l'espace, de grandes photos, des titres en serif,
               une palette restreinte, des détails réguliers.
   ACCESSIBLE  contraste AA partout, corps de texte à 18 px,
               focus clavier visible, animations désactivables.

   Elles ne s'opposent pas : le haut de gamme vient de l'espace et de
   la régularité, jamais du gris clair illisible.

   IMPORTANT : aucun style ne doit être écrit dans les fichiers .ejs
   (attribut style="..."). La politique de sécurité du site (CSP)
   les bloque. Tout se passe ici.

   Sommaire
     1. Réglages et palette      7. Cartes d'articles
     2. Base et typographie      8. Fiche article et avis
     3. Utilitaires              9. Formulaires
     4. En-tête et navigation   10. Alertes
     5. Sections et titres      11. Pied de page
     6. Boutons                 12. Back-office
                                13. Responsive et préférences
   ============================================================ */


/* ---------- 1. Réglages et palette ---------- */

:root {
  /* Fonds */
  --fond:        #faf6ef;   /* crème principal */
  --fond-creme:  #f2e9da;   /* crème appuyé, sections alternées */
  --blanc:       #ffffff;
  --sombre:      #2e241b;   /* brun très foncé, sections sombres */
  --sombre-plus: #221a13;

  /* Textes — contrastes vérifiés sur le fond crème */
  --texte:       #3a2e22;   /* 11,2:1  → AAA */
  --texte-doux:  #5e4e3d;   /* 7,1:1   → AAA */
  --texte-clair: #f5efe4;   /* pour les fonds sombres */

  /* Accents.
     --accent sert aux aplats, filets et grandes surfaces.
     --accent-texte est la version foncée, seule utilisée pour du TEXTE
     et des liens : la version claire ne passerait pas le contraste AA. */
  --accent:        #b5762f;
  --accent-texte:  #8a5718;   /* 5,9:1 sur le fond crème → AA */
  --accent-clair:  #e0c391;

  --second:       #6e8b6b;   /* vert sauge, usage rare */
  --second-fonce: #4a6347;

  /* États */
  --succes:       #2f6b3f;
  --succes-fond:  #e6f0e7;
  --danger:       #a32020;   /* boutons de suppression (modération) */
  --danger-fond:  #f8e8e8;
  --info-fond:    #eae2f0;

  /* Typographie */
  --police-titre: Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
  --police-texte: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Rythme : une seule échelle d'espacements, réutilisée partout.
     C'est la régularité qui fait « soigné », plus que les couleurs. */
  --espace-xs: 8px;
  --espace-s:  16px;
  --espace-m:  28px;
  --espace-l:  48px;
  --espace-xl: 88px;

  --largeur:      1180px;
  --largeur-texte: 68ch;

  --rayon:   8px;
  --rayon-s: 5px;

  --ombre-douce: 0 2px 6px rgba(58, 46, 34, .06), 0 12px 30px rgba(58, 46, 34, .08);
  --ombre-forte: 0 4px 12px rgba(58, 46, 34, .10), 0 24px 56px rgba(58, 46, 34, .16);

  --transition: .3s ease;
}


/* ---------- 2. Base et typographie ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--police-texte);
  font-size: 18px;          /* jamais en dessous : lisibilité */
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4 {
  font-family: var(--police-titre);
  font-weight: 600;
  line-height: 1.15;
  color: var(--texte);
  margin: 0 0 var(--espace-s);
  letter-spacing: -0.01em;
}

/* clamp() : la taille s'adapte à la largeur de l'écran sans media query */
h1 { font-size: clamp(2.2rem, 5vw, 3.6rem); }
h2 { font-size: clamp(1.8rem, 3.6vw, 2.6rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); }
h4 { font-size: 1.05rem; }

p { margin: 0 0 var(--espace-s); }

a { color: var(--accent-texte); text-underline-offset: 3px; }
a:hover { color: var(--texte); }

/* Le contour de focus ne se retire JAMAIS : c'est le seul repère
   d'une personne qui navigue au clavier. */
:focus-visible {
  outline: 3px solid var(--accent-texte);
  outline-offset: 3px;
  border-radius: var(--rayon-s);
}

hr {
  border: 0;
  border-top: 1px solid rgba(58, 46, 34, .14);
  margin: var(--espace-m) 0;
}


/* ---------- 3. Utilitaires ---------- */

.contenu {
  max-width: var(--largeur);
  margin: 0 auto;
  padding: 0 var(--espace-m);
}

.contenu--etroit { max-width: 780px; }

/* Visible uniquement pour les lecteurs d'écran. */
.lecteur-ecran {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Lien « Aller au contenu » : caché jusqu'à ce qu'on l'atteigne au clavier. */
.lien-evitement {
  position: absolute;
  left: var(--espace-s);
  top: -60px;
  z-index: 100;
  background: var(--sombre);
  color: var(--texte-clair);
  padding: 12px 20px;
  border-radius: var(--rayon-s);
  transition: top var(--transition);
}
.lien-evitement:focus { top: var(--espace-s); color: var(--texte-clair); }

.chapo {
  font-size: 1.15rem;
  color: var(--texte-doux);
  max-width: var(--largeur-texte);
}

.surtitre {
  font-family: var(--police-texte);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent-texte);
  margin: 0 0 var(--espace-xs);
}

.filet {
  width: 56px;
  height: 3px;
  background: var(--accent);
  border: 0;
  border-radius: 2px;
  margin: var(--espace-s) 0 var(--espace-m);
}

.centre { text-align: center; }
.centre .chapo, .centre .filet { margin-left: auto; margin-right: auto; }

.texte-doux { color: var(--texte-doux); }


/* ---------- 4. En-tête et navigation ---------- */

.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(250, 246, 239, .96);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(58, 46, 34, .12);
}

.entete__interieur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--espace-m);
  padding-top: 14px;
  padding-bottom: 14px;
}

.marque { display: flex; align-items: center; gap: 14px; text-decoration: none; }
.marque img { height: 52px; width: auto; }
.marque__texte {
  font-family: var(--police-titre);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--texte);
  line-height: 1.2;
}
.marque__texte small {
  display: block;
  font-family: var(--police-texte);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

.navigation { display: flex; align-items: center; gap: var(--espace-m); }

.navigation a {
  font-size: .92rem;
  font-weight: 500;
  color: var(--texte);
  text-decoration: none;
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: border-color var(--transition), color var(--transition);
}
.navigation a:hover { border-bottom-color: var(--accent); }

/* La page courante est signalée par la couleur ET le trait :
   jamais par la couleur seule. */
.navigation a[aria-current="page"] {
  color: var(--accent-texte);
  border-bottom-color: var(--accent-texte);
}

/* Pas de séparateur ici : « Connexion » et le choix de la langue sont
   dans la continuité du reste du menu. */
.navigation__secondaire {
  display: flex;
  align-items: center;
  gap: var(--espace-s);
}

.compteur-panier {
  display: inline-block;
  min-width: 22px;
  padding: 1px 7px;
  margin-left: 6px;
  background: var(--accent-texte);
  color: var(--blanc);
  border-radius: 11px;
  font-size: .78rem;
  font-weight: 600;
  text-align: center;
}

/* --- Menus déroulants (langue, public visé) ---
   Ce sont des balises « details ». Le triangle que le navigateur ajoute
   par défaut est retiré : on dessine notre propre chevron. */

summary { cursor: pointer; list-style: none; }
summary::-webkit-details-marker { display: none; }  /* Safari */
summary::marker { content: ""; }                    /* les autres */

/* Le chevron : deux bords d'un carré tourné à 45°. Aucune image à
   charger, et il suit automatiquement la couleur du texte. */
.chevron {
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--transition);
  flex-shrink: 0;
}
details[open] > summary .chevron { transform: rotate(-135deg) translate(-2px, -2px); }

/* --- Choix de la langue --- */

.menu-langue { position: relative; }

/* Le bouton n'a ni fond ni bordure : ce n'est pas une action de la page,
   juste un réglage. Seul le drapeau se voit. */
.menu-langue__bouton {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px;
  border-radius: var(--rayon-s);
  color: var(--texte);
}
.menu-langue__bouton:hover { background: rgba(58, 46, 34, .07); }

.drapeau {
  width: 24px;
  height: 16px;
  border-radius: 2px;
  border: 1px solid rgba(58, 46, 34, .22);
  object-fit: cover;
  flex-shrink: 0;
}

.menu-langue__liste {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 60;
  min-width: 190px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .16);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-forte);
}
.menu-langue__liste a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--rayon-s);
  border-bottom: 0;
  font-size: .92rem;
  color: var(--texte);
  text-decoration: none;
}
.menu-langue__liste a:hover { background: var(--fond-creme); }

/* La langue active est signalée par un fond ET une puce, jamais par la
   seule couleur. */
.menu-langue__liste a[aria-current="true"] {
  background: var(--fond-creme);
  font-weight: 600;
}
.menu-langue__liste a[aria-current="true"]::after {
  content: "•";
  margin-left: auto;
  color: var(--accent-texte);
}


/* ---------- 5. Sections et titres ---------- */

/* Les hauteurs de section sont dérivées des espacements de la charte, pas
   saisies en pixels : le facteur 0,7 (−30 %) reste lisible, et le jour où
   --espace-xl bouge, toutes les sections suivent ensemble. */
.section { padding: calc(var(--espace-xl) * .7) 0; }
.section--serree { padding: calc(var(--espace-l) * .7) 0; }
.section--creme { background: var(--fond-creme); }

.section--sombre {
  background: var(--sombre);
  color: var(--texte-clair);
}
.section--sombre h1,
.section--sombre h2,
.section--sombre h3 { color: var(--texte-clair); }
.section--sombre .chapo { color: rgba(245, 239, 228, .78); }
.section--sombre .surtitre { color: var(--accent-clair); }
.section--sombre a { color: var(--accent-clair); }

.entete-section { margin-bottom: var(--espace-l); }

/* Bandeau de haut de page (boutique, prototypes, contact…) */
.banniere {
  background: var(--sombre);
  color: var(--texte-clair);
  padding: calc(var(--espace-l) * .75) 0;
  text-align: center;
}
/* Le titre de bandeau est 20 % plus petit que le h1 courant : le bandeau
   est un en-tête de page, pas la vitrine de l'accueil. Les trois valeurs
   du clamp() sont réduites d'autant pour que l'échelle reste continue. */
.banniere h1 {
  color: var(--texte-clair);
  font-size: clamp(1.76rem, 4vw, 2.88rem);
  margin-bottom: var(--espace-xs);
}
.banniere .chapo {
  color: rgba(245, 239, 228, .8);
  margin-left: auto;
  margin-right: auto;
}

.fil-ariane {
  font-size: .86rem;
  color: var(--texte-doux);
  padding: var(--espace-s) 0;
}
.fil-ariane ol { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; }
.fil-ariane li:not(:last-child)::after { content: "›"; margin-left: 8px; color: var(--accent); }

/* --- Héros de la page d'accueil --- */

.heros {
  background: linear-gradient(170deg, var(--fond-creme) 0%, var(--fond) 100%);
  padding: calc(var(--espace-xl) / 2) 0;
}
.heros__grille {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--espace-l);
  align-items: center;
}
.heros__actions { display: flex; flex-wrap: wrap; gap: var(--espace-s); margin-top: var(--espace-m); }

/* Le cadre décalé derrière la photo : un détail discret qui « habille »
   sans coûter en lisibilité. */
.cadre-photo { position: relative; }
.cadre-photo img {
  width: 100%;
  border-radius: var(--rayon);
  box-shadow: var(--ombre-forte);
  position: relative;
  z-index: 1;
}
.cadre-photo::before {
  content: "";
  position: absolute;
  inset: 18px -18px -18px 18px;
  border: 2px solid var(--accent);
  border-radius: var(--rayon);
  z-index: 0;
}

/* Les classes « etapes », « numero » et « deux-colonnes » vivaient ici :
   elles habillaient la section « Le savoir-faire » de l'accueil, retirée
   à la demande du client. Plus aucun gabarit ne les emploie, donc elles
   sont parties avec — du CSS qui ne s'applique à rien finit par être
   recopié ailleurs « puisqu'il existe ». Elles sont dans l'historique
   Git si la section revient. */

/* --- Portrait de l'artisan (page « À propos ») ---
   Le logo est posé derrière, dans un cadre photo ; le portrait carré ne
   recouvre que sa partie basse.

   Le calcul du chevauchement : le logo fait 921 × 476 px, soit une
   hauteur égale à 0,5168 fois sa largeur. Il occupe ici 90 % de la
   largeur du bloc (L). Sa hauteur vaut donc 0,5168 × 0,9 × L ≈ 0,465 × L,
   et le cinquième de cette hauteur — les 20 % que la photo doit couvrir —
   vaut 0,2 × 0,465 × L ≈ 0,093 × L. Une marge négative en pourcentage se
   calculant sur la LARGEUR du parent, c'est bien -9,3 % qu'il faut. */

.portrait {
  position: relative;
  max-width: 560px;
  margin: var(--espace-l) auto;
}

.portrait__logo {
  width: 90%;
  margin: 0 auto;
  border-radius: var(--rayon);
}
.portrait__logo img { display: block; }

/* Ici, le filet n'est pas décalé comme ailleurs sur le site : il entoure
   le logo, à égale distance des quatre côtés. 14 px et pas davantage,
   parce que sur un téléphone il ne reste qu'une quinzaine de pixels de
   marge de chaque côté — au-delà, le cadre déborderait de l'écran. */
.portrait__logo::before { inset: -14px; }

.portrait__photo {
  position: relative;
  /* Au-dessus de l'image du cadre, qui est en z-index 1. */
  z-index: 2;
  margin: -9.3% auto 0;
  width: 34%;
  aspect-ratio: 1 / 1;
  /* Le rayon extérieur inclut la bordure de 6 px : c'est ce qui donne
     exactement --rayon à l'intérieur, comme partout ailleurs. */
  border-radius: calc(var(--rayon) + 6px);
  overflow: hidden;
  box-shadow: var(--ombre-forte);
  border: 6px solid var(--fond);
}
.portrait__photo img { width: 100%; height: 100%; object-fit: cover; }
.portrait__photo .media-vide { height: 100%; }

/* --- Biographie « Voir plus » --- */

.bio__texte { white-space: pre-wrap; }

/* Un bouton qui ressemble à un lien : c'est bien un bouton, parce qu'il
   agit sur la page et ne mène nulle part. */
.lien-texte {
  font: inherit;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-texte);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.lien-texte:hover { color: var(--texte); }

.bloc {
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .10);
  border-radius: var(--rayon);
  padding: var(--espace-m);
  box-shadow: var(--ombre-douce);
}
.bloc h3 { margin-bottom: var(--espace-xs); }
.bloc p:last-child { margin-bottom: 0; }

.section--sombre .bloc {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(224, 195, 145, .28);
  box-shadow: none;
}
.section--sombre .bloc p { color: rgba(245, 239, 228, .78); }


/* ---------- 6. Boutons ---------- */

.bouton {
  display: inline-block;
  padding: 14px 30px;
  font-family: inherit;
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  border: 2px solid var(--accent-texte);
  border-radius: var(--rayon-s);
  background: transparent;
  color: var(--accent-texte);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), transform var(--transition);
}
.bouton:hover { background: var(--accent-texte); color: var(--blanc); transform: translateY(-2px); }

.bouton--principal { background: var(--accent-texte); color: var(--blanc); }
.bouton--principal:hover { background: var(--texte); border-color: var(--texte); }

.bouton--sombre { background: var(--sombre); border-color: var(--sombre); color: var(--texte-clair); }
.bouton--sombre:hover { background: var(--accent-texte); border-color: var(--accent-texte); }

.bouton--petit { padding: 9px 18px; font-size: .88rem; border-width: 1px; }

.bouton--bloc { display: block; width: 100%; }

/* Publier un avis : vert. Supprimer : rouge (demandé par le client).
   Le mot du bouton dit toujours l'action : la couleur ne porte jamais
   l'information à elle seule. */
.bouton--succes { background: var(--succes); border-color: var(--succes); color: var(--blanc); }
.bouton--succes:hover { background: #24522f; border-color: #24522f; }

.bouton--danger { background: var(--danger); border-color: var(--danger); color: var(--blanc); }
.bouton--danger:hover { background: #7d1818; border-color: #7d1818; }

/* « Nouveau produit » et « Nouveau prototype », partout dans le
   back-office : même vert, même aspect. C'est la seule action qui
   crée quelque chose, elle mérite d'être reconnaissable d'une page à
   l'autre — et son libellé dit toujours ce qu'elle fait. */
.bouton--nouveau { background: var(--succes); border-color: var(--succes); color: var(--blanc); }
.bouton--nouveau:hover { background: #24522f; border-color: #24522f; }

.bouton--discret {
  border-color: rgba(58, 46, 34, .28);
  color: var(--texte-doux);
}
.bouton--discret:hover { background: var(--texte-doux); border-color: var(--texte-doux); color: var(--blanc); }

.groupe-boutons { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.groupe-boutons--centre { justify-content: center; }

/* --- Téléphone et e-mail, côte à côte ---
   En version vitrine, ces deux boutons remplacent le formulaire de
   contact : ce sont les seules façons de joindre l'atelier, ils
   méritent de l'air. L'écart de 12 px des autres groupes les collait
   l'un à l'autre et donnait à lire un seul bloc au lieu de deux
   choix. */
.boutons-contact {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--espace-m);
}

/* Une fois empilés, l'écart horizontal devient un écart vertical, et
   il doit être franc : deux boutons pleine largeur qui se touchent
   sont deux cibles voisines que le pouce confond. */
@media (max-width: 560px) {
  .boutons-contact { flex-direction: column; align-items: stretch; gap: var(--espace-s); }
  .boutons-contact .bouton { width: 100%; }
}

/* Bouton isolé sous une grille, centré et détaché du contenu. */
.actions-centrees { margin-top: var(--espace-l); text-align: center; }

.section--sombre .bouton {
  border-color: var(--accent-clair);
  color: var(--accent-clair);
}
.section--sombre .bouton:hover { background: var(--accent-clair); color: var(--sombre); }


/* ---------- 7. Cartes d'articles ---------- */

.grille-articles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: var(--espace-m);
}

.carte {
  display: flex;
  flex-direction: column;
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .10);
  border-radius: var(--rayon);
  overflow: hidden;
  box-shadow: var(--ombre-douce);
  transition: transform var(--transition), box-shadow var(--transition);
}
.carte:hover { transform: translateY(-4px); box-shadow: var(--ombre-forte); }

.carte__media {
  aspect-ratio: 4 / 3;
  background: var(--fond-creme);
  overflow: hidden;
}
.carte__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.carte:hover .carte__media img { transform: scale(1.04); }

/* Article sans photo : un aplat sobre plutôt qu'une image cassée. */
.media-vide {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: repeating-linear-gradient(115deg, #e6d9c4 0 16px, #ded0b8 16px 32px);
  color: var(--texte-doux);
  font-size: .85rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.carte__corps { padding: var(--espace-m); display: flex; flex-direction: column; flex: 1; }
.carte__corps h3 { margin-bottom: 6px; }
.carte__corps h3 a { color: var(--texte); text-decoration: none; }
.carte__corps h3 a:hover { color: var(--accent-texte); }
/* « margin-top: auto » pousse le résumé vers le BAS de la carte : quel
   que soit le nombre de lignes du titre, tous les résumés d'une même
   rangée s'alignent juste au-dessus du prix. */
.carte__resume { color: var(--texte-doux); font-size: .95rem; margin-top: auto; }

.carte__pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--espace-s);
  flex-wrap: wrap;
  margin-top: var(--espace-s);
  padding-top: var(--espace-s);
  border-top: 1px solid rgba(58, 46, 34, .12);
}

/* Le bouton d'une carte SANS PRIX occupe toute la largeur du pied.
   Seul et calé à gauche, il donnait une rangée de cartes aux boutons
   de largeurs différentes selon la longueur du libellé — c'est ce
   genre d'irrégularité qui fait « amateur ». « flex-basis: 100 % »
   est nécessaire en plus de la largeur : dans un conteneur flex, la
   base d'un élément reste sa taille naturelle. */
.carte__pied .bouton--bloc { flex: 1 0 100%; }

.prix {
  font-family: var(--police-titre);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--texte);
}

.etiquette {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.etiquette--prototype { background: var(--fond-creme); color: var(--accent-texte); border: 1px solid var(--accent); }
.etiquette--attente   { background: var(--info-fond);  color: #4a2f66; }
/* « Non lu » : du rouge, mais pas de pastille pleine — elle attirait
   l'œil plus que le nom de la personne qui a écrit. Sans fond, le
   retrait horizontal n'a plus lieu d'être. */
.etiquette--non-lu    { background: none; color: var(--danger); padding-left: 0; padding-right: 0; }
.etiquette--publie    { background: var(--succes-fond); color: var(--succes); }
.etiquette--refuse    { background: var(--danger-fond); color: var(--danger); }


/* ---------- 8. Fiche article et avis ---------- */

.fiche {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: var(--espace-l);
  align-items: start;
}

.fiche__photo img { width: 100%; border-radius: var(--rayon); box-shadow: var(--ombre-forte); }
.fiche__photo .media-vide { aspect-ratio: 4 / 3; border-radius: var(--rayon); }

.fiche__prix {
  font-family: var(--police-titre);
  font-size: 2.2rem;
  font-weight: 600;
  margin: var(--espace-s) 0;
}

/* Liste de définitions : chaque paire dt/dd est groupée dans un <div>,
   seule façon valide de les mettre côte à côte dans un <dl>. */
.caracteristiques { margin: var(--espace-m) 0; padding: 0; }
.caracteristiques > div {
  display: flex;
  justify-content: space-between;
  gap: var(--espace-s);
  padding: 11px 0;
  border-bottom: 1px solid rgba(58, 46, 34, .12);
  font-size: .95rem;
}
/* Les intitulés ne se coupent pas : « Convient à » renvoyait son « à »
   tout seul à la ligne sur mobile, et la ligne devenait illisible. Ils
   sont tous courts, la valeur en face a toute la place de passer à la
   ligne à leur place. */
.caracteristiques dt { color: var(--texte-doux); white-space: nowrap; }
.caracteristiques dd { margin: 0; font-weight: 500; text-align: right; }

/* --- Notes en étoiles ---
   Les étoiles sont décoratives (aria-hidden) : la note est toujours
   écrite en toutes lettres à côté, pour les lecteurs d'écran et pour
   les personnes qui distinguent mal les formes. */
.etoiles { color: var(--accent); letter-spacing: 2px; font-size: 1.1rem; }
.etoiles--grand { font-size: 1.5rem; }

.note-ligne { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: var(--espace-s); }
.note-ligne .detail { color: var(--texte-doux); font-size: .92rem; }

.liste-avis { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--espace-s); }

.avis {
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .10);
  border-radius: var(--rayon);
  padding: var(--espace-m);
}
.avis__entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--espace-s);
  flex-wrap: wrap;
  margin-bottom: var(--espace-xs);
}
.avis__auteur { font-weight: 600; }
.avis__date { color: var(--texte-doux); font-size: .86rem; }
/* pre-wrap : conserve les retours à la ligne saisis, sans autoriser de HTML */
.avis__texte { margin: 0; white-space: pre-wrap; }

/* Les boutons d'une fiche — modération d'un avis, message reçu — sont
   détachés du texte qu'ils concernent et espacés entre eux. Sans cette
   règle, les « formulaire-en-ligne » se collaient au commentaire et
   entre eux, et on cliquait sur « Refuser » en visant « Publier ». */
.avis .actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: var(--espace-m);
}

/* Le message reçu, encadré : sur la page des messages, le texte du
   visiteur suivait la liste de ses coordonnées sans rien pour l'en
   séparer, et on ne voyait plus où il commençait. */
.message-recu { margin-top: var(--espace-s); }
.message-recu__libelle {
  display: block;
  margin-bottom: 6px;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--texte-doux);
}
.message-recu__texte {
  margin: 0;
  white-space: pre-wrap;
  padding: var(--espace-s);
  background: var(--fond-creme);
  border-left: 3px solid var(--accent);
  border-radius: var(--rayon-s);
}

/* Un deuxième titre dans une même section a besoin d'air au-dessus,
   sinon il colle au paragraphe précédent (« Caractéristiques » juste
   après la description). */
.titre-suivant { margin-top: var(--espace-l); }


/* ---------- 8 bis. Panier ----------
   Une liste, pas un tableau : sur un téléphone, un tableau de quatre
   colonnes oblige à faire défiler la page latéralement. Ici, chaque
   ligne passe simplement en colonne sous 620 px. */

.panier-lignes { list-style: none; margin: 0 0 var(--espace-m); padding: 0; display: grid; gap: var(--espace-s); }

.panier-ligne {
  display: grid;
  grid-template-columns: 140px 1fr auto;
  gap: var(--espace-s);
  align-items: center;
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .10);
  border-radius: var(--rayon);
  padding: var(--espace-s);
  box-shadow: var(--ombre-douce);
}

.panier-ligne__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--rayon-s);
  display: block;
}
.panier-ligne__media .media-vide { aspect-ratio: 4 / 3; border-radius: var(--rayon-s); font-size: .8rem; }

.panier-ligne__nom { font-size: 1.25rem; margin-bottom: 2px; }
.panier-ligne__nom a { color: var(--texte); text-decoration: none; }
.panier-ligne__nom a:hover { color: var(--accent-texte); text-decoration: underline; }
.panier-ligne__unite { color: var(--texte-doux); font-size: .92rem; margin-bottom: var(--espace-xs); }

.panier-ligne__total {
  font-family: var(--police-titre);
  font-size: 1.4rem;
  font-weight: 600;
  margin: 0;
  white-space: nowrap;
}

.panier-quantite { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.panier-quantite form { display: inline; }

/* Cible d'au moins 44 px : c'est le minimum confortable au doigt et
   pour une main qui tremble. */
.bouton-quantite {
  width: 44px;
  height: 44px;
  font-size: 1.4rem;
  line-height: 1;
  background: var(--fond-creme);
  color: var(--texte);
  border: 1px solid rgba(58, 46, 34, .25);
  border-radius: var(--rayon-s);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
}
.bouton-quantite:hover { background: var(--accent-clair); border-color: var(--accent); }

.panier-quantite__valeur {
  font-weight: 700;
  font-size: 1.15rem;
  min-width: 2ch;
  text-align: center;
}

.panier-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--espace-s);
  padding-top: var(--espace-s);
  border-top: 2px solid var(--accent);
  font-family: var(--police-titre);
  font-size: 1.5rem;
}
.panier-total strong { font-size: 2rem; }
.panier-total__note { font-size: .92rem; margin-top: var(--espace-xs); }

/* Le paiement en ligne à venir : une information, pas un avertissement.
   Le filet accentué suffit à la détacher du récapitulatif. */
.panier-paiement {
  margin-top: var(--espace-m);
  padding: var(--espace-s) var(--espace-m);
  background: var(--fond-creme);
  border-left: 4px solid var(--accent);
  border-radius: var(--rayon-s);
}


/* ---------- 9. Formulaires ---------- */

.formulaire { display: grid; gap: var(--espace-s); max-width: 640px; }
.formulaire--large { max-width: none; }

.champ { display: grid; gap: 6px; }

/* « champ__libelle » sert là où un vrai <label> serait invalide : au-dessus
   d'un groupe de boutons radio, ou d'une information non modifiable. */
.champ label,
.champ__libelle { font-weight: 600; font-size: .95rem; }

.champ .indice { font-size: .86rem; color: var(--texte-doux); }

.champ .facultatif { font-weight: 400; color: var(--texte-doux); }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], input[type="tel"],
select, textarea {
  font-family: inherit;
  font-size: 1rem;
  padding: 12px 14px;
  border: 1px solid rgba(58, 46, 34, .28);
  border-radius: var(--rayon-s);
  background: var(--blanc);
  color: var(--texte);
  width: 100%;
  transition: border-color var(--transition), box-shadow var(--transition);
}
input:hover, select:hover, textarea:hover { border-color: rgba(58, 46, 34, .45); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent-texte);
  box-shadow: 0 0 0 3px rgba(138, 87, 24, .16);
}

textarea { min-height: 190px; resize: vertical; line-height: 1.6; }

/* Champ en erreur : bordure ET message écrit, jamais la couleur seule. */
.champ--erreur input,
.champ--erreur select,
.champ--erreur textarea { border-color: var(--danger); }
.message-erreur { color: var(--danger); font-size: .9rem; font-weight: 500; }

.cases { display: grid; gap: 10px; }
.case { display: flex; align-items: flex-start; gap: 10px; font-weight: 400; }
.case input { width: auto; margin-top: 4px; flex-shrink: 0; }

/* Le piège à robots : invisible à l'écran, ignoré des lecteurs d'écran
   (aria-hidden dans le HTML), mais rempli par les robots à formulaire. */
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.formulaire__actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: var(--espace-xs); }

/* Les liens de sortie d'un formulaire (« mot de passe oublié »,
   « pas encore de compte ») : sous le bouton, empilés, jamais à côté de
   l'action principale — deux actions sur une même ligne se disputent le
   regard, et la moins importante gagne une fois sur deux. */
.liens-formulaire {
  display: grid;
  justify-items: start;
  gap: var(--espace-xs);
  margin-top: var(--espace-m);
}

/* --- Panneau de filtres de la boutique ---
   Il n'y a pas de bouton « Appliquer » quand JavaScript est actif : les
   filtres partent une demi-seconde après la dernière saisie. */

.filtres {
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .12);
  border-radius: var(--rayon);
  padding: var(--espace-m);
  box-shadow: var(--ombre-douce);
  margin-bottom: calc(var(--espace-l) * .75);
}
.filtres__grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--espace-s);
  align-items: end;
}
.filtres__entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--espace-s);
}
.filtres h2 { font-size: 1.2rem; margin-bottom: var(--espace-s); }

/* Les deux boutons du repli mobile n'existent pas sur grand écran. */
.filtres__bascule,
.filtres__fermer { display: none; }

.voile { display: none; }

/* --- Liste de choix (le public visé) ---
   Un bouton ouvre la liste ; cliquer sur une ligne coche le bouton
   radio correspondant, et le formulaire part tout seul. */

.menu-choix { position: relative; }

.menu-choix__bouton {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--espace-xs);
  padding: 12px 14px;
  border: 1px solid rgba(58, 46, 34, .28);
  border-radius: var(--rayon-s);
  background: var(--blanc);
  color: var(--texte);
  font-size: 1rem;
  line-height: 1.3;
  transition: border-color var(--transition);
}
.menu-choix__bouton:hover { border-color: rgba(58, 46, 34, .45); }
.menu-choix[open] .menu-choix__bouton { border-color: var(--accent-texte); }

.menu-choix__liste {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  z-index: 40;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px;
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .16);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-forte);
}

.menu-choix__option {
  display: block;
  padding: 9px 12px;
  border-radius: var(--rayon-s);
  font-size: .95rem;
  font-weight: 400;
  cursor: pointer;
}
.menu-choix__option:hover { background: var(--fond-creme); }

/* Le bouton radio lui-même est masqué à l'écran, mais reste dans la page :
   il garde le focus clavier et sa nature de bouton radio pour les
   lecteurs d'écran. Le choix courant est marqué par un fond ET une
   coche — jamais par la couleur seule. */
.menu-choix__option input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.menu-choix__option:has(input:checked) {
  background: var(--fond-creme);
  font-weight: 600;
}
.menu-choix__option:has(input:checked)::after {
  content: " ✓";
  color: var(--accent-texte);
}
.menu-choix__option:has(input:focus-visible) {
  outline: 3px solid var(--accent-texte);
  outline-offset: 2px;
}

.resultats-nombre { color: var(--texte-doux); margin-bottom: var(--espace-m); }

.vide {
  text-align: center;
  padding: var(--espace-xl) var(--espace-m);
  color: var(--texte-doux);
  background: var(--blanc);
  border: 1px dashed rgba(58, 46, 34, .22);
  border-radius: var(--rayon);
}


/* ---------- 10. Alertes ---------- */

.alerte {
  padding: var(--espace-s) var(--espace-m);
  border-radius: var(--rayon-s);
  border-left: 4px solid;
  margin-bottom: var(--espace-m);
}
.alerte p:last-child { margin-bottom: 0; }
.alerte--succes { background: var(--succes-fond); border-color: var(--succes); color: #1f4a2c; }
.alerte--erreur { background: var(--danger-fond); border-color: var(--danger); color: #7d1818; }
.alerte--info   { background: var(--fond-creme);  border-color: var(--accent); color: var(--texte); }

/* Encadré de confirmation avant une suppression définitive. */
.confirmation {
  background: var(--danger-fond);
  border: 2px solid var(--danger);
  border-radius: var(--rayon);
  padding: var(--espace-m);
  max-width: 640px;
}
.confirmation h2 { color: #7d1818; }

/* --- « Mon compte » ---
   Quatre blocs indépendants les uns sous les autres. Chaque section se
   termine par un bouton, et le titre suivant arrivait juste derrière :
   on ne distinguait plus « Enregistrer le nom » de « Mot de passe ».
   Un même écart partout — celui de la charte — suffit à les séparer. */
.page-compte .formulaire { margin-bottom: var(--espace-l); }
.page-compte h2 { margin-top: var(--espace-l); }
.page-compte .liste-avis { margin-bottom: var(--espace-l); }

/* La déconnexion et la suppression sont deux gestes sans rapport : le
   second est définitif, il ne doit pas se trouver sous le doigt de qui
   visait le premier. */
.page-compte .actions-centrees { margin-bottom: var(--espace-l); }
.page-compte .confirmation { margin-top: var(--espace-l); }

/* L'écart est porté par l'encadré lui-même : son titre, lui, doit
   rester calé en haut de la zone rouge. */
.page-compte .confirmation h2 { margin-top: 0; }

/* La liste des champs manquants, dans le bandeau des mentions légales.
   Sans ce retrait, les puces débordent sur le liseré de gauche. */
.alerte ul { margin: 0 0 0 var(--espace-m); padding: 0; }
.alerte li { margin-bottom: 4px; }
.alerte li:last-child { margin-bottom: 0; }


/* ---------- 10 bis. Fiche d'identité légale ----------

   Les mentions légales sont une suite de « libellé : valeur ». Une liste
   de définitions le dit dans le balisage, ce qu'un lecteur d'écran
   restitue — un tableau ou une suite de paragraphes ne le diraient pas.

   Deux colonnes dès qu'il y a la place, une seule sur mobile : à
   320 px, « Immatriculation » et sa valeur ne tiennent pas côte à côte
   sans se couper en plein milieu d'un mot. */
.fiche-legale {
  display: grid;
  grid-template-columns: minmax(180px, 14rem) 1fr;
  gap: var(--espace-xs) var(--espace-m);
  margin: 0 0 var(--espace-l);
}
.fiche-legale dt {
  font-weight: 600;
  color: var(--texte-doux);
}
.fiche-legale dd {
  margin: 0;
  /* Un SIRET ou une adresse d'hébergeur n'a pas de point de coupure
     naturel : sans cela, il élargit la page sur un petit écran. */
  overflow-wrap: anywhere;
}

/* Une information encore absente. Elle est signalée par le mot ET par
   la couleur : la couleur seule ne dit rien à qui ne la perçoit pas,
   et rien ici ne doit pouvoir passer inaperçu. */
.a-completer {
  color: var(--danger);
  font-style: italic;
}

@media (max-width: 640px) {
  .fiche-legale { grid-template-columns: 1fr; gap: 2px; }
  .fiche-legale dd { margin-bottom: var(--espace-s); }
}


/* ---------- 11. Pied de page ---------- */

.pied {
  background: var(--sombre-plus);
  color: rgba(245, 239, 228, .74);
  padding: var(--espace-l) 0 var(--espace-m);
  font-size: .95rem;
  margin-top: auto;
}
.pied__grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--espace-m);
  padding-bottom: var(--espace-m);
  border-bottom: 1px solid rgba(224, 195, 145, .18);
}
.pied h2 {
  font-family: var(--police-texte);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-clair);
  margin-bottom: var(--espace-s);
}
.pied ul { list-style: none; margin: 0; padding: 0; }
.pied li { padding: 4px 0; }
.pied a { color: rgba(245, 239, 228, .8); text-decoration: none; }
.pied a:hover { color: var(--accent-clair); text-decoration: underline; }
.pied__bas {
  padding-top: var(--espace-s);
  text-align: center;
  font-size: .84rem;
  color: rgba(245, 239, 228, .5);
}

/* Colle le pied de page en bas même sur une page très courte. */
body { display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; }


/* ---------- 12. Back-office ---------- */
/* Volontairement sobre : c'est un outil de travail, pas une vitrine. */

.admin-entete {
  background: var(--sombre);
  color: var(--texte-clair);
  padding: var(--espace-s) 0;
}
.admin-entete__interieur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--espace-m);
  flex-wrap: wrap;
}
.admin-entete h1 { color: var(--texte-clair); font-size: 1.3rem; margin: 0; }
.admin-nav { display: flex; flex-wrap: wrap; gap: var(--espace-s); }
.admin-nav a {
  color: rgba(245, 239, 228, .84);
  text-decoration: none;
  font-size: .92rem;
  padding: 6px 12px;
  border-radius: var(--rayon-s);
}
.admin-nav a:hover { background: rgba(255, 255, 255, .1); color: var(--texte-clair); }
.admin-nav a[aria-current="page"] { background: var(--accent-texte); color: var(--blanc); }

.cartes-chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--espace-s); }
.carte-chiffre {
  background: var(--blanc);
  border: 1px solid rgba(58, 46, 34, .12);
  border-radius: var(--rayon);
  padding: var(--espace-m);
}
.carte-chiffre .nombre {
  display: block;
  font-family: var(--police-titre);
  font-size: 2.6rem;
  font-weight: 600;
  color: var(--accent-texte);
  line-height: 1;
}
.carte-chiffre .libelle { color: var(--texte-doux); font-size: .92rem; }

.tableau-enveloppe { overflow-x: auto; }  /* le tableau défile, jamais la page */

.tableau {
  width: 100%;
  border-collapse: collapse;
  background: var(--blanc);
  border-radius: var(--rayon);
  overflow: hidden;
  box-shadow: var(--ombre-douce);
}
.tableau th, .tableau td {
  padding: 13px var(--espace-s);
  text-align: left;
  border-bottom: 1px solid rgba(58, 46, 34, .10);
  font-size: .94rem;
  vertical-align: middle;
}
.tableau th {
  background: var(--fond-creme);
  font-weight: 700;
  font-size: .82rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.tableau tr:last-child td { border-bottom: 0; }
.tableau .actions { display: flex; gap: 8px; flex-wrap: wrap; }
.tableau .miniature { width: 62px; height: 46px; object-fit: cover; border-radius: var(--rayon-s); }

/* L'aperçu de la photo, dans le formulaire d'article : la photo déjà
   enregistrée, ou celle qu'on vient de choisir.
   Volontairement grande — c'est tout l'intérêt. Une vignette de 62 px
   ne dit pas si la photo est floue, mal cadrée ou à l'envers, et c'est
   exactement ce qu'on veut voir avant de publier. */
.apercu-photo { margin: 0; }
.apercu-photo[hidden] { display: none; }

.apercu-photo__image {
  display: block;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--fond-creme);
  border: 1px solid rgba(58, 46, 34, .12);
  border-radius: var(--rayon-s);
}

.apercu-photo__legende {
  margin-top: 6px;
  font-size: .86rem;
  color: var(--texte-doux);
  /* Un nom de fichier n'a pas d'espaces où se couper : sans cela, un
     nom à rallonge élargirait le formulaire entier. */
  overflow-wrap: anywhere;
}

/* Longueur, largeur, hauteur : trois champs de même taille sur une
   ligne, qui passent l'un sous l'autre quand la place manque. */
.champs-dimensions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--espace-s);
}

.formulaire-en-ligne { display: inline; }

.onglets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espace-xs);
  margin-bottom: var(--espace-m);
  border-bottom: 1px solid rgba(58, 46, 34, .16);
}
.onglets a {
  padding: 10px 18px;
  text-decoration: none;
  color: var(--texte-doux);
  font-weight: 600;
  font-size: .94rem;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
}
.onglets a[aria-current="page"] { color: var(--accent-texte); border-bottom-color: var(--accent-texte); }


/* ---------- 13. Responsive et préférences ---------- */

/* En dessous de cette largeur, le nom du site et les six liens de
   navigation ne tiennent plus côte à côte : les liens se serreraient
   jusqu'à se toucher. L'en-tête passe donc en deux étages — la marque
   au-dessus, la navigation et le sélecteur de langue en dessous. */
@media (max-width: 1100px) {
  .entete__interieur { flex-direction: column; align-items: stretch; gap: var(--espace-s); }
  .marque { justify-content: center; }
  .navigation { flex-wrap: wrap; justify-content: center; gap: var(--espace-s); }
  .navigation__secondaire { justify-content: center; }

  /* Le menu de langue s'ouvre au centre : calé à droite, il déborderait
     maintenant que le bouton n'est plus dans le coin de la page. */
  .menu-langue__liste { right: auto; left: 50%; transform: translateX(-50%); }
}

@media (max-width: 980px) {
  :root { --espace-xl: 60px; --espace-l: 36px; }

  .heros__grille,
  .fiche { grid-template-columns: 1fr; }

  /* La photo passe sous le texte : les deux boutons se retrouveraient
     seuls, collés à gauche sous un bloc qui occupe toute la largeur.
     Centrés, ils redeviennent le point d'arrivée du regard. */
  .heros__actions { justify-content: center; }

  .pied__grille { grid-template-columns: 1fr 1fr; }

  /* Le cadre décalé déborderait sur petit écran. Celui du logo, lui,
     reste : il n'est pas décalé mais centré, il tient donc dans la
     marge disponible. */
  .cadre-photo::before { display: none; }
  .portrait__logo::before { display: block; }

  /* --- Les filtres se replient derrière un bouton flottant ---
     Sur un téléphone, le panneau de filtres occupait tout le premier
     écran et repoussait les jeux hors de vue. On le range donc, et la
     boutique s'affiche tout de suite.

     Tout cela est conditionné à « .js » : sans JavaScript, personne ne
     pourrait rouvrir le panneau, alors on le laisse déplié. */

  .js .filtres { display: none; }

  .js .filtres--ouvert {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 70;
    margin: 0;
    max-height: 86vh;
    overflow-y: auto;
    border-radius: var(--rayon) var(--rayon) 0 0;
    box-shadow: var(--ombre-forte);
  }

  .js .filtres--ouvert .filtres__fermer { display: inline-block; }

  .js .filtres__bascule {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    position: fixed;
    right: var(--espace-s);
    bottom: var(--espace-s);
    z-index: 60;
    padding: 14px 26px;
    border: 2px solid var(--sombre);
    border-radius: 999px;
    background: var(--sombre);
    color: var(--texte-clair);
    font-family: inherit;
    font-size: .95rem;
    font-weight: 600;
    box-shadow: var(--ombre-forte);
    cursor: pointer;
  }
  .js .filtres__bascule::after {
    content: "";
    width: 7px;
    height: 7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-135deg);
  }

  .filtres__fermer {
    font: inherit;
    padding: 8px 14px;
    border: 1px solid rgba(58, 46, 34, .28);
    border-radius: var(--rayon-s);
    background: var(--blanc);
    color: var(--texte-doux);
    cursor: pointer;
  }

  .voile[hidden] { display: none; }
  .voile {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(46, 36, 27, .55);
  }

  /* Le fond ne glisse plus sous les doigts pendant que le panneau
     est ouvert. */
  body.sans-defilement { overflow: hidden; }
}

@media (max-width: 700px) {
  body { font-size: 17px; }

  .pied__grille { grid-template-columns: 1fr; }
  .carte__pied { flex-direction: column; align-items: stretch; }
  .formulaire__actions .bouton { width: 100%; }

  /* Le panier passe en colonne : photo, puis jeu, puis sous-total. */
  .panier-ligne { grid-template-columns: 90px 1fr; }
  .panier-ligne__total { grid-column: 2; text-align: right; }
}

/* Respecte le réglage système « réduire les animations » : indispensable
   pour les personnes sujettes au vertige ou aux migraines. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .carte:hover, .bouton:hover, .pastille:hover { transform: none; }
}

/* Impression : on enlève ce qui ne sert à rien sur papier. */
@media print {
  .entete, .pied, .filtres, .formulaire__actions, .lien-evitement { display: none; }
  body { background: #fff; font-size: 12pt; }
  .carte, .bloc { box-shadow: none; border: 1px solid #ccc; }
}
