/* Le Donjon — tout est texte sur fond noir. Seules la couleur et la taille parlent.
   🔴 Tout symbole doit exister dans Press Start 2P ou VT323 (voir jeu.js). */

/* 🔴 Polices HÉBERGÉES ICI, fichiers complets. Google Fonts sert aux navigateurs
   récents des sous-ensembles amputés de ♥ ♦ ★ ▶ ← : ces symboles tombaient alors
   dans une police du système, pas en pixel et différente d'un OS à l'autre.
   Licence SIL OFL 1.1 — voir polices/OFL-*.txt. */
@font-face {
  font-family: "Press Start 2P";
  src: url("polices/PressStart2P.ttf") format("truetype");
  font-display: block;
}
@font-face {
  font-family: "VT323";
  src: url("polices/VT323.ttf") format("truetype");
  font-display: block;
}

:root {
  --fond: #000;
  --texte: #d6d6cc;
  --pale: #6e6e68;
  --tres-pale: #3a3a36;
  --or: #ffd23f;
  --gemme: #c07ae6;     /* le violet de l'icône (entre #A053C0 et #CB89EE) : le cyan
                           se confondait avec les aventuriers (fondateur, Session 19) */
  --aventurier: #3fd0ff; /* le cyan de MÉLUSINE, gardé pour tous (Session 18) */
  --coeur: #ff3b4a;
  --coeur-vide: #4a1a1f;
  --trial: #b58cff;     /* les entités */
  --artefact: #f0e6c8;  /* les artefacts : ivoire, pour ne pas se confondre avec leur entité */
  --farfadet: #6dffa8;
  --danger: #ff4a3d;
  --choix: #ffffff;

  /* 9:16 centré sur desktop, plein écran sur mobile */
  --w: min(100vw, calc(100vh * 9 / 16));
}
@supports (height: 100dvh) {
  :root { --w: min(100vw, calc(100dvh * 9 / 16)); }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--fond);
  color: var(--texte);
  overflow: hidden;
}

body {
  display: flex;
  justify-content: center;
  font-family: "VT323", ui-monospace, monospace;
  -webkit-font-smoothing: none;
  font-smooth: never;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

#ecran {
  position: relative;
  width: var(--w);
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  font-size: calc(var(--w) * 0.056);
  line-height: 1.15;
  padding: calc(var(--w) * 0.045) calc(var(--w) * 0.05)
           max(calc(var(--w) * 0.045), env(safe-area-inset-bottom));
}

#haut, #milieu, #bas { position: relative; z-index: 1; }
/* seule la PREMIÈRE ligne du haut laisse la place au bouton MENU : les suivantes
   (les gemmes pendant la descente) vont jusqu'au bord droit */
#haut { flex: none; min-height: 1.2em; }
#haut > :first-child { margin-right: 3.2em; }
#milieu {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 0.4em 0;
  scrollbar-width: none;
}
#milieu::-webkit-scrollbar { display: none; }
#bas { flex: none; }

#menu {
  position: absolute;
  top: calc(var(--w) * 0.045);
  right: calc(var(--w) * 0.04);
  width: auto;
  padding: 0.3em 0.2em;
  font-family: "Press Start 2P", monospace;
  font-size: 0.42em;
  line-height: 1;
  color: var(--pale);
  z-index: 3;
}
#menu[hidden] { display: none; }

/* ------------------------------------------------------------------ texte */

.titre { font-family: "Press Start 2P", monospace; letter-spacing: 0.02em; }
/* les symboles de Press Start 2P, ramenés à la hauteur de VT323 */
.px { font-family: "Press Start 2P", monospace; font-size: 0.72em; }
.pale { color: var(--pale); }
.tres-pale { color: var(--tres-pale); }
.or { color: var(--or); }
/* les icônes des monnaies, à la hauteur du texte ; réduites, elles gardent leur
   lissage (le plus proche voisin les hachait) */
.ico { display: inline-block; height: 0.9em; width: auto; vertical-align: -0.12em; }
.ico.eteinte { filter: grayscale(1) brightness(0.45); }
/* la fin d'une descente réussie : « est remonté », sous le nom, en blanc */
.remonte { color: #fff; font-size: 0.8em; }

/* la caravane (jeu.js, caravane) : le coffre, son contenu dessous ; un coffre plein
   a trois petites piles de pièces devant lui, à gauche */
.coffre-case {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  vertical-align: bottom;
  margin-right: 0.5em;
}
.coffre-img { position: relative; display: block; height: 2em; margin: 0 0.3em; }
.coffre-img .coffre { display: block; height: 100%; width: auto; }
.tas-rangee { position: absolute; left: -0.3em; bottom: -0.05em; height: 38%; display: flex; }
.tas-rangee .tas-or { height: 100%; width: auto; margin-right: -0.12em; }
/* dans le bandeau : sur la ligne du compteur de pièces, sous les cœurs */
.bandeau-caravane { align-items: flex-end; }
.gemme { color: var(--gemme); }
.trial { color: var(--trial); }
.artefact { color: var(--artefact); }
.farfadet { color: var(--farfadet); }
.danger { color: var(--danger); }
.petit { font-size: 0.78em; }
.mini { font-size: 0.5em; }
.grand { font-size: 1.5em; }
.enorme { font-size: 2.3em; }
.gros-titre { font-size: 1.4em; line-height: 1.7; }
.centre { text-align: center; }
.ligne { display: block; }
.espace { height: 0.7em; }
.barre-haut { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5em; }

.c-plein { color: var(--coeur); }
.c-vide { color: var(--coeur-vide); }
.crochet { color: var(--pale); }
.coeurs-px { font-size: 0.8em; letter-spacing: 0.1em; }
.grand-coeurs .coeurs-px { font-size: 1em; }

/* ---------------------------------------------------------------- boutons */

button {
  display: block;
  width: 100%;
  background: none;
  border: none;
  padding: 0.28em 0;
  margin: 0;
  color: var(--choix);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: font-size 0.12s steps(3), color 0.1s;
}
button:disabled { cursor: default; }
/* aucun rectangle sur les boutons, pas même le contour de focus : les flèches du
   clavier servent à naviguer dans la galerie, pas à parcourir les boutons */
button:focus, button:focus-visible { outline: none; }
.action {
  font-family: "Press Start 2P", monospace;
  font-size: 0.72em;
  padding: 1em 0 0.4em;
  text-align: center;
}
.action:disabled { color: var(--tres-pale); }
.action.sous { color: var(--danger); }
.action.court { width: auto; padding-left: 0.6em; padding-right: 0.6em; }
/* la ligne du bas en jeu : SORTIE (ou RECULER) à gauche, les gemmes à droite, sous
   le compteur de pièces */
.rangee-bas { display: flex; justify-content: space-between; align-items: baseline; }
.action.court-gauche { width: auto; text-align: left; }
#compteur-butin { display: inline-block; transform-origin: center; }
.rangee { display: flex; justify-content: space-between; align-items: baseline; }

/* ---------------------------------------------------------------- accueil */

.accueil {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 0.5em;
}
.accueil .logo { font-family: "Press Start 2P", monospace; font-size: 1.9em; color: var(--or); line-height: 1.3; }
.accueil .jouer {
  width: auto;
  font-family: "Press Start 2P", monospace;
  font-size: 1em;
  padding: 1.2em 1em;
  text-align: center;
}
/* la vague (JOUER, nom de l'aventurier choisi) : chaque lettre saute puis se pose ;
   les retards (jeu.js) font passer la vague de gauche à droite en 0,3 s. Cycle de
   1,2 s : ~0,6 s de vague, puis autant d'immobilité. */
.vague {
  display: inline-block;
  animation: vague 1.2s infinite;
}
@keyframes vague {
  0%   { transform: translateY(0); }
  8%   { transform: translateY(-0.28em); }
  18%  { transform: translateY(0); }
  100% { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .vague { animation: none; } }

/* tous les aventuriers dans la même couleur (fondateur, Session 18) */
.aventurier { color: var(--aventurier); }

/* ---------------------------------------------------- milieu : le journal */

/* la pile prend la place que le journal laisse — et pas 100 % EN PLUS du journal,
   ce qui faisait défiler le milieu en permanence de la hauteur du journal */
#milieu { display: flex; flex-direction: column; }
#milieu > * { flex: none; }
#milieu > .pile, #milieu > .accueil { flex: 1 0 auto; }
.pile {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1em;
}
/* une ligne par action, jamais plus : ce qui dépasse est coupé */
.journal { font-size: 0.8em; }
.jl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jl.age2 { opacity: 0.35; }
.jl.age1 { opacity: 0.6; }
.jl.age0 { animation: apparait 0.25s steps(3); }
@keyframes apparait { from { opacity: 0; } }

/* -------------------------------------------------- milieu : les quadrants */

.quads { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.3em; }
.quad {
  min-height: 4.2em;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0.4em 0;
}
.quad.large { grid-column: 1 / -1; }
/* pas de rectangle au survol ni à l'appui (fondateur) : l'écho du clic suffit */
.quad .gros { display: block; font-size: 1.45em; line-height: 1.05; }
.quad .nom { display: block; font-size: 0.6em; }
/* 9 cœurs sélectionnés tiennent sur une ligne dans un quadrant de 172 px */
.quad .coeurs { font-size: 0.64em; margin-top: 0.4em; white-space: nowrap; }
.quad.choisi .nom { font-size: 0.9em; }
.quad.choisi .coeurs { font-size: 0.7em; }
/* mesuré à 390 px : 9 cœurs sélectionnés = 220 px à 1,4em, pour un quadrant de 172 px */
.quad .coeurs .coeurs-px { font-size: 1em; letter-spacing: 0.06em; }
.quad.efface { opacity: 0.4; }
.quad.parti .nom { color: var(--tres-pale) !important; }
.quad.barre-case { opacity: 0.3; text-decoration: line-through; }

/* les sprites des gardiens : pixels nets, jamais lissés */
.sprite {
  display: block;
  margin: 0 auto 0.2em;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
/* au combat : ×2,4 (fondateur), mais plafonné à la place disponible — sur un petit
   iPhone (667 px de haut), le nom du gardien passait sous les boutons */
.sprite-combat { width: auto; max-height: 38vh; } /* la largeur suit, en proportion */
@supports (height: 1dvh) { .sprite-combat { max-height: 38dvh; } }


/* la croix d'un corps : assez grosse pour être touchée seule */
.croix {
  display: inline-block;
  color: var(--danger);
  font-size: 1.5em;
  line-height: 1;
  padding: 0.1em 0.6em;
  cursor: pointer;
}

/* la fenêtre de la croix : du texte sur le noir, par-dessus le jeu */
#popup {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: rgba(0, 0, 0, 0.93);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 calc(var(--w) * 0.08);
  text-align: center;
  cursor: pointer;
}
#popup[hidden] { display: none; }

.accueil .jouer.dev { font-size: 0.6em; color: var(--pale); padding-top: 0.6em; }
.mini-dev { font-family: "VT323", monospace; font-size: 1.3em; color: var(--tres-pale); margin-top: 0.4em; }

/* ------------------------------------------------------------ fin de journée */

.score-ligne { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 0.5em; }
.score-ligne > :last-child { text-align: right; }
.blanc { color: #fff; }
.barre-texte { text-decoration: line-through; }

/* ------------------------------------------------------------ combat */

.rangee.coups { justify-content: space-around; }
.rangee.coups .coup { font-size: 0.6em; padding: 1.2em 0.4em; }

/* ------------------------------------------------------------ l'écho du clic
   Une copie du texte du bouton grossit et s'efface DERRIÈRE l'écran (#echo est
   sous #haut, #milieu et #bas). */
#echo { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.echo {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  animation: echo 0.42s ease-out forwards;
}
.echo-quad { flex-direction: column; }
.echo * { color: inherit; }
@keyframes echo {
  from { transform: scale(1); opacity: 0.55; }
  to   { transform: scale(2.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .echo { display: none; } }

/* ------------------------------------------------------ la vue des galeries
   La salle 3D (plus bas) ; ici, ce qu'elle partage avec l'ancienne vue plate.
   Le milieu défile d'ordinaire, donc rogne ce qui déborde : ici, la scène doit
   aller jusqu'aux bords de l'écran, marges comprises */
#ecran.mode-galeries #milieu { overflow: visible; }
.vue-galeries {
  position: absolute;
  top: 0;
  bottom: 0;
  /* toute la largeur de l'écran 9:16, marges comprises */
  left: calc(var(--w) * -0.05);
  right: calc(var(--w) * -0.05);
  overflow: hidden;
}
.arche {
  position: absolute;
  top: 0;
  height: 100%;
  padding: 0;
  text-shadow: 0 0 3px #000, 0 0 6px #000, 0 0 10px #000;
}
/* l'ennemi, les pieds posés au bas de l'ouverture */
.arche-pied {
  position: absolute;
  left: 0;
  right: 0;
  transform: translateY(-100%);
  display: flex;
  justify-content: center;
  align-items: flex-end;
}
.arche-sprite { margin: 0; }
.arche-entite { font-size: 1.7em; line-height: 1; padding-bottom: 0.4em; }
/* le nom et les informations, sur le sol */
.arche-sol {
  position: absolute;
  left: 0;
  right: 0;
  transform: translateY(-50%); /* centré sur le milieu de l'ouverture (Session 20) */
  text-align: center;
  font-size: 0.82em;
  line-height: 1.15;
  text-shadow: 0 0 3px #000, 0 0 6px #000;
}
.arche-nom { font-size: 1.45em; color: #fff; }
/* le passage (jeu.js, ecranPassage) : les autres arches s'éteignent, le gardien
   tombe en sable, une flèche invite à entrer */
.arche.eteinte { opacity: 0.35; pointer-events: none; }
.sable { display: block; image-rendering: pixelated; image-rendering: crisp-edges; }
.fleche {
  position: absolute;
  left: 50%;
  width: calc(11px * 1.6 * var(--e));
  height: calc(6px * 1.6 * var(--e));
  transform: translateX(-50%);
  visibility: hidden;
  filter: drop-shadow(0 0 calc(2px * var(--e)) #000);
}
.fleche svg { display: block; width: 100%; height: 100%; }
.fleche.visible { visibility: visible; animation: fleche 0.9s steps(1, end) infinite; }
@keyframes fleche {
  0%   { transform: translate(-50%, 0); }
  25%  { transform: translate(-50%, calc(2px * var(--e))); }
  50%  { transform: translate(-50%, calc(4px * var(--e))); }
  75%  { transform: translate(-50%, calc(2px * var(--e))); }
}
.vaincu-flotte {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  font-family: "Press Start 2P", monospace;
  font-size: 0.6em;
  color: var(--or);
  pointer-events: none;
  animation: vaincu-flotte 1.4s ease-out forwards;
}
@keyframes vaincu-flotte {
  from { transform: translateY(0); opacity: 1; }
  70%  { opacity: 1; }
  to   { transform: translateY(-1.6em); opacity: 0; }
}
.pieces-vol { position: absolute; line-height: 1; white-space: nowrap; pointer-events: none; }
/* l'entrée dans la galerie suivante (jeu.js, entrer) : plongée, LEVEL n, arche de
   lumière, fondu du blanc. Le calque capte les touchers : un toucher l'abrège. */
.fx-transition {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  cursor: pointer;
  overflow: hidden;
}
/* affiché avec l'arche de lumière, éteint quand elle s'emballe (durée posée par
   jeu.js) ; au-dessus d'elle, avec un contour noir s'ils se croisent */
.fx-level {
  position: relative;
  z-index: 1;
  font-family: "Press Start 2P", monospace;
  font-size: calc(var(--w) * 0.085);
  color: #fff;
  text-shadow: 0 0 4px #000, 0 0 8px #000;
  animation: level-fx 1s steps(1, end) forwards;
}
@keyframes level-fx {
  0%   { visibility: visible; }
  100% { visibility: hidden; }
}
/* le noir percé de l'arche, et le blanc qui la remplit (tracés par jeu.js) */
.fx-trou { position: absolute; inset: 0; }
.fx-lumiere { filter: drop-shadow(0 0 calc(var(--w) * 0.02) rgba(255, 255, 255, 0.5)); }
@media (prefers-reduced-motion: reduce) {
  .fleche.visible { animation: none; }
}

/* l'icône de la carte : en haut à DROITE de la zone centrale, sous le pouce droit
   (fondateur) — dans la galerie, sous les trois lignes du journal ; au camp, dans
   le coin */
.icone-carte {
  position: absolute;
  z-index: 2;
  width: calc(var(--w) * 0.12);
  height: calc(var(--w) * 0.12);
  padding: 0;
  filter: drop-shadow(0 0 4px #000);
}
.icone-carte img { display: block; width: 100%; height: 100%; image-rendering: pixelated; image-rendering: crisp-edges; }
.vue-galeries .icone-carte { right: calc(var(--w) * 0.05); top: 3.4em; }
#milieu > .icone-carte { right: 0; top: 0.4em; }

/* ------------------------------------------------------------ la carte du jour
   Un SVG qui défile dans les deux sens (jeu.js, ecranCarte). */
#ecran.mode-carte #milieu { overflow: hidden; padding: 0; }
.carte-vue {
  height: 100%;
  overflow: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* toute la largeur de l'écran 9:16, marges comprises */
  margin: 0 calc(var(--w) * -0.05);
}
.carte-vue::-webkit-scrollbar { display: none; }
.carte { display: block; font-family: "VT323", monospace; }
.legende { font-size: 0.7em; margin-top: 0.2em; }
.carte line { stroke-width: 2; stroke-linecap: square; }
.carte .c-plein { stroke: #d8d8d8; }
.carte .c-chemin { stroke: var(--aventurier); stroke-width: 3; }
.carte .c-gris { stroke: #4a4a4a; stroke-dasharray: 3 3; }
.carte .c-point { fill: #d8d8d8; }
.carte .c-point-chemin { fill: var(--aventurier); }
.carte .c-ici { fill: var(--aventurier); animation: ici 0.8s steps(1, end) infinite; }
@keyframes ici { 50% { fill: #fff; } }
.carte .c-toucher { fill: transparent; cursor: pointer; }
.carte text { font-size: 15px; }
.carte .c-bout { text-anchor: middle; }
.carte .c-marque { font-size: 13px; }
.carte .c-noeud { font-size: 17px; cursor: pointer; }
.carte .c-sortie { text-anchor: end; fill: #d8d8d8; cursor: default; font-size: 9px; }
.carte .c-entree { text-anchor: middle; fill: var(--pale); }
.carte .c-niveau { fill: #666; font-size: 13px; }
.carte .c-px { font-family: "Press Start 2P", monospace; font-size: 9px; }
.carte .c-or { fill: #9c7f2e; }
.carte .c-trial { fill: var(--trial); }
.carte .c-eteinte { filter: grayscale(1) brightness(0.45); }
.carte .c-farfadet { fill: var(--farfadet); }
.carte .c-mort { fill: var(--danger); }

/* ------------------------------------------------ la galerie en 3D
   jeu.js, ecranNoeud3d : une salle octogonale vue de son centre, aux textures du
   couloir de combat (Session 21). */
.salle {
  position: absolute;
  inset: 0;
  overflow: hidden;
  touch-action: none; /* le glisser fait tourner la vue, pas défiler la page */
  cursor: grab;
}
.camera { position: absolute; left: 50%; width: 0; height: 0; transform-style: preserve-3d; }
.salle img { -webkit-user-drag: none; user-select: none; }
.face, .sol-part {
  position: absolute;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.face { backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.sol-part { transform-origin: 50% 0; }
/* l'arche du couloir sur sa face : la pierre, et le noir du haut du mur par-dessus
   (un masque à sa silhouette) ; par son ouverture, on voit le couloir */
.arche-pierre, .arche-ombre {
  position: absolute;
  pointer-events: none;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.arche-pierre { display: block; }
/* le mur d'une face, en parts autour de l'ouverture de l'arche (le couloir s'y voit) */
.mur-part {
  position: absolute;
  pointer-events: none;
  background-repeat: no-repeat, repeat;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
/* le couloir derrière chaque arche (couloirsSalle) : ses plans sont ceux du couloir
   de combat (.c3-plan), dans le repère de la face */
.couloir-salle {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  transform-style: preserve-3d;
  pointer-events: none;
}
.couloir-salle img { display: block; width: 100%; height: 100%; -webkit-user-drag: none; }
.c3-nom-bout {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1;
  text-shadow: 0 0 0.2em #000;
}
/* dans une face, l'arche garde son gardien ; ses inscriptions flottent à plat */
.vue-3d .face .arche-sol { display: none; }
.etiquette-3d {
  position: absolute;
  transform: translate(-50%, -50%); /* centrée sur le milieu de l'ouverture (Session 20) */
  width: calc(var(--w) * 0.5);
  text-align: center;
  font-size: 0.82em;
  line-height: 1.15;
  text-shadow: 0 0 3px #000, 0 0 6px #000, 0 0 10px #000;
  pointer-events: none;
}
.etiquette-3d .croix { pointer-events: auto; }
.etiquette-3d.eteinte { filter: brightness(0.35); } /* pendant un passage (opacity sert au fondu) */
.vue-3d .journal-dessus, .vue-3d .icone-carte { z-index: 2; }

/* le journal, par-dessus la voûte */
.journal-dessus {
  position: absolute;
  top: 0.3em;
  left: calc(var(--w) * 0.05);
  right: calc(var(--w) * 0.05);
  pointer-events: none;
  text-shadow: 0 0 3px #000, 0 0 6px #000;
}

/* les artefacts : on les touche directement */
.grille3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.2em; }
.art { text-align: center; padding: 0.5em 0; color: var(--tres-pale); }
.art .num { font-size: 1.6em; line-height: 1; }
.art.pris { color: var(--artefact); }
.art.pris .num { font-size: 2.1em; }

/* ------------------------------------------------------------- les signaux
   Un calque par-dessus l'écran, qui ne capte aucun toucher. */

#fx {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 5;
  overflow: hidden;
}
.fx-calque { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }

/* cœur perdu : un filtre rouge sur tout l'écran, qui s'éteint en trois paliers
   (le grand cœur central a été retiré — fondateur, Session 18) */
.fx-rouge {
  position: absolute;
  inset: 0;
  background: var(--coeur);
  animation: rouge-fx 0.45s steps(1, end) forwards;
}
@keyframes rouge-fx {
  0%   { opacity: 0.42; }
  33%  { opacity: 0.28; }
  66%  { opacity: 0.14; }
  100% { opacity: 0; }
}

/* victoire : un écran à elle (1 s, voir jeu.js), noir, avec le nom du vaincu —
   blanc, puis or, en grossissant par paliers — et « vaincu » dessous. Un toucher
   l'abrège. */
.fx-victoire { background: var(--fond); pointer-events: auto; cursor: pointer; }
.fx-victoire-pile { display: flex; flex-direction: column; align-items: center; gap: 0.4em; }
.fx-nom {
  font-size: min(calc(var(--w) * 0.24), calc(var(--w) * 1.6 / var(--n)));
  line-height: 1;
  white-space: nowrap;
  color: #fff;
  animation: nom-fx 1s steps(1, end) forwards;
}
@keyframes nom-fx {
  0%   { color: #fff; transform: scale(0.85); }
  10%  { color: #fff; transform: scale(1); }
  20%  { color: var(--or); transform: scale(1.08); }
  100% { color: var(--or); transform: scale(1.08); }
}
/* une entité qui fuit : une phrase entière, donc en VT323, sur plusieurs lignes */
.fx-mention.fx-fuite {
  font-family: "VT323", monospace;
  font-size: calc(var(--w) * 0.075);
  white-space: normal;
  text-align: center;
  max-width: 85%;
  line-height: 1.1;
}

/* la gemme en vol, et le « +1 » du compteur (jeu.js, lanceGemmes) */
.gemme-vol { position: absolute; line-height: 1; pointer-events: none; color: var(--gemme); }
.gemme-vol .ico { height: 0.9em; image-rendering: pixelated; } /* agrandie en vol */
.plus-un {
  position: absolute;
  font-family: "Press Start 2P", monospace;
  font-size: calc(var(--w) * 0.035);
  color: var(--gemme);
  pointer-events: none;
}
#compteur-gemmes { display: inline-block; transform-origin: center; }

/* le (i) d'information : un bouton en ligne, pas un bloc */
.info-i {
  display: inline;
  width: auto;
  padding: 0.2em 0.3em;
  color: var(--pale);
  font-family: "Press Start 2P", monospace;
  font-size: 0.7em;
}

.fx-mention {
  font-family: "Press Start 2P", monospace;
  font-size: calc(var(--w) * 0.05);
  color: var(--or);
  visibility: hidden;
  animation: mention-fx 1s steps(1, end) forwards;
}
@keyframes mention-fx { 20% { visibility: visible; } 100% { visibility: visible; } }

/* cœur perdu : tout le texte de l'écran vire un instant au rouge — le fond reste
   noir (le calque #fx en est exclu : ses propres couleurs sont animées) */
body.flash-rouge #ecran > :not(#fx), body.flash-rouge #ecran > :not(#fx) * { color: var(--coeur) !important; }

/* la secousse, par à-coups comme un vieil écran */
#ecran.secousse { animation: secousse 0.24s steps(1, end); }
@keyframes secousse {
  0%   { transform: translateX(0); }
  15%  { transform: translateX(-7px); }
  35%  { transform: translateX(6px); }
  55%  { transform: translateX(-4px); }
  75%  { transform: translateX(3px); }
  100% { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  #ecran.secousse { animation: none; }
}

/* ------------------------------------------------ l'essai des combats (Session 20)
   combat.js : un couloir en CSS 3D, le mage au bout, un canvas pour les boules. */
#ecran.mode-combat #milieu { overflow: visible; }
.couloir {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--w) * -0.05);  /* toute la largeur de l'écran, marges comprises */
  right: calc(var(--w) * -0.05);
  overflow: hidden;
  touch-action: none;             /* le glisser est un coup d'épée, pas un défilement */
}
.c3-scene { position: absolute; inset: 0; }
.c3-camera { position: absolute; width: 0; height: 0; transform-style: preserve-3d; }
.c3-plan {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}
.c3-mage, .c3-epee {
  position: absolute;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  pointer-events: none;
  -webkit-user-drag: none;
}
/* le mage et les arches du couloir : l'image, et par-dessus le fondu au noir du haut
   (un dégradé découpé à la silhouette de l'image, combat.js) */
.c3-mage img, .c3-arche-couloir img {
  display: block;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  -webkit-user-drag: none;
}
/* un état de l'ennemi par calque, tous chargés, un seul visible (combat.js, majEnnemi) */
.c3-etat { position: absolute; inset: 0; visibility: hidden; }
.c3-etat.vu { visibility: visible; }
.c3-fondu {
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
/* l'épée pivote autour de sa garde (transform-origin posé par combat.js) ; les boules
   passent DEVANT elle, qui traverse l'écran : sinon elle les cacherait */
.c3-epee { z-index: 1; }
.c3-toile { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; }
.essai-haut { align-items: center; }
.essai-panneau, .essai-fin {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: rgba(0, 0, 0, 0.86);
  padding: 1em calc(var(--w) * 0.08);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.7em;
}
.essai-panneau[hidden], .essai-fin[hidden] { display: none; }
.essai-fin { align-items: center; text-align: center; }
.essai-curseur { display: flex; flex-direction: column; gap: 0.2em; }
.essai-curseur input[type=range] { width: 100%; accent-color: var(--or); }
.essai-curseur input[type=checkbox] { width: 1.2em; height: 1.2em; accent-color: var(--or); }
/* la fin d'un combat : le monde se rapproche du mage (un zoom centré sur lui), il
   s'effondre en sable, l'arche blanche apparaît derrière lui */
.c3-monde { position: absolute; inset: 0; }
.c3-sable { position: absolute; pointer-events: none; }
/* l'arche de sortie : la lumière dans l'ouverture d'une arche du couloir (combat.js),
   un aplat blanc découpé par le masque de l'ouverture. Elle seule se touche : les
   scènes 3D, qui couvrent tout l'écran, laissent passer les touchers. */
.c3-scene { pointer-events: none; }
/* l'ouverture de l'arche de sortie, à la victoire : NOIRE (fondateur, Session 21 —
   elle était blanche, une arche de lumière) ; pendant la traversée, elle s'efface et
   laisse voir la galerie suivante */
.c3-sortie {
  background: #000;
  -webkit-mask-image: url(combat/arche-ouverture.png);
  mask-image: url(combat/arche-ouverture.png);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  opacity: 0;
  transition: opacity 0.5s;
  cursor: pointer;
}
.c3-sortie.visible { opacity: 1; pointer-events: auto; }
/* dans la partie, la vraie galerie suivante se voit par l'arche : l'ouverture reste
   à toucher, mais transparente, et le seuil laisse voir le sol de la galerie */
.couloir.fenetre .c3-sortie { background: transparent; }
.couloir.fenetre .c3-seuil { display: none; }
/* le mur du fond, derrière l'arche de sortie : un grand mur noir percé du passage —
   c'est par lui seul qu'on voit la galerie suivante (combat.js, construitCouloir) */
.c3-fond { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.c3-fond-part { position: absolute; background: #000; }
.c3-fond-passage {
  -webkit-mask-image: url(combat/arche-passage.png);
  mask-image: url(combat/arche-passage.png);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
/* la galerie qu'on voit par l'arche du couloir (et pendant la traversée) n'a pas
   encore ses textes */
#ecran.traversee .journal-dessus, #ecran.traversee .etiquette-3d, #ecran.traversee .arche-sol,
#ecran.traversee .arche-entite, #ecran.traversee .icone-carte { visibility: hidden; }
/* le sol au bas de l'ouverture (il ferme la forme de l'arche) : on ne le voit que
   dans la lumière, donc il apparaît avec elle */
.c3-seuil {
  -webkit-mask-image: url(combat/arche-seuil.png);
  mask-image: url(combat/arche-seuil.png);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  opacity: 0;
  transition: opacity 0.5s;
}
.c3-seuil.visible { opacity: 1; }
/* « le mage n'a plus de mana » : le texte en haut, ATTAQUER à portée du pouce */
.essai-mana {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 12% 0 18%;
  text-align: center;
  pointer-events: none;
}
.essai-mana[hidden] { display: none; }
.essai-mana-texte { font-size: 0.8em; line-height: 1.6; color: #fff; text-shadow: 0 0 6px #000, 0 0 12px #000; }
/* ATTAQUER : le texte seul, sans bande sombre (fondateur, Session 21) — on attaque
   d'un toucher n'importe où sur l'écran (combat.js) */
.essai-mana button { pointer-events: auto; background: none; text-shadow: 0 0 6px #000, 0 0 12px #000; }
