/* =========================================================================
   ELEVEN PARK — Stylesheet V2
   Design system following the brand book (Edition 01 · 2026)
   ========================================================================= */


/* -------------------------------------------------------------------------
   00 · Polices (hébergées sur le site depuis le 25/09/2026, plus de Google Fonts)
   Mêmes fichiers et mêmes déclarations que Google Fonts : sous-ensembles
   latin et latin-ext, une règle par graisse (le fichier est variable, il est
   téléchargé une seule fois). Les polices ne se chargent qu’en http(s) :
   un index.html ouvert par double-clic (file://) retombe sur la police de secours.
   ------------------------------------------------------------------------- */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/cormorant-garamond-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cormorant-garamond-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/cormorant-garamond-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cormorant-garamond-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/cormorant-garamond-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cormorant-garamond-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/cormorant-garamond-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cormorant-garamond-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* -------------------------------------------------------------------------
   01 · Design tokens
   ------------------------------------------------------------------------- */
/* Mode sombre des téléphones (26/09/2026). Le site est conçu en clair uniquement :
   on le déclare (ici et en <meta name="color-scheme" content="only light"> dans chaque
   page), c’est le signal standard contre l’assombrissement forcé. Samsung Internet 30
   l’ignore encore et assombrit tout site quand le téléphone est en mode sombre ; son
   « mode sombre adaptatif » (encore dans Labs) respecte cette déclaration.
   Testé sur Galaxy S24 Ultra, Samsung Internet 30.0.0.67 : « only light » et
   « light dark » sont tous deux ignorés tant que l’option Labs n’est pas active. */
:root { color-scheme: only light; }
@media (prefers-color-scheme: dark) {
  html, body { background-color: #EDEAE2; color: #4A4A48; }
}

:root {
  /* V10 — Palette nommée (charte v4, 25/09/2026)
     4 couleurs de marque + une échelle de neutres, chacune avec un rôle.
     Contrastes mesurés sur le fond crème #EDEAE2 :
       graphite 11,2:1 · graphite 80 7,4:1 · graphite 60 5,0:1
       olive 3,7:1 (grands corps / graphique uniquement)
       beige 1,5:1 (JAMAIS pour du texte : filets et contours seulement) */
  --c-bg:           #EDEAE2;   /* Crème — fond principal (= palissades, = print) */
  --c-ivoire:       #F2EFE8;   /* Ivoire — texte clair sur graphite / photo */
  --c-graphite:     #2F2F2E;   /* Graphite — titres, aplats sombres */
  --c-text-strong:  #3A3A38;   /* Graphite 90 — libellés forts */
  --c-text:         #4A4A48;   /* Graphite 80 — texte courant */
  --c-muted:        #666360;   /* Graphite 60 — légendes, libellés discrets */
  --c-beige:        #C8C1B8;   /* Beige pierre — filets, contours */
  --c-olive:        #6F7A6A;   /* Olive — repère, état actif (≤ 5 %) */
  --c-olive-deep:   #5F6A5B;   /* Olive profond — fond des boutons olive (ivoire dessus : 4,9:1) */

  /* Versions RVB pour les transparences : rgb(var(--c-bg-rgb) / .9) */
  --c-bg-rgb:       237 234 226;
  --c-ivoire-rgb:   242 239 232;
  --c-graphite-rgb: 47 47 46;
  --c-beige-rgb:    200 193 184;

  --font-display: 'Cormorant Garamond', 'EB Garamond', Georgia, serif;   /* Canela retirée de la charte le 25/09/2026 */
  --font-body:    'Inter', system-ui, sans-serif;

  --fs-micro:    clamp(11px, 0.72vw + 8px, 13px);
  --fs-caption:  clamp(12px, 0.4vw + 11px, 14px);
  --fs-body:     clamp(15px, 0.3vw + 14px, 17px);
  --fs-label:    clamp(15px, 0.4vw + 14px, 18px);
  --fs-quote:    clamp(22px, 1.6vw + 16px, 32px);
  --fs-h2:       clamp(32px, 3vw + 16px, 56px);
  --fs-h1:       clamp(44px, 5vw + 16px, 84px);
  --fs-display:  clamp(56px, 8vw + 16px, 140px);
  --fs-stat:     clamp(36px, 3.4vw + 16px, 64px);

  --tr-tight:    -0.015em;
  --tr-snug:     -0.005em;
  --tr-normal:   0;
  --tr-wide:     0.08em;
  --tr-caps:     0.16em;

  --s-1:  8px;
  --s-2:  16px;
  --s-3:  24px;
  --s-4:  32px;
  --s-5:  48px;
  --s-6:  64px;
  --s-7:  96px;
  --s-8:  128px;
  --s-9:  192px;
  --s-10: 256px;

  /* ESPACEMENTS DE SECTION (V5.2 — système unifié)
     Une seule variable pilote le rythme vertical de toutes les sections
     non full-bleed. Override aux breakpoints uniquement (voir section 18).
     - Desktop (≥ 1280px) : 192px = grand souffle, registre éditorial
     - Tablet  (640-1280)  : 128px = transition douce
     - Mobile  (< 640px)   : 80px  = compacte mais lisible */
  --section-pad-y: clamp(128px, 11vw, 168px);  /* V10 — 192 → ~160 : le filet de chapitre porte la césure */
  --section-head-mb: var(--s-6);        /* espace entre l'eyebrow header et le H2 / contenu */
  --section-h2-mb: var(--s-5);          /* espace entre le H2 et le corps de section */
  --paragraph-gap: 1.4em;               /* espace entre paragraphes consécutifs */

  --container:    1440px;
  --container-narrow: 720px;
  --gutter:       clamp(20px, 4vw, 64px);

  --ease-soft:    cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-quiet:   cubic-bezier(0.65, 0, 0.35, 1);
  --d-slow:       1200ms;
  --d-medium:     800ms;
  --d-fast:       400ms;
}


/* -------------------------------------------------------------------------
   02 · Reset
   ------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  /* Pas de surbrillance bleue au toucher d’un lien (réglage par défaut des navigateurs
     mobiles ; décision de Simo du 26/09/2026). Le focus au clavier reste visible. */
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* V10 — Chiffres alignés partout. Par défaut, Cormorant dessine des
     chiffres « elzéviriens » : « 11 » s’affichait « I I » et « 1,1 »
     « I,I ». Pour une marque qui s’appelle Eleven, rédhibitoire. */
  font-variant-numeric: lining-nums;
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  /* V10 — Corps en Inter Regular (la Light reste réservée aux titres
     Cormorant) : même légèreté perçue, lisible sur tous les écrans. */
  font-weight: 400;
  line-height: 1.65;
  color: var(--c-text);
  background: var(--c-bg);
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { background: none; border: 0; cursor: pointer; font: inherit; color: inherit; }

::selection { background: var(--c-graphite); color: var(--c-bg); }


/* -------------------------------------------------------------------------
   03 · Typography primitives
   ------------------------------------------------------------------------- */
.eyebrow {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
  display: inline-flex;
  align-items: center;
  gap: 14px;               /* V10 — filet inline AVANT le libellé, écart fixe */
}
.eyebrow--beige { color: var(--c-beige); }   /* sur fond sombre uniquement */
.eyebrow--muted { color: var(--c-muted); }
.eyebrow--light { color: var(--c-beige); }
.eyebrow--light .filet,
.eyebrow--light .filet-grow { background: var(--c-beige); }

.h1 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-h1);
  letter-spacing: var(--tr-snug);
  line-height: 1.05;
  color: var(--c-graphite);
}

.h2 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-h2);
  letter-spacing: var(--tr-snug);
  line-height: 1.1;
  color: var(--c-graphite);
}


/* -------------------------------------------------------------------------
   04 · Filet
   ------------------------------------------------------------------------- */
.filet {
  display: inline-block;
  height: 1px;
  width: 56px;
  background: var(--c-graphite);
  vertical-align: middle;
}
.filet--beige  { background: var(--c-beige); height: 1px; }
.filet--short  { width: 32px; }
.filet--long   { width: 80px; }

.filet-grow {
  display: inline-block;
  height: 1px;
  background: var(--c-graphite);
  width: 0;
  transition: width var(--d-slow) var(--ease-quiet);
}
.filet-grow.is-revealed { width: 56px; }
.filet-grow.is-revealed.filet--long { width: 80px; }


/* -------------------------------------------------------------------------
   05 · Layout
   ------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-inline: var(--gutter);
}


/* -------------------------------------------------------------------------
   06 · Nav
   Logo small, fades in only AFTER scrolling past hero (because hero has
   its own large central logo).
   ------------------------------------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  padding: var(--s-3) var(--gutter);
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--c-bg);
  transition: color var(--d-medium) var(--ease-soft),
              background-color var(--d-medium) var(--ease-soft);
  pointer-events: none;
}
.nav > * { pointer-events: auto; }

.nav.is-scrolled {
  background: rgb(var(--c-bg-rgb) / 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--c-graphite);
  border-bottom: 1px solid rgba(200, 193, 184, 0.3);
}

.nav__logo-link {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity var(--d-medium) var(--ease-soft),
              transform var(--d-medium) var(--ease-soft);
  pointer-events: none;
}
.nav.is-scrolled .nav__logo-link {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.nav__logo {
  width: 110px;     /* tighter viewBox = visible logo larger; bumped from 92px */
  height: auto;
  color: currentColor;
}

.nav__right {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-weight: 500;
}

.nav__link, .lang {
  position: relative;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity var(--d-medium) var(--ease-soft),
              transform var(--d-medium) var(--ease-soft),
              color 200ms var(--ease-soft);
}
.nav__link:hover { color: var(--c-beige); }
.nav.is-scrolled .nav__link:hover { color: var(--c-text); }
body.is-loaded .nav__link, body.is-loaded .lang { opacity: 1; transform: translateY(0); transition-delay: 200ms; }

.lang { display: inline-flex; gap: var(--s-1); }
.lang span { opacity: 0.4; }
.lang .is-active { opacity: 1; }
.lang a { opacity: 0.4; }
.lang a:hover { opacity: 1; }


/* -------------------------------------------------------------------------
   07 · Hero — V10 : la composition du panneau
   Le haut de l’image est un ciel qui se fond dans la crème. Le logo et le
   titre s’y posent en graphite, SANS voile, comme sur le panneau.

   ÉCRAN PAYSAGE (ordinateur) : le hero est plus haut que l’écran. Le
   premier écran montre le ciel, la marque et la villa ; en descendant,
   l’image continue et le jardin se déploie en entier, avec la phrase
   « Le jardin, prolongement de la villa ». On mesure la grandeur du
   jardin en le parcourant, au lieu de le rogner.

   ÉCRAN PORTRAIT (mobile, tablette verticale) : l’image recadrée en 3:4
   contient la villa en entier. Elle est posée en bas de l’écran ; son
   ciel crème se fond dans le fond du hero (même couleur exacte), si bien
   que l’écran entier paraît être un seul ciel où flotte la marque.
   ------------------------------------------------------------------------- */
:root {
  --c-hero-sky: #F5F6F1;     /* couleur exacte du haut de l’image hero */
  --hero-crop: 7vw;          /* part du ciel crème masquée en haut (paysage) */
}

.hero {
  position: relative;
  width: 100%;
  overflow: hidden;
  color: var(--c-graphite);
  background: var(--c-hero-sky);
  /* L’image carrée à pleine largeur, moins le ciel masqué ;
     jamais moins d’un écran, jamais plus de 1,7 écran */
  height: clamp(100svh, calc(100vw - var(--hero-crop)), 170svh);
}

.hero__media {
  position: absolute;
  inset: 0;
  background: var(--c-hero-sky);
  opacity: 0;
  transform: scale(1.03);
  transform-origin: 50% 0%;
  transition: opacity 1800ms var(--ease-soft),
              transform 6000ms var(--ease-soft);
  overflow: hidden;
}
.hero__media picture { position: absolute; inset: 0; }
.hero__media img {
  position: absolute;
  left: 0;
  top: calc(-1 * var(--hero-crop));
  width: 100%;
  height: calc(100% + var(--hero-crop));
  object-fit: cover;
  object-position: 50% 0%;
  filter: saturate(0.9);
}
body.is-loaded .hero__media { opacity: 1; transform: scale(1.0); }

/* Voile conditionnel : uniquement sous les textes posés sur le jardin */
.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg,
    rgb(var(--c-graphite-rgb) / 0.55) 0%,
    rgb(var(--c-graphite-rgb) / 0.10) 34%,
    rgb(var(--c-graphite-rgb) / 0) 48%);
}

/* Le contenu occupe le PREMIER écran uniquement */
.hero__content {
  position: relative;
  z-index: 2;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(88px, 11vh, 124px) var(--gutter) var(--s-3);
}

.hero__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero__logo {
  width: clamp(190px, 16vw, 260px);
  height: auto;
  color: var(--c-graphite);
  margin-bottom: clamp(24px, 3vh, 36px);
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 1400ms var(--ease-soft),
              transform 1600ms var(--ease-soft);
}
body.is-loaded .hero__logo {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 100ms;
}

/* Titre sur une ligne, romain + italique à la même taille —
   exactement comme « Parmi les onze, la vôtre » sur le panneau. */
.hero__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(46px, 5vw + 14px, 104px);
  line-height: 1;
  letter-spacing: var(--tr-tight);
  color: var(--c-graphite);
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.26em;
  white-space: nowrap;
}
.hero__title-line { display: block; }
.hero__title-line--italic { font-style: italic; }

.hero__title .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 1100ms var(--ease-quiet),
              transform 1100ms var(--ease-quiet);
}
.hero__title.is-revealed .word {
  opacity: 1;
  transform: translateY(0);
  transition-delay: calc(520ms + var(--i, 0) * 110ms);
}

/* Pied du premier écran : adresse · appel à la visite */
.hero__foot {
  margin-top: auto;
  width: 100%;
  max-width: calc(var(--container) - 2 * var(--gutter));
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  color: var(--c-ivoire);
}
.hero__accroche {
  justify-self: start;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  text-align: left;
  color: var(--c-ivoire);
  opacity: 0;
  transform: translateY(12px);
  margin: 0;
  padding-bottom: var(--s-2);
}
.hero__accroche.is-revealed {
  opacity: 0.88;
  transform: translateY(0);
  transition: opacity 1200ms var(--ease-soft) 1050ms,
              transform 1200ms var(--ease-soft) 1050ms;
}

.hero__scroll {
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-weight: 500;
  opacity: 0;
  color: var(--c-ivoire);
}
.hero__scroll.is-revealed {
  opacity: 0.9;
  transition: opacity 1000ms var(--ease-soft) 1450ms;
}
.hero__scroll-line {
  width: 1px;
  height: 36px;
  background: rgb(var(--c-ivoire-rgb) / 0.55);
  position: relative;
  overflow: hidden;
}
.hero__scroll-line::after {
  content: '';
  position: absolute;
  top: -100%;
  left: 0;
  right: 0;
  height: 50%;
  background: linear-gradient(to bottom, transparent, var(--c-ivoire));
  animation: scroll-pulse 2.6s ease-in-out infinite;
}
@keyframes scroll-pulse {
  0% { top: -100%; }
  100% { top: 100%; }
}

/* Paysage : le bas du premier écran tombe sur la piscine — on n’y pose
   pas de texte. Seul reste le trait vertical animé, qui invite à descendre
   dans le jardin. (Le texte revient en portrait, où il repose sur la pelouse.) */
@media (min-aspect-ratio: 4/5) {
  .hero__accroche,
  .hero__scroll > span:first-child { display: none; }
  .hero__scroll-line { height: 56px; }
  /* 25/09/2026 : l’adresse masquée, le trait glissait dans la 1re colonne
     de la grille (à gauche, au-dessus de la piscine) : on le fixe au centre. */
  .hero__scroll { grid-column: 2; }
}

/* La phrase du jardin, révélée en descendant (paysage uniquement) */
.hero__garden {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  top: 80%;
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(28px, 2.2vw + 12px, 46px);
  letter-spacing: var(--tr-snug);
  color: var(--c-ivoire);
  text-shadow: 0 1px 18px rgb(var(--c-graphite-rgb) / 0.35);
  pointer-events: none;
}


/* ---- Portrait : mobile et tablette verticale ------------------------- */
@media (max-aspect-ratio: 4/5) {
  .hero {
    height: 100svh;
    min-height: 540px;
  }
  /* L’image 3:4 à pleine largeur, posée en bas. Si l’écran est court,
     elle se raccourcit par le bas (le jardin), jamais par les côtés :
     la villa reste entière. */
  .hero__media {
    top: auto;
    height: min(calc(100vw * 4 / 3), calc(100svh - 170px));
  }
  .hero__media img {
    top: 0;
    height: 100%;
  }
  .hero__media::after {
    background: linear-gradient(0deg,
      rgb(var(--c-graphite-rgb) / 0.6) 0%,
      rgb(var(--c-graphite-rgb) / 0.2) 20%,
      rgb(var(--c-graphite-rgb) / 0) 36%);
  }
  .hero__content {
    height: 100%;
    /* le bas laisse la place au bouton « Son » (fixe, en bas à droite) */
    padding: 0 var(--gutter) 64px;
  }
  /* La marque est centrée dans le ciel : de la nav jusqu’au toit de la
     villa (≈ 31 % de la hauteur de l’image) */
  .hero__brand {
    height: calc(100svh - 0.69 * min(calc(100vw * 4 / 3), calc(100svh - 170px)));
    min-height: 240px;
    justify-content: center;
    padding-top: 40px;
  }
  .hero__logo { width: min(52vw, 230px); margin-bottom: var(--s-3); }
  .hero__title {
    font-size: clamp(28px, 8.4vw, 44px);
    gap: 0.24em;
  }
  .hero__foot {
    grid-template-columns: 1fr;
    justify-items: center;
    row-gap: var(--s-3);
  }
  .hero__scroll { grid-row: 1; grid-column: 1; }
  .hero__scroll-line { height: 32px; }
  .hero__accroche {
    grid-row: 2;
    justify-self: center;
    text-align: center;
    font-size: 10px;
    letter-spacing: 0.14em;
  }
  .hero__garden { display: none; }
}


/* -------------------------------------------------------------------------
   08 · Section frame
   Toutes les sections non full-bleed utilisent --section-pad-y pour
   un rythme vertical homogène à tous les breakpoints.
   ------------------------------------------------------------------------- */
.section {
  padding: var(--section-pad-y) 0;
  position: relative;
}
.section--tight { padding: calc(var(--section-pad-y) * 0.6) 0; }

.section__head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--section-head-mb);
}
.section__head .num {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
}


/* -------------------------------------------------------------------------
   09 · Manifeste
   ------------------------------------------------------------------------- */
.manifeste {
  text-align: left;
  padding: var(--section-pad-y) 0;
}
.manifeste__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(36px, 3.6vw + 16px, 64px);
  line-height: 1.05;
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
  margin-top: var(--s-3);
  margin-bottom: var(--section-h2-mb);
  max-width: 16ch;
}
.manifeste__lead {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(22px, 1.8vw + 14px, 34px);
  line-height: 1.4;
  color: var(--c-graphite);
  margin-bottom: var(--s-5);
}
.manifeste__body p {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.8;
  color: var(--c-text);
}
.manifeste__body p + p { margin-top: var(--paragraph-gap); }
.manifeste__signoff {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(20px, 1.4vw + 14px, 28px);
  color: var(--c-graphite);
  margin-top: var(--s-6);
  line-height: 1.5;
}


/* -------------------------------------------------------------------------
   10 · L'art de vivre  (3-image gallery with offset)
   ------------------------------------------------------------------------- */
.art {
  background: var(--c-bg);
}
.art__head {
  text-align: left;
  margin-bottom: var(--section-head-mb);
  max-width: 720px;
}
.art__head .h2 { margin-top: var(--s-3); margin-bottom: var(--s-3); max-width: 18ch; }
.art__intro {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: var(--fs-quote);
  line-height: 1.4;
  color: var(--c-text-strong);
  max-width: 38ch;
}

.art__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5) var(--s-4);
  align-items: start;
}
.art__item {
  display: flex;
  flex-direction: column;
}
.art__item--offset {
  margin-top: var(--s-7);   /* visual rhythm — middle item drops slightly */
}
.art__media {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--c-bg);            /* matches page background — invisible "breathing" zones */
  margin-bottom: var(--s-3);
  display: flex;
  align-items: center;
  justify-content: center;
}
.art__media-inner {
  width: 100%;
  aspect-ratio: 1 / 1;                /* square photo holder */
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(200, 193, 184, 0.35);
}
.art__media-inner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.9) contrast(1.02);
  transform: scale(1);
  transition: transform 1800ms var(--ease-soft);
}
.art__item:hover .art__media-inner img { transform: scale(1.03); }

/* Mask reveal — clip-path expansion on the inner square image holder */
.art__media-inner::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c-bg);
  z-index: 2;
  transform-origin: top;
  transition: transform 1400ms var(--ease-quiet);
}
.art__media.is-revealed .art__media-inner::before { transform: scaleY(0); }

.art__item-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(22px, 1.2vw + 16px, 28px);
  letter-spacing: var(--tr-snug);
  line-height: 1.2;
  color: var(--c-graphite);
  margin-bottom: var(--s-2);
}
.art__item-text {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-caption);
  line-height: 1.7;
  color: var(--c-text);
}


/* -------------------------------------------------------------------------
   11 · Le Lieu
   ------------------------------------------------------------------------- */
.lieu {
  background: var(--c-bg);
  padding: var(--section-pad-y) 0;
}
.lieu__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--s-7);
  align-items: center;
}

.lieu__image {
  position: relative;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  background: var(--c-beige);
}
.lieu__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.9) contrast(1.02);
  transform: scale(1.08);
  transition: transform 6000ms var(--ease-soft);
}
.lieu__image.is-revealed img { transform: scale(1.0); }

.lieu__image::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c-bg);
  z-index: 2;
  transform-origin: top;
  transition: transform 1400ms var(--ease-quiet);
}
.lieu__image.is-revealed::before { transform: scaleY(0); }

.lieu__caption {
  position: absolute;
  bottom: var(--s-3);
  right: var(--s-3);
  z-index: 3;
  font-size: var(--fs-caption);
  color: var(--c-bg);
  letter-spacing: var(--tr-wide);
  font-weight: 400;
}

.lieu__title { margin-top: var(--s-3); margin-bottom: var(--section-h2-mb); }
.lieu__text p {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.75;
  color: var(--c-text);
}
.lieu__text p + p { margin-top: var(--paragraph-gap); }


/* -------------------------------------------------------------------------
   12 · Le Domaine — Interactive aerial map with hotspots
   ------------------------------------------------------------------------- */
.domaine {
  padding: var(--section-pad-y) 0;
  background: var(--c-bg);
}
.domaine__head {
  text-align: center;
  margin-bottom: var(--section-head-mb);
}
.domaine__head .h2 {
  margin-top: var(--s-3);
  margin-inline: auto;
  max-width: 22ch;
}
.domaine__intro {
  margin-top: var(--s-3);
  max-width: 48ch;
  margin-inline: auto;
  color: var(--c-text);
  font-style: italic;
  font-family: var(--font-display);
  font-size: var(--fs-quote);
  font-weight: 300;
}

.domaine__map-wrap {
  position: relative;
  margin: 0 auto;
  max-width: 1600px;
  padding-inline: var(--gutter);
}

.domaine__map {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--c-graphite);
}

.domaine__photo {
  display: block;
  width: 100%;
  height: auto;
  filter: saturate(0.78) contrast(1.05) brightness(0.96);
}

/* Subtle vignette to focus eye on the complex */
.domaine__map::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 30%, transparent 40%, rgba(47, 47, 46, 0.3) 100%);
}

.domaine__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
}

/* Hotspot button */
.hotspot {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(242, 239, 232, 0.95);
  border: 1px solid rgba(47, 47, 46, 0.5);
  color: var(--c-graphite);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform var(--d-fast) var(--ease-soft),
              background var(--d-fast) var(--ease-soft),
              box-shadow var(--d-fast) var(--ease-soft);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* Pulse ring */
.hotspot::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 1px solid rgba(242, 239, 232, 0.6);
  opacity: 0.7;
  animation: hotspot-pulse 2.6s var(--ease-soft) infinite;
  pointer-events: none;
}
@keyframes hotspot-pulse {
  0%   { transform: scale(1);   opacity: 0.7; }
  70%  { transform: scale(2.2); opacity: 0;   }
  100% { transform: scale(2.2); opacity: 0;   }
}

.hotspot:hover {
  background: var(--c-graphite);
  color: var(--c-bg);
  transform: translate(-50%, -50%) scale(1.15);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
}

.hotspot__num {
  position: relative;
  z-index: 1;
}

.hotspot--small {
  width: 30px;
  height: 30px;
  font-size: 10px;
}

.hotspot--exception {
  background: var(--c-graphite);
  color: var(--c-bg);
  border-color: var(--c-bg);
}
.hotspot--exception::before {
  border-color: rgba(242, 239, 232, 0.8);
  animation-duration: 2s;
}
.hotspot--exception:hover {
  background: var(--c-bg);
  color: var(--c-graphite);
}

/* Tooltip */
.hotspot__tip {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--c-graphite);
  color: var(--c-bg);
  padding: 8px 12px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--d-fast) var(--ease-soft),
              transform var(--d-fast) var(--ease-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.hotspot__tip small {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: none;
  opacity: 0.7;
}
.hotspot__tip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--c-graphite);
}
.hotspot:hover .hotspot__tip {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.domaine__legend {
  display: flex;
  justify-content: center;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin-top: var(--s-4);
  font-size: var(--fs-caption);
  color: var(--c-text);
  letter-spacing: var(--tr-wide);
}
.legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
}
.legend__dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(242, 239, 232, 1);
  border: 1px solid var(--c-graphite);
}
.legend__dot--small {
  width: 8px;
  height: 8px;
}
.legend__dot--exception {
  background: var(--c-graphite);
  border: 1px solid var(--c-graphite);
}


/* -------------------------------------------------------------------------
   11bis · Au fil des heures (cinematic video interlude)
   ------------------------------------------------------------------------- */
.au-fil {
  position: relative;
  width: 100%;
  height: 90vh;
  min-height: 560px;
  max-height: 900px;
  overflow: hidden;
  background: #1a1a19;
  color: var(--c-bg);
}

.au-fil__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
}

/* Soft vignette + bottom gradient so the title is always legible */
.au-fil__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(180deg,
      rgba(20, 20, 19, 0.45) 0%,
      rgba(20, 20, 19, 0.15) 30%,
      rgba(20, 20, 19, 0.15) 60%,
      rgba(20, 20, 19, 0.75) 100%);
  pointer-events: none;
}

.au-fil__content {
  position: absolute;
  inset: auto 0 var(--s-7) 0;
  z-index: 3;
}

.au-fil__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-bg);
  opacity: 0.85;
  margin-bottom: var(--s-3);
}
.au-fil__eyebrow .filet-grow { background: var(--c-bg); }

.au-fil__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(36px, 4.4vw + 16px, 76px);
  line-height: 1.05;
  letter-spacing: var(--tr-snug);
  color: var(--c-bg);
  max-width: 22ch;
}
.au-fil__title em {
  font-style: italic;
  font-weight: 300;
}

/* Video sound toggle — small pill, bottom-right of the video section */
.video-sound {
  position: absolute;
  right: var(--gutter);
  bottom: var(--s-5);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 8px 14px;
  background: rgba(20, 20, 19, 0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(242, 239, 232, 0.3);
  border-radius: 999px;
  color: var(--c-bg);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  transition: background 300ms var(--ease-soft),
              border-color 300ms var(--ease-soft);
}
.video-sound:hover {
  background: rgba(20, 20, 19, 0.75);
  border-color: rgba(242, 239, 232, 0.55);
}
.video-sound__icon {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 14px;
}
.video-sound__bar {
  display: block;
  width: 1.5px;
  height: 5px;
  background: var(--c-bg);
  border-radius: 1px;
  transition: height 200ms var(--ease-soft);
}
.video-sound[data-state="on"] .video-sound__bar {
  animation: ambient-wave 1.4s ease-in-out infinite;
}
.video-sound[data-state="on"] .video-sound__bar:nth-child(2) { animation-delay: 0.2s; }
.video-sound[data-state="on"] .video-sound__bar:nth-child(3) { animation-delay: 0.4s; }


/* -------------------------------------------------------------------------
   17ter · Ambient audio toggle (floating, fixed bottom-right)
   ------------------------------------------------------------------------- */
.ambient-toggle {
  position: fixed;
  right: var(--gutter);
  bottom: var(--gutter);
  z-index: 45;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 8px 14px;
  background: rgb(var(--c-bg-rgb) / 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(200, 193, 184, 0.5);
  border-radius: 999px;
  color: var(--c-graphite);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 600ms var(--ease-soft),
              transform 600ms var(--ease-soft),
              background 300ms var(--ease-soft);
}
.ambient-toggle.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.ambient-toggle:hover {
  background: var(--c-bg);
  border-color: var(--c-graphite);
}

.ambient-toggle__icon {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 14px;
}
.ambient-toggle__bar {
  display: block;
  width: 1.5px;
  height: 5px;
  background: var(--c-graphite);
  border-radius: 1px;
  transition: height 200ms var(--ease-soft);
}
.ambient-toggle[data-state="on"] .ambient-toggle__bar {
  animation: ambient-wave 1.4s ease-in-out infinite;
}
.ambient-toggle[data-state="on"] .ambient-toggle__bar:nth-child(2) { animation-delay: 0.2s; }
.ambient-toggle[data-state="on"] .ambient-toggle__bar:nth-child(3) { animation-delay: 0.4s; }

@keyframes ambient-wave {
  0%, 100% { height: 4px; }
  50% { height: 12px; }
}

/* Hide the audio element itself */
.ambient-audio { display: none; }


/* -------------------------------------------------------------------------
   13bis · Interstitial (full-width wireframe between Domaine and Villas)
   ------------------------------------------------------------------------- */
.interstitial {
  width: 100%;
  height: 70vh;
  min-height: 480px;
  max-height: 800px;
  overflow: hidden;
  position: relative;
  background: transparent;       /* V5.3 : transparent au lieu de beige */
}
.interstitial__media {
  position: absolute;
  inset: -10% 0;        /* negative inset to allow parallax movement */
  width: 100%;
}
.interstitial__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.9) contrast(1.02);
  will-change: transform;
}

/* Subtle vignette for depth */
.interstitial::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(242, 239, 232, 0.25) 0%,
    transparent 12%,
    transparent 88%,
    rgba(242, 239, 232, 0.25) 100%);
  pointer-events: none;
}

@media (max-width: 640px) {
  .interstitial { height: 50vh; min-height: 360px; }
}


/* -------------------------------------------------------------------------
   13 · Les Villas (3 typology cards)
   ------------------------------------------------------------------------- */
.villas {
  background: var(--c-bg);
}
.villas__head {
  text-align: center;
  margin-bottom: var(--section-head-mb);
}
.villas__head .h2 { margin-top: var(--s-3); max-width: 18ch; margin-inline: auto; }
.villas__intro {
  /* V6 — passé d'italique-quote court à paragraphe descriptif :
     le nouveau texte décrit composition, équipements et seul-différenciateur,
     incompatible avec le registre italique gros (lourd visuellement).
     Reste centré et discret comme une introduction de section. */
  margin-top: var(--s-4);
  max-width: 56ch;
  margin-inline: auto;
  color: var(--c-text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.7;
}

.villas__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
}

.card {
  position: relative;
  display: block;
  cursor: pointer;
  isolation: isolate;
}

.card__media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--c-beige);
  margin-bottom: var(--s-3);
  border: 1px solid rgba(200, 193, 184, 0.35);
}
.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.9) contrast(1.02);
  transform: scale(1.0);
  transition: transform 1800ms var(--ease-soft),
              filter 1200ms var(--ease-soft);
}
.card:hover .card__media img { transform: scale(1.04); filter: saturate(0.95) contrast(1.04); }

.card__media::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c-bg);
  z-index: 2;
  transform-origin: top;
  transition: transform 1400ms var(--ease-quiet) var(--reveal-delay, 0ms);
}
.card.is-revealed .card__media::before { transform: scaleY(0); }

.card__num {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.card__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(24px, 1.4vw + 18px, 34px);
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
  margin-top: var(--s-1);
  line-height: 1.15;
}

.card__desc {
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  color: var(--c-text);
  margin-top: var(--s-2);
  line-height: 1.6;
  max-width: 32ch;
}

.card__more {
  margin-top: var(--s-3);
  display: inline-block;
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  position: relative;
  padding-bottom: 4px;
}
.card__more::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  height: 1px;
  width: 24px;
  background: var(--c-graphite);
  transition: width 500ms var(--ease-quiet);
}
.card:hover .card__more::after { width: 100%; }


/* -------------------------------------------------------------------------
   14 · Stats (chiffres-clés)
   ------------------------------------------------------------------------- */
.stats {
  padding: 0 0 calc(var(--section-pad-y) * 0.4);
}
.stats__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-4);
}
.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-2);
  border-left: 1px solid rgba(200, 193, 184, 0.4);
}
.stat:first-child { border-left: none; }

.stat__num {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-stat);
  line-height: 1;
  color: var(--c-graphite);
  letter-spacing: var(--tr-tight);
}
.stat__label {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
}


/* -------------------------------------------------------------------------
   15 · L'engagement
   ------------------------------------------------------------------------- */
.engagement {
  background: var(--c-bg);
  padding: var(--section-pad-y) 0;
}
.engagement .h2 {
  margin-top: var(--s-3);
  margin-bottom: var(--section-h2-mb);
}
.engagement__lead {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(22px, 1.8vw + 14px, 32px);
  line-height: 1.4;
  color: var(--c-graphite);
  margin-bottom: var(--s-7);
  max-width: 48ch;
}
.engagement__cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-beige);
}
.engagement__cols .eyebrow {
  margin-bottom: var(--s-2);
}
.engagement__col-text {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-caption);
  line-height: 1.7;
  color: var(--c-text);
}


/* -------------------------------------------------------------------------
   16 · Footer
   ------------------------------------------------------------------------- */
.footer {
  background: var(--c-bg);
  border-top: 1px solid var(--c-beige);
  padding: var(--s-7) 0 var(--s-4);
  margin-top: 0;
}
.footer__top {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--s-5);
  margin-bottom: var(--s-7);
}
.footer__col h4 {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
  margin-bottom: var(--s-2);
}
.footer__col p, .footer__col a {
  display: block;
  font-size: var(--fs-caption);
  color: var(--c-text);
  line-height: 1.8;
}
.footer__col a:hover { color: var(--c-graphite); }

.footer__logo {
  width: 100px;     /* tighter viewBox: bumped from 64px */
  margin: 0 auto;
  color: var(--c-beige);
}

.footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--c-beige);
  padding-top: var(--s-3);
  margin-top: var(--s-5);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-wide);
  color: var(--c-beige);
}


/* -------------------------------------------------------------------------
   17 · Reveal-on-scroll
   ------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--d-slow) var(--ease-soft),
              transform var(--d-slow) var(--ease-soft);
}
.reveal.is-revealed { opacity: 1; transform: translateY(0); }
.reveal--lift { transform: translateY(48px); }


/* -------------------------------------------------------------------------
   17bis · Dock navigation (floating filets)
   Designed to feel native to the brand language: each link is just a 
   filet, the brand's signature graphic. Hover/active state extends the
   filet and reveals a label — like a quiet promise of progression.
   ------------------------------------------------------------------------- */
.dock {
  position: fixed;
  right: var(--gutter);
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;          /* below nav (50), above content */
  pointer-events: none;  /* rail itself doesn't block clicks */
  opacity: 0;
  transition: opacity 600ms var(--ease-soft);
}
.dock.is-visible { opacity: 1; }

.dock__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.dock__link {
  pointer-events: auto;   /* only links capture clicks */
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 0;          /* enlarge clickable area without visual change */
  text-decoration: none;
  position: relative;
  /* Keep the row fixed-width-from-left so labels don't push content around */
  justify-content: flex-end;
}

.dock__filet {
  display: block;
  height: 1px;
  width: 16px;
  background: var(--c-beige);
  transition: width 500ms var(--ease-quiet),
              background-color 400ms var(--ease-soft);
}

.dock__label {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  opacity: 0;
  transform: translateX(8px);
  transition: opacity 400ms var(--ease-soft),
              transform 500ms var(--ease-soft);
  white-space: nowrap;
  /* Position label so the filet stays anchored on the right */
  position: absolute;
  right: calc(100% + var(--s-2));
  top: 50%;
  transform: translateY(-50%) translateX(8px);
  pointer-events: none;
}

/* Hover: filet extends, label appears */
.dock__link:hover .dock__filet {
  width: 40px;
  background: var(--c-graphite);
}
.dock__link:hover .dock__label {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Active state: filet long and graphite, label always visible */
.dock__link.is-active .dock__filet {
  width: 56px;
  background: var(--c-graphite);
}
.dock__link.is-active .dock__label {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  color: var(--c-graphite);
}

/* On dark sections (hero, dark backgrounds), invert dock colors */
.dock.is-on-dark .dock__filet { background: rgba(242, 239, 232, 0.4); }
.dock.is-on-dark .dock__label { color: var(--c-bg); }
.dock.is-on-dark .dock__link:hover .dock__filet,
.dock.is-on-dark .dock__link.is-active .dock__filet { background: var(--c-bg); }
.dock.is-on-dark .dock__link.is-active .dock__label { color: var(--c-bg); }

/* Hide on small viewports — nav is sufficient there */
@media (max-width: 960px) {
  .dock { display: none; }
}

/* On medium-large but not huge screens, slim the visible width budget */
@media (max-width: 1280px) {
  .dock { right: 24px; }
  .dock__link.is-active .dock__filet { width: 40px; }
  .dock__link:hover .dock__filet { width: 30px; }
}


/* -------------------------------------------------------------------------
   18 · Responsive
   Système d'espacement piloté par --section-pad-y au :root.
   On override la variable à chaque breakpoint et TOUT s'adapte
   automatiquement (grâce au refactor des sections en V5.2).
   ------------------------------------------------------------------------- */

/* Tablet : largeur < 960px */
@media (max-width: 960px) {
  :root {
    --section-pad-y: var(--s-8);          /* 128px */
    --section-head-mb: var(--s-5);        /* 48px */
    --section-h2-mb: var(--s-4);          /* 32px */
  }
  .lieu__grid         { grid-template-columns: 1fr; gap: var(--s-5); }
  .villas__grid       { grid-template-columns: 1fr 1fr; gap: var(--s-4); }
  .footer__top        { grid-template-columns: 1fr 1fr; }
  /* L'art de vivre — go straight to single column on tablet to avoid
     an awkward 2-column / 3rd-orphan layout */
  .art__grid          { grid-template-columns: 1fr; gap: var(--s-6); max-width: 600px; margin-inline: auto; }
  .art__item--offset  { margin-top: 0; }
  .art__media         { aspect-ratio: auto; padding-block: var(--s-3); }
  .stats__grid        { grid-template-columns: 1fr 1fr; gap: var(--s-3); }
  .stat:nth-child(3)  { border-left: none; }
  .engagement__cols   { grid-template-columns: 1fr; gap: var(--s-4); }
  .domaine__legend    { gap: var(--s-3); font-size: 11px; }
  .hotspot            { width: 30px; height: 30px; font-size: 10px; }
  .hotspot--small     { width: 26px; height: 26px; }
  .dock { display: none; }
}

/* Mobile : largeur < 640px */
@media (max-width: 640px) {
  :root {
    --gutter: 20px;
    --section-pad-y: 80px;                /* compact mais aéré */
    --section-head-mb: var(--s-4);        /* 32px */
    --section-h2-mb: var(--s-3);          /* 24px */
    --paragraph-gap: 1.2em;               /* paragraphes légèrement plus serrés */
  }
  .nav__right         { gap: var(--s-3); }
  .nav__link          { display: none; }
  .nav__logo          { width: 100px; }
  .villas__grid       { grid-template-columns: 1fr; }
  .footer__top        { grid-template-columns: 1fr; gap: var(--s-3); }
  .footer__bottom     { flex-direction: column; gap: var(--s-2); text-align: center; }
  /* V10 — le hero mobile est réglé dans la section 07 */

  /* V9 — Le hero mobile utilise désormais sa propre photo
     (01-hero-villa-crepuscule-mobile.jpg, crop portrait 9:16)
     servie via <picture> dans le HTML. Plus besoin de tricher
     le cadrage ici. */
  .lieu__image        { aspect-ratio: 4 / 3; }
  .art__grid          { grid-template-columns: 1fr; gap: var(--s-4); }
  .stats__grid        { grid-template-columns: 1fr 1fr; }
  .hotspot            { width: 24px; height: 24px; font-size: 9px; }
  .hotspot--small     { width: 22px; height: 22px; }
  .hotspot__tip       { font-size: 10px; padding: 6px 8px; }
  .ambient-toggle     { padding: 6px 10px; font-size: 10px; right: var(--gutter); bottom: var(--gutter); }

  /* Section vidéo en mobile :
     On veut que la vidéo soit VISIBLE ENTIÈREMENT (pas de crop).
     - height: auto pour que la section prenne la hauteur naturelle
     - vidéo en object-fit: contain (ratio préservé)
     - titre passe SOUS la vidéo au lieu d'être en overlay
     - overlay caché car le titre n'est plus sur l'image */
  .au-fil {
    height: auto;
    min-height: 0;
    max-height: none;
    background: #1a1a19;
  }
  .au-fil__video {
    position: relative;
    inset: auto;
    width: 100%;
    height: auto;
    object-fit: contain;
    display: block;
  }
  .au-fil__overlay { display: none; }
  .au-fil__content {
    position: relative;
    inset: auto;
    padding: var(--s-5) var(--gutter) var(--s-6);
  }
  .au-fil__title { max-width: 14ch; font-size: clamp(28px, 7vw, 40px); }
  /* Bouton son : repositionné en bas-droite de la VIDÉO pour ne pas
     cacher le contenu visuel important. La vidéo étant en flow naturel
     (position relative), on calcule le bottom par rapport à la section
     entière, en sachant que sous la vidéo il y a le titre. */
  .video-sound {
    /* Aspect-ratio 16:9 sur 100vw donne une hauteur vidéo de 56.25vw.
       On positionne le bouton à -50px depuis le bas de la vidéo, soit
       à 56.25vw - 50px depuis le top de la section. */
    top: calc(56.25vw - 44px);
    bottom: auto;
    right: var(--s-3);
    padding: 6px 10px;
    font-size: 10px;
  }
}


/* -------------------------------------------------------------------------
   20 · Loader d'entrée
   Voile crème plein écran avec logo + filet animés.
   Skip automatique en 2e visite (sessionStorage géré côté script.js).
   Toutes les durées sont contrôlées depuis script.js → CONFIG.loader
   ------------------------------------------------------------------------- */

/* Voile : couvre tout l'écran, fond crème de la marque */
.loader {
  position: fixed;
  inset: 0;
  z-index: 100;                 /* au-dessus de TOUT (nav=50, dock=40) */
  background: var(--c-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  /* La sortie (slide up) est gérée via .loader.is-leaving + transition CSS,
     dont la durée est synchronisée avec CONFIG.loader.exit (script.js). */
  transition: clip-path 600ms var(--ease-quiet);
  clip-path: inset(0% 0% 0% 0%);
}
.loader.is-leaving {
  clip-path: inset(0% 0% 100% 0%);   /* le voile remonte vers le haut */
}
.loader.is-gone {
  display: none;                      /* libère le DOM */
}

/* Conteneur du logo : centré, légèrement étiré pour un beau placement */
.loader__inner {
  position: relative;
  width: min(280px, 60vw);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* SVG du logo : on cache d'abord les lettres (revealed via clip-path)
   et on cache le filet (animé séparément).
   La logique précise des classes is-filet-drawn / is-letters-revealed
   est appliquée par script.js. */
.loader__logo {
  width: 100%;
  height: auto;
  color: var(--c-graphite);
  /* Toutes les paths du logo SAUF la dernière (le filet) sont les lettres.
     Voir bloc ci-dessous pour la logique d'animation. */
}

/* Lettres du logo : initialement masquées par un clip-path qui les cache 
   complètement, puis se révèlent en descendant (effet rideau inversé). */
.loader__logo > use {
  /* On utilise un wrapper trick : le <use> hérite du clip-path 
     défini sur ses paths fils via JavaScript (voir script.js).
     Ici on prépare juste l'opacity de départ. */
}
/* État de départ : lettres invisibles + filet à largeur 0
   Ces états sont reset par script.js qui pilote l'animation via GSAP. */

/* Body bloqué pendant le loader */
body.is-loading {
  overflow: hidden;
  height: 100vh;
}
body.is-loading .nav,
body.is-loading .dock,
body.is-loading .ambient-toggle {
  opacity: 0 !important;
}


/* -------------------------------------------------------------------------
   21 · Curseur custom (luxe discret)
   Halo hairline qui suit le curseur natif (qui reste visible).
   Croît sur les éléments interactifs. Bascule en beige sur fonds sombres.
   Toutes les dimensions/durées sont dans script.js → CONFIG.cursor
   ------------------------------------------------------------------------- */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 14px;
  height: 14px;
  border: 0.5px solid rgba(47, 47, 46, 0.30);   /* graphite à 30% */
  border-radius: 50%;
  pointer-events: none;
  z-index: 95;                  /* sous nav (100 loader / 50 nav) mais au-dessus du contenu */
  /* Centré sur le point que JS lui donne */
  transform: translate(-50%, -50%);
  /* Lissage doux du suivi (le JS pose top/left brut, la transform-transition est CSS) */
  transition: width  200ms var(--ease-soft),
              height 200ms var(--ease-soft),
              border-color 250ms var(--ease-soft),
              opacity 200ms var(--ease-soft);
  opacity: 0;                   /* invisible avant que le curseur ne bouge */
  will-change: transform;
  mix-blend-mode: normal;
}
/* Visible une fois que JS a détecté un mouvement souris */
.cursor.is-active { opacity: 1; }

/* Variante grandie quand on est sur un élément interactif */
.cursor.is-hover {
  width: 36px;
  height: 36px;
  border-color: rgba(47, 47, 46, 0.50);
}

/* Variante claire (sur fonds sombres : hero, vidéo, interstitiel) */
.cursor.is-on-dark {
  border-color: rgba(242, 239, 232, 0.45);
}
.cursor.is-on-dark.is-hover {
  border-color: rgba(242, 239, 232, 0.75);
}

/* Sur tactile et reduced-motion → désactivé entièrement (caché par classe JS) */
.cursor.is-disabled { display: none; }


/* -------------------------------------------------------------------------
   22 · GSAP — révélation par lignes des H2 (data-anim="line-reveal")
   Le JS scinde le H2 en lignes via GSAP, chacune dans un masque qui se lève.
   Les états initiaux sont posés ici pour éviter le flash (FOUC).
   ------------------------------------------------------------------------- */

/* H2 ciblés : on désactive l'animation .reveal CSS héritée pour eux,
   GSAP prend le relais. */
[data-anim="line-reveal"] {
  opacity: 1;             /* on annule l'opacity:0 du .reveal */
  transform: none;        /* on annule le translateY du .reveal */
}

/* Titre en attente de son apparition (script.js § 6) : masqué, lignes mesurées au dernier moment */
.titre-attente { visibility: hidden; }

/* Wrapper de ligne créé par JS : masque qui clip vers le haut */
.line-mask {
  display: block;
  overflow: hidden;
  /* Hauteur de ligne avec un poil de souffle pour les descendantes (g, p, j) */
  padding-bottom: 0.06em;
  margin-bottom: -0.06em;
}

/* Ligne intérieure : translatée vers le bas au départ, GSAP la remonte */
.line-inner {
  display: block;
  /* État de départ posé en JS via gsap.set() ; rien ici. */
}


/* -------------------------------------------------------------------------
   23 · Hotspots — état initial pour animation Fibonacci au scroll
   Les hotspots démarrent invisibles ; GSAP les anime un par un (V01→V11).
   Le pulse ring du ::before ne démarre qu'après l'apparition (classe is-revealed).
   ------------------------------------------------------------------------- */
.domaine .hotspot {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.6);
  /* Le transform original (translate -50% -50%) est posé sur les hotspots
     via le CSS de la section 12. On le préserve dans l'animation. */
}
.domaine .hotspot.is-revealed {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
/* Le pulse ne se déclenche qu'une fois la révélation faite */
.domaine .hotspot::before { animation: none; opacity: 0; }
.domaine .hotspot.is-revealed::before {
  animation: hotspot-pulse 2.6s ease-out infinite;
  opacity: 1;
  transition: opacity 400ms var(--ease-soft);
}



/* -------------------------------------------------------------------------
   24 · Burger menu mobile (V5.2)
   - Trigger : mot "Menu" en caps Inter, visible uniquement < 640px
   - Panneau : plein écran crème qui descend depuis le haut (clip-path)
   - Liens : Cormorant Garamond en grand, stagger d'apparition
   - Fermeture : "Fermer" en bas, touche Échap, clic sur un lien, swipe
   ------------------------------------------------------------------------- */

/* Bouton trigger — caché par défaut (desktop), visible en mobile uniquement */
.nav__burger {
  display: none;
  background: none;
  border: 0;
  padding: 8px 4px;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 600ms var(--ease-soft) 200ms,
              transform 600ms var(--ease-soft) 200ms,
              color 300ms var(--ease-soft);
}
body.is-loaded .nav__burger { opacity: 1; transform: translateY(0); }
/* Sur le hero (avant scroll), texte clair. Après scroll, graphite. */
.nav:not(.is-scrolled) .nav__burger { color: var(--c-bg); }
.nav.is-scrolled .nav__burger { color: var(--c-graphite); }

/* État ouvert : on cache visuellement le bouton (le panneau a son propre "Fermer") */
.nav__burger[aria-expanded="true"] { opacity: 0; pointer-events: none; }


/* Panneau plein écran — caché par défaut */
.menu-panel {
  position: fixed;
  inset: 0;
  z-index: 90;            /* au-dessus de la nav (50) et du dock (40), sous le loader (100) */
  background: var(--c-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--s-7) var(--gutter);
  pointer-events: none;
  /* Animation : clip-path qui descend depuis le haut */
  clip-path: inset(0 0 100% 0);
  transition: clip-path 700ms var(--ease-quiet);
}
.menu-panel.is-open {
  clip-path: inset(0 0 0% 0);
  pointer-events: auto;
}

/* Liste des liens */
.menu-panel__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  text-align: center;
}
.menu-panel__link {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(32px, 7vw, 48px);
  line-height: 1.1;
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
  text-decoration: none;
  /* Apparition au stagger via JS quand le panneau s'ouvre */
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 600ms var(--ease-soft),
              transform 600ms var(--ease-soft);
}
.menu-panel.is-open .menu-panel__link {
  opacity: 1;
  transform: translateY(0);
}
/* Cascade : chaque lien apparaît avec un délai progressif */
.menu-panel.is-open .menu-panel__list li:nth-child(1) .menu-panel__link { transition-delay: 150ms; }
.menu-panel.is-open .menu-panel__list li:nth-child(2) .menu-panel__link { transition-delay: 230ms; }
.menu-panel.is-open .menu-panel__list li:nth-child(3) .menu-panel__link { transition-delay: 310ms; }
.menu-panel.is-open .menu-panel__list li:nth-child(4) .menu-panel__link { transition-delay: 390ms; }
.menu-panel.is-open .menu-panel__list li:nth-child(5) .menu-panel__link { transition-delay: 470ms; }
.menu-panel.is-open .menu-panel__list li:nth-child(6) .menu-panel__link { transition-delay: 550ms; }
.menu-panel.is-open .menu-panel__list li:nth-child(7) .menu-panel__link { transition-delay: 630ms; }

/* Sélecteur de langue : sous les liens, plus discret + bien centré */
.menu-panel__nav {
  text-align: center;        /* centre le .menu-panel__lang qui est inline-flex */
  width: 100%;
}
.menu-panel__lang {
  margin-top: var(--s-6);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text);
  display: inline-flex;
  gap: var(--s-2);
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 600ms var(--ease-soft) 720ms;
}
.menu-panel__lang .is-active { color: var(--c-graphite); font-weight: 600; }
.menu-panel__lang a { color: var(--c-text); }
.menu-panel.is-open .menu-panel__lang { opacity: 1; }

/* Bouton "Fermer" en bas */
.menu-panel__close {
  position: absolute;
  bottom: var(--s-5);
  left: 50%;
  transform: translateX(-50%);
  background: none;
  border: 0;
  padding: var(--s-2) var(--s-3);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
  opacity: 0;
  transition: opacity 500ms var(--ease-soft) 800ms,
              color 200ms var(--ease-soft);
}
.menu-panel.is-open .menu-panel__close { opacity: 1; }
.menu-panel__close:hover { color: var(--c-graphite); }
/* Petit filet sous le mot "Fermer" — signature graphique */
.menu-panel__close::after {
  content: '';
  display: block;
  width: 24px;
  height: 1px;
  background: currentColor;
  margin: 6px auto 0;
}

/* Active le burger uniquement en mobile */
@media (max-width: 640px) {
  .nav__burger { display: inline-block; }
  /* Cacher la nav__right (lang) en mobile pour éviter la duplication
     avec le sélecteur lang dans le panneau menu */
  .nav__right .lang { display: none; }
  /* Bloquer le scroll du body quand le menu est ouvert */
  body.menu-open { overflow: hidden; }
}



/* =========================================================================
   PAGES VILLA  (villa-exception.html, villas-principales.html, villas-intimistes.html)
   Toutes les sections spécifiques aux pages typologie sont ici, dans l'ordre
   d'apparition dans le DOM :
     1. .villa-hero       — hero photo + titre typologie
     2. .villa-composition — coupe horizontale pinnée 3D (layer cross-fade)
     3. .villa-character  — manifeste + chiffres clés en filet
     4. .visite           — la visite pièce par pièce (§ 27, plus bas)
     5. .villa-place      — mini-aérienne + lien retour domaine
     6. .villa-others     — 2 cards autres typologies
     7. .villa-cta        — bloc CTA "demander une présentation"
   ========================================================================= */


/* -------------------------------------------------------------------------
   1 · Villa hero — variation du pattern .hero, sans logo géant.
   ------------------------------------------------------------------------- */
.villa-hero {
  position: relative;
  min-height: 100svh;
  width: 100%;
  overflow: hidden;
  color: var(--c-bg);
}
.villa-hero__media {
  position: absolute;
  inset: 0;
  background-color: var(--c-graphite);
  overflow: hidden;
  /* 26/09/2026 : plus de filtre ici, l’étalonnage est dans les fichiers (.claude/photos) */
  transform: scale(1.04);
  opacity: 0;
  transition: opacity 1800ms var(--ease-soft),
              transform 6000ms var(--ease-soft);
}
.villa-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
}
body.is-loaded .villa-hero__media { opacity: 1; transform: scale(1); }
/* Voile graphite : lisibilité de la barre (haut) et du titre (bas). Réglé photo par
   photo dans chaque page : style="--voile-haut: … ; --voile-bas: …" sur .villa-hero */
.villa-hero { --voile-haut: 0.36; --voile-bas: 0.74; }
.villa-hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgb(47 47 46 / var(--voile-haut)) 0%,
    rgb(47 47 46 / 0) 24%,
    rgb(47 47 46 / 0) 46%,
    rgb(47 47 46 / var(--voile-bas)) 100%);
}
.villa-hero__content {
  position: relative;
  z-index: 2;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--s-7) var(--gutter) var(--s-6);
  max-width: var(--container);
  margin: 0 auto;
}
.villa-hero__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-bg);
  margin-bottom: var(--s-4);
  opacity: 0;
  transform: translateY(20px);
}
.villa-hero__eyebrow .filet-grow { background: var(--c-bg); }
.villa-hero__eyebrow.is-revealed {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 1000ms var(--ease-soft) 420ms,
              transform 1200ms var(--ease-soft) 420ms;
}
.villa-hero__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(48px, 6.5vw + 16px, 110px);
  letter-spacing: var(--tr-tight);
  line-height: 0.96;
  color: var(--c-bg);
  max-width: 18ch;
  margin-bottom: var(--s-4);
}
.villa-hero__title .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 1100ms var(--ease-quiet),
              transform 1100ms var(--ease-quiet);
}
.villa-hero__title.is-revealed .word {
  opacity: 1;
  transform: translateY(0);
  transition-delay: calc(520ms + var(--i, 0) * 110ms);
}
.villa-hero__subtitle {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: var(--fs-quote);
  line-height: 1.4;
  color: var(--c-bg);
  opacity: 0;
  transform: translateY(20px);
  max-width: 32ch;
}
.villa-hero__subtitle.is-revealed {
  opacity: 0.95;
  transform: translateY(0);
  transition: opacity 1200ms var(--ease-soft) 1300ms,
              transform 1400ms var(--ease-soft) 1300ms;
}


/* -------------------------------------------------------------------------
   2 · Villa composition — coupe horizontale 3D pinnée
   --------------------------------------------------------------------------
   Mécanique : la section est pinnée par ScrollTrigger sur 3× la hauteur
   du viewport. Pendant ce pin, 3 layers (étage, RDC, sous-sol) s'enchaînent
   en cross-fade selon la progression du scroll.
   Mobile et reduced-motion : pas de pin — les 3 layers s'empilent
   verticalement pour rester accessibles.
   ------------------------------------------------------------------------- */
.villa-composition {
  position: relative;
  background: var(--c-bg);
}
/* Section désactivée (attribut hidden) en attendant les plans du 3Diste, 26/09/2026 */
.villa-composition[hidden] { display: none !important; }
.villa-composition__stage {
  position: relative;
  height: 100svh;
  width: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.villa-composition__head {
  padding: calc(var(--s-7) + var(--s-2)) var(--gutter) var(--s-3);
  max-width: var(--container);
  margin: 0 auto;
  width: 100%;
  flex-shrink: 0;
}
.villa-composition__head .h2 {
  margin-top: var(--s-2);
  max-width: 22ch;
}
.villa-composition__layers {
  position: relative;
  flex: 1;
  width: 100%;
  overflow: hidden;
}
.villa-composition__layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 700ms var(--ease-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}
.villa-composition__layer.is-active { opacity: 1; }

.villa-composition__layer img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: saturate(0.95);
}

/* Indicateur de progression : 3 chiffres en filet à droite */
.villa-composition__indicator {
  position: absolute;
  right: var(--gutter);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  z-index: 3;
  pointer-events: none;
}
.villa-composition__step {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text);
  opacity: 0.4;
  transition: opacity 500ms var(--ease-soft), color 500ms var(--ease-soft);
}
.villa-composition__step::before {
  content: '';
  display: inline-block;
  width: 24px;
  height: 1px;
  background: var(--c-text);
  transition: width 500ms var(--ease-soft), background 500ms var(--ease-soft);
}
.villa-composition__step.is-active {
  opacity: 1;
  color: var(--c-graphite);
}
.villa-composition__step.is-active::before {
  width: 56px;
  background: var(--c-graphite);
}

/* Hint d'interaction (apparaît à l'entrée du pin, disparaît au scroll) */
.villa-composition__hint {
  position: absolute;
  left: 50%;
  bottom: var(--s-4);
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text);
  opacity: 0;
  transition: opacity 600ms var(--ease-soft);
  z-index: 3;
}
.villa-composition__hint.is-visible { opacity: 0.7; }
.villa-composition__hint::after {
  content: '';
  display: inline-block;
  width: 1px;
  height: 22px;
  background: var(--c-text);
  animation: villa-hint-pulse 2s var(--ease-soft) infinite;
}
@keyframes villa-hint-pulse {
  0%, 100% { transform: translateY(0); opacity: 1; }
  50%      { transform: translateY(6px); opacity: 0.4; }
}


/* -------------------------------------------------------------------------
   3 · Villa character — manifeste typologie + chiffres clés inline
   ------------------------------------------------------------------------- */
.villa-character {
  padding: var(--section-pad-y) 0;
  background: var(--c-bg);
}
.villa-character__inner {
  max-width: var(--container-narrow);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.villa-character__head {
  margin-bottom: var(--section-h2-mb);
}
.villa-character__head .h2 {
  margin-top: var(--s-3);
  max-width: 20ch;
}
.villa-character__lead {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: var(--fs-quote);
  line-height: 1.4;
  color: var(--c-text-strong);
  margin-bottom: var(--s-5);
  max-width: 38ch;
}
.villa-character__body p {
  margin-bottom: var(--paragraph-gap);
  max-width: 60ch;
}
.villa-character__body p:last-child { margin-bottom: 0; }

/* Chiffres clés en filet, inline, séparés par des filets verticaux */
.villa-character__facts {
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(200, 193, 184, 0.5);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-3);
}
.villa-character__fact {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}
.villa-character__fact-num {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(22px, 1.4vw + 16px, 32px);
  letter-spacing: var(--tr-snug);
  line-height: 1;
  color: var(--c-graphite);
}
.villa-character__fact-label {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text);
}


/* -------------------------------------------------------------------------
   5 · Villa place — mini-aérienne + retour vers home
   ------------------------------------------------------------------------- */
.villa-place {
  padding: var(--section-pad-y) 0;
  background: var(--c-bg);
}
.villa-place__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: var(--s-6);
  align-items: center;
}
.villa-place__text {
  max-width: 38ch;
}
.villa-place__text .h2 {
  margin-top: var(--s-3);
  margin-bottom: var(--s-4);
  max-width: 18ch;
}
.villa-place__text p {
  margin-bottom: var(--s-4);
}
.villa-place__back {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  text-decoration: none;
  position: relative;
  padding-bottom: 4px;
}
.villa-place__back::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  height: 1px;
  width: 24px;
  background: var(--c-graphite);
  transition: width 500ms var(--ease-quiet);
}
.villa-place__back:hover::after { width: 100%; }
.villa-place__map {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--c-beige);
  border: 1px solid rgba(200, 193, 184, 0.35);
}
.villa-place__map img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.85) contrast(0.95) brightness(1.02);
}

/* Hotspots de typologie sur la mini-aérienne — points en olive */
.villa-place__hotspot {
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--c-olive);
  border: 2px solid var(--c-bg);
  transform: translate(-50%, -50%);
  box-shadow: 0 0 0 3px rgba(111, 122, 106, 0.20);
}
.villa-place__hotspot--small {
  width: 12px;
  height: 12px;
  box-shadow: 0 0 0 2px rgba(111, 122, 106, 0.20);
}
/* 26/09/2026 : comme sur la carte de l’accueil, les points apparaissent l’un après
   l’autre quand la carte se découvre, puis un anneau pulse autour de chacun. */
.villa-place__hotspot {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.2);
  transition: opacity 600ms var(--ease-soft) calc(700ms + var(--i, 0) * 160ms),
              transform 800ms var(--ease-soft) calc(700ms + var(--i, 0) * 160ms);
}
.villa-place__map.is-revealed .villa-place__hotspot {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.villa-place__hotspot::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1.5px solid rgba(242, 239, 232, 0.9);
  opacity: 0;
  pointer-events: none;
}
.villa-place__map.is-revealed .villa-place__hotspot::before {
  animation: hotspot-pulse 2.6s ease-out calc(1500ms + var(--i, 0) * 160ms) infinite;
}
.villa-place__hotspot:nth-of-type(2) { --i: 1; }
.villa-place__hotspot:nth-of-type(3) { --i: 2; }
.villa-place__hotspot:nth-of-type(4) { --i: 3; }
.villa-place__hotspot:nth-of-type(5) { --i: 4; }
.villa-place__hotspot:nth-of-type(6) { --i: 5; }
.villa-place__hotspot:nth-of-type(7) { --i: 6; }
.villa-place__hotspot:nth-of-type(8) { --i: 7; }
.villa-place__hotspot:nth-of-type(9) { --i: 8; }
@media (prefers-reduced-motion: reduce) {
  .villa-place__hotspot { opacity: 1; transform: translate(-50%, -50%); transition: none; }
  .villa-place__hotspot::before { display: none; }
}
.villa-place__hotspot::after {
  content: attr(data-villa);
  position: absolute;
  top: 50%;
  left: calc(100% + 10px);
  transform: translateY(-50%);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-bg);
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}


/* -------------------------------------------------------------------------
   6 · Villa others — 2 cards des autres typologies (réutilise .card)
   ------------------------------------------------------------------------- */
.villa-others {
  padding: var(--section-pad-y) 0;
  background: var(--c-bg);
}
.villa-others__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.villa-others__head {
  margin-bottom: var(--section-head-mb);
  max-width: 720px;
}
.villa-others__head .h2 {
  margin-top: var(--s-3);
  max-width: 20ch;
}
.villa-others__intro {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--c-text);
  max-width: 50ch;
}
.villa-others__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-5);
  align-items: start;
}


/* -------------------------------------------------------------------------
   7 · Villa CTA — bloc demande de présentation
   ------------------------------------------------------------------------- */
.villa-cta {
  padding: var(--section-pad-y) 0;
  background: var(--c-graphite);
  color: var(--c-bg);
}
.villa-cta__inner {
  max-width: 880px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  text-align: center;
}
.villa-cta__eyebrow {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-beige);
  margin-bottom: var(--s-3);
}
.villa-cta__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-h2);
  letter-spacing: var(--tr-snug);
  line-height: 1.1;
  color: var(--c-bg);
  margin-bottom: var(--s-4);
  max-width: 22ch;
  margin-left: auto;
  margin-right: auto;
}
.villa-cta__lead {
  color: var(--c-beige);
  margin-bottom: var(--s-6);
  max-width: 50ch;
  margin-left: auto;
  margin-right: auto;
}
.villa-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: center;
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
}
.villa-cta__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-bg);
  background: transparent;
  border: 1px solid var(--c-bg);
  text-decoration: none;
  transition: background 500ms var(--ease-soft), color 500ms var(--ease-soft);
}
.villa-cta__btn:hover {
  background: var(--c-bg);
  color: var(--c-graphite);
}
.villa-cta__btn--ghost {
  border-color: var(--c-beige);
  color: var(--c-beige);
}
.villa-cta__btn--ghost:hover {
  background: var(--c-beige);
  color: var(--c-graphite);
}


/* -------------------------------------------------------------------------
   8 · Responsive pages villa
   ------------------------------------------------------------------------- */
@media (max-width: 960px) {
  .villa-character__facts { grid-template-columns: repeat(2, 1fr); gap: var(--s-4); }
  .villa-place__inner { grid-template-columns: 1fr; gap: var(--s-5); }
  .villa-others__grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  /* === Coupe villa pinnée sur mobile ===
     Le pin reste actif (mêmes Apple/Linear/Stripe), mais on adapte le layout :
     - head plus compact pour libérer de la place pour la coupe
     - indicateur 01/02/03 repositionné en haut (pas à droite, pas assez de place)
     - hint masqué (pouce sur le scroll = pas besoin d'indication) */
  .villa-composition__head {
    padding: var(--s-6) var(--gutter) var(--s-2);
  }
  .villa-composition__head .h2 {
    font-size: clamp(28px, 8vw, 38px);
  }
  .villa-composition__indicator {
    position: absolute;
    top: var(--s-3);
    right: var(--gutter);
    transform: none;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--s-2);
    justify-content: flex-end;
    max-width: 60%;
  }
  .villa-composition__step {
    font-size: 9px;
    letter-spacing: 0.12em;
  }
  .villa-composition__step::before { width: 14px; }
  .villa-composition__step.is-active::before { width: 28px; }
  /* Le step inactif n'affiche que son numéro pour économiser la place */
  .villa-composition__step:not(.is-active) {
    font-size: 0;
  }
  .villa-composition__step:not(.is-active)::after {
    content: attr(data-num);
    font-size: 9px;
  }

  /* Quand l'utilisateur a explicitement reduced-motion : fallback empilé */
  .villa-composition--unpinned .villa-composition__stage {
    height: auto;
  }
  .villa-composition--unpinned .villa-composition__layers {
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
    aspect-ratio: auto;
  }
  .villa-composition--unpinned .villa-composition__layer {
    position: relative;
    inset: auto;
    opacity: 1;
    aspect-ratio: 16 / 10;
  }
  .villa-composition--unpinned .villa-composition__indicator,
  .villa-composition--unpinned .villa-composition__hint {
    display: none;
  }

  .villa-hero__content { padding: var(--s-6) var(--gutter) var(--s-5); }
  .villa-cta__actions { flex-direction: column; align-items: stretch; }
}


@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal, .hero__title .word, .hero__eyebrow, .hero__accroche,
  .hero__scroll, .hero__logo, .nav__link, .lang {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero__media { opacity: 1 !important; transform: scale(1) !important; }
  .lieu__image::before, .card__media::before, .art__media::before { transform: scaleY(0) !important; }
  .hotspot::before { animation: none !important; }

  /* Loader : disparition instantanée */
  .loader { display: none !important; }
  body.is-loading { overflow: auto; height: auto; }

  /* Curseur custom : caché */
  .cursor { display: none !important; }

  /* H2 line-reveal : tout visible direct */
  .line-inner { transform: none !important; opacity: 1 !important; }

  /* Hotspots : tous visibles direct, pas d'animation */
  .domaine .hotspot { opacity: 1 !important; transform: translate(-50%, -50%) scale(1) !important; }
  .domaine .hotspot::before { opacity: 1 !important; }

  /* Pages villa : on désactive le pin et on rend tous les layers visibles */
  .villa-hero__title .word,
  .villa-hero__eyebrow,
  .villa-hero__subtitle {
    opacity: 1 !important;
    transform: none !important;
  }
  .villa-hero__media { opacity: 1 !important; transform: scale(1) !important; }
  .villa-composition__stage { height: auto !important; overflow: visible !important; }
  .villa-composition__layers {
    display: flex !important;
    flex-direction: column !important;
    gap: var(--s-4) !important;
  }
  .villa-composition__layer {
    position: relative !important;
    inset: auto !important;
    opacity: 1 !important;
    aspect-ratio: 16 / 10 !important;
  }
  .villa-composition__indicator,
  .villa-composition__hint { display: none !important; }
}


/* =========================================================================
   V9 — NOUVEAUX MODULES
   1. Rideau de révélation des médias (généralisation du langage des cards)
   2. Voile de transition de page
   3. Lien EN désactivé (en attendant la version anglaise)
   4. Parallaxe : préparation des conteneurs
   5. Stats : état initial des compteurs
   ========================================================================= */

/* -------------------------------------------------------------------------
   V9·1 — RIDEAU DE RÉVÉLATION
   Les cards avaient déjà un voile crème qui se lève (.card__media::before).
   On étend ce même langage à TOUS les médias du site : l'image se découvre
   par un rideau couleur de fond qui glisse vers le haut, pendant que la
   photo elle-même se "pose" (léger dé-zoom 1.05 → 1).
   Le déclenchement reste le système .is-revealed existant (zéro JS ajouté).
   ------------------------------------------------------------------------- */
.lieu__image::after,
.art__media-inner::after,
.villa-place__map::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c-bg);
  z-index: 2;
  transform-origin: top;
  transition: transform 1300ms var(--ease-quiet) var(--reveal-delay, 0ms);
  pointer-events: none;
}
.lieu__image.is-revealed::after,
.art__media.is-revealed .art__media-inner::after,
.villa-place__map.is-revealed::after {
  transform: scaleY(0);
}

/* La photo se pose : dé-zoom discret synchronisé avec le rideau */
.lieu__image img,
.art__media-inner img,
.card__media img,
.villa-place__map img {
  transform: scale(1.05);
}
.lieu__image.is-revealed img,
.art__media.is-revealed .art__media-inner img,
.card.is-revealed .card__media img,
.villa-place__map.is-revealed img {
  transform: scale(1.0);
  transition: transform 1600ms var(--ease-quiet) var(--reveal-delay, 0ms),
              filter 1200ms var(--ease-soft);
}
/* Le hover des cards garde la main après la révélation */
.card.is-revealed:hover .card__media img { transform: scale(1.04); }

/* Sur ces conteneurs, l'ancien reveal translateY+fade est remplacé par
   le rideau : on neutralise le déplacement pour éviter le double effet. */
.lieu__image, .art__media, .villa-place__map {
  opacity: 1;
  transform: none;
}

/* Reduced motion : tout apparaît sans rideau ni zoom */
@media (prefers-reduced-motion: reduce) {
  .lieu__image::after, .art__media-inner::after,
  .villa-place__map::after,
  .card__media::before { display: none; }
  .lieu__image img, .art__media-inner img, .card__media img, .villa-place__map img { transform: none; }
}


/* -------------------------------------------------------------------------
   V9·2 — VOILE DE TRANSITION DE PAGE
   Au clic vers une autre page du site, un voile crème descend (350 ms),
   puis la navigation s'effectue. À l'arrivée, le loader (déjà en mode
   "quick fade" dès la 2e page grâce au sessionStorage) complète la boucle.
   Résultat : on passe de page en page sans jamais voir de blanc brut.
   ------------------------------------------------------------------------- */
.page-veil {
  position: fixed;
  inset: 0;
  background: var(--c-bg);
  z-index: 9998;                /* juste sous le loader (9999) */
  transform: scaleY(0);
  transform-origin: bottom;     /* le voile monte depuis le bas */
  pointer-events: none;
}
.page-veil.is-active {
  transform: scaleY(1);
  transition: transform 380ms var(--ease-quiet);
}


/* -------------------------------------------------------------------------
   V9·3 — LIEN EN DÉSACTIVÉ
   La version anglaise n'existe pas encore : on évite le 404 en montrant
   "EN" atténué, non cliquable, avec une infobulle native (title).
   ------------------------------------------------------------------------- */
.lang .lang__soon,
.menu-panel__lang .lang__soon {
  opacity: 0.35;
  cursor: default;
}


/* -------------------------------------------------------------------------
   V9·4 — PARALLAXE (préparation des conteneurs)
   Le déplacement est piloté par GSAP/ScrollTrigger (script.js → CONFIG.parallax).
   Ici : on donne du débord vertical aux images pour qu'elles puissent
   glisser dans leur cadre sans laisser de bord vide.
   ------------------------------------------------------------------------- */
.lieu__image img {
  height: 114%;
  top: -7%;
  position: relative;
}
.interstitial__media img {
  height: 124%;
  top: -12%;
  position: relative;
  object-fit: cover;
  width: 100%;
}
/* Mobile : la parallaxe est désactivée (script.js) — on retire le débord */
@media (max-width: 640px) {
  .lieu__image img { height: 100%; top: 0; }
  .interstitial__media img { height: 100%; top: 0; }
}


/* -------------------------------------------------------------------------
   V9·5 — STATS / COMPTEURS
   Les chiffres porteurs de data-count démarrent le compte à l'entrée
   dans le viewport (script.js → initStatsCounter). Pas de style d'état
   nécessaire : on fige simplement la largeur pour éviter tout tressautement
   de mise en page pendant la montée des chiffres.
   ------------------------------------------------------------------------- */
.stat__num [data-count],
.stat__num[data-count] {
  /* V10 : « lining » obligatoire, sinon Cormorant repasse en elzévirien */
  font-variant-numeric: lining-nums tabular-nums;
}


/* =========================================================================
   V9·6 — LA DESCENTE (refonte de la composition pinnée)
   Le JS (initVillaComposition) pilote opacité/position/échelle en continu.
   Ici : neutralisation des transitions CSS en mode continu, libellé de
   niveau, filet de progression, et refonte du layout mobile.
   ========================================================================= */

/* Mode continu : les transitions CSS d'opacité laissent la main au scrub.
   (Sinon CSS et GSAP se disputent chaque frame → saccades.) */
.villa-composition--continuous .villa-composition__layer {
  transition: none;
  will-change: opacity, transform;
}

/* ---- Libellé de niveau (généré par le JS)
   Cormorant italic, sous le plan. Affiché sur MOBILE, où il remplit
   l'espace avec du sens au lieu du vide de la V8.
   Desktop : masqué tant que les placeholders portent leur propre titre —
   à activer plus tard en passant display:block ci-dessous. */
.villa-composition__level-label {
  display: none;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(26px, 7vw, 34px);
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
  text-align: center;
  opacity: 0.9;
  transition: opacity 180ms var(--ease-soft);
  pointer-events: none;
}
.villa-composition__level-label.is-switching { opacity: 0; }

/* ---- Filet de progression (signature de marque)
   Desktop : trait vertical 1px, bord droit, se remplit du haut vers le bas.
   Mobile : trait horizontal sous l'en-tête. */
.villa-composition__progress {
  position: absolute;
  z-index: 3;
  background: var(--c-graphite);
  opacity: 0.45;
  pointer-events: none;
  /* Desktop : vertical */
  right: calc(var(--gutter) / 2);
  top: 18%;
  height: 64%;
  width: 1px;
  transform-origin: top;
  transform: scaleY(0);
}

/* ---- MOBILE : refonte du layout de la scène
   Problèmes V8 mesurés : en-tête sous la nav fixe, indicateur qui
   chevauche le titre, plan minuscule perdu dans ~60% de vide.
   V9 : structure verticale claire —
   [dégagement nav] en-tête compact / indicateur en ligne / filet
   de progression / plan pleine largeur / libellé du niveau. */
@media (max-width: 640px) {
  .villa-composition__stage {
    /* Dégagement de la nav fixe pendant le pin */
    padding-top: 64px;
  }
  .villa-composition__head {
    padding: var(--s-3) var(--gutter) var(--s-2);
  }
  /* L'indicateur quitte l'absolu : il prend sa place dans le flux,
     en ligne, entre l'en-tête et le plan. Tous les niveaux lisibles. */
  .villa-composition__indicator {
    position: static;
    transform: none;
    flex-direction: row;
    justify-content: center;
    gap: var(--s-3);
    max-width: none;
    padding: 0 var(--gutter) var(--s-2);
    flex-wrap: nowrap;
  }
  .villa-composition__step { white-space: nowrap; }
  /* Le filet de progression devient horizontal, sous l'indicateur */
  .villa-composition__progress {
    right: auto;
    top: auto;
    position: relative;
    display: block;
    width: calc(100% - 2 * var(--gutter));
    height: 1px;
    margin: 0 auto var(--s-2);
    transform-origin: left;
    transform: scaleX(0);
  }
  /* Le plan : pleine largeur, hauteur naturelle, centré dans l'espace restant */
  .villa-composition__layer {
    align-items: center;
    padding: 0 var(--s-2);
  }
  .villa-composition__layer img {
    width: 100%;
    max-width: none;
    height: auto;
    max-height: 52svh;
    object-fit: contain;
  }
  /* Le libellé du niveau prend l'espace bas (au lieu du vide V8) */
  .villa-composition__level-label {
    display: block;
    flex-shrink: 0;
    padding: var(--s-3) var(--gutter) var(--s-2);
  }
  /* Ordre vertical de la scène mobile (indépendant de l'ordre DOM) :
     en-tête → indicateur → filet de progression → plan → libellé.
     Les margin:auto centrent ce groupe dans l'espace sous l'en-tête,
     au lieu de laisser deux poches de vide mal réparties (défaut V8). */
  .villa-composition__head      { order: 0; }
  .villa-composition__indicator { order: 1; margin-top: auto; }
  .villa-composition__progress  { order: 2; }
  .villa-composition__layers    {
    order: 3;
    /* Hauteur portée par le ratio (les coupes sont en 16:9).
       Si tes vraies 3D ont un autre ratio, ajuste ici : l'image
       reste en object-fit:contain, donc jamais rognée. */
    flex: 0 0 auto;
    aspect-ratio: 16 / 9;
  }
  .villa-composition__level-label { order: 4; margin-bottom: auto; }
  /* Le hint "Continuez à dérouler" reste inutile au pouce */
  .villa-composition__hint { display: none; }
}

/* Reduced-motion / fallback empilé : ni libellé ni filet de progression */
.villa-composition--unpinned .villa-composition__level-label,
.villa-composition--unpinned .villa-composition__progress {
  display: none;
}


/* =========================================================================
   V10 — NOUVEAUX MODULES (25/09/2026)
   1. Nav sur hero clair
   2. Rythme des chapitres : le filet sépare les sections (charte)
   3. Légendes « perspective d’étude » (règle 06_design_print)
   4. Le trait d’étude posé sur la page (wireframes sans fond)
   5. Le domaine : en-tête aligné, carte recadrée, repères olive
   6. Les villas : surfaces, en-tête aligné
   7. Chiffres-clés
   8. L’engagement
   9. Boutons (WhatsApp, e-mail) — charte, jamais de vert
  10. Footer « 4e de couverture » (contact)
  11. Dock : plus de chevauchement
  12. Menu mobile : contact direct
  13. Pages villa : carte juste, contact unique
   ========================================================================= */

/* ---- 1 · Nav sur hero clair (home) ---------------------------------- */
.nav--light-hero:not(.is-scrolled) { color: var(--c-graphite); }
.nav--light-hero:not(.is-scrolled) .nav__burger { color: var(--c-graphite); }
.nav--light-hero:not(.is-scrolled) .nav__link:hover { color: var(--c-muted); }


/* ---- 2 · Chapitres ---------------------------------------------------
   Chaque chapitre numéroté s’ouvre sur un filet pleine largeur qui se
   trace de gauche à droite à l’entrée dans l’écran, puis l’eyebrow.
   Le filet ne sépare pas « deux boîtes » : il ouvre une page, comme
   dans le catalogue. Les moments plein cadre (vidéo, carte, dessin)
   font eux-mêmes la césure. */
.chapter-rule {
  display: block;
  width: 100%;
  height: 1px;
  background: var(--c-beige);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1800ms var(--ease-quiet);
  margin-bottom: clamp(56px, 6vw, 88px);
}
.chapter-rule.is-revealed { transform: scaleX(1); }

.art__head,
.villas__head,
.domaine__head { text-align: left; }
.villas__head .h2,
.domaine__head .h2 { margin-inline: 0; }
.villas__intro,
.domaine__intro { margin-inline: 0; }
.domaine__intro { max-width: 40ch; }


/* En-têtes de chapitre en deux colonnes : titre à gauche, texte à droite,
   calé sur la dernière ligne du titre. Mieux qu’un bloc étroit à gauche
   et 60 % de vide à droite. */
@media (min-width: 961px) {
  .art__head,
  .villas__head,
  .domaine__head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(48px, 6vw, 120px);
    align-items: end;
    max-width: none;
  }
  .art__head > .eyebrow,
  .villas__head > .eyebrow,
  .domaine__head > .eyebrow { grid-column: 1; grid-row: 1; justify-self: start; }
  .art__head > .h2,
  .villas__head > .h2,
  .domaine__head > .h2 { grid-column: 1; grid-row: 2; margin-bottom: 0; }
  .art__intro,
  .villas__intro,
  .domaine__intro { grid-column: 2; grid-row: 2; margin: 0; max-width: 46ch; justify-self: start; }
  .domaine__head > .chapter-rule { grid-column: 1 / -1; grid-row: 1; }
  .domaine__head > .eyebrow { grid-row: 2; }
  .domaine__head > .h2 { grid-row: 3; }
  .domaine__intro { grid-row: 3; }
  .art__intro { font-size: clamp(20px, 1vw + 12px, 26px); }
}

/* ---- 3 · (Légendes « perspective d’étude » retirées le 25/09/2026) ---- */


/* ---- 4 · Le trait d’étude posé sur la page ---------------------------
   Les wireframes sont livrés « encre sur blanc » (fond supprimé). En
   multiply sur la crème, le blanc disparaît : il ne reste que le trait,
   comme dessiné sur la page. Bords fondus : pas de cadre. */
.lieu__image--trait {
  aspect-ratio: auto;
  overflow: visible;
  background: var(--c-bg);
}
.lieu__image--trait img {
  position: static;
  height: auto;
  top: 0;
  mix-blend-mode: multiply;
  filter: none;
  -webkit-mask-image: radial-gradient(ellipse 72% 70% at 50% 50%, #000 58%, transparent 100%);
          mask-image: radial-gradient(ellipse 72% 70% at 50% 50%, #000 58%, transparent 100%);
}

.interstitial--trait {
  height: auto;
  min-height: 0;
  max-height: none;
  background: var(--c-bg);
  padding: 0;
}
.interstitial--trait::after { display: none; }
.interstitial--trait .interstitial__media {
  position: relative;
  inset: auto;
  margin: 0;
  height: clamp(420px, 62vw, 820px);
  overflow: hidden;
  background: var(--c-bg);
}
.interstitial--trait .interstitial__media img {
  height: 112%;
  top: -6%;
  object-position: 50% 45%;
  mix-blend-mode: multiply;
  filter: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 18%, #000 80%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 18%, #000 80%, transparent 100%);
}
@media (max-width: 640px) {
  .interstitial--trait .interstitial__media { height: 72vw; }
  .interstitial--trait .interstitial__media img { height: 100%; top: 0; }
}


/* ---- 5 · Le domaine -------------------------------------------------- */
.domaine__head { margin-bottom: var(--s-6); }

.domaine__legend {
  max-width: var(--container);
  margin: var(--s-3) auto 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--s-3) var(--s-5);
  flex-wrap: wrap;
}
.domaine__legend-items {
  display: flex;
  gap: var(--s-4);
  flex-wrap: wrap;
  font-size: var(--fs-caption);
  color: var(--c-text);
  letter-spacing: 0.02em;
}

/* Les 11 repères sont des liens vers la page de leur typologie.
   Trois typologies, trois couleurs : principales ivoire, exception
   graphite, intimistes olive (l’olive = le repère). Au survol : graphite
   (ivoire pour l’exception), le numéro grossit. */
a.hotspot { text-decoration: none; }
.hotspot--intimiste {
  width: 32px;
  height: 32px;
  font-size: 10.5px;
  background: var(--c-olive);
  color: var(--c-ivoire);
  border-color: rgb(var(--c-ivoire-rgb) / 0.8);
}
.hotspot:hover,
.hotspot:focus-visible,
.hotspot--intimiste:hover,
.hotspot--intimiste:focus-visible {
  background: var(--c-graphite);
  border-color: var(--c-graphite);
  color: var(--c-ivoire);
  outline: none;
}
.hotspot--exception:hover,
.hotspot--exception:focus-visible {
  background: var(--c-ivoire);
  border-color: var(--c-graphite);
  color: var(--c-graphite);
}
.legend__dot--intimiste {
  width: 9px;
  height: 9px;
  background: var(--c-olive);
  border-color: var(--c-olive);
}
@media (max-width: 960px) { .hotspot--intimiste { width: 28px; height: 28px; font-size: 10px; } }
@media (max-width: 640px) { .hotspot--intimiste { width: 24px; height: 24px; font-size: 9px; } }
.hotspot:focus-visible .hotspot__tip,
.hotspot:focus .hotspot__tip {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}


/* ---- 6 · Les villas -------------------------------------------------- */
.card__area {
  display: block;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--c-graphite);
  margin-bottom: 6px;
}
.card__num { gap: 14px; }


/* ---- 7 · Chiffres-clés ----------------------------------------------- */
.stat__num { font-variant-numeric: lining-nums; }
.stat__sep {
  display: inline-block;
  margin: 0 0.22em;
  font-size: 0.5em;
  font-style: italic;
  vertical-align: 0.18em;
  color: var(--c-muted);
}
.stats__note {
  margin-top: var(--s-4);
  text-align: center;
  font-size: var(--fs-caption);
  color: var(--c-muted);
}


/* ---- 8 · L’engagement ------------------------------------------------ */
.engagement__inner { max-width: 880px; }
.engagement__lead {
  max-width: 34ch;
  font-style: normal;
  font-size: clamp(24px, 1.9vw + 14px, 36px);
  line-height: 1.35;
}
.engagement__cols {
  border-top-color: rgb(var(--c-beige-rgb) / 0.8);
}


/* ---- 9 · Boutons ------------------------------------------------------
   Un seul dessin de bouton pour tout le site : rectangle, filet 1 px,
   capitales Inter espacées. Le WhatsApp est un bouton de la marque
   comme les autres — jamais le vert de l’application. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 52px;
  padding: 0 28px;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid currentColor;
  transition: background-color 500ms var(--ease-soft),
              color 500ms var(--ease-soft),
              border-color 500ms var(--ease-soft);
}
.btn__arrow {
  width: 10px;
  height: 10px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.2;
  transition: transform 500ms var(--ease-soft);
}
.btn:hover .btn__arrow { transform: translate(2px, -2px); }

.btn--light { background: var(--c-ivoire); color: var(--c-graphite); border-color: var(--c-ivoire); }
.btn--light:hover { background: transparent; color: var(--c-ivoire); }
.btn--ghost-light { background: transparent; color: var(--c-ivoire); border-color: rgb(var(--c-beige-rgb) / 0.55); text-transform: none; letter-spacing: 0.04em; font-size: var(--fs-caption); font-weight: 400; }
.btn--ghost-light:hover { border-color: var(--c-ivoire); }
.btn--caps { text-transform: uppercase; letter-spacing: var(--tr-caps); font-size: var(--fs-micro); font-weight: 500; }
/* WhatsApp : bouton plein olive (le repère de la marque, jamais le vert
   de l’application). Olive profond pour que le texte ivoire reste lisible. */
.btn--olive { background: var(--c-olive-deep); border-color: var(--c-olive-deep); color: var(--c-ivoire); }
.btn--olive:hover { background: var(--c-olive); border-color: var(--c-olive); color: var(--c-ivoire); }
.btn--dark { background: var(--c-graphite); color: var(--c-ivoire); border-color: var(--c-graphite); }
.btn--dark:hover { background: transparent; color: var(--c-graphite); }
.btn--ghost { background: transparent; color: var(--c-graphite); border-color: rgb(var(--c-graphite-rgb) / 0.35); }
.btn--ghost:hover { border-color: var(--c-graphite); }


/* ---- 10 · Footer « 4e de couverture » ---------------------------------
   Graphite plein, logo crème, filet beige, LES ZAERS · TÉMARA : la même
   dernière page que le catalogue. Un seul moment de contact par page. */
.footer {
  background: var(--c-graphite);
  color: var(--c-ivoire);
  border-top: 0;
  padding: var(--section-pad-y) 0 var(--s-4);
}
.footer__contact {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--s-6);
  align-items: end;
  padding-bottom: var(--s-7);
  border-bottom: 1px solid rgb(var(--c-beige-rgb) / 0.28);
}
.footer__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-h2);
  line-height: 1.08;
  letter-spacing: var(--tr-snug);
  color: var(--c-ivoire);
  margin: var(--s-3) 0 var(--s-3);
  max-width: 16ch;
}
.footer__lead {
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--c-beige);
  max-width: 42ch;
}
.footer__reach { justify-self: end; text-align: left; }
.footer__phone {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(40px, 3.6vw + 14px, 68px);
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--c-ivoire);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  padding-bottom: 8px;
  transition: background-size 700ms var(--ease-quiet);
}
.footer__phone:hover { background-size: 100% 1px; }
.footer__phone-intl {
  margin-top: var(--s-2);
  font-size: var(--fs-caption);
  color: var(--c-beige);
}
.footer__phone-intl a {
  color: var(--c-ivoire);
  border-bottom: 1px solid rgb(var(--c-beige-rgb) / 0.5);
  padding-bottom: 2px;
  white-space: nowrap;
  transition: border-color 300ms var(--ease-soft);
}
.footer__phone-intl a:hover { border-bottom-color: var(--c-ivoire); }
.footer__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-4);
}

.footer__meta {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
  padding: var(--s-6) 0;
}
.footer__col h4 {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-beige);
  margin-bottom: var(--s-2);
}
.footer__col p,
.footer__col a {
  display: block;
  font-size: var(--fs-caption);
  line-height: 1.8;
  color: var(--c-ivoire);
}

.footer__col a.footer__link {
  display: inline-block;
  margin-top: var(--s-1);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-ivoire);
  border-bottom: 1px solid rgb(var(--c-beige-rgb) / 0.6);
  padding-bottom: 3px;
}
.footer__col a.footer__link:hover { border-bottom-color: var(--c-ivoire); }

.footer__sign {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-6) 0 var(--s-5);
}
.footer__logo {
  width: 150px;
  margin: 0;
  color: var(--c-ivoire);
}
.footer__place {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--c-beige);
}
.footer__bottom {
  border-top: 1px solid rgb(var(--c-beige-rgb) / 0.28);
  margin-top: 0;
  padding-top: var(--s-3);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: rgb(var(--c-beige-rgb) / 0.8);
}

@media (max-width: 960px) {
  .footer__contact { grid-template-columns: 1fr; align-items: start; }
  .footer__reach { justify-self: start; }
  .footer__meta { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .footer__meta { grid-template-columns: 1fr; gap: var(--s-3); }
  .footer__reach { width: 100%; }
  .footer__actions { flex-direction: column; align-items: stretch; }
  .domaine__legend-items { flex-direction: column; gap: var(--s-1); }
  .stats__grid { row-gap: var(--s-4); }
  .footer__bottom { flex-direction: column; gap: var(--s-1); text-align: center; }
}


/* ---- 11 · Dock : plus de chevauchement --------------------------------
   Les filets restent dans la marge ; le libellé n’apparaît qu’au survol,
   sur une pastille crème (il ne se pose plus jamais sur le texte). */
.dock { right: 18px; }
.dock__link.is-active .dock__filet { width: 32px; background: var(--c-olive); }
.dock__link:hover .dock__filet { width: 28px; }
.dock__link.is-active .dock__label { opacity: 0; }
.dock__link:hover .dock__label {
  opacity: 1;
  background: rgb(var(--c-bg-rgb) / 0.94);
  padding: 4px 8px;
}
.dock.is-on-dark .dock__link:hover .dock__label { background: rgb(var(--c-graphite-rgb) / 0.8); }
@media (max-width: 1280px) {
  .dock { right: 14px; }
  .dock__link.is-active .dock__filet { width: 24px; }
  .dock__link:hover .dock__filet { width: 22px; }
}
@media (max-width: 1180px) { .dock { display: none; } }


/* ---- 12 · Menu mobile : contact direct -------------------------------- */
.menu-panel__contact {
  margin-top: var(--s-6);
  display: flex;
  justify-content: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  opacity: 0;
  transition: opacity 600ms var(--ease-soft) 700ms;
}
.menu-panel.is-open .menu-panel__contact { opacity: 1; }
.menu-panel__contact a { border-bottom: 1px solid var(--c-beige); padding-bottom: 3px; }
.menu-panel__lang { margin-top: var(--s-4); }


/* ---- 13 · Pages villa ------------------------------------------------- */
.villa-place__map { aspect-ratio: 3 / 2; }
.villa-place__inner > .chapter-rule { grid-column: 1 / -1; margin-bottom: 0; }

.nowrap { white-space: nowrap; }
/* Les chambres (26/09/2026) : une ligne à part, sous les surfaces */
.villa-character__chambres {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: baseline;
  column-gap: var(--s-2);
  padding-top: var(--s-4);
  border-top: 1px solid rgba(200, 193, 184, 0.5);
}
.villa-character__chambres-detail {
  margin-left: var(--s-2);
  font-size: var(--fs-caption);
  line-height: 1.6;
  color: var(--c-text);
  max-width: 46ch;
}
/* Mise en avant (« face à la piscine ») : l’italique de la marque, comme « la vôtre » du
   haut de l’accueil, sur sa propre ligne, en fin de phrase (pas de gras : la charte l’exclut) */
.villa-character__chambres-detail em {
  display: block;
  margin-top: 6px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(24px, 1.2vw + 16px, 30px);
  line-height: 1.15;
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
}
@media (max-width: 640px) {
  .villa-character__chambres { grid-template-columns: auto minmax(0, 1fr); row-gap: var(--s-2); }
  .villa-character__chambres-detail { grid-column: 1 / -1; margin-left: 0; }
}
.villa-character__facts-note {
  grid-column: 1 / -1;
  font-size: var(--fs-caption);
  color: var(--c-muted);
}


/* ---- Reduced motion --------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .chapter-rule { transform: none; }
}


/* =========================================================================
   V10 · 14 — PAGE ITINÉRAIRE (itineraire.html, cible du QR code du panneau)
   Mobile d’abord, en voiture, première visite : trois choix en une seconde.
   La photo du panneau (→ le site) puis deux gros boutons GPS au pouce.
   ========================================================================= */

/* Lien de la page courante dans la nav : un filet olive (le repère) */
.nav__link[aria-current="page"]::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: var(--c-olive);
}
.menu-panel__link[aria-current="page"] {
  color: var(--c-olive);
  font-style: italic;
  display: inline-flex;
  align-items: center;
  gap: 14px;
}
.menu-panel__link[aria-current="page"]::before {   /* le filet de la marque, en olive */
  content: '';
  width: 28px;
  height: 1px;
  background: var(--c-olive);
}
/* Barre du haut (ordinateur) : filet olive un peu plus présent */
.nav__link[aria-current="page"]::after { height: 1.5px; bottom: -7px; }

.page-itineraire { background: var(--c-bg); }
/* Pas de loader sur cette page : la nav est visible tout de suite */
.page-itineraire .nav__link,
.page-itineraire .lang,
.page-itineraire .nav__burger { opacity: 1; transform: none; }

.itin {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* ---- 1 · Le projet : la photo du panneau, entière et cliquable ------ */
.itin__projet {
  position: relative;
  display: block;
  flex: 0 0 auto;
  height: clamp(230px, 44svh, 370px);
  overflow: hidden;
  background: var(--c-hero-sky);
  isolation: isolate;
}
.itin__projet picture,
.itin__projet img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.itin__projet img {
  object-fit: cover;
  object-position: 50% 100%;
  filter: saturate(0.9);
  transition: transform 900ms var(--ease-soft);
}
.itin__projet:active img { transform: scale(1.015); }
.itin__projet::after {                     /* voile uniquement sous le bouton */
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgb(var(--c-graphite-rgb) / 0.55) 0%, rgb(var(--c-graphite-rgb) / 0) 34%);
  pointer-events: none;
}
.itin__logo {
  position: absolute;
  z-index: 2;
  top: calc(env(safe-area-inset-top, 0px) + 18px);
  left: 50%;
  transform: translateX(-50%);
  width: clamp(112px, 30vw, 146px);
  height: auto;
  color: var(--c-graphite);
}
.itin__cta {
  position: absolute;
  z-index: 2;
  left: var(--gutter);
  bottom: 16px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 0 16px;
  border: 1px solid rgb(var(--c-ivoire-rgb) / 0.75);
  background: rgb(var(--c-graphite-rgb) / 0.22);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  color: var(--c-ivoire);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.itin__cta svg { width: 14px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.2; }

/* ---- 2 · Les choix ----------------------------------------------------- */
.itin__choix {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: clamp(20px, 3.4svh, 30px) var(--gutter) calc(env(safe-area-inset-bottom, 0px) + 22px);
}
.itin__title {
  margin: 10px 0 clamp(16px, 2.6svh, 24px);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(30px, 8.4vw, 40px);
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--c-graphite);
}

.itin-go {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 78px;
  padding: 14px 18px;
  background: var(--c-graphite);
  color: var(--c-ivoire);
  transition: background-color 300ms var(--ease-soft), transform 200ms var(--ease-soft);
}
.itin-go + .itin-go { margin-top: 10px; }
.itin-go:active { transform: scale(0.99); background: var(--c-text-strong); }
.itin-go__pin { flex: 0 0 auto; width: 22px; height: 28px; fill: none; stroke: var(--c-ivoire); stroke-width: 1.2; }
.itin-go__txt { flex: 1; min-width: 0; }
.itin-go__label {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 25px;
  line-height: 1.1;
}
.itin-go__sub {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--c-beige);
}
.itin-go__arrow {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: 1px solid rgb(var(--c-beige-rgb) / 0.5);
  border-radius: 50%;
  display: grid;
  place-items: center;
}
.itin-go__arrow svg { width: 12px; height: 12px; fill: none; stroke: var(--c-ivoire); stroke-width: 1.3; }

.itin__waze {
  margin-top: 14px;
  font-size: 12px;
  color: var(--c-muted);
  text-align: center;
}
.itin__waze a { color: var(--c-graphite); border-bottom: 1px solid var(--c-beige); padding-bottom: 2px; }

.itin__contact {
  margin-top: auto;
  padding-top: 22px;
  display: flex;
  justify-content: center;
  gap: 12px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-graphite);
}
.itin__contact span { color: var(--c-beige); }
.itin__contact a { border-bottom: 1px solid var(--c-beige); padding-bottom: 3px; }

/* Arrivée discrète (coupée si l’utilisateur limite les animations) */
@media (prefers-reduced-motion: no-preference) {
  .itin__choix > * { animation: itin-monte 600ms var(--ease-soft) both; }
  .itin__choix > :nth-child(2) { animation-delay: 60ms; }
  .itin__choix > :nth-child(3) { animation-delay: 120ms; }
  .itin__choix > :nth-child(4) { animation-delay: 180ms; }
  .itin__choix > :nth-child(5) { animation-delay: 240ms; }
}
@keyframes itin-monte { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---- Ordinateur / tablette paysage : deux colonnes -------------------- */
@media (min-width: 861px) {
  .itin { flex-direction: row; height: 100vh; min-height: 640px; }
  .itin__projet { flex: 0 0 50%; height: auto; }
  .itin__projet img { object-position: 50% 60%; }
  .itin__logo { width: 190px; top: 64px; }
  .itin__cta { left: 40px; bottom: 36px; min-height: 46px; padding: 0 20px; }
  .itin__choix {
    flex: 1;
    justify-content: center;
    max-width: 580px;
    margin: 0 auto;
    padding: 96px 56px 64px;
  }
  .itin__title { font-size: 56px; margin-bottom: 36px; }
  .itin-go { min-height: 92px; padding: 18px 24px; }
  .itin-go:hover { background: var(--c-text-strong); }
  .itin-go__label { font-size: 28px; }
  .itin__contact { margin-top: 48px; justify-content: flex-start; }
  .itin__waze { text-align: left; }
}


/* =========================================================================
   V10 · 15 — AJUSTEMENTS (25/09/2026, 3e passe)
   ========================================================================= */

/* Brochure : lien discret sous les boutons Appeler / WhatsApp */
.footer__brochure {
  display: inline-block;
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-beige);
  border-bottom: 1px solid rgb(var(--c-beige-rgb) / 0.5);
  padding-bottom: 3px;
}
.footer__brochure:hover { color: var(--c-ivoire); border-bottom-color: var(--c-ivoire); }

/* Cartes des villas en une colonne (mobile, tablette) : chaque carte est
   séparée de la suivante par un vrai temps et un filet. Sans cela,
   « Visiter la villa » semble appartenir à la photo qui suit. */
@media (max-width: 960px) {
  .villas__grid,
  .villa-others__grid { row-gap: 0; }
}
@media (max-width: 640px) {
  .villas__grid .card + .card,
  .villa-others__grid .card + .card {
    margin-top: 56px;
    padding-top: 56px;
    border-top: 1px solid rgb(var(--c-beige-rgb) / 0.7);
  }
  .card__more { margin-top: var(--s-2); }
}
@media (min-width: 641px) and (max-width: 960px) {
  .villas__grid { row-gap: var(--s-7); }
  .villa-others__grid .card + .card { margin-top: var(--s-7); }
}

/* Menu mobile : 7 entrées, on resserre pour tenir sur un écran court */
@media (max-width: 640px) {
  .menu-panel__list { gap: clamp(14px, 2.6svh, 28px); }
  .menu-panel__link { font-size: clamp(30px, 8vw, 42px); }
}


/* =========================================================================
   V10 · 16 — L’ART DE VIVRE EN PORTRAIT 4:5 (25/09/2026)
   Le carré (V9) coupait ce qui fait une pièce : la hauteur sous plafond,
   le sol, la lumière qui tombe. Le portrait 4:5 est le format éditorial
   de la marque (catalogue, Instagram 4:5) : une même image sert partout.
   L’image remplit désormais tout son cadre (plus de bandes vides).
   ========================================================================= */
.art__media {
  aspect-ratio: 4 / 5;
  display: block;
  padding: 0;
}
.art__media-inner {
  aspect-ratio: auto;
  height: 100%;
}
@media (max-width: 960px) {
  .art__media { aspect-ratio: 4 / 5; padding-block: 0; }
}

/* Accroche « Parmi les onze, la vôtre » : un peu plus longue que la
   précédente, on la resserre légèrement sur téléphone */
@media (max-aspect-ratio: 4/5) {
  .hero__title { font-size: clamp(26px, 7.6vw, 42px); gap: 0.22em; }
}


/* =========================================================================
   V10 · 17 — MOBILE : « LES VILLAS » À CÔTÉ DE « MENU » (25/09/2026)
   Beaucoup de visiteurs veulent aller droit aux villas : le lien est
   visible dès l’arrivée (le ciel du hero a la place), à gauche de « Menu ».
   Sur la section des villas, il se souligne d’un filet olive (le repère).
   ========================================================================= */
.nav__quick { display: none; }
@media (max-width: 640px) {
  .nav__right { display: none; }
  .nav__quick {
    display: inline-block;
    position: relative;
    margin-left: auto;
    margin-right: 22px;
    padding: 8px 2px;
    font-family: var(--font-body);
    font-size: var(--fs-micro);
    font-weight: 500;
    letter-spacing: var(--tr-caps);
    text-transform: uppercase;
    color: inherit;
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 600ms var(--ease-soft) 200ms,
                transform 600ms var(--ease-soft) 200ms,
                color 300ms var(--ease-soft);
  }
  body.is-loaded .nav__quick,
  .page-itineraire .nav__quick { opacity: 1; transform: none; }
  .nav__quick::after {
    content: '';
    position: absolute;
    left: 2px;
    right: 2px;
    bottom: 2px;
    height: 1px;
    background: var(--c-olive);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 500ms var(--ease-quiet);
  }
  .nav__quick.is-current::after { transform: scaleX(1); }
  /* menu ouvert : on le masque avec « Menu » (le panneau a ses liens) */
  body.menu-open .nav__quick { opacity: 0; pointer-events: none; }
  /* Page Itinéraire : pas de « Les villas » (il passait sur le logo de la photo
     du panneau) ; « Menu » reste. Décision du 25/09/2026. */
  .page-itineraire .nav__quick { display: none; }
}


/* =========================================================================
   V10 · 15 · Page introuvable (404.html) · 25/09/2026
   Mêmes composants que la page Itinéraire (itin-go, contact) ; pas de photo.
   Pas de loader : la barre est visible tout de suite, logo compris.
   ========================================================================= */
.page-404 { background: var(--c-bg); }
.page-404 .nav__link,
.page-404 .lang,
.page-404 .nav__burger,
.page-404 .nav__quick { opacity: 1; transform: none; }
.page-404 .nav__logo-link { opacity: 1; transform: none; pointer-events: auto; }
.itin--404 .itin__choix {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding-top: calc(var(--s-3) + 96px);
}
.p404__texte {
  margin: 0 0 clamp(20px, 3svh, 28px);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--c-text);
}
@media (min-width: 861px) {
  .itin--404 { flex-direction: column; height: auto; }
  .itin--404 .itin__choix { padding-top: 180px; padding-bottom: 64px; }
  .itin--404 .itin__contact { justify-content: flex-start; }
}


/* =========================================================================
   V10 · 16 · Fiche du projet (le-projet.html) · 25/09/2026
   Une planche technique du catalogue : les faits du projet en texte, pour
   Google et les assistants IA, propre si un client tombe dessus.
   Colonne gauche : eyebrow + titre ; colonne droite : les faits.
   ========================================================================= */
.page-fiche { background: var(--c-bg); }
.page-fiche .nav__link,
.page-fiche .lang,
.page-fiche .nav__burger,
.page-fiche .nav__quick { opacity: 1; transform: none; }
.page-fiche .nav__logo-link { opacity: 1; transform: none; pointer-events: auto; }
.page-fiche .chapter-rule { transform: scaleX(1); }

.fiche {
  max-width: var(--container);
  margin-inline: auto;
  padding: calc(var(--s-3) + 120px) var(--gutter) var(--section-pad-y);
}
.fiche__head { max-width: 760px; margin-bottom: var(--s-6); }
.fiche__title {
  margin: var(--s-3) 0 var(--s-3);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-h1);
  line-height: 1.05;
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
}
.fiche__lead {
  max-width: 34em;
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--c-text);
}

.fiche__figure { margin: 0 0 var(--section-pad-y); }
.fiche__figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1800 / 1199;
  object-fit: cover;
  background: var(--c-beige);
}
.fiche__figure figcaption {
  margin-top: var(--s-2);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-wide);
  color: var(--c-muted);
}

.fiche__section + .fiche__section { margin-top: clamp(72px, 7vw, 112px); }
.fiche__section .chapter-rule { margin-bottom: clamp(32px, 4vw, 56px); }
.fiche__cols {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--s-5) clamp(40px, 6vw, 120px);
  align-items: start;
}
.fiche__h2 {
  margin-top: var(--s-3);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(28px, 1.6vw + 18px, 42px);
  line-height: 1.12;
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
  max-width: 14ch;
}

/* Tableau des villas : pleine largeur, titre au-dessus (il lui faut la place) */
.fiche__cols--wide { grid-template-columns: 1fr; gap: var(--s-5); }
.fiche__cols--wide .fiche__h2 { max-width: none; }

/* Liste de définitions : libellé en capitales, valeur en texte courant */
.fiche__dl { margin: 0; }
.fiche__row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(0, 2.4fr);
  gap: var(--s-3);
  padding: 18px 0;
  border-bottom: 1px solid var(--c-beige);
}
.fiche__row:first-child { border-top: 1px solid var(--c-beige); }
.fiche__row dt {
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-muted);
  padding-top: 3px;
}
.fiche__row dd {
  margin: 0;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--c-text-strong);
}

.fiche__link {
  display: inline-block;
  margin-top: var(--s-4);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  border-bottom: 1px solid var(--c-olive);
  padding-bottom: 4px;
}

/* Tableau des typologies */
.fiche__table-wrap { width: 100%; }
.fiche__table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: lining-nums tabular-nums;
}
.fiche__table caption {
  caption-side: bottom;
  text-align: left;
  padding-top: var(--s-2);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-wide);
  color: var(--c-muted);
}
.fiche__table th,
.fiche__table td {
  padding: 16px 12px 16px 0;
  text-align: left;
  vertical-align: baseline;
  border-bottom: 1px solid var(--c-beige);
  font-size: var(--fs-caption);
  color: var(--c-text-strong);
  white-space: nowrap;
}
.fiche__table thead th {
  border-top: 1px solid var(--c-beige);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-muted);
  white-space: normal;
}
.fiche__table tbody th {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(19px, 0.6vw + 15px, 23px);
  white-space: nowrap;
}
.fiche__table tbody th a {
  color: var(--c-graphite);
  border-bottom: 1px solid var(--c-beige);
  transition: border-color 300ms var(--ease-soft);
}
.fiche__table tbody th a:hover { border-color: var(--c-olive); }

/* Listes : un filet court devant chaque ligne, comme les eyebrows */
.fiche__list { list-style: none; margin: 0; padding: 0; }
.fiche__list li {
  position: relative;
  padding: 16px 0 16px 36px;
  border-bottom: 1px solid var(--c-beige);
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--c-text-strong);
}
.fiche__list li:first-child { border-top: 1px solid var(--c-beige); }
.fiche__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(16px + 0.78em);
  width: 20px;
  height: 1px;
  background: var(--c-olive);
}

/* Tablette : une colonne, le titre au-dessus des faits */
@media (max-width: 960px) {
  .fiche__cols { grid-template-columns: 1fr; gap: var(--s-4); }
  .fiche__h2 { max-width: none; }
}
/* Mobile : le tableau devient une fiche par typologie */
@media (max-width: 640px) {
  .fiche { padding-top: calc(var(--s-3) + 96px); }
  .fiche__row { grid-template-columns: 1fr; gap: 4px; padding: 14px 0; }
  .fiche__table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .fiche__section + .fiche__section { margin-top: 56px; }
  .fiche__section .chapter-rule { margin-bottom: 28px; }
  .fiche__table { display: flex; flex-direction: column; }
  .fiche__table caption { display: block; order: 2; }   /* la légende passe sous les fiches */
  .fiche__table tbody,
  .fiche__table tr,
  .fiche__table th,
  .fiche__table td { display: block; }
  .fiche__table tr { padding: 16px 0 10px; border-bottom: 1px solid var(--c-beige); }
  .fiche__table tbody tr:first-child { border-top: 1px solid var(--c-beige); }
  .fiche__table tbody th { border: 0; padding: 0 0 8px; }
  .fiche__table td {
    display: flex;
    justify-content: space-between;
    border: 0;
    padding: 5px 0;
    white-space: normal;
  }
  .fiche__table td::before {
    content: attr(data-label);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tr-caps);
    text-transform: uppercase;
    color: var(--c-muted);
  }
}

/* Pied de page : lien discret vers la fiche du projet (toutes les pages) */
.footer__fiche {
  color: inherit;
  border-bottom: 1px solid rgb(var(--c-beige-rgb) / 0.35);
  padding-bottom: 2px;
  transition: border-color 300ms var(--ease-soft);
}
.footer__fiche:hover { border-color: var(--c-beige); }



/* =========================================================================
   27 · La visite pièce par pièce (pages villas, 26/09/2026)
   Section écrite par .claude/photos/visite.py (textes et photos s’y changent).
   Une pièce = un texte (numéro, titre, description, index des sous-pièces) et une
   galerie qui défile à l’horizontale : défilement natif et aimanté, au doigt sur
   téléphone, aux flèches sur ordinateur. La photo suivante dépasse toujours du bord :
   on voit qu’il y a une suite sans rien expliquer. Pas de défilement automatique.
   Un toucher ouvre la visionneuse plein écran (script.js § 19).
   Une pièce d’une seule photo (hall, cuisine) : la photo à gauche, le texte à droite.
   Le jardin (piece--paysage) : une grande photo horizontale en fin de visite.
   ========================================================================= */
.visite {
  --bord: max(var(--gutter), calc((100vw - var(--container)) / 2 + var(--gutter)));
  --vue-h: clamp(420px, 70vh, 700px);
  padding: var(--section-pad-y) 0;
  background: var(--c-bg);
  overflow: hidden;            /* les galeries courent jusqu’au bord de l’écran */
}
@supports (overflow: clip) { .visite { overflow: clip; } }
.visite__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---- En-tête : titre, intro, sommaire des pièces -------------------------- */
.visite__tete { margin-bottom: clamp(72px, 8vw, 128px); }
.visite__tete .h2 { margin-top: var(--s-3); max-width: 16ch; }
.visite__intro {
  margin-top: var(--s-3);
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(20px, 1vw + 12px, 26px);
  line-height: 1.4;
  color: var(--c-text-strong);
  max-width: 42ch;
  text-wrap: pretty;
}
.visite__sommaire { margin-top: var(--s-5); }
.visite__sommaire ol { flex: 1; }
.visite__sommaire ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 28px;
}
.visite__sommaire a {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 8px 0;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-text-strong);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 400ms var(--ease-soft);
}
.visite__sommaire a:hover { border-bottom-color: var(--c-beige); }
.visite__sommaire-num {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-muted);
  font-variant-numeric: lining-nums;
}
.visite__plein-ligne { margin-top: var(--s-4); }
.visite__plein {
  appearance: none;
  padding: 0 0 5px;
  border: 0;
  background: none;
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-graphite);
  cursor: pointer;
}
.visite__plein::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 24px;
  background: var(--c-graphite);
  transition: width 500ms var(--ease-quiet);
}
.visite__plein:hover::after { width: 100%; }
.visite__plein-nb { color: var(--c-muted); }

/* Téléphone et tablette : le sommaire en table des matières, un filet par pièce */
@media (max-width: 960px) {
  .visite__sommaire ol { display: block; border-top: 1px solid rgb(var(--c-beige-rgb) / 0.55); }
  .visite__sommaire li { border-bottom: 1px solid rgb(var(--c-beige-rgb) / 0.55); }
  .visite__sommaire a { display: flex; gap: 14px; padding: 15px 0; border-bottom: 0; }
  .visite__sommaire-num { min-width: 1.4em; }
}

@media (min-width: 961px) {
  .visite__tete {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(48px, 6vw, 120px);
    align-items: end;
  }
  .visite__tete > .eyebrow { grid-column: 1; grid-row: 1; justify-self: start; }
  .visite__tete > .h2 { grid-column: 1; grid-row: 2; }
  .visite__intro { grid-column: 2; grid-row: 2; margin: 0; }
  .visite__plein-ligne { grid-column: 2; grid-row: 3; }
  .visite__sommaire {
    grid-column: 1 / -1;
    grid-row: 4;
    margin-top: var(--s-6);
    padding-top: var(--s-3);
    border-top: 1px solid rgb(var(--c-beige-rgb) / 0.55);
  }
  .visite__sommaire ol { justify-content: space-between; flex-wrap: nowrap; }
}

/* ---- Une pièce --------------------------------------------------------------- */
.visite__pieces {
  display: flex;
  flex-direction: column;
  gap: clamp(104px, 11vw, 176px);
}
.piece {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "texte" "galerie" "nav";
  scroll-margin-top: 96px;
}
.piece__texte { grid-area: texte; min-width: 0; }
.piece__galerie { grid-area: galerie; position: relative; min-width: 0; margin-top: var(--s-4); }
.piece__nav { grid-area: nav; }

.piece__num {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: 19px;
  line-height: 1;
  color: var(--c-graphite);
  font-variant-numeric: lining-nums;
}
.piece__num::before {
  content: '';
  width: 32px;
  height: 1px;
  background: var(--c-beige);
}
.piece__num span { color: var(--c-muted); }
.piece__titre {
  margin-top: var(--s-3);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(32px, 2.2vw + 16px, 50px);
  line-height: 1.06;
  letter-spacing: var(--tr-snug);
  color: var(--c-graphite);
  font-variant-numeric: lining-nums;
}
.piece__desc {
  margin-top: var(--s-3);
  max-width: 44ch;
  text-wrap: pretty;
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--c-text);
}

/* Index des sous-pièces : l’état courant reprend le langage du menu (filet olive) */
.piece__index {
  position: relative;
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
}
.piece__aller {
  appearance: none;
  border: 0;
  background: none;
  padding: 9px 0;
  display: inline-flex;
  align-items: center;
  gap: 0;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--c-muted);
  cursor: pointer;
  transition: color 300ms var(--ease-soft), gap 500ms var(--ease-quiet);
}
.piece__aller::before {
  content: '';
  width: 0;
  height: 1px;
  background: var(--c-olive);
  transition: width 500ms var(--ease-quiet);
}
.piece__aller:hover { color: var(--c-graphite); }
.piece__aller[aria-current="true"] { color: var(--c-graphite); gap: 12px; }
.piece__aller[aria-current="true"]::before { width: 24px; }

/* Compteur, filet de progression, flèches */
.piece__nav {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: var(--s-3);
}
.piece__compteur {
  min-width: 4.6em;
  font-family: var(--font-display);
  font-size: 19px;
  line-height: 1;
  color: var(--c-muted);
  font-variant-numeric: lining-nums tabular-nums;
}
.piece__rang { color: var(--c-graphite); }
.piece__progres {
  position: relative;
  flex: 1 1 auto;
  max-width: 160px;
  height: 1px;
  background: rgb(var(--c-beige-rgb) / 0.7);
  overflow: hidden;
}
.piece__progres span {
  position: absolute;
  inset: 0;
  background: var(--c-graphite);
  transform-origin: left center;
  transform: scaleX(var(--p, 0.1));
  transition: transform 600ms var(--ease-quiet);
}
.piece__fleche {
  appearance: none;
  flex: none;
  width: 46px;
  height: 46px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgb(var(--c-graphite-rgb) / 0.22);
  background: transparent;
  color: var(--c-graphite);
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  transition: background-color 300ms var(--ease-soft), color 300ms var(--ease-soft),
              border-color 300ms var(--ease-soft), opacity 300ms var(--ease-soft);
}
.piece__fleche svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.2; }
.piece__fleche--prec svg { transform: scaleX(-1); }
.piece__fleche:hover:not(:disabled) { background: var(--c-graphite); border-color: var(--c-graphite); color: var(--c-bg); }
.piece__fleche:disabled { opacity: 0.28; cursor: default; }
.piece__fleche:focus-visible,
.piece__aller:focus-visible,
.visite__plein:focus-visible,
.visite__sommaire a:focus-visible { outline: 1px solid var(--c-graphite); outline-offset: 4px; }

/* La galerie : défilement natif, aimanté sur le début de chaque photo */
.piece__piste {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
  display: flex;
  gap: var(--s-3);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.piece__piste::-webkit-scrollbar { display: none; }
.piece__vue {
  flex: 0 0 auto;
  width: calc(var(--vue-h) * 0.8);
  scroll-snap-align: start;
}
.piece__photo {
  appearance: none;
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  background: #E3DFD6;
  cursor: zoom-in;
}
.piece__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 1600ms var(--ease-soft);
}
@media (hover: hover) {
  .piece__photo:hover img { transform: scale(1.03); }
}
.piece__photo:focus-visible { outline: 1px solid var(--c-graphite); outline-offset: 4px; }
.piece__legende {
  margin-top: 14px;
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  line-height: 1.5;
  color: var(--c-muted);
}
.piece__legende-titre {
  margin-right: 4px;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(17px, 0.4vw + 14px, 19px);
  color: var(--c-graphite);
}

/* Téléphone et tablette : texte, galerie pleine largeur, compteur dessous */
@media (max-width: 960px) {
  .piece__galerie { margin-left: calc(-1 * var(--gutter)); margin-right: calc(-1 * var(--gutter)); }
  .piece__piste { gap: 12px; padding: 0 var(--gutter); scroll-padding: 0 var(--gutter); }
  .piece__vue { width: min(78vw, 440px); }
  .piece__index {
    display: flex;
    gap: 22px;
    margin: var(--s-3) calc(-1 * var(--gutter)) 0;
    padding: 0 var(--gutter);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .piece__index::-webkit-scrollbar { display: none; }
  .piece__aller {
    padding: 12px 0 9px;
    white-space: nowrap;
    border-bottom: 1px solid transparent;
  }
  .piece__aller::before { display: none; }
  .piece__aller[aria-current="true"] { gap: 0; border-bottom-color: var(--c-olive); }
  .piece__nav { margin-top: var(--s-3); }
  .piece__progres { max-width: none; }
  .piece--seule .piece__galerie,
  .piece--paysage:not(.piece--multi) .piece__galerie { margin-left: 0; margin-right: 0; }
  .piece--seule .piece__piste,
  .piece--paysage:not(.piece--multi) .piece__piste { padding: 0; }
  .piece--seule .piece__vue,
  .piece--paysage:not(.piece--multi) .piece__vue { width: 100%; }
  .piece--multi .piece__vue { width: 86vw; }
  .piece--paysage .piece__photo { aspect-ratio: 4 / 3; }
}
/* Au doigt, pas de flèches : on fait glisser */
@media (hover: none) and (pointer: coarse) {
  .piece__fleche { display: none; }
}

/* Ordinateur : texte à gauche, galerie à droite jusqu’au bord de l’écran */
@media (min-width: 961px) {
  .piece {
    grid-template-columns: minmax(300px, 4fr) minmax(0, 8fr);
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "texte galerie" "nav galerie" ". galerie";
    column-gap: clamp(48px, 5vw, 96px);
    align-items: start;
  }
  .piece__galerie { margin-top: 0; margin-right: calc(-1 * var(--bord)); }
  .piece__piste { padding-right: var(--bord); }
  .piece__nav { margin-top: var(--s-5); }
  .piece__texte { padding-top: 4px; }

  /* Une seule photo : la photo à gauche, le texte à côté */
  .piece--seule {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto;
    grid-template-areas: "galerie texte";
    align-items: center;
  }
  .piece--seule .piece__galerie { margin-right: 0; }
  .piece--seule .piece__piste { padding-right: 0; overflow: visible; }
  .piece--seule .piece__texte { padding-left: clamp(8px, 4vw, 72px); }

  /* Le jardin : grande photo horizontale sous le texte */
  .piece--paysage {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    grid-template-areas: "texte" "galerie" "nav";
  }
  .piece--paysage .piece__texte {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(48px, 6vw, 120px);
    align-items: end;
  }
  .piece--paysage .piece__num { grid-column: 1; }
  .piece--paysage .piece__titre { grid-column: 1; }
  .piece--paysage .piece__desc { grid-column: 2; grid-row: 2; margin: 0; }
  .piece--paysage .piece__galerie { margin: var(--s-5) 0 0; }
  .piece--paysage:not(.piece--multi) .piece__piste { padding: 0; overflow: visible; }
  .piece--paysage:not(.piece--multi) .piece__vue { width: 100%; }
  .piece--paysage .piece__photo { aspect-ratio: 3 / 2; }
  /* Le jardin en plusieurs photos : la suivante dépasse, jusqu’au bord de l’écran */
  .piece--multi .piece__galerie { margin-right: calc(-1 * var(--bord)); }
  .piece--multi .piece__vue { width: min(1080px, 76vw); }
  .piece--multi .piece__nav { margin-top: var(--s-4); }
}

/* ---- Visionneuse plein écran (script.js § 19) --------------------------------- */
html.visionneuse-ouverte { overflow: hidden; }
.visionneuse {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: rgb(var(--c-graphite-rgb));
  color: var(--c-ivoire);
  opacity: 0;
  transition: opacity 380ms var(--ease-soft);
  overscroll-behavior: contain;
}
.visionneuse[hidden] { display: none; }
.visionneuse.is-ouverte { opacity: 1; }
.visionneuse__barre {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 16px;
  padding: 16px var(--gutter);
}
.visionneuse__titre { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.visionneuse__piece {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: 21px;
  line-height: 1.1;
}
.visionneuse__sous {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: rgb(var(--c-ivoire-rgb) / 0.6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.visionneuse__compteur {
  font-family: var(--font-display);
  font-size: 19px;
  line-height: 1;
  color: rgb(var(--c-ivoire-rgb) / 0.7);
  font-variant-numeric: lining-nums tabular-nums;
}
.visionneuse__actions { justify-self: end; display: flex; gap: 8px; }
.visionneuse__bouton {
  appearance: none;
  height: 40px;
  padding: 0 18px;
  border: 1px solid rgb(var(--c-ivoire-rgb) / 0.25);
  border-radius: 999px;
  background: transparent;
  color: var(--c-ivoire);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 300ms var(--ease-soft), color 300ms var(--ease-soft), border-color 300ms var(--ease-soft);
}
.visionneuse__bouton svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.3; }
.visionneuse__bouton:hover { background: var(--c-ivoire); border-color: var(--c-ivoire); color: rgb(var(--c-graphite-rgb)); }
.visionneuse__bouton:focus-visible,
.visionneuse__fleche:focus-visible { outline: 1px solid var(--c-ivoire); outline-offset: 3px; }
.visionneuse__piste {
  list-style: none;
  margin: 0;
  padding: 0;
  min-height: 0;
  display: flex;
  overflow-x: auto;
  overscroll-behavior: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.visionneuse__piste::-webkit-scrollbar { display: none; }
.visionneuse.is-zoom .visionneuse__piste { overflow: hidden; }
.visionneuse__vue {
  position: relative;
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}
.visionneuse__cadre {
  position: absolute;
  inset: 0 clamp(12px, 7vw, 112px);
  display: flex;
  overflow: hidden;
  overscroll-behavior: contain;
  cursor: zoom-in;
}
.visionneuse__cadre picture { display: contents; }
.visionneuse__cadre img {
  margin: auto;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
}
.visionneuse__cadre.is-zoom { overflow: auto; cursor: zoom-out; }
.visionneuse__cadre.is-zoom img { max-width: none; max-height: none; object-fit: fill; flex: none; }
.visionneuse__legende {
  padding: 14px var(--gutter) 20px;
  min-height: 1.5em;
  text-align: center;
  font-size: var(--fs-caption);
  line-height: 1.5;
  color: rgb(var(--c-ivoire-rgb) / 0.75);
}
.visionneuse__fleche {
  appearance: none;
  position: absolute;
  top: 50%;
  z-index: 2;
  width: 54px;
  height: 54px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgb(var(--c-ivoire-rgb) / 0.3);
  background: rgb(var(--c-graphite-rgb) / 0.4);
  color: var(--c-ivoire);
  display: grid;
  place-items: center;
  transform: translateY(-50%);
  cursor: pointer;
  transition: background-color 300ms var(--ease-soft), color 300ms var(--ease-soft), opacity 300ms var(--ease-soft);
}
.visionneuse__fleche svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.2; }
.visionneuse__fleche--prec { left: clamp(10px, 2vw, 32px); }
.visionneuse__fleche--prec svg { transform: scaleX(-1); }
.visionneuse__fleche--suiv { right: clamp(10px, 2vw, 32px); }
.visionneuse__fleche:hover:not(:disabled) { background: var(--c-ivoire); color: rgb(var(--c-graphite-rgb)); }
.visionneuse__fleche:disabled { opacity: 0; pointer-events: none; }
.visionneuse.is-zoom .visionneuse__fleche { opacity: 0; pointer-events: none; }
@media (hover: none) and (pointer: coarse) {
  .visionneuse__fleche { display: none; }
}
@media (max-width: 640px) {
  .visionneuse__barre { grid-template-columns: minmax(0, 1fr) auto; row-gap: 10px; padding-top: 12px; }
  .visionneuse__compteur { grid-column: 1; grid-row: 2; }
  .visionneuse__actions { grid-column: 2; grid-row: 1 / 3; align-self: start; }
  .visionneuse__bouton { padding: 0 14px; }
  .visionneuse__zoom { width: 40px; padding: 0; justify-content: center; }
  .visionneuse__zoom .visionneuse__libelle { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .piece__photo img,
  .piece__progres span,
  .visionneuse { transition: none; }
}

/* Versions Samsung (§ 25 et 26) : fonds de la visite et de la visionneuse */
.ep-nuit .visite { background: var(--nuit-fond); }
.ep-nuit .piece__photo { background: var(--nuit-releve); }
.ep-nuit .visionneuse { background: var(--nuit-profond); }
.ep-nuit .piece__num::before,
.ep-nuit .piece__progres { background: var(--nuit-filet); }
.ep-nuit .piece__progres span,
.ep-nuit .visite__plein::after { background: var(--nuit-trait); }
.ep-nuit .piece__aller::before { background: var(--nuit-olive); }


/* =========================================================================
   25 · Version « nuit » (26/09/2026) : la charte inversée
   Samsung Internet assombrit le site quand le téléphone est en mode sombre, sans
   qu’on puisse l’en empêcher. Depuis le 26/09/2026, ces visiteurs voient la version
   claire gardée (§ 26, assets/clair.js). Cette version graphite n’est plus qu’un REPLI :
   classe .ep-nuit, posée par le script de tête quand l’assombrissement a une autre
   empreinte que celle mesurée (Samsung 30) ou que la version est dans EXCLUES.
   Charte inversée (décision de Simo) : fond graphite, texte crème.
   Note complète : Site Web Claude/Samsung-mode-sombre.md.

   Ce que fait Samsung (mesuré sur Samsung Internet 30.0.0.67, S24 Ultra et émulateur) :
   - COULEURS DE FOND : ramenées au noir, jamais plus claires qu’environ 32 (crème →
     31,28,20, un brun ; graphite → 7,7,6). Le graphite est impossible en couleur.
   - IMAGES DE FOND (background-image) : luminosité divisée par deux, teinte gardée.
     D’où la méthode : chaque fond de la nuit est une image d’un pixel (data:),
     deux fois plus claire que la couleur voulue (--nuit-*, ci-dessous).
   - TEXTES : sombres → clairs (graphite → 222, #4D4943 → 206,202,196, graphite 60 → 187),
     clairs gardés (crème → 243,240,232, ivoire → 247). Entre les deux (beige, 200 à 225)
     ils foncent : beige → 123. Olive → 166,177,161 (sauge).
   - IMAGES (<img>, SVG, logo) : atténuées ×0,705, filtres CSS ignorés (fichiers « nuit »).
   - BORDURES : 86 au plus. Les masques (mask-image) sont respectés.
   On écrit ces règles pour ce que Samsung en fera : pour juger, regarder dans Samsung
   Internet (émulateur « ep-nuit » ou vrai téléphone), jamais sur un ordinateur.
   ========================================================================= */
.ep-nuit {
  /* Fonds : couleur voulue à l’écran → pixel deux fois plus clair */
  --nuit-fond:          url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mOIi4sBAAI2ARna1IAXAAAAAElFTkSuQmCC);             /* graphite 47,47,46 */
  --nuit-fond-voile:    url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOIi4t5DQAEOgIElJVV4AAAAABJRU5ErkJggg==);         /* graphite à 92 % (barre de navigation) */
  --nuit-profond:       url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mOwsbECAAFqALOJvCZXAAAAAElFTkSuQmCC);             /* 30,30,29 : pied de page, bandeaux */
  --nuit-releve:        url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mNoaWkAAAMYAYkEFNiwAAAAAElFTkSuQmCC);             /* 66,66,64 : cartes, repères */
  --nuit-appeler:       url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mO4cuEEAAToAm2182y8AAAAAElFTkSuQmCC);             /* 106,104,100 : bouton Appeler */
  --nuit-olive-profond: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mPYd2UbAAScAklAUrmOAAAAAElFTkSuQmCC);             /* olive profond 95,106,91 */
  --nuit-olive:         url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mO49+UKAAVaAqdlusTUAAAAAElFTkSuQmCC);             /* olive 111,122,106 */
  --nuit-filet:         url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mPYsWUNAARAAhnG7IsYAAAAAElFTkSuQmCC);             /* 92,90,86 : filets discrets (beige) */
  --nuit-trait:         url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP49+sDAAXiAumWMS55AAAAAElFTkSuQmCC);             /* 127,125,120 : filets marqués (graphite) */

  /* Textes : le graphite des titres devient crème ; le texte courant, un crème plus
     doux (Samsung affiche #4D4943 en 206,202,196) ; le beige des textes secondaires,
     qui foncerait (123), passe à #7A766F (175,171,164). Les fonds qui utilisaient ces
     couleurs sont repris un à un plus bas. */
  --c-graphite:    #EDEAE2;
  --c-text-strong: #EDEAE2;
  --c-text:        #4D4943;
  --c-beige:       #7A766F;
}

/* ---- Fonds de page : graphite -------------------------------------------- */
.ep-nuit,
.ep-nuit body,
.ep-nuit .hero,
.ep-nuit .hero__media,
.ep-nuit .art,
.ep-nuit .art__media,
.ep-nuit .art__media-inner::before,
.ep-nuit .lieu,
.ep-nuit .lieu__image::before,
.ep-nuit .lieu__image--trait,
.ep-nuit .domaine,
.ep-nuit .villas,
.ep-nuit .card__media::before,
.ep-nuit .engagement,
.ep-nuit .interstitial--trait,
.ep-nuit .interstitial--trait .interstitial__media,
.ep-nuit .loader,
.ep-nuit .menu-panel,
.ep-nuit .page-veil,
.ep-nuit .villa-composition,
.ep-nuit .villa-character,
.ep-nuit .villa-place,
.ep-nuit .villa-others,
.ep-nuit .villa-place__map::after,
.ep-nuit .page-itineraire,
.ep-nuit .page-404,
.ep-nuit .page-fiche,
.ep-nuit .itin__projet,
.ep-nuit .ambient-toggle:hover { background: var(--nuit-fond); }

.ep-nuit .nav.is-scrolled,
.ep-nuit .ambient-toggle,
.ep-nuit .dock__link:hover .dock__label { background: var(--nuit-fond-voile); }

/* Aplats sombres (graphite en clair) : un graphite plus profond */
.ep-nuit .footer,
.ep-nuit .villa-cta,
.ep-nuit .au-fil,
.ep-nuit .domaine__map,
.ep-nuit .villa-hero__media,
.ep-nuit .hotspot__tip { background: var(--nuit-profond); }

/* Fonds d’attente derrière les images (beige en clair) */
.ep-nuit .lieu__image,
.ep-nuit .card__media,
.ep-nuit .villa-place__map,
.ep-nuit .fiche__figure img { background: var(--nuit-releve); }

/* ---- Filets --------------------------------------------------------------- */
.ep-nuit .chapter-rule,
.ep-nuit .filet--beige,
.ep-nuit .eyebrow--light .filet-grow,
.ep-nuit .dock__filet { background: var(--nuit-filet); }
.ep-nuit .filet,
.ep-nuit .filet-grow,
.ep-nuit .card__more::after,
.ep-nuit .villa-place__back::after,
.ep-nuit .villa-composition__step.is-active::before,
.ep-nuit .villa-composition__progress,
.ep-nuit .au-fil__eyebrow .filet-grow,
.ep-nuit .villa-hero__eyebrow .filet-grow,
.ep-nuit .video-sound__bar,
.ep-nuit .ambient-toggle__bar,
.ep-nuit .hero__scroll-line,
.ep-nuit .dock__link.is-active .dock__filet,
.ep-nuit .dock__link:hover .dock__filet { background: var(--nuit-trait); }

/* ---- Hero : la marque sur le graphite, la photo se lève dessous ------------
   En clair, le ciel de la photo se fond dans la crème et la marque s’y pose. La nuit,
   le ciel clair ne peut pas se fondre dans le graphite : la marque se pose sur le
   graphite plein, et la photo commence juste sous le titre, son ciel s’effaçant
   (masque) avant les toits. Rien n’est écrit sur le dégradé. Le logo est un SVG, que
   Samsung atténue (178) : le titre prend le graphite 60, que Samsung affiche 187,
   pour que la marque et la phrase gardent le même ton. */
.ep-nuit .hero__logo { color: var(--c-ivoire); }
.ep-nuit .hero__title { color: var(--c-muted); }

/* Paysage (tablette, ordinateur) : la photo (carrée, pleine largeur) est placée
   d’après le bas du titre, calculé avec les mêmes valeurs que § 07 (marge du haut,
   logo 323:120, marge du logo, titre) : son ciel commence à s’effacer 48 px sous le
   titre (à 22 % de l’image) et a disparu avant les toits (32 %). Vérifié en 1024 × 768,
   1280 × 800, 1920 × 1080 et téléphone couché. */
@media (min-aspect-ratio: 4/5) {
  .ep-nuit .hero {
    --nuit-titre-bas: calc(clamp(88px, 11vh, 124px) + clamp(190px, 16vw, 260px) * 0.3715
                         + clamp(24px, 3vh, 36px) + clamp(46px, 5vw + 14px, 104px));
    --nuit-photo-haut: calc(var(--nuit-titre-bas) + 48px - 22vw);
    height: clamp(100svh, calc(100vw + var(--nuit-photo-haut)), 185svh);
  }
  .ep-nuit .hero__media img {
    top: var(--nuit-photo-haut);
    height: 100vw;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 22%, rgb(0 0 0 / 0.5) 26%, #000 30%);
            mask-image: linear-gradient(180deg, transparent 0%, transparent 22%, rgb(0 0 0 / 0.5) 26%, #000 30%);
  }
}
/* Portrait (téléphone) : on rogne le haut du ciel (jamais les côtés ni la villa) ;
   la photo commence sous le titre, le reste du ciel s’efface avant les toits. */
@media (max-aspect-ratio: 4/5) {
  .ep-nuit .hero__media { height: calc(0.8 * min(calc(100vw * 4 / 3), calc(100svh - 170px))); }
  .ep-nuit .hero__media img {
    object-position: 50% 100%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, rgb(0 0 0 / 0.5) 7%, #000 14%);
            mask-image: linear-gradient(180deg, transparent 0%, rgb(0 0 0 / 0.5) 7%, #000 14%);
  }
  .ep-nuit .hero__brand {
    height: calc(100svh - 0.8 * min(calc(100vw * 4 / 3), calc(100svh - 170px)) - 8px);
    min-height: 0;
    padding-top: 44px;
  }
}

/* ---- Itinéraire : même principe ------------------------------------------ */
.ep-nuit .itin__logo { color: var(--c-ivoire); }
.ep-nuit .itin__projet img {
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, rgb(0 0 0 / 0.45) 24%, #000 48%);
          mask-image: linear-gradient(180deg, transparent 0%, rgb(0 0 0 / 0.45) 24%, #000 48%);
}
.ep-nuit .itin-go { background: var(--nuit-releve); }
.ep-nuit .itin-go:active,
.ep-nuit .itin-go:hover { background: var(--nuit-appeler); }

/* ---- Images propres à la nuit ----------------------------------------------
   Une image .nuit-seule remplace sa voisine .jour-seul. Chargement différé :
   tant qu’elle est masquée, le navigateur ne la télécharge pas. */
.nuit-seule { display: none; }
.ep-nuit .jour-seul { display: none; }
.ep-nuit .nuit-seule { display: block; }

/* Dessins d’étude : en clair, encre sur blanc posée en « multiply » sur la crème.
   La nuit, version préparée (images/…-trait-nuit.jpg : trait crème sur graphite,
   éclairci de 1/0,705 pour compenser l’atténuation ; script .claude/trait-nuit.py).
   Plus de multiply ; le fondu des bords reste. */
.ep-nuit .lieu__image--trait img,
.ep-nuit .interstitial--trait .interstitial__media img { mix-blend-mode: normal; }

/* ---- Boutons --------------------------------------------------------------
   En clair : « Appeler » ivoire plein, puis WhatsApp olive profond plein. La nuit,
   les deux restent pleins : « Appeler » en pierre claire (le fond le plus clair qui
   garde le texte crème lisible, 4,9:1), WhatsApp en olive profond, texte crème. */
.ep-nuit .btn--light { background: var(--nuit-appeler); color: var(--c-graphite); border-color: transparent; }
.ep-nuit .btn--olive { background: var(--nuit-olive-profond); color: var(--c-graphite); border-color: transparent; }
.ep-nuit .btn--dark { background: var(--nuit-releve); border-color: transparent; }

/* ---- Carte du domaine : trois typologies, trois tons ----------------------- */
.ep-nuit .hotspot,
.ep-nuit .legend__dot { background: var(--nuit-releve); }
.ep-nuit .hotspot--exception,
.ep-nuit .legend__dot--exception { background: var(--nuit-profond); }
.ep-nuit .hotspot--intimiste,
.ep-nuit .legend__dot--intimiste { background: var(--nuit-olive); }
.ep-nuit .hotspot:hover,
.ep-nuit .hotspot:focus-visible { background: var(--nuit-appeler); }


/* =========================================================================
   26 · La version claire gardée sous Samsung Internet (26/09/2026)
   Quand Samsung assombrit la page et que sa version est connue, assets/clair.js
   repeint le site en clair (classe .ep-clair ; explications en tête du fichier).
   Sinon, repli sur la version graphite (§ 25), lisible quoi que fasse Samsung.
   ========================================================================= */
/* Le temps de décider (quelques millisecondes, 2,5 s au plus) */
.ep-attente body { opacity: 0 !important; }

/* Toiles : canevas d’un pixel étirés, que Samsung ne touche pas */
.ep-toile-page {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100lvh;
  z-index: -1;
  pointer-events: none;
}
.ep-toile {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  display: block;
}
.ep-sans-fond { background-color: transparent !important; }
.ep-peint { background-color: transparent !important; isolation: isolate; }
.ep-relatif { position: relative !important; }
.ep-tuile { background-color: transparent !important; background-image: var(--ep-tuile) !important; }
.ep-eclaire { filter: brightness(1.4184) !important; }

/* Textes : dessinés par leur ombre, dont Samsung garde la couleur exacte */
.ep-clair body *,
.ep-clair body *::before,
.ep-clair body *::after {
  -webkit-text-fill-color: transparent !important;
  text-shadow: 0 0 0 currentColor !important;
}
.ep-clair .hero__garden { text-shadow: 0 0 0 currentColor, 0 1px 18px rgb(var(--c-graphite-rgb) / 0.35) !important; }

/* Rideaux d’apparition des images (crème, pseudo-éléments : on ne peut pas les
   peindre) : supprimés, comme pour « mouvement réduit » */
.ep-clair .lieu__image::before,
.ep-clair .lieu__image::after,
.ep-clair .art__media-inner::before,
.ep-clair .art__media-inner::after,
.ep-clair .card__media::before,
.ep-clair .villa-place__map::after { display: none; }

/* Voiles graphite en dégradé : Samsung noircit leur couleur (47 → 7) ; on baisse
   leur opacité d’autant (× 0,45) pour garder la même ombre sur la photo. */
.ep-clair .hero__media::after {
  background: linear-gradient(0deg, rgb(var(--c-graphite-rgb) / 0.25) 0%, rgb(var(--c-graphite-rgb) / 0.045) 34%, rgb(var(--c-graphite-rgb) / 0) 48%);
}
@media (max-aspect-ratio: 4/5) {
  .ep-clair .hero__media::after {
    background: linear-gradient(0deg, rgb(var(--c-graphite-rgb) / 0.27) 0%, rgb(var(--c-graphite-rgb) / 0.09) 20%, rgb(var(--c-graphite-rgb) / 0) 36%);
  }
}
.ep-clair .itin__projet::after { background: linear-gradient(0deg, rgb(var(--c-graphite-rgb) / 0.25) 0%, rgb(var(--c-graphite-rgb) / 0) 34%); }
.ep-clair .domaine__map::after { background: radial-gradient(ellipse at 50% 30%, transparent 40%, rgba(47, 47, 46, 0.135) 100%); }
/* Facteur 0,65 mesuré dans l’émulateur le 26/09 (0,61 à 0,70 selon la photo) : à 0,45, le voile
   renforcé des pages villas ressortait trop léger (jusqu’à +18 sur 255 en bas de la photo). */
.ep-clair .villa-hero__media::after {
  background: linear-gradient(180deg, rgb(47 47 46 / calc(var(--voile-haut) * 0.65)) 0%, rgb(47 47 46 / 0) 24%, rgb(47 47 46 / 0) 46%, rgb(47 47 46 / calc(var(--voile-bas) * 0.65)) 100%);
}

/* Dessins d’étude : la version sur papier crème (plus de « multiply » possible) */
.clair-seul { display: none; }
.ep-clair .jour-seul { display: none; }
.ep-clair .clair-seul { display: block; }
.ep-clair .lieu__image--trait img,
.ep-clair .interstitial--trait .interstitial__media img { mix-blend-mode: normal; }

/* Logo sombre : dessiné par un masque sur une tuile de sa couleur (clair.js) */
.ep-logo-masque {
  background-image: var(--ep-tuile) !important;
  -webkit-mask: url(/assets/logo.svg) center / 100% 100% no-repeat;
          mask: url(/assets/logo.svg) center / 100% 100% no-repeat;
}
.ep-logo-masque use { visibility: hidden; }

/* Photos dessinées (clair.js) : l’image d’origine laisse sa place au canevas */
.ep-img-source { display: none !important; }
