/* =========================================================================
   AMORE CORP — le studio (piste B « la salle de projection », 30/09/2026)
   Tout ce qui suit la traversée sur l'accueil : la salle, le rideau (ce que
   fait la maison, les prix en générique), le contact. Chargé par l'accueil
   seul ; styles.css garde le commun (en-tête, pied, appels).

   TROIS RÈGLES QUI TIENNENT TOUT LE FICHIER
   1. Tous les fonds du studio sont OPAQUES : plus une particule derrière le
      contenu. La scène 3D s'arrête derrière lui (voir `.temoin`).
   2. L'état par défaut est l'état OUVERT : sans script, en mouvement réduit,
      ou script en 404, la salle est une suite d'images lisibles, rien n'est
      masqué. `.cine` (posée par studio.js) ne fait qu'ajouter le montage ;
      `.tranche` (posée par tranche.js) ne fait qu'ajouter le passage de la
      coupe — sans elle, c'est le fondu d'1 s.
   3. La mention de l'article 50 se règle à UN endroit (`.salle-mention`),
      dans sa couleur, sur son propre fond.
   ========================================================================= */

:root{
  /* L'en-tête COLLÉ, calculé depuis ses règles de styles.css : padding
     .85rem × 2 + appel de 44 px + filet d'1 px. studio.js le remesure sur la
     vraie boîte dès qu'il est collé ; cette valeur n'est que le repli. */
  --tete:calc(1.7rem + 45px);
  --mh:2.9rem;         /* hauteur de la mention ; studio.js pose la vraie */
  /* le format des tirages de la salle (atelier/img/salle/) : 21:9 sur écran
     couché, 4:5 debout (voir plus bas) — la suite d'images les montre sans
     rognure, au format exact */
  --scope:2560/1086;
  --nb:7;              /* nombre de pièces (les cases du banc, téléphone) */
  /* LA POSE (06/10) — la course où la salle reste entière avant que le clair
     ne monte. UNE pose, plus une longueur par pièce : le défilement ne change
     plus la pièce, on la choisit.
     ⚠ ELLE SE RÈGLE SUR LE FONDU, PAS SUR UN NOMBRE DE CRANS. La salle se lève
     en 1 s (LE FONDU D'ENTRÉE) pendant qu'on continue de défiler : à la
     molette continue (~700 px/s, un cran de 100 px toutes les 120 ms), une
     pose de 220-300 px laissait le clair monter à +0,45 s, montre à demi
     levée, vignettes jamais nettes (banc du 06/10). Il faut le fondu (nette à
     95 % vers 0,75 s) PLUS ~0,5 s de salle nette, avec une marge pour
     WebKit (0,55 s seulement à 860 px) : 940 px AU MOINS, un plancher en
     pixels parce qu'un cran de molette fait 100 px sur tous les écrans.
     (Les « 456 px, la page ne répond plus » d'avant valaient pour UNE pièce
     sur sept, pas pour la salle entière.) */
  --pose:clamp(940px,125vh,1120px);
  /* LA REMONTÉE (03/10) : la piste commence une demi-fenêtre AU-DESSUS de
     la salle, pour que l'écran collé y soit déjà à sa place quand on remonte.
     Le navigateur fait défiler avant que studio.js ait levé la coupe : il y
     avait 1 image où la salle descendait d'un cran, une bande noire sous
     l'en-tête. L'écran reste collé pendant cette image-là. */
  --avance:50vh;
  --gris-clair:#555D69;/* le texte courant sur l'ivoire : 5,6:1 sur #E9ECF1 */
  /* LE PASSAGE (tranche.js, 10/2026) — sa course : la longueur de molette entre
     la coupe et la pièce au point. EN PIXELS, la même sur tous les écrans
     (accord d'Enzo du 10/10 : la même durée partout — un cran de molette fait
     100 px quel que soit l'écran) : 1 940 px, la course du labo sur son Mac.
     Bornée pour les seuls écrans hors norme : jamais moins d'un écran et demi,
     jamais plus de quatre et demi. Elle ne s'applique que sous .tranche-longue
     (posée par studio.js avec le mode salle, quand la page porte le passage).
     Le passage lui-même en occupe les neuf premiers dixièmes (tranche.js :
     FIN) ; le dernier dixième est déjà de la pose. */
  --tranche-course:clamp(150vh,1940px,450vh);
  /* LA POSE APRÈS LE PASSAGE (accord d'Enzo du 10/10 : « vers 500 »). --pose
     se réglait sur le fondu d'1 s ; le passage n'en a pas, la pièce y arrive
     déjà nette : il reste à laisser la salle entière une demi-seconde à la
     molette continue. Mesuré au banc (≈ 700 px/s, Chrome et WebKit) : avec
     500 px de salle « à la main » avant le clair, elle l'a 0,45 à 0,58 s ;
     avec 560 px, 0,60 à 0,68 s. Depuis le 11/10 la salle a la main dès que
     l'image est posée et sa bande pleine (tranche.js, MAIN : 0,86 de la
     course), 272 px avant la fin de la course : la pose vaut le reste —
     290 px, soit 562 px de salle à la main. En pixels, comme la course : un
     cran de molette fait 100 px sur tous les écrans. */
  --tranche-pose:290px;
}
@supports (height:1svh){ :root{--pose:clamp(940px,125svh,1120px);--avance:50svh;--tranche-course:clamp(150svh,1940px,450svh);} }
/* écran debout : les tirages 4:5 (la même requête que les <source> du HTML) */
@media (orientation:portrait){ :root{--scope:4/5;} }

/* ---------------------------------------------------------------- le film
   Repli CSS de la toile du voyage sur un écran debout : la même image que
   celle que sequence.js y peindra (dossier vertical, même requête média que
   le script), au lieu de l'image couchée zoomée 2,6 fois. Rien d'autre du
   voyage n'est touché. */
@media (max-aspect-ratio:4/5){
  .voyage .plan-colle{background-image:url(/ouverture-v/f001.webp);}
}

/* ---------------------------------------------------------------- la coupe
   Posée par studio.js sur <html> quand le haut de la salle touche le haut
   de l'écran — c'est-à-dire quand le point d'or de « preuves. » passe le
   milieu (la marge négative du studio est calculée pour ça). Depuis le 05/10,
   la salle s'y lève en 1 s par-dessus le tunnel (voir LE FONDU D'ENTRÉE) ;
   le tunnel, le grain et la réglette partent à la fin du fondu.
   La réglette part AVEC le tunnel : elle s'arrêtait net au milieu de
   l'écran, sur le bord invisible de la salle (vu au contrôle du 30/09).
   Depuis l'intégration du passage (10/2026), CE FONDU EST LE REPLI : il joue
   quand le passage n'est pas armé (`:not(.tranche)` : pas de carte graphique,
   script absent, page rechargée au milieu…) ou quand on arrive par un saut
   (`.tranche-fondu` : un onglet, la touche Fin — et la panne en route). Le
   passage, lui, est réglé plus bas (LE PASSAGE). */
.coupe:not(.tranche) #scene,.coupe:not(.tranche) .grain,.coupe:not(.tranche) .reglette,
.coupe.tranche-fondu #scene,.coupe.tranche-fondu .grain,.coupe.tranche-fondu .reglette{visibility:hidden;transition:visibility 0s linear 1s;}
/* LE FONDU D'ENTRÉE (05/10, Enzo : « la montre spawn d'un coup »). La coupe
   reste au même instant, mais la salle ne tombe plus d'une image : pendant
   1 s elle se LÈVE par-dessus le tunnel et la phrase, qui restent dessous
   (leur disparition est retardée d'autant, ci-dessus) — un fondu enchaîné,
   jamais un passage au noir (l'ancienne « lampe » de 300 ms noirs avait l'air
   d'un plantage). Courbe douce aux deux bouts : en « sortie rapide » (0,7 s),
   le fondu faisait tout en 0,1 s et la montre surgissait encore. Fondent le
   fond, les images et la bande du générique ; la MENTION, elle, est là,
   pleine, dès la première image — une image générée n'est jamais à l'écran
   sans sa mention lisible. Au retour vers le tunnel, rien
   ne fond : il revient d'un coup, comme il était. */
@keyframes salle-fond{from{background-color:rgba(10,11,13,0);}to{background-color:#0A0B0D;}}
@keyframes salle-image{from{opacity:0;transform:scale(1.025);}to{opacity:1;transform:none;}}
@keyframes salle-bande{from{opacity:0;}to{opacity:1;}}
.cine.coupe:not(.tranche) .salle,.cine.coupe.tranche-fondu .salle{animation:salle-fond 1s cubic-bezier(.45,.05,.25,1) both;}
.cine.coupe:not(.tranche) .ecran,.cine.coupe.tranche-fondu .ecran{animation:salle-image 1s cubic-bezier(.45,.05,.25,1) both;}
.cine.coupe:not(.tranche) .bande,.cine.coupe.tranche-fondu .bande{animation:salle-bande 1s cubic-bezier(.45,.05,.25,1) both;}
/* LE SAUT QUI SURVOLE LA COURSE DU PASSAGE ET SE POSE DANS LA SALLE (tranche.js pose .tranche-vol au clic de l'onglet
   « Le travail », depuis le dessus de la coupe). La page défile encore pendant que la salle se lève : la phrase est
   déjà partie, et le début lent du fondu laissait 12 images presque noires (banc du 11/10). Le fondu part donc un
   quart de seconde « en avance » : même courbe, son début immobile en moins (à 0,25 s il n'a encore levé que 8 % :
   aucune marche visible). Jamais pour un saut qui dépasse la salle (« Les prix », touche Fin). */
.cine.coupe.tranche-vol:not(.tranche) .salle,.cine.coupe.tranche-vol.tranche-fondu .salle,
.cine.coupe.tranche-vol:not(.tranche) .ecran,.cine.coupe.tranche-vol.tranche-fondu .ecran,
.cine.coupe.tranche-vol:not(.tranche) .bande,.cine.coupe.tranche-vol.tranche-fondu .bande{animation-delay:-.25s;}
/* le léger agrandissement du fondu ne déborde pas de l'écran (sans ça, 5 relevés
   de débordement horizontal à la recette du 05/10, le temps du fondu) */
.cine .scene-salle{overflow:clip;}
/* Avant la coupe, le studio attend, invisible : il chevauche le bas de la
   traversée (marge négative calculée par studio.js), et le tunnel doit y
   rester entier jusqu'au point d'or. Sans script, rien de tout ça. */
.cine:not(.coupe) .studio{visibility:hidden;}

/* ---------------------------------------------------------------- le passage
   « La tranche devient l'écran » (10/2026, tranche.js). TOUT ce bloc est sous
   `.tranche`, que tranche.js ne pose sur <html> que s'il peut tourner (mode
   salle, carte graphique, tout chargé, page au-dessus de la coupe). SANS
   ELLE, LA FEUILLE FAIT CE QU'ELLE FAISAIT : le fondu d'1 s ci-dessus.
   Les états :
   · .tranche-longue posée par studio.js avec le mode salle, confirmée par
                     tranche.js : LA PAGE A LA LONGUEUR DU PASSAGE (sa course,
                     sa pose, l'arrivée de l'onglet), qu'il soit armé ou non —
                     elle ne change donc jamais de longueur en route (un onglet
                     cliqué pendant que tranche.js arrive ou se construit, une
                     page rechargée dans la salle arrivent où ils doivent).
                     Retirée seulement s'il ne peut pas tourner du tout ;
   et, posés par tranche.js au fil de la molette :
   · .tranche        le passage est armé : c'est lui qui joue à la coupe ;
   · .tranche-plein  la nuit est pleine sur le tunnel (fin de l'entrée du A) ;
   · .tranche-bande  la photo se retire vers l'écran de la salle : la bande
                     entre dans la place qu'elle libère ;
   · .tranche-pose   la lentille tient l'écran de la salle : l'<img> se montre
                     dessous ;
   · .tranche-choix  la bande est à moitié visible : elle répond déjà (clic,
                     toucher, clavier) — une vignette qu'on voit n'est jamais
                     morte ; y choisir une pièce pose la salle d'un coup ;
   · .tranche-main   l'image est posée, la bande pleine : LA SALLE A LA MAIN
                     (flèches et glisser compris) pendant que la toile finit
                     de s'effacer sur l'image ;
   · .tranche-fini   la toile est partie (0,9 de la course) : le reste de la
                     course n'est plus que de la pose ;
   · .tranche-fondu  arrivée par un saut (onglet, touche Fin) ou panne : à la
                     coupe c'est le fondu d'1 s qui joue, pas le passage ;
   · .tranche-queue  la coupe vient de se lever en remontant : la scène finit
                     de se résorber dans le point d'or (0,2 s au plus) ;
   · .tranche-panne  la carte graphique a lâché en route (avec .tranche-fondu :
                     la photo et la bande ; la course est gardée).
   Les variables ont pour repli l'état OUVERT (nuit pleine, image et bande
   entières) : un script en panne ne laisse rien de masqué. */
.tranche-toile,.tranche-course{display:none;}
.cine.tranche-longue .tranche-course{display:block;height:var(--tranche-course);}
/* LA TOILE : la largeur de l'écran et sa GRANDE hauteur (lvh). Sur iPhone, la
   barre d'adresse qui se replie ne change donc pas sa boîte — rien n'est
   réalloué en plein geste ; ce qui dépasse de l'écran collé est rogné
   (overflow:clip, plus haut). */
.cine.tranche .tranche-toile{
  display:block;position:absolute;left:0;top:0;width:100%;height:100vh;
  z-index:2;pointer-events:none;
}
@supports (height:1lvh){ .cine.tranche .tranche-toile{height:100lvh;} }
/* la bande passe devant la toile : le générique n'est jamais sous la lumière */
.cine.tranche .bande{position:relative;z-index:3;}

/* L'ENTRÉE DU A. La nuit de la salle ne tombe pas d'un coup : c'est l'écran
   collé qui la porte (il couvre tout l'écran, y compris pendant la queue de
   la remontée), de transparente à pleine — le tunnel tourne encore dessous.
   Le halo est celui du labo, très doux, derrière le A. */
.cine.tranche:not(.tranche-fondu) .salle{background-color:transparent;}
.cine.tranche:not(.tranche-fondu) .scene-salle{
  background:
    radial-gradient(ellipse 62% 58% at 50% 50%,rgba(15,31,51,calc(.5 * var(--tranche-halo,0))),rgba(15,31,51,0) 72%),
    rgba(10,11,13,var(--tranche-fond,1));
}
/* la phrase s'efface plus vite que le tunnel. Règle plus précise que celle de
   styles.css, qui n'est pas touché ; hero.js garde la main sur --traversee.
   (En mouvement réduit, .tranche n'est jamais posée : la phrase reste pleine.) */
.tranche .traversee .phrase{opacity:calc(var(--traversee,1) * var(--tranche-phrase,1));}
/* LE POINT D'OR RESTE, ET DEVIENT LE A. Tant que la coupe est posée, c'est
   l'écran collé qui porte le point (.tranche-point : un disque du même or,
   que tranche.js pose à la même place et à la même taille dans l'image où la
   coupe tombe) : celui de la phrase s'éteint, pour qu'il n'y en ait jamais
   deux — les mots montent et s'effacent, le point reste au fond du tunnel, le
   A grandit autour de lui et il s'y résorbe. L'opacité seule : la boîte du
   point de la phrase ne bouge pas (hero.js et studio.js la lisent). Jamais
   pendant un fondu ni une panne (.tranche-fondu) : la phrase y reste entière.
   Le disque : un élément de la page, à la pleine définition de l'écran (la
   toile, plafonnée en surface, le rendait mou à côté du point de la phrase).
   Tant que le script ne l'a pas posé (attribut hidden), il n'existe pas.
   ⚠ LES DEUX RÈGLES TIENNENT À LA MÊME CLASSE (.coupe) : dans l'image où la
   coupe tombe ou se lève, l'un paraît et l'autre s'éteint ensemble. Le disque
   ne se montre donc jamais sans la coupe — pendant la queue de la remontée
   (.tranche-queue) c'est le point de la phrase qui est là, et le A finit de
   rentrer en lui (vu au film : sans cela, deux points pendant 0,08 s).
   EN REMONTANT, LE POINT NE S'ÉTEINT PAS (12/10). À la levée de la coupe la
   phrase n'est pas encore revenue (elle suit la scène, 0,2 s de retard) : son
   point, pris dans son opacité, relayait le disque à 54 % à 250 px/s, 10 % à
   500, 0 au-delà — il clignotait. Pendant la queue, les mots reviennent donc
   par leur ENCRE (l'alpha de leur couleur, l'ivoire des titres ; le produit
   est le même qu'avant), et le point d'or, qui a sa propre couleur, reste
   entier : c'est le relais de la descente, à l'envers. Il paraît comme le
   disque (--tranche-point, posée par tranche.js : nul tant que le A est assez
   grand pour porter l'or seul, entier dès qu'il est petit). C'est le point de
   la PAGE, pas le disque : il défile avec ses mots, au pixel. */
.tranche.tranche-queue:not(.tranche-fondu) .traversee .phrase{
  opacity:var(--traversee,1);color:rgba(242,244,247,var(--tranche-phrase,1));
}
.tranche.tranche-queue:not(.tranche-fondu) .traversee .point-d-or{opacity:var(--tranche-point,1);}
.tranche.coupe:not(.tranche-fondu) .traversee .point-d-or{opacity:0;}
.tranche-point{display:none;}
.cine.tranche.coupe:not(.tranche-fondu) .tranche-point:not([hidden]){
  display:block;position:absolute;left:0;top:0;z-index:2;pointer-events:none;
  /* 16 px, mis à l'échelle depuis son coin par tranche.js (POINT_BOITE) : une
     boîte de taille fractionnaire serait arrondie au pixel, le disque avec */
  width:16px;height:16px;transform-origin:0 0;
  border-radius:50%;background:var(--or);opacity:var(--tranche-voile,1);
}
/* le tunnel, le grain et la réglette partent quand la nuit est pleine, sans délai */
.coupe.tranche-plein:not(.tranche-fondu) #scene,
.coupe.tranche-plein:not(.tranche-fondu) .grain,
.coupe.tranche-plein:not(.tranche-fondu) .reglette{visibility:hidden;}

/* PENDANT LE PASSAGE, la salle ne montre rien d'elle-même : c'est la toile
   qui porte l'image. L'écran (et la pièce active, nommée : elle sortirait de
   son parent caché) ne se montre que lorsque la lentille le recouvre
   exactement. La bande, elle, entre PENDANT que la photo se retire vers
   l'écran de la salle (.tranche-bande), liée à la molette : jamais une bande
   vide sous l'image. Elle ne prend ni clic ni clavier tant qu'elle n'est pas
   à moitié visible (tranche.js la rend inerte jusqu'à .tranche-choix), et les
   prend ensuite : une vignette qu'on voit répond. --tranche-voile : le fondu
   d'un saut. */
.cine.tranche:not(.tranche-fondu):not(.tranche-pose) .ecran,
.cine.tranche:not(.tranche-fondu):not(.tranche-pose) .salle-plan.actif,
.cine.tranche:not(.tranche-fondu):not(.tranche-pose) .salle-plan.sous,
.cine.tranche:not(.tranche-fondu):not(.tranche-bande) .bande{visibility:hidden;}
.cine.tranche:not(.tranche-fondu) .ecran{opacity:var(--tranche-voile,1);}
.cine.tranche:not(.tranche-fondu) .bande{opacity:calc(var(--tranche-bande,1) * var(--tranche-voile,1));}
/* la légende de la bande : sur un écran debout elle attend que la photo ait
   dégagé sa ligne (tranche.js, PLAGE_LEGENDE) — repli : 1, entière */
.cine.tranche:not(.tranche-fondu) .credit{opacity:var(--tranche-legende,1);}
.cine.tranche:not(.tranche-fondu):not(.tranche-choix) .bande{pointer-events:none;}
/* la toile est partie : l'<img> est exactement dessous */
.cine.tranche.tranche-fini .tranche-toile,
.cine.tranche.tranche-fondu .tranche-toile{visibility:hidden;}

/* LA QUEUE DE LA REMONTÉE. La coupe se lève quand le haut de la salle repasse
   sous le haut de l'écran ; la scène, lissée sur 0,2 s, a encore un peu de
   retard : le studio reste visible ce temps-là, pour que le A finisse de se
   résorber dans le point d'or au lieu de disparaître d'un coup. (L'écran est
   encore collé : la piste commence une demi-fenêtre au-dessus de la salle.) */
.cine.tranche.tranche-queue .studio{visibility:visible;}

/* LA MENTION ARRIVE AVEC LA PIÈCE, PAS AVEC LE A (le A est construit à la
   main : la mention « générés par intelligence artificielle » ne se lit pas
   sous lui). tranche.js la fait entrer à la molette quand la tranche s'allume
   et la tient PLEINE dès que la pièce peut se voir (--tranche-mention). Repli
   de la variable : 1, la mention pleine. Dans tous les autres modes (fondu,
   panne, sans passage, mouvement réduit, sans script) cette règle ne
   s'applique pas : la mention est pleine dès la coupe, comme avant.
   ⚠ C'est la SEULE opacité posée sur la mention, et elle ne vaut que tant
   qu'aucune image générée n'est à l'écran : son contraste, lui, se règle
   toujours à un seul endroit (.salle-mention). */
.cine.tranche:not(.tranche-fondu):not(.tranche-panne) .salle-mention{opacity:var(--tranche-mention,1);}

/* la pose après le passage, et l'onglet « Le travail » : il pose la page sur
   la pièce déjà nette, la toile partie — à 0,9 de la course (tranche.js :
   FIN, le même nombre) —, pas au début du passage. Sous .tranche-longue, pas
   sous .tranche : la longueur de la page ne dépend pas de l'armement (voir
   plus haut). */
.cine.tranche-longue .defile{height:var(--tranche-pose);}
.cine.tranche-longue .salle{scroll-margin-top:calc(-5.5rem - .9 * var(--tranche-course));}

/* ---------------------------------------------------------------- le studio */
.studio{position:relative;}

/* LES TÉMOINS. Des éléments vides qui portent .ivoire pour entrer dans la
   liste des sections opaques de hero.js — et dont on neutralise tout ce que
   .ivoire dessine : fond, coutures (::before/::after), position relative.
   `visibility:hidden` et pas `display:none` : hero.js lit leur boîte
   (getBoundingClientRect), et une boîte en display:none vaut zéro. */
.studio > .temoin,.pied > .temoin{
  position:absolute;left:0;width:1px;
  visibility:hidden;pointer-events:none;background:none;
}
.studio > .temoin{top:0;bottom:0;}
/* à la coupe le haut du studio est déjà au haut de l'écran ; il remonte en
   plus d'un écran, par sécurité contre les arrondis de la marge calculée */
.coupe .studio > .temoin{top:-100vh;}
/* PENDANT LE PASSAGE, le tunnel doit tourner tant qu'on le voit sous la nuit
   qui tombe : le témoin ne couvre l'écran qu'une fois la nuit pleine À L'ÉCRAN
   (.tranche-plein, posée par tranche.js, qui la retire avant qu'elle ne se
   lève en remontant et signale un défilement : hero.js relit alors sa boîte).
   Jusque-là il commence un écran plus bas : il ne couvre rien — et couvrirait
   quand même au bout d'un écran de défilement si le script s'arrêtait. */
.coupe.tranche:not(.tranche-fondu) .studio > .temoin{top:100vh;}
.coupe.tranche.tranche-plein:not(.tranche-fondu) .studio > .temoin{top:-100vh;}
/* celui du pied part de son bas (4 px sous le bord, contre les arrondis de
   position au bas de page) et remonte d'un écran au-dessus de son haut */
.pied > .temoin{top:-100vh;bottom:-4px;}
.pied{overflow:clip;}   /* le témoin n'allonge pas la page */

/* =========================================================================
   LA SALLE
   ========================================================================= */
.salle{
  position:relative;
  /* 16 : au-dessus de la réglette (15) et du grain (2) — rien ne passe sur
     une image projetée. Seul l'en-tête (20) reste devant. */
  z-index:16;
  background:var(--abysse);color:var(--ivoire-texte);
  /* l'onglet « Le travail » pose la salle au ras de l'écran, pas 88 px
     plus bas (html{scroll-padding-top:5.5rem}) : pile sur la coupe */
  scroll-margin-top:-5.5rem;
}

/* --------------------------------------------- par défaut : une suite d'images */
.scene-salle{padding:clamp(4rem,9vw,7rem) 0 0;}
.ecran{display:grid;gap:clamp(3rem,7vw,5.5rem);}
.salle-plan{margin:0;position:relative;}
.cadre{position:relative;aspect-ratio:var(--scope);overflow:hidden;background:var(--abysse);}
/* TOUTES LES PIÈCES AU MÊME CADRE (06/10, Enzo : « petite photo avec le tour
   noir : il faudrait toutes les photos à la même taille, quitte à créer une
   continuité autour du sujet »). Chaque pièce remplit toute la zone image,
   centrée, sans bord noir : ses tirages ont été agrandis AUTOUR du sujet
   (21:9 couché, 4:5 debout, <picture> du HTML) pour porter ce recadrage.
   Plus aucune pièce en `contain` (le « tour noir » du 05/10). */
.cadre img,.cadre video{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  object-fit:cover;object-position:50% 50%;
}
.salle-plan figcaption{padding:1.1rem var(--marge) 0;}
.metier-p{
  font-family:var(--display);font-style:italic;font-weight:500;
  font-size:1.55rem;line-height:1.1;color:var(--ivoire-titre);margin-right:.5rem;
}
.quoi{font-size:.9rem;line-height:1.5;color:rgba(228,230,234,.86);}
.credit,.montage,.defile{display:none;}
.bande{display:flex;justify-content:flex-end;padding:2.5rem var(--marge) 2.25rem;}

/* LA MENTION — collante par le bas, dernier enfant de la salle (voir le
   commentaire du HTML). Ivoire plein en graisse 600 : 16,9:1 sur la nuit, et
   le fût du I tient sur un écran de densité 1 (règle du 29/09). Sa hauteur
   est la sienne (padding + texte) : studio.js la mesure et la réserve au pied
   de l'écran (--mh), elle ne recouvre donc jamais le lien de l'atelier. */
.salle-mention{
  position:sticky;bottom:0;z-index:5;margin:0;
  display:flex;align-items:center;
  padding:.8rem var(--marge);background:var(--abysse);
  border-top:1px solid var(--filet-sombre);
  font-family:var(--texte);font-size:.78rem;line-height:1.45;font-weight:600;
  letter-spacing:.01em;color:#E9ECF1;
}

/* --------------------------------------------------- le montage (.cine)
   UN ÉCRAN QUI REMPLIT LA FENÊTRE. La pièce prend toute la largeur et toute
   la hauteur qui reste une fois ôtés l'en-tête, la bande du générique et la
   mention ; l'image la remplit (cover, depuis le 06/10). Il avait
   un format fixe (2,39 / 4:5) centré : hors des tailles du banc — MacBook
   1440×790, PC 1536×730, iPhone 390×664 — il flottait entre deux bandes
   noires, avec trois bords gauches (logo, image, générique). Les textes
   tiennent maintenant tous la marge du site : le A, le générique, la mention.

   LA PISTE. L'écran est collé (sticky) dans la piste, qui porte UNE
   pose (--pose ; jusqu'au 06/10, une longueur par pièce : le défilement
   changeait la pièce), puis un écran de plus qu'elle fait DÉBORDER sous le
   clair (marge négative). Après la pose, l'écran reste donc collé et c'est
   le clair qui monte par-dessus, la mention posée sur son bord : la mention
   couvre l'image par le bas et part avec sa dernière ligne. Elle restait
   avant une barre noire sous l'en-tête, au-dessus du clair, alors qu'aucune
   image n'était plus à l'écran. */
.cine .salle{display:flow-root;}   /* la marge de la piste ne sort pas de la salle */
.cine .piste{position:relative;margin-top:calc(-1 * var(--avance));margin-bottom:-100vh;}
/* ⚠ la queue qui déborde est un BLOC (::after), pas un padding : un élément
   collé ne sort jamais de la boîte de CONTENU de son parent, padding exclu.
   En padding, l'écran se décollait à l'arrivée du clair (vu au banc). */
.cine .piste::after{content:"";display:block;height:calc(100vh - var(--mh) + var(--avance));}
.cine .scene-salle{
  position:sticky;top:0;height:100vh;
  padding:var(--tete) 0 var(--mh);
  display:flex;flex-direction:column;
}
/* iPhone : quand la barre d'adresse se replie, la fenêtre grandit (664 →
   745 px) mais 100svh reste la PETITE fenêtre — un trou noir de ~89 px
   s'ouvrait entre le lien de l'atelier et la mention. L'écran suit donc la
   fenêtre RÉELLE (dvh), et la longueur de la page reste en svh : la marge du
   bas (dvh) annule l'écran (dvh), la queue (svh) ne bouge pas — la page ne
   change pas de longueur quand la barre se replie, rien ne saute. */
@supports (height:1dvh){
  .cine .piste{margin-bottom:-100dvh;}
  .cine .piste::after{height:calc(100svh - var(--mh) + var(--avance));}
  .cine .scene-salle{height:100dvh;}
}
.cine .ecran{display:block;position:relative;flex:1 1 auto;min-height:0;width:100%;}
/* au doigt, le glisser horizontal sur l'image change de pièce (studio.js) :
   le navigateur garde le défilement vertical et le zoom, il ne prend plus
   les gestes de côté */
.cine .ecran{touch-action:pan-y pinch-zoom;}
.cine .salle-plan{position:absolute;inset:0;visibility:hidden;}
/* LE DESSOUS (03/10) : la dernière pièce peinte reste visible sous la pièce
   active tant que celle-ci n'est pas décodée (studio.js) — WebKit montrait
   1 à 2 images noires à chaque coupe. Le cadre n'a donc plus de fond à
   lui : c'est le noir de la salle qui est derrière. */
.cine .salle-plan.actif{z-index:1;}
.cine .cadre{background:none;}
.coupe .salle-plan.sous{visibility:visible;}
/* coupe franche : aucun fondu entre deux pièces.
   ⚠ `.coupe` dans le sélecteur, et ce n'est pas une redondance : un enfant en
   `visibility:visible` SORT d'un parent en `visibility:hidden`. Sans lui, la
   pièce active perçait le studio invisible et se posait sur le tunnel avant
   la coupe (vu à la première capture, 30/09). */
.coupe .salle-plan.actif{visibility:visible;}
/* le clair a recouvert tout l'écran collé : l'écran est retiré, vignettes
   comprises (studio.js ; aucun pixel ne change — tout était déjà caché).
   La pièce active est nommée : elle sortirait sinon de son parent caché. */
.coupe .salle.rideau .scene-salle,
.coupe .salle.rideau .salle-plan.actif,
.coupe .salle.rideau .salle-plan.sous{visibility:hidden;}
.cine .cadre{position:absolute;inset:0;aspect-ratio:auto;}
/* les légendes restent dans la page pour les lecteurs d'écran ; à l'œil,
   c'est le générique de la bande qui les montre, une à la fois */
.cine .salle-plan figcaption{
  position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  white-space:nowrap;padding:0;
}
.cine .defile{display:block;height:var(--pose);}

/* LA BANDE — pleine largeur, sur la marge du site : le générique commence au
   bord gauche du A de l'en-tête, le banc et le lien finissent au bord droit
   de l'appel « Réserver trente minutes ». */
.cine .bande{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  grid-template-areas:"credit montage" "credit lien";
  align-items:start;column-gap:2rem;row-gap:.2rem;
  flex:none;width:100%;
  padding:.9rem var(--marge) .35rem;
}
.cine .credit{display:block;grid-area:credit;margin:0;line-height:1.35;}
.cine .montage{display:flex;grid-area:montage;justify-self:end;}
.cine .vers-atelier{grid-area:lien;justify-self:end;}

/* LE BANC DE MONTAGE — c'est lui qui choisit la pièce (06/10 : le
   défilement ne la change plus). Sept cases égales, comme les pièces : la
   vignette y est recadrée au centre. Un filet d'or sous celle qu'on
   projette — l'or désigne. */
.montage{gap:6px;align-items:flex-end;}
.montage button{
  all:unset;cursor:pointer;position:relative;display:block;width:54px;height:36px;
  opacity:.42;transition:opacity .2s ease;
}
.montage button img{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 50%;}
.montage button::after{
  content:"";position:absolute;left:0;right:0;bottom:-6px;height:1px;
  background:var(--or);transform:scaleX(0);transition:transform .25s ease;
}
.montage button[aria-current="true"]{opacity:1;}
.montage button[aria-current="true"]::after{transform:none;}
.montage button:hover{opacity:.8;}
.montage button:focus-visible{outline:2px solid var(--or);outline-offset:3px;opacity:1;}
/* au doigt (tablette), la cible de la maison : 44 px de haut ET de large */
@media (pointer:coarse){ .montage button{width:66px;height:44px;} }

/* =========================================================================
   LE RIDEAU — la salle se rallume
   Le clair monte sur la salle : un fil champagne d'1 px à la lisière, et
   l'ombre douce que la nuit porte sur le papier. Le papier a la matière de
   `.ivoire` (lumière haute à gauche, repli froid en bas à droite).
   ========================================================================= */
.clair{
  position:relative;z-index:3;          /* au-dessus du grain, sous la réglette */
  --focus:var(--bronze);                /* l'or ne fait que 2,1:1 sur l'ivoire */
  color:var(--encre);
  background-color:var(--ivoire);
  background-image:
    radial-gradient(118% 64% at 19% 9%,rgba(255,255,255,.66) 0%,rgba(255,255,255,0) 58%),
    radial-gradient(76% 46% at 97% 88%,rgba(191,200,214,.40) 0%,rgba(191,200,214,0) 74%);
  border-top:1px solid var(--champagne);
}
/* en montage, le clair passe AU-DESSUS de la salle (16) : c'est lui qui
   recouvre l'écran resté collé (la réglette, elle, est partie à la coupe) */
.cine .clair{z-index:17;}
.clair::before{
  content:"";position:absolute;left:0;right:0;top:0;height:56px;z-index:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(10,11,13,.20) 0%,rgba(10,11,13,.07) 45%,rgba(10,11,13,0) 100%);
}
.clair > *{position:relative;z-index:1;}
/* les appels gardent leur dessin (libellé + filet d'or) ; seule l'encre
   passe au bleu sur le papier */
.clair .appel{color:var(--bleu);font-weight:600;}

/* ------------------------------------------ ce que fait la maison */
.maison-dit{padding:clamp(5rem,13vh,8.5rem) var(--marge) clamp(2.5rem,6vh,4rem);}
/* LA LETTRINE — la première lettre du texte lui-même (::first-letter). Elle
   pend dans la marge : son encre tombe sur la marge gauche, et les lignes
   commencent au retrait `--retrait` ; le bloc court jusqu'à la marge droite
   (les deux bords tenus, le vide d'un seul morceau : règle du 05/09).
   ⚠ LE RETRAIT EST RÉGLÉ SUR L'ENCRE DU D, PAS SUR SA BOÎTE. Le 30/09 on
   lisait « D   es sites » : 41 px de blanc entre le D et « es » (en 1440),
   contre 11-12 px pour une espace entre deux mots — le D se détachait du mot
   qu'il commence. Le retrait valait la place de la boîte du D ; il vaut
   maintenant son encre (2,66 em en Cormorant 500, mesurée) plus un filet
   d'air, et la marge droite du D est légèrement négative : ce sont les
   lignes, pas la boîte du D, qui fixent l'écart. Mesuré sur les pixels :
   6 px en 1440, 7 px en 1920 (une espace : 11-12), 3 px sur téléphone
   (une espace : 7) — le D appartient à son mot.
   Marge gauche du D = −(retrait + approche gauche du D, ≈ .165 em mesuré) :
   son encre retombe pile sur la marge. */
.inventaire{
  --retrait:2.76em;
  margin:0 0 0 var(--retrait);
  font-family:var(--display);font-weight:500;color:var(--gris-clair);
  font-size:clamp(1.4rem,2.45vw,2.35rem);line-height:1.3;letter-spacing:-.004em;
  text-wrap:pretty;
}
.inventaire b{font-weight:600;color:var(--bleu);}
/* les em de ::first-letter sont ceux de la lettrine (4,35 fois le texte) :
   d'où la division */
.inventaire::first-letter{
  float:left;font-size:4.35em;line-height:.8;font-weight:500;color:var(--bleu);
  margin:.1em -.02em 0 calc(-1 * (var(--retrait) + .165em) / 4.35);
}

/* ------------------------------------------ les prix, en générique de fin
   Un axe au centre : le format à gauche du blanc, le montant à droite, comme
   un rôle et un nom. Aucun cadre, aucun pointillé, aucun montant géant. */
.prix{padding:clamp(2rem,5vh,3.5rem) var(--marge) clamp(3.5rem,8vh,5.5rem);text-align:center;}
/* le bloc occupe toute la largeur du papier (les prix en pages, 15/10) : une
   page entre par le bord de l'écran, pas par une frontière invisible au milieu
   du clair. Le titre et le pied sont centrés, ils ne dépendaient pas de la
   colonne de 84rem. */
.prix > .dans{max-width:none;}
.prix-tete{
  font-family:var(--display);font-style:italic;font-weight:500;
  font-size:clamp(1.35rem,2vw,1.7rem);line-height:1.2;letter-spacing:0;
  color:var(--bleu);margin:0 0 clamp(.7rem,1.8vh,1.2rem);
}
.generique{
  display:grid;grid-template-columns:1fr 1fr;column-gap:clamp(1.6rem,3vw,2.8rem);row-gap:1.05rem;
  max-width:64rem;margin:0 auto;align-items:baseline;
}
.generique dt{
  grid-column:1;text-align:right;font-family:var(--display);font-weight:500;
  font-size:clamp(1.45rem,2.2vw,1.9rem);line-height:1.12;color:var(--bleu);
}
.generique dt small{
  display:block;margin-top:.3rem;font-style:italic;font-weight:500;font-size:.62em;line-height:1.3;
  color:var(--gris-clair);
}
.generique dd{
  grid-column:2;text-align:left;margin:0;position:relative;
  font-size:1.08rem;font-weight:500;letter-spacing:.02em;color:var(--encre);
  font-variant-numeric:tabular-nums;text-wrap:balance;
}
/* le point de la maison, posé sur l'axe devant le seul format qu'on désigne */
.generique .phare::before{
  content:"";position:absolute;top:.55em;width:6px;height:6px;border-radius:50%;background:var(--or);
  left:calc(-1 * clamp(1.6rem,3vw,2.8rem) / 2 - 3px);
}
.prix-pied{
  margin:clamp(1rem,2.4vh,1.6rem) auto 0;max-width:80ch;
  font-size:.9375rem;line-height:1.7;color:#3F4750;text-wrap:balance;
}
.prix .appel{margin-top:.9rem;}
/* LE PIED ET LE LIEN DE LA CARTE SONT LÀ DÈS L'ARRIVÉE (15/10). main.js fait
   arriver les textes en fondu quand ils passent au-dessus des 10 % bas de
   l'écran : arrivé par « Les prix » en 1366×657, ou par /#prix au téléphone,
   le lien « La carte complète des tarifs » était dans ces 10 % — à l'écran,
   mais à opacité 0 jusqu'au premier cran de molette. Ces deux-là ne passent
   donc pas par le fondu : la porte vers la carte ne se cache jamais. */
.prix .prix-pied.rev,.prix .appel.rev{opacity:1;transform:none;}

/* =========================================================================
   LES PRIX EN PAGES (15/10/2026, d'après l'essai du labo du 11/10)
   Le générique de fin tourne ses pages : quatre familles, quatre lignes
   chacune, une page à la fois. Le dessin d'une ligne reste celui de
   `.generique` ci-dessus ; ce qui suit n'ajoute que le carnet autour — les
   noms des familles, la piste des pages, les deux flèches, le folio.

   CINQ RÈGLES QUI TIENNENT LE CARNET
   1. RIEN NE DÉFILE SEUL. Aucune avance automatique : la piste ne bouge que
      sous la main (doigt, nom, flèche, clavier, pavé tactile de côté).
   2. LE DOIGT RESTE AU NAVIGATEUR. Au toucher, la piste est un défilement
      horizontal natif à aimant (scroll-snap) : elle suit le doigt, se pose net,
      même parti d'une flèche (au doigt, les flèches laissent passer le doigt).
      Un glisser vertical fait défiler la page.
   3. LA MOLETTE NE CHANGE JAMAIS DE FAMILLE (sauf un geste franchement de
      côté). À la souris et au pavé tactile (hover + pointeur fin), la piste
      n'est plus défilable par l'utilisateur (overflow-x:hidden ET
      overscroll-behavior:auto — l'un sans l'autre ne suffit pas) : une molette
      verticale ou en biais posée sur les lignes fait défiler LA PAGE — dans
      Chrome comme dans WebKit, la piste native l'avalait (banc du 11/10 :
      0 px de page sur 400). studio.js tourne la page sur un geste nettement
      de côté (deux doigts sur le pavé, molette inclinable).
   4. L'ÉTAT PAR DÉFAUT EST L'ÉTAT OUVERT. Sans le script, les quatre pages
      sont là, côte à côte, la piste défile au doigt (et à la molette : la
      règle 3 ne s'applique qu'avec .prix-pret) et les noms des familles sont
      de vrais liens d'ancre. Le script n'ajoute que ce qui désigne et mène
      (filet d'or, flèches, folio) : `.prix-pret`. JavaScript coupé : les
      quatre familles s'empilent, titres visibles.
   5. LA HAUTEUR NE BOUGE JAMAIS : les quatre pages sont les cases d'une même
      rangée (la plus haute fixe la hauteur), les flèches sont posées sur la
      scène (position absolue, aucune hauteur), la place du folio est réservée.
   ========================================================================= */
.prix-carnet{
  margin-inline:calc(-1 * var(--marge));
  /* LES FLÈCHES — un dosage, quatre mesures : la longueur de la hampe, son
     épaisseur, la hauteur de la pointe, le jour au-dessus et au-dessous (la
     cible de clic). b « très franc » (intégré), a « franc » : plus bas. */
  --fl-long:88px;--fl-trait:2px;--fl-pointe:20px;--fl-pad:20px;
}

/* ------------------------------------------ les familles
   Quatre noms, en Cormorant comme les formats qu'ils rangent (pas une
   étiquette en petites capitales de plus). Celui de la page à l'écran passe
   à l'encre bleue ; un filet d'or d'1 px le désigne — l'or désigne, il ne
   remplit pas. `--trait` (0 → 1) et `--cote` sont posés par studio.js au
   rythme de la piste : le filet quitte un nom par le côté où part la page et
   gagne le suivant, il suit la main. Sans script : pas de filet. */
.prix-familles{padding-inline:var(--marge);margin:0 0 clamp(.8rem,2.2vh,1.45rem);}
.prix-familles ul{
  list-style:none;margin:0;padding:0;
  display:flex;flex-wrap:wrap;justify-content:center;column-gap:clamp(.5rem,2.4vw,2.6rem);
}
.prix-familles li{margin:0;}
.prix-familles a{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding-inline:.5rem;
  font-family:var(--display);font-weight:600;font-size:clamp(1.14rem,1.42vw,1.26rem);line-height:1.15;
  color:var(--gris-clair);text-decoration:none;transition:color .2s ease;
  /* au doigt : pas de voile gris au toucher, pas de zoom au double toucher */
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.prix-familles a[aria-current="true"]{color:var(--bleu);}
/* le survol, à la souris SEULEMENT : au doigt, le survol reste collé au dernier
   nom touché — deux noms auraient eu l'air désignés */
@media (hover:hover){ .prix-familles a:hover{color:var(--bleu);} }
/* le contour de focus serre le nom (celui du site, à 3 px dehors, ferait une boîte de 50 px de haut) */
.prix-familles a:focus-visible{outline-offset:-4px;}
.prix-familles a::after{
  content:"";position:absolute;left:.5rem;right:.5rem;bottom:7px;height:1px;
  background:var(--or);transform:scaleX(var(--trait,0));transform-origin:var(--cote,50%) 50%;
}

/* ------------------------------------------ la scène, la piste, les pages
   overflow-y:hidden : la piste ne défile que de côté.
   overscroll-behavior-x : au bout de la piste, le geste ne part pas en
   « page précédente » du navigateur.
   scroll-snap-stop : un geste, une page — même lancé fort.
   scroll-behavior:auto : c'est studio.js qui fait le glissement (0,45 s,
   courbe douce, la même partout) ; laissé au navigateur, il durait 0,18 s
   dans WebKit et 0,6 s dans Chrome (banc du 11/10). Pendant le trajet,
   studio.js coupe l'aimant (sinon il ramène la piste à chaque image).
   tabindex="-1" (index.html) : la piste n'est pas un arrêt de tabulation. */
.prix-scene{position:relative;}
.prix-pages{
  display:flex;overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;overscroll-behavior-x:contain;scroll-behavior:auto;
  scrollbar-width:none;padding-block:.35rem;outline:none;
}
.prix-pages::-webkit-scrollbar{display:none;}
/* ⚠ overflow-x:hidden NE SUFFIT PAS, il faut AUSSI overscroll-behavior:auto.
   Sonde du 15/10 (s01_sonde_biais.py, Chrome) : piste en hidden mais en
   « contain », une molette en biais (3,100) ou (30,100) posée sur les lignes
   ne faisait toujours défiler la page que de 0 px — Chrome garde tout le
   geste pour la piste qui le contient. Sans contain : +400 px, comme ailleurs.
   Ici « contain » ne sert plus : la piste ne défile pas à la main, et le geste
   de côté est intercepté par studio.js (pas de « page précédente »). */
@media (hover:hover) and (pointer:fine){
  .prix-pret .prix-pages{overflow-x:hidden;overscroll-behavior:auto;}
}
.prix-page{
  position:relative;flex:0 0 100%;min-width:0;padding-inline:var(--marge);
  scroll-snap-align:start;scroll-snap-stop:always;
  /* LIEN PROFOND (/#prix-ia) ET NOM CLIQUÉ SANS LE SCRIPT (15/10) : le
     navigateur posait le haut de la PAGE sous l'en-tête — le titre du bloc et
     les noms des familles partaient au-dessus de l'écran. La marge de
     défilement vaut ce qui les sépare du haut de la section : on arrive comme
     par « Les prix », titre et noms à l'écran. */
  scroll-margin-top:calc(clamp(2rem,5vh,3.5rem) + 2.05rem + clamp(.7rem,1.8vh,1.2rem) + 44px + clamp(.8rem,2.2vh,1.45rem) + .35rem);
}
/* le titre de chaque famille est dans la page pour les lecteurs d'écran et
   pour la version empilée ; à l'écran, c'est son nom dans la rangée du haut
   qui le porte (jamais deux fois le même mot l'un sous l'autre) */
.prix-page h3,.prix-cache{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;
}
/* UNE LIGNE HORS ÉCRAN QU'ON AMÈNE À L'ÉCRAN (recherche dans la page, lecteur
   d'écran) : le navigateur ne fait que le chemin nécessaire, moins d'une
   demi-page, et l'aimant ramenait à la page d'avant. Une marge de défilement
   d'une demi-largeur de chaque côté : amener la ligne, c'est amener sa page. */
.prix-page :is(h3,dt,dd){scroll-margin-inline:50vw;}
/* « HT » à chaque montant (Enzo, 27/10 : « ça fera plus pro ») : petites capitales
   grises, collé au montant, la phrase « hors taxes » du pied reste. 5,6:1 sur l'ivoire. */
.generique dd .ht{margin-left:.32em;font-size:.58em;font-weight:600;letter-spacing:.1em;
  color:var(--gris-clair);text-decoration:none;vertical-align:.12em;}
.generique .par-mois{font-weight:400;color:var(--gris-clair);letter-spacing:0;}

/* ------------------------------------------ les flèches (15/10, Enzo : « que
   les flèches soient plus voyantes, que l'on comprenne vraiment qu'on puisse
   swiper »). De part et d'autre des lignes, à égale distance de l'axe du
   générique : le bloc est encadré, on voit qu'il y a un avant et un après.
   Une hampe à l'encre et une pointe ouverte, tracées (aucune pastille, aucun
   bouton-carte). Au bout, la flèche s'éteint et sa pointe devient une BUTÉE
   (un trait debout) : on lit « c'est la dernière », pas « c'est cassé ».
   Dosage b : le nom de la famille où elle mène s'écrit sous la flèche — c'est
   le début de la page suivante qui affleure au bord. */
.prix-fleche{
  all:unset;box-sizing:border-box;cursor:pointer;
  position:absolute;z-index:2;top:calc(50% - var(--fl-pad) - var(--fl-pointe) / 2);
  display:flex;flex-direction:column;min-width:44px;min-height:44px;padding:var(--fl-pad) 12px;
  color:var(--bleu);-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  -webkit-user-select:none;user-select:none;
}
/* à égale distance de l'axe, jamais plus loin que 27,5rem (elles resteraient
   seules au bord d'un grand écran), jamais dans la marge */
.prix-fleche[data-sens="-1"]{right:calc(50% + min(27.5rem, 50% - var(--marge) - 6rem));align-items:flex-end;text-align:right;}
.prix-fleche[data-sens="1"]{left:calc(50% + min(27.5rem, 50% - var(--marge) - 6rem));align-items:flex-start;text-align:left;}
.prix-dessin{position:relative;display:block;flex:none;width:var(--fl-long);height:var(--fl-pointe);transition:transform .25s cubic-bezier(.4,0,.2,1);}
.prix-dessin::before{   /* la hampe */
  content:"";position:absolute;left:0;right:0;top:50%;height:var(--fl-trait);margin-top:calc(var(--fl-trait) / -2);
  background:currentColor;
}
.prix-dessin svg{
  position:absolute;top:0;right:0;width:calc(var(--fl-pointe) * 8 / 14);height:100%;overflow:visible;
  fill:none;stroke:currentColor;stroke-width:var(--fl-trait);stroke-linejoin:miter;
}
.prix-dessin path{vector-effect:non-scaling-stroke;}
.prix-dessin::after{    /* la butée, au bout seulement */
  content:"";position:absolute;top:0;bottom:0;right:0;width:var(--fl-trait);background:currentColor;display:none;
}
.prix-fleche[data-sens="-1"] .prix-dessin svg{right:auto;left:0;transform:scaleX(-1);}
.prix-fleche[data-sens="-1"] .prix-dessin::after{right:auto;left:0;}
.prix-vers{
  display:block;margin-top:.65rem;max-width:10em;
  font-family:var(--display);font-style:italic;font-weight:600;font-size:1.06rem;line-height:1.18;
  color:var(--gris-clair);transition:color .2s ease,opacity .18s ease;
}
/* PENDANT QUE LES PAGES BOUGENT, le nom s'efface (film du 15/10 : à mi-course
   les lignes qui passent dessous le croisaient, et il changeait de mot au
   milieu du trajet). Il revient, avec la nouvelle destination, quand la piste
   est posée (`.prix-en-route` : studio.js, au rythme de la piste). */
.prix-en-route .prix-vers{opacity:0;}
/* au bout : éteinte, la pointe devient butée, plus de nom (rien après) */
.prix-fleche[aria-disabled="true"]{cursor:default;color:var(--gris-clair);opacity:.5;}
.prix-fleche[aria-disabled="true"] svg{display:none;}
.prix-fleche[aria-disabled="true"] .prix-dessin::after{display:block;}
.prix-fleche[aria-disabled="true"] .prix-vers{display:none;}
/* à la souris seulement (au doigt le survol reste collé : la flèche serait restée décalée) */
@media (hover:hover){
  .prix-fleche[data-sens="1"]:not([aria-disabled="true"]):hover .prix-dessin{transform:translateX(5px);}
  .prix-fleche[data-sens="-1"]:not([aria-disabled="true"]):hover .prix-dessin{transform:translateX(-5px);}
  .prix-fleche:not([aria-disabled="true"]):hover .prix-vers{color:var(--bleu);}
}
.prix-fleche:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
/* AU DOIGT, UN GLISSER PEUT PARTIR D'UNE FLÈCHE (banc du 15/10) : posée
   par-dessus la piste, la flèche de droite est au bord, à mi-hauteur — là où
   le pouce droit commence son geste — et un glisser parti d'elle ne faisait
   rien (le bouton n'est pas dans la piste). Au doigt, la flèche laisse donc
   passer le doigt jusqu'à la piste (le glisser reste natif partout) ; un
   simple toucher dans sa zone tourne la page (studio.js lit la zone). Le
   clavier et les lecteurs d'écran gardent le vrai bouton. */
@media (hover:none) and (pointer:coarse){ .prix-pret .prix-fleche{pointer-events:none;} }

/* ------------------------------------------ le folio
   Le numéro de la page, sur l'axe. Au doigt seulement, « Faites glisser » :
   l'instruction que le dessin ne peut pas donner (la souris a ses flèches).
   Sa place est réservée (min-height), il ne s'allume qu'avec le script.
   ⚠ PAR `display`, JAMAIS PAR `visibility`. Avant la coupe, studio.css cache
   tout le studio (`.cine:not(.coupe) .studio{visibility:hidden}`) ; or
   `visibility:visible` SORT d'un parent caché : le folio serait resté
   visible et focalisable sous le tunnel (banc du 11/10). Même règle pour les
   flèches. */
.prix-folio{
  display:flex;justify-content:center;align-items:baseline;column-gap:1rem;
  min-height:1.6rem;margin:clamp(.35rem,1.2vh,.8rem) 0 0;
  -webkit-user-select:none;user-select:none;
}
.prix-carnet:not(.prix-pret) .prix-folio > *,
.prix-carnet:not(.prix-pret) .prix-fleche{display:none;}
.prix-ou{
  min-width:3.6em;font-size:.8125rem;line-height:1.6;font-weight:500;letter-spacing:.16em;
  color:var(--gris-clair);font-variant-numeric:tabular-nums;white-space:nowrap;
}
.prix-geste{
  display:none;font-size:.875rem;line-height:1.6;font-weight:600;letter-spacing:.02em;
  color:var(--bleu);white-space:nowrap;
}
@media (hover:none) and (pointer:coarse){ .prix-geste{display:inline;} }
/* ce que le folio dit aux lecteurs d'écran quand la page change */
.prix-dit{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}

/* ------------------------------------------ dosage a, « franc »
   Les mêmes flèches, plus fines et plus courtes, sans le nom de la famille ;
   « Faites glisser » en gris. Pour le choisir : data-fleches="a" (index.html). */
.prix-carnet[data-fleches="a"]{--fl-long:52px;--fl-trait:1.5px;--fl-pointe:14px;}
/* le nom de la famille où l'on va reste dans le nom du bouton (lecteurs
   d'écran), il n'est seulement plus écrit */
.prix-carnet[data-fleches="a"] .prix-vers{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;
}
.prix-carnet[data-fleches="a"] .prix-geste{font-weight:500;color:var(--gris-clair);}

/* LE NOM SOUS LA FLÈCHE A BESOIN DE 1340 PX DE FENÊTRE (sonde du 15/10,
   s04_bords.py) : en dessous, la flèche, tenue à l'écart des lignes, n'a plus
   assez de marge à sa gauche — le nom touchait le bord de l'écran (0 px entre
   1001 et 1180 px). Il n'y est plus écrit (il reste dans le nom du bouton). */
@media (max-width:1339px){
  .prix-vers{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
}

/* ------------------------------------------ fenêtre étroite, tablette, téléphone
   Sous 1000 px, la colonne des noms touche presque la place des flèches : elles
   se posent AU BORD DE L'ÉCRAN, de part et d'autre des lignes, plus courtes
   (une cible de 44 px de large) ; le nom de la famille n'y est plus écrit (il
   reste dans le nom du bouton). */
@media (max-width:1000px){
  /* AU TÉLÉPHONE, LA FLÈCHE GRANDIT AVEC L'ÉCRAN (Enzo, 15/10 : « plus voyantes,
     qu'on comprenne vraiment qu'on peut glisser » ; à 34 px sur 2 px, elle ne
     l'était guère plus que l'essai). Sonde s05_marge_tel.py : 52 px dès 365 px
     d'écran, 34 px à 320 ; au moins 24 px de jour avec le texte le plus proche,
     dans sa bande, sur les quatre pages, de 360 à 440 px. */
  .prix-carnet{--fl-long:min(52px, max(34px, 100vw - 313px));--fl-trait:2.5px;--fl-pointe:22px;--fl-pad:20px;}
  .prix-carnet[data-fleches="a"]{--fl-long:26px;--fl-trait:1.5px;--fl-pointe:12px;}
  .prix-fleche{width:calc(var(--fl-long) + 10px);padding-inline:0;align-items:center !important;}
  .prix-fleche[data-sens="-1"]{right:auto;left:0;}
  .prix-fleche[data-sens="1"]{left:auto;right:0;}
  .prix-vers{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
}
/* dès que les quatre noms ne tiennent plus sur une rangée (vers 800 px), ils se
   rangent DEUX ET DEUX : sans cette coupure, le quatrième restait seul. */
@media (max-width:860px){
  .prix-familles li:nth-child(-n+2){order:1;}
  .prix-familles ul::after{content:"";flex-basis:100%;order:2;}
  .prix-familles li:nth-child(n+3){order:3;}
}

/* ------------------------------------------ le contact — un diptyque
   Le titre tient la gauche, la suite tient la marge droite : un bloc qui ne
   touche aucune marge lit « posé n'importe où » (règle du 05/09). */
.contact{
  padding:clamp(3.5rem,9vh,5.5rem) var(--marge) clamp(4rem,10vh,6rem);
  border-top:1px solid rgba(22,52,85,.12);
}
.contact .dans{
  display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(2rem,6vw,6rem);align-items:end;
}
.contact h2{
  font-size:clamp(2.4rem,5vw,4.4rem);line-height:1.04;letter-spacing:-.012em;
  color:var(--bleu);max-width:14ch;
}
.contact-suite{justify-self:end;max-width:40ch;}
.contact-suite p{font-size:1.02rem;line-height:1.65;color:#3F4750;margin-bottom:1.3rem;}
#formulaire-entretien:empty{display:none;}

/* =========================================================================
   TÉLÉPHONE — l'écran remplit la largeur ; au-dessous, le générique, puis
   le banc de montage en 7 cases égales de 44 px (la cible tactile de la
   maison : elles faisaient 21×26 px), puis le lien de l'atelier.
   ========================================================================= */
@media (max-width:720px){
  :root{--tete:calc(1.4rem + 45px);--mh:3.7rem;}
  .metier-p{font-size:1.35rem;display:block;margin:0 0 .15rem;}
  .quoi{font-size:.86rem;}
  .salle-mention{font-size:.75rem;padding:.7rem var(--marge);}
  .bande{justify-content:flex-start;}
  .cine .bande{
    grid-template-columns:minmax(0,1fr);grid-template-areas:"credit" "montage" "lien";
    row-gap:.45rem;padding:.75rem var(--marge) .5rem;
  }
  .cine .vers-atelier{justify-self:start;}
  /* sept cases égales sur toute la largeur : le banc ne dépend plus du
     format de chaque pièce, et chaque case fait 44 px de haut */
  /* 3 px d'écart et pas 5 : à 375 px de large, chaque case garde 44 px */
  .cine .montage{display:grid;grid-template-columns:repeat(var(--nb),minmax(0,1fr));gap:3px;justify-self:stretch;}
  .cine .montage button{width:auto;height:44px;}
  .cine .montage button::after{bottom:-5px;}

  .maison-dit{padding-top:4.5rem;}
  /* sur 22 px de marge, le D ne pend plus : lettrine classique, dans la
     colonne. Même défaut, même remède — l'écart au mot vient de la marge
     droite du D, ramenée à un filet d'air. */
  .inventaire{margin-left:0;font-size:1.42rem;line-height:1.32;}
  .inventaire::first-letter{font-size:4.1em;line-height:.76;margin:.08em -.02em 0 0;}

  .generique{grid-template-columns:1fr;row-gap:.25rem;}
  .generique dt,.generique dd{grid-column:1;text-align:center;}
  .generique dd{margin-bottom:1.35rem;}
  .generique .phare::before{position:static;display:inline-block;margin:0 .55rem .15em 0;vertical-align:middle;}
  /* les prix en pages : les noms toujours deux et deux ; la première rangée
     (« Sites » + le nom le plus long) tient jusqu'à 360 px de large */
  .prix-familles{padding-inline:12px;margin-bottom:1.05rem;}
  .prix-familles ul{column-gap:4px;}
  .prix-familles a{padding-inline:8px;font-size:clamp(1rem,4.4vw,1.075rem);}
  .prix-familles a::after{left:8px;right:8px;bottom:9px;}
  .prix-page{scroll-margin-top:calc(clamp(2rem,5vh,3.5rem) + 1.62rem + clamp(.7rem,1.8vh,1.2rem) + 88px + 1.05rem + .35rem);}
  .prix-page .generique dd:last-child{margin-bottom:0;}
  .prix-folio{margin-top:.55rem;}
  .prix-pied{margin-top:1.1rem;}

  .contact .dans{grid-template-columns:1fr;gap:1.6rem;}
  .contact h2{font-size:2.45rem;}
  .contact-suite{justify-self:start;}
}
/* LE TÉLÉPHONE COURT (iPhone barres affichées 390×664, 375×667 : fenêtre
   plus large que 1:2). La bande de 194 px n'y laissait à l'image que
   390×344 — un cadre presque carré qui ne montrait que 71 % de la hauteur
   du tirage 4:5 : bouchon du flacon coupé (06/10). La bande s'y resserre à
   ~115 px : métier et description sur la même ligne, et le lien de
   l'atelier y est retiré — la même porte est déjà dans l'en-tête collé
   (« L'atelier »), visible au même instant. Le cadre passe à ~390×424
   (87 % de la hauteur du tirage). Les téléphones hauts (390×844…) gardent
   la bande entière : leur cadre est déjà plus haut que 4:5. */
@media (max-width:720px) and (orientation:portrait) and (min-aspect-ratio:1/2){
  .cine .bande{grid-template-areas:"credit" "montage";row-gap:.4rem;padding:.6rem var(--marge) .5rem;}
  .cine .vers-atelier{display:none;}
  .cine .credit{line-height:1.3;}
  .cine .credit .metier-p{display:inline;font-size:1.12rem;margin:0 .4rem 0 0;}
  .cine .credit .quoi{font-size:.8rem;line-height:1.3;}
}
@media (max-width:360px){
  :root{--mh:4.6rem;}
  .inventaire{font-size:1.3rem;}
}

/* =========================================================================
   MOUVEMENT RÉDUIT — tout reste lisible, rien ne bouge seul : pas de .cine
   (studio.js ne la pose pas), donc la salle est une suite d'images fixes,
   chacune à son format exact.
   ========================================================================= */
@media (prefers-reduced-motion:reduce){
  .montage button,.montage button::after{transition:none !important;}
  /* les prix en pages : la page change net (studio.js ne glisse pas) */
  .prix-familles a,.prix-dessin,.prix-vers{transition:none !important;}
  .prix-dessin{transform:none !important;}
}

@media print{
  .salle-mention{position:static;}
  .clair::before{display:none;}
}

/* =========================================================================
   LES PRIX EN PAGES — JAVASCRIPT COUPÉ, IMPRESSION : les quatre familles
   s'empilent, chacune sous son titre ; les noms du haut restent des liens qui
   y mènent. Rien n'est caché, rien ne demande un geste.
   ========================================================================= */
@media print, (scripting:none){
  .prix-pages{display:block;overflow:visible;padding-block:0;}
  .prix-page{scroll-margin-top:1rem;}
  .prix-page + .prix-page{margin-top:clamp(2rem,5vh,3rem);}
  .prix-page h3{
    position:static;width:auto;height:auto;margin:0 0 1rem;overflow:visible;clip-path:none;white-space:normal;
    font-style:italic;font-weight:500;font-size:clamp(1.2rem,1.7vw,1.45rem);line-height:1.2;color:var(--gris-clair);
  }
  .prix-folio,.prix-fleche{display:none !important;}
  .prix-pied{margin-top:clamp(2.2rem,4.5vh,3rem);}
}
