/* Biostem — feuille du site de maquette.
   Reprise telle quelle du vrai projet client dont elle sort ; seuls le nom
   de la police de titrage et le chemin du fichier ont changé. Ce qui
   distingue la maquette du site est dans biostem-mockup.css. */

/* « Biostem Titre » : Tenor Sans (piste B de _titres.html) aux accents de
   Jost. Ceux de Tenor, effilés en pointe, ne tenaient pas à la taille du
   slogan : à 34px le É se lisait È et le circonflexe paraissait cassé. Un
   défaut de dessin, qu'aucun réglage CSS ne corrigeait (contour, ombre,
   modes de rendu : tous essayés à l'écran).
   Les accents aigu, grave et circonflexe des 32 voyelles accentuées
   (capitales et minuscules) sont remplacés par ceux de Jost en graisse 360,
   à 85 % de leur taille, centrés là où Tenor posait les siens : un trait
   régulier, lisible à 34px, sans alourdir les lettres fines de Tenor. Les
   graisses 420 et l'échelle 1 ont été essayées, trop appuyées. Fichier
   construit avec fontTools, sans hinting.
   Licence OFL pour les deux polices (assets/fonts/OFL-*.txt). Tenor Sans
   réserve les noms « Tenor » et « Tenor Sans » : la version modifiée ne peut
   pas les porter, d'où « Biostem Titre ». */
@font-face{
  font-family:"Biostem Titre";
  src:url("../fonts/biostem-titre.woff2") format("woff2");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}

:root{
  --ink:      #0d0d0c;
  --paper:    #f4f2ee;
  /* piste C de _polices.html, d'après la charte de Chenot : Satoshi tient
     l'interface et le texte ; Zodiak, les accents. Les titres sont en Tenor
     Sans, choisie sur _titres.html (piste B), aux accents de Jost :
     « Biostem Titre », voir @font-face plus haut. */
  --font-ui:     "Satoshi","Helvetica Neue",Arial,sans-serif;
  --font-accent: "Zodiak",Georgia,"Times New Roman",serif;
  --font-titre:  "Biostem Titre","Helvetica Neue",Arial,sans-serif;

  --gutter:   clamp(21px, 4vw, 55px);
  --ease:     cubic-bezier(.22,.61,.36,1);

  /* bouton de réservation : rayon, et retrait du bas — les deux dans
     la suite fusionnée. 8 et non plus la demi-hauteur : les capsules passent
     à des rectangles aux angles adoucis, plus angulaires. */
  --pill-r:     8px;
  --resa-b:     clamp(21px, 5vh, 34px);

  
  --bleed: 13px;

  
  --espace-section: clamp(89px, 14vh, 199px);

  
  --or: #bf9b6f;
  
  --or-nappe: radial-gradient(76% 144% at 50% 110%,
    color-mix(in srgb, var(--or) 42%, transparent) 0%,
    color-mix(in srgb, var(--or) 16%, transparent) 55%,
    transparent 100%);
}

*,*::before,*::after{ box-sizing:border-box }

/* overflow:hidden et height:100% retirés : ils bloquaient le défilement, et
   n'avaient de raison que tant que rien ne suivait le banner — son débord de
   13px ne devait pas ouvrir un ascenseur sur du vide. Une section le suit
   désormais : le débord est ce qu'on découvre au premier geste. */
html,body{
  margin:0;
  background:var(--ink);
  font-family:var(--font-ui);
  font-weight:300;
}

html{
  scrollbar-width:none;
  -ms-overflow-style:none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar{ display:none }
img{ display:block; max-width:100% }
a{ color:inherit; text-decoration:none }

/* Pictos aux viewBox rognés au ras du dessin : la boîte du SVG coupe tout ce
   qui la dépasse, y compris le demi-pixel d'antialiasing de ses bords. Les
   courbes qui touchent le cadre en sortaient crénelées et aplaties — le G des
   avis paraissait tronqué en bas. overflow:visible laisse ce lissage déborder. */
.header__logo svg,
.header__icon svg,
.resaBar__points,
.hero__avisG{ overflow:visible }

/* --- Lenis (reprise de dist/lenis.css, intégrée pour éviter une requête) --- */
html.lenis, html.lenis body{ height:auto }
.lenis.lenis-smooth{ scroll-behavior:auto !important }
.lenis.lenis-smooth [data-lenis-prevent]{ overscroll-behavior:contain }
.lenis.lenis-stopped{ overflow:hidden }
.lenis.lenis-smooth iframe{ pointer-events:none }

/* overflow-x:clip   rien à faire défiler de côté ; clip et NON hidden, qui
                     ferait de la racine un conteneur de défilement et
                     casserait tout position:sticky à venir.
   overscroll-behavior  coupe le dépassement au-delà du haut ou du bas de la
                     page (elle se décollait de l'écran et découvrait le fond
                     du navigateur) et le balayage « retour » du pad.
   touch-action      au doigt, seul le défilement vertical passe ; pinch-zoom
                     reste permis pour les visiteurs qui voient mal. */
html, body{
  overflow-x:clip;
  overscroll-behavior:none;
  touch-action:pan-y pinch-zoom;
}

/* le texte ne se surligne plus ; les champs de saisie gardent la sélection */
body{
  -webkit-user-select:none;
  user-select:none;
}
input, textarea{
  -webkit-user-select:text;
  user-select:text;
}

/* le « fantôme » : la vignette qu'on détache en glissant une image, un logo,
   un picto ou un lien. -webkit-user-drag ne vaut que chez WebKit et Blink —
   l'écouteur dragstart de main.js couvre le reste. */
img, svg, video, picture, a{
  -webkit-user-drag:none;
}

.header{
  position:fixed;
  inset:0 0 auto 0;
  z-index:10;
  display:flex;
  flex-direction:column;
  
  background:var(--paper);
  /* Il remonte avec le banner, du même décalage que sa vidéo (--header-y,
     écrit par main.js avec --hero-y) : pendant que la section 1 glisse
     par-dessus, le header et l'image s'en vont ensemble, un peu moins vite
     que la page.
     Un transform et non top : les sous-menus sont dans le header, en
     position:fixed calés sur --header-h. Un transform fait du header leur
     bloc de référence — ils le suivent et restent accrochés dessous, là où
     un top les aurait laissés seuls en haut de l'écran.
     Sous prefers-reduced-motion, main.js n'écrit rien : il reste en place. */
  transform:translate3d(0, var(--header-y, 0px), 0);
}

.header.is-detache{
  transform:translate3d(0, -100%, 0);
  transition:transform 843ms cubic-bezier(.45,0,.55,1);
}
.header.is-detache.is-revele{
  transform:translate3d(0, 0, 0);
  transition:transform 1597ms cubic-bezier(.16,1,.3,1);
}
/* La bande du haut, et le bloc de référence du logo centré en absolu
   (position:relative) — avant, c'était .header qui jouait ce rôle ; passé sur
   deux bandes, le centrer sur .header l'aurait mis à cheval sur les deux. */
.header__top{
  position:relative;
  height:89px;
  display:flex;
  align-items:center;
  /* space-between : le logo sort du flux (centré en absolu, voir
     .header__logo) ; restent deux enfants à ranger, la langue sur la
     gouttière de gauche, le groupe d'actions sur celle de droite. */
  justify-content:space-between;
  gap:21px;
  padding:0 var(--gutter);
}

.header__logo{
  display:inline-flex;
  position:absolute;
  top:calc(50% - 3px); left:50%;
  transform:translate(-55.94%,-50%);
  color:var(--ink);
}

.header__logo svg{ display:block; height:21px; width:auto }

/* le groupe de droite : un seul bloc pour le space-between de header__top, le
   dernier picto fermant la ligne sur la gouttière */
.header__actions{
  display:flex;
  align-items:center;
  gap:21px;
}

.header__icon{
  display:block;
  padding:8px;
  margin:-8px;
  color:rgba(13,13,12,.86);
  transition:color .55s var(--ease);
}
.header__icon svg{ display:block; height:18px; width:auto }
.header__icon:hover{ color:var(--ink) }
.header__icon:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:-3px;
}

/* Les pictos gagnent un cran d'écart entre eux, au-delà du gap commun
   (21px). .header__icon s'agrandit par padding:8px puis se retire d'autant
   par margin:-8px, pour que la zone cliquable dépasse sans déplacer le
   dessin — les deux s'annulent, le picto reste visuellement à sa place nue.
   Ramener margin-left à 0 pour chaque picto qui en suit un autre rouvre
   exactement les 8px de padding qu'il masquait : 21 + 8 = 29, le terme
   suivant de la suite fusionnée — du téléphone au compte comme du compte au
   sac, les trois se répondent à intervalle égal. Écrire margin-left:8px ici
   aurait AJOUTÉ ce cran aux 8px déjà rendus par le padding, pour 37px au lieu
   de 29. Adjacence plutôt qu'un ordinal : ne dépend pas de l'ordre des
   pictos. */
.header__icon + .header__icon{ margin-left:0 }

/* --- le sac : la pastille du panier ------------------------------------------
   Le nombre d'articles (main.js, PANIER), en or, posé sur l'angle haut droit
   du sac ; masquée quand le panier est vide. */
.header__icon--panier{ position:relative }
.header__pastille{
  position:absolute; top:1px; right:-1px;
  min-width:15px; height:15px; padding:0 4px; border-radius:8px;
  background:var(--or); color:#fff;
  font-size:10px; font-weight:500; line-height:15px; letter-spacing:0; text-align:center;
  font-variant-numeric:tabular-nums; pointer-events:none;
}

.header__icon--tel{ position:relative }
.header__icon--tel::before{
  content:"";
  display:block;
  width:18px;
  height:18px;
}
/* la progression du dévoilement, de 0 (replié) à 1 (dévoilé) : UNE valeur
   animée, dont se déduisent la glissade, le rognage et le fondu du numéro —
   les trois restent calés l'un sur l'autre à chaque image. Héritée : le
   numéro la lit sur la piste. */
@property --tel-p{
  syntax:"<number>";
  inherits:true;
  initial-value:0;
}
/* la progression du fondu du numéro : la même que --tel-p à l'apparition,
   plus rapide à la disparition (voir .header__telNumero) */
@property --tel-f{
  syntax:"<number>";
  inherits:true;
  initial-value:0;
}
.header__telPiste{
  position:absolute;
  top:8px;
  right:8px;
  height:18px;
  display:flex;
  align-items:center;
  gap:13px;
  /* replié : décalée de sa largeur moins le picto ; dévoilé : 0 */
  translate:calc((1 - var(--tel-p)) * (100% - 18px)) 0;
  /* bord droit du visible FIXE, 13px à droite de la place du picto — dans
     l'écart qui le sépare du compte, jamais sur lui : au-delà, rien n'est vu
     ni survolable */
  clip-path:inset(-5px calc((1 - var(--tel-p)) * (100% - 18px) - 13px) -5px -5px);
  transition:--tel-p .61s cubic-bezier(.45,0,.55,1),
             --tel-f .377s cubic-bezier(.45,0,.55,1);
}
.header__telPiste svg{ flex:none }

.header__telNumero{
  --tel-bord:calc(var(--tel-f) * (100% + 13px - .199em));
  --tel-rampe:34px;
  padding-block:5px;
  margin-block:-5px;
  font-size:11px;
  font-weight:400;
  letter-spacing:.199em;
  margin-right:-.199em;
  line-height:1;
  text-box:trim-both cap alphabetic;
  white-space:nowrap;
  -webkit-mask-image:linear-gradient(to right, #000 calc(var(--tel-bord) - var(--tel-rampe) * (1 - var(--tel-f))), transparent var(--tel-bord));
  mask-image:linear-gradient(to right, #000 calc(var(--tel-bord) - var(--tel-rampe) * (1 - var(--tel-f))), transparent var(--tel-bord));
}
@media (hover:hover){
  .header__icon--tel:hover .header__telPiste{
    --tel-p:1;
    --tel-f:1;
    transition:--tel-p .987s cubic-bezier(.33,0,.2,1),
               --tel-f .987s cubic-bezier(.33,0,.2,1);
  }
  .header__icon--tel:hover .header__telNumero{ --tel-rampe:55px }
  .header__icon--tel:hover .header__telPiste svg{
    animation:tel-sonne .61s cubic-bezier(.45,0,.55,1);
  }
}
.header__icon--tel:focus-visible .header__telPiste{
  --tel-p:1;
  --tel-f:1;
  transition:--tel-p .987s cubic-bezier(.33,0,.2,1),
             --tel-f .987s cubic-bezier(.33,0,.2,1);
}
.header__icon--tel:focus-visible .header__telNumero{ --tel-rampe:55px }
@keyframes tel-sonne{
  0%, 100%{ translate:0 0 }
  18%{ translate:-2px 0 }
  41%{ translate:2px 0 }
  62%{ translate:-1px 0 }
  81%{ translate:1px 0 }
}

/* --- Langue ---------------------------------------------------------------
   Le sélecteur, sur la gouttière de gauche (index.html, .header__lang) : la
   pastille du drapeau, le code de la langue, une flèche tournée vers la
   droite. Le code a le corps, la graisse et l'interlettrage du libellé de la
   pilule ; l'encre, celle des pictos, en face : les deux bouts de la ligne se
   répondent.
   padding + marge négative, comme les pictos : zone cliquable élargie, rien
   ne bouge. Sous 760px la pastille reste seule (voir la requête plus bas). */
.header__lang{
  position:relative;
  display:flex;
}
.header__langBouton{
  display:flex;
  align-items:center;
  gap:8px;
  padding:8px;
  margin:-8px;
  border:0;
  background:none;
  font:inherit;
  color:rgba(13,13,12,.86);
  cursor:pointer;
  transition:color .55s var(--ease);
}
.header__langBouton:hover,
.header__lang.is-ouvert .header__langBouton{ color:var(--ink) }
.header__langBouton:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:-3px;
}
/* le rognage du libellé de la pilule (.resaBar__label) : le centre des
   lettres sur celui de la pastille. margin-right rend le blanc que
   l'interlettrage pose après la dernière lettre. */
.header__langCode{
  font-size:11px;
  font-weight:400;
  letter-spacing:.199em;
  margin-right:-.199em;
  line-height:1;
  text-box:trim-both cap alphabetic;
}
/* 4 × 7, pointe à droite : elle montre où l'autre langue attend. Ouvert,
   elle se retourne — pointe à gauche, pour la faire rentrer — en se repliant
   sur elle-même (scaleX) et non en tournant : une rotation passerait par une
   pointe en bas, la direction d'une liste déroulante. Mêmes durées et mêmes
   courbes que le glissement du néerlandais (plus bas) : les deux mouvements
   n'en font qu'un. */
.header__langChevron{
  display:block;
  overflow:visible;
  transition:transform .843s cubic-bezier(.45,0,.55,1);
}
.header__lang.is-ouvert .header__langChevron{
  transform:scaleX(-1);
  transition:transform 1.364s cubic-bezier(.33,0,.2,1);
}

/* La pastille : 13px, le drapeau rogné en cercle par son conteneur
   (border-radius + overflow:hidden) — un clipPath par exemplaire demanderait
   autant d'identifiants uniques. Le filet intérieur, à peine visible, tient
   le contour là où une bande blanche touche le bord : sur --paper, le blanc
   s'y confondait. */
.header__langDrapeau{
  position:relative;
  flex:none;
  width:13px;
  height:13px;
  border-radius:50%;
  overflow:hidden;
}
.header__langDrapeau svg{ display:block; width:100%; height:100% }
.header__langDrapeau::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  box-shadow:inset 0 0 0 1px rgba(13,13,12,.1);
}

.header__langFenetre{
  --lang-course:21px;
  position:absolute;
  top:-8px;
  bottom:-8px;
  left:100%;
  display:flex;
  padding-left:var(--lang-course);
  overflow:hidden;
  pointer-events:none;
  -webkit-mask-image:linear-gradient(to right, transparent, #000 var(--lang-course));
          mask-image:linear-gradient(to right, transparent, #000 var(--lang-course));
}
/* margin-left -8px rend le padding du premier lien : son drapeau tombe à
   --lang-course de la flèche. gap 5 : avec les 8px de padding de part et
   d'autre, 21px entre EN et le drapeau néerlandais, l'écart de la flèche au
   premier drapeau.
   calc(-100% - var(--lang-course)) : toute la liste, paddings compris, à
   gauche du bord. */
.header__langListe{
  display:flex;
  gap:5px;
  margin:0 0 0 -8px;
  padding:0;
  list-style:none;
  visibility:hidden;
  transform:translateX(calc(-100% - var(--lang-course)));
  transition:transform .843s cubic-bezier(.45,0,.55,1), visibility 0s .843s;
}
.header__lang.is-ouvert .header__langListe,
html:not(.langue-js) .header__lang:focus-within .header__langListe{
  visibility:visible;
  transform:none;
  transition:transform 1.364s cubic-bezier(.33,0,.2,1), visibility 0s;
}
.header__langListe li{ display:flex }
/* même encre et même survol que le bouton : les langues se lisent pareil,
   seule la flèche les sépare. 8px de zone cliquable de chaque côté. */
.header__langLien{
  display:flex;
  align-items:center;
  gap:8px;
  padding:0 8px;
  color:rgba(13,13,12,.86);
  transition:color .55s var(--ease);
}
.header__lang.is-ouvert .header__langLien,
html:not(.langue-js) .header__lang:focus-within .header__langLien{ pointer-events:auto }
.header__langLien:hover{ color:var(--ink) }
.header__langLien:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:-3px;
}

/* La bande des onglets — 18px (voir le calcul de hauteur plus haut), sans
   filet contre header__top : les deux bandes partagent le même blanc et
   s'accolent d'un bloc, rien ne vient les couper.
   top:-13px — les onglets remontés, pour les éloigner du bord bas du header.
   Un décalage relatif et non une marge : la bande garde sa place dans le flux,
   le header garde exactement sa hauteur, seul le texte monte. */
.header__tabs{
  position:relative;
  top:-13px;
  height:18px;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:47px;
  padding:0 var(--gutter);
}
/* Même famille et même majuscule que le libellé de la pastille de
   réservation, et le même corps (11) : la bande est trop resserrée pour
   porter un texte plus grand qu'elle.
   line-height:1, comme .header__langCode et .resaBar__label — il manquait ici :
   sans lui la ligne garde l'interligne par défaut de la police (plus grand
   que 11px), qui mangeait à lui seul une bonne part des 18px de la bande. */
.header__tab{
  font-size:11px;
  font-weight:400;
  letter-spacing:.144em;
  line-height:1;
  text-transform:uppercase;
  white-space:nowrap;
  
  color:rgba(13,13,12,.8);
  transition:color .55s var(--ease);
}
.header__tab:hover{ color:var(--ink) }
.header__tab:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

/* ==========================================================================
   SOUS-MENUS — Amincissement et Soins seuls en ont un (voir index.html).
   Un petit SOUS HEADER, pas un menu flottant sous l'onglet : la bande
   s'ouvre pleine largeur, juste sous le header entier, comme une seconde
   bande qui apparaît — pas une carte qui pend sous un mot.
   .header__tabWrap reste le conteneur du survol (position:relative n'y sert
   plus à ancrer le panneau, qui est fixed et se cale tout seul — il reste le
   territoire que :hover et :focus-within doivent couvrir).
   ========================================================================== */
/* LE CLIGNOTEMENT, et ce qui le causait. Le survol se tient sur la languette
   (le mot de l'onglet, ~11px de haut), le panneau commence au bas du header :
   entre les deux, ~16px où le curseur ne survolait RIEN — écart creusé quand
   les onglets ont été remontés de 13px. En les traversant, :hover tombait,
   le panneau entamait son fondu de sortie ; mais pendant ce fondu il restait
   visible, donc survolable : le curseur arrivé dessus rallumait :hover, qui
   le rouvrait… — d'où le clignotement. Même chose d'un onglet à l'autre, à
   travers les 47px qui les séparent.
   Trois parades :
   1. le pont (ci-dessous) : la zone de survol descend jusqu'au bas du header
      et s'élargit jusqu'à toucher l'onglet voisin — plus aucune zone morte ;
   2. un panneau qui se ferme cesse aussitôt d'être survolable
      (pointer-events:none), même pendant que son contenu s'efface : il ne
      peut pas se rouvrir sous le curseur qu'il vient de quitter ;
   3. l'ouverture et la fermeture sont pilotées par main.js (SOUS-MENUS —
      ouverture), avec un temps d'intention à l'entrée et un temps de grâce
      à la sortie. Sans script, le survol CSS d'origine reprend la main. */
.header__tabWrap{
  position:relative;
  align-self:stretch;
  display:flex;
  align-items:center;
}
/* Le pont : 13px sous la bande (le décalage de .header__tabs), soit
   exactement le bas du header, où commence le panneau ; 24px de part et
   d'autre, soit la moitié des 47px entre deux onglets. Invisible, il ne sert
   qu'au survol. */
.header__tabWrap::after{
  content:"";
  position:absolute;
  top:0;
  bottom:-13px;
  left:-24px;
  right:-24px;
}
/* le mot reste au-dessus du pont : cliquable, et son focus visible */
.header__tabWrap > .header__tab{ position:relative; z-index:1 }

.header__submenu{
  position:fixed;
  top:var(--header-h, 107px);
  left:0;
  right:0;
  z-index:9;
  display:grid;
  grid-template-columns:288px;
  grid-auto-columns:minmax(0, 377px);
  grid-auto-flow:column;
  align-items:start;
  column-gap:89px;
  padding:34px var(--gutter);
  visibility:hidden;
  pointer-events:none;
  transition:visibility 0s .61s;
}

/* --- le sous-header : une bande commune, des contenus en fondu enchaîné ----
   L'apparition était brutale : la courbe d'ouverture (.16,1,.3,1) parcourait
   l'essentiel de la course dans le premier cinquième du temps, le panneau
   claquait ouvert puis traînait ; et d'un onglet à l'autre le contenu était
   échangé d'un coup.
   Le fond et l'ombre ne sont donc plus portés par chaque panneau : UNE bande
   (.header__sousBande, créée par main.js) les porte pour les trois. Elle
   s'ouvre, glisse vers la hauteur du sous-menu actif, et se referme ; les
   panneaux, transparents, ne font plus que fondre leur contenu. D'un onglet à
   l'autre la bande ne se replie pas : elle s'ajuste en douceur pendant que
   l'ancien contenu s'efface et que le nouveau apparaît — un fondu enchaîné.
   Deux courbes :
     · .33,0,.2,1 — pente nulle au départ, pose très lente : tout ce qui
       s'ouvre ou apparaît ;
     · .45,0,.55,1 — symétrique, sans à-coup ni claquement : tout ce qui se
       referme ou s'efface.
   Durées de la suite : .987s pour la bande et pour l'apparition du contenu,
   .61s pour son effacement. Le contenu, immobile, n'apparaît qu'après .377s,
   quand la bande s'est presque ouverte ou que l'ancien contenu a commencé à
   partir ; à la
   fermeture, la bande attend .144s que le contenu ait commencé à s'effacer. */
.header__sousBande{
  position:fixed;
  top:var(--header-h, 107px);
  left:0;
  right:0;
  z-index:8;
  height:0;
  background:var(--paper);
  box-shadow:0 13px 34px rgba(0,0,0,0);
  visibility:hidden;
  pointer-events:none;
  transition:height .987s cubic-bezier(.45,0,.55,1) .144s,
             box-shadow .987s cubic-bezier(.45,0,.55,1) .144s,
             visibility 0s 1.131s;
}
.header__sousBande.is-ouverte{
  box-shadow:0 13px 34px rgba(0,0,0,.1);
  visibility:visible;
  transition:height .987s cubic-bezier(.33,0,.2,1),
             box-shadow .987s cubic-bezier(.33,0,.2,1),
             visibility 0s;
}

/* .header__tabWrap en tête du sélecteur, et c'est la correction : à
   spécificité égale, .header__subLink (déclaré plus bas, transition:color)
   écrasait cette transition. Les liens posés directement dans le panneau
   — ceux d'Amincissement — perdaient leur fondu de sortie et disparaissaient
   d'un coup quand on passait à un autre onglet (vérifié : transition
   calculée « color .3s », aucune transition d'opacité lancée). Soins et
   Produits y échappaient, leurs liens étant dans des groupes.
   color .3s est repris ici, sans quoi le survol des liens perdait le sien. */
.header__tabWrap .header__submenu > *{
  opacity:0;
  transition:opacity .61s cubic-bezier(.45,0,.55,1),
             color .3s var(--ease);
}

/* ouvert (.is-ouvert, posé par main.js) : le contenu apparaît lentement,
   une fois que la bande ou l'ancien contenu lui ont laissé la place */
.header__tabWrap.is-ouvert .header__submenu{
  visibility:visible;
  pointer-events:auto;
  transition:visibility 0s;
}
/* .377s d'attente et non plus .233 : le contenu ne descend plus avec la bande,
   il l'attend — posé à sa place finale, il dépasserait sinon d'une bande
   encore trop courte au premier dépliage */
.header__tabWrap.is-ouvert .header__submenu > *{
  opacity:1;
  transition:opacity .987s cubic-bezier(.33,0,.2,1) .377s,
             color .3s var(--ease);
}

/* sans script : chaque panneau porte son fond et s'ouvre au survol ou au
   focus, en simple fondu */
html:not(.sousmenus-js) .header__submenu{
  background:var(--paper);
  box-shadow:0 13px 34px rgba(0,0,0,.1);
}
html:not(.sousmenus-js) .header__tabWrap:hover .header__submenu,
html:not(.sousmenus-js) .header__tabWrap:focus-within .header__submenu{
  visibility:visible;
  pointer-events:auto;
  transition:visibility 0s;
}
html:not(.sousmenus-js) .header__tabWrap:hover .header__submenu > *,
html:not(.sousmenus-js) .header__tabWrap:focus-within .header__submenu > *{
  opacity:1;
}

.header__subGroup{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:13px;
  min-width:0;
}

.header__subGroup:has(> .header__subLink:nth-of-type(4)){
  display:grid;
  grid-template-columns:repeat(2, max-content);
  grid-template-rows:auto repeat(2, auto);
  grid-auto-flow:column;
  justify-items:start;
  gap:13px 55px;
}
.header__subGroup:has(> .header__subLink:nth-of-type(5)){
  grid-template-rows:auto repeat(3, auto);
}
.header__subGroup:has(> .header__subLink:nth-of-type(7)){
  grid-template-columns:repeat(3, max-content);
}
.header__subGroup:has(> .header__subLink:nth-of-type(4)) > .header__subGroupLabel{
  grid-column:1 / -1;
  grid-row:1;
}

.header__subGroupLabel{
  margin-bottom:8px;
  font-size:11.5px;
  font-weight:500;
  letter-spacing:.144em;
  text-transform:uppercase;
  color:var(--ink);
  white-space:nowrap;
}
/* Sentence case et corps plus grand (13) que les onglets : c'est une liste à
   lire, pas un intitulé à balayer — même écart de traitement que sur le site
   actuel entre son rail de catégories (capitales) et ses sous-menus (non). */
.header__subLink{
  font-size:13px;
  font-weight:400;
  white-space:nowrap;
  
  color:var(--ink);
  transition:color .3s var(--ease);
}
.header__subLink:hover{ color:rgba(13,13,12,.6) }

.header__subLink--tous{
  margin-bottom:8px;
  font-size:11.5px;
  font-weight:500;
  letter-spacing:.144em;
  text-transform:uppercase;
  color:var(--ink);
}
.header__subLink--tous:hover{ color:rgba(13,13,12,.6) }
.header__subLink:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

.header__subVisuel{
  position:relative;
  display:block;
  width:288px;
  height:162px;
  overflow:hidden;
  color:#fff;
}
.header__subVisuel img{
  width:100%;
  height:100%;
  object-fit:cover;
}
.header__subVisuel::after{
  content:"";
  position:absolute;
  inset:auto 0 0 0;
  height:89px;
  background:linear-gradient(to top, rgba(0,0,0,.42), rgba(0,0,0,0));
}
.header__subVisuelNom{
  position:absolute;
  left:13px;
  bottom:13px;
  z-index:1;
  font-size:11.5px;
  font-weight:500;
  letter-spacing:.144em;
  text-transform:uppercase;
  white-space:nowrap;
}

.header__subVisuel--produits{
  color:var(--ink);
  background:#fff;
}
.header__subVisuel--produits::after{ content:none }
.header__subVue{
  position:absolute;
  inset:0;
  opacity:0;
}
.header__subVue.is-active{ opacity:1 }
.header__tabWrap.is-ouvert .header__subVue{
  transition:opacity .61s cubic-bezier(.45,0,.55,1);
}
.header__tabWrap.is-ouvert .header__subVue.is-active{
  transition:opacity .61s cubic-bezier(.33,0,.2,1);
}
.header__subVisuel:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

.header__tabWrap::before{
  content:"";
  position:absolute;
  left:-13px;
  right:-13px;
  bottom:-13px;
  height:1px;
  background:var(--ink);
  transform:scaleX(0);
  pointer-events:none;
  transition:transform .61s cubic-bezier(.45,0,.55,1);
}
.header__tabWrap.is-ouvert::before,
html:not(.sousmenus-js) .header__tabWrap:hover::before{
  transform:scaleX(1);
  transition:transform .61s cubic-bezier(.33,0,.2,1);
}

.header__subVisite{
  display:grid;
  grid-template-columns:repeat(2, max-content);
  grid-template-rows:auto repeat(3, auto);
  grid-auto-flow:column;
  justify-items:start;
  gap:13px 55px;
}
.header__subVisite > .header__subGroupLabel{
  grid-column:1 / -1;
  grid-row:1;
}
.header__subAdresse{
  grid-column:1;
  grid-row:2 / span 2;
  display:flex;
  flex-direction:column;
  gap:13px;
}
.header__subAdresse:hover .header__subLink{ color:rgba(13,13,12,.6) }
.header__subAdresse:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

.header__subHoraires{
  grid-column:2;
  grid-row:2 / span 3;
  display:grid;
  grid-template-columns:repeat(2, max-content);
  grid-template-rows:subgrid;
  column-gap:21px;
  margin:0;
}
.header__subHoraires dt,
.header__subHoraires dd{
  margin:0;
  font-size:13px;
  font-weight:400;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
  color:var(--ink);
}

/* Sous 1364px (palier de la grille), visuel, liens et coordonnées ne
   tiennent plus côte à côte : le visuel de ce panneau tombe, et sa piste de
   288 accueille le groupe de l'institut. Sous 987px, où les autres visuels
   tombent aussi (plus bas), les deux colonnes se serrent sur leur texte et
   leurs écarts descendent d'un cran — 55 entre elles, 34 dans le bloc — pour
   tenir jusqu'à 760px, où les sous-menus disparaissent. */
@media(max-width:1364px){
  .header__submenu:has(> .header__subVisite) > .header__subVisuel{ display:none }
}
@media(max-width:987px){
  .header__submenu:has(> .header__subVisite){
    grid-auto-columns:max-content;
    column-gap:55px;
  }
  .header__subVisite{ column-gap:34px }
}

/* Sous 987px, visuel et deux colonnes ne tiennent plus (322 + 2 × 233 +
   2 × 55 = 898px, gouttières en plus) : le visuel tombe, les colonnes
   restent. */
@media(max-width:987px){
  .header__subVisuel{ display:none }
  /* plus de piste réservée au visuel : les groupes se partagent tout */
  .header__submenu{ grid-template-columns:none }
}

@media(max-width:760px){
  /* gap 13 : l'écart entre le bouton du menu et le logo, et le minimum entre
     le logo et les pictos. À 21, la ligne débordait dès 401px — du temps du
     numéro écrit. */
  .header__top{ height:76px; justify-content:space-between; gap:13px }
  /* Retour dans le flux, à gauche : sous 760px le groupe d'actions (les trois
     pictos) peut recouvrir un logo resté au centre —
     flex:none l'empêche alors de se tasser, comme avant le centrage.
     margin-right:auto le garde contre le bouton du menu : sans lui,
     space-between le poserait au milieu de l'espace libre. */
  .header__logo{ position:static; flex:none; transform:none; margin-right:auto }
  .header__logo svg{ height:18px }
  
  .header__lang{ display:none }
  .header__actions{ gap:13px }
  /* entre deux pictos, 13 + 5 = 18 : la marge descend à -3 et non à 0, elle
     ne rouvre que 5 des 8px de padding disponibles, pas la totalité. */
  .header__icon + .header__icon{ margin-left:-3px }
  
  .header__tabs,
  .header__submenu,
  .header__sousBande,
  .header__tabWrap::before{ display:none }
}

.header__menuBouton{ display:none }
@media(max-width:760px){
  .header__menuBouton{
    display:flex;
    align-items:center;
    justify-content:center;
    padding:8px;
    margin:-8px;
    border:0;
    background:none;
    color:rgba(13,13,12,.86);
    cursor:pointer;
  }
  .header__menuBouton svg{ display:block; height:18px; width:auto; overflow:visible }
  /* trois traits → croix : les deux extrêmes pivotent et se rejoignent au
     centre du picto (9,9), celui du milieu s'efface — le geste de
     .nouveaute__fermer, mais construit pour se déplier plutôt que fixe. */
  .header__menuTrait{
    transform-origin:9px 9px;
    transition:transform 377ms var(--ease), opacity 233ms var(--ease);
  }
  .header__menuBouton.is-ouvert .header__menuTrait--haut{ transform:translateY(4px) rotate(45deg) }
  .header__menuBouton.is-ouvert .header__menuTrait--bas{ transform:translateY(-4px) rotate(-45deg) }
  .header__menuBouton.is-ouvert .header__menuTrait--mid{ opacity:0 }
}

.header__menu{
  position:fixed;
  top:var(--header-h, 89px);
  left:0; right:0; bottom:0;
  z-index:95;
  overflow-y:auto;
  background:var(--paper);
  color:var(--ink);
  opacity:0;
  transform:translateY(-13px);
  transition:opacity 233ms cubic-bezier(.45,0,.55,1), transform 233ms cubic-bezier(.45,0,.55,1);
}
.header__menu[hidden]{ display:none }
.header__menu.is-ouverte{
  opacity:1;
  transform:none;
  transition:opacity 377ms cubic-bezier(.33,0,.2,1), transform 377ms cubic-bezier(.33,0,.2,1);
}
/* au-delà de 760px le bouton n'existe plus pour l'ouvrir : le panneau ne
   doit plus jamais se voir, même si la fenêtre est agrandie pendant qu'il
   est ouvert (main.js le referme aussi, au resize) */
@media(min-width:761px){
  .header__menu{ display:none }
}

.header__menuPanneau{ padding:34px var(--gutter) 55px }

.header__menuLangue{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:8px 21px;
  padding-bottom:34px;
  margin-bottom:34px;
  border-bottom:1px solid rgba(13,13,12,.13);
}
.header__menuLangActuelle,
.header__menuLangLien{
  display:flex;
  align-items:center;
  gap:8px;
  font-size:13px;
  font-weight:400;
  letter-spacing:.144em;
  text-transform:uppercase;
  color:rgba(13,13,12,.6);
}
.header__menuLangActuelle{ color:var(--ink) }
.header__menuLangLien{ transition:color .55s var(--ease) }
.header__menuLangLien:hover{ color:var(--ink) }
.header__menuLangLien:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

/* --- les catégories ---------------------------------------------------------
   Une ligne par onglet, filet sous chacune (l'écart seul séparait déjà les
   colonnes du bureau — ici une seule colonne, le filet fait le même travail).
   Le nom, dans la voix du slogan (Tenor Sans aux accents de Jost) : c'est la
   tête d'un menu plein écran, pas une bande de 18px. */
.header__menuListe{ display:flex; flex-direction:column }
.header__menuGroupe,
.header__menuLigne{ border-bottom:1px solid rgba(13,13,12,.13) }
.header__menuGroupeTete{ display:flex; align-items:center; justify-content:space-between; gap:13px }
.header__menuLien{
  display:block;
  padding:18px 0;
  flex:1 1 auto;
  font-family:var(--font-titre);
  font-size:21px;
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
  color:var(--ink);
}
.header__menuLien:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:-3px;
}
/* Le « + » qui déplie : zone cliquable de 47px sans agrandir la ligne
   (padding + marge négative, le procédé des pictos du header), tourne d'un
   huit de tour pour devenir une croix — la même idée que le bouton du menu
   lui-même, un cran plus discret. */
.header__menuGroupeBouton{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:13px;
  margin:-13px 0;
  border:0;
  background:none;
  color:rgba(13,13,12,.6);
  cursor:pointer;
}
.header__menuChevron{ display:block; transition:transform 233ms var(--ease) }
.header__menuGroupeBouton[aria-expanded="true"] .header__menuChevron{ transform:rotate(45deg) }
.header__menuGroupeBouton:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:-3px;
}
/* La liste dépliée : grid-template-rows en fr, sans mesure JS — 0fr fermé,
   1fr ouvert, le contenu rogné par son enveloppe pendant la course. Ouverture
   lente (.33,0,.2,1), fermeture symétrique (.45,0,.55,1), 377ms. */
.header__menuSub{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows 377ms cubic-bezier(.45,0,.55,1);
}
.header__menuGroupe:has(.header__menuGroupeBouton[aria-expanded="true"]) .header__menuSub{
  grid-template-rows:1fr;
  transition:grid-template-rows 377ms cubic-bezier(.33,0,.2,1);
}
.header__menuSubInner{ overflow:hidden; min-height:0 }
/* Le contenu repris du bureau (.header__subGroup, .header__subLink…) garde
   son corps et son encre — seule la mise en page change : une colonne, pas
   de sous-colonnes ni de grille (le bureau les range à plusieurs pour une
   piste étroite ; ici la largeur ne manque pas). Même spécificité que les
   règles du bureau (deux classes) : l'ordre dans la feuille tranche, celles-ci
   viennent après. */
.header__menu .header__subGroup,
.header__menu .header__subVisite{
  display:flex;
  flex-direction:column;
  gap:13px;
  padding:8px 0 21px;
}
.header__menu .header__subHoraires{
  display:grid;
  grid-template-columns:max-content max-content;
  grid-template-rows:none;
  column-gap:21px;
  row-gap:3px;
}
/* 400px et moins (la plupart des Android font 360) : les écarts se resserrent
   d'un cran plutôt que de réduire le logo */
@media(max-width:400px){
  .header__actions{ gap:8px }
}
/* 374px et moins : un cran de logo. Réglé quand le numéro de téléphone était
   écrit en toutes lettres : la langue prenant 26px à gauche (pastille 13,
   écart 13), le logo à 18px ne tenait plus entre elle et lui. Ce palier était
   à 340px avant la langue. Le numéro devenu picto, la place existe à nouveau :
   ce palier et ses deux voisins (400, 340) sont à revoir. */
@media(max-width:374px){
  .header__logo svg{ height:13px }
}
/* 340px et moins : même à 13px la ligne déborde de quelques pixels — les
   écarts se resserrent encore d'un cran */
@media(max-width:340px){
  .header__top{ gap:8px }
  .header__actions{ gap:5px }
}

/* ==========================================================================
   BANNER — vidéo plein écran, déborde de 13px sous la fenêtre
   ========================================================================== */

.hero{
  position:sticky;
  top:0;
  z-index:0;
  isolation:isolate;
  width:100%;
  height:calc(100vh + var(--bleed));
  overflow:hidden;
  background:var(--ink);
}
/* la couche qui remonte ; --hero-y est écrit à chaque image par main.js */
.hero__media{
  position:absolute; inset:0;
  transform:translate3d(0, var(--hero-y, 0px), 0);
  will-change:transform;
}
/* Cadrée plus bas, sans agrandir le banner : la vidéo descend de 55px DANS sa
   boîte (top, la hauteur reste 100 %) — ce qui était caché sous le header
   blanc réapparaît juste en dessous de lui, et le bas de l'image est rogné
   d'autant par l'overflow du banner.
   object-position ne pouvait pas le faire : aux proportions courantes
   (1280×733, 16:9 étiré au plus haut), la vidéo remplit déjà toute la hauteur
   et n'est rognée que sur les côtés — il n'y a rien à décaler verticalement.
   La bande vide ainsi ouverte en haut (55px) reste sous le header opaque
   (107px, 89 sous 760px) : elle ne se voit jamais. Si le header redevient
   transparent, cette valeur devra repasser à 0. */
.hero__video{
  position:absolute; inset:0;
  top:55px;
  width:100%; height:100%;
  object-fit:cover;
  object-position:center;
}
@media(max-width:760px){
  .hero__video{ top:34px }
}
/* voile bas seulement — juste ce qu'il faut pour que la pastille de
   réservation reste lisible quel que soit le plan de la vidéo en dessous.
   Le voile haut est retiré : il assombrissait la vidéo sous le logo et le
   numéro tant que le header était transparent. Plein et blanc (--paper),
   celui-ci n'a plus besoin que la vidéo s'assombrisse en dessous. */
.hero__scrim{
  position:absolute; inset:0;
  pointer-events:none;
  background: linear-gradient(to top, rgba(0,0,0,.50) 0%, rgba(0,0,0,.10) 18%, rgba(0,0,0,0) 38%);
}

.hero__avis{
  --pill-h:calc(13px * 3);
  position:absolute;
  left:0;
  right:0;
  margin-inline:auto;
  width:max-content;
  /* + --bleed : le banner dépasse la fenêtre de 13px et ce retrait se compte
     depuis SON bas. On tient la distance au bord de l'ÉCRAN, comme le bouton. */
  bottom:calc(var(--resa-b) + var(--bleed) + var(--pill-h) + 18px);
  z-index:1;
  display:flex;
  align-items:center;
  gap:13px;
  color:#fff;
  filter:drop-shadow(0 2px 11px rgba(0,0,0,.55));
}
.hero__avis:focus-visible{
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:8px;
}
/* le G à 18px, l'unité d'icône du site (les pictos du header) */
.hero__avisG{ display:block; height:18px; width:auto }
/* Corps 13, graisse 500 (Satoshi Medium), interlettrage .144em.
   margin-right : le blanc d'interlettrage après le dernier signe est rendu —
   les écarts visibles valent le gap, et la ligne se centre sur son encre. */
.hero__avisNote,
.hero__avisNb{
  font-size:13px;
  font-weight:500;
  letter-spacing:.144em;
  margin-right:-.144em;
  line-height:1;
  text-box:trim-both cap alphabetic;
  text-transform:uppercase;
  white-space:nowrap;
}
/* la note d'abord, le nombre d'avis en retrait */
.hero__avisNb{ opacity:.72 }

/* sous 760px le bouton perd 4px de haut (padding 11) : la ligne suit */
@media(max-width:760px){
  .hero__avis{ --pill-h:calc(11px * 2 + 13px) }
}

/* ==========================================================================
   SECTION 1 — le slogan, puis le paragraphe que le h1 ouvre
   Composition de Chenot (« Live healthier for longer ») : un seul axe, un
   titre en capitales, un paragraphe centré dessous. Le h1 n'est pas un titre
   à part : c'est la première phrase du paragraphe, en ligne avec la suite —
   même corps, même encre. Il reste le h1 pour les moteurs, sans se voir comme
   un intitulé.
   Le slogan est un <p> et non un <h2> : posé AVANT le h1, un titre de rang 2
   ferait ouvrir la page par un sous-titre.
   ========================================================================== */
.intro{
  position:relative;
  z-index:1;
  background:var(--paper);
  color:var(--ink);
  text-align:center;
  /* l'espace entre sections (--espace-section), en haut comme en bas : le
     banner au-dessus, les services en dessous */
  padding:var(--espace-section) var(--gutter);
  
  box-shadow:0 -29px 55px rgba(0,0,0,.45);
}

.intro:not(:has(~ section, ~ footer)){ padding-bottom:50vh }
.intro__wrap{
  max-width:843px;
  margin:0 auto;
  /* la largeur de l'image : 1151 au plus, les gouttières de page en dessous
     (voir « l'image sous le paragraphe »). Déclarée ici et non sur l'image :
     la relance, sa sœur, cale son bord droit dessus. */
  --visuel-l:min(1151px, calc(100vw - 2 * var(--gutter)));
}

.insecable{ white-space:nowrap }

.intro__slogan{
  margin:0 0 34px;
  font-family:var(--font-titre);
  font-size:clamp(21px, calc(1.44vw + 16.4px), 34px);
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
  text-wrap:balance;
}

.intro__texte{
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  color:var(--ink);
  text-wrap:pretty;
}
.intro__h1,
.intro__suite{
  display:inline;
  margin:0;
  font:inherit;
  letter-spacing:inherit;
  color:inherit;
}

@supports (animation-timeline: view()){
  .intro__texte{
    opacity:0;
    transform:translateY(21px);
    animation:introLire both;
    animation-timeline:view();
    animation-range:cover 21% cover 100%;
    animation-timing-function:cubic-bezier(.33,0,.2,1);
  }
}
@keyframes introLire{
  37%  { opacity:1; transform:none }
  76%  { opacity:1; transform:none }
  100% { opacity:0; transform:translateY(-8px) }
}

.intro__visuel{
  display:block;
  width:var(--visuel-l);
  max-width:none;
  height:auto;
  margin:144px 0 0 calc((100% - var(--visuel-l)) / 2);
}
@supports (animation-timeline: view()){
  .intro__visuel{
    opacity:0;
    transform:perspective(1597px) translate3d(0, -34px, 34px) rotateX(13deg);
    transform-origin:50% 0;
    animation:introPlonger both, introSortir forwards;
    animation-timeline:view(), view();
    animation-range:entry 0% entry 100%, exit 55% exit 100%;
    animation-timing-function:var(--ease), cubic-bezier(.45,0,.55,1);
  }
}
@keyframes introPlonger{
  21%  { opacity:1 }
  100% { opacity:1; transform:perspective(1597px) translate3d(0, 0, 0) rotateX(0deg) }
}
/* 0 % explicite : sans lui, le retrait partirait de l'état de départ de
   l'arrivée (transparente, basculée) au lieu de l'image posée */
@keyframes introSortir{
  0%   { opacity:1; transform:perspective(1597px) translate3d(0, 0, 0) rotateX(0deg) }
  100% { opacity:0; transform:perspective(1597px) translate3d(0, -8px, 0) rotateX(0deg) }
}

.intro__relance{
  width:min(521px, 100%);
  margin:55px calc((100% - var(--visuel-l)) / 2) 89px auto;
  text-align:left;
}
.intro__lien{
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  transition:color .3s var(--ease);
}
.intro__lien:hover{ color:rgba(13,13,12,.6) }
.intro__lien:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

.services{
  position:relative;
  z-index:1;
  background:var(--paper);
  color:var(--ink);
}
.service{
  display:grid;
  grid-template-columns:1fr 1fr;
}
.service:nth-child(even) .service__visuel{ grid-area:1 / 2 }
.service:nth-child(even) .service__texte{ grid-area:1 / 1 }

/* Le carré est celui du TEXTE : aspect-ratio sur sa cellule, qui fixe la
   hauteur de la rangée. L'image, sans rapport propre, s'étire sur la rangée
   (align-self:normal vaut stretch sans aspect-ratio, start avec) et se pose en
   absolu dedans, en object-fit:cover. Si le texte ne tient plus dans son carré
   — corps agrandi par le lecteur —, aspect-ratio n'est plus qu'un minimum : la
   rangée grandit et l'image suit, rien n'est rogné.
   overflow:clip et non hidden : hidden ferait de la cellule un conteneur de
   défilement, et la timeline view() de l'image s'y accrocherait au lieu de la
   page — l'image ne bougerait plus. */
.service__visuel{
  position:relative;
  overflow:clip;
}
.service__visuel img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
}
.service__texte{
  aspect-ratio:1;
  display:grid;
  place-items:center;
  padding:55px var(--gutter);
}

.service__contenu{
  width:min(521px, 100%);
  text-align:center;
}

/* Le nom : la voix du slogan (Tenor Sans aux accents de Jost, capitales
   espacées .089em), un cran plus bas — 29px au plus au lieu de 34 : le slogan
   reste la tête de la page, chaque service en est une partie. 21px au moins,
   le plancher du slogan. */
.service__nom{
  margin:0 0 21px;
  font-family:var(--font-titre);
  font-size:clamp(21px, calc(1.44vw + 11px), 29px);
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
  text-wrap:balance;
}
/* La présentation : le paragraphe de la section 1 (17/29, 400, pleine
   encre — voir .intro__texte pour l'écart du 17). */
.service__desc{
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  text-wrap:pretty;
}

.service__bouton,
.boutique__tous,
.diagnostic__bouton{
  display:inline-block;
  margin-top:34px;
  padding:13px 21px;
  border:1px solid var(--ink);
  border-radius:var(--pill-r);
  font-size:11px;
  font-weight:400;
  letter-spacing:.199em;
  line-height:1;
  text-box:trim-both cap alphabetic;
  text-transform:uppercase;
  white-space:nowrap;
  transition:background-color 377ms var(--ease), color 377ms var(--ease);
}
.service__bouton:hover,
.boutique__tous:hover,
.diagnostic__bouton:hover{ background:var(--ink); color:var(--paper) }
.service__bouton:focus-visible,
.boutique__tous:focus-visible,
.diagnostic__bouton:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}

@supports (animation-timeline: view()){
  .service__contenu{
    opacity:0;
    transform:translateY(21px);
    animation:serviceLire both, serviceQuitter forwards;
    animation-timeline:view(), view();
    animation-range:entry 0% entry 100%, cover 81% cover 100%;
    animation-timing-function:var(--ease), cubic-bezier(.33,0,.2,1);
  }
  .service__visuel img{
    transform:scale(1.089);
    animation:servicePoser both;
    animation-timeline:view();
    animation-range:cover 0% cover 50%;
    animation-timing-function:cubic-bezier(.33,0,.2,1);
  }
}
@keyframes servicePoser{
  to{ transform:none }
}
@keyframes serviceLire{
  to{ opacity:1; transform:none }
}
/* 0 % explicite : sans lui, le retrait partirait de l'état de départ de
   l'arrivée (transparent, décalé) au lieu du texte posé */
@keyframes serviceQuitter{
  0%   { opacity:1; transform:none }
  100% { opacity:0; transform:translateY(-8px) }
}

@media(max-width:987px){
  .service{ grid-template-columns:1fr }
  .service:nth-child(even) .service__visuel,
  .service:nth-child(even) .service__texte{ grid-area:auto }
  .service__visuel{ aspect-ratio:1 }
  .service__texte{ aspect-ratio:auto; padding:55px var(--gutter) 89px }
  .service:last-child .service__texte{ padding-bottom:0 }
}

.boutique{
  position:relative;
  z-index:1;
  background:var(--paper);
  color:var(--ink);
  padding:calc(var(--espace-section) + 89px) 0;
}
.boutique__wrap{
  max-width:1364px;
  margin:0 auto;
  padding:0 var(--gutter);
}

/* la tête : le titre dans la voix du slogan, l'introduction dans celle du
   paragraphe de la section 1, sur l'axe de la page */
.boutique__tete{
  max-width:843px;
  margin:0 auto 89px;
  text-align:center;
}
.boutique__titre{
  margin:0 0 21px;
  font-family:var(--font-titre);
  font-size:clamp(21px, calc(1.44vw + 16.4px), 34px);
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
  text-wrap:balance;
}
.boutique__intro{
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  text-wrap:pretty;
}

.boutique__grille{
  display:grid;
  gap:21px;
  margin:0;
  padding:0;
  list-style:none;
}

/* --- un produit --------------------------------------------------------------
   Tout le produit est le lien : l'aplat puis le texte, en colonne. L'aplat
   prend la hauteur que la grille lui laisse (flex:1) ; le packshot y est posé
   en absolu, centré (inset + margin:auto) et borné à l'aplat moins 34px de
   marge — il ne pèse donc rien dans le calcul des rangées, et ne dépasse
   jamais sa taille native (324px, recadré au carré autour du produit). */
.produit__lien{
  display:flex;
  flex-direction:column;
  height:100%;
}
.produit__lien:focus-visible{
  outline:1px solid rgba(13,13,12,.9);
  outline-offset:5px;
}
.produit__visuel{
  position:relative;
  flex:1 1 auto;
  isolation:isolate;
  background:color-mix(in srgb, var(--ink) 5%, var(--paper));
}

.produit__visuel img{
  position:absolute;
  inset:34px;
  margin:auto;
  max-width:calc(100% - 68px);
  max-height:calc(100% - 68px);
  object-fit:contain;
  mix-blend-mode:multiply;
  transition:transform 610ms var(--ease);
}
/* au survol, le produit se soulève de 8px : on le prend en main */
.produit__lien:hover .produit__visuel img{ transform:translateY(-8px) }

.produit__texte{ padding-top:21px }
.produit__gamme{
  display:block;
  margin-bottom:8px;
  font-size:11px;
  font-weight:500;
  letter-spacing:.144em;
  line-height:1;
  text-transform:uppercase;
}
.produit__nom{
  display:block;
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
}
/* l'accroche, sous le nom du grand produit seulement — celle de sa fiche */
.produit__accroche{
  max-width:377px;
  margin:3px 0 8px;
  font-size:13px;
  line-height:21px;
  font-weight:400;
}
.produit__prix{
  display:block;
  font-size:13px;
  line-height:21px;
  font-weight:400;
}

.boutique__grille--vedette{ grid-template-columns:5fr 8fr }
.boutique__grille--vedette .produit:first-child{
  grid-column:2;
  grid-row:1 / span 2;
}
.boutique__grille--vedette .produit:not(:first-child) .produit__visuel{
  flex:none;
  aspect-ratio:1;
}

.produit--photo .produit__visuel{ overflow:clip }
.produit--photo .produit__visuel img{
  inset:0;
  width:100%;
  height:100%;
  max-width:none;
  max-height:none;
  object-fit:cover;
  object-position:50% 20%;
  mix-blend-mode:normal;
  transition:transform 987ms var(--ease);
}
.produit--photo .produit__lien:hover .produit__visuel img{ transform:none }
@media (hover:hover){
  .produit--photo .produit__lien:hover .produit__visuel img{ transform:scale(1.034) }
}
.produit--photo .produit__lien:focus-visible .produit__visuel img{ transform:scale(1.034) }

.boutique__special{
  max-width:843px;
  margin:144px auto 55px;
  text-align:center;
}
.boutique__specialTitre{
  margin:0 0 21px;
  font-family:var(--font-titre);
  font-size:clamp(21px, calc(1.44vw + 11px), 29px);
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
}
.boutique__specialSur{
  display:block;
  margin-bottom:13px;
  font-family:var(--font-ui);
  font-size:11px;
  font-weight:500;
  letter-spacing:.144em;
  line-height:1;
}
.boutique__specialIntro{
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  text-wrap:pretty;
}
.boutique__grille--colonnes{
  grid-template-columns:repeat(3, 1fr);
  align-items:start;
}
.boutique__grille--colonnes .produit__visuel{
  flex:none;
  aspect-ratio:21 / 29;
}

.boutique__pied{
  margin-top:21px;
  text-align:center;
}

.boutique--apparition .produit{
  opacity:0;
  transform:translateY(21px);
}
.boutique--apparition .produit--vu{
  opacity:1;
  transform:none;
  transition:opacity 987ms cubic-bezier(.33,0,.2,1),
             transform 987ms cubic-bezier(.33,0,.2,1);
}

/* Sous 987px : la vedette passe sur deux colonnes — le coffret en tête, pleine
   largeur et en portrait (21/29, près du rapport de sa photo : elle reste
   entière), les deux petits côte à côte dessous ; le spécial garde ses trois
   colonnes. */
@media(max-width:987px){
  .boutique__grille--vedette{ grid-template-columns:1fr 1fr }
  .boutique__grille--vedette .produit:first-child{ grid-column:1 / -1; grid-row:auto }
  .boutique__grille--vedette .produit:first-child .produit__visuel{
    flex:none;
    aspect-ratio:21 / 29;
  }
}
/* Sous 610px : une colonne, tous les aplats en 29/21 ; la tête du spécial
   à 89px sous la vedette. */
@media(max-width:610px){
  .boutique__grille--vedette,
  .boutique__grille--colonnes{ grid-template-columns:1fr }
  .boutique__special{ margin-top:89px }
  .boutique__grille--colonnes .produit__visuel{ aspect-ratio:29 / 21 }
}

.avis{
  position:relative;
  z-index:1;
  background:var(--paper);
  color:var(--ink);
  padding:0 0 calc(var(--espace-section) + 89px);
}

/* le titre : la voix de « La boutique », sur l'axe de la page, 55 au-dessus
   des carrés */
.avis__titre{
  max-width:843px;
  margin:0 auto 55px;
  padding:0 var(--gutter);
  font-family:var(--font-titre);
  font-size:clamp(21px, calc(1.44vw + 16.4px), 34px);
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-align:center;
  text-transform:uppercase;
  text-wrap:balance;
}

/* Un rang. Sans script, ou sous prefers-reduced-motion, il défile de côté au
   doigt ou à la molette, barre masquée comme celle de la page ; la piste
   s'écarte des bords de la largeur du fondu, aucun carré n'y commence.
   Avec le script (html.avis-js), plus de défilement : la piste glisse dedans
   par transform et se saisit à la main. Elle garde son retrait à gauche : au
   premier regard, l'avis le plus récent est entier, hors du fondu. */
.avis__rang{
  --avis-fondu:clamp(34px, 8vw, 144px);
  overflow-x:auto;
  scrollbar-width:none;
  -ms-overflow-style:none;
  -webkit-mask-image:linear-gradient(to right, transparent, #000 var(--avis-fondu), #000 calc(100% - var(--avis-fondu)), transparent);
          mask-image:linear-gradient(to right, transparent, #000 var(--avis-fondu), #000 calc(100% - var(--avis-fondu)), transparent);
}
.avis__rang::-webkit-scrollbar{ display:none }
.avis__piste{
  display:flex;
  width:max-content;
  margin:0;
  padding:0 var(--avis-fondu);
  list-style:none;
}
html.avis-js .avis__rang{
  overflow:clip;
  cursor:grab;
}
html.avis-js .avis__rang.is-saisi{ cursor:grabbing }
html.avis-js .avis__piste{
  padding-right:0;
  will-change:transform;
}

/* --- un avis : un carré ------------------------------------------------------
   377 de côté, 34 de marge intérieure. Le nom dans la voix des gammes de la
   boutique (11px, 500, capitales espacées .144em) : les noms restent tels que
   leurs auteurs les ont tapés — « laura bourguignon », « Gilles BLAEVOET » —,
   les capitales les accordent sans rien réécrire. Le commentaire, le
   paragraphe de la section 1 (17/29). Le G et la date au bas du carré
   (margin-top:auto), en 13/21, encre à 60 %.
   Le carré ne grandit jamais : le commentaire s'arrête à huit lignes — 11 +
   13 pour le nom, 8 × 29, 13 + 21 pour le pied : 290 dans les 309 du carré.
   Un avis plus long (Adèle Bailly, 1 400 signes) est coupé sur des points de
   suspension ; le texte entier reste dans la page — lecteurs d'écran,
   moteurs. */
.avis__item{
  position:relative;
  flex:none;
  width:377px;
  aspect-ratio:1;
}

.avis__item::after{
  content:"";
  position:absolute;
  top:0;
  bottom:0;
  right:0;
  width:1px;
  background:rgba(13,13,12,.13);
}

.avis__bande{
  overflow:clip;
  background:color-mix(in srgb, var(--ink) 5%, var(--paper));
}
.avis__bande + .avis__bande{ margin-top:21px }
.avis__item > figure{
  display:flex;
  flex-direction:column;
  height:100%;
  margin:0;
  padding:34px;
}
.avis__nom{
  display:block;
  margin-bottom:13px;
  font-size:11px;
  font-weight:500;
  letter-spacing:.144em;
  line-height:1;
  text-transform:uppercase;
}
.avis__texte{
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:8;
  line-clamp:8;
  overflow:hidden;
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  text-wrap:pretty;
}
.avis__texte p{ margin:0 }
.avis__pied{
  display:flex;
  align-items:center;
  gap:8px;
  margin:auto 0 0;
  padding-top:13px;
  font-size:13px;
  line-height:21px;
  font-weight:400;
  color:rgba(13,13,12,.6);
}
/* le G à 13px, la hauteur de la ligne de la date. overflow:visible : viewBox
   rogné au dessin, comme celui du banner (voir les pictos, en tête de
   feuille). */
.avis__g{
  flex:none;
  display:block;
  height:13px;
  width:auto;
  overflow:visible;
}
/* le logo Treatwell de ses deux avis : plus large que haut, calé sur la
   largeur — 18, la hauteur des pictos du header */
.avis__tw{
  width:18px;
  height:auto;
}
/* le G dessiné une fois (index.html), hors du flux */
.avis__sprite{
  position:absolute;
  width:0;
  height:0;
  overflow:hidden;
}

/* --- apparition : UNE fois, comme les produits de la boutique ----------------
   main.js (AVIS GOOGLE) pose .avis--apparition sur la section, puis
   .avis__rang--vu sur chaque rang la première fois qu'il entre à l'écran.
   Sans script ou en mouvement réduit, rien n'est masqué. */
.avis--apparition .avis__rang{
  opacity:0;
  transform:translateY(21px);
}
.avis--apparition .avis__rang--vu{
  opacity:1;
  transform:none;
  transition:opacity 987ms cubic-bezier(.33,0,.2,1),
             transform 987ms cubic-bezier(.33,0,.2,1);
}

/* Sous 610px : le carré tient presque tout l'écran — 322 au plus, 286 à
   375px —, la marge intérieure descend d'un cran ; six lignes de
   commentaire (24 + 6 × 29 + 34 = 232 dans les 244 du carré de 286). */
@media(max-width:610px){
  .avis__titre{ margin-bottom:34px }
  .avis__item{ width:min(322px, calc(100vw - 89px)) }
  .avis__item > figure{ padding:21px }
  .avis__texte{ -webkit-line-clamp:6; line-clamp:6 }
  /* 13 de papier entre les bandes */
  .avis__bande + .avis__bande{ margin-top:13px }
}

.diagnostic{
  position:relative;
  z-index:1;
  background:var(--paper);
  color:var(--ink);
  padding:0 0 var(--espace-section);
}
.diagnostic__wrap{
  display:grid;
  grid-template-columns:5fr 8fr;
  max-width:1364px;
  margin:0 auto;
  padding:0 var(--gutter);
}
/* l'image couvre sa colonne, à la hauteur que l'aplat donne à la rangée ;
   cadrée sur le visage, à droite du milieu de la photo et un peu au-dessus :
   en 3/2 sous 987px, la bande visible garde le front et le menton.
   overflow:clip et non hidden, pour la timeline view() de l'image (voir
   .service__visuel). */
.diagnostic__visuel{
  position:relative;
  overflow:clip;
}
.diagnostic__visuel img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:62% 45%;
}
/* 521 de haut au moins (suite) ; la colonne de texte à 610 au plus */
.diagnostic__texte{
  display:grid;
  place-items:center;
  min-height:521px;
  padding:89px clamp(34px, 6.5vw, 89px);
  background:color-mix(in srgb, var(--ink) 5%, var(--paper));
}
.diagnostic__contenu{
  width:min(610px, 100%);
  text-align:center;
}
.diagnostic__sur{
  margin:0 0 34px;
  font-size:11px;
  font-weight:500;
  letter-spacing:.144em;
  line-height:1;
  text-transform:uppercase;
}
.diagnostic__titre{
  margin:0 0 21px;
  font-family:var(--font-titre);
  font-size:clamp(21px, calc(1.44vw + 11px), 29px);
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
  text-wrap:balance;
}
.diagnostic__desc{
  margin:0;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  text-wrap:pretty;
}

.diagnostic__bouton{
  position:relative;
  isolation:isolate;
  transition:border-color 1597ms cubic-bezier(.45,0,.55,1), color 1597ms cubic-bezier(.45,0,.55,1);
}
.diagnostic__bouton::before,
.diagnostic__bouton::after{
  content:"";
  position:absolute;
  border-radius:inherit;
  pointer-events:none;
  opacity:0;
  transition:opacity 1597ms cubic-bezier(.45,0,.55,1);
}
.diagnostic__bouton::before{
  inset:0;
  z-index:-1;
  background:var(--or-nappe);
}
.diagnostic__bouton::after{
  inset:-1px;
  padding:1px;
  background:radial-gradient(89% 144% at 50% 110%,
    color-mix(in srgb, var(--or) 55%, transparent) 0%,
    color-mix(in srgb, var(--or) 21%, transparent) 55%,
    transparent 89%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask-composite:exclude;
}
.diagnostic__bouton:hover{
  background:transparent;
  color:var(--ink);
  border-color:rgba(13,13,12,.34);
  transition:border-color 377ms var(--ease), color 377ms var(--ease);
}
.diagnostic__bouton:hover::before,
.diagnostic__bouton:hover::after{
  opacity:1;
  transition:opacity 377ms var(--ease);
}

/* --- au défilement : les gestes de la section 2 -------------------------------
   Le texte apparaît comme les paragraphes (introLire), l'image se pose
   (servicePoser). Plages avancées : écrite quand elle fermait la page, la
   section ne remontait pas jusqu'au centre de l'écran, et sur la plage des
   services le texte restait à demi transparent en bout de page. Le pied de
   page la suit désormais ; les plages restent avancées — le texte net à
   cover 37 %, l'image posée à cover 34 % —, lisibles plus tôt, juste au-dessus
   du pied de page. */
@supports (animation-timeline: view()){
  .diagnostic__contenu{
    opacity:0;
    transform:translateY(21px);
    animation:introLire both;
    animation-timeline:view();
    animation-range:cover 0% cover 100%;
    animation-timing-function:cubic-bezier(.33,0,.2,1);
  }
  .diagnostic__visuel img{
    transform:scale(1.089);
    animation:servicePoser both;
    animation-timeline:view();
    animation-range:cover 0% cover 34%;
    animation-timing-function:cubic-bezier(.33,0,.2,1);
  }
}

/* Sous 987px : l'image au-dessus, en 3/2, puis l'aplat à hauteur de contenu */
@media(max-width:987px){
  .diagnostic__wrap{ grid-template-columns:1fr }
  .diagnostic__visuel{ aspect-ratio:3 / 2 }
  .diagnostic__texte{ min-height:0; padding:55px 21px 89px }
}

/* ==========================================================================
   PIED DE PAGE — la composition de Chenot, en encre
   Le logotype centré, puis la visite à gauche et le plan du site à droite,
   dans le rapport 5/8 de la grille de 13 (la partition dorée de la vedette
   de la boutique) ; la ligne légale au ras du bas. Pleine largeur sur les
   gouttières du header, comme chez Chenot : le crédit tombe à l'aplomb des
   pictos du header.
   Même plan que les sections (au-dessus du banner collant). Ni filet ni
   icône : les écarts et deux encres — pleine pour ce qui se lit, estompée
   pour les intitulés et la ligne légale — tiennent la grille.
   ========================================================================== */
.footer{
  position:relative;
  z-index:1;
  background:var(--ink);
  color:var(--paper);
}

.footer__wrap{ padding:107px var(--gutter) 89px }

/* Le MOT sur l'axe, comme dans le header (.header__logo) : les points
   pendent à gauche, hors du centrage. Le milieu du mot est à 55,94 % de la
   largeur du logo : centré, la boîte est décalée de 5,94 % vers la gauche.
   34px, deux crans au-dessus du header (21) : le logotype ouvre le pied,
   comme celui de Chenot. */
.footer__logo{
  display:block;
  width:max-content;
  margin:0 auto 89px;
  translate:-5.94% 0;
}
.footer__logo svg{ display:block; height:34px; width:auto; overflow:visible }

/* 5fr / 8fr, avec deux planchers : 322 pour la mesure du texte, la largeur
   de ses trois colonnes pour le plan (max-content, rien ne se tasse). En
   dessous, empilés (voir plus bas). */
.footer__grille{
  display:grid;
  grid-template-columns:minmax(322px, 5fr) minmax(max-content, 8fr);
  column-gap:55px;
  align-items:start;
}
.footer__lettre{ max-width:521px }

/* l'intitulé : la voix des noms de services (Tenor aux accents de Jost,
   capitales .089em), à leur plancher de 21 — rogné à la capitale, son haut
   s'aligne sur celui des intitulés du plan */
.footer__titre{
  margin:0 0 29px;
  font-family:var(--font-titre);
  font-size:21px;
  line-height:1.272;
  font-weight:400;
  letter-spacing:.089em;
  text-transform:uppercase;
  text-box:trim-both cap alphabetic;
}
/* le paragraphe de la section 1 (17/29, 400) ; margin:0, c'est un <p> —
   font-style:normal reste de l'<address> qu'il remplaçait d'abord */
.footer__texte{
  margin:0;
  font-style:normal;
  font-size:17px;
  line-height:29px;
  font-weight:400;
  text-wrap:pretty;
}
/* soulignés comme le lien de la relance (.intro__lien) ; au survol ils
   s'estompent à 60 % */
.footer__lien{
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  transition:color .3s var(--ease);
}
.footer__lien:hover{ color:rgba(244,242,238,.6) }

.lettre{
  position:relative;
  max-width:377px;
  margin-top:34px;
}
/* masquée à l'œil, pas aux lecteurs d'écran : le placeholder, qui disparaît
   à la saisie, n'est pas une étiquette */
.lettre__label{
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}
/* le filet est porté par la LIGNE, sous la saisie et la flèche d'un seul
   trait, en pseudo-élément : au succès il se rétracte vers son centre */
.lettre__ligne{
  position:relative;
  display:flex;
  align-items:center;
  gap:13px;
}
.lettre__ligne::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background:rgba(244,242,238,.34);
  transform-origin:center;
  transition:background-color 377ms var(--ease),
             transform 610ms cubic-bezier(.33,0,.2,1) 233ms;
}
.lettre__ligne:focus-within::after{ background:var(--paper) }
.lettre__champ{
  appearance:none;
  -webkit-appearance:none;
  flex:1 1 auto;
  min-width:0;
  padding:13px 0;
  border:0;
  border-radius:0;
  background:none;
  font-family:var(--font-ui);
  font-size:17px;
  line-height:29px;
  font-weight:400;
  color:var(--paper);
}
.lettre__champ::placeholder{ color:rgba(244,242,238,.45) }
.lettre__champ:focus{ outline:none }

.lettre__champ:-webkit-autofill,
.lettre__champ:-webkit-autofill:hover,
.lettre__champ:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 100px var(--ink) inset;
  box-shadow:0 0 0 100px var(--ink) inset;
  -webkit-text-fill-color:var(--paper);
  caret-color:var(--paper);
}

.lettre__fleche{
  flex:0 0 auto;
  display:grid;
  place-items:center;
  width:34px;
  height:34px;
  padding:0;
  border:0;
  background:none;
  color:rgba(244,242,238,.55);
  cursor:pointer;
  transition:color 377ms var(--ease), transform 377ms var(--ease);
}
.lettre__fleche svg{ display:block; width:21px; height:21px }
.lettre__champ:valid ~ .lettre__fleche{ color:var(--paper) }
.lettre__fleche:hover{ color:var(--paper); transform:translateX(3px) }
.lettre__fleche:focus-visible{
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:3px;
}
.lettre__mention{
  margin:21px 0 0;
  font-size:13px;
  line-height:21px;
  font-weight:400;
  color:rgba(244,242,238,.55);
}
.lettre__mention a{
  color:var(--paper);
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
}
.lettre__mention a:focus-visible{
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:3px;
}
.lettre__retour{
  margin:0;
  font-size:13px;
  line-height:21px;
  font-weight:400;
  color:var(--paper);
}
.lettre__retour:not(:empty){ margin-top:13px }
.lettre__retour:focus{ outline:none }
/* pendant l'envoi la ligne s'estompe et ne répond plus : pas de double envoi */
.lettre.is-envoi .lettre__ligne{ opacity:.47; pointer-events:none }
/* envoi accepté : la saisie, la flèche et la mention s'effacent, le filet se
   rétracte, le merci prend leur place — sans rien retirer du flux, le pied
   ne saute pas */
.lettre.is-ok .lettre__champ,
.lettre.is-ok .lettre__fleche,
.lettre.is-ok .lettre__mention{
  opacity:0;
  transition:opacity 377ms cubic-bezier(.33,0,.2,1);
}
.lettre.is-ok .lettre__ligne{ pointer-events:none }
.lettre.is-ok .lettre__ligne::after{ transform:scaleX(0) }
.lettre.is-ok .lettre__retour{
  position:absolute;
  inset:0;
  display:flex;
  align-items:center;
  margin:0;
  font-size:17px;
  line-height:29px;
}

.footer__reseaux{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:21px;
  margin-top:55px;
}
.footer__reseaux .footer__reseau{
  display:block;
  padding:8px;
  margin:-8px;
  line-height:0;
}
.footer__reseaux .footer__reseau + .footer__reseau{ margin-left:0 }
.footer__reseau svg{ display:block; overflow:visible }
.footer__reseaux .footer__reseau:focus-visible{ outline-offset:-3px }

/* Le plan : trois colonnes réparties sur sa largeur, la dernière calée sur
   la gouttière. Un intitulé estompé, puis ses liens, au même pas (34). */
.footer__plan{
  display:flex;
  justify-content:space-between;
  gap:55px;
}
.footer__groupe{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:34px;
}
/* intitulés : capitales 11px, 500 — la voix de ceux du sous-menu —, en
   encre estompée comme chez Chenot : ce n'est pas une destination */
.footer__groupeTitre{
  font-size:11px;
  font-weight:500;
  letter-spacing:.144em;
  line-height:1;
  text-box:trim-both cap alphabetic;
  text-transform:uppercase;
  white-space:nowrap;
  color:rgba(244,242,238,.55);
}
/* liens : capitales 13px — la voix des avis du banner —, à 86 % comme les
   pictos du header ; le survol monte à l'encre pleine */
.footer__reseau,
.footer__groupeLien{
  font-size:13px;
  font-weight:400;
  letter-spacing:.144em;
  line-height:1;
  text-box:trim-both cap alphabetic;
  text-transform:uppercase;
  white-space:nowrap;
  color:rgba(244,242,238,.86);
  transition:color .55s var(--ease);
}
.footer__reseau:hover,
.footer__groupeLien:hover{ color:var(--paper) }

.footer__logo:focus-visible,
.footer__lien:focus-visible,
.footer__reseau:focus-visible,
.footer__groupeLien:focus-visible,
.footer__bas a:focus-visible{
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:5px;
}

.footer__bas{
  display:flex;
  flex-wrap:wrap;
  justify-content:space-between;
  align-items:baseline;
  gap:8px 34px;
  padding:0 var(--gutter) 13px;
  font-size:11px;
  font-weight:400;
  line-height:1;
  color:rgba(244,242,238,.5);
}
.footer__bas p{
  margin:0;
  white-space:nowrap;
  text-box:trim-both cap alphabetic;
}

.footer__legal{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  gap:13px 29px;
  white-space:normal;
}
.footer__legal > *{
  white-space:nowrap;
  text-box:trim-both cap alphabetic;
}
.footer__credit{ margin-left:auto }
.footer__bas a{ transition:color .55s var(--ease) }
.footer__bas a:hover{ color:var(--paper) }

@media(max-width:1151px){
  .footer__grille{
    grid-template-columns:minmax(0, 1fr);
    row-gap:55px;
  }
}
/* sous 760px, les trois colonnes s'empilent à leur tour */
@media(max-width:760px){
  /* 89 au-dessus : la hauteur du header sous 760px (76 + 13) ; 55 dessous */
  .footer__wrap{ padding:89px var(--gutter) 55px }
  .footer__logo{ margin-bottom:55px }
  .footer__plan{ flex-direction:column; gap:55px }
}

@media(max-width:987px){
  .footer__bas{
    flex-direction:column;
    align-items:center;
    gap:13px;
    padding-bottom:21px;
  }
  .footer__legal{
    justify-content:center;
    gap:0 29px;
  }
  .footer__legal > a:nth-of-type(-n+2){ order:1 }
  .footer__legal::before{ content:""; flex-basis:100%; height:21px; order:2 }
  .footer__legal > a:nth-of-type(n+3){ order:3 }
  .footer__legal::after{ content:""; flex-basis:100%; height:34px; order:4 }
  .footer__legal > span{ order:5 }
  .footer__credit{ margin-left:0 }
}

@supports (timeline-scope:--a){
  @media(max-width:987px){
    body{ timeline-scope:--colophon }
    .footer__legal{ view-timeline:--colophon block }
    .resaBar{
      animation:resaPoser linear both;
      animation-timeline:--colophon;
      animation-range:cover 0% cover 610px;
    }
    .footer:has(~ .resaBar) .footer__bas{ padding-top:calc(var(--resa-b) + 13px * 3) }
  }
  @media(max-width:760px){
    .footer:has(~ .resaBar) .footer__bas{ padding-top:calc(var(--resa-b) + 11px * 2 + 13px) }
  }
}
@supports not (timeline-scope:--a){
  @media(max-width:987px){
    .footer:has(~ .resaBar) .footer__bas{ padding-bottom:calc(var(--resa-b) + 13px * 3 + 21px) }
  }
  @media(max-width:760px){
    .footer:has(~ .resaBar) .footer__bas{ padding-bottom:calc(var(--resa-b) + 11px * 2 + 13px + 21px) }
  }
}
@keyframes resaPoser{ to{ translate:0 -610px } }

.resaBar{
  position:fixed;
  left:50%;
  bottom:var(--resa-b);
  transform:translateX(-50%);
  z-index:90;
}

.resaBar__group{ position:relative; display:inline-flex }

/* la pastille est la surface du verre (voir VERRE plus bas) */
.resaBar__pill{
  display:block;
  color:#fff;
}

/* Marge intérieure portée par le texte : la lumière du survol
   (.verre__texte::before) couvre ainsi toute la pastille. */
.resaBar__row{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:18px;
  padding:13px 21px;
}

/* text-box : la boîte du libellé est rognée de la hauteur de capitale à la
   ligne de base. Sans ça, align-items:center centrait la boîte de ligne, où
   les capitales montent au-dessus du milieu (la place des jambages, en bas,
   reste vide) : le texte flottait plus haut que l'axe des points. Rognée,
   c'est le centre des capitales qui se pose sur le centre des points. */
.resaBar__label{
  font-size:11px;
  font-weight:400;
  letter-spacing:.199em;
  line-height:1;
  text-box:trim-both cap alphabetic;
  text-transform:uppercase;
  white-space:nowrap;
}

.resaBar__points{
  flex:none;
  display:block;
  height:13px;
  width:auto;
}

.resaBar__pill:focus-visible{
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:5px;
}

@media(max-width:760px){
  .resaBar__row{ gap:13px; padding:11px 18px }
  .resaBar__label{ font-size:11px; letter-spacing:.144em }
}

@property --angle-1{
  syntax:"<angle>";
  inherits:false;
  initial-value:-75deg;
}

/* les durées et la courbe du verre. Posées aussi sur la surface : sans
   conteneur .verre (la carte Nouveauté), var() restait indéfinie, toutes les
   transitions du verre tombaient, et le survol basculait d'un coup. */
.verre,
.verre__bouton{
  --verre-t:521ms;
  --verre-ease:cubic-bezier(.33, 0, .2, 1);
}

/* conteneur : il se place (voir .resaBar__group), et c'est lui
   qui bascule à l'appui */
.verre{
  z-index:2;
  pointer-events:none;
  transition:transform var(--verre-t) var(--verre-ease);
}

/* la surface — couches 1 et 2, et l'assise */
.verre__bouton{
  position:relative;
  isolation:isolate;
  cursor:pointer;
  pointer-events:auto;
  -webkit-tap-highlight-color:transparent;
  border-radius:var(--pill-r);
  /* 2. la matière : un fond sombre à 22 % qui garde le texte lisible quand la
     vidéo passe au clair — le voile gris, lui, est sur ::before */
  background-color:rgba(18,18,18,.22);
  /* 1. le flou : 29px fondent la vidéo en nappe ; saturate garde ses couleurs
     vivantes au lieu de les griser — c'est LE signal du dépoli */
  backdrop-filter:blur(29px) saturate(1.55);
  -webkit-backdrop-filter:blur(29px) saturate(1.55);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.14),   /* épaisseur du verre, sous l'arête */
    inset 0 -1px 0 rgba(255,255,255,.05),
    0 13px 34px rgba(0,0,0,.34),           /* assise */
    0 2px 5px rgba(0,0,0,.22);             /* contact */
  transition:background-color var(--verre-t) var(--verre-ease),
             box-shadow var(--verre-t) var(--verre-ease),
             transform var(--verre-t) var(--verre-ease);
}

/* 2 + 3. la matière et la lumière : le voile gris plus clair en haut qu'en bas
   (la lumière vient du haut), un reflet en dôme au bord haut — une lumière sur
   une surface bombée, pas une barre —, un écho plus faible dans le coin bas
   droit, et le grain du dépoli : un bruit SVG blanc à 7 %, si fin qu'on ne le
   voit pas, on le sent. */
.verre__bouton::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  background:
    radial-gradient(89% 55% at 50% -8%, rgba(255,255,255,.30) 0%, rgba(255,255,255,.09) 42%, rgba(255,255,255,0) 68%),
    radial-gradient(34% 76% at 100% 110%, rgba(255,255,255,.09) 0%, rgba(255,255,255,0) 60%),
    linear-gradient(180deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,.05) 50%, rgba(255,255,255,.08) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='144' height='144'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* 4. l'arête : 1px de liseré, vif là où la lumière frappe (en haut à gauche,
   à --angle-1), presque éteint entre les deux, rallumé à l'opposé — la lumière
   que l'épaisseur du verre laisse passer. Un dégradé conique et non linéaire :
   c'est l'angle de départ qui tourne au survol, comme sur l'original. Peint par
   masque : le dégradé couvre la boîte, le masque n'en garde que le pourtour. */
.verre__bouton::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:2;
  border-radius:inherit;
  padding:1px;
  pointer-events:none;
  background:conic-gradient(from var(--angle-1) at 50% 50%,
    rgba(255,255,255,.72) 0%,
    rgba(255,255,255,.07) 12% 38%,
    rgba(255,255,255,.44) 50%,
    rgba(255,255,255,.07) 62% 88%,
    rgba(255,255,255,.72) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  opacity:.9;
  transition:opacity var(--verre-t) var(--verre-ease), --angle-1 500ms ease;
}

/* le contenu, au-dessus des couches ; une ombre d'un pixel sous les lettres
   pour les plans clairs de la vidéo */
.verre__texte{
  position:relative;
  z-index:1;
  text-shadow:0 1px 2px rgba(0,0,0,.25);
}
/* la lumière qui s'allume au survol : le même dôme, plus fort, invisible au
   repos — un dégradé ne s'anime pas, son opacité si */
.verre__texte::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:-1;
  border-radius:var(--pill-r);
  pointer-events:none;
  background:radial-gradient(89% 62% at 50% -8%, rgba(255,255,255,.26) 0%, rgba(255,255,255,.07) 45%, rgba(255,255,255,0) 70%);
  opacity:0;
  transition:opacity var(--verre-t) var(--verre-ease);
}
/* survol : la pastille se resserre, s'éclaircit, l'assise se rapproche ;
   l'arête tourne, le dôme s'allume */
.verre__bouton:hover{
  background-color:rgba(48,48,48,.24);
  transform:scale(0.975);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 -1px 0 rgba(255,255,255,.07),
    0 2px 1px -1px rgba(0,0,0,.25),
    0 8px 21px rgba(0,0,0,.30);
}
.verre__bouton:hover::after{ opacity:1; --angle-1:-125deg }
.verre__bouton:hover .verre__texte::before{ opacity:1 }

/* appui : tout le bloc bascule vers l'arrière, le verre s'assombrit */
.verre:has(.verre__bouton:active){
  transform:rotate3d(1, 0, 0, 25deg);
}
.verre__bouton:active{
  background-color:rgba(0,0,0,.30);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    inset 0 2px 6px rgba(0,0,0,.25),
    0 3px 1px 0 rgba(255,255,255,.18),
    0 5px 13px rgba(0,0,0,.30);
}
.verre__bouton:active::after{ --angle-1:-75deg }
.verre__bouton:active .verre__texte::before{ opacity:.5 }

/* au doigt, pas de survol : l'arête ne tourne pas */
@media (hover: none) and (pointer: coarse){
  .verre__bouton::after,
  .verre__bouton:hover::after,
  .verre__bouton:active::after{ --angle-1:-75deg }
}

.resaBar__pill,
.nouveaute{
  background-image:var(--or-nappe);
}
.resaBar__pill::after,
.nouveaute::after{
  background:conic-gradient(from var(--angle-1) at 50% 50%,
    rgba(255,255,255,.72) 0%,
    rgba(255,255,255,.07) 12% 38%,
    color-mix(in srgb, var(--or) 80%, transparent) 50%,
    rgba(255,255,255,.07) 62% 88%,
    rgba(255,255,255,.72) 100%);
}

/* --- la veille -----------------------------------------------------------
   Une lueur très douce qui fait lentement le tour du contour de la pastille de
   réservation, apparaît puis s'efface : une façon discrète de rappeler qu'elle
   est là, prête. Sur elle seule — un seul objet en avant à la fois.
   Construction : .verre__veille est un anneau d'un pixel (le masque ne garde
   que son padding) ; dedans, une tache de lumière (::before) suit le contour
   par offset-path. LE LONG du bord et non en tournant autour du centre : un
   dégradé conique, sur une pastille six fois plus large que haute, traînerait
   au milieu des grands côtés et fouetterait les angles. Ici la vitesse est la
   même partout.
   Deux cycles qui ne se recoupent jamais : un tour en 10,946s, un souffle en
   6,765s — deux termes consécutifs de Fibonacci, dans le rapport φ. La lueur
   ne réapparaît donc jamais deux fois au même endroit.
   Au survol elle s'efface : le visiteur a trouvé le bouton. */
.verre__veille{
  position:absolute;
  inset:0;
  z-index:3;
  border-radius:inherit;
  padding:1px;
  pointer-events:none;
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  /* La lueur AJOUTE sa lumière à celle de l'arête au lieu de se poser dessus :
     l'arête est déjà claire, une lueur en simple superposition s'y perdait —
     vérifié à l'écran, invisible même au sommet du souffle. */
  mix-blend-mode:plus-lighter;
  transition:opacity var(--verre-t) var(--verre-ease);
}
/* la tache : 55px de diamètre, un cœur blanc qui s'éteint vers les bords —
   sur la ligne d'un pixel, une lueur d'une quarantaine de pixels, sans arête */
.verre__veille::before{
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:55px;
  height:55px;
  border-radius:50%;
  background:radial-gradient(closest-side,
    rgba(255,255,255,1) 0%,
    rgba(255,255,255,.45) 40%,
    rgba(255,255,255,0) 100%);
  offset-path:inset(0 round var(--pill-r));
  offset-anchor:50% 50%;
  offset-rotate:0deg;
  opacity:0;
  animation:
    veille-tour 10946ms linear infinite,
    veille-souffle 6765ms ease-in-out infinite;
}
@keyframes veille-tour{
  from{ offset-distance:0% }
  to{ offset-distance:100% }
}
/* monte, redescend, puis un temps d'absence — visible sur 62 % du cycle. La
   douceur tient au fondu (2,1s pour monter, autant pour s'éteindre), pas à
   une intensité réduite : à .55 la lueur ne se voyait plus. */
@keyframes veille-souffle{
  0%, 100%{ opacity:0 }
  31%{ opacity:1 }
  62%{ opacity:0 }
}
.verre__bouton:hover .verre__veille{ opacity:0 }

/* la montée et le fondu au défilement, écrits à chaque image par main.js
   (NOUVEAUTÉ). Déclarées non héritées : les changer ne recalcule pas le
   style de tout le contenu de la carte. */
@property --nouveaute-y{
  syntax:"<length>";
  inherits:false;
  initial-value:0px;
}
@property --nouveaute-o{
  syntax:"<number>";
  inherits:false;
  initial-value:1;
}
.nouveaute{
  position:fixed;
  right:8px;
  bottom:8px;
  /* au rang du banner (0) et après lui dans la page : elle passe devant lui,
     et la section 1 (1) glisse par-dessus elle comme par-dessus lui. Le
     header (10) et le bouton de réservation (90) restent devant. */
  z-index:0;
  width:min(322px, calc(100% - 16px));
  color:#fff;
  font-family:"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,sans-serif;
  font-size:13px;
  font-weight:400;
  line-height:21px;
  /* translate et non transform : le survol du verre (scale) et la fermeture
     (translateX) gardent transform pour eux */
  translate:0 var(--nouveaute-y);
  opacity:var(--nouveaute-o);
}
/* le contenu (.verre__texte) porte les marges : le lien qui couvre la carte
   (::after de .nouveaute__corps) se cale sur lui, donc sur toute la carte */
.nouveaute__contenu{ padding:13px }

/* En-tête : les cinq points, « NOUVEAUTÉ », la croix calée à droite.
   En capitales, le mot remplit sa hauteur de capitale : son centre est au
   milieu de cette hauteur (en bas de casse, l'œil le plaçait plus bas, au
   milieu des minuscules). Les points mesurent 1cap et reposent sur la ligne
   de base (align-items:baseline — le bas d'un SVG lui sert de ligne de
   base) : même hauteur et même bas que le mot, quelle que soit la police.
   main.js arrondit leur hauteur au pixel d'écran et les cale sur la ligne
   de base du texte : sans ça, à 125 %, le point du haut débordait d'une
   rangée de pixels au-dessus des capitales et le mot paraissait bas.
   text-box ne fait que rogner la ligne à la hauteur du mot ; sans lui
   (Firefox), l'alignement tient.
   Interlettrage .144em, celui des capitales en 13 du site (les avis du
   banner). */
.nouveaute__tete{
  display:flex;
  align-items:baseline;
  gap:8px;
  margin-bottom:13px;
  font-size:13px;
}
.nouveaute__points{ flex:none; display:block; height:1cap; width:auto }
.nouveaute__app{
  line-height:1;
  letter-spacing:.144em;
  text-box:trim-both cap alphabetic;
  text-transform:uppercase;
  white-space:nowrap;
}

.nouveaute__fermer{
  position:relative;
  z-index:1;
  display:flex;
  align-items:center;
  justify-content:center;
  width:29px;
  height:29px;
  align-self:center;
  margin:-10px -8px -10px auto;
  padding:0;
  border:0;
  border-radius:4px;
  background:none;
  font:inherit;
  color:rgba(255,255,255,.79);
  cursor:pointer;
  transition:color .3s var(--ease);
}
.nouveaute__fermer svg{ display:block; height:1cap; width:auto }
.nouveaute__fermer path{ vector-effect:non-scaling-stroke }
.nouveaute__fermer:hover{ color:#fff }
.nouveaute__fermer:focus-visible{
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:-1px;
}

/* corps : la vignette, puis le titre et la description */
.nouveaute__corps{
  display:flex;
  align-items:flex-start;
  gap:13px;
}
/* toute la carte est cliquable */
.nouveaute__corps::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:8px;
}
.nouveaute__corps:focus-visible{ outline:none }
.nouveaute:has(.nouveaute__corps:focus-visible){
  outline:1px solid rgba(255,255,255,.9);
  outline-offset:3px;
}
.nouveaute__image{
  flex:none;
  width:76px;
  height:76px;
  border-radius:4px;
  object-fit:cover;
  background:#fff;
}
.nouveaute__texte{
  display:flex;
  flex-direction:column;
  min-width:0;
}
.nouveaute__titre{ font-weight:600 }
.nouveaute__desc{ color:rgba(255,255,255,.79) }

/* envolée : le fondu du défilement est à zéro, elle ne se clique plus et
   sort du clavier */
.nouveaute.is-envolee{ visibility:hidden }

/* fermée : elle sort vers la droite en s'effaçant ; visibility attend la fin
   du glissement puis la retire du clavier et des lecteurs d'écran */
.nouveaute.is-fermee{
  opacity:0;
  transform:translateX(calc(100% + 8px));
  visibility:hidden;
  transition:opacity 233ms var(--ease), transform 233ms var(--ease), visibility 0s 233ms;
}

/* En bas à droite tant qu'au moins 13px la séparent du bouton de
   réservation, centré en bas ; sous le palier 987, elle monte juste sous le
   header. À 322 de large, 987 suffit : la moitié de l'écran doit contenir la
   marge (8), la carte (322), l'écart (13) et la moitié du bouton (116), soit
   459 — 918px d'écran. */
@media(max-width:987px){
  .nouveaute{
    top:calc(var(--header-h, 107px) + 8px);
    bottom:auto;
  }
}

.demo{
  /* Outfit, la voix du studio, sur cette seule page ; portée par .demo et non
     par :root, rien d'autre ne doit l'attraper */
  --font-graphen:"Outfit","Helvetica Neue",Arial,sans-serif;
  min-height:100vh;
  min-height:100svh;
  display:grid;
  align-items:start;
  justify-items:center;
  padding:calc(var(--header-h, 107px) + clamp(47px, 8vh, 144px)) var(--gutter) clamp(21px, 4vh, 89px);
  background:var(--paper);
  color:var(--ink);
}

/* Une colonne par défaut, deux dès 1240 (plus bas). Les deux boîtes passent
   en display:contents et leurs enfants se rangent dans une seule pile par
   order — le balisage ne bouge pas d'un palier à l'autre. */
.demo__grille{
  width:100%;
  max-width:610px;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  text-align:left;
}
.demo__tete,
.demo__colonne{ display:contents }
.demo__page-nom{ order:1 }
.demo__sur{ order:2 }
.demo__info{ order:3 }
.demo__pages{ order:4 }
.demo__marque{ order:5 }
.demo__index{ order:6 }

.demo__page-nom{
  margin:0 0 13px;
  font-family:var(--font-graphen);
  font-size:47px;
  line-height:55px;
  font-weight:200;
  letter-spacing:-.021em;
  color:var(--ink);
}
.demo__sur{
  margin:0 0 29px;
  font-family:var(--font-graphen);
  font-size:11px;
  line-height:18px;
  font-weight:500;
  letter-spacing:.123em;
  text-transform:uppercase;
  color:rgba(13,13,12,.47);
}

/* la note : un cran sous le texte, bornée à 322 ; le « i » sort dans la
   marge, le texte retombe sur le fer du nom */
.demo__info{
  display:flex;
  align-items:flex-start;
  gap:11px;
  max-width:322px;
  margin:0 0 47px calc(-1 * (13px + 11px));
  color:rgba(13,13,12,.55);
}
.demo__info p{
  margin:0;
  font-family:var(--font-graphen);
  font-size:13px;
  line-height:21px;
  font-weight:300;
}
.demo__info-icone{
  flex:none;
  width:13px;
  height:13px;
  margin-top:4px;
}

/* l'index : quinze pages sur deux colonnes de huit, en capitales espacées ;
   la page courante (ou la rubrique) à l'encre pleine */
.demo__index{
  display:flex;
  align-items:flex-start;
  gap:11px;
  margin:47px 0 0 calc(-1 * (13px + 11px));
}
.demo__index-icone{
  flex:none;
  width:13px;
  height:13px;
  margin-top:2.5px;
  color:rgba(13,13,12,.34);
}
.demo__index-liste{
  display:grid;
  grid-template-rows:repeat(8, auto);
  grid-auto-flow:column;
  justify-content:start;
  column-gap:29px;
  row-gap:8px;
  font-family:var(--font-graphen);
  font-size:11px;
  line-height:18px;
  font-weight:300;
  letter-spacing:.123em;
  text-transform:uppercase;
}
.demo__index a{
  color:rgba(13,13,12,.47);
  transition:color .34s var(--ease);
}
.demo__index a:hover{ color:var(--ink) }
.demo__index a[aria-current]{
  color:var(--ink);
  font-weight:500;
}

/* la colonne de lecture : un paragraphe par phrase, 21 entre eux (plus serré
   que l'interligne, ils se lisent en un bloc) */
.demo__texte{
  margin:0;
  font-family:var(--font-graphen);
  font-size:18px;
  line-height:29px;
  font-weight:300;
  color:rgba(13,13,12,.78);
}
.demo__texte + .demo__texte{ margin-top:21px }
.demo__liste{
  margin:21px 0 0;
  padding:0;
  list-style:none;
}
.demo__liste li + li{ margin-top:21px }
/* Outfit n'a pas d'italique : l'emphase passe par la graisse médiane */
.demo__texte em{
  font-style:normal;
  font-weight:500;
}

/* la signature, au fer à droite, à la suite du texte */
.demo__marque{
  display:block;
  width:max-content;
  margin:55px 0 0 auto;
  transition:opacity .55s var(--ease);
}
.demo__marque:hover{ opacity:.55 }
.demo__marque img{ width:144px; height:auto }

@supports (animation-timeline: view()){
  .demo--defile .demo__texte{
    opacity:0;
    transform:translateY(21px);
    animation:demoParaitre both, demoPartir forwards;
    animation-timeline:view(), view();
    animation-range:entry 21% entry 100%, exit 0% exit 100%;
    animation-timing-function:cubic-bezier(.33,0,.2,1), cubic-bezier(.8,0,.67,1);
  }
}
@keyframes demoParaitre{ to{ opacity:1; transform:none } }
@keyframes demoPartir{ to{ opacity:0; transform:translateY(-21px) } }

/* l'ancre du filet, fixe et vide, calée sur la colonne de lecture */
.demo__pied{
  position:fixed;
  left:0;
  right:0;
  bottom:clamp(55px, 10vh, 123px);
  z-index:2;
  width:calc(100% - 2 * var(--gutter));
  max-width:610px;
  margin:0 auto;
  height:0;
  pointer-events:none;
}
/* le filet de défilement : une lampe qui descend un cheveu, à gauche du texte,
   seulement si la page défile */
.demo__filet{
  --filet-h:123px;
  --lampe-h:76px;
  display:none;
  position:absolute;
  left:-47px;
  bottom:0;
  width:1px;
  height:var(--filet-h);
  overflow:hidden;
}
.demo--defile .demo__filet{ display:block }
.demo__filet::after{
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:var(--lampe-h);
  background:linear-gradient(to bottom, rgba(13,13,12,0), rgba(13,13,12,.89), rgba(13,13,12,0));
  animation:demoTorche 5.5s ease-in-out infinite;
}
@keyframes demoTorche{
  0%, 8%{ transform:translateY(calc(var(--lampe-h) * -1)) }
  92%, 100%{ transform:translateY(var(--filet-h)) }
}

@media (max-width:610px){
  .demo{ padding-top:calc(var(--header-h, 89px) + clamp(18px, 3vh, 34px)) }
  .demo__page-nom{ font-size:29px; line-height:34px }
  .demo__texte{ font-size:13px; line-height:21px }
  .demo__texte + .demo__texte,
  .demo__liste,
  .demo__liste li + li{ margin-top:13px }
  /* les pictos rentrent dans le rang : la gouttière ne vaut plus que 21 */
  .demo__info{ margin-left:0; margin-bottom:29px }
  .demo__index{ margin-left:0 }
  .demo__info p{ font-size:11px; line-height:18px }
  .demo__info-icone{ margin-top:2.5px }
  .demo__marque{ margin:89px 0 89px auto }
  .demo__marque img{ width:123px }
  .demo__filet{ left:-13px; --filet-h:76px; --lampe-h:47px }
}

@media (min-width:1240px){
  .demo__grille{
    max-width:1076px;
    display:grid;
    grid-template-columns:377px minmax(0, 610px);
    column-gap:89px;
    align-items:start;
  }
  .demo__tete{
    display:flex;
    flex-direction:column;
    align-items:flex-start;
    position:fixed;
    top:calc(var(--header-h, 107px) + clamp(47px, 8vh, 144px));
    left:calc(50vw - 538px);
    width:377px;
    height:calc(100svh - var(--header-h, 107px) - clamp(47px, 8vh, 144px) - clamp(89px, 15vh, 199px));
  }
  .demo__colonne{ display:block; grid-column:2 }
  .demo__info{ margin-bottom:0 }
  .demo__index{ margin-top:auto }
  .demo__pied{
    left:calc(50vw - 72px);
    right:auto;
    width:610px;
    max-width:none;
    margin:0;
  }
}

@media (prefers-reduced-motion: reduce){
  .demo--defile .demo__texte{ opacity:1; transform:none; animation:none }
  .demo__filet::after{ animation:none; transform:translateY(21px) }
}

/* ==========================================================================
   ACCESSIBILITÉ
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  /* verre : ni resserrement ni bascule, l'arête ne tourne pas — la lumière
     s'allume sans fondu */
  .verre, .verre__bouton, .verre__bouton::after,
  .verre__texte::before{ transition:none !important }
  .verre__bouton:hover{ transform:none }
  .verre:has(.verre__bouton:active){ transform:none }
  /* la veille est un mouvement continu : elle n'a pas d'état stable, elle
     tombe tout entière */
  .verre__veille{ display:none }
  
  .intro__texte{ opacity:1; transform:none; animation:none }
  /* l'image dessous : visible d'emblée, à sa taille, sans resserrement */
  .intro__visuel{ opacity:1; transform:none; animation:none }
  
  .hero{ position:relative }
  .hero__media{ transform:none }
  .intro{ box-shadow:none }
  /* section 2 : le texte des services lisible d'emblée et jamais retiré ;
     les images à leur taille, sans se poser */
  .service__contenu{ opacity:1; transform:none; animation:none }
  .service__visuel img{ transform:none; animation:none }
  /* section 3 : les produits là d'emblée (main.js ne pose d'ailleurs pas
     .boutique--apparition sous ce réglage) ; au survol le packshot ne se
     soulève plus, la photo du coffret ne zoome plus (ses règles, plus
     précises, sont reprises ici pour être annulées) */
  .boutique--apparition .produit{ opacity:1; transform:none; transition:none }
  .produit__visuel img,
  .produit--photo .produit__visuel img{ transition:none }
  .produit__lien:hover .produit__visuel img,
  .produit--photo .produit__lien:hover .produit__visuel img,
  .produit--photo .produit__lien:focus-visible .produit__visuel img{ transform:none }
  /* la lettre du pied : la flèche paraît sans glisser, le filet et le merci
     changent sans fondu */
  .lettre__ligne::after,
  .lettre__fleche,
  .lettre.is-ok .lettre__champ,
  .lettre.is-ok .lettre__fleche,
  .lettre.is-ok .lettre__mention{ transition:none }
  .lettre__fleche:hover{ transform:none }
  /* section 4 : le texte du diagnostic lisible d'emblée ; l'image posée */
  .diagnostic__contenu{ opacity:1; transform:none; animation:none }
  .diagnostic__visuel img{ transform:none; animation:none }
  /* avis Google : les rangs ne défilent plus seuls (main.js ne s'y attache
     pas) — ils se parcourent de côté, au doigt ou à la molette ; rien n'est
     masqué au chargement */
  .avis--apparition .avis__rang{ opacity:1; transform:none; transition:none }
  /* sélecteur de langue : les langues sortent sans glisser, la flèche se
     retourne d'un coup ; sous 760px, le logo s'efface sans fondu */
  .header__langListe,
  .header__langChevron,
  .header__logo{ transition:none !important }
  /* les cinq points du logo : masque retiré, ils sont déjà allumés. Pas
     d'!important : le balayage anime le dégradé, pas la propriété mask, que
     la feuille de style emporte donc sur l'attribut sans aide. */
  .header__logoPoints{ mask:none }
  /* sous-menus : apparition instantanée, sans fondu ni glissement */
  .header__submenu,
  .header__submenu > *,
  .header__sousBande{ transition:none !important }
  .header__tabWrap::before{ transition:none !important }
  .header__tabWrap .header__subVue{ transition:none !important }
  /* carte Nouveauté : fermée, elle disparaît sans glisser */
  .nouveaute.is-fermee{ transition:none }
  /* téléphone : le numéro apparaît sans glissade, le combiné ne sonne pas */
  .header__telPiste{ transition:none !important }
  .header__telPiste svg{ animation:none !important }
}

html.pan-bloque, html.pan-bloque body,
html.menu-bloque, html.menu-bloque body{ overflow:hidden }
.pan{ position:fixed; inset:0; z-index:60; color:var(--ink) }
.pan[hidden]{ display:none }
.pan__voile{
  position:absolute; inset:0;
  background:rgba(13,13,12,.34);
  opacity:0; transition:opacity 377ms var(--ease);
}
.pan.is-ouverte .pan__voile{ opacity:1 }
.pan__boite{
  position:absolute; top:0; right:0; bottom:0;
  display:flex; flex-direction:column;
  width:min(413px, calc(100vw - 21px));
  background:#fff;
  transform:translateX(100%);
  transition:transform 610ms cubic-bezier(.16,1,.3,1);
}
.pan.is-ouverte .pan__boite{ transform:none }
.pan__tete{ display:flex; justify-content:space-between; align-items:center; gap:21px; padding:21px 29px 13px }
.pan__titre{ margin:0; font-size:21px; line-height:29px; font-weight:400 }
.pan__nombre{ font-size:13px; color:rgba(13,13,12,.55); font-variant-numeric:tabular-nums }
.pan__fermer{
  display:grid; place-items:center; flex:none; width:29px; height:29px; padding:0;
  border:1px solid rgba(13,13,12,.13); border-radius:50%;
  background:transparent; color:inherit; cursor:pointer;
  transition:border-color 377ms var(--ease);
}
.pan__fermer:hover{ border-color:var(--ink) }
.pan__corps{ flex:1; overflow:auto; overscroll-behavior:contain; scrollbar-width:none; padding:0 29px 13px }
.pan__corps::-webkit-scrollbar{ display:none }
.pan__vide{ padding:34px 0; font-size:13px; line-height:21px; text-align:center }
.pan__vide p{ margin:0 0 8px; color:rgba(13,13,12,.55) }
.pan__decouvrir{ border-bottom:1px solid currentColor }
.pan__lignes, .pan__suggestions{ margin:0; padding:0; list-style:none }
.pan__ligne{
  display:grid; grid-template-columns:47px minmax(0, 1fr) auto; align-items:center; gap:13px;
  padding:13px 0; border-top:1px solid rgba(13,13,12,.08);
}
.pan__ligne:first-child{ border-top:0 }
.pan__img{ display:block; width:47px; height:47px; object-fit:cover; border-radius:4px; background:var(--paper) }
.pan__texte{ display:grid; min-width:0 }
.pan__nom{ margin:0; font-size:13px; line-height:21px; font-weight:500 }
.pan__detail{ margin:0; font-size:11px; line-height:13px; color:rgba(13,13,12,.55) }
.pan__ligneprix{ font-size:13px; line-height:21px; font-variant-numeric:tabular-nums; white-space:nowrap }
.pan__retirer{
  justify-self:start; margin:2px 0 0; padding:0; border:0; background:none;
  color:rgba(13,13,12,.55); font:inherit; font-size:11px; letter-spacing:.144em;
  line-height:13px; text-transform:uppercase; cursor:pointer;
  transition:color 377ms var(--ease);
}
.pan__retirer:hover{ color:var(--ink) }
.pan__completer{ padding:13px 0 0; border-top:1px solid rgba(13,13,12,.08) }
.pan__sur{ margin:0 0 4px; font-size:11px; letter-spacing:.144em; line-height:21px; text-transform:uppercase; color:rgba(13,13,12,.55) }
.pan__ajout{
  display:grid; grid-template-columns:47px minmax(0, 1fr) auto 21px; align-items:center; gap:13px;
  width:100%; padding:8px 0; border:0; background:none; color:inherit;
  font:inherit; text-align:left; cursor:pointer;
}
.pan__plus{
  display:grid; place-items:center; width:21px; height:21px;
  border:1px solid rgba(13,13,12,.34); border-radius:50%;
  transition:border-color 377ms var(--ease);
}
.pan__ajout:hover .pan__plus{ border-color:var(--ink) }
.pan__ajout:focus-visible{ outline:1px solid rgba(13,13,12,.9); outline-offset:3px }
.pan__pied{ padding:13px 29px 29px; border-top:1px solid rgba(13,13,12,.08) }
.pan__total{ display:flex; justify-content:space-between; align-items:baseline; gap:21px; margin:0 0 4px; font-size:13px; line-height:21px; font-weight:500 }
.pan__prix{ font-size:21px; line-height:29px; font-variant-numeric:tabular-nums }
.pan__note{ margin:0 0 13px; font-size:11px; line-height:13px; color:rgba(13,13,12,.55) }
.pan__bouton{
  display:flex; align-items:center; justify-content:center; gap:13px;
  min-height:55px; padding:0 21px; border-radius:var(--pill-r);
  background:var(--ink); color:#fff;
  font-size:11px; font-weight:500; line-height:13px; letter-spacing:.199em; text-transform:uppercase;
  transition:background-color 377ms var(--ease);
}
.pan__bouton:hover{ background:color-mix(in srgb, var(--ink) 82%, var(--or)) }
.pan__bouton svg{ flex:none; display:block; transition:transform 377ms var(--ease) }
.pan__bouton:hover svg{ transform:translateX(4px) }
@media (prefers-reduced-motion: reduce){
  .pan__voile, .pan__boite, .pan__bouton svg{ transition:none }
}
