/* Le Palais de Rani, feuille commune */
/* Polices auto-hébergées (latin), aucun appel à Google.
   Bricolage Grotesque est variable : un seul fichier couvre 300 à 700
   et l'axe optique s'ajuste tout seul via font-optical-sizing. */
@font-face { font-family: "Bricolage Grotesque"; font-style: normal; font-weight: 300 700; font-display: swap; src: url(fonts/bricolage-grotesque-var.woff2) format("woff2") }
@font-face { font-family: "Switzer"; font-style: normal; font-weight: 400; font-display: swap; src: url(fonts/switzer-400.woff2) format("woff2") }
@font-face { font-family: "Switzer"; font-style: normal; font-weight: 500; font-display: swap; src: url(fonts/switzer-500.woff2) format("woff2") }

/* Les polices de secours, aux mesures des vraies.

   `font-display: swap` affiche d'abord la police système, puis bascule. Les deux
   dessins n'ont pas la même chasse : mesuré au navigateur, Bricolage écrit 9,8 %
   PLUS ÉTROIT que Helvetica Neue en graisse 600. Le titre de la page Salle changeait
   donc de découpe au moment de la bascule, et tout ce qui est dessous sautait — un
   décalage cumulé de 0,076 mesuré à 1 762 ms, le seul de la page, et le seul endroit
   où le site « bouge tout seul » sous les yeux du visiteur.

   Ces faces ne téléchargent rien : elles pointent sur des polices déjà installées et
   ne font que les redimensionner pour qu'elles occupent exactement la place de la
   vraie. Une face par graisse, parce que le rapport n'est pas le même d'une graisse à
   l'autre (0,9024 en 600, 0,9242 en 400). Si aucune des polices locales n'existe, la
   face échoue et la pile retombe sur l'entrée suivante, comme avant.

   Les hauteurs de ligne du site sont toutes écrites en nombre, donc les montantes et
   descendantes ne changent pas la hauteur des lignes ; elles sont reprises quand même
   pour que le secours soit fidèle là où l'interligne est « normal ». */
@font-face { font-family: "Bricolage secours"; font-weight: 400; size-adjust: 92.42%;
  ascent-override: 100.63%; descent-override: 29.21%; line-gap-override: 0%;
  src: local("Helvetica Neue"), local("Arial"), local("Roboto"), local("Liberation Sans") }
@font-face { font-family: "Bricolage secours"; font-weight: 500; size-adjust: 91.21%;
  ascent-override: 101.96%; descent-override: 29.60%; line-gap-override: 0%;
  src: local("Helvetica Neue"), local("Arial"), local("Roboto"), local("Liberation Sans") }
@font-face { font-family: "Bricolage secours"; font-weight: 600; size-adjust: 90.24%;
  ascent-override: 103.06%; descent-override: 29.92%; line-gap-override: 0%;
  src: local("Helvetica Neue"), local("Arial"), local("Roboto"), local("Liberation Sans") }
@font-face { font-family: "Switzer secours"; font-weight: 400; size-adjust: 100.35%;
  ascent-override: 97.66%; descent-override: 24.91%; line-gap-override: 8.97%;
  src: local("Helvetica Neue"), local("Arial"), local("Roboto"), local("Liberation Sans") }
@font-face { font-family: "Switzer secours"; font-weight: 500; size-adjust: 98.48%;
  ascent-override: 99.51%; descent-override: 25.39%; line-gap-override: 9.14%;
  src: local("Helvetica Neue"), local("Arial"), local("Roboto"), local("Liberation Sans") }

:root {
  /* Un seul habillage, clair : voir le commentaire de la balise <meta> du même nom. */
  color-scheme: light;

  /* La charte officielle d'Afshi Rani, à la lettre. Trois de ses cinq couleurs
     étaient déjà celles du site : marron noir #271210, beige #B07E41 et bordeaux
     #5F191F. Les deux qui manquaient — le rose et le vert du logo — sont ajoutées
     ici, et chacune porte la mesure qui dit où elle a le droit de servir. */
  --bg: #F5EDE0;              /* crème, le fond d'Afshi Bolly */
  --bg-alt: #EADFCB;          /* crème doux, bandes alternées */
  --surface: #FBF6EC;         /* surface posée : formulaire, cartes */
  --ink: #271210;             /* marron noir de la charte, 15,3:1 sur crème */
  --ink-muted: #6B5A44;       /* brun doux, 5,7:1 sur crème */
  --line: rgba(39, 18, 16, .14);

  --accent: #B07E41;          /* beige de la charte, 3,1:1 : gros chiffres seulement */
  --accent-deep: #5F191F;     /* bordeaux de la charte, 11:1 : texte accentué, titres */
  --or: #E3B36E;              /* or clair, 1,7:1 : jamais du texte sur crème */
  /* Le rose de la charte, tel quel. Mesuré sur le crème : 4,47:1 — au-dessus du
     seuil des GRANDS caractères (3:1), sous celui du petit texte (4,5:1). Il ne
     sert donc que dans les titres : les mots en italique des h1, h2 et h3, qui
     font tous au moins 26 px. Jamais un lien, jamais un paragraphe. */
  --rose: #D60361;            /* rose-afshi, 4,47:1 : grands caractères seulement */
  /* Le même, assombri juste assez pour passer le petit texte : c'est lui qui prend
     les survols de liens, les aplats de boutons et tout ce qui se lit à 15 px. */
  --rose-sombre: #BE0054;     /* 5,5:1 sur crème, 5,45:1 en fond sous du crème */
  /* Le vert de la charte. 3,9:1 sur crème : un trait, un pictogramme, un motif —
     c'est au-dessus du seuil des éléments graphiques (3:1). Aucun texte. */
  --vert: #00856C;            /* vert-afshi, 3,9:1 : traits et pictogrammes */

  --deep: #5F191F;            /* fond bordeaux : bandeau formulaire et pied de page */
  --deep-ink: #F5EDE0;        /* 11:1 sur le bordeaux */
  --deep-ink-muted: rgba(245, 237, 224, .78);   /* 7,2:1, un seul niveau atténué */

  /* Le secours ajusté ne sert QUE sous 861 px. Bricolage a un axe optique, et les titres
     changent de chasse avec leur taille : mesuré sur le h1 de la page Salle, la vraie
     police occupe 132 px de haut à 46 px de corps (téléphone) et 310 px à 80,6 px de
     corps (bureau). Le secours rétréci à 90,24 % donne 132 px au téléphone — exact — mais
     232 px au bureau, soit 78 px de moins que la vraie. Helvetica brute, elle, donne
     177 px au téléphone (45 px de trop) et 311 px au bureau, à un pixel près.
     Chaque largeur prend donc ce qui la sert : le secours ajusté en bas, rien en haut. */
  --f-display: "Bricolage Grotesque", "Bricolage secours", "Helvetica Neue", Arial, sans-serif;
  --f-body: "Switzer", "Switzer secours", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* Échelle typographique. Dix pas, neuf au maximum sur une même page :
     --t-geant ne sert qu'à l'accueil, --t-h1 qu'aux titres de page.
     Chaque pas est un clamp, donc une seule variable couvre mobile et bureau.
     Rien ne doit être écrit en dur en dehors d'ici — sauf la taille des champs
     de saisie, voir le commentaire dans salle/index.html. */
  --t-geant: clamp(64px, 12.5vw, 196px);
  --t-h1: clamp(46px, min(5.6vw, 9.2svh), 84px);
  --t-h2: clamp(38px, 5.4vw, 72px);
  --t-h3: clamp(32px, 3.4vw, 44px);
  --t-h4: clamp(26px, 2.6vw, 34px);
  --t-h5: clamp(21px, 2vw, 26px);
  --t-lede: clamp(18px, 1.6vw, 21px);
  --t-base: 17px;
  --t-ui: 15px;
  --t-micro: 13px;
  /* Le onzième pas, et il n'est pas de la typographie : c'est le nom du lieu en
     fond de pied de page, qui déborde l'écran exprès. Il vivait jusqu'ici en dur
     dans un pseudo-élément, où aucun outil de recette ne le voyait. Il est ici
     pour être compté comme les autres — une taille hors échelle qu'on connaît
     vaut mieux qu'une taille hors échelle qu'on ignore. Pas de clamp : c'est
     précisément son débordement proportionnel qui en fait une matière. */
  --t-marque: 16.4vw;

  /* La hauteur de l'en-tête fixe, en un seul endroit : elle sert à la barre
     elle-même et au repère de défilement des ancres (scroll-padding-top). Sans ce
     repère, taper « Demande » dans la barre amenait le haut de la section
     exactement sous l'en-tête, qui en mangeait les 64 premiers pixels. */
  --tete: 76px;
  --wrap: 1200px;
  --gutter: clamp(20px, 5vw, 56px);
  --radius: 4px;
  --arch: 999px 999px var(--radius) var(--radius);
  --ease: cubic-bezier(.22, .8, .24, 1);
}

*, *::before, *::after { box-sizing: border-box }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: var(--tete);
  /* Au doigt, tout lien affichait le cyan par défaut d'Android et d'iOS —
     rgba(51, 181, 229, .4) — le temps d'un appui. Une ombre d'encre à la place. */
  -webkit-tap-highlight-color: rgba(39, 18, 16, .08) }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto } }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 400 var(--t-base)/1.65 var(--f-body);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; height: auto }
a { color: inherit }
:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 3px; border-radius: 2px }
.sr-only { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap }

.wrap { width: min(var(--wrap), 100% - 2 * var(--gutter)); margin-inline: auto }

/* ---------- typo ---------- */
h1, h2, h3 { font-family: var(--f-display); font-weight: 600; line-height: 1.02; letter-spacing: -.035em; margin: 0; font-optical-sizing: auto }
h1 { font-size: var(--t-h1) }
h2 { font-size: var(--t-h2) }
h3 { font-size: var(--t-h4); line-height: 1.1 }
/* Le mot en italique de chaque titre est le seul endroit où le rose du logo
   apparaît en grand. Il y est à sa place : ces mots font 26 px au minimum, donc
   le seuil qui s'applique est celui des grands caractères. Sur le bordeaux des
   bandes inversées, le rose tombe à 2,46:1 — là, c'est l'or qui prend le relais,
   et cette règle est déjà écrite dans chaque bande. */
h1 em, h2 em, h3 em { font-style: normal; font-weight: 400; color: var(--rose) }
p { margin: 0 0 1em }
/* Le lieu ne surtitre plus : il signe le bas du hero, comme une adresse de devanture.
   Bas de casse, police de titre, rien autour. Le surtitre en capitales espacées au-dessus
   du grand titre était la silhouette repérée par les détecteurs comme le hero d'IA par
   défaut ; l'information, elle, valait d'être gardée. Le filet qui précédait cette ligne
   a été retiré : c'était un ornement de plus, il ne disait rien. */
.lieu {
  font: 400 var(--t-ui)/1.4 var(--f-display); color: var(--ink-muted);
  margin: clamp(30px, 5svh, 52px) 0 0;
}
.lede { font-size: var(--t-lede); line-height: 1.6; color: var(--ink-muted); max-width: 34ch }

/* ---------- boutons ---------- */
.btn {
  --b: var(--accent-deep);
  display: inline-flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 28px;
  border-radius: 999px; border: 1px solid var(--b); background: var(--b); color: var(--bg);
  font: 500 var(--t-ui)/1 var(--f-body); letter-spacing: .02em; text-decoration: none; cursor: pointer;
  transition: background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.btn:hover { background: var(--ink); border-color: var(--ink) }
/* Le bouton secondaire prend le rose de la charte au survol — assombri, parce
   qu'un libellé de 15 px sur un aplat demande 4,5:1 et que le rose de la charte
   s'arrête à 4,47. Mesuré ici : 5,45:1. */
.btn--ghost { background: transparent; color: var(--ink); border-color: rgba(39, 18, 16, .3) }
.btn--ghost:hover { background: var(--rose-sombre); color: var(--bg); border-color: var(--rose-sombre) }
.link {
  font-weight: 500; text-decoration: none; background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat;
  padding-bottom: 3px; transition: background-size .35s var(--ease);
}
.link:hover { background-size: 0 1px; background-position: 100% 100% }

/* ---------- en-tête ---------- */
/* La barre est sombre, et ce n'est pas une humeur : le lettrage du logo porte deux
   encres, et le pêche du « le » et du « de » tombait à 1,33:1 sur le crème. Invisible.
   Les couleurs d'un logo ne se retouchent pas — c'est donc le fond qui bouge.

   Le bordeaux de la charte, le réflexe évident, NE MARCHE PAS : il relève le pêche à
   8,28 mais écrase le rose du nom à 2,62. Mesuré, pas supposé. Le marron noir #271210,
   qui est déjà l'encre du site, est le seul aplat de la charte qui tienne les deux —
   rose 3,66, pêche 11,55 — et il n'introduit aucune couleur nouvelle.

   Elle est sombre EN PERMANENCE. Laissée transparente en haut de l'accueil, elle
   reposait le logo sur le hero clair et le défaut revenait au premier écran, là où il
   compte le plus. Plus de flou d'arrière-plan non plus : il n'avait de sens que sous
   une barre translucide, et il se recalculait à chaque pixel défilé. */
.site-head {
  position: fixed; inset: 0 0 auto; z-index: 50;
  background: var(--ink); color: var(--deep-ink);
  transition: box-shadow .4s, transform .4s var(--ease);
}
.site-head.is-solid { box-shadow: 0 1px 0 rgba(245, 237, 224, .16) }
.site-head .wrap { display: flex; align-items: center; justify-content: space-between; height: var(--tete) }
/* 44 px de haut : au doigt, la marque et le bouton de l'en-tête sont des cibles
   comme les autres, et le texte seul ne faisait que 26 px. Mesuré par
   _tests-site/passe-mobile.mjs. */
.brand { text-decoration: none; display: flex; align-items: center; min-height: 44px }
/* Le logo entier, reine et lettrage, et rien d'autre : le nom écrit à côté en
   Bricolage ferait doublon avec le lettrage dessiné. Il reste dans l'attribut alt,
   qui suffit aux moteurs, et le lien garde son aria-label.
   Le fichier est un lockup horizontal monté à partir du logo vertical de la charte,
   comme l'enseigne de la boutique : posée debout, la marque fait 36 px de large à
   56 px de haut et son lettrage 6 px par ligne. Voir CONTROLE-QUALITE.md.
   Aucun recadrage ici — ni rayon, ni débordement caché, ni `cover` : la hauteur
   commande, la largeur suit. Dimensions écrites sur l'image : la barre ne bouge pas
   pendant son chargement. */
.brand-logo { display: block; height: 56px; width: auto; object-fit: contain }

/* ---------- les quatre portes, en barre et en panneau ---------- */
/* Le même menu partout, dans le même ordre et avec les mêmes mots : louer la
   salle, la danse, la boutique, le massage. Quatre liens depuis l'ouverture du
   salon Mandala Shanti — « Massage » était jusque-là un <span> portant une pastille
   « Bientôt », puisqu'il n'y avait rien à ouvrir.
   Seule la destination de la première entrée change — sur la page Salle elle
   descend au formulaire, puisqu'on y est déjà. Le libellé ne bouge pas : une
   entrée qui se renomme d'une page à l'autre oblige le visiteur à la reconnaître
   deux fois. */
.nav { display: flex; align-items: center; gap: 26px; font-size: var(--t-ui) }
.nav a { text-decoration: none }
/* L'or de la charte au survol : le rose s'arrête à 3,45:1 sur ce fond et un libellé
   de 15 px en demande 4,5. L'or y est à 9,34. */
.nav a:not(.btn):hover { color: var(--or) }
/* Le bouton de la barre s'inverse : le bordeaux du bouton général ne fait que 1,40:1
   sur ce marron, il s'effacerait. Crème plein, encre sombre dessus, or au survol. */
.nav .btn { --b: var(--bg); color: var(--ink); min-height: 44px; padding: 0 20px; font-size: var(--t-ui) }
.nav .btn:hover { background: var(--or); border-color: var(--or); color: var(--ink) }
/* La bulle : le bouton du menu au doigt. Deux traits qui deviennent une croix. */
.bulle { display: none; width: 46px; height: 46px; padding: 0; border-radius: 50%;
  border: 1px solid rgba(245, 237, 224, .34); background: transparent; color: inherit;
  cursor: pointer; place-items: center; align-content: center; gap: 5px; justify-items: center }
.bulle span { display: block; width: 17px; height: 1.5px; background: currentColor; border-radius: 2px;
  transition: transform .3s var(--ease) }
body.menu-ouvert .bulle span:first-child { transform: translateY(3.25px) rotate(45deg) }
body.menu-ouvert .bulle span:last-child { transform: translateY(-3.25px) rotate(-45deg) }
@media (prefers-reduced-motion: reduce) { .bulle span { transition: none } }

/* Sous 920 px les quatre entrées ne tiennent plus sur la ligne : elles passent
   dans un panneau qui descend sous la barre, toute la largeur, une entrée par
   ligne et 60 px de haut chacune. Le voile derrière sert à deux choses : dire
   que la page est en attente, et donner une surface à toucher pour refermer. */
@media (min-width: 861px) {
  :root { --f-display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif }
}

@media (max-width: 920px) {
  .bulle { display: grid }
  .nav {
    position: fixed; inset: var(--tete) 0 auto 0;
    display: grid; gap: 0; align-items: stretch;
    background: var(--ink); padding: 14px var(--gutter) 20px;
    border-bottom: 1px solid rgba(245, 237, 224, .16);
    box-shadow: 0 22px 44px -28px rgba(39, 18, 16, .8);
    transform: translateY(-14px); opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity .26s var(--ease), transform .3s var(--ease), visibility .3s;
  }
  body.menu-ouvert .nav { transform: none; opacity: 1; visibility: visible; pointer-events: auto }
  body.menu-ouvert::after { content: ""; position: fixed; inset: 0; z-index: 40; background: rgba(39, 18, 16, .34) }
  .nav a:not(.btn) {
    font: 400 var(--t-h5)/1 var(--f-display); letter-spacing: -.02em; color: var(--deep-ink);
    min-height: 60px; display: flex; align-items: center; gap: 12px;
    border-top: 1px solid rgba(245, 237, 224, .16);
  }
  .nav .btn { width: 100%; justify-content: center; min-height: 56px; margin-bottom: 10px }
  @media (prefers-reduced-motion: reduce) { .nav { transition: none } }
}
@media (max-width: 760px) { :root { --tete: 64px } .brand-logo { height: 44px } }
/* Téléphone couché, ou fenêtre basse : 76 px d'en-tête sur 390 px de haut, c'est
   un cinquième de l'écran pris par une barre. Elle se resserre, sans descendre
   sous les 44 px de la cible tactile qu'elle contient. */
@media (max-height: 520px) {
  :root { --tete: 54px }
  .brand-logo { height: 38px }
  /* Panneau plus haut que l'écran couché : il défile au lieu de déborder. */
  @media (max-width: 920px) { .nav { max-height: calc(100svh - var(--tete)); overflow-y: auto } }
}

/* ---------- apparitions (sûres : visibles si le JS ne tourne pas) ---------- */
/* L'opacité et la translation n'ont pas la même durée : le texte est plein à 30 % de
   la course, pendant qu'il finit de monter. C'est ce décalage qui donne du poids au
   mouvement — et il supprime la longue fenêtre pendant laquelle un bloc entrant dans
   le cadre est illisible. */
.js [data-reveal] { opacity: 0; transform: translateY(22px); transition: opacity .28s var(--ease), transform .9s var(--ease); transition-delay: var(--d, 0s) }
.js [data-reveal].is-in { opacity: 1; transform: none }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none }
}

/* ---------- sections ---------- */
section { position: relative }
.pad { padding-block: clamp(80px, 11vw, 160px) }
.section-head { display: grid; gap: 18px; margin-bottom: clamp(40px, 5vw, 72px); max-width: 760px }

/* ---------- arche (motif de la porte) ---------- */
.arch { border-radius: var(--arch); overflow: hidden; background: var(--bg-alt) }
.arch img { width: 100%; height: 100%; object-fit: cover }

/* ---------- pied de page ---------- */
/* Trois registres : de quoi nous joindre, centré ; le nom du lieu en très grand et
   à presque pas d'encre, qui défile ; la barre légale sous un filet. Le plus gros
   caractère de toute la page est ici, et c'est l'échelle qui le porte, pas la couleur. */
.site-foot { position: relative; overflow: hidden; background: var(--deep); color: var(--deep-ink); padding: 72px 0 36px }
.site-foot a { color: var(--deep-ink) }

/* Un seul bloc, centré : l'adresse, le mail, le téléphone. Les deux colonnes de
   liens qui l'entouraient répétaient la barre de navigation, mot pour mot. */
.foot-trouver { display: grid; justify-items: center; text-align: center; gap: 6px }
.foot-trouver h2 { font: 400 var(--t-h5)/1 var(--f-display); letter-spacing: -.02em; opacity: .78; margin: 0 0 14px }
.foot-trouver p { margin: 0; font: 400 var(--t-lede)/1.5 var(--f-display); letter-spacing: -.01em }
.foot-trouver a { text-decoration: none; opacity: .9;
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; padding-bottom: 3px }
.foot-trouver a:hover { opacity: 1 }

/* Le nom du lieu, en bande défilante. Deux exigences tiennent la boucle :
   la piste contient exactement DEUX groupes identiques, et l'animation la
   décale de la moitié de sa largeur. À l'instant où elle se rembobine, le
   second groupe est pile là où le premier était — aucun saut, aucun trou.
   Tout est en CSS : rien à calculer à chaque image, le compositeur suffit,
   et un iPhone n'a rien d'autre à faire que déplacer une couche. */
/* La hauteur de la bande vient du nom lui-même, elle n'est plus posée à la main.
   Elle l'était — `clamp(46px, 11vw, 150px)` — et la police, elle, vaut 16,4vw :
   les deux échelles divergent dès qu'on élargit la fenêtre. Mesuré : à 1440 px
   l'encre du mot fait 168 px de haut dans une bande de 150, à 1920 px elle en
   fait 224 dans la même bande de 150. `overflow: hidden` rognait donc le haut
   des capitales et le bas des jambages, d'autant plus fort que l'écran est large.
   En hauteur automatique, la bande vaut exactement la ligne du mot. */
.marque-bande { overflow: hidden; margin-top: clamp(48px, 6vw, 96px);
  display: flex; align-items: center }
.marque-piste { display: flex; width: max-content; will-change: transform;
  animation: defile 30s linear infinite }
.marque-groupe { display: flex; align-items: center; flex: 0 0 auto }
.marque-groupe b {
  /* L'interlignage fait la hauteur de la ligne, donc de la bande. Métriques
     mesurées de Bricolage Grotesque 600 : montante 0,932 em, descendante
     0,271 em (zone de contenu 1,203 em), encre du mot 0,720 em au-dessus de la
     ligne de base et 0,014 em en dessous. Le demi-interligne vaut (L − 1,203)/2,
     donc le haut de l'encre tombe à (L − 1,203)/2 + 0,212 : il reste positif
     tant que L ≥ 0,78. 0,85 laisse 0,035 em d'air en haut et 0,081 em en bas —
     assez pour absorber une variation de rendu, assez peu pour que la bande
     reste une bande et non un bloc. */
  font: 600 var(--t-marque)/.85 var(--f-display); letter-spacing: -.045em; white-space: nowrap;
  /* L'axe optique de Bricolage change la chasse selon la taille : figé ici, pour que
     le mot garde la même largeur à toutes les largeurs de fenêtre. */
  font-optical-sizing: none;
  color: rgba(245, 237, 224, .09);
}
/* La bande ne porte plus de motif entre deux passages du nom. Elle en a porté deux —
   l'arche, puis le logo — et le logo a été retiré : en bas de l'accueil il tombait dans
   le même écran que celui de la carte de demande, et la cliente voyait la marque deux
   fois à trois centimètres d'intervalle. Celui de la carte reste ; c'est lui qui a un
   rôle. Ce qui sépare les deux passages du nom est maintenant un simple vide.
   Le retrait est à droite, donc identique sur les deux groupes : la piste vaut toujours
   exactement le double d'un groupe, et la boucle reste sans couture. */
.marque-groupe { padding-right: 6vw }
@keyframes defile { from { transform: translateX(0) } to { transform: translateX(-50%) } }
/* Mouvement réduit : la bande s'arrête, le nom reste là. */
@media (prefers-reduced-motion: reduce) { .marque-piste { animation: none } }

.foot-bottom { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  margin-top: clamp(30px, 4vw, 48px); padding-top: 28px; font-size: var(--t-micro); opacity: .78;
  border-top: 1px solid rgba(245, 237, 224, .18) }
/* Les cibles tactiles se règlent au doigt, pas à la largeur. La largeur servait
   jusqu'ici de test pour savoir si on était sur un téléphone : elle donne la mauvaise
   réponse dès qu'on le tourne, puisqu'un iPhone couché fait 844 px de large. Les liens
   du pied retombaient alors à 21 px et ceux de la barre à 25. `pointer: coarse` pose
   la seule question qui compte — est-ce un doigt ou une souris — et laisse le bureau
   intact. Mesuré par _tests-site/passe-mobile.mjs, qui passe les trois écrans. */
@media (pointer: coarse) {
  /* Les entrées du panneau font déjà 60 px : cette règle ne vaut plus que pour la
     barre en largeur de tablette, où elles sont encore sur une ligne. */
  .nav a:not(.btn) { padding: 10px 0 }
  /* 12 px de part et d'autre, pas 11 : à 13 px de corps et 1,65 d'interligne, la
     ligne fait 21,45 px, et 11 px de chaque côté donnent 43,45 — un pixel sous les
     44 exigés. Relevé par _tests-site/page-404.mjs, qui l'a attrapé. */
  .foot-trouver a, .foot-bottom a { display: inline-block; padding: 12px 0 }
  .foot-trouver { gap: 0 }
  .foot-bottom { row-gap: 0 }
  /* Le téléphone et l'adresse de la FAQ sont seuls sur leur ligne : ce sont des
     cibles à part entière, pas des liens posés au milieu d'une phrase. */
  li > a.link { display: inline-block; padding: 10px 0 }
}

/* ---------- le passage d'une page à l'autre ---------- */
/* Cliquer une porte ne recharge plus brutalement : l'arche de la carte DEVIENT l'arche
   de la page Salle, et le reste des deux pages se croise derrière elle. Le nom
   `view-transition-name` est porté par les deux arches, c'est lui qui les apparie.
   Rien à télécharger : c'est l'API native du navigateur. Là où elle n'existe pas —
   Firefox à ce jour — la navigation reste simplement instantanée, comme avant.
   Le nom doit rester unique dans la page : une seule arche de chaque côté le porte. */
@view-transition { navigation: auto }

::view-transition-group(porte) {
  animation-duration: .62s;
  animation-timing-function: var(--ease);
}
/* Le fond se croise plus vite que l'arche ne voyage : l'arche reste ainsi la seule
   chose que l'œil suit, au lieu de flotter au milieu d'un fondu général. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .38s }

/* Le mouvement réduit coupe le passage, pas la navigation. */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none }
}
