/* ─────────────────────────────────────────────────────────────────────────────
 *  ATOUM — feuille de style.
 *
 *  Palette de sable et d'or, sur fond de tombeau. Les couleurs des joueurs
 *  viennent de donnees/personnages.json : rien n'est codé ici.
 * ───────────────────────────────────────────────────────────────────────── */

:root, [data-theme="sombre"] {
  --fond:      #17130e;
  --carte:     #221c14;
  --creux:     #2c241a;
  --bord:      #453a2a;
  --texte:     #f0e7d8;
  --faible:    #a9987f;
  --or:        #e0a33a;
  --sable:     #c9b18a;
  --vert:      #6fae7c;
  --rouge:     #d46a5a;
  --pierre:    #3a3024;
  --pierre-c:  #4a3e2e;

  /* Alias employés par les écrans annexes et les modales. Ils manquaient : les
     replis en dur qui les remplaçaient restaient SOMBRES en mode clair, d'où
     des champs noirs sur fond crème. */
  --fond-0:    #17130e;
  --fond-2:    #221c14;
  --doux:      #a9987f;
  --accent:    #e0a33a;
  /* ── LES COULEURS DE MATIÈRE, PAR RÔLE ────────────────────────────────────
     Quatre-vingt-quinze teintes étaient écrites en dur dans cette feuille —
     soixante d'entre elles des variantes d'ocre. Elles datent d'un temps où il
     n'existait qu'un univers, et elles y sont restées : changer de décor ne
     changeait donc que les bordures.

     On les regroupe PAR RÔLE, pas par teinte. Un rôle se remplace d'un mot ;
     quatre-vingt-quinze teintes, non. Chaque univers redéfinit ces variables et
     tout suit — le plateau, les pions, les cartes.

     Ce qui n'est PAS ici : les couleurs de fonction — le rouge d'un piège, le
     vert d'une réussite. Elles doivent rester les mêmes d'un univers à l'autre,
     sinon le joueur réapprend à lire son écran à chaque bascule. */
  /* ── LE MUR SE DÉTACHE DU FOND ────────────────────────────────────────────
     Le mur et le fond rendaient 1,14 de contraste : on ne voyait pas où le
     tombeau s'arrête, et l'auteur l'a photographié deux fois.

     Le fond devient un gris CHAUD, plus présent ; les salles montent avec lui,
     sinon elles s'y noieraient. Le mur reste presque noir : c'est lui qui
     dessine la silhouette. Momies et cases vertes ont suivi — ce qui se pose
     sur une salle claire doit trancher sur elle, pas sur le vide. */
  --m-fond-plateau:   #2e2620;   /* le noir sous la pyramide */
  --m-fond-halo:      #3a3028;   /* le halo au centre du plateau */
  /* ── LA DALLE DOIT SE LIRE SUR LA PIERRE ────────────────────────────────
     Elle valait #2a2218 : 1,34 de contraste contre le noir du mur. Sur un
     écran de téléphone en plein jour, le couloir ne se distinguait plus de la
     pierre — on devinait le chemin au lieu de le voir.

     #3a3022 porte le rapport à 1,63. La pierre reste sombre, la dalle reste
     dans son ton de grès : c'est le même décor, mieux éclairé. */
  --m-salle:          #7a664a;   /* la pierre nue, sans image cuite */
  --m-salle-bord:     #5f4f38;
  --m-salle-entree:   #8a7458;
  --m-salle-tresor:   #8a6d33;
  --m-salle-sable:    #907a55;
  --m-case:           #b8dcb2;   /* une case où l'on peut aller */
  --m-case-survol:    #cdeac6;
  --m-momie:          #201929;   /* le pion momie */
  --m-momie-bord:     #a08ac0;
  --m-momie-texte:    #f0e7d8;
  --m-gardienne:      #2c1f38;   /* les cartes de la phase 2 */
  --m-gardienne-bord: #a08ac0;
  --m-puits:          #7fa8c9;   /* l'eau du puits */
  --m-portail:        #a08ac0;   /* la lueur d'un portail */
  --m-coffre:         #6b4a1e;
  --m-coffre-haut:    #8b6229;
  --m-or-vif:         #d8a24a;   /* l'or : trésor, marches, accents */
  --m-mur-dehors:     #060403;   /* au-delà d'une salle : rien */

  --titre: "Iowan Old Style", Palatino, Georgia, serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --r: 8px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

/* LA HAUTEUR RÉELLE DE L'ÉCRAN, barres du navigateur comprises. `100%` sur
   iOS installé se calait sur une hauteur théorique : le bas du panneau passait
   sous le bord. `dvh` suit la fenêtre telle qu'elle est, à l'instant présent. */
html, body { height: 100%; }
@supports (height: 100dvh) { html, body { height: 100dvh; } }

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  background: var(--fond);
  color: var(--texte);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overflow: hidden;
  /* LES MARGES DE SÛRETÉ NE SONT PLUS SUR LE CORPS. Posées ici, elles
     amputaient la hauteur utile en haut ET en bas : deux bandes vides, et le
     panneau coupé en bas d'écran une fois l'application installée. Elles vont
     désormais là où elles protègent vraiment — l'encoche sur la barre du
     haut, la barre d'accueil sous le panneau — sans rien retirer au plateau. */
}

/* ── Écran de démarrage ──────────────────────────────────────────────────── */
#demarrage {
  position: fixed; inset: 0; z-index: 500;
  display: grid; place-items: center;
  background: var(--fond); color: var(--faible);
}
#demarrage .erreur { max-width: 34ch; text-align: center; }
#demarrage .detail { font-family: var(--mono); font-size: 12px; color: var(--rouge); }

/* ── Barre du haut ───────────────────────────────────────────────────────── */
#barre {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 10px 16px;
  /* ── L'ENCOCHE ET LES COINS ARRONDIS ────────────────────────────────────
     `max(16px, env(...))` suffisait en portrait, où l'encoche latérale vaut
     zéro. En PAYSAGE sur un iPhone, l'écran est arrondi aux quatre coins et
     l'encoche mange le bord gauche : le « A » d'ATOUM et le « (s) » de
     « 2 action(s) » disparaissaient sous la courbe.

     On ajoute donc 16 points À L'ENCOCHE au lieu de prendre le plus grand des
     deux : le contenu s'écarte du bord même quand le système annonce zéro. */
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
  padding-left: calc(16px + env(safe-area-inset-left, 0px));
  padding-right: calc(16px + env(safe-area-inset-right, 0px));
  background: var(--carte); border-bottom: 1px solid var(--bord);
}
.titre { display: flex; align-items: baseline; gap: 12px; }
/* La marque est un h1 : on lui retire les marges et la taille par défaut du
   navigateur, pour qu'elle reste le mot discret de la barre. */
h1.marque { margin: 0; }

/* ── LE FOND PASSE SOUS L'ENCOCHE ────────────────────────────────────────────
   Le corps de la page portait la couleur, mais la zone de l'encoche restait
   noire : une bande sombre au-dessus de la barre, qui cassait l'ensemble.

   On peint le document lui-même. La couleur remplit alors tout l'écran, y
   compris derrière l'encoche et sous les coins arrondis, et seul le CONTENU
   respecte les marges de sécurité. */
html { background: var(--carte); }
@supports (padding: env(safe-area-inset-top)) {
  html { background: var(--carte); }
}
.marque {
  font: 700 15px/1 var(--mono); letter-spacing: .26em; color: var(--or);
}
.phase { font-size: 12.5px; color: var(--faible); }
.info { display: flex; align-items: center; gap: 14px; font-size: 13.5px; }
.tour-nom {
  font-weight: 650;
  padding: 3px 10px; border-radius: 20px;
  background: color-mix(in srgb, var(--teinte) 22%, transparent);
  border: 1px solid var(--teinte);
}
.tour-actions { color: var(--faible); font-family: var(--mono); font-size: 12.5px; }

/* ── Disposition principale ──────────────────────────────────────────────── */
#principal {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: 1fr 320px;
}

#zone-plateau {
  position: relative; min-width: 0; min-height: 0;
  overflow: auto;
  background:
    radial-gradient(ellipse at 50% 40%, var(--m-fond-halo) 0%, var(--m-fond-plateau) 70%);
  display: grid; place-items: center;
  padding: 16px;
}
.plateau { width: 100%; height: 100%; max-height: 100%; }

/* ── Le plateau ──────────────────────────────────────────────────────────── */
.tuile-fond { fill: var(--m-salle); stroke: var(--m-salle-bord); stroke-width: 1.5; }
.tuile-fond.type-entree  { fill: var(--m-salle-entree); stroke: var(--or); }
.tuile-fond.type-tresor  { fill: #3d2f16; stroke: var(--or); stroke-width: 2.5; }
.tuile-fond.type-puits   { fill: var(--m-salle); stroke: var(--m-puits); }
.tuile-fond.type-portail { fill: var(--m-salle); stroke: var(--m-portail); }
.tuile.ensablee .tuile-fond { fill: var(--m-salle-sable); }

.case {
  fill: var(--pierre); stroke: var(--pierre-c); stroke-width: .8;
  transition: fill .12s;
}
/* La jonction et le sable ne peignent plus le sol : la pierre s'en charge —
   une salle ensablée charge simplement l'autre série d'images. Ces deux fonds
   étaient des restes d'avant les dalles, et ils s'imprimaient par-dessus. */
.case.atteignable {
  fill: var(--m-case); stroke: var(--vert); stroke-width: 1.6; cursor: pointer;
}
.case.atteignable:hover { fill: var(--m-case-survol); }

.pose-zone {
  fill: rgb(224 163 58 / .07); stroke: var(--or); stroke-width: 1.4;
  stroke-dasharray: 5 4; cursor: pointer; transition: fill .12s;
}
.pose-zone:hover { fill: rgb(224 163 58 / .2); }
.pose-signe { fill: var(--or); font: 700 22px var(--mono); pointer-events: none; }

.momie-pion { fill: var(--m-momie); stroke: var(--m-momie-bord); stroke-width: 1.4; }
.momie-force { fill: var(--m-momie-texte); font: 700 11px var(--mono); pointer-events: none; }
.momie.visee .momie-pion {
  stroke: var(--rouge); stroke-width: 2.4; cursor: pointer;
  fill: #7a4b4b;
}

.jeton-rond { stroke: #17130e; stroke-width: 1.6; }
.jeton.actif .jeton-rond { stroke: #fff; stroke-width: 2.4; }
.jeton-lettre { fill: #17130e; font: 700 12px var(--mono); pointer-events: none; }

/* ── Colonne de droite ───────────────────────────────────────────────────── */
#colonne {
  border-left: 1px solid var(--bord); background: var(--carte);
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
}
.section { padding: 12px 14px; border-bottom: 1px solid var(--bord); }
.section h2 {
  margin: 0 0 8px; font: 650 11px/1 var(--mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--faible);
}
.section-journal { flex: 1; min-height: 0; display: flex; flex-direction: column; }

.etat { display: flex; gap: 14px; font-size: 12px; color: var(--faible); margin-bottom: 8px; }
.etat b { color: var(--texte); font-family: var(--mono); }

.joueur {
  padding: 7px 10px; margin-bottom: 6px; border-radius: var(--r);
  background: var(--creux); border-left: 3px solid var(--teinte);
  opacity: .62;
}
.joueur.actif { opacity: 1; background: color-mix(in srgb, var(--teinte) 14%, var(--creux)); }
.joueur-nom { font-weight: 650; font-size: 13.5px; }
.joueur-nom .forme { font-weight: 400; font-size: 11.5px; color: var(--faible); }
.joueur-stats {
  display: flex; flex-wrap: wrap; gap: 10px;
  font-size: 11.5px; color: var(--faible); margin-top: 2px;
}
.joueur-stats b { color: var(--texte); font-family: var(--mono); }

.carte {
  padding: 6px 9px; margin-bottom: 5px; border-radius: 6px;
  background: var(--creux); border-left: 3px solid var(--bord);
}
.carte-nom { display: block; font-weight: 650; font-size: 13px; }
.carte-effet { display: block; font-size: 11.5px; color: var(--faible); line-height: 1.4; }
.carte.cat-arme     { border-left-color: var(--rouge); }
.carte.cat-outil    { border-left-color: var(--vert); }
.carte.cat-trahison { border-left-color: #a08ac0; }
.carte.cat-pouvoir  { border-left-color: var(--or); }
.vide { margin: 0; font-size: 12.5px; color: var(--faible); font-style: italic; }

.journal { flex: 1; overflow-y: auto; font-size: 12.5px; line-height: 1.5; }
.journal .ligne { margin: 0 0 3px; padding-left: 8px; border-left: 2px solid var(--bord); }

/* ── LES TROIS PHASES SE VOIENT DANS LE JOURNAL ──────────────────────────────
   Le journal était une coulée de lignes toutes semblables : on ne savait plus
   où l'exploration finissait ni où la fuite commençait. Relire une partie
   revenait à compter les tours.

   Une phase devient un TITRE : plus grand, en or, sur toute la largeur, avec
   un filet au-dessus. On retrouve les trois moments d'un coup d'œil, sans
   lire — c'est exactement ce qu'on demande à un journal qu'on parcourt. */
.journal .genre-phase {
  margin: 14px 0 8px; padding: 7px 0 5px 0;
  border-left: 0; border-top: 1px solid var(--or);
  font: 700 13.5px/1.3 var(--mono); letter-spacing: .07em;
  text-transform: uppercase; color: var(--or);
}
/* La première n'a pas de filet : rien ne la précède. */
.journal .genre-phase:first-child { margin-top: 0; border-top: 0; }

/* La fin de partie se voit autant que les phases : c'est le dernier moment. */
.journal .genre-fin {
  margin: 10px 0 4px; padding: 6px 8px;
  border-left: 2px solid var(--or);
  background: color-mix(in srgb, var(--or) 12%, transparent);
  font-weight: 600;
}
.ligne.genre-tour    { border-left-color: var(--or); color: var(--or); font-weight: 650; margin-top: 7px; }
.ligne.genre-phase   { border-left-color: var(--or); color: var(--or); font-weight: 700; }
.ligne.genre-piege   { border-left-color: var(--rouge); color: #f3b0a4; }
.ligne.genre-succes  { border-left-color: var(--vert); color: #a8d6b1; }
.ligne.genre-echec   { border-left-color: var(--rouge); }
.ligne.genre-tresor  { border-left-color: var(--or); background: rgb(224 163 58 / .12);
                       color: var(--or); font-weight: 700; padding: 4px 8px; border-radius: 4px; }
/* ── LE JOURNAL SE LIT À LA COULEUR ────────────────────────────────────────
   Un piège se lisait déjà en rouge, une réussite en vert — mais un bonus
   trouvé, une capacité, une immunité restaient de la couleur du sable, comme
   une ligne d'information. On relit le journal après coup pour comprendre ce
   qui s'est passé : ce qui vous sert doit se distinguer d'un coup d'œil de ce
   qui vous coûte. */
.ligne.genre-bonus, .ligne.genre-carte,
.ligne.genre-capacite, .ligne.genre-immunite {
  border-left-color: var(--vert); color: #a8d6b1;
}
.ligne.genre-momie, .ligne.genre-combat { border-left-color: var(--rouge); color: #f3b0a4; }
.ligne.genre-tuile   { border-left-color: var(--sable); }

.invite { margin: 0 8px 0 0; font-size: 13.5px; color: var(--sable); }

.btn {
  padding: 9px 15px; border-radius: var(--r);
  border: 1px solid var(--bord); background: var(--creux); color: var(--texte);
  font: 600 13.5px/1 inherit; cursor: pointer;
  transition: border-color .12s, background .12s;
}
.btn:hover:not(:disabled) { border-color: var(--or); }
.btn:disabled { opacity: .38; cursor: default; }
.btn.primaire { background: var(--or); color: #17130e; border-color: var(--or); }
.btn.primaire:hover:not(:disabled) { background: #edb45a; }
.btn.discret { background: transparent; }
.btn.capacite { border-color: #a08ac0; }

/* ── Fenêtres ────────────────────────────────────────────────────────────── */
#modale-fond {
  position: fixed; inset: 0; z-index: 300;
  display: none; place-items: center; padding: 20px;
  background: rgb(0 0 0 / .72);
}
#modale-fond.ouverte { display: grid; }
#modale {
  width: min(560px, 100%); max-height: 86vh; overflow-y: auto;
  padding: 22px 24px; border-radius: 12px;
  background: var(--carte); border: 1px solid var(--bord);
  box-shadow: 0 18px 60px rgb(0 0 0 / .6);
}
#modale h2 { margin: 0 0 14px; font-size: 21px; font-weight: 650; }
.modale-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 20px; }

.champ { margin-bottom: 14px; }
.champ label {
  display: block; margin-bottom: 5px;
  font: 650 11px/1 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--faible);
}
.sous-titre { margin: 18px 0 8px; font-size: 13px; color: var(--faible); }
.groupe-nb, .groupe-perso { display: flex; gap: 6px; flex-wrap: wrap; }
.btn.nb { min-width: 42px; }
.btn.nb.actif { background: var(--or); color: #17130e; border-color: var(--or); }
.btn.perso {
  font-size: 12.5px; padding: 7px 11px;
  border-color: color-mix(in srgb, var(--teinte) 55%, var(--bord));
}
.btn.perso.actif {
  background: color-mix(in srgb, var(--teinte) 26%, transparent);
  border-color: var(--teinte);
}

/* ── Petits écrans ───────────────────────────────────────────────────────── */


/* ── Thème clair ─────────────────────────────────────────────────────────── */
/* Piloté par un attribut sur <html> et non par une seule media query : le
   joueur doit pouvoir choisir contre l'avis de son système. */
[data-theme="clair"] {
  /* ── LES MATIÈRES SUIVENT AUSSI LE MODE CLAIR ────────────────────────────
     Les variables `--m-*` ont été posées pour l'univers, en oubliant l'autre
     axe : sur fond crème, la pierre restait presque noire et les momies
     illisibles. Le garde-fou l'a signalé aussitôt.
     Deux axes veut dire QUATRE combinaisons — chacune doit tenir. */
  --m-fond-plateau:   #efe7d7;
  --m-fond-halo:      #f7f1e4;
  --m-salle:          #ddd0b6;
  --m-salle-bord:     #b8a684;
  --m-salle-entree:   #e6d5ab;
  --m-salle-tresor:   #eddba4;
  --m-salle-sable:    #d8c395;
  --m-case:           #a8c49f;
  --m-case-survol:    #93b88c;
  --m-momie:          #a794b8;
  --m-momie-bord:     #6d5a80;
  --m-momie-texte:    #241d14;
  --m-gardienne:      #d8cbe2;
  --m-gardienne-bord: #6d5a80;
  --m-puits:          #5d87a8;
  --m-portail:        #7a63a0;
  --m-coffre:         #a87c34;
  --m-coffre-haut:    #c39a4e;
  --m-or-vif:         #a87c1e;
  --m-mur-dehors:     #2b241a;

  /* Le vert était à 3,56 — au-dessus du minimum pour un gros texte, en
     dessous pour un texte courant. Il sert aux confirmations, qui se lisent
     en petit. #2e6a3d donne 5,51. */
  --vert:      #2e6a3d;
  --rouge:     #b8452f;
  --fond-0:    #f4efe4;
  --fond-2:    #ffffff;
  --doux:      #7a6b55;
  --accent:    #b5822a;
  --fond:     #f3ece0;
  --carte:    #fffdf9;
  --creux:    #ebe2d2;
  --bord:     #d6c8ae;
  --texte:    #241d14;
  --faible:   #6e6151;
  /* ── L'OR DU THÈME CLAIR ÉTAIT ILLISIBLE ────────────────────────────────
     #b8801c sur #f3ece0 donne un contraste de 2,91 — la norme demande 4,5
     pour un texte courant. C'est la couleur d'ACCENT du jeu : les boutons
     actifs, les emplacements de pose, le numéro de version. Tout ce qui doit
     attirer l'œil était justement ce qu'on lisait le moins bien.

     Le défaut ne se voit pas en intérieur : il se voit au soleil, ou sur un
     écran mal réglé — c'est-à-dire chez le joueur, pas chez moi.

     #8f6314 donne 4,51 : la teinte reste dorée, elle devient lisible. */
  --or:       #8f6314;
  --sable:    #7a6a52;
  --pierre:   #e3d8c2;
  --pierre-c: #cbbd9f;
}
[data-theme="clair"] #zone-plateau {
  background: radial-gradient(ellipse at 50% 40%, #fdf8ee 0%, #ece3d3 70%);
}
[data-theme="clair"] .tuile-fond { fill: #e8dcc4; stroke: #c3b092; }
[data-theme="clair"] .case { fill: var(--pierre); stroke: var(--pierre-c); }

[data-theme="clair"] .case.atteignable { fill: #b6d6b0; stroke: #4f8a58; }
[data-theme="clair"] .momie-pion { fill: #b6a4c4; stroke: #6b5b7a; }
[data-theme="clair"] .momie-force { fill: #241d14; }
[data-theme="clair"] .jeton-lettre { fill: #fffdf9; }
[data-theme="clair"] .jeton-rond { stroke: #fffdf9; }
[data-theme="clair"] #modale-fond { background: rgb(60 45 20 / .38); }

/* ── Barre du haut : le bouton de thème ──────────────────────────────────── */
#barre .droite { display: flex; align-items: center; gap: 14px; }
.btn.petit { padding: 6px 11px; font-size: 12px; }

/* ── Portraits ───────────────────────────────────────────────────────────── */
.portrait {
  flex: none;
  display: inline-grid; place-items: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: color-mix(in srgb, var(--teinte) 30%, var(--creux));
  border: 2px solid var(--teinte);
  color: var(--texte);
  font: 700 12px/1 var(--mono);
}
.tour-nom .portrait { width: 22px; height: 22px; font-size: 11px; margin-right: 7px; }
.tour-nom { display: inline-flex; align-items: center; }
.joueur-tete { display: flex; align-items: center; gap: 9px; }
.joueur-tete .joueur-nom { font-weight: 650; font-size: 13.5px; }

/* ── Fenêtres flottantes ─────────────────────────────────────────────────── */
/* Elles suivent le pion actif. Position absolue dans #zone-plateau, qui est
   en position: relative — c'est ce qui les fait défiler avec le plateau. */




.mini {
  padding: 3px 8px; border-radius: 4px; font: 600 10.5px/1 inherit;
  border: 1px solid var(--bord); background: var(--carte); color: var(--texte);
  cursor: pointer;
}
.mini:hover { border-color: var(--or); }
.mini.danger { border-color: var(--rouge); color: var(--rouge); }

/* La colonne de droite perd l'inventaire : il vit désormais près du pion. */
#colonne .section-inventaire { display: none; }


/* ── Portraits illustrés ─────────────────────────────────────────────────── */
/* L'image remplace l'initiale dès qu'elle existe ; l'initiale reste dessous
   comme secours, visible tant que l'image n'est pas chargée. */
.portrait { overflow: hidden; position: relative; }
.portrait img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; border-radius: 50%;
}
.joueur-tete .portrait { width: 34px; height: 34px; }

/* ── Aperçu de la salle à poser ──────────────────────────────────────────── */
.apercu-tuile {
  position: absolute; z-index: 30;
  left: 50%; bottom: 16px; transform: translateX(-50%);
  width: 190px; padding: 11px 13px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--carte) 96%, transparent);
  border: 1px solid var(--or);
  box-shadow: 0 14px 40px rgb(0 0 0 / .5);
  display: none;
}
.apercu-tuile.visible { display: block; }
.apercu-titre { font-weight: 650; font-size: 13.5px; }
.apercu-sous { font-size: 11px; color: var(--faible); margin-bottom: 8px; }
.apercu-cadre { display: grid; place-items: center; margin-bottom: 9px; }
.apercu-outils { display: flex; flex-wrap: wrap; gap: 5px; }
.apercu-outils .mini.primaire {
  background: var(--or); color: #17130e; border-color: var(--or);
}

.vignette-fond { fill: var(--creux); stroke: var(--bord); stroke-width: 1; }
.vignette-couloir { fill: var(--or); opacity: .85; }
.vignette-pierre { fill: var(--pierre); opacity: .5; }
.vignette.ensablee .vignette-couloir { fill: #c9a86a; }
.vignette.ensablee .vignette-fond { fill: #6b5836; }

/* ── Carte tirée ─────────────────────────────────────────────────────────── */
/* Elle s'affiche au centre, puis glisse vers l'inventaire ou vers la défausse.
   La trajectoire est le message : elle dit OÙ la carte est partie. */
.apercu-carte {
  position: absolute; z-index: 40;
  left: 50%; top: 44%; transform: translate(-50%, -50%) scale(.86);
  width: 214px;
  border-radius: 12px; overflow: hidden;
  background: var(--carte);
  border: 2px solid var(--bord);
  box-shadow: 0 22px 60px rgb(0 0 0 / .62);
  opacity: 0; pointer-events: none;
  transition: opacity .22s, transform .5s cubic-bezier(.4,0,.2,1);
}
.apercu-carte.visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.apercu-carte.genre-piege { border-color: var(--rouge); }
.apercu-carte.genre-bonus { border-color: var(--vert); }
.apercu-carte.vers-inventaire {
  opacity: 0;
  transform: translate(-50%, -50%) translate(-160px, 90px) scale(.28) rotate(-8deg);
}
.apercu-carte.vers-defausse {
  opacity: 0;
  transform: translate(-50%, -50%) translate(0, 120px) scale(.4) rotate(6deg);
}
.carte-illu { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; }
.carte-bandeau { padding: 9px 12px 11px; }
.carte-genre {
  display: inline-block; margin-bottom: 3px;
  font: 650 9.5px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase;
}
.genre-piege .carte-genre { color: var(--rouge); }
.genre-bonus .carte-genre { color: var(--vert); }
.carte-titre { display: block; font-weight: 650; font-size: 15px; }
.carte-action { display: block; font-size: 11.5px; color: var(--faible); line-height: 1.4; margin-top: 3px; }


/* ── Choix des personnages : portraits ───────────────────────────────────── */
.groupe-perso { gap: 8px; }
.btn.perso {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 92px; padding: 8px 6px;
}
.perso-portrait {
  width: 54px; height: 54px; border-radius: 50%; object-fit: cover;
  border: 2px solid var(--teinte);
}
.perso-nom { font-size: 11.5px; font-weight: 650; line-height: 1.2; text-align: center; }

/* ── LES TROIS CHIFFRES SE COLLAIENT LES UNS AUX AUTRES ────────────────────
   La ligne est faite de trois `span` — déplacement, attaque, inventaire — et
   aucune règle ne les concernait. Deux éléments en ligne mis bout à bout ne
   laissent aucun blanc entre eux : on lisait « DÉPL. 4ATT. 4INV. 4 », d'un
   seul tenant, et le texte débordait de la fiche pour empiéter sur la voisine.

   Une fiche fait quatre-vingt-douze pixels, soixante-quatorze sur petit écran :
   les trois chiffres n'y tiendront jamais sur une ligne. On les laisse donc
   se ranger d'eux-mêmes, deux par ligne ou un seul selon la place, et chacun
   reste insécable — « ATT. » et son chiffre ne se séparent pas. */
.perso-stats {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 1px 7px;
  font: 10px/1.35 var(--mono); color: var(--faible);
  text-align: center;
}
.perso-stats .stat { white-space: nowrap; }

/* Les fiches gardent la même hauteur quel que soit le nombre de lignes que
   prennent leurs chiffres : une rangée de portraits qui ondule se lit mal. */
.groupe-perso { align-items: stretch; }
.btn.perso { justify-content: flex-start; }
.btn.perso:disabled .perso-portrait { filter: grayscale(1); opacity: .5; }

/* ── Écran des gardiennes (phase 2) ──────────────────────────────────────── */
/* Il recouvre le plateau : à ce moment il n'y a plus rien à y lire, tout se
   joue dans une comparaison de forces. */
#ecran-gardiennes {
  position: fixed; inset: 0; z-index: 250;
  display: none; place-items: center; padding: 20px;
  background: rgb(12 9 5 / .92);
  overflow-y: auto;
}
#ecran-gardiennes.visible { display: grid; }

.gard-boite {
  width: min(620px, 100%);
  padding: 24px 26px; border-radius: 14px;
  background: var(--carte); border: 1px solid var(--or);
  box-shadow: 0 22px 70px rgb(0 0 0 / .6);
}
.gard-etiquette {
  font: 650 10.5px/1 var(--mono); letter-spacing: .16em;
  text-transform: uppercase; color: var(--or);
}
.gard-tete h2 { margin: 6px 0 16px; font-size: 21px; font-weight: 650; line-height: 1.25; }

.gard-rangee { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.gard-carte {
  width: 62px; padding: 10px 6px; border-radius: 8px; text-align: center;
  background: #3a2f45; border: 1px solid #6b5b7a;
}
.gard-carte.groupe { background: var(--m-gardienne); border-color: var(--m-gardienne-bord); }
.gard-force { display: block; font: 700 22px/1 var(--mono); color: #e8dcf2; }
.gard-type { display: block; margin-top: 3px; font-size: 9.5px; color: var(--faible); }

.gard-bilan {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  padding: 14px; margin-bottom: 16px; border-radius: 10px; background: var(--creux);
}
.gard-bilan div { text-align: center; }
.gard-bilan span { display: block; font-size: 11px; color: var(--faible); }
.gard-bilan b { display: block; font: 700 26px/1.2 var(--mono); }
.gard-bilan .contre { font-size: 12px; color: var(--faible); }

.gard-alerte {
  margin: 0 0 16px; padding: 10px 13px; border-radius: 8px;
  background: color-mix(in srgb, var(--or) 16%, transparent);
  border-left: 3px solid var(--or); font-size: 13.5px;
}

.gard-mise { border-top: 1px solid var(--bord); padding-top: 16px; }
.gard-joueur { display: flex; align-items: center; gap: 10px; font-weight: 650; }
.gard-consigne { margin: 6px 0 12px; font-size: 12.5px; color: var(--faible); }
.gard-cartes { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 16px; }
.gard-arme {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 12px; border-radius: 8px;
  border: 1px solid var(--bord); background: var(--creux); color: var(--texte);
  font: inherit; cursor: pointer; transition: border-color .12s, background .12s;
}
.gard-arme:hover { border-color: var(--or); }
.gard-arme.engagee {
  background: color-mix(in srgb, var(--vert) 22%, var(--creux));
  border-color: var(--vert);
}
.gard-arme .nom { font-size: 12px; font-weight: 650; }
.gard-arme .pts { font: 700 13px/1 var(--mono); color: var(--vert); }
.gard-vide { margin: 0; font-size: 12.5px; color: var(--faible); font-style: italic; }

/* Le porteur du trésor, en phase 3 */
.jeton.porteur .jeton-rond { stroke: var(--or); stroke-width: 3; }

.jeton-tresor { fill: var(--or); stroke: #17130e; stroke-width: 1.2; }

/* ── Carte personnage ────────────────────────────────────────────────────── */
/* Un seul panneau, fixe, au bord du plateau. Les deux fenêtres flottantes se
   disputaient la place et masquaient les salles qu'on lisait pour décider. */
.carte-perso {
  padding: 14px; border-bottom: 1px solid var(--bord);
  background: color-mix(in srgb, var(--teinte, var(--or)) 7%, var(--carte));
  border-left: 3px solid var(--teinte, var(--or));
}
.cp-tete { display: flex; align-items: center; gap: 11px; margin-bottom: 11px; }
.cp-portrait {
  position: relative; overflow: hidden; flex: none;
  display: inline-grid; place-items: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: color-mix(in srgb, var(--teinte) 30%, var(--creux));
  border: 2px solid var(--teinte);
  font: 700 17px/1 var(--mono); color: var(--texte);
}
.cp-portrait img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cp-identite { min-width: 0; }
.cp-nom { display: block; font-weight: 650; font-size: 15px; line-height: 1.2; }
.cp-forme { display: block; font-size: 11px; color: var(--faible); line-height: 1.3; }

.cp-stats { display: flex; gap: 8px; margin-bottom: 12px; }
.cp-stats div {
  flex: 1; text-align: center; padding: 6px 4px;
  border-radius: 6px; background: var(--creux);
}
.cp-stats span { display: block; font-size: 9.5px; color: var(--faible);
                 text-transform: uppercase; letter-spacing: .06em; }
.cp-stats b { display: block; font: 700 17px/1.25 var(--mono); }

.cp-sous-titre {
  font: 650 10px/1 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--faible); margin-bottom: 6px;
}
.cp-sous-titre.alerte { color: var(--rouge); }
.cp-note { margin: 4px 0 0; font-size: 11px; color: var(--faible); line-height: 1.4; }
.cp-invite {
  margin: 0 0 7px; padding: 6px 9px; border-radius: 5px;
  background: color-mix(in srgb, var(--rouge) 16%, transparent);
  border-left: 2px solid var(--rouge); font-size: 11.5px; line-height: 1.35;
}

/* LES MOMIES SONT DANS L'INVENTAIRE, pas dans un bloc à part. Elles y occupent
   de vrais emplacements — c'est la règle — et les montrer ailleurs laissait
   croire le contraire : on lisait « Inventaire 2/5 » pendant que le jeu
   réclamait une défausse. Quatre cases fixes, en tête, d'une autre couleur. */
.cp-momies { display: flex; gap: 5px; }
.cp-momies.dans-inventaire { margin: 0 0 9px; }
.cp-momie {
  flex: 1; text-align: center; padding: 7px 0; border-radius: 5px;
  background: var(--carte); border: 1px dashed var(--bord);
  font: 700 14px/1 var(--mono); color: var(--faible);
}
.cp-momie.prise {
  background: #4a3550; border: 1px solid #a08ac0; border-style: solid;
  color: #e8dcf2;
}

/* Le combat */
.cp-combat { margin-bottom: 12px; padding: 10px; border-radius: 8px;
             background: var(--creux); border: 1px solid var(--rouge); }
.cp-combat-score {
  display: flex; align-items: baseline; justify-content: center; gap: 8px;
  margin-bottom: 9px;
}
.cp-combat-score span { font-size: 12px; color: var(--faible); }
.cp-combat-score b { font: 700 26px/1 var(--mono); color: var(--rouge); }
.cp-combat-score.gagnant b { color: var(--vert); }
.cp-renforts { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.cp-renfort {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 9px; border-radius: 5px;
  border: 1px solid var(--bord); background: var(--carte); color: var(--texte);
  font: inherit; font-size: 12px; cursor: pointer;
}
.cp-renfort:hover { border-color: var(--or); }
.cp-renfort b { font: 700 12px/1 var(--mono); color: var(--vert); }
.cp-renfort.engagee {
  background: color-mix(in srgb, var(--vert) 20%, var(--carte));
  border-color: var(--vert);
}

/* Actions */
.cp-actions { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.cp-action {
  display: block; width: 100%; text-align: left;
  padding: 8px 10px; border-radius: 6px;
  border: 1px solid var(--bord); background: var(--creux); color: var(--texte);
  font: inherit; cursor: pointer; transition: border-color .12s, background .12s;
}
.cp-action:hover:not(:disabled) { border-color: var(--or); }
.cp-action:disabled { opacity: .4; cursor: default; }
.cp-action.primaire { background: var(--or); color: #17130e; border-color: var(--or); }
.cp-action.capacite { border-color: #a08ac0; }
.cp-action.discret { background: transparent; }
.cp-action.porteur { background: color-mix(in srgb, var(--or) 20%, var(--creux));
                     border-color: var(--or); }
.cp-a-nom { display: block; font-weight: 650; font-size: 13px; }
.cp-a-detail { display: block; font-size: 10.5px; color: var(--faible); line-height: 1.35; }
.cp-action.primaire .cp-a-detail { color: rgb(23 19 14 / .7); }

/* Inventaire utilisable */
.cp-inventaire { border-top: 1px solid var(--bord); padding-top: 11px; }
.cp-carte {
  display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap;
  padding: 6px; margin-bottom: 5px; border-radius: 6px;
  background: var(--creux); border-left: 3px solid var(--bord);
}
.cp-vignette { width: 38px; height: 38px; border-radius: 4px; object-fit: cover; flex: none; }
.cp-carte-texte { flex: 1; min-width: 0; }
.cp-carte-nom { display: block; font-weight: 650; font-size: 12px; }
.cp-carte-effet { display: block; font-size: 10.5px; color: var(--faible); line-height: 1.35; }
.cp-carte-outils { display: flex; gap: 5px; width: 100%; }
.cp-carte.cat-arme     { border-left-color: var(--rouge); }
.cp-carte.cat-outil    { border-left-color: var(--vert); }
.cp-carte.cat-trahison { border-left-color: #a08ac0; }
.cp-carte.cat-pouvoir  { border-left-color: var(--or); }



/* ═══ PETITS ÉCRANS ═══════════════════════════════════════════════════════ */
/*
 * Deux dispositions, pas une.
 *
 * En PORTRAIT, le plateau occupe le haut et la carte personnage glisse depuis
 * le bas : c'est la seule façon d'avoir les deux lisibles sur un écran plus
 * haut que large.
 *
 * En PAYSAGE — une console portable tenue à deux mains —, le plateau prend le
 * centre et la carte se range sur le côté, à portée de pouce.
 *
 * Le principe commun : rien ne se superpose au plateau, et tout ce qui est
 * cliquable reste dans la zone visible, encoches comprises.
 */

/* ── Portrait : téléphone tenu debout ────────────────────────────────────── */
@media (max-width: 820px) and (orientation: portrait) {
  body { overflow: hidden; }

  #barre { padding: 7px 12px; gap: 8px; flex-wrap: wrap; }
  .marque { font-size: 12px; letter-spacing: .18em; }
  .phase { font-size: 10.5px; }
  .info { font-size: 12px; gap: 8px; }
  .tour-actions { display: none; }
  .btn.petit { padding: 5px 9px; font-size: 11px; }

  #principal {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
    min-height: 0;
  }
  #zone-plateau { padding: 8px; }

  /* La colonne devient un tiroir, glissé depuis le bas. */
  #colonne {
    flex-direction: column;
    border-left: none;
    border-top: 1px solid var(--bord);
    max-height: 46vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .carte-perso { border-left: none; border-top: 3px solid var(--teinte, var(--or)); }
  .section { border-right: none; border-bottom: 1px solid var(--bord); min-width: 0; }

  /* Le journal se replie : il prend toute la hauteur pour rien. */
  .section-journal { max-height: 118px; }
  .journal { font-size: 11.5px; }

  /* Cibles tactiles : 44 px, sinon on rate un bouton sur deux. */
  .cp-action { padding: 11px 12px; }
  .cp-a-nom { font-size: 14px; }
  .mini { padding: 7px 12px; font-size: 12px; }
  .btn { padding: 11px 16px; }

  .apercu-tuile {
    left: 50%; bottom: 10px; transform: translateX(-50%);
    width: min(210px, 78vw);
  }
  .apercu-carte { width: min(190px, 62vw); top: 38%; }

  .gard-boite { padding: 16px 14px; }
  .gard-carte { width: 48px; padding: 8px 4px; }
  .gard-force { font-size: 18px; }
  .gard-arme { padding: 10px 12px; }
}

/* ── Paysage : console portable, téléphone couché ────────────────────────── */
@media (max-height: 760px) and (orientation: landscape) {
  body { overflow: hidden; }

  /* ── LE BANDEAU DU TOMBEAU MANGE DEUX LIGNES ─────────────────────────────
     Il n'était pas traité en paysage : « Le tombeau » sur une ligne, les
     quatre échelles sur une seconde. Sur un écran haut de 430 pixels, c'est
     un huitième de la hauteur pour une information qu'on lit d'un coup d'œil.

     Le titre disparaît — on sait où l'on est — et les échelles se serrent sur
     une seule ligne, à leur taille minimale lisible. */
  #bandeau-tombeau { padding: 2px 8px; gap: 8px; font-size: 11px; }
  #bandeau-tombeau .titre { display: none; }
  #bandeau-tombeau .echelles { gap: 6px; }
  #bandeau-tombeau .dernier { display: none; }
  #bandeau-tombeau .jauge i { width: 7px; height: 7px; }

  /* L'en-tête mange une hauteur précieuse : on la réduit au strict. */
  #barre { padding: 4px 10px; }
  .marque { font-size: 11px; letter-spacing: .14em; }
  .phase { display: none; }
  .info { font-size: 11.5px; }
  .tour-nom { padding: 2px 8px; }
  .tour-nom .portrait { width: 18px; height: 18px; font-size: 9px; }
  .btn.petit { padding: 4px 8px; font-size: 10.5px; }

  #principal { grid-template-columns: 1fr 268px; grid-template-rows: 1fr; }
  #zone-plateau { padding: 6px; }

  #colonne {
    flex-direction: column;
    border-left: 1px solid var(--bord);
    border-top: none;
    max-height: none;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: env(safe-area-inset-right, 0);
  }
  .carte-perso { padding: 10px; }
  .cp-tete { margin-bottom: 8px; }
  .cp-portrait { width: 36px; height: 36px; font-size: 14px; }
  .cp-nom { font-size: 13.5px; }
  .cp-forme { font-size: 10px; }
  .cp-stats { margin-bottom: 8px; }
  .cp-stats b { font-size: 15px; }
  .cp-action { padding: 8px 10px; }
  .cp-a-nom { font-size: 12.5px; }
  .cp-vignette { width: 30px; height: 30px; }

  /* Les autres joueurs et le journal se replient : la carte prime. */
  .section { padding: 8px 10px; }
  .section h2 { margin-bottom: 5px; }
  .section-journal { max-height: 92px; }
  .journal { font-size: 11px; }
  .joueur { padding: 5px 8px; }
  .joueur-tete .portrait { width: 26px; height: 26px; font-size: 11px; }

  .apercu-tuile {
    width: 156px; padding: 8px 10px;
    left: 8px; bottom: 8px; transform: none;   /* un coin, pas le centre */
  }
  .apercu-carte { width: 150px; top: 45%; }
  .carte-illu { aspect-ratio: 16/9; }

  /* L'écran des gardiennes doit tenir dans 560 px de haut, boutons compris. */
  #ecran-gardiennes { padding: 8px; align-items: start; }
  .gard-boite { padding: 12px 14px; max-height: calc(100vh - 16px); overflow-y: auto; }
  .gard-tete h2 { margin: 4px 0 9px; font-size: 16px; }
  .gard-rangee { margin-bottom: 10px; gap: 6px; }
  .gard-carte { width: 44px; padding: 6px 3px; }
  .gard-force { font-size: 16px; }
  .gard-type { font-size: 8.5px; }
  .gard-bilan { padding: 8px; margin-bottom: 10px; }
  .gard-bilan b { font-size: 19px; }
  .gard-mise { padding-top: 10px; }
  .gard-consigne { margin: 4px 0 8px; font-size: 11.5px; }
  .gard-cartes { margin-bottom: 10px; }
  .gard-arme { padding: 6px 10px; }

  #modale { padding: 14px 16px; max-height: calc(100vh - 20px); }
  #modale h2 { margin-bottom: 9px; font-size: 17px; }
  .btn.perso { width: 74px; padding: 6px 4px; }
  .perso-portrait { width: 42px; height: 42px; }
  .perso-nom { font-size: 10.5px; }
}

/* ── Très petits écrans : on abandonne la colonne fixe ───────────────────── */
@media (max-width: 400px) and (orientation: portrait) {
  #colonne { max-height: 52vh; }
  .cp-stats b { font-size: 15px; }
  .gard-carte { width: 42px; }
}

/* Le survol n'existe pas au doigt : on ne s'appuie dessus pour rien. */
@media (hover: none) {
  .cp-action:hover:not(:disabled),
  .btn:hover:not(:disabled),
  .mini:hover { border-color: var(--bord); }
  .cp-action:active:not(:disabled) { border-color: var(--or); }
  .btn:active:not(:disabled) { border-color: var(--or); }
}


/* ── Sécurité : rien ne déborde jamais du cadre ─────────────────────────── */
/* Un panneau plus large que l'écran met ses boutons hors d'atteinte : on ne
   peut ni les voir ni les toucher, et rien ne le signale. */
#carte-perso, #colonne, .gard-boite, #modale, .apercu-tuile, .apercu-carte {
  max-width: 100%;
}
#ecran-gardiennes, #modale-fond {
  padding-top: max(12px, env(safe-area-inset-top));
  padding-bottom: max(12px, env(safe-area-inset-bottom));
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
}
#barre { padding-left: max(12px, env(safe-area-inset-left)); }

/* Les zones défilables doivent l'être au doigt, sans emporter la page. */
#colonne, .journal, .gard-boite, #modale, #zone-plateau {
  -webkit-overflow-scrolling: touch;
}



@media (max-width: 820px) and (orientation: portrait) {
  .onglet {
    flex: 1; padding: 11px 6px;
    border: none; border-bottom: 2px solid transparent;
    background: none; color: var(--faible);
    font: 650 12.5px/1 inherit; cursor: pointer;
  }
  .onglet.actif { color: var(--or); border-bottom-color: var(--or); }
  .onglet.attention::after {
    content: ''; display: inline-block; margin-left: 5px;
    width: 6px; height: 6px; border-radius: 50%; background: var(--rouge);
    vertical-align: middle;
  }

  /* Le plateau EN HAUT, la carte du personnage EN BAS, dans la même vue :
     on voit où l'on est et on agit sans changer de page. */
  #principal { grid-template-rows: minmax(0, 1fr) auto; grid-template-columns: 1fr; }

  body[data-vue="plateau"] #zone-plateau { display: grid; min-height: 0; }
  body[data-vue="plateau"] #colonne {
    display: flex; grid-row: 2;
    max-height: 42vh; border-top: 1px solid var(--bord);
  }
  /* Sous le plateau, seule la carte du personnage : l'expédition et le
     journal ont leur propre onglet. */
  body[data-vue="plateau"] #colonne .section { display: none; }

  body[data-vue="journal"] #zone-plateau { display: none; }
  body[data-vue="journal"] #colonne {
    display: flex; grid-row: 1; max-height: none; border-top: none;
  }
  body[data-vue="journal"] #carte-perso { display: none; }
  body[data-vue="journal"] .section-journal { max-height: none; flex: 1; }

  /* La carte se resserre : sous le plateau, chaque pixel de hauteur compte. */
  body[data-vue="plateau"] .cp-tete { padding: 8px 12px; }
  body[data-vue="plateau"] .cp-portrait { width: 34px; height: 34px; font-size: 15px; }
  body[data-vue="plateau"] .cp-stats { padding: 6px 12px; }
  body[data-vue="plateau"] .cp-actions { padding: 8px 10px; gap: 6px; }

  /* L'aperçu de tuile et la carte tirée ne valent que sur la vue plateau. */
  body:not([data-vue="plateau"]) .apercu-tuile,
  body:not([data-vue="plateau"]) .apercu-carte { display: none; }
}

/* ── Concertation du cas C : les propositions de chacun, à découvert ─────── */
.gard-propositions { margin: .75rem 0; }
.gard-propositions h3 {
  font-size: .8rem; text-transform: uppercase; letter-spacing: .06em;
  opacity: .7; margin: 0 0 .4rem;
}
.gard-proposition {
  display: flex; justify-content: space-between; gap: .75rem;
  padding: .3rem .5rem; border-radius: .4rem;
  background: color-mix(in srgb, var(--fond-2) 70%, transparent);
  margin-bottom: .25rem; font-size: .9rem;
}
.gard-proposition .nom { color: var(--teinte, inherit); font-weight: 600; }
.gard-proposition .quoi { opacity: .85; text-align: right; }

/* ── Réaction à un piège : la carte, la question, le compte à rebours ────── */
.reaction { text-align: center; }
.reaction-carte {
  max-width: 9rem; border-radius: .6rem; margin: .6rem auto; display: block;
  box-shadow: 0 .4rem 1.2rem rgb(0 0 0 / .35);
}
.reaction-chrono { font-size: 1.6rem; margin: .4rem 0 0; font-variant-numeric: tabular-nums; }
.reaction-chrono b { color: var(--accent, #d8a24a); }
.choix-joueur { min-height: .5rem; }

/* ── Pierre, marches et portails ──────────────────────────────────────────── */
/* Les cases murées ne se dessinent plus : les murs pleins sont posés en SVG,
   par-dessus la pierre. Ces couleurs restent pour les vues qui n'ont pas les
   dalles, en valeurs explicites. */
.case-muree {
  fill: rgb(19, 16, 12);
  stroke: rgb(14, 12, 9);
  stroke-width: .5;
}
.reperes { pointer-events: none; }
.repere.marches rect {
  fill: rgb(232, 190, 103);            /* or éclairci, valeur explicite */
  opacity: .95;
}
.repere.portail circle {
  fill: none;
  stroke: #7ec8e3;
  stroke-width: 2;
  opacity: .9;
}
.repere.portail circle.coeur {
  fill: rgba(126, 200, 227, .35);
  stroke-dasharray: 3 3;
}
.tuile-fond.type-entree, .tuile-fond.type-puits {
  stroke: var(--accent, #d8a24a);
  stroke-width: 2;
}
.tuile-fond.type-portail { stroke: #7ec8e3; stroke-width: 2; }

/* ── Trésor du pharaon et margelle du puits ──────────────────────────────── */
.repere.tresor .coffre {
  fill: rgb(189, 136, 49);
  stroke: #3a2a10; stroke-width: 1;
}
.repere.tresor .couvercle {
  fill: rgb(228, 174, 82);
  stroke: #3a2a10; stroke-width: 1;
}
.repere.tresor .serrure { fill: #3a2a10; }
.repere.puits circle {
  fill: none; stroke: #9fb8c8; stroke-width: 2.5; opacity: .9;
}
.repere.puits circle.gouffre {
  fill: rgba(10, 15, 20, 0.80); stroke: none;
}
.tuile-fond.type-tresor { stroke: var(--accent, #d8a24a); stroke-width: 2.5; }

/* ── Portée cumulée : plus c'est loin, plus cela coûte d'actions ─────────── */
/* Le coût du déplacement, du plus proche au plus lointain. Couleurs
   explicites : une valeur qui demande à être calculée peut être ignorée, et la
   case redevient alors transparente — le déplacement cesse de se voir.

   UN FOND DE BASE POUR TOUTE CASE ATTEIGNABLE. Après un déplacement suivi
   d'une pose, les cases les plus proches coûtent ZÉRO action — la suite du
   déplacement en cours. Cette classe-là n'existait pas : les cases restaient
   incolores alors qu'elles étaient les moins chères de toutes. Un fond par
   défaut garantit qu'aucune case offerte ne puisse être invisible, quel que
   soit son coût. */
.case.atteignable { fill: rgba(76, 175, 80, .16); }
.case.atteignable.cout-0 { fill: rgba(76, 175, 80, .62); }
.case.atteignable.cout-1 { fill: rgba(76, 175, 80, .52); }
.case.atteignable.cout-2 { fill: rgba(76, 175, 80, .30); }
.case.atteignable.cout-3 { fill: rgba(76, 175, 80, .16); }
.case.atteignable.cout-2, .case.atteignable.cout-3 { stroke-dasharray: 3 2; }
.cout-actions {
  font: 600 9px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  fill: color-mix(in srgb, var(--or) 85%, #fff);
  pointer-events: auto; cursor: pointer; user-select: none;
}
@media (max-width: 820px) and (orientation: portrait) {
  .cout-actions { font-size: 11px; }
}

/* ── La couleur du joueur descend en dégradé sur la fiche ────────────────── */
/* Le trait du haut ne suffisait pas à repérer qui joue d'un coup d'œil : la
   teinte se prolonge maintenant en voile léger sur le premier tiers. */
#carte-perso {
  background-image: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--teinte, transparent) 26%, transparent) 0,
    color-mix(in srgb, var(--teinte, transparent) 9%, transparent) 38%,
    transparent 68%);
}

/* ── Le pion de celui qui vient de prendre la main respire ───────────────── */
@keyframes pouls-jeton {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.16); }
}
.jeton.actif .jeton-rond {
  transform-box: fill-box;
  transform-origin: center;
  animation: pouls-jeton 1.6s ease-in-out 3;
}
@media (prefers-reduced-motion: reduce) {
  .jeton.actif .jeton-rond { animation: none; }
  .jeton { transition: none !important; }
}

/* ── Le puits ne ressemble plus au portail ───────────────────────────────── */
.repere.puits circle.margelle { fill: none; stroke: #9fb8c8; stroke-width: 2.5; opacity: .95; }
.repere.puits line.pierre { stroke: #9fb8c8; stroke-width: 1.6; opacity: .8; }
.repere.puits circle.gouffre { fill: #05080b; stroke: none; opacity: .9; }
.repere.portail polygon {
  fill: rgba(126, 200, 227, 0.30);
  stroke: #7ec8e3; stroke-width: 1.8; stroke-linejoin: round;
}

/* ═══ Portrait : la place se gagne en haut ══════════════════════════════════ */

/* Le thème flotte, hors du flux : il ne prend plus de hauteur. */
#btn-theme.flottant {
  position: fixed; top: max(8px, env(safe-area-inset-top)); right: 10px;
  z-index: 40; opacity: .75;
}
#btn-theme.flottant:hover { opacity: 1; }

/* La bascule de vue n'existe que sur petit écran : ailleurs, tout tient. */
#btn-vue { display: none; }

/* Les caractéristiques : le chiffre passe à droite du libellé, la bande
   perd la moitié de sa hauteur. */
.cp-stats div {
  display: flex; align-items: baseline; justify-content: center; gap: 6px;
  padding: 4px 6px;
}
.cp-stats span { display: inline; }
.cp-stats b { display: inline; font-size: 15px; }

/* Le texte sous le nom tient sur deux lignes au lieu d'être coupé net. */
.cp-forme {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; white-space: normal;
}

/* Les quatre actions de base en grille, les capacités pleine largeur. */
.cp-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.cp-action { grid-column: 1 / -1; }
.cp-action.moitie { grid-column: auto; }

@media (max-width: 820px) and (orientation: portrait) {
  #btn-vue { display: inline-flex; }
  #barre { padding-top: max(6px, env(safe-area-inset-top)); }
  #btn-theme.flottant { top: auto; bottom: max(10px, env(safe-area-inset-bottom)); }
}

/* ═══ Paysage sur téléphone : la hauteur est la denrée rare ════════════════ */
/* ── TROIS COLONNES SUR LES GRANDS PAYSAGES ──────────────────────────────────
 *
 * Sur un iPhone Pro Max couché, l'écran fait plus de 900 points de large. Deux
 * colonnes y laissent une bande de journal étroite et haute, où l'on lit trois
 * mots par ligne — alors que la place ne manque pas.
 *
 * On sépare donc : le plateau, la fiche du personnage, et le journal. Chacun
 * respire, et l'on garde le journal sous les yeux au lieu de le faire défiler.
 *
 * La largeur des deux colonnes se règle par `--col-fiche` et `--col-journal` :
 * l'auteur peut les ajuster sans toucher à cette règle.
 */
:root {
  --col-fiche:   260px;
  --col-journal: 300px;
}

@media (min-width: 900px) and (max-height: 560px) and (orientation: landscape) {
  #btn-vue { display: none; }
  #barre { padding: 4px 10px; }
  #barre .phase { display: none; }

  #principal {
    grid-template-columns: 1fr var(--col-fiche) var(--col-journal);
    grid-template-rows: 1fr;
  }
  body[data-vue] #zone-plateau { display: grid; grid-row: 1; grid-column: 1; min-height: 0; }
  body[data-vue] #colonne {
    display: flex; flex-direction: column;
    grid-row: 1; grid-column: 2; max-height: none; border-top: none;
    border-left: 1px solid var(--bord);
    overflow: auto;
  }
  /* Le journal quitte la colonne et prend la troisième place. */
  body[data-vue] #colonne .section-journal {
    grid-row: 1; grid-column: 3;
    display: flex; flex-direction: column; min-height: 0;
    border-left: 1px solid var(--bord); overflow: auto;
  }
}

/* ── UN PAYSAGE BAS RESTE JOUABLE ──────────────────────────────────────────
   Un iPhone en paysage fait 852 × 393 px : il tombe dans cette règle et PAS
   dans celle des 900 px, qui donne trois colonnes.

   Cette règle cachait `#btn-vue` — le seul bouton qui mène au journal. Une vue
   journal existait pourtant, décrite trois lignes plus bas : elle était donc
   PRÉVUE et INATTEIGNABLE. Le joueur ne pouvait pas la voir, ni même savoir
   qu'elle existait.

   La colonne ne défilait pas non plus : `overflow` n'y était pas posé, et la
   fiche du personnage se coupait à la hauteur de l'écran. */
@media (max-height: 520px) and (orientation: landscape) {
  /* Le bouton RESTE : c'est la seule porte vers le journal sur cet écran. */
  #btn-vue { display: inline-flex; }

  /* ── LA BARRE PASSE SOUS L'ENCOCHE ──────────────────────────────────────
     `padding: 4px 10px` écrasait la marge de sécurité posée plus haut : en
     paysage, l'écran de l'iPhone est arrondi aux quatre coins, et le « A »
     d'ATOUM comme le « 2 action(s) » disparaissaient sous la courbe.

     On garde le resserrement vertical — la place manque — mais on rend au
     bord latéral ce que l'appareil réclame. */
  #barre {
    padding: 4px max(10px, env(safe-area-inset-left))
             4px max(10px, env(safe-area-inset-right));
  }
  #barre .marque { font-size: 13px; }
  #barre .phase { display: none; }

  /* Plateau à gauche, carte à droite : les deux tiennent côte à côte. */
  #principal { grid-template-columns: 1fr minmax(230px, 34vw); grid-template-rows: 1fr; }
  body[data-vue] #zone-plateau { display: grid; grid-row: 1; grid-column: 1; min-height: 0; }
  body[data-vue] #colonne {
    display: flex; flex-direction: column;
    grid-row: 1; grid-column: 2; max-height: none; border-top: none;
    border-left: 1px solid var(--bord);
    /* ELLE DOIT DÉFILER. Sans cela, la fiche se coupe à la hauteur de l'écran
       et l'on ne voit ni l'inventaire, ni les dernières actions. */
    overflow-y: auto; -webkit-overflow-scrolling: touch; min-height: 0;
  }
  /* En vue « plateau », la colonne montre la fiche ; en vue « journal », elle
     montre le journal. Une seule à la fois : la place ne permet pas les deux. */
  body[data-vue="plateau"] #colonne .section-journal { display: none; }
  body[data-vue="journal"] #colonne .section:not(.section-journal) { display: none; }
  body[data-vue="journal"] #colonne .section-journal {
    display: flex; flex-direction: column; min-height: 0; flex: 1;
  }
  body[data-vue="journal"] #zone-plateau { display: grid; }
  body[data-vue="journal"] #carte-perso { display: none; }

  /* ── LA TUILE À POSER SE TOUCHE AU DOIGT ────────────────────────────────
     Elle héritait de la règle des petits écrans — `min(210px, 78vw)` —, or en
     paysage `78vw` vaut plus de six cents pixels : c'est le `210px` qui
     gagnait, sur une hauteur de 393. La vignette occupait un quart de la
     hauteur disponible et se touchait mal.

     Ici, la largeur ne manque pas : c'est la HAUTEUR qui commande. On la cale
     donc sur elle, et on l'écarte du bord gauche où l'encoche mord. */
  .apercu-tuile {
    left: max(14px, env(safe-area-inset-left)); right: auto;
    bottom: 10px; transform: none;
    width: min(46vh, 200px);
  }
  .apercu-carte { width: min(52vh, 240px); top: 50%; transform: translate(-50%, -50%); }

  .cp-tete { padding: 6px 10px; }
  .cp-portrait { width: 30px; height: 30px; font-size: 14px; }
  .cp-stats { margin-bottom: 6px; }
  .cp-actions { gap: 5px; }
  .cp-action { padding: 6px 8px; }
  .cp-a-detail { display: none; }
  #btn-theme.flottant { top: auto; bottom: 8px; right: 8px; }
}

/* ── Écran de lancement : le bouton de départ prend toute la largeur ─────── */
#modale .actions .btn.primaire {
  flex: 1 1 100%;
  margin: 6px 2px 2px;
  padding-block: 12px;
  font-size: 15px;
}
.perso-stats { white-space: nowrap; font-variant-numeric: tabular-nums; }


.plateau-iso { width: 100%; height: 100%; }

/* Vu de très haut, le volume ne se lit plus aux faces mais au contraste :
   un dessus clair, une face sud sombre, une ombre portée courte. */
.iso-sol { fill: #6f5d45; stroke: #4a3d2d; stroke-width: .7; }
.iso-sol.sable { fill: #cba96b; stroke: #9c7f47; }
.iso-sol.marches { fill: #8d7551; }
.iso-sol.type-tresor { fill: #806737; }
.iso-sol.type-entree, .iso-sol.type-puits { fill: #79674c; }
.iso-relief-face { fill: #4c4030; }
.iso-relief-face.sable { fill: #9c7f47; }
.iso-degre { fill: #a08659; stroke: #5d4c34; stroke-width: .5; }

.iso-bloc-dessus { fill: #3c332a; stroke: #241d16; stroke-width: .8; }
.iso-bloc-face { fill: #241d16; }
.iso-arche { fill: #6d5d47; stroke: #3a3126; stroke-width: .8; }

.iso-fosse { fill: #55483a; }
.iso-gouffre { fill: #090705; }

.iso-atteignable {
  fill: color-mix(in srgb, var(--or, #d8a24a) 36%, transparent);
  stroke: var(--or, #d8a24a); stroke-width: 1.2; cursor: pointer;
}
.iso-atteignable.cout-2 { fill: color-mix(in srgb, var(--or, #d8a24a) 20%, transparent); }
.iso-atteignable.cout-3 { fill: color-mix(in srgb, var(--or, #d8a24a) 11%, transparent); }

.iso-momie .corps { fill: #33404c; stroke: #18202a; stroke-width: .9; }
.iso-momie .ombre { fill: rgb(0 0 0 / .35); }
.iso-momie.visee .corps { stroke: #c2523f; stroke-width: 1.8; cursor: pointer; }

.iso-jeton .ombre { fill: rgb(0 0 0 / .38); }
.iso-jeton .flanc { fill-opacity: .78; }
.iso-jeton .tete { stroke: rgb(0 0 0 / .5); stroke-width: 1; }
.iso-jeton.actif .tete { stroke: #fff; stroke-width: 1.8; }
.iso-jeton .jeton-lettre {
  fill: #1b1610; font: 700 13px/1 var(--titre, inherit); pointer-events: none;
}
.iso-jeton .jeton-tresor { fill: var(--or, #d8a24a); stroke: #6b4a10; stroke-width: .8; }

.iso-pose .halo {
  fill: color-mix(in srgb, var(--or, #d8a24a) 12%, transparent);
  stroke: var(--or, #d8a24a); stroke-width: 1.4; stroke-dasharray: 5 4; cursor: pointer;
}
.iso-pose .signe { fill: var(--or, #d8a24a); font: 700 20px/1 var(--mono); cursor: pointer; }

/* Le sable qui vient lécher le bas des pions : sans lui, ils flottent au lieu
   de patauger. */
.iso-ourlet-sable { fill: #d3b378; opacity: .95; }

/* La toile WebGL occupe la zone comme n'importe quel plateau. */
canvas.plateau-3d { width: 100%; height: 100%; display: block; touch-action: none; }

/* ── Le mini-plateau du tombeau ──────────────────────────────────────────── */
/* Quatre échelles, toujours sous les yeux. On voit la menace monter, et l'on
   sait qu'un symbole de plus la fera tomber.

   ── CES RÈGLES NE S'APPLIQUAIENT PLUS À RIEN ──────────────────────────────
   Le bandeau s'appelait « pyramide » ; il a été renommé « tombeau » dans le
   HTML quand le vocabulaire a changé, et ces sélecteurs sont restés sur
   l'ancien nom. Tout le bloc était donc mort : plus de marge, donc un titre
   collé au bord gauche de l'écran ; plus d'espacement entre les échelles,
   donc « Malédiction ■■□□□▽ Effondrement » d'un seul tenant, les mots contre
   les carrés et les symboles contre les mots.

   Rien n'avertit d'un sélecteur qui ne désigne plus rien : la page s'affiche,
   simplement sans style. C'est pourquoi un garde-fou vérifie désormais que
   chaque identifiant cité dans la feuille existe dans le HTML. */
#bandeau-tombeau {
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  padding: 6px 12px; border-bottom: 1px solid var(--bord);
  background: color-mix(in srgb, var(--fond-2) 70%, transparent);
  font-size: .78rem;
  /* L'encoche de l'iPhone mange le bord gauche en paysage. */
  padding-left: max(12px, env(safe-area-inset-left, 0px));
  padding-right: max(12px, env(safe-area-inset-right, 0px));
}
#bandeau-tombeau .titre {
  text-transform: uppercase; letter-spacing: .14em; font-size: .68rem;
  color: color-mix(in srgb, var(--or) 85%, #fff); font-weight: 600;
}
#tombeau-billes { display: flex; gap: 1.1rem; flex-wrap: nowrap; min-width: 0; }
/* Une échelle se lit en trois temps : le symbole, le nom, les crans. Ils
   avaient .28rem entre eux, ce qui les collait dès que le nom s'affichait. */
.echelle { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }
.echelle-icone { color: var(--faible); font-size: .9rem; line-height: 1; }
.echelle-nom { color: var(--faible); font-size: .72rem; }
/* Par défaut on n'affiche que l'icône : c'est le cas du téléphone en portrait. */
.echelle-nom { display: none; }
@media (min-width: 560px) { .echelle-nom.court { display: inline; } }
@media (min-width: 860px) {
  .echelle-nom.court { display: none; }
  .echelle-nom.long { display: inline; }
}
.crans { display: inline-flex; gap: 3px; }
.crans .cran {
  width: 8px; height: 8px; border-radius: 2px;
  background: color-mix(in srgb, var(--texte) 18%, transparent);
}
.crans .cran.plein { background: var(--or); }
.echelle.imminente .echelle-nom { color: var(--rouge); font-weight: 600; }
.echelle.imminente .crans .cran.plein { animation: pouls-cran 1.2s ease-in-out 6; }
@keyframes pouls-cran { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.35); } }
#bandeau-tombeau .dernier {
  margin-left: auto; opacity: .7; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 40%;
}
/* Sur un écran étroit, le dernier réveil s'efface plutôt que de faire déborder
   le bandeau sur une seconde ligne. */
@media (max-width: 700px) { #bandeau-tombeau .dernier { display: none; } }
#bandeau-tombeau { flex-wrap: nowrap; overflow: hidden; }
#bandeau-tombeau.reveil { animation: reveil-pyramide 1s ease-in-out 3; }
@keyframes reveil-pyramide {
  0%, 100% { background: color-mix(in srgb, var(--fond-2) 70%, transparent); }
  50%      { background: color-mix(in srgb, var(--or) 34%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  #bandeau-tombeau.reveil, .echelle.imminente .crans .cran.plein { animation: none; }
}

/* ── Le menu des outils ──────────────────────────────────────────────────── */
#menu {
  position: fixed; top: 46px; right: 8px; z-index: 60; min-width: 15rem;
  background: var(--fond-2); border: 1px solid var(--bord); border-radius: 8px;
  box-shadow: 0 .6rem 1.6rem rgb(0 0 0 / .45); padding: .3rem; display: grid;
}
#menu .entree {
  display: block; text-align: left; padding: .55rem .7rem; border-radius: 5px;
  color: var(--texte); text-decoration: none; background: none; border: none;
  font: inherit; font-size: .9rem; cursor: pointer;
}
#menu .entree:hover { background: color-mix(in srgb, var(--or, #d8a24a) 18%, transparent); }
@media (prefers-reduced-motion: reduce) { #bandeau-tombeau .bille.imminente { animation: none; } }

/* ── L'attribut « hidden » doit gagner ───────────────────────────────────── */
/* Un `display` posé sur un identifiant l'emporte sur la règle par défaut des
   navigateurs : sans ces deux lignes, le menu reste ouvert en permanence et le
   bandeau s'affiche en toutes phases. */
#menu[hidden], #bandeau-tombeau[hidden] { display: none !important; }

/* Le réveil de la pyramide : le bandeau bat trois fois, pour qu'on comprenne
   que quelque chose vient de se produire. */
@keyframes reveil-pyramide {
  0%, 100% { background: color-mix(in srgb, var(--fond-2) 70%, transparent); }
  50%      { background: color-mix(in srgb, var(--or, #d8a24a) 34%, transparent); }
}
#bandeau-tombeau.reveil { animation: reveil-pyramide 1s ease-in-out 3; }
.cp-carte.cat-pyramide, .apercu-carte.cat-pyramide {
  border-color: color-mix(in srgb, var(--or, #d8a24a) 60%, transparent);
}
@media (prefers-reduced-motion: reduce) { #bandeau-tombeau.reveil { animation: none; } }

/* ── La tuile pavée ──────────────────────────────────────────────────────── */
/* Les morceaux sont collés bord à bord : aucune marge, aucun trait. C'est la
   peinture des pierres qui fait le joint. */
/* LE SABLE. Un voile transparent plutôt qu'une teinte plaquée : la pierre se
   lit dessous, et un grain léger l'empêche d'être un aplat mort. */
/* Le sable ne teinte plus la pierre par un filtre : un voile transparent et
   grenu est posé par-dessus, dans le SVG. */

/* UN BORD LIBRE EST UN BORD. Tant qu'aucune salle ne s'y adosse, la demi-dalle
   s'assombrit vers l'extérieur et s'arrondit : on voit où la pyramide s'arrête,
   et l'on ne prend pas un bord pour un passage. */

/* UN COIN N'EST JAMAIS PRATICABLE. Il reste donc toujours nettement plus
   sombre que le chemin — sinon on croit pouvoir y aller. Le filtre porte sur
   l'IMAGE : posé sur le groupe, il ne s'appliquait pas, et les coins gardaient
   la couleur du sol. */
/* L'assombrissement des coins et des bords est DESSINÉ dans le SVG, pas filtré :
   Safari ignore largement les filtres CSS sur les éléments SVG. */


/* La salle qui arrive se pose : elle grandit un instant, puis s'installe. */
.dalle.neuve { animation: pose-tuile .42s cubic-bezier(.2,.9,.3,1.2) 1; transform-origin: center; }
@keyframes pose-tuile {
  0% { opacity: 0; transform: scale(1.14); }
  60% { opacity: 1; }
  100% { opacity: 1; transform: scale(1); }
}

/* Les murs pleins : du noir à 90 %, en attendant leurs propres images. */
/* UN MUR EST NOIR, ENTIÈREMENT. Il était à 90 % : la pierre transparaissait,
   et chaque mur devenait une superposition à composer — de la transparence
   partout, pour un effet que personne ne remarquait. Opaque, il coûte un
   aplat ; et la dalle dessous n'est même plus peinte. */
/* La pierre pleine d'une salle, sous les murs. Comme la bande du dehors, elle
   suit l'univers : en jungle, la masse végétale plutôt qu'un noir de basalte. */
.mur-plein { fill: var(--m-mur-dehors); }

/* Plus de liseré autour des tuiles : seule l'exploration en dessine un. */
.tuile-fond { display: none; }

/* Les cases ne peignent plus la pierre ; elles ne portent que les états.
   Le vert du déplacement s'éclaircit à mesure que la case coûte cher. */
.couche-murs ~ g .case { fill: transparent; stroke: none; }
.case.atteignable { stroke: #7fd68a; stroke-width: 1.4; }
.couche-murs ~ g .case-muree { display: none; }
.cout-actions { fill: #eafbe9; }

@media (prefers-reduced-motion: reduce) {
  .dalle.neuve { animation: none; }
}




/* ── Le menu passe au-dessus de tout, y compris des modales ──────────────── */
/* La modale de lancement monte à 300 : sans ce cran plus haut, le menu
   s'ouvrirait DERRIÈRE elle et paraîtrait ne rien faire. */
#menu { z-index: 400; }

/* ── Corrections de superposition et de pavage ───────────────────────────── */
/* LE RECTANGLE BEIGE. Une case de jonction était peinte en clair par une règle
   plus spécifique que celle qui rend les cases transparentes : elle trouait le
   pavage d'un aplat couleur parchemin, pile entre deux salles. */
/* AUCUNE CASE NE PEINT PAR-DESSUS LA PIERRE, sauf le déplacement. Les fonds
   de jonction et de sable ont été supprimés à leur source plutôt que
   neutralisés ici : deux règles qui se combattent finissent toujours par se
   départager autrement qu'on ne l'avait prévu. */
.couche-murs ~ g .case:not(.atteignable) { fill: transparent; stroke: none; }

/* Un bord sans voisine s'estompe vers l'extérieur : on voit d'un coup d'œil où
   la pyramide s'arrête. J'ai retiré ce dégradé une fois, pour gagner en
   fluidité — et les demi-dalles sont devenues sombres et inégales. Le gain ne
   valait pas ce que ça coûtait à l'œil : rendu tel qu'il était. */
.dalle.demi.libre { opacity: .82; }
.dalle.demi.bord-n { mask-image: linear-gradient(to top, #000 55%, transparent); }
.dalle.demi.bord-s { mask-image: linear-gradient(to bottom, #000 55%, transparent); }
.dalle.demi.bord-o { mask-image: linear-gradient(to left, #000 55%, transparent); }
.dalle.demi.bord-e { mask-image: linear-gradient(to right, #000 55%, transparent); }

/* LA POSE. Vue du dessus, une salle ne glisse pas : elle apparaît un peu plus
   grande à son emplacement et se réduit jusqu'à sa place exacte. Sans
   `transform-box`, un SVG met l'origine au coin du dessin et la mise à
   l'échelle se transforme en glissement — ce n'était pas cohérent. */
.dalle.neuve {
  transform-box: fill-box; transform-origin: center;
  animation: pose-tuile .38s cubic-bezier(.25,.9,.35,1) 1;
}
@keyframes pose-tuile {
  0%   { opacity: .2; transform: scale(1.18); }
  100% { opacity: 1;  transform: scale(1); }
}

/* La carte tirée descend un peu : elle était coupée par la barre du haut. */
.apercu-carte { top: 46%; }
#btn-menu { position: relative; z-index: 401; }
#menu hr { border: none; border-top: 1px solid var(--bord); margin: .3rem .4rem; }
#menu .entree.forte {
  background: color-mix(in srgb, var(--or, #d8a24a) 22%, transparent);
  font-weight: 600;
}
#menu .entree.bascule { display: flex; align-items: center; gap: .55rem; cursor: pointer; }
#menu .entree.bascule input { accent-color: var(--or, #d8a24a); }

/* Sans ornements : le plateau revient à ses formes nues. */
/* (les règles « sans-ornements » ont disparu avec la bascule du menu) */

/* ── Le seuil : comment on joue, avant de choisir qui ────────────────────── */
/* Le texte d un message peut contenir des retours à la ligne — la liste des
   choix en double, par exemple. Depuis qu il est ÉCHAPPÉ, un « <br> » n y
   passerait plus : c est au style de les rendre. */
.seuil-chapeau, .salon-chapeau {
  color: var(--doux); margin: 0 0 1rem; white-space: pre-line;
}
.seuil-choix {
  display: block; width: 100%; text-align: left; margin: 0 0 .7rem;
  background: var(--fond-2); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 10px; padding: .9rem 1rem;
  font: inherit; cursor: pointer;
}
.seuil-choix:hover { border-color: var(--or, #d8a24a); }
.seuil-titre { display: block; font-size: 1.05rem; font-weight: 600; margin-bottom: .2rem; }
.seuil-detail { display: block; color: var(--doux); font-size: .88rem; line-height: 1.45; }
.seuil-reprendre {
  display: block; margin: .4rem 0 0 auto; background: none; border: none;
  color: var(--texte); font: inherit; font-size: .92rem; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}

/* ── Le salon d'attente ──────────────────────────────────────────────────── */
.salon-etiquette { text-align: center; color: var(--doux); font-size: .82rem; margin: 0 0 .3rem; }
.salon-code {
  text-align: center; background: var(--fond-2); border-radius: 10px;
  padding: .9rem; font: 700 1.9rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: .18em; color: var(--or, #d8a24a);
}
.salon-joueurs { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center; margin: .9rem 0 0; }
.salon-joueur {
  border: 1px solid var(--bord); border-radius: 999px; padding: .25rem .7rem;
  font-size: .84rem; color: var(--doux);
}
.salon-joueur.present { color: var(--texte); border-color: var(--or, #d8a24a); }
.salon-pouls { display: flex; gap: .4rem; justify-content: center; margin: 1rem 0 .2rem; }
.salon-pouls i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--doux);
  animation: pouls-salon 1.4s ease-in-out 20;   /* borné : voir plus haut */
}
.salon-pouls i:nth-child(2) { animation-delay: .2s; }
.salon-pouls i:nth-child(3) { animation-delay: .4s; }
@keyframes pouls-salon { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .salon-pouls i { animation: none; } }

/* ── Le jeu en ligne ─────────────────────────────────────────────────────── */
.champ { display: block; margin: 0 0 .8rem; }
.champ span { display: block; color: var(--doux); font-size: .82rem; margin-bottom: .25rem; }
.champ input, .champ select {
  width: 100%; background: var(--fond-0, #14100c); color: var(--texte);
  border: 1px solid var(--bord); border-radius: 6px; padding: .5rem .6rem; font: inherit;
}
#ligne-code { text-transform: uppercase; letter-spacing: .16em; font-family: ui-monospace, Menlo, monospace; }
.ligne-separateur {
  text-align: center; color: var(--doux); font-size: .82rem; margin: .9rem 0;
}
.ligne-avis { color: var(--or, #d8a24a); font-size: .86rem; min-height: 1.2em; margin: .6rem 0 0; }

/* Quand ce n'est pas à nous, la carte du personnage se retire du jeu. */
body.attente-adversaire .cp-actions { opacity: .45; pointer-events: none; }
/* Une table orpheline n'est pas une attente : c'est une impasse dont il faut
   sortir. Le message est plus visible, et teinté d'alerte. */
body.partie-orpheline #zone-plateau::after {
  color: var(--rouge, #d98a72); font-weight: 600; font-size: .92rem;
  padding: 0 12px; line-height: 1.35;
}
body.attente-adversaire #zone-plateau::after {
  content: attr(data-attente); position: absolute; inset: auto 0 12px 0;
  text-align: center; color: var(--doux); font-size: .86rem; pointer-events: none;
}

/* La relecture : deux flèches et un compteur. */
.relecture-pas { text-align: center; font: 700 1.4rem/1 ui-monospace, Menlo, monospace; color: var(--or, #d8a24a); }
.relecture-quoi { text-align: center; color: var(--doux); margin-top: .4rem; font-size: .9rem; }

/* LE SABLE. Un lavis transparent, puis un grain plus dense par-dessus. Aucune
   double opacité : le voile en portait deux, ce qui donnait n'importe quoi. */
/* LE SABLE est une seconde série d'images, teintées à la conversion : rien à
   voiler, rien à filtrer, rien à recalculer. */

/* Le sable qui MONTE, et la salle que l'engrenage fait TOURNER : on voit ce
   que la pyramide vient de faire, au lieu de le découvrir après coup. */
/* Le sable qui monte : les dalles ensablées apparaissent en fondu. */
.dalle.ensablee.monte { animation: sable-monte 1.1s ease-out 1; }
@keyframes sable-monte { from { opacity: .15; } to { opacity: 1; } }

/* ET C'EST LA SALLE QUI PIVOTE. Une case ne tourne jamais sur elle-même : la
   seule rotation du jeu est celle d'une salle entière, d'un quart de tour,
   provoquée par l'engrenage. Animer les dalles une à une donnait un manège
   incompréhensible. */
.salle.pivote, .salle-murs.pivote {
  transform-box: fill-box; transform-origin: center;
  animation: salle-pivote-droite .55s cubic-bezier(.3,.8,.3,1) 1;
}

/* ET DANS LE SENS OÙ ELLE A TOURNÉ. L'animation partait toujours de la
   gauche : un quart à gauche s'animait vers la droite, la salle faisait un
   trois-quarts de tour à l'envers sous les yeux du joueur, et le dessin s'en
   trouvait brouillé. Le moteur annonce maintenant le nombre de quarts ; il y a
   donc trois animations, une par geste possible. L'image est déjà dans son
   orientation finale : on part de l'orientation PRÉCÉDENTE pour y revenir. */
.salle.pivote-q1, .salle-murs.pivote-q1 { animation-name: salle-pivote-droite; }
.salle.pivote-q2, .salle-murs.pivote-q2 { animation-name: salle-demi-tour; }
.salle.pivote-q3, .salle-murs.pivote-q3 { animation-name: salle-pivote-gauche; }

@keyframes salle-pivote-droite {
  from { transform: rotate(-90deg) scale(.9); opacity: .4; }
  to   { transform: rotate(0) scale(1); opacity: 1; }
}
@keyframes salle-pivote-gauche {
  from { transform: rotate(90deg) scale(.9); opacity: .4; }
  to   { transform: rotate(0) scale(1); opacity: 1; }
}
@keyframes salle-demi-tour {
  from { transform: rotate(-180deg) scale(.9); opacity: .4; }
  to   { transform: rotate(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .dalle.ensablee.monte, .dalle.pivote { animation: none; }
}

/* LA COUTURE. Le trait suit l'échelle du plateau : à fort agrandissement, un
   pixel de dessin en valait deux à l'écran. Le trait garde désormais son
   épaisseur réelle, quel que soit le zoom. */


/* ── Les symboles de réveil, dans les coins des salles ───────────────────── */
/* De l'or sur la pierre sombre : ils se lisent avant qu'on pose la salle. */
.symbole { fill: rgb(232, 184, 74); }
.symbole .trait { fill: none; stroke: rgb(232, 184, 74); stroke-width: 1.6; stroke-linecap: round; }
.symbole-malediction { fill: rgb(226, 150, 132); }
.symbole-effondrement { fill: rgb(216, 168, 92); }
.symbole-sable .trait { stroke: rgb(238, 206, 118); }
.symbole-rotation { fill: rgb(206, 190, 150); }


/* ── Le pincement sur le plateau ─────────────────────────────────────────── */
/* On prend la main sur les gestes qui commencent DANS la zone du plateau :
   deux doigts y agrandissent la pyramide, pas la page. Ailleurs, le navigateur
   fait comme d'habitude. */
#zone-plateau { touch-action: none; }
#zone-plateau svg.plateau { will-change: transform; }

/* ── L'effondrement : la salle se réduit et s'efface ──────────────────────── */
/* Elle disparaissait entre deux images. Elle tombe maintenant sur elle-même,
   en accélérant, avec un dernier tremblement. */
/* C'EST LA SALLE QUI TOMBE, pas ses cases une à une. */
.salle.tombe, .salle-murs.tombe, .symbole.tombe {
  transform-box: fill-box; transform-origin: center;
  animation: chute-salle .95s cubic-bezier(.45,.05,.6,.2) 1 forwards;
}
/* La salle TREMBLE d'abord — trois secousses sèches — puis s'effondre. Le
   tremblement annonce ; sans lui, la salle disparaissait sans prévenir et
   l'œil ratait l'événement. */
@keyframes chute-salle {
  0%   { opacity: 1;  transform: translate(0, 0) scale(1) rotate(0deg); }
  8%   { transform: translate(-1.5px, 1px) rotate(-.8deg); }
  16%  { transform: translate(1.5px, -1px) rotate(.8deg); }
  24%  { transform: translate(-1px, -1px) rotate(-.5deg); }
  32%  { opacity: 1;  transform: translate(0, 0) scale(1.03) rotate(-1.2deg); }
  52%  { opacity: .95; transform: scale(.97) rotate(1.4deg); }
  100% { opacity: 0;  transform: scale(.28) rotate(-4deg); }
}

/* ── Les momies qui surgissent : fondu et grossissement ───────────────────── */
.jeton.momie.neuve {
  transform-box: fill-box; transform-origin: center;
  animation: momie-surgit .48s cubic-bezier(.2,.9,.3,1.25) 1;
}
@keyframes momie-surgit {
  0%   { opacity: 0; transform: scale(.35); }
  60%  { opacity: 1; transform: scale(1.18); }
  100% { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .salle.tombe, .salle-murs.tombe, .symbole.tombe, .jeton.momie.neuve { animation: none; }
}

/* ── Le salon : copie du code, choix du personnage ───────────────────────── */
.salon-copies { display: flex; gap: .5rem; justify-content: center; margin: .6rem 0 0; }
.salon-persos { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center; margin: .3rem 0 0; }
.salon-perso {
  background: var(--fond-2); color: var(--texte); border: 1px solid var(--bord);
  border-radius: 999px; padding: .35rem .8rem; font: inherit; font-size: .86rem; cursor: pointer;
}
.salon-perso.choisi { background: var(--or); color: #14100c; border-color: var(--or); font-weight: 600; }
.salon-perso.pris { opacity: .35; cursor: not-allowed; text-decoration: line-through; }
.salon-code { font-size: 1.5rem; letter-spacing: .12em; }

/* Le salon : les personnages s'y présentent comme au lancement local. */
.salon-persos.groupe-perso { justify-content: center; margin: .4rem 0 0; }
.salon-valider { display: flex; justify-content: center; margin: .9rem 0 .2rem; }

/* ── La liaison coupée ───────────────────────────────────────────────────── */
#banniere-reseau {
  padding: 5px 12px; text-align: center; font-size: .8rem;
  background: rgba(212, 106, 90, .22); color: var(--rouge);
  border-bottom: 1px solid rgba(212, 106, 90, .4);
}
#banniere-reseau[hidden] { display: none !important; }

/* ── Le schéma : la pyramide en petit ────────────────────────────────────── */
.schema { width: 100%; max-height: 42vh; display: block; }
.schema-case { fill: #b08d5e; }
.schema-case.sable { fill: #d2b45a; }
.schema-case.muree { fill: #17130e; }
.schema-momie { fill: #8fb0c9; }
.schema-joueur { fill: var(--or); stroke: #fff; stroke-width: 1; }
.schema-joueur.tresor { stroke: var(--or); stroke-width: 1.6; }
.schema-lettre { font: 700 4.6px -apple-system, sans-serif; fill: #17130e; pointer-events: none; }
.schema-legende {
  display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; justify-content: center;
  margin: .5rem 0 0; color: var(--doux, #a9987f); font-size: .82rem;
}
.schema-legende i {
  display: inline-block; width: .7em; height: .7em; border-radius: 50%;
  margin-right: .35em; vertical-align: baseline; font-style: normal;
}
.schema-legende .lg-joueur { background: var(--or); border: 1px solid #fff; }
.schema-legende .lg-momie { background: #8fb0c9; }
.schema-legende .lg-sortie { background: #eadfc6; border-radius: 0;
  clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.schema-legende .lg-tresor { background: var(--or); border-radius: 2px; }
/* Le coffre : le but de la partie, reconnaissable d'un coup d'œil. */
.schema-coffre-haut { fill: #f0c46a; }
.schema-coffre-bas { fill: var(--or, #d8a24a); }
.schema-coffre-serrure { fill: #4a3618; }
/* La sortie : un triangle clair posé sur un disque sombre — sans ce fond, il
   se confondait avec la pierre, qui a presque sa couleur. */
.schema-sortie-fond { fill: #241c12; stroke: #eadfc6; stroke-width: .8; }
.schema-sortie { fill: #fff6e2; }
.schema-portail { fill: none; stroke: #7ec8e3; stroke-width: 1.4; stroke-dasharray: 2 2; }
/* Le schéma respire : sans marge, il touchait les bords de la fenêtre. */
.schema { margin: 1rem auto .2rem; max-width: 30rem; }

/* Pendant une relecture, le plateau ne répond plus. */
body.rejeu #zone-plateau { pointer-events: none; }
body.rejeu .cp-actions { opacity: .4; pointer-events: none; }
/* La barre de relecture : posée en bas, elle laisse le plateau entièrement
   visible — c'est lui qu'on est venu revoir. */
.rejeu-pas {
  font: 700 .95rem/1 ui-monospace, Menlo, monospace; color: var(--or);
  min-width: 4.2rem; text-align: center;
}

/* ── Les effets : le gaz, le passage secret ──────────────────────────────── */
/* Le voile vert du gaz : il monte, il stagne, il se dissipe. Un dessin, pas
   un filtre — la règle du projet vaut aussi pour les effets. */
.effet-gaz {
  fill: #5e9a4c; pointer-events: none;
  animation: gaz-voile 1.9s ease-in-out forwards;
}
@keyframes gaz-voile {
  0% { fill-opacity: 0; }
  25% { fill-opacity: .42; }
  70% { fill-opacity: .38; }
  100% { fill-opacity: 0; }
}
/* Le départ d'un passage secret s'efface en fondu. */
.effet-fantome {
  fill: #7ec8e3; pointer-events: none;
  animation: fantome-part .65s ease-out forwards;
}
@keyframes fantome-part {
  from { fill-opacity: .8; } to { fill-opacity: 0; }
}
/* Et l'arrivée apparaît de même. */
.jeton.apparition { animation: pion-apparait .6s ease-out; }
@keyframes pion-apparait {
  from { opacity: 0; } to { opacity: 1; }
}
/* Les portails s'offrent au clic : ils pulsent, sans jamais s'arrêter avant
   qu'on ait choisi — c'est une invitation, pas une décoration. */
.case.portail-cible {
  fill: #7ec8e3; fill-opacity: .5; cursor: pointer;
  /* Six battements puis l'arrêt : la garde du projet interdit les animations
     sans fin, et elle a raison — un pouls qui ne s'arrête jamais vide la
     batterie d'un téléphone posé. Six suffisent à dire « cliquez-moi ». */
  animation: portail-pulse 1.1s ease-in-out 6;
  fill-opacity: .55;
}
@keyframes portail-pulse {
  0%, 100% { fill-opacity: .3; } 50% { fill-opacity: .62; }
}

/* Revenir / Refaire tiennent sur une demi-ligne chacun : deux commandes
   jumelles, côte à côte, plutôt que deux pleines lignes. */
.cp-actions { flex-direction: row; flex-wrap: wrap; }
.cp-actions .cp-action { flex: 1 1 100%; }
.cp-actions .cp-action.demi { flex: 1 1 calc(50% - 5px); min-width: 0; }

/* ── L'écran de fin : le vainqueur, en grand ─────────────────────────────── */
.fin-vainqueur {
  display: flex; align-items: center; gap: .85rem;
  padding: .7rem .2rem 1rem; border-bottom: 1px solid #0001; margin-bottom: .9rem;
}
/* CEINTURE ET BRETELLES : toute image de ce bandeau est ronde, qu on ait pensé
   ou non à lui poser sa classe. Un portrait carré au milieu de portraits ronds
   se voit au premier coup d œil — l auteur l a signalé deux fois. */
.fin-vainqueur img {
  width: 62px; height: 62px; border-radius: 50%; object-fit: cover;
  border: 2.5px solid var(--teinte, #c8952f); flex: 0 0 auto;
}
.fin-portrait {
  width: 62px; height: 62px; border-radius: 50%; object-fit: cover;
  border: 2.5px solid var(--teinte, #c8952f); flex: 0 0 auto;
}
.fin-qui { display: flex; flex-direction: column; gap: .18rem; min-width: 0; }
.fin-qui strong { font-size: 1.22rem; color: var(--teinte, #c8952f); }
.fin-qui span { font-size: .94rem; opacity: .85; }

/* Revenir / Refaire : toujours les deux, côte à côte, l'un grisé au besoin.
   N'en montrer qu'un le laissait occuper la ligne entière. */
.cp-actions .cp-action.demi { flex: 1 1 calc(50% - 5px); min-width: 0; text-align: center; }

/* Un pion qui revient sur ses pas : un halo pâle le distingue d'un vrai
   déplacement. On défait, on ne joue pas. */
.jeton.a-reculons .jeton-rond { stroke: #cfd8e3; stroke-width: 2; opacity: .9; }

/* ── QUI PART EN EXPÉDITION (V10) ───────────────────────────────────────────
   Un joueur à la fois : les six portraits sur une ligne, le nom dessous, et
   le détail du personnage choisi juste en dessous. */
.lc-joueur {
  margin: 1.1rem 0 .5rem; font-size: .74rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--doux, #9a917f);
}
.lc-portraits { display: flex; gap: .4rem; justify-content: space-between; }
.lc-perso {
  flex: 1 1 0; min-width: 0; background: none; border: 0; padding: 0;
  display: flex; flex-direction: column; align-items: center; gap: .3rem;
  cursor: pointer; color: inherit; font: inherit;
}
.lc-perso img, .lc-vide {
  width: 100%; max-width: 58px; aspect-ratio: 1; border-radius: 50%;
  object-fit: cover; border: 2px solid transparent;
  background: var(--fond-2, #2a231a); transition: border-color .15s, transform .15s;
}
.lc-perso .lc-nom {
  font-size: .68rem; line-height: 1.15; text-align: center;
  color: var(--doux, #9a917f); overflow-wrap: anywhere;
}
.lc-perso.actif img { border-color: var(--teinte); transform: scale(1.06); }
.lc-perso.actif .lc-nom { color: var(--teinte); font-weight: 600; }
/* Un personnage déjà pris par un autre joueur : visible, mais éteint. */
.lc-perso.pris { opacity: .3; cursor: not-allowed; }

.lc-detail {
  margin-top: .9rem; padding: .8rem .85rem; border-radius: 8px;
  background: var(--fond-2, #2a231a);
  border-left: 3px solid var(--teinte, var(--or, #d8a24a));
}
.lc-chiffres { display: flex; gap: 1.4rem; margin-bottom: .6rem; }
.lc-chiffres span { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--doux, #9a917f); display: flex; align-items: baseline; gap: .3rem; }
.lc-chiffres b { font-size: 1.15rem; color: var(--teinte, var(--or, #d8a24a)); }
.lc-generale { margin: 0 0 .55rem; font-size: .92rem; line-height: 1.35; }
.lc-speciales p { margin: 0 0 .3rem; font-size: .86rem; line-height: 1.3;
  color: var(--doux, #b3a894); }
.lc-speciales span {
  display: inline-block; margin-right: .4rem; padding: .05rem .4rem;
  border-radius: 3px; background: color-mix(in srgb, var(--teinte) 22%, transparent);
  color: var(--teinte); font-size: .68rem; letter-spacing: .06em;
  text-transform: uppercase; vertical-align: 1px;
}
.lc-invite { margin: 0; color: var(--doux, #9a917f); font-size: .9rem; }
.lc-retour {
  margin-top: .7rem; background: none; border: 0; padding: .3rem 0;
  color: var(--doux, #9a917f); font: inherit; font-size: .85rem; cursor: pointer;
}

/* Le bouton du bas est CENTRÉ, pas rejeté à droite : c'est la seule action de
   l'écran, elle doit tomber sous le pouce. */
.modale-actions:has(.btn.centre) { justify-content: center; }
.btn.centre { min-width: 62%; }

/* ── CE QUI BORDE UNE SALLE SUIT L'UNIVERS ───────────────────────────────────
   Cette bande cerne chaque salle : elle dit « au-delà, rien ». Elle était en
   NOIR PUR, écrit en dur — et comme elle se dessine PAR-DESSUS l'image cuite,
   elle recouvrait le vert des murs. Les images étaient justes ; c'est ce voile
   qui les noircissait, et c'est lui que l'auteur voyait.

   Elle devient une couleur de matière, comme le reste. */
.mur-dehors { fill: var(--m-mur-dehors); }

/* ═══════════════════════════════════════════════════════════════════════════
   LE GRAND ÉCRAN (V10)

   Le jeu a été conçu pour un téléphone tenu debout, et cela restera son
   premier public. Mais sur un ordinateur, la même mise en page laissait le
   plateau au centre d'un désert pendant que la colonne de droite, figée à 320
   points, comprimait la carte du personnage et le journal l'un sur l'autre.

   Au-delà de 1100 points, on passe donc à TROIS COLONNES : le personnage à
   gauche — c'est là qu'on décide —, le labyrinthe au centre — c'est là qu'on
   regarde —, l'expédition et le journal à droite — c'est là qu'on vérifie.
   Rien ne bouge dans le HTML : la colonne de droite se dissout (`display:
   contents`) et ses trois enfants prennent place directement dans la grille.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 1100px) {
  #principal {
    grid-template-columns: minmax(300px, 340px) 1fr minmax(300px, 360px);
    grid-template-areas: 'perso plateau suivi';
    gap: 0;
  }
  /* La colonne s'efface : ses enfants deviennent ceux de la grille. */
  #colonne { display: contents; }

  #carte-perso {
    grid-area: perso;
    border-right: 1px solid var(--bord);
    /* LA TEINTE DU PERSONNAGE SURVIT AU PASSAGE À GAUCHE. Un `background`
       uni écrasait ici le fond teinté que la fiche porte en portrait : sur
       grand écran, on ne savait plus d'un coup d'œil qui avait la main. Le
       dégradé descend depuis la teinte vers le fond de la colonne. */
    background: linear-gradient(
      to bottom,
      color-mix(in srgb, var(--teinte, var(--or)) 12%, var(--carte)) 0,
      var(--carte) 22rem);
    overflow-y: auto; min-height: 0; padding-bottom: 1.5rem;
  }
  #zone-plateau { grid-area: plateau; }

  /* L'expédition et le journal s'empilent à droite, le journal prenant tout
     ce qui reste : c'est lui qui grandit, et c'est lui qu'on relit. */
  #colonne > .section {
    grid-area: suivi;
    border-left: 1px solid var(--bord); background: var(--carte);
  }
  #colonne > .section:not(.section-journal) {
    align-self: start; border-bottom: 1px solid var(--bord);
  }
  #colonne > .section-journal {
    align-self: stretch; min-height: 0; overflow: hidden;
    display: flex; flex-direction: column;
    margin-top: 0;
  }
  #colonne > .section-journal .journal { flex: 1; min-height: 0; overflow-y: auto; }

  /* Deux sections dans la même case de grille : on les empile à la main. */
  #principal { grid-template-rows: auto 1fr; }
  #carte-perso, #zone-plateau { grid-row: 1 / span 2; }
  #colonne > .section:not(.section-journal) { grid-row: 1; }
  #colonne > .section-journal { grid-row: 2; }

  /* À la souris, on vise mieux : on peut resserrer sans rien perdre. */
  .cp-action { padding: 7px 10px; }
  .section { padding: 14px 16px; }

  /* Les fenêtres respirent : elles étaient calibrées pour 390 points. */
  #modale { max-width: 640px; }
  .lc-perso img, .lc-vide { max-width: 78px; }
  .lc-portraits { gap: .7rem; }
  .lc-detail { padding: 1rem 1.1rem; }
  .btn.centre { min-width: 40%; }
}

/* Très grands écrans : le plateau ne gagne rien à s'étirer sans fin, mais les
   colonnes latérales, si — elles portent du texte. */
@media (min-width: 1600px) {
  #principal { grid-template-columns: 380px 1fr 420px; }
  #modale { max-width: 720px; }
}

/* ── LE SECOURS : les carrés à contour clair des premières versions ─────────
   Quand une salle n'a pas été cuite en image, on la TRACE plutôt que de
   recharger vingt-cinq textures : un seul chemin, aucun décodage. Le rendu est
   volontairement plus sobre que la pierre — on voit ainsi tout de suite
   qu'une salle manque à la cuisson. */
.salle-tracee {
  fill: #b08d5e; stroke: #e6c98a; stroke-width: 1; stroke-linejoin: round;
}
.salle-tracee.ensablee { fill: #cbab63; stroke: #f0dca8; }

/* Le sable qui a envahi une salle : un voile doré posé sur l'image cuite.
   Un aplat, pas un filtre — le navigateur n'a rien à recomposer. */
/* Le sable qui a envahi une salle : un voile doré posé sur la pierre, SOUS les
   murs — la couche des murs vient après, et le sable ne déteint donc pas sur
   la maçonnerie. Un aplat, pas un filtre. */
/* PLUS FRANC QU'AVANT. À .38 sous les murs, l'auteur ne reconnaissait pas une
   salle ensablée : il croyait le piège sans effet alors qu'il avait frappé.
   Un piège qu'on ne voit pas est un piège qui n'existe pas. */
.voile-sable { fill: #e0b348; fill-opacity: .55; pointer-events: none; }
/* Il MONTE, il n'apparaît pas : une seconde et demie, du rien à sa teinte,
   avec un léger dépassement au sommet — le temps de voir la salle changer. */
.voile-sable.monte { animation: sable-monte 1.5s cubic-bezier(.35,.7,.4,1) both; }
@keyframes sable-monte {
  0% { fill-opacity: 0; }
  70% { fill-opacity: .66; }
  100% { fill-opacity: .55; }
}

/* Le plan se tire à la souris : le curseur le dit. */
#zone-plateau { cursor: grab; }
#zone-plateau.en-tirage { cursor: grabbing; }
#zone-plateau.en-tirage * { pointer-events: none; }

/* ── Sur grand écran, la proposition de salle mérite sa place ─────────────── */
@media (min-width: 1100px) {
  /* À 190 points sur un écran de 1900, la vignette était un timbre-poste : on
     y décide pourtant d'une rotation et d'un emplacement. */
  .apercu-tuile { width: 300px; padding: 15px 17px; bottom: 24px; }
  .apercu-titre { font-size: 16px; }
  .apercu-sous { font-size: 12.5px; margin-bottom: 11px; }
  .apercu-outils .btn { font-size: 13px; padding: 7px 12px; }
}

/* ── Les coins libres s'arrondissent ────────────────────────────────────────
   Les images de salles sont cuites à angles droits — le plus simple, et le
   plus juste quand deux salles se touchent. Sur le POURTOUR de la pyramide, en
   revanche, la pierre paraissait découpée au couteau. Un coin dont les deux
   côtés n'ont pas de voisine s'adoucit donc, en CSS, sans recuire quoi que ce
   soit. */
/* Les coins libres sont arrondis par DÉCOUPE (voir plateau.js) : ni
   border-radius ni rx ne s'appliquent à une image SVG. */

/* Un bouton qui porte une miniature : la forme à gauche, le texte à droite. */
.cp-action.avec-vignette {
  display: flex; align-items: center; gap: 10px; text-align: left;
}
.cp-action.avec-vignette > svg {
  flex: 0 0 auto; border-radius: 4px; background: #0a0805;
}
.cp-action.avec-vignette > span { display: block; }

/* La case derrière un mur, offerte au Pilleur : une brèche qu'on devine. */
/* LA CASE OÙ L'ON PEUT PASSER EST VERTE, comme toute destination du jeu. Elle
   était ocre, de la couleur du mur qu'on franchit : le joueur ne comprenait
   pas qu'un déplacement était offert. Le pointillé clair la distingue d'un pas
   ordinaire — on passe en force, pas par le couloir. */
.case.percee-cible {
  fill: #5d9b52; fill-opacity: .62; cursor: pointer;
  stroke: #cfe8b8; stroke-width: 1.4; stroke-dasharray: 3 2;
  animation: percee-pulse 1.1s ease-in-out 6;
}
@keyframes percee-pulse { 0%,100% { fill-opacity: .42; } 50% { fill-opacity: .72; } }

/* Le Pilleur choisit ses salles à ensabler : celles qu'il peut encore prendre
   s'éclairent en sable, celles qu'il a déjà prises restent marquées. */
.case.ensable-cible {
  fill: #d9b45c; fill-opacity: .34; cursor: pointer;
  animation: ensable-pulse 1.2s ease-in-out 6;
}
.case.ensable-prise { fill: #d9b45c; fill-opacity: .62; }
@keyframes ensable-pulse { 0%,100% { fill-opacity: .22; } 50% { fill-opacity: .44; } }

/* Les scarabées se répandent : un cercle rouge dit jusqu'où, un signe marque
   chaque salle touchée. Sans cela, on passait son tour sans savoir pourquoi. */
/* L'essaim : chaque case porte SA force, transmise par --essaim. La case du
   fouilleur est la plus rouge ; les suivantes pâlissent avec la distance. */
.couche-scarabees { pointer-events: none; }
.effet-scarabees {
  /* Force de l'essaim sur CETTE case : posée par le plateau, la plus haute sur
     la case du fouilleur. Une valeur de repli pour qui n'en reçoit pas. */
  --essaim: .4;
  fill: #c0392b; fill-opacity: 0; pointer-events: none;
  animation: scarabees-onde 2.4s ease-out forwards;
}
@keyframes scarabees-onde {
  0%   { fill-opacity: 0; }
  14%  { fill-opacity: var(--essaim, .4); }
  70%  { fill-opacity: calc(var(--essaim, .4) * .8); }
  100% { fill-opacity: 0; }
}
/* LE SCARABÉE EST DESSINÉ, PAS ÉCRIT. C'était un caractère typographique —
   aucune police n'est garantie de le porter, et un carré vide au milieu de
   l'essaim ressemble à une panne. Il s'anime avec l'onde, comme les cases. */
.effet-scarabee-marque {
  pointer-events: none; opacity: 0;
  animation: scarabees-nuee 2.6s ease-out forwards;
}
.effet-scarabee-marque .corps { fill: #2a1a14; }
.effet-scarabee-marque .elytres,
.effet-scarabee-marque .patte { stroke: #6b4a3a; stroke-width: 1.1; stroke-linecap: round; }
@keyframes scarabees-nuee {
  0%   { opacity: 0; }
  14%  { opacity: .95; }
  70%  { opacity: .8; }
  100% { opacity: 0; }
}

/* Une demi-case qui bute sur un mur n'est pas un passage : on la ternit pour
   qu'elle cesse d'inviter. Assez sombre pour se distinguer, assez claire pour
   qu'on voie qu'il y a de la pierre. */
/* ── UNE DEMI-CASE MORTE N'EST PAS UN TROU NOIR ────────────────────────────
   Elle marque une jonction qui ne mène nulle part. Le noir plein à 46 % la
   rendait plus sombre que le mur lui-même — en jungle, une tache d'encre au
   milieu de la végétation. On emploie la même matière que le dehors : elle
   s'éteint sans percer. */
.demi-morte { fill: var(--m-mur-dehors); fill-opacity: .58; pointer-events: none; }

/* ── LE BAS DE L'ÉCRAN, UNE FOIS L'APPLICATION INSTALLÉE ────────────────────
   La barre d'accueil d'iOS mange une trentaine de points. On les rend au
   dernier bloc visible — le panneau du personnage en portrait, la colonne en
   paysage — plutôt que de les retirer à toute la page. Le plateau y gagne
   autant de hauteur, et le panneau cesse d'être tronqué. */
@media (max-width: 820px) and (orientation: portrait) {
  #carte-perso { padding-bottom: max(10px, env(safe-area-inset-bottom, 0px)); }
  body[data-vue="journal"] #colonne { padding-bottom: max(10px, env(safe-area-inset-bottom, 0px)); }
}
@media (min-width: 821px), (orientation: landscape) {
  #colonne { padding-bottom: env(safe-area-inset-bottom, 0px); }
}

/* ── LA LOUPE : revenir à la vue d'ensemble ─────────────────────────────────
   En bas à droite du plan, comme sur toutes les cartes en ligne. Discrète tant
   qu'elle ne sert à rien, franche dès qu'on s'est fabriqué une vue à soi. */
.loupe-plateau {
  position: absolute; right: 14px; bottom: 14px; z-index: 12;
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 20px; line-height: 1; cursor: pointer;
  background: color-mix(in srgb, var(--carte) 92%, transparent);
  color: var(--faible); border: 1px solid var(--bord);
  opacity: 0; pointer-events: none;
  transition: opacity .18s, color .18s, border-color .18s;
}
.loupe-plateau.utile {
  opacity: 1; pointer-events: auto;
  color: var(--or); border-color: var(--or);
  box-shadow: 0 6px 18px rgb(0 0 0 / .35);
}
.loupe-plateau:active { transform: scale(.94); }


/* ── LE MENU AU-DESSUS DU MASQUE SOMBRE ─────────────────────────────────────
   Le bouton flotte déjà par-dessus la modale, mais il gardait ses couleurs de
   fond clair : sombre sur sombre, on le croyait dessous. Il s'habille pour le
   masque tant qu'une modale est ouverte. */
body.modale-ouverte #btn-menu {
  color: #fff;
  border-color: rgb(255 255 255 / .55);
  background: rgb(255 255 255 / .10);
}
body.modale-ouverte #btn-menu:hover { background: rgb(255 255 255 / .18); }

/* ── LA FOSSE : un vide, pas un mur ─────────────────────────────────────────
   Troisième état d'une case, à côté du couloir et du mur. On n'y marche pas,
   mais elle ne se lit pas comme de la pierre : plus noire, et creusée d'une
   ombre portée qui suggère la profondeur. */
.fosse { fill: #14100b; }
[data-theme="clair"] .fosse { fill: #241c12; }

/* La lettre d'un pion ne doit jamais voler le clic destiné au pion. */
.jeton text, .momie text { pointer-events: none; }

/* Choisir les salles à faire pivoter : tout le plateau se propose, sobrement. */
.case.rotation-cible {
  fill: #7a86b8; fill-opacity: .30; cursor: pointer;
}
.case.rotation-cible:hover { fill-opacity: .48; }

/* Les petites victoires, à la fin : des visages, pas une phrase. */
.fin-petites { margin: 1rem 0 .4rem; }
.fin-petites-titre {
  font-size: .78rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faible); margin: 0 0 .5rem;
}
.fin-petite {
  display: inline-flex; align-items: center; gap: .45rem;
  margin: 0 .7rem .5rem 0; font-size: .92rem;
}
/* ── LE PORTRAIT PORTE LA COULEUR DE SON PERSONNAGE ──────────────────────────
   Il était cerné de `--bord`, le gris de toutes les bordures : deux échappés
   se ressemblaient donc, et l'on ne reconnaissait pas qui avait réussi.

   `--teinte` est posée sur chaque `.fin-petite` par l'écran. Le trait passe à
   deux pixels : à cette taille, un pixel ne se voit pas. */
.fin-petite img {
  width: 2rem; height: 2rem; border-radius: 50%;
  border: 2px solid var(--teinte, var(--bord)); object-fit: cover;
  display: block; flex: none;
}
/* L'initiale, quand le personnage n'a pas d'image : même rond, même trait. */
.fin-petite .fin-initiale {
  width: 2rem; height: 2rem; border-radius: 50%;
  border: 2px solid var(--teinte, var(--bord)); flex: none;
  display: inline-grid; place-items: center;
  background: color-mix(in srgb, var(--teinte, var(--bord)) 26%, var(--creux));
  font: 700 .85rem/1 var(--mono); color: var(--texte);
}

/* Ce que la Momie a écarté : une gardienne de moins en face, et l'on dit
   laquelle. Le pion qu'elle y laisse s'efface en même temps. */
.gard-ecartee {
  margin: .5rem 0 0; padding: .5rem .7rem; border-radius: 6px;
  background: color-mix(in srgb, var(--teinte, var(--or)) 12%, transparent);
  border-left: 3px solid var(--teinte, var(--or));
  font-size: .9rem; color: var(--texte);
  animation: ecartee-parait .6s ease-out both;
}
@keyframes ecartee-parait {
  from { opacity: 0; transform: scale(.94); }
  to   { opacity: 1; transform: scale(1); }
}

/* CELUI QUI SORT S'EFFACE, IL NE DISPARAÎT PAS D'UN COUP. Deux secondes : le
   temps de voir qui vient de s'en tirer, et par où. Ensuite la case est rendue
   aux autres — sans quoi le premier échappé condamnait les suivants. */
.jeton.sen-va {
  animation: jeton-sen-va 2s ease-in forwards;
  pointer-events: none;
}
@keyframes jeton-sen-va {
  0%   { opacity: 1; }
  55%  { opacity: .75; }
  100% { opacity: 0; }
}

/* LE PORTAIL APPELÉ BAT ET GRANDIT. La case s'éclaircissait déjà, mais l'étoile
   du portail est dessinée par-dessus : c'est elle qu'on regarde, et elle restait
   immobile. Six battements, puis l'arrêt — la garde du projet interdit les
   animations sans fin, et un pouls perpétuel vide la batterie d'un téléphone
   posé sur la table. */
.repere.portail.appele {
  transform-box: fill-box; transform-origin: center;
  animation: portail-appel 1.1s ease-in-out 6;
}
.repere.portail.appele polygon { stroke: #7ec8e3; stroke-width: 1.5; }
@keyframes portail-appel {
  0%, 100% { transform: scale(1);    opacity: .85; }
  50%      { transform: scale(1.18); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .repere.portail.appele { animation: none; }
}

/* LE SABLIER DE CELUI QUI PASSE SON TOUR. Les scarabées frappent, et au tour
   suivant un joueur était sauté sans explication. Le sablier le dit sur le
   plateau, là où l'on regarde. */
.jeton-sablier .fond { fill: #1d1710; opacity: .85; }
.jeton-sablier .verre { fill: #d8a24a; }

/* LES MARCHES DU PUITS DESCENDENT DANS LE GOUFFRE. La margelle était posée au
   centre de la salle — c'est-à-dire sur un MUR, puisque le puits est un couloir
   en U — et les marches vivaient une case plus bas, comme deux dessins sans
   rapport. Elles partagent maintenant la case, et se détachent sur le bleu
   sombre du gouffre. */
.repere.marches.au-puits rect { fill: #f0e0b8; opacity: 1; }

/* LA CARTE QUI VIENT D'ARRIVER SE DÉSIGNE. Avec six cartes en main et l'ordre
   d'en jeter une, rien ne disait laquelle on venait de trouver — c'est pourtant
   la première question du joueur, et celle qu'il peut jouer plutôt que jeter. */
.cp-carte.trouvee { border-color: var(--or); box-shadow: 0 0 0 1px var(--or) inset; }
.cp-neuve {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  background: var(--or); color: #1d1710; font: 600 10px/1.5 inherit;
  text-transform: lowercase; vertical-align: middle;
}

/* LE NUMÉRO DE LA FOUILLE. Le Touriste tire quatre cartes d'affilée : sans
   compteur, on ne sait pas si l'on regarde la première ou la dernière, et l'on
   croit n'en avoir tiré qu'une. Discret, en haut de la carte, hors du bandeau
   qui porte déjà le nom et l'effet. */
.apercu-carte .carte-compte {
  position: absolute; top: 8px; left: 0; right: 0;
  text-align: center; font: 600 12px/1 var(--mono, monospace);
  letter-spacing: .08em; color: var(--or); opacity: .9;
  text-shadow: 0 1px 3px rgba(0,0,0,.7); pointer-events: none;
}

/* LE SABLE SE VOIT SUR LA FICHE. Le déplacement passait de 4 à 1 sans un mot :
   on croyait à un défaut. La valeur normale reste visible, barrée, à côté de
   celle que le sable impose. */
.cp-stats .cp-barre { opacity: .55; text-decoration: line-through; margin-right: 5px; font-weight: 600; }
.cp-stats .cp-sable { color: var(--or); font-weight: 800; }

/* L'ÉCHELLE DE LA MOMIE. Ses valeurs changent avec le nombre de momies
   portées, mais elle commence à trois et ne peut se délester qu'en phase 2 :
   pendant toute l'exploration elle lisait « 1 » sans savoir pourquoi. Les trois
   paliers se lisent d'un coup d'œil, le sien en relief. */
.cp-echelle { display: flex; gap: 5px; margin: 0 0 10px; }
.cp-cran {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 5px 2px; border-radius: 6px; background: var(--carte);
  border: 1px dashed var(--bord); font-size: 10px; color: var(--faible);
}
.cp-cran b { font: 700 13px/1 var(--mono); }
.cp-cran em { font-style: normal; font-size: 9px; letter-spacing: .02em; opacity: .8; }
.cp-cran.ici {
  background: #4a3550; border: 1px solid #a08ac0; color: #e8dcf2;
}
.cp-cran.ici b { color: #fff; }

/* PENDANT LE TOUR DE L'AUTRE, ON NE MONTRE PAS SA FICHE. Masquer son inventaire
   ne suffisait pas : la fiche affichait SON nom et SON portrait avec, en
   dessous, VOTRE main — on croyait lire son inventaire à lui. Un bandeau
   d'attente, et rien d'autre. */
.cp-attente {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 12px; border-radius: 10px;
  background: var(--creux); border: 1px dashed var(--bord);
}
/* LE PORTRAIT RESTE ROND. Trois règles d'écran étroit réduisent `.cp-portrait`
   à 36, 34 puis 30 pixels ; ma règle du bandeau en imposait 46 EN LARGEUR
   seulement, et la hauteur suivait celle du petit écran : le rond devenait un
   ovale en portrait sur téléphone.
   On ne fixe donc plus de taille ici — on laisse celle de l'écran s'appliquer —
   et `aspect-ratio` garantit le cercle quoi qu'il arrive. */
.cp-attente .cp-portrait { flex: none; aspect-ratio: 1; }
.cp-portrait { aspect-ratio: 1; }
.cp-attente-texte { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cp-attente-qui { font: 650 15px/1.2 inherit; color: var(--texte); }
.cp-attente-quoi { font-size: 13px; color: var(--faible); }

/* CE QUE CHACUN APPORTE, EN CHIFFRES. On lisait le nom des cartes engagées sans
   savoir ce qu'elles pesaient — or c'est le total qui décide du combat, et au
   cas C on ajuste sa mise d'après celle des autres. */
.gard-proposition .appoint { color: var(--or); margin-left: 4px; }
.gard-bilan {
  margin: 8px 0 0; padding-top: 8px; border-top: 1px solid var(--bord);
  font-size: 13px; color: var(--faible); text-align: center;
}
.gard-bilan b { color: var(--texte); }

/* ── LE SALON DES PARTIES OUVERTES ────────────────────────────────────────────
   On ne pouvait rejoindre qu'avec un code reçu par message. La liste montre
   celles dont le créateur a voulu qu'on les voie : qui attend, combien de
   places restent, depuis quand. */
.salon-liste { margin-top: 14px; }
.salon-titre {
  margin: 0 0 8px; font: 650 13px/1.2 inherit; color: var(--faible);
  text-transform: uppercase; letter-spacing: .06em;
}
.salon-note { margin: 6px 0; font-size: 13px; color: var(--faible); }
.salon-verrouillees { padding-top: 8px; border-top: 1px solid var(--bord); }
.salon-partie {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; margin-bottom: 6px; padding: 10px 12px;
  border-radius: 8px; border: 1px solid var(--bord); background: var(--carte);
  color: var(--texte); font: inherit; text-align: left; cursor: pointer;
}
.salon-partie:hover { border-color: var(--or); }
.salon-hote { font-weight: 650; }
.salon-infos { display: flex; gap: 10px; font-size: 12px; color: var(--faible); }
.salon-libres { color: var(--or); }
/* ── UNE CASE À COCHER SE LIT EN LIGNE ─────────────────────────────────────
   `.champ` empile son libellé au-dessus de son champ, et `.champ span` est en
   `display: block` — le texte prenait donc toute la largeur, la case restait
   seule sur sa ligne, et l'explication partait au loin. C'est ce que montrait
   la capture de l'auteur.
   Passer le conteneur en ligne ne suffisait pas : il fallait aussi rendre au
   texte sa place DANS la ligne, sans la marge de dessous héritée de `.champ`. */
.champ.champ-case,
.champ-case { display: flex; flex-direction: row; align-items: flex-start; gap: 9px; }
.champ-case > span { display: block; flex: 1; margin: 0; color: var(--texte); font-size: .92rem; }
.champ-case input[type="checkbox"] {
  flex: none; width: 18px; height: 18px; margin: 2px 0 0; accent-color: var(--or, #d8a24a);
}
.champ-case small { display: block; margin-top: 3px; font-size: 11px;
  color: var(--faible); line-height: 1.35; }

/* L'HÔTE PEUT ÉCARTER QUI IL N'ATTENDAIT PAS. Une croix discrète sur chaque
   joueur assis, visible du seul créateur, et seulement avant le départ. */
.salon-joueur { position: relative; }
.salon-ecarter {
  margin-left: 6px; padding: 0 5px; border: 0; border-radius: 4px;
  background: transparent; color: var(--faible);
  font: 700 14px/1 var(--mono); cursor: pointer;
}
.salon-ecarter:hover { background: #6a2b28; color: #fff; }

/* ── L'ACCUEIL ET SES RETOURS ────────────────────────────────────────────────
   Aucune modale n'avait de bouton retour : on entrait dans un écran et le seul
   moyen d'en sortir était de faire le choix proposé. Sur téléphone, sans
   échappement au clavier, c'était un cul-de-sac. */
#modale h2 { position: relative; padding-right: 38px; }
.modale-retour {
  position: absolute; top: 50%; right: 0; transform: translateY(-50%);
  width: 34px; height: 34px; border: 0; border-radius: 8px;
  background: var(--creux); color: var(--texte);
  font: 400 19px/1 var(--mono); cursor: pointer;
}
.modale-retour:hover { background: var(--bord); }

.seuil-reprise { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.seuil-encours { border-color: var(--or); }
.seuil-abandon {
  align-self: flex-end; padding: 4px 10px; border: 0; border-radius: 6px;
  background: transparent; color: var(--faible); font-size: 12px; cursor: pointer;
}
.seuil-abandon:hover { color: #e2a09a; text-decoration: underline; }
.seuil-notif { margin-top: 10px; }
.seuil-notif .seuil-titre::before { content: '\1F514  '; }

/* UN CHEMIN DE RETOUR SUR CHAQUE PAGE. Trois pages annexes n'offraient aucun
   moyen de revenir au jeu : il fallait le bouton « précédent » du navigateur,
   qui n'existe pas toujours sur un site installé sur l'écran d'accueil. */
.retour-jeu {
  display: inline-block; margin-bottom: 10px; padding: 5px 11px;
  border-radius: 7px; border: 1px solid var(--bord, #3a3128);
  background: var(--creux, #221c14); color: var(--texte, #e8dcc8);
  font-size: 13px; text-decoration: none;
}
.retour-jeu:hover { border-color: var(--or, #d7a94b); }

/* ── ON DOIT VOIR OÙ L'ON EST ────────────────────────────────────────────────
   Le projet n'avait AUCUNE règle de focus : ni `:focus-visible`, ni `outline`.
   Au clavier, rien n'indiquait le bouton courant — on avançait à l'aveugle
   dans une modale, dans le salon, dans l'éditeur. Et le navigateur, lui, avait
   son propre anneau bleu, effacé par les fonds sombres.

   `:focus-visible` plutôt que `:focus` : l'anneau n'apparaît qu'à la
   navigation clavier, jamais après un clic à la souris ou au doigt. On ne
   gêne donc personne, et l'on rend le jeu praticable sans écran tactile. */
:focus-visible {
  outline: 2px solid var(--or, #d8a24a);
  outline-offset: 2px;
  border-radius: 4px;
}
/* Sur le plateau, l'anneau doit se voir sur la pierre comme sur le noir. */
svg.plateau :focus-visible {
  outline: 3px solid var(--or, #d8a24a);
  outline-offset: 1px;
}
/* Un bouton qu'on ne peut pas atteindre au clavier ne se signale pas : on le
   dit à qui lit l'écran plutôt que de le laisser muet. */
[aria-disabled="true"] { cursor: default; }

/* SAUTER AU CONTENU. Sur les pages longues — la règle, le projet —, la barre
   et le sommaire s'interposent entre le clavier et le texte. Ce lien ne se
   montre qu'au premier coup de tabulation. */
.saut-contenu {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: 10px 16px; border-radius: 0 0 8px 0;
  background: var(--or, #d8a24a); color: #1a1408; font-weight: 650;
}
.saut-contenu:focus { left: 0; }

/* ── LA PYRAMIDE SE REFERME : ON COMPTE ──────────────────────────────────────
   Dès qu'un joueur s'échappe, les autres n'ont plus qu'un nombre d'actions
   compté. Sans compteur visible, on ne sait pas s'il faut courir vers la sortie
   ou tenter le trésor — et c'est justement le choix que la règle veut poser. */
.bandeau-fermeture {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-radius: 8px;
  background: color-mix(in srgb, var(--rouge) 16%, var(--creux));
  border: 1px solid color-mix(in srgb, var(--rouge) 45%, transparent);
}
.ferm-compte {
  font: 800 22px/1 var(--mono); color: var(--rouge);
  min-width: 1.4em; text-align: center;
}
.ferm-texte { font-size: 13px; color: var(--texte); }
/* PAS D'ANIMATION SANS FIN : elle tiendrait le compositeur éveillé, et sur
   téléphone cela se paie en batterie. Le battement dit l'urgence puis s'arrête
   — six pulsations suffisent à attirer l'œil, et le chiffre reste rouge. */
.bandeau-fermeture.urgent { animation: ferm-battement 1.1s ease-in-out 6; }
@keyframes ferm-battement {
  0%, 100% { border-color: color-mix(in srgb, var(--rouge) 45%, transparent); }
  50%      { border-color: var(--rouge); }
}
@media (prefers-reduced-motion: reduce) { .bandeau-fermeture.urgent { animation: none; } }

/* ── « À VOUS DE JOUER » ─────────────────────────────────────────────────────
   Quand la main revient, pas de portrait ni de nom : la fiche juste dessous les
   porte déjà, et les répéter n'apprend rien. Trois mots qui respirent
   doucement — assez pour attirer l'œil, jamais assez pour agiter l'écran. */
.cp-mon-tour {
  padding: 10px 12px; margin-bottom: 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--or) 14%, var(--creux));
  border: 1px solid color-mix(in srgb, var(--or) 40%, transparent);
  font: 700 19px/1.2 inherit; letter-spacing: .01em;
  color: var(--or); text-align: center;
  animation: mon-tour-souffle 2.4s ease-in-out 8;
}
@keyframes mon-tour-souffle {
  0%, 100% { opacity: .82; }
  50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .cp-mon-tour { animation: none; } }

/* ── UNE PAGE DOCUMENTAIRE DOIT DÉFILER ──────────────────────────────────────
   La feuille commune enferme le corps — `height: 100%` et `overflow: hidden` —
   parce que le plateau, lui, ne défile jamais : il tient dans l'écran et se
   recadre au doigt.

   Depuis que les pages annexes chargent cette feuille (pour que leur barre et
   leur menu soient habillés), elles héritaient de cette prison : la règle et le
   matériel s'arrêtaient au premier écran, sans qu'on puisse descendre.

   Plutôt que de retirer une règle dont le jeu a besoin, on marque les pages qui
   se lisent : `<body data-page="document">`. */
body[data-page="document"] {
  height: auto;
  min-height: 100%;
  overflow: visible;
  display: block;
}
html:has(body[data-page="document"]) { height: auto; }

/* ── LA BARRE SUIT LA PAGE QUI SE LIT ────────────────────────────────────────
   `#barre` est bâtie pour le jeu : un corps en `flex`, dont elle est le premier
   enfant qui ne grandit pas. Sur une page documentaire, le corps repasse en
   `block` — la barre perdait sa mise en page, s'affichait comme deux mots nus
   en haut à gauche, et son menu, posé en `position: fixed` par rapport à elle,
   s'ouvrait hors de l'écran.

   On la rend collante : elle reste en tête pendant qu'on descend, ce qui vaut
   mieux sur une page longue que de la laisser filer avec le texte. */
body[data-page="document"] #barre {
  position: sticky;
  top: 0;
  z-index: 50;
  width: 100%;
}
/* Le menu se cale sous la barre, quelle que soit la page. */
body[data-page="document"] #menu { top: 52px; }

/* ── UN TABLEAU LARGE DOIT POUVOIR DÉFILER ───────────────────────────────────
   Les pages documentaires portent des tableaux à cinq ou six colonnes — le
   matériel, les cartes, les personnages. Sur un téléphone de 390 points, ils
   débordent : la dernière colonne sort de l'écran et rien ne permet d'y aller.

   La classe `.defilant` existait, employée dans `maj.html`, mais elle n'était
   stylée QUE dans `stats.html` : ailleurs elle ne faisait rien. Une classe qui
   ne fait rien est pire qu'une classe absente — on la pose en croyant le
   problème réglé.

   On la définit ici, une fois, pour toutes les pages qui chargent cette
   feuille. Et l'on donne le même comportement à TOUT tableau d'une page
   documentaire, même sans conteneur : c'est plus sûr que d'espérer que chacun
   pense à l'envelopper. */
.defilant { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.defilant table { min-width: max-content; }

body[data-page="document"] table {
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}
/* Un tableau en `display: block` perd la largeur automatique de ses colonnes :
   on la lui rend par une largeur minimale au contenu. */
body[data-page="document"] table > tbody,
body[data-page="document"] table > thead { display: table; width: 100%; min-width: max-content; }

/* La barre de défilement doit se voir, sinon personne ne devine qu'on peut
   pousser le tableau. Discrète, mais présente. */
.defilant::-webkit-scrollbar,
body[data-page="document"] table::-webkit-scrollbar { height: 6px; }
.defilant::-webkit-scrollbar-thumb,
body[data-page="document"] table::-webkit-scrollbar-thumb {
  background: var(--bord); border-radius: 3px;
}

/* ── LE PERSONNAGE À VENIR ───────────────────────────────────────────────────
   L'extension amènera un sixième personnage. Il n'existe pas encore : on le
   montre sans portrait et hors d'atteinte, pour dire ce qui vient sans laisser
   croire qu'on peut le prendre. */
.lc-perso.a-venir { opacity: .45; cursor: default; border-style: dashed; }
.lc-perso.a-venir .lc-vide {
  background: repeating-linear-gradient(45deg,
    var(--creux) 0 6px, transparent 6px 12px);
}
.lc-bientot {
  display: block; font-size: 9px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--faible); margin-top: 2px;
}

/* ── LE COFFRE ET SES CUBES ──────────────────────────────────────────────────
   La salle de l'extension s'affichait nue : aucun coffre, aucun cube. On posait
   la tuile, on marchait dessus, et rien ne disait qu'il y avait quelque chose à
   ouvrir. La règle existait dans le moteur ; le joueur n'en voyait pas trace. */
.coffre-cuve      { fill: var(--m-coffre); stroke: #3a2710; stroke-width: 1.2; }
.coffre-couvercle { fill: var(--m-coffre-haut); stroke: #3a2710; stroke-width: 1.2; }
.coffre-serrure   { fill: #d8a24a; stroke: #3a2710; stroke-width: .8; }
.coffre-cube      { fill: #e8c257; stroke: #8a6a1e; stroke-width: .8; }
/* UN CUBE PRIS RESTE À SA PLACE, MAIS S'ÉTEINT. On garde les cinq carrés
   toujours visibles : c'est la couleur qui dit ce qu'il reste, jamais la
   position. Un dessin qui ne bouge pas ne peut pas se tromper de place. */
.coffre-cube.pris { fill: var(--pierre); stroke: var(--bord); opacity: .55; }
[data-theme="clair"] .coffre-cuve      { fill: #8a6128; }
[data-theme="clair"] .coffre-couvercle { fill: #a87c34; }

/* Le second nom d'un personnage — « Officiellement guide local » pour le
   Pilleur. Il figure dans la règle papier et n'apparaissait nulle part. */
.cp-sous {
  display: block; font-size: 10.5px; line-height: 1.3;
  color: var(--faible); font-style: italic; margin-top: 1px;
}

/* ── DEUX AXES INDÉPENDANTS : LE THÈME ET L'UNIVERS ──────────────────────────
   `data-theme` décide du clair et du sombre — c'est le confort de lecture.
   `data-univers` décide de la CIVILISATION — c'est le décor du jeu.

   Les deux ne doivent pas se mêler : on veut la jungle en clair comme en
   sombre, et l'Égypte de même. Quatre combinaisons, donc, et non deux thèmes
   qui se remplaceraient.

   L'univers ne redéfinit QUE les couleurs de matière — la pierre, l'or, le
   sable. Les couleurs de fonction — le rouge d'un piège, le vert d'une
   réussite — restent communes : un joueur qui change d'univers ne doit pas
   avoir à réapprendre à lire son écran.

   L'ÉGYPTE est l'univers par défaut : le grès, l'ocre, l'or du désert. Elle
   n'a donc pas de bloc — c'est la palette de base, plus haut. */

/* ── L'UNIVERS JUNGLE — une cité de pierre reprise par la forêt ───────────── */
[data-univers="jungle"] {
  /* ── LE SOL EST GRIS, CE QUI L'ENTOURE EST VÉGÉTAL ──────────────────────
     On marche sur de la PIERRE — le passage est dégagé, c'est pour cela qu'on
     peut le suivre. Ce qui l'entoure est mangé par la forêt : vert profond mêlé
     de brun, mousse et humus. C'est ce contraste qui rend la jungle étouffante
     à l'œil — elle occupe tout sauf le chemin. */
  /* Même geste pour la jungle : le fond passe au vert de forêt humide, plus
     clair, et le mur au presque noir. Voir le commentaire de `:root`. */
  /* La canopée s'assombrit : la dalle était prise entre deux bornes qu'elle ne
     pouvait pas tenir ensemble — assez claire pour se détacher du fond, assez
     sombre pour laisser voir la case atteignable posée dessus. Descendre le
     fond libère les deux. */
  --m-fond-plateau:   #1e2e19;   /* la canopée, dense, presque sans lumière */
  --m-fond-halo:      #3f5834;   /* la trouée où l'on voit */
  /* ── LA DALLE SE DÉTACHAIT À PEINE DE LA CANOPÉE ────────────────────────
     Mesuré : 2,16 pour la dalle et 1,73 pour son joint, contre un minimum de
     3. Sur un téléphone au soleil, le mini-plateau de la jungle sombre était
     un aplat vert où l'on devinait des formes. Le contrôle le disait depuis
     des mois — mais son échec s'imprimait APRÈS le verdict du banc, qui le
     déclarait vert quand même. On a éclairci la pierre et franchi le joint :
     3,48 et 5,02, sans quitter le gris-vert humide voulu. */
  --m-salle:          #82918a;   /* la dalle : grise, humide, à peine verdie */
  --m-salle-bord:     #a8bf96;   /* le joint : la végétation reprend */
  --m-salle-entree:   #98a693;
  --m-salle-tresor:   #5a5c48;
  --m-salle-sable:    #46503a;   /* envahie : les lianes gagnent la dalle */
  --m-case:           #f2faf0;   /* la case atteignable : elle doit sauter aux yeux */
  --m-case-survol:    #c4ecc9;
  --m-momie:          #222e28;
  --m-momie-bord:     #93ad99;
  --m-momie-texte:    #e4ece5;
  --m-gardienne:      #1f2b24;
  --m-gardienne-bord: #7fa88c;
  --m-puits:          #6fa89c;
  --m-portail:        #8fbfa0;
  --m-coffre:         #4a3a1e;
  --m-coffre-haut:    #6b5229;
  --m-or-vif:         #d9b44a;
  /* ── LE MUR CREUSE, IL NE FLOTTE PAS ────────────────────────────────────
     Il valait #1b2415 — plus CLAIR que le fond d'écran (#0f1512). Le hors-jeu
     paraissait donc posé PAR-DESSUS le plateau au lieu d'être un vide, et
     l'auteur a signalé que la végétation se confondait avec la pierre.

     En Égypte le mur est noir pur : plus sombre que tout, il creuse. On applique
     la même logique — une végétation si dense qu'aucune lumière n'y entre. */
  --m-mur-dehors:     #0d1409;   /* la canopée fermée : aucune lumière */

  /* ── LA JUNGLE DOIT SE VOIR AU PREMIER COUP D'ŒIL ───────────────────────
     Le fond valait #0f1512 contre #17130e en Égypte : un écart de NEUF sur
     441 possibles. Deux univers qu'on ne distinguait pas, et l'auteur a cru
     que la bascule ne fonctionnait pas.

     #0c2617 porte l'écart à 24 : un vert de sous-bois franc, assez profond
     pour que le texte s'y lise à 11,9 de contraste. */
  --fond:      #0c2617;
  --carte:     #16211c;
  --creux:     #1c2a23;
  --bord:      #2f4438;
  --texte:     #e4ece5;
  --faible:    #8fa898;
  --or:        #d9b44a;       /* l'or reste l'or : c'est le trésor */
  --sable:     #9aae8e;       /* le « sable » devient mousse et lichen */
  --pierre:    #2b332e;       /* la roche grise, humide */
  --pierre-c:  #39433c;
  --fond-0:    #0f1512;
  --fond-2:    #16211c;
  --doux:      #8fa898;
  --accent:    #d9b44a;
}
[data-univers="jungle"][data-theme="clair"] {
  /* La jungle en plein jour : la pierre pâlit, la végétation s'éclaircit.
     Le rapport tient : le sol reste plus gris que ce qui l'entoure.
     Deux axes veut dire QUATRE combinaisons — chacune doit tenir. */
  --m-fond-plateau:   #d5ddcf;
  --m-fond-halo:      #e8eee2;
  --m-salle:          #ccd0c9;   /* dalle grise, à peine verdie */
  --m-salle-bord:     #8fa584;   /* la végétation, plus franche */
  --m-salle-entree:   #d4e0cd;
  --m-salle-tresor:   #d8e3c8;
  --m-salle-sable:    #bccdb2;
  --m-case:           #8fb894;
  --m-case-survol:    #7aa680;
  --m-momie:          #9aada0;
  --m-momie-bord:     #4e6355;
  --m-momie-texte:    #17231b;
  --m-gardienne:      #cfdcd0;
  --m-gardienne-bord: #4e6355;
  --m-puits:          #4d8878;
  --m-portail:        #5f8f70;
  --m-coffre:         #8a6a34;
  --m-coffre-haut:    #a8874a;
  /* Même raison en thème clair : #6d7d62 donnait 3,89 de contraste contre le
     fond, quand l'Égypte en offre 13. Le mur se lisait à peine. */
  --m-mur-dehors:     #2c3826;

  /* Même raison en thème clair : #eef2ea était à 13 d'écart du sable égyptien.
     #d6ead0 le porte à 33 — une clairière, pas un désert pâle. */
  --fond:      #d6ead0;
  --carte:     #ffffff;
  --creux:     #dfe7da;
  --bord:      #b8c9b4;
  --texte:     #17231b;
  --faible:    #5a6f60;
  --sable:     #7d9273;
  --pierre:    #c3cdbf;
  --pierre-c:  #b2beac;
  --fond-0:    #eef2ea;
  --fond-2:    #ffffff;
  --doux:      #5a6f60;
}

/* ── CE QUI RESTE PROPRE À LA JUNGLE ─────────────────────────────────────────
   Les couleurs de MATIÈRE passent maintenant par les variables `--m-*`, qui se
   redéfinissent en tête de l'univers. Il ne reste ici que ce qui n'a pas de rôle
   nommé : le chemin de l'aperçu et les lignes de tour du journal, qui suivaient
   l'or du désert. */
[data-univers="jungle"] .apercu-chemin,
[data-univers="jungle"] .apercu svg .chemin { fill: #6f8f74; }
[data-univers="jungle"] .ligne.genre-tour,
[data-univers="jungle"] .ligne.genre-phase { border-left-color: #a9c48f; color: #a9c48f; }

/* ── LES SYMBOLES DE RÉVEIL SUIVENT L'UNIVERS ────────────────────────────────
   Ils étaient en or et en ocre — les couleurs du désert — et le restaient sous
   la canopée. Chacun garde sa FORME, qui seule le distingue ; c'est la teinte
   qui change, vers le vert de mousse et la pierre humide.

   La malédiction garde son rouge : c'est une couleur de danger, pas de décor. */
[data-univers="jungle"] .symbole { fill: rgb(168, 198, 150); }
[data-univers="jungle"] .symbole .trait { stroke: rgb(168, 198, 150); }
[data-univers="jungle"] .symbole-effondrement { fill: rgb(150, 176, 148); }
[data-univers="jungle"] .symbole-sable { fill: rgb(126, 168, 118); }
[data-univers="jungle"] .symbole-rotation { fill: rgb(146, 180, 160); }

/* ── LES TITRES DU MENU ──────────────────────────────────────────────────────
   Douze entrées à plat, dans l'ordre où elles ont été ajoutées : on cherchait
   « régler les couleurs » entre « statistiques » et « éditeur ». Ce ne sont pas
   des sous-menus — tout reste visible d'un coup d'œil —, seulement des titres
   qui disent où l'on est. */
#menu .menu-titre {
  margin: .7rem 0 .15rem; padding: 0 .7rem;
  font: 650 10px/1.6 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--faible);
}
#menu .menu-titre:first-of-type { margin-top: .5rem; }

/* La dernière entrée du menu mène ailleurs : un filet la sépare de ce qui
   agit sur la partie en cours. */
#menu .entree.separee {
  margin-top: .5rem; padding-top: .65rem;
  border-top: 1px solid var(--bord); border-radius: 0 0 5px 5px;
}

/* ── LE SOMMAIRE DES ANNEXES ─────────────────────────────────────────────────
   Onze pages, en grille : on les embrasse d'un coup d'œil au lieu de dérouler
   une liste. Chaque entrée dit ce qu'on y trouve — un titre seul obligerait à
   ouvrir pour savoir. */
.sommaire-annexes { display: grid; gap: .7rem; margin: 1.4rem 0 2.4rem; }
@media (min-width: 34rem) { .sommaire-annexes { grid-template-columns: 1fr 1fr; } }
@media (min-width: 56rem) { .sommaire-annexes { grid-template-columns: 1fr 1fr 1fr; } }
.sommaire-annexes a {
  display: block; padding: .8rem .9rem; border-radius: 9px;
  border: 1px solid var(--bord); background: var(--carte);
  text-decoration: none; color: var(--texte);
}
.sommaire-annexes a:hover { border-color: var(--or); }
.sa-titre { display: block; font-weight: 650; font-size: .96rem; }
.sa-quoi { display: block; margin-top: .2rem; font-size: .82rem; color: var(--faible); line-height: 1.4; }

/* ── ATOUM REPREND CE QU'IL A DONNÉ ──────────────────────────────────────────
   Les salles qu'il peut retirer pulsent en rouge sombre : c'est une destruction,
   pas un déplacement, et la couleur doit le dire avant le clic. */
.case.atoum-cible {
  fill: #8c3a2c; fill-opacity: .38; cursor: pointer;
  stroke: #e0a090; stroke-width: 1.3; stroke-dasharray: 4 3;
  animation: atoum-pulse 1.2s ease-in-out 6;
}
@keyframes atoum-pulse { 0%,100% { fill-opacity: .26; } 50% { fill-opacity: .5; } }

/* Un réglage vrai/faux : une case à cocher, à la place du champ numérique. */
.mini input[type="checkbox"] {
  width: 22px; height: 22px; margin: 4px auto 0; display: block;
  accent-color: var(--or); cursor: pointer;
}


/* La version posée, dans les réglages : un repère pour comparer deux appareils
   quand ils ne se comportent pas pareil. */
.version-posee {
  font-size: .82rem; color: var(--faible); line-height: 1.5;
  padding: .5rem .7rem; margin: 0 0 1rem;
  border: 1px solid var(--bord); border-radius: 6px; background: var(--carte);
}
.version-posee strong { color: var(--or); font-family: var(--mono, monospace); }


/* Un réglage décidé par l hôte : montré, mais pas modifiable par les autres. */
.champ-case.fige { opacity: .62; cursor: default; }
.champ-case.fige small { color: var(--or); }


/* Une panne se distingue d un salon vide : la couleur le dit avant le texte. */
.salon-note.salon-panne { color: var(--or); }


/* ── LE CUBE D OR, À DROITE DU COMPTE ────────────────────────────────────────
   Gris tant qu on n a rien pris au coffre, doré dès le premier cube. Il tient
   dans la ligne d inventaire : c est le seul endroit qu on regarde à chaque
   tour, et un repère ailleurs ne se verrait jamais. */
.cp-cube {
  display: inline-flex; align-items: center; gap: 3px;
  margin-left: .5rem; vertical-align: -1px;
}
/* Un cube par fosse. Gris tant qu'il est à prendre, teinté dès qu'il est pris —
   la teinte vient des données, posée en style sur l'élément. */
.cp-cube svg { fill: var(--or); }
.cp-cube svg.vide { fill: var(--faible); opacity: .55; }
.cp-cube b { font-size: 10px; color: var(--or); font-variant-numeric: tabular-nums; }


/* ── LE TREMBLEMENT DES SERPENTS ─────────────────────────────────────────────
   Les pions ne glissent plus d un bout du tombeau à l autre : ils tremblent,
   s effacent, et reparaissent ailleurs. Le mouvement vit ici, dans la feuille
   de style — le script ne fait qu ajouter la classe. */
@keyframes serpente {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  15%  { transform: translate(-1.5px, 0.5px) rotate(-2.5deg); }
  30%  { transform: translate(1.5px, -0.5px) rotate(2.5deg); }
  45%  { transform: translate(-1px, -1px) rotate(-1.5deg); }
  60%  { transform: translate(1px, 1px) rotate(1.5deg); }
  75%  { transform: translate(-0.5px, 0.5px) rotate(-1deg); }
}
/* ── UNE ANIMATION SANS FIN NE S'ARRÊTE JAMAIS ─────────────────────────────
   Un banc l'interdit depuis longtemps, et il a raison : une animation
   `infinite` continue de tourner si le script qui devait retirer la classe
   échoue, et fait chauffer l'appareil sans que personne ne sache pourquoi.

   Sept répétitions de 0,28 s font 1,96 s — la durée du tremblement voulue.
   La feuille de style s'arrête donc d'elle-même, même si le script tombe. */
.serpente {
  animation: serpente .28s ease-in-out 7;
  transform-origin: center;
}

/* Qui préfère moins de mouvement garde le fondu, sans la secousse. */
@media (prefers-reduced-motion: reduce) {
  .serpente { animation: none; }
}


/* ── UN LIEN POUR SAUTER LE MENU ─────────────────────────────────────────────
   Qui navigue au clavier traverse la barre et le menu à chaque page avant
   d atteindre le contenu. Ce lien, premier de la page, permet de les sauter.

   Il est HORS DE L ÉCRAN tant qu on ne l atteint pas : invisible à la souris,
   il apparaît dès qu on tabule dessus. C est exactement ce qu on veut — aucun
   encombrement pour les uns, un raccourci pour les autres. */
/* ── IL NE SE VOIT QUE POUR QUI EN A BESOIN ────────────────────────────────
   `left: -9999px` suffit en théorie : le lien sort de l'écran. En pratique il
   restait visible — un style de page qui repositionne, un cache qui sert
   l'ancienne feuille, et il réapparaît en haut à gauche.

   On l'efface donc de trois façons à la fois. Chacune seule suffirait ; les
   trois ensemble ne laissent aucune prise :

     `clip-path: inset(50%)` — rien à peindre, quel que soit le placement ;
     `width/height: 1px`     — plus rien à occuper ;
     `overflow: hidden`      — le texte ne déborde pas de ce pixel.

   Un lecteur d'écran le lit quand même : il ne regarde pas ce qui est peint,
   mais ce qui est DANS la page. C'est tout l'intérêt — invisible pour l'œil,
   présent pour qui navigue au clavier ou à la voix.

   Au FOCUS, tout revient : il faut bien le voir pour l'employer. */
.evitement {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  z-index: 999;
}
.evitement:focus,
.evitement:focus-visible {
  position: fixed !important;
  left: 0; top: 0;
  width: auto; height: auto;
  margin: 0; padding: 10px 16px;
  overflow: visible; clip-path: none;
  border-radius: 0 0 8px 0;
  background: var(--or); color: #17130e;
  font: 600 14px/1 system-ui, -apple-system, sans-serif;
  text-decoration: none;
}


/* ── UN AUTRE ONGLET A ENREGISTRÉ ────────────────────────────────────────────
   On ouvre volontiers deux onglets sur une page de réglage. Chacun garde sa
   copie, et le dernier à enregistrer écrase l autre — en silence.

   Le bandeau ne bloque rien : il prévient, et laisse choisir. */
.autre-onglet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 300;
  padding: 12px 16px; font-size: 14px; line-height: 1.5;
  background: color-mix(in srgb, var(--rouge) 22%, var(--carte));
  border-top: 1px solid var(--rouge); color: var(--texte);
}
.autre-onglet button {
  margin-left: 8px; padding: 6px 12px; border-radius: 6px;
  border: 1px solid var(--bord); background: var(--carte);
  color: var(--texte); font: 600 13px system-ui, sans-serif; cursor: pointer;
}


