:root {
  color-scheme: dark;
  --cyan: #6ce8ff;
  --cyan-soft: rgba(108, 232, 255, .18);
  --ink: #061017;
  --panel: rgba(5, 18, 26, .82);
  --line: rgba(126, 221, 238, .25);
  --gold: #ffc875;
  --muted: #82a2ad;
  font-family: Inter, Bahnschrift, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: var(--ink); }
body { color: #e9fbff; user-select: none; }
button, input { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
button { color: inherit; cursor: pointer; }
#hub-scene { position: fixed; inset: 0; width: 100%; height: 100%; display: block; outline: 0; }

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(0,0,0,.23), transparent 22%, transparent 72%, rgba(0,0,0,.42)),
    repeating-linear-gradient(180deg, transparent 0 3px, rgba(74,179,198,.018) 3px 4px);
  z-index: 2;
}

.topbar {
  position: fixed;
  z-index: 10;
  left: 0;
  right: 0;
  top: 0;
  height: 86px;
  display: grid;
  grid-template-columns: 190px 1fr 210px;
  align-items: center;
  padding: 0 28px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(2,11,16,.9), rgba(2,11,16,.35), transparent);
}
.topbar > * { pointer-events: auto; }
.back-link {
  justify-self: start;
  display: flex;
  gap: 10px;
  align-items: center;
  color: #a9c7d0;
  text-decoration: none;
  font-weight: 800;
  font-size: 20px;
}
.back-link span { font-size: 10px; letter-spacing: .22em; }
.back-link:hover { color: var(--cyan); }
.brand { justify-self: center; text-align: center; text-shadow: 0 2px 15px #000; }
.brand-kicker { display: block; color: #8faab2; font-size: 8px; font-weight: 800; letter-spacing: .34em; }
.brand strong { display: block; margin-top: 2px; font-size: 27px; line-height: 1; letter-spacing: .16em; }
.brand strong span { color: var(--cyan); }
.population {
  justify-self: end;
  display: grid;
  grid-template-columns: 9px auto;
  column-gap: 10px;
  align-items: center;
  min-width: 170px;
  padding: 9px 13px;
  border: 1px solid rgba(100,221,240,.18);
  background: rgba(3,16,23,.58);
  backdrop-filter: blur(8px);
  clip-path: polygon(7px 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%,0 7px);
}
.population > i { width: 7px; height: 7px; border-radius: 50%; background: #f2b85e; box-shadow: 0 0 10px currentColor; }
.population[data-state="online"] > i { color: #62efa3; background: currentColor; }
.population > div { display: flex; gap: 8px; align-items: baseline; }
.population strong { color: #fff; font-size: 16px; }
.population span { color: #a8c2ca; font-size: 8px; font-weight: 800; letter-spacing: .16em; }
.population small { grid-column: 2; color: #718b94; font-size: 7px; font-weight: 700; letter-spacing: .12em; }

.eyebrow { margin: 0 0 4px; color: var(--cyan); font-size: 7px; font-weight: 900; letter-spacing: .28em; }
.directory {
  position: fixed;
  z-index: 6;
  top: 104px;
  left: 24px;
  width: 216px;
  padding: 16px 14px 12px;
  background: linear-gradient(145deg, rgba(4,18,25,.78), rgba(4,13,19,.5));
  border-left: 2px solid rgba(94,226,249,.5);
  backdrop-filter: blur(7px);
  transition: transform .25s, opacity .25s;
}
.directory h2 { margin: 0 0 11px; font-size: 15px; letter-spacing: .13em; }
.directory nav { display: grid; gap: 3px; }
.directory nav button {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  width: 100%;
  padding: 7px 8px;
  color: #a5bec6;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(112,204,222,.08);
  text-align: left;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: .09em;
}
.directory nav button i { color: var(--place-color, var(--cyan)); font-style: normal; font-size: 13px; text-align: center; }
.directory nav button span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.directory nav button small { opacity: 0; color: var(--cyan); font-size: 11px; transition: opacity .15s, transform .15s; }
.directory nav button:hover, .directory nav button.active { color: #fff; background: rgba(97,222,246,.08); }
.directory nav button:hover small, .directory nav button.active small { opacity: 1; transform: translateX(2px); }
.directory-help { margin: 10px 4px 0; color: #5e7780; font-size: 7px; }
.directory.is-hidden { transform: translateX(-115%); opacity: 0; pointer-events: none; }
kbd { padding: 2px 5px; border: 1px solid rgba(151,218,230,.28); border-radius: 3px; color: #dffaff; background: rgba(5,20,28,.72); font: 700 8px ui-monospace, monospace; box-shadow: inset 0 -1px rgba(255,255,255,.05); }

.radar-card {
  position: fixed;
  z-index: 6;
  top: 104px;
  right: 24px;
  width: 260px;
  overflow: hidden;
  background: rgba(3,15,22,.7);
  border: 1px solid rgba(105,216,235,.2);
  backdrop-filter: blur(7px);
}
.radar-head { display: flex; justify-content: space-between; padding: 9px 11px 7px; font-size: 7px; font-weight: 800; letter-spacing: .13em; }
.radar-head span { color: #718b94; }
.radar-head b { color: var(--cyan); }
.radar-actions{display:flex;align-items:center;gap:2px}.radar-head button{display:grid;place-items:center;margin:-5px -4px -4px 1px;padding:4px 5px;color:#76939b;background:transparent;border:0;font-size:11px}.radar-head button:hover{color:#e8fbff}.radar-head button svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.5}
#music-toggle{position:relative}#music-toggle[aria-pressed="true"]{color:#ff9a7e}#music-toggle[aria-pressed="true"]::after{content:"";position:absolute;width:15px;height:1px;background:currentColor;box-shadow:0 0 4px currentColor;transform:rotate(-45deg)}
#ambience-toggle{position:relative}#ambience-toggle[aria-pressed="true"]{color:#ff9a7e}#ambience-toggle[aria-pressed="true"]::after{content:"";position:absolute;width:15px;height:1px;background:currentColor;box-shadow:0 0 4px currentColor;transform:rotate(-45deg)}
#hub-radar { display: block; width: 260px; height: 164px; background: rgba(0,0,0,.16); }
.radar-legend { display: flex; gap: 12px; padding: 7px 10px; color: #69838c; font-size: 6px; font-weight: 800; letter-spacing: .09em; }
.radar-legend span { display: flex; align-items: center; gap: 4px; }
.radar-legend i { width: 5px; height: 5px; border-radius: 50%; background: #fff; }
.radar-legend .you { background: var(--gold); box-shadow: 0 0 5px var(--gold); }
.radar-legend .resident { background: #67dcf3; }
.radar-legend .place { border-radius: 0; transform: rotate(45deg); background: #81969d; }

.guide {
  position: fixed;
  z-index: 8;
  top: 90px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 9px;
  align-items: center;
  padding: 7px 10px 7px 13px;
  color: #b8eefa;
  background: rgba(3,19,27,.78);
  border: 1px solid rgba(90,225,249,.3);
  clip-path: polygon(7px 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%,0 7px);
  backdrop-filter: blur(6px);
}
.guide span { color: #6f8d96; font-size: 7px; font-weight: 800; letter-spacing: .18em; }
.guide strong { font-size: 9px; letter-spacing: .12em; }
.guide button { padding: 0; color: #78919a; background: none; border: 0; font-size: 16px; }

.controls-hint {
  position: fixed;
  z-index: 5;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  display: flex;
  gap: 13px;
  padding: 8px 13px;
  color: #6f8c95;
  background: rgba(3,13,19,.54);
  border: 1px solid rgba(118,207,223,.11);
  font-size: 7px;
  font-weight: 700;
  letter-spacing: .05em;
  backdrop-filter: blur(5px);
}
.controls-hint span { display: flex; gap: 5px; align-items: center; }

/* La bourse — les deux monnaies, **dans le panneau de combat**.
 * Elle flottait en position fixe juste au-dessus, et figurait dans la liste
 * `.immersive` : le joueur ne voyait jamais ce qu'il possédait. Rangée dans le
 * panneau, elle en hérite tout — la visibilité, le déplacement, le verrou et
 * l'échelle — et il n'y a plus qu'un bloc à poser à l'écran.
 * Les deux colonnes se partagent la largeur : le panneau fait 250 px à
 * l'échelle 1, et deux minimums de 92 px y tenaient à cinq pixels près. */
.wallet {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(3px * var(--echelle-hud, 1));
  margin-top: calc(6px * var(--echelle-hud, 1));
}
.wallet > span {
  display: grid; grid-template-columns: calc(13px * var(--echelle-hud, 1)) auto;
  column-gap: calc(4px * var(--echelle-hud, 1));
  align-items: center; min-width: 0;
  padding: calc(4px * var(--echelle-hud, 1)) calc(6px * var(--echelle-hud, 1));
  background: rgba(3,16,23,.7); border: 1px solid rgba(110,215,232,.14);
}
.wallet i { grid-row: 1 / 3; align-self: center; color: var(--gold); font-style: normal; font-size: calc(9px * var(--echelle-hud, 1)); }
.wallet b { font: 800 calc(9px * var(--echelle-hud, 1)) ui-monospace, monospace; font-variant-numeric: tabular-nums; color: #dff2f8; }
.wallet small { color: #617b84; font-size: calc(5.5px * var(--echelle-hud, 1)); font-weight: 800; letter-spacing: .1em; }

.action-dock { position: fixed; z-index: 12; right: 24px; bottom: 78px; display: grid; gap: 6px; width: 178px; }
.action-dock > * { display: grid; grid-template-columns: 28px 1fr; align-items: center; padding: 8px 9px; color: #9db8c0; background: rgba(3,15,22,.82); border: 1px solid rgba(115,211,229,.18); text-decoration: none; text-align: left; backdrop-filter: blur(9px); }
.action-dock > * > span { grid-row: 1 / 3; display: grid; place-items: center; width: 23px; height: 23px; color: var(--cyan); border: 1px solid currentColor; }
.action-dock b { font-size: 8px; letter-spacing: .1em; }.action-dock small { color: #5f7982; font-size: 6px; letter-spacing: .06em; }
.action-dock > *:hover { color: #fff; border-color: rgba(106,230,253,.46); }
.action-dock .pvp-quick { border-color: rgba(255,148,91,.35); }.action-dock .pvp-quick > span { color: #ff985d; }
#combat-toggle.active { color: #fff; border-color: rgba(255,112,91,.65); box-shadow: inset 0 0 18px rgba(255,96,74,.08); }
#combat-toggle.active > span { color: #ff705b; }
/* Le bandeau de combat, et son échelle.
 *
 * `--echelle-hud` est écrite en style **en ligne** par la poignée d'étirement
 * (`hudFit.js`) : la déclaration ci-dessous n'est donc que la valeur de repos,
 * l'inline la bat toujours. Tout ce qui donne sa taille au panneau la
 * multiplie — largeur, marges intérieures, jauge, corps de texte — sinon
 * agrandir les six cases de sort les ferait déborder d'un cadre resté à 250 px,
 * et « agrandir » deviendrait « déformer ». */
.combat-hud { --echelle-hud: 1; position: fixed; z-index: 9; left: 50%; top: 123px; width: calc(250px * var(--echelle-hud)); transform: translateX(-50%); padding: calc(8px * var(--echelle-hud)) calc(10px * var(--echelle-hud)); background: rgba(19,10,10,.78); border: 1px solid rgba(255,112,91,.28); backdrop-filter: blur(7px); }
.combat-hud > div:first-child { display: flex; justify-content: space-between; color: #ad8d8a; font-size: calc(7px * var(--echelle-hud)); font-weight: 800; letter-spacing: .11em; }
.combat-hud > div:first-child b { color: #ffd5d0; }
.health-track { height: calc(4px * var(--echelle-hud, 1)); margin: calc(5px * var(--echelle-hud, 1)) 0; overflow: hidden; background: rgba(255,255,255,.08); }
.health-track i { display: block; width: 100%; height: 100%; background: #ff705b; box-shadow: 0 0 8px #ff705b; transition: width .2s; }
.jetpack-fuel-hud { margin: calc(7px * var(--echelle-hud, 1)) 0 calc(5px * var(--echelle-hud, 1)); }
.jetpack-fuel-hud > div:first-child { display: flex; justify-content: space-between; color: #a9f5ff; font: 700 calc(9px * var(--echelle-hud, 1))/1.2 ui-monospace, monospace; letter-spacing: .08em; }
.jetpack-fuel-track { height: calc(5px * var(--echelle-hud, 1)); margin-top: calc(4px * var(--echelle-hud, 1)); overflow: hidden; background: rgba(255,255,255,.08); }
.jetpack-fuel-track i { display: block; width: 100%; height: 100%; background: #54eaff; box-shadow: 0 0 9px #36d9f1; transition: width .08s linear, background .15s; }
.jetpack-fuel-hud.low > div:first-child { color: #ff9a75; }
.jetpack-fuel-hud.low .jetpack-fuel-track i { background: #ff714d; box-shadow: 0 0 9px #ff714d; }
.combat-hud small { color: #765a58; font-size: calc(6px * var(--echelle-hud)); letter-spacing: .09em; }

/* La barre des six sorts — quatre de classe (A Z E R) et deux d'invocateur
 * (D F). Elle vit sous la structure et se lit d'un coup d'œil : la touche, ce
 * qu'elle lance, et si c'est disponible.
 *
 * Elle est en DOM et non dessinée au canvas comme celle de l'arène : le hub n'a
 * pas de canvas de HUD, et lui en ajouter un pour six cases coûterait une passe
 * de rendu par image pour quelque chose qui change trois fois par minute. */
/* Les six cases de sort vivent maintenant dans `src/ui/spellBar.css`, chargée
 * par `hub.html` ET `index.html` : l'arène et l'écran de chargement montrent
 * les mêmes cases, et cette feuille-ci n'est pas chargée par eux. */
/* `.environment-hud` et `.environment-track` ont été retirés le 16 août 2026,
 * avec le bandeau qu'ils habillaient : les biomes du large n'infligent plus
 * rien, il n'y a plus de jauge. */

/* Le voile de la chute.
 *
 * `opacity` est écrit image par image par `hub.js` sur les dix secondes de
 * chute : aucune transition CSS ici, sinon elle lisserait par-dessus la courbe
 * qu'on veut — noir tardif, pour qu'on voie tomber avant de perdre la vue.
 * `pointer-events: none` en permanence : le voile ne prend jamais un clic, même
 * opaque, sinon relâcher une touche pendant la chute deviendrait impossible. */
.fall-veil { position: fixed; z-index: 60; inset: 0; display: grid; place-items: center; opacity: 0; background: radial-gradient(circle at 50% 42%, rgba(4,12,20,.55), #01060a 78%); pointer-events: none; }
.fall-veil p { margin: 0; color: #9fd8ee; font-size: 9px; letter-spacing: .3em; text-align: center; text-shadow: 0 0 14px rgba(105,223,252,.5); }

/* La planche de bord, sous le repère d'interaction et alignée sur lui.
 *
 * `pointer-events: none` : elle est posée au milieu de l'écran, là où l'on
 * clique pour faire tourner la caméra. Une plaque de verre qui avale ce clic
 * bloquerait la vue pendant tout le vol — même piège que le voile de chute. */
.flight-hud {
  position: fixed;
  z-index: 15;
  left: 50%;
  bottom: 140px;
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 10px 20px 9px;
  color: #e8fbff;
  background: rgba(4,19,27,.86);
  border: 1px solid rgba(102,231,255,.32);
  box-shadow: 0 8px 30px rgba(0,0,0,.35), inset 0 0 18px rgba(87,217,241,.06);
  clip-path: polygon(10px 0,100% 0,100% calc(100% - 10px),calc(100% - 10px) 100%,0 100%,0 10px);
  backdrop-filter: blur(8px);
  pointer-events: none;
}
.flight-hud > strong { color: var(--cyan); font-size: 10px; letter-spacing: .22em; }
.flight-readout { display: flex; gap: 22px; }
.flight-readout span { display: grid; justify-items: center; gap: 1px; }
.flight-readout small { color: #6f929c; font-size: 6px; font-weight: 900; letter-spacing: .17em; }
/* Chiffres tabulaires : sans cela la vitesse fait sauter la largeur de la
 * planche à chaque unité, et l'œil suit la boîte au lieu du nombre. */
.flight-readout b { font-size: 15px; font-variant-numeric: tabular-nums; }
.flight-readout i { color: #6f929c; font-size: 6px; font-style: normal; letter-spacing: .12em; }
.flight-hud p { margin: 0; color: #6f929c; font-size: 6px; font-weight: 900; letter-spacing: .17em; }

/* La rangée de bord : manœuvres sur 1 2 3 4, missiles sur A Z E R en cockpit.
 *
 * Elle reprend la grammaire de la barre de sorts — une touche, un nom court,
 * un voile de recharge qui se vide par le bas — parce que c'est la **même**
 * promesse : quatre touches, quatre gestes, une recharge chacun.
 * Un second vocabulaire pour la même chose aurait obligé à réapprendre en
 * selle ce qu'on sait déjà à pied.
 *
 * La couleur vient de la manœuvre (`--teinte`), pas de la feuille de style :
 * c'est elle qu'on retrouve sur les particules au moment où la touche sort, et
 * c'est ce lien qui fait comprendre quel bouton vient de produire quoi. */
.flight-moves { display: flex; gap: 7px; }
.flight-move {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 1px;
  min-width: 42px;
  padding: 4px 6px 3px;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--teinte, #66e7ff) 45%, transparent);
  background: color-mix(in srgb, var(--teinte, #66e7ff) 9%, rgba(3,16,22,.7));
  clip-path: polygon(5px 0,100% 0,100% calc(100% - 5px),calc(100% - 5px) 100%,0 100%,0 5px);
}
.flight-move kbd {
  font: inherit;
  font-size: 7px;
  font-weight: 900;
  letter-spacing: .16em;
  color: var(--teinte, #66e7ff);
}
.flight-move span { font-size: 7px; font-weight: 900; letter-spacing: .1em; color: #cfeaf2; }
/* Le voile de recharge monte depuis le bas et se retire : la case redevient
 * lisible au fur et à mesure, ce qui donne à lire un temps restant et pas
 * seulement un état. */
.flight-move i {
  position: absolute;
  inset: auto 0 0 0;
  height: var(--recharge, 0%);
  background: rgba(2,12,17,.72);
  pointer-events: none;
}
.flight-move.prete { box-shadow: inset 0 0 10px color-mix(in srgb, var(--teinte, #66e7ff) 22%, transparent); }
.flight-move.active {
  border-color: var(--teinte, #66e7ff);
  background: color-mix(in srgb, var(--teinte, #66e7ff) 34%, rgba(3,16,22,.7));
}
.flight-move.active span { color: #04141b; }

/* Le nom de la dernière figure, et sa chaîne. Il pulse une fois à l'arrivée —
 * une figure réussie doit se **voir** arriver, pas apparaître entre deux
 * regards. */
.flight-figure {
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .2em;
  color: var(--teinte, #9bff8d);
  animation: figure-pop .34s ease-out;
}
@keyframes figure-pop {
  from { transform: scale(1.5); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

.interaction-prompt {
  position: fixed;
  z-index: 15;
  left: 50%;
  bottom: 94px;
  transform: translateX(-50%);
  display: flex;
  gap: 11px;
  align-items: center;
  padding: 9px 15px 9px 10px;
  color: #e8fbff;
  background: rgba(4,19,27,.9);
  border: 1px solid rgba(102,231,255,.42);
  box-shadow: 0 8px 30px rgba(0,0,0,.35), inset 0 0 18px rgba(87,217,241,.06);
  clip-path: polygon(8px 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%,0 8px);
  backdrop-filter: blur(8px);
}
/* La boussole.
 *
 * Posée sous le plan local, dans le même coin : les deux répondent à la même
 * question et se lisent d'un seul regard. Le plan dit **où sont les choses**,
 * elle dit **vers où l'on est tourné** — le plan est au nord et fixe, elle
 * tourne.
 *
 * Les quatre lettres sont posées sur les quatre côtés d'un carré plutôt que sur
 * un cercle : à cinquante-six pixels, quatre lettres sur un cercle se touchent
 * dès qu'on tourne de quarante-cinq degrés. Chacune se **contre-tourne** pour
 * rester lisible — une boussole dont le S est à l'envers ne se lit pas, elle se
 * déchiffre. */
.boussole {
  position: fixed; z-index: 6; right: 24px; top: 104px;
  display: grid; place-items: center; width: 56px; height: 56px;
  border: 1px solid rgba(104,210,230,.28); border-radius: 50%;
  background: rgba(4,16,22,.72); backdrop-filter: blur(6px);
  pointer-events: none;
}
.boussole-repere {
  position: absolute; top: -5px;
  width: 0; height: 0;
  border: 5px solid transparent; border-top-color: var(--cyan);
  border-bottom: 0;
}
.boussole-rose { position: absolute; inset: 5px; }
.boussole-rose b {
  position: absolute; display: block; width: 11px; height: 11px;
  color: #7fa8b8; font-size: 9px; font-weight: 900; line-height: 11px; text-align: center;
}
.boussole-rose b[data-cardinal="N"] { top: 0; left: 50%; margin-left: -5.5px; color: #8fd8ff; }
.boussole-rose b[data-cardinal="S"] { bottom: 0; left: 50%; margin-left: -5.5px; }
.boussole-rose b[data-cardinal="E"] { right: 0; top: 50%; margin-top: -5.5px; }
.boussole-rose b[data-cardinal="O"] { left: 0; top: 50%; margin-top: -5.5px; }
.boussole > span {
  color: #e8fbff; font-size: 11px; font-weight: 900; letter-spacing: .08em;
  text-shadow: 0 0 6px rgba(0,0,0,.8);
}
/* **Pas de règle `.immersive` ici.** `body` porte cette classe en dur : y
   inscrire la boussole ne l'aurait pas cachée « en exploration », cela l'aurait
   cachée tout le temps. C'est le piège déjà payé par la barre des sorts, et
   consigné dans CLAUDE.md — mesuré, la boussole sortait avec une boîte de
   0 × 0 px et ne tournait jamais. */
@media (max-width: 900px) { .boussole { right: 10px; top: 92px; width: 46px; height: 46px; } }

.interaction-prompt kbd { display: grid; place-items: center; width: 29px; height: 29px; color: #10232a; background: var(--cyan); border: 0; font-size: 12px; }
/* Ce qui n'a pas de touche n'a pas de pastille et ne se présente pas comme
   cliquable : le téléphérique se prend en montant dessus, et un bouton qui ne
   fait rien sous le doigt se lit comme une panne. */
.interaction-prompt.sans-touche { cursor: default; padding-left: 15px; }
.interaction-prompt.sans-touche kbd { display: none; }
.interaction-prompt span { display: grid; text-align: left; }
.interaction-prompt small { color: #6f929c; font-size: 6px; font-weight: 900; letter-spacing: .17em; }
.interaction-prompt strong { margin-top: 2px; font-size: 9px; letter-spacing: .09em; }

.glass-panel {
  position: fixed;
  z-index: 30;
  color: #def8fe;
  background:
    linear-gradient(145deg, rgba(10,32,43,.96), rgba(4,16,24,.97)),
    var(--panel);
  border: 1px solid rgba(107,226,247,.28);
  box-shadow: 0 22px 80px rgba(0,0,0,.58), inset 0 0 45px rgba(65,207,232,.035);
  clip-path: polygon(13px 0,100% 0,100% calc(100% - 13px),calc(100% - 13px) 100%,0 100%,0 13px);
  backdrop-filter: blur(14px);
}
.glass-panel::before { content: ""; position: absolute; inset: 7px; pointer-events: none; border: 1px solid rgba(133,225,241,.06); clip-path: inherit; }
.panel-close { position: absolute; z-index: 2; top: 10px; right: 11px; padding: 2px 7px; color: #7897a0; background: transparent; border: 0; font-size: 20px; }
.panel-close:hover { color: #fff; }

.social-card { right: 32px; top: 300px; width: 320px; padding: 20px; }
.social-card > header { display: grid; grid-template-columns: 58px 1fr; gap: 13px; align-items: center; padding-bottom: 14px; border-bottom: 1px solid rgba(110,215,232,.12); }
.social-avatar { width: 54px; height: 54px; border: 1px solid var(--avatar-color, var(--cyan)); background: radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--avatar-color, var(--cyan)) 55%, transparent), rgba(0,0,0,.35)); box-shadow: inset 0 0 17px color-mix(in srgb, var(--avatar-color, var(--cyan)) 20%, transparent); clip-path: polygon(9px 0,100% 0,100% calc(100% - 9px),calc(100% - 9px) 100%,0 100%,0 9px); }
.social-card header small, .trade-panel > small { color: var(--cyan); font-size: 7px; font-weight: 900; letter-spacing: .18em; }
.social-card h2, .trade-panel h2 { margin: 3px 0 2px; font-size: 17px; letter-spacing: .12em; }
.social-card header p { margin: 0; color: #819da6; font-size: 8px; }
.social-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding-top: 13px; }
/* Le défi reçu. Il reprend l'en-tête de la fiche sociale — c'est le même
   interlocuteur — mais se pose au centre : il attend une réponse, et un
   panneau qui attend une réponse ne se met pas dans un coin. */
.duel-invite { left: 50%; top: 50%; transform: translate(-50%, -50%); width: 360px; padding: 20px; border-color: rgba(255,139,102,.35); }
.duel-invite > header { display: grid; grid-template-columns: 58px 1fr; gap: 13px; align-items: center; padding-bottom: 14px; border-bottom: 1px solid rgba(255,139,102,.16); }
.duel-invite header small { color: #ff8b66; font-size: 7px; font-weight: 900; letter-spacing: .18em; }
.duel-invite h2 { margin: 3px 0 2px; font-size: 17px; letter-spacing: .12em; }
.duel-invite header p { margin: 0; color: #819da6; font-size: 8px; }
.duel-invite-actions { display: grid; gap: 6px; padding-top: 14px; }
.duel-invite-timer { display: block; padding-top: 9px; color: #6d8a93; font-size: 7px; letter-spacing: .1em; }
.social-actions button {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 9px 8px;
  color: #a7c3cb;
  background: rgba(92,202,222,.045);
  border: 1px solid rgba(111,213,231,.12);
  font-size: 7px;
  font-weight: 800;
  letter-spacing: .06em;
  text-align: left;
}
.social-actions button span { color: var(--cyan); font-size: 14px; }
.social-actions button:hover { color: #fff; border-color: rgba(102,231,255,.4); background: rgba(93,213,235,.1); }
.social-actions button.muted { color: #ff9a7e; border-color: rgba(255,122,96,.38); background: rgba(255,95,75,.08); }
.social-detail { margin-top: 11px; padding: 10px; color: #93afb7; background: rgba(0,0,0,.18); font-size: 8px; line-height: 1.65; }
.item-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.item-chips i { padding: 4px 6px; color: #c6ecf4; background: rgba(96,212,232,.08); border: 1px solid rgba(110,215,232,.12); font-style: normal; }

.location-panel { left: 50%; top: 50%; width: min(610px, calc(100vw - 40px)); max-height: min(690px, calc(100vh - 70px)); overflow: auto; transform: translate(-50%, -50%); padding: 25px; }
.location-panel > header { display: grid; grid-template-columns: 62px 1fr; gap: 14px; align-items: center; padding-bottom: 16px; border-bottom: 1px solid rgba(110,215,232,.13); }
.location-icon { display: grid; place-items: center; width: 58px; height: 58px; color: var(--location-color, var(--cyan)); background: rgba(79,205,230,.06); border: 1px solid currentColor; font-size: 25px; box-shadow: inset 0 0 24px color-mix(in srgb, currentColor 12%, transparent); }
.location-panel header small { color: var(--location-color, var(--cyan)); font-size: 7px; font-weight: 900; letter-spacing: .2em; }
.location-panel h2 { margin: 4px 0; font-size: 20px; letter-spacing: .13em; }
.location-panel header p { margin: 0; color: #829fa8; font-size: 9px; }
.robot-dialogue { position: relative; margin: 16px 0; padding: 11px 14px 11px 39px; color: #bce8f1; background: rgba(57,179,203,.07); border-left: 2px solid var(--location-color, var(--cyan)); font-size: 9px; line-height: 1.55; }
.robot-dialogue::before { content: "BOT"; position: absolute; left: 8px; top: 11px; color: var(--location-color, var(--cyan)); font: 900 7px ui-monospace, monospace; }
.location-content { display: grid; gap: 8px; }
.service-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.service-item { position: relative; min-height: 100px; padding: 12px; background: rgba(0,0,0,.2); border: 1px solid rgba(119,208,224,.12); }
.service-item b { display: block; color: #e8fbff; font-size: 9px; letter-spacing: .08em; }
.service-item p { margin: 6px 0 12px; color: #77949d; font-size: 8px; line-height: 1.4; }
.service-item em { position: absolute; right: 10px; bottom: 10px; color: var(--gold); font: normal 800 9px ui-monospace, monospace; }
.service-item button, .secondary-action { padding: 6px 8px; color: #bdeef7; background: rgba(94,215,238,.08); border: 1px solid rgba(103,222,244,.22); font-size: 7px; font-weight: 800; letter-spacing: .07em; }
.service-item button:disabled { color: #647b82; border-color: rgba(103,222,244,.08); cursor: default; }
.builder-link { display: inline-block; text-decoration: none; }
.content-label { margin-top: 6px; color: #78949d; font-size: 7px; letter-spacing: .16em; }
.housing-grid { grid-template-columns: repeat(4, 1fr); }
.customizer-loading{padding:22px;color:#83a8b1;border:1px dashed rgba(111,214,232,.2);font-size:8px;letter-spacing:.14em;text-align:center}.customizer-loading.error{color:#ff9a7e}
.hub-customizer{display:grid;grid-template-columns:180px 1fr;gap:12px}.skin-preview{--skin-base:#59666c;--skin-accent:#62dff5;position:relative;min-height:275px;overflow:hidden;background:radial-gradient(circle at 50% 42%,color-mix(in srgb,var(--skin-accent) 15%,transparent),rgba(3,15,21,.75));border:1px solid rgba(111,214,232,.14)}.skin-preview>i{position:absolute;display:block;background:var(--skin-base);border:1px solid color-mix(in srgb,var(--skin-accent) 60%,#fff);box-shadow:inset 0 0 15px color-mix(in srgb,var(--skin-accent) 16%,transparent)}.skin-head{left:67px;top:37px;width:46px;height:42px;clip-path:polygon(8px 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%,0 8px)}.skin-body{left:53px;top:86px;width:74px;height:87px;clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 18px,87% 100%,13% 100%,0 18px)}.skin-arm{top:91px;width:19px;height:91px}.skin-arm.left{left:28px;transform:rotate(7deg)}.skin-arm.right{right:28px;transform:rotate(-7deg)}.skin-leg{top:170px;width:25px;height:78px}.skin-leg.left{left:57px}.skin-leg.right{right:57px}.skin-preview::after{content:"";position:absolute;left:76px;top:52px;width:28px;height:5px;background:var(--skin-accent);box-shadow:0 0 11px var(--skin-accent)}.skin-preview>b,.skin-preview>small{position:absolute;left:0;right:0;text-align:center}.skin-preview>b{bottom:12px;color:#fff;font-size:9px;letter-spacing:.13em}.skin-preview>small{bottom:2px;color:#5f828c;font-size:5px;letter-spacing:.11em}.skin-controls{display:grid;gap:8px}.skin-controls label,.weapon-skins label{display:grid;gap:4px;color:#718f98;font-size:6px;font-weight:800;letter-spacing:.1em}.skin-controls select{width:100%;padding:7px;color:#c9edf4;background:#0b1b22;border:1px solid rgba(111,214,232,.15);font-size:7px}.skin-palette{display:grid;grid-template-columns:1fr 1fr;gap:6px}.skin-palette input,.weapon-skins input{width:100%;height:29px;padding:1px;background:#07161c;border:1px solid rgba(111,214,232,.16)}.skin-parts{display:grid;grid-template-columns:1fr 1fr;gap:6px}.weapon-skins{padding-top:10px;border-top:1px solid rgba(111,214,232,.12)}.weapon-skins>header{display:flex;justify-content:space-between;align-items:end;margin-bottom:7px}.weapon-skins>header b{font-size:8px;letter-spacing:.12em}.weapon-skins>header small{color:#607e87;font-size:6px}.weapon-skins>div{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}.weapon-skins article{display:grid;grid-template-columns:1fr 1fr;gap:5px;padding:8px;background:rgba(0,0,0,.16);border:1px solid rgba(111,214,232,.09)}.weapon-skins article>b{grid-column:1/-1;color:#aecbd2;font-size:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* La forge. Braise plutôt que cyan : c'est le seul établi de la ville, et il
   doit se distinguer de l'atelier chromatique qui, lui, ne fait que peindre. */
.forge-state{display:block;margin:0 0 10px;padding:8px 10px;color:#e7c9a8;background:rgba(255,154,77,.07);border-left:2px solid #ff9a4d;font-size:7px;letter-spacing:.09em}
.forge-state b{color:#ffc38a;font-size:8px;letter-spacing:.12em}
.forge-state[data-locked="true"]{background:rgba(126,233,189,.08);border-left-color:#7ee9bd}
.forge-state[data-locked="true"] b{color:#a9f4d5}
.forge-section{margin-bottom:12px}
.forge-section>header{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:6px}
.forge-section>header b{font-size:8px;letter-spacing:.12em}
.forge-section>header small{color:#607e87;font-size:6px;text-align:right}
.forge-section>select{width:100%;padding:7px;color:#c9edf4;background:#0b1b22;border:1px solid rgba(111,214,232,.15);font-size:7px}
.forge-kits{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.forge-kit{--kit:#ff9a4d;display:grid;gap:3px;padding:9px 8px;color:#9fb9c1;text-align:left;background:rgba(0,0,0,.2);border:1px solid rgba(111,214,232,.1);cursor:pointer}
.forge-kit b{color:#dceef3;font-size:8px;letter-spacing:.1em}
.forge-kit small{color:#68858e;font-size:5px;letter-spacing:.07em}
.forge-kit:hover:not(:disabled){border-color:var(--kit)}
.forge-kit[aria-pressed="true"]{color:#fff;background:color-mix(in srgb,var(--kit) 14%,transparent);border-color:var(--kit);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--kit) 35%,transparent)}
.forge-kit[aria-pressed="true"] b{color:var(--kit)}
.forge-kit:disabled{opacity:.45;cursor:progress}
/* La carte dont on attend le corps. Six cartes grisées à l'identique pendant
   qu'un GLB descend ne disaient pas laquelle : l'établi paraissait éteint. */
.forge-kit[data-montage]:disabled{opacity:1;color:#fff;background:color-mix(in srgb,var(--kit) 16%,transparent);border-color:var(--kit)}
.forge-kit[data-montage] b{color:var(--kit)}
.forge-kit[data-montage] b::after{content:" · MONTAGE…";color:#e7c9a8;font-size:5px;letter-spacing:.06em}
/* Le robot, en vrai. Un aperçu à plat en carrés CSS suffisait à l'atelier
   chromatique, qui ne fait que peindre ; la forge monte un kit, et il faut
   voir la silhouette qu'on monte. */
.forge-cabine{position:relative;height:230px;background:#080b12;border:1px solid rgba(255,154,77,.16)}
.forge-cabine-vue{display:block;width:100%;height:100%}
.forge-armes{display:grid;grid-template-columns:repeat(2,1fr);gap:6px}
.forge-armes.solo{grid-template-columns:1fr}
.forge-armes article{display:grid;gap:5px;padding:8px;background:rgba(0,0,0,.16);border:1px solid rgba(111,214,232,.09)}
.forge-armes article>b{color:#aecbd2;font-size:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.forge-arme-vue{display:block;width:100%;height:120px;background:#080b12;border:1px solid rgba(111,214,232,.09)}
.forge-armes.solo .forge-arme-vue{height:165px}
.forge-arme-teintes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}
.forge-armes label{display:grid;gap:4px;color:#718f98;font-size:6px;font-weight:800;letter-spacing:.1em}
.forge-armes input{width:100%;height:26px;padding:1px;background:#07161c;border:1px solid rgba(111,214,232,.16)}
.forge-vide{margin:0;color:#68858e;font-size:7px}
.forge-assortir{width:100%;margin:0 0 6px;padding:7px 8px;color:#ffd4ad;background:rgba(255,154,77,.08);border:1px solid rgba(255,154,77,.35);font-size:6px;font-weight:900;letter-spacing:.11em;cursor:pointer}
.forge-assortir:hover{color:#fff;border-color:#ff9a4d;background:rgba(255,154,77,.15)}
.forge-assortir:disabled{opacity:.35;cursor:default}
/* Un personnage validé n'est pas une action indisponible : il porte la couleur
   du verrou, pas le gris des boutons morts. La règle générique
   `.primary-action:disabled` gagnait — même spécificité, écrite plus bas — et
   le seul retour de la validation ressortait éteint. D'où les deux classes. */
.primary-action.forge-valide:disabled{color:#0f2a22;background:#7ee9bd;opacity:.85;cursor:default}
.forge-teintes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin-top:6px}

/* Palette tricolore : surcharge les deux grilles historiques compactées plus haut. */
.skin-palette,.weapon-skins article{grid-template-columns:repeat(3,minmax(0,1fr))}
.forge-teintes label{display:grid;gap:4px;color:#718f98;font-size:6px;font-weight:800;letter-spacing:.1em}
.forge-teintes input{width:100%;height:29px;padding:1px;background:#07161c;border:1px solid rgba(111,214,232,.16)}
/* Les deux teintes sont dans la case du robot, collées sous sa vue : on juge
   une couleur sur le robot, pas en descendant d'un écran pour aller le
   regarder. D'où la bordure haute absente et le fond commun avec la cabine. */
.forge-cabine + .forge-teintes{margin-top:0;padding:6px;background:rgba(0,0,0,.22);border:1px solid rgba(255,154,77,.16);border-top:0}

/* Le même choix global dans l'Armure et les ateliers : deux teintes propres ou
   la troisième couche de corruption. Le bouton actif se lit sans dépendre de
   la couleur elle-même, et le troisième sélecteur reste visible mais dormant. */
.armor-color-mode,.hub-color-mode{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}
.armor-color-mode button,.hub-color-mode button{min-width:0;padding:6px 5px;color:#718f98;background:#07161c;border:1px solid rgba(111,214,232,.16);font-size:6px;font-weight:800;letter-spacing:.07em;cursor:pointer}
.armor-color-mode button[aria-pressed="true"],.hub-color-mode button[aria-pressed="true"]{color:#ffe0be;background:rgba(255,154,77,.1);border-color:#ff9a4d;box-shadow:inset 0 0 10px rgba(255,154,77,.1)}
.weapon-color-mode{grid-column:1/-1}
.forge-weapon-mode{margin-top:0}
.armor-colors label.is-inactive,.skin-palette label.is-inactive,.forge-teintes label.is-inactive,.forge-arme-teintes label.is-inactive,.weapon-skins label.is-inactive{opacity:.32}
.armor-colors label.is-inactive input,.skin-palette label.is-inactive input,.forge-teintes label.is-inactive input,.forge-arme-teintes label.is-inactive input,.weapon-skins label.is-inactive input{cursor:not-allowed;filter:grayscale(1)}

/* Les six emplacements d'armure, dans la forge elle-même : c'est ici qu'on
   assemble un robot, et traverser la place jusqu'à l'atelier chromatique pour
   changer un casque n'avait pas de sens. */
.forge-pieces{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.forge-piece{display:grid;gap:5px;padding:7px 6px;background:rgba(0,0,0,.16);border:1px solid rgba(111,214,232,.09)}
.forge-piece>b{color:#718f98;font-size:6px;font-weight:800;letter-spacing:.1em;text-align:center}
.forge-piece>div{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:3px}
.forge-piece button{padding:4px 5px;color:#9fd6e4;background:#0b1b22;border:1px solid rgba(111,214,232,.16);font-size:9px;line-height:1;cursor:pointer}
.forge-piece button:hover{color:#fff;border-color:var(--cyan)}
.forge-piece span{color:#c9edf4;font-size:6px;font-weight:800;letter-spacing:.06em;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* La table de mixage : une ligne par son, curseur et valeur alignés. Les
   colonnes sont fixes pour que les curseurs forment une colonne lisible —
   sinon un nom long décale le sien et la table se lit en escalier. */
.mixage-liste{display:grid;gap:4px}
.mixage-ligne{display:grid;grid-template-columns:112px 1fr 44px;align-items:center;gap:8px;padding:5px 7px;background:rgba(0,0,0,.16);border:1px solid rgba(111,214,232,.08)}
.mixage-ligne b{color:#9fd6e4;font-size:6px;font-weight:800;letter-spacing:.08em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mixage-ligne span{color:#718f98;font-size:6px;font-weight:800;letter-spacing:.06em;text-align:right}
.mixage-ligne input[type=range]{width:100%;height:14px;accent-color:#7ee9bd;cursor:pointer}
/* Le releve sous le curseur de cadence : mesure, pas promesse. */
#cadence-content .mixage-ligne span{width:60px}
#cadence-content .mixage-ligne input[type=range]{accent-color:#ffd479}
.option-note{margin:8px 0 10px;color:#7f9aa4;font-size:6px;line-height:1.7;letter-spacing:.05em}

/* Les crans de qualite et les cadences rondes vivent dans
   `src/ui/parametresVideo.css`, partage avec l'arene : le panneau est le meme
   des deux cotes, et deux copies de ses regles auraient diverge. */

.forge-invoc{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.forge-invoc label{display:grid;gap:4px;color:#718f98;font-size:6px;font-weight:800;letter-spacing:.1em}
.forge-invoc select{width:100%;padding:7px;color:#c9edf4;background:#0b1b22;border:1px solid rgba(111,214,232,.15);font-size:7px}

.service-item button:hover, .secondary-action:hover { color: #fff; border-color: var(--cyan); }
.primary-action { width: 100%; padding: 10px; color: #10232a; background: var(--cyan); border: 0; font-size: 8px; font-weight: 900; letter-spacing: .13em; }
.arena-link { display: block; text-align: center; text-decoration: none; }
.primary-action:disabled { color: #688088; background: #23363d; cursor: default; }
.market-row { display: grid; grid-template-columns: 1fr auto auto; gap: 12px; align-items: center; padding: 9px 10px; background: rgba(0,0,0,.15); border-bottom: 1px solid rgba(104,203,220,.1); }
.market-row div b { display: block; font-size: 9px; }.market-row div small { color: #718b94; font-size: 7px; }
.market-row > b { color: var(--gold); font: 800 9px ui-monospace, monospace; }

.trade-panel { left: 50%; top: 50%; width: min(470px, calc(100vw - 36px)); transform: translate(-50%, -50%); padding: 24px; }
.trade-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 15px 0; }
.trade-columns > div > b { display: block; margin-bottom: 6px; color: #79959e; font-size: 7px; letter-spacing: .13em; }
.trade-slot { display: grid; place-items: center; width: 100%; min-height: 92px; color: #8eadb6; background: rgba(0,0,0,.18); border: 1px dashed rgba(117,218,236,.24); font-size: 8px; }
button.trade-slot:hover { color: var(--cyan); border-color: var(--cyan); }
.trade-slot.waiting { opacity: .65; }

.group-panel { left:50%;top:50%;width:min(680px,calc(100vw - 38px));max-height:calc(100vh - 60px);overflow:auto;transform:translate(-50%,-50%);padding:24px; }
.group-panel>header small{color:var(--cyan);font-size:7px;font-weight:900;letter-spacing:.17em}.group-panel>header h2{margin:4px 0;font-size:18px;letter-spacing:.12em}.group-panel>header p{margin:0;color:#75919a;font-size:8px}
.group-tabs{display:flex;margin:17px 0 12px;border-bottom:1px solid rgba(111,210,228,.12)}.group-tabs button{padding:9px 13px;color:#69858e;background:transparent;border:0;border-bottom:2px solid transparent;font-size:7px;font-weight:900;letter-spacing:.11em}.group-tabs button.active{color:var(--cyan);border-color:var(--cyan)}
.activity-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:7px}.activity-grid button{display:grid;grid-template-columns:34px 1fr;text-align:left;padding:11px;color:#9ab5bd;background:rgba(77,186,207,.04);border:1px solid rgba(110,211,229,.12)}.activity-grid button:hover,.activity-grid button.active{color:#fff;border-color:var(--cyan);background:rgba(89,211,235,.09)}.activity-grid i{grid-row:1/4;display:grid;place-items:center;width:28px;height:28px;color:var(--cyan);border:1px solid currentColor;font-style:normal}.activity-grid b{font-size:8px;letter-spacing:.08em}.activity-grid span{color:#d6a85f;font-size:6px;font-weight:800}.activity-grid small{color:#637e87;font-size:6px}
.queue-status{display:grid;grid-template-columns:10px 1fr auto;gap:9px;align-items:center;margin:10px 0;padding:10px;background:rgba(0,0,0,.17);border:1px solid rgba(111,210,228,.1)}.queue-status>i{width:7px;height:7px;border-radius:50%;background:#526d76}.queue-status.searching>i{background:#ffc45e;box-shadow:0 0 9px #ffc45e;animation:pulse-queue 1s infinite}.queue-status.matched>i{background:#5ee79d;box-shadow:0 0 9px #5ee79d}.queue-status b{display:block;font-size:7px;letter-spacing:.1em}.queue-status span{display:block;margin-top:2px;color:#627d86;font-size:7px}.queue-status button,.party-head button,.unit-card>button{padding:5px 7px;color:#9ab7bf;background:transparent;border:1px solid rgba(111,210,228,.15);font-size:6px;font-weight:800}@keyframes pulse-queue{50%{opacity:.35}}
.party-head{display:flex;justify-content:space-between;align-items:center;margin:14px 0 7px;color:#718c95;font-size:7px;letter-spacing:.1em}.party-list{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}.party-member{padding:9px;background:rgba(71,174,194,.045);border:1px solid rgba(111,210,228,.1)}.party-member i{display:block;width:19px;height:19px;margin-bottom:5px;background:var(--member-color);border:1px solid rgba(255,255,255,.25)}.party-member b{display:block;font-size:7px}.party-member small{color:#5e7881;font-size:6px}.party-empty{grid-column:1/-1;padding:14px;color:#536c74;border:1px dashed rgba(111,210,228,.12);font-size:7px;text-align:center}
#corpo-empty>p{color:#819da6;font-size:9px;line-height:1.6}#corpo-form{display:grid;grid-template-columns:1fr 150px;gap:8px}#corpo-form .primary-action{grid-column:1/-1}.corpo-note{margin:8px 0 0;color:#607b69;font-size:7px;line-height:1.6}.corpo-note code{color:#9be58d;font-family:ui-monospace,monospace}.unit-card{display:grid;grid-template-columns:68px 1fr auto;gap:13px;align-items:center;padding:18px;background:linear-gradient(135deg,rgba(112,225,151,.08),rgba(0,0,0,.18));border:1px solid rgba(128,225,154,.2)}#corpo-emblem{display:grid;place-items:center;width:62px;height:62px;color:#9be58d;border:1px solid currentColor;font-size:26px}.unit-card small{color:#83d99c;font-size:7px;letter-spacing:.15em}.unit-card h3{margin:4px 0;font-size:17px;letter-spacing:.1em}.unit-card div>b{color:#ffc65d;font:800 9px ui-monospace,monospace}.unit-card p{margin:5px 0 0;color:#658078;font-size:7px}
.corpo-annuaire-head{display:flex;justify-content:space-between;align-items:center;margin:14px 0 7px;color:#718c95;font-size:7px;letter-spacing:.1em}.corpo-annuaire-head button{padding:5px 7px;color:#9ab7bf;background:transparent;border:1px solid rgba(111,210,228,.15);font-size:6px;font-weight:800}.corpo-annuaire{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}.corpo-fiche{display:grid;grid-template-columns:1fr auto;gap:6px;align-items:center;padding:9px;background:rgba(71,174,194,.045);border-left:2px solid var(--corpo-color,#9be58d);border-top:1px solid rgba(111,210,228,.1);border-right:1px solid rgba(111,210,228,.1);border-bottom:1px solid rgba(111,210,228,.1)}.corpo-fiche b{display:block;font-size:7px}.corpo-fiche small{display:block;margin-top:2px;color:#5e7881;font-size:6px}.corpo-fiche button{padding:5px 7px;color:#9be58d;background:transparent;border:1px solid rgba(129,224,158,.2);font-size:6px;font-weight:800}.corpo-vide{grid-column:1/-1;padding:14px;color:#536c74;border:1px dashed rgba(111,210,228,.12);font-size:7px;text-align:center}.corpo-tresor{display:grid;grid-template-columns:1fr 150px;gap:8px;align-items:end;margin-top:10px}.corpo-tresor label{display:block;color:#718c95;font-size:6px;letter-spacing:.12em}.corpo-tresor input{width:100%;margin-top:4px;padding:7px;color:#dff0f4;background:rgba(0,0,0,.22);border:1px solid rgba(111,210,228,.14);font:800 9px ui-monospace,monospace}.corpo-tresor button{padding:9px 7px;color:#9be58d;background:rgba(79,178,111,.06);border:1px solid rgba(129,224,158,.2);font-size:7px;font-weight:800}.corpo-membres{margin-top:12px}.corpo-membres>header{display:flex;justify-content:space-between;align-items:center;margin-bottom:7px;color:#718c95;font-size:7px;letter-spacing:.1em}#corpo-membres-liste{display:grid;gap:4px}.corpo-membre{display:grid;grid-template-columns:1fr 92px auto;gap:6px;align-items:center;padding:7px 9px;background:rgba(71,174,194,.04);border:1px solid rgba(111,210,228,.09)}.corpo-membre b{font-size:7px}.corpo-membre b i{margin-left:5px;color:#ffc65d;font-style:normal;font-size:6px}.corpo-membre select{padding:4px;color:#cfe6ec;background:rgba(0,0,0,.25);border:1px solid rgba(111,210,228,.12);font-size:6px}.corpo-membre button{padding:4px 6px;color:#ff9a7e;background:transparent;border:1px solid rgba(255,154,126,.2);font-size:6px;font-weight:800}.corpo-membre span{color:#5e7881;font-size:6px;letter-spacing:.1em;text-align:right}.corpo-tour{margin-top:12px;padding:13px;background:rgba(44,116,87,.055);border:1px solid rgba(129,224,158,.17)}.corpo-tour>header{display:flex;justify-content:space-between;align-items:end;margin-bottom:8px}.corpo-tour header small{display:block;color:#70a682;font-size:6px;letter-spacing:.14em}.corpo-tour header b{display:block;margin-top:3px;font-size:9px;letter-spacing:.1em}.corpo-tour header strong{color:#9be58d;font-size:8px}.corpo-etages{display:flex;flex-direction:column-reverse;gap:4px}.corpo-etage{display:grid;grid-template-columns:34px 1fr auto;gap:8px;align-items:center;padding:8px 9px;background:rgba(79,178,111,.05);border:1px solid rgba(129,224,158,.12)}.corpo-etage.ferme{background:rgba(0,0,0,.16);border-color:rgba(111,210,228,.08)}.corpo-etage.courant{border-color:rgba(255,198,93,.4);box-shadow:inset 0 0 0 1px rgba(255,198,93,.12)}.corpo-etage>i{display:grid;place-items:center;height:30px;color:#9be58d;border:1px solid rgba(129,224,158,.22);font:800 10px ui-monospace,monospace;font-style:normal}.corpo-etage.franchi>i{color:#0f2018;background:#9be58d}.corpo-etage b{display:block;font-size:7px}.corpo-etage-reglages{display:flex;gap:4px;margin-top:4px;flex-wrap:wrap}.corpo-etage-reglages select{padding:3px;color:#cfe6ec;background:rgba(0,0,0,.25);border:1px solid rgba(111,210,228,.12);font-size:6px}.corpo-etage-actions{display:flex;gap:4px}.corpo-etage-actions button{padding:6px 7px;color:#a8c6b2;background:rgba(79,178,111,.05);border:1px solid rgba(129,224,158,.14);font-size:6px;font-weight:800}.corpo-etage-actions button.defi{color:#ffc65d;border-color:rgba(255,198,93,.24)}.corpo-etage-actions button:disabled{opacity:.35}#corpo-etage-ajoute{width:100%;margin-top:6px;padding:9px 7px;color:#a8c6b2;background:rgba(79,178,111,.05);border:1px dashed rgba(129,224,158,.2);text-align:center}#corpo-etage-ajoute b,#corpo-etage-ajoute small{display:block;font-size:6px}#corpo-etage-ajoute small{margin-top:3px;color:#5f7f69}#corpo-etage-ajoute:disabled{opacity:.42}

.options-panel{left:50%;top:50%;width:min(850px,calc(100vw - 36px));max-height:calc(100vh - 46px);overflow:auto;transform:translate(-50%,-50%);padding:25px}.options-panel>header{padding:0 35px 16px 0;border-bottom:1px solid rgba(111,214,232,.13)}.options-panel>header small{color:var(--cyan);font-size:7px;font-weight:900;letter-spacing:.2em}.options-panel>header h2{margin:4px 0;font-size:19px;letter-spacing:.13em}.options-panel>header p{margin:0;color:#718d96;font-size:8px}.option-section{margin-top:17px}.option-section>h3{margin:0 0 8px;color:#6e8992;font-size:7px;letter-spacing:.17em}.option-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:7px}.option-card{position:relative;display:grid;grid-template-rows:34px auto auto;align-content:start;min-width:0;min-height:104px;padding:12px 10px;color:#a9c3ca;background:rgba(62,170,191,.035);border:1px solid rgba(111,214,232,.11);text-align:left;text-decoration:none;clip-path:polygon(7px 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%,0 7px)}.option-card:hover,.option-card:focus-visible{color:#fff;border-color:rgba(108,232,255,.48);background:rgba(62,190,214,.09);outline:0}.option-card.active{color:#fff;border-color:var(--option-color,var(--cyan));box-shadow:inset 0 0 22px color-mix(in srgb,var(--option-color,var(--cyan)) 9%,transparent)}.option-card svg{width:27px;height:27px;color:var(--option-color,var(--cyan));fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}.option-card b{overflow:hidden;color:inherit;font-size:8px;line-height:1.25;letter-spacing:.07em;text-overflow:ellipsis}.option-card small{display:block;margin-top:5px;color:#5e7881;font-size:6px;line-height:1.3;letter-spacing:.05em}.option-card.active small{color:color-mix(in srgb,var(--option-color,var(--cyan)) 70%,#8ba0a6)}

/* Console d'auteur des quatre ambiances horaires. Elle reste dans le hub : le
   dôme, le brouillard et les lumières qu'elle pilote n'existent sur aucune
   autre page. */
.ciel-admin {
  left: 50%; top: 50%; z-index: 42;
  width: min(760px, calc(100vw - 36px)); max-height: calc(100vh - 42px);
  overflow: auto; transform: translate(-50%, -50%); padding: 25px;
}
.ciel-admin > header { padding: 0 35px 15px 0; border-bottom: 1px solid rgba(111,214,232,.13); }
.ciel-admin > header small { color: #9bbcff; font-size: 7px; font-weight: 900; letter-spacing: .2em; }
.ciel-admin > header h2 { margin: 4px 0; font-size: 19px; letter-spacing: .13em; }
.ciel-admin > header p { margin: 0; color: #718d96; font-size: 8px; }
.ciel-admin-phases { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 15px 0 9px; }
.ciel-admin-phases button,
.ciel-admin-actions button {
  padding: 9px 8px; color: #8ca5b1; background: rgba(74,137,178,.055);
  border: 1px solid rgba(139,188,255,.16); font-size: 7px; font-weight: 900; letter-spacing: .1em;
}
.ciel-admin-phases button:hover,
.ciel-admin-phases button.active { color: #fff; border-color: #9bbcff; background: rgba(108,139,255,.13); }
.ciel-admin-etat { display: grid; grid-template-columns: 8px 1fr auto; gap: 8px; align-items: center; padding: 7px 9px; background: rgba(0,0,0,.18); }
.ciel-admin-etat i { width: 6px; height: 6px; border-radius: 50%; background: #ffc253; box-shadow: 0 0 8px currentColor; }
.ciel-admin.ciel-auto .ciel-admin-etat i { color: #7ee9bd; background: currentColor; }
.ciel-admin-etat b { font-size: 7px; letter-spacing: .1em; }
.ciel-admin-etat span { color: #607985; font-size: 6px; letter-spacing: .12em; }
.ciel-admin-corps { display: grid; grid-template-columns: .85fr 1.15fr; gap: 10px; margin-top: 10px; }
.ciel-admin fieldset { min-width: 0; margin: 0; padding: 13px; border: 1px solid rgba(111,214,232,.12); background: rgba(0,0,0,.1); }
.ciel-admin legend { padding: 0 6px; color: #718d96; font-size: 6px; font-weight: 900; letter-spacing: .15em; }
.ciel-admin-couleurs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.ciel-admin-couleur { display: grid; grid-template-columns: 1fr 36px; gap: 7px; align-items: center; min-width: 0; color: #8ca5b1; font-size: 6px; font-weight: 800; letter-spacing: .07em; }
.ciel-admin-couleur input { width: 36px; height: 26px; padding: 1px; border: 1px solid rgba(139,188,255,.22); background: #08181f; cursor: pointer; }
.ciel-admin-curseurs { display: grid; gap: 8px; }
.ciel-admin-curseur { display: grid; grid-template-columns: 112px 1fr 34px; gap: 8px; align-items: center; color: #8ca5b1; font-size: 6px; font-weight: 800; letter-spacing: .07em; }
.ciel-admin-curseur input { width: 100%; accent-color: #9bbcff; }
.ciel-admin-curseur output { color: #ddecff; font: 8px/1 ui-monospace, Consolas, monospace; text-align: right; }
.ciel-admin-direction { display: grid; grid-template-columns: 112px repeat(3, 1fr); gap: 6px; align-items: center; margin-top: 12px; padding-top: 10px; border-top: 1px solid rgba(111,214,232,.09); color: #8ca5b1; font-size: 6px; font-weight: 800; letter-spacing: .07em; }
.ciel-admin-direction label { display: grid; grid-template-columns: auto 1fr; gap: 4px; align-items: center; }
.ciel-admin-direction input { min-width: 0; width: 100%; padding: 5px; color: #ddecff; background: #08181f; border: 1px solid rgba(139,188,255,.16); font: 8px ui-monospace, Consolas, monospace; }
.ciel-admin-actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; margin-top: 11px; }
.ciel-admin-actions button:hover { color: #fff; border-color: rgba(155,188,255,.55); }
.ciel-admin-actions button:last-child { color: #ffc69a; border-color: rgba(255,165,98,.22); }
.ciel-admin-actions [data-ciel-act="lock"][aria-pressed="true"] { color: #bff8df; border-color: rgba(126,233,189,.55); background: rgba(67,178,132,.12); }
.ciel-admin.ciel-verrouille .ciel-admin-etat i { color: #7ee9bd; background: currentColor; box-shadow: 0 0 10px currentColor; }

.chat {
  position: fixed;
  z-index: 12;
  left: 24px;
  bottom: 24px;
  width: 380px;
  overflow: hidden;
  background: rgba(3,14,20,.76);
  border: 1px solid rgba(114,211,228,.18);
  backdrop-filter: blur(10px);
  transition: height .2s, opacity .2s;
}
.chat > header { display: flex; justify-content: space-between; align-items: center; padding: 0 7px 0 10px; border-bottom: 1px solid rgba(118,211,227,.12); }
.chat-tabs { display: flex; gap: 4px; }
.chat-tabs button, #chat-collapse, #chat-mute-all { padding: 9px 6px 7px; color: #68848d; background: none; border: 0; border-bottom: 2px solid transparent; font-size: 7px; font-weight: 900; letter-spacing: .11em; }
.chat-tabs button.active { color: var(--cyan); border-bottom-color: var(--cyan); }
.chat-header-actions { display:flex; align-items:center; gap:2px; }
#chat-mute-all.active { color:#ff9a7e; border-bottom-color:#ff745f; }
#chat-collapse { font-size: 13px; }
.chat-log { height: 144px; overflow: auto; padding: 9px 11px; scrollbar-width: thin; scrollbar-color: rgba(99,205,224,.3) transparent; }
.chat-message { display: grid; grid-template-columns: auto 1fr; column-gap: 6px; margin: 0 0 6px; font-size: 9px; line-height: 1.35; }
.chat-message time { grid-column: 1; color: #536b73; font-size: 7px; }
.chat-message b { color: var(--message-color, #9cecff); font-size: 8px; }
.chat-message p { grid-column: 2; margin: 1px 0 0; color: #b7ccd2; user-select: text; overflow-wrap: anywhere; }
.chat-message.system { display: block; color: #66838c; font-size: 8px; font-style: italic; }
.chat form { display: grid; grid-template-columns: auto 1fr 32px; align-items: center; padding: 7px; background: rgba(0,0,0,.2); border-top: 1px solid rgba(118,211,227,.1); }
.chat form label { padding: 0 8px 0 3px; color: var(--cyan); font-size: 7px; font-weight: 900; }
.chat input { min-width: 0; padding: 7px 6px; color: #e8fbff; background: transparent; border: 0; outline: 0; font-size: 9px; user-select: text; }
.chat form button { width: 28px; height: 26px; color: #09202a; background: var(--cyan); border: 0; }
.chat.collapsed .chat-log, .chat.collapsed form { display: none; }

.voice-dock { position: fixed; z-index: 12; right: 24px; bottom: 24px; display: flex; gap: 8px; align-items: center; }
#voice-toggle { display: flex; gap: 9px; align-items: center; min-width: 158px; padding: 8px 11px; color: #88a4ad; background: rgba(3,15,22,.79); border: 1px solid rgba(115,211,229,.18); backdrop-filter: blur(9px); }
#voice-toggle:hover { color: #dffaff; border-color: rgba(106,230,253,.42); }
#voice-toggle[aria-pressed="true"] { color: #dffaff; border-color: rgba(95,237,159,.55); }
.mic-icon { display: grid; place-items: center; width: 25px; height: 25px; border: 1px solid currentColor; border-radius: 50%; font-size: 8px; }
#voice-toggle[aria-pressed="true"] .mic-icon { color: #5def9e; box-shadow: 0 0 12px rgba(93,239,158,.25); }
#voice-toggle > span:last-child { display: grid; text-align: left; }
#voice-toggle b { font-size: 8px; letter-spacing: .11em; }
#voice-toggle small { margin-top: 2px; color: #5f7982; font-size: 6px; letter-spacing: .08em; }
.voice-level { display: flex; gap: 2px; align-items: center; height: 28px; padding: 0 7px; background: rgba(3,15,22,.68); }
.voice-level i { display: block; width: 2px; height: 5px; background: #52717a; transition: height .08s, background .08s; }
.voice-level.live i { background: #5def9e; }
.voice-level.live i:nth-child(2) { height: 11px; }.voice-level.live i:nth-child(3) { height: 17px; }.voice-level.live i:nth-child(4) { height: 8px; }

.toast-stack { position: fixed; z-index: 60; right: 296px; top: 104px; display: grid; gap: 7px; width: 300px; pointer-events: none; }
.toast { position: relative; padding: 11px 13px 11px 35px; color: #ccecf3; background: rgba(5,21,29,.94); border: 1px solid rgba(108,219,238,.22); box-shadow: 0 9px 34px rgba(0,0,0,.35); font-size: 8px; line-height: 1.45; animation: toast-in .23s ease both; }
.toast::before { content: "◆"; position: absolute; left: 12px; color: var(--toast-color, var(--cyan)); }
.toast strong { display: block; margin-bottom: 2px; color: #fff; font-size: 8px; letter-spacing: .09em; }
.toast.out { animation: toast-out .2s ease both; }
@keyframes toast-in { from { opacity: 0; transform: translateX(22px); } }
@keyframes toast-out { to { opacity: 0; transform: translateX(22px); } }

.speech-bubble {
  position: fixed;
  z-index: 4;
  max-width: 170px;
  padding: 5px 8px;
  color: #fff;
  background: linear-gradient(135deg, rgba(31,87,102,.72), rgba(2,13,18,.82));
  border: 1px solid rgba(153,235,250,.55);
  box-shadow: 0 0 14px rgba(94,220,245,.22), inset 0 0 14px rgba(94,220,245,.08);
  transform: translate(-50%, -100%);
  font-size: 8px;
  line-height: 1.3;
  pointer-events: none;
  transition: opacity .2s;
  text-shadow: 0 0 5px rgba(255,255,255,.6);
}
.speech-bubble::after { content: ""; position: absolute; left: calc(50% - 3px); bottom: -4px; width: 6px; height: 6px; background: inherit; border-right: 1px solid rgba(124,219,235,.25); border-bottom: 1px solid rgba(124,219,235,.25); transform: rotate(45deg); }

.loading-screen { position: fixed; z-index: 100; inset: 0; display: grid; place-content: center; justify-items: center; background: #050e14; transition: opacity .5s; }
.loading-screen.done { opacity: 0; pointer-events: none; }
.loading-screen strong { margin-top: 16px; font-size: 25px; letter-spacing: .3em; text-indent: .3em; }
.loading-screen span { margin-top: 6px; color: #60808a; font-size: 7px; font-weight: 800; letter-spacing: .32em; text-indent: .32em; }
.loading-mark { display: flex; gap: 7px; align-items: center; height: 30px; }
.loading-mark i { display: block; width: 7px; height: 7px; background: var(--cyan); transform: rotate(45deg); animation: loading 1s ease-in-out infinite; }
.loading-mark i:nth-child(2) { animation-delay: .12s; }.loading-mark i:nth-child(3) { animation-delay: .24s; }
@keyframes loading { 0%,100% { opacity: .25; transform: rotate(45deg) scale(.7); } 50% { opacity: 1; transform: rotate(45deg) scale(1.25); box-shadow: 0 0 16px var(--cyan); } }

/* La pile de chargement. `position: absolute` porte sur `.loading-screen`, qui
   est en `fixed` — elle sort donc de la grille centree sans la deranger, et se
   pose en bas a gauche. Elle part avec l'ecran : rien a cacher ensuite, donc
   rien a inscrire dans la liste `.immersive`. */
.loading-pile { position: absolute; left: 22px; bottom: 20px; display: flex; align-items: center; gap: 9px; }
/* Le temoin prend la place que la pile vient de liberer : meme coin, meme
   dessin, pour qu'il se lise comme le meme objet qui continue. `fixed` et non
   `absolute` — son parent est `body`, qui n'est pas positionne. Sous l'ecran de
   chargement (z-index 100), qui doit le couvrir tant qu'il est la. */
.temoin-pret { position: fixed; z-index: 90; left: 22px; bottom: 20px; display: flex; align-items: center; gap: 9px; transition: opacity .6s; }
.temoin-pret.parti { opacity: 0; pointer-events: none; }
.loading-pile .pile-corps, .temoin-pret .pile-corps { position: relative; box-sizing: border-box; width: 48px; height: 20px; padding: 2px; border: 2px solid var(--cyan); border-radius: 4px; }
/* La borne de la pile, a droite du corps. */
.loading-pile .pile-corps::after, .temoin-pret .pile-corps::after { content: ""; position: absolute; left: 100%; top: 50%; width: 3px; height: 8px; background: var(--cyan); border-radius: 0 2px 2px 0; transform: translateY(-50%); }
.loading-pile .pile-corps i, .temoin-pret .pile-corps i { display: block; width: 0; height: 100%; background: var(--cyan); border-radius: 1px; transition: width .35s ease-out; }
/* `tabular-nums` : sans quoi la largeur du nombre saute a chaque chiffre et la
   pile tremble pendant tout le chargement. */
.loading-pile em, .temoin-pret em { color: var(--cyan); font-size: 11px; font-style: normal; font-weight: 800; letter-spacing: .1em; font-variant-numeric: tabular-nums; }
/* Tant que la ville monte, le remplissage respire : il n'y a pas de
   pourcentage honnete a afficher a ce moment-la — on ne sait pas combien de GLB
   restent a venir — et une barre figee se lirait comme un blocage. */
.temoin-pret.monte .pile-corps i { animation: temoin-respire 1.4s ease-in-out infinite; }
@keyframes temoin-respire { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
/* Le vert du « pret » : la seule couleur du temoin qui ne soit pas le cyan,
   parce que c'est la seule information qu'on veut lire sans la chercher. */
.temoin-pret.pret .pile-corps { border-color: #7ef0a8; }
.temoin-pret.pret .pile-corps::after, .temoin-pret.pret .pile-corps i { background: #7ef0a8; }
.temoin-pret.pret em { color: #7ef0a8; }

@media (max-width: 900px) {
  .topbar { grid-template-columns: 80px 1fr 130px; padding: 0 12px; }
  .population { min-width: 0; }.population span, .population small { display: none; }
  .directory { left: 10px; top: 88px; transform: scale(.86); transform-origin: top left; }
  .radar-card { right: 10px; top: 88px; transform: scale(.78); transform-origin: top right; }
  .controls-hint { display: none; }
  .chat { left: 10px; bottom: 10px; width: min(360px, calc(100vw - 20px)); }
  .voice-dock { right: 10px; bottom: 10px; }
  .action-dock { right: 10px; bottom: 64px; }
  .option-grid{grid-template-columns:repeat(4,1fr)}
}

@media (max-width: 640px) {
  .brand-kicker { display: none; }.brand strong { font-size: 19px; }
  .radar-card { display: none; }
  .directory { width: 188px; }
  .chat { width: calc(100vw - 20px); }
  .voice-dock { bottom: 220px; }.chat.collapsed + .voice-dock { bottom: 60px; }
  .action-dock { bottom: 270px; }
  .service-grid { grid-template-columns: 1fr; }
  .hub-customizer { grid-template-columns:1fr; }.skin-preview{min-height:245px}.weapon-skins>div{grid-template-columns:1fr 1fr}
  .social-card { right: 10px; top: 100px; width: calc(100vw - 20px); }
  .location-panel { padding: 18px; }
  .options-panel{padding:18px}.option-grid{grid-template-columns:repeat(3,1fr)}.option-card{min-height:92px;padding:9px}
  .ciel-admin{padding:18px}.ciel-admin-corps{grid-template-columns:1fr}.ciel-admin-phases{grid-template-columns:1fr 1fr}
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* Exploration immersive : seules la mini-map et les interfaces ouvertes par
   une action volontaire sont visibles.

   **`.combat-hud` n'en fait pas partie, et ne doit jamais y revenir.** Ce mode
   cache le mobilier de la *ville* — annuaire, portefeuille, barre d'actions,
   bandeau du haut. La structure et les six sorts ne sont pas du mobilier de
   ville : ce sont les deux seules choses que le joueur doit pouvoir lire pour
   se battre. `hub.html` le dit au-dessus du bloc — « jamais masqués […] en
   ville comme en duel » — et `body` porte `immersive` en dur, sans bascule :
   les mettre dans cette liste ne les cachait donc pas « en exploration », cela
   les cachait **tout le temps**. Les quatre sorts de classe partaient et le
   joueur n'en voyait ni l'icône, ni la recharge. */
/* `.toast-stack` a été retiré de cette liste le 18 août 2026, et c'est la
   quatrième fois que le même piège se referme ici (barre des sorts, boussole,
   bourse). Les notifications sont le **seul** retour du hub : achat confirmé,
   duel remporté, boulons insuffisants, PVP activé, défi reçu — une quarantaine
   d'appels à `toast()`. Aucun ne s'est jamais affiché. Rien ne le signalait :
   la fonction construit son nœud, l'ajoute, le retire au bout de trois
   secondes, et tout cela dans un conteneur en `display:none`. */
.immersive .topbar,.immersive .directory,.immersive .guide,.immersive .controls-hint,.immersive .action-dock,.immersive .interaction-prompt,.immersive .voice-dock{display:none!important}
.immersive .chat{display:none}.immersive .chat.open{display:block}
.immersive .radar-card{display:block;top:16px;right:16px;width:210px;opacity:.68;transform:none;transform-origin:top right;cursor:pointer;transition:width .28s,opacity .22s,background .22s;box-shadow:0 8px 28px rgba(0,0,0,.22)}
.immersive .radar-card:hover,.immersive .radar-card.expanded{opacity:1}
.immersive .radar-card.expanded{z-index:36;width:min(720px,calc(100vw - 32px));background:#0b2029;box-shadow:0 18px 80px rgba(0,0,0,.58)}
.immersive #hub-radar{width:100%;height:auto;aspect-ratio:640/404}
.immersive .radar-card:not(.expanded) .radar-legend{display:none}
.immersive .radar-card:not(.expanded) .radar-head>span{display:none}
.immersive .radar-card:not(.expanded) .radar-head{padding:6px 7px}
.immersive .radar-card:not(.expanded) .radar-head b{font-size:6px}
.immersive .toast-stack{top:16px;right:242px}
.immersive:has(.radar-card.expanded) .toast-stack{top:auto;right:16px;bottom:16px}
@media(max-width:640px){
  .immersive .radar-card{top:10px;right:10px;width:155px}
  .immersive .radar-card.expanded{width:calc(100vw - 20px)}
  .immersive .toast-stack{top:174px;right:10px;width:min(300px,calc(100vw - 20px))}
  .immersive:has(.radar-card.expanded) .toast-stack{top:auto;right:10px;bottom:10px}
}

/* La console de calage a sa propre feuille depuis le 16 août 2026 :
   src/ui/decorFit.css, chargée par hub.html ET index.html. */


/* --------------------------------------------------------------- HUD mobile
 * Les deux commandes du coin haut droit d'un panneau déplaçable
 * (`src/hub/hudFit.js`) : la poignée — un carré scindé en quatre — et le
 * verrou. Elles ne se montrent qu'au survol : un HUD de combat n'est pas un
 * panneau de réglage, et le reste du temps il ne doit rien afficher d'autre que
 * ce qu'il mesure. `:focus-within` les garde visibles à la navigation au
 * clavier, où il n'y a pas de survol. */
.hud-commandes {
  position: absolute; top: 2px; right: 2px; z-index: 2;
  display: flex; gap: 2px;
  opacity: 0; transition: opacity .14s ease-out; pointer-events: none;
}
.combat-hud:hover .hud-commandes,
.combat-hud:focus-within .hud-commandes,
.hud-en-main .hud-commandes { opacity: 1; pointer-events: auto; }

.hud-commandes button {
  display: grid; place-items: center;
  width: 13px; height: 13px; padding: 0;
  border: 1px solid rgba(255,213,208,.24);
  background: rgba(8,4,4,.72);
  color: #c8a5a1;
  cursor: pointer;
}
.hud-commandes button:hover:not(:disabled) { color: #ffd5d0; border-color: rgba(255,112,91,.6); }
.hud-commandes button:focus-visible { outline: 1px solid #ff705b; outline-offset: 1px; }
.hud-commandes svg { width: 8px; height: 8px; fill: currentColor; }
.hud-poignee { cursor: grab; }
.hud-en-main .hud-poignee { cursor: grabbing; }
/* La poignée d'étirement porte le curseur de redimensionnement en diagonale :
   c'est lui qui annonce le geste avant qu'on l'essaie. */
.hud-etirer { cursor: nwse-resize; }
.hud-etirer:disabled { cursor: default; }
/* Verrouillé, la poignée reste **visible** et se contente d'être éteinte : la
 * faire disparaître laisserait croire que le panneau n'a jamais été mobile. */
.hud-commandes button:disabled { cursor: not-allowed; opacity: .3; }
.hud-fige .hud-verrou { color: #ff705b; border-color: rgba(255,112,91,.5); }

@media (prefers-reduced-motion: reduce) {
  .hud-commandes { transition: none; }
}

/* Les outils de caméra du hub — en bas à droite, comme en duel.
 *
 * Mêmes cotes et même dessin que `.cam-tools` de l'arène : c'est la même
 * commande, et deux boutons de bascule de vue qui ne se ressemblent pas
 * obligeraient à réapprendre l'interface en changeant d'écran. La seule
 * différence est l'ancrage — l'arène pose les siens dans le cadre de la scène,
 * le hub est en plein écran. */
.cam-tools {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 6;
  display: flex;
  gap: 8px;
}

.cam-tools button {
  width: 38px;
  height: 38px;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: rgba(17, 19, 29, .72);
  border: 1px solid rgba(120, 134, 170, .35);
  backdrop-filter: blur(6px);
  color: #cfe9f2;
  cursor: pointer;
}

.cam-tools button svg { width: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.cam-tools button:hover { background: rgba(38, 44, 66, .85); }
.cam-tools button[aria-pressed="true"] { border-color: #66e7ff; color: #66e7ff; }

.cam-tools #hub-view-mode {
  width: auto;
  min-width: 78px;
  padding: 0 10px;
  grid-auto-flow: column;
  gap: 6px;
  font: 700 11px/1 var(--afficheur, ui-monospace, monospace);
  letter-spacing: .04em;
}

.cam-tools #hub-view-mode svg { width: 18px; }

/* La lecture de performance (F3). Posee en haut a gauche, sous la barre du
   haut, et volontairement sobre : elle doit se lire d'un coup d'oeil et se
   recopier dans un message. Elle n'entre PAS dans la liste `.immersive` — le
   piege documente quatre fois dans CLAUDE.md — parce qu'elle a son propre
   interrupteur. */
.perf-lecture { position: fixed; z-index: 70; left: 16px; top: 92px; padding: 9px 12px; color: #cfe9f2;
  background: rgba(5,21,29,.92); border: 1px solid rgba(108,219,238,.28); font-size: 9px; line-height: 1.75;
  letter-spacing: .06em; white-space: pre; pointer-events: none; }
.perf-lecture b { color: #7ee9bd; font-weight: 700; }
.perf-lecture i { color: #ffc253; font-style: normal; }


/* Le relevé réseau (F3) : des chiffres, lisibles, et rien d'autre.
   En haut à gauche, la seule zone que ni le panneau de combat ni la mini-map
   n'occupent. `pointer-events: none` — on lit par-dessus le jeu, on ne clique
   jamais dessus. */
#releve-reseau {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 60;
  margin: 0;
  padding: 8px 12px;
  font: 12px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: #b6f5d8;
  background: rgba(6, 14, 18, .78);
  border: 1px solid rgba(126, 233, 189, .35);
  border-radius: 8px;
  white-space: pre;
  pointer-events: none;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
}
/* Le diagnostic de cadence : il dit pourquoi, pas seulement combien. */
.option-diagnostic{color:#a8c4cd;border-left:2px solid rgba(255,212,121,.5);padding-left:8px}
