/* =========================================================================
   LA BEAUTÉ CACHÉE — CHARTE GRAPHIQUE GLOBALE
   ========================================================================= */

/* =====================================================================
   1. VARIABLES & BASE
   ===================================================================== */
:root {
  /* --- Couleurs officielles --- */
  --couleur-primaire: #9C0537;      /* Bordeaux / framboise — enseigne, boutons, icônes */
  --couleur-secondaire: #F0C3C8;    /* Rosé plus soutenu — footer, fonds d'accent, cartes de tarifs */
  --couleur-enseigne: #7A1C30;       /* Bordeaux profond — bandeau enseigne (titre, sous-titre, baseline) */
  --couleur-banniere-fond: #9C0538; /* Fond bordeaux exact de la bannière d'en-tête */

  /* Alias utilisés dans le reste de la feuille de style */
  --couleur-marque: var(--couleur-primaire);
  --couleur-marque-clair: #B8375A;
  --couleur-poudre: var(--couleur-secondaire);
  --couleur-dore: #C9A66B;          /* Doré discret — accents décoratifs (paquet cadeau) */

  --couleur-fond: #faf7f5;
  --couleur-carte: #ffffff;
  --couleur-texte: #2e2a2a;
  --couleur-texte-doux: #6f6666;
  --couleur-bordure: #eadfe2;
  --couleur-teinte: var(--couleur-poudre);

  --ombre-douce: 0 8px 24px rgba(156, 5, 55, 0.08);
  --ombre-hover: 0 16px 32px rgba(156, 5, 55, 0.15);
  --rayon-carte: 18px;
  --rayon-pilule: 999px;

  /* --- Polices officielles --- */
  --police-titres: 'Sacramento', cursive;         /* Enseigne « La Beauté Cachée » exclusivement */
  --police-corps: 'Montserrat', sans-serif;        /* Texte courant */
  --police-soins: 'Playfair Display', serif;       /* Noms de soins, titres de sous-sections, mentions d'offres (italique) */
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--police-corps);
  background: var(--couleur-fond);
  color: var(--couleur-texte);
  line-height: 1.6;
  /* Empêche la barre de défilement horizontale que provoqueraient les
     fonds "plein bord" du header/menu/footer (technique du box-shadow
     100vmax), sans avoir besoin de clip-path (qui rognerait aussi les
     sous-menus déroulants). */
  overflow-x: hidden;
}

a { color: inherit; }

/* =====================================================================
   2. HEADER — bandeau enseigne (logo + baseline + contact rapide) sur une
      seule ligne, inspiré de l'ancienne bannière du site, + menu responsive
   ===================================================================== */
/* Dégradé vertical du bordeaux profond (--couleur-enseigne) vers le bordeaux
   clair (--couleur-marque-clair) — valeurs de repli, reprises par
   LBC.appliquerParametresGlobaux() depuis Parametres_des_contenus.csv
   (page=global, sections couleur_header_debut / couleur_header_fin, si
   renseignées). S'étend sur tout le header (bandeau enseigne + menu), le
   menu récupère ensuite son propre fond blanc ci-dessous pour ne pas
   hériter du dégradé. */
/* position+z-index nécessaires : depuis que .menu-principal a son propre
   z-index (pour son fond "plein bord", cf. plus bas), il forme son propre
   contexte d'empilement — son sous-menu déroulant (z-index:200) ne se
   compare donc plus qu'à l'intérieur de ce contexte, pas au reste de la
   page. Sans ceci, le header entier (menu compris) redevient un simple
   élément "au fil du texte" et se fait recouvrir par tout ce qui suit dans
   le HTML (ex. le carrousel d'accueil), qui vient après lui dans l'ordre du
   DOM. Valeur (150) volontairement au-dessus de .barre-onglets (100,
   prestations.html) : sinon la barre d'onglets catégories, sticky, passe
   par-dessus le sous-menu déroulant "Prestations" et cache son dernier
   lien (Épilations) — le z-index:200 du sous-menu ne le protège pas, car
   il ne se compare qu'à l'intérieur du contexte d'empilement créé ici.
   Reste sous la modale (z-index:1000). */
.site-header {
  position: relative;
  z-index: 150;
  background: linear-gradient(to bottom, var(--couleur-enseigne) 0%, var(--couleur-marque-clair) 100%);
}

/* --- Bandeau enseigne : grille à 3 zones (enseigne gauche / baseline
   centre / contact rapide droite), alignées et centrées verticalement sur
   une seule ligne. La colonne centrale ("auto") reste toujours centrée sur
   la largeur totale car encadrée par deux colonnes "1fr" symétriques,
   quelles que soient les largeurs du bloc enseigne et du bloc contact. --- */
.header-principal {
  max-width: 1200px;
  margin: 0 auto;
  padding: 14px 20px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 20px;
  position: relative;
  /* z-index nécessaire : le menu juste en dessous (.menu-principal) déborde
     largement au-dessus de sa propre boîte à cause de son fond "plein bord"
     en box-shadow (spread 100vmax, qui s'étend dans toutes les directions,
     pas seulement horizontalement) — sans ce z-index, ce débord blanc
     recouvrirait le bandeau enseigne au lieu de s'arrêter dessous. */
  z-index: 1;
  /* Le dégradé bordeaux vient du parent .site-header (transparent ici) :
     comme .site-header n'est pas limité en largeur, il s'étend déjà d'un
     bord à l'autre de l'écran, sans avoir besoin de la technique du
     "bleed" en box-shadow (incompatible avec un dégradé). */
}

.logo-lien {
  grid-column: 1;
  justify-self: start;
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}

.logo-image {
  /* Hauteur choisie pour retrouver la même proportion logo / nom d'enseigne
     que sur la carte cadeau (68px de logo pour un nom affiché à 2.1rem/33.6px,
     ratio ~2.02) : 32px de logo-texte ici × 2.02 ≈ 65px. */
  height: 65px;
  width: auto;
  flex: none;
}

.enseigne-texte {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.15;
}

.logo-texte {
  display: inline-block;
  position: relative;
  line-height: 1;
  font-family: var(--police-titres);
  font-size: 32px;
  font-weight: 400;
  color: #ffffff;
  letter-spacing: normal;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

/* Filet sous "La Beauté Cachée", en pseudo-élément plutôt qu'en
   border-bottom : Sacramento (police script) réserve, dans sa propre boîte
   de ligne, une hauteur "descendante" bien plus grande que ce que les
   lettres dessinent réellement (mesuré : ~11px d'espace fantôme sous
   l'encre visible du texte, contre 1px de descente réelle) — un
   border-bottom classique s'accroche donc au bas de cette boîte gonflée et
   semble "flotter" loin du texte, pas centré avec "Institut de Beauté" en
   dessous. Un ::after positionné en absolu ignore cette boîte et se cale
   à une distance fixe (mesurée à l'œil) sous l'encre réelle des lettres. */
.logo-texte::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  height: 1.5px;
  background: #ffffff;
}

.logo-sous-titre {
  margin-top: 4px;
  font-family: var(--police-corps);
  font-size: 13px;
  font-weight: 700;
  color: #ffffff;
  letter-spacing: 2px;
  text-transform: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.baseline {
  grid-column: 2;
  margin: 0;
  text-align: center;
  font-family: var(--police-corps);
  font-size: 22px;
  font-weight: 700;
  color: #ffffff;
  letter-spacing: 1px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.baseline .baseline-signature {
  display: block;
  margin-top: 4px;
  font-family: var(--police-titres);
  font-style: normal;
  font-weight: 400;
  font-size: 28px;
  letter-spacing: normal;
  color: #ffffff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

/* --- Contact rapide (ex-bandeau supérieur), replié dans l'enseigne --- */
.header-contact-rapide {
  grid-column: 3;
  justify-self: end;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.topbar-lien {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #ffffff;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.3px;
  text-decoration: none;
  text-underline-offset: 2px;
  white-space: nowrap;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.topbar-lien:hover,
.topbar-lien:focus-visible { opacity: 0.85; text-decoration: underline; }

.topbar-lien .icone-mini { width: 14px; height: 14px; flex: none; }

/* Avis Google : texte au-dessus, étoiles centrées dessous */
.topbar-avis {
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}

.topbar-etoiles { color: #ffd66b; letter-spacing: 1px; font-size: 0.75rem; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); }

/* Nombre d'avis (ex. « 307 avis Google »), affiché seul au-dessus de la note et des étoiles. */
.topbar-avis-nombre { font-size: 0.72rem; font-weight: 600; color: #ffffff; opacity: 0.9; }

/* Note moyenne (ex. « 4,9 »), sur la même ligne que les étoiles, juste avant elles. */
.topbar-avis-ligne { display: inline-flex; align-items: center; gap: 4px; }
.topbar-avis-note { font-size: 0.75rem; font-weight: 600; color: #ffffff; }

/* --- Bouton burger (mobile) --- */
.menu-toggle {
  display: none;
  position: absolute;
  top: 16px;
  right: 20px;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  /* Contour qui "respire" en permanence pour inciter à déplier le menu —
     coupé dès que le menu est ouvert (.actif) ou au survol/focus, pour ne
     pas distraire une fois l'intention de l'utilisateur déjà là. */
  animation: pulsationMenuBurger 2.6s ease-in-out infinite;
}

.menu-toggle:hover,
.menu-toggle:focus-visible,
.menu-toggle.actif {
  animation: none;
  background: rgba(255, 255, 255, 0.26);
}

@keyframes pulsationMenuBurger {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); }
  50% { box-shadow: 0 0 0 6px rgba(255, 255, 255, 0); }
}

.menu-toggle span {
  display: block;
  width: 26px;
  height: 2px;
  background: #ffffff;
  transition: transform 0.25s ease, opacity 0.25s ease;
}

.menu-toggle.actif span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle.actif span:nth-child(2) { opacity: 0; }
.menu-toggle.actif span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- Menu principal --- */
.menu-principal {
  max-width: 1200px;
  margin: 6px auto 0;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 20px 10px;
  position: relative;
  z-index: 0;
  background: var(--couleur-carte);
}

/* Étend le fond blanc du menu (bordure basse comprise) jusqu'aux bords de
   l'écran, en ne débordant QUE horizontalement (top:0 / bottom:0 borne la
   hauteur exactement à celle du menu) — contrairement à un box-shadow à
   spread 100vmax, qui déborde dans toutes les directions et finit par
   "fuiter" par transparence derrière le bandeau enseigne du dessus. Un
   ::before (pas de vrais enfants) évite aussi tout risque de rogner le
   sous-menu déroulant. La bordure basse est ici (plutôt que sur
   .menu-principal directement) pour qu'elle aussi s'étende d'un bord à
   l'autre, sans quoi elle s'arrêtait net à 1200px avec un liseré bordeaux
   du bandeau visible juste au-dessus dans la zone de débord. */
.menu-principal::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
  background: var(--couleur-carte);
  border-bottom: 1px solid var(--couleur-bordure);
  z-index: -1;
}

.menu-lien {
  display: inline-block;
  padding: 6px 16px;
  border-radius: var(--rayon-pilule);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--couleur-texte);
  text-decoration: none;
  transition: background 0.2s ease, color 0.2s ease;
}

.menu-lien:hover {
  background: var(--couleur-poudre);
  color: var(--couleur-marque);
}

/* --- Sous-menus déroulants (« Prestations », « Plus ») --- */
.menu-item--dropdown { position: relative; }

.menu-lien-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  font-family: var(--police-corps);
  /* Un <button> ne reprend pas la hauteur de ligne du body comme le fait un
     <a> (les navigateurs lui appliquent leur propre line-height par défaut) :
     sans ce line-height:inherit, "Prestations"/"Plus" se retrouvaient un peu
     plus bas en hauteur totale, donc visuellement décalés vers le haut par
     rapport aux liens simples du menu. */
  line-height: inherit;
  cursor: pointer;
}

.chevron-menu {
  width: 9px;
  height: 6px;
  transition: transform 0.2s ease;
}

.menu-item--dropdown.ouvert .chevron-menu { transform: rotate(180deg); }

.sous-menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px;
  background: #fff;
  border: 1px solid var(--couleur-bordure);
  border-radius: 14px;
  box-shadow: var(--ombre-hover);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%) translateY(-6px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
  z-index: 200;
}

.menu-item--dropdown.ouvert .sous-menu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

.sous-menu-lien {
  display: block;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--couleur-texte);
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.2s ease, color 0.2s ease;
}

.sous-menu-lien:hover {
  background: var(--couleur-poudre);
  color: var(--couleur-marque);
}

@media (max-width: 860px) {
  .menu-toggle { display: flex; }

  /* La ligne unique (enseigne / baseline / contact rapide) n'a de sens
     qu'avec assez de largeur : en dessous de 860px, on repasse en colonne
     centrée et le contact rapide (déjà présent dans le menu « Plus » et
     dans le pied de page) est masqué pour garder un bandeau compact. */
  .header-principal {
    /* minmax(0, 1fr), pas juste "1fr" : "Nous contacter" (colonne 1) est
       plus large que le bloc avis (colonne 3), et un simple 1fr laisse le
       contenu le plus large pousser sa propre colonne au-delà de sa part
       équitable — les 2 colonnes latérales devenaient alors inégales, ce
       qui décalait aussi le centrage du logo/baseline (ligne au-dessus, en
       areas fusionnées sur les 3 colonnes) puisque les tracks de colonnes
       sont partagés entre toutes les lignes de la grille. minmax(0, 1fr)
       force les 2 colonnes à rester strictement égales ; un texte plus
       long que sa part déborde légèrement dans l'espace de gap voisin
       (blanc, sans collision avec le bouton burger) plutôt que d'élargir
       sa colonne. */
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    grid-template-areas:
      "logo     logo   logo"
      "baseline baseline baseline"
      "contact  toggle  avis";
    row-gap: 6px;
    padding: 16px 20px 14px;
    justify-items: center;
  }

  /* Le logo sort du flux (position absolute) pour ne plus peser dans le
     centrage : sans ça, justify-self:center centre le duo logo+texte, donc
     "La Beauté Cachée / Institut de Beauté" se retrouvait décalé vers la
     droite (le logo à sa gauche déséquilibrait le calcul). En absolute, il
     ne reste plus que .enseigne-texte comme contenu de .logo-lien, qui se
     centre alors seul sur la largeur de l'écran ; le logo est repositionné
     juste à sa gauche (12px d'écart, comme le gap desktop) et suit donc le
     texte plutôt que l'inverse. */
  .logo-lien { grid-area: logo; justify-self: center; position: relative; }
  .logo-image { position: absolute; top: 50%; right: calc(100% + 12px); transform: translateY(-50%); }
  .enseigne-texte { align-items: center; }
  .baseline { grid-area: baseline; }

  /* Le conteneur d'origine (desktop) empile "Nous contacter" et l'avis
     Google en colonne, dans un seul bloc à droite. En display:contents il
     disparaît du rendu (plus de boîte, plus de flex-column) et ses 2 liens
     enfants deviennent directement placables dans la grille du header :
     "Nous contacter" à gauche du bouton burger, l'avis Google à droite —
     aucune modification du HTML nécessaire, identique sur les 10 pages. */
  .header-contact-rapide { display: contents; }
  .topbar-lien:not(.topbar-avis) { grid-area: contact; justify-self: start; }
  .topbar-avis { grid-area: avis; justify-self: end; }

  /* Bouton burger replacé dans le flux (sous la baseline, entre les 2 liens
     ci-dessus) plutôt qu'en position absolute top-right : sinon le padding
     droit réservé pour lui désaxait le centrage du logo/baseline vers la
     gauche (le bloc de texte se centrait sur la largeur restante, pas sur
     la largeur réelle de l'écran). Ainsi le padding redevient symétrique et
     le centrage est correct pour toutes les largeurs mobiles. */
  .menu-toggle {
    grid-area: toggle;
    position: static;
  }

  .menu-principal {
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    border-bottom: none;
    padding: 10px 20px 20px;
  }

  .menu-principal.ouvert { display: flex; }

  .menu-lien { text-align: center; padding: 12px 16px; }

  .menu-lien-toggle { width: 100%; justify-content: center; }

  /* Sous-menus : accordéon empilé dans le flux du menu mobile */
  .sous-menu {
    position: static;
    top: auto;
    left: auto;
    transform: none;
    min-width: 0;
    margin-top: 2px;
    box-shadow: none;
    background: var(--couleur-fond);
    display: none;
  }

  .menu-item--dropdown.ouvert .sous-menu {
    display: flex;
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .sous-menu-lien { text-align: center; }
}

/* =====================================================================
   3. NAVIGATION À 2 NIVEAUX (onglets catégories / sous-catégories)
   ===================================================================== */
.barre-onglets {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(250, 247, 245, 0.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid #f1e5e8;
  transition: transform 0.25s ease;
}

.barre-onglets .onglets {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
}

/* Niveau 2 : masqué automatiquement si la catégorie n'a pas de sous-catégories */
.barre-onglets .onglets-niveau2 {
  padding-top: 0;
  padding-bottom: 14px;
  gap: 8px;
}

.barre-onglets .onglets-niveau2:empty { display: none; }

/* Masquage au défilement (mobile uniquement) : sur les catégories à
   sous-onglets (ex. "Les Massages"), la barre peut occuper plusieurs
   lignes et manger une bonne partie de l'écran. Un écouteur de défilement
   dans prestations.html bascule cette classe selon le sens du défilement —
   on la fait glisser hors champ en descendant, elle revient dès qu'on
   remonte. Sans effet en desktop, où la barre reste fine (une seule ligne). */
@media (max-width: 860px) {
  .barre-onglets--masquee {
    transform: translateY(-100%);
  }
}

.onglet {
  font-family: var(--police-corps);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.4px;
  padding: 10px 22px;
  border-radius: var(--rayon-pilule);
  border: 1px solid var(--couleur-bordure);
  background: #fff;
  color: var(--couleur-texte-doux);
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease,
              border-color 0.25s ease, transform 0.2s ease;
}

.onglet:hover {
  border-color: var(--couleur-marque-clair);
  color: var(--couleur-marque);
  transform: translateY(-1px);
}

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

.onglet[aria-selected="true"] {
  background: var(--couleur-marque);
  border-color: var(--couleur-marque);
  color: #fff;
  box-shadow: 0 6px 16px rgba(156, 5, 55, 0.22);
}

/* Onglets de niveau 2 : plus discrets que le niveau 1 */
.onglets-niveau2 .onglet {
  font-size: 0.74rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  padding: 7px 16px;
  background: transparent;
  border-color: transparent;
}

.onglets-niveau2 .onglet:hover {
  background: #fff;
  border-color: var(--couleur-bordure);
}

.onglets-niveau2 .onglet[aria-selected="true"] {
  background: var(--couleur-teinte);
  border-color: var(--couleur-marque);
  color: var(--couleur-marque);
  box-shadow: none;
}

/* =====================================================================
   4. SECTIONS & GRILLE
   ===================================================================== */
main {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px 80px;
}

.groupe { margin-bottom: 40px; }

/* Bandeau titre + chapô des pages éditoriales (Contact, Épilations, Le
   Hammam, L'Institut, À Découvrir, Nos Prestations…) : réglage unique de
   l'espace sous le titre de page et sous son chapô d'introduction, repris
   automatiquement partout — inutile de dupliquer ces deux règles dans le
   <style> de chaque page. */
.page-contenu h1.titre-script {
  text-align: center;
  margin: 0 0 8px;
  font-family: var(--police-titres);
  font-style: normal;
  font-weight: 400;
  font-size: 40px;
  color: #9A0033;
}
.page-chapo { text-align: center; color: var(--couleur-texte-doux); font-size: 1rem; margin: 0 0 24px; }

.groupe .eyebrow {
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 3px;
  font-size: 0.75rem;
  color: var(--couleur-texte-doux);
  margin-bottom: 4px;
}

/* Titre de sous-section réutilisable sur toutes les pages (catalogue, pages
   éditoriales, « bientôt disponible »…) : nom des soins, titres de
   sous-sections, mentions d'offres — jamais l'enseigne « La Beauté Cachée ». */
.titre-script {
  font-family: var(--police-soins);
  font-style: italic;
  font-weight: 500;
  color: var(--couleur-marque);
}

.groupe .titre-script {
  text-align: center;
  font-family: var(--police-titres);
  font-style: normal;
  font-weight: 400;
  color: #7A1C30;
  font-size: 2rem;
  margin: 0 0 24px;
}

.grille-cartes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  align-items: start;
}

/* Apparition douce au changement d'onglet */
@keyframes fondu-montant {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.panneau-anime { animation: fondu-montant 0.35s ease both; }

@media (prefers-reduced-motion: reduce) {
  .panneau-anime,
  .modal-box { animation: none; }
  .carte,
  .carte-image img,
  .barre-onglets { transition: none; }
  .astuce-paysage-mobile,
  .menu-toggle { animation: none; }
}

/* =====================================================================
   5. CARTE DE SOIN
   ===================================================================== */
.carte {
  background: var(--couleur-carte);
  border: 1px solid #d3d3d3;
  border-radius: var(--rayon-carte);
  overflow: hidden;
  box-shadow: var(--ombre-douce);
  transition: transform 0.35s ease, box-shadow 0.35s ease;
  display: flex;
  flex-direction: column;
}

.carte:hover {
  transform: translateY(-6px);
  box-shadow: var(--ombre-hover);
}

/* Le bloc image n'est créé que si la colonne image1 est renseignée */
.carte-image {
  width: 100%;
  height: 220px;
  overflow: hidden;
  background: #eee2e2;
}

.carte-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s ease;
}

.carte:hover .carte-image img { transform: scale(1.06); }

.carte-corps {
  padding: 20px 16px 22px;
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* --- Nouvelle disposition (v2, essai) : en-tête centré, photo réduite +
   liste de tarifs côte à côte, texte repliable, boutons en bas. Repli
   facile : `git checkout -- style.css prestations.html` restaure la
   disposition précédente (image pleine largeur en haut, menu déroulant,
   bouton « Détails » ouvrant une modale). --- */
/* Bandeau en dégradé rosé (même teinte que le reste du site) derrière le
   titre + sous-titre, pour qu'ils ressortent au premier coup d'œil dans la
   grille de cartes — déborde jusqu'aux bords de la carte (marges négatives
   annulant le padding de .carte-corps), les coins arrondis sont hérités du
   overflow:hidden de .carte. */
.carte-entete {
  text-align: center;
  margin: -20px -16px 8px;
  padding: 18px 16px 10px;
  background: linear-gradient(180deg, var(--couleur-poudre) 0%, #ffffff 100%);
}

.carte-corps h3 {
  margin: 0 0 4px;
  font-family: var(--police-corps);
  font-style: normal;
  font-size: 16px;
  font-weight: bold;
  color: #333333;
}

.carte-corps .sous-titre {
  margin: 0;
  font-size: 13px;
  font-weight: bold;
  color: #7A1C30;
  white-space: pre-line;
}

/* Photo (réduite) + liste des tarifs, côte à côte et de même largeur —
   s'il n'y a pas de photo, la liste occupe seule toute la largeur. */
.carte-media {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: 12px;
  align-items: start;
  margin-bottom: 14px;
}
.carte-media:not(.avec-image) { grid-template-columns: 1fr; }

.carte-media .carte-image {
  position: relative;
  width: 100%;
  height: 108px;
  border-radius: 12px;
  overflow: hidden;
  background: #eee2e2;
}

/* Marque produit (facultative, colonnes image2/legende_image2 de
   prestations.csv) : photo alignée à droite sous la description, avec une
   légende éditable, juste avant les boutons — indique l'origine des
   produits utilisés sans interrompre la lecture du texte. */
.carte-marque-bloc {
  align-self: flex-end;
  margin: 10px 0 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.carte-marque-image {
  max-width: 143px;
  max-height: 98px;
  object-fit: contain;
  border-radius: 6px;
}

/* Quand la description a un bouton « Lire la suite » visible : le bloc
   marque est déplacé (en JS, cf. ajusterRepliDescriptions) dans la ligne
   .description-pied elle-même plutôt que d'être remonté par-dessus le
   texte — ça évite tout chevauchement, quelle que soit la longueur du
   texte replié/déplié ou la présence d'un .details-note sur la même ligne.
   Les marges verticales de secours ci-dessus ne servent alors plus à rien
   (l'espacement horizontal vient du gap de .description-pied) donc on les
   annule. */
.description-pied .carte-marque-bloc {
  /* margin-left:auto (pas juste 0) : garde le bloc collé au bord droit
     même quand il passe seul à la ligne (bouton + details-note trop longs
     pour tenir sur la même ligne) — sans ça, un unique élément replié sur
     sa propre ligne flex se retrouve à gauche (justify-content:space-between
     n'a plus rien à répartir avec un seul enfant sur la ligne). */
  margin: 0 0 0 auto;
}

/* Valeurs alignées sur la ligne prestation_marque_legende de
   Parametres_des_styles.csv : sert de secours avant que le CSV ne soit
   chargé et appliqué (cf. appliquerStylesPrestations côté prestations.html). */
.carte-marque-legende {
  margin: 2px 0 0;
  font-family: 'Montserrat', sans-serif;
  font-size: 11px;
  font-style: italic;
  font-weight: normal;
  letter-spacing: 0px;
  color: #777777;
}
.carte-media .carte-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s ease;
}
.carte:hover .carte-media .carte-image img { transform: scale(1.06); }

.carte-media .tarif-zone { margin-top: 0; padding-top: 0; border-top: none; }

.description {
  font-size: 13px;
  color: #565656;
  margin-bottom: 12px;
}

.description p { margin: 0 0 12px; }
.description p:last-child { margin-bottom: 0; }

/* Liens [texte](url) saisis dans description/details du CSV (cf. enrichir
   dans prestations.html) : couleur de marque plutôt que le bleu par défaut,
   soulignage seulement au survol pour rester discret dans un texte courant. */
.description a,
.details-note a,
.modal-contenu a {
  color: var(--couleur-marque);
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: text-decoration-color 0.2s ease;
}
.description a:hover,
.details-note a:hover,
.modal-contenu a:hover {
  text-decoration-color: currentColor;
}

/* Lignes commençant par « - » dans un descriptif : puces rondes plutôt que
   le tiret brut (cf. rendreParagrapheEnHtml dans prestations.html). Mêmes
   marges que les paragraphes environnants pour un espacement homogène. */
.liste-puces { margin: 0 0 12px; padding-left: 1.15em; }
.liste-puces:last-child { margin-bottom: 0; }
.liste-puces li { margin: 0; line-height: 1.3; }

/* Description repliée sur quelques lignes (fondu en bas), avec une flèche
   pour la développer entièrement. La classe .sans-repli (posée en JS par
   ajusterRepliDescriptions, une fois la carte réellement mesurable dans le
   DOM) retire fondu + hauteur maximale sur les descriptions assez courtes
   pour tenir entièrement — sans quoi un « Lire la suite » qui ne
   développerait rien de plus apparaîtrait systématiquement. */
.description-repliable .description {
  max-height: 7.6em;
  overflow: hidden;
  position: relative;
  transition: max-height 0.35s ease;
}
.description-repliable .description p { margin: 0 0 10px; }
.description-repliable .description p:last-child { margin-bottom: 0; }
.description-repliable .description .liste-puces { margin: 0 0 10px; }
.description-repliable .description .liste-puces:last-child { margin-bottom: 0; }
.description-repliable.est-ouvert .description { max-height: 800px; }

.description-repliable .description::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.6em;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, var(--couleur-carte) 88%);
  transition: opacity 0.2s ease;
}
.description-repliable.est-ouvert .description::after { opacity: 0; }

.description-repliable.sans-repli .description {
  max-height: none;
  overflow: visible;
}
.description-repliable.sans-repli .description::after { display: none; }

/* Ligne de pied partagée : bouton « Lire la suite » à gauche, details à
   droite sur la même ligne (justify-content + margin-left:auto sur
   .details-note ci-dessous — celui-ci reste poussé à droite même quand le
   bouton est absent, ex. description assez courte pour ne pas être repliée,
   ou prestation sans description). Repasse à la ligne sur les cartes
   étroites plutôt que de laisser déborder un details trop long. */
.description-pied {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 6px;
}

.description-repliable-toggle {
  display: flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  padding: 0;
  font-family: var(--police-corps);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--couleur-marque);
  cursor: pointer;
}
.description-repliable-toggle svg { width: 9px; height: 6px; transition: transform 0.25s ease; }
.description-repliable-toggle.est-ouvert svg { transform: rotate(180deg); }

/* Details (souvent des précisions sur les tarifs) : toujours visible, jamais
   repliée, alignée à droite sur la ligne du bouton « Lire la suite »
   (cf. .description-pied ci-dessus) plutôt qu'en colonne à part sous les
   tarifs, pour ne pas faire varier la hauteur de la zone photo/tarifs d'une
   carte à l'autre et décaler le début de la description (cf. discussion
   2026-08-21). */
.details-note {
  margin-left: auto;
  text-align: right;
  font-size: 12px;
  font-style: normal;
  font-weight: bold;
  color: #7A1C30;
}
.details-note p { margin: 0; }
.details-note p + p { margin-top: 2px; }

.couleur-marque {
  color: var(--couleur-marque);
  font-weight: 500;
}

/* =====================================================================
   6. DURÉES / TARIFS
   ===================================================================== */
.tarif-zone {
  padding-top: 14px;
  border-top: 1px solid #f0e8e8;
}

/* Sélection de la durée : menu déroulant « durée — prix » sur toute la ligne
   (repli conservé — non utilisé par la disposition v2, cf. .tarif-liste
   ci-dessous, mais réutilisable si on revient à l'ancienne disposition). */
.tarif-selection { display: block; }

/* Liste de tarifs cliquables (disposition v2) : chaque ligne "durée — prix"
   est sélectionnable, la sélection active étant mise en couleur — remplace
   le menu déroulant lorsqu'il y a plusieurs tarifs. */
.tarif-liste {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}
.tarif-choix {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 6px;
  max-width: 100%;
  background: none;
  border: none;
  padding: 3px 4px;
  cursor: pointer;
  font-family: var(--police-corps);
  text-align: right;
}
/* La durée peut se réduire et passer sur 2 lignes si besoin (ex. "Dos et
   jambes 1h"), mais le prix ("90 €") garde toujours sa largeur et ne se
   coupe jamais entre le nombre et le symbole. */
.tarif-choix-duree { font-size: 14px; line-height: 1.25; color: var(--couleur-texte-doux); flex: 1 1 auto; min-width: 0; }
.tarif-choix-prix { font-size: 0.94rem; font-weight: 700; color: var(--couleur-texte-doux); white-space: nowrap; flex: 0 0 auto; }
/* Le tiret séparateur devant le prix a été retiré (cf. discussion
   2026-08-21) : une fois le prix sélectionné mis en badge plein
   (.tarif-choix.est-selectionne .tarif-choix-prix ci-dessous), le tiret se
   serait retrouvé à l'intérieur de la pilule — et supprimer le tiret
   partout plutôt que de le sortir du badge dans un seul contexte reste
   plus simple et cohérent entre les deux présentations. */
/* Sans photo, la liste de tarifs est seule sur toute la largeur de la
   carte : centrée plutôt qu'alignée à droite (l'alignement à droite n'a de
   sens que collé contre une photo à gauche). */
.carte-media:not(.avec-image) .tarif-liste { align-items: center; }
.carte-media:not(.avec-image) .tarif-choix { justify-content: center; text-align: center; }
.carte-media:not(.avec-image) .tarif-choix-duree { flex: 0 0 auto; }
.carte-media:not(.avec-image) .tarif-ligne-unique { justify-content: center; }

.tarif-choix.est-selectionne .tarif-choix-duree { color: var(--couleur-marque-clair); }
/* Prix sélectionné : fond plein + texte blanc (inversion vidéo), pas
   seulement un changement de couleur de texte — reste distinguable en
   niveaux de gris/N&B (daltonisme y compris), où le bordeaux et le gris de
   repos ont une luminosité trop proche pour se voir. */
.tarif-choix.est-selectionne .tarif-choix-prix {
  color: #fff;
  background: var(--couleur-marque);
  padding: 2px 9px;
  border-radius: var(--rayon-pilule);
}
.tarif-choix:hover .tarif-choix-prix { color: var(--couleur-marque-clair); }
.tarif-choix.est-selectionne:hover .tarif-choix-prix { color: #fff; }

.tarif-ligne.tarif-ligne-unique { justify-content: flex-end; }

.select-duree {
  display: block;
  width: 100%;
  padding: 9px 32px 9px 12px;
  border: 1.5px solid #c2c2c2;
  border-radius: 12px;
  background-color: #fff;
  /* Chevron dessiné en SVG (couleur marque) : évite la flèche native,
     inégale d'un OS à l'autre et impossible à colorer en CSS. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%239C0537' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 11px 8px;
  font-family: var(--police-corps);
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--couleur-marque);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition: border-color 0.2s ease, border-width 0.2s ease;
}

/* Liste déroulée : rendue par l'OS, seules la couleur et le fond sont pilotables */
.select-duree option {
  color: var(--couleur-marque);
  background-color: #fff;
}

.select-duree:hover { border-color: var(--couleur-marque-clair); border-width: 2px; }

.select-duree:focus-visible {
  outline: 2px solid var(--couleur-marque);
  outline-offset: 1px;
}

/* Tarif unique : simple ligne non interactive. gap aligné sur celui de
   .tarif-choix (liste à puces, cas le plus courant, 6px) pour que la durée
   et le prix restent aussi resserrés d'une présentation à l'autre. */
.tarif-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
  padding: 4px 2px;
}

.tarif-duree {
  font-size: 14px;
  color: #777777;
}

.prix-affiche {
  font-weight: 700;
  color: var(--couleur-marque);
  font-size: 1.05rem;
  white-space: nowrap;
}

/* Repli aligné sur prestation_item_price (Parametres_des_styles.csv) : ne
   s'applique qu'aux cartes de prestations (.carte-corps), pas à
   .prix-affiche réutilisé tel quel sur la page Épilations (aucune clé CSV
   de style ne cible ce dernier, sa valeur de base ci-dessus reste donc
   volontairement inchangée). */
.carte-corps .prix-affiche {
  font-size: 15px;
  color: #7A1C30;
}

/* Mention type « *avec 20 min de massage du dos » (durée sans prix associé) */
.tarif-note {
  margin: 8px 0 0;
  font-size: 0.76rem;
  font-style: italic;
  color: var(--couleur-texte-doux);
}

/* Affiché lorsque aucun couple durée/prix n'est renseigné */
.tarif-absent {
  margin: 0;
  padding: 10px 14px;
  border: 1px dashed var(--couleur-bordure);
  border-radius: 12px;
  font-size: 0.82rem;
  color: var(--couleur-texte-doux);
  text-align: center;
}

/* =====================================================================
   7. ACTIONS DE CARTE
   ===================================================================== */
.actions-carte {
  margin-top: auto;
  padding-top: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.btn-reserver {
  position: relative;
  overflow: hidden;
  flex: 1 1 auto;
  background: var(--couleur-marque);
  color: #fff;
  border: none;
  padding: 9px 18px;
  border-radius: var(--rayon-pilule);
  font-family: var(--police-corps);
  font-size: 15px;
  font-weight: bold;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: background 0.25s ease, transform 0.2s ease;
  box-shadow: 0 3px 10px rgba(156, 5, 55, 0.2);
}

.btn-reserver:hover {
  background: var(--couleur-marque-clair);
  transform: translateY(-1px);
}

/* Changement de prix sur le bouton « Acheter » (déclenché en JS via
   .anime-prix, cf. majTexteAchat dans prestations.html, quand le visiteur
   choisit un autre tarif) : un bandeau opaque (::before) balaye le bouton
   de gauche à droite, recouvrant l'ancien prix puis le « reconstruisant »
   — le texte est en fait échangé en JS pile à mi-parcours, à l'instant où
   le bandeau le recouvre entièrement, donnant l'impression d'un effacement
   suivi d'une réécriture plutôt qu'un changement net. Le reflet lumineux
   (::after, effet d'origine) reste en prime, par-dessus, à la même
   vitesse. Les deux animations doivent rester synchronisées avec
   DUREE_ANIMATION_ACHAT_MS dans prestations.html. */
.btn-reserver::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--couleur-marque);
  transform: translateX(-100%);
  pointer-events: none;
}

.btn-reserver.anime-prix::before {
  animation: effacementPrixBouton 0.55s ease-out;
}

@keyframes effacementPrixBouton {
  0%   { transform: translateX(-100%); }
  50%  { transform: translateX(0%); }
  100% { transform: translateX(100%); }
}

.btn-reserver::after {
  content: "";
  position: absolute;
  top: 0;
  left: -75%;
  width: 45%;
  height: 100%;
  background: linear-gradient(115deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0) 100%);
  transform: skewX(-20deg);
  pointer-events: none;
}

.btn-reserver.anime-prix::after {
  animation: balayagePrixBouton 0.55s ease-out;
}

@keyframes balayagePrixBouton {
  from { left: -75%; }
  to { left: 130%; }
}

.btn-offrir-cadeau {
  flex: 0 0 auto;
  background: var(--couleur-poudre);
  border: 1px solid transparent;
  color: var(--couleur-marque);
  padding: 9px 18px;
  border-radius: var(--rayon-pilule);
  font-family: var(--police-corps);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: background 0.25s ease, border-color 0.25s ease;
}

.btn-offrir-cadeau:hover {
  background: #fff;
  border-color: var(--couleur-marque);
}

/* Réduits au minimum sur les cartes de prestations spécifiquement (ces
   classes sont aussi utilisées ailleurs sur le site, où la taille normale
   reste voulue — cf. .btn-reserver / .btn-offrir-cadeau ci-dessus). */
.actions-carte .btn-reserver,
.actions-carte .btn-offrir-cadeau {
  padding: 6px 12px;
  font-size: 0.72rem;
}

/* Repli aligné sur prestation_btn_acheter_petit (Parametres_des_styles.csv) :
   ne s'applique qu'au bouton « Acheter » réduit des cartes de prestations,
   pas à .btn-offrir-cadeau ci-dessus (déjà à 600 / 0.3px par sa propre
   règle de base, donc inchangé ici). */
.actions-carte .btn-reserver {
  font-weight: 600;
  letter-spacing: 0.3px;
}

.btn-details {
  align-self: center;
  flex: 0 0 auto;
  background: transparent;
  border: 1px solid var(--couleur-marque);
  color: #7A1C30;
  padding: 9px 20px;
  border-radius: var(--rayon-pilule);
  font-family: var(--police-corps);
  font-size: 12px;
  font-weight: bold;
  letter-spacing: 1px;
  text-transform: none;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease;
}

.btn-details:hover {
  background: var(--couleur-marque);
  color: #fff;
}

/* Variante réduite : bouton « Détails » affiché juste sous le sous-titre
   de la carte, au-dessus du prix (au lieu du bouton pleine taille du bas). */
.btn-details-petit {
  align-self: flex-start;
  margin: 2px 0 10px;
  padding: 4px 14px;
  font-size: 0.68rem;
}

/* =====================================================================
   8. MODALE DE RÉSERVATION / PAIEMENT
   ===================================================================== */
.modal-reservation { max-width: 480px; }

.recap-prestation {
  background: var(--couleur-teinte);
  border-radius: 14px;
  padding: 12px 18px;
  margin-bottom: 16px;
}

.recap-titre {
  margin: 0 0 4px;
  font-weight: 600;
  font-size: 1rem;
  color: var(--couleur-texte);
}

.recap-tarif {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.9rem;
}

.recap-separateur {
  color: var(--couleur-marque);
  font-weight: 700;
  font-size: 1.05rem;
}

.paiement-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--couleur-texte);
  margin: 0 0 10px;
}

.coordonnees-client { margin-bottom: 16px; }

.champs-grille {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

/* Case à cocher de consentement RGPD (liste de diffusion), sous
   .champs-grille — jamais cochée par défaut, cf. LBC.envoyerContactListeDiffusion
   dans script.js qui n'ajoute l'e-mail à la liste que si elle est cochée. */
.champ-consentement {
  margin: 12px 0 0;
  text-align: left;
}

.champ-consentement label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 0.78rem;
  color: var(--couleur-texte-doux);
  cursor: pointer;
}

.champ-consentement input[type="checkbox"] {
  flex: none;
  margin-top: 2px;
  accent-color: var(--couleur-marque);
}

.champ {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.champ label {
  font-size: 0.72rem;
  color: var(--couleur-texte-doux);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.champ-facultatif {
  text-transform: none;
  letter-spacing: normal;
  opacity: 0.7;
}

.champ input,
.champ textarea {
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid #ddc9cf;
  background: #fff;
  font-family: var(--police-corps);
  font-size: 0.88rem;
  color: var(--couleur-texte);
}

.champ textarea {
  resize: vertical;
  min-height: 90px;
}

.champ input:focus,
.champ textarea:focus {
  outline: none;
  border-color: var(--couleur-marque);
}

/* Un champ qui doit occuper toute la largeur de .champs-grille (ex. un
   message de contact), au lieu d'une des 2 colonnes habituelles. */
.champ-pleine-largeur { grid-column: 1 / -1; }

.paiement-grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 6px;
}

.paiement-carte {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 10px;
  border: 2px solid var(--couleur-bordure);
  border-radius: 14px;
  background: #fff;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
  font-family: var(--police-corps);
  text-align: center;
}

.paiement-carte:hover { border-color: var(--couleur-marque-clair); }

.paiement-carte.actif {
  border-color: var(--couleur-marque);
  background: var(--couleur-teinte);
}

.paiement-carte .icone { width: 34px; height: 34px; }

.paiement-carte span {
  font-size: 0.78rem;
  color: var(--couleur-texte);
  line-height: 1.3;
}

.paiement-carte small {
  color: var(--couleur-texte-doux);
  font-size: 0.68rem;
  font-weight: 400;
}

.paiement-detail {
  display: none;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid #f0e8e8;
}

/* Même traitement visuel que .reservation-avis (reservation.html) : encart
   en retrait, non alarmiste, pour une info pratique plutôt qu'un avertissement. */
.reservation-note-dispo {
  margin: 0 0 16px;
  padding: 12px 16px;
  background: var(--couleur-fond);
  border: 1px dashed var(--couleur-bordure);
  border-radius: var(--rayon-carte);
  font-size: 0.85rem;
  color: var(--couleur-texte-doux);
  line-height: 1.5;
}

.paiement-instruction {
  font-size: 0.88rem;
  color: var(--couleur-texte);
  margin: 0 0 14px;
  line-height: 1.5;
}

.paiement-erreur {
  font-size: 0.82rem;
  color: var(--couleur-marque);
  margin-top: 8px;
}

.btn-confirmer {
  width: 100%;
  background: var(--couleur-marque);
  color: #fff;
  border: none;
  padding: 12px 20px;
  border-radius: var(--rayon-pilule);
  font-family: var(--police-corps);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.25s ease;
}

.btn-confirmer:hover { background: var(--couleur-marque-clair); }

.btn-sms {
  display: block;
  width: 100%;
  margin-top: 10px;
  background: transparent;
  border: 1px solid var(--couleur-marque);
  color: var(--couleur-marque);
  padding: 11px 20px;
  border-radius: var(--rayon-pilule);
  font-family: var(--police-corps);
  font-size: 0.82rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease;
}

.btn-sms:hover {
  background: var(--couleur-marque);
  color: #fff;
}

#paypal-button-container { min-height: 45px; }

.reservation-confirmation {
  text-align: center;
  padding: 10px 4px 4px;
}

.confirmation-icone {
  width: 56px;
  height: 56px;
  line-height: 56px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--couleur-marque);
  color: #fff;
  font-size: 1.6rem;
}

.reservation-confirmation h4 {
  margin: 0 0 10px;
  color: var(--couleur-marque);
  font-size: 1.15rem;
}

.reservation-confirmation p {
  font-size: 0.88rem;
  margin: 0 0 10px;
  color: var(--couleur-texte);
}

.confirmation-recap {
  background: var(--couleur-teinte);
  border-radius: 10px;
  padding: 10px 14px;
}

.btn-fermer-confirmation {
  margin-top: 8px;
  background: transparent;
  border: 1px solid var(--couleur-marque);
  color: var(--couleur-marque);
  padding: 9px 24px;
  border-radius: var(--rayon-pilule);
  font-family: var(--police-corps);
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease;
}

.btn-fermer-confirmation:hover {
  background: var(--couleur-marque);
  color: #fff;
}

/* =====================================================================
   9. MODALE GÉNÉRIQUE (détails)
   ===================================================================== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(46, 33, 33, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
}

.modal-overlay.ouvert { display: flex; }

.modal-box {
  background: #fff;
  max-width: 560px;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
  border-radius: var(--rayon-carte);
  padding: 28px 32px;
  position: relative;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25);
  animation: apparition 0.3s ease;
}

@keyframes apparition {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.modal-box h3 {
  font-size: 1.3rem;
  color: var(--couleur-marque);
  margin: 0 0 14px;
  padding-right: 30px;
}

.modal-box .modal-contenu p {
  margin: 0 0 12px;
  font-size: 0.92rem;
}

.modal-fermer {
  position: absolute;
  top: 18px;
  right: 20px;
  background: none;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--couleur-texte-doux);
  cursor: pointer;
}

.modal-fermer:hover { color: var(--couleur-marque); }

/* Modale « Offrir en cadeau » par soin (prestations.html) : plus large que
   .modal-box par défaut (la carte cadeau elle-même est pensée pour un
   format large) et sans padding propre — c'est carte-cadeau.html, chargée
   dans l'iframe, qui gère déjà son propre padding et son propre défilement
   interne (cf. .modal-carte-cadeau .modal-fermer plus bas, qui doit donc
   flotter par-dessus plutôt que suivre le flux). */
.modal-carte-cadeau {
  max-width: 760px;
  height: 90vh;
  padding: 0;
  overflow: hidden;
  display: flex;
}

.modal-carte-cadeau .modal-fermer {
  background: rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
  z-index: 1;
}

#carte-cadeau-iframe {
  flex: 1;
  width: 100%;
  border: none;
}

@media (max-width: 640px) {
  .modal-carte-cadeau {
    height: 100%;
    max-height: 100vh;
    border-radius: 0;
  }
  .modal-overlay:has(.modal-carte-cadeau) { padding: 0; }
}

/* =====================================================================
   10. ÉTATS : CHARGEMENT / ERREUR / VIDE
   ===================================================================== */
.message-etat {
  text-align: center;
  padding: 60px 20px;
  color: var(--couleur-texte-doux);
  font-size: 0.95rem;
}

.message-etat.erreur { color: var(--couleur-marque); }

.message-etat code {
  background: #f0e2e6;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 0.85em;
}

.message-etat .detail-technique {
  display: block;
  margin-top: 18px;
  font-size: 0.78rem;
  color: var(--couleur-texte-doux);
}

/* Petit indicateur de chargement */
.spinner {
  width: 34px;
  height: 34px;
  margin: 0 auto 18px;
  border: 3px solid #eadfe2;
  border-top-color: var(--couleur-marque);
  border-radius: 50%;
  animation: rotation 0.9s linear infinite;
}

@keyframes rotation { to { transform: rotate(360deg); } }

/* =====================================================================
   11. FOOTER — fond poudré, 3 colonnes, bande inférieure
   ===================================================================== */
.site-footer {
  /* Dégradé rosé (valeurs de repli — reprises par LBC.appliquerParametresGlobaux()
     depuis Parametres_des_contenus.csv, page=global, sections
     couleur_footer_debut / couleur_footer_fin, si renseignées). */
  background: linear-gradient(180deg, #F4D5D8 0%, #FBF0F1 100%);
  margin-top: 40px;
}

.footer-colonnes {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  padding: 34px 24px 26px;
  text-align: center;
}

.footer-colonne {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.footer-colonne-liens { gap: 4px; }
.footer-colonne-liens a { margin-top: 2px; }

.footer-icone {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--couleur-marque);
  color: #fff;
}

.footer-icone svg { width: 17px; height: 17px; }

.footer-colonne h3 {
  margin: 2px 0 0;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--couleur-texte);
}

.footer-colonne a,
.footer-colonne p {
  margin: 0;
  font-size: 0.8rem;
  color: var(--couleur-texte-doux);
  text-decoration: none;
  line-height: 1.4;
}

.footer-colonne a:hover { color: var(--couleur-marque); }

/* Bandeau distinct du reste du footer : même principe de dégradé que le
   header (--couleur-enseigne / --couleur-marque-clair) mais inversé — clair
   en haut (raccord avec les colonnes du footer), sombre en bas (symétrique
   du haut du header, pour "refermer" la page sur la même teinte). Valeurs de
   repli ci-dessous, reprises par LBC.appliquerParametresGlobaux() à partir
   des mêmes couleurs CSV que le header (couleur_header_debut / _fin). */
.footer-bas {
  background: linear-gradient(to bottom, var(--couleur-marque-clair) 0%, var(--couleur-enseigne) 100%);
  text-align: center;
  padding: 12px 20px;
}

.footer-bas p {
  margin: 0;
  font-size: 0.76rem;
  color: #ffffff;
  letter-spacing: 0.3px;
}

.footer-bas p + p { margin-top: 4px; }

/* Rempli en direct par LBC.appliquerParametresGlobaux() (page=global,
   section=footer_maj, colonne body_text de Parametres_des_contenus.csv) —
   reste vide et invisible tant que ce champ n'est pas renseigné. */
.footer-date-maj {
  color: rgba(255, 255, 255, 0.8);
  font-style: italic;
}

@media (max-width: 860px) {
  .footer-colonnes { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .footer-colonnes {
    grid-template-columns: 1fr;
    gap: 22px;
    padding: 28px 24px 20px;
  }
}

/* =====================================================================
   12. GABARIT UNIVERSEL — CARTE CADEAU (format carte postale, ~600×380)
   Déclinable pour un soin spécifique (data-type="soin") ou un chèque
   cadeau à montant libre (data-type="montant").
   ===================================================================== */
.carte-cadeau {
  --carte-cadeau-largeur: 680px;
  --carte-cadeau-or: #C6952E;
  width: 100%;
  max-width: var(--carte-cadeau-largeur);
  margin: 0 auto;
  padding: 5px;
  /* Angles droits (pas d'arrondi) et pas d'ombre portée : la carte est
     découpée au massicot après impression (2026-08-26), un contour arrondi
     ou une ombre autour du bord n'aurait pas de sens sur le papier imprimé. */
  background: linear-gradient(135deg, var(--couleur-poudre), #ffffff 55%, var(--couleur-poudre));
}

.carte-cadeau-cadre {
  position: relative;
  display: grid;
  /* La colonne "paquet" n'est plus qu'un nom réservé dans les areas
     ci-dessous : le paquet cadeau (.carte-cadeau-paquet) est en
     position:absolute (cf. sa règle plus bas), donc rien n'occupe
     réellement cette 2e colonne — sa largeur ne sert qu'à empêcher un
     intitulé de soin long de passer sous l'image. 2.8fr 1fr (plutôt que
     1.3fr 1fr) laisse le texte utiliser l'espace resté vide à gauche de
     l'image, tout en gardant ~19px de marge avant celle-ci (vérifié sur
     l'intitulé le plus long rencontré à ce jour). */
  grid-template-columns: 2.8fr 1fr;
  grid-template-areas:
    "entete  paquet"
    "titre   paquet"
    "champs  paquet"
    "message message"
    "pied    pied";
  align-items: center;
  gap: 8px 22px;
  border: 1.5px solid var(--couleur-marque);
  padding: 18px 32px 12px;
  /* Fond ivoire (plus chaud qu'un blanc pur). Le fin liseré or à l'intérieur
     de la bordure est un ::before ci-dessous (vraie bordure, pas un
     box-shadow) — cf. commentaire sur .carte-cadeau-cadre::before. */
  background: #FAF6F0;
}

/* Liseré or à l'intérieur de la bordure bordeaux : code visuel du
   certificat-cadeau haut de gamme, façon dorure à chaud (cf. discussion
   2026-08-21). Anciennement un box-shadow inset double-couche puis un
   ::before positionné en retrait — box-shadow, mal supporté par html2canvas
   (bibliothèque utilisée pour générer le PDF de la carte cadeau), décalait
   ou faisait disparaître le liseré à l'export. Le ::before qui a suivi
   souffrait d'un autre bug html2canvas, spécifique celui-là aux
   pseudo-éléments dans un conteneur en grille : sur un vrai navigateur ce
   ::before s'étale correctement sur toute la carte, mais html2canvas le
   plaçait à l'export dans la seule cellule "paquet" (colonne de droite)
   (retour utilisateur 2026-09-10, capture d'un PDF exporté). D'où
   .carte-cadeau-liseret : un vrai élément du DOM (ajouté en premier enfant
   de .carte-cadeau-cadre dans carte-cadeau.html et carte-cadeau-interne.html)
   plutôt qu'un pseudo-élément — rendu de façon fiable par html2canvas.
   Sans grid-column/grid-row (délibérément) : un premier essai les avait
   forcés à 1/-1 pour être sûr que l'élément couvre toute la carte, mais ça
   déplaçait son bloc englobant du padding-box (comportement par défaut d'un
   absolu sans zone de grille définie - le bon, resserré contre la bordure
   rouge) vers le content-box de la grille (qui exclut le padding de
   .carte-cadeau-cadre) - d'où un liseré excessivement retiré des bords,
   décalé de la valeur du padding (retour utilisateur 2026-09-10, 2e
   capture). Laisser grid-column/grid-row à leur valeur par défaut (aucune
   zone définie) suffit à la fois à obtenir un rectangle complet sur
   html2canvas et le bon inset de 5px. */
.carte-cadeau-liseret {
  position: absolute;
  top: 5px;
  right: 5px;
  bottom: 5px;
  left: 5px;
  border: 1px solid var(--carte-cadeau-or);
  pointer-events: none;
}

/* --- Zone haute gauche : logo décalé à gauche, avec un espace net avant
   l'enseigne (plus de centrage sur toute la largeur de la colonne — tout le
   bloc gauche, logo compris, s'aligne maintenant sur la même marge que le
   reste du texte en dessous). --- */
.carte-cadeau-entete {
  grid-area: entete;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 60px;
}

.carte-cadeau-logo {
  flex: none;
  height: 68px;
  width: auto;
}

/* Centré sur sa propre largeur (celle de "La Beauté Cachée", le plus large
   des deux) plutôt que par rapport au logo à côté — cf. discussion
   2026-08-21. Pas de ligne dédiée dans Parametres_des_styles.csv : c'est un
   choix d'alignement/mise en page, pas une propriété de police (le CSV ne
   pilote que police/taille/couleur/graisse/style/espacement/majuscules,
   cf. card_header_enseigne / card_header_sub, déjà câblées et inchangées). */
.carte-cadeau-enseigne-bloc {
  text-align: center;
}

.carte-cadeau-enseigne {
  display: inline-block;
  position: relative;
  margin: 0;
  font-family: var(--police-titres);
  font-weight: 400;
  font-size: 30px;
  color: var(--couleur-marque);
  line-height: 1;
}

/* Même logique que .logo-texte::after dans le header (Sacramento réserve
   une "descente" bien plus grande que ce que les lettres dessinent
   réellement) : un ::after positionné en absolu, calé à distance fixe de
   l'encre du texte, plutôt qu'un border-bottom qui s'accrocherait au bas
   de la boîte de ligne gonflée. */
.carte-cadeau-enseigne::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1px;
  height: 1.5px;
  background: var(--couleur-marque);
}

.carte-cadeau-baseline {
  margin: 3px 0 0;
  font-size: 14px;
  letter-spacing: 0.5px;
  font-style: italic;
  color: var(--couleur-texte-doux);
}

/* --- « Carte Cadeau » + montant / soin offert, sous le logo, alignés à
   gauche comme le reste de la colonne (un intitulé de soin long s'étale
   ainsi sur toute la largeur disponible au lieu d'être écrasé dans une
   étroite colonne de droite). --- */
.carte-cadeau-titre-bloc {
  grid-area: titre;
  text-align: left;
}

/* Sorti du flux de la grille (position absolue dans .carte-cadeau-cadre,
   position:relative) : en haut à droite de la carte, plutôt qu'empilé sous
   le logo avec la valeur (montant / soin) — cf. discussion 2026-08-21. */
.carte-cadeau-eyebrow {
  position: absolute;
  top: 24px;
  right: 34px;
  margin: 0;
  font-size: 16px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--couleur-texte-doux);
}

.carte-cadeau-objet {
  margin: 0;
  font-family: var(--police-corps);
  font-style: italic;
  font-weight: 600;
  font-size: 20px;
  line-height: 1.3;
  color: var(--couleur-marque);
}

/* Libellé « Soin offert » (mode "soin" uniquement) : reprend le style
   discret de carte-cadeau-champ (Pour / De la part de) plutôt que celui,
   mis en valeur, de carte-cadeau-objet juste en dessous. */
.carte-cadeau-soin-label {
  margin: 0 0 2px;
}

/* Sous-titre du soin offert, sous carte-cadeau-objet (mode "soin" uniquement,
   affiché seulement si prestations.csv en renseigne un). */
.carte-cadeau-soin-sous-titre {
  margin: 2px 0 0;
  font-size: 13px;
  font-style: italic;
  color: var(--couleur-texte-doux);
}

/* Contenu explicite du soin offert (mode "soin" uniquement, colonne
   Contenu_explicite de prestations.csv) : précise ce que contient le soin,
   pour que le destinataire n'ait pas besoin d'aller le vérifier sur le site. */
.carte-cadeau-soin-contenu {
  margin: 3px 0 0;
  font-size: 12.5px;
  color: var(--couleur-texte-doux);
}

/* --- Zone médiane gauche : champs à personnaliser --- */
.carte-cadeau-champs {
  grid-area: champs;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.carte-cadeau-champ {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 14px;
  color: var(--couleur-texte);
  white-space: nowrap;
}

.carte-cadeau-pointilles {
  display: inline-block;
  flex: 1 1 auto;
  min-width: 90px;
  border-bottom: 1px dotted var(--couleur-bordure);
}

/* "Pour :" / "De la part de :" — vraies saisies (remplacent les pointillés
   décoratifs), même police que le libellé, juste soulignées en pointillé
   pour garder l'esprit "à remplir" de la carte. */
.carte-cadeau-champ-saisie {
  flex: 1 1 auto;
  min-width: 90px;
  border: none;
  border-bottom: 1px dotted var(--couleur-bordure);
  background: transparent;
  padding: 0 0 2px;
  font-family: inherit;
  font-size: inherit;
  color: var(--couleur-texte);
}
.carte-cadeau-champ-saisie::placeholder { color: var(--couleur-texte-doux); }
.carte-cadeau-champ-saisie:focus-visible {
  outline: none;
  border-bottom-style: solid;
  border-bottom-color: var(--couleur-marque);
}

/* --- Message personnalisé (3-4 lignes) que le client peut saisir pour
   accompagner son cadeau. Le libellé réutilise le style de "Pour :" / "De
   la part de :" (carte-cadeau-champ) plutôt qu'une nouvelle clé CSV, les
   deux étant visuellement identiques. Ce champ n'est pour l'instant qu'un
   aperçu sur la carte (comme le code ou la date de validité) : sa valeur
   n'est pas encore transmise à la réservation/au paiement. --- */
.carte-cadeau-message {
  grid-area: message;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.carte-cadeau-message-label { margin: 0; }

.carte-cadeau-message-zone {
  width: 100%;
  /* Hauteur fixe (pas min-height) + overflow masqué : un message de
     plusieurs lignes ne doit jamais agrandir la carte au-delà de sa taille
     imprimée prévue — cf. retour utilisateur 2026-08-26 après un test
     d'impression avec un message très long. Au moins 4 lignes visibles
     (retour du 2026-08-26 : 2 lignes étaient trop court), interligne
     resserré à 1.15 pour limiter la hauteur nécessaire. Valeur mesurée
     empiriquement, pas calculée depuis les métriques théoriques de la
     police (ça avait surestimé la hauteur réelle nécessaire la 1ère fois) —
     ne pas recalculer sans re-tester visuellement. */
  height: 161px;
  overflow: hidden;
  line-height: 1.15;
  padding: 8px 10px;
  border: 1px dashed var(--couleur-bordure);
  border-radius: 10px;
  /* Même ivoire que le fond de la carte (#FAF6F0) plutôt que blanc pur : la
     zone message se fondait dans la carte comme un post-it plaqué dessus. */
  background: #FAF6F0;
  font-family: var(--police-corps);
  font-size: 0.82rem;
  color: var(--couleur-texte);
}

.carte-cadeau-message-zone::placeholder { color: var(--couleur-texte-doux); }

.carte-cadeau-message-zone:focus-visible {
  outline: none;
  border-color: var(--couleur-marque);
}

/* --- Paquet cadeau (images/cadeau2.png) : sorti de la grille, en position
   absolue (comme carte-cadeau-eyebrow, cf. plus haut) plutôt que centré sur
   toute la hauteur entête+titre+champs — placé près du bord droit et centré
   verticalement entre le bas de l'intitulé « Carte Cadeau » et le haut de
   la zone Message (cf. discussion 2026-08-21). Repasse en position normale,
   centrée, dans la disposition mobile empilée sur une colonne (cf. media
   query plus bas) : la position absolue n'a de sens que dans la grille à
   deux colonnes. --- */
.carte-cadeau-paquet {
  /* Pas de grid-area ici (contrairement à la version mobile ci-dessous) :
     pour un item de grille en position:absolute, la zone de grille elle-même
     sert de bloc englobant (donc right/top se recalculeraient par rapport à
     la cellule "paquet", décalée par le padding de .carte-cadeau-cadre) —
     en le retirant de la grille, right/top se calculent directement depuis
     le cadre, comme pour carte-cadeau-eyebrow juste au-dessus. */
  position: absolute;
  top: 76px;
  right: 18px;
}

.carte-cadeau-paquet-image {
  width: 100%;
  max-width: 170px;
  height: auto;
  object-fit: contain;
}

/* --- Zone basse : horaires, code d'authentification, validité, coordonnées --- */
.carte-cadeau-pied {
  grid-area: pied;
  border-top: 1px dashed var(--couleur-bordure);
  padding-top: 6px;
  text-align: center;
}

.carte-cadeau-pied-ligne {
  margin: 0 0 2px;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--couleur-texte);
}

.carte-cadeau-pied-ligne strong { color: var(--couleur-marque); font-size: 13px; letter-spacing: 0.5px; }

/* Séparateur discret entre date de validité et code, réunis sur une même
   ligne (2026-08-26, pour gagner une ligne de hauteur). */
.carte-cadeau-pied-separateur { margin: 0 6px; color: var(--couleur-texte-doux); }

.carte-cadeau-code strong {
  color: var(--couleur-marque);
  letter-spacing: 0.5px;
}

.carte-cadeau-contact {
  margin: 2px 0 0;
  font-size: 0.7rem;
  line-height: 1.25;
  color: var(--couleur-texte-doux);
}

/* Petit sceau "LBC" en coin, façon cachet de cire — une signature discrète
   plutôt qu'une décoration qui recouvre la carte (cf. discussion
   2026-08-21). Positionné hors du flux, sur le coin bas-droit du cadre.
   right/bottom élargis de 12/10px à 18/16px (2026-08-26) : le sceau étant
   un cercle, son point le plus bas/droit est plus proche du liseré or
   (inset 5px) que ne le suggère la boîte englobante carrée, et la
   compression JPEG de l'export PDF rapprochait encore visuellement les deux
   traits dorés au point de sembler se toucher sur la carte imprimée. */
.carte-cadeau-sceau {
  position: absolute;
  right: 18px;
  bottom: 16px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--carte-cadeau-or);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--police-corps);
  font-size: 0.56rem;
  font-weight: 600;
  letter-spacing: 1px;
  color: var(--carte-cadeau-or);
  pointer-events: none;
}

.grille-cartes-cadeaux {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 40px;
  padding: 20px 0 60px;
}

/* --- Sélecteur de montant épuré (saisie libre + suggestions) --- */
.selecteur-montant {
  max-width: 420px;
  margin: 0 auto 36px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.montant-champ-principal {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.montant-champ-principal label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--couleur-texte);
}

.montant-saisie {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  border: 1.5px solid var(--couleur-marque);
  border-radius: var(--rayon-pilule);
  background: #fff;
}

.montant-saisie input {
  width: 110px;
  border: none;
  outline: none;
  font-family: var(--police-corps);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--couleur-marque);
  text-align: right;
  background: transparent;
}

.montant-saisie span {
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--couleur-marque);
}

.montant-suggestions {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.montant-suggestions label {
  font-size: 0.76rem;
  color: var(--couleur-texte-doux);
}

.select-montant {
  width: 100%;
  max-width: 260px;
  padding: 9px 32px 9px 16px;
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%239C0537' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 11px 8px;
  font-family: var(--police-corps);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--couleur-marque);
  text-align: center;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

@media (max-width: 640px) {
  .carte-cadeau-cadre {
    grid-template-columns: 1fr;
    grid-template-areas:
      "entete"
      "titre"
      "paquet"
      "champs"
      "pied";
    padding: 26px 24px 18px;
    text-align: center;
  }
  .carte-cadeau-entete { justify-content: center; min-height: 0; padding-top: 42px; }
  .carte-cadeau-logo { left: 50%; top: 0; transform: translateX(-50%); height: 52px; }
  .carte-cadeau-enseigne { font-size: 1.7rem; }
  .carte-cadeau-eyebrow { top: 20px; right: 24px; }
  .carte-cadeau-champ { justify-content: center; white-space: normal; }
  .carte-cadeau-paquet { grid-area: paquet; position: static; display: flex; justify-content: center; }
  .carte-cadeau-paquet-image { max-width: 130px; }
}

/* Option retenue le 2026-09-11 : la carte cadeau est pensée pour un format
   large et s'affiche décalée en mobile portrait — plutôt que de la montrer
   mal formée, on la masque entièrement tant que l'écran n'est pas en mode
   paysage, et on affiche à la place cette astuce bien visible (pulsation)
   invitant à pivoter le téléphone. Elle disparaît d'elle-même, et la carte
   réapparaît, dès que l'orientation passe en paysage. */
.astuce-paysage-mobile {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 10px;
  max-width: 480px;
  margin: 0 auto 28px;
  padding: 16px 22px;
  background: var(--couleur-poudre);
  border: 1.5px solid var(--couleur-marque-clair);
  border-radius: 12px;
  color: var(--couleur-marque);
  font-weight: 600;
  font-size: 0.95rem;
  text-align: center;
  animation: astucePaysagePulse 2.2s ease-in-out infinite;
}

@keyframes astucePaysagePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(184, 55, 90, 0.35); }
  50% { box-shadow: 0 0 0 9px rgba(184, 55, 90, 0); }
}

@media (max-width: 640px) and (orientation: portrait) {
  /* Scopé à #page-carte-cadeau (carte-cadeau.html) uniquement : l'outil
     interne carte-cadeau-interne.html réutilise .bloc-carte-cadeau pour
     l'aperçu à capturer en PDF et n'a pas cette astuce — il ne doit pas se
     retrouver avec une carte masquée sans remplacement si un membre du
     personnel l'ouvre sur son téléphone en portrait. Seuil (640px) aligné
     sur celui de la mise en page mobile de .carte-cadeau-cadre ci-dessus :
     c'est exactement là que la carte se retrouve compressée. */
  #page-carte-cadeau .bloc-carte-cadeau { display: none; }
  .astuce-paysage-mobile { display: flex; }
}

/* =====================================================================
   13. RESPONSIVE GÉNÉRAL
   ===================================================================== */
@media (max-width: 640px) {
  .header-principal { padding: 12px 16px 10px; }
  /* Hauteur ajustée pour que le haut/bas du logo affleure le haut/bas du
     bloc "La Beauté Cachée / Institut de Beauté" à côté (mesuré : 55px
     aligne les deux, contre 50px qui laissait le logo visiblement plus
     court que le texte). */
  .logo-image { height: 55px; }
  .logo-texte { font-size: 24px; }
  .logo-sous-titre { font-size: 10px; letter-spacing: 1.5px; }
  /* !important nécessaire : ces 2 tailles sont normalement pilotées par
     Parametres_des_styles.csv via un style inline (LBC.appliquerStyleElement),
     qui l'emporte toujours sur une règle CSS classique quelle que soit sa
     spécificité — voir la note équivalente sur .btn-reserver dans
     contact.html. Ici on veut délibérément ajuster uniquement l'affichage
     mobile sans toucher à la valeur CSV (identique sur desktop, 22px/28px).
     Texte principal légèrement réduit pour laisser plus de place à la
     signature cursive, remontée à 24px : les deux tiennent sur une ligne
     chacune dès 320px de large (vérifié par mesure de largeur réelle du
     texte, avec marge). */
  .baseline { font-size: 20px !important; }
  .baseline .baseline-signature { font-size: 24px !important; }
  .groupe .titre-script { font-size: 2.2rem; }
  main { padding: 0 16px 60px; }
  .barre-onglets .onglets { padding: 12px 16px; gap: 8px; }
  .onglet { font-size: 0.76rem; padding: 8px 16px; }
}

@media (max-width: 420px) {
  .champs-grille,
  .paiement-grille { grid-template-columns: 1fr; }
}
