/* ============================================================
   L'immeuble : la feuille des scènes en trois dimensions (accueil et pages d'étage).

   Le script d'une scène (assets/js/immeuble/hall.js pour l'accueil, etage-<slug>.js pour un étage,
   construits dans blog-usine/immeuble) dessine dans une toile fixée derrière la page. Le défilement
   conduit la caméra ; le texte reste du HTML, posé devant la toile dans des stations (les sections
   marquées data-station). Chaque station reçoit du script trois variables : --pe (elle entre dans la
   fenêtre), --pt (sa course, pendant qu'elle est collée), --ps (elle sort), de 0 à 1.

   Tant que la scène ne tourne pas (script pas encore arrivé, WebGL absent, mouvement réduit, réglage du
   panneau, impression, sans script), la page est à plat : les stations se lisent comme des sections
   ordinaires. Le script pose accueil-3d sur <html> quand la première image est dessinée, sans-entree
   si WebGL manque, et data-salle pour la palette de la station courante.
   ============================================================ */

/* ---- Le mot de la tablette : Great Vibes (TypeSETit, licence SIL Open Font 1.1), réduite aux lettres de
        « Bienvenue », servie avec le site ---- */
@font-face {
    font-family: "Great Vibes";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/great-vibes-bienvenue.woff2") format("woff2");
    unicode-range: U+42, U+65, U+69, U+6E, U+75-76;
}

/* ---- La toile et le voile ---- */
.scene-toile {
    position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; display: block;
    pointer-events: none; opacity: 0; transition: opacity 0.2s ease-out;   /* la toile apparaît avant que le voile ne finisse de se lever */
}
html.accueil-3d .scene-toile { opacity: 1; }
/* Le voile de la montée : la page s'éteint dans la couleur de l'étage visé, puis la page change */
.scene-voile { position: fixed; inset: 0; z-index: 4; background: var(--bg); opacity: 1; pointer-events: none; transition: opacity 0.6s ease; }
/* Le voile couvre la page dès la première image, dans la couleur de la salle (data-salle écrit dans le HTML) : on ne voit
   jamais la page à plat pendant que la scène se charge. La scène le lève à sa première image (est-leve) ; sans scène
   (mouvement réduit, WebGL absent, script en retard), le socle ou main.js le lèvent aussi ; sans script, sans-script.css le cache. */
.scene-voile.est-leve { opacity: 0; }
.scene-voile.est-actif { opacity: 1; }
/* À l'accueil, le voile couvre la scène et le reste de la page, pas le premier écran : la barre et le cadre de la rue
   passent devant lui dès le premier affichage, lisibles sur sa couleur, et la scène paraît derrière quand elle est
   prête. En trois dimensions, la page (z-index 1, après lui) reste devant pendant son fondu. Il repasse devant tout pour
   une montée ou une coupe (est-actif) ; éteint ensuite, il ne redescend qu'à la fin de son fondu. */
html:has(main.immeuble) .scene-voile:not(.est-actif) { z-index: 1; transition: opacity 0.6s ease, z-index 0s 0.6s; }
/* le cadre de la rue devant le voile : collant au bureau (la mise en page de la scène, plus bas), relatif sinon */
html:has(main.immeuble):not(.accueil-3d):has(.scene-voile:not(.est-leve)) .station--rue > .station-cadre { z-index: 2; }
:where(html:has(main.immeuble):not(.accueil-3d):has(.scene-voile:not(.est-leve))) .station--rue > .station-cadre { position: relative; }
.scene-voile.palette-vitrine { background: #0b1a2e; }
.scene-voile.palette-machines { background: #eef1f4; }
.scene-voile.palette-lecture { background: #1c1a1a; }
.scene-voile.palette-terrain { background: #2b0f14; }
.scene-voile.palette-salon { background: #0f2230; }
.scene-voile.palette-avis { background: #0a0a0b; }
.scene-voile.palette-toit { background: #0b1224; }
.scene-voile.palette-plateau { background: #0e1013; }
.scene-voile.palette-imprimerie { background: #14161a; }
.scene-voile.palette-standard { background: #151c19; }
.scene-voile.palette-controle { background: #12171e; }
.scene-voile.palette-registres { background: #1a1714; }
/* un produit (Nestor) : une page à plat, aux couleurs du site ; le voile de la montée prend son fond, clair ou sombre */
.scene-voile.palette-produit { background: #ffffff; }
html[data-theme="dark"] .scene-voile.palette-produit { background: #000000; }
/* un étage : le voile en deux vantaux (2 px de recouvrement), ouverts au fondu, refermés au départ */
html:not([data-salle="imprimerie"]):has(main.etage) .scene-voile { background: transparent; --voile: var(--bg); }
html:not([data-salle="imprimerie"]):has(main.etage) .scene-voile.palette-cabine { --voile: #23262c; }
html:not([data-salle="imprimerie"]):has(main.etage) .scene-voile::before,
html:not([data-salle="imprimerie"]):has(main.etage) .scene-voile::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: calc(50% + 1px);
    background: linear-gradient(to left, rgb(0 0 0 / 0.18) 0 1px, rgb(0 0 0 / 0.05) 1px, transparent 16px) var(--voile);
}
html:not([data-salle="imprimerie"]):has(main.etage) .scene-voile::after { left: auto; right: 0; background: linear-gradient(to right, rgb(0 0 0 / 0.18) 0 1px, rgb(0 0 0 / 0.05) 1px, transparent 16px) var(--voile); }
@media screen and (prefers-reduced-motion: no-preference) {
    html.accueil-3d:not(.a11y-animations):not([data-salle="imprimerie"]):has(main.etage) .scene-voile::before,
    html.accueil-3d:not(.a11y-animations):not([data-salle="imprimerie"]):has(main.etage) .scene-voile::after { transition: transform 0.6s var(--mv-entree), background-color 0.5s ease; }
    html.accueil-3d:not(.a11y-animations):not([data-salle="imprimerie"]):has(main.etage) .scene-voile.est-leve::before { transform: translateX(-12%); }
    html.accueil-3d:not(.a11y-animations):not([data-salle="imprimerie"]):has(main.etage) .scene-voile.est-leve::after { transform: translateX(12%); }
    html.accueil-3d:not(.a11y-animations):not([data-salle="imprimerie"]):has(main.etage) .scene-voile.est-actif::before,
    html.accueil-3d:not(.a11y-animations):not([data-salle="imprimerie"]):has(main.etage) .scene-voile.est-actif::after { transform: none; transition-duration: 0.5s; }
}
/* Le contenu passe devant la toile, le pied de page aussi : rien ne se cache derrière la scène */
html.accueil-3d main, html.accueil-3d footer { position: relative; z-index: 1; }
html.accueil-3d footer { background: var(--bg); }
html.accueil-3d body { transition: background-color 0.7s ease, color 0.7s ease; }
html.accueil-3d .fond-particules { display: none; }
html.accueil-3d body::before, html.accueil-3d body::after { display: none; }   /* le fond de page laisse la place à la scène */

/* ---- Les palettes : la station courante colore la page (barre, textes, panneaux).
        Contrastes : encre et gris au-dessus de 4,5 pour 1 sur chaque fond. ---- */
html[data-salle="rue"] { --bg: #0a0f1a; --bg-alt: #111a2b; --ink: #f2f4f8; --mute: #aab3c5; --rule: #2a3550; --accent: #8fb0e8; --accent-hover: #a9c4f0; --card: #121b2c; --card-on-alt: #121b2c; --nav-bg: rgba(10, 15, 26, 0.72); --navy: #1b3a63; --sur-accent: #000000; }
html[data-salle="hall"] { --bg: #f4f2ed; --bg-alt: #ebe8e1; --ink: #1d1d1f; --mute: #5e6168; --rule: #d4d0c8; --accent: #14345f; --accent-hover: #1d477f; --card: #ffffff; --card-on-alt: #ffffff; --nav-bg: rgba(244, 242, 237, 0.72); --navy: #0e2a4d; --sur-accent: #ffffff; }
html[data-salle="cabine"] { --bg: #23262c; --bg-alt: #2b2f36; --ink: #f2f4f8; --mute: #b3b9c4; --rule: #454a53; --accent: #d9b56a; --accent-hover: #e6c886; --card: #2b2f36; --card-on-alt: #2b2f36; --nav-bg: rgba(35, 38, 44, 0.72); --navy: #3a3f48; --sur-accent: #000000; }
html[data-salle="vitrine"] { --bg: #0b1a2e; --bg-alt: #10233d; --ink: #f2f4f8; --mute: #a9b6cc; --rule: #26395a; --accent: #8fb0e8; --accent-hover: #a9c4f0; --card: #112542; --card-on-alt: #112542; --nav-bg: rgba(11, 26, 46, 0.72); --navy: #1b3a63; --sur-accent: #000000; }
/* La salle d'exposition (Sites et logiciels) : le seul étage allumé à plein, le gris clair des murs en fond, l'encre en texte, le bleu de la marque en accent */
html[data-salle="machines"] { --bg: #eef1f4; --bg-alt: #e2e7ec; --ink: #161a1f; --mute: #565d67; --rule: #cbd2da; --accent: #14345f; --accent-hover: #1d477f; --card: #ffffff; --card-on-alt: #ffffff; --nav-bg: rgba(238, 241, 244, 0.72); --navy: #0e2a4d; --sur-accent: #ffffff; }
html[data-salle="lecture"] { --bg: #1c1a1a; --bg-alt: #242120; --ink: #f4efe6; --mute: #b8ada0; --rule: #3a3532; --accent: #d19a3a; --accent-hover: #e0ad52; --card: #262322; --card-on-alt: #262322; --nav-bg: rgba(28, 26, 26, 0.72); --navy: #3a2f1f; --sur-accent: #000000; }
html[data-salle="terrain"] { --bg: #2b0f14; --bg-alt: #36161c; --ink: #f2e9df; --mute: #c9b3ad; --rule: #4d2a30; --accent: #e9c9b0; --accent-hover: #f3d9c4; --card: #391a20; --card-on-alt: #391a20; --nav-bg: rgba(43, 15, 20, 0.72); --navy: #4a2028; --sur-accent: #000000; }
html[data-salle="salon"] { --bg: #0f2230; --bg-alt: #14303f; --ink: #eef3f6; --mute: #a7b8c4; --rule: #274454; --accent: #ffc46b; --accent-hover: #ffd48f; --card: #143140; --card-on-alt: #143140; --nav-bg: rgba(15, 34, 48, 0.72); --navy: #1d4258; --sur-accent: #000000; }
html[data-salle="avis"] { --bg: #0a0a0b; --bg-alt: #141416; --ink: #f5f2ea; --mute: #b3ad9f; --rule: #2e2c28; --accent: #c9b37a; --accent-hover: #d9c68f; --card: #161618; --card-on-alt: #161618; --nav-bg: rgba(10, 10, 11, 0.72); --navy: #2a2620; --sur-accent: #000000; }
/* Le magasin du Registre (Entreprise) : la nuit du magasin, le brun-noir du kraft éteint en fond, le papier en texte, le laiton des plaques en accent */
html[data-salle="registres"] { --bg: #1a1714; --bg-alt: #221e1a; --ink: #f1ebe0; --mute: #b7ad9e; --rule: #3a332c; --accent: #d9a95d; --accent-hover: #e6bd7c; --card: #231f1b; --card-on-alt: #231f1b; --nav-bg: rgba(26, 23, 20, 0.72); --navy: #3a2e20; --sur-accent: #1a1714; }
/* Le bureau de contrôle (Comment je travaille) : le laboratoire de nuit, le bleu-noir de la salle en fond, l'ivoire de l'émail en texte, le bleu clair de la marque en accent */
html[data-salle="controle"] { --bg: #12171e; --bg-alt: #191f28; --ink: #eef1f4; --mute: #adb7c4; --rule: #2b343f; --accent: #8fb8ea; --accent-hover: #aacbf3; --card: #1a212b; --card-on-alt: #1a212b; --nav-bg: rgba(18, 23, 30, 0.72); --navy: #22304a; --sur-accent: #12171e; }
/* Le standard (Questions fréquentes) : la salle de nuit, le vert-gris des murs en fond, l'ivoire de l'émail en texte, le vert des lignes en ligne en accent */
html[data-salle="standard"] { --bg: #151c19; --bg-alt: #1c2521; --ink: #f1efe7; --mute: #b4bcb3; --rule: #33403a; --accent: #7fd6a3; --accent-hover: #9be3b9; --card: #1e2924; --card-on-alt: #1e2924; --nav-bg: rgba(21, 28, 25, 0.72); --navy: #2a3a33; --sur-accent: #151c19; }
/* L'imprimerie (Blog) : la halle de nuit, l'encre en fond, le papier en texte, l'orange du gyrophare en accent */
html[data-salle="imprimerie"] { --bg: #14161a; --bg-alt: #1c1f24; --ink: #f3efe6; --mute: #b3ada2; --rule: #2f3238; --accent: #ff9a3c; --accent-hover: #ffb066; --card: #1d2026; --card-on-alt: #1d2026; --nav-bg: rgba(20, 22, 26, 0.72); --navy: #2b2f38; --sur-accent: #14161a; }
/* Le plateau (Presse) : le noir du studio, l'ambre des projecteurs en accent */
html[data-salle="plateau"] { --bg: #0e1013; --bg-alt: #16191e; --ink: #f2f4f8; --mute: #aab1bd; --rule: #2a2f38; --accent: #ffb35c; --accent-hover: #ffc98a; --card: #171b22; --card-on-alt: #171b22; --nav-bg: rgba(14, 16, 19, 0.72); --navy: #1f2430; --sur-accent: #0e1013; }
/* Le toit (Contact) : la nuit bleue de la ville, les ampoules de la guirlande en accent */
html[data-salle="toit"] { --bg: #0b1224; --bg-alt: #121a30; --ink: #f5f2ea; --mute: #aeb4c4; --rule: #263049; --accent: #ffd27a; --accent-hover: #ffe0a0; --card: #141c33; --card-on-alt: #141c33; --nav-bg: rgba(11, 18, 36, 0.72); --navy: #1d2742; --sur-accent: #0b1224; }
/* les deux formulaires (Contact, Presse) vivent sur un fond sombre en toute préférence : l'erreur prend le rouge clair du thème sombre */
html[data-salle="toit"], html[data-salle="plateau"] { --erreur: #ffb4ab; }
/* Dans les salles, le bouton d'appel de la barre reprend l'accent de la palette ; son texte suit le jeton --sur-accent (noir sur
   les accents clairs des salles sombres, blanc sur l'accent foncé d'une salle claire) */
@media (min-width: 821px) { html[data-salle]:not([data-salle="hall"]) .nav-menu a.nav-cta { background: var(--accent); color: var(--sur-accent); } }
/* le texte du bouton suit le jeton de la palette : noir sur les accents clairs des salles sombres, blanc sur les accents
   foncés des salles claires (registres) ; un noir forcé tomberait sous 4,5 pour 1 sur ces accents */
html[data-salle]:not([data-salle="hall"]) .btn-primary { background: var(--accent); color: var(--sur-accent); }
html[data-salle]:not([data-salle="hall"]) .btn-primary:focus-visible { background: var(--accent-hover); }
@media (hover: hover) and (pointer: fine) { html[data-salle]:not([data-salle="hall"]) .btn-primary:hover { background: var(--accent-hover); } }
html[data-salle]:not([data-salle="hall"]) .btn-primary:active { background: color-mix(in srgb, var(--accent) 84%, #000); }

/* ---- Les stations ---- */
.piece-numero {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); margin: 0 0 var(--s-3);
}
.station { position: relative; --pe: 0; --pt: 0; --ps: 0; overflow-x: clip; }   /* le voile derrière un texte peut dépasser le bord : rien ne fait défiler la page en largeur */
.station-cadre { padding: calc(52px + var(--s-12)) var(--gutter) var(--s-16); }
/* Le texte d'un plan : une colonne, un voile dégradé de la couleur de la page derrière lui pour rester
   lisible sur la scène, sans bord visible */
.plan-texte { position: relative; max-width: 560px; }
.plan-texte::before {
    content: ""; position: absolute; inset: -12vh -30vw -12vh -40vw; z-index: -1; pointer-events: none;
    background: radial-gradient(ellipse 60% 70% at 45% 50%, color-mix(in srgb, var(--bg) 82%, transparent), color-mix(in srgb, var(--bg) 45%, transparent) 50%, transparent 72%);   /* transparent avant le bord de la boîte : aucun bord dur sur la scène */
}
.plan-texte--droite::before { inset: -12vh -40vw -12vh -30vw; }
/* Salle claire (étage 2, palette machines) : le halo du voile commun est réglé pour des salles sombres (une nappe très large et
   plate, invisible sur du noir) ; ici il se lisait comme un rectangle plus clair derrière la colonne de texte. Pour cette palette
   seulement : une boîte plus haute et moins large, un ovale centré sur le bloc de texte, plein à 70 % jusqu'aux bords du bloc, encore à 46 % à
   ses coins (le titre y commence, le lien y finit) puis fondu à zéro avant les bords de la boîte (en portrait la boîte s'élargit : le texte prend toute la largeur). Le mélange se fait
   en sRGB : sur l'enduit à l'ombre (gris 70) ou un costume noir, 70 % de la couleur de page donnent un fond de luminance 0,41 à
   0,50, ce qu'il faut pour tenir 4,5:1 avec le texte courant (mêlé aux trois quarts à l'encre : le gris de la page ne tient pas)
   et avec les liens (le bleu nuit de la maison : l'accent tenait 4,1). Le palier garde le halo commun, son texte passe sur les
   portes sombres. Mesuré à chaque arrêt par la sonde de contraste du chantier, au 5e centile de la luminance derrière chaque bloc. */
html[data-salle="machines"] .station .plan-texte::before {
    inset: -24vh -22vw -24vh -22vw;
    background: radial-gradient(ellipse 50% 50% at 50% 50%, color-mix(in srgb, var(--bg) 70%, transparent) 46%, color-mix(in srgb, var(--bg) 46%, transparent) 72%, transparent 100%);
}
@media (max-width: 899px) { html[data-salle="machines"] .station .plan-texte::before { inset: -24vh -45vw -24vh -45vw; } }
html[data-salle="machines"] .station .plan-texte p, html[data-salle="machines"] .station .plan-texte .indice, html[data-salle="machines"] .station .plan-texte .piece-numero { color: color-mix(in srgb, var(--ink) 75%, var(--mute)); }
html[data-salle="machines"] .station .plan-texte .link-more, html[data-salle="machines"] .station .plan-texte .text-link { color: var(--navy); }
.plan-texte h1, .plan-texte h2 { margin-bottom: var(--s-4); }
.plan-texte--hero h1 { font-size: clamp(1.9rem, 2.6vw + 0.6rem, 2.5rem); letter-spacing: -0.03em; line-height: 1.04; }
.plan-texte--hero .hero-lede { font-size: clamp(1.0625rem, 1.5vw, 1.2rem); }
.plan-texte h2 { font-size: clamp(1.75rem, 3.6vw, 2.75rem); }
.plan-texte p { color: var(--mute); font-size: var(--text-lg); line-height: 1.5; }
.plan-texte p.hero-lede { color: var(--mute); }
.plan-texte .hero-cta { justify-content: flex-start; margin-top: var(--s-8); }
.plan-texte .hero-cta + p { margin-top: var(--s-3); }   /* Contact : la ligne du chantier sous le bouton Appeler */
.plan-texte .section-suite { text-align: left; margin-top: var(--s-6); }
.plan-texte--droite { margin-left: auto; }
.plan-texte--centre { margin: 0 auto; text-align: center; }
.plan-texte--centre .hero-cta { justify-content: center; }
/* Le premier écran de l'accueil : le titre en deux moitiés (une ligne chacune au bureau ; au téléphone, chaque moitié se
   coupe après sa virgule, la fin reste d'un bloc), les trois gestes, les deux métiers reliés à leur étage, la cible.
   Les blocs ont leur fond : le texte tient le contraste quel que soit l'arrière-plan de la scène. */
.plan-texte--hero { max-width: 640px; }
.plan-texte--hero h1 .titre-fin { display: inline-block; max-width: 100%; }
.plan-texte--hero .hero-kicker { margin-bottom: var(--s-3); }
.plan-texte--hero .hero-cta { margin-top: var(--s-6); gap: var(--s-3); }
.btn.hero-visite { background: transparent; color: var(--ink); padding-inline: var(--s-3); text-decoration: underline color-mix(in srgb, currentColor 45%, transparent); text-underline-offset: 0.2em; }
.btn.hero-visite:focus-visible { text-decoration-color: currentColor; }
@media (hover: hover) and (pointer: fine) { .btn.hero-visite:hover { text-decoration-color: currentColor; } }
.hero-metiers { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); margin-top: var(--s-6); }
.plan-texte .hero-metier { position: relative; margin: 0; padding: 14px 16px; border: 1px solid var(--rule); border-radius: var(--r-lg); background: color-mix(in srgb, var(--bg) 88%, transparent); color: var(--ink); font-size: 0.9375rem; line-height: 1.45; }
.hero-metier a { color: var(--accent); font-weight: 700; }
.hero-metier a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.hero-metier:has(a:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }
@supports selector(:has(*)) { .hero-metier a:focus-visible { outline: 0; } }
@media (hover: hover) and (pointer: fine) { .hero-metier:has(a:hover) { border-color: var(--accent); } }
.plan-texte .hero-cible { margin-top: var(--s-4); color: var(--ink); font-size: var(--text-base); }
/* Sur la scène, le surtitre, la cible et l'indice passent devant des fenêtres éclairées (au téléphone, la cible est devant
   l'entrée vitrée) : un voile doux de la couleur de la page derrière chacun, sans bord ; « Écrire » prend le fond des blocs */
html.accueil-3d .plan-texte--hero :is(.hero-kicker, .hero-cible, .indice) { position: relative; width: fit-content; }
html.accueil-3d .plan-texte--hero :is(.hero-kicker, .hero-cible, .indice)::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: 12px; background: color-mix(in srgb, var(--bg) 78%, transparent); box-shadow: 0 0 16px 8px color-mix(in srgb, var(--bg) 78%, transparent); }
:where(html.accueil-3d .plan-texte--hero) .btn-ghost { background: color-mix(in srgb, var(--bg) 88%, transparent); }
.plan-texte--hero .indice { margin-top: var(--s-6); }
@media (max-width: 720px) {
    .plan-texte--hero h1 { font-size: clamp(1.75rem, 9vw, 2.2rem); }
    .hero-metiers { grid-template-columns: 1fr; }
}

/* La scène tourne : chaque station devient un plan épinglé, le texte y entre et en sort */
html.accueil-3d .station--rue { min-height: 130vh; }
html.accueil-3d .station--hall { min-height: 160vh; }
html.accueil-3d .station--arrivee { min-height: 300vh; }   /* courses longues : la caméra avance peu par cran de molette (à 140 et 220 vh le mouvement était sec, à 220 et 360 vh encore trop rapide, repéré par Maël les 17 et 20/09) ; la rue et le hall gardent leurs courses */
html.accueil-3d .station--piece { min-height: 720vh; }
html.accueil-3d .station-cadre {
    position: sticky; top: 0; height: 100vh; height: 100svh; box-sizing: border-box;
    padding: calc(52px + 4vh) var(--gutter) 6vh;
    display: flex; flex-direction: column; justify-content: center;
}
/* L'accueil a la mise en page de sa scène dès le premier affichage, tant que le voile couvre la scène : rien ne bouge
   quand elle arrive (la tablette et la cabine, qui passent alors en calques fixes, restent cachées d'ici là : la tablette
   n'a pas de fondu à jouer, ses liens pas encore posés sur l'écran dessiné). Mouvement réduit, animations
   arrêtées, WebGL absent, voile levé sans scène (script en échec, quinze secondes sans image) : la page est à plat. */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
    html:not(.a11y-animations):not(.sans-entree):has(.scene-voile:not(.est-leve)) .station--rue { min-height: 130vh; }
    html:not(.a11y-animations):not(.sans-entree):has(.scene-voile:not(.est-leve)) .station--hall { min-height: 160vh; }
    html:not(.a11y-animations):not(.sans-entree):has(.scene-voile:not(.est-leve)) :is(.station--rue, .station--hall) > .station-cadre {
        position: sticky; top: 0; height: 100vh; height: 100svh; box-sizing: border-box;
        padding: calc(52px + 4vh) var(--gutter) 6vh;
        display: flex; flex-direction: column; justify-content: center;
    }
    html:not(.a11y-animations):not(.sans-entree):has(.scene-voile:not(.est-leve)) .station--hall > .station-cadre { justify-content: flex-end; }
    html:not(.a11y-animations):not(.sans-entree):has(.scene-voile:not(.est-leve)) .indice { display: block; }
    html:not(.a11y-animations):not(.sans-entree):not(.accueil-3d):has(.scene-voile:not(.est-leve)) .station--cabine { visibility: hidden; }
    html:not(.a11y-animations):not(.sans-entree):not(.accueil-3d):has(.scene-voile:not(.est-leve)) .tablette { visibility: hidden; opacity: 0; }
    @media (max-width: 720px), (max-height: 640px) {
        html:not(.a11y-animations):not(.sans-entree):has(.scene-voile:not(.est-leve)) .station--rue > .station-cadre { position: relative; height: auto; min-height: 100vh; min-height: 100svh; justify-content: flex-start; padding-top: calc(52px + 3vh); }
    }
}
/* Le hero s'efface quand la caméra traverse la rue, sans bouger */
html.accueil-3d .plan-texte--hero { opacity: clamp(0, calc(1 - (var(--pt) - 0.3) / 0.35), 1); }
/* Au téléphone et sur un écran bas, le premier écran dépasse la hauteur de l'écran : le cadre de la rue suit la page (le
   titre et « Appeler » d'abord, les deux métiers ensuite), sans fondu ; le rail se règle sur le cadre du hall (hall.js) */
@media (max-width: 720px), (max-height: 640px) {
    html.accueil-3d .station--rue > .station-cadre { position: relative; height: auto; min-height: 100vh; min-height: 100svh; justify-content: flex-start; padding-top: calc(52px + 3vh); }
    html.accueil-3d .plan-texte--hero { opacity: 1; }
}
/* Le texte d'un étage arrive avec sa station et se retire avant la fin */
html.accueil-3d .station--arrivee .plan-texte { opacity: clamp(0, calc(1 - (var(--pt) - 0.55) / 0.3), 1); }
html.accueil-3d .station--piece .plan-texte {
    opacity: clamp(0, min(calc((var(--pe) - 0.55) / 0.3), calc(1 - (var(--pt) - 0.72) / 0.22)), 1);
}
/* machines : la colonne part avant les plaques */
html.accueil-3d[data-salle="machines"] .station--piece .plan-texte { opacity: clamp(0, min(calc((var(--pe) - 0.55) / 0.3), calc(1 - (var(--pt) - 0.8) / 0.025)), 1); }
/* le surligneur (titres.js pose data-actif) */
[data-legende] { background: linear-gradient(color-mix(in srgb, var(--accent) 20%, transparent), color-mix(in srgb, var(--accent) 20%, transparent)) no-repeat 0 100% / 0 58%; -webkit-box-decoration-break: slice; box-decoration-break: slice; }
@media screen and (prefers-reduced-motion: no-preference) {
    html.accueil-3d:not(.a11y-animations) [data-legende] { transition: background-size var(--mv-court) var(--mv-sortie); }
    html.accueil-3d:not(.a11y-animations) [data-legende][data-actif] { background-size: 100% 58%; transition: background-size 480ms var(--mv-entree); }
}
/* Le portable parle pour la scène : son texte est lu par le script et n'est pas affiché */
.ecran-contenu[hidden] { display: none; }
.indice {
    margin: var(--s-10) 0 0; font-size: var(--text-sm); letter-spacing: 0.18em; text-transform: uppercase; color: var(--mute);
}
/* sur un téléphone court, l'indice passe sur le vitrage éclairé du hall : une ombre douce le détache */
html.accueil-3d .indice { opacity: clamp(0, calc(1 - var(--pt) / 0.12), 1); text-shadow: 0 0 8px rgb(0 0 0 / 0.75), 0 1px 2px rgb(0 0 0 / 0.6); }
html:not(.accueil-3d) .indice { display: none; }

/* ---- Les accès rapides (sur l'accueil, trois, dont « Aller au panneau de l'ascenseur ») paraissent sans glisser, à
        l'écran dès qu'ils ont le focus : la suite de tabulation d'une page à scène n'arrête jamais le focus hors de la
        fenêtre ; ils repartent en glissant. De même, un bouton flottant effacé revient d'un coup quand il prend le focus. ---- */
html:has([data-station]) .skip-link:focus, .retour-ascenseur:focus-visible, html:has([data-station]) .a11y-bouton:focus-visible { transition: none; }
/* À plat (mouvement réduit, animations arrêtées), le focus qui fait défiler la page pose l'élément sous la barre de menu
   fixe (52 px) et jamais contre le bord bas de l'écran ; animations arrêtées, la page ne défile plus en glissant
   (la règle commune « html.a11y-animations * » ne touche pas <html> lui-même) */
html:has(.station--cabine):not(.accueil-3d) { scroll-padding-block: 64px 16px; }
html.a11y-animations:has(.station--cabine) { scroll-behavior: auto; }

/* ---- Le hall : la tablette ---- */
.tablette {
    max-width: 420px; margin: 0 auto; padding: var(--s-8) var(--s-8) var(--s-6);
    background: var(--card); color: var(--ink); border: 1px solid var(--rule); border-radius: 22px; text-align: center;
    box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.45);
}
.tablette-bienvenue { font-family: "Great Vibes", "Brush Script MT", cursive; font-size: clamp(2.6rem, 6vw, 3.6rem); line-height: 1; margin: 0 0 var(--s-3); color: var(--ink); }
.tablette-question { color: var(--mute); font-size: var(--text-lg); margin: 0 0 var(--s-6); }
.tablette-boutons { display: flex; gap: var(--s-3); justify-content: center; flex-wrap: wrap; }
.tablette-boutons .btn { min-width: 128px; justify-content: center; }
.tablette-boutons > [hidden] { display: none; }   /* un lien sans place sur l'écran dessiné s'efface ; le style des .btn ne doit pas le ressusciter */
/* « Voir tous les étages » : un lien discret, seul sur la ligne sous les deux choix, sa cible à 30 px de haut */
.tablette-boutons::after { content: ""; flex-basis: 100%; order: 1; }
.tablette-tous { order: 2; padding: 4px 6px; color: var(--accent); font-size: var(--text-sm); text-decoration: underline; text-underline-offset: 3px; }
html.accueil-3d .station--hall .station-cadre { justify-content: flex-end; }
/* En trois dimensions, la carte disparaît : la caméra vient sur la tablette du comptoir et ses boutons dessinés
   deviennent les vrais liens. Le HTML reste (titre et question pour les lecteurs d'écran, liens au clavier) :
   le script pose chaque lien exactement sur la zone dessinée (--bx --by --bw --bh), aux couleurs de l'écran. */
html.accueil-3d .tablette {
    position: fixed; inset: 0; z-index: 3; max-width: none; margin: 0; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none;
    opacity: 0; visibility: hidden; transform: none; pointer-events: none; transition: opacity 0.3s ease, visibility 0s 0.3s;
}
html.accueil-3d .station--hall.est-tablette .tablette { opacity: 1; visibility: visible; transition: opacity 0.3s ease; }
html.accueil-3d .tablette-bienvenue, html.accueil-3d .tablette-question { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
html.accueil-3d .tablette-boutons { display: contents; }
html.accueil-3d .tablette-boutons::after { content: none; }
html.accueil-3d .tablette-boutons > :is(.btn, .tablette-tous) {
    position: fixed; left: var(--bx, 50%); top: var(--by, 50%); width: var(--bw, 48px); height: var(--bh, 44px); min-width: 48px; min-height: 44px;
    transform: translate(-50%, -50%); padding: 0; border-radius: 999px; box-shadow: none; pointer-events: auto;
    font-size: clamp(14px, calc(var(--bh, 44px) * 0.4), 40px); line-height: 1; font-weight: 600;
}
html.accueil-3d .tablette-boutons .btn-primary { background: #14345f; color: #fff; }
html.accueil-3d .tablette-boutons .btn-primary:focus-visible { background: #1d477f; color: #fff; box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.35); }
/* le lien sous les choix : du texte bleu souligné sur l'écran clair, sa cible tactile à la taille de sa zone */
html.accueil-3d .tablette-boutons > .tablette-tous {
    display: flex; align-items: center; justify-content: center; border-radius: 10px; background: transparent; color: #14345f;
    font-size: clamp(14px, calc(var(--bh, 44px) * 0.42), 26px); font-weight: 500;
}
html.accueil-3d .tablette-boutons > .tablette-tous:focus-visible { outline: 2px solid #14345f; outline-offset: 2px; }
html.accueil-3d .tablette-boutons > [hidden] { display: none; }
@media (hover: hover) and (pointer: fine) {
    html.accueil-3d .tablette-boutons .btn-primary:hover { background: #1d477f; color: #fff; box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.35); }
    html.accueil-3d .tablette-boutons > .tablette-tous:hover { color: #1d477f; text-decoration-thickness: 2px; }
}
html.accueil-3d .tablette-boutons .btn-primary:active, html.accueil-3d .tablette-boutons .btn-primary.est-appuye, html.accueil-3d .tablette-boutons .btn-primary.est-choisi { background: #0e2a4d; color: #fff; }
html.accueil-3d .tablette-boutons .btn-primary.est-choisi { box-shadow: 0 0 0 3px #fff, 0 0 0 4px #14345f; }
html.accueil-3d .tablette-boutons > .tablette-tous:is(:active, .est-appuye, .est-choisi) { color: #0e2a4d; background: rgb(20 52 95 / 0.08); }
html.accueil-3d .tablette-boutons .btn-primary::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: radial-gradient(closest-side, rgb(255 255 255 / 0.34), transparent); opacity: 0; pointer-events: none; }
html.accueil-3d .tablette-boutons .btn-primary:is(:active, .est-appuye, .est-choisi)::before { opacity: 1; }
@media screen and (prefers-reduced-motion: no-preference) {
    html.accueil-3d:not(.a11y-animations) .tablette-boutons > :is(.btn, .tablette-tous) { transition: background-color var(--mv-t-relache) var(--mv-appui), color var(--mv-t-relache) var(--mv-appui), box-shadow var(--mv-t-survol) var(--mv-appui), transform var(--mv-t-relache) var(--mv-appui), opacity var(--mv-moyen) var(--mv-entree); }
    html.accueil-3d:not(.a11y-animations) .tablette-boutons > :is(.btn, .tablette-tous):active, html.accueil-3d:not(.a11y-animations) .tablette-boutons .btn-primary.est-appuye { transform: translate(-50%, -50%) scale(0.95); transition-duration: var(--mv-t-appui), var(--mv-t-appui), var(--mv-t-appui), var(--mv-t-appui), 140ms; }
    html.accueil-3d:not(.a11y-animations) .tablette-boutons .btn-primary::before { transition: opacity var(--mv-t-relache) var(--mv-appui); }
    html.accueil-3d:not(.a11y-animations) .tablette-boutons .btn-primary:is(:active, .est-appuye)::before { transition-duration: var(--mv-t-appui); }
    html.accueil-3d:not(.a11y-animations) .tablette-boutons .btn-primary.est-choisi { transform: translate(-50%, -50%) scale(0.95); transition-duration: var(--mv-t-appui), var(--mv-t-appui), 120ms, var(--mv-t-appui), 140ms; }
    html.accueil-3d:not(.a11y-animations) .station--hall.est-tablette .tablette { transition: opacity 0.3s ease 120ms; }
}
html.accueil-3d .hall-legende { display: none; }
.hall-legende { max-width: var(--container-text); margin: var(--s-8) auto 0; text-align: center; color: var(--mute); }
.hall-legende a { color: var(--ink); text-decoration: underline; text-underline-offset: 0.15em; text-decoration-thickness: 1px; }

/* ---- La cabine : le panneau ---- */
.cabine-texte { max-width: 560px; margin: 0 auto var(--s-5); text-align: center; }
.cabine-texte .piece-numero { margin-bottom: var(--s-2); }
.cabine-texte h2 { font-size: clamp(1.4rem, 2.6vw, 2rem); margin-bottom: var(--s-2); }
.cabine-texte p { color: var(--mute); font-size: var(--text-sm); line-height: 1.5; }
.cabine-texte .cabine-etages { color: var(--ink); font-size: var(--text-base); }
.cabine-texte .tuyau-aura { color: var(--ink); font-size: clamp(1.05rem, 1.8vw, 1.35rem); font-weight: 600; letter-spacing: -0.02em; margin: var(--s-3) 0 0; }
.cabine-texte .tuyau-aura a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.panneau {
    display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--s-2) var(--s-5); align-items: start;
    max-width: 680px; margin: 0 auto; padding: var(--s-4) var(--s-5);
    background: linear-gradient(160deg, #3a3e46, #23262c 60%, #2b2f36); color: #f2f4f8;
    border-radius: 18px; border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 40px 90px -40px rgba(0, 0, 0, 0.7);
}
.panneau-colonne { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
/* Les zones du panneau : Numérique, Commercial, Avis et contact, Pour en savoir plus ; un petit titre en capitales espacées avant chaque groupe */
.panneau-zone { padding: 10px 10px 3px; font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: #b3b9c4; }
.panneau-zone:first-child { padding-top: 4px; }
.panneau-barre { display: block; width: 2px; align-self: stretch; background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.35) 15%, rgba(255, 255, 255, 0.35) 85%, transparent); }
.panneau-bouton {
    display: flex; align-items: center; gap: var(--s-3); padding: 5px 10px; border-radius: 14px; font-size: var(--text-sm);
    color: inherit; text-decoration: none; transition: background 0.25s var(--ease), transform 0.25s var(--ease);
}
.panneau-bouton { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.panneau-bouton:focus-visible { background: rgba(255, 255, 255, 0.07); }
.panneau-bouton:focus-visible { outline: 2px solid #d9b56a; outline-offset: 2px; }
/* le bouton entier reçoit le pointeur, ses morceaux (numéro, titre, ligne) non : un toucher n'importe où dans le bouton est le bouton */
.panneau-bouton * { pointer-events: none; }
.panneau-numero {
    flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%;
    display: grid; place-items: center; font-weight: 700; font-variant-numeric: tabular-nums;
    background: radial-gradient(circle at 35% 30%, #c9cdd4, #7c8189 70%, #5a5f67); color: #111318;
    box-shadow: inset 0 -2px 3px rgba(0, 0, 0, 0.35), 0 2px 4px rgba(0, 0, 0, 0.4);
    transition: box-shadow 0.25s var(--ease), background 0.25s var(--ease);
}
.panneau-numero--point { width: 26px; height: 26px; margin: 7px; }
.cabine-contact { margin-top: var(--s-5); }
.panneau-bouton:focus-visible .panneau-numero { background: radial-gradient(circle at 35% 30%, #eef0f3, #a9aeb6 70%, #7c8189); box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.3), 0 2px 4px rgba(0, 0, 0, 0.4); }
@media (hover: hover) and (pointer: fine) {
    .panneau-bouton:hover { background: rgba(255, 255, 255, 0.07); }
    .panneau-bouton:hover .panneau-numero { background: radial-gradient(circle at 35% 30%, #eef0f3, #a9aeb6 70%, #7c8189); box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.3), 0 2px 4px rgba(0, 0, 0, 0.4); }
}
.panneau-bouton:active .panneau-numero { box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.45), 0 1px 1px rgba(0, 0, 0, 0.3); }
.panneau-bouton[aria-current="true"] .panneau-numero {
    background: radial-gradient(circle at 35% 30%, #ffe7b0, #d9b56a 70%, #a8853f); box-shadow: 0 0 0 4px rgba(217, 181, 106, 0.25), 0 0 28px rgba(217, 181, 106, 0.55);
}
html.accueil-3d .panneau:has([aria-current="true"]) .panneau-bouton:not([aria-current="true"]) { opacity: 0.4; pointer-events: none; }
@keyframes mv-zone { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0); } }
@keyframes mv-fondu { from { opacity: 0; } to { opacity: 1; } }
@media screen and (prefers-reduced-motion: no-preference) {
    html:not(.a11y-animations) .panneau-numero { transition: box-shadow var(--mv-t-survol) var(--mv-appui), transform var(--mv-t-relache) var(--mv-appui); }
    html:not(.a11y-animations) .panneau-bouton:active .panneau-numero { transform: translateY(1px) scale(0.94); transition-duration: var(--mv-t-appui); }
    html.accueil-3d:not(.a11y-animations) .panneau-bouton { transition: background var(--mv-t-survol) var(--ease), opacity 200ms var(--mv-sortie); }
    /* la cascade de la première visite (titres.js : cabine-premiere, panneau-pose), une fois la cabine atteinte : jamais pendant la marche */
    html.accueil-3d.dans-cabine:not(.a11y-animations) .cabine-premiere.est-panneau:not(.panneau-pose) .panneau-zone { animation: mv-zone 220ms var(--mv-entree) calc(var(--rg, 0) * 25ms) 1 backwards; }
    html.accueil-3d.dans-cabine:not(.a11y-animations) .cabine-premiere.est-panneau:not(.panneau-pose) .panneau-bouton > .panneau-numero, html.accueil-3d.dans-cabine:not(.a11y-animations) .cabine-premiere.est-panneau:not(.panneau-pose) .panneau-bouton > .panneau-libelle { animation: mv-cascade 200ms var(--mv-entree) calc(var(--rg, 0) * 25ms) 1 backwards; }
    html.accueil-3d.dans-cabine:not(.a11y-animations) .cabine-premiere.est-panneau:not(.panneau-pose) .cabine-contact { animation: mv-fondu 200ms linear 300ms 1 backwards; }
}
.panneau-colonne > li:nth-child(2) { --rg: 1; } .panneau-colonne > li:nth-child(3) { --rg: 2; } .panneau-colonne > li:nth-child(4) { --rg: 3; }
.panneau-colonne > li:nth-child(5) { --rg: 4; } .panneau-colonne > li:nth-child(6) { --rg: 5; } .panneau-colonne > li:nth-child(7) { --rg: 6; }
.panneau-colonne > li:nth-child(8) { --rg: 7; } .panneau-colonne > li:nth-child(9) { --rg: 8; } .panneau-colonne > li:nth-child(10) { --rg: 9; }
.panneau-libelle { display: flex; flex-direction: column; gap: 2px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; }
/* les titres des étages et des annexes en capitales espacées, comme une vraie plaque de cabine */
.panneau-titre { text-transform: uppercase; letter-spacing: 0.07em; font-size: 0.88em; }
/* Sous le libellé d'un étage, la ligne qui dit ce qu'on y trouve */
.panneau-sous { font-weight: 400; font-size: var(--text-sm); color: #b3b9c4; }
.panneau-bouton--page .panneau-libelle { font-weight: 500; }
.cabine-contact { max-width: 560px; margin: var(--s-8) auto 0; text-align: center; color: var(--mute); font-size: var(--text-sm); }
.cabine-contact a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
/* La page finit dans la cabine : les liens obligatoires vivent sous les boutons, il n'y a pas de pied de page */
.cabine-legal { max-width: 560px; margin: var(--s-4) auto 0; text-align: center; color: var(--mute); font-size: var(--text-sm); }
.cabine-legal a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.cabine-legal a:hover { color: var(--ink); }
/* En trois dimensions, la cabine n'est pas conduite par le défilement : la page s'arrête à la tablette du hall, et la
   tablette joue la marche jusqu'à l'ascenseur. La station devient un calque fixe, invisible tant qu'on n'est pas dedans ;
   le bloc du panneau se pose sur la plaque de la paroi de droite, à l'échelle de sa projection (--px --py --ps
   écrits par le script), sa tête en haut de la plaque (le titre, les étages par métier, le numéro), le petit titre
   « La cabine » pour les lecteurs d'écran. La plaque est large (860 px) : chaque ligne d'étage tient sur une ligne et
   la tête ne fait pas rétrécir le bloc. Remonter la page fait sortir. */
html.accueil-3d .station--cabine {
    position: fixed; inset: 0; z-index: 3; min-height: 0; overflow: visible;
    opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.35s ease, visibility 0s 0.35s;
}
html.accueil-3d.dans-cabine .station--cabine.est-panneau { opacity: 1; visibility: visible; transition: opacity 0.35s ease; }
html.accueil-3d .station--cabine .station-cadre { position: static; height: auto; min-height: 0; padding: 0; display: block; opacity: 1; }
html.accueil-3d .cabine-texte .piece-numero { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
html.accueil-3d .cabine-panneau .cabine-texte { max-width: none; margin: 0 0 8px; }
html.accueil-3d .cabine-texte h2 { color: #f2f4f8; font-size: 1.375rem; line-height: 1.2; margin: 0 0 4px; }
html.accueil-3d .cabine-texte .cabine-etages { color: #c9ced8; font-size: var(--text-sm); }
html.accueil-3d .cabine-texte .tuyau-aura { color: #f2f4f8; font-size: 1rem; margin: 4px 0 0; }
html.accueil-3d .cabine-texte .tuyau-aura a { color: #d9b56a; }
/* sur la plaque, la tête et les marges se serrent : le panneau garde à peu près l'échelle qu'il avait sans elle */
@media (min-width: 641px) {
    html.accueil-3d .cabine-texte h2 { line-height: 1.1; margin-bottom: 2px; }
    html.accueil-3d .cabine-texte :is(.cabine-etages, .tuyau-aura) { line-height: 1.3; }
    html.accueil-3d .cabine-texte .tuyau-aura { margin-top: 2px; }
}
html.accueil-3d .cabine-panneau {
    position: fixed; left: var(--px, 50%); top: var(--py, 50%); width: min(860px, 100vw - 32px); margin: 0; box-sizing: border-box;
    padding: 8px 10px 10px; border-radius: 6px; background: #14161a; border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);   /* la plaque porte son propre fond : ses textes ne dépendent pas de la toile derrière */
    transform-origin: 0 0; transform: scale(var(--ps, 1)); pointer-events: auto;
}
html.accueil-3d .cabine-panneau .panneau { margin: 0; max-width: none; border-radius: 12px; }
html.accueil-3d .cabine-panneau .cabine-contact { max-width: none; margin: 12px 0 0; color: #b3b9c4; }
html.accueil-3d .cabine-panneau .cabine-contact a { color: #d9b56a; }
html.accueil-3d .cabine-panneau .cabine-legal { max-width: none; margin: 8px 0 0; color: #b3b9c4; }
html.accueil-3d .cabine-panneau .cabine-legal a:hover { color: #f2f4f8; }
@media (max-width: 640px) {
    .panneau { grid-template-columns: 1fr; padding: var(--s-5) var(--s-4); }
    .panneau-barre { width: auto; height: 2px; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35) 15%, rgba(255, 255, 255, 0.35) 85%, transparent); }
    /* Au téléphone, le panneau se lit à taille réelle, à plat comme dans la cabine : titres de zone et d'étage à 16 px,
       lignes à 14 px, cibles de 46 px de haut (le kit de marque : jamais moins de 14 px) */
    .panneau-colonne { gap: 0; }
    .panneau-zone { font-size: 1rem; line-height: 1.2; letter-spacing: 0.12em; padding: 8px 8px 2px; }
    .panneau-zone:first-child { padding-top: 4px; }
    .panneau-bouton { min-height: 46px; padding: 4px 8px; font-size: 1rem; }
    .panneau-titre { font-size: 1rem; letter-spacing: 0.06em; }
    .panneau-sous { font-size: 0.875rem; }
    .panneau-numero { width: 36px; height: 36px; }
    /* En trois dimensions, le panneau devient une feuille pleine largeur montée du bas, au-dessus de la cabine assombrie ;
       la bande libre au-dessus, sous la barre de menu, montre l'afficheur (la caméra l'y cadre : hall.js, poseFeuille).
       Rien ne se projette : la feuille est fixe, elle monte pendant le dernier pas de la marche. Quand elle ne tient
       pas, elle défile d'elle-même : les douze boutons d'abord, puis la ligne de contact et les liens obligatoires. */
    html.accueil-3d:has(.station--cabine) { --bande-feuille: clamp(84px, 12svh, 124px); }
    html.accueil-3d .station--cabine { background: linear-gradient(180deg, rgba(6, 7, 9, 0.1), rgba(6, 7, 9, 0.16) 18%, rgba(6, 7, 9, 0.66) 40%); }
    html.accueil-3d .station--cabine.est-panneau { opacity: 1; visibility: visible; transition: opacity 0.35s ease; }
    html.accueil-3d .cabine-panneau {
        left: 0; right: 0; top: calc(52px + var(--bande-feuille)); bottom: 0; width: auto;
        padding: 4px 8px 0;
        border: 0; border-top: 1px solid rgba(255, 255, 255, 0.14); border-radius: 18px 18px 0 0;
        box-shadow: 0 -24px 48px -16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.06);
        overflow-y: auto; overscroll-behavior: contain; scroll-padding: 8px 0 28px;
        transform: translateY(calc(100% + 24px)); transition: transform 0.45s var(--ease);
    }
    html.accueil-3d .station--cabine.est-panneau .cabine-panneau { transform: none; }
    /* le bas de la feuille : l'air sous les liens obligatoires, qui reste collé au bord de l'écran tant qu'il y a encore à
       lire dessous et y fond le texte, pour dire que la feuille continue */
    html.accueil-3d .cabine-panneau::after {
        content: ""; display: block; position: sticky; bottom: 0; height: calc(16px + env(safe-area-inset-bottom)); pointer-events: none;
        background: linear-gradient(180deg, rgba(20, 22, 26, 0), #14161a 70%);
    }
    html.accueil-3d .cabine-panneau .panneau { padding: 2px 4px 6px; row-gap: 4px; border-radius: 14px; }
    /* la tête de la feuille, lue en premier quand elle monte */
    html.accueil-3d .cabine-panneau .cabine-texte { margin: 10px var(--s-2) 12px; }
    html.accueil-3d .cabine-texte h2 { font-size: 1.25rem; }
    html.accueil-3d .cabine-panneau .cabine-contact { margin: var(--s-4) var(--s-2) 0; }
    html.accueil-3d .cabine-panneau .cabine-legal { margin: var(--s-3) var(--s-2) 0; }
    /* la pastille d'accessibilité ne mord pas sur la feuille : quand la feuille est montée, elle remonte dans la bande */
    html.accueil-3d:has(.station--cabine) .a11y-bouton { top: calc(100% - 72px); bottom: auto; transition: transform 0.2s var(--ease), background 0.2s var(--ease), top 0.45s var(--ease); }
    html.accueil-3d:has(.station--cabine.est-panneau) .a11y-bouton { top: calc(52px + (var(--bande-feuille) - 48px) / 2); }
}

/* ---- Les étages : le bouton de retour, le contenu à plat ---- */
/* La pastille reste sous la barre de menu (1000) et sous les zones de saisie (960, main.css section 17) : un formulaire
   passe devant elle. Elle suit le contenu (main.js section 19) : pleine pendant la scène, réduite à son bouton d'appel
   (les deux flèches d'un ascenseur, 48 px, le texte gardé pour les lecteurs d'écran) dès que le contenu à plat passe
   dans le bas de l'écran, effacée tant qu'un formulaire occupe ce bas ou qu'un lien de station passe sous elle. */
.retour-ascenseur {
    position: fixed; left: var(--gutter); bottom: var(--s-4); z-index: 950;
    display: inline-flex; align-items: center; gap: var(--s-2); padding: 12px 18px; border-radius: var(--r-pill);
    max-width: min(16rem, calc(100vw - 2 * var(--gutter))); height: 46px; overflow: hidden; white-space: nowrap;
    background: var(--ink); color: var(--bg); font-weight: 600; font-size: var(--text-sm); letter-spacing: -0.01em;
    box-shadow: 0 12px 30px -12px rgba(0, 0, 0, 0.5);
}
.retour-ascenseur::before { content: ""; flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.retour-ascenseur { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
@media (hover: hover) and (pointer: fine) { .retour-ascenseur:hover { transform: translateY(-2px); } }
.retour-ascenseur.est-reduite { max-width: 48px; height: 48px; padding: 0 0 0 15px; gap: 40px; bottom: var(--s-6); }
.retour-ascenseur.est-reduite::before {
    width: 18px; height: 18px; border-radius: 0; box-shadow: none; background: currentColor;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'><path d='M9 1.5l5.5 6h-11zM9 16.5l-5.5-6h11z'/></svg>") center / contain no-repeat;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'><path d='M9 1.5l5.5 6h-11zM9 16.5l-5.5-6h11z'/></svg>") center / contain no-repeat;
}
/* réduite, l'anneau de l'appui entoure la pastille : le masque de la flèche couperait celui du point */
.retour-ascenseur.est-reduite:active { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 45%, transparent), 0 12px 30px -12px rgba(0, 0, 0, 0.5); }
.etage-contenu { position: relative; background: var(--bg); }
/* Les quatre grands formats de la galerie (étage 1), à plat : deux colonnes, le cartel sous chaque cadre */
.formats-grille { max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-8) var(--s-6); }
.format { margin: 0; }
.format .cadre { display: block; box-shadow: 0 18px 44px -20px var(--halo); }
.format a.cadre { color: inherit; text-decoration: none; }
.format figcaption { margin-top: var(--s-3); display: flex; flex-direction: column; gap: 2px; }
.format-titre { font-weight: 600; color: var(--ink); }
.format-sous { color: var(--mute); font-size: var(--text-sm); line-height: 1.5; }
@media (max-width: 720px) { .formats-grille { grid-template-columns: 1fr; } }
.etage-contenu .section-head { text-align: left; margin-left: 0; }
.etage-contenu .section-head h2::after { margin-left: 0; }
@media (max-width: 899px) {
    /* le bloc de texte se cale au bas de l'écran, au-dessus de la pastille « Retourner à l'ascenseur » (16 px du bord, 46 px de haut, 10 px d'air : 72 px) ; à 6 vh, le lien de la station passait sous la pastille */
    html.accueil-3d .station--piece .station-cadre, html.accueil-3d .station--arrivee .station-cadre { justify-content: flex-end; padding-bottom: 72px; }
    .plan-texte { max-width: none; }
    .plan-texte--droite { margin-left: 0; }
}
@media (min-width: 900px) {
    .plan-texte--droite { margin-left: 52%; }
}

/* ---- La fin de la pièce : au bout de la dernière station, la toile s'éteint vers la couleur de la salle (le script lie
        son opacité à la montée du contenu, commun-etage.js) pendant que le contenu à plat monte avec un bord fondu de
        36 vh, posé au-dessus du premier bloc ; sur une page qui finit par le palier, un bord de 30 vh sous le dernier bloc
        fond la page dans le palier (le blog finit par son pied court : rien ne le recouvre). Chaque bord prend la couleur
        du fond que son bloc peint vraiment (background-color: inherit) et la fond par un masque : aucune ligne au raccord.
        Le masque suit une courbe douce : aucune ligne ne se lit là où il commence. Les pages document (questions
        fréquentes, méthode) portent les leurs sur la page elle-même (main.css, section 12). ---- */
html.accueil-3d main.etage:not(.legal-page--doc) > [data-station] + :not([data-station]),
html.accueil-3d:has(footer.palier) main.etage:not(.legal-page--doc) > :not([data-station]):has(+ .retour-ascenseur) { position: relative; }
html.accueil-3d main.etage:not(.legal-page--doc) > [data-station] + :not([data-station])::before,
html.accueil-3d:has(footer.palier) main.etage:not(.legal-page--doc) > :not([data-station]):has(+ .retour-ascenseur)::after {
    content: ""; position: absolute; left: 0; right: 0; pointer-events: none; background-color: inherit;
    -webkit-mask-image: linear-gradient(to bottom, rgb(0 0 0 / 0), rgb(0 0 0 / 0.03) 12%, rgb(0 0 0 / 0.12) 26%, rgb(0 0 0 / 0.3) 42%,
        rgb(0 0 0 / 0.55) 58%, rgb(0 0 0 / 0.8) 76%, rgb(0 0 0 / 0.95) 90%, rgb(0 0 0));
    mask-image: linear-gradient(to bottom, rgb(0 0 0 / 0), rgb(0 0 0 / 0.03) 12%, rgb(0 0 0 / 0.12) 26%, rgb(0 0 0 / 0.3) 42%,
        rgb(0 0 0 / 0.55) 58%, rgb(0 0 0 / 0.8) 76%, rgb(0 0 0 / 0.95) 90%, rgb(0 0 0));
}
html.accueil-3d main.etage:not(.legal-page--doc) > [data-station] + :not([data-station])::before { bottom: 100%; height: 36vh; }
html.accueil-3d:has(footer.palier) main.etage:not(.legal-page--doc) > :not([data-station]):has(+ .retour-ascenseur)::after { top: 100%; height: 30vh; transform: scaleY(-1); }

/* ---- Le palier de sortie : le pied de page des étages et des annexes, face aux portes de l'ascenseur. Rien ne part sans
        un geste : le lien « Retourner à l'ascenseur » appuie sur le bouton d'appel de la scène, les portes s'ouvrent, la
        caméra entre dans la cabine. En trois dimensions, le bloc de tête monte au-dessus des portes (la caméra cadre les
        portes dessous) et les mentions légales se posent en bas, au-dessus de la bande des boutons flottants. ---- */
footer.palier { position: relative; background: var(--bg-alt); padding: 0; overflow-x: clip; }   /* le voile derrière le texte déborde du bord : jamais de défilement horizontal */
footer.palier .station-cadre { display: flex; align-items: center; justify-content: center; text-align: center; padding: var(--section-pad) var(--gutter); }
html.accueil-3d footer.palier { background: transparent; min-height: 150vh; }
.palier-texte { position: relative; max-width: 560px; margin: 0 auto; }
.palier-tete, .palier-legal { position: relative; }
.palier-tete::before, .palier-legal::before {
    content: ""; position: absolute; inset: -12vh -30vw; z-index: -1; pointer-events: none;
    background: radial-gradient(closest-side at 50% 50%, color-mix(in srgb, var(--bg) 82%, transparent) 30%, color-mix(in srgb, var(--bg) 45%, transparent) 62%, transparent 100%);   /* transparent au bord de la boîte : aucun bord dur sur la scène */
}
.palier-legal::before { inset: -3vh -12vw; }
.palier-titre { font-size: clamp(1.6rem, 3vw, 2.4rem); margin-bottom: var(--s-3); text-wrap: balance; }
/* le geste (sync.js, etages.json) : sous la phrase de besoin, ce que cela vous demande ; Appeler, Écrire, puis le retour */
.palier-demande { color: var(--mute); max-width: 46ch; margin: 0 auto var(--s-2); text-wrap: balance; }
.palier-etat { min-height: 1.6em; color: var(--mute); margin: 0; }
.palier-actions { display: flex; gap: var(--s-3); justify-content: center; flex-wrap: wrap; margin: var(--s-6) 0 var(--s-8); }
.palier-legal { font-size: var(--text-sm); color: var(--mute); margin: 0; }
.palier-legal a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
html.accueil-3d footer.palier .station-cadre {
    flex-direction: column; align-items: stretch; justify-content: flex-start;
    padding: calc(52px + 3vh) var(--gutter) calc(96px + env(safe-area-inset-bottom));
}
html.accueil-3d .palier-texte { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 640px; height: 100%; }
html.accueil-3d .palier-actions { margin-bottom: 0; }
html.accueil-3d .palier-legal { margin-top: auto; }
/* au bout de dix secondes au palier sans geste, « Appeler » pulse doucement (le retour, sur un palier sans geste ; le
   script pose est-appel) ; jamais en mouvement réduit */
@media (prefers-reduced-motion: no-preference) {
    html.accueil-3d .palier-actions .btn.est-appel { animation: palier-appel 2.8s var(--ease) infinite; }
}
@keyframes palier-appel {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
    60% { box-shadow: 0 0 0 14px color-mix(in srgb, var(--accent) 0%, transparent); }
}
.retour-ascenseur {
    transition: opacity 0.3s var(--ease), transform 0.2s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease),
                max-width 0.3s var(--ease), padding 0.3s var(--ease), height 0.3s var(--ease), bottom 0.3s var(--ease);
}
.retour-ascenseur.est-cache {
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity 0.25s var(--ease), visibility 0s linear 0.25s;
}
/* effacée devant la saisie ou un lien (main.js section 19) : elle fond et laisse passer le pointeur, mais reste dans
   la suite du clavier ; au focus, elle revient */
.retour-ascenseur.est-effacee { opacity: 0; pointer-events: none; }
.retour-ascenseur.est-effacee:focus-visible { opacity: 1; pointer-events: auto; }
.scene-voile.palette-cabine { background: #23262c; }
html.accueil-3d footer.palier .station-cadre { opacity: clamp(0, calc((var(--pe) - 0.4) / 0.35), 1); }
/* le départ : la ligne d'état parle, le palier s'efface */
@media screen and (prefers-reduced-motion: no-preference) {
    html.accueil-3d:not(.a11y-animations) footer.palier:has(.palier-etat:not(:empty)) .palier-tete > .piece-numero,
    html.accueil-3d:not(.a11y-animations) footer.palier:has(.palier-etat:not(:empty)) .palier-titre,
    html.accueil-3d:not(.a11y-animations) footer.palier:has(.palier-etat:not(:empty)) .palier-demande,
    html.accueil-3d:not(.a11y-animations) footer.palier:has(.palier-etat:not(:empty)) .palier-actions .btn { opacity: 0; transition: opacity 220ms var(--mv-appui); }
    html.accueil-3d:not(.a11y-animations) footer.palier:has(.palier-etat:not(:empty)) .palier-actions .btn { transform: scale(0.97); }
    html.accueil-3d:not(.a11y-animations) footer.palier:has(.palier-etat:not(:empty)) .palier-legal { opacity: 0; transition: opacity 160ms var(--mv-appui); }
}

/* ---- Une ancre du contenu (contact.html#ecrire, depuis un article du blog) s'arrête sous la barre de menu ; à plat,
        la page à scène porte déjà 68 px de marge de défilement en haut (main.css, section 17) ---- */
.etage-contenu[id] { scroll-margin-top: calc(52px + var(--s-6)); }
html:not(.accueil-3d) .etage-contenu[id] { scroll-margin-top: var(--s-2); }

/* ---- Les pages « document » devenues scènes (questions fréquentes, méthode) : grille sommaire + corps ---- */
/* les stations prennent toute la largeur de la grille ; après elles, la page elle-même couvre la toile d'un bord à l'autre
   de l'écran, par son fond et ses bords fondus (main.css, section 12) */
main.legal-page--doc.etage > .station { grid-column: 1 / -1; }
/* un bandeau .panel dont le fond suit la palette de la salle prend aussi ses encres et la couleur de ses liens :
   le gris et le bleu clair des bandeaux noirs tombaient sous 4,5 pour 1 sur un fond de salle */
.panel.etage-contenu { --panel-ink: var(--ink); --panel-mute: var(--mute); --accent-on-dark: var(--accent); }
/* le contenu à plat après les stations : la première section garde de l'air sous la scène */
html.accueil-3d main.etage > .hero.etage-contenu { padding-top: var(--s-16); }

/* ---- La régie (?regie) ---- */
.regie {
    position: fixed; right: var(--s-4); top: 64px; z-index: 1002; width: 340px; max-width: calc(100vw - 32px);
    padding: var(--s-3) var(--s-4); border-radius: 12px; background: rgba(12, 14, 18, 0.88); color: #e8eaf0;
    font: 12px/1.45 ui-monospace, Menlo, Consolas, monospace; box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.6);
}
.regie pre { margin: 0 0 var(--s-2); white-space: pre-wrap; word-break: break-all; color: #ffd27a; }
.regie-actions { display: flex; gap: var(--s-2); margin-bottom: var(--s-2); }
.regie button { font: inherit; padding: 6px 10px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.25); background: transparent; color: inherit; cursor: pointer; }
.regie button[aria-pressed="true"] { background: #ffd27a; color: #111; }
.regie-defilement { display: flex; align-items: center; gap: var(--s-2); }
.regie-defilement input { flex: 1; }
.regie-aide { margin: var(--s-2) 0 0; color: #a9afbb; }

/* ---- Replis : pas de scène, la page à plat ---- */
/* « Lire l'offre sans la visite » (main.js, section 17) : html.sans-visite, la page à plat jusqu'au rechargement */
html.sans-entree .scene-toile, html.a11y-animations .scene-toile, html.sans-visite .scene-toile { display: none; }
html.a11y-animations .station-cadre { position: static; height: auto; }
html.a11y-animations .plan-texte, html.a11y-animations .tablette, html.a11y-animations .station-cadre { opacity: 1 !important; visibility: visible !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) { .scene-toile { display: none; } }
@media print { .scene-toile, .scene-voile, .retour-ascenseur, .regie { display: none !important; } }
