/* =========================================================
   HARMONY INTERIORS — "L'Expérience" (version originale)
   One-page immersive · horizontal cinematic reel · dark
   ========================================================= */

:root{
  --ink:#070F1C;        /* near-black navy */
  --ink-2:#0C1B30;
  --ink-3:#12243C;
  --cream:#EDE6DA;
  --cream-dim:rgba(237,230,218,.62);
  --brass:#C6A972;
  --brass-2:#A98545;
  --steel:#8095AD;
  --line:rgba(237,230,218,.16);
  --line-soft:rgba(237,230,218,.08);

  --f-display:"Cormorant Garamond",Georgia,serif;
  --f-sans:"Jost","Avenir Next",system-ui,sans-serif;
  --f-script:"Pinyon Script",cursive;

  --s-1:clamp(.78rem, .74rem + .2vw, .9rem);
  --s0:clamp(1rem, .96rem + .2vw, 1.1rem);
  --s1:clamp(1.3rem, 1.1rem + .6vw, 1.7rem);
  --s2:clamp(2rem, 1.5rem + 2vw, 3.2rem);
  --s3:clamp(2.6rem, 1.8rem + 3.6vw, 5rem);
  --s4:clamp(3.4rem, 2rem + 7vw, 9rem);

  --gutter:clamp(1.25rem,4vw,4rem);
  --ease:cubic-bezier(.22,.61,.36,1);
  --slow:cubic-bezier(.16,1,.3,1);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
.lenis.lenis-smooth{scroll-behavior:auto !important}
.lenis.lenis-stopped{overflow:hidden}
body{
  font-family:var(--f-sans);font-weight:300;font-size:var(--s0);line-height:1.6;
  color:var(--cream);background:var(--ink);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden;
}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
ul{list-style:none}
::selection{background:var(--brass);color:var(--ink)}
:focus-visible{outline:2px solid var(--brass);outline-offset:4px}
.cf:focus-visible,.book:focus-visible,.leaf:focus-visible{outline-offset:8px}

/* subtle film grain overlay */
body::after{
  content:"";position:fixed;inset:0;z-index:9;pointer-events:none;opacity:.05;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.display{font-family:var(--f-display);font-weight:600;line-height:1.02;letter-spacing:-.01em}
.italic,i{font-style:italic}
.script{font-family:var(--f-script);font-style:normal;font-weight:400}
h1,h2,h3{font-family:var(--f-display);font-weight:600;line-height:1.04;letter-spacing:-.01em}
.eyebrow{font-size:var(--s-1);font-weight:500;letter-spacing:.34em;text-transform:uppercase;color:var(--brass);display:inline-flex;align-items:center;gap:.9em}
.eyebrow::before{content:"";width:2.4em;height:1px;background:var(--brass);opacity:.8}

/* =========================================================
   CUSTOM CURSOR
   ========================================================= */
/* Masqués par défaut : sur tactile (pointer:coarse) les styles position:fixed + span{opacity:0}
   du bloc @media(pointer:fine) ne s'appliquent pas → l'élément .cursor-ring s'affichait en flux
   normal EN HAUT de page avec son texte « ouvrir » visible. On le cache partout par défaut ;
   le bloc fine ci-dessous le réactive (display:block / grid) sur souris. */
.cursor,.cursor-ring{display:none}
@media(pointer:fine){
  body,body *{cursor:none!important}
  .cursor{position:fixed;top:0;left:0;z-index:1000;pointer-events:none;
    width:7px;height:7px;border-radius:50%;background:var(--brass);
    transform:translate3d(-50%,-50%,0);transition:width .18s var(--ease),height .18s var(--ease),background .18s;display:block;will-change:transform}
  .cursor-ring{position:fixed;top:0;left:0;z-index:1000;pointer-events:none;
    width:42px;height:42px;border:1px solid var(--line);border-radius:50%;
    transform:translate3d(-50%,-50%,0);display:grid;place-items:center;will-change:transform;
    transition:width .18s var(--ease),height .18s var(--ease),border-color .18s,background .18s}
  .cursor-ring span{font-size:.6rem;letter-spacing:.2em;text-transform:uppercase;color:var(--brass);opacity:0;transition:opacity .3s}
  body.cur-link .cursor{width:0;height:0}
  body.cur-link .cursor-ring{width:64px;height:64px;border-color:var(--brass)}
  body.cur-contact .cursor{opacity:0}
  body.cur-contact .cursor-ring{width:108px;height:108px;border-color:var(--cream);background:rgba(237,230,218,.02);mix-blend-mode:difference}
  body.cur-contact .cursor-ring span{opacity:1;color:var(--cream)}
  body.cur-drag .cursor{opacity:0}
  body.cur-drag .cursor-ring{width:108px;height:108px;border-color:var(--cream);background:rgba(237,230,218,.02);mix-blend-mode:difference}
  body.cur-drag .cursor-ring span{color:var(--cream)}
  body.cur-drag .cursor-ring span{opacity:1}
  /* text cursor: thin vertical bar */
  body.cur-text .cursor{width:2px;height:20px;border-radius:1px;background:var(--cream)}
  body.cur-text .cursor-ring{width:0;height:0;border-color:transparent}
}

/* =========================================================
   PRELOADER
   ========================================================= */
.pre{position:fixed;inset:0;z-index:1100;background:var(--ink);display:grid;place-items:center;overflow:hidden}
.pre__in{text-align:center}
.pre__word{font-family:var(--f-script);font-size:clamp(3.4rem,11vw,7rem);color:var(--brass);line-height:1}
.pre__logo{width:clamp(180px,34vw,330px);height:auto;display:block;margin-inline:auto;filter:drop-shadow(0 0 18px rgba(198,169,114,.18))}
.pre__sub{margin-top:.55rem;font-size:var(--s-1);letter-spacing:.5em;text-transform:uppercase;color:rgba(198,169,114,.72)}
.pre__count{position:absolute;right:var(--gutter);bottom:var(--gutter);font-family:var(--f-display);font-size:clamp(3rem,9vw,6rem);color:var(--ink-3)}

/* =========================================================
   HEADER
   ========================================================= */
/* En-tête : ancré en HAUT À DROITE. Panneau = nav (en colonne) puis logo dessous.
   Au scroll, le panneau se replie en un bouton (charte) ; un clic le ré-ouvre (JS). */
.hd{position:fixed;top:0;right:0;z-index:90;display:flex;flex-direction:column;align-items:flex-end;
  padding:clamp(1rem,2.4vw,1.8rem) clamp(1.2rem,3vw,2.2rem);pointer-events:none}
.hd > *{pointer-events:auto}
.hd__panel{display:flex;flex-direction:column;align-items:flex-end;gap:clamp(.7rem,1.6vw,1.1rem);
  mix-blend-mode:difference;transform-origin:right top;
  transition:opacity .4s var(--ease),transform .5s var(--slow)}
.hd__nav{display:flex;flex-direction:column;align-items:flex-end;gap:.5rem}
.hd__nav a{font-size:var(--s-1);letter-spacing:.16em;text-transform:uppercase;color:#fff;position:relative}
.hd__nav a::after{content:"";position:absolute;left:0;bottom:-3px;width:100%;height:1px;background:#fff;transform:scaleX(0);transform-origin:right;transition:transform .45s var(--slow)}
.hd__nav a:hover::after{transform:scaleX(1);transform-origin:left}
.hd__time{font-size:var(--s-1);letter-spacing:.14em;color:#fff;font-variant-numeric:tabular-nums;margin-top:.15rem}
.hd__brand{display:block}
.hd__brand img{height:clamp(64px,7.5vw,96px);width:auto}
/* bouton replié — charte LAITON (verre navy + liseré et traits brass, comme le reste du site) */
.hd__toggle{position:absolute;top:clamp(1rem,2.4vw,1.8rem);right:clamp(1.2rem,3vw,2.2rem);
  width:48px;height:48px;display:grid;place-content:center;gap:5px;border-radius:999px;
  border:1px solid rgba(198,169,114,.6);background:rgba(7,15,28,.42);
  -webkit-backdrop-filter:blur(14px) saturate(1.2);backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:0 0 18px rgba(198,169,114,.12);
  opacity:0;transform:scale(.82);pointer-events:none;transition:opacity .35s var(--ease),transform .35s var(--ease)}
.hd__toggle:hover{border-color:var(--brass)}
.hd__toggle span{display:block;width:18px;height:1.5px;border-radius:1px;background:var(--brass)}
.hd.is-collapsed .hd__panel{opacity:0;transform:translateY(-10px) scale(.96);pointer-events:none}
.hd.is-collapsed .hd__toggle{opacity:1;transform:scale(1);pointer-events:auto}
@media(max-width:720px){.hd__brand img{height:clamp(52px,15vw,78px)}}

/* ---- COMMUN aux deux orientations ---- */
/* ☰ au-dessus du panneau (sinon le panneau, transparent mais cliquable, avale le clic) */
.hd__toggle{z-index:6}
/* rangé : le panneau laisse passer les clics (seul le ☰ — et le logo — restent actifs) */
.hd.is-collapsed .hd__panel{pointer-events:none}
.hd.is-collapsed .hd__panel .hd__brand{pointer-events:auto}
/* rangé : les liens rentrent dans le bouton — CASCADE 3D (glisse + bascule, flou → net) */
.hd__nav{perspective:640px}
.hd.is-collapsed .hd__nav{pointer-events:none}
.hd__nav a,.hd__time{transform-origin:right center;
  transition:opacity .4s var(--ease),transform .55s var(--slow),filter .4s var(--ease)}
.hd.is-collapsed .hd__nav a,.hd.is-collapsed .hd__time{opacity:0;filter:blur(7px);
  transform:translate3d(34px,-14px,0) rotateY(38deg);transition-delay:0s}
.hd:not(.is-collapsed) .hd__nav a:nth-of-type(1){transition-delay:.06s}
.hd:not(.is-collapsed) .hd__nav a:nth-of-type(2){transition-delay:.14s}
.hd:not(.is-collapsed) .hd__nav a:nth-of-type(3){transition-delay:.22s}
.hd:not(.is-collapsed) .hd__time{transition-delay:.3s}
/* FERMETURE = la cascade d'ouverture jouée À L'ENVERS (le dernier entré sort en premier) :
   l'horloge part d'abord, puis les liens du bas vers le haut → même anim, en inverse. */
.hd.is-collapsed .hd__time{transition-delay:0s}
.hd.is-collapsed .hd__nav a:nth-of-type(3){transition-delay:.08s}
.hd.is-collapsed .hd__nav a:nth-of-type(2){transition-delay:.16s}
.hd.is-collapsed .hd__nav a:nth-of-type(1){transition-delay:.24s}
/* logo : fondu passé le hero (JS pose .is-faded), réapparaît en revenant */
.hd__brand{transition:opacity .65s var(--ease)}
.hd__brand.is-faded{opacity:0;pointer-events:none}

/* ---- AFFICHAGE HORIZONTAL (paysage / desktop) : barre en ligne, déployée DANS le hero ----
   Logo à gauche · liens + horloge à droite. Passé le hero : tout se range dans le bouton (JS). */
@media (min-aspect-ratio: 1/1){
  .hd{left:0;flex-direction:row;align-items:center}
  .hd__panel{width:100%;flex-direction:row-reverse;justify-content:space-between;align-items:center;
    gap:clamp(1rem,3vw,2rem)}
  .hd__nav{flex-direction:row;align-items:center;gap:clamp(1.1rem,2.6vw,2rem)}
  .hd__time{margin-top:0;margin-left:clamp(.5rem,1.4vw,1rem)}
  .hd__brand img{height:clamp(54px,6.2vw,80px)}
  /* le panneau reste posé : seuls les ITEMS se rangent (cascade commune) ; le ☰ apparaît rangé (base).
     pointer-events:none rangé → le panneau n'avale pas le clic destiné au ☰ */
  .hd.is-collapsed .hd__panel{opacity:1;transform:none;pointer-events:none}
}

/* ---- AFFICHAGE VERTICAL (portrait) : logo seul EN HAUT (gauche), liens à DROITE cachés en
   permanence derrière le bouton ☰ ; le bouton les révèle / referme (JS). ---- */
@media (max-aspect-ratio: 1/1){
  .hd__brand{position:fixed;top:clamp(.9rem,2.5vw,1.4rem);left:clamp(1rem,4vw,1.6rem)}
  .hd .hd__brand img{height:clamp(64px,19vw,96px)}          /* légèrement plus grand en vertical */
  .hd__toggle{opacity:1;transform:scale(1);pointer-events:auto;
    transition:opacity .35s var(--ease),transform .35s var(--ease),filter .45s var(--ease)}
  .hd__toggle span{transition:transform .45s var(--slow),opacity .3s var(--ease)}
  /* bouton OUVERT : les traits se croisent en ✕ + le bouton passe en FLOU (défocalisé) */
  .hd:not(.is-collapsed) .hd__toggle{filter:blur(2.2px)}
  .hd:not(.is-collapsed) .hd__toggle span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
  .hd:not(.is-collapsed) .hd__toggle span:nth-child(2){opacity:0;transform:scaleX(.15)}
  .hd:not(.is-collapsed) .hd__toggle span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}
  .hd__nav{padding-top:clamp(3.4rem,13vw,4.2rem)}
  /* le repli ne cache QUE la nav — le logo reste affiché en haut.
     pointer-events:none rangé → le panneau n'avale pas le clic du ☰ (le logo est ré-activé en base) */
  .hd.is-collapsed .hd__panel{opacity:1;transform:none;pointer-events:none}
}

/* =========================================================
   INTRO
   ========================================================= */
.intro{position:relative;isolation:isolate;height:100svh;display:flex;flex-direction:column;justify-content:center;padding-inline:var(--gutter);overflow:hidden}
.intro__bg{position:absolute;inset:0;z-index:0;
  /* fade the hero image's bottom to TRANSPARENT (not a solid navy band) so the ambient halos behind the
     page show through where the hero melts into the next section → one continuous space, no solid block */
  -webkit-mask:linear-gradient(to bottom, #000 70%, transparent 100%);
  mask:linear-gradient(to bottom, #000 70%, transparent 100%)}
.intro__bg img,.intro__bg video{width:100%;height:100%;object-fit:cover;opacity:1}
.intro__bg video{filter:none}
.intro__bg img{filter:brightness(.6) contrast(1.04) saturate(1.06)}
.intro__bg::after{display:none}
/* high-quality still that takes over when the video ends — same frame, cross-faded → invisible swap */
.intro__bg img.intro__still{position:absolute;inset:0;z-index:1;opacity:0;transition:opacity .5s ease}
.intro__bg.show-still img.intro__still{opacity:1}
/* bottom fade now handled by the .intro__bg mask above (fades to transparent → reveals the halos),
   so this overlay no longer paints opaque navy over them. Kept transparent (neutralised). */
.intro::after{content:"";position:absolute;left:0;right:0;bottom:0;height:24vh;z-index:-1;pointer-events:none;
  background:linear-gradient(to bottom, transparent, transparent)}
.intro > :not(.intro__bg){position:relative;z-index:2}
/* cursor spotlight: a fixed-size disc moved only via GPU transforms (no per-frame repaint).
   It reveals the photo's TRUE colours; the disc holds a counter-transformed copy of the image
   so the picture stays world-aligned with the dark base while the disc glides. */
.intro__reveal{position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:0;transition:opacity .5s var(--ease);
  -webkit-mask-image:radial-gradient(circle var(--r,250px) at var(--mx,50%) var(--my,42%), #000 0%, rgba(0,0,0,.6) 26%, rgba(0,0,0,.2) 62%, transparent 100%);
          mask-image:radial-gradient(circle var(--r,250px) at var(--mx,50%) var(--my,42%), #000 0%, rgba(0,0,0,.6) 26%, rgba(0,0,0,.2) 62%, transparent 100%)}
.intro__reveal img,.intro__reveal video{width:100%;height:100%;object-fit:cover;filter:saturate(1.38) brightness(1.33) contrast(1.06)}
.intro.is-lit .intro__reveal{opacity:1}
@media(prefers-reduced-motion:reduce){.intro__reveal{display:none}}
@media(hover:none){.intro__reveal{display:none}}
.intro__kicker{position:absolute;top:38%;left:var(--gutter);transform:translateY(-50%)}
.intro h1{font-size:var(--s4);letter-spacing:-.02em;color:var(--cream);position:relative}
.intro h1 .l{display:block;overflow:hidden}
.intro h1 .l > span{display:block}
.intro h1 .script{color:var(--brass);font-size:1.05em;line-height:.92}
.intro h1 .l--script{overflow:visible;padding-left:.08em;margin-left:-.08em}
.intro h1 .hero-script{display:inline-block;letter-spacing:0}
/* « l'h » : ces spans étaient en display:inline-block → sur iOS Safari, le dégradé clippé au texte
   (background-clip:text + text-fill-color:transparent du parent) NE traverse PAS un enfant inline-block
   → « l'h » rendu transparent = INVISIBLE sur iPhone (Chrome le gérait, d'où l'effet invisible). En
   display:inline ils redeviennent partie du texte du parent → le dégradé les couvre → « l'h » visible. */
.intro h1 .hero-script .k-lh{display:inline}
.intro h1 .hero-script .k-l{display:inline}
.intro h1 .hero-script .k-ap{display:inline;margin-left:.018em}
.intro h1 .hero-brass3d{
  --shy:11;
  transform-origin:50% 58%;
  background-image:
    linear-gradient(104deg,
      #d8b878 0%,
      #d3b06a 20%,
      #cca055 calc(var(--sx) - 24%),
      #ddb964 calc(var(--sx) - 10%),
      #ffe6a5 var(--sx),
      #dfbd68 calc(var(--sx) + 10%),
      #b38238 78%,
      #76572a 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  filter:
    drop-shadow(calc(var(--shx) * 1px) calc(var(--shy) * 1px) 14px rgba(0,0,0,.48))
    drop-shadow(0 1px 7px rgba(92,61,24,.22));
}
.intro h1 .hero-brass3d .float3d__glow{
  background-image:linear-gradient(100deg,
    transparent calc(var(--sx) - 11%),
    #fff7e4 var(--sx),
    transparent calc(var(--sx) + 11%));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  opacity:var(--glow);
  mix-blend-mode:screen;
  filter:blur(3px) drop-shadow(0 0 9px rgba(255,247,228,.95)) drop-shadow(0 0 19px rgba(255,223,154,.5));
}
.intro h1 .hero-brass3d .float3d__glow .k-lh{filter:none}
.intro__foot{position:absolute;left:var(--gutter);right:var(--gutter);bottom:clamp(1.4rem,4vw,2.6rem);display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;flex-wrap:wrap}
.intro__lead{position:relative;top:clamp(.45rem,1vw,.85rem);max-width:40ch;color:var(--cream-dim);font-size:var(--s1);line-height:1.45}
.js:not(.no-gsap) .intro [data-fade]{opacity:0;transform:translateY(24px)}
.no-gsap .pre{display:none}
.no-gsap .intro [data-fade]{opacity:1 !important;transform:none !important}
.intro__scroll{display:flex;align-items:center;gap:.8rem;font-size:var(--s-1);letter-spacing:.24em;text-transform:uppercase;color:var(--cream-dim)}
.intro__scroll i{width:46px;height:1px;background:var(--brass);position:relative;overflow:hidden;display:inline-block}
.intro__scroll i::after{content:"";position:absolute;inset:0;left:-100%;background:var(--cream);animation:slide 2.4s var(--ease) infinite}
@keyframes slide{0%{left:-100%}60%,100%{left:100%}}

/* =========================================================
   COVER-FLOW GALLERY (3D, drag left/right — no scroll hijack)
   ========================================================= */
.g3d{position:relative;padding:clamp(4rem,9vw,7rem) 0 clamp(3rem,6vw,5rem);overflow-x:clip}
/* during preview: also clip vertically so nothing bleeds above/below the section */
.g3d.is-preview-open{overflow:clip}
.g3d__head{padding-inline:var(--gutter);margin-bottom:clamp(1.8rem,4vw,3rem)}
.g3d__head .eyebrow{margin-bottom:1.1rem}
.g3d__head h2{font-size:var(--s3);color:var(--cream);max-width:18ch}
.g3d__sub{margin-top:.7rem;font-size:var(--s-1);letter-spacing:.16em;text-transform:uppercase;color:var(--cream-dim)}
/* category chips — quiet floating pills (same ghost language as .mthd__dot) */
.cf-cats{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:clamp(1rem,2.2vw,1.5rem)}
.cf-cat{padding:.58em 1.05em;border:1px solid var(--line);border-radius:999px;
  background:rgba(7,15,28,.18);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:var(--cream-dim);
  transition:color .4s var(--ease),border-color .4s var(--ease),box-shadow .4s var(--ease),transform .4s var(--ease)}
.cf-cat:hover{color:var(--brass);border-color:rgba(198,169,114,.55)}
.cf-cat.is-on{color:var(--brass);border-color:rgba(198,169,114,.75);transform:translateY(-2px);
  box-shadow:0 0 20px rgba(198,169,114,.14), 0 8px 20px -12px rgba(0,0,0,.7)}

.cf{position:relative;height:clamp(360px,54vh,560px);perspective:1250px;
  cursor:grab;touch-action:pan-y;outline:none;-webkit-tap-highlight-color:transparent}
.cf:active{cursor:grabbing}
.cf__stage{position:absolute;inset:0;transform-style:preserve-3d;
  transition:transform .9s cubic-bezier(.16,1,.3,1),opacity .48s ease,filter .48s ease}
.cf.is-previewing .cf__stage{
  transform:translate3d(clamp(-470px,-34vw,-250px),clamp(185px,31vh,310px),0) scale(.58);
  transform-origin:12% 86%;
  filter:brightness(.72) saturate(.82);
  opacity:.9;
  animation:cfPileFloat 5.8s ease-in-out infinite;
}
.cf.is-previewing .cf__nav,.cf.is-previewing + .cf__cap{opacity:0;pointer-events:none;transition:opacity .24s ease}
.cf__item{position:absolute;top:50%;left:50%;width:clamp(158px,20vw,268px);aspect-ratio:4/5;margin:0;
  transform-style:preserve-3d;will-change:transform,opacity;backface-visibility:hidden;
  transition:transform .55s var(--slow),opacity .55s var(--slow),filter .35s ease;
  --shadow:.65;
  border-radius:9px;cursor:pointer;
  /* soft, diffuse ambient shadow → depth without a hard edge: wide low-opacity halo all around + a
     gently blurred cast below (bigger blur, no tight negative spread → blends into the bg, not "dry"). */
  box-shadow:
    0 0 54px rgba(0,0,0,calc(var(--shadow) * .24)),
    0 28px 76px -20px rgba(0,0,0,calc(var(--shadow) * .38))}
.cf__item img{width:100%;height:100%;object-fit:cover;border-radius:9px;pointer-events:none;-webkit-user-drag:none;user-select:none}
/* depth veil = the SITE BACKGROUND colour (not black): far covers melt into the bg blue, opaque */
.cf__item::after{content:"";position:absolute;inset:0;border-radius:9px;background:var(--ink);opacity:var(--veil,0)}
/* REAL reflection: a mirrored copy of the cover that fades into the bg-ink "floor". Opaque (image→ink),
   so a front cover's reflection masks the one behind it (no translucent see-through), yet looks natural. */
/* height 56% (not 100%): the reflection is only visible in its top ~half (it's opaque navy below the fade
   point), so the lower half was an INVISIBLE navy tail that overflowed .cf and painted over the counter
   numbers below — especially on mobile (tall covers). Trimming it keeps the visible reflection identical
   (gradient stops rescaled by /0.56 so the opaque point lands at the same pixel) and clears the numbers. */
/* top:calc(100% + 7px) → a small gap between the cover and its reflection so the cover looks like it
   FLOATS slightly above the floor. height 54%: only the top half is visible (opaque navy below). */
.cf__refl{position:absolute;top:calc(100% + 7px);left:0;right:0;height:54%;pointer-events:none;border-radius:9px;
  background:var(--rimg) center/cover;transform:scaleY(-1);opacity:.34;filter:blur(1.65px) saturate(.82) contrast(.86) brightness(.68);
  /* fade the far end of the reflection to TRANSPARENT (not opaque navy) so the ambient halo field shows
     through the "floor" → no solid navy block sitting in front of the halos. The element is scaleY(-1)-
     flipped, so in its local box "to bottom→transparent" maps to the on-screen far end (away from cover). */
  -webkit-mask:linear-gradient(to bottom, transparent 28%, rgba(0,0,0,.72) 58%, #000 78%);
  mask:linear-gradient(to bottom, transparent 28%, rgba(0,0,0,.72) 58%, #000 78%);
  transition:opacity .34s ease,filter .34s ease}
.cf__refl{display:none!important}
.cf.is-previewing .cf__refl{opacity:0;filter:blur(3px)}
/* NB: NO brightness filter here — it would darken the gradient's opaque navy below the cover BELOW the
   real bg colour → a visible dark rectangle. Dimness comes purely from the navy veil (matches bg exactly). */
.cf__refl::after{content:"";position:absolute;inset:0;transform:scaleY(-1);   /* un-flip → screen coords */
  background:linear-gradient(to bottom, rgba(7,15,28,.18) 0%, rgba(7,15,28,.58) 42%, rgb(7,15,28) 82%)}
.cf.is-drag .cf__item,.cf.is-assembling .cf__item{transition:none}
.cf.is-preview-returning{z-index:2}   /* render above .cfx (z:1) so the slide-back is visible */
.cf.is-preview-returning .cf__item{transition:none}
/* reflection stays visible while sliding (it's static CSS — kept on during motion as the user asked) */

.cf__nav{position:absolute;top:50%;transform:translateY(-50%);z-index:60;width:48px;height:48px;
  border:1px solid var(--line);border-radius:50%;color:var(--cream);background:rgba(7,15,28,.45);
  backdrop-filter:blur(6px);font-size:1.6rem;line-height:1;display:grid;place-items:center;transition:.4s var(--ease)}
.cf__nav:hover{border-color:var(--brass);color:var(--brass)}
.cf__prev{left:clamp(.5rem,3vw,2.5rem)}
.cf__next{right:clamp(.5rem,3vw,2.5rem)}

/* position+z-index → the caption (title/meta/counter) always paints ABOVE the covers' reflections,
   so a reflection overflowing downward can never hide the text (esp. on mobile). */
/* légende remontée vers la pile (le bas du cover-flow est vide → on rapproche titre+sous-titre des covers) */
.cf__cap{position:relative;z-index:2;text-align:center;margin-top:clamp(-3.5rem,-3vw,-1.2rem);padding-inline:var(--gutter)}
.cf__cap h3{font-family:var(--f-display);font-size:var(--s2);color:var(--cream);line-height:1.1}
.cf__cap > span{font-size:var(--s-1);letter-spacing:.18em;text-transform:uppercase;color:var(--brass)}
.cf__count{margin-top:.8rem;font-family:var(--f-display);font-size:var(--s1);color:var(--cream-dim);font-variant-numeric:tabular-nums}
.cf__count b{color:var(--brass)}.cf__count em{font-style:normal}

.btn{display:inline-flex;align-items:center;gap:.7em;font-size:var(--s-1);letter-spacing:.18em;text-transform:uppercase;
  padding:1em 2em;border:1px solid var(--brass);color:var(--cream);border-radius:2px;position:relative;overflow:hidden;isolation:isolate;transition:color .5s}
.btn::after{content:"";position:absolute;inset:0;z-index:-1;background:var(--brass);transform:translateY(101%);transition:transform .5s var(--slow)}
.btn:hover{color:var(--ink)}.btn:hover::after{transform:translateY(0)}
@media(hover:none){.cf__nav{display:grid}}

/* Full-zone preview: the chosen realisation fills the whole gallery zone as a background; the collapsed
   flow floats in front (z 3, click → deploy + close); a glass text panel slides in from the right (z 5). */
/* Full-zone background preview — slightly inset from the section edges, slides in/out from the right. */
.cfx{position:absolute;top:0;left:0;
  width:var(--cfx-w,min(78vw,1180px));height:var(--cfx-h,100%);
  right:auto;bottom:auto;z-index:1;overflow:hidden;touch-action:pan-y;
  opacity:0;visibility:hidden;pointer-events:none;transform:translateX(-7vw) scale(1.025);
  transition:transform .58s cubic-bezier(.16,1,.3,1),opacity .5s var(--ease),visibility 0s linear .58s}
.cfx.is-open{opacity:1;visibility:visible;pointer-events:auto;cursor:grab;
  transform:translateX(0) scale(1);
  transition:transform .55s cubic-bezier(.16,1,.3,1),opacity .45s var(--ease)}
.cfx.is-open:active{cursor:grabbing}
.cfx.is-closing{opacity:0;visibility:visible;pointer-events:none;transform:translateX(-42vw) scale(1.025);
  transition:transform .66s cubic-bezier(.55,0,1,1),opacity .5s ease,visibility 0s linear .66s}
.cfx__bg{display:none}
/* No background on the figure — empty areas are transparent (halos show through). */
.cfx__fig{position:absolute;inset:0;margin:0;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,#000 0%,#000 55%,rgba(0,0,0,.78) 70%,rgba(0,0,0,.28) 88%,transparent 100%);
  mask-image:linear-gradient(90deg,#000 0%,#000 55%,rgba(0,0,0,.78) 70%,rgba(0,0,0,.28) 88%,transparent 100%)}
/* Image centred at natural size (equivalent to contain); mask starts at the image's own edges
   so the fade zone is always at the photo boundary, regardless of aspect ratio.            */
.cfx__fig img{position:absolute;inset:0;
  transform:none;
  width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;
  display:block;transition:opacity .45s var(--ease);
  -webkit-mask-image:none;mask-image:none}
.cfx__fig.is-fading img{opacity:0}
.cfx__fig::after{display:none}

/* glass text panel — anchored to the right edge, mostly off-screen; slides in on hover (desktop) or tap */
.cfx__panel{position:absolute;top:50%;right:0;z-index:5;
  width:min(36vw,430px);max-height:88%;
  transform:translateY(-50%) translateX(78%);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:transform .62s cubic-bezier(.16,1,.3,1),opacity .45s var(--ease),visibility 0s linear .62s}
.cfx__panel.is-open{opacity:1;visibility:visible;pointer-events:auto;
  transition:transform .62s cubic-bezier(.16,1,.3,1),opacity .45s var(--ease)}
.cfx__panel.is-closing{opacity:0;visibility:visible;pointer-events:none;
  transform:translateY(-50%) translateX(112%);
  transition:transform .58s cubic-bezier(.55,0,1,1),opacity .42s ease,visibility 0s linear .58s}
/* Reveal: hover (CSS, desktop) OR click/tap (JS .is-revealed, both platforms) */
.cfx__panel.is-open:hover,
.cfx__panel.is-open.is-revealed{transform:translateY(-50%) translateX(0)}
/* flèche « signalisation » HORS du cadre (juste à gauche du panneau) → montre qu'on peut le sortir ; desktop + mobile, en PULSATION ; cachée une fois révélé / au survol */
.cfx__panel::before{content:"\2039";position:absolute;top:50%;left:-34px;font-family:Georgia,serif;font-size:2.1rem;line-height:1;color:var(--brass);text-shadow:0 0 16px rgba(198,169,114,.65);transform:translateY(-50%);animation:cfxPullPulse 1.4s ease-in-out infinite;z-index:6;pointer-events:none;transition:opacity .3s ease}
.cfx__panel.is-open.is-revealed::before,.cfx__panel.is-open:hover::before{opacity:0;animation:none}
@keyframes cfxPullPulse{0%,100%{transform:translateY(-50%) translateX(0) scale(1);opacity:.72}50%{transform:translateY(-50%) translateX(-8px) scale(1.22);opacity:1}}
.cfx__panel-in{position:relative;display:flex;flex-direction:column;gap:.6rem;
  padding:clamp(1.3rem,2.4vw,2.1rem);border-radius:22px 0 0 22px;color:rgba(237,230,218,.92);isolation:isolate;
  background:linear-gradient(135deg,rgba(255,255,255,.055),rgba(255,255,255,.012) 45%,rgba(255,255,255,.035)),rgba(7,15,28,.14);
  -webkit-backdrop-filter:blur(34px) saturate(1.25);backdrop-filter:blur(34px) saturate(1.25)}
.cfx__panel-in::before{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;
  background:linear-gradient(120deg,rgba(255,255,255,.05),transparent 32%,rgba(255,255,255,.02) 72%,rgba(255,255,255,.04))}
.cfx__panel-in > *{position:relative;z-index:2}
.cfx__info-kicker{font-size:.64rem;letter-spacing:.22em;text-transform:uppercase;color:rgba(255,255,255,.62)}
.cfx__panel h3{font-family:var(--f-display);font-size:clamp(1.6rem,3vw,2.4rem);line-height:1.02;color:var(--cream)}
.cfx__panel span:not(.cfx__info-kicker){font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:rgba(198,169,114,.86)}

/* Preview nav bar — flex group, JS positions it just below the collapsed pile */
.cfx__nav-bar{position:absolute;display:none;gap:.5rem;z-index:6;pointer-events:none}
/* visibility controlled by JS in positionPreviewNav (show) and close* (hide) */
/* Individual arrows — no absolute positioning (handled by the bar + JS) */
.cfx__nav{width:48px;height:48px;border:1px solid var(--line);border-radius:50%;
  color:var(--cream);background:rgba(7,15,28,.45);backdrop-filter:blur(6px);
  font-size:1.6rem;line-height:1;display:grid;place-items:center;
  transition:.4s var(--ease);cursor:pointer;pointer-events:auto;flex-shrink:0}
.cfx__nav:hover{border-color:var(--brass);color:var(--brass)}
.cfx__panel p{max-width:34ch;font-size:clamp(.92rem,1.2vw,1.04rem);line-height:1.58;color:rgba(237,230,218,.78)}

/* collapsed flow floats above the background preview but is non-interactive while previewing, so it can't
   steal the drag/tap gestures (those go to the full-zone .cfx: drag = navigate, tap = close) */
.cf.is-previewing{z-index:3;pointer-events:none}
/* outgoing image during 3D cover-flow navigation */
.cfx__ghost{position:fixed;margin:0;z-index:63;border-radius:14px;overflow:hidden;
  will-change:transform,opacity;pointer-events:none;backface-visibility:hidden}
.cfx__ghost img{width:100%;height:100%;object-fit:contain;display:block;border-radius:14px;filter:drop-shadow(0 22px 30px rgba(0,0,0,.34))}
@media(max-width:900px){
  html,body{scrollbar-width:none;-ms-overflow-style:none}
  html::-webkit-scrollbar,body::-webkit-scrollbar{display:none;width:0;height:0}
  .intro__bg img,.intro__bg video{object-position:20% 50%}
  .hd__brand img{height:clamp(52px,15vw,78px)}
  .intro{justify-content:flex-start;padding-top:clamp(8.8rem,25svh,12rem)}
  .intro .eyebrow{margin-bottom:clamp(1.35rem,4.8vw,2rem)}
  .intro h1{font-size:clamp(3.9rem,18vw,5.65rem)}
  .intro__foot{bottom:clamp(-.35rem,-1svh,.05rem)}
  .intro__lead{max-width:30ch;color:rgba(237,230,218,.82);font-size:clamp(1.05rem,4.7vw,1.28rem);line-height:1.55}
  .svcs__hint{margin-top:.7rem;font-size:clamp(.68rem,.62rem + .18vw,.76rem);letter-spacing:.16em;text-transform:uppercase;color:var(--cream-dim);line-height:1.6}
  .book{height:clamp(370px,53vh,535px);perspective-origin:28% 46%}
  .leaf{left:13%;width:clamp(156px,48vw,278px);height:clamp(282px,50vh,468px)}
  .cf__nav{display:none}
  /* MOBILE : section galerie resserrée → la légende .cf__cap (qui se cache/réapparaît) reste visible AVEC le cover-flow (plus sous le pli) */
  .g3d{padding:clamp(2.4rem,6vw,4rem) 0 clamp(1.6rem,4vw,3rem)}
  .g3d__head{margin-bottom:clamp(1rem,3vw,1.8rem)}
  .cf{height:clamp(300px,44vh,460px)}
  .cf__cap{margin-top:clamp(.7rem,2vw,1.3rem)}
  .cf.is-previewing .cf__stage{
    transform:none;
    transform-origin:center center;
    animation:none;
    opacity:0;
    filter:blur(5px);
  }
  .cf.is-previewing + .cf__cap{opacity:0}
  .cfx{display:block!important;top:50%;left:50%;right:auto;bottom:auto;z-index:4;
    width:var(--cfx-w,min(84vw,420px));height:var(--cfx-h,min(54svh,500px));overflow:visible;touch-action:pan-y;
    transform:translate(-50%,-46%) scale(.96);
    transition:transform .5s cubic-bezier(.16,1,.3,1),opacity .42s var(--ease),visibility 0s linear .5s}
  .cfx.is-open{transform:translate(-50%,-50%) scale(1)}
  .cfx.is-closing{transform:translate(-74%,-50%) scale(.96)}
  .cfx__fig{position:absolute;inset:0;margin:0;overflow:hidden;border-radius:0;
    -webkit-mask-image:none;mask-image:none}
  .cfx__fig img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;border-radius:0;filter:none}
  .cfx__fig::after{display:block;content:"";position:absolute;inset:0;pointer-events:none;
    background:
      radial-gradient(ellipse 62% 52% at 0% 0%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%),
      radial-gradient(ellipse 62% 52% at 100% 0%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%),
      radial-gradient(ellipse 62% 52% at 0% 100%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%),
      radial-gradient(ellipse 62% 52% at 100% 100%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%)}
  .cfx__nav-bar{display:none!important}
  .cfx__nav{width:40px;height:40px;font-size:1.35rem}
  .cfx__panel{width:min(84vw,360px);max-height:80%}
  .cfx__panel{transform:translateY(-50%) translateX(calc(100% - 52px))}   /* mobile : caché mais ~52px dépassent (poignée verre arrondie ; la flèche-signal est gérée par .cfx__panel::before, hors-cadre) */
  .cfx__panel.is-open.is-revealed{transform:translateY(-50%) translateX(0)}
}
/* Mobile landscape — max-height:500px suffit : aucun mobile en portrait n'est aussi court.
   orientation:landscape retiré : Chromium (headless + certains WebKit) ignore cette condition
   dans les media queries CSS tout en la reportant vrai en JS. */
@media(max-height:500px){
  .cf.is-previewing .cf__stage{transform:translate3d(-30vw,38vh,0) scale(.46);transform-origin:12% 86%;opacity:.9;animation:none}
  .cf__nav{display:none}
  /* LANDSCAPE — l'OVERLAY entier scrolle (formulaire à hauteur naturelle).
     Pattern le + robuste sur iOS : c'est .contact-modal (plein écran, SANS
     backdrop-filter ni transform) qui scrolle ; le scroll interne d'un élément
     verre échoue sur Safari iOS. Double classe (.contact-modal.contact-modal)
     pour passer devant les règles de base situées plus bas dans le fichier. */
  .contact-modal.contact-modal{display:block;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;padding:0}
  .contact-modal .contact-modal__frame{width:100%;min-height:100%;display:flex;align-items:flex-start;justify-content:center;padding:.5rem .75rem}
  .contact-modal .contact-modal__glass{max-height:none;height:auto;width:min(100%,620px)}
  .contact-modal .contact-modal__scroll{flex:none;min-height:0;height:auto;overflow:visible;padding:.9rem 1.1rem}
  .contact-modal .contact-modal__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}
  .contact-modal .contact-modal__scroll h3{font-size:1.25rem;margin-bottom:.35rem}
  .contact-modal .contact-modal__kicker{margin-bottom:.2rem}
  .contact-modal .contact-modal__scroll textarea{min-height:64px}
  /* F3x col: centrée dans le verre (le scroll vit dans .f3x__body) */
  .f3x__glass{height:min(90vh,380px)}
  .f3x__col{height:min(78vh,320px);align-self:center}
}
@media(max-height:500px) and (max-width:950px){
  .f3x__glass{height:min(80vh,340px)}
  .f3x__col{height:min(66vh,276px)}
}

@keyframes cfPileFloat{
  0%,100%{transform:translate3d(clamp(-430px,-31vw,-240px),0,0) translateY(0) translateZ(0) rotateX(0deg) rotateZ(0deg) scale(.66)}
  34%{transform:translate3d(clamp(-430px,-31vw,-240px),0,0) translateY(-9px) translateZ(18px) rotateX(1.2deg) rotateZ(-.65deg) scale(.665)}
  68%{transform:translate3d(clamp(-430px,-31vw,-240px),0,0) translateY(5px) translateZ(-6px) rotateX(-.7deg) rotateZ(.45deg) scale(.658)}
}
@keyframes cfPileFloatMobile{
  0%,100%{transform:translate3d(-35vw,0,0) translateY(0) translateZ(0) rotateX(0deg) rotateZ(0deg) scale(.48)}
  34%{transform:translate3d(-35vw,0,0) translateY(-6px) translateZ(10px) rotateX(.9deg) rotateZ(-.5deg) scale(.484)}
  68%{transform:translate3d(-35vw,0,0) translateY(4px) translateZ(-4px) rotateX(-.5deg) rotateZ(.35deg) scale(.477)}
}

/* =========================================================
   SERVICES · SIDE-HINGED PAGE FAN ("a book opening")
   Pages (image + text) pivot around a vertical hinge on the LEFT, fanned out to the right like a hand
   fan. Drag turns them far→front in an infinite loop. The PAGE scroll is never hijacked — a vertical
   gesture is released to the page; only a horizontal drag/swipe ON the fan turns the pages.
   ========================================================= */
.svcs{position:relative;padding:clamp(4.5rem,10vw,8rem) var(--gutter) clamp(5rem,11vw,9rem);border-top:1px solid var(--line);overflow:hidden}
.svcs__head{max-width:34ch;margin-bottom:clamp(1.4rem,3.4vw,2.6rem)}
.svcs__head .eyebrow{margin-bottom:1.1rem}
.svcs__head h2{font-size:var(--s3);color:var(--cream);max-width:min(100%,20ch)}
.svcs-title .float3d__in{line-height:.95;display:block;max-width:100%}
.svcs-title__line{display:block;white-space:normal;text-wrap:balance}
.svcs__hint{margin-top:.7rem;font-size:var(--s-1);letter-spacing:.16em;text-transform:uppercase;color:var(--cream-dim)}
@media(min-width:761px){
  .svcs__head{max-width:none}
  .svcs__hint{white-space:nowrap}
}

.book{position:relative;height:clamp(420px,62vh,620px);perspective:1150px;perspective-origin:32% 46%;
  touch-action:pan-y;cursor:grab;outline:none;-webkit-tap-highlight-color:transparent}   /* pan-y → vertical swipe still scrolls */
.book:active{cursor:grabbing}
.book *,.f3x,.f3x *{outline:0!important;-webkit-tap-highlight-color:transparent}
.book__stage{position:absolute;inset:0;transform-style:preserve-3d}
@media(min-width:761px){
  .book__stage{transform:translateX(clamp(-128px,-7vw,-54px))}
}
/* a page of the fan — a realisation photo with the discipline printed on it, hinged on its LEFT edge */
.leaf{position:absolute;left:17%;top:50%;width:clamp(206px,26vw,330px);height:clamp(300px,52vh,500px);
  margin:0;padding:0;border:0;border-radius:5px;overflow:hidden;cursor:pointer;
  transform-origin:left center;transform-style:preserve-3d;backface-visibility:hidden;will-change:transform,opacity;
  outline:0!important;
  background:var(--ink-2) center/cover no-repeat;
  box-shadow:0 34px 80px -26px rgba(0,0,0,.82), 0 0 60px rgba(0,0,0,.4);-webkit-tap-highlight-color:transparent}
.leaf.is-hit{z-index:9999!important;pointer-events:auto}
/* paper catches light (a soft sheen top-left) + a bottom scrim so the text stays legible — kept light
   enough that the photograph clearly reads through */
.leaf__shade{position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(110deg, rgba(255,255,255,.08), rgba(7,15,28,.04) 42%, rgba(7,15,28,.22)),
             linear-gradient(to top, rgba(7,15,28,.84), rgba(7,15,28,.05) 52%)}
/* depth veil = the site navy → far pages melt into the background, opaque (set per-frame in JS) */
.leaf::after{content:"";position:absolute;inset:0;background:var(--ink);opacity:var(--shade,0);pointer-events:none;z-index:2}
.leaf__in{position:absolute;left:clamp(.95rem,1.7vw,1.5rem);right:clamp(.95rem,1.7vw,1.5rem);bottom:clamp(1rem,2.2vw,1.6rem);
  display:flex;flex-direction:column;gap:.28rem;text-align:left;color:var(--cream);z-index:3;
  opacity:0;transition:opacity .28s var(--ease)}
.leaf.is-active .leaf__in{opacity:1}
.leaf__no{font-family:var(--f-display);font-style:italic;font-size:var(--s1);color:var(--brass);line-height:1}
.leaf__name{font-family:var(--f-display);font-size:clamp(1.4rem,2.7vw,2.05rem);line-height:1.04}
.leaf__tags{font-size:.66rem;letter-spacing:.13em;text-transform:uppercase;color:var(--cream-dim);margin-top:.15rem}
/* hinge gold line — attached to the leaf, turns WITH it in 3D (opacity driven by JS --line-op).
   A tight specular highlight sweeps top→bottom as it rotates (--line-shine = 0..1 vertical position,
   --line-glow = bloom intensity peaking when facing the light). The base brass is mostly DARK so the
   bright spot reads as a single travelling glint, not an even glow. */
.leaf::before{content:"";position:absolute;left:0;top:7%;height:86%;width:1.5px;border-radius:999px;
  pointer-events:none;z-index:5;
  background:
    linear-gradient(to bottom,
      transparent calc(var(--line-shine,.5)*100% - 24%),
      rgba(255,244,214,calc(.7*var(--line-glow,0))) calc(var(--line-shine,.5)*100% - 11%),
      rgba(255,253,243,var(--line-glow,0)) calc(var(--line-shine,.5)*100%),
      rgba(255,244,214,calc(.7*var(--line-glow,0))) calc(var(--line-shine,.5)*100% + 11%),
      transparent calc(var(--line-shine,.5)*100% + 24%)),
    linear-gradient(to bottom,transparent,rgba(110,82,40,.5) 14%,rgba(140,104,54,.38) 50%,rgba(110,82,40,.46) 86%,transparent);
  opacity:var(--line-op,0)}
/* the glow's OWN halo — SAME technique as the floating titles' glint (.float3d__glow):
   a bright band confined to the lit zone, mix-blend screen, with warm-white drop-shadow blooms that
   flare only from that band. Travels down with --line-shine, fades with --line-glow. */
.leaf__glint{position:absolute;left:-1px;width:4px;top:7%;height:86%;border-radius:999px;
  z-index:4;pointer-events:none;mix-blend-mode:screen;
  background:linear-gradient(to bottom,
    transparent calc(var(--line-shine,.5)*100% - 13%),
    #fff7e4 var(--line-shine,.5),
    transparent calc(var(--line-shine,.5)*100% + 13%));
  filter:blur(2px) drop-shadow(0 0 9px rgba(255,247,228,.95)) drop-shadow(0 0 19px rgba(255,243,214,.55));
  opacity:calc(var(--line-op,0)*var(--line-glow,0))}
.leaf:focus,.leaf:focus-visible{outline:0!important}

.f3x{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
  visibility:hidden;padding:0;overflow:hidden;perspective:1200px}
.f3x.is-open{visibility:visible}
.f3x.is-closing{visibility:visible;pointer-events:none}
.f3x__bg{position:absolute;inset:0;background:rgba(5,11,22,.12);opacity:0;cursor:zoom-out;
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity .55s var(--ease)}
.f3x.is-open .f3x__bg{opacity:1}
.f3x__glass{position:relative;z-index:2;display:flex;align-items:flex-start;width:min(84vw,920px);height:min(52vh,440px);max-height:none;
  overflow:hidden;padding:clamp(1.2rem,5vw,1.65rem);border-radius:18px;
  background:
    linear-gradient(135deg,rgba(255,255,255,.018),rgba(255,255,255,.001) 44%,rgba(255,255,255,.012)),
    linear-gradient(180deg,rgba(7,15,28,.018),rgba(7,15,28,.002));
  -webkit-backdrop-filter:blur(50px) saturate(1.35);backdrop-filter:blur(50px) saturate(1.35);
  box-shadow:none;opacity:1;transform:translate3d(calc(112vw + var(--f3x-x,0px)),var(--f3x-y,0px),0) rotateY(var(--f3x-rot,0deg));transform-origin:center;isolation:isolate;
  transform-style:preserve-3d;--f3x-rot:0deg;--f3x-gx:-30%;--f3x-face-o:0;--f3x-edge-o:0;--f3x-edge-r:-12%;--f3x-edge-l:112%;cursor:pointer;
  transition:transform .72s var(--slow),opacity .35s var(--ease)}
.f3x__glass::before{content:"";position:absolute;inset:0;z-index:1;border-radius:inherit;pointer-events:none;
  background:
    linear-gradient(120deg,rgba(255,255,255,.012),transparent 32%,rgba(255,255,255,.004) 72%,rgba(255,255,255,.01)),
    linear-gradient(180deg,rgba(237,230,218,.004),rgba(237,230,218,.001))}
.f3x__glass::after{content:"";position:absolute;inset:-1px;z-index:12;border-radius:inherit;
  pointer-events:none;mix-blend-mode:screen;opacity:var(--f3x-edge-o);
  background:
    linear-gradient(to bottom,
      transparent calc(var(--f3x-edge-l) - 9%),
      rgba(255,255,255,.9) calc(var(--f3x-edge-l) - 2%),
      #fff var(--f3x-edge-l),
      rgba(255,255,255,.9) calc(var(--f3x-edge-l) + 2%),
      transparent calc(var(--f3x-edge-l) + 9%)) left top / 1px 100% no-repeat,
    linear-gradient(to bottom,
      transparent calc(var(--f3x-edge-r) - 9%),
      rgba(255,255,255,.9) calc(var(--f3x-edge-r) - 2%),
      #fff var(--f3x-edge-r),
      rgba(255,255,255,.9) calc(var(--f3x-edge-r) + 2%),
      transparent calc(var(--f3x-edge-r) + 9%)) right top / 1px 100% no-repeat}
.f3x.is-open .f3x__glass{opacity:1;transform:translate3d(var(--f3x-x,0px),var(--f3x-y,0px),0) rotateY(var(--f3x-rot,0deg));transition:transform .72s var(--slow),opacity .35s var(--ease)}
.f3x.is-flipped .f3x__glass{--f3x-rot:180deg}
.f3x.is-closing .f3x__glass{opacity:1;transform:translate3d(calc(112vw + var(--f3x-x,0px)),var(--f3x-y,0px),0) rotateY(var(--f3x-rot,0deg));transition:transform 2.6s var(--slow),opacity 2.6s var(--ease)}
.f3x.is-closing .f3x__bg{opacity:0}
.f3x__face{position:absolute;inset:0;z-index:3;display:flex;padding:inherit;border-radius:inherit;overflow:hidden;
  backface-visibility:hidden;transform-style:preserve-3d;box-sizing:border-box}
.f3x__face::after{content:"";position:absolute;inset:0;z-index:9;border-radius:inherit;pointer-events:none;
  mix-blend-mode:screen;opacity:var(--f3x-face-o);
  background:linear-gradient(112deg,
    transparent calc(var(--f3x-gx) - 26%),
    rgba(255,250,238,.045) calc(var(--f3x-gx) - 11%),
    rgba(255,252,242,.22) var(--f3x-gx),
    rgba(255,250,238,.055) calc(var(--f3x-gx) + 11%),
    transparent calc(var(--f3x-gx) + 26%))}
.f3x__face--front{align-items:center;justify-content:center;text-align:center;transform:translateZ(.1px);opacity:1;
  transition:opacity .08s linear .18s}
.f3x__face--back{align-items:flex-start;justify-content:flex-start;transform:rotateY(180deg) translateZ(8px);opacity:0;pointer-events:none;
  backface-visibility:visible;transition:opacity .08s linear 0s}
.f3x.is-flipped .f3x__face--front{opacity:0!important;visibility:hidden;pointer-events:none;transition-delay:0s}
.f3x.is-flipped .f3x__face--back{display:flex;z-index:7;opacity:1!important;visibility:visible;pointer-events:auto;transition-delay:.12s}
.f3x__front-title{position:relative;z-index:2;display:flex;flex-direction:column;align-items:center;justify-content:center;max-width:min(78%,560px)}
/* the text column: the HEADER (no/title/tags) is pinned, only .f3x__body below it scrolls.
   The group stays top-anchored so the title and paragraph always begin at the top of the glass. */
.f3x__col{position:relative;z-index:2;width:min(58%,520px);height:100%;align-self:flex-start;min-height:0;
  padding-right:.25rem;display:flex;flex-direction:column}
.f3x__body{flex:1 1 auto;min-height:0;margin-top:.95rem;overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;touch-action:pan-y;
  --fadeT:0px;--fadeB:0px;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 var(--fadeT),#000 calc(100% - var(--fadeB)),transparent 100%);
  mask-image:linear-gradient(to bottom,transparent,#000 var(--fadeT),#000 calc(100% - var(--fadeB)),transparent 100%);
  transition:--fadeT .4s var(--ease),--fadeB .4s var(--ease)}
.f3x__body::-webkit-scrollbar{display:none}
@property --fadeT{syntax:"<length>";inherits:false;initial-value:0px}
@property --fadeB{syntax:"<length>";inherits:false;initial-value:0px}
/* two quiet brass chevrons beside the text — desktop only, only when the text overflows.
   They hint that the zone scrolls, and click-scroll it for mice without a wheel. */
.f3x__nav{display:none;position:relative;z-index:3;align-self:center;flex-direction:column;align-items:center;gap:.62rem;
  margin-left:clamp(.55rem,1.4vw,1rem);opacity:0;transition:opacity .5s var(--ease) .25s}
.f3x.is-open .f3x__nav{opacity:1}
.f3x__navbtn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;margin:0;padding:0;
  border:1px solid rgba(237,230,218,.16);border-radius:999px;background:rgba(7,15,28,.12);cursor:pointer;
  color:var(--cream-dim);transition:color .35s var(--ease),border-color .35s var(--ease),opacity .35s var(--ease)}
.f3x__navbtn svg{width:13px;height:8px;display:block}
.f3x__navbtn:hover{color:var(--brass);border-color:rgba(198,169,114,.55)}
.f3x__navbtn.is-off{opacity:.22;pointer-events:none}
@media(min-width:761px){
  .f3x__nav.is-on{display:flex}
}
.f3x__no{font-family:var(--f-display);font-style:italic;font-size:var(--s1);color:var(--brass);line-height:1}
.f3x__title{font-family:var(--f-display);font-size:var(--s2);color:var(--cream);line-height:1.06;margin:.25rem 0 .5rem}
.f3x__tags{font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--cream-dim)}
.f3x__desc{max-width:none;margin-top:0;line-height:1.62;color:rgba(237,230,218,.86)}
.f3x.is-flipped .f3x__desc{display:block;opacity:1;color:rgba(237,230,218,.92)}
.f3x.is-flipped .f3x__body{display:block;opacity:1;visibility:visible}
.f3x__close{display:none}
.f3x__back-photo{position:absolute;inset:0 0 0 auto;width:54%;height:100%;z-index:0;border-radius:0;pointer-events:none;
  background:linear-gradient(135deg,rgba(237,230,218,.045),rgba(237,230,218,.006) 48%,rgba(237,230,218,.03));
  -webkit-mask-image:linear-gradient(to left,#000 0%,#000 42%,rgba(0,0,0,.55) 66%,transparent 88%);
  mask-image:linear-gradient(to left,#000 0%,#000 42%,rgba(0,0,0,.55) 66%,transparent 88%)}
.f3x__back-photo::before{content:"";position:absolute;inset:0;border:0;border-radius:0;
  background:linear-gradient(135deg,rgba(255,255,255,.03),rgba(255,255,255,.004));box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.f3x__pile{position:absolute;inset:0;z-index:0;height:auto;overflow:hidden;perspective:none;pointer-events:none}
.f3x__pile::after{content:"";position:absolute;inset:0;z-index:2;
  background:linear-gradient(to right,rgba(7,15,28,.16) 0%,rgba(7,15,28,.08) 48%,rgba(7,15,28,0) 82%)}
.f3x__pile img{position:absolute;inset:0 0 0 auto;top:0;left:auto;width:54%;height:100%;aspect-ratio:auto;
  object-fit:cover;border-radius:0;cursor:default;box-shadow:none;opacity:0;filter:saturate(1.18) contrast(1.08) brightness(1.03);
  transform:none!important;transition:opacity .45s var(--ease);
  -webkit-mask-image:linear-gradient(to left,#000 0%,#000 42%,rgba(0,0,0,.55) 66%,transparent 88%);
  mask-image:linear-gradient(to left,#000 0%,#000 42%,rgba(0,0,0,.55) 66%,transparent 88%)}
.f3x__pile img.is-ambient{opacity:.82}
@media(max-width:900px){
  /* PERF MOBILE : le grain plein écran (mix-blend overlay) et les grosses ombres floues de l'éventail
     se re-rastérisent à CHAQUE frame des animations 3D → coupés/allégés sur mobile (desktop intact). */
  body::after{display:none}
  .book{height:clamp(390px,54vh,540px);perspective-origin:10% 48%}
  .leaf{left:10%;width:clamp(166px,50vw,286px);height:clamp(286px,50vh,462px);border-radius:7px;
    box-shadow:0 8px 20px -12px rgba(0,0,0,.6)}   /* ombre légère (plus de 80px/60px floues = bcp moins de GPU) */
  .f3x__glass{gap:0;max-height:none;overflow:hidden;width:min(86vw,420px);height:min(62vh,560px)}
  .f3x__front-title{max-width:82%}
  /* the text zone ends where the photo's bottom fade begins (img = bottom 52%, faint from ~57% of
     the glass): the body's fade-out lands exactly on the photo's fade-in — text never rides over it */
  .f3x__col{width:100%;height:57%}
  .f3x__back-photo{inset:auto 0 0 0;width:100%;height:52%;
    -webkit-mask-image:linear-gradient(to top,#000 0%,#000 36%,rgba(0,0,0,.55) 58%,transparent 82%);
    mask-image:linear-gradient(to top,#000 0%,#000 36%,rgba(0,0,0,.55) 58%,transparent 82%)}
  .f3x__pile::after{background:linear-gradient(to bottom,rgba(7,15,28,.26) 0%,rgba(7,15,28,.16) 42%,rgba(7,15,28,.05) 68%,rgba(7,15,28,0) 100%)}
  .f3x__pile img{inset:auto 0 0 0;top:auto;left:0;width:100%;height:52%;
    -webkit-mask-image:linear-gradient(to top,#000 0%,#000 36%,rgba(0,0,0,.55) 58%,transparent 82%);
    mask-image:linear-gradient(to top,#000 0%,#000 36%,rgba(0,0,0,.55) 58%,transparent 82%)}
  .f3x__pile{height:auto}
}
@media(max-height:500px) and (max-width:950px){
  .f3x__glass{height:min(80vh,340px)}
  .f3x__col{height:min(66vh,276px)}
}
@media(prefers-reduced-motion:reduce){
  .f3x__glass,.f3x.is-open .f3x__glass{transition:opacity .3s var(--ease) !important;transform:translate3d(var(--f3x-x,0px),var(--f3x-y,0px),0) rotateY(var(--f3x-rot,0deg)) !important}
}
/* =========================================================
   STATEMENT / QUOTE (fullscreen image + words)
   ========================================================= */
.stmt{position:relative;height:100svh;display:grid;place-items:center;overflow:hidden;text-align:center;padding-inline:var(--gutter)}
.stmt__bg{position:absolute;inset:0;z-index:-1}
.stmt__bg img{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:cover;opacity:.28;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0%,transparent 10%,rgba(0,0,0,.08) 22%,rgba(0,0,0,.52) 36%,#000 48%,#000 76%,rgba(0,0,0,.45) 90%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0%,transparent 10%,rgba(0,0,0,.08) 22%,rgba(0,0,0,.52) 36%,#000 48%,#000 76%,rgba(0,0,0,.45) 90%,transparent 100%)}
.stmt__bg::before{display:none}
.stmt__bg::after{display:none}
.stmt blockquote{font-family:var(--f-display);font-style:italic;font-size:var(--s3);line-height:1.16;color:var(--cream);max-width:20ch;margin-inline:auto}
.stmt blockquote .script{font-style:normal;color:var(--brass);display:block;font-size:1.1em}
.stmt blockquote .stmt-script{overflow:visible}
.stmt .stmt-brass3d{
  --shy:11;
  transform-origin:50% 58%;
  background-image:
    linear-gradient(104deg,
      #7a5a2b 0%,
      #9d7536 20%,
      #c59843 calc(var(--sx) - 24%),
      #ddb964 calc(var(--sx) - 10%),
      #ffe6a5 var(--sx),
      #dfbd68 calc(var(--sx) + 10%),
      #b38238 78%,
      #76572a 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  filter:
    drop-shadow(calc(var(--shx) * 1px) calc(var(--shy) * 1px) 14px rgba(0,0,0,.48))
    drop-shadow(0 1px 7px rgba(92,61,24,.22));
}
.stmt .stmt-brass3d .float3d__glow{
  background-image:linear-gradient(100deg,
    transparent calc(var(--sx) - 11%),
    #fff7e4 var(--sx),
    transparent calc(var(--sx) + 11%));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  opacity:var(--glow);
  mix-blend-mode:screen;
  filter:blur(3px) drop-shadow(0 0 9px rgba(255,247,228,.95)) drop-shadow(0 0 19px rgba(255,223,154,.5));
}
.stmt cite{display:block;margin-top:1.8rem;font-style:normal;font-size:var(--s-1);letter-spacing:.2em;text-transform:uppercase;color:var(--cream-dim)}

/* =========================================================
   CONTACT + FOOTER
   ========================================================= */
.contact{padding:clamp(5rem,12vw,10rem) var(--gutter) clamp(2rem,5vw,3rem);border-top:1px solid var(--line)}
.contact .eyebrow{margin-bottom:1.4rem}
.contact h2{font-size:var(--s4);color:var(--cream);line-height:.98}
.contact h2 a{position:relative;display:inline-block}
.contact h2 a::after{content:"";position:absolute;left:0;bottom:.08em;width:100%;height:2px;background:var(--brass);transform:scaleX(0);transform-origin:right;transition:transform .6s var(--slow)}
.contact h2 a:hover::after{transform:scaleX(1);transform-origin:left}
.contact__lead{max-width:52ch;margin-top:clamp(1.5rem,3vw,2.3rem);font-family:var(--f-display);font-size:clamp(1.25rem,1rem + .9vw,2rem);line-height:1.38;color:rgba(237,230,218,.76)}
.contact__lead::before{content:"";display:block;width:clamp(42px,6vw,78px);height:1px;margin-bottom:1rem;background:linear-gradient(90deg,var(--brass),transparent);opacity:.9}
.contact__row{display:flex;flex-wrap:wrap;justify-content:space-between;gap:2rem;margin-top:clamp(2.5rem,6vw,4.5rem)}
.contact__info{display:flex;gap:clamp(2rem,5vw,4rem);flex-wrap:wrap}
.contact__info div h4{font-size:var(--s-1);letter-spacing:.2em;text-transform:uppercase;color:var(--brass);margin-bottom:.5rem;font-weight:500}
.contact__info div p,.contact__info div a{font-family:var(--f-display);font-size:var(--s1);color:var(--cream)}
.contact__socials{display:flex;gap:1.4rem;align-items:flex-end}
.contact__socials a{font-size:var(--s-1);letter-spacing:.14em;text-transform:uppercase;color:var(--cream-dim);transition:color .3s}
.contact__socials a:hover{color:var(--brass)}

/* modal: centrage, pas de overflow (le scroll est dans .contact-modal__scroll) */
.contact-modal{position:fixed;inset:0;z-index:240;display:grid;place-items:center;
  visibility:hidden;pointer-events:none;
  padding:clamp(1rem,3vh,2.5rem) var(--gutter);overflow:hidden;overflow:clip}
.contact-modal.is-open,.contact-modal.is-closing{visibility:visible;pointer-events:auto}
.contact-modal__bg{position:fixed;inset:0;background:rgba(5,11,22,.16);opacity:0;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);transition:opacity .42s var(--ease)}
.contact-modal.is-open .contact-modal__bg{opacity:1}
.contact-modal.is-closing .contact-modal__bg{opacity:0}
/* frame: slide depuis la droite — transform sur le wrapper, pas sur le glass */
.contact-modal__frame{width:min(92vw,860px);transform:translate3d(calc(112vw + var(--contact-modal-x,0px)),var(--contact-modal-y,0px),0);transition:transform .72s var(--slow);pointer-events:none}
.contact-modal.is-open .contact-modal__frame{transform:translate3d(var(--contact-modal-x,0px),var(--contact-modal-y,0px),0);pointer-events:auto}
.contact-modal.is-closing .contact-modal__frame{transform:translate3d(calc(112vw + var(--contact-modal-x,0px)),var(--contact-modal-y,0px),0);transition:transform .82s var(--slow);pointer-events:none}
/* glass: conteneur visuel avec backdrop-filter — overflow:hidden clipe le scroll sans casser le blur */
.contact-modal__glass{position:relative;z-index:1;width:100%;
  max-height:88vh;max-height:88dvh;
  display:flex;flex-direction:column;
  border:0;border-radius:20px;color:var(--cream);
  background:linear-gradient(135deg,rgba(255,255,255,.026),rgba(255,255,255,.004) 45%,rgba(255,255,255,.018)),linear-gradient(180deg,rgba(7,15,28,.03),rgba(7,15,28,.006));
  -webkit-backdrop-filter:blur(52px) saturate(1.35);backdrop-filter:blur(52px) saturate(1.35);
  isolation:isolate;box-shadow:none}
.contact-modal__glass::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;background:linear-gradient(120deg,rgba(255,255,255,.014),transparent 32%,rgba(255,255,255,.006) 72%,rgba(255,255,255,.012))}
/* scroll: seul élément avec overflow — pas de backdrop-filter dessus */
.contact-modal__scroll{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;
  -webkit-overflow-scrolling:touch;touch-action:pan-y;overscroll-behavior:contain;
  scrollbar-width:none;padding:clamp(1.35rem,3.2vw,2.6rem)}
.contact-modal__kicker{display:block;font-size:.68rem;letter-spacing:.22em;text-transform:uppercase;color:rgba(198,169,114,.86);margin-bottom:.55rem}
.contact-modal h3{font-family:var(--f-display);font-size:clamp(2rem,4vw,3.4rem);line-height:1;color:var(--cream);margin-bottom:clamp(1.2rem,2.6vw,2rem)}
.contact-modal__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(.85rem,1.7vw,1.2rem);align-items:start}
.contact-modal label{display:flex;flex-direction:column;gap:.42rem;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:rgba(237,230,218,.58)}
.contact-modal input,.contact-modal textarea,.contact-choice__btn{width:100%;font:inherit;font-size:1rem;letter-spacing:0;text-transform:none;color:var(--cream);background:rgba(237,230,218,.055);border:0;border-radius:10px;padding:.86rem .95rem;outline:0;text-align:left}
.contact-modal input[type="hidden"]{display:none!important;padding:0;background:none;border:none}
.contact-modal textarea{resize:vertical;min-height:110px}
.contact-modal input:focus,.contact-modal textarea:focus,.contact-choice__btn:focus{background:rgba(237,230,218,.085)}
.contact-choice{position:relative;display:flex;flex-direction:column;gap:.42rem;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;color:rgba(237,230,218,.58)}
.contact-choice__label{display:block}
.contact-choice__btn{display:flex;align-items:center;justify-content:flex-start;padding-right:1.1rem}
/* higher specificity (0,2,0 > 0,1,1) — overrides .contact-modal button for all conflicting props */
.contact-modal .contact-choice__btn{
  display:flex;justify-content:flex-start;margin-top:0;
  font-size:1rem;padding:.86rem .95rem;letter-spacing:0;
  text-transform:none;border-radius:10px;
  background:rgba(237,230,218,.055);
  -webkit-appearance:none;appearance:none}
.contact-modal .contact-choice__btn:focus,.contact-modal .contact-choice__btn:active,.contact-modal .contact-choice__btn:hover{background:rgba(237,230,218,.085)}
.contact-choice__btn::after{content:"";width:.48rem;height:.48rem;margin-left:auto;margin-right:.55rem;flex-shrink:0;border-right:1px solid rgba(237,230,218,.72);border-bottom:1px solid rgba(237,230,218,.72);transform:rotate(45deg) translateY(-2px);transition:transform .28s var(--ease)}
.contact-choice.is-open .contact-choice__btn::after{transform:rotate(225deg) translate(-2px,-1px)}
.contact-choice__menu{position:absolute;left:0;right:0;top:calc(100% + .45rem);z-index:30;display:block;
  height:clamp(190px,28vh,228px);overflow:hidden;padding:0;border-radius:12px;
  opacity:0;pointer-events:none;transform:translateY(-6px);
  touch-action:none;cursor:ns-resize;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(to bottom,#000 36%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 36%,transparent 100%);
  background:linear-gradient(135deg,rgba(255,255,255,.05),rgba(255,255,255,.012)),rgba(7,15,28,.38);
  -webkit-backdrop-filter:blur(42px) saturate(1.28);backdrop-filter:blur(42px) saturate(1.28);
  box-shadow:none;transition:opacity .22s var(--ease),transform .22s var(--ease)}
.contact-choice.is-open .contact-choice__menu{opacity:1;pointer-events:auto;transform:translateY(0)}
.contact-choice__item{position:absolute;left:0;right:0;height:48px;display:flex;align-items:center;
  padding:0 .88rem;font-size:.95rem;color:rgba(237,230,218,.84);
  cursor:pointer;user-select:none;will-change:transform}
.contact-choice__item:hover,.contact-choice__item:focus{background:rgba(237,230,218,.055);color:var(--cream);outline:none}
.contact-modal__message{margin-top:clamp(.85rem,1.7vw,1.2rem)}
.contact-modal button{margin-top:clamp(1rem,2vw,1.5rem);display:inline-flex;align-items:center;justify-content:center;padding:.9rem 1.35rem;border-radius:999px;background:rgba(198,169,114,.16);color:var(--cream);letter-spacing:.14em;text-transform:uppercase;font-size:.76rem}

@media(max-width:900px){
  /* portrait : marge sur les côtés (centrage + zone de clic pour fermer) */
  .contact-modal{padding:1rem;justify-items:center}
  .contact-modal__frame{width:min(90vw,400px);margin-inline:auto}
  .contact-modal__glass{border-radius:16px}
  .contact-modal__scroll{padding:.9rem}
  .contact-modal__grid{grid-template-columns:1fr;gap:.5rem}
  /* PORTRAIT : les petits libellés (Nom/Email/Telephone/Type/Quelques mots) glissent DANS leur
     champ via placeholder → on masque les libellés au-dessus (sr-only = toujours lus par les
     lecteurs d'écran) et on retire leur espace → la hauteur récupérée révèle le bouton « Envoyer ». */
  .contact-modal__grid label > span,
  .contact-modal .contact-choice__label,
  .contact-modal__message > span{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;margin:-1px;padding:0;border:0}
  .contact-modal__grid label,.contact-modal .contact-choice{gap:0}
  .contact-modal h3{font-size:1.6rem;margin-bottom:.7rem}
  .contact-modal__kicker{margin-bottom:.3rem}
  .contact-modal input,.contact-modal textarea,.contact-choice__btn{padding:.65rem .8rem;font-size:.95rem}
  .contact-modal .contact-choice__btn{padding:.65rem .8rem;font-size:.95rem}
  .contact-modal textarea{min-height:72px}
  .contact-modal__message{margin-top:.5rem}
  .contact-modal button{margin-top:.65rem;padding:.75rem 1.1rem;font-size:.72rem}
}
/* Desktop : les libellés sont AU-DESSUS des champs → on masque les placeholders de la grille
   (sinon doublon « NOM » au-dessus + « Nom » dans le champ). Le placeholder du message reste. */
@media(min-width:761px){
  .contact-modal__grid input::placeholder{color:transparent}
}


.foot{display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem;padding:2rem var(--gutter);
  border-top:1px solid var(--line-soft);font-size:var(--s-1);letter-spacing:.04em;color:var(--cream-dim)}

/* marquee */
.marq{overflow:hidden;border-block:1px solid var(--line);padding-block:1.3rem;white-space:nowrap}
.marq__t{display:inline-flex;gap:3rem;animation:marq 28s linear infinite}
.marq__item{font-family:var(--f-display);font-style:italic;font-size:var(--s2);color:var(--cream);opacity:.9;display:inline-flex;gap:3rem;align-items:center}
.marq__word{
  line-height:1;
  color:var(--cream)
}
.marq__item::after{
  content:"✦";font-style:normal;font-size:.55em;line-height:1;color:var(--brass)
}
@keyframes marq{to{transform:translateX(-50%)}}

/* reveal */
.r{opacity:0;transform:translateY(30px)}
.is-in .r,.r.is-in{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important;transition-duration:.001ms !important}
  .r{opacity:1;transform:none}
  .intro [data-fade]{opacity:1 !important;transform:none !important}
  .pre{display:none}
  body{cursor:auto}.cursor,.cursor-ring{display:none}
  .float3d__in{transform:none !important}
}

/* =========================================================
   AMBIENT HALOS — one continuous coloured-glow field behind
   the whole page (sits above the navy body, shows through every
   transparent section → ties the sections into one space).
   Dark but elegant muted colours, screen-blended + heavily blurred
   so they melt into the navy. Gentle autonomous drift (works on
   touch devices with no pointer) + cursor parallax (JS).
   ========================================================= */
.aura{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
.aura__orb{
  position:absolute;border-radius:50%;
  background:radial-gradient(closest-side, var(--c), transparent 72%);
  mix-blend-mode:screen;filter:blur(48px);opacity:.5;
  translate:0 0;transition:translate 1.4s cubic-bezier(.22,.61,.36,1);
  will-change:transform,translate;
  /* clearly-visible autonomous drift (also runs with no cursor → mobile). Composes with the
     JS cursor parallax, which lives on the separate `translate` property, so both happen at once. */
  animation:auraDrift 22s ease-in-out infinite;
}
html:not(.fx-ready) .aura__orb{animation-play-state:paused}
.aura__orb:nth-child(1){width:60vmax;height:60vmax;left:-16vmax;top:-12vmax;opacity:.5;animation-duration:23s}
.aura__orb:nth-child(2){width:46vmax;height:46vmax;right:-12vmax;top:16%;opacity:.4;animation-duration:27s;animation-delay:-6s}
.aura__orb:nth-child(3){width:40vmax;height:40vmax;left:6%;top:40%;opacity:.32;animation-duration:31s;animation-delay:-11s}
.aura__orb:nth-child(4){width:54vmax;height:54vmax;right:-12vmax;top:58%;opacity:.46;animation-duration:25s;animation-delay:-3s;animation-name:auraDrift2}
.aura__orb:nth-child(5){width:44vmax;height:44vmax;left:-10vmax;top:76%;opacity:.4;animation-duration:29s;animation-delay:-16s;animation-name:auraDrift2}
.aura__orb:nth-child(6){width:36vmax;height:36vmax;right:12%;bottom:-10vmax;opacity:.3;animation-duration:33s;animation-delay:-9s;animation-name:auraDrift2}
/* seamless loop (100% == 0%), enough travel + scale pulse to read as living motion on its own */
@keyframes auraDrift{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  25%{transform:translate3d(9%,-8%,0) scale(1.16)}
  50%{transform:translate3d(-7%,9%,0) scale(.9)}
  75%{transform:translate3d(8%,6%,0) scale(1.08)}
}
@keyframes auraDrift2{
  0%,100%{transform:translate3d(0,0,0) scale(1.04)}
  25%{transform:translate3d(-8%,7%,0) scale(.92)}
  50%{transform:translate3d(9%,-6%,0) scale(1.18)}
  75%{transform:translate3d(-6%,-8%,0) scale(1)}
}

/* =========================================================
   FLOATING 3D SECTION TITLES — float in the void, tilt to cursor,
   drift gently on their own. The 3D transform lives on an inner
   span so the GSAP ".r" reveal (on the <h2>) never conflicts.
   ========================================================= */
.float3d{perspective:780px;overflow:visible}
.float3d__in{display:inline-block;position:relative;transform-style:preserve-3d;backface-visibility:hidden;
  will-change:transform,filter;
  /* live "material" of a 3D block floating in the void — JS drives these per frame from the tilt: */
  --sx:50%;       /* specular highlight position (sweeps as the title yaws) */
  --shx:0;        /* cast-shadow x offset (shifts opposite the tilt → fixed light source) */
  --shy:13;       /* cast-shadow y offset (rises/sinks with the pitch) */
  --glow:0;       /* specular GLINT (0..1): blooms when the highlight crosses its sweet spot (JS) */
  /* SHEEN: a soft brighter band sweeps across the glyphs, brass-tinted at the edges */
  background-image:linear-gradient(100deg,
    #cdb88f 0%, var(--cream) calc(var(--sx) - 26%), #fbf4e6 var(--sx), var(--cream) calc(var(--sx) + 26%), #c2a675 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  /* the gradient only paints inside the element box; with the tight title line-height the 'g' descenders
     spill BELOW it → no fill → they look cut off. Pad the box out (esp. bottom) so the gradient covers the
     full glyphs, and cancel it with a negative margin so the layout/position is unchanged. */
  padding:.08em .16em .24em;margin:-.08em -.16em -.24em;
  /* SHADOW: a cast shadow whose offset moves with the tilt (drop-shadow keeps it on the glyph shapes
     even with a transparent text fill — text-shadow would not render reliably here) */
  /* cast shadow + a faint brass ambient. The GLINT bloom is NOT here (it would light the whole glyph) —
     it lives in the .float3d__glow overlay below so it only emanates from the lit band. */
  filter:drop-shadow(calc(var(--shx) * 1px) calc(var(--shy) * 1px) 18px rgba(0,0,0,.55))
         drop-shadow(0 2px 9px rgba(198,169,114,.08))}
/* GLINT bloom layer — a clone of the title text that is opaque ONLY inside the sheen's bright band
   (transparent elsewhere), blurred → the glow flares from the lit zone alone, never the shadowed letters.
   Inherits --sx/--glow from the parent; the whole layer fades in/out with --glow (gaussian peak). */
.float3d__glow{position:absolute;left:0;top:0;width:100%;height:100%;padding:inherit;
  pointer-events:none;user-select:none;opacity:var(--glow);mix-blend-mode:screen;
  background-image:linear-gradient(100deg,
    transparent calc(var(--sx) - 11%), #fff7e4 var(--sx), transparent calc(var(--sx) + 11%));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  filter:blur(3px) drop-shadow(0 0 9px rgba(255,247,228,.95)) drop-shadow(0 0 19px rgba(255,243,214,.55))}

/* =========================================================
   ★ VOID v1 — INFINITE-SPACE BACKGROUND (white light particles)
   A fixed canvas BEHIND the ambient halos (z -2 < aura's -1):
   tiny white particles at different depths — far ones sharp and
   faint, near ones big soft bokeh, a few with a fine flare.
   Slow, almost imperceptible drift + depth parallax on scroll.
   REVERT: remove this block + the <canvas class="void-stars">
   in experience.html + the voidStars() block in experience.js.
   Quick A/B without the field: load experience.html?nostars
   ========================================================= */
.void-stars{position:fixed;inset:0;z-index:-2;pointer-events:none}

/* =========================================================
   MÉTHODE · ORBIT OF FOUR STEPS — the process floats in the void.
   The four steps ride a slow, slightly tilted 3D orbit: the front
   one reads sharp; the others turn away, recede and melt into the
   navy. Autonomous meditative rotation; drag / horizontal wheel
   turns it; the floating ghost numbers below summon a step.
   Page scroll is never hijacked (same rule as the book/cover flow).
   ========================================================= */
.mthd{position:relative;padding:clamp(4.5rem,10vw,8rem) var(--gutter) clamp(4rem,9vw,7rem);
  border-top:1px solid var(--line);overflow:hidden}
.mthd__head{margin-bottom:clamp(.4rem,1.6vw,1.2rem)}
.mthd__head .eyebrow{margin-bottom:1.1rem}
.mthd__head h2{font-size:var(--s3);color:var(--cream);max-width:20ch}
.mthd__hint{margin-top:.7rem;font-size:var(--s-1);letter-spacing:.16em;text-transform:uppercase;color:var(--cream-dim)}
.mthd__orbit{position:relative;height:clamp(330px,46vh,470px);margin-top:clamp(1.35rem,3vw,2.25rem);perspective:1200px;perspective-origin:50% 38%;
  touch-action:pan-y;cursor:grab;outline:none;-webkit-tap-highlight-color:transparent}
.mthd__orbit:active{cursor:grabbing}
.mthd__stage{position:absolute;inset:0;transform-style:preserve-3d}
/* one step — a POLISHED-GLASS slab floating in the void. The orbit transform lives on .mstep (JS) ;
   the card inside FLIPS on its own Y axis on click (fast, with a depth pop at mid-turn) to reveal
   the full text on its back, scrollable like the Prestations window (fade masks + quiet chevrons). */
.mstep{position:absolute;left:50%;top:50%;width:min(78vw,430px);height:clamp(310px,44vh,410px);margin:0;
  --edge-glow:0;--edge-shine:.5;
  will-change:transform,opacity,filter;user-select:none;perspective:1150px}
.mstep.is-reading-step{will-change:auto;perspective:none;transform-style:flat}
.mstep__card{position:relative;width:100%;height:100%;transform-style:preserve-3d;cursor:pointer}
.mstep__card::after{content:"";position:absolute;inset:-1px;border-radius:18px;pointer-events:none;z-index:4;
  mix-blend-mode:screen;opacity:var(--edge-glow);
  background:
    linear-gradient(to bottom,
      transparent calc(var(--edge-shine)*100% - 16%),
      rgba(255,255,255,.34) calc(var(--edge-shine)*100% - 5%),
      #fff calc(var(--edge-shine)*100%),
      rgba(255,255,255,.34) calc(var(--edge-shine)*100% + 5%),
      transparent calc(var(--edge-shine)*100% + 16%)) left top / 1px 100% no-repeat,
    linear-gradient(to bottom,
      transparent calc(var(--edge-shine)*100% - 16%),
      rgba(255,255,255,.3) calc(var(--edge-shine)*100% - 5%),
      #fff calc(var(--edge-shine)*100%),
      rgba(255,255,255,.3) calc(var(--edge-shine)*100% + 5%),
      transparent calc(var(--edge-shine)*100% + 16%)) right top / 1px 100% no-repeat,
    linear-gradient(to bottom,
      transparent calc(var(--edge-shine)*100% - 13%),
      rgba(255,255,255,.16) calc(var(--edge-shine)*100%),
      transparent calc(var(--edge-shine)*100% + 13%)) left top / 5px 100% no-repeat,
    linear-gradient(to bottom,
      transparent calc(var(--edge-shine)*100% - 13%),
      rgba(255,255,255,.14) calc(var(--edge-shine)*100%),
      transparent calc(var(--edge-shine)*100% + 13%)) right top / 5px 100% no-repeat;
  filter:drop-shadow(0 0 8px rgba(255,255,255,.95)) drop-shadow(0 0 16px rgba(255,255,255,.45))}
/* flip aller/retour : rapide mais marqué — pop de profondeur (translateZ) + léger sursaut d'échelle à
   mi-course quand l'arête traverse l'écran. `was-flipped` (posée au 1er flip) évite que l'animation
   de retour ne se joue au chargement de la page. */
/* AXE AU CENTRE : translateZ AVANT rotateY — le pop de profondeur part droit vers le spectateur,
   l'axe de rotation reste pile au milieu du bloc (après rotateY, un translateZ déporte le bloc
   sur le CÔTÉ en plein virage → l'axe semblait décentré).
   SANS PAUSE : l'easing CSS s'applique à CHAQUE segment de keyframes → avec un seul bezier le bloc
   s'arrêtait net à mi-course. Ici : segment 1 accélère, segment 2 décélère → vitesse continue. */
.mstep__card.is-flipped{animation:mstepFlip .72s linear both}
.mstep__card.was-flipped:not(.is-flipped){animation:mstepFlipBack .66s linear both}
.mstep__card.is-flipped.is-reading{animation:none;transform:none;transform-style:flat}
@keyframes mstepFlip{
  0%{transform:translateZ(0) rotateY(0deg);animation-timing-function:cubic-bezier(.55,.06,.78,.46)}
  50%{transform:translateZ(74px) rotateY(90deg);animation-timing-function:cubic-bezier(.22,.54,.25,1)}
  100%{transform:translateZ(0) rotateY(180deg)}}
@keyframes mstepFlipBack{
  0%{transform:translateZ(0) rotateY(180deg);animation-timing-function:cubic-bezier(.55,.06,.78,.46)}
  50%{transform:translateZ(74px) rotateY(90deg);animation-timing-function:cubic-bezier(.22,.54,.25,1)}
  100%{transform:translateZ(0) rotateY(0deg)}}
/* polished glass — same material family as the f3x window / preview panel */
.mstep__face{position:absolute;inset:0;border-radius:18px;overflow:hidden;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  display:flex;flex-direction:column;padding:clamp(1.15rem,2.4vw,1.7rem);isolation:isolate;
  border:1px solid rgba(237,230,218,.16);
  background:
    linear-gradient(135deg,rgba(255,255,255,.075),rgba(255,255,255,.024) 45%,rgba(255,255,255,.052)),
    rgba(7,15,28,.28);
  -webkit-backdrop-filter:blur(34px) saturate(1.32);backdrop-filter:blur(34px) saturate(1.32);
  box-shadow:0 30px 70px -30px rgba(0,0,0,.78), 0 0 50px rgba(0,0,0,.25)}
.mstep__face::before{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;
  background:linear-gradient(120deg,rgba(255,255,255,.07),transparent 30%,rgba(255,255,255,.024) 70%,rgba(255,255,255,.05))}
/* REFLET DE RELIEF mouvant — une bande spéculaire (blend screen) qui GLISSE sur le verre avec le
   mouvement : --gx est posé chaque frame par le JS depuis l'angle du bloc (orbite + flottement + FLIP),
   même principe que le glint des feuilles de la section Prestations. */
.mstep__face::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:1;
  mix-blend-mode:screen;
  background:linear-gradient(112deg,
    transparent calc(var(--gx,50%) - 16%),
    rgba(255,250,238,.07) calc(var(--gx,50%) - 5%),
    rgba(255,252,242,.13) var(--gx,50%),
    rgba(255,250,238,.07) calc(var(--gx,50%) + 5%),
    transparent calc(var(--gx,50%) + 16%))}
.mstep__face > *{position:relative;z-index:2;opacity:var(--mtext-o,1);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  transform:translateZ(.01px);transition:opacity .12s linear}
.mstep__front{align-items:center;justify-content:center;text-align:center}
.mstep__no{display:block;font-family:var(--f-display);font-style:italic;font-weight:600;
  font-size:clamp(2.1rem,4.6vw,3rem);line-height:1;color:var(--brass);
  filter:drop-shadow(0 0 14px rgba(198,169,114,.26))}
.mstep__line{display:block;width:clamp(44px,6vw,76px);height:1px;margin:.8rem auto .9rem;
  background:linear-gradient(90deg,transparent,var(--brass) 30%,var(--brass) 70%,transparent);opacity:.75}
.mstep__name{font-family:var(--f-display);font-size:clamp(1.45rem,2.8vw,2.1rem);line-height:1.08;color:var(--cream)}
.mstep__txt{margin:.7rem auto 0;max-width:32ch;font-size:clamp(.9rem,1vw,1rem);line-height:1.6;color:var(--cream-dim)}
.mstep__cue{position:absolute;left:0;right:0;bottom:clamp(.85rem,1.8vw,1.2rem);z-index:2;
  font-size:.6rem;letter-spacing:.24em;text-transform:uppercase;color:rgba(198,169,114,.8);text-align:center}
/* back face — pre-turned 180°, revealed by the flip; the text scrolls like the Prestations window */
.mstep__back{transform:rotateY(180deg);text-align:left}
.mstep__card.is-reading .mstep__front{opacity:0!important;visibility:hidden;pointer-events:none}
.mstep__card.is-reading .mstep__back{transform:none;backface-visibility:visible;-webkit-backface-visibility:visible}
.mstep__card.is-reading .mstep__back > *{opacity:1!important;transform:none}
.mstep__card.is-reading .mstep__body{-webkit-mask-image:none;mask-image:none;transition:none}
.mstep__card.is-reading .mstep__back,
.mstep__card.is-reading .mstep__back *{filter:none!important;text-shadow:none!important;-webkit-font-smoothing:auto;text-rendering:auto}
.mstep__bhead{display:flex;align-items:baseline;gap:.6rem;flex:0 0 auto;
  padding-bottom:.6rem;margin-bottom:.75rem;border-bottom:1px solid rgba(237,230,218,.13)}
.mstep__bno{font-family:var(--f-display);font-style:italic;font-size:1.15rem;color:var(--brass);line-height:1}
.mstep__bhead h4{margin:0;font-family:var(--f-display);font-weight:600;font-size:clamp(1.15rem,2vw,1.4rem);line-height:1.1;color:var(--cream)}
.mstep__body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;touch-action:pan-y;
  --fadeT:0px;--fadeB:0px;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 var(--fadeT),#000 calc(100% - var(--fadeB)),transparent 100%);
  mask-image:linear-gradient(to bottom,transparent,#000 var(--fadeT),#000 calc(100% - var(--fadeB)),transparent 100%);
  transition:--fadeT .4s var(--ease),--fadeB .4s var(--ease)}
.mstep__body::-webkit-scrollbar{display:none}
.mstep__body p{margin:0;font-size:clamp(.88rem,1vw,.97rem);line-height:1.62;color:rgba(237,230,218,.85)}
.mstep__body p + p{margin-top:.75rem}
.mstep__cue--back{position:static;margin-top:.7rem;flex:0 0 auto;text-align:left}
/* quiet chevrons (desktop only, shown when the text overflows) — same language as the f3x window */
.mstep__bnav{display:none;position:absolute;right:.6rem;top:50%;transform:translateY(-50%);z-index:3;
  flex-direction:column;gap:.5rem}
.mstep__bbtn{display:flex;align-items:center;justify-content:center;width:26px;height:26px;margin:0;padding:0;
  border:1px solid rgba(237,230,218,.16);border-radius:999px;background:rgba(7,15,28,.18);cursor:pointer;
  color:var(--cream-dim);transition:color .35s var(--ease),border-color .35s var(--ease),opacity .35s var(--ease)}
.mstep__bbtn svg{width:11px;height:7px;display:block}
.mstep__bbtn:hover{color:var(--brass);border-color:rgba(198,169,114,.55)}
.mstep__bbtn.is-off{opacity:.22;pointer-events:none}
@media(min-width:761px){
  .mstep__bnav.is-on{display:flex}
  .mstep__back .mstep__body{padding-right:2.1rem}
}
/* floating ghost number buttons — same quiet language as .f3x__navbtn / .cf__nav */
.mthd__dial{display:flex;justify-content:center;gap:clamp(.7rem,2vw,1.15rem);
  margin-top:clamp(.4rem,1.6vw,1.1rem)}
.mthd__dot{width:46px;height:46px;border:1px solid var(--line);border-radius:50%;
  display:grid;place-items:center;background:rgba(7,15,28,.18);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  font-family:var(--f-display);font-style:italic;font-size:.92rem;color:var(--cream-dim);
  transition:color .4s var(--ease),border-color .4s var(--ease),transform .4s var(--ease),box-shadow .4s var(--ease)}
.mthd__dot:hover{color:var(--brass);border-color:rgba(198,169,114,.55)}
.mthd__dot.is-on{color:var(--brass);border-color:rgba(198,169,114,.75);transform:translateY(-3px);
  box-shadow:0 0 22px rgba(198,169,114,.16), 0 10px 24px -12px rgba(0,0,0,.7)}
@media(max-width:900px){
  .mthd__orbit{height:clamp(300px,44vh,420px)}
}
/* boutons 01-04 retirés en MOBILE et TABLETTE/iPad (appareil tactile OU écran ≤1024px) :
   l'orbite se pilote au doigt (glisser) et avance toute seule — les chiffres flottants restent desktop. */
@media (hover:none),(max-width:1024px){
  .mthd__dial{display:none}
}
/* ============================================================================
   MÉTHODE — 4 BANDES VERTICALES, photo plein cadre, en 3D.
   Idle : rangée de 4 bandes verticales (chacune affiche SA photo, plein cadre). Au clic,
   la carte choisie passe DEVANT (photo + texte dans le même bloc) et les autres PIVOTENT
   (rotateY) et se rangent sur les côtés — elles ne sortent plus de l'écran. Les positions
   sont calculées par experience.js (layoutMethod) ; le CSS tient la matière + le texte.
   ============================================================================ */
.mthd__head{margin-bottom:clamp(1.6rem,3.4vw,2.8rem)}
.mthd__bands{position:relative;height:clamp(360px,56vh,560px);margin:0 auto;
  perspective:1600px;perspective-origin:50% 48%;transform-style:preserve-3d}
.mband{position:absolute;top:50%;left:50%;height:clamp(320px,50vh,500px);width:200px;
  border-radius:20px;overflow:hidden;cursor:pointer;transform:translate(-50%,-50%);
  transform-origin:center center;backface-visibility:hidden;border:1px solid rgba(237,230,218,.14);
  box-shadow:0 34px 80px -36px rgba(0,0,0,.85);
  transition:transform .72s cubic-bezier(.2,.7,.2,1), width .72s cubic-bezier(.2,.7,.2,1),
             opacity .55s var(--ease), box-shadow .55s var(--ease);
  will-change:transform,width,opacity}
.mband__photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(1.08) contrast(1.03)}
.mband__scrim{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,rgba(6,13,26,.9) 0%,rgba(6,13,26,.42) 42%,rgba(6,13,26,.06) 100%);
  transition:background .55s var(--ease)}
.mband__hit{position:absolute;inset:0;z-index:2;border:0;background:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.mband__face{position:absolute;inset:0;z-index:3;pointer-events:none;display:flex;flex-direction:column;
  justify-content:flex-end;padding:clamp(1rem,2.2vw,1.6rem);color:var(--cream)}
.mband__no{font-family:var(--f-display);font-style:italic;font-weight:600;line-height:1;
  font-size:clamp(1.5rem,2.6vw,2.2rem);color:var(--brass);filter:drop-shadow(0 1px 8px rgba(0,0,0,.5))}
.mband__name{margin:.35rem 0 0;font-family:var(--f-display);line-height:1.08;
  font-size:clamp(1.15rem,1.7vw,1.6rem);color:var(--cream);text-shadow:0 2px 14px rgba(0,0,0,.6)}
/* accroche masquée : les titres des 4 bandes s'alignent ainsi tous à la même hauteur (bas) */
.mband__tease{display:none}
.mband__body{margin:.7rem 0 0;font-size:clamp(.9rem,1.02vw,1rem);line-height:1.65;color:rgba(237,230,218,.9);
  text-shadow:0 1px 10px rgba(0,0,0,.55);max-width:42ch;max-height:0;overflow:hidden;opacity:0;
  transition:max-height .6s var(--ease),opacity .5s var(--ease),margin .5s var(--ease)}
.mband__body p{margin:0}
.mband__body p+p{margin-top:.7rem}
/* flèches de défilement SOBRES (desktop uniquement, affichées seulement si le texte déborde) :
   pas de bouton « Revenir » — on referme en re-cliquant la carte, sur une autre, ou via Échap. */
.mband__nav{position:absolute;right:clamp(.7rem,1.6vw,1.2rem);bottom:clamp(.7rem,1.6vw,1.2rem);z-index:4;
  display:none;flex-direction:column;gap:.5rem;pointer-events:none}
.mband__navbtn{pointer-events:auto;display:flex;align-items:center;justify-content:center;width:30px;height:30px;
  padding:0;border:1px solid rgba(237,230,218,.3);border-radius:999px;background:rgba(6,13,26,.5);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:var(--cream-dim);cursor:pointer;
  transition:color .3s var(--ease),border-color .3s var(--ease),opacity .3s var(--ease)}
.mband__navbtn svg{width:11px;height:7px;display:block}
.mband__navbtn path{fill:none;stroke:currentColor;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}
.mband__navbtn:hover{color:var(--brass);border-color:rgba(198,169,114,.6)}
.mband__navbtn.is-off{opacity:.22;pointer-events:none}
/* survol au repos : léger lift (le transform reste piloté par le JS) */
.mthd__bands:not(.has-open) .mband:hover{box-shadow:0 42px 90px -36px rgba(0,0,0,.9),0 0 30px -10px rgba(198,169,114,.3)}
.mthd__bands:not(.has-open) .mband:hover .mband__scrim{background:linear-gradient(to top,rgba(6,13,26,.82) 0%,rgba(6,13,26,.3) 46%,rgba(6,13,26,0) 100%)}
/* carte SÉLECTIONNÉE (en face) : photo + texte dans le même bloc, dégradé renforcé pour lire le texte */
.mband.is-open{z-index:60;border-color:rgba(198,169,114,.5);
  box-shadow:0 50px 110px -40px rgba(0,0,0,.92),0 0 40px -10px rgba(198,169,114,.28)}
.mband.is-open .mband__scrim{background:linear-gradient(100deg,rgba(5,12,24,.93) 0%,rgba(5,12,24,.74) 40%,rgba(5,12,24,.2) 72%,rgba(5,12,24,0) 100%)}
.mband.is-open .mband__face{justify-content:flex-start;
  padding:clamp(.65rem,1.6vw,1.3rem) clamp(1.6rem,3.2vw,3rem) clamp(1.4rem,3vw,2.6rem)}
.mband.is-open .mband__name{font-size:clamp(1.6rem,2.6vw,2.3rem)}
.mband.is-open .mband__tease{opacity:0;max-height:0;margin:0}
.mband.is-open .mband__body{max-height:46vh;opacity:1;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none;
  pointer-events:auto;touch-action:pan-y;-webkit-overflow-scrolling:touch}
.mband.is-open .mband__body::-webkit-scrollbar{display:none}
/* Fondu bas = calque STATIQUE sur la carte (ne scrolle PAS). Un mask-image sur la zone qui défile
   re-rasterise à chaque frame = vibration. Affiché seulement si le texte déborde (.has-scroll posé par le JS). */
.mband.is-open.has-scroll::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:clamp(1.5rem,3.4vw,2.4rem);z-index:3;pointer-events:none;
  background:linear-gradient(to top,rgba(5,12,24,.96),rgba(5,12,24,.6) 45%,transparent)}
/* flèches visibles UNIQUEMENT sur desktop, et seulement quand le texte de la carte ouverte déborde */
@media(min-width:761px){
  .mband.is-open .mband__nav.is-scrollable{display:flex}
}
@media(max-width:900px){
  /* MÉTHODE MOBILE = ACCORDÉON À PHOTOS, 100% PLAT — aucune 3D/perspective (la scène 3D laissait un
     calque GPU lourd sur iOS = lag persistant au retour). 4 cartes empilées, tap = déplie le texte. */
  .mthd__bands{position:static;display:flex;flex-direction:column;gap:.7rem;height:auto;min-height:0;
    perspective:none;transform-style:flat;padding:0 clamp(1rem,4vw,1.5rem);max-width:560px;margin:0 auto;
    align-items:stretch}
  .mband{position:relative;top:auto;left:auto;width:auto!important;height:auto;
    transform:none!important;opacity:1!important;border:0;border-radius:16px;overflow:hidden;
    box-shadow:0 8px 22px -16px rgba(0,0,0,.55);will-change:auto;transition:none}
  .mband__photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
  .mband__scrim{position:absolute;inset:0;
    background:linear-gradient(to top,rgba(6,13,26,.92),rgba(6,13,26,.42) 48%,rgba(6,13,26,.12))}
  .mband.is-open .mband__scrim{background:linear-gradient(to bottom,rgba(5,12,24,.55),rgba(5,12,24,.9) 30%,rgba(5,12,24,.96))}
  /* la FACE (en flux, position:relative) pilote la hauteur de la carte : repli = bannière ; ouvert = + texte */
  .mband__face{position:relative;inset:auto;z-index:3;justify-content:flex-end;
    min-height:clamp(104px,29vw,146px);padding:clamp(.85rem,3.4vw,1.2rem)}
  .mband.is-open .mband__face{justify-content:flex-start}
  .mband__no{font-size:clamp(1.3rem,5vw,1.7rem)}
  .mband__name{font-size:clamp(1.05rem,4.6vw,1.35rem)}
  .mband__tease{display:block;opacity:.82;font-size:.8rem;margin-top:.18rem}      /* accroche visible quand replié */
  .mband.is-open .mband__tease{display:none}
  .mband__body{max-height:0;opacity:0;overflow:hidden;margin:0;
    transition:max-height .45s var(--ease),opacity .35s var(--ease),margin .35s var(--ease)}
  .mband.is-open .mband__body{max-height:1200px;opacity:1;margin-top:.55rem;overflow:visible}
  .mband__nav{display:none!important}                  /* pas de flèches : la carte grandit, la page défile */
  .mband.is-open.has-scroll::after{display:none}       /* pas de fondu/scroll interne en mobile plat */
}
@media(prefers-reduced-motion:reduce){
  .void-stars{display:none}
}

@media(max-height:500px) and (pointer:coarse){
  .cf.is-previewing .cf__stage{
    transform:none;
    transform-origin:center center;
    animation:none;
    opacity:0;
    filter:blur(5px);
  }
  .cf.is-previewing + .cf__cap{opacity:0}
  .cfx{display:block!important;top:50%;left:50%;right:auto;bottom:auto;z-index:4;
    width:var(--cfx-w,min(76vw,420px));height:var(--cfx-h,min(62svh,390px));overflow:visible;touch-action:pan-y;
    transform:translate(-50%,-46%) scale(.96)}
  .cfx.is-open{transform:translate(-50%,-50%) scale(1)}
  .cfx.is-closing{transform:translate(-74%,-50%) scale(.96)}
  .cfx__fig{position:absolute;inset:0;margin:0;overflow:hidden;border-radius:0;
    -webkit-mask-image:none;mask-image:none}
  .cfx__fig img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;border-radius:0;filter:none}
  .cfx__fig::after{display:block;content:"";position:absolute;inset:0;pointer-events:none;
    background:
      radial-gradient(ellipse 62% 52% at 0% 0%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%),
      radial-gradient(ellipse 62% 52% at 100% 0%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%),
      radial-gradient(ellipse 62% 52% at 0% 100%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%),
      radial-gradient(ellipse 62% 52% at 100% 100%,rgba(7,15,28,1) 0%,rgba(7,15,28,.9) 18%,rgba(7,15,28,.52) 48%,transparent 82%)}
  .cfx__nav-bar{display:none!important}
}

/* ============================================================================
   PERF MOBILE — le backdrop-filter (flou du fond) est RECALCULÉ à chaque frame dès
   qu'une animation 3D bouge devant/autour (cover-flow, éventail, Méthode) → c'est LE
   tueur de FPS sur téléphone (animations « au ralenti »). On le SUPPRIME entièrement
   sur mobile et on rend opaques les éléments « verre » qui s'appuyaient dessus pour
   leur lisibilité. DESKTOP STRICTEMENT INCHANGÉ (bloc sous @media max-width:900px).
   ========================================================================== */
@media (max-width:900px){
  .hd__toggle,.cf-cats,.cf-cat,.g3d__sub,.cf__nav,.cfx__nav,.cfx__nav-bar,
  .mthd__dial,.mthd__dot,.mband__navbtn,.cfx__panel-in,.f3x__glass,.f3x__bg,.contact-modal__glass,
  .contact-choice__menu,.contact-modal__bg,.mstep__face{
    -webkit-backdrop-filter:none !important;backdrop-filter:none !important}
  /* fonds opaques de repli (le flou n'assure plus le contraste) */
  .cfx__panel-in,.f3x__glass,.contact-modal__glass,.contact-choice__menu,.mstep__face{
    background:rgba(10,17,30,.94) !important}
  .hd__toggle{background:rgba(7,15,28,.86) !important}
  /* POP-UPS OUVERTS (prestations / contact) : on REMET le verre poli + l'arrière-plan flou. Sans coût :
     quand le pop-up est ouvert, le scroll et toutes les animations 3D sont bloqués → RIEN ne bouge
     derrière le flou → le backdrop-filter ne se recalcule pas par frame. À la fermeture (retrait de
     is-open), tout redevient net/léger automatiquement. Spécificité (0,2,0)+!important > le none ci-dessus. */
  /* iOS Safari N'APPLIQUE PAS backdrop-filter ici (désactivé en mode éco + ignoré sous les ancêtres
     transform/perspective de la carte) → « pas de flou ». On floute donc le CONTENU de la page derrière
     avec un `filter:blur` CLASSIQUE (fiable partout, même mode éco), posé par JS via .popup-blur sur
     <html>. Les pop-ups (.f3x/.contact-modal, enfants directs de main) sont EXCLUS → restent nets.
     Tout est figé pendant l'ouverture → le flou est calculé une fois = aucun lag. À la fermeture, la
     classe part → tout redevient net instantanément. */
  html.popup-blur .hd,
  html.popup-blur main > *:not(.f3x):not(.contact-modal){
    filter:blur(9px) brightness(.84) !important}
  /* La carte = VERRE POLI bien visible SANS dépendre du backdrop (qui échoue sur iOS) : reflet de
     lumière en diagonale (dégradé clair) + liseré clair + highlight interne en haut → ça lit comme
     du verre dépoli sur n'importe quel fond. Le filter:blur du contenu (ci-dessus) ajoute le flou
     quand le fond a du détail ; sinon le fond reste nettement assombri (modal). */
  .f3x.is-open .f3x__glass,
  .contact-modal.is-open .contact-modal__glass{
    -webkit-backdrop-filter:none !important;backdrop-filter:none !important;
    background:linear-gradient(135deg,rgba(255,255,255,.14),rgba(255,255,255,.03) 42%,rgba(255,255,255,.09)),rgba(16,24,40,.6) !important;
    border:0 !important;                                              /* pas de contour/relief (demande user) */
    box-shadow:0 30px 80px -28px rgba(0,0,0,.6) !important}           /* ombre douce de profondeur uniquement (pas d'inset highlight) */
  .f3x.is-open .f3x__bg,
  .contact-modal.is-open .contact-modal__bg{
    -webkit-backdrop-filter:none !important;backdrop-filter:none !important;
    background:rgba(4,9,18,.5) !important}
  .contact-modal.is-open .contact-choice__menu{
    -webkit-backdrop-filter:blur(20px) saturate(1.2) !important;backdrop-filter:blur(20px) saturate(1.2) !important;
    background:linear-gradient(135deg,rgba(255,255,255,.05),rgba(255,255,255,.012)),rgba(8,14,26,.5) !important}
  /* halos du fond FIGÉS sur mobile (plus de dérive en boucle = perf + demande user) ; restent visibles */
  .aura__orb{animation:none !important}
  .cf__nav,.cfx__nav{background:rgba(7,15,28,.72) !important}
  .cf-cat,.mthd__dial,.mthd__dot{background:rgba(7,15,28,.62) !important}
  .mband__navbtn{background:rgba(6,13,26,.78) !important}
  /* Ombres des covers ALLÉGÉES sur mobile : l'ombre 54/76px agrandit énormément la texture GPU de
     chaque cover (mémoire VRAM, critique sur iOS). Une ombre compacte = texture plus petite, peinte
     une fois, déplacée par transform. Le voile est géré par opacity (JS) → ::after neutralisé ici. */
  .cf__item{box-shadow:none !important}   /* ombre retirée : re-rastérisée à chaque frame pendant la rotation 3D = coût fill-rate */
  .cf__item::after{display:none}
  /* ÉVENTAIL — overlays coûteux RETIRÉS sur mobile : le « fan se dégrade quand on montre son bas »
     = fill-rate (plus la surface des feuilles animées est visible, plus c'est lourd). Le glint
     (filter:blur + mix-blend-mode:screen + 2 drop-shadow) est recomposé à CHAQUE frame de rotation
     ×8 feuilles = le tueur de FPS ; la ligne laiton (::before) est aussi un dégradé repeint. On les
     supprime (gelés en v6 = valeur figée mais TOUJOURS peints). Le voile/dégradé de lisibilité reste. */
  .leaf__glint{display:none !important}
  .leaf::before{display:none !important}
  /* section hors écran (classe posée par IntersectionObserver) : on relâche les bitmaps décodées
     → rend la VRAM iOS aux autres sections. Re-décodage bref au retour. Une seule section garde
     ses images décodées à la fois (cover-flow ↔ éventail ↔ Méthode). */
  /* (cover-flow : plus de imgs-free — covers -xs gardés décodés en permanence) */
  .book.imgs-free .leaf{background-image:none !important}           /* éventail : background des feuilles (l'inline revient au retour) */
  /* (Méthode : plus de imgs-free — 4 photos gardées décodées) */
  /* MÉTHODE : on retire la « lueur/halo » laiton qui sort des bandes (0 0 40px rgba(198,169,114))
     et on réduit fortement les ombres floues (perf + demande user). Le liseré laiton fin reste. */
  .mband{box-shadow:0 8px 22px -16px rgba(0,0,0,.55) !important}
  .mthd__bands:not(.has-open) .mband:hover{box-shadow:0 8px 22px -16px rgba(0,0,0,.55) !important}
  .mband.is-open{box-shadow:0 10px 26px -18px rgba(0,0,0,.55) !important}
  /* will-change PONCTUEL : au REPOS, feuilles de l'éventail et bandes Méthode ne gardent PAS de calque
     GPU (sinon 8 + 4 calques permanents s'ajoutent aux covers → la VRAM iOS sature et la page ralentit
     de plus en plus en passant d'un bloc à l'autre). Le calque est créé seulement pendant l'animation. */
  .leaf{will-change:auto}
  .book.is-busy .leaf{will-change:transform,opacity}
  .mband{will-change:auto}
  .mthd__bands.has-open .mband,.mband.is-open{will-change:transform}
  /* titres figés (JS) → plus besoin d'un calque GPU permanent */
  .float3d__in{will-change:auto}
  /* mobile : pas de catégorie « Toutes » (57 covers d'un coup = trop lourd) → on navigue par catégorie */
  .cf-cats [data-cf-cat="toutes"]{display:none !important}
}
