/* ═══════════════════════════════════════════════════════════════════════════
   Player de réalité augmentée — plein écran, sur le flux caméra
   ═══════════════════════════════════════════════════════════════════════════ */

/* MindAR insère sa vidéo caméra en enfant direct de <body> avec z-index: -2.
   Dans l'ordre de peinture CSS, le fond propre du <body> est dessiné APRÈS les
   descendants à z-index négatif : un fond opaque sur <body> recouvre donc la
   caméra. La couleur de fond vit sur <html> — elle sert de fond au canevas,
   toujours derrière tout — et <body> reste transparent. */
html { background: #05070c; }
html, body.player { margin: 0; height: 100%; overflow: hidden; }
body.player { color: #fff; background: transparent; }

/* ── Écran d'accueil ──────────────────────────────────────────────────────── */
.pl-accueil {
  position: fixed; inset: 0; z-index: 30; display: flex;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 28px; text-align: center;
  background: radial-gradient(120% 90% at 50% 0%, #262347 0%, #0e1119 60%, #05070c 100%);
}
.pl-accueil h1 { font-size: 1.45rem; margin: 0; letter-spacing: -.02em; }
.pl-accueil .auteur { color: #9aa3bd; font-size: .93rem; margin: 0; }
.pl-accueil .consigne {
  max-width: 340px; color: #c2c9dd; font-size: .93rem; line-height: 1.55;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1);
  border-radius: 14px; padding: 14px 16px; margin: 4px 0;
}
.pl-accueil .cible-apercu {
  max-width: 190px; border-radius: 12px; border: 2px solid rgba(255,255,255,.22);
  box-shadow: 0 8px 30px rgba(0,0,0,.5);
}
.pl-demarrer {
  padding: 15px 30px; border: 0; border-radius: 999px;
  background: linear-gradient(135deg, #5b4bdb, #00b3a4); color: #fff;
  font: inherit; font-size: 1.03rem; font-weight: 650; cursor: pointer;
  box-shadow: 0 8px 26px rgba(91,75,219,.45);
}
.pl-erreur {
  max-width: 360px; background: rgba(200,56,47,.14); border: 1px solid rgba(240,115,106,.45);
  color: #ffb4ae; border-radius: 14px; padding: 14px 16px; font-size: .9rem; line-height: 1.5;
}
.pl-erreur strong { color: #fff; }

/* ── Vue caméra (mode superposition) ──────────────────────────────────────── */
.pl-vue { position: fixed; inset: 0; display: none; }
.pl-vue.actif { display: block; }
.pl-camera { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Le repère de composition : même proportion que dans l'éditeur, ajusté à l'écran
   en « contain » pour que rien de ce qui a été placé ne soit coupé. */
.pl-scene {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  aspect-ratio: 9 / 16; height: 100%; max-width: 100%;
  pointer-events: none;
  /* Même rognage que l'éditeur : ce qui sortait du cadre de composition n'y
     était pas visible, il ne doit pas apparaître ici. */
  overflow: hidden;
}
.pl-scene .el { position: absolute; transform-origin: center; pointer-events: none; }
.pl-scene .el .contenu {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  overflow: hidden; box-sizing: border-box;
}
.pl-scene .el .contenu img,
.pl-scene .el .contenu video { width: 100%; height: 100%; object-fit: contain; display: block; }
.pl-scene .el .contenu.texte {
  padding: .35em .6em; line-height: 1.25; border-radius: 8px;
  word-break: break-word; white-space: pre-wrap;
  overflow: visible;
}
.pl-scene .el .contenu.bouton {
  border-radius: 999px; padding: .3em 1em; font-weight: 650; white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0,0,0,.4);
}
.pl-scene .el .contenu.pl-diaporama-vide { font-size: 1.8rem; opacity: .5; background: #0b0f1a; }
/* Même vue que l'éditeur (assets/modele3d.js) : le canevas déborde de la boîte. */
.pl-scene .el .contenu.modele3d { position: relative; overflow: visible; }
.pl-scene .el .contenu.modele3d canvas { display: block; max-width: none; }
.pl-modele3d-vide {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; width: 100%; height: 100%; font-size: 1.8rem; color: #fff;
  text-shadow: 0 1px 4px rgba(0,0,0,.6);   /* lisible sur flux caméra comme sur l'image cible */
}
.pl-modele3d-vide small { font-size: .6rem; opacity: .7; }
.pl-scene .el.cliquable { pointer-events: auto; cursor: pointer; }
/* Un doigt couvre une dizaine de pixels : la zone de toucher d'une image ou
   d'un bouton déborde un peu de sa boîte, sans rien changer à ce qu'on voit. */
.pl-scene .el.cliquable::after { content: ''; position: absolute; inset: -10px; }
.pl-scene .el.cliquable:active { filter: brightness(1.15); }

/* ── Barre d'outils flottante ─────────────────────────────────────────────── */
/* La barre d'outils est du décor d'application, pas du contenu : elle ne doit
   jamais recouvrir la scène de l'étudiant. Deux mesures conjointes —
   1. elle se replie en bas à droite au lieu de barrer toute la largeur ;
   2. elle s'efface au bout de quelques secondes, et un toucher la ramène.
   Sans cela, un bouton placé en bas de scène était définitivement inaccessible :
   pointer-events: none sur le conteneur n'y change rien, ce sont les boutons
   eux-mêmes qui se superposaient. */
.pl-outils {
  position: fixed; right: 0; bottom: 0; z-index: 20;
  display: flex; align-items: center; gap: 7px; justify-content: flex-end;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  pointer-events: none;
  transition: opacity .35s ease, transform .35s ease;
}
.pl-outils > * { pointer-events: auto; transition: opacity .35s ease, transform .35s ease; }
/* Repliée, la barre ne garde que « Quitter », estompé mais toujours touchable
   du premier coup : avant, le premier toucher ne faisait que ramener la barre,
   et il fallait tapoter deux fois pour sortir. Seul dans le coin, il ne masque
   rien de la scène. */
.pl-outils.replie > * { opacity: 0; transform: translateY(8px); pointer-events: none; }
.pl-outils.replie > #btnQuitter { opacity: .6; transform: none; pointer-events: auto; }
.pl-bouton {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 15px; min-height: 44px; box-sizing: border-box;   /* 44 px : cible tactile minimale recommandée */
  border: 1px solid rgba(255,255,255,.22); border-radius: 999px;
  background: rgba(15,18,28,.8); color: #fff; backdrop-filter: blur(8px);
  font: inherit; font-size: .82rem; font-weight: 550; cursor: pointer; text-decoration: none;
  white-space: nowrap;
}
.pl-bouton:hover { background: rgba(35,40,58,.85); }
.pl-bouton.principal { background: var(--primaire, #5b4bdb); border-color: transparent; }
/* Écoute en cours : la barre se replie, mais le bouton doit dire d'un coup
   d'œil que le son continue quand le panneau est refermé. */
.pl-bouton.actif { background: rgba(18,145,95,.55); border-color: rgba(63,201,141,.6); }

/* Indication de recherche de la cible */
.pl-indice {
  position: fixed; left: 50%; top: 22px; transform: translateX(-50%); z-index: 20;
  padding: 9px 17px; border-radius: 999px; font-size: .86rem;
  background: rgba(15,18,28,.78); backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.16); display: none; text-align: center;
  pointer-events: none;   /* purement informatif : ne doit rien intercepter */
}
.pl-indice.visible { display: block; }

/* Panneau d'information déclenché par un bouton de la scène */
.pl-info {
  position: fixed; inset: auto 0 0; z-index: 40; display: none;
  background: #171b26; border-radius: 20px 20px 0 0;
  padding: 22px 20px calc(22px + env(safe-area-inset-bottom));
  box-shadow: 0 -8px 40px rgba(0,0,0,.6); max-height: 70dvh; overflow-y: auto;
}
.pl-info.visible { display: block; animation: plMonte .22s ease; }
@keyframes plMonte { from { transform: translateY(24px); opacity: 0; } }
.pl-info p { white-space: pre-wrap; line-height: 1.6; margin: 0 0 16px; }

/* La scène A-Frame occupe tout l'écran en mode image cible */
.a-enter-vr, .a-enter-ar { display: none !important; }
a-scene { position: fixed !important; inset: 0; }

/* ── Mode simulation : la scène sans caméra ───────────────────────────────── */
/* La marge est volontairement fine : c'est le script qui met la composition à
   l'échelle de la fenêtre (mettreALEchelle), en tenant compte des éléments
   placés au-delà des bords de la cible. Une marge en pourcentage ne pouvait pas
   le faire — un pourcentage de padding se calcule sur la LARGEUR, même en
   vertical : sur une fenêtre large et basse, elle mangeait toute la hauteur. */
.pl-simu-fond {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: #0d1017; padding: 16px;
  /* Le pincer-zoomer du navigateur est coupé sur toute la page (user-scalable=no,
     indispensable ailleurs pour ne pas dérégler la caméra) : c'est cette zone qui
     gère elle-même le geste, molette/pincer/glisser (brancherZoomSimu). */
  touch-action: none;
}
.pl-simu-fond.zoome { cursor: grab; }
.pl-simu-fond.zoome:active { cursor: grabbing; }
.pl-simu-fond.pl-simu-camera {
  background: radial-gradient(120% 90% at 30% 15%, #3a4a63 0%, #1d2432 55%, #12161f 100%);
}
/* En superposition, le cadre EST l'écran du téléphone : ce qui en sort ne serait
   jamais visible, la simulation le rogne comme l'éditeur et le player. */
.pl-simu-fond.pl-simu-camera .pl-simu { overflow: hidden; }

/* Le repère de la scène EST le support : mêmes bords, même format. En image
   cible, on ne rogne pas — des éléments peuvent flotter tout autour de l'objet.
   Les dimensions exactes sont posées en pixels par mettreALEchelle() ; celles
   qui suivent ne sont qu'un filet, le temps que le script s'exécute. */
.pl-simu {
  position: relative; pointer-events: none; display: block;
  width: 60vmin; height: 60vmin;
}
/* La cible remplit exactement le repère : c'est le script qui donne à celui-ci
   le format de l'image, si bien que « contain » ne laisse aucun bord. */
.pl-simu-cible {
  display: block; width: 100%; height: 100%; object-fit: contain;
  border-radius: 4px; box-shadow: 0 8px 40px rgba(0,0,0,.55);
}
.pl-simu { outline: 1px dashed rgba(255,255,255,.28); }
.pl-simu .el { position: absolute; transform-origin: center; pointer-events: none; z-index: 2; }
.pl-simu .el .contenu {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  overflow: hidden; box-sizing: border-box;
}
.pl-simu .el .contenu img,
.pl-simu .el .contenu video { width: 100%; height: 100%; object-fit: contain; display: block; }
.pl-simu .el .contenu.texte {
  padding: .35em .6em; line-height: 1.25; border-radius: 8px;
  word-break: break-word; white-space: pre-wrap;
  overflow: visible;
}
.pl-simu .el .contenu.bouton {
  border-radius: 999px; padding: .3em 1em; font-weight: 650; white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0,0,0,.4);
}
.pl-simu .el.cliquable { pointer-events: auto; cursor: pointer; }
.pl-simu .el.cliquable:active { filter: brightness(1.15); }

.pl-etiquette {
  padding: 9px 15px; border-radius: 999px; font-size: .84rem; font-weight: 600;
  background: rgba(184, 115, 10, .22); border: 1px solid rgba(224, 160, 52, .5);
  color: #f0c483; backdrop-filter: blur(8px);
}

/* ── Plusieurs contenus ───────────────────────────────────────────────────── */
.pl-accueil .cibles-apercu {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; max-width: 360px;
}
.pl-accueil .cibles-apercu img {
  max-width: 190px; max-height: 26dvh; border-radius: 12px; border: 2px solid rgba(255,255,255,.22);
  box-shadow: 0 8px 30px rgba(0,0,0,.5);
}
.pl-accueil .cibles-apercu.multiples img { max-width: 108px; max-height: 15dvh; }

/* En simulation, une barre pour passer d'un contenu à l'autre. */
.pl-simu-choix {
  position: fixed; z-index: 44; top: calc(10px + env(safe-area-inset-top)); left: 10px; right: 10px;
  display: flex; gap: 8px; overflow-x: auto; justify-content: center; pointer-events: none;
}
.pl-simu-choix button {
  pointer-events: auto; flex: 0 0 auto; padding: 8px 15px; font: inherit; font-size: .84rem; font-weight: 600;
  color: #dfe4f3; cursor: pointer; border-radius: 999px; backdrop-filter: blur(8px);
  background: rgba(20,24,36,.72); border: 1px solid rgba(255,255,255,.2);
}
.pl-simu-choix button.actif { background: var(--primaire, #5b4bdb); border-color: transparent; color: #fff; }


/* Simulation : la partie de l'image que la caméra reconnaît */
.pl-simu-zone {
  position: absolute; pointer-events: none; box-sizing: border-box;
  border: 2px dashed rgba(255, 176, 32, .9); border-radius: 4px;
}

.pl-indice img { width:48px; height:48px; object-fit:contain; vertical-align:middle; border-radius:6px; margin-right:10px; }
.pl-indice { pointer-events:none; }
.pl-reveler { position:absolute; inset:0; width:100%; height:100%; border:1px solid #ffffff70; border-radius:10px; background:#263246; color:white; font:600 16px system-ui; cursor:pointer; }
.pl-outils [hidden] { display:none !important; }
.pl-scene video, .pl-simu video { pointer-events:auto; }


/* ── Vidéos en ligne, sons, lecteur par-dessus la scène ───────────────────── */
.pl-scene .el .contenu iframe,
.pl-simu .el .contenu iframe { width: 100%; height: 100%; border: 0; display: block; background: #000; }
.pl-scene .el .contenu.son,
.pl-simu .el .contenu.son {
  border-radius: 999px; padding: .3em 1em; font-weight: 650; white-space: nowrap;
  box-shadow: 0 2px 10px rgba(0,0,0,.4);
}
.pl-lecteur {
  position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.8);
  display: grid; place-items: center; padding: 14px; animation: plMonte .2s ease;
}
.pl-lecteur-boite { width: min(100%, 720px); display: flex; flex-direction: column; gap: 12px; }
.pl-lecteur-boite iframe,
.pl-lecteur-boite video { width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: 12px; background: #000; display: block; }
/* Spotify, SoundCloud, Deezer : un bandeau, pas un écran de cinéma */
.pl-lecteur-boite.son iframe { aspect-ratio: auto; height: 166px; }
/* Image agrandie : pas de format imposé, elle garde ses proportions. */
.pl-lecteur-boite.image img {
  display: block; width: auto; height: auto; max-width: 100%; max-height: 80dvh;
  margin: 0 auto; border-radius: 12px; object-fit: contain;
}

/* Gros boutons lecture/pause et son d'une vidéo posée dans la scène : les
   commandes natives sont trop fines pour un doigt sur un élément déjà petit
   ou pivoté (voir noeudOverlay/brancherVideoOverlay, assets/player.js). */
.pl-scene .el .contenu.video,
.pl-simu .el .contenu.video { position: relative; }
.pl-video-bouton {
  position: absolute; left: 50%; transform: translateX(-50%);
  padding: .3em .85em; border: 0; border-radius: 999px; font: inherit; font-size: .78rem; font-weight: 650;
  background: rgba(17,24,39,.85); color: #fff; cursor: pointer; white-space: nowrap;
  max-width: 92%; overflow: hidden; text-overflow: ellipsis; z-index: 2;
}
.pl-video-bouton:active { background: rgba(17,24,39,1); }
.pl-video-lecture { bottom: 6%; }
.pl-video-son { top: 6%; }

/* Lecteur tiers suivi en mode image cible : posé par-dessus le canevas 3D, repositionné
   image par image sur la projection écran du plan qu'il remplace (assets/player.js,
   demarrerSuiviLecteurs). Une iframe ne peut pas être une texture WebGL — c'est
   l'approximation qui s'en rapproche le plus, un cadre 2D qui suit la cible plutôt qu'un
   vrai plan 3D. Taille interne fixe (posée en JS) : seul le `transform` (translate+scale)
   bouge à chaque image, sans mise en page — la iframe reste précise sous le doigt.
   `transform-origin` est posé en JS avec la taille, avant le premier positionnement. */
.pl-video-ar-suivie {
  position: fixed; left: 0; top: 0; border: 0; display: none;
  z-index: 5; border-radius: 8px; overflow: hidden; background: #000;
}
/* Lecture/pause d'une vidéo en lien, sous sa vidéo (une par vidéo, voir creerLecteurSuivi). */
.pl-commande-video {
  position: fixed; left: 0; top: 0; z-index: 6; display: none;
  transform-origin: 0 0; will-change: transform;
}
