/* ==========================================================================
   ENDEVELOPMENT · one-page site
   --------------------------------------------------------------------------
   Colours: sampled from the swatches of the charte graphique (p. 36). The HEX
   printed under all five swatches (#2E5895, a blue) matches none of them and is
   a layout error in the PDF, so the visible swatch colour is the reference.
   Type: Old Standard TT (logo-style display, p. 40), Inter (web titles, p. 41),
   Montserrat (texts, p. 42–44).

   Progressive enhancement: every rule outside `.is-*` states describes the
   static page (no JavaScript, or prefers-reduced-motion). main.js adds the
   `.is-*` classes that turn sections into pinned, scroll-driven scenes, so any
   element hidden for an animation is hidden by script, never by CSS alone.
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root {
  --blanc: #FFFFFF;
  --gris-clair: #D4D4D4;
  --gris-cendre: #4F4F4F;
  --anthracite: #323331;
  --graphite: #2C2E35;

  /* Tints from the "Dégradés de couleurs" page (100/80/60/40/20 %) */
  --gris-clair-40: #EEEEEE;
  --gris-clair-20: #F6F6F6;

  /* The only colour the charte actually names (p. 36). It is kept for one job:
     the accent that answers a focus or a hover on an interactive element. */
  --bleu: #2E5895;
  /* A warm off-white, the single non-neutral tint in the type: it marks the
     card a cursor is on in "Savoir-faire", nothing else. */
  --creme: #E8E0D2;

  /* Glass, one recipe. The navigation capsule, the nuit/jour switch, the plan
     buttons and the social buttons of the contact page all read these, so they
     cannot drift apart; the "on-light" set is the same glass, inverted. */
  --glass-blur: blur(20px) saturate(1.25);
  --glass-on-dark: rgba(255, 255, 255, .12);
  --glass-on-dark-line: rgba(255, 255, 255, .17);
  --glass-on-dark-hi: rgba(255, 255, 255, .22);
  --glass-on-light: rgba(44, 46, 53, .05);
  --glass-on-light-line: rgba(44, 46, 53, .13);
  --glass-on-light-hi: rgba(44, 46, 53, .1);
  /* Pop-overs float over photographs with no scrim of their own, so they take
     a denser version of the same glass. */
  --glass-panel-on-dark: rgba(26, 27, 32, .66);
  --glass-panel-on-light: rgba(255, 255, 255, .8);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-strong: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  --font-display: "Old Standard TT", "Times New Roman", Times, serif;
  --font-ui: "Inter", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Montserrat", "Helvetica Neue", Arial, sans-serif;

  --gutter: clamp(16px, 4.2vw, 72px);
  --maxw: 1440px;
  --header-h: 88px;

  /* z-index scale */
  --z-scene: 1;
  --z-header: 40;
  --z-grain: 60;
  --z-cursor: 70;
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--graphite);
}
html.lenis, html.lenis body { height: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent], .lenis [data-lenis-prevent-horizontal] { overscroll-behavior: contain; }

body {
  margin: 0;
  background: var(--graphite);
  color: var(--blanc);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-kerning: normal;
}

main { display: block; overflow: clip; }
img, video, canvas, svg { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; }
address { font-style: normal; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }

::selection { background: var(--anthracite); color: var(--blanc); }

:focus-visible {
  outline: 1px solid currentColor;
  outline-offset: 4px;
}

.skip {
  position: absolute;
  left: var(--gutter);
  top: 12px;
  z-index: calc(var(--z-cursor) + 1);
  padding: 12px 18px;
  background: var(--blanc);
  color: var(--anthracite);
  font: 600 12px/1 var(--font-ui);
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
}
/* visible only while focused from the keyboard */
.skip:not(:focus) {
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.skip:focus-visible { outline-color: var(--anthracite); }
.skip--film { position: absolute; top: calc(var(--header-h) + 12px); }

.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- 3. Section heading (the charte's "LOGOTYPE ——— Variations" bar) ---------- */
.shead {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 32px);
  max-width: var(--maxw);
  margin-inline: auto;
}
.shead__title {
  font: 800 clamp(1.125rem, 1.9vw, 1.75rem)/1 var(--font-ui);
  letter-spacing: .16em;
  text-transform: uppercase;
}
.shead__rule {
  flex: 1 1 24px;
  height: 1px;
  background: currentColor;
  opacity: .42;
  transform-origin: left center;
}
.shead__label {
  font: 300 clamp(.95rem, 1.25vw, 1.25rem)/1.2 var(--font-body);
  white-space: nowrap;
}
.shead__link { text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 2px; transition: opacity 300ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .shead__link:hover { opacity: .64; }
}

/* ---------- 4. Header ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 var(--gutter);
  color: var(--blanc);
  pointer-events: none;
  /* One set of glass values for the whole page: the capsule, the nuit/jour
     switch and the social buttons of the contact page all read from here, so
     they cannot drift apart. They flip with the section the header sits over. */
  --glass-bg: var(--glass-on-dark);
  --glass-line: var(--glass-on-dark-line);
  --glass-hi: var(--glass-on-dark-hi);
  --glass-panel: var(--glass-panel-on-dark);
  transition: transform 600ms var(--ease-out), color 400ms var(--ease-out);
}
.site-header > * { pointer-events: auto; }
.site-header[data-theme="light"] {
  color: var(--anthracite);
  --header-scrim: rgba(255, 255, 255, .92);
  --glass-bg: var(--glass-on-light);
  --glass-line: var(--glass-on-light-line);
  --glass-hi: var(--glass-on-light-hi);
  --glass-panel: var(--glass-panel-on-light);
}
.site-header.is-hidden { transform: translate3d(0, -110%, 0); }
/* Once the header floats over content instead of the first screen, a soft scrim
   keeps the monogram and the links readable above photographs and text. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0 0 -28px;
  z-index: -1;
  background: linear-gradient(to bottom, var(--header-scrim, rgba(44, 46, 53, .82)), transparent);
  opacity: 0;
  transition: opacity 400ms var(--ease-out);
  pointer-events: none;
}
.site-header.is-floating::before { opacity: 1; }

.brand {
  position: relative;
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  color: inherit;
  flex: none;
}
/* Logo symbole at its charte minimum (56 px), untouched; the progress ring
   sits outside it with its own clear space and is a separate UI element. */
.brand__symbol { width: 56px; height: 56px; fill: currentColor; }
.brand__ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  overflow: visible;
}
.brand__ring circle { fill: none; stroke: currentColor; stroke-width: 1; }
.brand__track { opacity: .16; }
.brand__progress { stroke-dasharray: 1 1; stroke-dashoffset: 1; }

/* The glass capsule ------------------------------------------------------- */
.capsule {
  display: flex;
  align-items: center;
  gap: clamp(4px, .8vw, 10px);
  min-width: 0;
  padding: 5px;
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  transition: background 400ms var(--ease-out), border-color 400ms var(--ease-out);
}
.capsule__rule {
  flex: none;
  width: 1px;
  height: 22px;
  background: currentColor;
  opacity: .22;
}

.nav { position: relative; min-width: 0; }
.nav > ul { display: flex; align-items: center; }
.nav__item { position: relative; display: flex; align-items: center; }
.nav a {
  position: relative;
  display: block;
  padding: 11px clamp(10px, 1.4vw, 20px);
  border-radius: 999px;
  font: 600 12px/1 var(--font-ui);
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  opacity: .72;
  transition: opacity 320ms var(--ease-out);
}
.nav a[aria-current] { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .nav a:hover { opacity: 1; }
}
.nav a:focus-visible { opacity: 1; outline-offset: -3px; }
/* The pill behind the current item. Its width has to follow the label, so this
   is the one place on the page where a size is animated — a single element,
   out of flow, so it costs no layout anywhere else. */
.nav__pill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--pill-w, 0px);
  border-radius: 999px;
  background: var(--glass-hi);
  opacity: var(--pill-o, 0);
  transform: translate3d(var(--pill-x, 0px), 0, 0);
  transition: transform 560ms var(--ease-strong), width 560ms var(--ease-strong), opacity 320ms var(--ease-out);
  pointer-events: none;
}

/* The chevron that opens the home page's own sections. It is a second,
   smaller control inside the Accueil pill: the label still goes to the top of
   the home page, the chevron opens the list. */
.nav__more {
  display: grid;
  place-items: center;
  width: 22px;
  height: 30px;
  margin-left: -8px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  color: inherit;
  opacity: .58;
  cursor: pointer;
  transition: opacity 300ms var(--ease-out), rotate 360ms var(--ease-strong);
}
.nav__more svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.nav__more[aria-expanded="true"] { opacity: 1; rotate: 180deg; }
@media (hover: hover) and (pointer: fine) {
  .nav__more:hover { opacity: 1; }
}

.submenu {
  position: absolute;
  top: calc(100% + 14px);
  left: -6px;
  z-index: 2;
  min-width: 210px;
  padding: 8px;
  border: 1px solid var(--glass-line);
  border-radius: 20px;
  background: var(--glass-panel);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  box-shadow: 0 24px 50px -30px rgba(12, 13, 16, .6);
  opacity: 0;
  visibility: hidden;
  translate: 0 -8px;
  transition: opacity 260ms var(--ease-out), translate 300ms var(--ease-out), visibility 0s linear 300ms;
}
.nav__item--menu.is-open .submenu {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition-delay: 0s;
}
.submenu li { display: block; }
.submenu a {
  display: block;
  padding: 10px 14px;
  border-radius: 999px;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  opacity: .74;
  transition: opacity 260ms var(--ease-out), background-color 260ms var(--ease-out);
}
.submenu a[aria-current] { opacity: 1; background: var(--glass-hi); }
@media (hover: hover) and (pointer: fine) {
  .submenu a:hover { opacity: 1; background: var(--glass-hi); }
}
.submenu a:focus-visible { opacity: 1; outline-offset: -3px; }

/* The nuit / jour switch -------------------------------------------------- */
.daynight {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--glass-line);
  border-radius: 50%;
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  color: inherit;
  cursor: pointer;
  transition: background 320ms var(--ease-out), border-color 320ms var(--ease-out), scale 320ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .daynight:hover { background: var(--glass-hi); scale: 1.05; }
}
.daynight:active { scale: .97; }
.daynight.is-busy { cursor: progress; }
.daynight__label {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.daynight__faces { position: relative; display: block; width: 22px; height: 22px; }
.daynight__face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity 400ms var(--ease-out), rotate 420ms var(--ease-strong), scale 420ms var(--ease-strong);
}
.daynight__sky circle { fill: currentColor; stroke: none; }
.daynight__face--nuit .daynight__sky path { fill: currentColor; stroke: none; }
.daynight__sky { opacity: .9; }
.daynight[data-state="nuit"] .daynight__face--jour,
.daynight[data-state="jour"] .daynight__face--nuit {
  opacity: 0;
  rotate: -32deg;
  scale: .72;
}
.daynight[data-state="jour"] .daynight__face--nuit { rotate: 32deg; }
/* While the clip runs, the ring traces how far the sun has come up. */
.daynight__progress {
  position: absolute;
  inset: -1px;
  width: calc(100% + 2px);
  height: calc(100% + 2px);
  transform: rotate(-90deg);
  opacity: 0;
  transition: opacity 240ms var(--ease-out);
}
.daynight__progress circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
}
.daynight.is-busy .daynight__progress { opacity: .85; }

/* ---------- 5. Hero ---------- */
.hero {
  position: relative;
  height: 100svh;
  min-height: 560px;
  overflow: clip;
  background: var(--graphite);
  color: var(--blanc);
  perspective: 1400px;
}
.hero__media {
  position: absolute;
  inset: -3%;
  transform-origin: 50% 45%;
  will-change: transform;
}
/* Three layers, one framing: the night still (it carries the first paint, and
   the whole hero when there is no JavaScript), the day still, and the clip the
   nuit/jour switch drives. Under prefers-reduced-motion the clip never loads
   and the switch cross-fades the two stills instead. */
.hero__img, .hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* the villa fills the upper two thirds, the dark lawn below carries the logo */
  object-position: 50% 60%;
  transform: scale(1.06);
  will-change: transform;
}
.hero__img--jour, .hero__video { opacity: 0; transition: opacity 760ms var(--ease-out); }
.hero.is-video .hero__video { opacity: 1; }
.hero.is-stills.is-jour .hero__img--jour { opacity: 1; }
.hero__veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(44, 46, 53, .55) 0%, rgba(44, 46, 53, 0) 20%, rgba(44, 46, 53, 0) 42%, rgba(44, 46, 53, .62) 60%, rgba(44, 46, 53, .9) 100%);
  pointer-events: none;
}
.hero__content {
  position: absolute;
  inset: auto 0 0 0;
  display: grid;
  justify-items: center;
  gap: clamp(22px, 3.6vh, 40px);
  padding: 0 var(--gutter) clamp(88px, 12vh, 132px);
  text-align: center;
}
.hero__logo img {
  width: clamp(240px, 32vw, 480px);
  height: auto;
  aspect-ratio: 390.9 / 114.1;
  /* clear space around the mark (charte p. 29) */
  margin: 8px;
}
.hero__line { display: block; }
.hero__line--lead {
  font: 400 clamp(1.25rem, 2vw, 1.75rem)/1.3 var(--font-display);
  letter-spacing: .01em;
}
.hero__line--sub {
  margin-top: 14px;
  font: 600 clamp(.625rem, .78vw, .75rem)/1.9 var(--font-ui);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gris-clair);
  max-width: 62ch;
}
.hero__scroll {
  position: absolute;
  left: 50%;
  bottom: 24px;
  width: 1px;
  height: 56px;
  margin-left: -.5px;
  overflow: hidden;
  background: rgba(255, 255, 255, .22);
}
.hero__scroll::before { content: ""; position: absolute; inset: -12px -20px; }
.hero__scroll span {
  position: absolute;
  inset: 0;
  background: var(--blanc);
  transform: translate3d(0, -100%, 0);
  animation: cue 2.4s var(--ease-in-out) infinite;
}
@keyframes cue {
  0% { transform: translate3d(0, -100%, 0); }
  55% { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(0, 100%, 0); }
}

/* ---------- 6. Film (PROLIT) ---------- */
.film {
  position: relative;
  z-index: var(--z-scene);
  background: var(--graphite);
  color: var(--blanc);
}

/* Static storyboard (no JS / reduced motion) */
.film__stage { padding: calc(var(--header-h) + 40px) var(--gutter) clamp(72px, 12vh, 140px); }
.film__media {
  position: relative;
  max-width: 1200px;
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  background: #000;
}
.film__poster { display: none; }
.film__video { width: 100%; height: 100%; object-fit: cover; }
.film__scrim, .film__hud, .film__rail, .film__loader { display: none; }
.film__title {
  max-width: 1200px;
  margin: 40px auto 0;
  font: 400 clamp(2rem, 4vw, 3.5rem)/1.1 var(--font-display);
}
.film__title span {
  display: block;
  margin-top: 10px;
  font: 600 12px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-clair);
}
.film__chapters {
  max-width: 1200px;
  margin: 40px auto 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: 48px 32px;
}
.chapter__still { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.chapter__name {
  margin-top: 18px;
  display: flex;
  justify-content: space-between;
  font: 700 12px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
}
.chapter__name span { font-weight: 600; color: var(--gris-clair); letter-spacing: .08em; }
.chapter__body { margin-top: 12px; display: grid; gap: 8px; }

.beat { display: block; }
.beat--display { font: 400 1.5rem/1.2 var(--font-display); }
.beat--title { font: 400 1.75rem/1.1 var(--font-display); }
.beat--room { font: 400 1.5rem/1.15 var(--font-display); }
.beat--quote { font: 400 1.125rem/1.45 var(--font-display); display: inline; }
.beat--label {
  font: 600 11px/1.5 var(--font-ui);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--gris-clair);
}
.beat--sub { font: 300 .9375rem/1.5 var(--font-body); color: var(--gris-clair); }
.beat--sign {
  font: 700 11px/1.5 var(--font-ui);
  letter-spacing: .22em;
  text-transform: uppercase;
}
.beat--sign span {
  display: block;
  font-weight: 600;
  letter-spacing: .16em;
  color: var(--gris-clair);
}
.beat--logo { width: min(260px, 70%); height: auto; aspect-ratio: 390.9 / 114.1; fill: var(--blanc); margin: 8px 0; }
.beat--cta {
  position: relative;
  justify-self: start;
  display: inline-block;
  padding: 12px 0;
  font: 600 12px/1 var(--font-ui);
  letter-spacing: .22em;
  text-transform: uppercase;
  text-decoration: none;
}
.beat--cta::after {
  content: "";
  position: absolute;
  left: 0; right: .22em; bottom: 4px;
  height: 1px;
  background: currentColor;
  transform-origin: left center;
}

/* Scroll-scrubbed mode */
.film.is-scrub .film__track { height: calc(var(--film-screens, 16) * 100svh); }
.film.is-scrub .film__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  padding: 0;
  overflow: clip;
}
.film.is-scrub .film__media {
  position: absolute;
  inset: 0;
  max-width: none;
  aspect-ratio: auto;
  overflow: hidden;
  background: var(--graphite);
}
.film.is-scrub .film__poster,
.film.is-scrub .film__video {
  display: block;
  position: absolute;
  left: 50%;
  top: 50%;
  /* exactly 16:9 and never smaller than the screen: cover, but panned by transform */
  width: max(100vw, 177.78svh);
  height: max(100svh, 56.25vw);
  max-width: none;
  object-fit: cover;
  transform: translate(-50%, -50%);
  will-change: transform;
}
.film.is-scrub .film__video { opacity: 0; transition: opacity 600ms var(--ease-out); }
.film.is-scrub .film__video.is-ready { opacity: 1; }
.film.is-scrub .film__scrim {
  display: block;
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(44, 46, 53, .42) 0%, rgba(44, 46, 53, 0) 18%),
    linear-gradient(to top, rgba(44, 46, 53, .8) 0%, rgba(44, 46, 53, .38) 28%, rgba(44, 46, 53, 0) 52%);
}
.film__veil { display: none; }
.film.is-scrub .film__veil {
  display: block;
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 75% 65% at 50% 50%, rgba(44, 46, 53, .66), rgba(44, 46, 53, .42));
}
.film.is-scrub .film__veil--soft {
  background: radial-gradient(ellipse 60% 50% at 50% 50%, rgba(44, 46, 53, .36), rgba(44, 46, 53, 0));
}
.film.is-scrub .film__title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); margin: 0; }
.film.is-scrub .film__chapters {
  position: absolute;
  inset: 0;
  max-width: none;
  margin: 0;
  display: block;
  pointer-events: none;
}
.film.is-scrub .chapter { position: absolute; inset: 0; }
.film.is-scrub .chapter__still,
.film.is-scrub .chapter__name { display: none; }
.film.is-scrub .chapter__body {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: clamp(104px, 15vh, 160px);
  margin: 0;
  gap: 14px;
  max-width: 820px;
}
.film.is-scrub .chapter__body--center {
  left: 50%;
  right: auto;
  bottom: 50%;
  width: min(92vw, 900px);
  transform: translate(-50%, 50%);
  justify-items: center;
  text-align: center;
}
.film.is-scrub .chapter__body--quote { max-width: min(880px, 78vw); gap: 22px; }
.film.is-scrub .chapter__body--finale {
  left: 50%;
  right: auto;
  bottom: 50%;
  width: min(92vw, 640px);
  transform: translate(-50%, 50%);
  justify-items: center;
  gap: clamp(28px, 5vh, 48px);
}
.film.is-scrub .beat { will-change: opacity, transform; }
.film.is-scrub .beat--display { font-size: clamp(2rem, 5vw, 4.75rem); line-height: 1.05; letter-spacing: -.005em; }
.film.is-scrub .beat--title { font-size: clamp(2.5rem, 6vw, 5.5rem); line-height: 1; }
.film.is-scrub .beat--room { font-size: clamp(2rem, 4.2vw, 3.75rem); line-height: 1.05; }
.film.is-scrub .beat--quote { display: block; font-size: clamp(1.375rem, 2.7vw, 2.5rem); line-height: 1.28; }
.film.is-scrub .beat--quote + .beat--quote { margin-top: .35em; }
.film.is-scrub .beat--sub { font-size: clamp(.9375rem, 1.2vw, 1.125rem); color: var(--blanc); opacity: .9; }
.film.is-scrub .beat--label { color: var(--blanc); }
.film.is-scrub .beat--logo { width: clamp(240px, 30vw, 440px); }
.film.is-scrub .beat--cta { justify-self: center; pointer-events: auto; }

/* HUD: chapter name, timecode, tick rail */
.film.is-scrub .film__hud {
  display: flex;
  position: absolute;
  right: calc(var(--gutter) + 36px);
  bottom: clamp(30px, 5vh, 48px);
  gap: 22px;
  align-items: baseline;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .9);
}
.hud__time { font-variant-numeric: tabular-nums; letter-spacing: .08em; color: rgba(255, 255, 255, .62); }
.hud__now { color: var(--blanc); }

.film.is-scrub .film__rail {
  display: flex;
  flex-direction: column;
  position: absolute;
  right: var(--gutter);
  top: 50%;
  width: 20px;
  height: min(58vh, 540px);
  transform: translateY(-50%);
}
.rail__seg {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
  padding: 4px 0;
}
.rail__tick {
  display: block;
  width: 6px;
  height: 1px;
  background: rgba(255, 255, 255, .45);
  transition: background-color 300ms var(--ease-out);
}
.rail__tick:first-child { width: 14px; background: rgba(255, 255, 255, .6); }
.rail__seg.is-active .rail__tick { background: var(--blanc); }
.rail__head {
  position: absolute;
  right: 0;
  top: 0;
  width: 20px;
  height: 1px;
  background: var(--blanc);
  will-change: transform;
}

.film.is-scrub .film__loader {
  display: flex;
  position: absolute;
  left: var(--gutter);
  bottom: clamp(30px, 5vh, 48px);
  align-items: center;
  gap: 14px;
  font: 600 10px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .7);
  opacity: 0;
  transition: opacity 400ms var(--ease-out);
}
.film.is-waiting .film__loader { opacity: 1; }
.film__loader-bar {
  position: relative;
  width: 96px;
  height: 1px;
  overflow: hidden;
  background: rgba(255, 255, 255, .22);
}
.film__loader-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--blanc);
  transform: scaleX(var(--loaded, 0));
  transform-origin: left center;
}

/* ---------- 7. Réalisations: presenter scene ---------- */
.realisations { position: relative; z-index: 2; background: var(--blanc); color: var(--anthracite); }
.presenter { position: relative; background: var(--blanc); }

/* Static layout: presenter beside the mosaic */
.presenter__stage {
  position: relative;
  display: grid;
  grid-template-columns: minmax(200px, 28%) 1fr;
  grid-template-areas:
    "head head"
    "figure mosaic"
    "caption caption";
  gap: 32px clamp(24px, 4vw, 64px);
  padding: calc(var(--header-h) + 48px) var(--gutter) clamp(48px, 8vh, 96px);
  max-width: var(--maxw);
  margin: 0 auto;
}
.presenter__bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  /* fades to pure white at the bottom, where the stage meets the page */
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 62%, transparent 96%);
}
.blob {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(212, 212, 212, .55), rgba(212, 212, 212, 0));
  will-change: transform;
}
.blob--1 { width: 70vmax; height: 70vmax; left: -22vmax; top: -30vmax; animation: drift1 26s var(--ease-in-out) infinite alternate; }
.blob--2 { width: 60vmax; height: 60vmax; right: -24vmax; bottom: -30vmax; animation: drift2 32s var(--ease-in-out) infinite alternate; }
.blob--3 { width: 38vmax; height: 38vmax; left: 38%; top: 30%; opacity: .7; animation: drift3 22s var(--ease-in-out) infinite alternate; }
@keyframes drift1 { to { transform: translate3d(14vmax, 10vmax, 0) scale(1.08); } }
@keyframes drift2 { to { transform: translate3d(-12vmax, -8vmax, 0) scale(.94); } }
@keyframes drift3 { to { transform: translate3d(-10vmax, 8vmax, 0) scale(1.12); } }
.motes { position: absolute; inset: 0; }
.motes i {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--gris-clair);
  opacity: 0;
  animation: mote 14s linear infinite;
}
.motes i:nth-child(1)  { left: 8%;  top: 82%; animation-delay: -1s; }
.motes i:nth-child(2)  { left: 16%; top: 64%; animation-delay: -7s; width: 2px; height: 2px; }
.motes i:nth-child(3)  { left: 24%; top: 90%; animation-delay: -3s; }
.motes i:nth-child(4)  { left: 33%; top: 72%; animation-delay: -11s; width: 4px; height: 4px; }
.motes i:nth-child(5)  { left: 41%; top: 86%; animation-delay: -5s; width: 2px; height: 2px; }
.motes i:nth-child(6)  { left: 52%; top: 78%; animation-delay: -9s; }
.motes i:nth-child(7)  { left: 60%; top: 94%; animation-delay: -2s; width: 4px; height: 4px; }
.motes i:nth-child(8)  { left: 67%; top: 70%; animation-delay: -12s; width: 2px; height: 2px; }
.motes i:nth-child(9)  { left: 74%; top: 88%; animation-delay: -6s; }
.motes i:nth-child(10) { left: 81%; top: 66%; animation-delay: -10s; width: 2px; height: 2px; }
.motes i:nth-child(11) { left: 88%; top: 84%; animation-delay: -4s; width: 4px; height: 4px; }
.motes i:nth-child(12) { left: 94%; top: 74%; animation-delay: -8s; }
.motes i:nth-child(13) { left: 12%; top: 96%; animation-delay: -13s; width: 2px; height: 2px; }
.motes i:nth-child(14) { left: 46%; top: 60%; animation-delay: -0.5s; }
@keyframes mote {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  15% { opacity: .9; }
  85% { opacity: .6; }
  100% { transform: translate3d(3vw, -55vh, 0); opacity: 0; }
}

.presenter__head { grid-area: head; position: relative; z-index: 4; margin-inline: 0; max-width: none; }
.presenter__film { display: none; }
.presenter__figure {
  grid-area: figure;
  position: relative;
  z-index: 2;
  align-self: end;
  justify-self: center;
  width: 100%;
  max-width: 360px;
}
.presenter__figure img { width: auto; height: auto; aspect-ratio: 331 / 950; max-height: min(72vh, 680px); margin: 0 auto; }

.mosaic {
  grid-area: mosaic;
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: clamp(8px, .9vw, 14px);
  height: clamp(420px, 66vh, 720px);
}
.tile--b { grid-column: 1 / 3; grid-row: 1; }
.tile--c { grid-column: 3; grid-row: 1 / 3; }
.tile--d { grid-column: 4; grid-row: 1; }
.tile--e { grid-column: 1; grid-row: 2; }
.tile--f { grid-column: 2; grid-row: 2; }
.tile--g { grid-column: 4; grid-row: 2; }

.tile {
  position: relative;
  overflow: hidden;
  background: var(--gris-clair-40);
  outline-offset: 3px;
}
.tile__img, .tile__alt {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1000ms var(--ease-out);
}
.tile__alt { opacity: 0; }
.tile__cap, .shot__cap span, .estate__slide {
  transition: transform 460ms var(--ease-out), opacity 460ms var(--ease-out);
}
.tile__cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 36px 16px 14px;
  font: 600 11px/1.3 var(--font-ui);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--blanc);
  background: linear-gradient(to top, rgba(44, 46, 53, .78), rgba(44, 46, 53, 0));
  transform: translate3d(0, 100%, 0);
}
@media (hover: hover) and (pointer: fine) {
  .tile:hover .tile__img, .tile:hover .tile__alt { transform: scale(1.07); }
  .tile:hover .tile__cap { transform: none; }
}
.tile.is-active .tile__img, .tile.is-active .tile__alt { transform: scale(1.07); }
.tile:focus-visible .tile__cap, .tile.is-active .tile__cap { transform: none; }

.presenter__caption {
  grid-area: caption;
  position: relative;
  z-index: 4;
  font: 600 12px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.presenter__caption span {
  display: block;
  margin-bottom: 6px;
  font: 400 clamp(1.5rem, 2.4vw, 2.25rem)/1.1 var(--font-display);
  letter-spacing: 0;
  text-transform: none;
  color: var(--anthracite);
}

/* Live (pinned, scroll-driven) presenter scene */
.presenter.is-live { margin-top: -100svh; }
.presenter.is-live .presenter__track { height: 340svh; }
.presenter.is-live .presenter__stage {
  position: sticky;
  top: 0;
  display: block;
  height: 100svh;
  max-width: none;
  padding: 0;
  overflow: clip;
  /* Transparent while it slides over the film's last pinned screen; switched on
     (.is-on) in the very frame where both stages meet at the top, so the film's
     last frame is replaced by an identical card without a visible seam. */
  background: transparent;
  pointer-events: none;
}
.presenter.is-live { background: transparent; }
/* the section starts one screen early (it overlaps the film), so that screen stays see-through */
.realisations.has-live-presenter {
  background: linear-gradient(to bottom, transparent 0, transparent 100svh, var(--blanc) 100svh);
}
.presenter.is-live .presenter__bg,
.presenter.is-live .presenter__film { visibility: hidden; }
.presenter.is-live.is-on .presenter__stage { background: var(--blanc); pointer-events: auto; }
.presenter.is-live.is-on .presenter__bg,
.presenter.is-live.is-on .presenter__film { visibility: visible; }
.presenter.is-live .presenter__head {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: calc(var(--header-h) + 10px);
}
.presenter.is-live .presenter__film {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  will-change: transform;
}
.presenter.is-live .presenter__film img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(100vw, 177.78svh);
  height: max(100svh, 56.25vw);
  max-width: none;
  object-fit: cover;
  transform: translate(-50%, -50%) translateX(var(--end-pan, 0px));
}
.presenter.is-live .presenter__figure {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: auto;
  max-width: none;
  height: 80svh;
  margin-left: calc(80svh * -0.1742);
}
.presenter.is-live .presenter__figure img { height: 100%; width: auto; aspect-ratio: 331 / 950; }
.presenter.is-live .mosaic {
  position: absolute;
  left: clamp(300px, 35vw, 620px);
  right: var(--gutter);
  top: calc(var(--header-h) + 124px);
  bottom: 7svh;
  height: auto;
}
.presenter.is-live .tile { z-index: 1; will-change: transform, opacity; }
.presenter.is-live .tile--c,
.presenter.is-live .tile--e { z-index: 3; }
.presenter.is-live .presenter__caption {
  position: absolute;
  left: clamp(300px, 35vw, 620px);
  right: var(--gutter);
  top: calc(var(--header-h) + 64px);
}
.presenter.is-live .presenter__caption span { display: inline; margin: 0 14px 0 0; }

/* ---------- 8. Villa Lestòbi ---------- */
.villa {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 6vw, 120px);
  align-items: end;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(96px, 16vh, 180px) var(--gutter) clamp(48px, 8vh, 88px);
  color: var(--anthracite);
}
.villa__name {
  font: 400 clamp(2.75rem, 6vw, 5.75rem)/1 var(--font-display);
  letter-spacing: -.01em;
}
.villa__place {
  margin-top: 22px;
  font: 600 12px/1.5 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.villa__lead {
  font: 300 clamp(1.125rem, 1.55vw, 1.4rem)/1.6 var(--font-body);
  max-width: 38ch;
}

.specs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px clamp(20px, 3vw, 44px);
  margin-top: 44px;
}
.specs > div { padding-top: 14px; border-top: 1px solid var(--gris-clair); }
.specs dt {
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.specs dd {
  margin-top: 10px;
  font: 400 clamp(1.25rem, 1.7vw, 1.625rem)/1.2 var(--font-display);
}
.specs--compact { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 28px; gap: 22px 28px; }
.specs--compact dd { font-size: 1.1875rem; }

/* ---------- 9. Gallery (horizontal) ---------- */
.gallery { position: relative; background: var(--blanc); padding-bottom: clamp(72px, 12vh, 140px); }
.gallery__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x pan-y pinch-zoom;
}
.gallery__viewport.is-dragging { scroll-snap-type: none; }
/* how far along the strip the visitor is; also shows that it can be dragged */
.gallery__bar {
  position: relative;
  height: 1px;
  margin: clamp(18px, 3vh, 32px) var(--gutter) 0;
  background: var(--gris-clair);
  overflow: hidden;
}
.gallery__bar span {
  position: absolute;
  inset: 0;
  background: var(--anthracite);
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
}
.gallery__viewport::-webkit-scrollbar { display: none; }
.gallery__track {
  display: flex;
  align-items: flex-end;
  user-select: none;
  -webkit-user-drag: none;
  gap: clamp(16px, 2vw, 32px);
  width: max-content;
  padding: 0 var(--gutter);
}
.shot {
  flex: none;
  width: clamp(260px, 40vw, 640px);
  scroll-snap-align: center;
  outline-offset: 4px;
}
.shot--tall { width: clamp(220px, 27vw, 440px); }
.shot__frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--gris-clair-40);
}
.shot--tall .shot__frame { aspect-ratio: 4 / 5; }
.shot__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.01);
  transition: transform 1000ms var(--ease-out);
}
.shot__cap {
  overflow: hidden;
  margin-top: 14px;
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.shot__cap span { display: inline-block; transform: translate3d(0, 110%, 0); }
@media (hover: hover) and (pointer: fine) {
  .shot:hover .shot__frame img { transform: scale(1.07); }
  .shot:hover .shot__cap span { transform: none; }
}
.shot.is-active .shot__frame img { transform: scale(1.07); }
.shot:focus-visible .shot__cap span, .shot.is-active .shot__cap span { transform: none; }

.gallery__label {
  max-width: var(--maxw);
  margin: 0 auto 28px;
  padding: 0 var(--gutter);
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.gallery__label span { color: var(--anthracite); margin-right: 14px; }

.gallery.is-pinned .gallery__viewport { overflow: visible; scroll-snap-type: none; }
.gallery.is-pinned .gallery__pin {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: clip;
}
.gallery.is-pinned .gallery__label { margin: 0 0 3vh; max-width: none; }
.gallery.is-pinned .gallery__bar { margin-top: 4vh; }
.gallery.is-pinned .gallery__track { will-change: transform; }
.gallery.is-pinned .shot { width: auto; }
.gallery.is-pinned .shot__frame { height: min(62svh, 640px); width: auto; }
.gallery.is-pinned .shot--tall .shot__frame { height: min(70svh, 720px); }

/* ---------- 10. Du tracé à la réalité (0916) ---------- */
.trace { background: var(--blanc); color: var(--anthracite); }
.trace__stage {
  display: grid;
  gap: 24px;
  padding: clamp(72px, 12vh, 140px) var(--gutter);
  max-width: var(--maxw);
  margin: 0 auto;
}
.trace__title { font: 400 clamp(2.25rem, 5vw, 4.5rem)/1.04 var(--font-display); letter-spacing: -.005em; }
.trace__title span { display: inline-block; }
.trace__frame { position: relative; }
.trace__static { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.trace__static img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.trace__canvas, .trace__edge { display: none; }
.trace__caption {
  font: 600 11px/1.5 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}

.trace.is-scrub .trace__track { height: 330svh; }
.trace.is-scrub .trace__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  max-width: none;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: clamp(10px, 1.6vh, 18px);
  padding: calc(var(--header-h) + 4px) var(--gutter) clamp(14px, 2.4vh, 26px);
  overflow: clip;
}
.trace.is-scrub .trace__title { font-size: clamp(2rem, 4.2vw, 3.75rem); }
.trace.is-scrub .trace__static { display: none; }
.trace.is-scrub .trace__canvas {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.trace.is-scrub .trace__edge {
  display: block;
  position: absolute;
  inset: -1px;
  pointer-events: none;
  box-shadow: inset 0 0 48px 36px var(--blanc);
  will-change: opacity;
}
.trace.is-scrub .trace__a, .trace.is-scrub .trace__b { will-change: opacity, transform; }

/* ---------- 11. Mougins estates ---------- */
.domaines {
  background: linear-gradient(to bottom, var(--blanc), var(--gris-clair-20) 40%);
  padding: clamp(96px, 16vh, 180px) var(--gutter) clamp(72px, 12vh, 140px);
  color: var(--anthracite);
}
.estates {
  display: grid;
  gap: clamp(64px, 11vh, 120px);
  max-width: var(--maxw);
  margin: clamp(48px, 8vh, 88px) auto 0;
}
.estate { display: grid; gap: 26px; align-content: start; }
.estate--wide { grid-template-columns: 1.4fr 1fr; gap: clamp(28px, 5vw, 88px); align-items: end; }
.estates__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px clamp(24px, 4vw, 64px);
}
.estates__pair .estate:last-child { margin-top: clamp(0px, 10vh, 120px); }
.estates__pair-note {
  grid-column: 1 / -1;
  max-width: 34ch;
  font: 400 clamp(1.375rem, 2.2vw, 2rem)/1.25 var(--font-display);
}
.estate__visual {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  background: linear-gradient(140deg, var(--graphite) 0%, var(--anthracite) 55%, var(--gris-cendre) 130%);
  color: var(--blanc);
  outline-offset: 4px;
}
.estate--wide .estate__visual { aspect-ratio: 16 / 10; }
.estate__figure {
  font: 400 clamp(3rem, 7vw, 6rem)/1 var(--font-display);
  letter-spacing: -.01em;
  transition: transform 1000ms var(--ease-out);
}
.estate__figure small { font-size: .38em; letter-spacing: .02em; }
.estate__todo {
  position: absolute;
  top: 18px;
  left: 20px;
  font: 600 10px/1 var(--font-ui);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gris-clair);
}
.estate__slide {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: grid;
  gap: 4px;
  padding: 40px 20px 18px;
  font: 400 .9375rem/1.5 var(--font-body);
  background: linear-gradient(to top, rgba(44, 46, 53, .9), rgba(44, 46, 53, 0));
  transform: translate3d(0, 100%, 0);
}
@media (hover: hover) and (pointer: fine) {
  .estate__visual:hover .estate__figure { transform: scale(1.06); }
  .estate__visual:hover .estate__slide { transform: none; }
}
.estate__visual:focus-visible .estate__slide,
.estate__visual.is-active .estate__slide { transform: none; }
.estate__visual.is-active .estate__figure { transform: scale(1.06); }
.estate__name { font: 400 clamp(2rem, 3.6vw, 3.25rem)/1.05 var(--font-display); }
.estate__place {
  margin-top: 12px;
  font: 600 11px/1.5 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.estate__text { margin-top: 18px; font: 300 1.0625rem/1.65 var(--font-body); max-width: 44ch; }

/* ---------- 12. Grey-scale transitions between light and dark ---------- */
.fade { height: clamp(180px, 38vh, 440px); }
.fade--to-dark {
  background: linear-gradient(to bottom, var(--gris-clair-20) 0%, var(--gris-clair) 32%, var(--gris-cendre) 70%, var(--graphite) 100%);
}
.fade--to-light {
  margin-top: clamp(96px, 16vh, 180px);
  margin-inline: calc(var(--gutter) * -1);
  background: linear-gradient(to bottom, var(--graphite) 0%, var(--gris-cendre) 34%, var(--gris-clair) 70%, var(--blanc) 100%);
}

/* ---------- 13. Keywords marquee ---------- */
.keywords {
  position: relative;
  margin-top: -1px; /* covers the sub-pixel seam under the grey-scale fade */
  background: var(--graphite);
  color: var(--blanc);
  padding: clamp(40px, 9vh, 110px) var(--gutter);
  overflow: clip;
}
.marquee__track { display: flex; flex-wrap: wrap; justify-content: center; }
.marquee__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  row-gap: 6px;
}
.marquee__list[aria-hidden="true"] { display: none; }
.marquee__list li {
  display: flex;
  align-items: center;
  white-space: nowrap;
  font: 400 clamp(1.5rem, 3.4vw, 2.75rem)/1.2 var(--font-display);
}
/* the charte's square separator */
.marquee__list li::after {
  content: "";
  flex: none;
  width: .14em;
  height: .14em;
  margin: 0 .6em;
  background: var(--gris-cendre);
}
.marquee.is-running { margin-inline: calc(var(--gutter) * -1); }
.marquee.is-running .marquee__track { flex-wrap: nowrap; justify-content: flex-start; width: max-content; will-change: transform; }
.marquee.is-running .marquee__list { flex-wrap: nowrap; }
.marquee.is-running .marquee__list[aria-hidden="true"] { display: flex; }
.marquee.is-running .marquee__list li { font-size: clamp(2.5rem, 6.4vw, 6rem); line-height: 1.1; }

/* ---------- 14. Savoir-faire ---------- */
.pillars {
  position: relative;
  background: var(--graphite);
  color: var(--blanc);
  padding: clamp(80px, 13vh, 150px) var(--gutter) clamp(90px, 15vh, 170px);
}
.pillars__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 56px);
  max-width: var(--maxw);
  margin: clamp(48px, 9vh, 100px) auto 0;
  align-items: start;
  perspective: 1200px;
}
.pillar {
  position: relative;
  padding: clamp(28px, 3vw, 48px);
  border: 1px solid rgba(212, 212, 212, .16);
  transform-style: preserve-3d;
  will-change: transform;
}
.pillar:nth-child(2) { margin-top: clamp(32px, 9vh, 110px); }
.pillar:nth-child(3) { margin-top: clamp(64px, 18vh, 220px); }
.pillar__rule {
  display: block;
  width: 40px;
  height: 1px;
  background: var(--gris-clair);
  transform-origin: left center;
}
.pillar__title {
  margin-top: 28px;
  font: 400 clamp(1.75rem, 2.7vw, 2.625rem)/1.08 var(--font-display);
  transform: translateZ(28px);
}
.pillar__text {
  margin-top: 18px;
  font: 300 1.0625rem/1.65 var(--font-body);
  color: var(--gris-clair);
  max-width: 32ch;
  transform: translateZ(14px);
}

/* ---------- 15. Contact ---------- */
.contact {
  position: relative;
  margin-top: -1px; /* covers the sub-pixel seam under the grey-scale fade */
  background: var(--blanc);
  color: var(--anthracite);
  padding: clamp(40px, 8vh, 96px) var(--gutter) clamp(96px, 16vh, 180px);
}
.contact__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(48px, 8vw, 140px);
  max-width: var(--maxw);
  margin: clamp(48px, 9vh, 100px) auto 0;
}
.contact__lead { font: 400 clamp(2.25rem, 4.6vw, 4.25rem)/1.05 var(--font-display); max-width: 12ch; }
.contact__details { margin-top: clamp(32px, 6vh, 56px); }
.contact__details > div {
  display: grid;
  grid-template-columns: minmax(96px, 30%) 1fr;
  gap: 16px;
  align-items: baseline;
  padding: 16px 0;
  border-top: 1px solid var(--gris-clair);
}
.contact__details dt {
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.contact__details dd { font: 400 1.0625rem/1.5 var(--font-body); }
.contact__details a { text-decoration: none; background: linear-gradient(currentColor, currentColor) left bottom / 100% 1px no-repeat; }

.form { display: grid; align-content: start; }
.field { margin-bottom: 26px; }
.field__label {
  display: block;
  margin-bottom: 8px;
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
  transition: color 240ms var(--ease-out);
}
.field__control { position: relative; display: block; }
.field__control::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--anthracite);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 520ms var(--ease-out);
}
.field__input {
  display: block;
  width: 100%;
  padding: 10px 0 12px;
  border: 0;
  border-bottom: 1px solid #8A8A8A;
  border-radius: 0;
  background: transparent;
  color: var(--anthracite);
  font: 400 1.0625rem/1.5 var(--font-body);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.field__input--area { resize: vertical; min-height: 112px; }
.field:focus-within .field__control::after,
.field.is-invalid .field__control::after { transform: scaleX(1); }
.field:focus-within .field__label { color: var(--anthracite); }
.field__error {
  min-height: 1.4em;
  margin-top: 8px;
  font: 400 .8125rem/1.4 var(--font-body);
  font-style: italic;
  color: var(--anthracite);
}
.form__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 18px 28px; margin-top: 8px; }
.form__helper { font: 300 .9375rem/1.5 var(--font-body); color: var(--gris-cendre); }
.form__status { min-height: 1.5em; margin-top: 18px; font: 400 .9375rem/1.5 var(--font-body); }
.form__legal { margin-top: 10px; font: 300 .8125rem/1.6 var(--font-body); color: var(--gris-cendre); }

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 0 34px;
  overflow: hidden;
  border: 1px solid var(--anthracite);
  border-radius: 0;
  background: var(--anthracite);
  color: var(--blanc);
  font: 600 12px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 160ms var(--ease-out);
}
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--blanc);
  transform: translate3d(0, 101%, 0);
  transition: transform 460ms var(--ease-out);
}
.btn__label { position: relative; transition: color 300ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover::before { transform: none; }
  .btn:hover .btn__label { color: var(--anthracite); }
}
.btn:active { transform: scale(.97); }
.btn:focus-visible { outline-color: var(--anthracite); }
.btn[aria-busy="true"] { opacity: .7; pointer-events: none; }

.linkish {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  cursor: pointer;
}

/* ---------- 16. Footer ---------- */
.footer {
  position: relative;
  background: var(--graphite);
  color: var(--blanc);
  padding: clamp(88px, 14vh, 160px) var(--gutter) 28px;
}
.footer__brand { display: flex; justify-content: center; }
.footer__logo {
  width: clamp(220px, 24vw, 340px);
  height: auto;
  aspect-ratio: 390.9 / 114.1;
  fill: var(--blanc);
  margin: 24px;
}
.footer__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 40px 32px;
  max-width: var(--maxw);
  margin: clamp(64px, 11vh, 120px) auto 0;
  padding-top: 40px;
  border-top: 1px solid rgba(212, 212, 212, .22);
}
.fcol--wide { grid-column: span 2; }
.fcol__label {
  margin-bottom: 12px;
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-clair);
}
.fcol p:not(.fcol__label), .fcol address, .fcol li { font: 300 1rem/1.7 var(--font-body); }
.footer a {
  text-decoration: none;
  background: linear-gradient(currentColor, currentColor) left bottom / 0 1px no-repeat;
  transition: background-size 420ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .footer a:hover { background-size: 100% 1px; }
}
.footer__bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 16px 32px;
  max-width: var(--maxw);
  margin: clamp(56px, 9vh, 96px) auto 0;
  padding-top: 22px;
  border-top: 1px solid rgba(212, 212, 212, .22);
  font: 400 .8125rem/1.5 var(--font-body);
  color: var(--gris-clair);
}
.footer__legal { display: flex; flex-wrap: wrap; gap: 8px 28px; }
.footer__legal .linkish { text-decoration: none; min-height: 44px; }
@media (hover: hover) and (pointer: fine) {
  .footer__legal .linkish:hover { text-decoration: underline; }
}

/* ---------- 17. Legal dialogs ---------- */
.dialog {
  width: min(720px, calc(100vw - 32px));
  max-height: min(84vh, 760px);
  padding: 0;
  border: 0;
  background: var(--blanc);
  color: var(--anthracite);
}
.dialog::backdrop { background: rgba(44, 46, 53, .76); }
.dialog[open] { animation: dialog-in 420ms var(--ease-out); }
@keyframes dialog-in { from { opacity: 0; transform: translate3d(0, 16px, 0) scale(.98); } }
.dialog__inner { display: flex; flex-direction: column; max-height: inherit; }
.dialog__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 28px;
  border-bottom: 1px solid var(--gris-clair);
}
.dialog__title {
  font: 800 1rem/1.2 var(--font-ui);
  letter-spacing: .16em;
  text-transform: uppercase;
}
.dialog__close {
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  cursor: pointer;
}
.dialog__body { overflow: auto; padding: 8px 28px 32px; font: 300 1rem/1.7 var(--font-body); }
.dialog__body h3 {
  margin: 26px 0 8px;
  font: 700 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.dialog__body p + p { margin-top: 12px; }

/* ---------- 18. Cursor + grain ---------- */
.cursor, .cursor-ring { display: none; }
@media (hover: hover) and (pointer: fine) {
  html.has-cursor .cursor,
  html.has-cursor .cursor-ring {
    display: block;
    position: fixed;
    left: 0;
    top: 0;
    z-index: var(--z-cursor);
    pointer-events: none;
    color: var(--blanc);
    will-change: transform;
    transition: color 300ms var(--ease-out), opacity 200ms var(--ease-out);
  }
  html.has-cursor[data-ui="light"] .cursor,
  html.has-cursor[data-ui="light"] .cursor-ring { color: var(--anthracite); }
  html.has-cursor .cursor { width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: currentColor; }
  html.has-cursor .cursor-ring { width: 40px; height: 40px; margin: -20px 0 0 -20px; }
  .cursor-ring svg {
    width: 100%;
    height: 100%;
    overflow: visible;
    transition: transform 420ms var(--ease-out);
  }
  .cursor-ring circle { fill: currentColor; fill-opacity: 0; stroke: currentColor; stroke-width: 1; transition: fill-opacity 300ms var(--ease-out); }
  .cursor-ring__label {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font: 600 9px/1 var(--font-ui);
    letter-spacing: .22em;
    text-transform: uppercase;
    opacity: 0;
    transition: opacity 240ms var(--ease-out);
  }
  html.has-cursor[data-cursor="link"] .cursor-ring svg { transform: scale(1.5); }
  html.has-cursor[data-cursor="link"] .cursor { opacity: 0; }
  html.has-cursor[data-cursor="view"] .cursor-ring svg { transform: scale(2.2); }
  html.has-cursor[data-cursor="view"] .cursor-ring circle { fill-opacity: .12; }
  html.has-cursor[data-cursor="view"] .cursor-ring__label { opacity: 1; }
  html.has-cursor[data-cursor="view"] .cursor { opacity: 0; }
  html.has-cursor[data-cursor="text"] .cursor,
  html.has-cursor[data-cursor="text"] .cursor-ring,
  html.has-cursor.cursor-out .cursor,
  html.has-cursor.cursor-out .cursor-ring { opacity: 0; }

  /* The system pointer is replaced over imagery and controls only. Over running
     text and form fields the native cursor stays (caret, I-beam). */
  html.has-cursor body,
  html.has-cursor a,
  html.has-cursor button,
  html.has-cursor [data-cursor] { cursor: none; }
  html.has-cursor input,
  html.has-cursor textarea,
  html.has-cursor p,
  html.has-cursor dd,
  html.has-cursor address,
  html.has-cursor blockquote,
  html.has-cursor dialog { cursor: auto; }
  html.has-cursor dialog a,
  html.has-cursor dialog button { cursor: pointer; }
  html.has-cursor .film__chapters p,
  html.has-cursor .tile p,
  html.has-cursor .estate__visual p { cursor: none; }
}

.grain {
  position: fixed;
  inset: -12%;
  z-index: var(--z-grain);
  pointer-events: none;
  background: url("assets/img/grain.webp") repeat;
  background-size: 160px 160px;
  opacity: .032;
}
@media (hover: hover) and (pointer: fine) {
  .grain { animation: grain 900ms steps(5) infinite; }
}
@keyframes grain {
  0% { transform: translate3d(0, 0, 0); }
  20% { transform: translate3d(-4%, 3%, 0); }
  40% { transform: translate3d(3%, -5%, 0); }
  60% { transform: translate3d(-6%, -2%, 0); }
  80% { transform: translate3d(5%, 4%, 0); }
  100% { transform: translate3d(-2%, 6%, 0); }
}

/* ---------- 19. Motion states set by script ---------- */
/* The tagline is the LCP element: it starts dimmed, never invisible, so it
   counts as painted on the first frame and the entrance only lifts it. */
html.js-pending .hero__scroll { opacity: 0; }
html.js-pending .hero__logo,
html.js-pending [data-hero-line] { opacity: .22; translate: 0 14px; }
/* Scroll scenes are coming. Reserve the film's scroll length from the first
   paint (no layout jump when main.js arrives, and the lazy images further down
   stay far away) and skip the storyboard stills. */
html.motion-ok .chapter__still { display: none; }
html.motion-ok .film__track { min-height: calc(var(--film-screens, 16) * 100svh); }
@media (max-width: 899px) {
  html.motion-ok .film__track { min-height: calc(var(--film-screens, 13.5) * 100svh); }
}
.gallery.is-pinned { padding-bottom: 0; }
html.js-motion [data-reveal],
html.js-motion [data-reveal-group] > * { will-change: transform, opacity; }

/* ---------- 20. Responsive ---------- */
@media (max-width: 899px) {
  :root { --header-h: 80px; }

  .presenter__stage {
    grid-template-columns: 1fr;
    grid-template-areas: "head" "figure" "mosaic" "caption";
  }
  .presenter__figure { max-width: 240px; }
  .mosaic {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(4, 1fr);
    height: clamp(560px, 120vw, 900px);
  }
  .tile--b { grid-column: 1 / 3; grid-row: 1; }
  .tile--c { grid-column: 1; grid-row: 2 / 4; }
  .tile--d { grid-column: 2; grid-row: 2; }
  .tile--e { grid-column: 2; grid-row: 3; }
  .tile--f { grid-column: 1; grid-row: 4; }
  .tile--g { grid-column: 2; grid-row: 4; }

  .presenter.is-live .presenter__figure { height: 66svh; margin-left: calc(66svh * -0.1742); }
  .presenter.is-live .mosaic {
    left: var(--gutter);
    right: var(--gutter);
    top: calc(var(--header-h) + 64px);
    bottom: calc(5svh + 56px);
  }
  .presenter.is-live .presenter__caption { top: auto; left: var(--gutter); right: var(--gutter); bottom: 3svh; max-width: none; }
  .presenter.is-live .presenter__caption span { display: inline; margin-right: 10px; font-size: 1.375rem; }

  .film.is-scrub .chapter__body { bottom: 112px; }
  .film.is-scrub .chapter__body--quote { max-width: none; }
  .film.is-scrub .film__rail {
    flex-direction: row;
    top: auto;
    right: var(--gutter);
    left: var(--gutter);
    bottom: 22px;
    width: auto;
    height: 16px;
    transform: none;
  }
  .rail__seg { flex-direction: row; align-items: flex-end; padding: 0 3px; }
  .rail__tick { width: 1px; height: 6px; }
  .rail__tick:first-child { width: 1px; height: 14px; }
  .rail__head { top: auto; bottom: 0; right: auto; left: 0; width: 1px; height: 20px; }
  .film.is-scrub .film__hud { right: auto; left: var(--gutter); bottom: 54px; }
  .film.is-scrub .film__loader { left: auto; right: var(--gutter); bottom: 54px; }

  .villa { grid-template-columns: 1fr; align-items: start; gap: 28px; }
  .specs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .estate--wide, .estates__pair { grid-template-columns: 1fr; }
  .estates__pair .estate:last-child { margin-top: 0; }
  .pillars__list { grid-template-columns: 1fr; }
  .pillar:nth-child(2), .pillar:nth-child(3) { margin-top: 0; }

  .capsule { padding: 4px; }
  .nav a { padding: 10px 12px; letter-spacing: .12em; }
  .daynight { width: 36px; height: 36px; }
  .daynight__faces { width: 20px; height: 20px; }

  .contact__grid { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .shead { flex-wrap: wrap; row-gap: 10px; }
  .shead__rule { flex-basis: 40px; }
  .shead__label { flex-basis: 100%; text-align: right; }
  /* Three links instead of five leaves room for the monogram on every phone:
     the capsule takes what is left of the row and shares it between them. */
  .site-header { gap: 8px; }
  .capsule { flex: 1 1 auto; min-width: 0; }
  .nav { flex: 1 1 auto; }
  .nav > ul { justify-content: space-between; }
  .nav a { font-size: 10px; padding: 11px 8px; letter-spacing: .06em; }
  .nav__more { width: 18px; height: 26px; margin-left: -6px; }
  .capsule__rule { height: 18px; }
  .daynight { width: 34px; height: 34px; }
  .daynight__faces { width: 19px; height: 19px; }
  .submenu { min-width: 176px; }
  .footer__grid { grid-template-columns: 1fr; }
  .fcol--wide { grid-column: auto; }
  .contact__details > div { grid-template-columns: 1fr; gap: 4px; }
  .btn { width: 100%; }
}

/* ---------- 21. Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .hero__scroll span { transform: none; }
  .blob, .motes { display: none; }
  .tile__img, .tile__alt, .shot__frame img, .estate__figure { transition: none; }
  .tile__cap, .shot__cap span, .estate__slide { transition: opacity 300ms ease; }
  .tile:hover .tile__img, .shot:hover .shot__frame img, .estate__visual:hover .estate__figure { transform: none; }
  .grain { animation: none; }
}

/* ---------- 22. Du tracé: the two drawings, annotated ---------- */
/* Static layout (no JavaScript, or prefers-reduced-motion): the two pictures
   with their notes underneath, the buttons opening the same sheets. */
.trace__notes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(20px, 3vw, 44px);
  margin-top: clamp(24px, 4vh, 44px);
}
.plannote { max-width: 34ch; }
.plannote__level {
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.plannote__title {
  margin-top: 12px;
  font: 400 clamp(1.5rem, 2.4vw, 2.125rem)/1.1 var(--font-display);
}
.plannote__text {
  margin-top: 12px;
  font: 300 1rem/1.6 var(--font-body);
  color: var(--gris-cendre);
}
.plannote__btn {
  margin-top: 18px;
  padding: 13px 22px;
  border: 1px solid rgba(50, 51, 49, .28);
  border-radius: 999px;
  background: rgba(255, 255, 255, .72);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  color: var(--anthracite);
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 300ms var(--ease-out), background-color 300ms var(--ease-out), color 300ms var(--ease-out), scale 260ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .plannote__btn:hover { border-color: var(--bleu); background: var(--blanc); color: var(--bleu); scale: 1.03; }
}
.plannote__btn:active { scale: .98; }

/* Scrubbed layout: the notes float in the white margin beside the drawing.
   Their coordinates come from the positionsByTime table in main.js and are
   written on the element, so moving a note is one number in that table. */
.trace.is-scrub .trace__notes {
  position: absolute;
  inset: 0;
  display: block;
  margin: 0;
  z-index: 2;
  pointer-events: none;
}
/* --plan-left / --plan-right are written by main.js: they are the real edges
   of the drawing inside the frame, whatever the window's shape. The note takes
   the margin beside it, and never lands on the plan. */
.trace.is-scrub .plannote {
  position: absolute;
  --note-gap: clamp(20px, 2.4vw, 40px);
  top: var(--note-y, 20%);
  max-width: none;
  opacity: 0;
  translate: 0 16px;
  /* Hidden for the keyboard as well as the eye: the note only becomes
     visible (and its button reachable) while its drawing is on screen. */
  visibility: hidden;
  transition:
    opacity 420ms var(--ease-out),
    translate 460ms var(--ease-out),
    left 520ms var(--ease-strong),
    top 520ms var(--ease-strong),
    visibility 0s linear 460ms;
}
.trace.is-scrub .plannote.is-on {
  opacity: 1;
  translate: 0 0;
  visibility: visible;
  transition-delay: 0s;
}
.trace.is-scrub .plannote[data-side="left"] {
  right: calc(100% - var(--plan-left, 32%) + var(--note-gap));
  left: auto;
  width: min(320px, calc(var(--plan-left, 32%) - var(--note-gap) - 4px));
}
.trace.is-scrub .plannote[data-side="right"] {
  left: calc(var(--plan-right, 68%) + var(--note-gap));
  right: auto;
  width: min(320px, calc(100% - var(--plan-right, 68%) - var(--note-gap) - 4px));
}
/* Too little white beside the drawing (a short, wide window): both notes drop
   under it, exactly as they do on a phone. */
.trace.is-scrub .trace__notes.is-tight .plannote,
.trace.is-scrub .trace__notes.is-tight .plannote[data-side="left"],
.trace.is-scrub .trace__notes.is-tight .plannote[data-side="right"] {
  left: 0;
  right: 0;
  top: auto;
  bottom: 0;
  width: auto;
  max-width: 46ch;
}
.trace.is-scrub .trace__notes.is-tight .plannote__text { display: none; }
/* The note itself never eats the pointer — the frame below keeps reacting to
   the mouse — but its button does, with its own hover. */
.trace.is-scrub .plannote__btn { pointer-events: auto; }
.trace.is-scrub .plannote__title { font-size: clamp(1.375rem, 2vw, 1.875rem); }
.trace.is-scrub .plannote__text { font-size: .9375rem; }

/* The drawing is line art: a touch more contrast makes the strokes bite on a
   screen without turning the photograph at the other end of the clip harsh. */
.trace.is-scrub .trace__canvas {
  filter: contrast(1.05) brightness(1.02);
  transform: translate3d(var(--trace-x, 0px), var(--trace-y, 0px), 0);
  will-change: transform;
}

/* ---------- 23. The plan sheet, full size ---------- */
.planmodal {
  width: min(1240px, 94vw);
  max-width: none;
  height: min(88svh, 900px);
  max-height: none;
  padding: 0;
  border: 0;
  border-radius: 20px;
  background: var(--blanc);
  color: var(--anthracite);
  box-shadow: 0 60px 140px -60px rgba(0, 0, 0, .6);
}
.planmodal::backdrop { background: rgba(20, 21, 24, .68); }
.planmodal__inner {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  height: 100%;
}
.planmodal__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(18px, 3vw, 28px) clamp(18px, 3vw, 32px) 14px;
  border-bottom: 1px solid var(--gris-clair);
}
.planmodal__level {
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.planmodal__title { margin-top: 8px; font: 400 clamp(1.5rem, 2.6vw, 2.25rem)/1.05 var(--font-display); }
.planmodal__tools { display: flex; align-items: center; gap: 8px; }
.planmodal__zoom, .planmodal__close {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(50, 51, 49, .2);
  border-radius: 50%;
  background: transparent;
  font: 400 20px/1 var(--font-ui);
  cursor: pointer;
  transition: border-color 260ms var(--ease-out), background-color 260ms var(--ease-out), color 260ms var(--ease-out), scale 220ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .planmodal__zoom:hover, .planmodal__close:hover { border-color: var(--bleu); color: var(--bleu); scale: 1.06; }
}
.planmodal__close { font-size: 24px; }
.planmodal__ratio {
  min-width: 5ch;
  text-align: center;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .12em;
  color: var(--gris-cendre);
}
.planmodal__viewport {
  position: relative;
  overflow: hidden;
  touch-action: none;
  cursor: grab;
  background: var(--gris-clair-20);
}
.planmodal__viewport.is-dragging { cursor: grabbing; }
.planmodal__img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  max-width: none;
  height: auto;
  transform-origin: 0 0;
  translate: -50% -50%;
  user-select: none;
  -webkit-user-drag: none;
}
.planmodal__hint {
  padding: 12px clamp(18px, 3vw, 32px) clamp(16px, 2.6vw, 24px);
  font: 300 .8125rem/1.5 var(--font-body);
  color: var(--gris-cendre);
}

/* ---------- 24. Savoir-faire, the cascade ---------- */
.pillars { overflow: clip; isolation: isolate; }
/* A very faint grain that breathes, so the dark field is never quite flat. */
.pillars__grain {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("assets/img/grain.webp");
  background-size: 180px 180px;
  opacity: .04;
  mix-blend-mode: overlay;
  pointer-events: none;
  animation: pillarsBreathe 11s ease-in-out infinite;
}
@keyframes pillarsBreathe {
  0%, 100% { opacity: .03; }
  50% { opacity: .075; }
}
/* A soft patch of light that trails the cursor with inertia (main.js). */
.pillars__glow {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 52vmax;
  height: 52vmax;
  margin: -26vmax 0 0 -26vmax;
  border-radius: 50%;
  background: radial-gradient(circle closest-side, rgba(232, 224, 210, .16), rgba(232, 224, 210, 0) 70%);
  opacity: 0;
  pointer-events: none;
  transform: translate3d(var(--glow-x, 50vw), var(--glow-y, 40vh), 0);
  transition: opacity 700ms var(--ease-out);
  will-change: transform;
}
.pillars.is-lit .pillars__glow { opacity: 1; }
.pillars > .shead, .pillars__list, .pillars > .fade { position: relative; z-index: 1; }
/* Letters of the title, split by the script. */
.shead__title .ltr { display: inline-block; white-space: pre; will-change: transform, opacity, filter; }

.pillar {
  background: rgba(255, 255, 255, .012);
  transition:
    border-color 420ms var(--ease-out),
    box-shadow 520ms var(--ease-out),
    translate 420ms var(--ease-out);
}
.pillar__rule { transition: width 460ms var(--ease-strong), background-color 420ms var(--ease-out); }
.pillar__title { transition: color 420ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .pillar:hover {
    border-color: rgba(232, 224, 210, .48);
    translate: 0 -4px;
    box-shadow: 0 30px 70px -34px rgba(0, 0, 0, .9);
  }
  .pillar:hover .pillar__rule { width: 48px; background: var(--creme); }
  .pillar:hover .pillar__title { color: var(--creme); }
}

/* ---------- 25. Inner pages: shell ---------- */
.page {
  padding: calc(var(--header-h) + clamp(28px, 6vh, 64px)) 0 0;
  background: var(--gris-clair-20);
  color: var(--anthracite);
}
.page__head {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: clamp(24px, 6vh, 72px) var(--gutter) clamp(28px, 5vh, 56px);
}
.page__eyebrow {
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.page__title {
  margin-top: clamp(14px, 2vh, 24px);
  font: 400 clamp(2.5rem, 6.4vw, 5rem)/1.02 var(--font-display);
  letter-spacing: -.01em;
}
.page__lead {
  margin-top: clamp(16px, 2.4vh, 28px);
  max-width: 58ch;
  font: 300 clamp(1.0625rem, 1.5vw, 1.25rem)/1.65 var(--font-body);
  color: var(--gris-cendre);
}
.page__back {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(20px, 3vh, 32px);
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
}
.page__back::before { content: ""; width: 26px; height: 1px; background: currentColor; transition: width 360ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .page__back:hover::before { width: 42px; }
}

/* ---------- 26. Contact page ---------- */
.contactpage {
  position: relative;
  min-height: 100svh;
  padding: calc(var(--header-h) + clamp(28px, 6vh, 72px)) var(--gutter) clamp(72px, 12vh, 140px);
  background: var(--gris-clair-20);
  color: var(--anthracite);
  overflow: clip;
}
/* The decorative blur behind the card: the one colour the charte names
   (#2E5895) at low opacity, warmed by a second, paler tone. */
.contactpage__blur {
  position: absolute;
  right: -14vmax;
  bottom: -18vmax;
  width: 62vmax;
  height: 62vmax;
  border-radius: 50%;
  background:
    radial-gradient(circle at 38% 34%, rgba(46, 88, 149, .26), rgba(46, 88, 149, 0) 62%),
    radial-gradient(circle at 70% 68%, rgba(150, 197, 186, .3), rgba(150, 197, 186, 0) 60%);
  filter: blur(46px);
  pointer-events: none;
}
.contactpage__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(28px, 4vw, 0px);
  max-width: var(--maxw);
  margin-inline: auto;
}
.card {
  position: relative;
  z-index: 1;
  padding: clamp(28px, 4vw, 56px);
  border-radius: 24px;
  background: var(--blanc);
  box-shadow: 0 40px 90px -46px rgba(24, 26, 32, .46), 0 2px 10px -4px rgba(24, 26, 32, .1);
}
.card__title { font: 400 clamp(2rem, 4vw, 3rem)/1.05 var(--font-display); }
.card__sub {
  margin-top: 12px;
  max-width: 46ch;
  font: 300 1rem/1.65 var(--font-body);
  color: var(--gris-cendre);
}

/* Rounded fields, the site's type, the charte's blue on focus. */
.cform { margin-top: clamp(22px, 3vw, 34px); display: grid; gap: 18px; }
.cfield__label {
  display: block;
  margin-bottom: 8px;
  font: 600 11px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
  transition: color 240ms var(--ease-out);
}
.cfield__input {
  display: block;
  width: 100%;
  padding: 15px 18px;
  border: 1px solid #DCDCDC;
  border-radius: 14px;
  background: var(--blanc);
  color: var(--anthracite);
  font: 400 1rem/1.5 var(--font-body);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 260ms var(--ease-out), box-shadow 260ms var(--ease-out);
}
.cfield__input--area { min-height: 132px; resize: vertical; }
.cfield__input:focus { border-color: var(--bleu); box-shadow: 0 0 0 4px rgba(46, 88, 149, .16); }
.cfield:focus-within .cfield__label { color: var(--bleu); }
.cfield.is-invalid .cfield__input { border-color: #B3432F; box-shadow: 0 0 0 4px rgba(179, 67, 47, .12); }
.cfield__error {
  min-height: 1.3em;
  margin-top: 7px;
  font: 400 .8125rem/1.4 var(--font-body);
  font-style: italic;
  color: #8E3423;
}
.cform__actions { display: grid; justify-items: center; gap: 14px; margin-top: 6px; }
.cbtn {
  min-height: 56px;
  padding: 0 40px;
  border: 0;
  border-radius: 999px;
  background: var(--anthracite);
  color: var(--blanc);
  font: 600 12px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 300ms var(--ease-out), scale 220ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .cbtn:hover { background: var(--bleu); scale: 1.03; }
}
.cbtn:active { scale: .98; }
.cbtn[disabled] { opacity: .55; cursor: default; scale: 1; }
.cform__legal { font: 300 .8125rem/1.6 var(--font-body); color: var(--gris-cendre); text-align: center; }
.cform__status {
  margin-top: clamp(18px, 3vh, 28px);
  text-align: center;
  font: 400 1.0625rem/1.6 var(--font-body);
  opacity: 0;
  translate: 0 10px;
  scale: .96;
  transition: opacity 520ms var(--ease-out), translate 520ms var(--ease-out), scale 520ms var(--ease-out);
}
.cform__status.is-on { opacity: 1; translate: 0 0; scale: 1; }

/* The round window ------------------------------------------------------- */
.portal {
  position: relative;
  z-index: 2;
  width: clamp(260px, 30vw, 420px);
  aspect-ratio: 1;
  margin-left: clamp(-120px, -6vw, -40px);
  perspective: 1200px;
}
.portal__flip {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 720ms var(--ease-in-out), scale 720ms var(--ease-in-out);
}
.portal.is-flipped .portal__flip { transform: rotateY(180deg); }
.portal.is-turning .portal__flip { scale: 1.05; }
.portal__face {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  clip-path: circle(50%);
}
.portal__face--back { transform: rotateY(180deg); }
.portal__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.portal__button {
  position: absolute;
  inset: 0;
  z-index: 3;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
}
.portal__button:focus-visible { outline-color: var(--bleu); outline-offset: 6px; }
/* The ring of ticks. It turns once every 25 s; three neighbouring ticks glow
   and drift around it like a sweep. */
.portal__ring {
  position: absolute;
  /* -12 % of the circle on every side, and the viewBox is 248 units for the
     200 the circle occupies: the ticks stand just outside the video's edge at
     any size. The size is spelled out instead of being solved from the insets,
     because the base rule gives every <svg> max-width: 100 % — which clamped
     the ring back to the size of the circle and left it 29 px off centre, so
     the ring and the video did not line up. */
  left: -12%;
  top: -12%;
  width: 124%;
  height: 124%;
  max-width: none;
  z-index: 1;
  transform-box: border-box;
  transform-origin: 50% 50%;
  pointer-events: none;
  animation: portalSpin 25s linear infinite;
}
.portal__ring line { stroke: rgba(50, 51, 49, .28); stroke-width: 1; stroke-linecap: round; }
.portal__ring .is-lit { stroke: var(--bleu); opacity: .9; }
@keyframes portalSpin { to { transform: rotate(360deg); } }
/* The glow that answers a finished submission. */
.portal__halo {
  position: absolute;
  inset: -6px;
  z-index: 0;
  border-radius: 50%;
  opacity: 0;
  box-shadow: 0 0 0 0 rgba(46, 88, 149, .45);
}
.portal.is-accepting .portal__halo { animation: portalPulse 900ms var(--ease-out); }
@keyframes portalPulse {
  0% { opacity: 1; box-shadow: 0 0 0 0 rgba(46, 88, 149, .5), 0 0 30px 6px rgba(46, 88, 149, .35); }
  100% { opacity: 0; box-shadow: 0 0 0 42px rgba(46, 88, 149, 0), 0 0 60px 20px rgba(46, 88, 149, 0); }
}
/* The back of the coin: the message that was just sent. */
.portal__card {
  display: grid;
  align-content: center;
  gap: 10px;
  width: 100%;
  height: 100%;
  padding: clamp(24px, 4vw, 44px);
  background: var(--anthracite);
  color: var(--blanc);
  text-align: center;
}
.portal__eyebrow {
  font: 600 10px/1 var(--font-ui);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gris-clair);
}
.portal__name { font: 400 clamp(1.25rem, 2vw, 1.75rem)/1.15 var(--font-display); }
.portal__mail { font: 300 .875rem/1.5 var(--font-body); color: var(--gris-clair); word-break: break-word; }
.portal__msg {
  font: 300 .875rem/1.6 var(--font-body);
  color: var(--gris-clair);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.portal__again {
  justify-self: center;
  margin-top: 8px;
  padding: 8px 16px;
  border: 1px solid var(--glass-on-dark-line);
  border-radius: 999px;
  background: var(--glass-on-dark);
  color: inherit;
  font: 600 10px/1 var(--font-ui);
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 260ms var(--ease-out), scale 220ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .portal__again:hover { background: var(--glass-on-dark-hi); scale: 1.05; }
}
/* A field being pulled into the portal. The script sets the vector; the
   keyframes do the spiral. */
.cfield.is-spiralling {
  pointer-events: none;
  animation: spiralIn var(--spiral-ms, 850ms) cubic-bezier(.62, .02, .28, 1) var(--spiral-delay, 0ms) forwards;
  will-change: transform, opacity;
}
@keyframes spiralIn {
  0% { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); opacity: 1; }
  55% { transform: translate3d(calc(var(--spiral-x) * .58), calc(var(--spiral-y) * .46), 0) rotate(240deg) scale(.58); opacity: .9; }
  100% { transform: translate3d(var(--spiral-x), var(--spiral-y), 0) rotate(560deg) scale(.04); opacity: 0; }
}

/* The social buttons: the capsule's glass, on the light card. */
.socials { display: flex; align-items: center; gap: 10px; margin-top: clamp(22px, 3vw, 32px); }
.socials__label {
  margin-right: 4px;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.social {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--glass-on-light-line);
  border-radius: 999px;
  background: var(--glass-on-light);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  color: var(--anthracite);
  transition: background-color 300ms var(--ease-out), border-color 300ms var(--ease-out), color 300ms var(--ease-out), scale 260ms var(--ease-out);
}
.social svg { width: 18px; height: 18px; fill: currentColor; }
@media (hover: hover) and (pointer: fine) {
  .social:hover { border-color: var(--bleu); color: var(--bleu); background: var(--glass-on-light-hi); scale: 1.05; }
}
.social:active { scale: .97; }

.contactpage__details {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(18px, 3vw, 40px);
  max-width: var(--maxw);
  margin: clamp(48px, 8vh, 96px) auto 0;
}
.contactpage__details dt {
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gris-cendre);
}
.contactpage__details dd { margin-top: 10px; font: 300 1.0625rem/1.6 var(--font-body); }
.contactpage__details a { text-decoration: none; border-bottom: 1px solid currentColor; }

/* ---------- 27. Mougins page ---------- */
.mhero {
  position: relative;
  height: min(86svh, 820px);
  min-height: 480px;
  overflow: clip;
  background: var(--graphite);
  color: var(--blanc);
}
.mhero__media, .mhero__media img, .mhero__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mhero__media video { opacity: 0; transition: opacity 800ms var(--ease-out); }
.mhero.is-video .mhero__media video { opacity: 1; }
.mhero__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(44, 46, 53, .62) 0%, rgba(44, 46, 53, .08) 30%, rgba(44, 46, 53, .34) 56%, rgba(44, 46, 53, .74) 78%, rgba(44, 46, 53, .94) 100%);
}
/* On the photograph the eyebrow has to read light, not grey. */
.mhero__content .page__eyebrow { color: var(--gris-clair); }
.mhero__content {
  position: absolute;
  inset: auto 0 0 0;
  max-width: var(--maxw);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(36px, 7vh, 80px);
}
.mhero__title { margin-top: 14px; font: 400 clamp(2.75rem, 7vw, 5.5rem)/1 var(--font-display); }
.mhero__place {
  margin-top: 16px;
  font: 600 11px/1.8 var(--font-ui);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gris-clair);
}

.mvilla {
  background: var(--blanc);
  color: var(--anthracite);
  padding: clamp(64px, 12vh, 140px) var(--gutter);
}
.mvilla__inner { max-width: var(--maxw); margin-inline: auto; }
.mgrid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 26px);
  margin-top: clamp(32px, 6vh, 72px);
}
.mshot { position: relative; overflow: clip; }
.mshot img { width: 100%; height: 100%; object-fit: cover; transition: scale 900ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .mshot:hover img { scale: 1.04; }
}
.mshot--wide { grid-column: span 12; aspect-ratio: 16 / 9; }
.mshot--half { grid-column: span 6; aspect-ratio: 3 / 2; }
.mshot--third { grid-column: span 4; aspect-ratio: 4 / 5; }
.mshot--twothirds { grid-column: span 8; aspect-ratio: 3 / 2; }
.mshot__cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 44px 18px 16px;
  background: linear-gradient(to top, rgba(28, 29, 33, .74), transparent);
  color: var(--blanc);
  font: 600 10px/1.4 var(--font-ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 360ms var(--ease-out);
}
.mshot:hover .mshot__cap, .mshot:focus-within .mshot__cap { opacity: 1; }
.mnote {
  margin-top: clamp(28px, 5vh, 56px);
  padding: clamp(18px, 2.4vw, 28px);
  border: 1px solid var(--gris-clair);
  font: 300 .9375rem/1.65 var(--font-body);
  color: var(--gris-cendre);
}
.mambiance { background: var(--gris-clair-20); }
.mpair { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: clamp(20px, 3vw, 48px); align-items: start; margin-top: clamp(32px, 6vh, 64px); }

/* ---------- 28. The narrowest phones ---------- */
@media (max-width: 400px) {
  .site-header { padding: 0 10px; gap: 6px; }
  .brand { width: 62px; height: 62px; }
  .brand__symbol { width: 56px; height: 56px; }
  .nav a { font-size: 9.5px; padding: 11px 6px; letter-spacing: .03em; }
  .daynight { width: 32px; height: 32px; }
  .daynight__faces { width: 18px; height: 18px; }
}

/* ---------- 29. Responsive and reduced motion, sections 22-28 ----------
   These come last on purpose: they override the base rules a few sections
   above, and a media query carries no extra weight in the cascade. */
@media (max-width: 899px) {
  /* The drawing fills a narrow frame, so the note sits under it, full width. */
  .trace.is-scrub .plannote,
  .trace.is-scrub .plannote[data-side="left"],
  .trace.is-scrub .plannote[data-side="right"] {
    left: 0;
    right: 0;
    top: auto;
    bottom: clamp(8px, 2vh, 20px);
    width: auto;
  }
  .trace.is-scrub .plannote__text { display: none; }
  .trace.is-scrub .plannote__title { font-size: 1.25rem; }
  .trace.is-scrub .plannote__btn { margin-top: 12px; }

  /* The round window moves above the card and tucks under its top edge. */
  .contactpage__grid { grid-template-columns: 1fr; justify-items: center; gap: 0; }
  .portal { order: -1; margin: 0 0 clamp(-44px, -7vw, -20px); }
  .card { width: 100%; }
  .contactpage__blur { right: -30vmax; bottom: -30vmax; }

  .mshot--half, .mshot--third, .mshot--twothirds { grid-column: span 12; }
  .mshot--third { aspect-ratio: 3 / 2; }
  .mhero { height: min(78svh, 720px); }
}

@media (max-width: 560px) {
  .socials { flex-wrap: wrap; row-gap: 12px; }
  .portal { width: clamp(220px, 62vw, 300px); }
}

@media (prefers-reduced-motion: reduce) {
  .portal__ring, .pillars__grain { animation: none; }
  .pillars__glow { display: none; }
  .cfield.is-spiralling { animation: none; opacity: 0; }
  /* No coin flip: the two faces simply cross-fade in place. */
  .portal__flip { transition: none; }
  .portal__face { backface-visibility: visible; transition: opacity 320ms ease; }
  .portal__face--back { transform: none; opacity: 0; }
  .portal.is-flipped .portal__face--front { opacity: 0; }
  .portal.is-flipped .portal__face--back { opacity: 1; }
  .trace.is-scrub .trace__canvas { transform: none; }
  .mshot img { transition: none; }
}

/* ---------- 30. Contact: the villa seen through turning windows ----------
   Wide screens only. One <video> decodes; the canvas paints it once per
   window, each time behind its own clip, so there is a single video stream no
   matter how many windows turn. The ring orbits the card, not the section. */
.portholes { display: none; }
.portholes__canvas { display: block; width: 100%; height: 100%; }
.portholes__src {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
}

/* ---------- 31. The message is on its way ---------- */
.done { display: none; }
.card.is-sent .cform,
.card.is-sent .socials,
.card.is-sent .card__sub { display: none; }
.card.is-sent .done {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: clamp(22px, 4vw, 44px) 0 clamp(6px, 1vw, 14px);
  text-align: center;
}
.done__mark {
  width: clamp(78px, 9vw, 108px);
  height: auto;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.done__ring {
  stroke: var(--bleu);
  stroke-width: 2;
  opacity: .45;
  stroke-dasharray: 195;
  stroke-dashoffset: 195;
}
.done__check {
  stroke: var(--bleu);
  stroke-width: 4.5;
  stroke-dasharray: 44;
  stroke-dashoffset: 44;
}
.card.is-sent .done__ring { animation: doneRing 760ms var(--ease-out) forwards; }
.card.is-sent .done__check { animation: doneCheck 460ms var(--ease-out) 500ms forwards; }
.card.is-sent .done__mark { animation: donePop 720ms var(--ease-strong) 620ms; }
@keyframes doneRing { to { stroke-dashoffset: 0; } }
@keyframes doneCheck { to { stroke-dashoffset: 0; } }
@keyframes donePop {
  0%, 100% { scale: 1; }
  42% { scale: 1.07; }
}
.done__title { font: 400 clamp(1.625rem, 2.8vw, 2.25rem)/1.1 var(--font-display); }
.done__text {
  max-width: 42ch;
  font: 300 1rem/1.65 var(--font-body);
  color: var(--gris-cendre);
}
.done__mail { color: var(--anthracite); }
.done__again {
  margin-top: 8px;
  padding: 12px 24px;
  border: 1px solid rgba(50, 51, 49, .22);
  border-radius: 999px;
  background: none;
  color: inherit;
  font: 600 11px/1 var(--font-ui);
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 280ms var(--ease-out), color 280ms var(--ease-out), scale 240ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .done__again:hover { border-color: var(--bleu); color: var(--bleu); scale: 1.03; }
}

/* ---------- 32. Contact, wide screens ---------- */
@media (min-width: 900px) {
  .contactpage {
    display: grid;
    align-content: center;
    min-height: 100svh;
    background: var(--gris-clair-20);
  }
  .portholes {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
  }
  /* The windows are bright; the card needs its own weight to sit on top. */
  .contactpage__grid {
    z-index: 1;
    grid-template-columns: minmax(0, 640px);
    justify-content: center;
    gap: 0;
  }
  /* A shade deeper than the page usually is, so the white card reads as a
     sheet laid over the windows rather than a panel of the same paper. */
  .contactpage { background: #EAEAEC; }
  .card {
    background: var(--blanc);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    box-shadow: 0 70px 130px -60px rgba(20, 22, 28, .6), 0 6px 22px -10px rgba(20, 22, 28, .18);
  }
  /* The round window belongs to the phone layout. */
  .portal { display: none; }
  .contactpage__details { position: relative; z-index: 1; }
  .contactpage__blur { opacity: .7; }
}

@media (prefers-reduced-motion: reduce) {
  /* The check mark is already drawn; nothing sweeps or pops. */
  .card.is-sent .done__ring,
  .card.is-sent .done__check,
  .card.is-sent .done__mark { animation: none; }
  .done__ring, .done__check { stroke-dashoffset: 0; }
}
