/* =============================================================
   Maquette 360 Muato — interface inspirée de visionOS (Apple Vision Pro)
   Verre sombre, texte blanc, ornement de navigation flottant, sans framework.
   Icônes : Lucide (ISC). Police : système Apple (SF Pro), sinon Inter locale (OFL).
   ============================================================= */

@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-VariableFont.ttf') format('truetype');
  font-weight: 100 900;
  font-display: swap;
}

:root {
  --police: 'Roboto', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;   /* Roboto partout */

  /* ---- Les deux verres dépolis : il n'y en a pas d'autre ----
     --flou        : panneaux de verre sombre (barre du bas, exposition,
                     chargement, fenêtre des images)
     --verre-leger : petits éléments posés sur la 3D (boutons de la barre,
                     infobulles des punaises) */
  --verre: rgba(28, 28, 30, 0.42);
  --verre-fort: rgba(28, 28, 30, 0.72);          /* sans flou (navigateurs non compatibles) */
  --flou: blur(7px) saturate(100%);            /* LE flou du verre : partout, boutons comme panneaux */
  --verre-leger: var(--flou);                  /* alias : même flou partout */
  /* Teinte des boutons de verre (boutons de vue, barre du bas, flèches et nom
     de la galerie) : verre dépoli teinté ardoise (#5f6975, le gris d'OrbitalHub),
     trois niveaux, du plus léger au plus foncé. Jamais de noir pur. */
  --verre-bouton: rgba(255, 255, 255, 0.14);         /* inactif : le verre blanc du « liquid glass » de référence */
  --verre-bouton-survol: rgba(95, 105, 117, 0.08);   /* survol */
  --verre-bouton-actif: rgba(95, 105, 117, 0.36);    /* actif */
  /* états sur verre sombre (barre du bas = la référence, boutons de vue) */
  --survol-verre: rgba(255, 255, 255, 0.12);
  --actif-verre: rgba(255, 255, 255, 0.28);

  /* ---- Barre de gauche et boutons blancs ---- */
  --blanc-barre: rgba(255, 255, 255, 0.6);       /* fond plat de la barre, sans verre */
  --contour: rgba(95, 105, 117, 0.35);           /* contour fin des boutons de verre */
  --contour-barre: rgba(28, 27, 25, 0.1);        /* contour de la barre de gauche et de sa poignée */

  /* Galerie : la montée et la descente du panneau. La barre de gauche fond
     avec exactement la même durée et la même courbe, dans les deux sens. */
  --galerie-montee: 500ms cubic-bezier(0.32, 0.72, 0, 1);
  --galerie-descente: 500ms cubic-bezier(0.32, 0, 0.67, 0);
  --encre: #1f1f1f;                              /* texte sombre : graphite, jamais de noir pur */
  --encre-2: rgba(28, 27, 25, 0.55);             /* texte sombre secondaire */
  --trait: 1px solid rgba(28, 27, 25, 0.18);     /* LA bordure fine, partout */
  --trait-survol: rgba(28, 27, 25, 0.45);        /* sa couleur au survol */
  --focus: 2px solid rgba(28, 27, 25, 0.7);      /* contour clavier */

  /* ---- Arrondis ---- */
  --rayon-carte: 0.5rem;                            /* miniatures */
  /* --rayon-bouton (pilule) et 50 % (rond) : voir plus bas */
  /* Liseré « liquid glass » : reflet en haut, plus léger en bas, contour fin */
  --lisere: inset 0 1px 1px rgba(255, 255, 255, 0.7), inset 0 -1px 1px rgba(255, 255, 255, 0.15), inset 0 0 0 1px rgba(255, 255, 255, 0.28);
  --ombre-verre: 0 0.625rem 1.875rem -0.625rem rgba(0, 0, 0, 0.12);   /* ombre des boutons de verre */
  /* Boutons de verre : texte noir et gras dans les trois états, liseré
     (reflets blancs, contour ardoise fin) identique ; seule la teinte change. */
  --lisere-bouton: inset 0 1px 1px rgba(255, 255, 255, 0.7), inset 0 -1px 1px rgba(255, 255, 255, 0.15), inset 0 0 0 1px var(--contour);
  --ombre: 0 0.375rem 1.125rem rgba(0, 0, 0, 0.14), 0 1px 3px rgba(0, 0, 0, 0.08);

  /* Texte et états */
  --texte: #ffffff;
  --texte-2: rgba(255, 255, 255, 0.62);
  --survol: rgba(255, 255, 255, 0.12);
  --actif: rgba(255, 255, 255, 0.28);

  /* Formes et mouvement */
  --rayon-panneau: 2rem;
  --rayon-bouton: 62.4375rem;
  --marge: 1.25rem;

  /* Fenêtre du projet (réf. fenêtre visionOS) et environnement autour */
  --marge-fenetre: 0px;   /* pas de marge blanche autour, dans l'iframe du site */
  --rayon-fenetre: 0px;   /* bord extérieur de la maquette : coins droits */
  --ombre-fenetre: 0 2.5rem 7.5rem rgba(0, 0, 0, 0.55), 0 0.5rem 1.5rem rgba(0, 0, 0, 0.3);

  /* Taille de la fenêtre : format des images de la maquette (2560x1440 = 16:9),
     la plus grande possible dans l'écran moins les marges */
  --ratio-l: 16;
  --ratio-h: 9;
  --largeur-fenetre: min(calc(100vw - 2 * var(--marge-fenetre)), calc((100vh - 2 * var(--marge-fenetre)) * var(--ratio-l) / var(--ratio-h)));
  --hauteur-fenetre: min(calc(100vh - 2 * var(--marge-fenetre)), calc((100vw - 2 * var(--marge-fenetre)) * var(--ratio-h) / var(--ratio-l)));
  /* Position du bord de la fenêtre (fenêtre centrée) */
  --bord-gauche: calc((100vw - var(--largeur-fenetre)) / 2);
  --bord-haut: calc((100vh - var(--hauteur-fenetre)) / 2);

  /* Largeur du panneau de navigation (utilisée aussi par la mini barre et les fenêtres) */
  --largeur-nav: 12.5rem;

  /* Bordure lumineuse visionOS (fenêtres d'images, infobulles) : épaisseur max */
  --arete: 3px;
  --ressort: cubic-bezier(0.34, 1.4, 0.64, 1);

  interpolate-size: allow-keywords;
}

/* ---------- L'échelle de l'interface ----------
   Toutes les tailles de ce fichier sont en rem. 1 rem vaut 16 px quand la
   fenêtre de la maquette fait 1440 px de large ou plus ; en dessous, il
   rétrécit en proportion, jusqu'à un plancher de 55 % (8,8 px). Barre de
   gauche, boutons, barre du bas, loader, galerie : tout suit, dans une
   iframe comme en pleine page. Restent en px : les filets de 1 à 3 px et
   les flous. */
html {
  font-size: clamp(8.8px, calc(var(--largeur-fenetre) / 90), 16px);
  -webkit-text-size-adjust: 100%;   /* le téléphone ne regonfle pas les petits textes */
  text-size-adjust: 100%;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: #ffffff;
  font-family: var(--police);
  -webkit-font-smoothing: antialiased;
}

button { font: inherit; color: inherit; }
[hidden] { display: none !important; }

.icone { width: 1.125rem; height: 1.125rem; flex: none; }

/* ---------- Mise en page ---------- */
.app { position: relative; width: 100%; height: 100%; }

/* Cadre extérieur : filet fin sur les quatre bords de la fenêtre du navigateur,
   posé au-dessus de tout et non cliquable */
.app::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 100;
  border: var(--trait);
  pointer-events: none;
}

/* Bordure de la fenêtre 3D, au-dessus des barres latérales */
.app::after {
  content: '';
  position: absolute;
  top: var(--bord-haut);
  left: var(--bord-gauche);
  width: var(--largeur-fenetre);
  height: var(--hauteur-fenetre);
  z-index: 101;
  border: var(--trait);
  pointer-events: none;
}

/* En plein écran : la maquette garde son format 16:9 et reste centrée. Sur un
   écran d'un autre format (tablette, téléphone), le blanc l'entoure — le
   fond est posé ici, sinon le navigateur peint en noir ce qui dépasse. Toute
   l'interface reste calée sur la fenêtre de la maquette, comme hors plein écran. */
.app:fullscreen,
.app:-webkit-full-screen {
  background: #ffffff;
}
.app:fullscreen::before,
.app:-webkit-full-screen::before { display: none; }
.app:fullscreen::backdrop,
.app:-webkit-full-screen::backdrop { background: #ffffff; }

/* Scène 3D : fenêtre aux coins arrondis au format des images, centrée, fixe ;
   ce qui dépasse au zoom est coupé */
.scene {
  position: absolute;
  inset: 0;
  margin: auto;
  width: var(--largeur-fenetre);
  height: var(--hauteur-fenetre);
  overflow: hidden;
  border-radius: var(--rayon-fenetre);
  background: #ffffff;
  isolation: isolate;          /* garantit la découpe du lecteur, zoom compris */
}
/* Bordure de la fenêtre 3D : dessinée en surcouche (voir .app::after),
   pour passer au-dessus des barres latérales */
.scene .wr360_player { width: 100%; height: 100%; background: #ffffff; }

/* ---------- Ornement de navigation ---------- */
.ornement {
  /* Panneau latéral de la fenêtre, toute la hauteur (réf. visionOS) */
  position: absolute;
  top: var(--bord-haut);
  left: var(--bord-gauche);
  z-index: 10;
  width: var(--largeur-nav);
  height: var(--hauteur-fenetre);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1.75rem 0.75rem 1rem;
  border-radius: var(--rayon-fenetre) 0 0 var(--rayon-fenetre);   /* suit les coins gauches de la fenêtre */
  /* Blanc plat, sans verre dépoli (ce sont les boutons qui ont le verre) ;
     texte noir : couleurs redéfinies ici pour tout le contenu de la barre */
  --texte: var(--encre);
  --texte-2: var(--encre-2);
  --survol: rgba(28, 27, 25, 0.08);
  --actif: rgba(28, 27, 25, 0.14);
  background-color: var(--blanc-barre);
  /* Contour du bord droit : un seul trait, qui s'interrompt derrière la poignée
     (sur la hauteur de la poignée) — c'est le contour de la poignée qui prend le relais.
     Jamais deux traits côte à côte. */
  background-image: linear-gradient(to bottom, var(--contour-barre) calc(1rem + 1px), transparent calc(1rem + 1px), transparent calc(4.5rem - 1px), var(--contour-barre) calc(4.5rem - 1px));
  background-position: right top;
  background-size: 1px 100%;
  background-repeat: no-repeat;
  color: var(--texte);
  transition: clip-path 0.35s ease, background-color var(--galerie-descente);   /* retour au blanc à 60 % : calé sur la descente */
}
.ornement::-webkit-scrollbar { display: none; }
/* Blanc plein quand la galerie est ouverte : fondu calé sur la montée du panneau. */
.app.galerie-ouverte .ornement { background-color: #ffffff; transition: clip-path 0.35s ease, background-color var(--galerie-montee); }   /* blanc plein quand la galerie est ouverte */
/* Pareil quand un plan de vente est ouvert : le fondu suit la montée du panneau
   du plan, puis sa descente (classes posées par vision.js). */
.app.plan-ouvert .ornement { background-color: #ffffff; transition: clip-path 0.35s ease, background-color 0.45s cubic-bezier(0.22, 1, 0.36, 1); }
.app.plan-fermeture .ornement { transition: clip-path 0.35s ease, background-color 0.4s cubic-bezier(0.55, 0, 0.55, 0.2); }

/* Barre repliée : elle se rétracte vers le bord gauche sans sortir du cadre,
   la languette reste au bord. Le découpage n'est posé que pendant le repli :
   en permanence, il couperait le verre dépoli des boutons de la 3D derrière. */
.app.nav-anim .ornement { clip-path: inset(0 0 0 0); }
.app.nav-repliee .ornement { clip-path: inset(0 100% 0 0); pointer-events: none; }

.ornement-bascule {
  position: absolute;
  z-index: 11;
  top: calc(var(--bord-haut) + 1rem);   /* en haut de la barre */
  left: calc(var(--bord-gauche) + var(--largeur-nav));
  width: 1.375rem;
  height: 3.5rem;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* même contour fin que les boutons de verre, sur les trois côtés libres */
  border: 1px solid var(--contour-barre);
  border-left: 0;
  border-radius: 0 0.625rem 0.625rem 0;
  background: var(--blanc-barre);                  /* comme la barre dont elle dépasse */
  color: var(--encre);
  cursor: pointer;
  transition: left 0.35s ease, background 0.2s ease;
}
.ornement-bascule:hover { background: rgba(255, 255, 255, 0.85); }
.ornement-bascule .icone { width: 1rem; height: 1rem; transition: transform 0.35s ease; }
.app.nav-repliee .ornement-bascule { left: var(--bord-gauche); }
.app.nav-repliee .ornement-bascule .icone { transform: rotate(180deg); }

/* Sans flou : le verre sombre devient opaque. (La barre de gauche n'en a pas
   besoin : elle n'a plus de verre ; avant, elle devenait noire ici.) */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .chargement { background: rgba(255, 255, 255, 0.9); }
}

/* Logo clair à l'origine : passé en noir pour le verre blanc */
/* Logo en haut, le reste de la barre poussé vers le bas */
.ornement-logo { display: block; width: 100%; height: auto; margin: 0 auto 0; }

/* Infos du lot, sous le logo, tant qu'un plan de vente est ouvert. Le bloc ne
   prend aucune hauteur dans la barre (son contenu déborde dessous) : rien ne
   bouge quand il apparaît, et c'est lui qui pousse le reste vers le bas. */
.lot-infos {
  height: 0;
  margin: 0 0 auto;
  overflow: visible;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.lot-infos-contenu { padding: 1.5rem 0.75rem 0; color: var(--texte); }
.lot-infos-nom { font-size: 1.375rem; font-weight: 400; line-height: 1.2; margin-bottom: 0.375rem; }
.lot-infos-ligne { font-size: 0.9375rem; font-weight: 400; line-height: 1.5; }

/* Plan ouvert : les infos du lot apparaissent sous le logo ; les boutons de la
   barre restent en place. Le fondu suit la montée du panneau du plan, puis sa
   descente. */
.app.plan-ouvert .lot-infos {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.app.plan-fermeture .lot-infos { transition: opacity 0.4s cubic-bezier(0.55, 0, 0.55, 0.2), visibility 0s linear 0.4s; }

/* Groupes repliables (details / summary natifs) */
.groupe summary { list-style: none; }
.groupe summary::-webkit-details-marker { display: none; }

.groupe-titre {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0.75rem;
  border-radius: 1rem;
  color: var(--texte);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
}
.groupe-titre span { flex: 1; }

.chevron { width: 1rem; height: 1rem; transition: transform 0.3s ease; }
.groupe[open] .chevron { transform: rotate(180deg); }

/* Ouverture / fermeture animée (Chrome, Edge ; instantanée ailleurs) */
.groupe::details-content {
  height: 0;
  opacity: 0;
  overflow: clip;
  transition: height 0.3s ease, opacity 0.3s ease, content-visibility 0.3s allow-discrete;
}
.groupe[open]::details-content { height: auto; opacity: 1; }

.groupe-contenu { display: flex; flex-direction: column; gap: 2px; padding: 2px 0 0.625rem; }
.boutons-chips { gap: 0.5rem; }   /* boutons de vue : un peu plus espacés */
/* Filtres : deux par ligne, et les deux ensemble font la largeur d'un bouton classique. */
.groupe-pilules { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; padding: 2px 0 0.75rem; }
.groupe-pilules .pilule { width: 100%; }

/* Choix : étages et outils (un seul sélectionné à la fois) */
.choix {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.5625rem 0.875rem;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: var(--texte);
  font-size: 0.9375rem;
  font-weight: 300;
  text-align: left;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.25s var(--ressort);
}
.choix:hover { background: var(--survol); }
.choix:active { transform: scale(0.97); }
.choix[aria-pressed="true"] {
  background: var(--actif);
  font-weight: 400;
}
/* Boutons de vue (Maquette, Plan de masse, Galerie) : verre « liquid glass »,
   trois états (voir --bouton-* en tête de fichier), texte toujours en gras. */
.boutons-chips .choix {
  border: 0;
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: var(--encre);
  font-weight: 400;
  position: relative;
  overflow: hidden;                    /* garde la tache de lumière dans le bouton */
  transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;   /* le mouvement : le ressort (vision.js) */
  will-change: transform;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.boutons-chips .choix:active { transform: none; }   /* l'appui est géré par le ressort */
.boutons-chips .choix:hover { background: var(--verre-bouton-survol); }
.boutons-chips .choix[aria-pressed="true"],
.boutons-chips .choix[aria-pressed="true"]:hover { background: var(--verre-bouton-actif); }

/* Pilules de filtre par typologie (pastille = couleur des infobulles du type).
   Le même verre que les boutons de vue, avec les trois mêmes états : cochée =
   actif, décochée = inactif, survol. L'appui est géré par le ressort (vision.js). */
.pilule {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4375rem 0.8125rem 0.4375rem 0.625rem;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: var(--encre);
  font-size: 0.875rem;
  font-weight: 400;
  cursor: pointer;
  position: relative;
  overflow: hidden;                    /* garde la tache de lumière dans le bouton */
  transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
  will-change: transform;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.pilule:hover { background: var(--verre-bouton-survol); }
.pilule[aria-pressed="true"],
.pilule[aria-pressed="true"]:hover { background: var(--verre-bouton-actif); }

.pastille {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--couleur, #ffffff);
  box-shadow: 0 0 0 2px rgba(28, 27, 25, 0.1);
}
/* Surface : réglette à deux poignées (min et max) */
.surface { padding: 0.25rem 0.5rem 0.875rem; }
.surface-entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.625rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texte);
  white-space: nowrap;   /* « 102 – 164 m² » sur une seule ligne */
}
/* Les valeurs : la typo du titre « Surface » à côté d'elles (taille, graisse,
   interlettrage, couleur). Seule exception, les capitales : « m² » reste en minuscule. */
.surface-valeurs { font-size: inherit; font-weight: inherit; letter-spacing: inherit; text-transform: none; color: var(--texte); }

.surface-reglette { position: relative; height: 1.625rem; }
.surface-piste,
.surface-plage {
  position: absolute;
  top: 50%;
  height: 0.3125rem;
  transform: translateY(-50%);
  border-radius: 62.4375rem;
  pointer-events: none;
}
/* Version sombre du verre : la barre de gauche est blanche, une tirette
   blanche ne s'y voit pas. Même verre que la tirette d'exposition (teinte
   translucide + flou), l'ardoise des boutons à la place du blanc — jamais
   d'aplat noir. */
.surface-piste {
  left: 0;
  right: 0;
  background: rgba(95, 105, 117, 0.14);          /* ardoise à 14 %, comme le blanc de la piste d'exposition */
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: 0 0 0 1px var(--contour);          /* la bordure des boutons, autour de la barre entière */
}
/* La partie choisie. Elle couvre toute la piste par défaut, pour que rien ne
   change à la fin du chargement, quand vision.js la cale sur les deux poignées. */
.surface-plage {
  left: 0;
  right: 0;
  background: rgba(95, 105, 117, 0.75);          /* ardoise à 75 %, comme le blanc de la partie parcourue */
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
}

.surface-reglette input[type="range"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1.625rem;
  margin: 0;
  background: none;
  pointer-events: none;
  -webkit-appearance: none;
  appearance: none;
}

/* Poignées façon Apple : pastille blanche, ombre douce, léger grossissement au clic */
/* poignées : flèche du système, pas de main d'attrape */
.surface-reglette input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  pointer-events: auto;
  width: 1.25rem;
  height: 1.25rem;
  border: 0;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 0 0 0.5px rgba(0, 0, 0, 0.06);
  cursor: grab;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.surface-reglette input[type="range"]::-moz-range-thumb {
  pointer-events: auto;
  width: 1.25rem;
  height: 1.25rem;
  border: 0;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 0 0 0.5px rgba(0, 0, 0, 0.06);
  cursor: grab;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.surface-reglette input[type="range"]:active::-webkit-slider-thumb {
  transform: scale(1.08);
  box-shadow: 0 2px 0.375rem rgba(0, 0, 0, 0.32), 0 0 0 0.5px rgba(0, 0, 0, 0.06);
  cursor: grabbing;
}
.surface-reglette input[type="range"]:active::-moz-range-thumb {
  transform: scale(1.08);
  box-shadow: 0 2px 0.375rem rgba(0, 0, 0, 0.32), 0 0 0 0.5px rgba(0, 0, 0, 0.06);
  cursor: grabbing;
}
.surface-reglette input[type="range"]:focus-visible::-webkit-slider-thumb { outline: var(--focus); outline-offset: 2px; }

.pilule[aria-pressed="false"] .pastille {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px rgba(28, 27, 25, 0.35);
}

.groupe-titre:focus-visible,
.choix:focus-visible,
.pilule:focus-visible {
  outline: var(--focus);
  outline-offset: 2px;
}


/* ---------- TEST RDC : barre du lot, à droite ---------- */
.ornement-droite {
  left: auto;
  right: var(--bord-gauche);
  width: var(--largeur-nav);   /* même largeur que la barre de gauche */
  border-radius: 0 var(--rayon-fenetre) var(--rayon-fenetre) 0;
  background-image: none;                           /* son trait est à gauche */
  box-shadow: inset 1px 0 0 var(--contour-barre);
  opacity: 1;
}

/* Croix de fermeture */
/* Lot, type et surface */
.panneau-infos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 1.125rem 0.25rem 0;
}
.panneau-lot-nom { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; }
.panneau-lot-type { font-size: 0.9375rem; }
.panneau-lot-surface { font-size: 0.8125rem; color: var(--texte-2); }

/* Bouton Ouvrir */
.panneau-ouvrir {
  margin: 1rem 0.25rem 0;
  padding: 0.625rem 1rem;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: var(--actif);
  color: var(--texte);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.25s var(--ressort);
}
.panneau-ouvrir:hover { background: rgba(28, 27, 25, 0.2); }
.panneau-ouvrir:active { transform: scale(0.97); }
.panneau-ouvrir:focus-visible { outline: var(--focus); outline-offset: 2px; }

/* Plan de vente : reste dans la fenêtre de la maquette, du bord gauche
   jusqu'à la barre de droite (qu'il ne recouvre pas) */
.pdf-plein {
  position: absolute;
  top: var(--bord-haut);
  /* à droite de la navigation, et jusqu'au bord droit de la 3D :
     il n'y a plus de barre à droite */
  left: calc(var(--bord-gauche) + var(--largeur-nav));
  right: var(--bord-gauche);
  height: var(--hauteur-fenetre);
  z-index: 90;
  background: #ffffff;
  overflow: hidden;
}
.pdf-plein img {
  position: absolute;
  top: 3.5rem;                      /* sous la barre du haut */
  left: 0;
  width: 100%;
  height: calc(100% - 3.5rem);
  object-fit: contain;
}

/* Barre du haut du plan : croix, Plan 2D, Plan 3D */
.plan-barre {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: 3.5rem;
  padding: 0 0.875rem;
}
/* ---------- Boutons blancs : LA famille de boutons sur fond blanc ----------
   Fond blanc plein, bordure fine (--trait), libellé gris ; au survol le trait
   et le libellé foncent, le fond ne bouge pas. Deux formes :
     .bouton-blanc       texte, en pilule   : Plan 2D, Plan 3D, PDF
     .bouton-blanc-rond  icône, ronde       : croix du plan, flèches de la galerie
   Les classes existantes sont rangées ici, sans toucher au HTML. */
.galerie-apercu {
  border: var(--trait);
  background: #ffffff;
  cursor: pointer;
}
.plan-onglet:focus-visible,
.plan-pdf:focus-visible,
.galerie-fleche:focus-visible,
.galerie-apercu:focus-visible { outline: var(--focus); outline-offset: 2px; }

/* Barre du plan : Plan 2D, Plan 3D, PDF et la croix. Le même verre que les
   boutons de vue de la barre de gauche, avec les trois mêmes états — inactif,
   survol, actif — et le même texte. L'appui est géré par le ressort (vision.js). */
.plan-onglet,
.plan-pdf,
.plan-barre .panneau-fermer {
  border: 0;
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: var(--encre);
  cursor: pointer;
  position: relative;
  overflow: hidden;                    /* garde la tache de lumière dans le bouton */
  transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
  will-change: transform;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.plan-onglet:hover:not(:disabled),
.plan-pdf:hover,
.plan-barre .panneau-fermer:hover { background: var(--verre-bouton-survol); }

/* Forme texte : pilule, aux mesures des boutons de vue. */
.plan-onglet,
.plan-pdf {
  padding: 0.5625rem 0.875rem;
  border-radius: var(--rayon-bouton);
  font-size: 0.9375rem;
  font-weight: 400;
}

/* L'onglet affiché est à l'état actif, comme le bouton de la vue en cours. */
.plan-onglet.is-actif,
.plan-onglet.is-actif:hover:not(:disabled) { background: var(--verre-bouton-actif); }
.plan-onglet:disabled { opacity: 0.35; cursor: default; }
.plan-onglet[hidden] { display: none; }

/* Bouton du PDF d'origine : ouvre un nouvel onglet, donc sans état actif. */
.plan-pdf { display: inline-flex; align-items: center; gap: 0.4375rem; }
/* display: inline-flex l'emporterait sur l'attribut hidden : il faut le dire. */
.plan-pdf[hidden] { display: none; }
.plan-pdf .icone { width: 0.9375rem; height: 0.9375rem; }

/* Forme icône : ronde. Dans la barre du plan, la croix prend la hauteur des onglets. */
.plan-barre .panneau-fermer {
  position: relative;
  top: auto;
  left: auto;
  margin-right: 0.375rem;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  opacity: 1;
}
.plan-barre .panneau-fermer .icone { width: 1rem; height: 1rem; stroke-width: 2; }

/* Barre de droite opaque tant que le plan est ouvert */
.ornement-droite.est-opaque {
  background: #ffffff;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.ornement-droite { transition: background 0.3s ease; }

/* Croix sur le plan : en encre, comme les onglets et le bouton du PDF. */
.pdf-plein .panneau-fermer { color: var(--encre); }

/* Ouverture : monte depuis le bas en fondu */
.pdf-plein.est-ouverture { animation: plan-entree 0.45s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes plan-entree {
  from { opacity: 0; transform: translateY(100%); }
  60%  { opacity: 1; }
  to   { opacity: 1; transform: translateY(0); }
}

/* Fermeture : repart vers le bas en fondu */
.pdf-plein.est-fermeture { animation: plan-sortie 0.4s cubic-bezier(0.55, 0, 0.55, 0.2) both; }
@keyframes plan-sortie {
  from { opacity: 1; transform: translateY(0); }
  40%  { opacity: 1; }
  to   { opacity: 0; transform: translateY(100%); }
}

@media (prefers-reduced-motion: reduce) {
  .pdf-plein.est-ouverture { animation: none; }
  .pdf-plein.est-fermeture { animation-duration: 0.01s; }
}

/* Croix simple, comme celle du lecteur d'origine : juste l'icône, sans fond ni ombre */
.panneau-fermer {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  width: 1.375rem;
  height: 1.375rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--texte);
  opacity: 0.7;
  cursor: pointer;
}
.panneau-fermer:hover { opacity: 1; }
.panneau-fermer .icone { width: 1.375rem; height: 1.375rem; stroke-width: 1.5; }

/* Ouverture : glisse depuis la droite, dépasse et revient (effet gelée) */
.ornement-droite.est-ouverture {
  animation: panneau-entree 0.6s cubic-bezier(0.34, 1.5, 0.64, 1) both;
  animation-timing-function: linear(0, 0.063 3.1%, 0.25 6.6%, 0.557 11.2%, 0.886 16.9%, 1.026 20.7%, 1.069 23.6%, 1.08 26.4%, 1.068 29.6%, 1.034 34%, 0.994 40.4%, 0.985 44.7%, 0.987 51.4%, 1.002 64.2%, 1);
}
@keyframes panneau-entree {
  from { opacity: 0; transform: translateX(100%) scaleX(1.04); }
  to { opacity: 1; transform: translateX(0) scaleX(1); }
}

/* Fermeture : repart vers la droite */
.ornement-droite.est-fermeture {
  animation: panneau-sortie 0.26s cubic-bezier(0.4, 0, 1, 1) both;
}
@keyframes panneau-sortie {
  from { opacity: 1; transform: translateX(0); }
  to { opacity: 0; transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  /* ouverture sans mouvement ; la fermeture garde une animation très courte,
     sinon la barre ne se cacherait jamais (c'est sa fin qui déclenche le masquage) */
  .ornement-droite.est-ouverture { animation: none; }
  .ornement-droite.est-fermeture { animation-duration: 0.01s; }
}


/* ---------- Exposition : horloge et tirette, à la place de la barre du bas ----------
   Même capsule de verre que la barre du bas, au même endroit : en bas, centrée
   sur le cadre entier. La classe .expo-active, posée sur le cadre par
   vision.js, efface la barre et montre la tirette, en fondu. */
.expo {
  position: absolute;
  bottom: calc(var(--bord-haut) + 1.25rem);      /* la hauteur de la barre du bas */
  left: 50%;                                     /* centrée sur le cadre entier, comme elle */
  transform: translateX(-50%);
  z-index: 12;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  min-height: 3.5rem;                            /* celle de la barre : boutons de 2.75rem + 2 × 0.375rem */
  padding: 0.375rem 1.25rem;
  border-radius: var(--rayon-bouton);
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: #ffffff;                                /* heure et tirette en blanc */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s ease, visibility 0s linear 0.25s;
}
.app.expo-active .expo {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.25s ease;
}
.app.expo-active .scene .wr360_player .container .theme_panel .toolbar {
  opacity: 0 !important;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .expo, .app.expo-active .expo { transition: none; } }

/* Les saisons passent à la ligne, sous l'horloge et la tirette. */
.expo { flex-wrap: wrap; }
.expo-saisons {
  flex-basis: 100%;
  display: flex;
  gap: 0.375rem;
}
.expo-saison {
  flex: 1;
  padding: 0.375rem 0.5rem;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: #ffffff;
  font-size: 0.8125rem;
  font-weight: 400;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.25s var(--ressort);
}
.expo-saison:hover { background: var(--verre-bouton-survol); }
.expo-saison:active { transform: scale(0.97); }
.expo-saison[aria-pressed="true"] { background: var(--verre-bouton-actif); }

.expo-heure {
  min-width: 3.25rem;
  font-size: 0.9375rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.expo-reglette { position: relative; width: 11.875rem; height: 1.625rem; }
.expo-piste,
.expo-plage {
  position: absolute;
  top: 50%;
  height: 0.3125rem;
  transform: translateY(-50%);
  border-radius: 62.4375rem;
  pointer-events: none;
}
/* La piste : le verre des boutons (fond et flou), sans liseré. */
.expo-piste {
  left: 0;
  right: 0;
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
}
.expo-plage { left: 0; background: rgba(255, 255, 255, 0.75); }

.expo-reglette input[type="range"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1.625rem;
  margin: 0;
  background: none;
  -webkit-appearance: none;
  appearance: none;
}
.expo-reglette input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 1.25rem;
  height: 1.25rem;
  border: 0;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  cursor: grab;
  transition: transform 0.15s ease;
}
.expo-reglette input[type="range"]::-moz-range-thumb {
  width: 1.25rem;
  height: 1.25rem;
  border: 0;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  cursor: grab;
}
.expo-reglette input[type="range"]:active::-webkit-slider-thumb { transform: scale(1.08); cursor: grabbing; }

/* ---------- Chargement ----------
   Le logo Muato Studio sur une carte de verre clair, au centre du cadre,
   une fine barre de progression dessous. La première image de la maquette
   reste visible autour, la barre de gauche et la barre du bas sont déjà là.
   À 100 %, la carte s'efface en fondu (vision.js, progression). */
.chargement {
  position: absolute;
  top: 50%;
  left: 50%;                                     /* centré sur le cadre entier, comme la barre du bas */
  transform: translate(-50%, -50%);
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.125rem 0.875rem;
  border-radius: 1.375rem;
  background: var(--blanc-barre);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  transition: opacity 0.4s ease;
}
.chargement.est-fini { opacity: 0; pointer-events: none; }
/* Sur le plan de masse, le chargement de la rotation ne se montre pas */
.app:has(.vue-pdm.est-visible) .chargement { opacity: 0; }
.chargement-logo { display: block; width: 11.875rem; height: auto; }
.chargement-piste { display: block; width: 11.875rem; height: 3px; border-radius: 62.4375rem; background: rgba(31, 31, 31, 0.12); overflow: hidden; }
.chargement-barre { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--encre); transition: width 0.3s linear; }
@media (prefers-reduced-motion: reduce) { .chargement, .chargement-barre { transition: none; } }

/* ---------- Infobulles au survol des punaises ----------
   Le style des boutons : même verre clair, même flou, même bordure, même
   ombre, texte en encre. Plus de couleur de typologie. */
.spot_indicator_custom {
  position: absolute;
  left: 2.75rem;
  top: 50%;
  display: none;
  width: max-content;
  max-width: 15rem;
  padding: 0.625rem 0.875rem 0.6875rem;
  border-radius: 1.125rem;
  /* Blanc à 60 %, celui de la barre de gauche : les boutons sont lisibles parce
     que la barre blanche est derrière eux ; l'infobulle, elle, est posée sur
     l'image, et le verre des boutons seul (blanc à 14 %) y laisse le texte illisible. */
  background: var(--blanc-barre);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: var(--encre);
  font-family: var(--police);
  font-weight: 400;
  font-size: 0.9375rem;                /* les infos : la taille et la graisse du texte des boutons */
  line-height: 1.35;
  white-space: nowrap;
  pointer-events: none;
  /* Au repos : effacée, à 95 %. La fermeture y revient en 0,16 s. */
  opacity: 0;
  transform: translateY(-50%) scale(0.95);
  transform-origin: left center;       /* elle s'ouvre toujours du même côté : depuis la punaise, vers la droite */
  transition: opacity 0.16s, transform 0.16s;
}

/* Ouverture « souple » : fondu court, et l'échelle part de 85 % sur une courbe
   de ressort — elle dépasse sa taille puis se pose. */
.spot_indicator_custom.est-visible {
  opacity: 1;
  transform: translateY(-50%) scale(1);
  transition: opacity 0.22s ease-out;
  /* repli pour les navigateurs sans linear() */
  animation: bulle-souple 0.5s cubic-bezier(0.34, 1.45, 0.64, 1) both;
  /* ressort */
  animation: bulle-souple 700ms linear(0, 0.04, 0.144, 0.288, 0.451, 0.615, 0.768, 0.901, 1.008, 1.088, 1.141, 1.171, 1.179, 1.172, 1.153, 1.128, 1.098, 1.069, 1.041, 1.018, 0.998, 0.984, 0.975, 0.969, 0.968, 0.969, 0.973, 0.977, 0.982, 0.988, 0.993, 0.997, 1, 1.003, 1.005, 1.005, 1.006, 1.006, 1.005, 1.004, 1) both;
}
@keyframes bulle-souple {
  from { transform: translateY(-50%) scale(0.85); }
  to   { transform: translateY(-50%) scale(1); }
}

/* La ligne de tête, en gros et en gras : le nom du lot (ou du bâtiment). Celui
   d'un lot prend la couleur de son filtre, posée par vision.js. */
.hspot_type {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
/* Les autres infos, dessous. */
.hspot_lot,
.hspot_surface,
.hspot_niveaux { color: var(--encre); }
.hspot_lot { margin-top: 2px; }
.hspot_niveaux { margin-top: 2px; }
.hspot_surface_nb { color: var(--encre); font-weight: 400; }

@media (prefers-reduced-motion: reduce) {
  .spot_indicator_custom { transition: none; }
  .spot_indicator_custom.est-visible { animation: none; }
}

/* ---------- Disponibilité des lots ----------
   La classe est posée par vision/statuts.js, d'après le fichier statuts.json
   qu'écrit OrbitalHub. Sans ce fichier, aucune de ces règles ne s'applique et
   les punaises restent telles qu'elles sont aujourd'hui.

   Aucune pastille n'est ajoutée sur les punaises, et rien n'est grisé ici :
   pour un lot retiré du marché, c'est statuts.js qui fait pointer l'icône sur
   la version grise de la palette, celle-là même que tu utilises déjà. Le
   dessin reste donc exactement celui d'origine, à la couleur près. */

/* Un lot vendu ou réservé se repère aussi dans son infobulle, où la mention
   se pose à côté de la typologie. */
[data-statut="reserve"] .hspot_type::after,
[data-statut="vendu"] .hspot_type::after {
  margin-left: 0.5rem;
  padding: 2px 0.5rem;
  border-radius: 62.4375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  vertical-align: middle;
}
/* Couleurs foncées : l'infobulle est maintenant claire. */
[data-statut="reserve"] .hspot_type::after {
  content: 'Réservé';
  background: rgba(224, 162, 26, 0.22);
  color: #8a5a00;
}
[data-statut="vendu"] .hspot_type::after {
  content: 'Vendu';
  background: rgba(208, 69, 58, 0.22);
  color: #a8322a;
}
/* Le lot disponible porte lui aussi sa mention dans l'infobulle. Il n'a pas
   de pastille sur la punaise pour autant : c'est le cas courant, le signaler
   partout couvrirait la maquette. */
[data-statut="disponible"] .hspot_type::after {
  content: 'Disponible';
  margin-left: 0.5rem;
  padding: 2px 0.5rem;
  border-radius: 62.4375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  vertical-align: middle;
  background: rgba(47, 168, 79, 0.22);
  color: #1f7a3a;
}

/* Lot vendu : infobulle grise, écriture blanche, et son plan ne s'ouvre plus
   (vision.js). Le nom du lot perd la couleur de son filtre, posée en style
   direct par le script : seule une règle !important peut la reprendre. */
[data-statut="vendu"] .spot_indicator_custom {
  background: rgba(92, 92, 92, 0.85);          /* le gris des pastilles de bâtiment */
  color: #ffffff;
}
[data-statut="vendu"] .spot_indicator_custom .hspot_type,
[data-statut="vendu"] .spot_indicator_custom .hspot_lot,
[data-statut="vendu"] .spot_indicator_custom .hspot_surface,
[data-statut="vendu"] .spot_indicator_custom .hspot_niveaux,
[data-statut="vendu"] .spot_indicator_custom .hspot_surface_nb { color: #ffffff !important; }
[data-statut="vendu"] .hspot_type::after { background: rgba(255, 255, 255, 0.22); color: #ffffff; }
/* la punaise d'un lot vendu ne se clique plus */
.scene .wr360_player .container .hotspot_indicator[data-statut="vendu"] { cursor: default; }

/* ---------- Fenêtre des punaises (images et plans de lots) ----------
   Style visionOS : fenêtre de verre sombre, texte blanc, boutons en verre sans bordure.
   Elle s'ouvre dans la zone de la 3D, sans recouvrir la navigation. */
.popup-image {
  position: absolute;
  top: var(--bord-haut);
  left: calc(var(--bord-gauche) + var(--largeur-nav));
  width: calc(var(--largeur-fenetre) - var(--largeur-nav));
  height: var(--hauteur-fenetre);
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 var(--rayon-fenetre) var(--rayon-fenetre) 0;   /* suit les coins droits de la fenêtre */
  background: rgba(255, 255, 255, 0.45);   /* voile blanc à opacité réduite, sans flou */
}

/* La fenêtre = l'image seule ; les boutons flottent dessus */
.popup-image-carte {
  --bordure-popup: 0px;                      /* pas de bande autour de l'image */
  position: relative;
  border-radius: calc(1.375rem + var(--bordure-popup));
  box-shadow: var(--ombre);
  color: var(--texte);
  font-family: var(--police);
}

/* Carte cachée tant que l'image n'est pas chargée : elle apparaît directement au bon format */
.popup-image-carte.est-en-attente { visibility: hidden; }

/* Voile : fondu doux à l'ouverture */
.popup-image { animation: popup-voile 0.25s ease-out both; }
@keyframes popup-voile { from { opacity: 0; } }

/* Ouverture effet gelée : un seul mouvement d'échelle piloté par une courbe de ressort
   (léger dépassement puis retour), fondu séparé et plus court. Seuls transform et opacity
   sont animés, sur une couche GPU dédiée, pour rester fluide. */
.popup-image-carte { will-change: transform, opacity; }
.popup-image-carte.est-ouverte {
  /* repli pour navigateurs sans linear() */
  animation: popup-fondu 0.2s ease-out both, popup-ressort 0.55s cubic-bezier(0.34, 1.45, 0.64, 1) both;
  /* ressort (Chrome, Edge, Firefox, Safari récents) */
  animation: popup-fondu 0.2s ease-out both, popup-ressort 0.7s linear(0, 0.063 3.1%, 0.25 6.6%, 0.557 11.2%, 0.886 16.9%, 1.026 20.7%, 1.069 23.6%, 1.08 26.4%, 1.068 29.6%, 1.034 34%, 0.994 40.4%, 0.985 44.7%, 0.987 51.4%, 1.002 64.2%, 1) both;
}
@keyframes popup-fondu { from { opacity: 0; } to { opacity: 1; } }
@keyframes popup-ressort { from { transform: scale(0.86); } to { transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
  .popup-image, .popup-image-carte.est-ouverte { animation: none; }
}

/* Bordure style visionOS des fenêtres d'images, posée sur le bord (aucune bande) : blanche et
   transparente, plus lumineuse en haut à gauche et en bas à droite (reflet). Les infobulles
   n'en ont plus : elles portent la bordure des boutons. */
.popup-image-carte::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  padding: calc(var(--arete) / var(--finesse, 1));   /* --finesse : 2 = bordure deux fois plus fine */
  border-radius: inherit;
  background: linear-gradient(135deg,
    rgba(255, 255, 255, 0.9) 0%,
    rgba(255, 255, 255, 0.45) 20%,
    rgba(255, 255, 255, 0.12) 48%,
    rgba(255, 255, 255, 0.22) 75%,
    rgba(255, 255, 255, 0.7) 100%);
  /* ne garde que l'anneau de la bordure */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}

/* Arête lumineuse d'épaisseur variable : plus marquée en haut à gauche, fine en bas à droite */
.popup-image-carte::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  box-shadow:
    inset calc(1.5px / var(--finesse, 1)) calc(1.5px / var(--finesse, 1)) 0 rgba(255, 255, 255, 0.8),
    inset calc(-1px / var(--finesse, 1)) calc(-1px / var(--finesse, 1)) 0 rgba(255, 255, 255, 0.3),
    inset 0 0 0 calc(1px / var(--finesse, 1)) rgba(255, 255, 255, 0.12);
  pointer-events: none;
}

/* Boutons du haut, posés sur l'image */
.popup-image-entete {
  position: absolute;
  top: calc(var(--bordure-popup) + 0.75rem);
  right: calc(var(--bordure-popup) + 0.75rem);
  z-index: 4;
}
/* Titre et surface : lus par les lecteurs d'écran, pas affichés */
.popup-image-titres {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.popup-image-actions { display: flex; align-items: center; gap: 0.5rem; }

/* Niveaux : sélecteur segmenté en verre */
.popup-image-niveaux:not(:empty) {
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--rayon-bouton);
  background: var(--verre);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere);
}
.popup-image-niveau {
  height: 1.875rem;
  padding: 0 0.75rem;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: var(--texte);
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s ease;
}
.popup-image-niveau:hover:not(:disabled) { background: var(--survol); }
.popup-image-niveau.is-actif { background: var(--actif); font-weight: 600; cursor: default; }

/* Boutons ronds en verre : fermer, flèches */
.popup-image-fermer,
.popup-image-fleche {
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--texte);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.25s var(--ressort);
}
.popup-image-fermer {
  background: var(--verre);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere);
}
.popup-image-fermer:hover { background: var(--verre-fort); }
.popup-image-fermer:active,
.popup-image-fleche:active { transform: scale(0.94); }

.popup-image-fermer:focus-visible,
.popup-image-niveau:focus-visible,
.popup-image-fleche:focus-visible,
.popup-image-point:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.85);
  outline-offset: 2px;
}

/* Image : coins très arrondis, liseré clair type Apple, taille réduite par rapport à la zone de la 3D */
.popup-image-cadre {
  position: relative;
  overflow: hidden;
  box-sizing: content-box;                   /* la bordure s'ajoute autour de l'image, sans la rogner */
  border: 0;
  border-radius: calc(1.375rem + var(--bordure-popup));
  aspect-ratio: var(--ratio, 1);
  width: min(
    calc((var(--largeur-fenetre) - var(--largeur-nav)) * 0.7),
    calc(var(--hauteur-fenetre) * 0.78 * var(--ratio, 1))
  );
}
.popup-image-cadre img { position: absolute; max-width: none; height: auto; }

/* Perspectives (punaises « Images ») : hauteur fixe selon l'orientation de l'image,
   largeur au format de l'image, réduite seulement si elle dépasse la zone de la 3D */
.popup-image-carte.est-paysage { --part-hauteur: 0.75; }
.popup-image-carte.est-portrait { --part-hauteur: 0.86; }
.popup-image-carte.est-photo .popup-image-cadre {
  width: min(
    calc((var(--largeur-fenetre) - var(--largeur-nav)) * 0.9),
    calc(var(--hauteur-fenetre) * var(--part-hauteur) * var(--ratio, 1))
  );
}

.popup-image-fleche {
  position: absolute;
  top: 50%;
  z-index: 1;
  translate: 0 -50%;
  background: var(--verre);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere);
}
.popup-image-fleche:hover { background: var(--verre-fort); }
.popup-image-fleche-gauche { left: 0.625rem; }
.popup-image-fleche-droite { right: 0.625rem; }

/* Points et lien, posés en bas de l'image */
.popup-image-pied {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--bordure-popup) + 0.75rem);
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  pointer-events: none;
}
.popup-image-points:not(:empty),
.popup-image-lien:not([hidden]) {
  pointer-events: auto;
  border-radius: var(--rayon-bouton);
  background: var(--verre);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere);
}
.popup-image-points { display: flex; gap: 0.375rem; }
.popup-image-points:not(:empty) { padding: 0.5rem 0.625rem; }
.popup-image-lien { padding: 0.375rem 0.75rem; }
.popup-image-point {
  width: 0.4375rem;
  height: 0.4375rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #ffffff;
  opacity: 0.35;
  cursor: pointer;
  transition: opacity 0.2s ease;
}
.popup-image-point.is-actif { opacity: 1; }
.popup-image-lien { font-size: 0.8125rem; font-weight: 600; color: var(--texte); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Curseur sur la 3D : main d'attrape ----------
   WebRotate impose « cursor:pointer » sur son conteneur et ses images. La vue
   se fait tourner par glissement, pas par clic : on met la main ouverte, qui
   se ferme pendant la rotation. Les curseurs de zoom (loupe) sont conservés. */
.scene .wr360_player,
.scene .wr360_player .container,
.scene .wr360_player .container > img {
  cursor: grab !important;
}
.scene .wr360_player .container:active,
.scene .wr360_player .container:active > img {
  cursor: grabbing !important;
}

/* ---------- Mini barre du bas : zoom et plein écran ----------
   Ce sont les boutons natifs de WebRotate (fonctionnement d'origine conservé),
   rhabillés en capsule de verre avec des icônes Lucide (masques SVG). */
.scene .wr360_player .container .theme_panel_back { display: none !important; }

.scene .wr360_player .container .theme_panel {
  left: 0 !important;                       /* centrée sur le cadre entier de la maquette */
  width: 100% !important;
  bottom: 1.25rem !important;
  height: auto !important;
  background: none !important;
  cursor: default !important;
  pointer-events: none;
}

.scene .wr360_player .container .theme_panel .toolbar {
  display: flex !important;
  gap: 0.25rem;
  width: max-content !important;
  height: auto !important;
  margin: 0 auto !important;
  padding: 0.375rem !important;
  border-radius: var(--rayon-bouton);
  background: var(--verre-bouton) !important;
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  pointer-events: auto;
  transition: opacity 0.25s ease;      /* s'efface devant la tirette d'exposition */
}

/* Changement d'étage : l'image qu'on quitte reste un instant par-dessus la
   nouvelle et s'efface (vision.js, fonduDeRangee). */
.fondu-rangee {
  position: absolute;
  z-index: 1;                 /* celui de l'image du lecteur : posée après elle, la copie passe dessus, et reste sous les punaises et la barre */
  margin: 0;
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.4s ease;
}
.fondu-rangee.est-efface { opacity: 0; }

/* Les pastilles des punaises sont toujours à 100 % d'opacité. Le lecteur les
   fait parfois apparaître en fondu, et un fondu interrompu (changement d'image
   en cours de route) peut les laisser à moitié transparentes : on l'interdit. */
.scene .wr360_player .container .hotspot_indicator { opacity: 1 !important; }

/* Filtre décoché : la punaise repart comme elle est arrivée, en rétrécissant —
   l'inverse de l'effet « scaleUp » du lecteur, même durée, même courbe.
   vision.js (cacherPunaise) la cache pour de bon à la fin. */
.scene .wr360_player .container .hotspot_indicator.est-sortie {
  pointer-events: none;
  animation: punaise-sortie 0.3s cubic-bezier(.22, .02, .13, .99) forwards;
}
@keyframes punaise-sortie {
  from { transform: scale(1, 1); }
  to   { transform: scale(0, 0); }
}

.scene .wr360_player .container .theme_panel .toolbar > a {
  position: relative;
  float: none !important;
  width: 2.75rem !important;
  height: 2.75rem !important;
  margin: 0 !important;
  border-radius: 50%;
  background: transparent none !important;
  opacity: 1 !important;
  cursor: pointer;
  overflow: hidden;                    /* garde la tache de lumière dans le bouton */
  will-change: transform;
  transition: background-color 0.2s ease !important;   /* le mouvement est piloté par le ressort */
}
.scene .wr360_player .container .theme_panel .toolbar > a:hover { background-color: var(--verre-bouton-survol) !important; }

/* Icône blanche dessinée par un masque SVG */
.scene .wr360_player .container .theme_panel .toolbar > a::before {
  content: '';
  position: absolute;
  inset: 0.6875rem;
  background-color: var(--encre);
  -webkit-mask: var(--icone) center / contain no-repeat;
  mask: var(--icone) center / contain no-repeat;
}

/* Lucide zoom-in */
.scene .wr360_player .container .theme_panel .toolbar a.zoomin_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' x2='16.65' y1='21' y2='16.65'/%3E%3Cline x1='11' x2='11' y1='8' y2='14'/%3E%3Cline x1='8' x2='14' y1='11' y2='11'/%3E%3C/svg%3E");
}
/* Lucide zoom-out */
.scene .wr360_player .container .theme_panel .toolbar a.zoomout_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' x2='16.65' y1='21' y2='16.65'/%3E%3Cline x1='8' x2='14' y1='11' y2='11'/%3E%3C/svg%3E");
}
/* Lucide maximize */
.scene .wr360_player .container .theme_panel .toolbar a.fullscreenon_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 3H5a2 2 0 0 0-2 2v3'/%3E%3Cpath d='M21 8V5a2 2 0 0 0-2-2h-3'/%3E%3Cpath d='M3 16v3a2 2 0 0 0 2 2h3'/%3E%3Cpath d='M16 21h3a2 2 0 0 0 2-2v-3'/%3E%3C/svg%3E");
}

/* Flèches haut / bas : masquées, le changement de rangée se fait par la navigation */
.scene .wr360_player .container .theme_panel .toolbar a.up_button,
.scene .wr360_player .container .theme_panel .toolbar a.down_button { display: none !important; }

/* Lucide chevron-left */
.scene .wr360_player .container .theme_panel .toolbar a.left_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 18-6-6 6-6'/%3E%3C/svg%3E");
}
/* Lucide chevron-right */
.scene .wr360_player .container .theme_panel .toolbar a.right_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
}
/* Lucide play */
.scene .wr360_player .container .theme_panel .toolbar a.play_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z'/%3E%3C/svg%3E");
}
/* Lucide pause */
.scene .wr360_player .container .theme_panel .toolbar a.pause_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='14' y='3' width='5' height='18' rx='1'/%3E%3Crect x='5' y='3' width='5' height='18' rx='1'/%3E%3C/svg%3E");
}
/* Lucide map-pin */
.scene .wr360_player .container .theme_panel .toolbar a.hotspotson_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}
/* Lucide map-pin-off */
.scene .wr360_player .container .theme_panel .toolbar a.hotspotsoff_button {
  --icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12.75 7.09a3 3 0 0 1 2.16 2.16'/%3E%3Cpath d='M17.072 17.072c-1.634 2.17-3.527 3.912-4.471 4.727a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 1.432-4.568'/%3E%3Cpath d='m2 2 20 20'/%3E%3Cpath d='M8.475 2.818A8 8 0 0 1 20 10c0 1.183-.31 2.377-.81 3.533'/%3E%3Cpath d='M9.13 9.13a3 3 0 0 0 3.74 3.74'/%3E%3C/svg%3E");
}

/* Zoom indisponible (état géré par WebRotate) */
.scene .wr360_player .container_zoomoff .theme_panel .toolbar a.zoomin_button { opacity: 0.4 !important; cursor: default; }

/* ---------- Galerie : s'ouvre comme le plan de vente ----------
   Image en pleine page (paysage recadré, portrait entier), fondu enchaîné
   entre deux images empilées ; miniatures en bas, flèches sur les côtés.
   Bordure et fond des miniatures et flèches : famille « boutons blancs ». */
.galerie-plein img.galerie-vue {
  top: 0; left: 0; width: 100%; height: 100%;
  object-fit: cover;                 /* paysage : pleine page */
  background: transparent;           /* pas de voile blanc pendant le fondu */
  opacity: 0;
  transition: opacity 600ms ease-in-out;
}
.galerie-plein img.galerie-vue.est-visible { opacity: 1; }
.galerie-plein img.galerie-vue.est-portrait { object-fit: contain; }
@media (prefers-reduced-motion: reduce) { .galerie-plein img.galerie-vue { transition: none; } }

/* Miniatures : posées sur l'image, sans bloc autour */
.galerie-apercus {
  position: absolute;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  gap: 0.5rem;
  max-width: calc(100% - 2.5rem);
  overflow-x: auto;
  scrollbar-width: none;
  padding: 0.25rem;                      /* laisse la place au contour clavier */
}
.galerie-apercus::-webkit-scrollbar { display: none; }
.galerie-apercu {
  position: relative;
  flex: none;
  width: 6rem;
  height: 3.75rem;
  padding: 0;                        /* l'image va jusqu'à la bordure */
  border-radius: var(--rayon-carte);
  overflow: hidden;
}
/* position: static annule la règle « .pdf-plein img » (image du plan, en absolu) */
.galerie-apercu img { position: static; display: block; width: 100%; height: 100%; object-fit: cover; }
/* Inactive : voile blanc léger ; survolée ou affichée : sans voile */
.galerie-apercu::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.25);
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.galerie-apercu:hover::after,
.galerie-apercu.is-actif::after { opacity: 0; }

/* Nom de l'image : masqué pour le moment (retirer cette ligne pour le remettre) */
.galerie-titre { display: none !important; }
/* Nom de l'image, en haut à droite : pilule de verre, comme les boutons */
.galerie-titre {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 2;
  max-width: calc(100% - 2.5rem);
  padding: 0.5rem 1rem;
  border-radius: var(--rayon-bouton);
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: var(--encre);
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

/* Flèches du carrousel */
.galerie-fleche {
  position: absolute;
  top: calc(50% - 1.5rem);
  z-index: 2;
  width: 3rem;
  height: 3rem;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* « liquid glass », comme les boutons de vue et la barre du bas */
  border: 0;
  background: var(--verre-bouton);
  -webkit-backdrop-filter: var(--flou);
  backdrop-filter: var(--flou);
  box-shadow: var(--lisere-bouton), var(--ombre-verre);
  color: var(--encre);
  cursor: pointer;
  overflow: hidden;                    /* garde la tache de lumière dans le bouton */
  will-change: transform;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.2s ease;    /* le mouvement est piloté par le ressort */
}
.galerie-fleche:hover { background: var(--verre-bouton-survol); }
.galerie-fleche .icone { width: 1.375rem; height: 1.375rem; stroke-width: 2.4; }
.galerie-fleche-gauche { left: 1.25rem; }
.galerie-fleche-droite { right: 1.25rem; }
.galerie-fleche[hidden] { display: none; }

/* ---------- Rebond au clic ----------
   Écrasement puis retour, comme les filtres du portfolio de muato.studio.
   La classe is-jelly est posée par vision.js (initGelee). */
.galerie-apercu.is-jelly { animation: chip-jelly 0.4s ease-out; }
@keyframes chip-jelly {
  0% { transform: scale(1, 1); }
  30% { transform: scale(0.98, 0.97); }
  65% { transform: scale(1.01, 1.01); }
  100% { transform: scale(1, 1); }
}
@media (prefers-reduced-motion: reduce) {
  .galerie-apercu.is-jelly { animation: none; }
}

/* ---------- Appui « liquid glass » ----------
   Boutons de vue et boutons de la barre du bas : à l'appui, le bouton s'écrase
   vers le doigt et une tache de lumière s'allume dessous ; au relâché, il
   revient en rebondissant. Ressort physique dans vision.js (initAppuiVerre). */
.appui-lumiere {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
}

/* ---------- Galerie : croix, et ouverture sans fondu ----------
   La croix reprend le bouton de verre des flèches, en haut à droite. */
.galerie-fleche.galerie-fermer { top: 1.25rem; right: 1.25rem; left: auto; }
/* À l'ouverture, le panneau monte sans fondu, façon feuille iOS : départ doux,
   arrivée posée (500 ms). La fermeture redescend en 350 ms, départ doux puis accélération. */
.galerie-plein.est-ouverture { animation: galerie-montee var(--galerie-montee) both; }
/* Fermeture : le panneau redescend, sans fondu lui non plus */
.galerie-plein.est-fermeture { animation: galerie-descente var(--galerie-descente) both; }
@keyframes galerie-descente {
  from { transform: translateY(0); }
  to   { transform: translateY(100%); }
}
@keyframes galerie-montee {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
/* et la première image est posée d'emblée */
.galerie-plein.sans-fondu img.galerie-vue { transition: none; }

/* ---------- Plan de masse : image unique sur la 3D ----------
   Un voile blanc couvre tout le lecteur (barre du bas comprise) ; l'image est
   montrée entière dans la zone à droite de la barre de gauche, et ne bouge
   pas quand la barre se replie. Apparition et disparition en fondu. */
.vue-pdm {
  position: absolute;
  inset: 0;
  z-index: 50;
  background: #ffffff;
  opacity: 0;
  visibility: hidden;
  transition: opacity 600ms ease-in-out, visibility 0s 600ms;
}
.vue-pdm.est-visible { opacity: 1; visibility: visible; transition: opacity 600ms ease-in-out; }
/* Domaine Ilia : le plan de masse est au format et au cadrage des étages. Il
   occupe donc tout le cadre et passe sous la barre de gauche, comme eux — et
   ne bouge pas quand la barre se replie. */
.vue-pdm-zone {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  container-type: size;
  display: grid;
  place-items: center;
}
/* Le cadre : l'image entière, la plus grande possible dans la zone, à son format. */
.vue-pdm-cadre {
  position: relative;
  aspect-ratio: var(--ratio, 1.7778);
  width: min(100cqw, calc(100cqh * var(--ratio, 1.7778)));
}
.vue-pdm-cadre > img { display: block; width: 100%; height: 100%; }

/* Hotspots de bâtiment : posés dans WebRotate sur la rangée du plan de masse,
   relevés par la procédure (medias.json), recréés ici à la même place. Même
   icône que dans le lecteur, même infobulle que les lots. */
.pdm-spot {
  position: absolute;
  z-index: 4;
  width: 1.5625rem;
  height: 1.5625rem;
  transform: translate(-50%, -50%);
}
.pdm-spot > img { display: block; width: 100%; height: 100%; }
@media (prefers-reduced-motion: reduce) { .vue-pdm, .vue-pdm.est-visible { transition: none; } }
