/* ============================================================
   T'NATURE · Feuille principale
   Sommaire
     1. Base et typographie
     2. Utilitaires de mise en page
     3. Texture aquarelle et motif signature
     4. Placeholders d'images (brief photo)
     5. Boutons, puces, badge d'avis, logo
     6. Écran de chargement
     7. En-tête et navigation
     8. Hero
     9. Bande des points forts
    10. La Maison
    11. Les Chambres
    12. Prestations
    13. Galerie
    14. Activités
    15. Contact
    16. Pied de page
    17. Modales et carrousels
    18. Pages légales
    19. Apparitions au scroll
   ============================================================ */

/* ========== 1. BASE ET TYPOGRAPHIE ========== */

html{
  scroll-behavior: smooth;
  /* Plus de zoom au double-appui. C'est lui le coupable du bug signalé le
     20 octobre 2026 : deux appuis rapides sur une flèche de carrousel, le
     téléphone y lit un double-tap et agrandit la page.

     `manipulation` dit au navigateur de ne garder que le défilement et le
     pincement : il n'a plus à attendre un éventuel second appui, ce qui
     supprime au passage le délai de 300 ms sur chaque bouton. Le pincement
     reste possible, volontairement : une personne malvoyante doit pouvoir
     agrandir, et iOS ignore de toute façon les réglages qui l'interdisent. */
  touch-action: manipulation;
}
/* `touch-action` ne s'hérite pas. Posée sur `html` seule, la règle suffit en
   théorie (le navigateur remonte la chaîne des ancêtres avant d'autoriser un
   geste) mais elle ne se lit nulle part sur le bouton qu'on vient de toucher,
   et les moteurs n'ont pas toujours été d'accord sur ce point. On la répète
   donc sur ce qui se touche : c'est là que le double-appui se produit. */
button, a, summary, label, select, input, textarea,
[role="tab"], [data-modale-cible], [data-rail-piste]{
  touch-action: manipulation;
}

body{
  font-family: var(--f-corps);
  font-size: var(--fs-body);
  line-height: var(--lh-corps);
  color: var(--texte);
  background: var(--fond-page);
}

/* Verrou du défilement quand une modale ou le menu est ouvert */
body.est-verrouille{ overflow: hidden; }

h1, h2{
  font-family: var(--f-titre);
  font-weight: 400;
  line-height: var(--lh-titre);
  letter-spacing: .01em;
}
h1{ font-size: var(--fs-h1); }
h2{ font-size: var(--fs-h2); }

h3, h4, h5, h6{
  font-family: var(--f-ui);
  font-weight: 500;
  line-height: 1.25;
}
h3{ font-size: var(--fs-h3); }
h4{ font-size: var(--fs-h4); }

p{ max-width: var(--largeur-texte); }
/* Le texte n'est jamais justifié : défaut corrigé de l'ancien site. */
p, li{ text-align: left; }

a{ text-decoration-thickness: 1px; text-underline-offset: .18em; }

strong{ font-weight: 600; }

::selection{ background: var(--c-rose-poudre); color: var(--c-encre); }

/* Lien d'évitement */
.saut-contenu{
  position: absolute; left: -9999px; top: 0;
  z-index: calc(var(--z-loader) + 1);
  background: var(--c-encre); color: var(--c-blanc);
  padding: var(--e-3) var(--e-5);
  border-radius: 0 0 var(--r-champ) 0;
  font-family: var(--f-ui);
}
.saut-contenu:focus{ left: 0; }

.lecture-seule{
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ========== 2. UTILITAIRES DE MISE EN PAGE ========== */

.contenant{
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}
.contenant--etroit{ max-width: 860px; }

.section{ padding-block: var(--section-y); position: relative; }
.section--ivoire{ background: var(--c-ivoire); }
.section--blanc{ background: var(--c-blanc); }
.section--encre{ background: var(--c-encre); color: var(--texte-inverse); }

.section__entete{
  max-width: 760px;
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}
.section__entete--centre{ margin-inline: auto; text-align: center; }
/* `p, li { text-align: left }` cible directement le <p> : il l'emporte sur le
   centrage hérité du parent et les sous-titres restaient alignés à gauche
   dans un bloc pourtant centré. Il faut donc viser le <p> explicitement. */
.section__entete--centre p{ margin-inline: auto; text-align: center; }

.surtitre{
  display: block;
  font-family: var(--f-ui);
  /* « La maison », « Les chambres », « Galerie »… : ce sont eux qui annoncent
     la section et ils se lisaient plus petits que le corps de texte.
     Demande de la cliente du 30/09/2026. */
  font-size: clamp(1rem, 1.3vw, 1.15rem);
  font-weight: 500;
  letter-spacing: var(--ls-surtitre);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--e-3);
}
.section--encre .surtitre{ color: var(--c-peche); }

.chapo{
  font-size: clamp(1.0625rem, 1.5vw, 1.1875rem);
  color: var(--texte-doux);
  margin-top: var(--e-4);
}
/* Chapô réduit : pour les sections dont l'introduction n'est qu'un repère et non
   un argument. Posé sur « Activités » le 07/10/2026, où quatre lignes pleine
   taille écrasaient la grille de cartes qui suit. */
.chapo--compact{ font-size: clamp(.95rem, 1.15vw, 1.0625rem); }

/* Séparateur : le brin d'herbes du logo */
.brin{
  display: block;
  width: 26px; height: auto;
  margin: var(--e-6) auto;
  color: var(--texte);
  opacity: .55;
}

/* ========== 3. TEXTURE AQUARELLE ET MOTIF SIGNATURE ========== */

/* Reproduction en CSS pur de la texture du carré du logo.
   Aucune image : quatre lavis radiaux + un grain SVG en multiply. */
.texture-aquarelle{
  position: relative;
  isolation: isolate;
  background-color: var(--c-creme);
  background-image:
    radial-gradient(60% 50% at 20% 25%, rgba(248,200,168,.55) 0%, transparent 70%),
    radial-gradient(50% 45% at 78% 18%, rgba(248,232,200,.65) 0%, transparent 72%),
    radial-gradient(55% 55% at 62% 80%, rgba(248,216,216,.50) 0%, transparent 70%),
    radial-gradient(40% 40% at 12% 82%, rgba(232,184,152,.35) 0%, transparent 75%);
}
.texture-aquarelle::after{
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: .16;
  mix-blend-mode: multiply;
  z-index: -1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)' opacity='.55'/%3E%3C/svg%3E");
}
/* Variante très pâle, pour la section Contact */
.texture-aquarelle--pale{ background-color: #FDF8F3; }
/* z-index négatif indispensable : sans lui, ce voile positionné se peint
   PAR-DESSUS le contenu en flux et délave les titres de la section Contact,
   qui paraissaient alors d'une autre couleur que les autres. */
.texture-aquarelle--pale::before{
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--c-blanc); opacity: .6; pointer-events: none;
}

/* Le motif signature : rectangle mauve plein + carré aquarelle décalé.
   Repris du bloc « AU CŒUR DE CHÂTEAU-CHALON » de l'ancien site. */
.motif-signature{
  position: relative;
  padding: 0 2rem 2rem 0;   /* réserve la place du décalage */
}
.motif-signature::before{
  content: "";
  position: absolute;
  inset: 2rem 0 0 2rem;
  background: var(--c-mauve);
  border-radius: 4px;
}
.motif-signature > *{ position: relative; z-index: 1; }

.motif-signature--inverse{ padding: 0 0 2rem 2rem; }
.motif-signature--inverse::before{ inset: 2rem 2rem 0 0; }

.motif-signature--petit{ padding: 0 1.25rem 1.25rem 0; }
.motif-signature--petit::before{ inset: 1.25rem 0 0 1.25rem; }

/* Pastille décorative en texture, utilisée en fond de section */
.tache-aquarelle{
  position: absolute;
  border-radius: 50%;
  filter: blur(28px);
  opacity: .5;
  pointer-events: none;
  z-index: 0;
}

/* ========== 4. PLACEHOLDERS D'IMAGES ========== */

/* Chaque emplacement d'image du site est un brief photo.
   Le ratio est déclaré pour que la mise en page finale soit
   exactement celle du site livré : CLS nul au remplacement. */
.placeholder-img{
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  aspect-ratio: var(--ratio, 3/2);
  margin: 0;
  padding: clamp(.75rem, 2.5%, 1.5rem);
  text-align: center;
  overflow: hidden;
  border-radius: inherit;
  background-color: var(--c-creme);
  background-image:
    radial-gradient(60% 50% at 20% 25%, rgba(248,200,168,.42) 0%, transparent 70%),
    radial-gradient(50% 45% at 78% 18%, rgba(248,232,200,.50) 0%, transparent 72%),
    radial-gradient(55% 55% at 62% 80%, rgba(248,216,216,.38) 0%, transparent 70%);
  color: var(--c-encre-doux);
}
.placeholder-img::before{
  content: "";
  position: absolute; inset: 6px;
  border: 2px dashed var(--c-terre);
  border-radius: inherit;
  pointer-events: none;
  opacity: .75;
}
.placeholder-img__icone{ color: var(--c-terre); flex: none; }
.placeholder-img__icone svg{ width: 26px; height: 26px; }
.placeholder-img__texte{
  font-family: var(--f-ui);
  font-size: clamp(.72rem, 1.15vw, .85rem);
  line-height: 1.45;
  max-width: 34ch;
  /* Sur les très petites vignettes, on tronque proprement */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
}
.placeholder-img__meta{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--texte-brun);
  flex: none;
}
/* Version sombre, pour le loader et le hero */
.placeholder-img--sombre{
  background-color: #4A4038;
  background-image:
    radial-gradient(70% 60% at 25% 25%, rgba(232,184,152,.28) 0%, transparent 70%),
    radial-gradient(60% 55% at 80% 70%, rgba(248,152,168,.18) 0%, transparent 72%);
  color: rgba(250,246,241,.82);
}
.placeholder-img--sombre::before{ border-color: rgba(232,184,152,.45); }
.placeholder-img--sombre .placeholder-img__icone,
.placeholder-img--sombre .placeholder-img__meta{ color: rgba(232,184,152,.75); }
/* Vignette : on masque le texte, illisible en dessous de 150 px */
.placeholder-img--vignette .placeholder-img__texte,
.placeholder-img--vignette .placeholder-img__meta{ display: none; }

/* ---------- Emplacement pourvu : la vraie photo ----------
   La photo livrée prend la boîte du brief qu'elle remplace, même ratio,
   même rayon, même position dans la grille. C'est ce qui fait qu'aucune
   mise en page n'a bougé en passant des placeholders aux photos. */
.placeholder-img--photo{
  padding: 0;
  background-image: none;
  background-color: var(--c-creme);   /* le temps que l'image arrive */
}
.placeholder-img--photo::before{ display: none; }
.placeholder-img--photo img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---------- Fond plein écran : hero et rideau de chargement ---------- */
.image-fond{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* Diaporama : les vues sont superposées, une seule est opaque. Le fondu dure
   un peu plus d'une seconde, sur trois secondes d'affichage. */
.diaporama{ position: absolute; inset: 0; }
.diaporama .image-fond{ opacity: 0; transition: opacity 1.1s ease; }
.diaporama .image-fond[data-actif="1"]{ opacity: 1; }
@media (prefers-reduced-motion: reduce){
  .diaporama .image-fond{ transition: none; }
}

/* ========== 5. BOUTONS, PUCES, AVIS, LOGO ========== */

.btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: 48px;
  padding: .9rem 2rem;
  border-radius: var(--r-pilule);
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  transition: background-color var(--t-base), color var(--t-base),
              transform var(--t-base), box-shadow var(--t-base),
              border-color var(--t-base);
}
.btn:hover{ transform: translateY(-2px); }
.btn:active{ transform: translateY(0); }

.btn--primaire{
  background: var(--action-fond);
  color: var(--action-texte);
  box-shadow: 0 6px 18px rgba(56,56,56,.18);
}
.btn--primaire:hover{ background: var(--action-fond-survol); box-shadow: var(--ombre-survol); }

/* « Réserver » se distinguait de l'action courante quand celle-ci était sombre.
   Depuis que tous les boutons sont roses, il n'a plus de couleur propre : la règle
   ne garde que l'ombre portée pour le détacher de l'en-tête transparent. */
.btn--reserver{ box-shadow: var(--ombre-survol); }

.btn--secondaire{
  background: transparent;
  color: var(--c-blanc);
  border: 1.5px solid rgba(255,255,255,.75);
}
.btn--secondaire:hover{ background: rgba(255,255,255,.14); border-color: #fff; }

.btn--contour{
  background: transparent;
  color: var(--texte);
  border: 1.5px solid var(--c-terre);
}
.btn--contour:hover{ background: var(--c-creme); border-color: var(--accent); }

.btn--compact{ min-height: 40px; padding: .55rem 1.15rem; font-size: var(--fs-micro); }
/* Bouton blanc : fond plein, texte encre, filet discret. Sert dans le pied du
   menu mobile, où il porte le numéro de téléphone à côté de la réservation :
   l'un propose, l'autre reste disponible sans se disputer le regard. */
.btn--blanc{
  background: var(--c-blanc);
  color: var(--texte);
  border: 1.5px solid var(--bordure-douce);
}
.btn--blanc:hover{ background: var(--c-creme); border-color: var(--accent); }
.btn--pleine{ width: 100%; }

/* CTA en lien fléché, mise en page reprise de la référence client */
.lien-fleche{
  display: inline-flex;
  align-items: center;
  gap: var(--e-3);
  min-height: 44px;
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--texte);
  transition: color var(--t-base), gap var(--t-base);
}
.lien-fleche svg{ width: 18px; height: 18px; flex: none; transition: transform var(--t-base); }
.lien-fleche:hover{ color: var(--accent-fonce); gap: var(--e-4); }
.lien-fleche:hover svg{ transform: translateX(3px); }

/* Puces d'équipement, style de la référence client */
.puces{ display: flex; flex-wrap: wrap; gap: var(--e-2); }
.puce{
  display: inline-flex;
  align-items: center;
  padding: .4rem .85rem;
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-pilule);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  line-height: 1.3;
  color: var(--texte-doux);
  background: var(--c-blanc);
}
.puce--todo{
  border-style: dashed;
  border-color: var(--c-terre);
  color: var(--texte-brun);
  font-style: italic;
}

/* Étiquette de saison / de statut */
.etiquette{
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: .3rem .7rem;
  border-radius: var(--r-pilule);
  background: var(--c-creme);
  color: var(--texte);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.etiquette--loin{ background: var(--c-mauve); }
.etiquette--sur-image{
  position: absolute;
  top: var(--e-4); left: var(--e-4);
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(6px);
  box-shadow: 0 2px 10px rgba(56,56,56,.12);
  z-index: 2;
}

/* Badge d'avis, une seule source de vérité pour la note (brief §5) */
.avis-badge{
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-1);
  font-family: var(--f-ui);
}
.avis-badge__ligne{ display: inline-flex; align-items: center; gap: var(--e-3); }
.avis-badge__etoiles{ display: inline-flex; gap: 2px; color: var(--etoile); }
.avis-badge__etoiles svg{ width: 17px; height: 17px; }
.avis-badge__note{
  font-size: var(--fs-petit);
  font-weight: 500;
  letter-spacing: .06em;
}
.avis-badge__source{
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  opacity: .8;
}
/* Variante de la carte de contact : les étoiles sur leur propre ligne, au-dessus
   de la note. Le conteneur est déjà une colonne centrée, il n'y a donc rien à
   faire de plus que de ne pas envelopper les deux dans `.avis-badge__ligne`. */
.avis-badge--compact{ gap: 4px; }
.avis-badge--compact .avis-badge__etoiles svg{ width: 18px; height: 18px; }
/* L'interligne par défaut donnait 24 px à une ligne de 15 : serré ici, la case
   gagne six pixels sans que la note se tasse. */
.avis-badge--compact .avis-badge__note{ line-height: 1.2; }

.avis-badge--clair{ color: var(--c-blanc); }
.avis-badge--clair .avis-badge__etoiles{ color: var(--c-sable); }
/* Sur le hero, la source ne doit pas être atténuée : le voile est déjà
   sombre et l'opacité ferait tomber le contraste sous 4,5:1. */
.avis-badge--clair .avis-badge__source{ opacity: 1; }

/* Logo, le vrai, extrait de la carte de visite fournie par la cliente
   (voir assets/logo/LISEZ-MOI.md : comment il en a été tiré et comment le
   refabriquer). Deux cadrages : le lettrage seul, assez large pour tenir dans
   la hauteur d'en-tête ; le lettrage + le brin, pour le rideau de chargement
   et le pied de page. Et pour chacun une version blanche.

   Le lettrage reste en couleur dans les deux versions : c'est une aquarelle,
   la repeindre en blanc la ferait disparaître. Seuls le « T’ », la baseline
   et les deux tirets passent au blanc. */
.logo{
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  line-height: 0;            /* supprime le blanc sous l'image en ligne */
}
.logo__image{
  display: block;
  width: auto;
  height: var(--h-logo, 44px);
}

/* ========== 6. ÉCRAN DE CHARGEMENT ========== */

.loader{
  position: fixed; inset: 0;
  z-index: var(--z-loader);
  display: grid; place-items: center;
  overflow: hidden;
  background: var(--c-encre);
  transform: translateY(0);
  transition: transform var(--t-rideau);
}
.loader[data-sortie="1"]{ transform: translateY(-100%); }

.loader__fond{ position: absolute; inset: 0; }
.loader__fond .placeholder-img,
.loader__fond .image-fond{
  width: 100%; height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
  animation: loader-zoom 3s ease-out both;
}
@keyframes loader-zoom{ from{ transform: scale(1); } to{ transform: scale(1.06); } }

/* Le voile du rideau : la photo livrée est un paysage de plein jour, très
   clair. À 45 % le logo blanc s'y perdait ; à 58 % il se détache et la photo
   reste lisible. */
.loader__voile{
  position: absolute; inset: 0;
  background: var(--c-encre);
  opacity: .58;
}
/* Halo sombre sous le logo. La photo du rideau est un paysage de plein jour :
   avec le seul voile uniforme, le blanc du lettrage tombait à 3,5:1. Épaissir
   le voile jusqu'à 4,5:1 aurait éteint la photo ; un halo local l'assombrit là
   où c'est nécessaire et la laisse claire ailleurs. Mesuré : 7:1 au centre. */
.loader__logo::before{
  content: "";
  position: absolute;
  inset: -22% -14%;
  background: radial-gradient(closest-side, rgba(56,56,56,.58), rgba(56,56,56,0) 100%);
  pointer-events: none;
}
.loader__logo > *{ position: relative; }

.loader__logo{
  position: relative;
  --h-logo: clamp(6.5rem, 17vw, 10.5rem);
  display: grid; place-items: center;
  animation: loader-logo .7s ease-out both;
}
@keyframes loader-logo{
  from{ opacity: 0; transform: translateY(12px); }
  to{ opacity: 1; transform: translateY(0); }
}

/* ========== 7. EN-TÊTE ET NAVIGATION ========== */

.entete{
  position: sticky; top: 0;
  z-index: var(--z-header);
  height: var(--h-header);
  display: flex; align-items: center;
  transition: background-color var(--t-base), box-shadow var(--t-base);
}
.entete__grille{
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--e-4);
  width: 100%;
}
.entete__logo{ --h-logo: 44px; justify-self: start; }
@media (max-width: 767px){ .entete__logo{ --h-logo: 34px; } }

/* Au-dessus du hero, l'en-tête est transparent : le logo passe en blanc,
   comme les liens de menu. Deux images superposées dans le HTML, une seule
   affichée, le basculement se fait sans JavaScript et sans requête en plus,
   les deux fichiers étant chargés avec la page. */
.entete__logo .logo__image--clair{ display: none; }
.entete[data-etat="transparent"] .logo__image--sombre{ display: none; }
.entete[data-etat="transparent"] .logo__image--clair{ display: block; }

/* État par-dessus le hero : transparent, tout en blanc */
.entete[data-etat="transparent"]{ background: transparent; box-shadow: none; }
.entete[data-etat="transparent"] .nav__lien{ color: var(--c-blanc); }
.entete[data-etat="transparent"] .burger{ color: var(--c-blanc); }

/* État après 80 px de défilement : opaque */
.entete[data-etat="opaque"]{
  background: var(--c-blanc);
  box-shadow: var(--ombre-header);
}

.nav{ justify-self: center; }
.nav__liste{ display: flex; gap: clamp(1rem, 2.2vw, 2.2rem); }
.nav__lien{
  position: relative;
  display: inline-block;
  padding: .4rem 0;
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--texte);
  transition: color var(--t-base);
}
.nav__lien::after{
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--accent);   /* bois de rose : 3:1 mini exigé pour un composant */
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-base);
}
.nav__lien:hover{ color: var(--accent); }
.nav__lien:hover::after,
.nav__lien[aria-current="true"]::after{ transform: scaleX(1); }
.nav__lien[aria-current="true"]{ color: var(--accent); }

.entete__actions{ justify-self: end; display: flex; align-items: center; gap: var(--e-3); }

/* ---------- Bascule de langue ----------
   Un seul element pour les deux ecrans. Le bouton « Reserver » est masque
   sous 768 px (voir plus bas), donc ce drapeau se retrouve naturellement a
   gauche de « Reserver » sur ordinateur et a gauche du burger sur telephone.
   Le drapeau montre la langue vers laquelle on va, pas celle qu'on lit. */
.bascule-langue{
  display: inline-flex; align-items: center; gap: var(--e-2);
  min-height: 44px; padding-inline: var(--e-2);
  border-radius: 999px;
  font-family: var(--f-ui); font-size: var(--fs-micro); font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
  color: inherit; text-decoration: none;
  transition: background-color .2s ease;
}
/* Le survol depend du fond sur lequel l'en-tete se trouve.

   Au-dessus du hero il est transparent sur une photo : un voile clair s'y
   voit. Une fois pose sur le blanc, ce meme voile clair devient invisible,
   et rien ne dit plus que le drapeau se clique. Il faut la l'inverse : une
   pastille creme, bordee, qui se detache du blanc.

   La regle precedente visait une classe « est-posee » qui n'a jamais existe
   dans ce projet. Elle etait donc vraie partout, et c'est le voile clair qui
   s'appliquait aussi sur fond blanc, ou on ne le voyait pas. Corrige le
   21/10/2026 : on s'appuie sur « data-etat », que nav.js ecrit reellement. */
.bascule-langue:hover,
.bascule-langue:focus-visible{ background: rgb(0 0 0 / .07); }

.entete[data-etat="transparent"] .bascule-langue:hover,
.entete[data-etat="transparent"] .bascule-langue:focus-visible{
  background: rgb(255 255 255 / .22);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .5);
}

.entete[data-etat="opaque"] .bascule-langue:hover,
.entete[data-etat="opaque"] .bascule-langue:focus-visible{
  background: var(--c-creme);
  box-shadow: inset 0 0 0 1px var(--bordure-douce);
}
/* Pastille ronde, demandee le 21/10/2026. Le dessin du drapeau est au format
   2:1 : « preserveAspectRatio=slice » le recadre au centre pour remplir le
   cercle, au lieu de l'ecraser a la hauteur du carre. */
.bascule-langue__drapeau{
  display: block; width: 24px; height: 24px;
  border-radius: 50%; overflow: hidden;
  box-shadow: 0 0 0 1px rgb(0 0 0 / .18);
}
.bascule-langue__drapeau svg{ display: block; width: 100%; height: 100%; }
@media (max-width: 767px){
  /* Sur telephone le drapeau parle seul : la place manque pour le libelle. */
  .bascule-langue__texte{ display: none; }
}

.burger{
  display: none;
  width: 44px; height: 44px;
  place-items: center;
  color: var(--texte);
}
.burger svg{ width: 24px; height: 24px; }
.burger__fermer{ display: none; }
.burger[aria-expanded="true"] .burger__ouvrir{ display: none; }
.burger[aria-expanded="true"] .burger__fermer{ display: block; }

/* Panneau mobile */
.nav-mobile{
  position: fixed; inset: 0;
  z-index: calc(var(--z-header) - 1);
  display: none;
  padding: calc(var(--h-header) + var(--e-6)) var(--gouttiere) var(--e-6);
  overflow-y: auto;
}
.nav-mobile[data-ouvert="1"]{ display: block; }
.nav-mobile__liste{ display: grid; gap: var(--e-2); position: relative; z-index: 1; }
.nav-mobile__lien{
  display: block;
  padding: var(--e-4) 0;
  border-bottom: 1px solid rgba(56,56,56,.12);
  font-family: var(--f-ui);
  font-size: 1.5rem;
  letter-spacing: .04em;
  text-decoration: none;
  color: var(--texte);
}
.nav-mobile__lien[aria-current="true"]{ color: var(--accent-fonce); }
.nav-mobile__pied{ margin-top: var(--e-6); position: relative; z-index: 1; }
/* Les deux actions du pied de menu, côte à côte et de largeur égale. Elles
   passent l'une sous l'autre si l'écran est vraiment étroit : mieux vaut deux
   lignes qu'un numéro de téléphone tronqué. */
.nav-mobile__pied--duo{
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
}
.nav-mobile__pied--duo .btn{
  /* `flex: 1 1 0` : les deux partent de rien et se partagent la largeur à
     parts égales. Une base en rem les aurait fait passer l'une sous l'autre
     sur un écran de 375 px, le numéro de téléphone étant plus long que le
     mot « Réserver ». */
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  padding-inline: var(--e-2);
  font-size: var(--fs-micro);
  letter-spacing: .02em;
  white-space: nowrap;
}
/* Au doigt posé, la réservation s'éclaircit : c'est le retour tactile demandé
   le 20 octobre 2026. */
.nav-mobile__pied--duo .btn--primaire:active{
  background: var(--c-blanc);
  color: var(--texte);
}

@media (max-width: 1023px){
  .nav{ display: none; }
  .burger{ display: grid; }
}

/* ========== 8. HERO ========== */

.hero{
  position: relative;
  min-height: min(100svh, 900px);
  margin-top: calc(-1 * var(--h-header));
  display: grid;
  align-items: center;
  overflow: hidden;
  color: var(--c-blanc);
  isolation: isolate;
}
.hero__fond{ position: absolute; inset: 0; z-index: -2; }
.hero__fond .placeholder-img{ width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
/* Voile dégradé : garantit un contraste ≥ 4,5:1 sur tous les textes */
.hero__voile{
  position: absolute; inset: 0; z-index: -1;
  /* Le brief prévoit 0 % en haut ; on part de 34 % car un ciel clair sous des
     liens de menu blancs ne passerait pas 4,5:1. À revérifier une fois la
     vraie photo en place (README §« Contrastes »). */
  background: linear-gradient(to bottom,
    rgba(56,56,56,.34) 0%,
    rgba(56,56,56,.42) 35%,
    rgba(56,56,56,.66) 100%);
}
.hero__contenu{
  display: grid;
  justify-items: center;
  gap: var(--e-5);
  text-align: center;
  padding-block: calc(var(--h-header) + var(--e-7)) var(--e-9);
}
.hero__titre{
  /* Le titre est coupé à la main dans le gabarit, après « caractère » : deux
     lignes, jamais trois. Encore faut-il qu'aucune des deux ne se replie,
     d'où une largeur qui laisse passer la plus longue (« au cœur de
     Château-Chalon », 25 signes) et un plancher de taille plus bas que celui
     des autres h1, pour les petits téléphones. */
  max-width: 26ch;
  font-size: clamp(1.9rem, 7vw, 5rem);
  text-shadow: 0 2px 18px rgba(56,56,56,.35);
}
/* Sous 360 px, un iPhone SE de première génération, 32 px ne passent plus :
   « au cœur de Château-Chalon » se replie et le titre reprend trois lignes.
   Mesuré, pas estimé : à 28 px il tient jusqu'à 320 px de large. */
@media (max-width: 359px){
  .hero__titre{ font-size: 1.75rem; }
}
.hero__sous-titre{
  /* Le bloc est centré, mais `p, li { text-align: left }` vise le <p> lui-même
     et l'emporte sur le centrage hérité : il faut le dire ici aussi. */
  text-align: center;
  margin-inline: auto;
  max-width: 52ch;
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  text-shadow: 0 1px 10px rgba(56,56,56,.4);
}
.hero__ctas{ display: flex; flex-wrap: wrap; gap: var(--e-3); justify-content: center; }

.hero__chevron{
  position: absolute;
  left: 50%; bottom: var(--e-5);
  transform: translateX(-50%);
  color: rgba(255,255,255,.8);
  animation: chevron 1.9s ease-in-out infinite;
}
.hero__chevron svg{ width: 26px; height: 26px; }
@keyframes chevron{
  0%,100%{ transform: translate(-50%, 0); opacity: .55; }
  50%{ transform: translate(-50%, 7px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce){ .hero__chevron{ display: none; } }

/* ========== 9. BANDE DES POINTS FORTS ========== */

.points{ background: var(--c-encre); color: var(--texte-inverse); }
.points__liste{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  /* Marge verticale : assez d'air pour que la bande respire, sans en faire
     un bloc à part entière. Les textes ne bougent pas. */
  padding-block: clamp(1.4rem, 2.6vw, 2.15rem);
}
.points__item{
  display: grid;
  justify-items: center;
  gap: var(--e-2);
  padding-inline: var(--e-4);
  text-align: center;
  border-left: 1px solid rgba(250,246,241,.2);
}
.points__item:first-child{ border-left: 0; }
/* Les copies ne servent qu'au défilement mobile (voir §22) */
.points__item--copie{ display: none; }
.points__icone{ color: var(--c-creme); }
.points__icone svg{ width: 32px; height: 32px; }
.points__chiffre{
  font-family: var(--f-titre);
  font-size: clamp(1.75rem, 3.2vw, 2.6rem);
  line-height: 1;
  color: var(--c-blanc);
}
.points__libelle{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: rgba(250,246,241,.85);
  max-width: 22ch;
}

@media (max-width: 900px){
  .points__liste{
    display: flex;
    gap: var(--e-4);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-inline: var(--gouttiere);
    margin-inline: calc(-1 * var(--gouttiere));
    /* Moins d'air au-dessus et en dessous qu'en grand écran : sur un
       téléphone cette bande n'est qu'un préambule, elle ne doit pas manger la
       place de ce qui vient après. */
    padding-block: var(--e-4);
  }
  .points__liste::-webkit-scrollbar{ display: none; }
  /* Le chiffre remonte à côté de son icône au lieu de passer dessous : une
     rangée de moins par carte et la bande y gagne la hauteur d'une ligne.
     Flex plutôt que grille : les trois enfants se suivent et le libellé,
     forcé à toute la largeur, repart seul à la ligne, le couple icône +
     chiffre reste centré, ce qu'une grille à deux colonnes ne donnait pas,
     le libellé qui les enjambe élargissant les colonnes à sa guise. */
  .points__item{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    column-gap: var(--e-2);
    row-gap: var(--e-1);
    flex: 0 0 min(58vw, 215px);
    scroll-snap-align: center;
    border-left: 0;
    padding: var(--e-4);
    background: rgba(250,246,241,.06);
    border-radius: var(--r-carte);
  }
  /* `line-height: 0` : sans lui le SVG s'assoit sur la ligne de base et traîne
     sous lui le creux réservé aux jambages, l'icône paraîtrait remontée par
     rapport au chiffre qu'elle accompagne. */
  .points__icone{ line-height: 0; }
  .points__icone svg{ width: 26px; height: 26px; }
  .points__chiffre{ font-size: 1.5rem; }
  .points__libelle{ flex: 0 0 100%; }
}

/* ========== 10. LA MAISON ========== */

.maison{ position: relative; overflow: hidden; }
.maison .tache-aquarelle{
  width: 380px; height: 380px;
  top: -120px; right: -110px;
  background: radial-gradient(circle, var(--c-rose-poudre) 0%, transparent 70%);
}

.histoire{
  display: grid;
  grid-template-columns: 5fr 6fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
  position: relative;
  z-index: 1;
}
.histoire__visuel{ position: relative; }
.histoire__visuel .placeholder-img{ border-radius: var(--r-carte); box-shadow: var(--ombre-carte); }

.histoire__texte > * + *{ margin-top: var(--e-4); }

.encadre-equipe{
  margin-top: var(--e-6);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-4);
  align-items: center;
  padding: var(--e-5);
  background: var(--c-blanc);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
}
.encadre-equipe__portrait{
  width: 84px; height: 84px;
  border-radius: 50%;
  overflow: hidden;
  flex: none;
}
.encadre-equipe__portrait .placeholder-img{ aspect-ratio: 1/1; border-radius: 50%; }
.encadre-equipe blockquote{ margin: 0; }
.encadre-equipe__citation{
  font-family: var(--f-titre);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1.25;
  color: var(--texte);
}
.encadre-equipe__signature{
  display: block;
  margin-top: var(--e-2);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--texte-doux);
  font-style: normal;
}

/* Les Espaces */
.espaces{ margin-top: clamp(3rem, 7vw, 5.5rem); position: relative; z-index: 1; }
.espaces__grille{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--gouttiere);
  margin-top: var(--e-6);
}
.carte-espace{
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4/3;
  border-radius: var(--r-carte);
  overflow: hidden;
  box-shadow: var(--ombre-carte);
  text-align: left;
  transition: box-shadow var(--t-base), transform var(--t-base);
}
.carte-espace:hover{ transform: translateY(-3px); box-shadow: var(--ombre-survol); }
.carte-espace__media{ position: absolute; inset: 0; transition: transform var(--t-lent); }
.carte-espace__media .placeholder-img{ width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
.carte-espace:hover .carte-espace__media{ transform: scale(1.03); }
.carte-espace__voile{
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(56,56,56,.78) 0%, rgba(56,56,56,.18) 45%, transparent 75%);
}
.carte-espace__pied{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--e-3);
  padding: var(--e-4) var(--e-5);
  color: var(--c-blanc);
}
.carte-espace__titre{
  font-family: var(--f-titre);
  font-size: clamp(1.4rem, 2.4vw, 1.9rem);
  line-height: 1.1;
}
.carte-espace__loupe{
  flex: none;
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgba(255,255,255,.2);
  backdrop-filter: blur(4px);
}
.carte-espace__loupe svg{ width: 18px; height: 18px; }

/* Carte carte-Google-Maps : écran de consentement RGPD */
.carte-maps{
  position: relative;
  aspect-ratio: 4/3;
  border-radius: var(--r-carte);
  overflow: hidden;
  box-shadow: var(--ombre-carte);
  background: var(--c-creme);
}
.carte-maps iframe{ width: 100%; height: 100%; border: 0; }
.consentement{
  position: absolute; inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: var(--e-3);
  padding: var(--e-5);
  text-align: center;
  background-color: var(--c-creme);
  background-image:
    radial-gradient(60% 50% at 20% 25%, rgba(248,200,168,.5) 0%, transparent 70%),
    radial-gradient(50% 45% at 78% 18%, rgba(248,232,200,.55) 0%, transparent 72%);
}
.consentement__icone{ color: var(--c-terre); }
.consentement__icone svg{ width: 30px; height: 30px; }
.consentement__titre{ font-family: var(--f-ui); font-weight: 500; }
.consentement__note{
  font-size: var(--fs-micro);
  color: var(--texte-doux);
  max-width: 34ch;
}

@media (max-width: 900px){
  .histoire{ grid-template-columns: 1fr; }
  .histoire__visuel{ order: -1; }
}

/* ========== 11. LES CHAMBRES ==========
   Mise en page des cartes reprise de la référence visuelle client :
   image + pastille, titre, ligne de métadonnées en capitales espacées,
   puces d'équipement, puis CTA en lien fléché en bas. */

.chambres__grille{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gouttiere);
}
@media (max-width: 1023px){ .chambres__grille{ grid-template-columns: repeat(2, 1fr); } }
/* Une seule colonne dès 767 px : c'est là que le rail prend la main et
   « La maison entière » doit alors se poser au-dessus de lui, pas à côté. */
@media (max-width: 767px){ .chambres__grille{ grid-template-columns: 1fr; } }

.carte-chambre{
  display: flex;
  flex-direction: column;
  /* Hauteur naturelle : c'est ce qui rend les quatre chambres identiques
     entre elles, la différence avec la carte « maison entière » étant
     comblée par le bloc mauve. */
  flex: 0 0 auto;
  background: var(--c-blanc);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
  overflow: hidden;
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.chambres__cellule:hover .carte-chambre{
  transform: translateY(-3px);
  box-shadow: var(--ombre-survol);
}
.carte-chambre--phare{ border: 2px solid var(--accent); }
.carte-chambre--phare .carte-chambre__titre{ color: var(--accent-fonce); }

/* Cellule de grille : elle s'étire sur toute la hauteur de la ligne. La carte
   garde sa hauteur de contenu et le bloc mauve comble la différence. */
.chambres__cellule{
  display: flex;
  flex-direction: column;
}

/* Bloc de comblement, repris du mauve du motif signature de la section
   « La maison ». Arrondi en bas seulement et séparé de la carte par une
   marge : il se lit comme un socle, pas comme un prolongement de la carte. */
.chambres__comble{
  display: none;              /* affiché seulement là où il est utile, plus bas */
  flex: 1 1 auto;
  /* Hauteur plancher : depuis que les cinq cartes de chambre réservent le même
     nombre de lignes, elles ont grandi et l'écart avec la carte « maison
     entière » s'est refermé, le bloc était tombé à trois pixels, autant dire
     disparu. Il a maintenant une hauteur à lui ; quand l'écart est plus grand,
     il s'étire pour le combler comme avant. */
  min-height: 92px;
  margin-top: var(--e-3);
  border-radius: 0 0 var(--r-carte) var(--r-carte);
  /* Même fond que la carte « Autres prestations sur demande » : ivoire et deux
     lavis très doux. Les deux blocs jouent le même rôle, remplir une case
     sans photo et se ressemblent donc. Sur le blanc de cette section, ce fond
     seul ne se voyait pas : le liseré et l'ombre, ceux des cartes du site, le
     posent comme un vrai rectangle sans changer sa couleur. */
  background-color: var(--c-ivoire);
  background-image:
    radial-gradient(60% 50% at 30% 30%, rgba(248,216,216,.5) 0%, transparent 70%),
    radial-gradient(50% 45% at 75% 70%, rgba(248,232,200,.55) 0%, transparent 72%);
  border: 1px solid var(--bordure-douce);
  box-shadow: var(--ombre-carte);
}

/* La carte « maison entière » occupe alors toute la hauteur de sa cellule :
   sans ça, le bloc plancher creusait un vide sous elle. Son bouton reste collé
   en bas, l'air se répartit au-dessus. */
.chambres__cellule .carte-chambre--phare{ flex: 1 1 auto; }
.carte-chambre--phare .carte-chambre__pied{ margin-top: auto; }

/* Le comble n'a de sens qu'à côté de la carte « maison entière », plus haute.
   Les positions dépendent du nombre de colonnes : en 3 colonnes la première
   ligne est [maison · Chambre 1 · Chambre 2], en 2 colonnes [maison · Chambre 1].
   Ailleurs il n'y a rien à combler, donc on ne l'affiche pas, ce qui écarte
   aussi tout risque de débordement quand la différence de hauteur est nulle.
   Les rangs se comptent DANS LA PISTE, qui ne contient plus que les chambres :
   `display: contents` aplatit les boîtes, pas l'arbre du document et
   `nth-child` lit l'arbre. D'où le décalage d'un cran depuis que « La maison
   entière » a quitté la piste. */
@media (min-width: 1024px){
  .chambres__piste .chambres__cellule:nth-child(1) .chambres__comble,
  .chambres__piste .chambres__cellule:nth-child(2) .chambres__comble{ display: block; }
}
@media (min-width: 768px) and (max-width: 1023px){
  .chambres__piste .chambres__cellule:nth-child(1) .chambres__comble{ display: block; }
}

.carte-chambre__media{
  position: relative;
  overflow: hidden;
}
.carte-chambre__media .placeholder-img{
  border-radius: 0;
  transition: transform var(--t-lent);
}
.carte-chambre:hover .carte-chambre__media .placeholder-img{ transform: scale(1.03); }

.carte-chambre__corps{
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-5);
  flex: 1;
}
.carte-chambre__titre{
  font-family: var(--f-ui);
  font-size: 1.375rem;
  font-weight: 500;
  letter-spacing: .005em;
  color: var(--texte);
}
.carte-chambre__meta{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--texte-doux);
  margin-top: calc(-1 * var(--e-2));
}
/* La ligne de métadonnées est un emplacement de hauteur fixe : deux lignes.
   Sans cette réserve, « SUITE · 54 M² · CAPACITÉ À CONFIRMER » tient sur une
   ligne alors que « CHAMBRE · SURFACE À CONFIRMER · CAPACITÉ À CONFIRMER » en
   prend deux et les cartes cessent d'avoir la même hauteur. Réserver la place
   règle le problème définitivement, y compris quand les vrais libellés
   arriveront. La carte « maison entière » est exclue : elle est volontairement
   plus haute, lui ajouter une ligne vide ne ferait qu'un trou. */
/* Les cinq cartes de chambre doivent faire la même hauteur, quel que soit le
   texte qu'on y met. Plutôt que de figer la hauteur de la carte, qui casserait
   au premier libellé plus long, on réserve à chaque bloc le nombre de lignes
   du plus bavard : deux lignes de titre, deux de métadonnées, trois de résumé,
   trois rangs de pastilles. Un texte plus court laisse du blanc ; il ne décale
   plus la grille. */
.carte-chambre:not(.carte-chambre--phare) .carte-chambre__titre{
  min-height: 2.5em;   /* 2 lignes à line-height 1,25 */
}
.carte-chambre:not(.carte-chambre--phare) .carte-chambre__meta{
  min-height: 3.4em;   /* 2 lignes à line-height 1.7 */
}
.carte-chambre:not(.carte-chambre--phare) .carte-chambre__resume{
  min-height: 5.1em;   /* 3 lignes à line-height 1.7 */
}
.carte-chambre:not(.carte-chambre--phare) .carte-chambre__puces{
  min-height: calc(3 * var(--h-puce) + 2 * var(--e-2));
}
.carte-chambre__resume{
  font-size: var(--fs-petit);
  color: var(--texte-doux);
  max-width: none;
}
.carte-chambre__puces{ margin-top: var(--e-1); }
.carte-chambre__tarif{
  margin-top: auto;
  padding-top: var(--e-3);
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  color: var(--texte);
}
.carte-chambre__tarif b{ font-weight: 500; }
.carte-chambre__pied{
  padding-top: var(--e-2);
  border-top: 1px solid var(--bordure-douce);
}

/* ========== 12. PRESTATIONS ==========
   Grille asymétrique : la randonnée avec les ânes occupe 2×2. */

.prestations__grille{
  /* Quatre cartes de format identique sur une ligne : petits dejeuners, anes,
     raquettes, autres. En dessous de 1200 px elles se rangent en 2x2. */
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gouttiere);
  align-items: stretch;
}
@media (max-width: 1199px){
  .prestations__grille{ grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px){
  .prestations__grille{ grid-template-columns: 1fr; }
}

.carte-presta{
  position: relative;
  display: flex;
  flex-direction: column;
  text-align: left;
  background: var(--c-blanc);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
  overflow: hidden;
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.carte-presta:hover{ transform: translateY(-3px); box-shadow: var(--ombre-survol); }
.carte-presta__media{ position: relative; overflow: hidden; }
.carte-presta__media .placeholder-img{ border-radius: 0; transition: transform var(--t-lent); }
.carte-presta:hover .carte-presta__media .placeholder-img{ transform: scale(1.03); }
.carte-presta__corps{
  display: flex; flex-direction: column; gap: var(--e-2);
  padding: var(--e-5); flex: 1;
}
.carte-presta__titre{
  font-family: var(--f-ui);
  font-size: var(--fs-h3);
  font-weight: 500;
}
.carte-presta__accroche{ font-size: var(--fs-petit); color: var(--texte-doux); max-width: none; }
.carte-presta__pied{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-3); margin-top: auto; padding-top: var(--e-4);
}
.carte-presta__savoir{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-fonce);
  display: inline-flex; align-items: center; gap: var(--e-2);
}
.carte-presta__savoir svg{ width: 16px; height: 16px; transition: transform var(--t-base); }
.carte-presta:hover .carte-presta__savoir svg{ transform: translateX(3px); }

/* ========== 13. GALERIE ========== */

/* Tuiles de hauteur uniforme : c'est ce qui garantit qu'aucune case ne reste
   vide. Les deux dernières sont panoramiques et complètent la dernière ligne,
   avec une largeur adaptée au nombre de colonnes de chaque rupture. */
.galerie__grille{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.galerie__item{
  position: relative;
  border-radius: var(--r-vignette);
  overflow: hidden;
  padding: 0;
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.galerie__item .placeholder-img{ aspect-ratio: 4/3; border-radius: 0; }
.galerie__item:hover{ transform: scale(1.015); box-shadow: var(--ombre-survol); z-index: 1; }

/* Le remplissage dépend du nombre de tuiles ET du nombre de colonnes. Les deux
   vues du village ajoutées le 19/10/2026 portent la galerie de 16 à 18 tuiles,
   ce qui retourne complètement la règle précédente :
    ── 4 colonnes : 18 tuiles laissaient deux cases vides en bas. Deux tuiles
       panoramiques prennent deux colonnes, ce qui fait 20 cases, soit 5 lignes
       pleines ;
    ── 3 colonnes : 18 se divise par 3, donc aucune tuile double, sinon on
       repasse à 20 et le compte retombe faux ;
    ── 2 colonnes : 18 ou 20, les deux tombent juste. On garde les tuiles
       doubles, qui donnent du rythme.
   `dense` rebouche les trous que le placement automatique laisserait devant
   une tuile double. */
.galerie__grille{ grid-auto-flow: dense; }
.galerie__item--large{ grid-column: span 2; }
.galerie__item--large .placeholder-img{ aspect-ratio: 8/3; }

@media (max-width: 1023px){
  .galerie__grille{ grid-template-columns: repeat(3, 1fr); }
  .galerie__item--large{ grid-column: span 1; }
  .galerie__item--large .placeholder-img{ aspect-ratio: 4/3; }
}
@media (max-width: 700px){
  .galerie__grille{ grid-template-columns: repeat(2, 1fr); }
  .galerie__item--large{ grid-column: span 2; }
  .galerie__item--large .placeholder-img{ aspect-ratio: 8/3; }
}

/* ========== 14. ACTIVITÉS ========== */

.activites__grille{
  /* Flex plutôt que grid : c'est ce qui permet de centrer les deux cartes de
     la seconde ligne au lieu de les coller à gauche. */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gouttiere);
}
/* Carte à fond aquarelle. Le fond est une région du lavis de la carte de
   visite (outils/fonds-activites.py) ; le voile BLANC qui s'épaissit vers le
   bas est ce qui permet d'écrire dessus en anthracite. Assombrir le lavis
   pour y mettre du texte blanc le faisait virer au gris sale, voir le
   README §« Fonds des activités ». Le contraste est vérifié par le script
   qui fabrique les images : au pire 5,1:1. */
.carte-activite{
  flex: 0 1 calc((100% - 2 * var(--gouttiere)) / 3);
  min-width: 240px;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  min-height: 300px;
  text-align: left;
  background: var(--c-creme);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.carte-activite:hover{ transform: translateY(-3px); box-shadow: var(--ombre-survol); }
@media (max-width: 900px){
  .carte-activite{ flex: 0 1 calc((100% - var(--gouttiere)) / 2); }
}
@media (max-width: 560px){
  .carte-activite{ flex: 1 1 100%; }
}
.carte-activite__fond{
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-lent);
}
.carte-activite:hover .carte-activite__fond{ transform: scale(1.04); }
.carte-activite__voile{
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    rgba(255,255,255,.30) 0%,
    rgba(255,255,255,.55) 45%,
    rgba(255,255,255,.84) 100%);
}
.carte-activite__corps{
  display: flex; flex-direction: column; gap: var(--e-3);
  width: 100%;
  padding: var(--e-5);
  justify-content: flex-end;   /* le texte se pose dans le bas de la carte */
}
.carte-activite__embleme{ color: var(--texte); margin-bottom: auto; }
.carte-activite__embleme svg{ width: 40px; height: 40px; }
.carte-activite__titre{ font-family: var(--f-ui); font-size: var(--fs-h3); font-weight: 500; }
/* Anthracite et non gris doux : le gris doux ne tient pas 4,5:1 au-dessus des
   éclaboussures de rose du lavis. */
.carte-activite__accroche{ font-size: var(--fs-petit); color: var(--texte); max-width: none; }
/* Y compris au survol : le bois de rose plafonne à 3,4:1 sur le lavis. */
.carte-activite__pied .lien-fleche,
.carte-activite:hover .carte-activite__pied .lien-fleche{ color: var(--texte); }
.carte-activite__compte{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-fonce);
  display: inline-flex; align-items: center; gap: var(--e-2);
}
.carte-activite__compte svg{ width: 16px; height: 16px; transition: transform var(--t-base); }
.carte-activite:hover .carte-activite__compte svg{ transform: translateX(3px); }

/* Liste de lieux dans la modale */
.lieux{ display: grid; gap: var(--e-3); }
.lieu{
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--e-3) var(--e-5);
  align-items: start;
  padding: var(--e-4);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-champ);
  background: var(--c-blanc);
}
.lieu[hidden]{ display: none !important; }
.lieu__titre{ font-family: var(--f-ui); font-size: 1.0625rem; font-weight: 500; }
.lieu__meta{
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-2);
  margin-top: 2px;
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--texte-doux);
}
.lieu__accroche{ font-size: var(--fs-petit); color: var(--texte-doux); margin-top: var(--e-2); max-width: 62ch; }
.lieu__actions{ display: flex; flex-wrap: wrap; gap: var(--e-2); align-self: center; }
@media (max-width: 640px){
  .lieu{ grid-template-columns: 1fr; }
  .lieu__actions{ align-self: start; }
}


/* ========== 15. CONTACT ========== */

.contact{ position: relative; }
.contact__grille{
  display: grid;
  grid-template-columns: 6fr 5fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
  position: relative; z-index: 1;
}
@media (max-width: 900px){ .contact__grille{ grid-template-columns: 1fr; } }

.formulaire{
  padding: clamp(1.5rem, 3vw, 2.5rem);
  background: var(--c-blanc);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
}
.formulaire__grille{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--e-4);
}
/* Sous 560 px, une seule colonne : les champs de date ont une largeur
   minimale incompressible (« jj/mm/aaaa » plus l'icône du calendrier) et à
   deux colonnes le formulaire faisait 420 px de large sur un écran de 375.
   Le navigateur élargissait alors toute la page pour l'y faire tenir. */
@media (max-width: 560px){
  .formulaire__grille{ grid-template-columns: 1fr; }
}
.champ{ display: grid; gap: var(--e-2); }
.champ--large{ grid-column: 1 / -1; }
.champ__label{
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  font-weight: 500;
  color: var(--texte);
}
.champ__label .requis{ color: var(--accent-fonce); }
.champ input, .champ select, .champ textarea{
  width: 100%;
  min-height: 48px;
  padding: .7rem .9rem;
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-champ);
  background: var(--c-ivoire);
  font-family: var(--f-corps);
  font-size: var(--fs-body);
  color: var(--texte);
  transition: border-color var(--t-base), background-color var(--t-base);
}
.champ textarea{ min-height: 130px; padding-top: .8rem; }
.champ input:hover, .champ select:hover, .champ textarea:hover{ border-color: var(--c-terre); }
.champ input:focus, .champ select:focus, .champ textarea:focus{
  background: var(--c-blanc);
  border-color: var(--accent);
}
.champ input[aria-invalid="true"],
.champ select[aria-invalid="true"],
.champ textarea[aria-invalid="true"]{
  border-color: var(--accent-fonce);
  background: #FFF6F8;
}
.champ__erreur{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--accent-fonce);
  min-height: 1em;
}
.champ__erreur:empty{ min-height: 0; }
.champ__aide{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  line-height: 1.45;
  color: var(--texte-doux);
  max-width: none;
}

/* ---------- Prestations supplémentaires : un groupe de cases ---------- */
.champ-groupe{
  display: grid;
  gap: var(--e-2);
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;        /* un <fieldset> refuse de rétrécir sans ça */
}
.cases-prestations{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--e-2) var(--e-4);
  margin-top: var(--e-1);
}
.case-presta{
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  align-items: center;
  font-size: var(--fs-petit);
  cursor: pointer;
}
.case-presta input{
  width: 20px; height: 20px; min-height: 0;
  accent-color: var(--c-encre);
}
.case-presta__nom{ display: block; }
/* L'état d'une case verrouillée, dit en toutes lettres sous son intitulé :
   « compris dans le prix de la chambre ». Sans cette ligne, une case cochée
   qu'on ne peut pas décocher est une énigme. */
.case-presta__etat{
  display: block;
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--texte-doux);
  line-height: 1.35;
}
/* Prestation comprise dans la formule : cochée, verrouillée, mais bien
   présente, ce n'est pas une ligne grisée, c'est une ligne acquise. */
.case-presta--incluse{ cursor: default; }
.case-presta--incluse .case-presta__nom{ color: var(--texte); }

.consent{
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e-3);
  align-items: start;
}
/* Le message d'erreur occupe les deux colonnes. Placé automatiquement, il
   tombait dans la première, celle de la case à cocher et sa largeur y
   poussait l'étiquette vers la droite dès qu'un texte s'y affichait. */
.consent .champ__erreur{ grid-column: 1 / -1; }
.consent input[type="checkbox"]{
  width: 22px; height: 22px; min-height: 0;
  margin-top: 2px;
  accent-color: var(--c-encre);
  flex: none;
}
.consent label{ font-size: var(--fs-petit); color: var(--texte-doux); }
.consent a{ color: var(--accent-fonce); }

/* Piège à robots : invisible pour l'humain, sans CAPTCHA */
.appat{
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px; overflow: hidden;
}

.formulaire__message{
  grid-column: 1 / -1;
  padding: var(--e-4);
  border-radius: var(--r-champ);
  font-size: var(--fs-petit);
}
.formulaire__message[data-type="succes"]{ background: #F2F8F2; border: 1px solid #BFD9BF; }
.formulaire__message[data-type="erreur"]{ background: #FFF6F8; border: 1px solid var(--c-rose); }
.formulaire__message:empty{ display: none; }

/* Colonne droite : 4 cartes */
.contact__cartes{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--gouttiere);
}
/* Une seule colonne UNIQUEMENT dans la bande 901-1150 px : la grille du
   contact y tient encore deux colonnes, donc celle des cases est etroite et
   deux cases cote a cote y seraient illisibles. Sous 901 px la grille passe a
   une colonne, les cases reprennent toute la largeur de la page et tiennent de
   nouveau deux par ligne, comme sur l'ordinateur. Demande de Nathan,
   21/10/2026. La case « Nous trouver » garde sa pleine largeur par
   .carte-contact--large, elle porte le plan. */
@media (max-width: 1150px) and (min-width: 901px){
  .contact__cartes{ grid-template-columns: 1fr; }
}
.carte-contact{
  display: grid; gap: var(--e-2);
  padding: var(--e-5);
  background: var(--c-blanc);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
}
.carte-contact--large{ grid-column: 1 / -1; }
/* Carte des avis : tout est centré sur la largeur de la case, titre compris.
   Le bouton était calé à droite quand la carte faisait toute la largeur ; en
   demi-largeur il se centre sous la note. */
.carte-contact--avis{ justify-items: center; text-align: center; }
.carte-contact--avis .carte-contact__liens{ justify-self: center; }

/* Les cases d'une même rangée s'étirent à la hauteur de la plus haute. Sans
   cette ligne, c'est la GRILLE INTERNE de la case qui absorbait le surplus :
   elle le répartissait entre ses lignes, et le mot « Email » décrochait de son
   icône de vingt pixels alors que « Instagram » et « Téléphone » restaient
   collés aux leurs. Le contenu se cale en haut, le surplus tombe en bas.
   La carte « Nous trouver » est exclue : sa dernière ligne vaut `1fr` et doit
   justement prendre la hauteur restante pour que le plan s'étire. */
.carte-contact:not(.carte-contact--trouver){ align-content: start; }
.carte-contact__icone{ color: var(--accent); }
.carte-contact__icone svg{ width: 24px; height: 24px; }
.carte-contact__titre{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--texte-doux);
}
.carte-contact__valeur{
  font-family: var(--f-ui);
  font-size: clamp(1.05rem, 1.7vw, 1.3rem);
  font-weight: 500;
  color: var(--texte);
  text-decoration: none;
  word-break: break-word;
}
.carte-contact__valeur:hover{ color: var(--accent-fonce); }
.carte-contact__note{ font-size: var(--fs-micro); color: var(--texte-doux); }
.carte-contact blockquote{
  margin: 0;
  font-size: var(--fs-petit);
  font-style: italic;
  color: var(--texte-doux);
}
.carte-contact__liens{ display: flex; flex-wrap: wrap; gap: var(--e-2); margin-top: var(--e-2); }

/* ---------- Telephone : les quatre cases deux par ligne ----------
   A demi-largeur il reste 134 px de texte utile. Mesure faite dans le
   navigateur : « +33 6 30 53 30 82 » occupe 145 px a la taille de base de
   16,8 px et 121 px a 14 px. La taille de base cassait donc le numero en deux
   lignes et coupait « contact@tnature.fr » juste avant le « .fr ».
   Ce bloc est pose APRES .carte-contact__valeur a dessein : a specificite
   egale, c'est la derniere regle qui gagne. Place plus haut dans le fichier,
   il etait silencieusement annule par le clamp de la regle de base. */
@media (max-width: 480px){
  .contact__cartes{ gap: var(--e-3); }
  .carte-contact{ padding: var(--e-4); }
  /* Le texte descend a 14 px, mais la zone touchable garde 44 px de haut :
     en rapetissant le libelle j'avais ramene ces liens de 27 a 24 px, sous le
     seuil ou le doigt commence a manquer sa cible. Le lien reste visuellement
     de la meme taille, c'est sa boite qui s'ouvre. */
  .carte-contact__valeur{
    font-size: var(--fs-petit);
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* Le bouton d'itineraire plafonnait a 41 px, trois pixels sous le seuil.
     C'etait deja le cas avant ce lot. */
  .carte-contact .btn--compact{ min-height: 44px; }
  /* Le bouton des avis prend toute la case et garde 44 px de haut, la hauteur
     minimale pour etre touche au doigt sans viser. */
  .carte-contact--avis .carte-contact__liens{ width: 100%; }
  .carte-contact--avis .carte-contact__liens .btn{
    width: 100%;
    min-height: 44px;
    padding-inline: var(--e-2);
    font-size: .72rem;
    /* Interlettrage ramene a zero. Mesure au navigateur : « 87 AVIS SUR
       AIRBNB » occupe 126 px avec l'espacement courant et 110 px sans, pour
       116 px disponibles. C'est l'espacement, pas la taille, qui jetait le
       libelle sur trois lignes. */
    letter-spacing: normal;
  }
}

/* ========== 16. PIED DE PAGE ========== */

.pied{ background: var(--c-encre); color: var(--texte-inverse); }
.pied__grille{
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: clamp(1.5rem, 3vw, 3rem);
  padding-block: clamp(3rem, 6vw, 4.5rem) var(--e-6);
}
@media (max-width: 900px){ .pied__grille{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px){ .pied__grille{ grid-template-columns: 1fr; } }

.pied__logo{ --h-logo: 92px; align-items: flex-start; }
.pied__baseline{
  margin-top: var(--e-3);
  font-size: var(--fs-petit);
  color: rgba(250,246,241,.75);
  max-width: 30ch;
}
.pied__titre{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--c-peche);
  margin-bottom: var(--e-4);
}
.pied__liste{ display: grid; gap: var(--e-2); }
.pied a{
  color: rgba(250,246,241,.85);
  text-decoration: none;
  font-size: var(--fs-petit);
  transition: color var(--t-base);
}
.pied a:hover{ color: var(--c-blanc); text-decoration: underline; }
.pied__social{
  display: inline-flex; align-items: center; gap: var(--e-2);
  margin-top: var(--e-4);
}
.pied__social svg{ width: 22px; height: 22px; }
.pied__bas{
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--e-3);
  padding-block: var(--e-4);
  border-top: 1px solid rgba(250,246,241,.15);
  font-size: var(--fs-micro);
  color: rgba(250,246,241,.65);
}
.pied__bas a{ font-size: var(--fs-micro); }

/* ========== 17. MODALES ET CARROUSELS ========== */

.modale{
  position: fixed; inset: 0;
  z-index: var(--z-modale);
  display: none;
  padding: var(--e-4);
  place-items: center;
}
.modale[data-ouvert="1"]{ display: grid; }
.modale__voile{
  position: absolute; inset: 0;
  background: rgba(56,56,56,.6);
  backdrop-filter: blur(4px);
}
/* C'est le CORPS qui défile, pas la boîte : la croix de fermeture, posée sur
   la boîte, reste donc à l'écran du début à la fin de la modale, y compris
   au bas d'une fiche longue. La barre d'action collante, elle, est dans le
   corps et continue de se coller au bas de la zone de défilement. */
.modale__boite{
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(1100px, 92vw);
  max-height: 88vh;
  overflow: hidden;
  background: var(--c-blanc);
  border-radius: var(--r-modale);
  box-shadow: 0 30px 80px rgba(56,56,56,.35);
  animation: modale-entree var(--t-base) both;
}
.modale--large .modale__boite{ width: min(1240px, 94vw); }
@keyframes modale-entree{
  from{ opacity: 0; transform: translateY(14px) scale(.99); }
  to{ opacity: 1; transform: none; }
}
.modale__fermer{
  position: absolute; top: var(--e-4); right: var(--e-4);
  z-index: 5;
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(255,255,255,.92);
  color: var(--texte);
  box-shadow: 0 2px 12px rgba(56,56,56,.18);
  transition: background-color var(--t-base), transform var(--t-base);
}
.modale__fermer:hover{ background: var(--c-creme); transform: rotate(90deg); }
.modale__fermer svg{ width: 20px; height: 20px; }
.modale__corps{
  padding: clamp(1.25rem, 3vw, 2.25rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Seul l'en-tête se décale sous la croix : le reste du corps garde toute la
   largeur. */
.modale__entete{ margin-bottom: var(--e-5); padding-right: 52px; }
.modale__titre{
  font-family: var(--f-titre);
  font-size: clamp(1.9rem, 3.6vw, 2.9rem);
  line-height: 1.05;
}
.modale__titre--embleme{ display: flex; align-items: center; gap: var(--e-3); }
.modale__embleme{ color: var(--accent); flex: none; }
.modale__embleme svg{ width: 34px; height: 34px; display: block; }
.modale__meta{
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3);
  margin-top: var(--e-2);
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  color: var(--texte-doux);
}
/* Prix rappele en haut de modale de chambre, juste avant « Ce qui vous attend » */
.modale__tarif{
  margin-top: var(--e-4);
  margin-bottom: 0;
  font-family: var(--f-ui);
  font-size: var(--fs-petit);
  color: var(--texte-doux);
}
.modale__tarif__valeur{
  font-family: var(--f-titre);
  font-size: clamp(1.375rem, 2.2vw, 1.75rem);
  line-height: 1;
  color: var(--accent);
  margin-inline: .12em;
}
.modale__tarif--demande{
  font-family: var(--f-titre);
  font-size: clamp(1.125rem, 1.8vw, 1.375rem);
  color: var(--accent);
}

.modale__section{ margin-top: var(--e-6); }
.modale__section > h3{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--e-3);
}
.modale__texte > * + *{ margin-top: var(--e-3); }

/* Le texte des modales occupe toute la largeur de sa colonne.
   La limite globale de 68 caractères (confort de lecture) laissait un vide à
   droite dans les modales, où la colonne de texte est déjà étroite du fait du
   média flottant : la borne n'y sert plus à rien et se voit. */
.modale__corps p,
.modale__corps li,
.modale__corps blockquote{ max-width: none; }
.lieu__accroche{ max-width: none; }

/* Chaque section de modale établit son propre contexte de formatage.
   Sans ça, un bloc voisin d'un flottant a une boîte pleine largeur, seules
   ses LIGNES sont décalées. Les blocs à fond coloré (tarifs, verbatims,
   fiches d'adresse) passaient donc sous l'image et l'on voyait une carte
   large dont le texte s'arrêtait au milieu. `flow-root` fait rétrécir la
   boîte pour longer le flottant et les sections situées sous le bas de
   l'image reprennent d'elles-mêmes toute la largeur. */
.modale__flux > .modale__section{ display: flow-root; }

/* La partie descriptive passe toujours SOUS l'image, jamais à côté. Sans ça,
   son alignement dépendait de la longueur de la liste de bénéfices qui la
   précède : long, elle dépassait l'image et le texte reprenait à gauche ;
   court, elle restait collée au flanc droit de l'image. Deux fiches ne se
   ressemblaient plus. `clear` rend la mise en page indépendante du texte. */
.modale__section--sous-media{ clear: both; }

/* Barre d'action, posée au bas de la boîte, hors de la zone qui défile.
   Elle ne bouge donc pas d'un pixel pendant qu'on parcourt la fiche. */
.modale__cta{
  flex: none;
  display: grid; gap: var(--e-2);
  padding: var(--e-4) clamp(1.25rem, 3vw, 2.25rem);
  background: var(--c-blanc);
  border-top: 1px solid var(--bordure-douce);
}
.modale__cta-boutons{
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3);
}
.modale__cta .btn{ flex: 1 1 auto; }
/* Ligne de réassurance : elle lève les trois objections de dernière seconde
   (délai de réponse, fiabilité, frais). Elle ne dit que des faits déjà
   affichés ailleurs sur le site. */
.modale__cta-note{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--texte-doux);
  max-width: none;
}
.modale__cta a:not(.btn){
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

/* ---------- Argumentaire : promesse, puis bénéfices ----------
   L'ordre de lecture d'une modale est celui d'une page de vente : ce qu'on
   promet, ce qu'on y gagne, ce que les autres en disent, puis les détails,
   le prix et l'action. Le descriptif n'a pas disparu, il est descendu. */
.modale__promesse{
  margin-top: var(--e-3);
  font-family: var(--f-corps);
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.5;
  color: var(--texte);
  max-width: none;
}
.benefices{ display: grid; gap: var(--e-3); }
.benefice{
  display: flex; align-items: flex-start; gap: var(--e-3);
  font-size: var(--fs-petit);
}
.benefice > svg{
  width: 20px; height: 20px; flex: none;
  margin-top: 2px;
  color: var(--accent);
}
.benefice__titre{
  display: block;
  font-family: var(--f-ui);
  font-weight: 500;
  font-size: var(--fs-body);
  color: var(--texte);
}
.benefice__texte{ display: block; color: var(--texte-doux); }

/* Bloc tarif */
.bloc-tarif{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--e-4);
  padding: var(--e-5);
  background: var(--c-ivoire);
  border-radius: var(--r-champ);
}
.bloc-tarif__prix{
  font-family: var(--f-titre);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  line-height: 1.1;
}
.bloc-tarif__liste{ display: grid; gap: var(--e-1); font-size: var(--fs-petit); }
.bloc-tarif__liste li{ display: flex; gap: var(--e-2); }
.bloc-tarif__liste li::before{ content: "·"; color: var(--accent); font-weight: 700; }

/* Grille d'équipements */
.equipements{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--e-2) var(--e-4);
}
.equipements li{
  display: flex; align-items: center; gap: var(--e-2);
  font-size: var(--fs-petit);
}
.equipements svg{ width: 15px; height: 15px; color: var(--accent); flex: none; }
/* L'aperçu porte un picto par ligne au lieu de la coche : un dessin de cuisine
   ou de vélo a besoin d'un peu plus de place qu'une coche pour rester lisible. */
.equipements--pictos li{ align-items: center; }
.equipements--pictos svg{ width: 19px; height: 19px; }

/* Liste ordonnée du déroulé d'une prestation */
.deroule{ counter-reset: etape; display: grid; gap: var(--e-3); }
.deroule li{
  counter-increment: etape;
  display: grid; grid-template-columns: auto 1fr; gap: var(--e-3);
  align-items: start;
  font-size: var(--fs-petit);
}
.deroule li::before{
  content: counter(etape);
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--c-creme);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 500;
}

/* Verbatims d'avis */
.verbatims{ display: grid; gap: var(--e-4); }
.verbatim{
  padding: var(--e-4);
  background: var(--c-ivoire);
  border-radius: var(--r-champ);
  border-left: 3px solid var(--accent-decor);
}
.verbatim p{ font-style: italic; font-size: var(--fs-petit); max-width: none; }
.verbatim footer{
  margin-top: var(--e-2);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--texte-doux);
}

/* Carrousel */
.carrousel{ position: relative; }
.carrousel__cadre{ position: relative; overflow: hidden; border-radius: var(--r-carte); }
.carrousel__piste{ display: flex; transition: transform var(--t-lent); }
.carrousel__vue{ flex: 0 0 100%; }
/* ---------- Photos verticales dans les carrousels ----------
   Le cadre garde un format fixe : sinon il changerait de hauteur à chaque vue
   et le texte qui l'entoure sauterait à chaque clic. C'est donc l'IMAGE qui
   s'adapte au cadre : une photo prise à la verticale y est posée entière, dans
   sa hauteur, sur un fond crème, jamais rognée en bandeau horizontal. Les
   photos horizontales, elles, continuent de remplir le cadre.
   Le cadre est passé de 3:2 à 4:3 : moins large, il laisse plus de place aux
   verticales tout en ne coupant presque rien aux horizontales. */
.carrousel__vue .placeholder-img{ border-radius: 0; aspect-ratio: 4/3; }
.carrousel__vue .placeholder-img--portrait img{
  object-fit: contain;
  position: relative;
  z-index: 1;
}
/* Derrière elle, sa propre image en grand et floutée, plutôt qu'une bande de
   couleur unie : les côtés reprennent les teintes de la photo et le cadre
   cesse de ressembler à un trou.

   Le doublon n'existe QUE dans les carrousels : ailleurs la photo remplit son
   cadre et ce fond ne servirait qu'à télécharger un fichier de plus. Masqué
   avec `display: none`, il n'est pas chargé du tout.
   L'agrandissement de 12 % masque les bords délavés que le flou laisse. */
.photo__fond{ display: none; }
.carrousel__vue .placeholder-img--portrait .photo__fond{
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
  transform: scale(1.12);
  filter: blur(26px) saturate(1.15) brightness(.92);
}
/* Dans la lightbox, le cadre est sombre : le fond flouté y est assombri pour
   que la photo reste le point clair de l'écran. */
.modale--lightbox .carrousel__vue .placeholder-img--portrait .photo__fond{
  filter: blur(26px) saturate(1.1) brightness(.55);
}
.modale--lightbox .carrousel__vue .placeholder-img--photo{ background: var(--c-encre); }
.carrousel--bandeau .carrousel__vue .placeholder-img{ aspect-ratio: 16/6; }
@media (max-width: 700px){
  .carrousel--bandeau .carrousel__vue .placeholder-img{ aspect-ratio: 3/2; }
}
.carrousel__nav{
  position: absolute; top: 50%;
  transform: translateY(-50%);
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(255,255,255,.9);
  color: var(--texte);
  box-shadow: 0 2px 12px rgba(56,56,56,.2);
  transition: background-color var(--t-base);
}
.carrousel__nav:hover{ background: var(--c-blanc); }
.carrousel__nav svg{ width: 20px; height: 20px; }
.carrousel__nav--prec{ left: var(--e-3); }
.carrousel__nav--suiv{ right: var(--e-3); }
.carrousel__nav[disabled]{ opacity: .4; cursor: default; }

.carrousel__barre{
  display: flex; align-items: center; justify-content: center; gap: var(--e-3);
  margin-top: var(--e-3);
}
.carrousel__pastilles{ display: flex; gap: var(--e-2); }
.carrousel__pastille{
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--c-terre);
  opacity: .45;
  transition: all var(--t-base);
}
.carrousel__pastille[aria-current="true"]{ opacity: 1; width: 22px; border-radius: var(--r-pilule); background: var(--c-encre); }
.carrousel__compteur{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}

/* Bande de vignettes sous la grande image */
.vignettes{
  display: flex; gap: var(--e-2);
  margin-top: var(--e-3);
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: var(--e-2);
}
.vignettes__item{
  flex: 0 0 92px;
  border-radius: var(--r-vignette);
  overflow: hidden;
  opacity: .55;
  transition: opacity var(--t-base), outline-color var(--t-base);
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.vignettes__item[aria-current="true"]{ opacity: 1; outline-color: var(--c-encre); }
.vignettes__item:hover{ opacity: .85; }
.vignettes__item .placeholder-img{ aspect-ratio: 3/2; border-radius: 0; }

/* Lightbox de la galerie */
.modale--lightbox .modale__boite{
  width: min(1100px, 94vw);
  background: transparent;
  box-shadow: none;
}
.modale--lightbox .modale__corps{ padding: 0; }
.modale--lightbox .carrousel__cadre{ background: var(--c-encre); }
.modale__legende{
  margin-top: var(--e-3);
  text-align: center;
  color: var(--c-ivoire);
  font-size: var(--fs-petit);
}

/* Modale de choix de réservation */
.choix-reservation{ display: grid; gap: var(--e-4); }
.choix-reservation__note{
  padding: var(--e-4);
  background: var(--c-creme);
  border-radius: var(--r-champ);
  font-size: var(--fs-petit);
}
/* Phrase qui a remplace le bouton « Reserver sur Airbnb » */
.choix-reservation__direct{
  margin: 0;
  text-align: center;
  font-size: var(--fs-petit);
  color: var(--texte-doux);
}

/* ---------- Bas de la section Espaces : equipements a gauche, carte a droite ---------- */
.espaces__bas{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gouttiere);
  margin-top: var(--gouttiere);
  align-items: stretch;
}
@media (max-width: 860px){
  .espaces__bas{ grid-template-columns: 1fr; }
}
.carte-maps--colonne{ aspect-ratio: auto; min-height: 340px; }

.equipements-maison{
  display: flex;
  flex-direction: column;
  gap: var(--e-4);
  padding: var(--e-5);
  background: var(--c-blanc);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-carte);
}
.equipements-maison__titre{
  margin: 0;
  font-family: var(--f-titre);
  font-size: var(--fs-h3);
  font-weight: 400;
  line-height: 1.2;
}
/* Les trois points ferment la premiere colonne de l'apercu : ils disent que la
   liste continue, le bouton juste en dessous l'ouvre en entier. Alignes sur le
   texte des autres lignes, pas sur leurs coches. */
.equipements__suite{
  padding-left: calc(15px + var(--e-2));
  color: var(--accent);
  font-size: 1.3rem;
  line-height: 1;
  letter-spacing: .12em;
}
/* Le bouton est pousse en bas : les deux colonnes gardent la meme hauteur
   quel que soit le nombre de lignes de l'apercu. */
.equipements-maison > .btn{ align-self: flex-start; margin-top: auto; }

/* ---------- La fiche complete, ouverte par « Voir tous les equipements » ---------- */
/* Colonnes de texte et non une grille. En grille, chaque rubrique occupe une
   cellule et toutes les cellules d'une rangée prennent la hauteur de la plus
   haute : « Cuisine et salle à manger » porte dix-neuf lignes, sa rangée faisait
   713 px et ses voisines laissaient trois cents pixels de vide, plus une cellule
   entièrement vide en bout de rangée. Les colonnes CSS remplissent de haut en
   bas et le navigateur équilibre leurs hauteurs : il ne reste plus de trou.
   `break-inside: avoid` interdit de couper une rubrique entre deux colonnes. */
.equipements-groupes{
  margin-top: var(--e-6);
  columns: 3 300px;
  column-gap: var(--gouttiere);
}
.equipements-groupe{
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  margin-bottom: var(--e-6);
}
.equipements-groupe__titre{
  display: flex;
  align-items: center;
  gap: var(--e-2);
  flex-wrap: wrap;
  margin: 0 0 var(--e-3);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.equipements-groupe__titre svg{ width: 17px; height: 17px; flex: none; }
/* Le titre est devenu une ligne flex : sans cette base, la note se rangerait à
   côté du titre au lieu de passer dessous. */
.equipements-groupe__note{
  flex: 0 0 100%;
  margin-top: .25em;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
  color: var(--texte-doux);
}
/* Dans la fiche complete chaque groupe tient sa colonne : une seule colonne d'items. */
.equipements-groupe .equipements{ grid-template-columns: 1fr; }
.equipements-groupe .equipements li{ align-items: flex-start; }
.equipements-groupe .equipements svg{ margin-top: .25em; }

/* ========== 18. PAGES LÉGALES ========== */

.page-legale{ padding-block: calc(var(--h-header) + var(--e-7)) var(--e-9); }
.page-legale h1{ margin-bottom: var(--e-6); }
.page-legale h2{
  font-family: var(--f-ui);
  font-size: var(--fs-h3);
  font-weight: 500;
  margin-top: var(--e-7);
  margin-bottom: var(--e-3);
  padding-bottom: var(--e-2);
  border-bottom: 1px solid var(--bordure-douce);
}
.page-legale h3{ margin-top: var(--e-5); margin-bottom: var(--e-2); }
.page-legale p, .page-legale li{ margin-top: var(--e-3); }
.page-legale ul{ padding-left: var(--e-5); list-style: disc; }
.page-legale a{ color: var(--accent-fonce); }
.a-confirmer{
  display: inline-block;
  padding: .1rem .5rem;
  border: 1px dashed var(--c-terre);
  border-radius: var(--r-pilule);
  background: var(--c-creme);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--texte-brun);
  white-space: nowrap;
}

/* ========== 19. APPARITIONS AU SCROLL ========== */

.apparait{
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .5s ease, transform .5s ease;
  transition-delay: var(--delai, 0ms);
}
.apparait[data-vu="1"]{ opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce){
  /* `transition: none` et pas seulement `opacity: 1` : si la transition ne
     s'exécute pas (onglet en arrière-plan, moteur qui la throttle, page non
     rendue), l'élément resterait bloqué à son opacité de départ, donc
     invisible. On veut la valeur finale appliquée immédiatement. */
  .apparait{ opacity: 1; transform: none; transition: none; }
  html{ scroll-behavior: auto; }
  .loader{ display: none !important; }
}

/* Sans JavaScript : rien ne doit rester masqué et rien n'est animé,
   même raison que ci-dessus, la valeur doit s'appliquer sans transition. */
.sans-js .apparait{ opacity: 1; transform: none; transition: none; }
.sans-js .loader{ display: none !important; }

/* ========== 20. MODE DÉGRADÉ SANS JAVASCRIPT ==========
   `<html class="sans-js">` est retiré par un script inline dès le <head>.
   Sans JS, la classe reste : les modales se déplient en sections normales
   et tout le contenu est lisible et indexable. */

.sans-js .modale{
  display: block;
  position: static;
  inset: auto;
  padding: 0;
  margin-block: var(--e-6);
}
.sans-js .modale__voile,
.sans-js .modale__fermer,
.sans-js [data-rail-copie],
.sans-js .carrousel__nav,
.sans-js .carrousel__barre,
.sans-js .vignettes,
.sans-js .galerie__filtres{ display: none !important; }
/* Sans JavaScript, l'en-tête ne peut pas changer d'état au défilement : on le
   fige en version opaque, faute de quoi liens et logo blancs se perdent sur le
   contenu clair dès qu'on descend. */
.sans-js .entete{ background: var(--c-blanc); box-shadow: var(--ombre-header); }
.sans-js .entete .nav__lien,
.sans-js .entete .burger{ color: var(--texte); }
.sans-js .logo__image--clair{ display: none !important; }
.sans-js .logo__image--sombre{ display: block !important; }

.sans-js .modale__corps{ overflow: visible; }
.sans-js .modale__boite{
  width: 100%;
  max-height: none;
  overflow: visible;
  animation: none;
  box-shadow: var(--ombre-carte);
  border: 1px solid var(--bordure-douce);
}
.sans-js .modale__cta{ position: static; backdrop-filter: none; }
/* Le carrousel devient une simple grille d'images */
.sans-js .carrousel__cadre{ overflow: visible; }
.sans-js .carrousel__piste{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--e-2);
  transform: none !important;
}
.sans-js .carrousel__vue{ flex: none; }
.sans-js .carrousel__vue .placeholder-img{ border-radius: var(--r-vignette); }
/* Les cartes cliquables deviennent des ancres visibles */
.sans-js [data-modale-cible]{ cursor: pointer; }
.sans-js .consentement{ position: static; }

/* ========== 21. AJUSTEMENTS DES PLACEHOLDERS PLEIN ÉCRAN ==========
   Sur le hero et le loader, le brief photo est centré par défaut et vient
   se placer derrière le titre. On le renvoie en bas à gauche : il reste
   lisible pour le photographe sans concurrencer le contenu. */

.hero__fond .placeholder-img,
.loader__fond .placeholder-img{
  align-items: flex-start;
  justify-content: flex-end;
  text-align: left;
  padding: var(--e-6) var(--gouttiere);
  gap: var(--e-1);
}
.hero__fond .placeholder-img__texte,
.loader__fond .placeholder-img__texte{
  max-width: 46ch;
  -webkit-line-clamp: 3;
}
.hero__fond .placeholder-img::before,
.loader__fond .placeholder-img::before{ inset: 10px; }

/* ============================================================
   22. MODIFICATIONS DEMANDÉES : révision du 10 septembre 2026
   ============================================================ */

/* ---------- Titre de section tenu sur une seule ligne ---------- */
.section__entete--large{ max-width: none; }
@media (min-width: 1024px){
  .titre-une-ligne{
    /* Taille plafonnée pour que le titre tienne en une ligne sans déborder ;
       en dessous de 1024 px on laisse le retour à la ligne se faire. */
    font-size: clamp(1.9rem, 3.1vw, 2.7rem);
    white-space: nowrap;
  }
}

/* ---------- Carte « Nous trouver » sur toute la largeur ---------- */
.carte-maps--pleine{
  grid-column: 1 / -1;
  aspect-ratio: auto;
  min-height: 320px;
}
.carte-maps--pleine .consentement{ position: absolute; }

/* ---------- « Nous trouver » : bouton en haut à droite, plan élastique ----------
   Deux colonnes : le texte à gauche, le bouton d'itinéraire calé dans le coin
   haut droit ; le plan reprend toute la largeur en dessous et s'étire pour
   occuper ce qui reste. C'est cet étirement qui aligne le bas de la carte sur
   le bas du formulaire, sans hauteur écrite en dur nulle part. */
.carte-contact--trouver{
  grid-template-columns: 1fr auto;
  align-content: start;
}
.carte-contact--trouver > *{ grid-column: 1; }
/* Le bouton d'itinéraire est posé sur la LIGNE DE L'ADRESSE, à droite : il
   arrive donc à la hauteur de « 1 rue de l'Église » et non tout en haut de la
   carte. */
.carte-contact--trouver .carte-contact__liens--coin{
  grid-column: 2;
  grid-row: 3;
  justify-self: end;
  align-self: start;
  margin: 0;
}
.carte-contact--trouver .carte-maps{
  grid-column: 1 / -1;
  margin-top: 0;
}
.carte-maps--remplit{ aspect-ratio: auto; min-height: 180px; }

@media (min-width: 901px){
  /* Les deux colonnes du contact partagent la hauteur de la plus haute : le
     formulaire la fixe, la colonne de cartes s'y cale. */
  .contact__grille{ align-items: stretch; }
  /* Trois lignes depuis le 20/10/2026 : Instagram et téléphone, puis l'e-mail
     et les avis, puis le plan, qui s'étire pour remplir la hauteur du
     formulaire. */
  .contact__cartes{ grid-template-rows: auto auto 1fr; }
  /* C'est le PLAN qui absorbe la hauteur restante, quatre lignes, la
     quatrième élastique. Quand c'était la ligne de l'adresse qui s'étirait,
     le plan se retrouvait repoussé tout en bas de la carte, loin du code
     postal. */
  .carte-contact--trouver{ grid-template-rows: auto auto auto 1fr; }
  .carte-contact--trouver .carte-maps{ min-height: 180px; height: 100%; }
}

/* ---------- Mise en page des modales : média flottant ----------
   Le flottement fait que le texte passe à côté du média PUIS reprend
   en dessous, sans colonne vide, ce que ne permet pas une grille. */
.modale__flux::after{ content: ""; display: block; clear: both; }

.modale__media{
  width: min(42%, 400px);
  margin-bottom: var(--e-5);
}
/* Fiches de la maison, des chambres et des prestations : exactement la moitié
   de la boîte pour l'image, l'autre moitié pour le texte. La gouttière est
   prise sur la colonne de texte, pas sur l'image. */
.modale__media--moitie{ width: 50%; }
.modale__media--gauche{ float: left; margin-right: clamp(1.25rem, 2.5vw, 2rem); }
.modale__media--droite{ float: right; margin-left: clamp(1.25rem, 2.5vw, 2rem); }

/* Le média reste visible pendant qu'on parcourt une longue liste */
.modale__media--droite{ position: sticky; top: 0; }

.modale__flux > .modale__entete:first-child,
.modale__flux > *:first-child{ margin-top: 0; }

@media (max-width: 820px){
  .modale__media{
    float: none !important;
    position: static;
    width: 100%;
    margin: 0 0 var(--e-5) 0;
  }
}

.modale__aide{
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  color: var(--texte-doux);
  margin-bottom: var(--e-3);
}

/* ---------- Cartes entièrement cliquables ----------
   Le lien du pied porte un ::after qui couvre toute la carte : un seul
   élément interactif, HTML valide, un seul arrêt de tabulation. */
.carte-chambre--cliquable,
.carte-presta--cliquable,
.carte-activite--cliquable{ position: relative; }

.lien-fleche--etendu::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--r-carte);
}
.carte-chambre--cliquable:hover,
.carte-presta--cliquable:hover,
.carte-activite--cliquable:hover{ cursor: pointer; }

/* Le focus clavier encadre la carte entière, pas seulement le lien */
.lien-fleche--etendu:focus-visible{ outline: none; }
.lien-fleche--etendu:focus-visible::after{
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Les puces et le tarif ne doivent pas intercepter le clic */
.carte-chambre__puces,
.carte-chambre__tarif,
.carte-presta__accroche,
.carte-activite__accroche{ position: relative; z-index: 0; }

/* ---------- Prestations : la carte sans image ---------- */
.carte-presta__sans-image{
  display: grid;
  place-items: center;
  aspect-ratio: 3/2;
  background-color: var(--c-ivoire);
  background-image:
    radial-gradient(60% 50% at 30% 30%, rgba(248,216,216,.5) 0%, transparent 70%),
    radial-gradient(50% 45% at 75% 70%, rgba(248,232,200,.55) 0%, transparent 72%);
  border-bottom: 1px solid var(--bordure-douce);
}
.carte-presta__symbole{ color: var(--c-terre); opacity: .8; }
.carte-presta__symbole svg{ width: 46px; height: auto; }

.carte-activite__pied,
.carte-presta__pied{ margin-top: auto; padding-top: var(--e-4); }

/* Les quatre prestations regroupées dans la modale « autres » */
.sous-prestas{ display: grid; gap: var(--e-5); }
.sous-presta{
  padding: var(--e-5);
  background: var(--c-ivoire);
  border-radius: var(--r-champ);
  border-left: 3px solid var(--accent-decor);
}
.sous-presta__titre{
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3);
  margin-bottom: var(--e-2);
  font-size: 1.0625rem;
}
.sous-presta__accroche{ color: var(--texte-doux); font-size: var(--fs-petit); }
.sous-presta p + p{ margin-top: var(--e-2); }
.sous-presta .deroule{ margin-top: var(--e-3); }

/* ---------- Activités : une liste d'adresses, rien d'autre ----------
   Il y avait ici un maître-détail : les adresses à gauche, un carrousel à
   droite qui changeait au clic et une liste à défilement interne plafonnée à
   62vh. Les 117 lieux n'ayant pas de photo, le carrousel n'affichait que des
   emplacements vides : tout est parti le 19/10/2026, carrousel, galeries par
   lieu et barre de défilement comprise. La fiche prend la pleine largeur de la
   boîte et c'est le corps de la modale qui défile, comme partout ailleurs. */

/* ---------- Texture de papier sur les sections blanches ---------- */
.section--blanc{
  position: relative;
  isolation: isolate;
  background-color: var(--c-blanc);
}
.section--blanc::before{
  content: "";
  position: absolute; inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .5;
  mix-blend-mode: multiply;
  /* Fibres de papier : deux bruits fractals superposés, l'un fin l'autre plus
     large, pour éviter le motif régulier qui trahit une texture générée. */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23p)' opacity='.42'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='560' height='560'%3E%3Cfilter id='q'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.035' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='560' height='560' filter='url(%23q)' opacity='.2'/%3E%3C/svg%3E");
  background-size: 220px 220px, 560px 560px;
}

/* Sans JavaScript, le média flottant des fiches chambres et prestations repasse
   en pleine largeur. Les fiches d'activités n'en ont plus du tout. */
.sans-js .modale__media{ float: none !important; position: static; width: 100%; }
.sans-js .lien-fleche--etendu::after{ display: none; }


/* ========== 22. MOBILE : RÉGLAGES PROPRES AU TÉLÉPHONE ==========
   Tout ce qui suit ne s'applique qu'en dessous de 768 px, à la demande du
   client : l'ordinateur garde le badge Airbnb du hero, ses tailles de texte,
   sa bande statique en quatre colonnes, les vignettes des carrousels et la
   ligne de réassurance des fiches.
   ============================================================ */

/* ---------- En-tête ---------- */
@media (max-width: 767px){
  /* Le bouton « Réserver » disparaît de la barre : le menu suffit et la
     barre respire. Il reste dans le hero, juste en dessous. */
  .entete__actions .btn{ display: none; }
  /* Le burger se rapproche du bord : il reprend la moitié de la gouttière du
     conteneur. Sa zone tactile de 44 px, elle, ne bouge pas. */
  .entete__actions{ margin-right: calc(-1 * var(--gouttiere) / 2); }
}

/* Panneau de menu ouvert : l'en-tête repasse en blanc. Au-dessus du hero il
   est transparent, avec logo et croix blancs, sur le fond clair du panneau,
   ils devenaient invisibles. Vaut partout où le menu existe (≤ 1023 px). */
@media (max-width: 1023px){
  /* `[data-etat]` est là pour la spécificité, pas pour filtrer : les règles de
     l'état « transparent » valent (0,2,0), une simple classe ne les aurait pas
     emportées et l'en-tête serait resté transparent, logo blanc compris. */
  .entete[data-etat].entete--menu-ouvert{
    background: var(--c-blanc);
    box-shadow: var(--ombre-header);
  }
  .entete[data-etat].entete--menu-ouvert .burger{ color: var(--texte); }
  .entete[data-etat].entete--menu-ouvert .logo__image--clair{ display: none; }
  .entete[data-etat].entete--menu-ouvert .logo__image--sombre{ display: block; }
}

@media (max-width: 767px){
  /* ---------- Hero ---------- */
  /* La source de la note, « Airbnb · Superhôte depuis 8 ans », sort : sur un
     écran étroit elle passait à la ligne et poussait le titre vers le bas.
     La note elle-même (4,93/5 · 86 avis) reste. */
  .hero .avis-badge__source{ display: none; }

  /* Une seule taille pour toutes les introductions : le sous-titre du hero et
     les chapôs de section. Elles annonçaient le texte en plus gros que lui. */
  .hero__sous-titre,
  .chapo,
  .chapo--compact{ font-size: var(--fs-mobile-chapo); }

  /* Les deux appels du hero tiennent sur une ligne. Mis bout à bout dans leurs
     tailles d'ordinateur ils faisaient 386 px pour 343 utiles : ce sont les
     marges intérieures et l'interlettrage qui cèdent, pas le texte. */
  .hero__ctas{
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: center;
    align-items: center;
    gap: var(--e-3);
  }
  .hero__ctas .btn{
    flex: 0 1 auto;
    min-width: 0;
    padding-inline: var(--e-4);
    font-size: var(--fs-micro);
    letter-spacing: .06em;
    white-space: nowrap;
  }

  /* ---------- Corps de texte des sections Maison et Chambres ----------
     Même taille que le sous-titre du hero : sur un téléphone, le pas entre les
     deux ne se voyait pas et les paragraphes prenaient trop de hauteur. */
  /* `:not(.chapo)` : le chapô de section a sa propre taille, plus petite, et
     ces sélecteurs-ci portent un identifiant, donc un poids que la règle de
     classe ne pourrait pas reprendre. On exclut plutôt que d'empiler. */
  #maison p:not(.chapo), #maison li,
  #chambres p:not(.chapo), #chambres li{ font-size: var(--fs-mobile-texte); }
  #maison .etiquette, #chambres .etiquette,
  #maison .puce, #chambres .puce,
  #maison .carte-chambre__meta{ font-size: var(--fs-micro); }

  /* ---------- Fiches : ni vignettes, ni pastilles, ni réassurance ----------
     Il reste les flèches : elles suffisent à dire qu'il y a d'autres photos.
     La bande de vignettes prenait un tiers de la hauteur utile. */
  .carrousel--fiche .vignettes,
  .carrousel--fiche .carrousel__barre{ display: none; }
  .modale__cta-note{ display: none; }
  /* La puce qui sépare les métadonnées de la note : sur une ligne qui passe à
     la ligne, elle restait suspendue en fin de ligne. */
  .modale__meta > span[aria-hidden="true"]:not(.avis-badge__etoiles){ display: none; }

  /* ---------- Le titre d'une fiche de chambre tient sur une ligne ----------
     « Chambre 2 — La Mercantine » passait à la ligne et la fiche s'ouvrait sur
     deux lignes de titre avant la première photo. La taille s'adapte à la
     largeur de l'écran plutôt que de couper le nom. */
  .modale__titre{
    font-size: clamp(1.25rem, 6.2vw, 1.75rem);
    white-space: nowrap;
  }

  /* ---------- La carte de situation ----------
     Le pavé de consentement tenait la hauteur d'une carte d'ordinateur pour
     trois lignes de texte et un bouton. */
  /* C'est `min-height` qui tient la hauteur, le pavé de consentement n'étant
     qu'une couche posée dessus : 340 px pour trois lignes et un bouton, c'est
     un tiers d'écran de téléphone pour pas grand-chose. */
  /* La carte de situation de la section « La maison » est retiree sur
     telephone, demande de Nathan du 21/10/2026 : la meme adresse et le meme
     plan figurent deja dans la section Contact, juste en dessous. Sur
     ordinateur elle reste, elle y equilibre la colonne des equipements. */
  .carte-maps--colonne{ display: none; }
  .consentement{ padding: var(--e-4) var(--e-3); gap: var(--e-2); }
  .consentement__icone svg{ width: 22px; height: 22px; }
  .consentement__note{ font-size: var(--fs-micro); }

  /* ---------- Les équipements : le bouton, et rien d'autre ----------
     L'aperçu de douze lignes doublait la hauteur du bloc pour dire ce que le
     bouton dit déjà. Demande du 20 octobre 2026. */
  .equipements-maison__titre,
  .equipements-maison .equipements--pictos{ display: none; }
  .equipements-maison{ padding: var(--e-4); }

  /* ---------- Le repli de l'histoire ----------
     Les deux derniers paragraphes et l'encadré ne s'ouvrent qu'à la demande.
     Sur ordinateur le dépliant reste ouvert et sa commande disparaît (§ plus
     bas, au-dessus de 768 px). */
  .repli__bouton{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--e-2);
    width: 100%;
    min-height: 44px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font-family: var(--f-ui);
    font-size: var(--fs-petit);
    font-weight: 500;
    letter-spacing: .06em;
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
  }
  .repli__bouton::-webkit-details-marker{ display: none; }
  .repli__bouton svg{
    width: 20px; height: 20px;
    transition: transform var(--t-base);
  }
  .repli[open] .repli__bouton svg{ transform: rotate(180deg); }
  .repli[open] .repli__bouton .repli__dire--plus,
  .repli:not([open]) .repli__bouton .repli__dire--moins{ display: none; }

  /* Déplié, la commande passe SOUS le texte qu'elle vient de montrer : on
     replie là où la lecture s'arrête, pas là où elle a commencé. `order`
     suffit, l'ordre du document ne bouge pas et `<summary>` reste la commande
     que le navigateur actionne.

     Le `gap` remplace les marges : la rangée d'origine
     (`.histoire__texte > * + *`) ne vaut que pour les enfants directs du bloc
     et sautait ceux du dépliant, si bien que les paragraphes dévoilés se
     touchaient. Avec le même écart partout, dérouler revient exactement à
     sauter une ligne de plus. */
  details.repli[open]{
    display: flex;
    flex-direction: column;
    gap: var(--e-4);
  }
  details.repli[open] > summary{ order: 2; }
  /* L'écart entre les deux paragraphes dévoilés se pose sur eux et non par le
     `gap` du dépliant : les navigateurs récents enveloppent le contenu d'un
     `<details>` dans une boîte anonyme, si bien que le `gap` sépare cette
     boîte de la commande sans rien faire à l'intérieur. Mesuré : 16 px entre
     la boîte et la commande, 0 entre les deux paragraphes. */
  details.repli > p + p{ margin-top: var(--e-4); }

  /* ---------- Les cartes de chambre font toutes la même hauteur ----------
     Les cases du rail étaient déjà égales : c'est la carte qui ne remplissait
     pas la sienne, parce que son résumé fait trois lignes pour les unes et
     cinq pour les autres. Deux gestes, pas un : la carte prend toute sa case
     et le résumé reçoit une hauteur de trois lignes. Le corps passe au micro
     pour que le plus long des cinq textes y tienne en entier : rien n'est
     coupé, le `line-clamp` n'est là que comme garde-fou. */
  .chambres__piste > *{ display: flex; }
  .chambres__piste > * > .carte-chambre{ flex: 1 1 auto; }
  .chambres__piste .carte-chambre__resume{
    font-size: var(--fs-micro);
    min-height: calc(3 * 1.55em);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* ---------- « Réserver cette chambre » : un bouton, pas un lien ----------
     Arrondi, sans flèche, sur une seule ligne, et de la couleur d'action du
     site : exactement celle du bouton « Demander cette chambre » que la fiche
     ouvre derrière. Un violet y a figuré quelques heures le 20 octobre 2026,
     écarté le jour même : deux roses voisins dans la même suite de gestes se
     lisaient comme une erreur, pas comme une distinction. */
  .carte-chambre__pied{ margin-top: auto; }
  .carte-chambre__pied .lien-fleche{
    display: flex;
    justify-content: center;
    width: 100%;
    min-height: 44px;
    padding: .6rem var(--e-4);
    border-radius: 999px;
    background: var(--action-fond);
    color: var(--action-texte);
    font-size: var(--fs-micro);
    letter-spacing: .06em;
    white-space: nowrap;
  }
  .carte-chambre__pied .lien-fleche > span{
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .carte-chambre__pied .lien-fleche svg{ display: none; }
  .carte-chambre__pied .lien-fleche:hover,
  .carte-chambre__pied .lien-fleche:active{
    background: var(--action-fond-survol);
    color: var(--action-texte);
  }
}

/* ---------- Les rails : sur téléphone, les cartes tournent ----------
   Un même dispositif pour les Espaces, les Chambres, les Prestations et les
   Activités. Empilées, ces quatre sections faisaient des milliers de pixels
   de haut sur un téléphone, la seule des Chambres en faisait 4 400, cinq
   écrans à traverser. En rang, les cartes se suivent, se calent au milieu de
   l'écran et tournent sans fin.

   Le balisage n'a besoin que de trois attributs : `data-rail` sur le cadre,
   `data-rail-piste` sur la rangée, `data-rail-copie` sur les copies qui font
   la boucle. Le comportement suit (carousel.js, `TN.rail`).

   Le défilement est celui du navigateur : on glisse au doigt, avec son
   inertie et son calage. Les flèches ne font que lui demander d'avancer d'une
   carte. Sans JavaScript elles s'effacent (§20), les copies aussi et la
   rangée reste glissable.

   Ce bloc est volontairement écrit APRÈS toutes les grilles de section : à
   poids égal, c'est la dernière règle qui gagne et c'est elle qu'on veut. */
@media (max-width: 767px){
  /* `min-width: 0` : le cadre des chambres est une case de grille et une case
     refuse par défaut de devenir plus étroite que son contenu. Sans cette
     ligne, les quinze cartes de la piste poussent la colonne à plus de
     4 000 px et c'est la page entière qui déborde à l'horizontale au lieu de
     la piste qui défile. Les trois autres rails sont de simples blocs et ne
     connaissent pas ce piège, la règle est posée pour tous, elle ne coûte
     rien là où elle ne sert pas. */
  [data-rail]{ position: relative; min-width: 0; }
  [data-rail-piste]{
    /* La carte se mesure sur l'écran et non sur la zone intérieure de la
       piste : celle-ci dépend du retrait ci-dessous, qui dépend lui-même de
       la carte, en pourcentage, le calcul tournerait en rond. */
    --carte: 72vw;
    display: flex;
    flex-wrap: nowrap;
    /* Les activités sont centrées en grand écran, pour rattraper la seconde
       ligne. Centrer un contenu qui déborde rend son début inatteignable au
       défilement : ici, la piste repart de la gauche. */
    justify-content: flex-start;
    gap: var(--gouttiere);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* La piste traverse l'écran d'un bord à l'autre, d'où la marge négative,
       qui annule la gouttière du contenant. Le retrait latéral, lui, vaut
       exactement ce qui reste de l'écran une fois la carte posée : sans lui,
       la première et la dernière ne pourraient pas se centrer, faute de place
       pour défiler au-delà. */
    padding-inline: calc((100vw - var(--carte)) / 2);
    margin-inline: calc(-1 * var(--gouttiere));
  }
  [data-rail-piste]::-webkit-scrollbar{ display: none; }
  /* Chaque carte s'arrête au milieu de l'écran, ses deux voisines dépassant
     d'autant de part et d'autre. Pas de `scroll-padding` : le retrait étant le
     même à gauche et à droite, le centre de la zone de calage est déjà celui
     de l'écran.
     `min-width` est remis à zéro : les cartes d'activité en portent un de
     240 px qui, sur un écran étroit, les rendrait plus larges que ce que le
     retrait a prévu et le calage tomberait à côté du centre. */
  [data-rail-piste] > *{
    flex: 0 0 var(--carte);
    min-width: 0;
    scroll-snap-align: center;
  }
  /* Pas d'apparition carte par carte dans un rail (§19) : l'observateur prend
     l'écran pour référence et les cartes posées hors de l'écran, à droite, ne
     seraient « vues » qu'au moment où on les amène, arrivées blanches,
     remplies une demi-seconde plus tard, sous les yeux du visiteur. Empilées,
     elles entraient par le bas, une par une : le cas ne se posait pas. */
  [data-rail-piste] .apparait{ opacity: 1; transform: none; transition: none; }
}

/* ---------- Les pastilles des rails ----------
   Deux rails se mènent au doigt : « Prestations » et « Activités ». Les
   flèches y cèdent la place à une rangée de points qui dit où l'on en est.
   Hors du téléphone, le rail redevient une grille et la rangée n'a plus de
   sens : elle disparaît (voir plus bas, au-dessus de 768 px). */
.rail__pastilles{
  display: flex;
  justify-content: center;
  gap: var(--e-2);
  margin-top: var(--e-4);
}
.rail__pastille{
  width: 8px; height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--c-terre);
  opacity: .35;
  cursor: pointer;
  transition: opacity var(--t-base), transform var(--t-base), background var(--t-base);
}
/* La cible du doigt fait 44 px alors que le point en fait 8 : c'est un
   pseudo-élément qui l'agrandit, sans écarter les points les uns des autres. */
.rail__pastille::before{
  content: "";
  position: absolute;
  width: 44px; height: 44px;
  transform: translate(-18px, -18px);
}
.rail__pastille{ position: relative; }
.rail__pastille.est-active{
  opacity: 1;
  background: var(--accent);
  transform: scale(1.35);
}
.rail__pastille:focus-visible{ outline: 2px solid var(--accent); outline-offset: 3px; }

@media (max-width: 767px){
  /* Là où il y a des pastilles, plus de flèches. */
  [data-rail]:has([data-rail-pastilles]) .rail__nav{ display: none; }
}

/* Sur ordinateur, l'histoire se lit d'un trait : le dépliant reste ouvert et
   sa commande n'a pas lieu d'être. L'attribut `open` est posé dans le HTML,
   c'est un script d'une ligne qui le retire sur téléphone (nav.js). */
@media (min-width: 768px){
  .repli__bouton{ display: none; }
  .rail__pastilles{ display: none; }
}

@media (min-width: 768px){
  /* Hors du rail, ni copies ni flèches. La classe des flèches est doublée
     pour passer devant `.carrousel__nav`, dont elles héritent le rond blanc :
     à poids égal c'est la plus spécifique qui gagne. Ne pas « simplifier ». */
  [data-rail-copie]{ display: none; }
  .carrousel__nav.rail__nav{ display: none; }

  /* Les chambres et elles seules : le cadre et la piste s'effacent et les
     cinq cellules redeviennent des cases de la grille, à la suite de « La
     maison entière ». La mise en page en grand écran ne bouge donc pas d'un
     pixel, c'est tout l'intérêt de `display: contents` ici. */
  .chambres__rail, .chambres__piste{ display: contents; }
}

/* ---------- La bande de chiffres défile ----------
   Une seule piste, les quatre points écrits deux fois, translatée de la moitié
   de sa largeur : au moment où la copie arrive à la place de l'original,
   l'animation reboucle et le raccord est invisible.
   La marge est portée par les items et non par un `gap` : avec un `gap`, la
   moitié de la piste ne tombe pas sur un multiple entier d'items et le
   raccord saute d'un demi-espace à chaque tour. */
@media (max-width: 767px){
  .points{ overflow: hidden; }
  .points > .contenant{ max-width: none; padding-inline: 0; }
  .points__liste{
    display: flex;
    width: max-content;
    gap: 0;
    overflow: visible;
    scroll-snap-type: none;
    padding-inline: 0;
    margin-inline: 0;
    animation: defile-points 30s linear infinite;
  }
  .points__item,
  .points__item--copie{
    display: flex;
    flex: 0 0 auto;
    width: min(58vw, 215px);
    margin-right: var(--e-4);
    scroll-snap-align: none;
  }
  /* La bande ne s'arrête jamais, survol compris : c'est demandé. Le moyen de
     l'arrêter reste la préférence système « animations réduites », prise en
     compte juste en dessous, c'est elle qui répond au critère WCAG 2.2.2. */
}
@keyframes defile-points{
  from{ transform: translateX(0); }
  to{ transform: translateX(-50%); }
}
/* Animations réduites : la bande ne défile plus, elle redevient une rangée
   qu'on fait glisser au doigt. */
@media (max-width: 767px) and (prefers-reduced-motion: reduce){
  .points__liste{ animation: none; overflow-x: auto; scroll-snap-type: x mandatory; }
  .points__item{ scroll-snap-align: center; }
  .points__item--copie{ display: none; }
}

/* ---------- Panneau de reservation : bouton « Conditions du sejour » ----------
   Defaut constate par Nathan le 21/10/2026 sur telephone : le bouton faisait
   26 px de haut alors que son contenu en demande 53, et le texte sortait du
   cadre.

   Cause, mesuree au navigateur. Le corps du panneau est une colonne flexible
   a hauteur fixe. Le panneau applique « min-height: 0 » a tous ses boutons,
   pour se proteger des styles du site qui l'accueille. Effet de bord : cette
   ligne supprime la taille minimale automatique des elements flexibles, donc
   des que le contenu de l'etape depasse la hauteur de l'ecran, c'est ce
   bouton qui absorbe la difference et s'ecrase.

   On lui rend donc le droit de ne pas retrecir, et un minimum tactile. On ne
   touche qu'a ce bouton : les autres ne sont pas affectes, verifie un par un.
   Ce correctif est purement visuel. Il ne modifie ni le script du panneau, ni
   les donnees echangees, ni les appels a l'application de gestion.

   Le vrai correctif serait dans la feuille du panneau, cote application :
   remplacer « min-height: 0 » par « min-height: auto » sur les boutons qui
   sont des elements flexibles directs. Tant que ce n'est pas fait, cette
   regle tient. */
html body .obt-bk-panel .obt-bk-terms{
  flex: 0 0 auto;
  min-height: 44px;
}
