@charset "UTF-8";

/* ==========================================================================
   Casa Paradisu - Mises en page specifiques aux pages
   ========================================================================== */

/* ==========================================================================
   1. Hero
   ========================================================================== */

.hero {
  position: relative;
  min-height: var(--hero-h);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  /* Fond d'attente en tons de marque plutot qu'un aplat noir : tant que la
     photographie n'est pas peinte, le bloc ne se lit pas comme une erreur. */
  background-color: var(--c-charcoal);
  background-image: linear-gradient(160deg, #2C302A 0%, #20231F 55%, #171A16 100%);
  isolation: isolate;
}

/* Gabarit editorial commun aux pages « La villa » et « Autour » :
   meme hauteur, meme voile, meme position de texte, meme largeur de mesure. */
.hero--page {
  min-height: var(--hero-h-page);
  align-items: flex-end;
}
.hero--page .hero__inner { padding-bottom: var(--sp-7); }
/* Un H1 pose sur une photographie de demi-hauteur porte moins que celui de
   l accueil : il descend d un cran, sans changer de famille ni de graisse. */
.hero--page h1 { font-size: var(--fs-display-photo); }

/* Le hero de page est deux fois plus court : le texte y occupe une bande ou le
   voile commun s'affaiblirait. Meme logique directionnelle, meme couleur, mais
   la montee est plus rapide et la composante horizontale un peu plus marquee,
   le bloc de texte etant proportionnellement plus large. */
.hero--page .hero__scrim {
  background:
    linear-gradient(to top,
      rgba(7, 12, 13, 0.68) 0%,
      rgba(7, 12, 13, 0.30) 38%,
      rgba(7, 12, 13, 0) 70%),
    linear-gradient(to right,
      rgba(7, 12, 13, 0.30) 0%,
      rgba(7, 12, 13, 0.11) 46%,
      rgba(7, 12, 13, 0) 72%);
}

/* --- Calques du hero -------------------------------------------------------
   `.hero` porte `isolation: isolate` : tout ce qui suit vit dans SON contexte
   d'empilement, et rien n'en sort. L'en-tete, lui, est `position: fixed` avec
   `z-index: 60` au niveau de la racine : il passe donc necessairement au-dessus
   de l'ensemble, sans qu'aucune valeur n'ait a etre surenchere.

     0  la photographie
     1  le voile de contraste du contenu, directionnel
     2  le voile superieur, qui passe DERRIERE l'en-tete
     3  le contenu editorial

   Les deux voiles sont `pointer-events: none` : ils ne captent ni clic ni
   geste tactile. Aucune `opacity` ni aucun `filter` n'est pose sur un parent
   commun a la photographie et a l'en-tete, ce qui teindrait tous les enfants.
   -------------------------------------------------------------------------- */
.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.hero__media img,
.hero__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 52%);
}

/* Voile de contraste du contenu. Il est DIRECTIONNEL : le texte occupe le bas
   a gauche, l'assombrissement y est donc reel et s'efface completement sur la
   droite et en haut. La photographie garde sa luminosite, ses couleurs et le
   detail de son architecture partout ailleurs. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to top,
      rgba(7, 12, 13, 0.68) 0%,
      rgba(7, 12, 13, 0.32) 42%,
      rgba(7, 12, 13, 0) 72%),
    linear-gradient(to right,
      rgba(7, 12, 13, 0.40) 0%,
      rgba(7, 12, 13, 0.18) 48%,
      rgba(7, 12, 13, 0) 76%);
}

/* Voile superieur. Il ne sert qu'a poser un fond au logo et a la navigation ;
   il s'eteint donc vite et ne descend pas dans l'image. Il vit dans le hero,
   jamais dans l'en-tete : c'est ce qui garantit qu'il ne peut plus ternir le
   logo ni le bouton. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  /* 104px : la barre fait 72px, le voile ne la depasse que de 32px. Il
     s eteint donc juste sous elle au lieu de descendre dans la photographie. */
  height: calc(var(--header-h) + 2rem);
  z-index: 2;
  pointer-events: none;
  /* Le premier palier tient la ligne de la navigation ; la chute est ensuite
     franche, pour qu on ne percoive aucune bande sous l en-tete. Sous la barre
     l opacite est deja retombee de 0,35 a 0,24 par rapport au reglage
     precedent, et le voile se termine 24px plus haut. */
  background: linear-gradient(to bottom,
    rgba(8, 14, 16, 0.64) 0%,
    rgba(8, 14, 16, 0.46) 40%,
    rgba(8, 14, 16, 0) 100%);
}

/* Le hero de page est deux fois plus court : la bande de l en-tete y tombe
   au-dessus du voile de contenu, qui s eteint plus bas. Le voile superieur y
   travaille donc seul et doit etre un cran plus dense que sur l accueil.
   Declare APRES `.hero::before` : a specificite egale, c est l ordre qui
   tranche. */
.hero--page::before {
  background: linear-gradient(to bottom,
    rgba(8, 14, 16, 0.74) 0%,
    rgba(8, 14, 16, 0.52) 42%,
    rgba(8, 14, 16, 0) 100%);
}

.hero__inner {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 0 var(--gutter) var(--sp-8);
  color: var(--c-ivory);
}

/* Calee sur Libre Baskerville a son corps maximal : le H1 tient sur deux
   lignes sans jamais former de ligne veuve d'un seul mot. */
.hero__content { max-width: 52rem; }
.hero__eyebrow {
  color: rgba(244, 240, 231, 0.9);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.3);
}
.hero h1 {
  margin-top: var(--gap-label);
  color: var(--c-ivory);
}

/* Ombre reservee aux titres poses sur une photographie, jamais aux H1 des
   pages a fond clair : la classe est portee par les trois heros du site.
   Le travail de lisibilite est fait par le voile directionnel ; cette ombre
   n'a plus qu'a detacher les lettres des details fins de l'image, la ou elles
   croisent le mobilier sombre, une structure metallique ou un reflet. Deux
   couches tres basses, aucune de contour : la graisse de Libre Baskerville
   n'est pas epaissie et le titre ne parait pas flotter. */
.hero__title {
  text-shadow:
    0 2px 4px rgba(0, 0, 0, 0.24),
    0 8px 24px rgba(0, 0, 0, 0.18);
}

.hero__intro {
  margin-top: var(--gap-title);
  max-width: var(--measure-lead);
  color: rgba(244, 240, 231, 0.92);
  font-size: var(--fs-lead);
  /* Sur photographie, le texte remonte a 400 : la 300 se delave des que le
     fond s eclaircit. */
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
}
.hero__actions {
  margin-top: var(--gap-action);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

/* Commande de lecture video, discrete, en bas a droite */
.hero__videobtn {
  position: absolute;
  right: var(--gutter);
  bottom: var(--sp-8);
  width: 44px; height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(244, 240, 231, 0.4);
  border-radius: var(--radius);
  color: var(--c-ivory);
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.hero__videobtn:hover { background-color: rgba(244, 240, 231, 0.14); border-color: var(--c-ivory); }
.hero__videobtn[hidden] { display: none; }
/* L'icone dit toujours ce que le bouton va faire : deux barres quand la
   lecture est en cours, un triangle quand elle est arretee. */
.hero__videobtn[data-state="playing"] .hero__videobtn-play,
.hero__videobtn[data-state="paused"] .hero__videobtn-pause { display: none; }

/* ==========================================================================
   1 bis. Hero sequentiel de l'accueil
   Une video puis quatre vues aeriennes, enchainees par le defilement.

   Le principe tient en trois pieces :
     .hero--sequence  un conteneur haut de N ecrans, qui n'existe que pour
                      donner au defilement la course necessaire
     .hero__scene     une scene collante d'exactement un ecran, qui reste
                      fixee pendant toute la traversee
     .hero__panel     N panneaux empiles, glisses en Y selon la progression

   Le mouvement est un glissement pur : le panneau sortant va de 0 a -100 %
   de la hauteur d'ecran pendant que l'entrant va de +100 % a 0. Les deux
   restent OPAQUES ; la separation vient de leur position, jamais d'un fondu
   ni d'un fond intermediaire.

   Les decalages sont poses en PIXELS ENTIERS, pas en pourcentages : deux
   pourcentages arrondis independamment laissaient une ligne d'un pixel entre
   les panneaux, ou l'on apercevait le fond sombre de la section.
   ========================================================================== */

/* Repli pour les moteurs sans `svh` : `vh` ne suit pas la barre d adresse
   mobile, mais il vaut mieux un ecran legerement trop haut qu une scene qui
   se redimensionne a chaque geste. */
@supports not (height: 100svh) {
  .hero--sequence { --hero-screen: 100vh; }
}

.hero--sequence {
  /* Hauteur du conteneur de progression. Tant que le script n'a rien pose,
     elle vaut un ecran : sans JavaScript, ou sous `prefers-reduced-motion`,
     il n'y a aucun conteneur de plusieurs centaines de vh a traverser.
     Le script la remplace par la course reelle de la chronologie, deduite du
     nombre de medias presents dans le DOM. */
  --hero-track: var(--hero-screen, 100svh);
  min-height: 0;
  height: var(--hero-track);
  display: block;
  /* PAS d'`overflow: hidden` ici : un ancetre qui coupe le debordement
     desactive silencieusement `position: sticky` sur ses descendants. Le
     recadrage est porte par la scene, qui elle peut couper sans dommage. */
  overflow: visible;
}

/* Le voile superieur du hero classique est repris par la scene : pose sur la
   section, il defilait des le premier ecran et laissait ensuite les
   photographies sans protection sous l'en-tete. */
.hero--sequence::before { content: none; }

.hero__scene {
  position: sticky;
  top: 0;
  height: var(--hero-screen, 100svh);
  overflow: hidden;
  isolation: isolate;
  /* Fond de securite. Il ne doit jamais devenir visible pendant une transition
     normale : les deux panneaux couvrent l'ecran a tout instant. */
  background-color: var(--c-charcoal);
}

/* AUCUN degrade sous l'en-tete : la lisibilite de la barre vient de la couleur
   blanche de ses elements et d'une ombre de texte tres basse, pas d'un voile
   pose sur la video. */

/* Les panneaux sont empiles dans l'ordre du document : le suivant recouvre le
   precedent. C'est ce qui permet a l'image entrante de masquer la sortante. */
.hero__panel {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* Le panneau se comporte comme le hero d origine : son contenu editorial
     se cale en bas, sur le meme axe que le reste du site. */
  display: flex;
  align-items: flex-end;
  /* Chaque panneau est son propre contexte d empilement : son filtre noir ne
     peut donc jamais assombrir un autre panneau. */
  isolation: isolate;
  transform: translate3d(0, var(--panel-y, 0px), 0);
}

/* PILE INVERSEE. Le premier panneau est AU-DESSUS, le dernier tout au fond.
   Le media suivant est donc deja en place, plein ecran, derriere l'actuel :
   il ne bouge jamais. C'est le panneau du dessus qui remonte et decouvre
   d'abord le BAS de l'image situee derriere lui, comme on retire une couche.
   Ces valeurs sont decroissantes pour six panneaux au plus ; le script ne les
   touche pas. */
.hero__panel:nth-child(1) { z-index: 6; }
.hero__panel:nth-child(2) { z-index: 5; }
.hero__panel:nth-child(3) { z-index: 4; }
.hero__panel:nth-child(4) { z-index: 3; }
.hero__panel:nth-child(5) { z-index: 2; }
.hero__panel:nth-child(6) { z-index: 1; }

.hero__panel-media {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  /* AUCUNE transformation ici. Le media ne bouge pas, ne zoome pas, ne change
     pas de cadrage : seul le panneau du dessus se deplace. */
}

/* --- Filtre permanent ------------------------------------------------------
   Il vaut ZERO par defaut : une photographie entierement decouverte est
   entierement claire, sans le moindre filtre. Le calque reste en place, pret a
   servir : le jour ou un panneau recevra du texte, il suffira de lui poser un
   `--base-scrim` pour retrouver le contraste necessaire, sans toucher au
   filtre de revelation.

   Le panneau de la video, lui, garde son voile directionnel : dense a gauche
   sous le titre, presque nul a droite. C'est lui qui assure la lisibilite. */
.hero__panel-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background-color: #000;
  opacity: var(--base-scrim, 0);
  pointer-events: none;
}

/* --- Filtre de revelation --------------------------------------------------
   Il appartient au panneau situe DERRIERE, jamais a celui qui remonte. Il vaut
   1 tant que le media est cache, et s'efface a mesure que le panneau du dessus
   le decouvre : le media apparait donc tres sombre par le bas, puis retrouve
   sa lumiere. C'est lui, et lui seul, qui assombrit ; ni l'image, ni la video,
   ni le panneau ne descendent jamais sous l'opacite 1.

   `--reveal` est pose par le script. Aucune transition CSS ici : elle se
   battrait avec les mises a jour pilotees par le defilement. */
.hero__panel-reveal {
  position: absolute;
  inset: 0;
  z-index: 3;
  background-color: #000;
  opacity: var(--reveal, 0);
  pointer-events: none;
}

/* Ordre des calques a l'interieur d'un panneau :
   media (1) -> filtre permanent (2) -> filtre de revelation (3) ->
   contenu (5). */

/* `will-change` n'est pose que sur les panneaux reellement en mouvement. */
.hero__panel.is-active { will-change: transform; }
.hero__panel.is-active .hero__panel-reveal { will-change: opacity; }

/* L'image de repli et la video occupent EXACTEMENT la meme boite, superposees.
   Sans `position: absolute`, la video, second enfant en flux, etait poussee un
   ecran plus bas : des que l'image passait a l'opacite 0, il ne restait que le
   fond sombre de la section, soit un ecran noir. La video est apres l'image
   dans le document, elle se peint donc au-dessus sans z-index. */
.hero__panel-media > img,
.hero__panel-media > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
  display: block;
}

/* L'image ne s'efface que lorsque le script a la preuve qu'une image de la
   video est reellement affichee. En cas d'echec, elle reste en place. */
.hero__panel-media > img {
  transition: opacity var(--dur-slow) var(--ease);
}

/* --- Repere de progression -------------------------------------------------
   Un trait par media, compact, le long du bord droit. Trois etats : a venir,
   deja parcouru, en cours. Aucun fond, aucune pastille, aucun chiffre. */
.hero__progress {
  position: absolute;
  right: 60px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 12;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  pointer-events: none;
  opacity: var(--bar-o, 1);
}
.hero__progress span {
  display: block;
  width: 1px;
  height: 24px;
  background-color: rgba(255, 255, 255, 0.22);
  overflow: hidden;
  transition: height var(--dur) var(--ease);
}
.hero__progress span::after {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background-color: #fff;
  opacity: 0.55;
  transform: scaleY(var(--seg, 0));
  transform-origin: top;
}
/* En cours : plus long, pleinement lumineux. Hauteur totale voisine de 160px
   pour cinq medias, contre 220 auparavant. */
.hero__progress span.is-active { height: 36px; }
.hero__progress span.is-active::after { opacity: 1; }

/* --- Signature de marque sur la video --------------------------------------
   Deux elements, rien de plus : le nom et une invitation a decouvrir. Le bloc
   appartient au panneau de la video, il remonte donc avec lui sans logique
   d'animation propre. Seul le lien capte le pointeur : le reste laisse passer
   les clics vers la commande de lecture. */
.hero-intro__content {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  padding-inline: var(--gutter);
}

/* Exception assumee a la regle typographique du site : ce seul titre est en
   lineale, tous les autres restent en Libre Baskerville. L'echelle est celle
   d'un titre de couverture : 8.35vw, plancher 64px, plafond strict 160px. */
.hero-intro__title {
  margin: 0;
  padding: 0;
  color: #fff;
  font-family: var(--font-hero);
  font-size: clamp(64px, 8.35vw, 160px);
  font-weight: var(--fw-light);
  line-height: 0.95;
  letter-spacing: -3.5px;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  /* Presque invisible : elle detache le titre des hautes lumieres sans poser
     de halo ni assombrir la video. Aucun voile n'est ajoute pour autant. */
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.28);
}

.hero-intro__discover {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  pointer-events: auto;
  margin-top: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 205px;
  min-width: 205px;
  height: 46px;
  padding: 12px 20px;
  border: 1px solid rgba(255, 255, 255, 0.95);
  border-radius: 9999px;
  background-color: transparent;
  color: #fff;
  font-family: var(--font-hero);
  font-size: 16px;
  font-weight: var(--fw-regular);
  line-height: 16px;
  letter-spacing: 0;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 300ms ease, border-color var(--dur) var(--ease);
}
/* Remplissage VERTICAL, du bas vers le haut. Le pseudo-element porte seul le
   mouvement : la boite du lien ne bouge ni ne change de largeur, donc aucun
   saut, aucun clignotement au retrait du curseur. */
.hero-intro__discover::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-color: #fff;
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.4s cubic-bezier(0.76, 0, 0.24, 1);
}
.hero-intro__discover span { position: relative; }
.hero-intro__discover svg {
  position: relative;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}
.hero-intro__discover:hover::before,
.hero-intro__discover:focus-visible::before {
  transform: scaleY(1);
}
.hero-intro__discover:hover,
.hero-intro__discover:focus-visible {
  color: var(--c-charcoal);
  border-color: #fff;
}
.hero-intro__discover:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}
.hero-intro__discover:hover svg,
.hero-intro__discover:focus-visible svg { transform: translateX(4px); }

/* Sur ecran tactile, aucun etat de survol ne doit rester colle apres un appui. */
@media (hover: none) {
  .hero-intro__discover:hover::before { transform: scaleY(0); }
  .hero-intro__discover:hover { color: #fff; }
  .hero-intro__discover:hover svg { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-intro__discover::before,
  .hero-intro__discover svg { transition-duration: 0.01ms; }
}

/* --- Information chiffree posee sur chaque photographie ---------------------
   Un bloc par panneau, jamais un calque global : il vit au-dessus du voile de
   SA photographie et sous le panneau qui la recouvre. Il est donc invisible
   tant que l'image n'est pas decouverte, puis il remonte avec elle. */
.hero-stat {
  position: absolute;
  inset: 0;
  /* Au-dessus du voile permanent (2) et du filtre de revelation (3) de son
     propre panneau, exactement comme la signature posee sur la video. */
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  padding-inline: var(--gutter);
}
/* Repli pour les moteurs qui ne connaissent pas encore `inert`. */
.hero-stat[inert] { pointer-events: none; }

/* --- Luminosite de repos des quatre photographies --------------------------
   Le voile permanent deja present dans chaque panneau reprend du service : il
   n'est plus a zero sur les photographies, mais a 0.18. C'est la luminosite
   FINALE des images, celle qui detache le texte et le bouton des zones tres
   claires. Il est pose sur l'image et sous le contenu, il monte avec son
   panneau, il est uniforme et sans bord.

   Le panneau vise est celui qui porte une information chiffree, pas le premier
   ni le dernier d'une liste : la video, qui n'en porte pas, reste a zero. Le
   filtre de revelation, lui, n'est pas touche : il continue d'aller de 1 a 0
   exactement comme avant, et c'est ce voile qui devient son point d'arrivee. */
.hero__panel:has(.hero-stat) { --base-scrim: 0.18; }

/* Le chiffre et le libelle forment UNE seule ligne : deux echelles, un bloc
   cale a gauche a l'interieur du groupe, le groupe restant centre dans la
   fenetre. C'est ce qui garde le chiffre a gauche quand le libelle passe sur
   deux lignes. */
/* L'echelle de reference est portee par la LIGNE, pas par le libelle : le
   libelle la reprend telle quelle et le chiffre en vaut exactement la moitie.
   Le rapport de 0.5 est donc structurel, il ne peut pas deriver d'un point de
   rupture a l'autre. */
.hero-stat__line {
  display: inline-flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(8px, 0.7vw, 14px);
  max-width: calc(100vw - 100px);
  margin: 0;
  color: #fff;
  font-family: var(--font-hero);
  font-size: clamp(50px, 6.25vw, 120px);
  text-transform: uppercase;
  text-align: left;
  /* Deux niveaux : un liseré tres court qui detache la lettre du grain de la
     photographie, et une ombre large et faible qui assoit l'ensemble. Aucun
     contour, aucun halo visible en tant qu'effet. */
  text-shadow:
    0 1px 3px rgba(0, 0, 0, 0.5),
    0 8px 28px rgba(0, 0, 0, 0.32);
}

/* Le chiffre : exactement la moitie du libelle, pose en haut a gauche comme un
   petit indice. Il est d'un cran plus epais que le libelle, sans quoi il
   deviendrait fragile a cette taille sur une photographie. */
.hero-stat__number {
  display: block;
  flex: 0 0 auto;
  font-size: 0.5em;
  font-weight: var(--fw-regular);
  line-height: 0.9;
  letter-spacing: -1px;
  font-variant-numeric: lining-nums tabular-nums;
  /* `align-items: flex-start` aligne les BOITES, pas les lettres : deux corps
     differents ne posent pas leur capitale au meme endroit dans leur boite.
     Le retrait vaut 0.0865 fois le corps du chiffre, valeur mesuree sur les
     glyphes a sommet plat, ce qui remet les deux hauts sur la meme ligne a
     toutes les largeurs. Aucun alignement par le bas n'est employe. */
  padding-top: 0.0865em;
}

.hero-stat__label {
  display: block;
  /* Reprend l'echelle de la ligne : c'est elle qui porte la valeur. */
  font-size: 1em;
  font-weight: 300;
  line-height: 0.9;
  letter-spacing: -3.5px;
}

/* --- Revelation interne du contenu -----------------------------------------
   Trois progressions posees par le module du hero, deduites de la SEULE
   progression locale de la transition en cours. Le masque fait l'essentiel du
   travail, le deplacement ne depasse pas 22px, et rien ne se joue tout seul :
   a une position de defilement donnee correspond toujours la meme image, dans
   un sens comme dans l'autre.

   Ces regles ne s'appliquent QUE pendant la revelation. Des que le panneau est
   en place la classe tombe : plus de rognage, plus de transformation, le texte
   redevient parfaitement net et le contour de focus du bouton n'est plus
   coupe. */
.hero__panel.is-revealing .hero-stat__number,
.hero__panel.is-revealing .hero-stat__label,
.hero__panel.is-revealing .hero-stat .hero-intro__discover {
  clip-path: inset(calc((1 - var(--p, 1)) * 100%) 0 0 0);
  transform: translateY(calc((1 - var(--p, 1)) * 22px));
  opacity: var(--p, 1);
}
.hero__panel.is-revealing .hero-stat__number { --p: var(--stat-number-p, 1); }
.hero__panel.is-revealing .hero-stat__label  { --p: var(--stat-label-p, 1); }
.hero__panel.is-revealing .hero-stat .hero-intro__discover { --p: var(--stat-button-p, 1); }

/* Mouvement reduit : le contenu du panneau est pose d'emblee, entier et net.
   Aucun texte n'est jamais retire definitivement. */
@media (prefers-reduced-motion: reduce) {
  .hero__panel.is-revealing .hero-stat__number,
  .hero__panel.is-revealing .hero-stat__label,
  .hero__panel.is-revealing .hero-stat .hero-intro__discover {
    clip-path: none;
    transform: none;
    opacity: 1;
  }
}

/* --- Video au repos --------------------------------------------------------
   AUCUN etalonnage, AUCUN voile, AUCUNE opacite : la video du premier panneau
   garde ses couleurs naturelles. Les voiles animes entre panneaux, eux, sont
   intacts : ils appartiennent a `.hero__panel-reveal`, pilote par le script, et
   ne sont pas concernes par cette suppression. */

/* --- Commande de la video --------------------------------------------------
   Elle ne pilote que le premier panneau : elle s'efface avec lui et cesse
   d'etre atteignable, au clavier comme a la souris. */
.hero--sequence .hero__videobtn {
  z-index: 13;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  background-color: transparent;
  color: #fff;
  /* Presente sans s'imposer : elle ne prend sa pleine intensite qu'au survol
     ou au focus. */
  opacity: 0.32;
  transition:
    opacity 300ms ease,
    border-color 300ms ease;
}
.hero--sequence .hero__videobtn:hover,
.hero--sequence .hero__videobtn:focus-visible {
  opacity: 1;
  border-color: rgba(255, 255, 255, 0.9);
  background-color: transparent;
}
/* La zone tactile reste au-dessus de 44px sans agrandir le dessin. */
.hero--sequence .hero__videobtn::after {
  content: "";
  position: absolute;
  inset: -3px;
}
.hero--sequence .hero__videobtn[aria-hidden="true"] {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* --- En-tete pendant la sequence -------------------------------------------
   La barre s'escamote vers le haut des que l'on entre dans la sequence et
   revient des que l'on remonte. Sans cela, une bande de l'ancienne image
   restait visible derriere elle pendant que la suivante montait, et l'en-tete
   paraissait detache du hero. La classe n'est posee que par le module de
   l'accueil : les autres pages ne connaissent pas cet etat. */
/* Le bandeau est desormais dans le flux : il quitte l'ecran de lui-meme au
   defilement. L'escamotage n'a donc plus lieu d'etre ; la classe reste posee
   par le module, sans effet. */
.site-header.is-hero-hidden { transform: none; }

/* --- Repli sans JavaScript et mouvement reduit -----------------------------
   `--hero-track` vaut un ecran tant que le script n'a rien pose : la section
   fait alors la hauteur du viewport, la scene n'a rien a coller et seul le
   premier panneau est visible. Les suivants sont ecartes pour ne pas se
   superposer au texte. */
.hero--sequence:not(.is-ready) .hero__panel + .hero__panel { display: none; }
.hero--sequence:not(.is-ready) .hero__progress { display: none; }

/* ==========================================================================
   2. Accueil
   ========================================================================== */

/* --------------------------------------------------------------------------
   SYSTEME COMMUN A TOUTE LA SUITE DE L'ACCUEIL
   Une seule grille, une seule echelle d'espacement, une seule famille de
   liens. Rien ici ne concerne le hero : ces regles ne sortent jamais des
   sections `.home-*`, posees APRES la sequence.

   Les couleurs ne sont pas redefinies : la page reprend les roles deja
   etablis dans les jetons du projet (fond ivoire, fond creuse, encre, encre
   attenuee, filets). Aucun ton supplementaire n'est introduit.
   -------------------------------------------------------------------------- */
/* UNE SEULE famille pour toute la page d'accueil, posee a la racine du
   document : titres, textes, listes, liens, boutons et pied de page en
   heritent. Libre Baskerville reste chargee et employee par les autres pages,
   elle n'a simplement plus aucun emploi ici. `font-synthesis: none` interdit
   toute graisse ou italique fabriques par le moteur. */
body[data-page="accueil"] {
  font-family: var(--font-azimut);
  font-synthesis: none;
  --home-cols: 12;
  --home-gap: 24px;
  --home-pad: 50px;
  /* Un seul ecart entre deux grandes sections, jamais une valeur au cas par
     cas. Les rythmes internes viennent de l'echelle `--sp-*` du projet. */
  --home-space: clamp(112px, 10vw, 180px);
}

.home-section {
  padding-inline: var(--home-pad);
  padding-block: var(--home-space);
  background-color: var(--bg-page);
  color: var(--text-strong);
}
/* Premiere section apres la sequence : elle respire un cran de plus, le temps
   que l'oeil sorte de l'immersion, sans laisser de trou. */
.home-section--open { padding-block: clamp(120px, 10vw, 180px); }
/* Un seul fond creuse sur la page, jamais deux consecutifs. */
.home-section--sunken { background-color: var(--bg-sunken); }
/* Seule exception a la gouttiere : le media pleine largeur. Son contenu
   editorial, lui, revient sur les memes lignes que le reste de la page. */
.home-section--wide { padding-inline: 0; }

.home-grid {
  display: grid;
  grid-template-columns: repeat(var(--home-cols), minmax(0, 1fr));
  column-gap: var(--home-gap);
  align-items: start;
}

/* --- Typographie de la suite de l'accueil ----------------------------------
   La meme lineale que l'en-tete et le hero, du premier au dernier bloc. Aucun
   registre serif ne subsiste sur cette page : la hierarchie repose sur les
   corps, les graisses fines et l'interlettrage negatif, jamais sur un
   changement de famille. */
.home-title {
  margin: 0;
  font-family: var(--font-azimut);
  font-weight: var(--fw-light);
  font-size: clamp(64px, 6.54vw, 125px);
  line-height: 0.95;
  letter-spacing: -3.5px;
  text-transform: none;
  color: var(--text-strong);
  text-wrap: balance;
  /* A 320px, « contemporaine » depasse a lui seul la colonne. La cesure
     francaise le coupe proprement ; la rupture forcee ne sert que de garde-fou
     si le dictionnaire de cesure manque. Le corps du titre n'est pas reduit. */
  hyphens: auto;
  overflow-wrap: break-word;
}
/* Echelle intermediaire : les cinq titres de section. */
.home-title--m {
  font-size: clamp(36px, 3.475vw, 66px);
  line-height: 0.98;
  letter-spacing: -1.5px;
}
/* Reserve aux veritables petits titres, jamais a un paragraphe ni a un label. */
.home-title--s {
  font-size: 31px;
  line-height: 37px;
  letter-spacing: -0.8px;
}

.home-label {
  margin: 0;
  font-family: var(--font-azimut);
  font-size: 11px;
  font-weight: var(--fw-medium);
  line-height: 14px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.home-text,
.home-lead {
  margin: 0;
  max-width: 58ch;
  font-family: var(--font-azimut);
  font-weight: var(--fw-light);
  letter-spacing: 0;
  color: var(--text-body);
}
.home-text { font-size: 16px; line-height: 1.65; }
.home-lead { font-size: clamp(17px, 1.2vw, 20px); line-height: 1.6; }

/* --- Lien editorial --------------------------------------------------------
   La seconde et derniere famille d'action du site. Aucun fond, aucune pilule,
   aucune boite : un filet fin, une fleche, et un trait qui se developpe de
   gauche a droite au survol. */
.home-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 7px;
  color: var(--text-strong);
  font-family: var(--font-azimut);
  font-size: 13px;
  font-weight: var(--fw-medium);
  line-height: 18px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  text-decoration: none;
}
.home-link::before,
.home-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
}
.home-link::before { background-color: var(--rule); }
.home-link::after {
  background-color: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 380ms cubic-bezier(0.22, 1, 0.36, 1);
}
.home-link:hover::after,
.home-link:focus-visible::after { transform: scaleX(1); }
.home-link svg {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  transition: transform 380ms cubic-bezier(0.22, 1, 0.36, 1);
}
.home-link:hover svg,
.home-link:focus-visible svg { transform: translateX(4px); }
.home-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }

.home-link--light { color: var(--text-on-dark); }
.home-link--light::before { background-color: var(--rule-on-dark); }
.home-link--light:focus-visible { outline-color: var(--c-ivory); }

/* --- Photographies ---------------------------------------------------------
   Angles droits, aucune ombre, aucune carte. Le rapport est declare sur le
   conteneur : la mise en page ne bouge pas pendant le chargement. */
.home-media {
  position: relative;
  display: block;
  margin: 0;
  overflow: hidden;
  background-color: var(--bg-sunken);
}
.home-media > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
  transform: scale(var(--media-scale, 1));
  transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
.home-media--4x3 { aspect-ratio: 4 / 3; }
.home-media--3x2 { aspect-ratio: 3 / 2; }
/* Apparition : le cadre monte avec le texte, l'image se detend de 1.03 a 1.
   Aucun flou, aucune parallaxe, rien ne continue apres la pose. */
.home-media.reveal:not(.is-in) > img { --media-scale: 1.03; }
a.home-media:hover > img,
a.home-media:focus-visible > img { --media-scale: 1.025; transition-duration: 800ms; }
a.home-media:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

/* --- Apparitions -----------------------------------------------------------
   Le meme observateur que le reste du site, deja partage : aucune seconde
   boucle, aucun minuteur. Seules l'amplitude et la duree sont un cran plus
   lentes ici que sur les pages interieures. */
body[data-page="accueil"] .home-section .reveal {
  transform: translate3d(0, 20px, 0);
  transition-duration: 800ms;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}
body[data-page="accueil"] .home-section .reveal.is-in,
body[data-page="accueil"] .home-section .reveal.is-settled { transform: none; }

/* Un seul decalage, court, entre les elements d'un meme bloc de lecture. */
.home-seq > .reveal:nth-child(2) { transition-delay: 80ms; }
.home-seq > .reveal:nth-child(3) { transition-delay: 160ms; }
.home-seq > .reveal:nth-child(4) { transition-delay: 240ms; }

@media (prefers-reduced-motion: reduce) {
  body[data-page="accueil"] .home-section .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .home-media > img,
  .home-link::after,
  .home-link svg { transition: none; }
  .home-media.reveal:not(.is-in) > img { --media-scale: 1; }
}

/* --------------------------------------------------------------------------
   1. Introduction editoriale
   -------------------------------------------------------------------------- */
.home-intro__label { grid-column: 1 / span 3; }
.home-intro__title { grid-column: 4 / -1; }
.home-intro__aside {
  grid-column: 8 / -1;
  margin-top: var(--sp-7);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-6);
}

/* --------------------------------------------------------------------------
   2. Composition en deux blocs : photographie et colonne editoriale
   Le meme composant sert l'architecture et les alentours ; seule la variante
   inversee change les colonnes, ce qui cree le rythme entre les deux.
   -------------------------------------------------------------------------- */
.home-split__media { grid-column: 1 / span 8; }
.home-split__body {
  grid-column: 9 / -1;
  /* Le texte se cale sur le bas de la photographie : c'est ce qui evite la
     diagonale vide d'un bloc centre. */
  align-self: end;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-5);
}
.home-split__body > .home-label + .home-title { margin-top: calc(var(--sp-5) * -1 + var(--sp-3)); }
.home-split__body > .home-link { margin-top: var(--sp-3); }

.home-split--reverse .home-split__body {
  grid-column: 1 / span 4;
  align-self: center;
}
.home-split--reverse .home-split__media { grid-column: 6 / -1; }

/* --------------------------------------------------------------------------
   3. Photographie pleine largeur, puis bloc editorial sur deux colonnes
   -------------------------------------------------------------------------- */
.home-wide__media {
  display: block;
  margin: 0;
  height: 78svh;
  overflow: hidden;
  background-color: var(--bg-sunken);
}
.home-wide__media > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
  transform: scale(var(--media-scale, 1));
  transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
.home-wide__media.reveal:not(.is-in) > img { --media-scale: 1.03; }
.home-wide__body {
  padding-inline: var(--home-pad);
  margin-top: clamp(48px, 4vw, 64px);
}
.home-wide__body > .home-title { grid-column: 1 / span 5; }
.home-wide__body > .home-text { grid-column: 7 / -1; }

/* --------------------------------------------------------------------------
   4. Espaces et equipements : une liste, pas une grille de petits blocs
   -------------------------------------------------------------------------- */
.home-facts__head {
  grid-column: 1 / span 5;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
.home-facts__list {
  grid-column: 7 / -1;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--rule);
}
.home-facts__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-5);
  padding-block: 27px;
  border-bottom: 1px solid var(--rule);
}
.home-facts__name {
  font-family: var(--font-azimut);
  font-size: 16px;
  font-weight: var(--fw-regular);
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--text-strong);
}
/* Volontairement discrets : ils ordonnent la liste, ils ne rivalisent pas
   avec les informations chiffrees de la sequence. */
.home-facts__num {
  flex: 0 0 auto;
  font-family: var(--font-azimut);
  font-size: 11px;
  font-weight: var(--fw-medium);
  line-height: 14px;
  letter-spacing: 1.2px;
  color: var(--text-muted);
  font-variant-numeric: lining-nums tabular-nums;
}

/* --------------------------------------------------------------------------
   5. Apercu de la galerie : une grande image, deux secondaires alignees
   -------------------------------------------------------------------------- */
.home-gallery { row-gap: var(--home-gap); }
.home-gallery__head {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  margin-bottom: clamp(40px, 3.5vw, 56px);
}
.home-gallery__lead { grid-column: 1 / span 7; grid-row: 2 / span 2; }
.home-gallery__side { grid-column: 9 / -1; }
.home-gallery__cta { grid-column: 1 / -1; margin: clamp(32px, 3vw, 48px) 0 0; }

/* --------------------------------------------------------------------------
   6. Appel final : la seule action forte de la page
   -------------------------------------------------------------------------- */
.home-final {
  min-height: 75svh;
  display: grid;
  place-items: center;
  background-color: var(--c-charcoal);
  color: var(--text-on-dark);
  text-align: center;
}
.home-final .home-label { color: var(--text-on-dark-muted); }
.home-final .home-title { color: var(--text-on-dark); }
.home-final__inner {
  width: min(100%, 62rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-5);
}
.home-final .home-lead {
  max-width: 55ch;
  color: var(--text-on-dark-muted);
}
.home-final__actions {
  margin: var(--sp-2) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
}
.home-final__fine {
  margin: var(--sp-4) 0 0;
  max-width: 52ch;
  font-family: var(--font-azimut);
  font-size: 13px;
  font-weight: var(--fw-light);
  line-height: 1.6;
  color: var(--text-on-dark-muted);
}

/* Bouton principal : meme famille que celui du hero, meme rayon, meme
   remplissage vertical, meme fleche. Aucun troisieme style n'est introduit. */
.home-btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-width: 205px;
  height: 46px;
  padding: 12px 26px;
  border: 1px solid var(--c-ivory);
  border-radius: 9999px;
  background-color: transparent;
  color: var(--c-ivory);
  font-family: var(--font-azimut);
  font-size: 16px;
  font-weight: var(--fw-regular);
  line-height: 16px;
  letter-spacing: 0;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 300ms ease;
}
.home-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-color: var(--c-ivory);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.4s cubic-bezier(0.76, 0, 0.24, 1);
}
.home-btn:hover::before,
.home-btn:focus-visible::before { transform: scaleY(1); }
.home-btn:hover,
.home-btn:focus-visible { color: var(--c-charcoal); }
.home-btn svg {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}
.home-btn:hover svg,
.home-btn:focus-visible svg { transform: translateX(4px); }
.home-btn:focus-visible { outline: 2px solid var(--c-ivory); outline-offset: 3px; }

@media (hover: none) {
  .home-btn:hover::before { transform: scaleY(0); }
  .home-btn:hover { color: var(--c-ivory); }
  .home-btn:hover svg,
  .home-link:hover svg { transform: none; }
  .home-link:hover::after { transform: scaleX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .home-btn::before,
  .home-btn svg { transition-duration: 0.01ms; }
}

/* Rythme interne des colonnes editoriales : surtitre 12px sous, titre 24px
   sous, paragraphes 16px entre eux, lien 32px sous le dernier paragraphe. */
.around__body > * + * { margin-top: var(--gap-text); }
.around__body > .eyebrow + * { margin-top: var(--gap-label); }
.around__body > h2 + * { margin-top: var(--gap-title); }
.around__body > * + .link-line { margin-top: var(--gap-action); }

/* Environnement : carte + distances, en deux colonnes egales.
   La seule composition reellement asymetrique de l'accueil est la
   presentation generale ; ici les deux colonnes se repondent a parts egales. */
/* `align-items: center` centrait verticalement la carte par rapport au texte :
   la carte demarrait plus haut que le titre et les deux blocs ne se lisaient
   plus comme une seule composition. Les hauts sont desormais alignes, sur
   l accueil comme sur la page Autour, avec le meme principe. */
.around {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--grid-gap);
  align-items: start;
}
/* Texte a gauche, carte a droite : les six H2 de l'accueil demarrent ainsi
   tous sur le meme axe. */
/* Sept colonnes pour le texte, cinq pour la carte. A parts egales, la carte
   depassait 740px de haut et dominait la section ; le bloc editorial, lui,
   s arretait bien avant. Le desequilibre venait de la repartition, pas du
   dessin : aucun lieu n est coupe. */
.around__body { grid-column: 1 / span 7; }
.around__map { grid-column: 8 / span 5; }

.distances { margin-top: var(--gap-action); }
.distances__row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-4);
  align-items: baseline;
  padding-block: var(--sp-3);
  border-top: 1px solid var(--rule-soft);
}
.distances__row:last-child { border-bottom: 1px solid var(--rule-soft); }
.distances__name { font-size: var(--fs-small); line-height: var(--lh-secondary); color: var(--text-strong); }
.distances__time {
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Carte editoriale dessinee : aucun marqueur precis de la propriete */
.map-editorial {
  position: relative;
  background-color: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
/* La carte est un SVG externe charge en <img> : il doit occuper la colonne. */
.map-editorial img {
  width: 100%;
  height: auto;
  display: block;
}
.map-editorial__note {
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
  background-color: var(--bg-raised);
}

/* Bloc de demande final */
.request-band { background-color: var(--c-charcoal); }
.request-band .input,
.request-band .select,
.request-band .textarea {
  background-color: rgba(244, 240, 231, 0.06);
  border-color: rgba(244, 240, 231, 0.18);
  color: var(--c-ivory);
}
.request-band .input:focus,
.request-band .select:focus,
.request-band .textarea:focus {
  background-color: rgba(244, 240, 231, 0.1);
  border-color: var(--c-gold);
  box-shadow: 0 0 0 3px rgba(185, 154, 95, 0.16);
}
.request-band .select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23F4F0E7' stroke-width='1.2' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
}
.request-band .input::placeholder,
.request-band .textarea::placeholder { color: rgba(244, 240, 231, 0.4); }
.request-band .btn--primary {
  background-color: var(--c-ivory);
  color: var(--c-charcoal);
  border-color: var(--c-ivory);
}
.request-band .btn--primary:hover { background-color: var(--c-gold); border-color: var(--c-gold); color: var(--c-charcoal); }
.request-band .form-status { background-color: rgba(244, 240, 231, 0.06); border-left-color: var(--c-gold); }

/* ==========================================================================
   3. Page La villa
   ========================================================================== */

/* Sommaire interne colle sous l'en-tete */
.section-nav {
  position: sticky;
  top: var(--header-h);
  z-index: var(--z-sticky);
  background-color: rgba(244, 240, 231, 0.94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.section-nav__list {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  height: var(--subnav-h);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.section-nav__list::-webkit-scrollbar { display: none; }
.section-nav__link {
  white-space: nowrap;
  font-size: var(--fs-small);
  font-weight: var(--fw-regular);
  letter-spacing: var(--ls-button);
  line-height: var(--lh-ui);
  color: var(--text-muted);
  padding-block: var(--sp-2);
  border-bottom: 2px solid transparent;
  /* Cible tactile de 44px conservee malgre une barre plus basse. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.section-nav__link:hover { color: var(--text-strong); }
/* L onglet actif se distingue par la couleur ET par un filet de 2px : jamais
   par la seule couleur. */
.section-nav__link.is-current { color: var(--text-strong); border-bottom-color: var(--c-gold); }

/* Un espace de la visite : titre, description courte, informations pratiques,
   deux a quatre photographies complementaires, et le renvoi vers la galerie
   filtree pour tout le reste. */
/* Le texte et la photographie partagent la meme ligne, dans les memes
   proportions que la presentation generale de l'accueil : la page se lit sur
   un seul axe et sa hauteur est divisee d'autant. */
.space {
  display: grid;
  grid-template-columns: minmax(0, 38fr) minmax(0, 57fr);
  column-gap: var(--grid-gap);
  row-gap: var(--sp-5);
  align-items: start;
  padding-block: var(--sp-7);
  border-top: 1px solid var(--rule-soft);
}
.space:first-of-type { border-top: 0; padding-top: 0; }

.space__head { grid-column: 1; }
.space__gallery { grid-column: 2; }

/* Alternance sobre : une sous-partie sur deux inverse les colonnes. L ordre du
   DOM ne change pas, donc en colonne unique la lecture reste titre, texte,
   caracteristiques, photographie, lien, partout sur la page. */
.space--reverse { grid-template-columns: minmax(0, 57fr) minmax(0, 38fr); }
.space--reverse .space__head { grid-column: 2; }
.space--reverse .space__gallery { grid-column: 1; grid-row: 1; }

.space__title { font-size: var(--fs-heading-card); }
/* Titre vers paragraphe : 12px. */
.space__intro { margin-top: var(--sp-3); }
.space__intro p { font-size: var(--fs-small); line-height: var(--lh-secondary); max-width: var(--measure); }

/* Informations pratiques : une ligne sobre de faits, jamais des pictogrammes */
/* Grille 2 par 2 plutot qu une rangee flex : trois faits sur la premiere
   ligne et un seul sur la seconde donnaient une liste bancale. */
.space__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-3) var(--sp-5);
  margin-top: var(--sp-5);
}
.space__facts li {
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}
.space__facts li::before {
  content: "";
  width: 4px; height: 4px;
  border-radius: 50%;
  background-color: var(--c-gold);
}
.space__more { margin-top: var(--sp-6); }

/* Deux a quatre photographies : la premiere donne le volume, les suivantes
   se partagent la largeur restante. Les tracks vides se replient d'elles-memes,
   la composition reste juste avec deux comme avec quatre images. */
/* Flex plutot que grid : les vignettes secondaires se partagent exactement la
   largeur restante, qu'il y en ait une, deux ou trois. Une grille auto-fit
   creait des colonnes vides et laissait les images orphelines a gauche. */
.space__gallery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  align-items: flex-start;
}
.space__gallery .gallery-item {
  margin: 0;
  cursor: zoom-in;
  flex: 1 1 12rem;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  background-color: var(--bg-sunken);
}
/* 16:10 plutot que 3:2, et une hauteur plafonnee. La photographie faisait
   511px pour un texte de 227px : elle continuait sur pres de 300px apres la
   fin du bloc et gonflait toute la page. Elle reste largement dominante sans
   creer de vide dans la colonne de texte. */
.space__gallery .gallery-item--lead {
  flex: 1 0 100%;
  aspect-ratio: 16 / 10;
  max-height: 22rem;
}
.space__gallery .gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
  border-radius: var(--radius);
}
@media (hover: hover) {
  .space__gallery .gallery-item img { transition: transform var(--dur-slow) var(--ease-out); }
  .space__gallery .gallery-item:hover img { transform: scale(1.02); }
}

/* --------------------------------------------------------------------------
   Chambres : six fiches comparables plutot que six grandes sections
   -------------------------------------------------------------------------- */

.rooms-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: var(--sp-8) var(--sp-7);
}

/* La note concerne les six fiches, pas la derniere : elle occupe une ligne de
   grille complete, detachee par un filet et une vraie respiration. */
.rooms-note {
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--rule);
  max-width: var(--measure);
}

/* Meme motif pour un lien qui conclut une grille entiere : il ne doit pas
   sembler appartenir a la premiere colonne. */
.section-note-cta { margin-top: var(--sp-7); }

.room-card { display: flex; flex-direction: column; }

/* Une photographie par chambre, toujours au meme ratio : les six fiches sont
   strictement comparables et la page ne devient pas une seconde galerie. */
.room-card__media {
  display: block;
  /* 4:3 plutot que 3:2 : une chambre se lit mieux dans un cadre moins
     panoramique, ou le lit et les ouvertures tiennent ensemble. */
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  background-color: var(--bg-sunken);
}
.room-card__media .gallery-item {
  margin: 0;
  height: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  background-color: var(--bg-sunken);
  cursor: zoom-in;
}
.room-card__media .gallery-item img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
}

.room-card__name {
  margin-top: var(--sp-5);
  font-size: var(--fs-heading-s);
  font-weight: var(--fw-medium);
  color: var(--text-strong);
}
.room-card__tag {
  display: inline-block;
  margin-left: var(--sp-3);
  font-family: var(--font-text);
  font-size: var(--fs-eyebrow);
  line-height: var(--lh-ui);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
  vertical-align: 0.18em;
}

.room-card__specs { margin-top: var(--sp-3); }
.room-card__specs div {
  display: grid;
  grid-template-columns: minmax(6.5rem, 8rem) 1fr;
  gap: var(--sp-4);
  padding-block: var(--sp-2);
  border-top: 1px solid var(--rule-soft);
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
}
.room-card__specs dt { color: var(--text-muted); }
.room-card__specs dd { color: var(--text-body); }
/* `auto` cale le lien en bas de fiche : d'une chambre a l'autre, les liens
   s'alignent meme quand une caracteristique passe sur deux lignes. */
.room-card__link { margin-top: auto; padding-top: var(--sp-4); align-self: flex-start; }

/* ==========================================================================
   4. Page Autour
   ========================================================================== */

/* Chaque destination : nom, categorie, temps de trajet, description courte,
   un conseil concret quand il existe, et le lien officiel. */
/* Meme grille que la presentation generale de l'accueil et que les espaces de
   la page Villa : 38 / 57. Les huit destinations se lisent donc sur les memes
   deux axes que le reste du site. */
.places { display: grid; gap: 0; }
.place {
  display: grid;
  grid-template-columns: minmax(0, 38fr) minmax(0, 57fr);
  column-gap: var(--grid-gap);
  row-gap: var(--sp-4);
  padding-block: var(--sp-7);
  border-top: 1px solid var(--rule-soft);
  align-items: start;
}
.place:last-child { border-bottom: 1px solid var(--rule-soft); }

.place__name { font-size: var(--fs-heading-card); }
.place__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-3);
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
}
.place__cat {
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  font-weight: var(--fw-medium);
}
.place__time {
  padding: var(--sp-1) var(--sp-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.place__text { font-size: var(--fs-small); line-height: var(--lh-secondary); }
.place__tip {
  margin-top: var(--sp-4);
  padding-left: var(--sp-4);
  border-left: 2px solid var(--rule);
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
}
.place__link { margin-top: var(--sp-3); }

.activities {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-5);
}
.activities li {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-body);
}

.addresses { display: grid; gap: var(--sp-5); }
.address-item {
  padding-block: var(--sp-4);
  border-top: 1px solid var(--rule-soft);
}
.address-item h3 { font-size: var(--fs-heading-s); }
.address-item p { margin-top: var(--sp-2); font-size: var(--fs-small); line-height: var(--lh-secondary); }
.address-item a { margin-top: var(--sp-3); }

/* ==========================================================================
   5. Page Tarifs et disponibilites
   ========================================================================== */

/* Ordre du DOM : calendrier, estimation, puis explications tarifaires.
   Sur mobile cet ordre est exactement ce que l'on veut lire ; sur grand
   ecran la grille replace l'estimation en colonne de droite. */
.booking {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  column-gap: var(--grid-gap);
  row-gap: var(--sp-8);
  align-items: start;
}
/* Premiere rangee : calendrier a gauche, estimation a droite. Le detail des
   montants et les periodes d ouverture passent SOUS les deux colonnes : ils
   restaient auparavant confines dans la colonne gauche, laissant une grande
   zone vide a droite sur toute la partie basse de la page. */
.booking__calendar { grid-column: 1; grid-row: 1; }
.booking__estimate { grid-column: 2; grid-row: 1; }
.booking__details  { grid-column: 1 / -1; grid-row: 2; }

.rate-table { margin-top: var(--sp-6); }
.rate-table caption {
  text-align: left;
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
  padding-bottom: var(--sp-3);
}
.rate-table th,
.rate-table td {
  text-align: left;
  padding: var(--sp-4) var(--sp-4) var(--sp-4) 0;
  border-bottom: 1px solid var(--rule-soft);
  font-size: var(--fs-small);
  line-height: var(--lh-secondary);
  vertical-align: baseline;
}
.rate-table th {
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  line-height: var(--lh-ui);
  text-transform: uppercase;
}
.rate-table td:last-child { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-strong); }
.rate-table tbody tr:last-child td { border-bottom: 0; }

/* Le detail occupe maintenant les deux colonnes. Sans repartition explicite,
   la colonne de libelle restait etroite pendant que la colonne de montant
   s'etirait sur plusieurs centaines de pixels vides. Trois parts fixes :
   le libelle, la precision, le montant. */
.rate-table { table-layout: fixed; }
.rate-table th[scope="row"] { width: 30%; }
.rate-table td:nth-child(2) { width: 52%; color: var(--text-muted); }
.rate-table td:last-child { width: 18%; }

.season {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--sp-5);
  margin-top: var(--sp-6);
}
.season__item { padding-top: var(--sp-4); border-top: 1px solid var(--rule-gold); }
.season__period {
  font-family: var(--font-text);
  font-weight: var(--fw-medium);
  font-size: var(--fs-heading-s);
  line-height: var(--lh-title);
  letter-spacing: var(--ls-title);
  color: var(--text-strong);
}
.season__note { margin-top: var(--sp-2); font-size: var(--fs-fine); font-weight: var(--fw-regular); line-height: var(--lh-secondary); color: var(--text-muted); }

.notice {
  margin-top: var(--sp-6);
  padding: var(--sp-5);
  background-color: var(--bg-sunken);
  border-left: 2px solid var(--c-gold);
  font-size: var(--fs-small);
  line-height: var(--lh-secondary);
}

/* ==========================================================================
   6. Page Contact
   ========================================================================== */

.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  gap: var(--grid-gap);
  align-items: start;
}
.contact-aside { position: sticky; top: calc(var(--header-h) + var(--sp-6)); }
.contact-aside .facts { margin-top: var(--sp-5); }

/* Resume des dates en toutes lettres : le rendu natif d'un champ `date`
   depend de la langue du navigateur et « 09/05/2026 » reste ambigu. */
.date-summary {
  padding: var(--sp-4) var(--sp-5);
  line-height: var(--lh-secondary);
  background-color: var(--bg-sunken);
  border-left: 2px solid var(--rule-gold);
  font-size: var(--fs-small);
  color: var(--text-muted);
}
.date-summary.is-set {
  color: var(--text-strong);
  border-left-color: var(--c-maquis);
  font-weight: var(--fw-regular);
}

/* ==========================================================================
   6 bis. La conclusion : modale de remerciement
   -----------------------------------------------------------------------------
   C'est le dernier moment de l'experience, et le seul ou le site annonce une
   bonne nouvelle. Il merite une orchestration, pas une apparition.

   Une seule classe pilote tout — `is-ouvert`, posee par le script sur le
   `<dialog>`. Chaque element porte son propre retard, exactement comme la
   liste de la page « La villa » et le menu mobile : le vocabulaire de
   mouvement du site ne change pas d'un endroit a l'autre.

   Sequence, en millisecondes apres l'ouverture :
       0    le fond s'assombrit et se trouble
       60   le panneau monte de 18px et se pose
       200  le cercle du sceau se dessine
       620  la coche se trace
       340  le surtitre, puis le titre, le texte, le recapitulatif, les
            actions — un cran de 70ms entre chacun
   ========================================================================== */

.merci {
  /* Les jetons de mouvement ne vivent que sur la page Tarifs : on redeclare
     ici les deux seules courbes utilisees, plutot que d'en importer une
     feuille entiere. */
  --merci-lux:  cubic-bezier(0.22, 1, 0.36, 1);
  --merci-pas:  70ms;

  width: min(34rem, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100svh - 2 * var(--sp-7));
  padding: 0;
  border: 0;
  border-top: 2px solid var(--c-gold);
  border-radius: var(--radius);
  background-color: var(--bg-raised);
  color: var(--text-body);
  box-shadow: var(--shadow-lg);
  overflow: hidden auto;

  /* Etat d'arrivee. `showModal()` met le panneau dans la couche superieure
     AVANT que la classe n'arrive : il part donc bien d'ici. */
  opacity: 0;
  transform: translateY(18px) scale(0.985);
  transition:
    opacity 380ms var(--merci-lux),
    transform 520ms var(--merci-lux);
}
.merci.is-ouvert { opacity: 1; transform: none; }

/* Le fond. `::backdrop` n'existe que pendant que la modale est ouverte : il
   est donc peint transparent, puis transitionne des que la classe arrive. Le
   trouble est leger — six pixels — parce qu'il doit adoucir la page, pas
   l'effacer : on veut sentir qu'on est toujours sur le site. */
.merci::backdrop {
  background-color: rgba(20, 23, 19, 0);
  -webkit-backdrop-filter: blur(0px);
  backdrop-filter: blur(0px);
  transition:
    background-color 420ms var(--merci-lux),
    -webkit-backdrop-filter 420ms var(--merci-lux),
    backdrop-filter 420ms var(--merci-lux);
}
.merci.is-ouvert::backdrop {
  background-color: rgba(20, 23, 19, 0.52);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.merci__in {
  padding: clamp(30px, 3.8vw, 46px) clamp(26px, 3.4vw, 44px) clamp(26px, 3.4vw, 40px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* --- Le sceau -------------------------------------------------------------- */

.merci__sceau {
  display: block;
  color: var(--c-gold-ink);
  margin-bottom: var(--sp-5);
}
.merci__sceau svg { display: block; }

/* Longueurs mesurees, pas approchees : circonference = 2 x pi x 26 = 163,4 ;
   la coche fait racine(7^2+7^2) + racine(14^2+16^2) = 9,9 + 21,3 = 31,2. */
.merci__cercle {
  stroke-dasharray: 164;
  stroke-dashoffset: 164;
  transition: stroke-dashoffset 820ms var(--merci-lux) 200ms;
}
.merci__coche {
  stroke-dasharray: 32;
  stroke-dashoffset: 32;
  transition: stroke-dashoffset 380ms var(--merci-lux) 620ms;
}
.merci.is-ouvert .merci__cercle,
.merci.is-ouvert .merci__coche { stroke-dashoffset: 0; }

/* --- Le texte -------------------------------------------------------------- */

/* Tous les blocs entrent de la meme facon : huit pixels, jamais davantage.
   Seul le retard change, et il est ecrit sur chacun. */
.merci__sur,
.merci__titre,
.merci__texte,
.merci__recap,
.merci__fine,
.merci__actions {
  opacity: 0;
  transform: translateY(8px);
  /* Aucune transition dans l'etat de depart : declaree ici, elle se
     rejouerait a l'envers a la fermeture, sous un panneau deja efface. */
  transition: none;
}
.merci.is-ouvert .merci__sur,
.merci.is-ouvert .merci__titre,
.merci.is-ouvert .merci__texte,
.merci.is-ouvert .merci__recap,
.merci.is-ouvert .merci__fine,
.merci.is-ouvert .merci__actions {
  opacity: 1;
  transform: none;
  transition:
    opacity 460ms var(--merci-lux) var(--merci-retard, 0ms),
    transform 520ms var(--merci-lux) var(--merci-retard, 0ms);
}
.merci__sur     { --merci-retard: 340ms; }
.merci__titre   { --merci-retard: calc(340ms + 1 * var(--merci-pas)); }
.merci__texte   { --merci-retard: calc(340ms + 2 * var(--merci-pas)); }
.merci__recap   { --merci-retard: calc(340ms + 3 * var(--merci-pas)); }
.merci__fine    { --merci-retard: calc(340ms + 4 * var(--merci-pas)); }
.merci__actions { --merci-retard: calc(340ms + 5 * var(--merci-pas)); }

.merci__sur {
  font-family: var(--font-text);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-medium);
  line-height: var(--lh-ui);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-gold-ink);
}
.merci__titre {
  margin-top: var(--sp-3);
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  font-size: clamp(1.5rem, 1.2rem + 1.1vw, 2.125rem);
  line-height: var(--lh-title);
  color: var(--text-strong);
  text-wrap: balance;
}
.merci__texte {
  margin-top: var(--sp-4);
  font-size: var(--fs-small);
  line-height: var(--lh-secondary);
  color: var(--text-body);
  max-width: 32rem;
}

/* --- Le recapitulatif ------------------------------------------------------ */

/* Ce que le visiteur vient d'envoyer, relu. C'est la difference entre « c'est
   parti » et « c'est parti, et voici quoi ». */
/* La ligne `.recap__row` du socle est reprise TELLE QUELLE : libellé à gauche,
   valeur à droite, filet entre les deux. C'est déjà celle du panneau posé
   sous la modale, et deux récapitulatifs dessinés différemment sur le même
   écran se remarqueraient. Seuls le cadre et le pas vertical sont resserrés :
   une modale est plus dense qu'une page. */
.merci__recap {
  width: 100%;
  margin: var(--sp-5) 0 0;
  padding: 0 var(--sp-5);
  background-color: var(--bg-sunken);
  border-left: 2px solid var(--rule-gold);
}
.merci__recap:empty { display: none; }
.merci__recap .recap__row { padding-block: var(--sp-2); }
/* Le dernier filet tomberait sur le bord du cadre. */
.merci__recap .recap__row:last-child { border-bottom: 0; }

.merci__fine {
  margin-top: var(--sp-5);
  font-size: var(--fs-fine);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
}

.merci__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
  width: 100%;
}
.merci__actions .btn { flex: 1 1 12rem; }

/* Étroit : « 7 août 2027 → 14 août 2027 » ne tient plus à côté de son
   libellé. La ligne se replie au lieu de comprimer la valeur.

   Et le panneau se resserre. Mesuré sur un écran de 812 px de haut, avec le
   récapitulatif le plus long possible — quatre lignes, deux semaines, douze
   voyageurs : le contenu atteignait 750 px pour 716 disponibles, et la
   conclusion se lisait en défilant. Quarante pixels repris sur le sceau et
   trois marges suffisent à la faire tenir d'un seul regard. Au-delà, le
   défilement reste là : c'est un filet, pas le fonctionnement normal. */
@media (max-width: 560px) {
  .merci__recap .recap__row { flex-wrap: wrap; gap: 0; }
  .merci__recap .recap__row dd { text-align: left; }

  .merci__sceau { margin-bottom: var(--sp-4); }
  .merci__sceau svg { width: 48px; height: 48px; }
  .merci__fine { margin-top: var(--sp-4); }
  .merci__actions { margin-top: var(--sp-4); }
  .merci__in { padding-bottom: var(--sp-5); }
}

/* Le mouvement retire : tout est en place des l'ouverture, y compris le
   sceau, qui se montre entier plutot que de se dessiner. */
@media (prefers-reduced-motion: reduce) {
  .merci,
  .merci.is-ouvert { opacity: 1; transform: none; transition: none; }
  .merci::backdrop,
  .merci.is-ouvert::backdrop {
    background-color: rgba(20, 23, 19, 0.52);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    transition: none;
  }
  .merci__cercle,
  .merci__coche { stroke-dashoffset: 0; transition: none; }
  .merci__sur, .merci__titre, .merci__texte,
  .merci__recap, .merci__fine, .merci__actions,
  .merci.is-ouvert .merci__sur, .merci.is-ouvert .merci__titre,
  .merci.is-ouvert .merci__texte, .merci.is-ouvert .merci__recap,
  .merci.is-ouvert .merci__fine, .merci.is-ouvert .merci__actions {
    opacity: 1; transform: none; transition: none;
  }
}


/* ==========================================================================
   7. Pages legales et textes longs
   ========================================================================== */

/* Colonne de lecture centree. Elle etait calee a gauche dans une coquille de
   1440px : au-dela de 1000px, toute la moitie droite restait vide et la page
   se lisait comme une mise en page inachevee. */
.legal { max-width: var(--measure-legal); margin-inline: auto; }
/* Un H2 de page legale titre une section de premier niveau : meme rang,
   donc meme corps que les H2 des autres pages. */
.legal h2 {
  font-size: var(--fs-heading-functional);
  margin-top: var(--sp-8);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--rule-gold);
}
.legal h2:first-of-type { margin-top: 0; }
.legal h3 {
  font-family: var(--font-text);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-eyebrow);
  line-height: var(--lh-ui);
  text-transform: uppercase;
  margin-top: var(--sp-7);
  color: var(--text-strong);
}
/* Texte suivi d une page legale : c est du paragraphe courant, pas du texte
   secondaire. Meme corps et meme interlignage que partout ailleurs. */
/* Texte suivi d une page juridique : c est du paragraphe courant, pas du
   texte secondaire. La 300 tient sur un paragraphe isole mais se delave sur
   plusieurs ecrans de texte dense d affilee ; 350 rend le trait sans alourdir
   la page, et la couleur reste celle du corps de texte. */
.legal p,
.legal li {
  font-size: var(--fs-body);
  font-weight: var(--fw-book);
  line-height: var(--lh-body);
}
.legal p { margin-top: var(--gap-text); }
.legal ul { margin-top: var(--gap-text); display: grid; gap: var(--sp-3); }
.legal li { padding-left: var(--sp-5); position: relative; }
.legal li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.72em;
  width: 10px; height: 1px;
  background-color: var(--c-gold);
}
.legal a { border-bottom: 1px solid var(--rule-gold); }
/* Specificite alignee sur `.legal p`, qui sinon lui imposait 16px. */
.legal .legal__updated {
  margin-top: var(--sp-8);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-fine);
  font-weight: var(--fw-regular);
  line-height: var(--lh-secondary);
  color: var(--text-muted);
}

/* ==========================================================================
   8. Introduction commune aux pages fonctionnelles
   Galerie, Tarifs, Contact et pages legales partagent exactement le meme
   bloc : hauteur, place du surtitre, taille du H1, mesure du paragraphe et
   espacement avec le contenu qui suit.
   ========================================================================== */

.page-head {
  padding-top: var(--intro-pt);
  padding-bottom: var(--intro-pb);
  border-bottom: 1px solid var(--rule);
  background-color: var(--bg-page);
}
.page-head h1 {
  margin-top: var(--gap-label);
  /* Page fonctionnelle : Galerie, Tarifs, Contact. */
  font-size: var(--fs-display-page);
  max-width: 20ch;
}
/* Page juridique : le cran le plus bas du registre serif. Un titre de 76px
   au-dessus de mentions legales etait disproportionne. */
body[data-page="legal"] .page-head h1 { font-size: var(--fs-display-legal); }
.page-head .lead {
  margin-top: var(--gap-title);
  max-width: var(--measure-lead);
}
/* Le contenu qui suit demarre toujours a la meme distance. */
/* Sur la Galerie, le contenu utile EST la grille : elle doit apparaitre dans
   la premiere fenetre. Le bloc de presentation garde sa composition, mais la
   distance qui le separe des filtres est reduite d un cran. */
.page-head + .section { padding-top: var(--sp-7); }
body[data-page="galerie"] .page-head + .section { padding-top: var(--sp-6); }
body[data-page="galerie"] .page-head { padding-bottom: var(--sp-6); }
