:root {
  --bg: #0f1220;
  --bg-glow: #1c2140;
  --panel: #1a1e33;
  --panel-2: #232849;
  --text: #f2f2f7;
  --muted: #8a8fa8;
  --nav-border: rgba(255, 255, 255, 0.15);
  --row-tint: rgba(255, 255, 255, 0.05);

  --common: #9aa0b4;
  --uncommon: #4caf6a;
  --rare: #4a8ff0;
  --double-rare: #9a5cf0;
  --ultra-rare: #ff9d2f;
  --illustration-rare: #ff6fae;
  --special-illustration-rare: #ff3b5c;
  --hyper-rare: #f5c518;

  /* 6 raretés ajoutées le 2026-08-14 (voir server/pack.js RARITY_ORDER pour
     l'ordre/le raisonnement) — restent fixes quel que soit le thème, comme
     les 8 au-dessus. */
  --ace-spec-rare: #2fd0c7;
  --shiny-rare: #5ad1ff;
  --shiny-ultra-rare: #22c7b5;
  --mega-attack-rare: #ff7a1a;
  --mega-hyper-rare: #ff2fd6;
  --black-white-rare: #eef0f5;
}

/* ---------- Thèmes ---------- */
/* Variantes de couleurs/fonds (2026-08-12), choisies dans le menu ☰ →
   thème. "nuit" reprend les valeurs par défaut ci-dessus (pas de bloc dédié
   nécessaire) ; seules les variables neutres bg/panel/text sont redéfinies,
   les couleurs de rareté restent fixes quel que soit le thème (elles
   encodent une info de jeu, pas une préférence visuelle). Appliqué sur
   <html data-theme="..."> par script.js, lu depuis localStorage avant même
   le premier paint (voir le script inline dans index.html) pour éviter un
   flash du thème par défaut. */
:root[data-theme="ocean"] {
  --bg: #081820;
  --bg-glow: #103042;
  --panel: #0f2a35;
  --panel-2: #163a47;
  --text: #eaf6f6;
  --muted: #7fa8ad;
}

:root[data-theme="foret"] {
  --bg: #0d1a10;
  --bg-glow: #16301c;
  --panel: #17301d;
  --panel-2: #1f3d26;
  --text: #eef7ec;
  --muted: #8aab8c;
}

:root[data-theme="coucher-de-soleil"] {
  --bg: #1a1016;
  --bg-glow: #3a1a2a;
  --panel: #2a1620;
  --panel-2: #3a1f2c;
  --text: #fbeee7;
  --muted: #c08a8a;
}

:root[data-theme="clair"] {
  --bg: #f4f5fb;
  --bg-glow: #e4e8fb;
  --panel: #ffffff;
  --panel-2: #eef0f9;
  --text: #1a1e2e;
  --muted: #666b85;
  --nav-border: rgba(0, 0, 0, 0.12);
  --row-tint: rgba(0, 0, 0, 0.04);
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  min-height: 100vh;
  background: radial-gradient(circle at top, var(--bg-glow), var(--bg) 60%);
  color: var(--text);
  font-family: "Segoe UI", Arial, sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.5rem 1rem 3rem;
  transition: background 0.3s ease, color 0.3s ease;
}

header {
  position: relative;
  text-align: center;
  margin-bottom: 1.5rem;
  width: 100%;
  max-width: 1000px;
}

header h1 {
  margin: 0 0 0.75rem;
  line-height: 0;
}

#logo {
  height: clamp(2.2rem, 8vw, 3.2rem);
  width: auto;
}

/* Cluster des boutons utilitaires en haut à droite du header : changelog en
   accès direct (2026-08-11), + un bouton ☰ qui déroule comment jouer/à
   propos/admin/déconnexion ("?" reparti dans le dropdown le même jour,
   après un aller-retour). Changelog et ☰ restent visibles même déconnecté ;
   admin/déconnexion sont montrés/masqués par showApp()/showLogin() dans
   script.js (à l'intérieur du dropdown). */
#header-actions {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Menu ☰ déplacé en haut à gauche (2026-08-25, demande joueur), séparé du
   cluster chat/thème resté à droite — même #menu-wrap/#menu-dropdown
   qu'avant, juste un conteneur différent pour le positionnement. */
#header-menu {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
}

#header-actions button {
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 999px;
  width: 2.2rem;
  height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-shadow: none;
  color: var(--text);
  flex-shrink: 0;
  cursor: pointer;
}

/* Pastille de notification (2026-08-13) : nouveaux messages de chat non lus
   (voir checkChatUnread()/wireChatModal côté script.js) — masquée par
   défaut, activée en ajoutant .has-unread sur #chat-btn. Bordure de la
   couleur du bouton pour rester lisible sur l'icône même en thème clair. */
#chat-btn {
  position: relative;
}

#chat-btn.has-unread::after {
  content: "";
  position: absolute;
  top: 1px;
  right: 1px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #e0393e;
  border: 1.5px solid var(--panel-2);
}

#menu-wrap {
  position: relative;
}

/* #menu-btn stylé à part (2026-08-25) : n'est plus dans #header-actions
   depuis le déplacement du menu à gauche, il perd donc le style de bouton
   rond hérité de la règle `#header-actions button` — reproduit ici à
   l'identique. */
#menu-btn {
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 999px;
  width: 2.2rem;
  height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-shadow: none;
  color: var(--text);
  flex-shrink: 0;
  cursor: pointer;
}

#menu-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 180px;
  background: color-mix(in srgb, var(--panel-2) 65%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--nav-border);
  border-radius: 14px;
  padding: 0.5rem;
}

/* Boutons du dropdown : icône rondes → ligne icône + texte (2026-08-25,
   demande joueur), plus lisible qu'une colonne d'icônes muettes. */
#menu-dropdown button {
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 0.45rem 0.6rem;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.6rem;
  box-shadow: none;
  color: var(--text);
  font-size: 0.8rem;
  white-space: nowrap;
  cursor: pointer;
}

#menu-dropdown button svg {
  flex-shrink: 0;
}

#menu-dropdown button:hover,
#menu-dropdown button:focus-visible {
  background: var(--panel-2);
}

#user-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  margin-bottom: 0.75rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.user-bar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
}

/* Badges header (pièces/combat/rang de prestige/jetons) resserrés le
   2026-08-20 (demande joueur) : taille/padding réduits pour tenir sur une
   ligne plus compacte, même palette de couleurs qu'avant. Cliquables depuis
   le 2026-08-25 (demande joueur : ouvrir les stats prestige/dresseur
   directement depuis la bulle plutôt que via un bouton dédié dans l'onglet
   Profil/Combat, voir wireStatsModals()/wireTrainerStatsModal()) — curseur
   + léger effet au survol pour signaler l'interactivité. */
.prestige-badge {
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  color: var(--hyper-rare);
  font-size: 0.62rem;
  font-weight: 600;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s ease;
}

.prestige-badge:hover,
.prestige-badge:focus-visible {
  background: color-mix(in srgb, var(--panel-2) 70%, var(--hyper-rare) 30%);
}

.coins-badge {
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  color: var(--hyper-rare);
  font-size: 0.62rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  white-space: nowrap;
}

.tokens-badge {
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  color: var(--ultra-rare);
  font-size: 0.62rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  white-space: nowrap;
}

#admin-panel {
  position: relative;
  width: 100%;
  max-width: 420px;
  margin: 0 auto 0.75rem;
  background: var(--panel);
  border-radius: 12px;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}

#admin-panel-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

#admin-panel .shop-hint {
  margin-bottom: 0.15rem;
}

/* Actions admin : icônes rondes + petit label, sur une ligne (même
   vocabulaire visuel que la nav), mais en gardant les couleurs "chaudes"
   des boutons d'origine (danger rouge, dégradé du bouton principal pour
   l'action positive) au lieu du monochrome utilisé pour la nav/le header. */
#admin-actions {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.admin-action {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--muted);
  font-size: 0.65rem;
  font-weight: 600;
}

.admin-action svg {
  flex-shrink: 0;
  width: 2.4rem;
  height: 2.4rem;
  padding: 0.55rem;
  border-radius: 10px;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  box-sizing: border-box;
  color: var(--text);
}

.admin-action.danger svg {
  background: #c0392b;
  border-color: transparent;
  color: #fff;
}

.admin-action.hot svg {
  background: linear-gradient(135deg, #ffcc33, #e0393e);
  border-color: transparent;
  color: #1a1a2e;
}

.nav-btn {
  font: inherit;
  font-weight: 600;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  border: 1px solid var(--nav-border);
  cursor: pointer;
  background: transparent;
  color: var(--muted);
  white-space: nowrap;
}

.nav-btn.active {
  background: var(--panel-2);
  color: var(--text);
  border-color: transparent;
}

/* Nav principale, style "tab bar" (2026-08-25, refonte demandée par le
   joueur : "pas jolie et trop nombreuse" sur les 7 icônes en chips carrées
   — voir todo.txt) : plus de fond carré par icône, juste l'icône seule
   (pas de label, cf. aria-label/title sur chaque bouton pour
   l'accessibilité) + un petit point sous l'icône active, façon tab bar
   iOS/Android. Remplace l'ancien vocabulaire "cercle monochrome" utilisé
   ici jusqu'à cette date (encore en usage sur #admin-btn/#logout-btn,
   header, non touchés par ce changement). */
#view-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem;
  margin-bottom: 1.5rem;
}

#view-nav .nav-btn {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.5rem 0.9rem;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  box-shadow: none;
  transition: color 0.15s ease;
}

#view-nav .nav-btn svg {
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  color: inherit;
}

/* Indicateur d'onglet actif : petit point plutôt qu'un fond plein, pour
   rester discret (tab bar minimaliste) tout en restant visible dans les
   deux thèmes. */
#view-nav .nav-btn::after {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: transparent;
  transition: background 0.15s ease;
}

#view-nav .nav-btn.active {
  color: var(--rare);
}

#view-nav .nav-btn.active::after {
  background: var(--rare);
}

main {
  width: 100%;
  max-width: 1000px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
}

.hidden {
  display: none !important;
}

/* ---------- Booster ---------- */

#view-pack {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
}

#pack-stage {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

#pack-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 800px;
}

#pack-wrapper.fading-out {
  transition: opacity 0.3s ease;
  opacity: 0;
}

/* Flèches de sélection de série (2026-08-06, repurposé le 2026-08-20 :
   plus de tiers classique/premium/ultra à choisir, juste la série ciblée
   par le tirage — voir cycleSet()/updatePackDisplay() dans script.js). */
.pack-nav {
  flex-shrink: 0;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  line-height: 1;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  box-shadow: none;
}

#pack-tier-line {
  text-align: center;
  margin: -0.5rem 0 0;
}

#pack-tier-name {
  font-weight: 700;
}

#pack-tier-cap {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted);
}

#pack {
  width: clamp(220px, 60vw, 340px);
  height: auto;
  aspect-ratio: 466 / 700;
  object-fit: contain;
  filter: drop-shadow(0 12px 30px rgba(0, 0, 0, 0.5));
  transition: transform 0.4s ease, opacity 0.4s ease;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  user-select: none;
  pointer-events: none;
}

/* Badge Vault sur le booster (2026-08-25, demande joueur) : X/Y cartes de
   la série affichée déjà vaultées — même vocabulaire visuel que
   .new-badge/.vault-badge (pastille sombre coin haut-droit) ailleurs sur
   le site. z-index au-dessus de #pack (drop-shadow) mais pas besoin d'en
   fixer un explicitement sur les rabats/flash : ceux-ci sont display:none
   hors animation d'ouverture, où le badge n'a de toute façon pas besoin
   de rester visible. */
.pack-vault-badge {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  white-space: nowrap;
}

/* Animation d'ouverture (2026-08-10) : le pack fait un petit tremblement
   d'anticipation, puis se "déchire" en deux rabats qui pivotent en 3D
   pendant qu'un flash radial éclate, avant que la pile de cartes apparaisse
   en pop-in — remplace l'ancien fade simple (#pack.opening). */
#pack.anticipating {
  animation: bstAnticipate 0.15s ease;
}

.pack-flap {
  position: absolute;
  inset: 0;
  display: none;
  pointer-events: none;
}

.pack-flap img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

#pack-flap-top {
  clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 90% 54%, 80% 48%, 70% 55%, 60% 47%, 50% 55%, 40% 47%, 30% 55%, 20% 48%, 10% 54%, 0% 50%);
  transform-origin: top center;
}

#pack-flap-bottom {
  clip-path: polygon(0% 50%, 10% 54%, 20% 48%, 30% 55%, 40% 47%, 50% 55%, 60% 47%, 70% 55%, 80% 48%, 90% 54%, 100% 50%, 100% 100%, 0% 100%);
  transform-origin: bottom center;
}

.pack-flap.tearing#pack-flap-top {
  display: block;
  animation: bstTearTop 0.6s ease-in forwards;
}

.pack-flap.tearing#pack-flap-bottom {
  display: block;
  animation: bstTearBottom 0.6s ease-in forwards;
}

#pack-flash {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 140%;
  height: 140%;
  margin-left: -70%;
  margin-top: -70%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 244, 214, 0.95), rgba(255, 204, 51, 0.55) 40%, transparent 72%);
  pointer-events: none;
  opacity: 0;
}

#pack-flash.flashing {
  animation: bstFlash 0.5s ease-out forwards;
}

#stack.popping-in {
  animation: bstStackIn 0.45s cubic-bezier(0.2, 0.9, 0.25, 1.4);
}

@keyframes bstAnticipate {
  0% { transform: scale(1) rotate(0); }
  40% { transform: scale(0.94) rotate(-1deg); }
  70% { transform: scale(1.05) rotate(1deg); }
  100% { transform: scale(1) rotate(0); }
}

@keyframes bstTearTop {
  from { transform: rotateX(0) translateY(0); opacity: 1; }
  to { transform: rotateX(-118deg) translateY(-46px); opacity: 0; }
}

@keyframes bstTearBottom {
  from { transform: rotateX(0) translateY(0); opacity: 1; }
  to { transform: rotateX(118deg) translateY(40px); opacity: 0; }
}

@keyframes bstFlash {
  0% { opacity: 0; transform: scale(0.2); }
  35% { opacity: 1; transform: scale(1.4); }
  100% { opacity: 0; transform: scale(2.6); }
}

@keyframes bstStackIn {
  0% { opacity: 0; transform: scale(0.82) translateY(28px); }
  60% { opacity: 1; transform: scale(1.04) translateY(-4px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}

/* Reflet qui balaie le dos de la carte active, pour inciter à la toucher. */
.stack-card.active .card-back::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(75deg, transparent 40%, rgba(255, 255, 255, 0.25) 50%, transparent 60%);
  background-size: 250% 100%;
  animation: bstShimmer 2.4s ease-in-out infinite;
}

@keyframes bstShimmer {
  0% { background-position: -150% 0; }
  100% { background-position: 250% 0; }
}

/* Éclat de rareté (2026-08-10) : burst + étincelles affichés brièvement sur
   #stack quand une carte Ultra Rare ou plus est révélée, voir
   playRarityBurst() dans script.js. */
.rarity-burst {
  position: absolute;
  inset: -20%;
  border-radius: 50%;
  pointer-events: none;
  animation: bstBurst 0.7s ease-out forwards;
}

@keyframes bstBurst {
  0% { opacity: 0.95; transform: scale(0.3); }
  100% { opacity: 0; transform: scale(2.4); }
}

.rarity-sparkle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  pointer-events: none;
  animation: bstSparkle 0.7s ease-out forwards;
}

@keyframes bstSparkle {
  0% { opacity: 1; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0); }
}

.credit-line {
  margin: 0.6rem 0 0;
  text-align: center;
  font-size: 0.7rem;
  color: var(--muted);
}


.credit-line a {
  color: var(--muted);
}

.credit-line a.donate-link {
  color: var(--muted);
  text-decoration: underline;
  font-weight: 600;
}

.credit-line-small {
  font-size: 0.6rem;
}

#open-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  box-shadow:
    0 0 0 4px rgba(255, 255, 255, 0.25),
    0 0 26px 10px rgba(255, 204, 51, 0.75),
    0 0 55px 20px rgba(224, 57, 62, 0.5);
  animation: btn-glow 2s ease-in-out infinite alternate;
}

@keyframes btn-glow {
  from {
    box-shadow:
      0 0 0 4px rgba(255, 255, 255, 0.25),
      0 0 26px 10px rgba(255, 204, 51, 0.75),
      0 0 55px 20px rgba(224, 57, 62, 0.5);
  }
  to {
    box-shadow:
      0 0 0 4px rgba(255, 255, 255, 0.3),
      0 0 34px 14px rgba(255, 204, 51, 0.9),
      0 0 70px 26px rgba(224, 57, 62, 0.65);
  }
}

/* ---------- Stack (one card at a time) ---------- */

#stack-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  width: 100%;
}

#stack-progress {
  color: var(--muted);
  margin: 0;
  font-size: 0.9rem;
  text-align: center;
}

#stack {
  position: relative;
  width: clamp(200px, 65vw, 300px);
  aspect-ratio: 63 / 88;
  margin-top: 16px;
}

.stack-card {
  position: absolute;
  inset: 0;
  perspective: 900px;
  cursor: pointer;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.stack-card .card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.stack-card.flipped .card-inner {
  transform: rotateY(180deg);
}

.stack-card.consumed {
  transform: translateY(-120%) rotate(-8deg) scale(0.9);
  opacity: 0;
  pointer-events: none;
}

.stack-card:not(.active) {
  pointer-events: none;
}

.card-price {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  right: 0;
  text-align: center;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--text);
  opacity: 0;
  transition: opacity 0.3s ease 0.15s;
}

.stack-card.flipped .card-price {
  opacity: 1;
}

.card-face {
  position: absolute;
  inset: 0;
  border-radius: 10px;
  backface-visibility: hidden;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.card-back {
  background: linear-gradient(135deg, #3b6fd6, #1a1a2e);
  border: 3px solid #0f1220;
}

.card-back::after {
  content: "?";
  font-size: 3rem;
  font-weight: bold;
  color: rgba(255, 255, 255, 0.6);
}

.card-front {
  transform: rotateY(180deg);
  background: var(--panel);
  border: 3px solid var(--common);
  flex-direction: column;
}

.card-front img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #fff;
}

.card-front.rarity-common { border-color: var(--common); }
.card-front.rarity-uncommon { border-color: var(--uncommon); box-shadow: 0 0 12px var(--uncommon); }
.card-front.rarity-rare { border-color: var(--rare); box-shadow: 0 0 14px var(--rare); }
.card-front.rarity-double-rare { border-color: var(--double-rare); box-shadow: 0 0 16px var(--double-rare); }
.card-front.rarity-ultra-rare { border-color: var(--ultra-rare); box-shadow: 0 0 18px var(--ultra-rare); }
.card-front.rarity-illustration-rare { border-color: var(--illustration-rare); box-shadow: 0 0 20px var(--illustration-rare); }
.card-front.rarity-special-illustration-rare { border-color: var(--special-illustration-rare); box-shadow: 0 0 24px var(--special-illustration-rare); }
.card-front.rarity-hyper-rare {
  border-color: var(--hyper-rare);
  box-shadow: 0 0 28px var(--hyper-rare);
  animation: shimmer 1.6s ease-in-out infinite alternate;
}

@keyframes shimmer {
  from { box-shadow: 0 0 16px var(--hyper-rare); }
  to { box-shadow: 0 0 34px var(--hyper-rare); }
}

/* 6 raretés ajoutées le 2026-08-14 — ACE SPEC/Shiny/Mega Attack en glow simple (même
   famille visuelle que Rare→Special Illustration Rare ci-dessus), Mega
   Hyper Rare et Black White Rare en scintillement dédié (au-dessus du Hyper
   Rare d'origine, la keyframe `shimmer` étant câblée sur sa propre couleur
   on ne peut pas la réutiliser telle quelle). */
.card-front.rarity-ace-spec-rare { border-color: var(--ace-spec-rare); box-shadow: 0 0 17px var(--ace-spec-rare); }
.card-front.rarity-shiny-rare { border-color: var(--shiny-rare); box-shadow: 0 0 19px var(--shiny-rare); }
.card-front.rarity-shiny-ultra-rare { border-color: var(--shiny-ultra-rare); box-shadow: 0 0 21px var(--shiny-ultra-rare); }
/* Classe en underscore (pas en tiret comme les autres) : slugify() ne
   transforme que les espaces, et la rareté brute renvoyée par l'API est
   "MEGA_ATTACK_RARE" (voir server/pack.js RARITY_ORDER). */
.card-front.rarity-mega_attack_rare { border-color: var(--mega-attack-rare); box-shadow: 0 0 26px var(--mega-attack-rare); }
.card-front.rarity-mega-hyper-rare {
  border-color: var(--mega-hyper-rare);
  box-shadow: 0 0 32px var(--mega-hyper-rare);
  animation: shimmer-mega 1.4s ease-in-out infinite alternate;
}
.card-front.rarity-black-white-rare {
  border-color: var(--black-white-rare);
  box-shadow: 0 0 36px var(--black-white-rare);
  animation: shimmer-bw 1.2s ease-in-out infinite alternate;
}

@keyframes shimmer-mega {
  from { box-shadow: 0 0 18px var(--mega-hyper-rare); }
  to { box-shadow: 0 0 40px var(--mega-hyper-rare); }
}

@keyframes shimmer-bw {
  from { box-shadow: 0 0 20px var(--black-white-rare); }
  to { box-shadow: 0 0 46px var(--black-white-rare); }
}

.rarity-badge {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  font-size: 0.65rem;
  text-align: center;
  padding: 0.2rem 0.3rem;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Badge "Nouveau" (2026-08-20) : carte tirée pas encore dans le Vault —
   voir buildStackCard(), public/script.js. Coin opposé au rarity-badge
   (haut plutôt que bas) pour ne jamais se chevaucher. */
.new-badge {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  font-size: 0.6rem;
  font-weight: 700;
  padding: 0.15rem 0.4rem;
  border-radius: 999px;
  background: var(--special-illustration-rare);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

.card-name {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  font-size: 0.65rem;
  text-align: center;
  padding: 0.2rem 0.3rem;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
}

/* ---------- Buttons ---------- */

button {
  font: inherit;
  font-weight: 600;
  padding: 0.75rem 1.5rem;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  background: linear-gradient(135deg, #ffcc33, #e0393e);
  color: #1a1a2e;
  box-shadow: 0 6px 18px rgba(224, 57, 62, 0.35);
  transition: transform 0.15s ease, opacity 0.15s ease;
}

button:hover {
  transform: translateY(-2px);
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn-secondary {
  background: var(--panel-2);
  color: var(--text);
  box-shadow: none;
  border: 1px solid var(--nav-border);
  font-size: 0.85rem;
  padding: 0.6rem 1.1rem;
}

/* ---------- Collection ---------- */

#view-collection {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}

/* Cases stats en tête de page (Bûcheronnage, etc.) : display/gap viennent de
   .stats-grid.cols-2/.cols-3, ces ids ne gardent que largeur/centrage. */
#woodcut-stocks {
  width: 100%;
  max-width: 460px;
  margin: 0 auto 1rem;
}

#collection-actions-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

/* Boutons icône ronds de #collection-actions-row (tri, prestige, vaulter
   tout) — remplace .prestige-row-btn (2026-08-25, retour joueur : "réduit
   l'icône passer prestige à la même taille que les autres" + les 3 tenant
   maintenant sur une seule ligne). Même gabarit que #menu-btn du header
   pour rester cohérent avec l'autre bouton icône rond de l'app. */
.icon-row-btn {
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: 1rem;
  box-shadow: none;
  flex-shrink: 0;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--nav-border);
}

/* ---------- Profil (2026-08-13, fusion Village/Vault) : pseudo + avatar ---------- */

.profile-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 0.25rem 0 0.75rem;
}

.profile-avatar {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--nav-border);
  padding: 0;
  box-shadow: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  flex-shrink: 0;
}

.profile-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Version en lecture seule (modale de visite) : pas de bouton d'upload, pas
   de curseur ni de badge crayon sur le conteneur — seule la photo elle-même
   (#profile-visit-avatar-img, curseur zoom ci-dessous) est cliquable, pas le
   pictogramme silhouette affiché quand le joueur n'a pas d'avatar. */
.profile-avatar-readonly {
  cursor: default;
}

#profile-visit-avatar-img {
  cursor: zoom-in;
}

button.profile-avatar {
  cursor: pointer;
}

.profile-avatar-edit {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 6px;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.65rem;
  color: var(--text);
}

.profile-name {
  font-size: 1.15rem;
  font-weight: 700;
}

/* Tuiles condensées (2026-08-10) : grille de cases carrées pour les stats
   en tête d'onglet. Passé de 2 à 4 colonnes (même jour) et aspect-ratio
   4/3 → 1 : les tuiles en 2 colonnes étaient jugées trop larges — 4 par
   ligne donne de vrais carrés plus étroits. */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.5rem;
}

/* Variante 2 cases (2026-08-25, demande joueur : même format "cases" que les
   modales de stats, mais dans les onglets Village/Combat/Vault qui n'ont que
   2 stats à afficher) — largeur de tuile fixée à ~90-100px (proche de la
   taille réelle des tuiles en 4 colonnes dans une modale à max-width 420px)
   plutôt que 1fr, sinon 2 tuiles étirées sur toute la largeur de l'onglet
   deviendraient énormes et perdraient l'esprit "petite case" demandé. */
.stats-grid.cols-2 {
  grid-template-columns: repeat(2, minmax(0, 100px));
  justify-content: center;
}

.stats-grid.cols-3 {
  grid-template-columns: repeat(3, minmax(0, 100px));
  justify-content: center;
}

.stat-tile {
  position: relative;
  min-width: 0;
  overflow: hidden;
  background: var(--panel);
  border-radius: 10px;
  padding: 0.4rem 0.3rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  text-align: center;
  aspect-ratio: 1;
}

.stat-tile-label {
  color: var(--muted);
  font-size: 0.6rem;
  line-height: 1.15;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.stat-tile-value {
  font-weight: 700;
  font-size: 0.9rem;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.odds-row.rarity-common { border-color: var(--common); }
.odds-row.rarity-uncommon { border-color: var(--uncommon); }
.odds-row.rarity-rare { border-color: var(--rare); }
.odds-row.rarity-double-rare { border-color: var(--double-rare); }
.odds-row.rarity-ultra-rare { border-color: var(--ultra-rare); }
.odds-row.rarity-illustration-rare { border-color: var(--illustration-rare); }
.odds-row.rarity-special-illustration-rare { border-color: var(--special-illustration-rare); }
.odds-row.rarity-hyper-rare { border-color: var(--hyper-rare); }
.odds-row.rarity-ace-spec-rare { border-color: var(--ace-spec-rare); }
.odds-row.rarity-shiny-rare { border-color: var(--shiny-rare); }
.odds-row.rarity-shiny-ultra-rare { border-color: var(--shiny-ultra-rare); }
.odds-row.rarity-mega_attack_rare { border-color: var(--mega-attack-rare); }
.odds-row.rarity-mega-hyper-rare { border-color: var(--mega-hyper-rare); }
.odds-row.rarity-black-white-rare { border-color: var(--black-white-rare); }

.odds-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  background: var(--panel-2);
  border-radius: 8px;
  padding: 0.4rem 0.75rem;
  border-left: 4px solid var(--common);
  font-size: 0.85rem;
}

.odds-row .odds-name {
  color: var(--text);
}

.odds-row .odds-value {
  font-weight: 700;
  color: var(--muted);
}

#collection-empty {
  color: var(--muted);
}

.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 0.85rem;
  width: 100%;
}

.collection-card {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  border: 3px solid var(--common);
  aspect-ratio: 63 / 88;
  cursor: pointer;
  transition: transform 0.15s ease;
}

.collection-card:hover {
  transform: translateY(-2px);
}

.collection-card img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #fff;
}

.collection-card .count-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
}

.collection-card .price-badge {
  position: absolute;
  bottom: 4px;
  left: 4px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 0.65rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
}

.collection-card.missing {
  cursor: default;
  border-color: var(--nav-border);
}

.collection-card.missing img {
  filter: grayscale(1);
  opacity: 0.35;
}

.collection-card.missing:hover {
  transform: none;
}

/* Vault (2026-08-06) : carte débloquée en permanence — jamais grisée même
   sans exemplaire possédé (voir buildCollectionCardEl(), script.js), léger
   liseré doré en plus de la bordure de rareté. */
.collection-card.vaulted {
  box-shadow: 0 0 0 2px var(--hyper-rare);
}

.collection-card .vault-badge {
  position: absolute;
  top: 4px;
  left: 4px;
  background: rgba(0, 0, 0, 0.75);
  font-size: 0.75rem;
  padding: 0.1rem 0.3rem;
  border-radius: 999px;
}

/* Showroom (2026-08-14) : bouton +/🏆 sur une carte du Vault (renderVaultView,
   script.js) pour l'épingler/retirer du Showroom du classement. Coin
   bas-droit, seul emplacement libre (count/vault en haut, prix en bas-gauche). */
.collection-card .showroom-toggle-badge {
  position: absolute;
  bottom: 4px;
  right: 4px;
  min-width: 1.4rem;
  height: 1.4rem;
  padding: 0 0.3rem;
  border: none;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.4rem;
  cursor: pointer;
}

.collection-card .showroom-toggle-badge:hover {
  background: rgba(0, 0, 0, 0.9);
}

.collection-card .showroom-toggle-badge.pinned {
  background: var(--hyper-rare);
  color: #000;
}

/* Vault rapide (2026-08-20, demande joueur) : même coin/style que
   .showroom-toggle-badge ci-dessus — jamais affichés en même temps sur la
   même carte (l'un exige vaulted, l'autre !vaulted), pas de conflit visuel. */
.collection-card .quick-vault-badge {
  position: absolute;
  bottom: 4px;
  right: 4px;
  width: 1.4rem;
  height: 1.4rem;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: var(--hyper-rare);
  color: #000;
  font-size: 0.8rem;
  line-height: 1.4rem;
  cursor: pointer;
}

.collection-card .quick-vault-badge:hover {
  filter: brightness(1.1);
}

.collection-card .quick-vault-badge:disabled {
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  opacity: 0.6;
  cursor: not-allowed;
}

.type-groups {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  width: 100%;
}

.type-group-title {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-size: 1rem;
}

.type-group-count {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
}

.collection-card.rarity-common { border-color: var(--common); }
.collection-card.rarity-uncommon { border-color: var(--uncommon); }
.collection-card.rarity-rare { border-color: var(--rare); }
.collection-card.rarity-double-rare { border-color: var(--double-rare); }
.collection-card.rarity-ultra-rare { border-color: var(--ultra-rare); }
.collection-card.rarity-illustration-rare { border-color: var(--illustration-rare); }
.collection-card.rarity-special-illustration-rare { border-color: var(--special-illustration-rare); }
.collection-card.rarity-hyper-rare { border-color: var(--hyper-rare); }
.collection-card.rarity-ace-spec-rare { border-color: var(--ace-spec-rare); }
.collection-card.rarity-shiny-rare { border-color: var(--shiny-rare); }
.collection-card.rarity-shiny-ultra-rare { border-color: var(--shiny-ultra-rare); }
.collection-card.rarity-mega_attack_rare { border-color: var(--mega-attack-rare); }
.collection-card.rarity-mega-hyper-rare { border-color: var(--mega-hyper-rare); }
.collection-card.rarity-black-white-rare { border-color: var(--black-white-rare); }

@media (max-width: 480px) {
  .cards-grid {
    grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
  }

  /* Nav mobile : retour à 1 seule ligne de 7, en reprenant un peu de
     largeur au padding de la page (2026-08-22, joueur : "reduit, ca dois
     tenir sur 1 ligne sur iphone 17 ou equivalent, tu peux prendre un
     peu la largeur", après le passage à 2 lignes de 4+3 du même jour
     jugé trop réduit / pas le format voulu). iPhone 17 = 402px de large
     en CSS (confirmé par recherche) — dans la fourchette déjà couverte
     par ce media query (≤480px). flex: 1 1 0 sur les 7 boutons (comme la
     v1.25.2, avant le passage à 2 lignes) garantit structurellement une
     seule ligne quelle que soit la largeur d'écran (7 items flex-grow
     somment toujours à exactement 100% du conteneur, jamais de
     débordement) — donc pas besoin de calibrer sur un écran précis.
     Contrairement à la v1.25.2, #view-nav gagne ici une marge négative
     de chaque côté (+ largeur compensée d'autant) pour mordre sur une
     partie du padding latéral de la page (1rem de base, body { padding:
     1.5rem 1rem 3rem }) et donner un peu plus de place aux 7 icônes sans
     les faire déborder du contenu ni toucher le bord de l'écran.
     Rabotée de 0.5rem à 0.3rem puis à 0.2rem (2026-08-22, joueur :
     "réduit un tout petit peu" puis "réduit encore un peu" juste après
     chaque déploiement précédent) — légère réduction à chaque fois, la
     nav reprend un peu moins de largeur sur le padding de page. */
  #view-nav {
    gap: 0.4rem;
    flex-wrap: nowrap;
    margin-left: -0.2rem;
    margin-right: -0.2rem;
    width: calc(100% + 0.4rem);
  }

  #view-nav .nav-btn {
    flex: 1 1 0;
    min-width: 0;
    padding: 0.4rem 0.2rem;
  }

  /* Icônes en taille fixe plutôt qu'étirées à 100% de la cellule flex
     (2026-08-25, refonte tab bar — ex-chip carrée pleine largeur, voir plus
     haut #view-nav .nav-btn svg) : flex: 1 1 0 ci-dessus garde la garantie
     structurelle "toujours 1 seule ligne, jamais de débordement" (7 cellules
     de largeur égale), seule la taille de l'icône dans sa cellule change. */
  #view-nav .nav-btn svg {
    width: 1.35rem;
    height: 1.35rem;
  }

  #user-bar {
    gap: 0.25rem;
    font-size: 0.8rem;
  }

  .user-bar-row {
    gap: 0.3rem;
  }
}

/* ---------- Connexion ---------- */

#view-login {
  width: 100%;
  display: flex;
  justify-content: center;
  padding-top: 2rem;
}

#login-form {
  background: var(--panel);
  border-radius: 12px;
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  max-width: 320px;
}

#login-form label {
  font-size: 0.9rem;
  color: var(--muted);
}

#login-form input {
  font: inherit;
  padding: 0.65rem 0.9rem;
  border-radius: 8px;
  border: 1px solid var(--nav-border);
  background: var(--panel-2);
  color: var(--text);
}

#login-error {
  color: var(--special-illustration-rare);
  font-size: 0.85rem;
  margin: 0;
}

/* ---------- Limite de packs ---------- */

#pack-limit {
  display: inline-block;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  color: var(--ultra-rare);
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  margin: 0 0 0.75rem;
}

/* ---------- Classement ---------- */

#view-leaderboard {
  width: 100%;
}

#leaderboard-table {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  border-collapse: collapse;
  background: var(--panel);
  border-radius: 12px;
  overflow: hidden;
}

#leaderboard-table th,
#leaderboard-table td {
  padding: 0.5rem 0.55rem;
  text-align: left;
  font-size: 0.82rem;
}

#leaderboard-table th {
  color: var(--muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--nav-border);
}

#leaderboard-table tbody tr:nth-child(even) {
  background: var(--row-tint);
}

#leaderboard-table tr.me {
  outline: 2px solid var(--hyper-rare);
  outline-offset: -2px;
}

.leaderboard-name-link {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--text);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--nav-border);
  text-underline-offset: 3px;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.leaderboard-name-link:hover {
  color: var(--rare);
  text-decoration-color: var(--rare);
}

/* Mini avatar (2026-08-13) : classement + showroom, à côté du pseudo — */
/* placeholder silhouette non dupliqué ici, l'image n'est rendue que si */
/* row.avatar existe (voir renderLeaderboardView/renderLeaderboardShowroom). */
.leaderboard-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  cursor: zoom-in;
}

.leaderboard-showroom-title {
  margin: 2rem 0 1rem;
  text-align: center;
}

.showroom-player {
  background: var(--panel);
  border-radius: 12px;
  padding: 1rem;
  margin-bottom: 1rem;
}

.showroom-player-name {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.75rem;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
  font: inherit;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}

.showroom-player-name:hover {
  color: var(--rare);
}

.showroom-cards {
  grid-template-columns: repeat(3, minmax(100px, 160px));
}

/* ---------- Modale "à propos" (contenu ex-footer) ---------- */

#about-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#about-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#about-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(90vw, 420px);
  max-height: 90vh;
  overflow-y: auto;
  color: var(--muted);
  font-size: 0.8rem;
  text-align: center;
}

#about-modal-content p {
  margin: 0 0 0.5rem;
}

#about-modal-content .legal {
  font-size: 0.7rem;
  opacity: 0.7;
  line-height: 1.5;
}

#about-modal-content a {
  color: var(--muted);
  text-decoration: underline;
}

#about-modal-content .version {
  opacity: 0.6;
  font-size: 0.7rem;
  margin-bottom: 0;
}

#about-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

/* ---------- Modale "comment jouer" ---------- */

#help-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#help-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#help-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(92vw, 520px);
  max-height: 85vh;
  overflow-y: auto;
  color: var(--text);
  font-size: 0.8rem;
  text-align: left;
}

#help-modal-title {
  margin: 0 0 1rem;
  font-size: 1rem;
  text-align: center;
}

#help-modal-body p {
  margin: 0 0 0.75rem;
  line-height: 1.5;
}

#help-modal-body p:last-child {
  margin-bottom: 0;
}

#help-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

/* ---------- Modale "changelog" ---------- */

#changelog-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#changelog-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#changelog-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(92vw, 520px);
  max-height: 85vh;
  overflow-y: auto;
  color: var(--text);
  font-size: 0.8rem;
  text-align: left;
}

#changelog-modal-title {
  margin: 0 0 1rem;
  font-size: 1rem;
  text-align: center;
}

#changelog-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

.changelog-day + .changelog-day {
  margin-top: 1.1rem;
}

.changelog-day-title {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--nav-border);
  padding-bottom: 0.3rem;
}

.changelog-entry {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  line-height: 1.45;
}

.changelog-entry:last-child {
  margin-bottom: 0;
}

.changelog-tag {
  flex-shrink: 0;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  padding: 0.12rem 0.4rem;
  border-radius: 999px;
  border: 1px solid currentColor;
  white-space: nowrap;
}

.changelog-tag.ajout { color: var(--uncommon); }
.changelog-tag.modification { color: var(--rare); }
.changelog-tag.suppression { color: var(--special-illustration-rare); }
.changelog-tag.evenement { color: var(--double-rare); }

.changelog-entry-text {
  color: var(--muted);
}

/* ---------- Modale "activité récente" (2026-08-25) ---------- */

#activity-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#activity-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#activity-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(92vw, 520px);
  max-height: 85vh;
  overflow-y: auto;
  color: var(--text);
  font-size: 0.8rem;
  text-align: left;
}

#activity-modal-title {
  margin: 0 0 1rem;
  font-size: 1rem;
  text-align: center;
}

#activity-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

#activity-modal-empty {
  color: var(--muted);
  text-align: center;
  margin: 0;
}

.activity-entry {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
  line-height: 1.45;
}

.activity-entry:last-child {
  margin-bottom: 0;
}

.activity-entry-icon {
  flex-shrink: 0;
}

.activity-entry-text {
  flex: 1;
}

.activity-entry-time {
  flex-shrink: 0;
  font-size: 0.68rem;
  color: var(--muted);
  white-space: nowrap;
}

/* ---------- Popup d'annonce (2026-08-06) ---------- */

#announcement-modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#announcement-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
}

#announcement-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border: 1px solid var(--hyper-rare);
  border-radius: 14px;
  padding: 1.5rem;
  max-width: min(90vw, 480px);
  max-height: 85vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

#announcement-modal-title {
  margin: 0;
  text-align: center;
}

#announcement-modal-body {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--text);
}

#announcement-modal-body p {
  margin: 0 0 0.6rem;
}

#announcement-modal-body ul {
  margin: 0 0 0.6rem;
  padding-left: 1.2rem;
}

#announcement-close {
  background: linear-gradient(135deg, var(--hyper-rare), var(--double-rare));
  color: #1a1a2e;
  font-weight: 700;
}

/* ---------- Boutique ---------- */

#view-shop,
#view-woodcut,
#view-market {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}

/* #shop-buy/#shop-sell n'avaient pas de gap propre : leurs blocs internes
   (ex. Booster et Bâtiments & voitures) se retrouvaient collés l'un à
   l'autre au lieu d'hériter de l'espacement de #view-shop. */
#shop-buy,
#shop-sell {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}

.shop-block {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.shop-block h2 {
  margin: 0;
  font-size: 1.1rem;
}

.shop-hint {
  color: var(--muted);
  font-size: 0.8rem;
  text-align: center;
  margin: 0;
  max-width: 480px;
}

.shop-sell-list {
  width: 100%;
  max-width: 560px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.shop-sell-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--panel);
  border-radius: 10px;
  padding: 0.5rem 0.75rem;
}

.shop-sell-row img {
  width: 40px;
  height: 56px;
  object-fit: contain;
  background: #fff;
  border-radius: 6px;
  flex-shrink: 0;
}

.shop-sell-info {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.shop-sell-name {
  font-size: 0.85rem;
}

.shop-sell-count {
  color: var(--muted);
}

.shop-sell-price {
  color: var(--muted);
  font-size: 0.75rem;
}

.shop-sell-qty {
  width: 3.5rem;
  font: inherit;
  padding: 0.4rem;
  border-radius: 6px;
  border: 1px solid var(--nav-border);
  background: var(--panel-2);
  color: var(--text);
  text-align: center;
}

.shop-catalog {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.75rem;
  width: 100%;
}

.shop-item {
  background: var(--panel);
  border-radius: 12px;
  padding: 0.9rem 0.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  text-align: center;
}

.shop-item-emoji {
  font-size: 2rem;
}

.shop-item-name {
  font-size: 0.85rem;
  font-weight: 600;
}

.shop-item-category {
  color: var(--muted);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.shop-item-income {
  color: var(--uncommon);
  font-size: 0.7rem;
  font-weight: 600;
}

.shop-item-buy {
  font-size: 0.8rem;
  padding: 0.5rem 1rem;
  margin-top: 0.25rem;
}

.shop-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Dropdown de tri (2026-08-25, remplace les 3 boutons #collection-sort-tabs
   "Rareté/Prix - Par type - Par série") : même pattern visuel que
   #menu-wrap/#menu-dropdown du header (bouton icône rond + panneau flottant
   flouté), pour que le tri tienne sur la ligne #collection-actions-row avec
   Passer prestige/Vaulter tout au lieu de sa propre rangée pleine largeur. */
#sort-wrap {
  position: relative;
}

#sort-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 160px;
  background: color-mix(in srgb, var(--panel-2) 65%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--nav-border);
  border-radius: 14px;
  padding: 0.5rem;
}

#sort-dropdown button {
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 0.45rem 0.6rem;
  display: block;
  text-align: left;
  box-shadow: none;
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

#sort-dropdown button:hover,
#sort-dropdown button:focus-visible {
  background: var(--panel-2);
}

#sort-dropdown button.active {
  background: var(--panel-2);
  font-weight: 700;
}

/* ---------- Bûcheronnage (2026-08-26) ---------- */

#woodcut-click-btn {
  width: 100%;
  max-width: 460px;
  padding: 0.9rem;
  font-size: 1.1rem;
  font-weight: 700;
  background: linear-gradient(135deg, var(--hyper-rare), var(--double-rare));
  color: #1a1a2e;
}

#woodcut-sell-row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
  width: 100%;
  max-width: 460px;
}

.woodcut-sell-btn {
  flex: 1 1 0;
  font-size: 0.75rem;
  padding: 0.45rem 0.3rem;
}

/* ---------- Marché & Cosmétiques (2026-08-26) ---------- */

.market-listing-price {
  font-size: 0.7rem;
  color: var(--muted);
  text-align: center;
  padding: 0.15rem 0.3rem;
}

.market-action-btn {
  font-size: 0.7rem;
  padding: 0.2rem 0.5rem;
  margin-top: 0.15rem;
}

.cosmetic-badge {
  display: inline-block;
  background: var(--panel);
  border: 1px solid var(--nav-border);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  font-size: 0.75rem;
  margin: 0 0.3rem 0.3rem 0;
}

#profile-visit-cosmetics:empty {
  display: none;
}

/* ---------- Modale visite de profil (depuis un pseudo cliqué au classement/showroom) ---------- */

#profile-visit-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#profile-visit-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#profile-visit-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: min(90vw, 480px);
  max-height: 90vh;
  overflow-y: auto;
}

#profile-visit-modal-content .cards-grid {
  max-width: 100%;
}

#profile-visit-modal-content h2 {
  margin: 0;
  text-align: center;
  font-size: 1.1rem;
}

#profile-visit-modal-content .profile-header {
  flex-direction: column;
  gap: 0.4rem;
}

#profile-visit-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

/* ---------- Modale chat global (2026-08-13, bouton 💬 dans le header) ---------- */

#chat-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#chat-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#chat-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: min(90vw, 420px);
  height: min(75vh, 560px);
}

#chat-modal-content h2 {
  margin: 0;
  text-align: center;
  font-size: 1.1rem;
  flex-shrink: 0;
}

#chat-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

#chat-messages {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-right: 0.25rem;
}

.chat-message {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}

.chat-message-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  flex-shrink: 0;
}

.chat-message-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: zoom-in;
}

.chat-message-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.chat-message-meta {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}

.chat-message-name {
  font-weight: 600;
  font-size: 0.8rem;
}

.chat-message-time {
  color: var(--muted);
  font-size: 0.65rem;
}

.chat-message-text {
  margin: 0;
  font-size: 0.9rem;
  overflow-wrap: anywhere;
}

#chat-form {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

#chat-input {
  flex: 1;
  min-width: 0;
}

/* ---------- Modale roulette quotidienne ---------- */

#roulette-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#roulette-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#roulette-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(90vw, 380px);
  max-height: 90vh;
  overflow-y: auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

#roulette-modal-content h2 {
  margin: 0;
}

#roulette-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

#roulette-wheel {
  font-size: 4rem;
  line-height: 1;
}

#roulette-wheel.spinning {
  animation: roulette-spin 0.5s linear infinite;
}

@keyframes roulette-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

#roulette-result {
  font-weight: 600;
  font-size: 1.05rem;
}

/* ---------- Modale taux de drop par booster ---------- */

#pack-odds-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#pack-odds-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#pack-odds-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(90vw, 380px);
  max-height: 90vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
}

#pack-odds-modal-content h2 {
  margin: 0 0 0.25rem;
  text-align: center;
}

#pack-odds-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

#pack-odds-list {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.pack-odds-group {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.odds-rows {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* ---------- Modale carte agrandie ---------- */

#card-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#card-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#card-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  max-width: min(90vw, 380px);
  max-height: 90vh;
  overflow-y: auto;
}

#card-modal-img {
  width: 100%;
  border-radius: 10px;
  background: #fff;
}

#card-modal-name {
  font-weight: 700;
  text-align: center;
  margin: 0;
}

#card-modal-meta {
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
  margin: 0;
}

#card-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

/* ---------- Modale "photo de profil en grand" (2026-08-13) ---------- */
/* Avatars en lecture seule uniquement (classement, showroom, modale de */
/* visite, chat) — voir wireAvatarZoomTrigger()/openAvatarZoom() côté script.js. */

#avatar-zoom-modal {
  position: fixed;
  inset: 0;
  z-index: 210;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#avatar-zoom-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
}

#avatar-zoom-modal-content {
  position: relative;
  z-index: 1;
}

#avatar-zoom-img {
  display: block;
  width: min(90vw, 420px);
  height: min(90vw, 420px);
  max-height: 80vh;
  object-fit: cover;
  border-radius: 16px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}

#avatar-zoom-modal-close {
  position: absolute;
  top: -0.6rem;
  right: -0.6rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

/* ---------- Modale "thème" ---------- */

#theme-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

#theme-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
}

#theme-modal-content {
  position: relative;
  z-index: 1;
  background: var(--panel);
  border-radius: 14px;
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: min(92vw, 420px);
  max-height: 85vh;
  overflow-y: auto;
  color: var(--text);
  text-align: left;
}

#theme-modal-title {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  text-align: center;
}

#theme-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--panel-2);
  border: 1px solid var(--nav-border);
  border-radius: 8px;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  padding: 0;
  box-shadow: none;
  color: var(--text);
}

#theme-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
}

.theme-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  background: var(--panel-2);
  border: 2px solid var(--nav-border);
  border-radius: 12px;
  padding: 0.6rem;
  box-shadow: none;
  color: var(--text);
  font-size: 0.75rem;
  font-weight: 600;
}

.theme-swatch.active {
  border-color: var(--hyper-rare);
}

.theme-swatch-preview {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.9rem;
}

.theme-swatch-label {
  text-align: center;
}
