/* =========================================================================
   Shiatsu Jiyū, feuille de style.

   Trois partis pris, et tout le reste en decoule.

   1. LE VERRE EST DU VERRE, PAS UN FLOU.
      Un `backdrop-filter: blur()` fait du verre depoli : on ne voit plus
      rien derriere. Le verre d'Apple ne trouble pas l'arriere-plan, il le
      DEVIE : les bords d'un galet de verre decalent ce qui passe dessous.
      C'est un filtre SVG (`feDisplacementMap`) nourri par une carte de
      deviation, fabriquee par `refraction.mjs`. Voir `.verre`.

   2. LES ANIMATIONS SONT PILOTEES PAR LE DEFILEMENT, PAS PAR UNE MINUTERIE.
      `animation-timeline: view()` lie la progression d'une animation a la
      position de l'element dans la fenetre. Pas de JavaScript, pas
      d'IntersectionObserver, et surtout : ca tourne sur le fil du
      compositeur, donc c'est fluide meme sur un telephone d'occasion.
      Un repli en JS existe pour les navigateurs qui ne savent pas encore.

   3. IL Y A DE LA VIDEO PARTOUT, MAIS ELLE NE PARLE JAMAIS PLUS FORT QUE
      LE TEXTE. Quatre films, un par chapitre, toujours derriere du verre.

   Palette : creme, blanc, et l'orange de son logo. Rien d'autre.
   ========================================================================= */

@property --angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; }

:root {
  /* --- couleurs --- */
  --creme:      #fff8ef;
  --creme-fond: #fdf2e4;
  --blanc:      #ffffff;
  --encre:      #3d2213;
  --encre-doux: #7c5a44;
  --encre-pale: #a98d78;

  --orange:      #e2711d;
  --orange-vif:  #f2913c;
  --orange-clair:#fbd9b4;
  --orange-nuit: #a8480c;

  /* --- rythme --- */
  --serre: 1180px;
  --marge: 28px;
  --rond: 30px;
  --rond-l: 42px;

  /* --- courbes --- */
  --sortie: cubic-bezier(.16, 1, .3, 1);
  --doux:   cubic-bezier(.4, 0, .2, 1);

  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

/* NE JAMAIS POSER overflow-x SUR LA RACINE.
   Une version precedente y mettait `clip` pour rattraper un debordement de
   la largeur de l'ascenseur, visible seulement sur ordinateur. Ca a coute
   TOUTES les animations du site : des que la racine porte un overflow, les
   minuteries de defilement (`animation-timeline: view()`) n'ont plus de
   scrollport valide, elles restent inactives, et les elements gardent leur
   etat de depart, c'est a dire invisibles. Le bas du site devenait
   transparent et la phrase ne s'allumait plus.
   Le debordement qu'on voulait corriger n'existe pas sur telephone : il n'y
   a pas de barre de defilement. On ne corrige donc rien. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font: 400 17px/1.65 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  color: var(--encre);
  background: var(--creme-fond);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--orange); color: #fff; }

.serre { position: relative; width: min(100% - var(--marge) * 2, var(--serre)); margin-inline: auto; }

/* =========================================================================
   TYPOGRAPHIE
   Grand, serre, et un mot en italique serif quand il faut respirer.
   ========================================================================= */
h1, h2, h3 { font-weight: 500; letter-spacing: -.035em; line-height: 1.04; text-wrap: balance; }

h1 { font-size: clamp(3rem, 9vw, 7rem); }
h2 { font-size: clamp(2.1rem, 5.2vw, 4.1rem); }
h3 { font-size: clamp(1.15rem, 2.2vw, 1.5rem); letter-spacing: -.02em; line-height: 1.22; }

em, .serif {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  letter-spacing: -.005em;
  color: var(--orange);
}

.sur-titre {
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--orange);
  display: flex;
  align-items: center;
  gap: 12px;
}
.sur-titre::before {
  content: ''; width: 26px; height: 1px; background: currentColor; opacity: .5; flex: none;
}
.centre .sur-titre { justify-content: center; }

.chapeau {
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  line-height: 1.68;
  color: var(--encre-doux);
  max-width: 62ch;
  text-wrap: pretty;
}
.chapeau b, .chapeau strong { color: var(--encre); font-weight: 600; }

/* =========================================================================
   LE GRAIN
   Une trame de bruit tres faible sur toute la page. Invisible si on la
   cherche, mais sans elle les aplats creme ont l'air d'etre en plastique.
   ========================================================================= */
body::after {
  content: '';
  position: fixed; inset: 0;
  pointer-events: none; z-index: 9999;
  opacity: .26; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");
}

/* =========================================================================
   LA JAUGE DE LECTURE
   Une ligne orange en haut, qui avance avec le defilement. Zero JS :
   l'animation est liee au scroll du document.
   ========================================================================= */
.jauge {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 200;
  background: linear-gradient(90deg, var(--orange-vif), var(--orange));
  transform-origin: 0 50%; transform: scaleX(0);
}
@supports (animation-timeline: scroll()) {
  .jauge {
    animation: avancer linear both;
    animation-timeline: scroll(root block);
  }
}
@keyframes avancer { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* =========================================================================
   LE VERRE LIQUIDE

   .verre           le corps translucide et le flou
   .verre::before   la couche de REFRACTION, le filtre SVG qui devie
                    l'arriere-plan sur les bords. Si le navigateur ne sait
                    pas faire, la propriete est simplement ignoree et il
                    reste un verre depoli tout a fait correct.
   .verre::after    l'arete lumineuse : un lisere blanc en haut a gauche
                    qui s'eteint en bas. C'est ce reflet, plus que le flou,
                    qui fait lire « epaisseur ».
   ========================================================================= */
.verre {
  position: relative;
  isolation: isolate;
  border-radius: var(--rond);
  background:
    linear-gradient(150deg, rgba(255,255,255,.72), rgba(255,255,255,.44) 46%, rgba(255,246,235,.60));
  backdrop-filter: blur(22px) saturate(185%) brightness(1.04);
  -webkit-backdrop-filter: blur(22px) saturate(185%);
  box-shadow:
    0 1px 0 rgba(255,255,255,.9) inset,
    0 -1px 0 rgba(255,255,255,.35) inset,
    0 2px 6px -2px rgba(120,60,15,.10),
    0 32px 64px -34px rgba(120,60,15,.38);
}
.verre > * { position: relative; z-index: 1; }
.verre::before {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  backdrop-filter: url(#refraction);
  -webkit-backdrop-filter: url(#refraction);
}
.verre::after {
  content: '';
  position: absolute; inset: 0; z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  padding: 1px;
  background: linear-gradient(145deg,
    rgba(255,255,255,.95) 0%,
    rgba(255,255,255,.30) 34%,
    rgba(255,255,255,0) 58%,
    rgba(255,214,168,.55) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
.verre.haut::before  { backdrop-filter: url(#refraction-haut); }
.verre.barre::before { backdrop-filter: url(#refraction-barre); }

/* =========================================================================
   LE VERRE ALLEGE SUR LES PETITS ECRANS

   Matheo, sur son telephone : « le site bug de ouf », et Chrome declare ne
   plus repondre. Ce n'etait pas une impression, c'est mesurable : la page
   d'accueil demandait VINGT-QUATRE couches de filtre de fond.

   D'ou elles viennent : chaque bloc de verre en porte DEUX. L'element
   lui-meme, avec un flou, et son `::before`, avec un filtre SVG a carte de
   deplacement. Ce second filtre charge une image, la lit comme une carte de
   vecteurs, et deplace chaque pixel du fond REEL en dessous. A refaire pour
   chaque element, a chaque image, pendant le defilement. Sur un ordinateur ca
   tient ; sur un telephone ca ne tient pas.

   CE QU'ON ENLEVE, ET POURQUOI CELUI-LA. On garde le flou et la saturation,
   qui sont faits par le processeur graphique et coutent peu. On retire la
   refraction, qui coute le plus et se voit le moins : c'est une deformation
   de quelques pixels sur les bords d'une carte, invisible sur une carte de
   trois cent quarante pixels de large. On ne perd donc presque rien a l'oeil,
   et on divise le nombre de couches par deux.

   Et le flou passe de 22 a 13 : son cout croit avec le rayon, et a cette
   taille d'ecran la difference ne se lit pas.
   ========================================================================= */
@media (max-width: 900px) {
  .verre::before { display: none; }
  .verre {
    backdrop-filter: blur(13px) saturate(175%) brightness(1.03);
    -webkit-backdrop-filter: blur(13px) saturate(175%);
  }
  /* Le panneau d'accueil n'est plus une carte de verre depuis le 25 aout : il
     n'a plus rien a flouter. C'etait le plus gros filtre de fond de la page,
     30 pixels de flou sur toute la largeur, au-dessus d'une video.

     ET LE FLOU ETAIT POSE SUR LA MAUVAISE BOITE : « .nav » n'est pas la
     pastille du menu, c'est le CONTENEUR QUI PREND TOUTE LA LARGEUR de
     l'ecran, et qui ne se voit pas parce qu'il n'a ni fond ni bordure.
     Il portait donc un flou de quinze pixels sur toute la largeur, y compris
     a gauche et a droite de la pastille ou il n'y a rien. Matheo l'a vu tout
     de suite sur son telephone : « une bande qui depasse ce menu, derriere et
     sur les cotes la ou il n'y a meme pas le menu ».

     UN FILTRE DE FOND N'A PAS BESOIN D'ETRE VISIBLE POUR FLOUTER : il
     s'applique a la boite de l'element, pas a ce qu'on y a dessine. Un
     conteneur transparent et invisible floute tout ce qui passe dessous.
     Le flou va desormais sur la pastille elle-meme. */
  .nav-boite, .formulaire-carte {
    backdrop-filter: blur(15px) saturate(180%);
    -webkit-backdrop-filter: blur(15px) saturate(180%);
  }

  /* ET ON VA PLUS LOIN LA OU LE VERRE NE SERT PLUS A RIEN.

     Six des dix blocs de verre de l'accueil sont les cartes d'avis. Or elles
     sont deja remplies a 88 % de blanc : ce qu'un flou irait chercher derriere
     elles est presque entierement recouvert. On payait donc six floutages du
     fond pour un effet qu'on ne voit pas. Meme chose pour les cartes de
     contenu, posees sur du creme uni.

     On leur rend un fond simple. Le verre reste la ou il travaille vraiment :
     la barre du haut, le panneau d'accueil, la carte de rendez-vous et le
     formulaire, tous poses sur une video ou sur une image. */
  .avis, .carte {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .avis-bandeau .avis { background: rgba(255,255,255,.94); }

  /* L'etiquette « Le cabinet » est traitee plus bas, JUSTE APRES sa regle de
     base : ici, elle aurait ete annulee. Voir la note la-bas. */
  .carte { background: linear-gradient(150deg, rgba(255,253,249,.94), rgba(255,248,239,.9)); }
}

/* Le verre pose au-dessus d'une video : on remonte la dominante creme pour
   qu'il reste lisible sans s'alourdir. */
.verre.sur-film {
  background: linear-gradient(150deg, rgba(255,252,246,.46), rgba(255,246,235,.26) 52%, rgba(255,238,220,.42));
  backdrop-filter: blur(30px) saturate(200%) brightness(1.06);
  -webkit-backdrop-filter: blur(30px) saturate(200%);
}

/* =========================================================================
   LE HALO QUI SUIT LE CURSEUR
   Deux variables mises a jour au pointeur ; tout le reste est du CSS.
   ========================================================================= */
.halo {
  position: fixed; z-index: 1; pointer-events: none;
  width: 460px; height: 460px; left: 0; top: 0;
  translate: calc(var(--sx, 50vw) - 230px) calc(var(--sy, 50vh) - 230px);
  background: radial-gradient(circle, rgba(242,145,60,.17), rgba(242,145,60,0) 62%);
  opacity: 0; transition: opacity .6s var(--doux);
}
body.pointe .halo { opacity: 1; }

/* =========================================================================
   LES BOUTONS
   Un balayage lumineux passe dessus au survol, et le bouton se decale
   legerement vers le pointeur (les variables viennent du JS).
   ========================================================================= */
.bouton {
  --tx: 0px; --ty: 0px;
  position: relative;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 28px;
  border-radius: 999px;
  font-size: .96rem; font-weight: 500; letter-spacing: -.01em;
  background: linear-gradient(140deg, var(--orange-vif), var(--orange) 60%, var(--orange-nuit));
  color: #fff;
  overflow: hidden;
  translate: var(--tx) var(--ty);
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset, 0 12px 28px -12px rgba(200,100,20,.75);
  transition: translate .35s var(--sortie), box-shadow .35s var(--doux), scale .35s var(--sortie);
  will-change: translate;
}
.bouton::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 32%, rgba(255,255,255,.55) 48%, transparent 64%);
  translate: -130% 0;
  transition: translate .75s var(--doux);
}
.bouton:hover { scale: 1.03; box-shadow: 0 1px 0 rgba(255,255,255,.5) inset, 0 20px 42px -14px rgba(200,100,20,.8); }
.bouton:hover::after { translate: 130% 0; }
.bouton:active { scale: .985; }

.bouton.clair {
  background: rgba(255,255,255,.62);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  color: var(--encre);
  box-shadow: 0 1px 0 rgba(255,255,255,.95) inset, 0 0 0 1px rgba(226,113,29,.16), 0 14px 30px -18px rgba(120,60,15,.5);
}
.bouton.clair:hover { background: rgba(255,255,255,.84); }

/* Le lien-fleche : le trait se remplit, la fleche avance. */
.suite {
  display: inline-flex; align-items: center; gap: 9px;
  font-weight: 500; font-size: .97rem; color: var(--orange);
  padding-bottom: 3px;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size .45s var(--sortie);
}
.suite svg { transition: translate .35s var(--sortie); }
.suite:hover { background-size: 100% 1px; }
.suite:hover svg { translate: 5px 0; }

/* =========================================================================
   LA BARRE DE NAVIGATION
   Une pastille de verre flottante. Elle se resserre au defilement, encore
   une animation liee au scroll, pas un ecouteur d'evenement.
   ========================================================================= */
.nav {
  position: fixed; z-index: 100;
  inset: 18px 0 auto 0;
  display: flex; justify-content: center;
  pointer-events: none;
}
.nav-boite {
  pointer-events: auto;
  display: flex; align-items: center; gap: clamp(8px, 2vw, 24px);
  width: min(100% - 32px, 1000px);
  padding: 11px 11px 11px 19px;
  border-radius: 999px;
  transform-origin: 50% 0;
}
@supports (animation-timeline: scroll()) {
  .nav-boite {
    animation: navSerre linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 260px;
  }
}
/* On resserre la barre par une MISE A L'ECHELLE, pas en animant sa
   largeur. Une largeur qui change a chaque image force un recalcul de
   mise en page, et Chrome cesse alors de repeindre le contenu de
   l'element floute : la pastille restait visible mais vide. `scale` se
   joue sur le compositeur, sans toucher a la mise en page. */
@keyframes navSerre {
  from { scale: 1; }
  to   { scale: .93; }
}

.nav-marque { display: flex; align-items: center; gap: 11px; margin-right: auto; }
.nav-marque img { width: 38px; height: auto; mix-blend-mode: multiply; transition: rotate .8s var(--sortie); }
.nav-marque:hover img { rotate: -8deg; }
.nav-marque .nom { font-weight: 600; font-size: 1.02rem; letter-spacing: -.02em; white-space: nowrap; }

.nav-liens { display: flex; align-items: center; gap: clamp(2px, 1.2vw, 6px); }
.nav-liens > a:not(.bouton) {
  position: relative;
  padding: 9px 14px; border-radius: 999px;
  font-size: .93rem; font-weight: 450; color: var(--encre-doux);
  transition: color .3s var(--doux), background .3s var(--doux);
  white-space: nowrap;
}
.nav-liens > a:not(.bouton):hover { color: var(--encre); background: rgba(255,255,255,.55); }
.nav-liens > a.ici { color: var(--encre); font-weight: 550; }
.nav-liens > a.ici::after {
  content: ''; position: absolute; left: 50%; bottom: 3px;
  width: 4px; height: 4px; margin-left: -2px; border-radius: 50%;
  background: var(--orange);
}
.nav .bouton { padding: 11px 20px; font-size: .9rem; }

/* --- LE MENU DU TELEPHONE ------------------------------------------------

   Il y avait ici une barre posee en bas de l'ecran. Elle etait juste, et
   invisible : a quatorze pixels du bord, elle passait DERRIERE la barre
   d'outils de Safari sur iPhone. Le site avait donc un menu que personne ne
   pouvait voir, ce qui revient a ne pas en avoir.

   On revient au bouton en haut a droite, la ou on le cherche, et il ouvre
   un panneau plein ecran. */
.burger {
  display: none;
  width: 42px; height: 42px; flex: none;
  border: 0; padding: 0 11px; background: none; cursor: pointer;
  border-radius: 999px;
  flex-direction: column; justify-content: center; gap: 5px;
}
.burger span {
  display: block; height: 2px; width: 20px; border-radius: 2px;
  background: var(--encre);
  transition: transform .4s var(--sortie), opacity .25s var(--doux);
}
body.menu-ouvert .burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.menu-ouvert .burger span:nth-child(2) { opacity: 0; }
body.menu-ouvert .burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.menu { position: fixed; inset: 0; z-index: 90; }
/* LE FOND DU MENU N'EST PLUS DU VERRE, ET C'ETAIT LE DEFAUT LE PLUS ANCIEN.
 *
 * Julie, le 27 aout : « quand on clique sur les 3 tirets pour voir les
 * sections, ca met du temps, ca bug, ca depuis le debut et c'est encore le
 * cas ». Elle a raison sur les deux points, y compris sur « depuis le debut ».
 *
 * CE QUE LE NAVIGATEUR DEVAIT FAIRE EN UN SEUL CLIC. Le menu est `hidden`
 * quand il est ferme, donc il n'existe pas. A l'ouverture il fallait, d'un
 * coup : fabriquer un plan de TOUT L'ECRAN, 329 000 pixels carres a 390 de
 * large, y appliquer un flou de 26 pixels en echantillonnant la page entiere
 * derriere, puis animer son opacite pendant 400 ms, ce qui REFAIT ce flou a
 * chaque image de la transition. Sur un telephone, ca se sent.
 *
 * ET CE FLOU NE SE VOYAIT PAS. Le degrade etait deja opaque a 86 et 90 pour
 * cent : derriere un panneau presque plein, il n'y a rien a flouter. On paie
 * un effet que personne ne peut percevoir.
 *
 * Le fond monte donc a 97 pour cent et le flou part. L'opacite seule se joue
 * sur le compositeur, sans repeindre. La duree passe de 400 a 260 ms : une
 * partie du « ca met du temps » etait le temps lui-meme, choisi quand
 * l'animation coutait cher et qu'il fallait masquer sa lenteur.
 *
 * CORRIGE ICI ET PAS EN FIN DE FEUILLE : ce n'est pas une surcharge, c'est la
 * regle d'origine qui change. Une correction posee ailleurs laisserait la
 * mauvaise valeur lisible juste au-dessus, et quelqu'un la relirait un jour en
 * croyant que c'est celle qui s'applique. */
.menu-fond {
  position: absolute; inset: 0;
  background: linear-gradient(160deg, rgba(255,249,241,.97), rgba(253,237,218,.98));
  opacity: 0; transition: opacity .18s var(--doux);
}
.menu-liens {
  position: relative; height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  gap: 4px; padding: 0 var(--marge);
}
.menu-liens a {
  font-size: clamp(1.9rem, 9vw, 2.6rem); font-weight: 500; letter-spacing: -.035em;
  padding: 10px 0;
  opacity: 0; translate: 0 14px;
  /* LE MENU S'OUVRAIT EN 670 ms, ET C'ETAIT LE DEFAUT QU'ELLE DECRIT.

     « Les 3 tirets, ça met du temps, on reclique et du coup ça referme les
     sections », 3 septembre. Les liens entraient l'un apres l'autre : 55 ms
     de decalage par lien, plus 450 ms d'animation, donc le dernier finissait
     220 + 450 ms apres l'appui. Assez long pour croire que rien ne s'est
     passe, appuyer une seconde fois, et refermer le menu soi-meme.

     Le defile n'est pas supprime, il est ramene a ce qu'un doigt tolere :
     le dernier lien est en place en 240 ms. */
  transition: opacity .2s var(--sortie), translate .2s var(--sortie);
  transition-delay: calc(var(--i) * 12ms);
}
.menu-liens a.ici { color: var(--orange); }
/* Le numero est la seule chose qu'on vient chercher en urgence dans ce
   menu. En 1,2 rem il se lisait comme une note de bas de page. */
/* L'etiquette « Numéro » a saute : Julie ne veut que le numero, ecrit avec
   des points. Le mot ne disait rien que le chiffre ne dise deja. */
.menu-liens .menu-tel {
  margin-top: 30px;
  font-size: clamp(1.55rem, 7.5vw, 2rem);
  font-weight: 500;
  letter-spacing: -.02em;
  color: #fff;
  align-self: flex-start;
  padding: 15px 26px;
  border-radius: 999px;
  background: linear-gradient(140deg, var(--orange-vif), var(--orange) 60%, var(--orange-nuit));
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset, 0 14px 30px -14px rgba(200,100,20,.8);
}
body.menu-ouvert { overflow: hidden; }
body.menu-ouvert .menu-fond { opacity: 1; }
body.menu-ouvert .menu-liens a { opacity: 1; translate: 0 0; }

@media (max-width: 900px) {
  .burger { display: flex; }
  .nav-boite { padding-right: 6px; }
  /* Le bouton de rendez-vous sort de la barre sur telephone : a quatre
     elements dans une pastille de 343 pixels, plus rien ne respire. Il
     reste present deux fois dans l'ecran d'accueil, et le numero est en
     gros dans le menu. */
  .nav .bouton { display: none; }
}

/* =========================================================================
   LES FONDS FILMES
   La video remplit le bloc, un voile tres leger la calme, et elle se
   deplace un peu moins vite que la page (parallaxe).
   ========================================================================= */
.film { position: absolute; inset: 0; overflow: hidden; z-index: 0; }
.film video, .film img.tenant {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center 58%;
  filter: saturate(1.16) contrast(1.03);
}
/* L'image tient la place SOUS la video : posee dessous, elle evite le
   rectangle creme qui apparaissait le temps que la video se decide. Sur
   telephone, la video est retiree du document et c'est elle qui reste
   visible, sans qu'aucune regle n'ait a la montrer. */
.film img.tenant { z-index: 0; }
.film video { z-index: 1; }

/* LE BOUTON « LIRE » QUE JULIE A VU AU MILIEU DU FOND.

   « Pourquoi y a-t-il un logo play dans le fond sans animation ? Erreur ? »
   Oui, et le defaut est reel. Ces videos sont decoratives : pas de `controls`,
   pas de son, elles se lancent seules. Mais quand iOS REFUSE la lecture
   automatique, en mode economie d'energie ou en economiseur de donnees, Safari
   dessine SON PROPRE gros bouton de lecture par-dessus l'affiche. Il n'est
   dans aucun de nos fichiers, c'est le navigateur qui l'ajoute, et il ne mene
   nulle part puisqu'il n'y a rien a regarder.

   On le retire. Ce qui reste est l'affiche, c'est-a-dire une image tiree de la
   video elle-meme : la page perd son mouvement, elle ne perd ni son decor ni
   son sens. C'est exactement la degradation qu'on veut. */
.film video::-webkit-media-controls,
.film video::-webkit-media-controls-panel,
.film video::-webkit-media-controls-start-playback-button,
.film video::-webkit-media-controls-play-button {
  display: none !important;
  -webkit-appearance: none;
  appearance: none;
  opacity: 0;
}

@supports (animation-timeline: view()) {
  .film video {
    animation: derive linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
}
@keyframes derive { from { scale: 1.14; translate: 0 -4%; } to { scale: 1.14; translate: 0 4%; } }

/* Le voile : assez pour poser le texte, jamais assez pour cacher le film.
   (Une version precedente montait a 88 % d'opacite : la video tournait
   sous un aplat creme, on ne la voyait pas du tout.) */
.voile {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 92% at 50% 40%, rgba(255,252,246,.30), rgba(255,248,239,.02) 60%),
    linear-gradient(180deg, rgba(255,248,239,.34) 0%, rgba(255,248,239,0) 24%,
                    rgba(255,248,239,0) 60%, rgba(253,242,228,.88) 93%, var(--creme-fond) 100%);
}

/* LE VOILE DE L'ECRAN D'ACCUEIL PORTE LA LISIBILITE DEPUIS LE 25 AOUT.
   Le panneau de verre est parti, choix de Julie apres comparaison. Ce n'etait
   pas qu'un decor : son fond clair etait CE QUI RENDAIT LE TITRE LISIBLE sur
   une video de fumee orange. Le voile prend le relais avec une nappe centrale
   plus soutenue, resserree la ou le texte se trouve et effacee vers les bords
   pour que la fumee vive.
   UNIQUEMENT SUR L'ENTREE : les autres bandeaux filmes gardent le leur, ils
   n'ont pas de texte a porter au milieu de l'image. */
.entree .voile {
  background:
    radial-gradient(70% 52% at 50% 46%, rgba(255,250,242,.80), rgba(255,250,242,.34) 55%,
                    rgba(255,248,239,.04) 78%),
    linear-gradient(180deg, rgba(255,248,239,.40) 0%, rgba(255,248,239,0) 26%,
                    rgba(255,248,239,0) 58%, rgba(253,242,228,.90) 93%,
                    var(--creme-fond) 100%);
}
.voile.court {
  background: linear-gradient(180deg, rgba(255,248,239,.42) 0%, rgba(255,248,239,.05) 40%,
                              rgba(253,242,228,.9) 92%, var(--creme-fond) 100%);
}

/* =========================================================================
   L'ACCUEIL
   ========================================================================= */
.entree {
  position: relative;
  min-height: 100svh;
  display: grid; place-items: center;
  padding: 130px 0 100px;
  overflow: clip;
}
.entree .serre { z-index: 2; text-align: center; }

/* Le bloc entier recule et s'efface quand on descend : le geste signature
   des pages produit d'Apple. Il se declenche a la sortie, pas a l'entree. */
@supports (animation-timeline: view()) {
  .entree-bloc {
    animation: reculer linear both;
    animation-timeline: view();
    /* `exit 0%` commence des le premier pixel de defilement : le titre se
       brouillait avant meme qu'on ait vraiment commence a descendre. On
       laisse passer le premier tiers d'ecran net, et l'effacement se joue
       sur le reste. */
    animation-range: exit 34% exit 100%;
  }
}
/* Meme raison que pour `.rev` : le bloc d'accueil contient le panneau de
   verre et les trois reperes. Un flou sur lui ferait de lui une racine
   d'arriere-plan et viderait ces panneaux pendant tout le mouvement. Il
   recule et s'efface, il ne se brouille plus. */
@keyframes reculer {
  from { opacity: 1; scale: 1;   translate: 0 0; }
  to   { opacity: 0; scale: .90; translate: 0 -5vh; }
}

/* Le titre apparait mot par mot, chacun venant de plus bas et de plus
   flou que le precedent. */
.titre-anime .mot { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .08em; }
.titre-anime .mot > i {
  display: inline-block; font-style: inherit;
  animation: monterMot 1.2s var(--sortie) both;
  animation-delay: calc(var(--i) * 95ms);
}
@keyframes monterMot {
  from { translate: 0 108%; opacity: 0; filter: blur(10px); rotate: 2deg; }
  to   { translate: 0 0;    opacity: 1; filter: blur(0);    rotate: 0deg; }
}

.entree h1 { margin-bottom: 4px; }
.baseline {
  display: block;
  font-size: clamp(1.02rem, 2.3vw, 1.6rem);
  letter-spacing: -.02em;
  color: var(--encre-doux);
  margin-top: 16px;
  font-weight: 400;
  animation: paraitre 1.1s var(--sortie) .6s both;
}
.entree .chapeau { margin: 20px auto 0; text-align: center; animation: paraitre 1.1s var(--sortie) .75s both; }
/* `paraitre` s'applique entre autres aux trois reperes, qui sont en verre
   sur ordinateur. Pas de flou la non plus, pour la meme raison. */
@keyframes paraitre { from { opacity: 0; translate: 0 22px; } to { opacity: 1; translate: 0 0; } }

.actions {
  display: flex; flex-wrap: wrap; gap: 13px; justify-content: center;
  margin-top: 32px;
  animation: paraitre 1.1s var(--sortie) .9s both;
}
/* Il ne reste du panneau que sa largeur et son centrage. Le rembourrage
   LATERAL dessinait le bord de la carte ; sans carte, il ne fait que retrecir
   le titre. Le vertical reste : il tient le texte loin de la barre de
   navigation en haut et du ruban en bas. */
.entree-panneau {
  padding-block: clamp(26px, 3.4vw, 44px);
  width: min(100%, 820px); margin-inline: auto;
}

/* La fleche « on continue en bas » */
.descendre {
  position: absolute; left: 50%; bottom: 26px; z-index: 3;
  translate: -50% 0;
  display: grid; place-items: center; gap: 9px;
  font-size: .7rem; letter-spacing: .2em; text-transform: uppercase; color: var(--encre-pale);
  animation: paraitre 1s var(--sortie) 1.5s both;
}
.descendre i {
  display: block; width: 1px; height: 40px;
  background: linear-gradient(var(--orange), transparent);
  animation: filer 2.2s ease-in-out infinite;
  transform-origin: top;
}
@keyframes filer {
  0%   { scale: 1 0; opacity: 0; }
  35%  { scale: 1 1; opacity: 1; }
  100% { scale: 1 1; opacity: 0; transform-origin: bottom; }
}

/* =========================================================================
   LE BANDEAU DEFILANT

   Julie voulait pouvoir le pousser du doigt en plus de le laisser tourner.
   Une animation CSS ne se pousse pas : on ne peut pas prendre une animation
   en main. Le bandeau devient donc un VRAI conteneur de defilement
   horizontal, ce qui donne le glissement au doigt et son inertie sans une
   ligne de code, et c'est le JavaScript qui avance le defilement de quelques
   dixiemes de pixel par image quand personne n'y touche.

   La barre de defilement est cachee : on la sent, on ne la voit pas.
   ========================================================================= */
.bandeau {
  position: relative; z-index: 3;
  padding: 20px 0;
  border-block: 1px solid rgba(226,113,29,.16);
  background: linear-gradient(90deg, rgba(255,248,239,.6), rgba(255,236,214,.8), rgba(255,248,239,.6));
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  /* Sans ca, un glissement horizontal arrive en bout de course declenche le
     geste « page precedente » du navigateur. */
  overscroll-behavior-x: contain;
  cursor: grab;
  -webkit-mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.bandeau::-webkit-scrollbar { display: none; }
.bandeau.tenu { cursor: grabbing; }
.bandeau:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.ruban { display: flex; width: max-content; user-select: none; }
.ruban b {
  display: flex; align-items: center; gap: 28px;
  padding-right: 28px;
  font-size: clamp(.94rem, 1.4vw, 1.1rem); font-weight: 450; color: var(--encre-doux);
  white-space: nowrap;
}
.ruban b::after { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--orange); opacity: .55; flex: none; }

/* =========================================================================
   LES SECTIONS
   ========================================================================= */
.pan { position: relative; padding: clamp(78px, 10vw, 145px) 0; }
.pan.serree { padding-block: clamp(54px, 7vw, 88px); }

/* DEUX MARGES DE SECTION S'ADDITIONNENT, ET CA SE VOIT.

   Entre la phrase en gros (« Un lieu où l'on prend le temps. ») et le titre
   suivant, il y avait deux cent quatre-vingt-quatorze pixels de rien : la marge
   basse de la phrase PLUS la marge haute de la section d'après. Chacune est
   raisonnable seule ; mises bout à bout elles font un trou.

   La phrase en gros a déjà tout l'air qu'il lui faut autour d'elle. Ce qui la
   suit n'a donc pas besoin de rouvrir la même distance : on la ramène à un
   tiers. Le mot `.pan` reste intact pour tous les autres enchaînements, c'est
   la SUITE d'une phrase-éclat qu'on resserre, pas les sections en général.

   ET IL FAUT LE FAIRE DES DEUX COTES, sinon on ne repare qu'a moitie. Apres
   la premiere correction, la phrase avait 280 pixels au-dessus d'elle et 88 en
   dessous : elle ne flottait plus, elle etait collee a ce qui suit. Une phrase
   qu'on isole doit l'etre symetriquement, sans quoi elle appartient au bloc
   d'apres. On vise a peu pres autant d'air des deux cotes. */
.pan:has(+ .eclat-zone) { padding-bottom: clamp(34px, 4.2vw, 62px); }
.pan + .eclat-zone { padding-top: clamp(34px, 4.2vw, 62px); }
.eclat-zone + .pan { padding-top: clamp(26px, 3.2vw, 52px); }

/* Les taches d'orange qui respirent au fond de la page. Elles bougent
   lentement et en decalage, donc le fond n'est jamais deux fois le meme.

   Elles debordent volontairement de la section, de dix pour cent de chaque
   cote. Sans le `clip` ci-dessous, ce debordement ouvrait un defilement
   horizontal de cinquante pixels sur toute la page. On le coupe ICI, sur la
   section, et surtout pas sur la racine : `overflow` sur la racine se
   propage a la fenetre, la fenetre cesse d'etre un conteneur de defilement
   valide, et toutes les animations liees au defilement meurent avec elle.
   `clip` plutot que `hidden` : il coupe sans creer de conteneur de
   defilement, donc les blocs colles et les minuteries continuent de
   fonctionner. */
.pan.tache { overflow-x: clip; }
.pan.tache::before,
.pan.tache::after {
  content: ''; position: absolute; z-index: 0; border-radius: 50%;
  filter: blur(70px); pointer-events: none;
}
.pan.tache::before {
  width: 46vw; height: 46vw; max-width: 620px; max-height: 620px;
  top: -8%; right: -10%;
  background: radial-gradient(circle, rgba(242,145,60,.36), rgba(242,145,60,0) 70%);
  animation: respirer 17s ease-in-out infinite;
}
.pan.tache::after {
  width: 38vw; height: 38vw; max-width: 520px; max-height: 520px;
  bottom: -12%; left: -12%;
  background: radial-gradient(circle, rgba(251,217,180,.6), rgba(251,217,180,0) 70%);
  animation: respirer 21s ease-in-out -6s infinite reverse;
}
@keyframes respirer {
  0%, 100% { translate: 0 0 ; scale: 1; }
  50%      { translate: -5% 7%; scale: 1.16; }
}

.deux {
  display: grid; gap: clamp(30px, 5vw, 70px);
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  align-items: start;
}
/* Un bloc colle ne peut pas porter lui-meme une animation liee a `view()` :
   sa position dans la fenetre ne bouge plus une fois qu'il est accroche,
   donc la progression reste bloquee et l'element ne s'affiche jamais. On
   colle le conteneur, on anime l'enfant. */
.colle { position: sticky; top: 122px; }
.centre { text-align: center; display: grid; justify-items: center; gap: 18px; }

/* --- l'apparition au defilement ----------------------------------------- */
.rev { opacity: 0; translate: 0 44px; }

/* PLUS AUCUN `filter` DANS LES APPARITIONS.

   Le flou d'entree etait joli et il coutait bien trop cher. `filter` fait de
   l'element une « racine d'arriere-plan » : tout `backdrop-filter` situe en
   dessous cesse d'echantillonner la page et se met a echantillonner le
   contenu de cette racine, qu'il repeint par-dessus le texte. Autrement dit,
   n'importe quel panneau de verre place a l'INTERIEUR d'un bloc qui apparait
   devenait un rectangle blanc.

   J'avais d'abord traite le seul cas du verre qui porte lui-meme `.rev`. Ca
   ne suffisait pas : la carte « Formation » est un panneau de verre a
   l'interieur d'un `.rev`, et c'est le filtre du PARENT qui la vidait. Elle
   restait blanche jusqu'a ce qu'on la touche, parce que le contact forcait un
   repeint.

   Les apparitions se font maintenant en opacite et en deplacement. Ni l'une
   ni l'autre ne laisse de racine d'arriere-plan derriere elle une fois
   l'animation finie. */

.rev.vu { opacity: 1; translate: 0 0;
          transition: opacity .9s var(--sortie), translate .9s var(--sortie);
          transition-delay: calc(var(--i, 0) * 90ms); }

@supports (animation-timeline: view()) {
  .rev {
    animation: surgir linear both;
    animation-timeline: view();
    animation-range: entry 4% cover 27%;
    transition: none;
  }
  /* Les elements d'une meme rangee doivent se decaler : on retarde leur
     plage de defilement, puisqu'un delai n'a pas de sens sur une
     minuterie qui est en fait une position. */
  .rev[data-i='1'] { animation-range: entry 4% cover 34%; }
  .rev[data-i='2'] { animation-range: entry 4% cover 41%; }
  .rev[data-i='3'] { animation-range: entry 4% cover 48%; }
}
@keyframes surgir {
  from { opacity: 0; translate: 0 52px; }
  to   { opacity: 1; translate: 0 0; }
}

/* =========================================================================
   LA PHRASE QUI S'ALLUME
   Chaque mot s'eclaire a son tour a mesure qu'on descend. La minuterie,
   c'est la position de la phrase dans la fenetre.
   ========================================================================= */
.eclat-zone { view-timeline-name: --phrase; view-timeline-axis: block; }
.eclat {
  --n: 30;                       /* nombre de mots, pose par le generateur */
  font-size: clamp(1.6rem, 4.4vw, 3.3rem);
  font-weight: 500; letter-spacing: -.035em; line-height: 1.25;
  text-wrap: balance;
}
.eclat w { color: rgba(169,141,120,.34); }
@supports (animation-timeline: view()) {
  .eclat w {
    animation: allumer linear both;
    animation-timeline: --phrase;
    /* `cover` et pas `contain` : une phrase plus haute que la fenetre n'est
       jamais « contenue », la plage serait vide et rien ne s'allumerait.

       La fin de chaque mot est calculee A PARTIR DU NOMBRE DE MOTS, pour
       que le dernier s'allume vers 55 % de la course, c'est a dire quand la
       phrase est encore au milieu de l'ecran. Avec un pas fixe, une phrase
       longue finissait de s'allumer une fois deja sortie par le haut : on
       ne voyait jamais la fin de l'animation. */
    animation-range:
      cover calc(14% + var(--i) * (30% / var(--n)))
      cover calc(27% + var(--i) * (30% / var(--n)));
  }

  /* LA DERNIERE PHRASE D'UNE PAGE.

     `cover` va de l'instant ou le bloc entre par le bas a celui ou il sort par
     le haut. Un bloc pose en fin de page ne sort jamais : le document s'arrete
     avant, la course plafonne aux alentours de la moitie, et les mots calcules
     au-dela ne s'allument jamais. Sur la page Contact, la fin de la phrase
     restait donc dans son gris de depart, ce qui se lit comme du texte
     transparent.

     `entry` s'acheve des que le bloc est entierement visible. Une derniere
     section l'atteint toujours, quelle que soit la hauteur du pied de page. */
  .eclat-zone.fin .eclat w {
    animation-range:
      entry calc(26% + var(--i) * (46% / var(--n)))
      entry calc(44% + var(--i) * (46% / var(--n)));
  }
}
@keyframes allumer {
  from { color: rgba(169,141,120,.30); }
  to   { color: var(--encre); }
}
.eclat w.chaud {
  font-family: 'Instrument Serif', Georgia, serif; font-style: italic;
  animation-name: allumerChaud;
}
@keyframes allumerChaud {
  from { color: rgba(226,113,29,.28); }
  to   { color: var(--orange); }
}

/* =========================================================================
   LE FILM QUI S'OUVRE
   Une carte arrondie qui s'elargit jusqu'au bord de l'ecran et perd ses
   coins a mesure qu'on descend. Le bloc est colle, donc le film reste en
   place pendant que le mouvement se joue.
   ========================================================================= */
.ouverture { position: relative; height: 200vh; }
.ouverture-cadre {
  position: sticky; top: 0;
  height: 100svh;
  display: grid; place-items: center;
  overflow: clip;
}
.ouverture-film {
  position: relative;
  width: min(92%, 1180px); height: min(72svh, 640px);
  border-radius: var(--rond-l);
  overflow: hidden;
  box-shadow: 0 40px 90px -40px rgba(120,60,15,.5);
}
@supports (animation-timeline: view()) {
  .ouverture-film {
    animation: ouvrir linear both;
    animation-timeline: view();
    animation-range: entry 62% cover 60%;
  }
}
@keyframes ouvrir {
  from { width: min(92%, 1180px); height: min(72svh, 640px); border-radius: var(--rond-l); }
  to   { width: 100vw;            height: 100svh;            border-radius: 0; }
}
.ouverture-film video { width: 100%; height: 100%; object-fit: cover; }
/* LA LEGENDE DU FILM.
   Elle etait en blanc sur un degrade sombre. Sur une image aussi claire que
   ce galet dans l'eau, le blanc se posait sur du beige et devenait penible a
   lire, en plus de jurer avec le reste du site ou tout le texte est encre
   sur verre. Elle est donc sur verre elle aussi, comme partout ailleurs. */
.ouverture-texte {
  position: absolute; z-index: 2;
  inset: auto clamp(14px, 3vw, 34px) clamp(14px, 3vw, 34px) clamp(14px, 3vw, 34px);
  width: fit-content; max-width: min(100% - clamp(28px, 6vw, 68px), 34rem);
  padding: clamp(18px, 2.6vw, 28px) clamp(20px, 3vw, 34px);
  border-radius: var(--rond);
  display: grid; gap: 11px; justify-items: start;
  background: linear-gradient(150deg, rgba(255,252,246,.80), rgba(255,244,230,.66));
  backdrop-filter: blur(26px) saturate(180%);
  -webkit-backdrop-filter: blur(26px) saturate(180%);
  box-shadow: 0 1px 0 rgba(255,255,255,.9) inset, 0 26px 54px -30px rgba(120,60,15,.5);
  color: var(--encre);
}
/* Vingt caracteres et non seize : la phrase de « Mon approche » est plus
   longue que l'ancienne legende du cabinet, et a seize elle tombait sur cinq
   lignes de tres gros corps. */
.ouverture-texte h2 { color: var(--encre); max-width: 20ch; font-size: clamp(1.5rem, 3.4vw, 2.6rem); }
.ouverture-texte p { color: var(--encre-doux); max-width: 46ch; }
.ouverture-texte .sur-titre { color: var(--orange); }

/* =========================================================================
   LES CARTES
   ========================================================================= */
/* CINQ CARTES NE SE RANGENT PAS EN QUATRE COLONNES.
   `auto-fit` en donnait quatre sur grand ecran, donc quatre en haut et UNE
   toute seule en bas, collee a gauche : ca se lit comme un oubli. En bornant
   a trois colonnes, cinq font trois puis deux, et les deux du bas se centrent
   sous les trois du haut. Une ligne incomplete centree est une composition ;
   une ligne incomplete alignee a gauche est un trou. */
.grille {
  display: grid; gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(266px, 1fr));
  margin-top: clamp(38px, 5vw, 60px);
  justify-content: center;
}
/* SIX COLONNES, ET CHAQUE CARTE EN OCCUPE DEUX.

   Premiere tentative : trois colonnes, et la derniere ligne centree avec une
   marge de 50 %. Ca centrait, mais une marge RETRECIT la carte : les deux du
   bas devenaient deux fois plus etroites que celles du haut, et le texte y
   tombait a trois mots par ligne.

   Une grille de six colonnes ou chaque carte en couvre deux donne exactement
   trois cartes par ligne, ET permet de decaler la derniere ligne d'UNE
   colonne, soit une demi-carte. La ligne se centre sans qu'aucune carte ne
   change de largeur. */
@media (min-width: 1060px) {
  .grille { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .grille > * { grid-column: span 2; }
  /* Avant-derniere carte en tete d'une ligne incomplete de deux : on decale. */
  .grille > :nth-last-child(2):nth-child(3n + 1) { grid-column: 2 / span 2; }
  /* Carte seule sur sa ligne : on la met au milieu. */
  .grille > :nth-last-child(1):nth-child(3n + 1) { grid-column: 3 / span 2; }
}

.carte {
  --rx: 0deg; --ry: 0deg;
  padding: 30px 28px 32px;
  display: grid; gap: 12px; align-content: start;
  transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform .5s var(--sortie), box-shadow .5s var(--doux);
  will-change: transform;
}
.carte:hover {
  box-shadow:
    0 1px 0 rgba(255,255,255,.95) inset,
    0 42px 80px -34px rgba(120,60,15,.5);
}
/* LES VIGNETTES DEVIENNENT LES BULLES DE L'ACCUEIL.

   « Possible les mêmes cadres/bulles que les 3 photos de la section bienvenue
   à la place des cadres déjà existants ? » Oui, et ça règle un autre de ses
   reproches par la même occasion.

   ELLE DEMANDAIT DE « RECENTRER » DEUX IMAGES, ET LA CAUSE N'ETAIT PAS LE
   CADRAGE : la vignette etait en `object-fit: cover` dans un carre de
   soixante-deux pixels. Un dessin plus haut que large y perdait sa tete et ses
   pieds, quel que soit le recadrage du fichier. On passe en `contain` : le
   dessin se pose au lieu de se faire tailler, et les cinq se voient en entier
   sans avoir a retoucher une seule image.

   La forme organique est celle des galets de l'accueil, et chaque carte a la
   sienne : trois bulles identiques a la suite redeviennent des carrés. */
.carte .vignette {
  width: 78px; height: 78px;
  border-radius: 58% 42% 46% 54% / 48% 56% 44% 52%;
  display: grid; place-items: center; overflow: hidden;
  background: linear-gradient(140deg, var(--orange-clair), rgba(255,255,255,.6));
  outline: 1.5px solid rgba(226,113,29,.42); outline-offset: 4px;
  box-shadow: 0 1px 0 rgba(255,255,255,.9) inset;
  margin-bottom: 10px;
  transition: outline-color .4s var(--doux);
}
.carte:nth-of-type(2n) .vignette { border-radius: 47% 53% 55% 45% / 52% 46% 54% 48%; }
.carte:nth-of-type(3n) .vignette { border-radius: 52% 48% 57% 43% / 44% 53% 47% 56%; }
.carte:hover .vignette { outline-color: var(--orange); }
/* SES DESSINS SONT AU TRAIT GRIS CLAIR, et poses tels quels dans une bulle
   creme ils disparaissaient : on distinguait une tache, pas un nuage ni une
   silhouette. `multiply` n'y pouvait rien, un gris clair multiplie par un
   creme reste un gris clair. On les FONCE, ce qui epaissit le trait a l'oeil
   sans y toucher, et on les tire vers l'encre du site plutot que vers le noir
   pur : c'est un dessin a elle, pas un pictogramme d'interface. */
.carte .vignette img {
  width: 100%; height: 100%; object-fit: contain; padding: 13%;
  filter: brightness(.42) sepia(.35) saturate(1.4) hue-rotate(-12deg);
  transition: scale .6s var(--sortie);
}
.carte:hover .vignette img { scale: 1.1; }
.carte p { color: var(--encre-doux); font-size: .99rem; line-height: 1.62; }

/* Les tarifs */
.tarifs { display: grid; gap: 14px; margin-top: clamp(34px, 4.5vw, 52px); }
.tarif {
  display: grid; grid-template-columns: 1fr auto; gap: 26px; align-items: center;
  padding: 24px 30px;
  transition: translate .45s var(--sortie), box-shadow .45s var(--doux);
}
.tarif:hover { translate: 0 -4px; box-shadow: 0 1px 0 rgba(255,255,255,.95) inset, 0 38px 70px -34px rgba(120,60,15,.48); }
.tarif-nom { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; }

/* Le nom d'une seance se lit en deux temps. « Seance » est commun aux quatre
   et ne distingue rien : on l'allege. Ce qui suit prend l'italique serif et
   l'orange deja reserves aux mots mis en avant dans les grands titres, ce qui
   evite d'inventer un style de plus pour un seul endroit. */
.tarif-nom h3 { font-weight: 420; color: var(--encre-doux); }
.tarif-nom h3 em { font-size: 1.12em; color: var(--orange); }
.tarif-duree {
  font-size: .75rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--orange); padding: 4px 11px; border-radius: 999px;
  background: rgba(226,113,29,.10); white-space: nowrap;
}
.tarif p { color: var(--encre-doux); font-size: .96rem; margin-top: 7px; max-width: 58ch; }
.tarif-prix {
  font-size: clamp(1.9rem, 3.4vw, 2.6rem); font-weight: 500; letter-spacing: -.045em;
  color: var(--encre); white-space: nowrap;
}
.tarif-prix span { font-size: .48em; color: var(--orange); margin-left: 2px; }
.note { font-size: .88rem; color: var(--encre-pale); margin-top: 20px; }
.note a { color: var(--orange); }

/* LE DEROULE, SANS LES NUMEROS.
   « Retirer 01, 02, 03, 04 et garder la même présentation. » Un numero devant
   « L'accueil » et « L'échange » promet une procedure a suivre, alors qu'elle
   decrit un moment qui se deroule. Le filet reste, il suffit a separer.
   Un petit point orange prend la place, pour que la colonne de gauche ne
   devienne pas un blanc sans raison. */
.etapes { display: grid; margin-top: 6px; }
.etape {
  display: grid; grid-template-columns: 22px 1fr; gap: 18px; align-items: start;
  padding: 24px 4px;
  border-top: 1px solid rgba(226,113,29,.16);
}
.etape::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%;
  background: var(--orange); opacity: .55; margin-top: .62em;
}
.etape h3 { margin-bottom: 7px; }
.etape p { color: var(--encre-doux); font-size: 1rem; }

/* =========================================================================
   L'APPEL
   ========================================================================= */
.appel { position: relative; overflow: clip; padding: clamp(76px, 10vw, 128px) 0; }
.appel-carte {
  z-index: 2;
  padding: clamp(38px, 6vw, 74px);
  text-align: center;
  display: grid; gap: 17px; justify-items: center;
  border-radius: var(--rond-l);
}
.appel-carte h2 { max-width: 15ch; }
.appel-carte p { color: var(--encre-doux); max-width: 48ch; }
.appel-carte .actions { margin-top: 10px; animation: none; }

/* =========================================================================
   LE CONTACT
   ========================================================================= */
.contact-grille { display: grid; gap: 22px; grid-template-columns: 1.22fr .95fr; align-items: start; }
.coord-ligne {
  display: grid; grid-template-columns: 148px 1fr; gap: 20px; align-items: baseline;
  padding: 20px 30px;
  border-bottom: 1px solid rgba(226,113,29,.14);
}
.coord-ligne:last-child { border-bottom: 0; }
.coord .etiq { font-size: .75rem; letter-spacing: .16em; text-transform: uppercase; color: var(--orange); }
.coord .val { font-size: 1.05rem; font-weight: 450; }
.coord .val small { display: block; font-size: .88rem; color: var(--encre-pale); font-weight: 400; margin-top: 3px; }
.coord .val a { border-bottom: 1px solid rgba(226,113,29,.35); transition: border-color .3s; }
.coord .val a:hover { border-color: var(--orange); }

/* Les reseaux : le logo porte la reconnaissance, le nom porte la certitude.
   L'un sans l'autre laisse un doute, alors on garde les deux, dans une pastille
   assez large pour qu'un pouce l'atteigne sans viser. */
.coord .val.reseaux { display: flex; flex-wrap: wrap; gap: 10px; }
.reseau {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 15px 8px 12px; border-radius: 999px;
  font-size: .95rem; font-weight: 450; line-height: 1;
  color: var(--encre);
  border: 1px solid rgba(226,113,29,.28);
  background: rgba(255,255,255,.5);
  transition: border-color .3s, background .3s, transform .3s;
}
.reseau svg { flex: none; color: var(--orange); }
.reseau:hover { border-color: var(--orange); background: rgba(226,113,29,.09); transform: translateY(-1px); }

/* =========================================================================
   L'ENTETE DES PAGES INTERIEURES
   ========================================================================= */
.entete {
  position: relative;
  padding: clamp(146px, 19vh, 210px) 0 clamp(58px, 8vw, 96px);
  overflow: clip;
}
.entete .serre { z-index: 2; display: grid; gap: 18px; }
.entete h1 { font-size: clamp(2.6rem, 7vw, 5.2rem); }

/* =========================================================================
   LE PIED
   ========================================================================= */
/* « Mieux séparer le bas de page pour comprendre que c'est la fin : ligne
   épaisse, léger fond de couleur… », 25 aout.

   Elle a raison, et le defaut etait mesurable : le pied avait un filet d'UN
   pixel a 16 pour cent d'opacite, et son fond partait de `--creme-fond`,
   c'est-a-dire EXACTEMENT la couleur de la section juste au-dessus. La
   separation existait dans le code et pas a l'oeil.

   Trois choses, et il faut les trois. Le filet passe a 3 pixels en orange
   franc, le fond demarre plus soutenu que la page au lieu de la prolonger, et
   une lueur interieure blanche marque l'arete. UN SEUL DE CES TROIS CHANGEMENTS
   NE SUFFIT PAS : un trait epais sur un fond identique se lit comme une
   decoration, un fond different sans trait se lit comme une autre section. */
.pied {
  position: relative;
  padding: clamp(52px, 6vw, 78px) 0 34px;
  background: linear-gradient(180deg, #fbeada, #f6e0c8);
  border-top: 3px solid rgba(226,113,29,.5);
  box-shadow: 0 1px 0 rgba(255,255,255,.75) inset;
}
.pied .serre + .serre { margin-top: 34px; }

/* Quatre colonnes : la marque, les coordonnees, le plan du site, les reseaux.
   C'est la structure du bas de page de la presidente de la Federation, que
   Julie a donnee en exemple. */
/* DEUX COLONNES, PAS QUATRE. Julie a fait retirer « Me contacter » et « Le
   site » : les deux ne faisaient que repeter la barre du haut et la
   navigation. Restent la marque et l'invitation a la suivre, et le pied
   respire enfin. */
.pied-grille {
  display: grid; gap: clamp(28px, 5vw, 64px);
  grid-template-columns: 1.35fr 1fr;
  align-items: start;
}
.pied-marque { display: grid; gap: 14px; justify-items: start; }
.pied-marque .nav-marque { margin-right: 0; }
.pied-marque p { font-size: .95rem; color: var(--encre-doux); line-height: 1.6; }

.pied-note {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: .88rem; color: var(--encre-doux);
  padding: 8px 14px; border-radius: 999px;
  background: rgba(255,255,255,.5);
  border: 1px solid rgba(226,113,29,.2);
  transition: border-color .3s, background .3s;
}
.pied-note:hover { border-color: var(--orange); background: rgba(255,255,255,.8); }
.pied-note b { color: var(--encre); font-weight: 600; }
.etoiles { display: inline-flex; gap: 1px; color: var(--orange); line-height: 0; }

.pied-bloc { display: grid; gap: 9px; justify-items: start; align-content: start; }
.pied-bloc h2 {
  font-size: .76rem; font-weight: 500; letter-spacing: .2em; text-transform: uppercase;
  color: var(--orange); margin-bottom: 4px;
}
.pied-bloc a, .pied-bloc span {
  font-size: .95rem; color: var(--encre-doux);
  display: inline-flex; align-items: center; gap: 7px;
}
.pied-bloc a { position: relative; padding-bottom: 2px; }
.pied-bloc a::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 1px; background: var(--orange);
  scale: 0 1; transform-origin: left; transition: scale .4s var(--sortie);
}
.pied-bloc a:hover { color: var(--encre); }
.pied-bloc a:hover::after { scale: 1 1; }
.pied-suivre p { font-size: .92rem; color: var(--encre-doux); line-height: 1.6; max-width: 34ch; }
.pied-reseaux { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 6px; }
/* Les pastilles de reseau n'ont pas de soulignement qui court dessous. */
.pied-reseaux a::after { display: none; }

/* TROIS LOGOS SUR UNE LIGNE, SANS UN MOT.
   « Insta / Facebook possible juste le logo ? » Oui : ces marques se
   reconnaissent a leur forme, et le nom ecrit a cote ne dit rien de plus. Il
   reste dans `aria-label` et dans l'infobulle, donc un lecteur d'ecran et une
   souris hesitante le trouvent tous les deux. La cible fait 44 pixels, la
   taille minimale d'une cible au pouce : un logo de dix-neuf pixels dans une
   pastille de quarante-quatre se rate beaucoup moins qu'un logo nu. */
/* DEUX CHOSES QUE LA MESURE A SORTIES, ET QU'ON NE VOIT PAS EN RELISANT.

   UN, LES GLYPHES ETAIENT A ONZE PIXELS DU CENTRE, tous les trois, vers la
   gauche. `place-items: center` centre l'element DANS SA PISTE ; mais sans
   colonne declaree, la piste se dimensionne au contenu, dix-neuf pixels, et
   elle se pose au DEBUT de la boite de quarante-quatre. On centrait donc
   parfaitement un glyphe dans une piste elle-meme collee a gauche.
   `place-content: center` centre la piste ; c'est elle qu'il fallait bouger.

   DEUX, LA COULEUR DECLAREE ICI NE SERVAIT A RIEN. `.pied-bloc a` impose
   `--encre-doux` plus bas dans le fichier, a specificite egale, donc c'est lui
   qui gagnait : les icones sortaient brunes au lieu d'orange, comme le reste
   des accents du site. Meme piege que pour l'alignement du nom sous la photo,
   et meme remede, on monte d'un cran. */
.pied-reseaux .reseau-icone {
  display: inline-grid;
  place-items: center;
  place-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  color: var(--orange);
  background: rgba(255,255,255,.55);
  border: 1px solid rgba(226,113,29,.22);
  transition: border-color .3s var(--doux), background .3s var(--doux),
              translate .3s var(--sortie);
}
.reseau-icone:hover {
  border-color: var(--orange); background: #fff; translate: 0 -2px;
}
/* UN SVG EN LIGNE SE POSE SUR LA LIGNE DE BASE, pas au milieu de sa boite :
   meme centre par la grille, il gardait le creux reserve aux jambages sous
   lui et paraissait remonte de deux pixels. `display:block` supprime ce
   creux. C'est ce decalage que Matheo a vu. */
.reseau-icone svg, .reseau-icone img { display: block; }
/* Le pictogramme de Resalib est en trait fin et dans un bleu pale, la ou les
   deux autres sont des contours nets en orange : a taille egale il paraissait
   plus petit et plus faible. On le monte de deux pixels pour que les trois
   pesent pareil. */
.reseau-resalib img { width: 24px; height: auto; object-fit: contain; }

/* Le logo de la Federation, contre la ligne d'identite qu'il accompagne. */
.pied-logos { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; }
.pied-logos img {
  height: 52px; width: auto;
  /* Un gris complet les effacait : sur un fond creme, un logo desature a
     moitie transparent ne se lit plus du tout. On les calme sans les
     eteindre, et ils reprennent toutes leurs couleurs au survol. */
  filter: grayscale(.55) opacity(.82);
  transition: filter .4s var(--doux), scale .4s var(--sortie);
}
.pied-logos a:hover img { filter: none; scale: 1.04; }

.avertissement { font-size: .82rem; line-height: 1.7; color: var(--encre-pale); max-width: 80ch; }
.pied-bas {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 18px; font-size: .84rem; color: var(--encre-pale);
}
.pied-ffst img {
  height: 46px; width: auto; display: block;
  filter: grayscale(.55) opacity(.82);
  transition: filter .4s var(--doux), scale .4s var(--sortie);
}
.pied-ffst:hover img { filter: none; scale: 1.04; }

/* LE LOGO DE LA FEDERATION, DANS « MA FORMATION ».
   Il ferme la liste au lieu de l'ouvrir : la liste dit les faits, le logo les
   signe. Un filet le separe des trois lignes pour qu'il ne se lise pas comme
   un quatrieme point. Il reste en couleur, contrairement a celui du pied :
   ici, c'est une piece justificative, pas un ornement de bas de page. */
.formation-ffst {
  display: block; width: fit-content; margin: 16px auto 0;
  padding-top: 14px; border-top: 1px solid rgba(226,113,29,.18);
}
.formation-ffst img {
  height: 62px; width: auto; display: block;
  transition: scale .4s var(--sortie);
}
.formation-ffst:hover img { scale: 1.05; }

.pied-signature { margin-top: 10px; font-size: .78rem; color: var(--encre-pale); }
.pied-signature a { color: inherit; border-bottom: 1px solid rgba(169,141,120,.35); }
.pied-signature a:hover { color: var(--orange); border-color: var(--orange); }

@media (max-width: 700px) {
  .pied-grille { grid-template-columns: 1fr; gap: 30px; }
  .pied-logos img { height: 40px; }
}

/* =========================================================================
   ADAPTATIONS
   ========================================================================= */
.bouton .court { display: none; }

@media (max-width: 900px) {
  .deux, .contact-grille { grid-template-columns: 1fr; }
  .colle { position: static; }
  .nav-liens > a:not(.bouton) { display: none; }
  .nav .bouton .long { display: none; }
  .nav .bouton .court { display: inline; }
  .coord-ligne { grid-template-columns: 1fr; gap: 5px; }
  .tarif { grid-template-columns: 1fr; gap: 14px; }
  .tarif-prix { justify-self: start; }
  /* « Mettre les titres à côté de chaque point », 9 septembre.

     La regle d'origine repliait l'etape sur UNE colonne sous 900 px : la
     pastille orange passait alors sur sa propre ligne, au-dessus du titre, et
     ne designait plus rien. On garde donc les deux colonnes sur telephone, en
     resserrant la gouttiere. Le point reste a cote du titre, ce qui est tout
     son interet. */
  .etape { grid-template-columns: 16px 1fr; gap: 10px; }
  .pan { padding: clamp(60px, 12vw, 96px) 0; }

  /* LE FILM QUI S'OUVRE, SUR TELEPHONE.

     Deux corrections. D'abord la forme : en plein ecran vertical, un film en
     16/9 est recadre si durement qu'il ne reste qu'un gros plan flou. Le
     cadre garde donc une forme paysage.

     Ensuite l'amplitude. Il partait a 92 % de la largeur pour finir a 100 % :
     huit pour cent de croissance, c'est a dire rien. On voyait l'image bouger
     de deux pixels sans jamais l'avoir en plus grand. Il part maintenant a
     56 %, ce qui fait presque doubler sa largeur, et sa legende n'apparait
     qu'a la fin. L'ouverture se voit, et elle raconte quelque chose. */
  /* PLUS DE BLOC EPINGLE SUR TELEPHONE.

     Le film etait tenu en place dans un cadre d'un ecran de haut, lui-meme
     dans un conteneur plus grand. Resultat : avant, on defilait dans du vide
     en attendant qu'il arrive ; apres, on defilait encore dans du vide avec
     un film immobile a l'ecran. Et comme le film se trouvait DANS un bloc
     colle, sa propre minuterie ne bougeait presque plus : c'est ce qui
     donnait l'impression qu'il n'y avait aucune animation.

     Il redevient un bloc normal, qui grandit en traversant l'ecran. Pas de
     vide avant, pas de vide apres, et l'animation se joue vraiment. */
  .ouverture { height: auto; }
  .ouverture-cadre {
    position: static; height: auto;
    padding: clamp(20px, 5vw, 44px) 0;
  }
  .ouverture-film {
    width: 56%; height: auto; aspect-ratio: 4 / 3;
  }
  .ouverture-texte { gap: 8px; }
  .ouverture-texte h2 { font-size: clamp(1.35rem, 6vw, 2rem); }
  .ouverture-texte p { font-size: .92rem; }
  .ouverture-texte .sur-titre { font-size: .68rem; }
}
@supports (animation-timeline: view()) {
  @media (max-width: 900px) {
    .ouverture-film {
      animation-name: ouvrirLarge;
      animation-range: entry 30% cover 52%;
    }
    .ouverture-texte {
      animation: legende linear both;
      animation-timeline: view();
      animation-range: entry 60% cover 50%;
    }
  }
}
@keyframes ouvrirLarge {
  from { width: 56%;   border-radius: var(--rond); }
  to   { width: 100vw; border-radius: 0; }
}
/* La legende est elle aussi un panneau de verre. Animer son opacite la
   rendait a demi transparente pendant toute la montee, texte compris : un
   element dont l'opacite n'est pas 1 devient une racine d'arriere-plan, et
   son propre `backdrop-filter` n'echantillonne plus rien. Elle monte donc
   sans changer d'opacite. */
@keyframes legende {
  from { translate: 0 18px; }
  to   { translate: 0 0; }
}

@media (max-width: 640px) {
  :root { --marge: 18px; --rond: 24px; --rond-l: 30px; }

  /* L'ACCUEIL SUR TELEPHONE.

     Julie voulait que le titre, les trois images, la citation et les deux
     boutons tiennent ensemble sur le premier ecran, sans avoir a descendre.
     C'est la seule contrainte de cette section, et tout y est plie : le
     panneau perd de sa marge, les blocs perdent leurs ecarts, la citation
     descend d'un cran. On garde `100svh` et non `100vh` : `vh` compte la
     hauteur sans les barres du navigateur, donc le bas du bloc passait
     dessous, et c'etaient les boutons qui disparaissaient.

     Le panneau reste tres transparent : a pleine largeur, un verre aussi
     opaque que sur ordinateur cacherait le film en entier. */
  .entree { min-height: 100svh; padding: 96px 0 32px; align-content: center; }
  /* Plus de fond ni de flou : c'est le voile qui porte la lisibilite. */
  .entree-panneau { padding: 22px 4px 24px; }
  .baseline { font-size: 1.02rem; margin-top: 12px; }
  .baseline.serre-titre { font-size: .98rem; }

  /* Deux boutons cote a cote deviennent illisibles sous 400 pixels : on les
     empile, pleine largeur, pour qu'ils restent des cibles franches. */
  .actions { flex-direction: column; align-items: stretch; margin-top: 26px; }
  .actions .bouton { justify-content: center; padding: 16px 22px; }
  .entree .actions { margin-top: 18px; gap: 9px; }
  .entree .actions .bouton { padding: 13px 20px; font-size: .92rem; }

  /* Un lien de vingt-neuf pixels de haut se rate au pouce. On ne change pas
     sa taille de texte, on lui donne de la marge autour. */
  .suite { padding-block: 10px; }

  .descendre { display: none; }
  .entete { padding: 124px 0 56px; }
  .entete h1 { font-size: clamp(2.4rem, 12vw, 3.4rem); }
  .eclat { font-size: clamp(1.5rem, 7vw, 2.4rem); }
  .tarif { padding: 22px 22px; }
  .carte { padding: 26px 22px 28px; }
  .appel-carte { padding: 34px 24px; }
  .coord-ligne { padding: 18px 22px; }
  .pied-haut { gap: 18px; }
}
@media (max-width: 400px) {
  .nav-marque img { width: 32px; }
  .nav-marque .nom { font-size: .93rem; }
  .nav .bouton { padding: 10px 15px; font-size: .82rem; }
}

/* Pas d'ecran tactile : pas de halo qui traine. */
@media (hover: none) { .halo { display: none; } }

/* Quelqu'un qui a demande moins de mouvement a de bonnes raisons. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .rev { opacity: 1; translate: 0; filter: none; }
  .eclat w { color: var(--encre); }
}

/* =========================================================================
   LE PORTRAIT
   Sur la page du shiatsu, le film reste dans son cadre au lieu de s'ouvrir
   en plein ecran : le geste de l'accueil ne doit servir qu'une fois.
   ========================================================================= */
.portrait .deux { grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); align-items: center; }
.portrait-film {
  position: relative; overflow: hidden;
  border-radius: var(--rond-l);
  aspect-ratio: 4 / 5;
  box-shadow: 0 1px 0 rgba(255,255,255,.6) inset, 0 40px 80px -40px rgba(120,60,15,.5);
}
.portrait-film video { width: 100%; height: 100%; object-fit: cover; }
.portrait-film::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.35);
  background: linear-gradient(190deg, rgba(255,248,239,.14), transparent 45%);
}
@media (max-width: 900px) {
  .portrait .deux { grid-template-columns: 1fr; }
  .portrait-film { aspect-ratio: 4 / 3; }
}

/* =========================================================================
   DEUXIEME SERIE DE CORRECTIONS DE JULIE (17 aout 2026)

   Tout ce qui suit est ne de son document. Chaque bloc porte la demande a
   laquelle il repond, pour qu'on sache dans six mois pourquoi il existe.
   ========================================================================= */

/* --- Un texte lu par les machines, pas par l'oeil ------------------------
   Le titre de l'accueil est une image (le dessin de son flyer). Un moteur de
   recherche ne lit pas les images : le mot reste donc ecrit dans la page,
   simplement pose hors du champ de vision. `display:none` ne conviendrait
   pas, un lecteur d'ecran l'ignorerait aussi. */
.hors-vue {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* --- LE TITRE DU FLYER ---------------------------------------------------
   « Titre à modifier comme sur mon flyer idéalement, Shiatsu, Harmoniser le
   corps et l'esprit plus collé au mot shiatsu, avec le rond orange Enso et un
   décor au bout, logo à retirer. »

   Le rond, le mot et le petit epi sont un seul dessin, decoupe dans son
   flyer : aucune police ne rendrait ce trait de pinceau, et il est a elle.
   L'entree se joue comme un coup de pinceau qu'on pose : le dessin arrive
   legerement tourne et se redresse. */
.titre-bloc { width: min(100%, 560px); margin-inline: auto; }
.titre-flyer { line-height: 0; }
.titre-flyer img {
  width: 100%; height: auto;
  animation: poserEnso 1.5s var(--sortie) both;
}
@keyframes poserEnso {
  from { opacity: 0; scale: .82; rotate: -8deg; }
  to   { opacity: 1; scale: 1;   rotate: 0deg; }
}
/* « plus collé au mot shiatsu » : la ligne vient se poser juste sous les
   lettres, donc PAR-DESSUS le bas du rond, exactement comme sur le flyer.
   Le dessin garde un dixieme de sa largeur de vide sous les capitales : on
   remonte de huit et demi pour cent, ce qui laisse un cheveu d'air, et le
   calcul tient a toutes les tailles puisqu'il porte sur la largeur. */
.baseline.serre-titre {
  margin-top: -8.5%;
  color: var(--encre);
  position: relative; z-index: 1;
}

/* --- LES TROIS EMPLACEMENTS ---------------------------------------------
   « Création de 3 emplacements : pour 2 photos et 1 image (celle avec les
   mains et le cœur), des encadrements avec des courbes. »

   Chaque cadre a sa propre forme, comme les taches de ses publications, et un
   liseré orange qui suit la courbe. `outline` epouse le `border-radius`, donc
   il n'y a pas besoin d'un deuxieme element pour dessiner le contour.

   LES DEUX PHOTOS SONT PROVISOIRES. Julie doit envoyer les siennes ; d'ici
   la ce sont deux images du site qui tiennent la place. */
.galerie {
  display: flex; justify-content: center; align-items: center;
  gap: clamp(14px, 1.7vw, 20px);   /* 14 au minimum : voir .galet */
  margin-top: clamp(20px, 2.8vw, 32px);
  animation: paraitre 1.1s var(--sortie) .62s both;
}
/* « Les 3 bulles pour les photos, possible un peu plus grandes ? Sans abuser,
   un peu, que l'encadrement reste visible en entier version mobile », 25 aout.

   Sa condition EST la contrainte de calcul, et elle l'a formulee mieux qu'un
   cahier des charges. Le cerclage n'est pas dans la bulle : `outline-offset`
   le pose 5 pixels DEHORS, plus 1,5 de trait. Chaque bulle demande donc 13
   pixels de plus que sa largeur, et les deux bulles des bords en perdent la
   moitie hors de l'ecran si on serre trop.

   MESURE A 390 : la carte offre 339 pixels utiles. Il faut y loger deux fois
   la bulle laterale, la centrale, deux ecarts, et 6 pixels de cerclage a
   chaque extremite.

   Mon premier essai a 26 et 29 vw debordait de 7 pixels : elle aurait vu
   exactement ce qu'elle demandait d'eviter. On tient a 24 et 27, avec 7
   pixels de marge dans la carte.

   ET L'ECART PASSE DE 9 A 14 PIXELS, ce qui corrige un defaut plus ancien :
   a 9 pixels, deux cerclages voisins se chevauchaient de 3, et cela depuis
   toujours. Il en reste 2 d'air entre eux. */
.galet {
  position: relative; flex: none;
  width: clamp(84px, 24vw, 180px); aspect-ratio: 1;
  overflow: hidden;
  background: rgba(255,255,255,.55);
  outline: 1.5px solid rgba(226,113,29,.5);
  outline-offset: 5px;
  box-shadow: 0 1px 0 rgba(255,255,255,.85) inset,
              0 22px 44px -26px rgba(120,60,15,.55);
  transition: translate .6s var(--sortie), outline-color .4s var(--doux);
}
.galet img { width: 100%; height: 100%; object-fit: cover; }
/* Le dessin au trait est transparent : il ne se recadre pas, il se pose. */
.galet .dessin { object-fit: contain; padding: 13%; mix-blend-mode: multiply; }

.g1 { border-radius: 58% 42% 46% 54% / 48% 56% 44% 52%; translate: 0 7%; }
.g2 { border-radius: 47% 53% 55% 45% / 52% 46% 54% 48%; width: clamp(96px, 27vw, 208px); }
.g3 { border-radius: 52% 48% 57% 43% / 44% 53% 47% 56%; translate: 0 -7%; }
.galet:hover { outline-color: var(--orange); }
.g1:hover { translate: 0 4%; }
.g3:hover { translate: 0 -10%; }

/* --- LA CITATION ---------------------------------------------------------
   « Ajouter citation : Il n'y a pas de hasard, il n'y a que des rendez-vous.
   Paul Eluard. » Les guillemets sont dessines par le CSS pour qu'on n'ait
   jamais a se demander lesquels ont ete tapes. */
.citation {
  display: grid; gap: 7px; justify-items: center;
  margin-top: clamp(18px, 2.4vw, 28px);
  animation: paraitre 1.1s var(--sortie) .8s both;
}
.citation blockquote {
  font-family: 'Instrument Serif', Georgia, serif; font-style: italic;
  font-size: clamp(1.04rem, 2.1vw, 1.52rem); line-height: 1.34;
  color: var(--encre); max-width: 28ch;
}
.citation blockquote::before { content: '\00ab\00a0'; color: var(--orange); }
.citation blockquote::after  { content: '\00a0\00bb'; color: var(--orange); }
.citation figcaption {
  font-size: .72rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--orange);
}

/* --- LES QUATRE QUESTIONS -----------------------------------------------
   Elles remplacent le lien « Comment se passe une séance ». Toutes menent a
   la page Shiatsu : « peu importe sur quelle question ils cliquent ». */
.questions { display: grid; gap: 8px; margin-top: 28px; }
.questions a {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 20px; border-radius: var(--rond);
  background: rgba(255,255,255,.5);
  border: 1px solid rgba(226,113,29,.16);
  font-size: 1.01rem; font-weight: 450; color: var(--encre);
  transition: background .3s var(--doux), border-color .3s var(--doux),
              translate .35s var(--sortie);
}
.questions a:hover {
  background: rgba(255,255,255,.86); border-color: var(--orange); translate: 4px 0;
}
.questions a svg { color: var(--orange); flex: none; transition: translate .35s var(--sortie); }
.questions a:hover svg { translate: 4px 0; }

/* --- LE CADRE DU DRAP ----------------------------------------------------
   « Inclure une future vidéo de la pièce avec pour titre Le cabinet. » Le
   cartouche est en place ; la video de la piece prendra la suite. */
.ecran-film {
  position: relative; overflow: hidden;
  border-radius: var(--rond-l); aspect-ratio: 16 / 10;
  box-shadow: 0 1px 0 rgba(255,255,255,.6) inset,
              0 40px 80px -40px rgba(120,60,15,.5);
}
.ecran-film video { width: 100%; height: 100%; object-fit: cover; }

/* LE CADRE SUIT LE FORMAT DE LA PRISE, il ne le contraint pas.

   Le cadre etait en 16/10 en dur. Une video verticale posee dedans en
   `object-fit: cover` n'aurait montre qu'une bande horizontale d'un tiers de
   sa hauteur : on aurait perdu la piece pour garder le plafond. Chaque format
   a donc son rapport, et le portrait se borne en largeur pour ne pas devenir
   une colonne de mille pixels de haut a cote du texte. */
.ecran-film.paysage { aspect-ratio: 16 / 9; }
.ecran-film.portrait {
  aspect-ratio: 3 / 4;
  width: min(100%, 380px); margin-inline: auto;
}
.ecran-film figcaption {
  position: absolute; z-index: 2;
  left: clamp(12px, 2vw, 20px); bottom: clamp(12px, 2vw, 20px);
  padding: 9px 18px; border-radius: 999px;
  font-size: .74rem; letter-spacing: .2em; text-transform: uppercase;
  font-weight: 500; color: var(--encre);
  background: rgba(255,252,246,.82);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  box-shadow: 0 1px 0 rgba(255,255,255,.9) inset;
}

/* ET SUR TELEPHONE, CE FILTRE PART.
 *
 * Cette etiquette est posee SUR UNE VIDEO QUI JOUE, et c'est la pire
 * combinaison qui existe. Un filtre de fond au-dessus d'une image immobile se
 * calcule une fois et se garde ; au-dessus d'une video, il se REFAIT a chaque
 * image, vingt-quatre fois par seconde, pendant que la page defile. C'est
 * exactement la saccade que Matheo sentait sous le doigt le 25 aout, apres
 * qu'on ait deja allege tout le reste.
 *
 * ET LA REGLE EST ICI, PAS DANS LE BLOC MOBILE PLUS HAUT. Je l'y avais mise
 * d'abord : meme specificite que la regle de base, mais ECRITE AVANT elle dans
 * le fichier, donc annulee. La sonde a continue de compter le filtre et c'est
 * elle qui me l'a appris. A SPECIFICITE EGALE, C'EST L'ORDRE D'ECRITURE QUI
 * TRANCHE : troisieme fois que ce piege se referme sur cette feuille.
 *
 * Rien ne se perd a l'oeil : le fond etait deja opaque a 82 pour cent, on le
 * monte a 94 et la difference ne se voit pas. */
@media (max-width: 900px) {
  .ecran-film figcaption {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(255,252,246,.94);
  }
}

/* --- QUI JE SUIS, EN PUBLICATION ----------------------------------------
   « Cette photo avec un contour arrondi et les annotations Julie Marguier,
   Praticienne shiatsu, Passionnée par les pratiques naturelles et
   holistiques, Soif d'apprendre toujours plus. Mise en page animée ? »

   La photo au centre, deux annotations au-dessus, deux en dessous, reliees
   par de petites fleches tracees a la main : c'est la mise en page de sa
   publication. Sur telephone la grille se defait et tout se met a la suite,
   parce qu'a 375 pixels il n'y a de place ni a gauche ni a droite. */
.portrait-annote {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas:
    "a1 photo a2"
    "a3 photo a4";
  gap: clamp(14px, 2.4vw, 30px) clamp(18px, 3vw, 44px);
  align-items: center;
  margin-top: clamp(26px, 3.4vw, 44px);
}
.portrait-photo { grid-area: photo; width: clamp(196px, 25vw, 310px); }
.portrait-photo img {
  /* `height: auto` n'est pas decoratif ici. Les attributs width et height de
     la balise sont des indications de presentation : ils posent une hauteur
     reelle de 725 pixels, et cette hauteur l'emporte sur `aspect-ratio` tant
     qu'on ne la remet pas explicitement a `auto`. Sans cette ligne, la photo
     s'affichait a 300 sur 725 au lieu de 300 sur 400. */
  width: 100%; height: auto;
  aspect-ratio: 3 / 4; object-fit: cover; object-position: center 22%;
  /* « un contour arrondi » : une arche, ronde en haut, posee en bas. */
  border-radius: 999px 999px var(--rond-l) var(--rond-l);
  outline: 1.5px solid rgba(226,113,29,.45); outline-offset: 7px;
  box-shadow: 0 30px 70px -34px rgba(120,60,15,.55);
}
.annot {
  font-size: clamp(.95rem, 1.35vw, 1.1rem); line-height: 1.5;
  color: var(--encre-doux); max-width: 24ch;
  display: grid; gap: 2px;
}
.annot-nom { font-size: clamp(1.5rem, 3.2vw, 2.3rem); line-height: 1.1; }
.annot-nom em { font-size: 1em; }

/* LE J DE JULIE RESSEMBLAIT A UN I, et elle a raison de l'avoir vu deux fois :
   sous le portrait et sous son histoire. C'est l'ITALIQUE d'Instrument Serif
   qui en est la cause, son J penche tellement que son crochet disparait. La
   police romaine de la meme famille a un J parfaitement lisible, et elle est
   deja chargee : on ne telecharge rien de plus, on cesse simplement de pencher
   le seul mot ou ca posait probleme. */
.annot-julie {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: normal; color: var(--encre);
  display: block;
}
/* « Rapprocher Praticienne shiatsu de Julie Marguier » : sous le nom, colle,
   et non de l'autre cote de la photo. */
.annot-role {
  display: block; margin-top: 2px;
  font-size: .5em; color: var(--encre-doux); line-height: 1.4;
}

/* DEUX ANNOTATIONS AU LIEU DE QUATRE : la photo n'a plus besoin de quatre
   coins, elle a besoin d'un vis-a-vis.

   ET LE BLOC SE RESSERRE. La grille d'origine etait taillee pour quatre
   annotations reparties sur toute la largeur de la page. Avec deux elements,
   elle laissait un vide de six cents pixels a gauche et poussait la photo
   contre le bord droit : le nom finissait tout seul au milieu de nulle part.
   On borne donc l'ensemble et on le centre, pour que le nom et la photo se
   fassent vraiment face. */
/* CENTRER LE CONTENEUR NE CENTRE PAS LE CONTENU.

   Premiere version : deux colonnes `1fr` et `290px`, le tout borne a 720 px et
   centre. Mesure : le conteneur tombait bien au milieu, a 966 px, mais ce
   qu'on VOIT etait centre sur 1084. La colonne de gauche faisait 370 px pour
   un nom qui en occupe 172 : deux cent dix-sept pixels de vide a gauche, rien
   a droite, donc un bloc qui penche.

   `auto auto` plus `justify-content: center` : chaque colonne prend la largeur
   de son contenu, et c'est la PAIRE qui se centre. Le vide se repartit alors
   des deux cotes, ce qui est la definition de centrer.

   Et la photo reprend sa largeur ICI : `.portrait-photo` en impose une de
   310 px qui l'emportait sur la colonne de 290 et la faisait deborder de vingt
   pixels vers la droite. Une largeur fixe posee ailleurs gagne toujours contre
   une colonne de grille : on la redit plutot que de croire la grille. */
/* C'EST LA PHOTO QUI DOIT ETRE SUR L'AXE, PAS LA PAIRE.

   Deuxieme correction du meme bloc, et la premiere n'etait qu'a moitie juste.
   Centrer la PAIRE mettait le milieu du groupe sur l'axe, donc la photo a
   cent deux pixels a droite. Or au-dessus il y a « QUI JE SUIS », centre : l'oeil
   descend le long de cet axe et attend la photo dessous, pas a cote.

   Trois colonnes, `1fr auto 1fr` : la photo prend la colonne du milieu, donc
   elle tombe exactement sur l'axe quoi qu'il arrive, et le nom se pose dans la
   colonne de gauche, colle contre elle. La troisieme colonne reste vide et
   c'est son role : c'est elle qui garantit la symetrie. */
.portrait-duo {
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: 'a1 photo vide';
  align-items: center;
  gap: clamp(16px, 3vw, 44px);
}
/* DEUX CLASSES DANS LE SELECTEUR, ET CE N'EST PAS DU ZELE.

   `.annot:nth-of-type(1)` pose `align-self: end` quinze lignes plus bas. A
   specificite EGALE, c'est la derniere ecrite qui gagne : mon `center` etait
   ecrase et le nom restait colle au bas de la photo. On monte donc d'un cran
   avec les deux classes de l'element, et l'ordre dans le fichier cesse de
   compter.

   Et le nom vise le HAUT du tiers median, pas le milieu exact : sous le nom il
   y a le metier puis la flechette, donc le bloc est lourd du bas. Centre
   geometriquement, il paraissait encore bas. */
.portrait-duo .annot.annot-nom {
  grid-area: a1; justify-self: end; text-align: right;
  max-width: 18ch; align-self: center;
  padding-bottom: clamp(28px, 4vw, 62px);
}
.portrait-duo .portrait-photo { grid-area: photo; width: clamp(196px, 22vw, 292px); }
/* La flechette part du nom vers la photo : elle descend legerement, comme une
   main la tracerait. */
.portrait-duo .flechette { justify-self: end; rotate: 4deg; margin-top: 10px; }

.annot:nth-of-type(1) { grid-area: a1; justify-self: end; text-align: right; align-self: end; }
.annot:nth-of-type(2) { grid-area: a2; justify-self: start; align-self: end; }
.annot:nth-of-type(3) { grid-area: a3; justify-self: end; text-align: right; align-self: start; }
.annot:nth-of-type(4) { grid-area: a4; justify-self: start; align-self: start; }

.flechette { width: 56px; height: 35px; color: var(--orange); opacity: .75; }
.f1 { justify-self: end; rotate: 8deg; margin-top: 4px; }
.f2 { justify-self: start; scale: -1 1; rotate: 8deg; margin-top: 4px; }
.f3 { justify-self: end; rotate: -32deg; margin-top: 8px; }
.f4 { justify-self: start; scale: -1 1; rotate: -32deg; margin-top: 8px; }

.bloc-formation {
  margin-top: clamp(40px, 5vw, 68px);
  max-width: 620px; margin-inline: auto;
}

.blocs-moi {
  grid-template-columns: 1fr 1fr;
  margin-top: clamp(40px, 5vw, 68px);
  align-items: stretch;
}
.liste-nette { display: grid; gap: 10px; list-style: none; }
.liste-nette li {
  position: relative; padding-left: 20px;
  color: var(--encre-doux); font-size: .99rem; line-height: 1.62;
}
.liste-nette li::before {
  content: ''; position: absolute; left: 0; top: .66em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--orange); opacity: .6;
}
.liste-nette b { color: var(--encre); font-weight: 600; }

/* « Bien laisser ce paragraphe entre guillemets pour montrer que c'est moi
   qui parle. » Les guillemets sont donc dans le texte, et la signature les
   ferme visuellement. */
.recit { display: grid; gap: 12px; }
.recit p { color: var(--encre-doux); font-size: .99rem; line-height: 1.68; }
.recit .signature {
  font-family: 'Instrument Serif', Georgia, serif; font-style: italic;
  font-size: 1.4rem; color: var(--orange); margin-top: 2px;
}

/* UNE ANCRE DOIT S'ARRETER SOUS LA BARRE, PAS DESSOUS.
   La barre de navigation est fixe en haut de l'ecran. Sans cette marge, un
   lien qui pointe sur une section amene son titre EXACTEMENT sous la barre,
   qui le recouvre : on arrive au bon endroit et on croit s'etre trompe. */
.ancre { scroll-margin-top: 96px; }
@media (max-width: 700px) { .ancre { scroll-margin-top: 78px; } }

/* --- L'INTRODUCTION DU SHIATSU, ET LA FILE DES AGES --------------------- */
.intro-shiatsu {
  display: grid; gap: clamp(22px, 4vw, 50px);
  grid-template-columns: 1.1fr .9fr; align-items: center;
}
.intro-shiatsu .chapeau { max-width: 46ch; }
/* Le dessin est au trait et transparent : il se pose sur le fond, il ne se
   met pas dans une boite. Un cadre autour l'aurait transforme en illustration
   de catalogue, alors que c'est une respiration. */
.ages img {
  width: 100%; height: auto; display: block;
  filter: brightness(.55) sepia(.3) saturate(1.3) hue-rotate(-12deg);
}
@media (max-width: 860px) {
  .intro-shiatsu { grid-template-columns: 1fr; }
  .ages img { max-width: 420px; margin-inline: auto; }
}

/* « Y aller », sous la phrase des communes. Discret : c'est un service rendu
   a qui se demande ou c'est, pas un appel a l'action de plus. */
.lien-itineraire {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: .95rem; font-weight: 500; color: var(--orange);
  border-bottom: 1px solid rgba(226,113,29,.35); padding-bottom: 2px;
  transition: border-color .3s var(--doux);
}
.lien-itineraire:hover { border-color: var(--orange); }
.lien-itineraire svg { transition: translate .35s var(--sortie); }
.lien-itineraire:hover svg { translate: 4px 0; }

/* --- LE BON CADEAU, EN BANDEAU ------------------------------------------
   « Présentation différente si possible, autre que dans cet encadrement. »
   Meme principe que le bandeau des avis : ce qui detache un bloc, ce n'est
   pas un cadre de plus, c'est une bande qui touche les deux bords. */
.cadeau-bandeau { position: relative; isolation: isolate; }
.cadeau-bandeau::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.5), transparent 62%),
    linear-gradient(180deg, #fbe3c6, #f6cfa3 55%, #fbe3c6);
}
.cadeau-bandeau::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  border-top: 1px solid rgba(226,113,29,.28);
  border-bottom: 1px solid rgba(226,113,29,.28);
}
.cadeau-centre {
  display: grid; gap: 14px; justify-items: center; text-align: center;
  max-width: 62ch;
}
.cadeau-centre h2 { font-size: clamp(1.7rem, 3.4vw, 2.7rem); }
.cadeau-centre .chapeau { max-width: 52ch; }
.cadeau-centre .actions { margin-top: 10px; }

/* --- MON HISTOIRE, HORS DU CADRE ----------------------------------------
   « Pas d'encadrement, centrer le texte et le mettre en italique. »

   Elle avait raison sur le fond avant meme de le formuler : une liste de
   diplomes et un souvenir d'adolescence n'ont aucune raison de se ressembler.
   Deux cartes de verre cote a cote, l'oeil lit un tableau ; une confidence
   centree, sans bord, dans une colonne etroite, il lit quelqu'un qui parle.

   La colonne fait 60 caracteres au maximum. Au-dela, l'oeil perd la ligne
   suivante en revenant a gauche, et c'est exactement ce qui fatigue. */
.histoire-pan { padding-top: 0; position: relative; overflow-x: clip; }
/* Elle sort par la gauche des deux tiers de sa largeur : ce qui reste dans le
   cadre est une courbe, pas une forme. A moitie transparente et posee derriere
   le texte, elle donne une couleur au fond sans jamais gener la lecture. */
.tache-flyer {
  position: absolute; left: 0; top: 50%;
  translate: -62% -50%;
  width: clamp(190px, 26vw, 330px); height: auto;
  opacity: .42; z-index: 0; pointer-events: none;
}
.histoire-pan .serre { position: relative; z-index: 1; }
/* Sous 900 px, la colonne de texte occupe toute la largeur : la tache passerait
   dessous et brouillerait les premieres lettres de chaque ligne. Elle descend
   dans le coin bas et s'efface encore. */
/* SUR TELEPHONE, ELLE DISPARAIT.

   Sur un grand ecran, la tache sort par la gauche et il en reste une courbe :
   on lit un fond. Sur 390 px, la meme forme occupe un quart de la largeur, se
   fait couper par le bord de la section et tombe juste au-dessus de la bande
   orange des avis : Matheo l'a signalee comme « un truc orange en haut qui est
   coupe », et il l'a lue comme un bogue, pas comme un decor.

   Une decoration qu'on prend pour un defaut vaut moins que pas de decoration.
   Elle reste sur les ecrans ou elle fait ce qu'elle doit faire. */
@media (max-width: 900px) {
  .tache-flyer { display: none; }
}
.histoire {
  max-width: 60ch; margin: clamp(16px, 3vw, 30px) auto 0;
  text-align: center; display: grid; gap: 14px;
  position: relative; padding-top: 26px;
}
/* « Police à changer, écriture trop ronde, difficile à lire je trouve »,
   25 aout, et elle a mis le doigt sur trois choses a la fois.

   Ce paragraphe cumulait TOUT ce qui fatigue : une serif d'affiche, en
   ITALIQUE, a 1,06 rem, en encre douce, centree sur sept lignes. Chacun de ces
   choix se defend seul ; ensemble ils font un texte qu'on dechiffre au lieu de
   le lire. Et c'est le passage le plus personnel du site, celui qu'on veut
   qu'on lise en entier.

   UNE POLICE D'AFFICHE N'EST PAS UNE POLICE DE LECTURE. Instrument Serif est
   faite pour des titres de trois mots. On repasse sur Inter, deja chargee,
   deja lue partout ailleurs sur le site sans qu'elle s'en plaigne : pas de
   troisieme fonte a telecharger, et une famille de moins a accorder.

   Le redressement, la taille et le contraste vont ensemble : redresser sans
   agrandir donnerait un bloc plat. La signature « Julie », elle, GARDE la
   serif : c'est un nom, pas un texte, et c'est ce qui donne son caractere au
   bloc une fois le corps devenu sobre. */
.histoire p {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: clamp(1.04rem, 1.55vw, 1.18rem);
  line-height: 1.72;
  letter-spacing: .002em;
  color: var(--encre);
}
/* Un filet orange court au-dessus, seule marque de cadre qui reste : il donne
   un debut au texte sans l'enfermer. */
.histoire::before {
  content: ''; position: absolute; top: 0; left: 50%; translate: -50% 0;
  width: 54px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--orange), transparent);
}
.histoire-nom {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: normal;              /* le J, encore : voir .annot-julie */
  font-size: 1.5rem; color: var(--orange); margin-top: 4px;
}
.sur-titre.centre { text-align: center; }

/* --- LE CHOIX DU RESEAU -------------------------------------------------
   « Bouton Me suivre sur les réseaux, en cliquant choix entre Instagram ou
   Facebook, souvent les personnes n'ont pas les deux. » */
.centre-bloc { text-align: center; }
.choix-reseaux { display: grid; justify-items: center; gap: 14px; }
.reseaux-choix {
  display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;
  opacity: 0; translate: 0 -8px; pointer-events: none;
  transition: opacity .35s var(--doux), translate .4s var(--sortie);
}
.reseaux-choix.ouvert { opacity: 1; translate: 0 0; pointer-events: auto; }
.choix-reseaux .bouton svg { transition: rotate .4s var(--sortie); }
.choix-reseaux [aria-expanded='true'] svg { rotate: 90deg; }

/* --- LES BONS CADEAUX ---------------------------------------------------- */
.cadeau { padding: clamp(30px, 4.4vw, 54px); }
.cadeau h2 { max-width: 20ch; }

/* --- LE CARROUSEL D'AVIS -------------------------------------------------
   « Entre les 2 blocs, ajouter un carrousel avec des avis clients, un titre
   accrocheur au-dessus, 5 étoiles, et si on clique sur Resalib ca envoie sur
   mon lien direct. »

   Les avis sont ceux de sa page Resalib publique, signes et dates. On n'en
   ecrit jamais un : si le tableau `AVIS` du generateur est vide, la section
   n'existe pas. */
/* La largeur se pose sur le TITRE, pas sur son conteneur : `ch` se mesure
   dans la police de l'element qui le porte, et le conteneur est en corps de
   texte. Vingt-quatre `ch` y valaient deux cents pixels, et le titre tombait
   a un mot par ligne. */
.avis-tete h2 { max-width: 13ch; }
.avis-carrousel { margin-top: clamp(28px, 3.6vw, 44px); }
.avis-piste {
  display: flex; gap: 16px;
  overflow-x: auto; scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding: 6px 2px 16px;
}
.avis-piste::-webkit-scrollbar { display: none; }
.avis {
  flex: none; width: min(84%, 372px);
  scroll-snap-align: center;
  padding: 26px 28px 24px;
  display: grid; gap: 13px; align-content: start;
  /* « Ajouter un cadre orange sur chaque contour des avis ? » Oui, mais fin et
     franc. Un liseré d'un pixel suffit à détacher la carte du fond ; épaissi,
     il ferait six rectangles orange alignés, ce qui est exactement l'agression
     qu'elle ne veut pas (« un peu plus punchy, sans être agressif ni rien »). */
  border: 1px solid rgba(226,113,29,.34);
}

/* --- LE CADRE ORANGE AUTOUR DES AVIS -------------------------------------
   Julie proposait deux choses : « un bandeau orange plus foncé à l'arrière »
   OU « un bandeau orange sur le contour du cadre du moins ». Matheo a tranche
   pour le contour, et il a raison sur ce bloc-la.

   La grande bande pleine largeur marchait, mais elle en faisait trop ICI : les
   avis sont deja six cartes claires alignees, poser dessous un aplat orange
   sur toute la largeur donnait un encart publicitaire. Le cadre, lui, dit la
   meme chose plus bas : « ceci est un bloc a part », sans crier.

   Le fond reste, tres pale, parce qu'un cadre sans fond flotte : c'est le
   leger changement de teinte qui fait que l'oeil comprend qu'il entre dans une
   zone, et le trait qui lui en donne les limites. */
/* --- LA BANDE DES AVIS, SANS CADRE ET COURBEE ---------------------------

   Julie, deuxieme vocal : « ce grand cadre principal à l'arrière orange
   m'embête. Je trouve qu'il y a trop de cadres dans mon site. » Et pour le
   reste : « tout est gardé, paroles de clients, les étoiles, les avis dans les
   encadrés avec la petite touche dans les angles, tous les avis sur Resalib.
   Juste le fond à changer. » Puis : « une bande sans cadre, idéalement orangée
   plus foncée sans être agressive, encore plus foncée, et idéalement en haut
   et en bas des courbes, pas quelque chose de droit. »

   Trois choses, donc, et rien d'autre ne bouge.

   PLUS DE CADRE. La bordure et le rayon disparaissent : c'est une bande qui
   traverse, pas une boite posee au milieu. Elle avait raison sur le fond, ce
   site accumulait les rectangles.

   PLUS FONCE. On passe d'un creme a peine teinte a un vrai orange. Il reste
   doux parce qu'il est DESATURE : c'est la saturation qui agresse, pas la
   valeur. Le texte reste sur l'encre du site, verifie au contraste.

   ET COURBEE. Le fond est un element plus LARGE que la page, 148 %, a qui on
   donne un rayon elliptique enorme. Sa courbe s'etale donc sur toute cette
   largeur, et l'ecran n'en montre que la partie centrale : un arc doux au lieu
   d'un demi-cercle. C'est ce qui separe une courbe d'une bosse. */
.avis-bandeau {
  --bord: 0px;
  position: relative; isolation: isolate;
  padding-block: clamp(66px, 8.5vw, 124px);
  margin-block: clamp(16px, 2.6vw, 40px);
  /* CE QUI DEPASSE DOIT ETRE COUPE ICI, SINON C'EST LA PAGE QUI S'ELARGIT.

     Le fond ci-dessous fait 148 % de large pour que sa courbe soit douce : il
     sort donc de 24 % de chaque cote. Sans cette ligne, ces 24 % ne sont pas
     decoratifs, ils AJOUTENT de la largeur au document : 345 pixels de
     defilement horizontal sur un ecran de 1439, 116 sur un telephone. On peut
     alors faire glisser tout le site sur le cote, et c'est exactement ce qui
     donne l'impression d'un site pas fait pour le mobile.

     `clip` et non `hidden` : `hidden` fabrique un conteneur de defilement, et
     un conteneur de defilement casse les animations liees au defilement. Le
     piege a deja ete paye sur ce site pour les taches d'orange. */
  overflow-x: clip;
}
.avis-bandeau::before {
  content: ''; position: absolute; z-index: -1;
  inset-block: 0; left: 50%; width: 148%; translate: -50% 0;
  border-radius: 50% / clamp(46px, 6.5vw, 104px);
  background: linear-gradient(180deg, #f6c496 0%, #f0ac6d 52%, #f5bd88 100%);
}

/* LE CARROUSEL VA JUSQU'AU BORD DU CADRE, ET S'Y EFFACE.

   Dans le cadre, la piste s'arretait sur la marge interieure : la troisieme
   carte etait tranchee net en plein milieu d'une phrase, a trois centimetres
   du trait orange. On lit ca comme un defaut d'affichage, pas comme « il y en
   a d'autres a droite ».

   Elle deborde donc jusqu'au trait, et un fondu de vingt-huit pixels mange le
   dernier centimetre. Une carte qui s'efface dit qu'elle continue ; une carte
   coupee au couteau dit qu'elle est cassee. Le fondu est pose sur les DEUX
   bords, sinon revenir en arriere donnerait le meme defaut a gauche. */
/* Le carrousel deborde de la colonne jusqu'aux bords de l'ecran et s'y efface.
   Sans cadre, il n'y a plus de trait ou s'arreter : les cartes glissent sous
   le bord de la fenetre, et le fondu dit qu'il y en a d'autres. */
.avis-bandeau .avis-carrousel {
  margin-inline: calc(50% - 50vw);
}
.avis-bandeau .avis-piste {
  padding-inline: max(var(--marge), calc(50vw - var(--serre) / 2));
  mask-image: linear-gradient(90deg, transparent, #000 40px,
              #000 calc(100% - 40px), transparent);
}
/* La barre de navigation, elle, revient dans la colonne. */
.avis-bandeau .avis-barre { margin-inline: max(var(--marge), calc(50vw - var(--serre) / 2)); }
/* SUR UN ORANGE FRANC, LE VERRE DOIT REDEVENIR BLANC.
   Les cartes etaient a 66 % de blanc : sur un creme a peine teinte ca passait,
   sur ce fond-la elles prenaient l'orange et se fondaient dedans. C'est le
   contraire de ce qu'elle demande, « pour que les avis ressortent mieux ». On
   les remonte a 88 %, et le liseré orange autour d'elles disparait : sur un
   fond orange, un trait orange ne detache rien. Les petites touches dans les
   angles restent, elle y tient et elles font le charme de la carte. */
.avis-bandeau .avis {
  background: rgba(255,255,255,.88);
  border-color: rgba(255,255,255,.5);
  box-shadow: 0 18px 36px -22px rgba(140,70,20,.45);
}
.avis-bandeau .avis-fleches button {
  background: rgba(255,255,255,.86); border-color: rgba(255,255,255,.6);
}
/* CE QUI ETAIT ORANGE SUR CREME NE PEUT PAS RESTER ORANGE SUR ORANGE.

   Mesure, pas impression : l'orange du site donne 2,00 de contraste sur le
   haut de la bande et 1,64 au milieu. Il en faut 4,5 pour du petit texte. Le
   sur-titre « PAROLE DE CLIENTS » etait donc a peu pres invisible, et je ne
   l'aurais pas vu a l'oeil parce qu'on devine un texte qu'on a soi-meme ecrit.
   L'encre du site, elle, donne 9,23 et 7,54. */
.avis-bandeau .sur-titre { color: var(--encre); }

/* Les etoiles et la note passent sur une pastille blanche, comme au pied de
   page. Julie veut garder les etoiles, et une etoile orange sur un fond orange
   n'est plus une etoile. La pastille les rend, sans ajouter de « cadre » au
   sens ou elle l'entend : c'est la meme forme que celle qui existe deja. */
.avis-bandeau .avis-note {
  /* `align-self` ne retrecit pas un conteneur flex de niveau bloc : la
     pastille s'etirait sur toute la colonne et devenait une barre. Il lui faut
     `inline-flex`, qui la fait tenir a la largeur de son contenu. */
  display: inline-flex; width: fit-content;
  padding: 9px 16px; border-radius: 999px;
  background: rgba(255,255,255,.86);
  border: 1px solid rgba(255,255,255,.6);
  color: var(--encre);
  box-shadow: 0 12px 26px -18px rgba(140,70,20,.5);
}

/* Les pastilles sont des `button`, et l'active porte la classe `.ici` : sur
   l'orange, l'orange de l'active ne se voyait plus, elle passe au blanc. */
.avis-bandeau .avis-points button { background: rgba(255,255,255,.5); }
.avis-bandeau .avis-points button.ici { background: #fff; }
/* Le renvoi Resalib est lui-meme le lien, pas un lien dedans. */
.avis-bandeau .avis-source {
  background: rgba(255,255,255,.86);
  border-color: rgba(255,255,255,.6);
}
.avis blockquote { color: var(--encre-doux); font-size: 1rem; line-height: 1.66; }
.avis figcaption { font-weight: 550; font-size: .97rem; }
.avis figcaption span {
  display: block; font-weight: 400; font-size: .84rem;
  color: var(--encre-pale); margin-top: 2px;
}
.avis-barre { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.avis-points { display: flex; gap: 7px; }
.avis-points button {
  width: 7px; height: 7px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: rgba(169,141,120,.42);
  transition: background .3s var(--doux), scale .3s var(--sortie);
}
.avis-points button.ici { background: var(--orange); scale: 1.35; }
.avis-fleches { display: flex; gap: 8px; }
.avis-fleches button {
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid rgba(226,113,29,.26);
  background: rgba(255,255,255,.55); color: var(--encre);
  transition: background .3s var(--doux), border-color .3s var(--doux), opacity .3s;
}
.avis-fleches button:hover { background: #fff; border-color: var(--orange); }
.avis-fleches button[disabled] { opacity: .32; cursor: default; }
.avis-source { text-align: center; margin-top: 12px; }
.avis-source a { color: var(--orange); border-bottom: 1px solid rgba(226,113,29,.4); }

/* --- LE PLAN -------------------------------------------------------------
   « Image de plan pour cliquer dessus et obtenir un itinéraire jusqu'au
   cabinet. »

   C'est la vraie geographie du Sundgau, dessinee a partir d'OpenStreetMap par
   `plan.mjs` : les bois, les villages, le Rhin, les autoroutes, la frontiere
   suisse. Le trace est dans la page, servi par son propre site : aucune tuile
   n'est demandee a un serveur tiers, donc aucune adresse IP de visiteuse ne
   part ailleurs et il n'y a rien a faire accepter. Le lien, lui, ouvre bien
   Google Maps, mais seulement si on clique.

   LE POINT ORANGE EST LE CENTRE DE LA COMMUNE, PAS SA MAISON. Son adresse
   n'apparait qu'au bout du lien, dans l'itineraire.

   Toute une couche tient dans un seul `path` : c'est pour ca que la page
   n'explose pas malgre quatre mille traces. */
.plan-bloc { display: block; }
.plan { display: block; padding: 20px 20px 0; overflow: hidden; }
.plan-cadre {
  display: block; overflow: hidden; border-radius: 18px;
  /* Le point orange sert d origine au rapprochement : les deux nombres sont
     calcules a la construction a partir de plan.json, donc ils suivent tout
     seuls si le cadre de la carte change un jour. */
  transform-origin: var(--ici-x) var(--ici-y);
}
.plan-carte {
  width: 100%; height: auto; aspect-ratio: 4 / 3;
  transform-origin: var(--ici-x) var(--ici-y);
  transition: scale .75s var(--sortie);
  /* Le dessin est transparent : c'est le verre qui fait le fond, et la carte
     flotte dedans au lieu d'etre posee sur une plaque blanche. */
  overflow: hidden;
}
.plan text { font-family: inherit; }

/* Les masses, du fond vers la surface. */
.p-bois     { fill: rgba(104,122,78,.17); stroke: none; }
.p-plan-eau { fill: rgba(86,124,150,.30); stroke: none; }
.p-cours    { fill: none; stroke: rgba(86,124,150,.5); stroke-width: 1.1; }
.p-bati     { fill: rgba(61,34,19,.14); stroke: rgba(61,34,19,.20); stroke-width: .7; }

/* Les routes, de la plus discrete a la plus forte. Les autoroutes sont
   orange : ce sont les deux axes qu'on suit vraiment pour venir, et ca ancre
   la carte dans ses couleurs a elle plutot que dans celles d'un atlas. */
.p-route   { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.p-route-3 { stroke: rgba(61,34,19,.22); stroke-width: 1; }
.p-route-2 { stroke: rgba(61,34,19,.34); stroke-width: 1.4; }
.p-route-1 { stroke: rgba(226,113,29,.62); stroke-width: 2.1; }

.p-frontiere {
  fill: none; stroke: rgba(61,34,19,.34); stroke-width: 1;
  stroke-dasharray: 6 3 1.6 3; stroke-linecap: round;
}

/* Tous les noms sont cernes de creme : sans ce liseré, un nom pose sur une
   tache de bati ou sur une route devient illisible. C'est le vieux truc des
   cartographes, et `paint-order` le rend possible en une ligne. */
.plan text {
  text-anchor: middle;
  paint-order: stroke; stroke: var(--creme); stroke-width: 3.4;
  stroke-linejoin: round; fill: var(--encre-doux);
}
.p-pays {
  font-size: 10.5px; font-weight: 500; letter-spacing: 3.4px;
  fill: rgba(61,34,19,.34); stroke-width: 3;
}
.p-grand { font-size: 14px;   font-weight: 600; fill: var(--encre); }
.p-moyen { font-size: 11.5px; font-weight: 500; }
.p-petit { font-size: 10px;   fill: var(--encre-pale); stroke-width: 3; }

/* L'echelle : la reponse a « est-ce que c'est loin » sans une phrase. */
.p-echelle path { fill: none; stroke: rgba(61,34,19,.36); stroke-width: 1; }
.p-echelle text { font-size: 8.5px; fill: var(--encre-pale); stroke-width: 2.6; }

/* Elle. */
.p-onde {
  fill: none; stroke: var(--orange); stroke-width: 1.3;
  transform-box: fill-box; transform-origin: center;
  animation: plan-onde 4.4s var(--sortie) infinite;
}
@keyframes plan-onde {
  0%        { scale: .28; opacity: .6; }
  72%, 100% { scale: 1;   opacity: 0; }
}
.p-point {
  fill: var(--orange); stroke: var(--creme); stroke-width: 1.5;
  transition: r .4s var(--sortie);
}
.plan:hover .p-point { r: 6; }
.plan:hover .plan-carte { scale: 1.05; }
.p-nom {
  font-size: 15.5px; font-weight: 700; fill: var(--encre);
  stroke-width: 4.2; letter-spacing: .2px;
}

.plan-pied {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin: 4px -20px 0; padding: 17px;
  font-size: .95rem; font-weight: 500; color: var(--orange);
  border-top: 1px solid rgba(226,113,29,.16);
}
.plan-pied svg { width: 15px; height: 15px; aspect-ratio: auto; transition: translate .35s var(--sortie); }
.plan:hover .plan-pied svg { translate: 4px 0; }

/* L'attribution n'est pas une politesse : la licence ODbL l'exige des qu'on
   redessine leurs donnees. Et sur une carte, ca se fait depuis toujours. */
.plan-credit {
  margin: 9px 0 0; text-align: center;
  font-size: .74rem; color: var(--encre-pale);
}
.plan-credit a { color: inherit; border-bottom: 1px solid rgba(169,141,120,.4); }

/* --- ADAPTATIONS --------------------------------------------------------- */
@media (max-width: 900px) {
  .blocs-moi { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  /* La publication se deplie : la photo d'abord, les annotations a la suite.
     Les fleches n'ont plus rien a relier, elles disparaissent. */
  .portrait-annote {
    grid-template-columns: 1fr;
    grid-template-areas: "photo" "a1" "a2" "a3" "a4";
    justify-items: center; text-align: center;
    gap: 12px;
  }
  .portrait-photo { width: min(74%, 260px); margin-bottom: 10px; }
  .annot, .annot:nth-of-type(1), .annot:nth-of-type(2),
  .annot:nth-of-type(3), .annot:nth-of-type(4) {
    justify-self: center; text-align: center; max-width: 30ch;
  }
  .annot-nom { margin-bottom: 2px; }
  .flechette { display: none; }
}
@media (max-width: 640px) {
  .avis { width: min(88%, 340px); padding: 22px 22px 20px; }
  .questions a { padding: 13px 16px; font-size: .96rem; }
  .plan { padding: 14px 14px 0; }
  .plan-pied { margin: 2px -14px 0; padding: 15px; }

  /* LES NOMS D UNE CARTE NE SE REDUISENT PAS AVEC ELLE.
     Les tailles sont en unites du dessin, donc elles suivent la largeur : sur
     un telephone la carte fait trois cent quarante pixels au lieu de quatre
     cent soixante-dix, et « Sierentz » tombait sous sept pixels. On les
     grossit d un tiers, ce qui les ramene exactement la ou ils etaient sur
     ordinateur. Le trace, lui, ne bouge pas. */
  .p-grand { font-size: 18.5px; }
  .p-moyen { font-size: 15.5px; }
  .p-petit { font-size: 13.5px; stroke-width: 4; }
  .p-pays  { font-size: 13px; letter-spacing: 4px; }
  .p-nom   { font-size: 21px; stroke-width: 5.5; }
  .p-echelle text { font-size: 11.5px; stroke-width: 3.5; }
  .plan text { stroke-width: 4.4; }
}

/* Sans mouvement, la galerie ne flotte pas et le titre ne tourne pas. */
@media (prefers-reduced-motion: reduce) {
  .g1, .g3 { translate: 0 0; }
  .titre-flyer img { animation: none; }
  .p-onde { animation: none; opacity: 0; }
  .plan:hover .plan-carte { scale: 1; }
}

/* =========================================================================
   LE FORMULAIRE DE CONTACT
   Julie, 19 aout : « court, simple et intuitif ». Donc quatre champs, un
   seul bouton, aucun mouvement inutile, et rien qui gronde pendant la frappe.
   ========================================================================= */

/* LE TIROIR. « Je préfère qu'il y ait une touche formulaire de contact plutôt
   que le formulaire en entier. Ça laisse le choix et visuellement c'est moins
   lourd. » Un `details` : le navigateur donne le repli, le clavier, l'etat et
   l'annonce vocale, sans une ligne de script. */
.formulaire-tiroir { max-width: 620px; margin: 0 auto; }
.formulaire-poignee {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 0 auto; cursor: pointer;
  list-style: none;                 /* le triangle par defaut de Firefox */
}
.formulaire-poignee::-webkit-details-marker { display: none; }
.formulaire-tiroir { display: grid; justify-items: center; gap: 18px; }
.formulaire-chevron { transition: rotate .45s var(--sortie); flex: none; }
.formulaire-tiroir[open] .formulaire-chevron { rotate: 180deg; }

/* Le contenu descend au lieu d'apparaitre d'un coup. `interpolate-size` rend
   la hauteur automatique animable ; la ou il manque, le panneau s'affiche
   simplement, sans transition, ce qui reste correct. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .formulaire-tiroir::details-content {
    block-size: 0; overflow: hidden; opacity: 0;
    transition: block-size .5s var(--sortie), opacity .4s var(--doux),
                content-visibility .5s allow-discrete;
  }
  .formulaire-tiroir[open]::details-content { block-size: auto; opacity: 1; }
}

.formulaire-carte {
  padding: clamp(30px, 5vw, 58px);
  border-radius: var(--rond-l);
  display: grid;
  gap: 14px;
  max-width: 620px;
  margin: 0 auto;
}
.formulaire-carte h2 { font-size: clamp(1.6rem, 2.7vw, 2.1rem); }
.formulaire-chapeau { color: var(--encre-doux); max-width: 46ch; }

/* L'ETIQUETTE MUETTE. Retiree de l'ecran comme Julie le demande, gardee pour
   la voix : un lecteur d'ecran annonce l'etiquette, jamais le texte gris
   d'une case, et sans elle il ne dirait que « champ de saisie ». On ne la
   cache donc PAS avec `display:none`, qui la retirerait aussi de la voix. */
.etiquette-muette {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* LE REMERCIEMENT, a sa phrase exacte. Il remplace le formulaire au lieu de
   s'ajouter dessous : des champs vides sous un « merci » donnent l'impression
   qu'il faut peut-etre recommencer. */
.formulaire-merci {
  display: grid; gap: 10px; padding: 34px 30px; margin-top: 8px;
  text-align: center; border-radius: var(--rond);
  background: rgba(255,255,255,.6);
  border: 1px solid rgba(226,113,29,.28);
  animation: merci-parait .6s var(--sortie) both;
}
.formulaire-merci p { color: var(--encre); font-size: 1.05rem; line-height: 1.7; }
.formulaire-merci-nom { color: var(--orange); font-weight: 550; }
.formulaire-merci:focus-visible { outline: 2px solid var(--orange); outline-offset: 4px; }
@keyframes merci-parait { from { opacity: 0; translate: 0 10px; } to { opacity: 1; translate: 0; } }
@media (prefers-reduced-motion: reduce) { .formulaire-merci { animation: none; } }

.formulaire { display: grid; gap: 18px; margin-top: 8px; }
.champ { display: grid; gap: 7px; margin: 0; }

.champ label {
  font-size: .93rem;
  font-weight: 550;
  color: var(--encre);
  letter-spacing: .01em;
}
.facultatif {
  font-weight: 400;
  color: var(--encre-pale);
  font-size: .82rem;
}

.champ input,
.champ textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--encre);
  /* Seize pixels au minimum : en dessous, un iPhone zoome tout seul sur le
     champ actif et la page se decale sous les doigts de la personne. */
  padding: 14px 16px;
  border: 1px solid rgba(169, 141, 120, .38);
  border-radius: 16px;
  background: rgba(255, 255, 255, .66);
  transition: border-color .18s var(--doux), box-shadow .18s var(--doux);
}
.champ textarea { resize: vertical; min-height: 128px; line-height: 1.55; }
.champ input::placeholder,
.champ textarea::placeholder { color: var(--encre-pale); opacity: 1; }

.champ input:focus-visible,
.champ textarea:focus-visible {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(226, 113, 29, .18);
}
.champ input[aria-invalid='true'],
.champ textarea[aria-invalid='true'] { border-color: var(--orange-nuit); }

.erreur {
  min-height: 0;
  font-size: .86rem;
  color: var(--orange-nuit);
}
.erreur:empty { display: none; }

/* Le piege a robots. `display: none` ne suffit pas : certains robots lisent
   la feuille de style et sautent ce qui est masque ainsi. On le sort du cadre
   sans le retirer du document. */
.pot-de-miel {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.formulaire-mention {
  font-size: .84rem;
  color: var(--encre-pale);
  line-height: 1.5;
  margin: -2px 0 0;
}

.formulaire .actions { margin-top: 4px; animation: none; }
.formulaire button[disabled] { opacity: .6; cursor: progress; }

.formulaire-etat {
  margin: 0;
  font-size: .95rem;
  line-height: 1.5;
}
.formulaire-etat:empty { display: none; }
.formulaire-etat.bon { color: var(--orange-nuit); font-weight: 550; }
.formulaire-etat.mauvais { color: var(--orange-nuit); }

@media (max-width: 560px) {
  .formulaire-carte { padding: 26px 20px 30px; border-radius: var(--rond); }
  .formulaire { gap: 15px; }
}

/* =========================================================================
   LES PAGES LEGALES

   Meme matiere que le reste du site, mais aucun bandeau filme et aucune
   grande image : ce sont des pages qu'on vient LIRE. Une colonne etroite,
   une hierarchie franche, et rien qui distraie du texte.
   ========================================================================= */

.pan-legal {
  padding: clamp(120px, 18vh, 190px) 0 clamp(70px, 12vh, 120px);
}

/* 68 signes par ligne : au-dela, l'oeil perd le debut de la ligne suivante,
   et c'est precisement sur ce genre de texte qu'on decroche le plus vite. */
.legal { max-width: 68ch; }
.legal h1 { margin-top: 10px; }
.legal > .chapeau { margin-top: 18px; }

.legal-bloc { margin-top: clamp(34px, 5vw, 52px); }
.legal-bloc h2 {
  font-size: clamp(1.15rem, 2.2vw, 1.42rem);
  letter-spacing: -.02em;
  margin-bottom: 14px;
}
.legal-bloc p { margin-bottom: 12px; line-height: 1.72; }
.legal-bloc p:last-child { margin-bottom: 0; }
/* UN LIEN DOIT SE VOIR, SURTOUT SUR CES PAGES-LA.
   Les blocs legaux heritaient de la couleur du texte : « appelez le 06… » et
   « le formulaire de contact » etaient bien des liens, mais rien ne le disait.
   Sur une page dont le seul but est de renvoyer ailleurs, un lien invisible
   est un lien mort. Couleur ET soulignement : la couleur seule ne suffit pas
   a qui distingue mal les teintes. */
.legal-bloc a, .legal-attente a, .legal p a {
  color: var(--orange-nuit);
  text-decoration: underline;
  text-decoration-color: rgba(168,72,12,.4);
  text-underline-offset: 3px;
  transition: text-decoration-color .3s var(--doux);
}
.legal-bloc a:hover, .legal-attente a:hover, .legal p a:hover {
  text-decoration-color: var(--orange-nuit);
}

/* UN TROU DOIT SE VOIR. Tant qu'une information legale manque, elle apparait
   en clair sur la page au lieu d'etre remplacee par une formule plausible.
   Une mention legale fausse est pire qu'une mention legale incomplete : la
   premiere trompe, la seconde signale. */
.legal-trou {
  background: color-mix(in srgb, var(--orange) 22%, transparent);
  color: var(--orange-nuit);
  font-weight: 550;
  padding: 2px 8px;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange-nuit) 30%, transparent);
}

.legal-verif {
  font-size: .92rem;
  color: var(--encre-douce, inherit);
  opacity: .82;
  padding-left: 16px;
  border-left: 2px solid color-mix(in srgb, var(--orange) 45%, transparent);
}

.legal-attente {
  margin-top: clamp(28px, 4vw, 44px);
  padding: clamp(22px, 3vw, 34px);
  border-radius: var(--rond);
  background: color-mix(in srgb, var(--orange) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange) 28%, transparent);
}
.legal-attente p { margin-bottom: 12px; line-height: 1.72; }
.legal-attente p:last-child { margin-bottom: 0; }

/* Les liens legaux du pied. Discrets, mais presents sur TOUTES les pages :
   la loi veut qu'ils soient accessibles depuis n'importe ou. */
.pied-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin-top: 10px;
  font-size: .88rem;
}
.pied-legal a { opacity: .8; text-underline-offset: 3px; }
.pied-legal a:hover { opacity: 1; }

/* =========================================================================
   LES AVIS, APRES SA DEMANDE DU 20 AOUT

   Une seule fois cinq etoiles, en tete, avec la note globale et le nombre.
   Elles etaient repetees sur chaque carte : quatre fois la meme note finit
   par ne plus rien dire, alors qu'une note globale sur soixante-quatre avis
   est un fait.
   ========================================================================= */

.avis-note {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  font-size: .98rem;
}
.avis-note b { font-weight: 600; }

/* UNE SEULE LIGNE, ET ON LE DIT AU NAVIGATEUR.
   `nowrap` interdit le retour a la ligne : sans lui, le texte se recasserait
   des qu'un mot s'allonge, par exemple le jour ou le nombre d'avis passe a
   trois chiffres. Le texte a ete raccourci pour que ca tienne vraiment ;
   `nowrap` est la pour que ca le reste. */
.avis-note { white-space: nowrap; flex-wrap: nowrap; }
.avis-note .etoiles { flex: none; }

/* Sous 430 px, les etoiles et le corps se resserrent d'un cheveu. Mesure a
   l'appui : la pastille passe de 236 a 210 px de large, pour 334 disponibles.
   On garde donc de la marge meme sur les plus petits telephones. */
@media (max-width: 430px) {
  .avis-note { font-size: .92rem; gap: 8px; }
  .avis-note .etoiles svg { width: 13px; height: 13px; }
}

/* Sans prenom, la date porte seule le pied de la carte : on lui donne assez
   de presence pour ne pas ressembler a un reste. */
.avis figcaption {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: .88rem;
  opacity: .78;
}
.avis figcaption span { font-variant-numeric: tabular-nums; }

/* Le renvoi vers Resalib. Le logo dit d'ou vient la note, et un visiteur qui
   doute peut aller verifier en un clic : c'est ce qui rend un avis credible. */
a.avis-source {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  margin-top: clamp(22px, 3vw, 32px);
  padding: 10px 18px 10px 12px;
  border-radius: 999px;
  text-decoration: none;
  font-size: .92rem;
  background: color-mix(in srgb, var(--orange) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange) 26%, transparent);
  transition: background-color .35s var(--sortie, ease);
}
a.avis-source:hover { background: color-mix(in srgb, var(--orange) 16%, transparent); }
a.avis-source img {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  object-fit: contain;
  background: #fff;
}
a.avis-source b { font-weight: 600; }
a.avis-source svg { opacity: .6; }

/* =========================================================================
   L'ALLEGEMENT DU TELEPHONE, ECRIT EN DERNIER ET C'EST VOULU
   =========================================================================

   Audit du 25 aout 2026, apres que Matheo ait signale « des qu'on descend, ca
   galere, c'est horrible ». Trente-quatre passes de lecture, chaque trouvaille
   soumise a un contradicteur.

   POURQUOI TOUT EST DANS UN SEUL BLOC, A LA TOUTE FIN DU FICHIER.

   Trois fois sur ce projet, une correction a ete posee AVANT la regle qu'elle
   corrigeait, a specificite egale, et annulee en silence. On ne se fie plus a
   la specificite : a la fin du fichier, le dernier ecrit gagne toujours. Les
   selecteurs sont ecrits a la specificite exacte de leur cible, jamais plus
   faible : « .verre.sur-film » et non « .sur-film », qui serait battu.

   CE QUI A ETE MESURE, ET CE QUI NE POUVAIT PAS L'ETRE.

   Aucune mesure de fluidite n'existe ici, et aucune n'etait possible : sous
   temps virtuel, cette machine rend 0,2 a 3 images par seconde et l'observateur
   de taches longues ne voit presque rien. Tout ce qui suit vient de la
   STRUCTURE et de comptages exacts. LE SEUL JUGE EST LE TELEPHONE.
   ========================================================================= */
@media (max-width: 900px) {

  /* 1. LE GRAIN. C'est la trouvaille que j'avais ratee tout seul, et c'est la
        plus grosse. `body::after` est un plan FIXE de tout l'ecran, en
        `mix-blend-mode: multiply`, pose au-dessus de TOUT, sur les huit pages.
        Une fusion plein ecran oblige le navigateur a ecrire puis relire une
        texture de la taille de l'ecran a chaque image de defilement, et un
        telephone peint par tuiles : c'est exactement le genre de cout qui ne
        se voit dans aucun profil d'animation parce qu'il est dans la
        composition.

        A 390 pixels et trois pixels physiques par pixel CSS, un motif de 140
        pixels a 26 pour cent d'opacite ne se voit deja pas. Le grain avait ete
        ajoute pour les grands aplats d'ordinateur, ou il reste. */
  body::after { display: none; }

  /* 2. LE PLUS GROS FLOU DU SITE, et il echappait a l'allegement mobile depuis
        le debut. `.verre.sur-film` vaut 0,2,0 en specificite : la regle
        d'allegement `.avis, .carte` ne l'atteint pas, et `.verre` non plus.
        Il gardait donc `blur(30px)` sur 155 347 pixels carres a l'accueil,
        soit 76 pour cent de toute la surface floutee de la page, empile au-
        dessus d'une image qui porte deja son propre filtre.

        Le flou de 30 pixels avait ete choisi pour poser du verre SUR UNE
        VIDEO. Sous 900 pixels il n'y a plus de video, elles sont retirees du
        document : il ne reste qu'une image fixe. Le flou n'a plus d'objet. */
  .verre.sur-film {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: linear-gradient(150deg, rgba(255,252,246,.93), rgba(255,244,230,.90));
  }

  /* 3. LES TACHES QUI RESPIRENT. Quatre a six couches en `filter: blur(70px)`
        mises a l'echelle sans fin. Une mise a l'echelle est gratuite sur un
        element ordinaire ; sur un element FILTRE elle ne l'est pas, parce que
        le flou est rasterise dans une surface et qu'une surface dont l'echelle
        change doit etre refaite.

        On garde le decor, on arrete le mouvement : a l'arret elles sont
        exactement dans leur pose de depart, et un halo floute a 70 pixels qui
        cesse de bouger de cinq pour cent en dix-sept secondes ne se remarque
        pas. */
  .pan.tache::before,
  .pan.tache::after { animation: none; }

  /* 4. LES PROMOTIONS INUTILES. `will-change` fabrique une couche de
        composition en permanence, et ces couches-la servent des effets de
        survol que le script N'INSTALLE JAMAIS sur telephone : les trois blocs
        concernes vivent derriere `matchMedia('(hover: hover)')`, faux sur un
        ecran tactile. On payait la memoire video sans rien obtenir.

        Pour `.carte` il faut annuler LES DEUX : ce n'est pas seulement le
        `will-change` qui la promeut, c'est aussi sa perspective. */
  .bouton { will-change: auto; }
  .carte { will-change: auto; transform: none; }

  /* 5. L'ONDE DU PLAN, sur la page de contact. Une animation SVG sans fin, non
        compositable, et la seule source d'images permanente de cette page. */
  .plan-onde, .p-onde { animation: none; opacity: 0; }
}

/* =========================================================================
   SUITE DE L'ALLEGEMENT, APRES ESSAI SUR LE TELEPHONE DE MATHEO
   =========================================================================

   26 aout. Quatre versions de l'accueil, une variable changee par version, et
   son verdict au doigt :

     A  temoin                              ca saccade
     B  sans la video                       75 % mieux, mais plus de video
     C  video gardee, cadre sans masque     ca passe, ca bogue quelques secondes
     D  carrousel sans accrochage           ca passe, ca bogue quelques secondes
        et dans les deux cas : « au deuxieme passage ca va mieux »

   CETTE DERNIERE PHRASE EST LA PLUS UTILE DES QUATRE. Un cout qui disparait au
   second passage n'est pas un cout par image, c'est un cout de CHARGEMENT et de
   DECODAGE : la deuxieme fois, tout est dans le cache. C'est traite ailleurs,
   dans construire.mjs : plus aucune video n'a d'adresse dans le HTML.

   Restent ici les deux gains que C et D ont montres.
   ========================================================================= */
@media (max-width: 900px) {

  /* C. LE CADRE DE LA VIDEO NE LA DECOUPE PLUS.
        Le cadre avait `overflow: hidden` et un arrondi de 30 pixels. UNE VIDEO
        DECOUPEE PAR UN MASQUE ARRONDI QUITTE LE CHEMIN MATERIEL du telephone :
        au lieu d'etre posee telle quelle par le processeur graphique, elle doit
        etre recomposee a travers un masque a chaque image. L'ombre de 80 pixels
        de flou sur la meme boite n'aidait pas.

        On garde un arrondi, mais porte par la VIDEO elle-meme au lieu d'etre
        un decoupage du parent : le rendu est le meme a l'oeil, sans le masque.
        Si ca saccade encore, c'est cette ligne qu'il faut passer a zero. */
  .ecran-film {
    overflow: visible;
    box-shadow: 0 18px 34px -24px rgba(120,60,15,.42);
  }
  .ecran-film video { border-radius: var(--rond); }

  /* D. LE CARROUSEL D'AVIS N'ACCROCHE PLUS.
        `scroll-snap-type: x mandatory` sur un defilement horizontal IMBRIQUE
        dans le defilement vertical de la page : a chaque geste, le navigateur
        doit d'abord decider a qui il appartient, puis recalculer ses points
        d'ancrage. On garde le glissement libre, qui ne coute rien. */
  .avis-piste { scroll-snap-type: none; overscroll-behavior-x: auto; }
  .avis { scroll-snap-align: none; }
}

/* =========================================================================
   RETOURS DE JULIE, 3 SEPTEMBRE 2026
   ========================================================================= */

/* LE PORTRAIT PASSE AU-DESSUS, LE NOM CENTRE DESSOUS.

   « Agrandir la photo, version mobile trop petite. Centrer Julie Marguier et
   Praticienne shiatsu sous la photo, retirer la flèche. »

   La disposition en vis-a-vis existait deja sous 760 px : la photo, puis les
   annotations dessous, centrees. On la generalise a toutes les largeurs au
   lieu de la reserver au telephone, et la flechette disparait pour de bon
   puisqu'elle n'a plus rien a relier. */
.portrait-sous {
  grid-template-columns: 1fr;
  grid-template-areas: 'photo' 'a1';
  justify-items: center;
  text-align: center;
  gap: clamp(14px, 2vw, 22px);
}
.portrait-sous .portrait-photo {
  grid-area: photo;
  /* 240 px au minimum : l'ancien reglage tombait a 196 px sur telephone, et
     c'est ce qu'elle a trouve trop petit. */
  width: clamp(240px, 30vw, 320px);
}
.portrait-sous .annot.annot-nom {
  grid-area: a1;
  justify-self: center; align-self: start; text-align: center;
  max-width: 30ch; padding-bottom: 0;
}
.portrait-sous .flechette { display: none; }

/* Le titre « Mon histoire » d'un cran, sans toucher aux autres sur-titres. */
.sur-titre-grand { font-size: .92rem; letter-spacing: .2em; }
.sur-titre-grand::before { width: 34px; }

/* SON TEXTE EN ITALIQUE, ET C'EST SANS DANGER CETTE FOIS.

   L'italique avait ete retire le 25 aout parce qu'elle le trouvait illisible,
   mais c'etait l'italique d'INSTRUMENT SERIF, une serif d'affiche penchee sur
   sept lignes. Le paragraphe est passe a Inter depuis. L'italique d'Inter est
   une vraie italique de labeur : on peut le lui rendre sans ramener le
   probleme. */
.histoire p { font-style: italic; }

/* La phrase « Un lieu où l'on prend le temps » vit maintenant dans la colonne
   de droite, sous la video du cabinet. Deux fois plus etroite que la pleine
   page, elle a besoin d'un corps plus mesure, sinon elle part sur quatre
   lignes. */
.eclat-cabinet { margin-top: 26px; }
.eclat-cabinet .eclat { font-size: clamp(1.35rem, 2.5vw, 2.05rem); }

/* --- LES CONDITIONS GENERALES DE VENTE ----------------------------------
   Le texte de Julie, recu le 10 septembre. Douze articles, des listes et un
   encart pour le mediateur : trois choses que les pages legales n'avaient
   pas encore, parce qu'elles ne contenaient que des paragraphes. */
.legal-date {
  margin-top: 6px;
  font-size: .92rem;
  color: var(--encre-pale);
}
.legal-liste {
  margin: 0 0 14px;
  padding-left: 1.15em;
  list-style: none;
}
.legal-liste li {
  position: relative;
  margin-bottom: 8px;
  line-height: 1.72;
  color: var(--encre-doux);
}
/* Une puce dessinee plutot qu'un disque : le meme orange que le reste du
   site, et elle ne saute pas a la ligne quand l'element fait trois lignes. */
.legal-liste li::before {
  content: '';
  position: absolute;
  left: -1.15em; top: .72em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--orange);
  opacity: .55;
}
.legal-liste li:last-child { margin-bottom: 0; }
.legal-liste b { color: var(--encre); }

/* Les coordonnees du mediateur se lisent comme une adresse a recopier, pas
   comme une phrase : on les sort du fil du texte. */
.legal-encart {
  margin: 16px 0;
  padding: 16px 18px;
  border-radius: var(--rond-s, 14px);
  background: rgba(255,255,255,.55);
  border: 1px solid rgba(226,113,29,.22);
  line-height: 1.62;
}

/* Douze articles dans une seule section : sans respiration au-dessus des
   titres, ils se collaient au paragraphe precedent. La regle d'origine ne
   posait qu'une marge basse, parce qu'il n'y avait jamais eu qu'un titre. */
.legal-bloc h2:not(:first-child) { margin-top: clamp(30px, 4vw, 46px); }

/* UN TEXTE LEGAL NE S'ALLUME PAS AU DEFILEMENT.

   Les apparitions sont pilotees par la POSITION de l'element dans la fenetre,
   pas par une minuterie : `animation-range: entry 4% cover 27%` veut dire que
   l'opacite monte de 0 a 1 pendant que l'element traverse l'ecran. Sur un
   bloc court, c'est une apparition. Sur les CGV, dont le corps mesure
   6 495 px, soit huit ecrans, la traversee dure huit ecrans de defilement :
   le texte reste a moitie transparent, et souvent tout a fait invisible,
   pendant des pages entieres. Mesure : opacite 0 en haut de page, encore 0
   apres 2 500 px de descente.

   Le corps legal est donc rendu opaque d'emblee. L'apparition reste sur le
   titre et sur la date, qui sont courts et pour qui la mecanique fonctionne.
   Une page qu'on consulte pour ses obligations doit se lire, pas se meriter. */
.legal-bloc.rev,
.legal-bloc.rev.vu {
  opacity: 1;
  translate: none;
  animation: none;
  transition: none;
}

/* LE MENU SUR LES IPHONE ANCIENS.

   `inset` n'existe dans Safari que depuis iOS 14.5. Plus tot, `.menu` en
   `position: fixed` sans aucune coordonnee se ramasse en un point de zero
   pixel : ouvert pour le code, invisible et intouchable a l'ecran. Les quatre
   cotes explicites disent la meme chose a tous les Safari. */
.menu, .menu-fond { top: 0; right: 0; bottom: 0; left: 0; }

/* Sur iPhone, un toucher sur un simple bloc ne produit pas de clic tant que
   le bloc n'annonce pas qu'il en attend un. Sans ce curseur, toucher le fond
   du menu ne le refermait jamais. */
.menu-fond { cursor: pointer; }

/* `touch-action: manipulation` coupe le delai que Safari garde pour guetter
   un double toucher de zoom : le bouton repond au premier appui. */
.burger { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

/* iOS ne bloque pas le defilement avec `overflow: hidden` sur body, seulement
   sur la racine. La classe y est posee par le script du menu. */
html.menu-ouvert { overflow: hidden; }

/* =========================================================================
   SAFARI : LA REFRACTION SVG EST RETIREE, ET C'ETAIT LA LENTEUR SUR IPHONE.

   « Sur Xiaomi ca marche, sur iPhone c'est tres lent, comme une image par
   seconde », et le conjoint de Julie a la meme chose.

   Le verre du site pose un filtre SVG en arriere-plan :
   `backdrop-filter: url(#refraction)`, une carte de deplacement
   (feDisplacementMap). MESURE dans les deux moteurs, en iPhone :
     Chromium   CSS.supports('backdrop-filter', 'url(#a)')  -> false
     WebKit     CSS.supports('backdrop-filter', 'url(#a)')  -> true
   Chrome REFUSE la declaration : sur Android l'effet n'a jamais existe, et
   rien ne ralentit. Safari L'ACCEPTE : sur iPhone le filtre est reellement
   calcule, sur le processeur, pour chaque image, sur tout ce qui passe
   derriere la barre du haut, les cartes et les avis. Quand le menu s'anime
   sous la barre, tout ce qui est derriere elle change a chaque image, et
   Safari refait le filtre a chaque fois.

   La condition vise exactement les moteurs qui calculent ce filtre, donc
   Safari, sur iPhone comme sur Mac. Chrome n'entre pas dans le bloc : ce
   qu'il affiche ne change pas d'un pixel. Et puisque Chrome n'a jamais montre
   la refraction, Safari devient simplement identique a ce que tout le monde
   voyait deja ailleurs.
   ========================================================================= */
@supports (-webkit-backdrop-filter: url(#a)) {
  .verre::before,
  .verre.haut::before,
  .verre.barre::before {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* Sur telephone, meme la barre perd son flou sous Safari. Un flou
   d'arriere-plan au-dessus d'un menu plein ecran qui s'anime est recalcule a
   chaque image de l'ouverture ; le fond du menu est de toute facon opaque a
   97 %, il n'y a rien a voir a travers la barre pendant qu'il est ouvert. */
@supports (-webkit-backdrop-filter: url(#a)) {
  @media (max-width: 900px) {
    .nav-boite,
    .bouton {
      backdrop-filter: none;
      -webkit-backdrop-filter: none;
    }
    .nav-boite { background: linear-gradient(150deg, rgba(255,252,247,.97), rgba(255,246,236,.95)); }
  }
}

/* Menu ouvert et fondu termine : le contenu dessous ne se peint plus. */
html.menu-pose main,
html.menu-pose body > footer { visibility: hidden; }

/* =========================================================================
   MENU LENT SUR IPHONE : LES FLOUS PEINTS SOUS LE MENU.

   2 images par seconde a l'ouverture chez Julie et son conjoint, 60 sur
   Android. Sous le menu, la page porte de grands calques en
   `filter: blur(70px)` (les taches orange, jusqu'a 390 x 1014 points, soit
   plus de trois millions de pixels a la densite d'un iPhone) et un filtre
   de couleur sur l'image plein ecran de l'accueil. Chrome confie ces
   filtres a la carte graphique. Safari iOS les calcule sur le processeur, et
   des qu'un calque plein ecran s'anime par-dessus, il repeint ce qui est
   dessous a chaque image : un flou de 210 pixels de rayon, recalcule vingt
   fois, ce sont les dix secondes qu'elle decrit.

   Sur telephone, le flou n'est plus calcule : le degrade radial est deja
   doux par nature, on l'etale jusqu'au bord pour obtenir le meme halo sans
   aucun filtre. L'animation du menu reste exactement la meme.
   ========================================================================= */
@media (max-width: 900px) {
  .pan.tache::before,
  .pan.tache::after { filter: none; }
  .pan.tache::before {
    background: radial-gradient(circle, rgba(242,145,60,.30), rgba(242,145,60,.14) 40%, rgba(242,145,60,0) 72%);
    scale: 1.5;
  }
  .pan.tache::after {
    background: radial-gradient(circle, rgba(251,217,180,.5), rgba(251,217,180,.22) 40%, rgba(251,217,180,0) 72%);
    scale: 1.5;
  }
  .film video, .film img.tenant { filter: none; }
}

/* =========================================================================
   PASSAGE D'UNE PAGE A L'AUTRE SANS COUPURE.

   Julie, sur iPhone, apres le clic dans le menu : « mieux mais pas propre ».
   Le menu restait bien en place, mais la page suivante tombait d'un coup,
   parfois apres un blanc. Deux causes :
   1. La racine n'avait pas de couleur : entre deux pages, Safari montre le
      blanc par defaut avant que le fond creme du body soit peint.
   2. Le changement de page etait une coupure seche.
   La racine prend le creme du site, et le navigateur fond l'ancienne page
   dans la nouvelle (Safari 18.2 et plus, Chrome 126 et plus). Ailleurs, la
   regle est ignoree et rien ne change.
   ========================================================================= */
html { background: var(--creme-fond); }
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: .22s; animation-timing-function: ease-out; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* LE MENU EST DESSINE DES LE CHARGEMENT, PAS A LA PREMIERE OUVERTURE.

   Ferme, il etait `hidden`, donc absent : au premier appui Safari devait le
   construire, calculer ses textes, ses polices et son plan, pendant que le
   fondu demarrait. D'ou l'accroc de la premiere fois seulement. Il est
   maintenant construit d'avance, invisible et intouchable, et l'ouverture
   n'a plus qu'a le montrer. `visibility: hidden` le retire aussi des
   lecteurs d'ecran, comme `hidden` le faisait. */
.menu[hidden] { display: block; visibility: hidden; pointer-events: none; }

/* Le bouton de lecture de Safari, masque sur TOUTES les videos du site et
   plus seulement celles des fonds : la video du cabinet l'affichait aussi. */
video::-webkit-media-controls,
video::-webkit-media-controls-panel,
video::-webkit-media-controls-overlay-play-button,
video::-webkit-media-controls-start-playback-button,
video::-webkit-media-controls-play-button {
  display: none !important;
  -webkit-appearance: none;
  appearance: none;
  opacity: 0;
}
/* Video en attente du premier toucher : invisible, donc sans le bouton de
   lecture de Safari. Le fond garde son image, le cabinet montre son affiche. */
video.film-attente { opacity: 0; }
.ecran-film > img.affiche-attente {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border-radius: inherit; pointer-events: none;
}
@media (max-width: 900px) { .ecran-film > img.affiche-attente { border-radius: var(--rond); } }
