/* ==========================================================================
   LASTBORDER — habillage « HUD tactique ».

   Trois partis pris tiennent tout le reste :

   1. Les panneaux sont a coins coupes (clip-path). Un clip-path rogne aussi
      la bordure : le liseré est donc peint par le fond de l'element, et le
      ::before (retire d'1.5 px, meme decoupe) pose la vraie matiere par
      dessus. D'ou `isolation:isolate` + `z-index:-1` un peu partout.
   2. Les chiffres sont en fonte a chasse fixe et tabulaire : un compteur qui
      change ne doit jamais faire bouger ce qui l'entoure.
   3. Aucun `backdrop-filter` au-dessus du terrain : le canvas change a chaque
      image et le refloutage couterait tres cher en GPU. Les overlays plein
      ecran (accueil, options, fin) y ont droit, le jeu y est fige.
   ========================================================================== */

/* ============================================================ base */
:root{
  --bg:#05070d;
  --panel:#0b111c;
  --panel2:#111a29;
  --panel3:#1a2537;
  --line:#22314a;
  --line2:#314566;
  --txt:#e8f0fb;
  --dim:#7f92ad;
  --acc:#3ff2a4;          /* vert « signal » : action, soi, succes */
  --acc2:#4dd8ff;         /* cyan : information secondaire */
  --warn:#ffb03a;         /* ambre : hote, avertissement */
  --danger:#ff3b5c;
  --ink:#03150e;          /* texte pose sur l'accent */

  --f-ui:"Bahnschrift","DIN Alternate","Segoe UI",Inter,system-ui,sans-serif;
  --f-num:ui-monospace,"Cascadia Mono",Consolas,"SF Mono",monospace;

  --cut:12px;             /* coin coupe des panneaux */
  --cut-s:8px;            /* coin coupe des cartes et boutons */
  --radius:4px;
  --r-xl:0px;
  --r-lg:6px;
  --r-md:4px;
  --side:400px;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg);color:var(--txt);overflow:hidden;
  font:15px/1.5 var(--f-ui);
  -webkit-font-smoothing:antialiased;
}
button,input{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
.hidden{display:none !important}
kbd{
  font:600 12px/1 var(--f-num);background:#080d15;
  border:1px solid var(--line);border-bottom-width:2px;border-radius:3px;
  padding:3px 5px;color:var(--dim);
}

/* coins coupes : haut-droit et bas-gauche, la diagonale donne la lecture
   « materiel militaire » sans qu'aucune image ne soit chargee */
.cut,.hud-card,.panel,.opt-row,.er,.lp,.code-box,.cs-box,.bf-box,
.cs-cell,.lobby-box,.end-box,.opt-box,.row button,.opt-actions button,
.end-actions button,.go-actions button,.go-box,
#csConfirm,#toast,#zoomHud{
  --c:var(--cut-s);
  clip-path:polygon(0 0,calc(100% - var(--c)) 0,100% var(--c),
                    100% 100%,var(--c) 100%,0 calc(100% - var(--c)));
}
.panel,.lobby-box,.end-box,.opt-box,.cs-box,.bf-box,.go-box{--c:var(--cut)}

#app{display:flex;height:100vh;width:100vw}

/* ============================================================ terrain */
#stage{
  position:relative;flex:1;min-width:0;overflow:hidden;
  background:
    radial-gradient(1000px 680px at 50% -10%,#0f1c2c 0%,transparent 68%),
    radial-gradient(760px 540px at 16% 108%,#0b1826 0%,transparent 70%),
    #04060b;
}
#board{position:absolute;inset:0;display:block;cursor:crosshair}

/* lignes de balayage + trame : tres discretes (l'opacite fait tout le
   travail), elles suffisent a donner l'impression d'un ecran de console */
#scan,#vign{position:absolute;inset:0;pointer-events:none;z-index:2}
#scan{
  background:repeating-linear-gradient(
    0deg,rgba(255,255,255,.028) 0 1px,transparent 1px 3px);
  mix-blend-mode:overlay;opacity:.5;
}
#vign{
  box-shadow:inset 0 0 190px 20px rgba(0,0,0,.75),
             inset 0 0 0 1px rgba(63,242,164,.05);
  background:
    linear-gradient(180deg,rgba(4,8,14,.45),transparent 16%,transparent 84%,rgba(4,8,14,.5));
}

/* ---- HUD ---- */
#hud{
  position:absolute;top:14px;left:14px;display:flex;gap:8px;z-index:3;
  pointer-events:none;flex-wrap:wrap;max-width:calc(100% - 28px);
}
.hud-card{
  position:relative;isolation:isolate;
  display:flex;align-items:center;gap:10px;
  background:var(--line);            /* = liseré, le ::before pose la matiere */
  padding:8px 15px 8px 11px;min-width:104px;
  box-shadow:0 14px 30px rgba(0,0,0,.6);
}
.hud-card::before{
  content:"";position:absolute;inset:1.5px;z-index:-1;
  clip-path:inherit;
  background:linear-gradient(160deg,rgba(17,26,41,.97),rgba(7,11,18,.97));
}
/* liseré vert sur le bord gauche : repere l'oeil sans ajouter d'element */
.hud-card::after{
  content:"";position:absolute;left:0;top:var(--c);bottom:0;width:2px;
  background:linear-gradient(180deg,var(--acc),transparent);opacity:.65;
}
.hud-card .ic{
  font-size:16px;line-height:1;color:var(--acc);opacity:.75;
  text-shadow:0 0 12px rgba(63,242,164,.6);
}
.hud-txt{display:block;min-width:0}
.hud-card .lbl{
  display:block;font-size:9.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--dim);margin-bottom:2px;font-weight:600;
}
.hud-card b{
  display:block;font:700 21px/1 var(--f-num);font-variant-numeric:tabular-nums;
  letter-spacing:.02em;color:#f2f8ff;text-shadow:0 0 16px rgba(120,190,255,.25);
}
#hudRoom b{color:var(--acc);letter-spacing:.24em;
  text-shadow:0 0 18px rgba(63,242,164,.45)}
#hudMe b{font-family:var(--f-ui);font-size:17px;letter-spacing:.02em}
#hudMines b{color:var(--warn);text-shadow:0 0 16px rgba(255,176,58,.35)}
.dot{width:11px;height:11px;border-radius:50%;background:#5b6a80;
  display:inline-block;box-shadow:0 0 12px currentColor,
  inset 0 0 0 1.5px rgba(0,0,0,.45)}

#zoomHud{
  position:absolute;right:14px;bottom:14px;pointer-events:none;z-index:3;
  display:flex;align-items:baseline;gap:8px;
  background:rgba(9,14,23,.94);border:1px solid var(--line);
  padding:6px 13px;font-size:12.5px;color:var(--dim);
}
#zoomHud i{font-style:normal;font-size:9.5px;letter-spacing:.2em;
  text-transform:uppercase}
#zoomHud span{color:var(--acc);font:700 13px/1 var(--f-num);
  font-variant-numeric:tabular-nums}

/* ---- penalite ---- */
/* derniere minute d'operation : le chrono passe au rouge, comme la penalite */
#hudTime.low b{color:var(--danger)}
#hudTime.low .ic{color:var(--danger);animation:blink 1s steps(1) infinite}

#penalty{
  position:absolute;inset:0;display:flex;flex-direction:column;z-index:4;
  align-items:center;justify-content:center;gap:16px;pointer-events:none;
  background:
    radial-gradient(circle at 50% 50%,transparent 26%,rgba(140,0,20,.36) 100%),
    repeating-linear-gradient(45deg,rgba(255,59,92,.05) 0 12px,transparent 12px 24px);
  animation:penPulse 1s ease-in-out infinite;
}
@keyframes penPulse{0%,100%{opacity:.85}50%{opacity:1}}
.pen-ring{
  width:140px;height:140px;border-radius:50%;
  border:3px solid var(--danger);display:grid;place-items:center;
  font:800 56px/1 var(--f-num);color:#fff;
  background:rgba(34,0,8,.6);
  box-shadow:0 0 80px rgba(255,59,92,.55),inset 0 0 50px rgba(255,59,92,.35);
}
/* second anneau qui bat : le compte a rebours se lit d'un coup d'oeil */
.pen-ring::after{
  content:"";position:absolute;width:172px;height:172px;border-radius:50%;
  border:1px solid rgba(255,59,92,.45);animation:penRing 1s ease-out infinite;
}
@keyframes penRing{from{transform:scale(.86);opacity:.9}to{transform:scale(1.1);opacity:0}}
.pen-txt{letter-spacing:.5em;text-indent:.5em;font-weight:800;font-size:15px;
  color:var(--danger);text-shadow:0 0 20px rgba(255,59,92,.85)}

/* ---- toast ---- */
#toast{
  position:fixed;left:50%;top:92px;transform:translateX(-50%);z-index:95;
  background:rgba(24,10,16,.96);border-left:3px solid var(--danger);
  padding:11px 20px;font-size:14px;font-weight:600;letter-spacing:.02em;
  box-shadow:0 16px 38px rgba(0,0,0,.7),0 0 34px rgba(255,59,92,.16);
  animation:toastIn .18s ease;pointer-events:none;
}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,-8px)}}

#tips{
  position:absolute;bottom:13px;left:50%;transform:translateX(-50%);z-index:3;
  font-size:12px;color:var(--dim);background:rgba(8,12,20,.94);
  padding:8px 20px;border:1px solid var(--line);border-left:2px solid var(--acc2);
  pointer-events:none;white-space:nowrap;letter-spacing:.02em;
}
#tips b{color:#cfe0f4;font-weight:700}

/* ============================================================ panneau */
#side{
  width:var(--side);flex:none;display:flex;flex-direction:column;gap:10px;
  padding:12px;background:linear-gradient(180deg,#090e17,#06090f);
  border-left:1px solid var(--line);box-shadow:-18px 0 48px rgba(0,0,0,.65);
  position:relative;
}
/* filet lumineux le long de la separation : la colonne parait allumee */
#side::before{
  content:"";position:absolute;left:-1px;top:0;bottom:0;width:1px;
  background:linear-gradient(180deg,transparent,rgba(63,242,164,.45),transparent);
}
#brand{display:flex;align-items:center;gap:11px;padding:2px 2px 4px}
.brand-txt{flex:1;min-width:0}
.logo{
  width:44px;height:44px;display:grid;place-items:center;flex:none;
  position:relative;overflow:hidden;
  font-size:23px;background:linear-gradient(150deg,#1d2b3f,#0d1420);
  border:1px solid var(--line2);box-shadow:0 8px 22px rgba(0,0,0,.6),
  inset 0 1px 0 rgba(255,255,255,.08);
  clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,100% 100%,8px 100%,0 calc(100% - 8px));
}
/* l'icone recouvre le degrade et le glyphe de repli. Le coin coupe du HUD
   mange deja la marge de l'icone : un leger zoom evite de rogner la tour. */
.logo img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;transform:scale(1.08);
}
#brand h1{font-size:17px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
#brand h1 em{font-style:normal;color:var(--acc);margin-left:.35em;
  text-shadow:0 0 16px rgba(63,242,164,.4)}
#brand p{font-size:11px;color:var(--dim);letter-spacing:.1em;text-transform:uppercase}
#brand b{color:var(--acc);letter-spacing:.26em;font:700 13px/1 var(--f-num)}
#btnOptions{
  width:40px;height:40px;flex:none;font-size:19px;
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  transition:.15s;
  clip-path:polygon(0 0,calc(100% - 7px) 0,100% 7px,100% 100%,7px 100%,0 calc(100% - 7px));
}
#btnOptions:hover{color:var(--acc);background:var(--panel3);transform:rotate(45deg)}

.panel{
  position:relative;isolation:isolate;
  background:var(--line);            /* liseré */
  padding:13px 14px 14px;
  box-shadow:0 12px 28px rgba(0,0,0,.45);
}
.panel::before{
  content:"";position:absolute;inset:1px;z-index:-1;clip-path:inherit;
  background:linear-gradient(170deg,#0e1725,#080d15);
}
.panel.grow{flex:1;display:flex;flex-direction:column;min-height:0}
.panel h2{
  display:flex;align-items:center;gap:9px;
  font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--acc2);margin-bottom:12px;font-weight:700;
}
/* chevron + filet : l'entete se lit comme un intitule de console, et le
   filet mange l'espace restant quel que soit le titre */
.panel h2::before{content:"▍";color:var(--acc);font-size:12px;margin-right:-3px}
.panel h2::after{
  content:"";flex:1;height:1px;
  background:linear-gradient(90deg,rgba(77,216,255,.35),transparent);
}

/* ---- scores ---- */
/* la colonne est fixe : si le classement se remplit, c'est lui qui defile,
   pas la page — le radar et les transmissions restent en place */
#scores{counter-reset:rank;overflow-y:auto;max-height:52vh}
.score{counter-increment:rank;margin-bottom:11px;
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:11px;align-items:center}
.score-body{min-width:0}
.score:last-child{margin-bottom:2px}
.score-top{display:flex;align-items:center;gap:8px;margin-bottom:6px}
/* le rang vient d'un compteur CSS : les lignes sont reordonnees par le JS,
   rien a mettre a jour ici */
.score-top::before{
  content:counter(rank);flex:none;width:19px;height:19px;
  display:grid;place-items:center;font:700 11px/1 var(--f-num);
  color:var(--dim);background:rgba(255,255,255,.05);
  border:1px solid var(--line);
}
.score:first-child .score-top::before{
  color:var(--ink);background:var(--warn);border-color:var(--warn);
  box-shadow:0 0 16px rgba(255,176,58,.5);
}
.score-top .dot{width:10px;height:10px;flex:none}
.score-name{flex:1;font-size:14.5px;font-weight:700;letter-spacing:.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.score-name.me::after{content:" ▸ vous";color:var(--acc);font-weight:600;font-size:11px;
  letter-spacing:.1em}
.score-val{font:700 17px/1 var(--f-num);font-variant-numeric:tabular-nums}
.score-sub{font-size:11.5px;color:var(--dim);margin-top:5px;display:flex;
  gap:10px;justify-content:space-between;letter-spacing:.02em}
.bar{
  height:10px;background:#0a1019;position:relative;overflow:hidden;
  border:1px solid rgba(255,255,255,.06);
  box-shadow:inset 0 1px 4px rgba(0,0,0,.8);
}
/* cranelage : la jauge se lit comme un indicateur segmente */
.bar::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(
    90deg,transparent 0 7px,rgba(4,7,12,.85) 7px 9px);
}
.bar i{
  position:absolute;inset:0;width:0;
  transition:width .5s cubic-bezier(.22,1,.36,1);
  box-shadow:0 0 16px currentColor;
}
.score.off{opacity:.42}
.badge{font-size:10.5px}
.badge-pen{
  font:700 10.5px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  background:rgba(255,59,92,.16);color:#ff8b9d;
  border:1px solid rgba(255,59,92,.45);padding:3px 7px;
}
.badge-win{
  font:700 10.5px/1 var(--f-ui);letter-spacing:.1em;text-transform:uppercase;
  background:rgba(63,242,164,.16);color:var(--acc);
  border:1px solid rgba(63,242,164,.45);padding:3px 7px;
  box-shadow:0 0 18px rgba(63,242,164,.28);
}

/* ---- radar ---- */
.radar-wrap{position:relative;line-height:0}
#radar{width:100%;height:auto;display:block;
  background:#060a11;border:1px solid var(--line);image-rendering:pixelated;
  cursor:crosshair;user-select:none}
/* equerres de visee aux quatre coins de la carte */
.radar-wrap::before,.radar-wrap::after{
  content:"";position:absolute;width:12px;height:12px;pointer-events:none;
  border:1px solid var(--acc);opacity:.7;
}
.radar-wrap::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.radar-wrap::after{bottom:-1px;right:-1px;border-left:0;border-top:0}

/* ---- chat ---- */
#chatLog{
  flex:1;overflow-y:auto;display:flex;flex-direction:column;
  gap:7px;padding:2px 6px 2px 2px;min-height:120px;
}
#chatLog::-webkit-scrollbar{width:6px}
#chatLog::-webkit-scrollbar-thumb{background:#233350}
#chatLog::-webkit-scrollbar-track{background:transparent}

/* La tete de l'auteur borde la bulle du cote d'ou vient la parole : a gauche
   pour l'interlocuteur, a droite pour soi. La rangee est donc simplement
   retournee, elle n'est pas ecrite deux fois. */
.msg{display:flex;align-items:flex-end;gap:8px;max-width:92%;
  animation:msgIn .2s ease}
@keyframes msgIn{from{opacity:0;transform:translateY(6px) scale(.97)}}
.msg-body{display:flex;flex-direction:column;min-width:0}
.msg.them{align-self:flex-start}
.msg.them .msg-body{align-items:flex-start}
.msg.me{align-self:flex-end;flex-direction:row-reverse}
.msg.me .msg-body{align-items:flex-end}
.msg-face{
  flex:none;width:40px;height:40px;overflow:hidden;
  display:grid;place-items:center;
  background:radial-gradient(circle at 50% 32%,
    rgba(120,180,255,.14),rgba(4,8,14,.9) 72%);
  border:1px solid rgba(255,255,255,.08);
  clip-path:polygon(0 0,calc(100% - 7px) 0,100% 7px,
                    100% 100%,7px 100%,0 calc(100% - 7px));
}
.msg-face img{display:block;width:100%;height:100%;
  object-fit:cover;object-position:0% 100%;
  animation:faceLoop 1.05s steps(3) infinite}
/* dirigeant sans planche : sa carte, recadree sur le visage comme partout */
.msg-face.card img{object-fit:cover;object-position:50% 8%;animation:none}
/* les deux interlocuteurs se regardent : celle de droite est retournee */
.msg.me .msg-face img{transform:scaleX(-1)}
/* messages qui se suivent : la place reste prise pour que les bulles restent
   alignees, mais on ne repete ni le nom ni la tete */
.msg.tail .msg-face{visibility:hidden}
.msg .who{font-size:10.5px;font-weight:700;margin:0 4px 3px;
  letter-spacing:.14em;text-transform:uppercase}
.bubble{
  padding:8px 13px;font-size:14px;line-height:1.42;
  word-break:break-word;box-shadow:0 3px 12px rgba(0,0,0,.4);
}
.msg.them .bubble{
  background:#18222f;color:#e7f0fb;border-left:2px solid var(--line2);
  clip-path:polygon(0 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%);
}
.msg.me .bubble{
  font-weight:600;
  clip-path:polygon(0 0,100% 0,100% 100%,7px 100%,0 calc(100% - 7px));
}
.msg.tail .who{display:none}

#chatForm{display:flex;gap:8px;margin-top:10px}
#chatInput{
  flex:1;background:#0a111b;border:1px solid var(--line);
  padding:10px 14px;outline:none;font-size:14px;
  clip-path:polygon(0 0,100% 0,100% 100%,7px 100%,0 calc(100% - 7px));
  transition:border-color .16s,box-shadow .16s;
}
#chatInput::placeholder{color:#59688191;letter-spacing:.04em}
#chatInput:focus{border-color:var(--acc);box-shadow:0 0 0 2px rgba(63,242,164,.12)}
#chatSend{
  width:44px;background:linear-gradient(150deg,var(--acc),#17a373);color:var(--ink);
  font-size:15px;font-weight:800;box-shadow:0 4px 16px rgba(63,242,164,.3);
  clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,100% 100%,8px 100%,0 calc(100% - 8px));
  transition:filter .15s,transform .15s;
}
#chatSend:hover{filter:brightness(1.12)}
#chatSend:active{transform:scale(.94)}

/* la tete que l'on montrera en parlant : le bouton la porte, il n'y a donc
   pas de reglage cache — on voit ce qu'on va envoyer */
#chatMood{
  flex:none;width:42px;height:42px;padding:0;overflow:hidden;
  display:grid;place-items:center;font-size:19px;line-height:1;
  background:#0a111b;border:1px solid var(--line);
  clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,
                    100% 100%,8px 100%,0 calc(100% - 8px));
  transition:border-color .16s,transform .16s;
}
#chatMood img{display:block;width:100%;height:100%;
  object-fit:cover;object-position:0% 100%;
  animation:faceLoop 1.05s steps(3) infinite}
#chatMood.card img{object-fit:cover;object-position:50% 8%;animation:none}
#chatMood:hover{border-color:var(--acc)}
#chatMood:active{transform:scale(.94)}

/* posee au-dessus du champ, dans le panneau : c'est une surcouche locale, pas
   un plein ecran — le fil de discussion reste lisible derriere */
#moodPick{position:absolute;inset:0;z-index:6;display:flex;
  align-items:flex-end;padding:12px;background:rgba(3,6,11,.55)}
.mp-box{
  width:100%;background:var(--line);padding:1px;
  box-shadow:0 18px 40px rgba(0,0,0,.6);
  animation:slamUp .3s cubic-bezier(.16,.9,.3,1) both;
}
.mp-head{
  display:flex;align-items:center;gap:8px;
  padding:9px 8px 9px 12px;background:linear-gradient(170deg,#0e1725,#080d15);
}
.mp-head b{flex:1;font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--acc2);font-weight:700}
#mpClose{width:26px;height:26px;font-size:13px;color:var(--dim);
  background:rgba(255,255,255,.05);border:1px solid var(--line);
  transition:color .15s,border-color .15s}
#mpClose:hover{color:var(--danger);border-color:var(--danger)}
.mp-grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;
  background:var(--line);
}
.mp-cell{
  display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:7px 4px 6px;background:#080d15;border:0;
  transition:background .14s;
}
.mp-cell img{width:100%;max-width:58px;aspect-ratio:1;
  object-fit:cover;object-position:0% 100%;
  animation:faceLoop 1.05s steps(3) infinite}
.mp-cell i{font-style:normal;font-size:11px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--dim);max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mp-cell:hover{background:#111c2c}
.mp-cell.on{background:#132133;box-shadow:inset 0 0 0 1px var(--acc)}
.mp-cell.on i{color:var(--acc)}

#status{display:flex;align-items:center;gap:8px;font-size:10.5px;color:var(--dim);
  padding:2px 6px;letter-spacing:.2em;text-transform:uppercase;font-weight:600}
#status .dot{width:8px;height:8px;background:var(--acc);
  animation:blink 2s ease-in-out infinite}
#status .dot.off{background:var(--danger)}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.35}}

/* ============================================================ overlays */
#lobby,#endcard,#options{
  position:fixed;inset:0;display:grid;place-items:center;z-index:40;
  background:radial-gradient(900px 700px at 50% 40%,rgba(16,30,48,.6),rgba(2,4,8,.95));
  backdrop-filter:blur(8px);
}
#options{z-index:45}
/* dernier recours quand meme le panneau reduit ne tient pas (fenetre tres
   basse) : le fond defile plutot que de garder des boutons hors d'atteinte */
#lobby.scroll,#endcard.scroll,#options.scroll{
  place-items:start center;overflow:auto;padding:14px 0;
}
#lobby.scroll .fit,#endcard.scroll .fit,#options.scroll .fit{
  transform-origin:top center;      /* sinon la reduction laisse un vide en haut */
}

/* ---- accueil : decor anime derriere le panneau ---- */
#lobby{background:#03050a;backdrop-filter:none;overflow:hidden}
#menuFx{position:absolute;inset:0;display:block;z-index:0}
#lobby::before{                      /* lignes de balayage sur tout l'ecran */
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:repeating-linear-gradient(
    0deg,rgba(0,0,0,.28) 0 1px,transparent 1px 3px);
  opacity:.55;
}
#lobby::after{                       /* halo qui respire, sous le panneau */
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(760px 520px at 50% 46%,rgba(63,242,164,.11),transparent 68%),
             radial-gradient(620px 460px at 18% 88%,rgba(255,120,50,.09),transparent 70%);
  animation:breathe 9s ease-in-out infinite;
}
@keyframes breathe{0%,100%{opacity:.6}50%{opacity:1}}
#lobby .fit{position:relative;z-index:2}

.lobby-box,.end-box,.opt-box{
  position:relative;isolation:isolate;
  background:linear-gradient(150deg,var(--line2),var(--line) 40%,#16233a);
  padding:var(--bx-pt) clamp(20px,3.4vw,38px) var(--bx-pb);
  box-shadow:0 44px 110px rgba(0,0,0,.82),0 0 60px rgba(63,242,164,.06);
  animation:pop .28s cubic-bezier(.2,1.1,.4,1);
  /* pas d'ascenseur : les postes verticaux sont en clamp(min, vh, max) pour
     se tasser d'eux-memes, et si cela ne suffit pas .fit reduit le panneau
     entier a l'echelle (UI.fit) plutot que d'en rendre le bas inaccessible */
  --bx-pt:clamp(18px,3.4vh,38px);
  --bx-pb:clamp(14px,2.6vh,30px);
  width:100%;
}
.lobby-box::before,.end-box::before,.opt-box::before{
  content:"";position:absolute;inset:2px;z-index:-1;clip-path:inherit;
  background:linear-gradient(180deg,rgba(17,27,44,.97),rgba(6,10,17,.98));
}

/* enveloppe mise a l'echelle : le transform vit ici et non sur la boite,
   dont l'animation d'ouverture utilise deja transform */
.fit{
  position:relative;z-index:1;width:min(620px,94vw);
  transform-origin:center center;transition:transform .16s ease;
}
/* l'accueil porte le selecteur de dirigeant : il lui faut la largeur d'une
   borne d'arcade. La salle d'attente, elle, reste etroite */
#lobby .fit:has(#lobbyForm:not(.hidden)){width:min(1080px,96vw)}
@keyframes pop{from{opacity:0;transform:translateY(16px) scale(.97)}}

/* fenetre tres basse : le decor de l'entete part en premier, pour que la
   reduction d'echelle reste legere et le formulaire lisible */
@media (max-height:620px){
  .lobby-box .sub,.rs-bars,.rs-note,#rsFaces{display:none}
  .lobby-head{margin-bottom:8px}
}

/* halos colores derriere le panneau : la profondeur vient de la, pas d'une
   bordure lumineuse qui ferait vibrer le texte pose dessus */
.glow{
  position:absolute;border-radius:50%;pointer-events:none;z-index:0;
  filter:blur(90px);opacity:.45;
}
.glow.g1{top:-22%;right:-14%;width:58%;height:52%;background:rgba(63,242,164,.5)}
.glow.g2{bottom:-26%;left:-16%;width:54%;height:48%;background:rgba(255,120,50,.34)}
.lobby-box>*:not(.glow),.end-box>*,.opt-box>*{position:relative;z-index:1}

.lobby-head{text-align:center;margin-bottom:clamp(12px,2.8vh,30px)}
.sub{color:var(--dim);font-size:clamp(13px,1.7vh,16px);
  margin-top:clamp(6px,1.2vh,12px);line-height:1.55;letter-spacing:.02em}
/* en salle d'attente la table des joueurs prend toute la place : le
   sous-titre decoratif s'efface plutot que de pousser un ascenseur */
.lobby-box:has(#lobbyRoom:not(.hidden)) .sub{display:none}

/* ---- gros titre facon borne d'arcade -----------------------------------
   Un logo de jeu de combat, sans image : trois couches empilees sur le meme
   texte. Le ::before pose un contour epais (-webkit-text-stroke) puis
   l'extrusion, en pile de text-shadow pleines et non floues ; le mot lui-meme
   est un degrade decoupe (background-clip:text), qui interdit toute ombre,
   d'ou la couche separee. L'inclinaison est portee par le h1 pour que les
   deux lignes penchent ensemble. */
h1.title{
  display:flex;flex-direction:column;align-items:center;
  font-weight:900;line-height:.82;text-transform:uppercase;
  transform:skewX(-8deg);
  margin-bottom:clamp(4px,1vh,10px);
}
h1.title span{position:relative;display:block;white-space:nowrap}
h1.title span::before{
  content:attr(data-t);position:absolute;left:0;top:0;z-index:-1;
  letter-spacing:inherit;text-indent:inherit;
  color:#120409;
}

/* LAST : la ligne d'appel, etroite, acier */
h1.title .t1{
  font-size:clamp(19px,min(4.2vw,3.6vh),40px);
  letter-spacing:.42em;text-indent:.42em;
  background:linear-gradient(180deg,#ffffff 4%,#d7e6f7 40%,#7f9cbe 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
h1.title .t1::before{
  /* contour et extrusion en em : le titre est en clamp(), tout doit suivre */
  -webkit-text-stroke:.2em #120409;
  text-shadow:0 .06em 0 #120409,0 .1em 0 #120409,0 .14em .3em rgba(0,0,0,.9);
}

/* BORDER : le mot d'enseigne, or chaud borde de rouge */
h1.title .t2{
  font-size:clamp(40px,min(11.5vw,9.4vh),108px);
  letter-spacing:.01em;
  background:linear-gradient(180deg,
    #fff8d8 2%,#ffe066 26%,#ffb020 52%,#ff7a12 74%,#ffd66b 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 30px rgba(255,150,30,.35));
  animation:titleGlow 4.5s ease-in-out infinite;
}
h1.title .t2::before{
  -webkit-text-stroke:.17em #120409;
  /* l'extrusion : des copies pleines, de plus en plus sombres, decalees vers
     le bas — c'est ce qui donne le volume des logos de borne */
  text-shadow:
    0 .03em 0 #8d1220,0 .06em 0 #6d0d18,0 .09em 0 #4e0912,
    0 .12em 0 #33060c,0 .15em 0 #1d0407,0 .2em .32em rgba(0,0,0,.85);
}
/* liseré rouge entre le contour noir et l'or : deuxieme copie, contour plus
   fin, posee au-dessus du ::before et sous le degrade */
h1.title .t2::after{
  content:attr(data-t);position:absolute;left:0;top:0;z-index:-1;
  color:transparent;-webkit-text-stroke:.07em #d81f35;
}
@keyframes titleGlow{
  0%,100%{filter:drop-shadow(0 0 18px rgba(255,150,30,.3))}
  50%{filter:drop-shadow(0 0 40px rgba(255,120,20,.6))}
}

/* ---- selecteur de dirigeant, pose dans l'accueil -------------------------
   Trois zones : la carte a gauche entre deux fleches, le dossier a droite,
   la planche des dirigeants en dessous sur toute la largeur. --pick porte la
   couleur du dirigeant courant (posee en JS sur #lobby) et irrigue liseres,
   jauges et halos : aucune autre couleur a synchroniser. */
.rs{
  display:grid;gap:clamp(10px,2vh,20px) clamp(14px,2.2vw,26px);
  grid-template-columns:minmax(0,auto) minmax(0,1fr);
  margin-bottom:clamp(10px,2.2vh,20px);
}
#lobby{--pick:var(--acc)}

.rs-stage{display:flex;align-items:center;gap:clamp(4px,1vw,12px)}
.rs-arrow{
  flex:none;width:clamp(24px,3vw,34px);height:clamp(44px,9vh,86px);
  font-size:clamp(20px,3vh,30px);font-weight:900;line-height:1;
  color:var(--dim);background:rgba(255,255,255,.05);
  border:1px solid var(--line);
  transition:color .15s,background .15s,transform .15s,border-color .15s;
}
.rs-arrow:hover{color:var(--pick);border-color:var(--pick);
  background:rgba(255,255,255,.09);transform:scale(1.06)}
.rs-arrow:active{transform:scale(.94)}

/* la carte est un portrait 2:3 : sa hauteur est le poste vertical qui plie,
   la largeur suit — elle ne pousse donc jamais le panneau */
.rs-card{
  position:relative;flex:none;overflow:hidden;isolation:isolate;
  height:clamp(150px,30vh,300px);aspect-ratio:2 / 3;
  /* le clip-path rogne aussi la bordure : le liseré est donc le fond de la
     carte, la photo etant rentree de 2px (convention du reste du fichier) */
  background:var(--pick);padding:2px;
  clip-path:polygon(0 0,calc(100% - 16px) 0,100% 16px,
                    100% 100%,16px 100%,0 calc(100% - 16px));
  box-shadow:0 20px 46px rgba(0,0,0,.7),0 0 34px -8px var(--pick);
  transition:border-color .25s,box-shadow .25s;
}
.rs-card img{width:100%;height:100%;object-fit:cover;display:block;
  animation:pop .22s ease}
.rs-scan{                            /* balayage : la carte reste « a l'ecran » */
  position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(0deg,
    rgba(0,0,0,.24) 0 1px,transparent 1px 3px);
  mix-blend-mode:multiply;
}
.rs-tag{
  position:absolute;left:0;bottom:0;padding:5px 10px;
  font-size:12.5px;font-weight:800;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink);background:var(--pick);
}

.rs-file{display:flex;flex-direction:column;justify-content:center;
  gap:clamp(6px,1.2vh,12px);min-width:0}
/* Deux lignes fixes, le drapeau a cheval sur les deux : en rangee souple, un
   nom long (« Jean-Luc Melenchon », « Volodymyr Zelensky ») passait a la ligne
   et le dossier entier sautait d'un dirigeant a l'autre. La grille lui donne
   sa ligne, quelle que soit sa longueur. */
.rs-id{display:grid;grid-template-columns:auto minmax(0,1fr);
  align-items:baseline;column-gap:11px;row-gap:2px}
.rs-flag{grid-row:1 / span 2;align-self:center;line-height:0}

/* ------------------------------------------------------------- pavillons
   Le drapeau est une image et non l'emoji du catalogue : Windows ne rend pas
   les emoji drapeaux, il retombe sur les deux lettres du pays — « FR », lu a
   cote d'un nom, passe pour du texte et non pour un pavillon. Le fichier est
   en 4:3 : on ne fixe que la hauteur, la largeur suit, et un liseré le detache
   des fonds sombres comme des fonds clairs (le drapeau japonais est blanc). */
.flag-img{
  display:block;flex:none;height:1.15em;width:auto;
  border:1px solid rgba(255,255,255,.22);
  box-shadow:0 1px 3px rgba(0,0,0,.6);
  vertical-align:middle;
}
.rs-flag .flag-img{height:clamp(19px,2.7vh,27px)}
.rs-id b{min-width:0;font-size:clamp(18px,2.6vh,27px);font-weight:900;
  letter-spacing:.02em;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs-id i{font-style:normal;font-size:14px;font-weight:700;color:var(--dim);
  letter-spacing:.2em;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs-meta{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.rs-meta span{min-width:0}
.rs-meta u{display:block;text-decoration:none;font-size:12.5px;font-weight:800;
  letter-spacing:.2em;text-transform:uppercase;color:var(--acc2);opacity:.8}
.rs-meta b{display:block;font-size:18px;font-weight:800;letter-spacing:.03em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs-meta i{display:block;font-style:normal;font-size:14px;color:var(--dim);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs-bar{display:flex;align-items:center;gap:10px;margin-bottom:5px}
.rs-bar i{font-style:normal;flex:none;width:98px;font-size:12.5px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--dim)}
.rs-bar u{flex:1;display:block;height:7px;text-decoration:none;
  background:rgba(255,255,255,.08);overflow:hidden}
.rs-bar b{display:block;height:100%;transition:width .25s}
.rs-note{font-size:13px;color:var(--dim);opacity:.75;line-height:1.5}

/* la planche : toutes les cartes visibles d'un coup, pas de defilement cache */
.rs-grid{
  grid-column:1 / -1;display:grid;gap:clamp(5px,.7vw,9px);
  grid-template-columns:repeat(auto-fit,minmax(56px,1fr));
}
.rs-cell{
  position:relative;overflow:hidden;aspect-ratio:2 / 3;
  background:#070c14;border:2px solid var(--line);padding:0;
  transition:border-color .16s,transform .16s,box-shadow .16s;
}
/* `>` et non un descendant : le pavillon est une <img> lui aussi, niche dans
   la pastille, et il n'a rien a faire en pleine case ni en noir et blanc */
.rs-cell > img{width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(.75) brightness(.62);transition:filter .16s,transform .16s}
/* Le nom du dirigeant est imprime dans la carte, en bas : y poser le pavillon
   le rendait illisible (« ROUTINE », « FRACRON »). Il monte donc en haut, sur
   le fond du portrait. */
.rs-cell-flag{
  position:absolute;left:4px;top:4px;z-index:1;
  padding:0;line-height:0;
  box-shadow:0 1px 4px rgba(0,0,0,.8);
}
.rs-cell-flag .flag-img{height:11px;border-color:rgba(255,255,255,.3)}
.rs-cell:hover{border-color:var(--line2);transform:translateY(-3px)}
.rs-cell:hover > img{filter:grayscale(.25) brightness(.9)}
.rs-cell.on{border-color:var(--pick);
  box-shadow:0 0 0 1px var(--pick),0 10px 24px -6px var(--pick)}
.rs-cell.on > img{filter:none;transform:scale(1.05)}

/* etroit : la carte passe au-dessus du dossier plutot que de l'ecraser */
@media (max-width:720px){
  .rs{grid-template-columns:1fr}
  .rs-stage{justify-content:center}
  .rs-meta{grid-template-columns:1fr}
}

/* ---- pseudo ---- */
.name-wrap{position:relative;min-width:0;--pf-h:clamp(46px,7.6vh,68px)}
.name-wrap input{
  width:100%;height:var(--pf-h);background:#070c14;
  border:2px solid var(--line);padding:0 22px;outline:none;
  font-size:clamp(17px,2.6vh,26px);font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,
                    100% 100%,12px 100%,0 calc(100% - 12px));
  box-shadow:inset 0 3px 14px rgba(0,0,0,.6);
  transition:border-color .18s,background .18s,box-shadow .18s;
}
.name-wrap input::placeholder{color:rgba(232,240,251,.15);font-weight:800}
.name-wrap input:focus{
  border-color:var(--acc);background:#050a11;
  box-shadow:inset 0 3px 14px rgba(0,0,0,.6),0 0 26px rgba(63,242,164,.18);
}
#nameCount{
  position:absolute;right:16px;bottom:9px;
  font:700 13.5px/1 var(--f-num);color:var(--dim);letter-spacing:.05em;
}

/* ---- boutons ---- */
.row{display:flex;gap:12px;margin-top:4px}
.row button{
  position:relative;isolation:isolate;
  flex:1;padding:clamp(10px,1.8vh,17px);
  background:var(--line2);          /* liseré : le ::before pose la matiere */
  font-weight:800;font-size:16.5px;letter-spacing:.14em;text-transform:uppercase;
  transition:transform .16s,box-shadow .16s,filter .16s;
}
.row button::before{
  content:"";position:absolute;inset:2px;z-index:-2;clip-path:inherit;
  background:linear-gradient(180deg,#1a2639,#0d1521);
}
.row button::after{                  /* reflet qui balaie au survol */
  content:"";position:absolute;inset:2px;z-index:-1;clip-path:inherit;
  background:linear-gradient(115deg,transparent 38%,rgba(255,255,255,.25) 50%,transparent 62%);
  transform:translateX(-120%);transition:transform .55s ease;
}
.row button:hover::after{transform:translateX(120%)}
.row button:hover{transform:translateY(-2px);
  box-shadow:0 16px 32px rgba(0,0,0,.55),0 0 26px rgba(77,216,255,.12)}
.row button:active{transform:translateY(1px) scale(.985)}
.row button.primary{
  background:#0c6b4e;color:var(--ink);
  text-shadow:0 1px 0 rgba(255,255,255,.28);
  box-shadow:0 16px 36px rgba(46,200,154,.34);
}
.row button.primary::before{background:linear-gradient(180deg,#6dffc8,#25b585 58%,#159a6e)}
.row button.primary:hover{filter:brightness(1.07);
  box-shadow:0 20px 44px rgba(46,200,154,.44)}
.row button.big{padding:clamp(12px,2.2vh,21px);font-size:19px;
  font-weight:900;letter-spacing:.18em}

.sep{position:relative;text-align:center;margin:clamp(10px,2.2vh,22px) 0;
  color:var(--dim);font-size:12px;font-weight:800;letter-spacing:.24em;
  text-transform:uppercase}
.sep::before{content:"";position:absolute;top:50%;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.14),transparent)}
.sep span{position:relative;background:#101a28;padding:0 16px}
.row.join input{
  margin:0;flex:1;min-width:0;text-align:center;letter-spacing:.55em;text-indent:.55em;
  font:900 clamp(20px,3vh,30px)/1 var(--f-num);
  padding:clamp(9px,1.5vh,15px) 16px;
  background:#070c14;border:2px solid var(--line);
  outline:none;color:var(--acc);text-transform:uppercase;
  clip-path:polygon(0 0,calc(100% - 10px) 0,100% 10px,
                    100% 100%,10px 100%,0 calc(100% - 10px));
  box-shadow:inset 0 3px 14px rgba(0,0,0,.6);transition:border-color .18s,box-shadow .18s;
}
.row.join input::placeholder{color:rgba(232,240,251,.13)}
.row.join input:focus{border-color:var(--acc);
  box-shadow:inset 0 3px 14px rgba(0,0,0,.6),0 0 26px rgba(63,242,164,.2)}
/* le bouton reprend le pan coupe du champ qu'il accompagne : cote a cote, un
   rectangle franc a cote d'un cadre biseaute se voit tout de suite */
.row.join button{flex:none;width:auto;padding:0 clamp(18px,2.2vw,32px);
  clip-path:polygon(0 0,calc(100% - 10px) 0,100% 10px,
                    100% 100%,10px 100%,0 calc(100% - 10px))}
.err{color:var(--danger);font-size:14px;font-weight:600;letter-spacing:.04em;
  margin-top:clamp(6px,1.4vh,14px);
  min-height:clamp(0px,1.8vh,18px);text-align:center}
.hint{font-size:clamp(12px,1.7vh,14px);color:var(--dim);
  margin-top:clamp(8px,1.8vh,18px);text-align:center;line-height:1.6}

/* ---- code du salon ---- */
.code-box{
  position:relative;isolation:isolate;
  display:flex;align-items:center;gap:16px;justify-content:center;
  background:rgba(63,242,164,.28);
  padding:clamp(10px,2vh,20px);
  margin-bottom:clamp(10px,2.2vh,22px);
}
.code-box::before{
  content:"";position:absolute;inset:1.5px;z-index:-1;clip-path:inherit;
  background:linear-gradient(180deg,#08131b,#050a10);
}
.code-box span{font-size:12px;color:var(--dim);text-transform:uppercase;
  letter-spacing:.22em;font-weight:700}
.code-box b{
  font:900 clamp(24px,4vh,38px)/1 var(--f-num);
  letter-spacing:.36em;text-indent:.36em;
  color:var(--acc);text-shadow:0 0 30px rgba(63,242,164,.6);
}
.code-box button{font-size:19px;color:var(--dim);padding:8px 11px}
.code-box button:hover{color:var(--acc)}

/* ---- table des joueurs ---- */
#lobbyPlayers{display:grid;grid-template-columns:1fr;
  gap:clamp(5px,1.1vh,11px);margin-bottom:clamp(10px,2vh,20px)}
/* six lignes empilees ne tiennent pas sous 80vh sur un ecran de portable :
   on passe alors la table en deux colonnes plutot que de la faire defiler */
@media (max-height:860px){
  #lobbyPlayers{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
}
.lp{
  position:relative;isolation:isolate;
  display:flex;align-items:center;gap:14px;
  background:rgba(255,255,255,.09);
  padding:clamp(6px,1.3vh,13px) 15px;
  transition:background .2s;
}
.lp::before{
  content:"";position:absolute;inset:1.5px;z-index:-1;clip-path:inherit;
  background:rgba(11,17,28,.9);transition:background .2s;
}
.lp .lp-av{
  flex:none;width:clamp(34px,5.6vh,56px);height:clamp(34px,5.6vh,56px);
  display:grid;place-items:center;font-size:clamp(18px,3vh,30px);
  line-height:1;overflow:hidden;
  background:#070c14;border:1px solid rgba(255,255,255,.1);
  clip-path:polygon(0 0,calc(100% - 9px) 0,100% 9px,
                    100% 100%,9px 100%,0 calc(100% - 9px));
  box-shadow:inset 0 2px 10px rgba(0,0,0,.6);
}
.lp .lp-av img{width:100%;height:100%;object-fit:cover;object-position:50% 8%}
.lp .lp-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.lp .who{font-size:clamp(14px,1.8vh,18px);font-weight:800;letter-spacing:.03em;
  text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lp .tag{font-size:11.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);display:flex;align-items:center;gap:6px}
.lp .tag .flag-img{height:12px}
.lp .tag .crown{color:var(--warn);font-style:normal;animation:bob 1.6s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
.lp .dot{width:13px;height:13px;flex:none}
.lp.ok{background:rgba(63,242,164,.5)}
.lp.ok::before{background:rgba(9,26,22,.92)}
.lp.ok .tag{color:var(--acc)}
.lp.off{opacity:.48}
.lp.free{background:rgba(255,255,255,.06)}
.lp.free .lp-av{border-style:dashed;background:none;box-shadow:none;
  color:rgba(232,240,251,.2);font-size:24px}
.lp.free .who{color:rgba(232,240,251,.28);font-size:15.5px;font-weight:700}

/* ---- options ---- */
.opt-box h2{font-size:16.5px;margin-bottom:clamp(10px,2.2vh,22px);text-align:center;
  letter-spacing:.34em;text-indent:.34em;text-transform:uppercase;color:var(--acc2)}
.opt-row{
  position:relative;isolation:isolate;
  display:flex;align-items:center;gap:12px;
  background:rgba(255,255,255,.08);
  padding:clamp(7px,1.3vh,12px) 15px;margin-bottom:clamp(6px,1.2vh,12px);
}
.opt-row::before{
  content:"";position:absolute;inset:1.5px;z-index:-1;clip-path:inherit;
  background:#0d1522;
}
.opt-row>span{font-size:12px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--dim);font-weight:700;min-width:86px}
.opt-row>b{flex:1;font:800 20px/1 var(--f-num);letter-spacing:.3em;color:var(--acc)}
.opt-row #optZoomVal,.opt-row #optMusicVal,.opt-row #optFxVal{
  flex:none;font:700 15px/1 var(--f-num);letter-spacing:normal;
  color:var(--txt);min-width:56px;text-align:right}
.opt-row #optMuteVal{flex:1;font:600 14px/1 var(--f-ui);letter-spacing:.12em;
  text-transform:uppercase;color:var(--txt)}
.opt-row button.spk{
  font-size:18px;line-height:1;padding:7px 11px;
  background:var(--panel3);border:1px solid var(--line);transition:.15s;
}
.opt-row button.spk:hover{background:#26324a;transform:translateY(-1px)}
.opt-row button.spk.off{
  color:var(--danger);border-color:rgba(255,59,92,.5);
  background:rgba(255,59,92,.14);
}
.opt-row button{
  padding:8px 14px;background:var(--panel3);
  border:1px solid var(--line);font-size:13px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;
}
.opt-row button:hover{background:#26324a;border-color:var(--line2)}
.opt-row input[type=range]{flex:1;accent-color:var(--acc);height:4px}
.opt-field{display:block;font-size:12px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--dim);font-weight:700;margin-bottom:14px}
.opt-inline{display:flex;gap:9px;margin-top:8px;align-items:stretch}
.opt-inline .av-sm{width:44px;height:auto}
.opt-inline input{
  flex:1;background:#0a111b;border:1px solid var(--line);
  padding:11px 14px;outline:none;font-size:15.5px;text-transform:none;
  letter-spacing:normal;font-weight:600;color:var(--txt);
}
.opt-inline input:focus{border-color:var(--acc)}
.opt-inline button{
  padding:0 16px;background:var(--panel3);
  border:1px solid var(--line);font-size:13px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;
}
.opt-actions{display:flex;flex-direction:column;gap:9px;margin-top:18px}
.opt-actions button{
  position:relative;isolation:isolate;
  padding:14px;background:var(--line);
  font-weight:700;font-size:14px;letter-spacing:.16em;text-transform:uppercase;
  transition:transform .15s,box-shadow .15s,filter .15s;
}
.opt-actions button::before{
  content:"";position:absolute;inset:1.5px;z-index:-1;clip-path:inherit;
  background:linear-gradient(180deg,#182334,#0d1521);
}
.opt-actions button:hover{transform:translateY(-1px);
  box-shadow:0 10px 24px rgba(0,0,0,.5)}
.opt-actions .danger{color:#ff8b9d;background:rgba(255,59,92,.4)}
.opt-actions .danger::before{background:linear-gradient(180deg,#2a1018,#150a0f)}
.opt-actions .primary{color:var(--ink);background:#0c6b4e;
  box-shadow:0 12px 26px rgba(46,200,154,.28)}
.opt-actions .primary::before{background:linear-gradient(180deg,#57e9b4,#1a9e75)}

/* ---- fin ---- */
.end-box{text-align:center}
.end-box h1{font-size:clamp(20px,3.2vh,30px);margin-bottom:clamp(10px,2.2vh,22px);
  font-weight:900;letter-spacing:.16em;text-transform:uppercase;
  text-shadow:0 0 34px rgba(63,242,164,.35)}
/* le meme tableau sert a la fin de manche et a l'encerclement : la ligne de
   contexte n'apparait que dans le second cas, elle dit pourquoi il s'ouvre */
#endSub{font-size:13.5px;color:var(--dim);line-height:1.5;
  margin:-8px 0 clamp(10px,2vh,20px);letter-spacing:.02em}
#endList{display:flex;flex-direction:column;gap:clamp(5px,1vh,9px);
  margin-bottom:clamp(10px,2.2vh,22px)}
.er{
  position:relative;isolation:isolate;
  display:flex;align-items:center;gap:11px;
  background:rgba(255,255,255,.08);
  padding:clamp(7px,1.3vh,13px) 16px;font-size:15.5px;
}
.er::before{content:"";position:absolute;inset:1.5px;z-index:-1;clip-path:inherit;
  background:#0d1522}
.er .who{flex:1;text-align:left;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase}
.er b{font-family:var(--f-num);color:var(--acc)}
.er.win{background:rgba(63,242,164,.55);box-shadow:0 0 34px rgba(63,242,164,.22)}
.er.win::before{background:#0a1c19}
.end-box .primary{
  position:relative;isolation:isolate;width:100%;padding:15px;
  background:#0c6b4e;color:var(--ink);
  font-weight:900;font-size:16px;letter-spacing:.18em;text-transform:uppercase;
  clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,
                    100% 100%,8px 100%,0 calc(100% - 8px));
  box-shadow:0 14px 32px rgba(46,200,154,.3);transition:filter .15s,transform .15s;
}
.end-box .primary::before{content:"";position:absolute;inset:2px;z-index:-1;
  clip-path:inherit;background:linear-gradient(180deg,#6dffc8,#1a9e75)}
.end-box .primary:hover{filter:brightness(1.07);transform:translateY(-2px)}

@media (max-width:1280px){ :root{--side:340px} }
@media (max-width:1040px){
  :root{--side:300px}
  #tips{display:none}
}

/* ================================================ choix du dirigeant */
/* Trois colonnes : le portrait a gauche, la grille au centre, le dossier a
   droite. --pick porte la couleur du dirigeant courant et irrigue tout
   l'ecran (liseres, jauges, halo) : une seule variable a poser en JS. */
#charSelect{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  background:radial-gradient(120% 90% at 50% 0%,rgba(19,29,47,.9),rgba(2,5,10,.95));
  backdrop-filter:blur(10px);animation:fadeIn .18s ease;
  --pick:var(--acc);
}
.cs-box{
  position:relative;isolation:isolate;
  width:min(1180px,96vw);max-height:93vh;overflow:hidden;
  display:flex;flex-direction:column;
  background:linear-gradient(150deg,var(--line2),var(--line) 45%,#16233a);
  box-shadow:0 44px 110px rgba(0,0,0,.85);
  animation:pop .26s cubic-bezier(.2,1.1,.4,1);
}
.cs-box::before{content:"";position:absolute;inset:2px;z-index:-1;clip-path:inherit;
  background:linear-gradient(180deg,rgba(17,27,44,.98),rgba(6,10,17,.99))}
.cs-head{
  display:flex;align-items:center;justify-content:space-between;flex:none;
  padding:14px 22px;border-bottom:1px solid rgba(255,255,255,.08);
  background:rgba(77,216,255,.05);
}
.cs-head h2{font-size:14px;font-weight:800;letter-spacing:.24em;
  text-transform:uppercase;color:var(--acc2)}
#csClose{font-size:17px;color:var(--dim);padding:2px 8px}
#csClose:hover{color:var(--danger)}

.cs-body{
  display:grid;grid-template-columns:.8fr 1.25fr 1fr;gap:22px;
  padding:18px 22px 22px;overflow:auto;
}

/* ---- portrait ---- */
.cs-stage{
  position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  min-height:0;padding-bottom:10px;
}
.cs-stage::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:radial-gradient(70% 55% at 50% 32%,var(--pick),transparent 70%);
  opacity:.16;transition:opacity .3s;
}
/* la carte est deja encadree et signee : on la montre entiere, juste posee
   sur son halo de couleur */
.cs-portrait{
  position:relative;z-index:1;width:100%;max-height:min(54vh,520px);
  object-fit:contain;
  filter:drop-shadow(0 22px 38px rgba(0,0,0,.8));
}
.cs-id{position:relative;z-index:1;text-align:center;margin-top:10px}
.cs-flag{display:block;line-height:0}
.cs-flag .flag-img{height:21px}
.cs-id b{display:block;font-size:clamp(17px,2.2vw,23px);font-weight:900;
  letter-spacing:.02em;text-transform:uppercase}
.cs-id span:last-child{font-size:14px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--pick)}

/* ---- grille ---- */
.cs-mid{display:flex;flex-direction:column;gap:14px;min-width:0}
.cs-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
/* les cartes sont au format 784x1168 : la case suit, sinon `cover` mangerait
   le cadre dore et le nom peint en bas */
.cs-cell{
  position:relative;aspect-ratio:784/1168;overflow:hidden;padding:0;
  background:#0a1119;border:2px solid var(--line);--c:7px;
  transition:border-color .16s,box-shadow .16s,transform .16s;
}
/* les cartes non retenues restent en retrait : l'oeil va au choix courant */
.cs-cell img{width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(.9) brightness(.66);transition:filter .18s,transform .18s}
.cs-cell:hover{border-color:var(--line2);transform:translateY(-3px)}
.cs-cell:hover img{filter:grayscale(.2) brightness(.95)}
.cs-cell.on{border-color:var(--pick);
  box-shadow:0 0 30px -6px var(--pick),inset 0 0 24px -12px var(--pick)}
.cs-cell.on img{filter:none;transform:scale(1.04)}
#csConfirm{
  position:relative;isolation:isolate;margin-top:auto;padding:15px;
  background:var(--pick);color:var(--ink);
  font-weight:900;font-size:15.5px;letter-spacing:.2em;text-transform:uppercase;
  transition:filter .16s,transform .12s;
}
#csConfirm:hover{filter:brightness(1.12)}
#csConfirm:active{transform:scale(.98)}

/* ---- dossier ---- */
.cs-file{display:flex;flex-direction:column;gap:16px;min-width:0}
.cs-lbl{
  display:flex;align-items:center;gap:8px;
  font-size:13px;font-weight:700;color:var(--acc2);
  letter-spacing:.2em;text-transform:uppercase;margin-bottom:9px;
}
.cs-lbl::after{content:"";flex:1;height:1px;
  background:linear-gradient(90deg,rgba(77,216,255,.28),transparent)}
.cs-line{display:flex;align-items:center;gap:13px}
.cs-logo{width:58px;height:58px;object-fit:contain;flex:none;
  filter:drop-shadow(0 0 14px rgba(255,255,255,.12))}
.cs-craft{width:96px;height:auto;object-fit:contain;flex:none}
.cs-line b{display:block;font-size:16.5px;font-weight:800;letter-spacing:.04em}
.cs-line i{display:block;font-style:normal;font-size:14px;color:var(--dim);
  line-height:1.45}
.cs-bar{display:flex;align-items:center;gap:10px;margin-bottom:7px}
.cs-bar i{font-style:normal;flex:none;width:98px;font-size:13px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.cs-bar u{flex:1;display:block;height:8px;text-decoration:none;
  background:#080e17;border:1px solid var(--line)}
.cs-bar b{display:block;height:100%;transition:width .25s}
.cs-note{font-size:13px;line-height:1.5;color:var(--dim);opacity:.75;margin-top:6px}

@media (max-width:940px){
  .cs-body{grid-template-columns:1fr 1fr}
  .cs-stage{grid-column:1 / -1;flex-direction:row;align-items:flex-end;gap:16px}
  .cs-portrait{max-height:26vh;width:auto}
  .cs-id{text-align:left}
}
@media (max-width:620px){
  .cs-body{grid-template-columns:1fr}
}

/* ============================================== briefing du renseignement */
#brief{
  position:fixed;inset:0;z-index:70;display:grid;place-items:center;
  background:rgba(2,4,8,.94);animation:fadeIn .25s ease;cursor:pointer;
  --pick:var(--acc);
}
.bf-box{
  position:relative;isolation:isolate;
  width:min(640px,92vw);padding:34px 38px 30px;text-align:center;
  background:linear-gradient(160deg,rgba(20,30,48,.98),rgba(6,10,17,.99));
  box-shadow:0 40px 100px rgba(0,0,0,.9),0 0 90px -30px var(--pick);
  animation:pop .3s cubic-bezier(.2,1.1,.4,1);
}
/* lignes de balayage : la note a l'air d'arriver sur un moniteur */
.bf-box::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(180deg,
    rgba(255,255,255,.035) 0 1px,transparent 1px 3px);
}
.bf-stamp{
  position:absolute;top:13px;left:0;right:0;
  font:700 11px/1 var(--f-num);letter-spacing:.3em;text-transform:uppercase;
  color:var(--pick);opacity:.85;
}
#briefLogo{
  display:block;width:106px;height:106px;object-fit:contain;margin:16px auto 12px;
  filter:drop-shadow(0 0 26px var(--pick));
}
#briefAgency{display:block;font-size:31px;font-weight:900;letter-spacing:.18em}
#briefTitle{
  display:block;margin:2px 0 18px;font-size:12.5px;color:var(--dim);
  letter-spacing:.14em;text-transform:uppercase;
}
#briefText{min-height:4.4em;font-size:16.5px;line-height:1.62}
#briefText::after{content:"\258B";color:var(--pick);animation:caret 1s steps(1) infinite}
@keyframes caret{50%{opacity:0}}
.bf-who{display:flex;align-items:center;justify-content:center;gap:9px;
  margin-top:16px;font-size:13.5px;color:var(--dim);letter-spacing:.06em}
.bf-who .flag-img{height:16px}
.bf-skip{position:absolute;right:14px;bottom:9px;font-size:11.5px;
  color:var(--dim);opacity:.55}

/* ---- l'arme engagee, nommee dans le briefing ----
   Le joueur doit reconnaitre a l'ecran ce qu'il vient de lire : meme
   silhouette d'arsenal que celle qui survolera la case. */
.bf-arm{
  display:flex;align-items:center;gap:14px;justify-content:center;
  margin:18px auto 0;padding:11px 16px;max-width:420px;
  background:rgba(255,255,255,.05);border:1px solid var(--line);
  text-align:left;
}
.bf-arm img{width:84px;height:auto;flex:none;object-fit:contain;
  filter:drop-shadow(0 0 12px rgba(255,255,255,.14))}
.bf-arm u{display:block;text-decoration:none;font-size:10.5px;font-weight:800;
  letter-spacing:.2em;text-transform:uppercase;color:var(--pick);opacity:.9}
.bf-arm b{display:block;font-size:16px;font-weight:800;letter-spacing:.03em}
.bf-arm i{display:block;font-style:normal;font-size:12.5px;color:var(--dim)}
.bf-doc{
  margin:12px auto 0;max-width:520px;font-size:13.5px;line-height:1.6;
  color:var(--dim);border-left:2px solid var(--pick);padding-left:12px;
  text-align:left;
}

/* ---- pied : entrer en jeu sans attendre, et le temps qu'il reste ---- */
.bf-foot{display:flex;align-items:center;justify-content:center;gap:14px;
  margin-top:16px}
#briefOk{
  padding:9px 20px;font-size:12.5px;font-weight:800;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink);
  background:var(--pick);border:1px solid var(--pick);
  transition:filter .15s,transform .15s;
}
#briefOk:hover{filter:brightness(1.12);transform:translateY(-1px)}
#briefOk:active{transform:translateY(0) scale(.97)}
.bf-count{font-size:12px;color:var(--dim);letter-spacing:.1em}
.bf-count b{font:800 21px/1 var(--f-num);color:var(--pick);margin-right:2px;
  font-variant-numeric:tabular-nums}

/* =================================================== dernier en lice */
/* Une question posee en plein ecran : c'est le seul moment ou la manche
   attend une reponse du joueur. Elle monte du bas comme la selection et la
   fin — la direction dit qu'on est au bout de quelque chose. */
#goOn{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  padding:20px;background:rgba(2,4,8,.82);backdrop-filter:blur(10px);
  animation:fadeIn .18s ease;
}
.go-box{
  position:relative;isolation:isolate;width:min(520px,94vw);
  background:var(--line);padding:26px 26px 22px;text-align:center;
  box-shadow:0 30px 70px rgba(0,0,0,.7);
  animation:slamUp .34s cubic-bezier(.16,.9,.3,1) both;
}
.go-box::before{content:"";position:absolute;inset:1.5px;z-index:-1;
  clip-path:inherit;background:linear-gradient(170deg,#101a29,#070c14)}
.go-tag{
  display:inline-block;margin-bottom:12px;padding:4px 11px;
  font-size:10px;font-weight:800;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ink);background:var(--acc);
}
.go-box h2{font-size:clamp(18px,2.8vh,26px);font-weight:900;
  letter-spacing:.14em;text-transform:uppercase;margin-bottom:10px}
.go-box p{font-size:14px;line-height:1.55;color:var(--dim);
  margin-bottom:20px;max-width:42ch;margin-left:auto;margin-right:auto}
#goClose{
  position:absolute;top:10px;right:10px;width:28px;height:28px;font-size:14px;
  color:var(--dim);background:rgba(255,255,255,.05);border:1px solid var(--line);
  transition:color .15s,border-color .15s;
}
#goClose:hover{color:var(--acc);border-color:var(--acc)}
.go-actions{display:flex;gap:10px;align-items:stretch}
/* meme matiere que les autres boutons du jeu : un lisere, et le ::before pose
   le degrade a l'interieur. Sans cette paire, ils tombaient nus. */
.go-actions button{
  position:relative;isolation:isolate;flex:1;padding:14px;
  background:var(--line2);color:var(--txt);
  font-size:13px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  transition:transform .15s,filter .15s,box-shadow .15s;
}
.go-actions button::before{
  content:"";position:absolute;inset:1.5px;z-index:-1;clip-path:inherit;
  background:linear-gradient(180deg,#182334,#0d1521);
}
.go-actions button:hover{transform:translateY(-2px);
  box-shadow:0 12px 26px rgba(0,0,0,.5)}
.go-actions .primary{
  flex:1.4;color:var(--ink);background:#0c6b4e;
  box-shadow:0 14px 30px rgba(46,200,154,.28);
}
.go-actions .primary::before{background:linear-gradient(180deg,#6dffc8,#1a9e75)}
.go-actions .primary:hover{filter:brightness(1.07)}

/* ============================================================ expressions */
/* La tete d'un dirigeant n'est pas une image mais une bande de trois, cote a
   cote : les images de sa boucle d'animation (tools/cut_expressions.py). Une
   bande 3:1 posee dans un carre en `cover` cale sa hauteur et laisse deux
   tiers hors cadre — `object-position` choisit alors laquelle des trois est
   visible, et trois crans suffisent a la faire tourner. Le gain est de ne
   jamais toucher au `src` de l'<img> : changer de source, c'est un decodage
   et un blanc a chaque image. Toute pastille qui recoit une tete doit donc
   etre carree, sans quoi le cadrage rognerait le portrait. */
@keyframes faceLoop{
  from{object-position:0% 100%}
  to{object-position:150% 100%}   /* steps(3) : 0%, 50%, 100% */
}
.av-face{
  /* la tete tient toute la hauteur du bloc de classement, soit deux fois la
     carte « Salon » du HUD : c'est elle qu'on surveille, pas le rang */
  flex:none;width:96px;height:96px;position:relative;overflow:hidden;
  display:grid;place-items:center;font-size:20px;line-height:1;
  background:
    radial-gradient(circle at 50% 32%,rgba(120,180,255,.16),rgba(4,8,14,.92) 72%);
  border:1px solid rgba(255,255,255,.1);
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,
                    100% 100%,12px 100%,0 calc(100% - 12px));
}
.av-face img{
  display:block;width:100%;height:100%;
  object-fit:cover;object-position:0% 100%;
  animation:faceLoop 1.05s steps(3) infinite;
  filter:drop-shadow(0 3px 7px rgba(0,0,0,.65));
}
/* dirigeant sans planche : sa carte prend la place, recadree comme partout */
.av-face.card img{object-fit:cover;object-position:50% 8%;animation:none}
/* le bandeau du terrain n'a pas besoin d'une grande tete : il sert a lire des
   chiffres d'un coup d'oeil, c'est le classement qu'on regarde vivre */
.av-face.hud{width:40px;height:40px;
  clip-path:polygon(0 0,calc(100% - 7px) 0,100% 7px,
                    100% 100%,7px 100%,0 calc(100% - 7px))}
.av-face.end{width:85px;height:85px}
/* l'humeur vient de changer : la tete accuse le coup, une seule fois. La
   boucle est reconduite dans la meme declaration : `animation` est un
   raccourci, l'omettre ici figerait la tete sur sa premiere image. */
.av-face.shift img{animation:faceLoop 1.05s steps(3) infinite,
  moodIn .34s cubic-bezier(.22,1,.36,1)}
.av-face.card.shift img{animation:moodIn .34s cubic-bezier(.22,1,.36,1)}
/* l'a-coup ne joue que sur l'echelle : faire varier l'opacite d'une image qui
   vient de changer de source se lit comme un clignotement, pas comme un choc */
@keyframes moodIn{
  0%{transform:translateY(3px) scale(.88)}
  60%{transform:translateY(0) scale(1.06)}
  100%{transform:none}
}

/* la planche complete, dans le dossier : les six humeurs d'un coup d'oeil */
.faces{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:6px}
.faces .face{display:flex;flex-direction:column;align-items:center;gap:3px;
  min-width:0}
.faces .face img{
  width:100%;aspect-ratio:1;
  object-fit:cover;object-position:0% 100%;
  animation:faceLoop 1.05s steps(3) infinite;
  background:linear-gradient(180deg,rgba(255,255,255,.06),transparent);
  border:1px solid var(--line);
}
.faces .face i{
  font-style:normal;font-size:11px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--dim);max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* ============================================================ avatars */
/* ---- pastilles reutilisables : options, classement, fin de manche ---- */
.av-sm{
  flex:none;width:36px;height:36px;font-size:19px;line-height:1;
  display:grid;place-items:center;overflow:hidden;
  background:#070c14;border:1px solid rgba(255,255,255,.1);
  clip-path:polygon(0 0,calc(100% - 7px) 0,100% 7px,
                    100% 100%,7px 100%,0 calc(100% - 7px));
  transition:border-color .16s,transform .16s;
}
.av-sm img{width:100%;height:100%;object-fit:cover;object-position:50% 8%}
button.av-sm:hover{border-color:var(--acc)}
button.av-sm:active{transform:scale(.92)}
.av-xs{
  flex:none;width:24px;height:24px;font-size:14px;line-height:1;
  display:grid;place-items:center;overflow:hidden;
  background:#070c14;border:1px solid rgba(255,255,255,.09);
  clip-path:polygon(0 0,calc(100% - 6px) 0,100% 6px,
                    100% 100%,6px 100%,0 calc(100% - 6px));
}
.av-xs img{width:100%;height:100%;object-fit:cover;object-position:50% 8%}

/* ---- reglages systeme ---- */
@media (prefers-reduced-motion:reduce){
  /* le delai compte autant que la duree : les entrees echelonnees du menu
     laisseraient sinon des lignes invisibles le temps de leur tour */
  *,*::before,*::after{animation-duration:.001ms !important;
    animation-delay:0s !important;
    animation-iteration-count:1 !important;transition-duration:.001ms !important}
}

/* ================================================ carte des operations
   Mode aventure : le planisphere est un ecran radar, pas un atlas. Le
   canvas garde ses proportions (2:1) et se reduit avec la fenetre ; le
   dossier de la region passe dessous des que la largeur manque. */
#world{
  position:fixed;inset:0;z-index:62;display:grid;place-items:center;
  background:radial-gradient(120% 90% at 50% 0%,rgba(19,29,47,.92),rgba(2,5,10,.97));
  backdrop-filter:blur(10px);animation:fadeIn .18s ease;
  --pick:var(--acc);
}
.w-box{
  position:relative;isolation:isolate;--c:var(--cut);
  width:min(1240px,96vw);max-height:94vh;overflow:hidden;
  display:flex;flex-direction:column;
  background:linear-gradient(150deg,var(--line2),var(--line) 45%,#16233a);
  box-shadow:0 44px 110px rgba(0,0,0,.85);
  animation:pop .26s cubic-bezier(.2,1.1,.4,1);
  clip-path:polygon(0 0,calc(100% - var(--c)) 0,100% var(--c),
                    100% 100%,var(--c) 100%,0 calc(100% - var(--c)));
}
.w-box::before{content:"";position:absolute;inset:2px;z-index:-1;clip-path:inherit;
  background:linear-gradient(180deg,rgba(17,27,44,.98),rgba(6,10,17,.99))}

.w-head{
  display:flex;align-items:center;gap:14px;flex:none;
  padding:13px 20px;border-bottom:1px solid rgba(255,255,255,.08);
  background:rgba(77,216,255,.05);
}
.w-head h2{flex:none;font-size:13.5px;font-weight:800;letter-spacing:.24em;
  text-transform:uppercase;color:var(--acc2)}
.w-prog{flex:1;height:5px;background:#070c14;border:1px solid var(--line);
  overflow:hidden}
.w-prog i{display:block;height:100%;width:0;background:var(--acc);
  transition:width .5s cubic-bezier(.2,1,.3,1)}
.w-head b{flex:none;font:700 13px/1 var(--f-num);color:var(--acc)}
#wClose{font-size:17px;color:var(--dim);padding:2px 8px}
#wClose:hover{color:var(--danger)}

.w-body{display:grid;grid-template-columns:1fr 300px;gap:20px;
  padding:18px 20px 20px;overflow:auto}
.w-mapwrap{position:relative;min-width:0}
#worldMap{
  display:block;width:100%;height:auto;
  background:
    radial-gradient(120% 140% at 50% 0%,#0d1a2b 0%,#05080f 72%);
  border:1px solid var(--line);
}
.w-done{
  position:absolute;left:50%;bottom:10px;transform:translateX(-50%);
  font-size:13px;font-weight:800;letter-spacing:.2em;text-transform:uppercase;
  color:var(--acc);text-shadow:0 0 18px rgba(63,242,164,.5);
}

/* ---- dossier de la region visee ---- */
.w-file{display:flex;flex-direction:column;gap:8px;min-width:0}
/* la carte du dirigeant, et elle seule : le pavillon du defenseur est une
   image lui aussi et un selecteur d'element l'etirerait sur toute la largeur */
#wCard{
  width:100%;aspect-ratio:3/2;object-fit:cover;object-position:50% 8%;
  border:1px solid var(--line);background:#070c14;
}
.w-file>b{font-size:19px;font-weight:900;letter-spacing:.04em;color:var(--pick)}
#wHolder{display:flex;align-items:center;gap:7px;
  font-size:12.5px;color:var(--dim)}
#wHolder .flag-img{height:13px}
/* trois cases etroites : « 104 x 56 » doit tenir sans deborder, d'ou une
   taille de chiffre plus mesuree que dans le HUD */
.w-meta{display:flex;gap:8px;margin-top:2px}
.w-meta span{flex:1;min-width:0;background:rgba(255,255,255,.04);
  border:1px solid var(--line);padding:7px 8px}
.w-meta u{display:block;text-decoration:none;font-size:9px;font-weight:800;
  letter-spacing:.12em;text-transform:uppercase;color:var(--dim);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.w-meta b{font:700 13px/1.35 var(--f-num);white-space:nowrap}
#wNote{flex:1;font-size:12.5px;line-height:1.6;color:var(--dim);
  border-left:2px solid var(--pick);padding-left:10px}
#wGo{
  padding:13px;font-size:15px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:#04140d;background:var(--acc);
}
#wGo:hover{filter:brightness(1.08)}
#wGo:disabled{background:var(--panel3);color:var(--dim);cursor:not-allowed;
  filter:none}
#wReset{font-size:11.5px;color:var(--dim);padding:6px;
  border:1px solid var(--line)}
#wReset:hover{color:var(--danger);border-color:var(--danger)}

/* le bouton d'accueil qui ouvre la campagne : ambre, pour ne pas se
   confondre avec le vert « creer une partie » du multijoueur */
.row button.camp{
  background:linear-gradient(180deg,#20304a,#16233a);
  border:1px solid var(--acc2);color:var(--acc2);
  font-weight:800;letter-spacing:.06em;
}
.row button.camp:hover{background:linear-gradient(180deg,#2a3d5c,#1b2c46);
  box-shadow:0 0 26px rgba(77,216,255,.22)}

/* Deux boutons cote a cote : le principal garde exactement le style de
   `.end-box .primary` (relief, degrade, ombre), le retour a la carte est un
   secondaire sobre — deux boutons pleins se seraient disputes le regard. */
.end-actions{display:flex;gap:10px;margin-top:6px;align-items:stretch}
.end-actions .primary{flex:2}
#btnMap,#btnWatch{
  flex:1;padding:15px;font-weight:800;font-size:13px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--dim);
  background:var(--panel2);border:1px solid var(--line2);
  transition:color .15s,border-color .15s,transform .15s;
}
#btnMap:hover,#btnWatch:hover{color:var(--acc2);border-color:var(--acc2);
  transform:translateY(-2px)}

@media (max-width:900px){
  .w-body{grid-template-columns:1fr}
  #wCard{aspect-ratio:16/6}
}

/* =========================================================== cinematiques
   Le splash « versus » et les bandeaux. Tout le mouvement est ici : le JS ne
   fait que poser `data-phase` (in | hold | out) sur #splash.

   Regle de rythme : l'entree prend 420 ms et amortit, la sortie 300 ms et
   accelere (courbe inversee). C'est ce desequilibre qui donne la sensation
   de vitesse — un aller-retour symetrique parait mou.
   Rien n'utilise `animationend` : sous « mouvement reduit » les animations
   durent 1 ms, les etats finaux (`both`) restent justes et la sequence tient
   quand meme grace aux minuteurs du JS. */
#splash{
  position:fixed;inset:0;z-index:80;overflow:hidden;cursor:pointer;
  display:grid;place-items:center;user-select:none;
  background:radial-gradient(120% 120% at 50% 50%,rgba(6,10,18,.72),rgba(2,4,8,.96));
  --sp-key:var(--acc);
}

/* ---- lignes de vitesse : deux nappes qui balaient en sens contraire ---- */
.sp-rays,.sp-flash{position:absolute;inset:-20% -60%;pointer-events:none}
.sp-rays{
  background:
    repeating-linear-gradient(100deg,transparent 0 26px,
      rgba(255,255,255,.055) 26px 28px,transparent 28px 64px),
    repeating-linear-gradient(100deg,transparent 0 90px,
      rgba(77,216,255,.07) 90px 94px,transparent 94px 190px);
  animation:spRays 1.1s linear infinite;
  opacity:.55;
}
[data-phase="in"] .sp-rays{animation-duration:.28s;opacity:.9}
[data-phase="out"] .sp-rays{animation-duration:.18s;opacity:1}

@keyframes spRays{from{transform:translateX(0) skewX(-12deg)}
  to{transform:translateX(-190px) skewX(-12deg)}}

/* ---- eclair d'impact : ne vit que sur la premiere frame du « hold » ---- */
.sp-flash{
  inset:0;opacity:0;
  background:radial-gradient(60% 60% at 50% 50%,rgba(255,255,255,.85),transparent 70%);
}
[data-phase="hold"] .sp-flash{animation:spFlash .34s ease-out both}
@keyframes spFlash{0%{opacity:.95;transform:scale(.7)}
  100%{opacity:0;transform:scale(1.35)}}

/* ---- les deux cartes ---- */
.sp-duel{
  position:relative;display:flex;align-items:center;justify-content:center;
  gap:clamp(10px,4vw,54px);width:100%;
}
[data-phase="hold"] .sp-duel{animation:spShake .4s cubic-bezier(.36,.07,.19,.97) both}
@keyframes spShake{
  0%{transform:translate3d(0,0,0)} 12%{transform:translate3d(-9px,3px,0)}
  26%{transform:translate3d(8px,-4px,0)} 42%{transform:translate3d(-6px,2px,0)}
  60%{transform:translate3d(4px,-2px,0)} 100%{transform:translate3d(0,0,0)}
}
.sp-banner .sp-duel{display:none}

.sp-card{
  --sp-col:var(--txt);
  position:relative;width:clamp(130px,20vw,232px);
  background:linear-gradient(160deg,var(--sp-col),transparent 70%),var(--panel);
  padding:3px;box-shadow:0 26px 70px rgba(0,0,0,.7);
  --c:14px;
  clip-path:polygon(0 0,calc(100% - var(--c)) 0,100% var(--c),
                    100% 100%,var(--c) 100%,0 calc(100% - var(--c)));
}
.sp-av{display:block;aspect-ratio:2/3;overflow:hidden;background:#070c14}
.sp-av img{width:100%;height:100%;object-fit:cover;object-position:50% 8%;
  display:block}
.sp-card figcaption{
  display:block;padding:8px 10px 9px;text-align:center;background:#070c14;
}
.sp-card b{display:block;font-size:clamp(14px,1.5vw,19px);font-weight:900;
  letter-spacing:.06em;color:var(--sp-col);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sp-card i{display:block;font-style:normal;font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--dim)}

[data-phase="in"] .sp-card.left{animation:spInL .42s cubic-bezier(.16,.9,.3,1) both}
[data-phase="in"] .sp-card.right{animation:spInR .42s cubic-bezier(.16,.9,.3,1) both}
[data-phase="out"] .sp-card.left{animation:spOutL .3s cubic-bezier(.7,0,.9,.15) both}
[data-phase="out"] .sp-card.right{animation:spOutR .3s cubic-bezier(.7,0,.9,.15) both}

@keyframes spInL{
  0%{opacity:0;transform:translateX(-115vw) skewX(14deg) scale(1.06)}
  70%{opacity:1;transform:translateX(3%) skewX(-4deg)}
  100%{transform:none}
}
@keyframes spInR{
  0%{opacity:0;transform:translateX(115vw) skewX(-14deg) scale(1.06)}
  70%{opacity:1;transform:translateX(-3%) skewX(4deg)}
  100%{transform:none}
}
@keyframes spOutL{from{transform:none;opacity:1}
  to{opacity:0;transform:translateX(-125vw) skewX(-16deg)}}
@keyframes spOutR{from{transform:none;opacity:1}
  to{opacity:0;transform:translateX(125vw) skewX(16deg)}}

/* ---- le VS : il eclot sur l'impact, pas a l'arrivee ---- */
.sp-vs{
  position:relative;flex:none;
  font:900 clamp(30px,6vw,74px)/1 var(--f-num);letter-spacing:-.04em;
  color:#fff;text-shadow:0 0 26px rgba(255,255,255,.5),0 6px 0 rgba(0,0,0,.55);
  opacity:0;
}
[data-phase="hold"] .sp-vs{animation:spVs .42s cubic-bezier(.2,1.5,.4,1) both}
[data-phase="out"] .sp-vs{animation:spVsOut .22s ease-in both}
@keyframes spVs{
  0%{opacity:0;transform:scale(3.2) rotate(-14deg)}
  60%{opacity:1;transform:scale(.88) rotate(4deg)}
  100%{opacity:1;transform:scale(1) rotate(-5deg)}
}
@keyframes spVsOut{to{opacity:0;transform:scale(1.9) rotate(-16deg)}}

/* ---- bandeau : il traverse, il ne s'installe pas ---- */
.sp-band{
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  padding:clamp(10px,2vh,20px) 6vw;text-align:center;
  background:linear-gradient(90deg,transparent,rgba(7,12,20,.94) 12%,
    rgba(7,12,20,.94) 88%,transparent);
  border-top:1px solid var(--sp-key);border-bottom:1px solid var(--sp-key);
  box-shadow:0 0 60px rgba(0,0,0,.6);
}
.sp-versus .sp-band{top:auto;bottom:clamp(24px,9vh,88px);transform:none;
  background:linear-gradient(90deg,transparent,rgba(7,12,20,.9) 18%,
    rgba(7,12,20,.9) 82%,transparent);border-bottom:0}
.sp-band b{
  display:block;font-size:clamp(18px,3.4vw,40px);font-weight:900;
  letter-spacing:.2em;text-transform:uppercase;color:var(--sp-key);
  text-shadow:0 0 30px rgba(63,242,164,.35);
}
.sp-versus .sp-band b{font-size:clamp(13px,1.5vw,17px);letter-spacing:.34em;
  color:var(--txt);text-shadow:none}
.sp-band i{display:block;margin-top:5px;font-style:normal;
  font-size:clamp(11px,1.3vw,14.5px);letter-spacing:.14em;color:var(--dim);
  text-transform:uppercase}
.sp-win{--sp-key:var(--acc)}
.sp-lose{--sp-key:var(--danger)}
.sp-lose .sp-band b{text-shadow:0 0 30px rgba(255,59,92,.35)}

/* meme mention que sur le briefing : une cinematique doit dire qu'on peut la
   passer, sinon on la subit une fois de trop avant de le decouvrir */
.sp-skip{
  position:absolute;right:16px;bottom:12px;font-size:11.5px;
  color:var(--dim);opacity:.55;letter-spacing:.08em;
}

[data-phase="in"] .sp-band{animation:spBandIn .42s cubic-bezier(.16,.9,.3,1) both}
[data-phase="out"] .sp-band{animation:spBandOut .3s cubic-bezier(.7,0,.9,.15) both}
@keyframes spBandIn{
  0%{opacity:0;transform:translateY(-50%) translateX(60vw) skewX(-10deg)}
  100%{opacity:1;transform:translateY(-50%) translateX(0) skewX(0)}
}
@keyframes spBandOut{
  from{opacity:1;transform:translateY(-50%) translateX(0)}
  to{opacity:0;transform:translateY(-50%) translateX(-70vw) skewX(10deg)}
}
/* en mode versus le bandeau est ancre en bas et non centre : il lui faut ses
   propres trajectoires, sans le translateY qui recentre l'autre */
[data-phase="in"].sp-versus .sp-band{animation-name:spBandInLow}
[data-phase="out"].sp-versus .sp-band{animation-name:spBandOutLow}
@keyframes spBandInLow{
  0%{opacity:0;transform:translateX(60vw) skewX(-10deg)}
  100%{opacity:1;transform:none}
}
@keyframes spBandOutLow{from{opacity:1;transform:none}
  to{opacity:0;transform:translateX(-70vw) skewX(10deg)}}

/* ==================================================== entrees des panneaux
   Chaque panneau arrive par le bord qui correspond a ce qu'il est, et
   repartira par le meme : la carte des operations tombe du haut comme une
   table qu'on pose, le choix du dirigeant monte du bas comme une main de
   cartes, les options glissent de la droite comme un tiroir. Le sens de
   l'arrivee est une information, pas une decoration — on retrouve d'un coup
   d'oeil « ou » on est dans l'interface.

   Meme rythme que les cinematiques : arrivee longue et amortie, avec un
   depassement leger, jamais de rebond mou. */
@keyframes slamDown{
  0%{opacity:0;transform:translateY(-42vh) skewY(2.5deg) scale(.97)}
  72%{opacity:1;transform:translateY(1.2%) skewY(-.5deg)}
  100%{transform:none}
}
@keyframes slamUp{
  0%{opacity:0;transform:translateY(42vh) skewY(-2.5deg) scale(.97)}
  72%{opacity:1;transform:translateY(-1.2%) skewY(.5deg)}
  100%{transform:none}
}
@keyframes slamRight{
  0%{opacity:0;transform:translateX(46vw) skewX(-5deg) scale(.98)}
  72%{opacity:1;transform:translateX(-1.4%) skewX(1deg)}
  100%{transform:none}
}
@keyframes menuIn{
  0%{opacity:0;transform:translateX(-26px) skewX(-5deg)}
  100%{opacity:1;transform:none}
}
@keyframes erIn{
  0%{opacity:0;transform:translateX(-38px) skewX(-7deg)}
  100%{opacity:1;transform:none}
}

.w-box{animation:slamDown .34s cubic-bezier(.16,.9,.3,1) both}
.cs-box{animation:slamUp .34s cubic-bezier(.16,.9,.3,1) both}
.opt-box{animation:slamRight .32s cubic-bezier(.16,.9,.3,1) both}
.end-box{animation:slamUp .36s cubic-bezier(.16,.9,.3,1) both}

/* l'accueil se remonte ligne a ligne : le regard descend le menu au lieu de
   recevoir un bloc entier. Repasser par le menu rejoue la sequence (le bloc
   revient de `display:none`), ce qui marque le retour. */
#lobbyForm>*{animation:menuIn .38s cubic-bezier(.16,.9,.3,1) both}
#lobbyForm>*:nth-child(1){animation-delay:.02s}
#lobbyForm>*:nth-child(2){animation-delay:.08s}
#lobbyForm>*:nth-child(3){animation-delay:.14s}
#lobbyForm>*:nth-child(4){animation-delay:.20s}
#lobbyForm>*:nth-child(5){animation-delay:.26s}
#lobbyForm>*:nth-child(6){animation-delay:.32s}
#lobbyForm>*:nth-child(n+7){animation-delay:.36s}

/* classement de fin : les lignes tombent une a une, du meilleur au dernier */
.er{animation:erIn .34s cubic-bezier(.16,.9,.3,1) both;
  animation-delay:calc(var(--i,0)*70ms + 120ms)}

/* ============================================================ ergonomie
   Le focus clavier n'etait visible nulle part : impossible de traverser un
   panneau au clavier en sachant ou l'on est. Un seul liseré, partout. */
:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
input:focus-visible,button.av-sm:focus-visible{outline-offset:1px}
.row button:focus-visible,#wGo:focus-visible,.end-actions button:focus-visible{
  outline-offset:4px}

/* fermetures : une croix de 17px avec 2px de marge etait une cible de 21px,
   sous le minimum confortable. Meme aspect, cible carree de 34px. */
#csClose,#wClose{
  width:34px;height:34px;display:grid;place-items:center;padding:0;flex:none;
}

/* rappels clavier dans le menu : ils ne prennent pas de place et evitent
   d'avoir a chercher la souris */
.row button .k{
  margin-left:10px;font:600 11.5px/1 var(--f-num);opacity:.55;
  letter-spacing:.08em;
}

/* ============================================== accueil : les deux familles
   Solo a gauche, multijoueur a droite, chacune sous son intitule. Les trois
   boutons se suivaient auparavant separes par deux « ou », sans dire lequel
   menait ou : le regard devait tout lire pour choisir. */
/* Les deux familles d'action se repondent, donc elles font la meme hauteur :
   a droite un bouton *et* la ligne du code de partie, a gauche un seul bouton
   — laisse a `start`, il restait suspendu en haut, decale par rapport a son
   vis-a-vis. Il prend maintenant toute la hauteur de sa colonne. */
.acts{display:grid;grid-template-columns:1fr 1fr;gap:clamp(12px,2vw,26px);
  align-items:stretch;margin-top:clamp(8px,1.6vh,16px)}
.act:first-child .row{flex:1}
.act{display:flex;flex-direction:column;gap:10px;min-width:0}
.act-h{
  font-size:12.5px;font-weight:800;letter-spacing:.22em;text-transform:uppercase;
  color:var(--dim);padding-left:2px;
  display:flex;align-items:center;gap:10px;
}
.act-h::after{content:"";flex:1;height:1px;background:var(--line)}
.act .row{margin-top:0}
/* une ligne a bouton unique : il occupe toute la colonne. La ligne du code,
   elle, en a deux — imposer 100% au bouton le poussait hors du panneau, ou il
   restait large et vide, coupe par le bord de la carte. */
.act .row:not(.join) button{width:100%}

/* le bouton de campagne porte l'etat de la partie en cours : « 3 / 8 regions
   tenues » vaut mieux qu'un libelle fige qu'on relit sans rien y apprendre */
.row button.camp{display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:3px;line-height:1.15}
.row button.camp i{
  font-style:normal;font-size:12px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;opacity:.62;
}

@media (max-width:860px){ .acts{grid-template-columns:1fr} }

/* retour depuis la salle d'attente : discret mais toujours la — sans lui, un
   salon cree etait sans issue, il fallait recharger la page */
.ghost-back{
  display:block;margin:12px auto 0;padding:8px 16px;
  font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim);background:transparent;border:1px solid var(--line);
  transition:color .15s,border-color .15s,transform .15s;
}
.ghost-back:hover{color:var(--txt);border-color:var(--line2);transform:translateX(-2px)}
