:root {
  --bg-deep: #0d2b45;
  --bg-mid: #123a5c;
  --blue: #1e88c7;
  --blue-light: #5fc2f2;
  --red: #e63946;
  --red-dark: #b3202c;
  --green: #2ecc71;
  --yellow: #ffcb3d;
  --card-bg: #ffffff;
  --card-bg-done: #d9f2e1;
  --text-dark: #16324a;
  --text-light: #eaf6ff;
  --radius: 14px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #06131f;
  color: var(--text-light);
  font-family: "Segoe UI", "Trebuchet MS", system-ui, -apple-system, sans-serif;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
}

button { font-family: inherit; }

.app-frame {
  position: relative;
  width: 100%;
  max-width: 520px;
  height: 100vh;
  height: 100dvh;
  margin: 0 auto;
  background: linear-gradient(180deg, var(--bg-deep) 0%, var(--bg-mid) 55%, #0a2338 100%);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 0 60px rgba(0,0,0,.6);
  isolation: isolate;
}


/* ===================== HUD ===================== */
/* Mobile : le titre occupe sa propre ligne pleine largeur, tout le reste
   (boutons, niveau, vies, ARV/score) passe sur la ligne en dessous. */
.hud {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: calc(8px + var(--safe-top)) 10px 6px;
  flex: 0 0 auto;
}
.hud .hud-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  width: 100%;
}
.hud-title-text { flex: 0 0 auto; }
.arv-thumbs-mobile-slot { display: flex; gap: 2px; flex: 0 0 auto; }
/* Le conteneur #arvThumbs est déplacé ici tel quel : on annule sa grille 2 colonnes
   (pensée pour la colonne PC) au profit d'une simple ligne compacte à côté du titre. */
.arv-thumbs-mobile-slot .arv-thumbs { display: flex; gap: 2px; width: auto; }
.arv-thumbs-mobile-slot .arv-thumb { width: 13px; height: 17px; aspect-ratio: auto; border-radius: 2px; }

.hud-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  width: 100%;
}

.hud-buttons { display: flex; gap: 6px; flex: 0 0 auto; }
.hud-center { text-align: center; flex: 1; min-width: 0; }
.hud-title {
  font-weight: 800;
  letter-spacing: .12em;
  font-size: clamp(15px, 4.4vw, 20px);
  color: var(--yellow);
  text-shadow: 0 2px 0 rgba(0,0,0,.35);
}
.hud-level {
  font-size: clamp(11px, 3vw, 13px);
  color: var(--blue-light);
  font-weight: 600;
}
.hud-target {
  font-size: clamp(9.5px, 2.6vw, 11.5px);
  color: var(--yellow);
  font-weight: 700;
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon-btn {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35);
  background: rgba(255,255,255,.08);
  color: var(--text-light);
  font-weight: 700;
  font-size: 16px;
  cursor: pointer;
}
.icon-btn:active { transform: scale(.92); }
#btnOpenLeaderboard, #btnRestartGame { font-size: 14px; }

.hud-right {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

/* Exactement 4 cœurs par ligne (2 lignes pour 8 vies) : laisse une largeur prévisible
   dans l'en-tête mobile pour la zone ARV/score juste à côté. */
.hearts {
  display: grid;
  grid-template-columns: repeat(4, auto);
  grid-auto-flow: row;
  justify-items: end;
  gap: 2px 3px;
  flex: 0 0 auto;
}
.heart {
  width: clamp(16px, 4vw, 20px);
  height: clamp(16px, 4vw, 20px);
  color: var(--red);
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.4));
}
.heart.lost { color: rgba(255,255,255,.18); }
.heart.pulse { animation: heartPulse .5s ease; }
@keyframes heartPulse {
  0% { transform: scale(1); }
  30% { transform: scale(1.5); }
  60% { transform: scale(.85); }
  100% { transform: scale(1); }
}
.heart.gained { animation: heartGain .6s ease; }
@keyframes heartGain {
  0% { transform: scale(0) rotate(-30deg); opacity: 0; }
  60% { transform: scale(1.4) rotate(8deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}

.progress-track {
  height: 5px;
  margin: 0 12px 6px;
  border-radius: 4px;
  background: rgba(255,255,255,.12);
  flex: 0 0 auto;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--blue-light), var(--green));
  transition: width .35s ease;
}

/* Simple passe-plat en portrait (empile progress-track + board-wrap, comme avant qu'ils ne
   soient regroupés) ; devient la colonne principale à droite de la barre latérale .hud en
   paysage mobile/tablette, voir plus bas. */
.main-area {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* ===================== GAME BOARD ===================== */
/* La zone ARV vit hors du plateau de jeu, en colonne latérale : le plateau
   récupère toute la hauteur qu'elle occupait auparavant en bas, au profit du champ de mines. */
.board-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: row;
  gap: clamp(4px, 1.5vw, 10px);
  padding: 0 6px;
}

.game-board {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0;
}

.row {
  display: grid;
  column-gap: clamp(5px, 2vw, 10px);
  row-gap: clamp(14px, 3vh, 18px);
  padding: 2px 4px;
  flex: 0 0 auto;
  justify-items: stretch;
  align-items: center;
  align-content: center;
}
/* Mobile : les 8 cartes se répartissent sur 2 lignes de 4 (convoyeur pour le haut, groupes
   fixes pour le bas), afin de laisser un maximum de hauteur au champ de mines. À partir de
   la tablette (voir media query plus bas), les 8 cartes reviennent sur une seule ligne. */
.row-top, .row-bottom { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Plus d'écart superflu ici : le champ de mines a déjà sa propre marge basse de 2px
   (voir .battlefield), donc la ligne rouge du bas colle à 2px du haut des cartes B1-B4 —
   et l'espace ainsi libéré revient au champ de mines (flex: 1), qui gagne d'autant en hauteur. */
.row-bottom { margin-top: 0; }

.battlefield {
  position: relative;
  flex: 1;
  min-height: 90px;
  margin: 2px 8px;
  border-radius: 16px;
  background:
    radial-gradient(circle at 20% 30%, rgba(230,57,70,.10), transparent 55%),
    radial-gradient(circle at 80% 70%, rgba(230,57,70,.10), transparent 55%),
    repeating-linear-gradient(45deg, rgba(255,255,255,.03) 0 10px, transparent 10px 20px),
    #0a1f33;
  border: 2px dashed rgba(230,57,70,.35);
  overflow: hidden;
}

.battlefield-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 10px 18px;
  font-size: clamp(11px, 3vw, 13px);
  color: rgba(255,255,255,.45);
  pointer-events: none;
}

/* ===================== CARDS ===================== */
.card {
  position: relative;
  min-width: 0;
  width: 100%;
  /* Hauteur fixe et indépendante de la largeur de colonne (pas d'aspect-ratio) : sous
     certaines versions de WebKit/Safari (iOS), une hauteur dérivée d'un aspect-ratio
     appliqué à une largeur de grille en 1fr n'est pas toujours recalculée correctement,
     ce qui provoquait un chevauchement des deux lignes de cartes — invisible sous Chrome/
     Android. L'image à l'intérieur garde ses proportions réelles via `background-size:
     contain` (voir .card-face plus bas), quelle que soit la forme de cette boîte. */
  height: clamp(42px, 9vh, 66px);
  perspective: 500px;
  touch-action: none;
  cursor: grab;
  user-select: none;
}
.card.locked, .card.arv-slot, .card.pending, .card.failed { cursor: default; }

/* Cartes du haut : une seule est jouable à la fois (activation séquentielle
   de gauche à droite) ; les suivantes patientent, estompées. */
.card.pending .card-inner {
  opacity: .4;
  filter: grayscale(.4);
}
.card.top.active .card-inner {
  animation: activePulse 1.6s ease-in-out infinite;
}
@keyframes activePulse {
  0%, 100% { box-shadow: 0 2px 0 rgba(0,0,0,.15), 0 6px 10px rgba(0,0,0,.35), 0 0 0 0 rgba(95,194,242,.6); }
  50% { box-shadow: 0 2px 0 rgba(0,0,0,.15), 0 6px 10px rgba(0,0,0,.35), 0 0 0 5px rgba(95,194,242,0); }
}

.card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: var(--radius);
  background: #eef6fc;
  box-shadow:
    0 2px 0 rgba(0,0,0,.15),
    0 6px 10px rgba(0,0,0,.35),
    inset 0 1px 0 rgba(255,255,255,.9);
  overflow: hidden;
  transition: transform .18s ease, box-shadow .18s ease;
  border: 2px solid #d7e6f2;
}

.card:not(.dragging):not(.locked):not(.pending):not(.failed):hover .card-inner {
  transform: translateY(-3px) rotateX(6deg);
  box-shadow:
    0 4px 0 rgba(0,0,0,.15),
    0 12px 18px rgba(0,0,0,.4),
    inset 0 1px 0 rgba(255,255,255,.9);
}

.card-face {
  position: absolute;
  inset: 0;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}

.card .icon-wrap {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16%;
  color: var(--blue);
  background: linear-gradient(155deg, #ffffff 0%, #eef6fc 100%);
}
.card .icon-wrap svg { width: 100%; height: 100%; }

.card .card-banner {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(0deg, rgba(4,14,24,.88) 0%, rgba(4,14,24,.55) 65%, rgba(4,14,24,0) 100%);
  color: #fff;
  font-size: clamp(6.5px, 2.1vw, 10.5px);
  line-height: 1.12;
  font-weight: 800;
  text-align: center;
  padding: 5px 3px 4px;
  text-shadow: 0 1px 2px rgba(0,0,0,.6);
}

.card .card-tag {
  position: absolute;
  top: 2px;
  left: 3px;
  font-size: clamp(6px, 1.6vh, 7.5px);
  font-weight: 800;
  color: #fff;
  background: rgba(4,14,24,.5);
  border-radius: 3px;
  padding: 0 2px;
  letter-spacing: .02em;
  z-index: 1;
}

.card.risk .icon-wrap { color: var(--red); }
.card.risk .card-face::after {
  content: "⚡";
  position: absolute;
  top: 2px;
  right: 4px;
  font-size: 12px;
  filter: drop-shadow(0 0 2px rgba(255,203,61,.9));
  z-index: 1;
}

.card.dragging {
  position: fixed;
  z-index: 500;
  cursor: grabbing;
  filter: drop-shadow(0 10px 14px rgba(0,0,0,.5));
}
.card.dragging .card-inner {
  transform: scale(1.08) rotateZ(-2deg);
}
/* La carte rétrécit de 40% dès qu'elle entre dans le champ de mines (toutes tailles
   d'écran), pour faciliter le déplacement au milieu des virus. */
.card.dragging.drag-shrink .card-inner {
  transform: scale(.6) rotateZ(-2deg);
}

.card.locked .card-inner {
  border-color: var(--green);
}
.card.locked .card-face { opacity: .45; filter: grayscale(.3); }
.card.locked::before {
  content: "✔";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(16px, 5vh, 26px);
  color: var(--green);
  text-shadow: 0 1px 2px rgba(0,0,0,.3);
}

.card.failed .card-inner {
  border-color: var(--red);
}
.card.failed .card-face { opacity: .45; filter: grayscale(.5); }
.card.failed::before {
  content: "✖";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(16px, 5vh, 26px);
  color: var(--red);
  text-shadow: 0 1px 2px rgba(0,0,0,.3);
}

.card.matched-target .card-inner {
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(46,204,113,.4), 0 4px 10px rgba(0,0,0,.3);
}

.card.spring-back .card-inner { animation: springBack .35s ease; }
@keyframes springBack {
  0% { transform: scale(1.05); }
  50% { transform: scale(.95) rotate(-3deg); }
  100% { transform: scale(1) rotate(0); }
}

.card.wrong-flash .card-inner { animation: wrongFlash .4s ease; }
@keyframes wrongFlash {
  0%, 100% { box-shadow: 0 2px 0 rgba(0,0,0,.15), 0 6px 10px rgba(0,0,0,.35); }
  40% { box-shadow: 0 0 0 4px rgba(230,57,70,.6); }
}

.card.exploding .card-inner {
  animation: explode .62s cubic-bezier(.36,.07,.19,.97) forwards;
}
@keyframes explode {
  0% { transform: scale(1) rotate(0); filter: none; }
  8% { transform: scale(1.05) rotate(-4deg) translateX(-4px); filter: brightness(2.2) saturate(2); }
  16% { transform: scale(1.1) rotate(5deg) translateX(4px); filter: brightness(1.8) saturate(2); }
  24% { transform: scale(1.3) rotate(-6deg) translateX(-3px); filter: brightness(2.4) saturate(2.4); }
  38% { transform: scale(1.15) rotate(10deg); opacity: .95; filter: brightness(1.6) hue-rotate(-10deg); }
  65% { transform: scale(.45) rotate(-16deg); opacity: .5; filter: brightness(2.2) hue-rotate(-25deg); }
  100% { transform: scale(.08) rotate(6deg); opacity: 0; }
}

/* Tremblement bref du champ de mines à l'impact */
.battlefield.shake { animation: battlefieldShake .4s ease; }
@keyframes battlefieldShake {
  0%, 100% { transform: translate(0, 0); }
  15% { transform: translate(-6px, 2px); }
  30% { transform: translate(5px, -3px); }
  45% { transform: translate(-4px, -2px); }
  60% { transform: translate(4px, 3px); }
  75% { transform: translate(-3px, 1px); }
  90% { transform: translate(2px, -1px); }
}

/* Le virus percuté flashe brièvement en blanc avant de reprendre sa route.
   Seul `filter` est animé : `transform` reste piloté image par image par le JS
   du virus (sa position), l'animer ici entrerait en conflit et ferait sauter sa position. */
.virus.hit-flash svg { animation: virusHitFlash .35s ease; }
@keyframes virusHitFlash {
  0%, 100% { filter: brightness(1) saturate(1); }
  30% { filter: brightness(3.2) saturate(0); }
}

/* Onde de choc au point exact de la collision carte/virus */
.impact-burst {
  position: fixed;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 900;
}
.impact-burst::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  border: 3px solid rgba(255, 203, 61, .9);
  box-shadow: 0 0 14px 4px rgba(230, 57, 70, .6);
  animation: impactRing .45s ease-out forwards;
}
@keyframes impactRing {
  0% { transform: scale(.3); opacity: 1; }
  100% { transform: scale(4.5); opacity: 0; }
}
.impact-spark {
  position: absolute;
  left: -2px;
  top: -2px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--yellow);
  box-shadow: 0 0 6px 1px rgba(255, 203, 61, .8);
  animation: impactSpark .4s ease-out forwards;
}
@keyframes impactSpark {
  0% { transform: translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(var(--sx), var(--sy)) scale(0); opacity: 0; }
}

.points-float {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, 0);
  font-size: clamp(11px, 3vh, 16px);
  font-weight: 800;
  color: var(--yellow);
  text-shadow: 0 1px 3px rgba(0,0,0,.7);
  pointer-events: none;
  z-index: 5;
  animation: pointsFloat .9s ease-out forwards;
}
@keyframes pointsFloat {
  0% { transform: translate(-50%, 0); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translate(-50%, -28px); opacity: 0; }
}

/* Zone ARV, sortie des rangées et affichée à part en bas du plateau */
.arv-strip {
  flex: 0 0 auto;
  width: clamp(46px, 15vw, 76px);
  padding: 2px 0 calc(2px + var(--safe-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.score-label {
  flex: 0 0 auto;
  width: 100%;
  font-size: clamp(8px, 2.2vw, 10.5px);
  font-weight: 800;
  line-height: 1.2;
  text-align: center;
  color: var(--yellow);
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.2);
  border-radius: 8px;
  padding: 3px 2px;
}

.arv-card-slot {
  /* Ne prend que la place nécessaire à la carte : les miniatures qui suivent se collent
     juste en dessous, au lieu d'être repoussées tout en bas de la colonne (flex:1 les
     aurait éloignées de la carte ARV sur un plateau haut). */
  flex: 0 0 auto;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
@media (min-width: 700px) { .arv-strip { width: clamp(64px, 11vw, 96px); } }
@media (min-width: 1024px) { .arv-strip { width: clamp(74px, 9vw, 112px); } }

/* Juste sous la carte ARV : une miniature par carte attrapée par un virus sur le niveau en
   cours (remis à zéro à chaque nouveau niveau, comme le compteur). Deux par ligne, en
   occupant toute la largeur réservée à la colonne ARV. */
.arv-thumbs {
  flex: 0 0 auto;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
}
.arv-thumb {
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: 3px;
  background-color: #2c3d55;
  background-size: cover;
  background-position: center;
  border: 1px solid rgba(255,255,255,.3);
  box-shadow: 0 1px 2px rgba(0,0,0,.4);
  animation: arvThumbDrop .35s ease;
}
@keyframes arvThumbDrop {
  0% { transform: translateY(-10px) scale(.4); opacity: 0; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}

/* Mobile : la carte ARV vit dans l'en-tête, à côté des vies — format compact horizontal. */
.arv-header-slot { display: flex; align-items: center; flex: 0 0 auto; }
#arvHeaderSlot .arv-strip {
  width: auto;
  flex-direction: row;
  align-items: center;
  gap: 4px;
  padding: 0;
}
#arvHeaderSlot .score-label {
  width: auto;
  font-size: 8px;
  line-height: 1.05;
  padding: 2px 4px;
  white-space: nowrap;
}
#arvHeaderSlot .arv-card-slot { width: 26px; height: 26px; flex: 0 0 auto; }
#arvHeaderSlot .card.arv-slot.standalone { width: 26px; aspect-ratio: 1; }
#arvHeaderSlot .card-banner { display: none; }
#arvHeaderSlot .card-tag { display: none; }
/* Les miniatures ne vivent jamais ici : #arvThumbs est déplacé séparément vers la ligne du
   titre sur mobile (voir .arv-thumbs-mobile-slot), pas dans cet en-tête compact. */
#arvHeaderSlot .arv-counter {
  min-width: 14px;
  height: 14px;
  padding: 0 2px;
  font-size: 8px;
  top: -2px;
  right: -2px;
}

.card.arv-slot.standalone {
  width: 100%;
  aspect-ratio: 4 / 5;
  height: auto;
  cursor: default;
}

.card.arv-slot .card-inner {
  border-color: var(--yellow);
}
.card.arv-slot .icon-wrap {
  color: var(--yellow);
  background: linear-gradient(155deg, #2c3d55, #1a2739);
}
.card.arv-slot .card-banner { font-size: clamp(9px, 2.6vw, 12px); }
.arv-counter {
  position: absolute;
  top: 3px;
  right: 3px;
  min-width: clamp(20px, 6.5vw, 32px);
  height: clamp(20px, 6.5vw, 32px);
  padding: 0 4px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: clamp(11px, 3.8vw, 17px);
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  border: 2px solid rgba(255,255,255,.85);
  box-shadow: 0 2px 4px rgba(0,0,0,.4);
}
.card.arv-slot.pulse .card-inner { animation: arvPulse .5s ease; }
@keyframes arvPulse {
  0% { box-shadow: 0 0 0 0 rgba(255,203,61,.7); }
  100% { box-shadow: 0 0 0 14px rgba(255,203,61,0); }
}

/* ===================== VIRUS / MINES ===================== */
.virus {
  position: absolute;
  width: var(--vsize, 28px);
  height: var(--vsize, 28px);
  color: var(--red);
  will-change: transform;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.5));
}
.virus svg { width: 100%; height: 100%; animation: virusSpin 4s linear infinite; }
@keyframes virusSpin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
.virus.fast svg { animation-duration: 1.4s; }

/* ===================== OVERLAYS ===================== */
.overlay {
  position: absolute;
  inset: 0;
  background: rgba(4, 14, 24, .82);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 1000;
  transition: opacity .25s ease;
}
.overlay.hidden { display: none; }

.overlay-panel {
  background: linear-gradient(160deg, #123a5c, #0c2438);
  border: 2px solid rgba(255,255,255,.12);
  border-radius: 20px;
  padding: 26px 22px;
  max-width: 380px;
  width: 100%;
  text-align: center;
  box-shadow: 0 20px 50px rgba(0,0,0,.6);
  max-height: 90%;
  overflow-y: auto;
}
.overlay-panel-slim { padding: 30px 24px; }

.overlay-panel h1 {
  margin: 0 0 6px;
  font-size: clamp(24px, 7vw, 30px);
  color: var(--yellow);
  letter-spacing: .08em;
}
.overlay-panel h2 { margin: 0 0 10px; color: var(--yellow); }
.overlay-panel .tagline { color: var(--blue-light); font-size: 14px; margin-bottom: 14px; }

.rules-list {
  text-align: left;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-light);
  margin: 0 0 18px;
  padding-left: 18px;
}
.rules-list:not(.numbered) { list-style: none; padding-left: 2px; }

.bonus-text {
  color: var(--yellow);
  font-weight: 700;
  margin-bottom: 12px;
}
.reached-level { color: var(--blue-light); font-size: 14px; }

.btn {
  border: none;
  border-radius: 12px;
  padding: 13px 28px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .03em;
  cursor: pointer;
  width: 100%;
}
.btn-primary {
  background: linear-gradient(180deg, var(--blue-light), var(--blue));
  color: #06131f;
  box-shadow: 0 5px 0 #0f5f8c, 0 8px 14px rgba(0,0,0,.35);
}
.btn-primary:active { transform: translateY(3px); box-shadow: 0 2px 0 #0f5f8c; }

.btn-ghost {
  background: transparent;
  color: var(--blue-light);
  border: 2px solid rgba(95,194,242,.4);
  margin-top: 10px;
}
.btn-ghost:active { transform: translateY(2px); }

.link-btn {
  background: none;
  border: none;
  color: var(--yellow);
  font-size: 12.5px;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
  padding: 4px 0;
}

/* ===================== FORMULAIRE JOUEUR ===================== */
.player-form {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 14px;
}
.player-form .field {
  flex: 1 1 120px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
}
.player-form .field-code { flex-basis: 100%; }
/* Le lien et le bouton passent sur leur propre ligne plutôt que de s'écraser à côté
   des champs, puisque le formulaire est en flex-wrap et non en grille. */
.player-form .link-btn,
.player-form .btn { flex-basis: 100%; }
.player-form .field span {
  font-size: 11px;
  font-weight: 800;
  color: var(--blue-light);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.player-form input {
  background: rgba(255,255,255,.08);
  border: 2px solid rgba(255,255,255,.18);
  border-radius: 10px;
  padding: 10px 10px;
  /* 16px minimum : en dessous, Safari iOS zoome automatiquement la page au focus du champ
     (même avec user-scalable=no) et le layout peut rester "coincé" zoomé ensuite, donnant
     l'impression que le champ a rétréci une fois qu'on retape après une erreur. */
  font-size: 16px;
  color: var(--text-light);
  width: 100%;
}
.player-form input:focus {
  outline: none;
  border-color: var(--blue-light);
}
.player-form input::placeholder { color: rgba(255,255,255,.35); }
#inputCode { text-transform: uppercase; letter-spacing: .15em; text-align: center; font-family: monospace; }

.form-error {
  flex-basis: 100%;
  color: var(--red);
  font-size: 12.5px;
  font-weight: 700;
  margin: -6px 0 8px;
  text-align: left;
}

.player-welcome {
  margin-bottom: 14px;
  font-size: 13.5px;
  color: var(--text-light);
}
.player-welcome p { margin: 0 0 4px; }
.player-welcome strong { color: var(--yellow); }
.player-code strong {
  letter-spacing: .08em;
  font-family: monospace;
  font-size: 15px;
}
.player-code-hint {
  display: block;
  color: rgba(255,255,255,.5);
  font-size: 11px;
  font-weight: 400;
}

/* ===================== CLASSEMENT ===================== */
.lb-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
}
.lb-tab {
  flex: 1;
  background: rgba(255,255,255,.06);
  border: 2px solid rgba(255,255,255,.14);
  border-radius: 10px;
  padding: 8px 4px;
  font-size: 12.5px;
  font-weight: 800;
  color: var(--text-light);
  cursor: pointer;
}
.lb-tab.active {
  background: var(--blue);
  border-color: var(--blue-light);
  color: #06131f;
}

.lb-list {
  min-height: 120px;
  max-height: 40vh;
  overflow-y: auto;
  margin-bottom: 14px;
}
.lb-row {
  display: grid;
  grid-template-columns: 26px 1fr auto auto;
  gap: 8px;
  align-items: center;
  padding: 7px 6px;
  border-bottom: 1px solid rgba(255,255,255,.08);
  font-size: 12.5px;
  color: var(--text-light);
  text-align: left;
}
.lb-row .lb-rank { font-weight: 800; color: var(--yellow); }
.lb-row .lb-pseudo { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-row .lb-score { font-weight: 800; color: var(--blue-light); }
.lb-row .lb-time { color: rgba(255,255,255,.6); font-size: 11.5px; }
.lb-empty { padding: 20px 8px; text-align: center; color: rgba(255,255,255,.5); font-size: 13px; }

.hidden { display: none !important; }

/* Confetti for victory */
.confetti-piece {
  position: absolute;
  top: -10px;
  width: 8px;
  height: 14px;
  opacity: .9;
  animation: confettiFall linear forwards;
}
@keyframes confettiFall {
  to { transform: translateY(110vh) rotate(600deg); opacity: 0; }
}

/* ===================== RESPONSIVE (mobile-first : ces blocs doivent rester
   tout en bas du fichier pour bien surcharger les règles de base ci-dessus) ==== */

/* Tablette : plateau agrandi, mais cartes toujours sur 2 lignes comme sur smartphone
   (seul un vrai grand écran passe en ligne unique, voir plus bas). Sur tablette, les
   cartes restent volontairement deux fois plus petites (en hauteur) que sur smartphone,
   pour ne jamais se chevaucher malgré la largeur d'écran plus généreuse. */
@media (min-width: 700px) {
  .app-frame {
    max-width: 700px;
    height: min(100dvh, 1020px);
    margin-top: env(safe-area-inset-top, 12px);
    border-radius: 28px;
    border: 6px solid #0a1c2e;
  }
  .card { width: 100%; height: clamp(29px, 7.5vh, 47px); }

  /* Le titre revient sur la même ligne que le reste : plus besoin de l'empiler à part. */
  .hud { flex-direction: row; align-items: center; }
  .hud .hud-title { width: auto; }
  .hud-row { display: contents; }
  .arv-thumbs-mobile-slot { display: none; } /* les miniatures vivent sous la carte ARV sur PC */
}

/* PC / grand écran seulement : les 8 cartes reviennent sur une seule ligne. */
@media (min-width: 1024px) {
  .app-frame {
    max-width: 880px;
    height: min(100dvh, 1180px);
  }
  .card { width: 100%; max-width: 104px; height: clamp(70px, 9vh, 110px); }
  .row-top, .row-bottom { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .row-bottom { margin-top: 0; }
  .battlefield { min-height: 200px; }
}

/* Téléphone/tablette tourné en paysage (largeur < 1024px) : on retrouve la disposition PC
   (une seule ligne de 8 cartes, carte ARV dans sa colonne à côté du plateau — piloté depuis
   le JS via _isMobileLayout()), mais avec des tailles adaptées à la faible hauteur
   disponible en paysage plutôt que celles, plus généreuses, du vrai grand écran. */
@media (orientation: landscape) and (max-width: 1023px) {
  .row-top, .row-bottom { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .row-bottom { margin-top: 0; }
  .card { height: clamp(34px, 20vh, 64px); }
  .battlefield { min-height: 60px; }
  .arv-thumbs-mobile-slot { display: none; } /* la carte ARV n'est plus dans l'en-tête ici */

  /* L'en-tête devient une colonne étroite à gauche (pleine hauteur) au lieu d'une bande en
     haut : toute la hauteur qu'elle prenait auparavant revient au plateau, donc au champ
     de mines. La zone principale (progress-track + plateau) occupe le reste de la largeur. */
  .app-frame { flex-direction: row; }
  .hud {
    flex: 0 0 clamp(76px, 21vw, 104px);
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    height: 100%;
    gap: 8px;
    padding: calc(6px + var(--safe-top)) 6px calc(6px + var(--safe-bottom)) calc(6px + var(--safe-left));
    overflow-y: auto;
  }
  .hud-title { width: auto; flex-direction: column; gap: 4px; }
  .hud-title .hud-title-text { font-size: 11px; letter-spacing: .08em; }
  .hud-row { flex-direction: column; align-items: stretch; gap: 10px; }
  .hud-buttons { justify-content: center; }
  .hud-center { text-align: center; }
  .hud-right { flex-direction: column; align-items: center; gap: 6px; }
  .hearts { justify-content: center; }

  .main-area { height: 100%; }
}
