/*
 * menu.css — **l'avant-partie** : l'accueil, la carte du monde, le salon, le chargement.
 *
 * Fichier séparé de `game.css` à dessein : le HUD est un ensemble de plaques posées sur le
 * plateau de jeu, l'avant-partie est un **écran plein**. Ils partagent la palette (les
 * variables de `game.css`, chargé avant) et rien d'autre.
 *
 * La carte du monde **fait office de menu** — c'est écrit dans `rules/matchmaking.md`, et c'est
 * la raison pour laquelle il n'y a pas d'écran de liste de serveurs : les 25 cases *sont* la
 * liste. Elles doivent donc dire tout ce qu'on attend d'une liste de serveurs : qui attend,
 * combien de places, verrouillée ou non, et ce qu'il y a à gagner sur cette case.
 */

/* ---- l'accueil : la première chose qu'on voit ------------------------------------- */

.accueil {
  position: fixed; inset: 0; z-index: 30; display: grid; place-items: center;
  background: radial-gradient(120% 90% at 50% 0%, #241a10 0%, #0d0906 70%);
}
.accueil .bloc { text-align: center; max-width: 560px; padding: 0 24px; }
/*
 * Le `h1` ne contient plus de texte mais **l'enseigne** (`accueil.js`). Les règles
 * de texte restent : elles ne servent plus qu'au repli, quand l'image ne charge
 * pas et que l'`alt` s'affiche à sa place — ce jour-là on veut encore un titre.
 */
.accueil h1 {
  margin: 0 0 6px; font-size: 46px; letter-spacing: .04em; color: #e9cf9d;
  text-shadow: 0 3px 18px rgba(0, 0, 0, .8);
}
.accueil h1 .marque {
  display: block; width: min(300px, 62vw); height: auto; margin: 0 auto 4px;
  filter: drop-shadow(0 8px 30px rgba(0, 0, 0, .8));
}
.accueil .sous {
  margin: 0 0 30px; font-size: 14.5px; color: #9d8155; line-height: 1.7;
}
.accueil .portes { display: flex; flex-direction: column; gap: 10px; }
.accueil .porte {
  font: 17px var(--serif); padding: 14px 20px; cursor: pointer; text-align: left;
  background: var(--bois); border: 1px solid var(--bord); border-radius: 2px;
  box-shadow: var(--ombre); color: var(--titre);
}
.accueil .porte small {
  display: block; font-size: 12.5px; color: var(--encre-pale); margin-top: 3px;
}
.accueil .porte:hover { filter: brightness(1.06); }
.accueil .pied { margin-top: 22px; font-size: 12px; color: #6d5836; }
/* La porte qui dit « ce n'est pas ici » : reconnaissable au premier coup d'œil. */
.accueil .ailleurs { background: linear-gradient(178deg, #efd4b2, #dcb894); }
.accueil .ailleurs small { white-space: pre-line; color: #8a4a2c; }
.accueil .ailleurs[disabled] { opacity: .6; cursor: default; }

/* ---- LA CARTE DU MONDE : un monde, pas une liste ---------------------------------- */

/*
 * ⚠️ **Ce n'était pas une carte, c'était un tableau de sélection de niveau.**
 *
 * Vingt-cinq vignettes séparées par des gouttières, chacune dans son cadre, avec son titre et
 * ses deux lignes de texte. Or les 25 territoires sont **adjacents dans le monde**
 * (`rules/monde.md`) : (2,3) touche (3,3). Ce qu'on veut lire, c'est **une seule feuille** —
 * cinq plaques par cinq, jointives, sans gouttière, sans cadre par case et sans ombre par case
 * (deux ombres côte à côte creusent un sillon : c'est exactement ce qui faisait le carrelage).
 *
 * Ce qui reste pour tenir la lecture :
 *   - la **teinte de domaine** posée sur le terrain, un lavis, comme sur une carte politique ;
 *   - les **frontières** entre domaines différents, bicolores, et **rien** entre deux
 *     territoires de la même faction — c'est ça qui fait qu'un empire se lit comme une tache ;
 *   - une **brume commune** à toute la carte, une seule, qui recoud les plaques en parchemin ;
 *   - des **repères** (donjon, obélisque, épées, bannière, cadenas) posés sur la carte, et le
 *     détail au survol, dans une fiche — plus vingt-cinq blocs de texte sur le terrain.
 */

/*
 * ⚠️ **La carte est le héros de cet écran, pas un encart dedans.**
 *
 * Tout était empilé en colonne : réglages, bouton de rendez-vous, compte, carte, légende. Sur
 * une fenêtre de 1280 × 820, la carte tombait à **543 px de côté** — coincée entre les 720 px
 * de large de `.boite` et les 66 vh de haut qui restaient sous le titre — et **la légende
 * passait sous le bord de l'écran**, donc les repères de la carte n'avaient plus de clé. On
 * demandait « un immense monde » et on montrait une vignette de 543 px entourée de parchemin.
 *
 * Ici, la carte prend toute la hauteur et le reste passe dans une **colonne de côté**. Les
 * zones sont nommées : le DOM ne change pas d'un nœud, donc ni `essai-reseau.mjs` ni
 * `monde.test.js` ne perdent leurs sélecteurs — c'est exactement ce qui les avait déjà cassés
 * une fois, quand l'atlas a remplacé la grille de fiches.
 *
 * En dessous de 1000 px de large, on repasse en colonne : une carte de 300 px avec un rail à
 * côté ne serait plus une carte du tout.
 */
.monde {
  display: grid; gap: 10px 20px;
  grid-template-columns: minmax(0, 84vh) minmax(230px, 300px);
  grid-template-rows: auto auto auto 1fr;
  grid-template-areas:
    "atlas reglages"
    "atlas porte"
    "atlas compte"
    "atlas legende";
  align-items: start;
}
.monde .atlas { grid-area: atlas; }
.monde .reglages { grid-area: reglages; }
.monde > .porte { grid-area: porte; }
.monde .compte { grid-area: compte; }
.monde .legende { grid-area: legende; }

@media (max-width: 1000px) {
  .monde {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto auto auto;
    grid-template-areas: "reglages" "porte" "compte" "atlas" "legende";
  }
}

/*
 * Les réglages valent pour tout ce qu'on ouvrira ; dans la colonne de côté ils se lisent **en
 * pile**, chaque champ sur toute la largeur. En rang, à 300 px, ils se coupaient en plein
 * milieu d'une phrase : « Ma race [Hommes] · Nouvelle partie à » puis, à la ligne, le nombre de
 * places — la légende de la commande séparée de la commande.
 */
.monde .reglages { display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.monde .reglages .g { font-size: 12px; }
.monde .reglages select, .monde .reglages input { width: 100%; box-sizing: border-box; }
@media (max-width: 1000px) {
  .monde .reglages { flex-direction: row; align-items: center; flex-wrap: wrap; }
  .monde .reglages select, .monde .reglages input { width: auto; }
}

/* Le bouton de rendez-vous reprend l'allure d'une porte de l'accueil : c'en est une. */
.monde > .porte {
  font: 16px var(--serif); padding: 11px 16px; cursor: pointer; text-align: left;
  background: var(--bois); border: 1px solid var(--bord); border-radius: 2px;
  box-shadow: var(--ombre); color: var(--titre);
}
.monde > .porte strong { font-weight: 700; }
.monde > .porte small {
  display: block; font-size: 12px; color: var(--encre-pale); margin-top: 2px;
}
.monde > .porte:hover:not([disabled]) { filter: brightness(1.06); }
.monde > .porte[disabled] { opacity: .5; cursor: default; }
/* Quelqu'un attend vraiment : la porte le dit avant même qu'on lise. */
.monde > .porte.appel {
  background: linear-gradient(178deg, #f7dfb0, #e7bd7f);
  box-shadow: var(--ombre), 0 0 0 2px rgba(216, 167, 90, .6);
}

.monde .compte { margin: 0; font-size: 13px; color: #a8631f; font-weight: 700; }
.monde .compte.vide { color: var(--encre-pale); font-weight: 400; }

/* ---- 🔴 PLEIN ÉCRAN : la carte n'est pas un encart, c'est le fond ------------------- */

/*
 * ⚠️ **« j'aimerais que tout l'écran soit le monde, et les boutons par-dessus, pas juste un petit
 * carré qui représente le monde. »** (le joueur, 2026-08-15)
 *
 * C'est un changement de **nature d'écran**, pas de taille. La grille ci-dessus mettait la carte
 * dans une colonne et les commandes dans l'autre : quelle que soit la place qu'on lui donnait,
 * elle restait un panneau *dans* une page. Ici le monde est le fond — il occupe la fenêtre — et
 * tout le reste est **posé dessus**, exactement comme le HUD du jeu est posé sur le plateau.
 *
 * ⚠️ **Aucun nœud du DOM ne bouge**, et c'est délibéré : `essai-reseau.mjs` et `monde.test.js`
 * tiennent l'écran par ses sélecteurs (`.monde .atlas .terr`, `.monde > .porte` — un enfant
 * **direct**), et un changement de structure les a déjà cassés une fois. On ne déplace donc rien,
 * on repositionne.
 *
 * La classe est posée par `reseau.js` au montage de l'atlas et retirée en le quittant. Un
 * `:has(.monde)` s'en passerait — c'est ce que fait `game.css` pour la largeur de la boîte — mais
 * une classe **se voit en test**, et le vrai risque ici n'est pas de la poser : c'est de l'oublier
 * en revenant au salon, où l'on redevient un formulaire.
 */
.vestiaire.plein-monde { place-items: stretch; background: #0b0805; }
.vestiaire.plein-monde .boite {
  position: relative; width: 100%; height: 100%;
  min-width: 0; max-width: none; max-height: none;
  padding: 0; background: none; border: 0; box-shadow: none; overflow: hidden;
}
.vestiaire.plein-monde .corps { position: absolute; inset: 0; }
.vestiaire.plein-monde .monde { display: block; position: absolute; inset: 0; }
/* La carte occupe tout, sans cadre ni arrondi : un cadre en referait un encart. */
/*
 * 🔴 **`width: 100%` ET `inset: 0` — les deux, et le « auto » d'avant rendait l'écran NOIR.**
 *
 * Signalé par un joueur le 2026-08-16 : carte du monde entièrement noire, les boutons flottant
 * par-dessus. Mesuré dans la page — le canevas faisait **1 × 900** : la bonne hauteur, et un
 * pixel de large. La scène 3D tournait parfaitement et peignait dans une bande d'un pixel.
 *
 * La cause est ici. `inset: 0` seul avec `width: auto` laissait l'axe en ligne se résoudre en
 * **rétrécissement au contenu** — et tous les enfants de `.atlas` (le canevas, les plaques, les
 * frontières, la brume) sont eux-mêmes en `position: absolute`, donc le contenu mesure **zéro**.
 * L'axe de bloc, lui, se remplissait bien : d'où une hauteur juste et une largeur nulle, cette
 * asymétrie étant le seul indice visible.
 *
 * ⚠️ Vérifié dans la page plutôt que raisonné : `width: 100%` → **1400**, `inset: 0` seul → **0**,
 * le parent mesurant 1400 dans les deux cas.
 *
 * ⚠️ Et la règle du canevas trois blocs plus bas (`.monde .atlas .relief`) posait **déjà** les
 * deux — `inset: 0; width: 100%; height: 100%`. La bonne recette était écrite à quinze lignes de
 * là, sur l'enfant, et pas sur le parent qui en avait autant besoin.
 */
.vestiaire.plein-monde .monde .atlas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  max-width: none; aspect-ratio: auto;
  margin: 0; border: 0; border-radius: 0; box-shadow: none;
}

/*
 * Les commandes deviennent des **plaques posées sur la carte**. Fond sombre translucide plutôt
 * que le parchemin plein : sur une carte en relief, une plaque opaque fait un trou.
 */
.vestiaire.plein-monde .monde > *:not(.atlas),
.vestiaire.plein-monde .tete,
.vestiaire.plein-monde .pied {
  position: absolute; z-index: 4; margin: 0;
  background: rgba(20, 14, 8, .82); border: 1px solid rgba(120, 92, 52, .55);
  border-radius: 3px; padding: 10px 13px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .55); backdrop-filter: blur(3px);
}
.vestiaire.plein-monde .tete { top: 14px; left: 16px; }
.vestiaire.plein-monde .tete h1 { font-size: 19px; }
.vestiaire.plein-monde .monde .reglages {
  top: 14px; right: 16px; width: min(250px, 40vw); box-sizing: content-box;
}
.vestiaire.plein-monde .monde > .porte { left: 16px; bottom: 108px; width: min(320px, 46vw); }
.vestiaire.plein-monde .monde .compte { left: 16px; bottom: 66px; width: min(320px, 46vw); }
.vestiaire.plein-monde .monde .legende { right: 16px; bottom: 14px; max-width: min(420px, 52vw); }
/* Le message d'étape se pose au-dessus de la carte, au centre — et disparaît quand il est vide. */
.vestiaire.plein-monde .pied {
  top: 14px; left: 50%; transform: translateX(-50%); max-width: 46vw; text-align: center;
}
.vestiaire.plein-monde .pied:empty { display: none; }
/* Sur la carte, les textes des plaques s'éclaircissent : le parchemin n'est plus dessous. */
.vestiaire.plein-monde .monde .compte { color: #f0b562; }
.vestiaire.plein-monde .monde .compte.vide { color: #a08a66; }
.vestiaire.plein-monde .monde .legende { color: #c9b48c; }
.vestiaire.plein-monde .monde .reglages .g { color: #b09b76; }
.vestiaire.plein-monde .pied.g { color: #c9b48c; }

@media (max-width: 760px) {
  /* Trop étroit pour deux colonnes de plaques : la légende passe sous les réglages. */
  .vestiaire.plein-monde .monde .legende { display: none; }
  .vestiaire.plein-monde .monde .reglages { width: min(200px, 46vw); }
}

/* ---- l'atlas : les couches empilées ----------------------------------------------- */

/*
 * `--cote` vient du serveur (déduit des cases reçues, `coteDuMonde`) : la carte ne suppose pas
 * qu'elle fait 5 de côté, elle le lit. Carrée, parce que le monde l'est, et **jamais plus haute
 * que l'écran** — la boîte du vestiaire défile, mais une carte qui demande de faire défiler pour
 * voir le sud n'est plus une carte.
 */
.monde .atlas {
  position: relative; width: 100%; max-width: min(100%, 84vh); aspect-ratio: 1;
  margin: 0 auto; justify-self: center;
  border: 1px solid rgba(58, 38, 18, .8); border-radius: 2px; overflow: hidden;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .6), 0 0 0 1px rgba(240, 220, 180, .18);
  background: #1a140d;
}
.monde .plaques {
  position: absolute; inset: 0;
  display: grid; gap: 0;
  grid-template-columns: repeat(var(--cote), 1fr);
  grid-template-rows: repeat(var(--cote), 1fr);
}

/*
 * Un territoire. **Aucune bordure, aucune ombre, aucun arrondi** : tout ce qui dessinerait le
 * contour d'une case reconstruirait le carrelage qu'on vient de démolir.
 */
.monde .terr {
  position: relative; padding: 0; margin: 0; border: 0; background: #2a2117;
  cursor: pointer; overflow: hidden; color: inherit; font: inherit;
  transition: filter .12s ease;
}
.monde .terr > * { position: absolute; inset: 0; pointer-events: none; }

/* Le terrain : la **vraie** carte de cette graine, engendrée dans le navigateur. */
.monde .terr .sol { background-size: 100% 100%; background-position: center; }
/*
 * Tant qu'il n'est pas peint — les 25 cartes 96×96 arrivent **une par image**, ~7,4 ms l'une —
 * le territoire porte une hachure d'attente plutôt qu'un trou noir. Ça dit « ça vient », ce
 * qu'un aplat ne dit pas.
 */
.monde .terr:not(.avec-vignette) .sol {
  background: repeating-linear-gradient(45deg, #2c2318 0 7px, #342a1c 7px 14px);
}
/*
 * Le lavis de domaine. `soft-light` colore sans écraser : le fleuve reste bleu et la coulée
 * reste rouge — la géographie est ce qu'on vient regarder, la possession se lit par-dessus.
 */
.monde .terr .teinte {
  background: var(--teinte, transparent); opacity: .34; mix-blend-mode: soft-light;
}
.monde .terr.neutre .teinte { opacity: .22; }

/* Le survol et le focus : un liseré **à l'intérieur**, qui ne pousse rien et ne clignote pas. */
.monde .terr:hover { filter: brightness(1.1) saturate(1.06); }
.monde .terr:hover .lueur { box-shadow: inset 0 0 0 2px rgba(255, 234, 190, .85); }
.monde .terr:focus-visible { outline: none; }
.monde .terr:focus-visible .lueur {
  box-shadow: inset 0 0 0 2px #fff2d6, inset 0 0 0 4px rgba(40, 26, 12, .8);
}
/* La cible de « Partie rapide », allumée depuis le bouton : on voit où il mène. */
.monde .terr.vise .lueur { box-shadow: inset 0 0 0 3px rgba(255, 226, 160, .95); }

/*
 * **Le territoire où l'on attend se voit de loin.** C'est le rendez-vous, c'est ce qui fait
 * vivre le monde : sur 25 plaques de terrain, une ligne de texte orange se noie, et on passe à
 * côté du seul joueur connecté. L'animation est lente, sur une lueur intérieure, jamais sur la
 * mise en page.
 */
.monde .terr.attente .lueur { animation: attente 2.4s ease-in-out infinite; }
@keyframes attente {
  0%, 100% { box-shadow: inset 0 0 0 2px rgba(255, 205, 110, .45); }
  50%      { box-shadow: inset 0 0 0 5px rgba(255, 205, 110, .95); }
}
/* On respecte qui a demandé moins d'animations : la lueur reste, elle ne bat plus. */
@media (prefers-reduced-motion: reduce) {
  .monde .terr.attente .lueur { animation: none; box-shadow: inset 0 0 0 4px rgba(255, 205, 110, .9); }
}

/*
 * **Une bataille en cours est injouable, et ça ne se devine pas.** On l'éteint (elle sort du
 * premier plan) et on croise deux épées dessus. Le bouton reste vivant : il doit pouvoir dire
 * qui se bat là, et son clic explique pourquoi on n'entre pas.
 */
.monde .terr.injouable .sol { filter: saturate(.35) brightness(.55); }
.monde .terr.injouable { cursor: not-allowed; }
.monde .terr.injouable:hover { filter: brightness(1.02); }

/* ---- les repères posés sur la carte ------------------------------------------------ */

.monde .terr .reperes {
  inset: auto 5% 6% 5%; display: flex; gap: 5px; align-items: flex-end; justify-content: center;
}
.monde .repere {
  width: 17px; height: 17px; flex: 0 0 auto;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .95));
}
.monde .repere path, .monde .repere circle { fill: #f3e3c2; }
.monde .r-bastion path { fill: #ffe6b4; }
.monde .r-monument path { fill: #d9ecff; }
.monde .r-bataille path, .monde .r-bataille circle { fill: #ff9d6b; }
.monde .r-fanion path { fill: #ffc861; }
.monde .r-verrou path { fill: #e8d2ae; }
.monde .terr.attente .r-fanion { width: 21px; height: 21px; }

/* La stèle : le nom du bâtisseur du Monument, **sur** la carte — il a gagné, ça se lit. */
.monde .terr .stele {
  inset: auto 4% 25% 4%; height: auto; display: none;
  font: 700 9.5px/1.25 var(--serif); text-align: center; letter-spacing: .02em;
  color: #eaf3ff; text-shadow: 0 1px 3px #000, 0 0 6px rgba(0, 0, 0, .9);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.monde .terr .stele.visible { display: block; }

/* Le badge de places : deux chiffres, pas une phrase. */
.monde .terr .badge {
  inset: 5% 5% auto auto; width: auto; height: auto; display: none;
  padding: 1px 5px; border-radius: 2px; font: 700 10.5px var(--serif);
  background: rgba(20, 14, 8, .78); color: #e9d7b2; border: 1px solid rgba(240, 214, 168, .35);
}
.monde .terr .badge.visible { display: block; }
.monde .terr .badge.chaud { background: #a8631f; color: #fff3dc; border-color: #ffd79a; }

/* ---- les frontières politiques ----------------------------------------------------- */

/*
 * Un trait par couture entre deux domaines **différents**, dessiné **une seule fois** et à
 * cheval sur la couture — la moitié de la couleur de chaque côté, comme sur un atlas. Rien
 * entre deux territoires de la même faction : c'est là que la carte cesse d'être un damier.
 */
.monde .frontieres { position: absolute; inset: 0; pointer-events: none; }
.monde .front {
  position: absolute; display: block;
  box-shadow: 0 0 0 1px rgba(16, 10, 4, .75), 0 0 5px rgba(0, 0, 0, .5);
}
.monde .front.v { width: 4px; margin-left: -2px; }
.monde .front.h { height: 4px; margin-top: -2px; }

/*
 * **La brume est commune à toute la carte, et c'est tout son intérêt** : une par territoire
 * rendrait le carrelage. Elle assombrit les bords du monde, pose un grain unique et fait
 * respirer le centre.
 */
.monde .brume {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 120% at 50% 45%,
    rgba(0, 0, 0, 0) 42%, rgba(14, 9, 4, .28) 78%, rgba(10, 6, 2, .62) 100%);
  box-shadow: inset 0 0 60px rgba(10, 6, 2, .55);
}

/* ---- LE RELIEF : la carte du monde en trois dimensions ------------------------------ */

/*
 * Le canevas de la scène 3D, **sous toutes les autres couches**. Il n'existe que si three.js et
 * WebGL ont répondu (`reseau.js#_demarrerRelief`) ; sinon `.en-relief` n'est jamais posée et tout
 * ce bloc reste inerte — l'atlas 2D d'avant continue de vivre, à l'identique.
 */
.monde .atlas .relief {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  touch-action: none;                     /* le glisser déplace la carte, il ne fait pas défiler */
}

/*
 * ⚠️ **Les 25 boutons restent, et ils ne dessinent plus le terrain.** C'est le point délicat du
 * passage en 3D : la scène sait peindre la géographie, elle ne sait ni prendre le focus, ni
 * porter une étiquette lue par un lecteur d'écran, ni répondre aux flèches. Les boutons gardent
 * donc tout ça — mais ils deviennent des **repères posés au-dessus de leur case**, projetés à
 * chaque mouvement de caméra (`_majCadrage`), au lieu d'être posés par la grille.
 */
.monde .atlas.en-relief .plaques { display: block; pointer-events: none; }
.monde .atlas.en-relief .terr {
  position: absolute; width: 74px; height: 74px; margin: 0;
  transform: translate(-50%, -50%);
  background: none; overflow: visible; pointer-events: none;
}
/* Le terrain et le lavis sont dans la scène : les redessiner par-dessus les doublerait. */
.monde .atlas.en-relief .terr .sol,
.monde .atlas.en-relief .terr .teinte { display: none; }
/*
 * Le survol est peint dans la scène (un liseré qui suit le relief) ; il ne reste au DOM que
 * l'indicateur de **focus clavier**, qui n'a pas d'équivalent en 3D.
 */
.monde .atlas.en-relief .terr:hover .lueur { box-shadow: none; }
.monde .atlas.en-relief .terr:focus-visible .lueur {
  border-radius: 50%; box-shadow: 0 0 0 3px rgba(255, 226, 160, .95), 0 0 14px rgba(0, 0, 0, .8);
}
/* Seuls les repères se cliquent : le reste du canevas appartient à la scène. */
.monde .atlas.en-relief .terr .reperes,
.monde .atlas.en-relief .terr .badge,
.monde .atlas.en-relief .terr .stele { pointer-events: auto; }
.monde .atlas.en-relief .terr .reperes { inset: auto 0 58% 0; height: auto; }
.monde .atlas.en-relief .terr .stele { inset: auto 0 8% 0; }
.monde .atlas.en-relief .terr .badge { inset: 8% 50% auto auto; transform: translateX(50%); }
/*
 * ⚠️ **Un repère sorti du cadre s'estompe — on ne le cache pas.** `visibility: hidden` (ce que
 * faisait la première version) retire l'élément de la navigation au clavier : les flèches se
 * bloquaient net dès qu'on avait zoomé, `focus()` s'appliquant à un bouton infocusable. En
 * `opacity`, il reste focalisable, la caméra le ramène (`reseau.js`), et il se rallume dans la
 * foulée. Les enfants portent `pointer-events: auto` — c'est donc à eux qu'il faut le retirer,
 * sinon on cliquerait un repère invisible.
 */
.monde .atlas.en-relief .terr.hors-cadre { opacity: 0; }
.monde .atlas.en-relief .terr.hors-cadre * { pointer-events: none; }
/* Les frontières sont des bandes de terrain dans la scène, pas des traits CSS. */
.monde .atlas.en-relief .frontieres { display: none; }

/*
 * 🔴 **L'interrupteur de carte politique, côté 2D.** « un interrupteur pour la désactiver et mieux
 * voir la carte » — et il doit marcher **aussi sans WebGL**, sinon le bouton ne fait rien sur une
 * machine sans GPU, ce qui est pire que de ne pas l'avoir. En relief, les deux couches s'éteignent
 * ailleurs : le lavis est remaillé dans les sommets, les frontières sont un groupe de la scène
 * (`reseau.js#_basculerPolitique`).
 */
.monde .atlas.sans-politique .teinte,
.monde .atlas.sans-politique .frontieres { display: none; }

/* ---- la fiche de survol ------------------------------------------------------------ */

/*
 * Le détail, à la demande. Elle remplace les deux lignes de texte que chaque case portait en
 * permanence — vingt-cinq fois « Hommes / 0 / 2 joueurs / libre » écrasaient le terrain qu'on
 * était venu regarder. Elle bascule de côté sur les deux dernières colonnes et lignes (`--tx`,
 * `--ty`, posés en JS), donc elle reste dans la carte **sans qu'on mesure rien**.
 */
.monde .fiche {
  position: absolute; z-index: 3; pointer-events: none; opacity: 0; visibility: hidden;
  transform: translate(var(--tx, 0), var(--ty, 0));
  min-width: 178px; max-width: 240px; margin: 4px;
  padding: 8px 11px 9px; border-radius: 2px;
  background: rgba(24, 17, 9, .95); border: 1px solid rgba(226, 196, 145, .45);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .7);
  font: 12px/1.5 var(--serif); color: #e2cda4; text-align: left;
  transition: opacity .1s ease;
}
.monde .fiche.ouverte { opacity: 1; visibility: visible; }
.monde .fiche .tete { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.monde .fiche strong { font-size: 13.5px; color: #ffe6bb; }
.monde .fiche .lieu, .monde .fiche .variante { color: #a08a67; font-size: 11px; }
.monde .fiche .etat { margin-top: 5px; font-weight: 700; }
.monde .fiche .etat.ouvrir { color: #9fc06e; }
.monde .fiche .etat.rejoindre { color: #ffb659; }
.monde .fiche .etat.injouable { color: #e08360; }
.monde .fiche .monument { color: #bcd8f5; font-size: 11.5px; }
.monde .fiche .note { color: #a08a67; font-size: 11px; }
.monde .fiche .faire {
  margin-top: 6px; padding-top: 5px; border-top: 1px solid rgba(226, 196, 145, .22);
  color: #cbb491; font-size: 11px;
}

/* ---- la légende --------------------------------------------------------------------- */

/*
 * Dans la colonne de côté, la légende se lit **en liste** : une clé par ligne. En bandeau sous
 * la carte elle tenait sur deux rangs serrés et débordait de l'écran ; ici chaque entrée a sa
 * ligne, ce qui est ce qu'on attend d'une légende d'atlas.
 */
.monde .legende {
  margin: 0; display: flex; flex-direction: column; align-items: start; gap: 5px;
  font-size: 11.5px; color: #8a7048;
}
@media (max-width: 1000px) {
  .monde .legende { flex-direction: row; flex-wrap: wrap; gap: 4px 13px; align-items: center; }
}
/*
 * ⚠️ `align-items: start` sur la colonne, et **`cle` plutôt que `groupe`** : ce dernier est la
 * pastille de sélection du HUD dans `game.css`, dont la légende héritait cadre et fond. Dix
 * entrées encadrées sous les vraies commandes ressemblaient à dix boutons désactivés. Les deux
 * feuilles partagent la palette et **pas** l'espace de noms de classes — c'est un piège dormant,
 * et celui-ci est le premier qui s'est réveillé.
 */
.monde .legende .cle { display: inline-flex; width: auto; align-items: center; gap: 6px; }
.monde .legende .pastille {
  width: 11px; height: 11px; border-radius: 2px; border: 1px solid rgba(40, 26, 12, .45);
}
.monde .legende .repere { width: 13px; height: 13px; filter: none; }
.monde .legende .repere path, .monde .legende .repere circle { fill: #8a7048; }

/* ---- le dialogue : le mot de passe d'une partie privée ------------------------------- */

.dialogue {
  position: fixed; inset: 0; z-index: 41; display: grid; place-items: center;
  background: rgba(8, 6, 4, .78); backdrop-filter: blur(2px); text-align: center;
}
.dialogue .boite {
  background: var(--bois); border: 1px solid var(--bord); box-shadow: var(--ombre);
  padding: 20px 28px; border-radius: 2px; max-width: 380px;
}
.dialogue h2 { margin: 0 0 6px; font-size: 20px; color: var(--titre); }
.dialogue p { margin: 0 0 12px; font-size: 13.5px; color: var(--encre); line-height: 1.5; }
.dialogue .form { display: flex; flex-direction: column; gap: 9px; }
.dialogue input {
  font: 14px var(--serif); padding: 6px 9px; border: 1px solid var(--bord);
  background: #f6ead1; color: var(--encre); border-radius: 2px;
}
.dialogue .ligne { display: flex; gap: 8px; justify-content: center; }
.dialogue button {
  font: 14px var(--serif); padding: 6px 14px; border: 1px solid var(--bord);
  background: #f0e0c1; color: var(--titre); border-radius: 2px; cursor: pointer;
}
.dialogue button.secondaire { color: var(--encre-pale); }

/* ---- le choix du mode : ce que la partie fera au monde -------------------------------- */

/*
 * Deux portes, l'une sous l'autre, chacune avec **sa conséquence écrite**. Ce n'est pas un
 * « facile / difficile » : c'est la différence entre conquérir un territoire du monde partagé et
 * jouer sur sa copie sans que le monde en sache rien (`chantiers/CONTRATS.md` §3). Un menu
 * déroulant l'aurait rendu invisible ; deux boutons qui expliquent, non.
 */
.dialogue.mode .boite { max-width: 460px; text-align: left; }
.dialogue.mode h2 { text-align: center; }
.dialogue.mode > .boite > p { text-align: center; }
.dialogue.mode .choix { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.dialogue.mode .porte {
  display: block; width: 100%; text-align: left; padding: 11px 15px;
  background: var(--bois); border: 1px solid var(--bord); box-shadow: var(--ombre);
  color: var(--titre); font: 16px var(--serif); cursor: pointer;
}
.dialogue.mode .porte strong { display: block; font-weight: 700; }
.dialogue.mode .porte small {
  display: block; margin-top: 3px; font-size: 12px; line-height: 1.45; color: var(--encre-pale);
}
.dialogue.mode .porte:hover { filter: brightness(1.06); }
.dialogue.mode .porte.entrainement { background: linear-gradient(178deg, #efe0c4, #ddc7a1); }
/*
 * Le réglage de difficulté se range **sous** la porte de l'entraînement, décalé, pour se lire
 * comme sa suite et non comme un troisième mode. Il ne peut pas vivre *dans* le bouton : un
 * contrôle imbriqué dans un `<button>` n'est pas activable.
 */
.dialogue.mode .difficulte {
  display: flex; align-items: center; gap: 8px; margin: -4px 0 0 15px;
  font-size: 12.5px; color: var(--encre-pale);
}
.dialogue.mode .difficulte select {
  font: 13px var(--serif); padding: 3px 6px; border: 1px solid var(--bord);
  background: #f6ead1; color: var(--encre); border-radius: 2px;
}
.dialogue.mode .renoncer { display: block; margin: 0 auto; }

/* ---- la boutique : vide, et honnête sur son vide ------------------------------------- */

.dialogue.boutique .boite { max-width: 420px; }
.dialogue.boutique .solde {
  display: flex; gap: 10px; justify-content: center; margin: 0 0 14px;
}
.dialogue.boutique .jeton {
  padding: 5px 12px; border-radius: 2px; font: 700 14px var(--serif);
  background: rgba(60, 42, 22, .18); border: 1px solid var(--bord); color: var(--titre);
}
.dialogue.boutique .jeton.or { color: #a8631f; }
.dialogue.boutique .vide {
  font-size: 15px; color: var(--titre); font-weight: 700; margin-bottom: 6px;
}
.dialogue.boutique .g { color: var(--encre-pale); font-size: 12.5px; }

/* Le bouton de boutique, dans la colonne des réglages. */
.monde .reglages .boutique { margin-top: 4px; }

/* ---- le chargement ------------------------------------------------------------------ */

.chargement { text-align: center; }
.chargement .barre {
  height: 6px; margin: 14px 0 8px; background: rgba(70, 54, 37, .25); border-radius: 3px;
  overflow: hidden;
}
.chargement .barre i {
  display: block; height: 100%; width: 0; background: #a8631f; transition: width .25s ease;
}
.chargement .etape { font-size: 13px; color: var(--encre-pale); }

/* Les réglages de la partie d'entraînement, dans la porte elle-même. */
.accueil .ligne { display: flex; gap: 6px; flex-wrap: wrap; }
.accueil .ligne input, .accueil .ligne select {
  font: 13px var(--serif); padding: 5px 7px; border: 1px solid var(--bord);
  background: #f6ead1; color: var(--encre); border-radius: 2px;
}
.accueil .ligne input:focus, .accueil .ligne select:focus { outline: 1px solid #a8631f; }

/* ---- l'avis : connexion perdue, session reprise ------------------------------------- */

.avis {
  position: fixed; inset: 0; z-index: 40; display: grid; place-items: center;
  background: rgba(8, 6, 4, .82); backdrop-filter: blur(2px); text-align: center;
}
.avis .boite {
  background: var(--bois); border: 1px solid var(--bord); box-shadow: var(--ombre);
  padding: 24px 36px; border-radius: 2px; max-width: 460px;
}
.avis h2 { margin: 0 0 8px; font-size: 24px; color: var(--titre); }
.avis p { margin: 0 0 16px; font-size: 14px; color: var(--encre); line-height: 1.6; }
.avis button {
  font: 15px var(--serif); padding: 8px 18px; border: 1px solid var(--bord);
  background: #f0e0c1; color: var(--titre); border-radius: 2px; cursor: pointer;
}
