/* ============================================================
   WaifuCatch Dex — feuille de style
   Esthétique gacha sombre, tropicale / néon
   ============================================================ */

:root{
  /* Fond / surfaces */
  --bg: #130c24;        /* nuance noir ↔ violet Twitch (fond de page) */
  --bg-2: #1a1138;
  --surface: #1c1533;   /* cartes/encarts : même base, légèrement violacée */
  --surface-2: #261a47;
  --border: #36295e;
  --text: #eaf0ff;
  --text-dim: #9aa6c9;
  --text-faint: #8b97bd;
  /* ⚠️ ALIAS OBLIGATOIRES (2026-08-04). `--text-primary`, `--text-secondary` et
     `--text-muted` étaient employés 14 fois dans la feuille — dont 5 SANS repli — mais
     n'étaient définis NULLE PART (ni ici, ni dans arena-board.css). Une `var()` sans
     valeur ni repli rend la déclaration invalide : la propriété retombe sur l'HÉRITAGE.
     MESURÉ AU NAVIGATEUR : `.dk-chip` (pastilles de « Mes Decks ») calculait
     rgb(234,240,255) — soit exactement --text, la couleur du TITRE du deck. Le ton
     « secondaire » voulu n'existait donc pas, et toute la fiche s'affichait à plat.
     Ces trois alias pointent sur la palette existante : aucune couleur nouvelle. */
  --text-primary: var(--text);
  --text-secondary: #c3ccea;   /* entre --text et --text-dim : lisible, mais en retrait */
  --text-muted: var(--text-dim);

  /* Accents néon tropicaux (RÉSERVÉS AUX CARTES : holo, auras de rareté, céleste) */
  --neon-1: #00e5ff;   /* cyan lagon */
  --neon-2: #ff4d8d;   /* rose corail */
  --neon-pink: #ff4d8d;
  --neon-purple: #b14dff;

  /* Accents du CHROME (interface) — lavande douce, aligné sur le dashboard streamer.
     Le chrome (header, nav, boutons, sidebar, titres, filtres) utilise ces teintes,
     PAS les --neon-* (qui restent l'identité des cartes). Zéro néon criard. */
  --chrome-1: #a78bfa;   /* lavande douce */
  --chrome-2: #8b5cf6;   /* lavande profonde */

  /* Couleurs de rareté */
  --r-common: #9e9e9e;
  --r-rare: #2196f3;
  --r-epic: #9c27b0;
  --r-legendary: #ff9800;
  --r-mythic: #f44336;
  --r-divine: #e040fb;
  --r-celestial: #ffffff;   /* céleste = BLANC de base (le halo/aura, lui, est multicolore) */

  --radius: 16px;
  --radius-sm: 10px;
  --shadow: 0 10px 40px rgba(0, 0, 0, .45);
  --maxw: 1240px;

  /* Mise en page application */
  --sidebar-w: 300px;

  /* ══════════════════════════════════════════════════════════════════════════
     ✍️ POLICES — TROIS VARIABLES, UN SEUL ENDROIT (2026-08-04)
     --------------------------------------------------------------------------
     DEMANDE ADMIN : « essayons de revenir sur une autre police plus intéressante,
     sans modifier les nombres et chiffres qui sont bien écrits sur les cartes. Si tu
     modifies la police cela devra se faire pour TOUT, pas que le deck. »

     CE QUI EXISTAIT. 77 déclarations `font-family` en dur, réparties dans toute la
     feuille : Rajdhani pour le corps, Orbitron pour à peu près tous les titres ET
     tous les compteurs, Righteous pour le wordmark. Trois familles GOOGLE FONTS,
     donc trois requêtes vers un CDN, et aucun moyen de changer la police du Dex
     autrement qu'en éditant 77 lignes.

     CE QUI S'APPLIQUE MAINTENANT.
       --font-ui   → LE texte, partout : titres, boutons, pastilles, libellés, cartes.
                     Une seule famille pour tout le Dex ET pour le plateau
                     (arena-board.css pose la MÊME pile dans --tcg-sans).
       --font-num  → les CHIFFRES et les STATS. C'est la famille des CARTES, celle
                     que l'admin trouve réussie : on n'y touche pas. `lining-nums
                     tabular-nums` l'accompagne systématiquement — la fonte de
                     chiffres par défaut de Palatino est ANCIENNE (chiffres bas de
                     casse à jambages descendants) : sans ça, « 96/140 » danse.
       --font-mono → les CODES à recopier (promo, Discord, commandes de chat).

     AUCUNE POLICE EXTERNE. Uniquement des faces présentes sur les systèmes, avec un
     repli explicite. Le repli JAPONAIS est explicite (Hiragino Sans, Noto Sans JP,
     Yu Gothic UI, Meiryo) : le Dex est servi en ja, et sans lui la page bascule sur
     une face au hasard. Les faces EMOJI restent dans la pile — le Dex écrit 🃏 👑 ⚔️
     dans son texte courant.

     ⚠️ TROISIÈME ET DERNIÈRE PASSE — 2026-08-05. DEUX POLICES REJETÉES DE SUITE.
     1) Palatino en serif sur le texte des cartes → « rendu Yu-Gi-Oh », rejetée.
     2) Trebuchet MS partout (le réglage ci-dessus) → « la police d'écriture ne me
        plaît pas », rejetée aussi.
     CONSIGNE APPLIQUÉE : arrêter de chercher une police « de caractère ». `--font-ui`
     est désormais une PILE SYSTÈME NEUTRE : `system-ui` d'abord — la face d'interface
     de l'OS, celle que le lecteur lit toute la journée sans y penser (Segoe UI Variable
     sur Windows 11, SF sur Apple, Roboto sur Android) — puis les mêmes faces nommées
     en repli pour les moteurs qui ignorent `system-ui`. Trebuchet MS ne figure PLUS
     dans la pile, à aucun rang.
     Le cachet « jeu de cartes » ne vient plus de la fonte mais de la MISE EN PAGE et
     de la COULEUR (cf. le bloc « CONSTRUCTEUR DE DECK — CHÂSSIS SOBRE » en fin de
     feuille). C'est aussi ce qui rend ce choix tenable : une pile système ne se
     télécharge pas, ne clignote pas au chargement, et rend correctement les quatre
     langues servies (fr / en / ja / rcf).
     ⚠️ `--font-num` N'EST PAS TOUCHÉE : Palatino sur les CHIFFRES et les STATS est le
     SEUL point que l'administrateur valide depuis le début. Toute modification de
     cette ligne est une régression.
     (Vérifié au navigateur sur cette machine : Segoe UI / Yu Gothic UI / Palatino
     Linotype présents ; Rajdhani, Orbitron et Righteous ABSENTS — ils ne venaient QUE
     du CDN.)
     ══════════════════════════════════════════════════════════════════════════ */
  --font-ui: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
             'Hiragino Sans', 'Noto Sans JP', 'Yu Gothic UI', Meiryo,
             'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif;
  --font-num: 'Palatino Linotype', 'Book Antiqua', Palatino, Georgia, 'Times New Roman', serif;
  --font-mono: Consolas, ui-monospace, SFMono-Regular, Menlo, 'Liberation Mono', monospace;
}

*{ box-sizing: border-box; }

html, body{ margin: 0; padding: 0; }

body{
  font-family: var(--font-ui);
  color: var(--text);
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(145, 70, 255, .24), transparent 60%),
    radial-gradient(1000px 500px at 0% 0%, rgba(145, 70, 255, .16), transparent 55%),
    radial-gradient(900px 700px at 50% 120%, rgba(255, 77, 141, .08), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
body.sidebar-open{ overflow: hidden; }

h1, h2, h3{ font-family: var(--font-ui); letter-spacing: .5px; margin: 0; }

a{ color: inherit; text-decoration: none; }

img{ display: block; }

/* ===================== APP : 2 COLONNES ===================== */
.app{
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  align-items: start;
  min-height: 100vh;
}

/* ===================== SIDEBAR ===================== */
.sidebar{
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 22px 18px 28px;
  background: linear-gradient(180deg, rgba(22, 28, 48, .92), rgba(13, 17, 30, .96));
  border-right: 1px solid var(--border);
  backdrop-filter: blur(10px);
  z-index: 30;
  scrollbar-width: thin;
  scrollbar-color: var(--surface-2) transparent;
}
.sidebar::-webkit-scrollbar{ width: 8px; }
.sidebar::-webkit-scrollbar-thumb{ background: var(--surface-2); border-radius: 999px; }

.brand{ display: flex; align-items: center; gap: 12px; min-width: 0; }
.brand-mark{
  font-size: 1.55rem;
  line-height: 1;
  filter: drop-shadow(0 0 8px rgba(0, 229, 255, .6));
  flex: 0 0 auto;
}
.brand-logo{
  height: 30px; width: 30px;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
}
/* Wordmark « WaifuDex » (header + footer). Il portait Righteous, une display GRASSE de
   poids UNIQUE 400 : sur --font-ui, ce même 400 rendait un wordmark maigrelet. La
   signature passe donc au POIDS et à l'interlettrage — pas à une 4e famille. */
.brand-title{
  font-family: var(--font-ui);
  font-weight: 800;
  font-size: 1.32rem;
  letter-spacing: .5px;
  white-space: nowrap;
}
/* « Waifu » : lavande douce (chrome dé-néonisé, cohérent avec le dashboard streamer). */
.brand-title-accent{
  background: linear-gradient(135deg, var(--chrome-1), var(--chrome-2));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* Zone connexion / profil dans la sidebar */
.header-right{ display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
/* ⚠️ SEUL point du chrome où --font-ui a coûté une ligne (2026-08-04). MESURÉ au
   navigateur, avant/après, sur les 47 éléments de la barre latérale et de la landing :
   un seul a changé de hauteur au-delà de 2 px — « Se connecter avec Twitch », 43 px → 60 px.
   Rajdhani était CONDENSÉE ; --font-ui ne l'est pas, et le libellé le plus long du site
   dépassait de ~3 px la largeur utile de la sidebar (300 px, moins 36 px de marges, moins
   2×20 px de padding de bouton, moins le logo Twitch). On rend les 12 px qui manquent :
   c'est le seul bouton contraint par une colonne fixe, les autres vivent dans des
   conteneurs fluides. Rien d'autre du chrome n'est touché. */
.header-right .btn{ justify-content: center; padding-left: 14px; padding-right: 14px; }

/* Pied de sidebar : « Se déconnecter » épinglé tout en bas */
.sidebar-foot{ margin-top: auto; display: flex; flex-direction: column; align-items: stretch; }
.sidebar-foot:empty{ display: none; }
.sidebar-foot .btn{ justify-content: center; }

/* Sections de la sidebar */
.sidebar-dex{ display: flex; flex-direction: column; gap: 18px; }
.side-section{
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.side-title{
  font-family: var(--font-ui);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 12px;
}

/* ---- Sélecteur de langue (FR / EN) ---- */
.lang-switch{
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}
.lang-switch button{
  font-family: var(--font-ui);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--text-faint);
  background: transparent;
  border: 0;
  border-radius: 999px;
  padding: 5px 12px;
  line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: color .15s ease, background .15s ease, box-shadow .15s ease;
}
.lang-switch button:hover{ color: var(--text); }
.lang-switch button.active{
  color: #fff;
  background: linear-gradient(135deg, var(--chrome-1), var(--chrome-2));
  box-shadow: 0 2px 8px rgba(139, 92, 246, .3);
}

/* ---- Repli de la sidebar (bureau) ---- */
.sidebar-collapse{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: .85rem;
  color: var(--text-dim);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 14px;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.sidebar-collapse:hover{ color: var(--text); border-color: var(--chrome-1); }
.sidebar-collapse-chevron{ font-size: 1.1rem; line-height: 1; }

/* Bouton de réouverture, affiché dans le contenu quand la sidebar est repliée */
.sidebar-expand{
  display: none;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  margin-bottom: 18px;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: .9rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .2s ease;
}
.sidebar-expand:hover{ border-color: var(--chrome-1); box-shadow: 0 2px 12px rgba(139, 92, 246, .18); }

/* État replié : la grille occupe toute la largeur */
body.sidebar-collapsed .app{ grid-template-columns: minmax(0, 1fr); }
body.sidebar-collapsed .sidebar{ display: none; }
body.sidebar-collapsed .sidebar-expand{ display: inline-flex; }

/* Bouton fermeture + voile (mobile uniquement) */
.sidebar-close{ display: none; }
.sidebar-overlay{
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(5, 7, 14, .6);
  backdrop-filter: blur(2px);
}

/* Barre mobile (cachée en bureau) */
.mobile-topbar{ display: none; }
.menu-toggle{
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 9px 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.menu-toggle-bars, .menu-toggle-bars::before, .menu-toggle-bars::after{
  content: '';
  display: block;
  width: 18px; height: 2px;
  background: var(--chrome-1);
  border-radius: 2px;
  position: relative;
}
.menu-toggle-bars::before{ position: absolute; top: -6px; }
.menu-toggle-bars::after{ position: absolute; top: 6px; }

.user-chip{
  display: flex; align-items: center; gap: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 6px 5px 12px;
}
.user-chip-name{ font-weight: 600; font-size: 1rem; line-height: 1; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-avatar{
  height: 34px; width: 34px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--chrome-2);
}

/* ===================== BOUTONS ===================== */
.btn{
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1rem;
  border: none;
  border-radius: 999px;
  padding: 11px 20px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  transition: transform .12s ease, box-shadow .2s ease, filter .2s ease;
  color: #fff;
}
.btn:active{ transform: translateY(1px) scale(.99); }
.btn-twitch{
  background: #9146ff;
  box-shadow: 0 6px 22px rgba(145, 70, 255, .45);
}
.btn-twitch:hover{ filter: brightness(1.08); box-shadow: 0 8px 28px rgba(145, 70, 255, .6); }
.btn-twitch svg{ width: 18px; height: 18px; fill: currentColor; }
.btn-twitch.is-disabled{ background: #4a4566; box-shadow: none; cursor: not-allowed; }

.btn-ghost{
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
}
.btn-ghost:hover{ border-color: var(--chrome-1); color: var(--text); }

/* Bouton "Se déconnecter" : fond rouge. */
.btn-logout{
  background: linear-gradient(135deg, #e23b4e, #b1182c);
  color: #fff;
  box-shadow: 0 5px 18px rgba(226, 59, 78, .38);
}
.btn-logout:hover{ filter: brightness(1.08); box-shadow: 0 7px 24px rgba(226, 59, 78, .55); }

/* ===================== MAIN / ÉTATS ===================== */
.main{
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding: 28px 28px 50px;
}
.main > .footer{ margin-top: auto; }

.state{ animation: fade .35s ease; }
@keyframes fade{ from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.state-loading, .state-error{
  text-align: center;
  padding: 64px 24px;
  color: var(--text-dim);
  max-width: 520px;
  margin: 48px auto;
  border-radius: 22px;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(167, 139, 250, .12), transparent 60%),
    linear-gradient(180deg, rgba(28, 34, 58, .55), rgba(15, 20, 36, .55));
  border: 1px solid color-mix(in srgb, var(--chrome-1) 18%, var(--border));
  box-shadow: 0 24px 60px -34px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .05);
}
.state-loading p{ font-size: 1.05rem; margin: 0; animation: statePulse 1.8s ease-in-out infinite; }
@keyframes statePulse{ 0%, 100% { opacity: .6; } 50% { opacity: 1; } }
.state-icon{ font-size: 3rem; margin-bottom: 8px; filter: drop-shadow(0 4px 14px rgba(0, 0, 0, .5)); }
.state-error h2{ margin-bottom: 10px; color: var(--text); }
.state-error p{ margin: 0 auto 18px; max-width: 460px; }

/* Spinner : double anneau doux (lavande), plus élégant qu'un simple bord */
.spinner{
  position: relative;
  width: 52px; height: 52px;
  margin: 0 auto 22px;
  border: 4px solid color-mix(in srgb, var(--chrome-1) 16%, var(--surface-2));
  border-top-color: var(--chrome-1);
  border-radius: 50%;
  animation: spin .9s cubic-bezier(.5, .15, .5, .85) infinite;
}
.spinner::after{
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  border: 3px solid transparent;
  border-bottom-color: color-mix(in srgb, var(--chrome-2) 70%, transparent);
  animation: spin 1.4s linear infinite reverse;
}
@keyframes spin{ to { transform: rotate(360deg); } }

/* Badge mode aperçu */



/* ===================== LANDING ===================== */
.state-landing{ position: relative; padding-top: 40px; }
/* Halo radial lavande doux derrière la carte d'accueil (profondeur, façon dashboard streamer) */
.state-landing::before{
  content: '';
  position: absolute;
  left: 50%; top: -40px;
  width: min(760px, 92%); height: 520px;
  transform: translateX(-50%);
  z-index: 0;
  background:
    radial-gradient(60% 55% at 50% 40%, rgba(167, 139, 250, .22), transparent 70%),
    radial-gradient(45% 40% at 70% 80%, rgba(139, 92, 246, .14), transparent 72%);
  filter: blur(6px);
  pointer-events: none;
}
.landing-card{
  position: relative;
  z-index: 2;
  max-width: 620px;
  margin: 40px auto;
  text-align: center;
  background:
    radial-gradient(130% 90% at 50% -18%, rgba(167, 139, 250, .18), transparent 62%),
    linear-gradient(180deg, rgba(28, 34, 58, .94), rgba(15, 20, 36, .95));
  border: 1px solid color-mix(in srgb, var(--chrome-1) 26%, var(--border));
  border-radius: 24px;
  padding: 48px 34px;
  box-shadow:
    0 34px 90px -34px rgba(0, 0, 0, .78),
    0 0 60px -30px rgba(139, 92, 246, .5),
    inset 0 1px 0 rgba(255, 255, 255, .07);
}
/* Filet lumineux lavande le long du bord supérieur de la carte d'accueil */
.landing-card::before{
  content: '';
  position: absolute;
  left: 22%; right: 22%; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--chrome-1) 70%, transparent), transparent);
  pointer-events: none;
}
.landing-title{ font-size: clamp(1.7rem, 5vw, 2.55rem); margin-bottom: 16px; line-height: 1.12; }
.grad-text{
  background: linear-gradient(90deg, var(--chrome-1), var(--chrome-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.landing-sub{ color: var(--text-dim); font-size: 1.15rem; line-height: 1.5; margin: 0 auto 26px; max-width: 480px; }
.landing-actions{ display: flex; justify-content: center; }
.landing-note{ color: var(--text-faint); margin-top: 16px; font-size: .98rem; }

/* Aperçu des cartes verrouillées derrière */
.landing-preview{
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 16px;
  opacity: .35;
  filter: blur(1px);
  pointer-events: none;
  overflow: hidden;
  max-height: 640px;
  mask-image: linear-gradient(180deg, transparent, #000 30%, #000 70%, transparent);
}

/* ===================== STATS (sidebar) ===================== */
.stats-bar{ border-top: none; padding-top: 4px; }
.stats-head{ display: flex; align-items: baseline; justify-content: center; flex-wrap: wrap; gap: 6px; }
.stats-summary{ font-size: 1.1rem; width: 100%; text-align: center; }
.stats-summary strong{ font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums; font-size: 1.5rem; color: var(--chrome-1); }
.stats-pct{
  margin-left: 8px;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--chrome-2);
}
.progress{
  margin: 14px 0 0;
  height: 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .4);
}
.progress-fill{
  position: relative;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--chrome-1), var(--chrome-2));
  box-shadow: 0 0 10px rgba(139, 92, 246, .35), inset 0 1px 0 rgba(255, 255, 255, .25);
  transition: width .8s cubic-bezier(.2, .8, .2, 1);
  overflow: hidden;
}
/* Reflet doux qui balaie la barre de progression */
.progress-fill::after{
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .35) 50%, transparent 80%);
  transform: translateX(-100%);
  animation: progressSheen 3.2s ease-in-out infinite;
}
@keyframes progressSheen{ 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(100%); } }
.rarity-stats{ display: flex; flex-direction: column; gap: 8px; }
.rarity-stat{ font-size: .98rem; font-weight: 600; color: var(--text-dim); display: flex; align-items: center; gap: 8px; }
.rarity-stat .dot{ width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 6px currentColor; flex: 0 0 auto; }
.rarity-stat b{ color: var(--text); font-weight: 700; margin-left: auto; }

/* ===================== FILTRES ===================== */
.filters{ margin-bottom: 18px; display: flex; flex-direction: column; gap: 12px; }
.chips{ display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
/* Filtres GROUPÉS (Rareté / Éléments / Tri) : le conteneur passe en colonne de groupes. */
#rarityChips{ flex-direction: column; align-items: stretch; gap: 14px; margin-bottom: 14px; }
.filter-group{ display: flex; flex-direction: column; gap: 7px; }
.filter-group-label{ font-size: .7rem; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-faint); }
.filter-group-chips{ display: flex; flex-wrap: wrap; gap: 8px; }
.chip{
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: .95rem;
  padding: 7px 15px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  transition: all .15s ease;
  display: inline-flex; align-items: center; gap: 7px;
}
.chip:hover{ color: var(--text); border-color: var(--chrome-1); transform: translateY(-1px); box-shadow: 0 4px 12px -6px rgba(139, 92, 246, .5); }
.chip:active{ transform: translateY(0); }
.chip .dot{ width: 9px; height: 9px; border-radius: 50%; }
/* Icône-image d'élément (assets/images/elements/<clé>.webp) + repli emoji */
.el-icon{ width: 18px; height: 18px; object-fit: contain; flex: 0 0 auto; vertical-align: middle; display: inline-block; }
.el-emoji{ display: inline-block; line-height: 1; }
.chip .el-icon{ width: 18px; height: 18px; }
.chip.is-active{
  color: #fff;
  border-color: var(--chip-color, var(--chrome-1));
  background: color-mix(in srgb, var(--chip-color, var(--chrome-1)) 22%, var(--surface));
  box-shadow: 0 0 0 1px var(--chip-color, var(--chrome-1));
}

.search{
  width: 100%;
  min-width: 0;
  font-family: var(--font-ui);
  font-size: 1rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 10px 18px;
  outline: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.search::placeholder{ color: var(--text-faint); }
.search:focus{ border-color: var(--chrome-1); box-shadow: 0 0 0 3px rgba(167, 139, 250, .18); }

/* Toggle obtenues seulement */
.toggle{ display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.toggle input{ position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-track{
  width: 46px; height: 26px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  position: relative;
  transition: background .2s ease, border-color .2s ease;
}
.toggle-thumb{
  position: absolute; top: 2px; left: 2px;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--text-faint);
  transition: transform .2s ease, background .2s ease;
}
.toggle input:checked + .toggle-track{ background: color-mix(in srgb, var(--chrome-1) 35%, var(--surface)); border-color: var(--chrome-1); }
.toggle input:checked + .toggle-track .toggle-thumb{ transform: translateX(20px); background: var(--chrome-1); }
.toggle input:focus-visible + .toggle-track{ box-shadow: 0 0 0 3px rgba(167, 139, 250, .25); }
.toggle-label{ font-weight: 600; color: var(--text-dim); }

/* ===================== GRILLE ===================== */
.grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 22px;
}

.card{
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface);
  aspect-ratio: 3 / 4;
  display: flex;
  flex-direction: column;
  transition: transform .18s ease, box-shadow .25s ease;
  /* Perf : les cartes hors écran ne sont ni peintes ni animées (énorme gain sur
     les longues grilles mobiles — les auras box-shadow ne tournent que si visibles). */
  content-visibility: auto;
  contain-intrinsic-size: auto 340px;
}
.card:hover{ transform: translateY(-6px); }

/* Carte obtenue : aura de rareté de base (raffinée par .dex-r-* plus bas) */
.card-owned{
  border-color: var(--rc, var(--border));
  box-shadow: 0 0 0 1px var(--rc), 0 8px 26px -8px var(--rc);
}
.card-owned:hover{
  box-shadow: 0 0 0 2px var(--rc), 0 18px 42px -8px var(--rc), 0 0 30px -4px var(--rc);
}
.card-locked:hover{
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rc) 45%, transparent), 0 14px 34px -10px var(--rc);
}

/* ============================================================
   AURAS DE RARETÉ (grille) — langage visuel repris de l'overlay
   de spawn, adapté au thème sombre cyan/violet du Dex. Chaque
   rareté est plus intense que la précédente (céleste = max).
   Halo multi-couches sobre par défaut, intensifié au survol.
   ============================================================ */
.card-owned{
  --aura: 0 0 0 1px var(--rc), 0 0 14px -4px var(--rc), 0 10px 26px -10px #000;
  --aura-hover: 0 0 0 2px var(--rc), 0 0 22px -2px var(--rc), 0 0 44px -8px var(--rc), 0 18px 40px -10px #000;
}
.card-owned{ box-shadow: var(--aura); }
.card-owned:hover{ box-shadow: var(--aura-hover); }

/* ── Rareté PERSONNALISÉE (registre /rarities, P2) — repli d'aura GÉNÉRIQUE ───────────
   Une rareté custom porte la classe .dex-r-custom (posée par rarityClass() côté JS) car
   elle n'a AUCUN preset .dex-r-<id> dédié. Repli PROPRE : halo simple basé sur --rc (la
   couleur du registre), SANS animation — la carte reste lisible et jamais « cassée ».
   Le mapping visuel fin par TIER (auras/holo/pulse via data-tier="0..5", déjà posé sur
   les cartes mais INERTE ici) arrive en P3. Les 7 raretés standard ne matchent jamais
   cette règle (elles ont leur propre .dex-r-<id>), donc leur rendu est inchangé. */
.dex-r-custom{
  --aura: 0 0 0 1px var(--rc), 0 0 16px -4px var(--rc), 0 10px 26px -10px #000;
  --aura-hover: 0 0 0 2px var(--rc), 0 0 24px -3px var(--rc), 0 18px 40px -10px #000;
}

.dex-r-rare{
  --aura: 0 0 0 1px var(--rc), 0 0 16px -4px var(--rc), 0 0 30px -8px color-mix(in srgb, var(--rc) 60%, transparent);
  --aura-hover: 0 0 0 2px var(--rc), 0 0 24px -2px var(--rc), 0 0 50px -6px color-mix(in srgb, var(--rc) 55%, transparent), 0 18px 42px -10px #000;
}
.dex-r-epic{
  --aura: 0 0 0 1px var(--rc), 0 0 18px -3px var(--rc), 0 0 36px -8px color-mix(in srgb, var(--rc) 60%, transparent);
  --aura-hover: 0 0 0 2px var(--rc), 0 0 28px -2px var(--rc), 0 0 60px -6px color-mix(in srgb, var(--rc) 55%, transparent), 0 18px 44px -10px #000;
}
/* PERF : l'animation `dexAuraPulse` n'est ATTACHÉE qu'aux cartes .in-view
   (visibles à l'écran). Hors vue, la carte garde son aura STATIQUE de base
   (box-shadow: var(--aura) hérité de .card-owned) → rendu identique, sans le
   coût d'animation box-shadow (très coûteux) sur les ~900 cartes du DOM. */
.dex-r-legendary{
  --aura: 0 0 0 1px var(--rc), 0 0 20px -3px var(--rc), 0 0 44px -8px color-mix(in srgb, var(--rc) 55%, transparent);
  --aura-hover: 0 0 0 2px var(--rc), 0 0 30px -2px var(--rc), 0 0 70px -6px color-mix(in srgb, var(--rc) 55%, transparent), 0 0 96px -14px color-mix(in srgb, var(--rc) 40%, transparent);
}
.dex-r-mythic{
  --aura: 0 0 0 1px var(--rc), 0 0 22px -3px var(--rc), 0 0 50px -8px color-mix(in srgb, var(--rc) 55%, transparent);
  --aura-hover: 0 0 0 2px var(--rc), 0 0 34px -2px var(--rc), 0 0 80px -6px color-mix(in srgb, var(--rc) 50%, transparent), 0 0 110px -12px color-mix(in srgb, var(--rc) 38%, transparent);
}
.dex-r-divine{
  --aura: 0 0 0 1px var(--rc), 0 0 24px -2px var(--rc), 0 0 56px -8px color-mix(in srgb, var(--rc) 55%, transparent), 0 0 80px -14px color-mix(in srgb, var(--neon-purple) 50%, transparent);
  --aura-hover: 0 0 0 2px var(--rc), 0 0 38px -2px var(--rc), 0 0 90px -6px color-mix(in srgb, var(--rc) 50%, transparent), 0 0 130px -12px color-mix(in srgb, var(--neon-purple) 45%, transparent);
}
/* Céleste : cœur BLEU (var --rc) + halo ARC-EN-CIEL (violet/rose/or) en périphérie. */
.dex-r-celestial{
  --aura: 0 0 0 1px var(--rc), 0 0 26px -2px var(--rc),
    0 0 60px -8px color-mix(in srgb, var(--rc) 60%, transparent),
    0 0 80px -10px color-mix(in srgb, var(--neon-purple) 42%, transparent),
    0 0 100px -12px color-mix(in srgb, var(--neon-pink) 30%, transparent),
    0 0 124px -14px color-mix(in srgb, #ffd76a 26%, transparent);
  --aura-hover: 0 0 0 2px var(--rc), 0 0 44px -2px var(--rc),
    0 0 96px -6px color-mix(in srgb, var(--rc) 55%, transparent),
    0 0 120px -10px color-mix(in srgb, var(--neon-purple) 45%, transparent),
    0 0 150px -12px color-mix(in srgb, var(--neon-pink) 32%, transparent);
}
/* L'aura ne PULSE que pour les cartes visibles. */
.dex-r-legendary.in-view{ animation: dexAuraPulse 2.4s ease-in-out infinite; }
.dex-r-mythic.in-view{ animation: dexAuraPulse 1.9s ease-in-out infinite; }
.dex-r-divine.in-view{ animation: dexAuraPulse 1.6s ease-in-out infinite; }
.dex-r-celestial.in-view{ animation: dexAuraPulse 1.2s ease-in-out infinite; }
/* Le survol garde le halo intensifié même si une pulsation tourne */
.dex-r-legendary:hover, .dex-r-mythic:hover, .dex-r-divine:hover, .dex-r-celestial:hover{ animation: none; box-shadow: var(--aura-hover); }

@keyframes dexAuraPulse{
  0%, 100% { box-shadow: var(--aura); }
  50%      { box-shadow: var(--aura-hover); }
}

/* ── Balayage de lumière (shine) façon overlay, au survol ── */
.card .card-shine{
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  border-radius: inherit; overflow: hidden; opacity: 0;
}
.card .card-shine::before{
  content: ''; position: absolute; top: -60%; left: -75%;
  width: 62%; height: 220%;
  /* Reflet adouci (cohérent avec la modale) : plus discret + bords floutés. */
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.18) 50%, transparent 62%);
  filter: blur(4px);
  transform: rotate(8deg) translateX(0);
}
.card-owned:hover .card-shine{ opacity: 1; }
@keyframes dexShine{
  0%   { transform: rotate(8deg) translateX(0); }
  100% { transform: rotate(8deg) translateX(420%); }
}

/* ── Brillance PERMANENTE façon overlay WC, réservée aux très hautes raretés ──
   Balayage périodique (passage rapide puis pause) comme le shimmer de l'overlay.
   Peu de mythic+ visibles à la fois → coût GPU négligeable ; coupé sur mobile
   (.card-shine y est déjà display:none) et en mouvement réduit. */
.card-owned.dex-r-mythic .card-shine, .card-owned.dex-r-divine .card-shine, .card-owned.dex-r-celestial .card-shine{ opacity: 1; }
/* PERF : le balayage permanent ne tourne que pour les cartes visibles (.in-view).
   Hors écran, le reflet reste figé sur sa position de départ (rendu inchangé). */
.card-owned.dex-r-mythic.in-view .card-shine::before{ animation: dexShineLoop 5.2s ease-in-out infinite; }
.card-owned.dex-r-divine.in-view .card-shine::before{ animation: dexShineLoop 4.2s ease-in-out infinite; }
.card-owned.dex-r-celestial.in-view .card-shine::before{ animation: dexShineLoop 3.2s ease-in-out infinite; }
@keyframes dexShineLoop{
  0%   { transform: rotate(8deg) translateX(0); }
  34%  { transform: rotate(8deg) translateX(420%); }
  100% { transform: rotate(8deg) translateX(420%); }
}
/* Le survol reprend toujours le balayage rapide (déclaré APRÈS pour gagner la cascade) */
.card-owned:hover .card-shine::before{ animation: dexShine .85s ease-out; }
@media (prefers-reduced-motion: reduce){
  .card-owned.dex-r-mythic .card-shine::before, .card-owned.dex-r-divine .card-shine::before, .card-owned.dex-r-celestial .card-shine::before{ animation: none; }
}

/* ── Céleste : l'AURA (halo autour de la carte) scintille ARC-EN-CIEL comme une étoile
   Mario, SANS toucher l'art. Le cœur de l'aura (anneau + halo proche) reste CYAN → le
   bleu est la couleur primaire ; seul le HALO EXTÉRIEUR cycle ses couleurs. */
/* Spécificité 3 classes : gagne sur dexAuraPulse ET sur evolvedGlow (céleste évoluée).
   Halo ENTIÈREMENT arc-en-ciel (aucune couleur dominante) qui cycle toutes les teintes. */
.card-owned.dex-r-celestial.in-view{ animation: dexStarAura 3s linear infinite; }
/* Cœur BLANC fixe (anneau + halo proche) + HALO EXTÉRIEUR qui cycle l'arc-en-ciel. */
@keyframes dexStarAura{
  0%   { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(255,77,141,.9); }
  17%  { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(255,170,60,.88); }
  33%  { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(108,255,138,.88); }
  50%  { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(0,229,255,.92); }
  67%  { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(77,124,255,.9); }
  83%  { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(177,77,255,.9); }
  100% { box-shadow: 0 0 0 1.5px #fff, 0 0 22px -3px rgba(255,255,255,.95), 0 0 92px -6px rgba(255,77,141,.9); }
}
/* Même halo arc-en-ciel sur la grande carte de la modale. */
.cd-head-card.dex-r-celestial .cd-card-art{ animation: dexStarArtGlow 3s linear infinite; }
/* Grande carte de la modale : même principe — cœur blanc fixe, halo extérieur arc-en-ciel. */
@keyframes dexStarArtGlow{
  0%   { box-shadow: 0 0 0 1.5px #fff, 0 0 26px -3px rgba(255,255,255,.92), 0 0 86px -8px rgba(255,77,141,.72); }
  17%  { box-shadow: 0 0 0 1.5px #fff, 0 0 26px -3px rgba(255,255,255,.92), 0 0 86px -8px rgba(255,170,60,.68); }
  33%  { box-shadow: 0 0 0 1.5px #fff, 0 0 26px -3px rgba(255,255,255,.92), 0 0 86px -8px rgba(108,255,138,.68); }
  50%  { box-shadow: 0 0 0 1.5px #fff, 0 0 28px -2px rgba(255,255,255,.95), 0 0 92px -6px rgba(0,229,255,.76); }
  67%  { box-shadow: 0 0 0 1.5px #fff, 0 0 26px -3px rgba(255,255,255,.92), 0 0 86px -8px rgba(77,124,255,.7); }
  83%  { box-shadow: 0 0 0 1.5px #fff, 0 0 26px -3px rgba(255,255,255,.92), 0 0 86px -8px rgba(177,77,255,.7); }
  100% { box-shadow: 0 0 0 1.5px #fff, 0 0 26px -3px rgba(255,255,255,.92), 0 0 86px -8px rgba(255,77,141,.72); }
}
/* Céleste : CONTOUR BLANC (le halo autour reste arc-en-ciel). */
.card-owned.dex-r-celestial{ border-color: #fff; }
.cd-head-card.dex-r-celestial .cd-card-art{ border-color: #fff; }
@media (prefers-reduced-motion: reduce){
  .card-owned.dex-r-celestial.in-view, .cd-head-card.dex-r-celestial .cd-card-art{ animation: none !important; }
}

/* ── Légère mise à l'échelle + remontée au survol (en plus du translate) ── */
.card-owned:hover{ transform: translateY(-6px) scale(1.015); }

/* ============================================================
   OVERLAY STATISTIQUES (HP/ATK/DEF/VIT) — révélé au survol
   ============================================================ */
.card-stats-overlay{
  position: absolute;
  top: 40px; left: 10px; right: 10px;
  z-index: 5;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity .22s ease, transform .22s ease;
  pointer-events: none;
}
.card-owned:hover .card-stats-overlay{ opacity: 1; transform: translateY(0); }
.cstat{
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px;
  padding: 3px 8px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--rc) 16%, rgba(7,10,18,.78));
  border: 1px solid color-mix(in srgb, var(--rc) 45%, transparent);
  backdrop-filter: blur(6px);
}







/* Indice de compteur (tooltip discret) sous le méta, révélé au survol */
.card-count-hint{
  font-family: var(--font-ui);
  font-size: .68rem; font-weight: 600;
  color: var(--neon-1);
  opacity: 0; max-height: 0; overflow: hidden;
  transition: opacity .2s ease, max-height .2s ease;
}
.card-owned:hover .card-count-hint{ opacity: .85; max-height: 2.4em; }

/* ============================================================
   BANDEAU SOUS L'ART — élément + attaques + passif (compact)
   ============================================================ */
.card-footer{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 5;
  padding: 8px 10px;
  display: flex; flex-direction: column; gap: 5px;
  background: linear-gradient(0deg, rgba(7,10,18,.96), rgba(7,10,18,.72) 70%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--rc) 35%, transparent);
  transform: translateY(100%);
  opacity: 0;
  transition: transform .24s ease, opacity .24s ease;
}
.card-owned:hover .card-footer{ transform: translateY(0); opacity: 1; }
.cf-el{
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .64rem; font-weight: 700;
  padding: 2px 8px; border-radius: 999px;
  color: var(--el, var(--text));
  background: color-mix(in srgb, var(--el, var(--rc)) 18%, rgba(0,0,0,.5));
  border: 1px solid color-mix(in srgb, var(--el, var(--rc)) 55%, transparent);
}
.cf-el .el-icon{ width: 13px; height: 13px; }
.cf-el .el-emoji{ font-size: .9em; }
.cf-atks{ display: flex; flex-wrap: wrap; gap: 4px; }
.cf-atk{
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .64rem; font-weight: 600;
  color: var(--text);
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 6px;
  padding: 2px 6px;
  max-width: 100%;
}
.cf-atk-dot{
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--el, var(--rc));
  box-shadow: 0 0 6px var(--el, var(--rc));
  flex: 0 0 auto;
}
.cf-passive{
  font-size: .62rem;
  color: #ffd76a;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ============================================================
   AURA SPÉCIALE — cartes SECRÈTES / manipulation (ex. Nao-Chan)
   En plus de l'aura de rareté : un balayage holographique arc-en-ciel
   + un anneau pulsant, pour les distinguer des cartes normales.
   ============================================================ */
.card-secret::after{
  content: '';
  position: absolute; inset: 0; z-index: 2;
  border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg,
    transparent 30%,
    rgba(255,0,128,.16), rgba(0,229,255,.16),
    rgba(177,77,255,.16), rgba(255,215,64,.16),
    transparent 70%);
  background-size: 300% 300%;
  mix-blend-mode: screen;
}
/* PERF : holo + anneau pulsant uniquement pour les cartes secrètes visibles. */
.card-secret.in-view::after{ animation: dexHolo 5s linear infinite; }
.card-secret{ position: relative; }
.card-owned.card-secret{
  box-shadow: var(--aura), 0 0 0 2px color-mix(in srgb, var(--neon-purple) 55%, transparent);
}
.card-owned.card-secret.in-view{
  animation: dexSecretRing 2.8s ease-in-out infinite;
}
.card-owned.card-secret:hover{ animation: none; box-shadow: var(--aura-hover), 0 0 0 2px var(--neon-purple); }
@keyframes dexHolo{
  0%   { background-position: 0% 50%; }
  100% { background-position: 300% 50%; }
}
@keyframes dexSecretRing{
  0%, 100% { box-shadow: var(--aura), 0 0 0 2px color-mix(in srgb, var(--neon-purple) 45%, transparent), 0 0 22px -6px var(--neon-purple); }
  50%      { box-shadow: var(--aura-hover), 0 0 0 2px var(--neon-1), 0 0 40px -6px var(--neon-1); }
}
.badge-secret{
  position: absolute;
  top: 6px; left: 50%; transform: translateX(-50%);
  z-index: 4;
  font-size: 1rem;
  color: #d9b8ff;
  text-shadow: 0 0 8px var(--neon-purple), 0 0 14px var(--neon-1);
  pointer-events: none;
}
.in-view .badge-secret{ animation: dexSecretSpark 2.6s ease-in-out infinite; }
/* Décale le ◈ si la carte est aussi évoluée (le ✦ occupe déjà le haut-centre) */
.card-evolved .badge-secret{ top: auto; bottom: 8px; }
@keyframes dexSecretSpark{
  0%, 100% { opacity: .8; transform: translateX(-50%) scale(1); filter: hue-rotate(0deg); }
  50%      { opacity: 1;  transform: translateX(-50%) scale(1.2); filter: hue-rotate(60deg); }
}

/* Mobile / tactile : on fige les animations coûteuses et on révèle les
   infos en permanence (pas de survol fiable sur écran tactile). */
@media (hover: none), (max-width: 820px){
  /* On cible aussi les variantes .in-view pour que la coupe mobile l'emporte
     (mêmes anims, conditionnées à la visibilité côté desktop pour la perf). */
  .dex-r-legendary, .dex-r-mythic, .dex-r-divine, .dex-r-celestial, .card-owned.card-secret, .card-secret::after, .badge-secret, .dex-r-legendary.in-view, .dex-r-mythic.in-view, .dex-r-divine.in-view, .dex-r-celestial.in-view, .card-owned.dex-r-celestial.in-view, .card-owned.card-secret.in-view, .card-secret.in-view::after, .in-view .badge-secret{ animation: none; }
  /* Auras allégées : on garde le halo coloré (par --rc) mais SANS les énormes
     flous multi-couches (jusqu'à 150px) qui font ramer le scroll sur mobile.
     On réduit le rayon de flou → rasterisation bien moins coûteuse. */
  .dex-r-legendary{ --aura: 0 0 0 1px var(--rc), 0 0 13px -4px var(--rc); }
  .dex-r-mythic{ --aura: 0 0 0 1px var(--rc), 0 0 15px -4px var(--rc); }
  .dex-r-divine{ --aura: 0 0 0 1px var(--rc), 0 0 17px -4px var(--rc); }
  .dex-r-celestial{ --aura: 0 0 0 1px var(--rc), 0 0 19px -4px var(--rc); }
  .card-owned:hover{ transform: translateY(-4px); }
  .card .card-shine{ display: none; }
  /* Sur tactile, pas de survol fiable : on NE montre PAS les stats/élément en
     permanence (ça donnait un faux air de "carte survolée" et ça surchargeait).
     Un appui sur la carte ouvre la fiche détaillée avec toutes les infos. */
  .card-stats-overlay, .card-footer{ display: none !important; }
  .card-count-hint{ opacity: .85; max-height: none; }
  /* PERF MOBILE CRITIQUE : backdrop-filter est ruineux pendant le scroll, et ici il
     est multiplié par carte (le #numéro + les 4 lignes de stats toujours affichées).
     On le supprime sur tactile et on opacifie les fonds pour garder la lisibilité. */
  .card .cstat, .card .badge-event, .card .card-number, .card .card-overlay{ backdrop-filter: none; -webkit-backdrop-filter: none; }
  .card .cstat{ background: color-mix(in srgb, var(--rc) 16%, rgba(7,10,18,.92)); }
  .card .badge-event, .card .card-number{ background: rgba(11, 15, 26, .9); }
}
.card-art{
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  background: var(--bg-2);
  opacity: 0;
  transition: opacity .35s ease;
}
.card-art.is-loaded{ opacity: 1; }
.card-art-fallback{
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui);
  font-size: 2.4rem;
  color: var(--rc, var(--text-faint));
  background: linear-gradient(160deg, var(--surface-2), var(--bg-2));
}
.card-overlay{
  position: absolute;
  inset: 0;
  z-index: 4;
  background: linear-gradient(180deg, transparent 45%, rgba(7, 10, 18, .92) 100%);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 12px;
  gap: 6px;
  transition: padding-bottom .24s ease;
}
/* Au survol d'une carte obtenue, le bandeau (élément/attaques/passif) remonte :
   on réserve de l'espace pour que le nom reste lisible au-dessus. */
.card-owned:hover .card-overlay{ padding-bottom: 86px; }
.card-name{
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.15;
  text-shadow: 0 2px 8px rgba(0, 0, 0, .8);
}
.card-title{ font-size: .9rem; color: var(--text-dim); line-height: 1.1; }
/* Une seule ligne : rareté + ✦ Évoluée + Nv. + pastilles. Tailles réduites pour
   tout faire tenir sans retour à la ligne. */
.card-meta{ display: flex; align-items: center; gap: 4px; flex-wrap: nowrap; min-width: 0; }

.rarity-badge{
  font-size: .62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .3px;
  white-space: nowrap;
  padding: 2px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--rc) 26%, #0b0f1a);
  color: #fff;
  border: 1px solid var(--rc);
}
/* Badge des cartes verrouillées : neutre, ne révèle aucune rareté. */
.rarity-badge-mystery{
  min-width: 22px; text-align: center;
  background: rgba(108, 115, 147, .22);
  color: #c7cbe0;
  border-color: rgba(108, 115, 147, .6);
}
.card-level{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .62rem;
  font-weight: 700;
  white-space: nowrap;
  color: var(--r-legendary);
  background: rgba(0, 0, 0, .45);
  padding: 2px 7px;
  border-radius: 999px;
}
.card-count{
  margin-left: auto;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-weight: 700;
  font-size: .8rem;
  color: var(--neon-1);
  background: rgba(0, 0, 0, .5);
  padding: 3px 9px;
  border-radius: 999px;
}
/* Exemplaires possédés : pastilles (1 point = 1 copie) — clair sans texte. */
.card-copies{
  margin-left: auto;
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 4px;
  background: rgba(0, 0, 0, .5);
  padding: 4px 7px; border-radius: 999px;
}
.card-copies .pip{
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--neon-1);
  box-shadow: 0 0 5px var(--neon-1);
}
.card-copies .pip-more{
  color: var(--neon-1); font-weight: 800; font-size: .8rem; line-height: 1; margin-left: 1px;
}

/* Badge évènement / exclusif */
.badge-event{
  position: absolute;
  top: 8px; right: 8px;
  z-index: 3;
  font-size: .8rem;
  background: rgba(11, 15, 26, .7);
  border: 1px solid rgba(255, 255, 255, .25);
  border-radius: 999px;
  padding: 2px 8px;
  backdrop-filter: blur(4px);
}

/* Numéro de Dex (#001) — coin haut-gauche, sur cartes obtenues, verrouillées et vides */
.card-number{
  position: absolute;
  top: 8px; left: 8px;
  z-index: 3;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--text-faint, #cfe);
  background: rgba(11, 15, 26, .6);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 999px;
  padding: 2px 8px;
  backdrop-filter: blur(4px);
}

/* Cœur favori CLIQUABLE (coin haut-droit). Off = discret, On = rose vif. z-index au-dessus des badges. */
.card-fav{
  position: absolute; top: 8px; right: 8px; z-index: 6; /* AU-DESSUS de .card-overlay (z-index 4) sinon l'overlay capte le clic */
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(11, 15, 26, .92); border: 1px solid rgba(255, 255, 255, .22);
  color: rgba(255, 255, 255, .55); font-size: 15px; line-height: 1; cursor: pointer;
  /* Fond OPAQUE (pas de backdrop-filter) : rien ne transparaît derrière le bouton —
     évitait le « disque violet flou » sur les cartes Céleste (art + holo + aura derrière). */
  transition: transform .12s ease, color .15s ease, background .15s ease, border-color .15s ease;
}
.card-fav:hover{ transform: scale(1.12); color: #ff5fa2; }
.card-fav.is-on{ color: #ff3b6b; border-color: rgba(255, 59, 107, .65); background: rgba(46, 14, 24, .92); text-shadow: 0 0 8px rgba(255, 59, 107, .7); }
.card-fav:focus-visible{ outline: 2px solid #ff5fa2; outline-offset: 2px; }

/* Mini-toast transitoire (favori plein, erreurs brèves…) */
.dex-toast{
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(10px); z-index: 9999;
  background: rgba(11, 15, 26, .95); border: 1px solid rgba(255, 255, 255, .2); color: #fff;
  padding: 10px 16px; border-radius: 10px; font-size: .9rem; max-width: 90vw; text-align: center;
  opacity: 0; pointer-events: none; box-shadow: 0 8px 28px -8px rgba(0, 0, 0, .6);
  transition: opacity .2s ease, transform .2s ease;
}
.dex-toast.show{ opacity: 1; transform: translateX(-50%) translateY(0); }

/* Carte verrouillée */
.card-locked{
  border-color: var(--rc, var(--border));
  background:
    radial-gradient(120% 80% at 50% 0%, color-mix(in srgb, var(--rc) 14%, transparent), transparent 60%),
    linear-gradient(170deg, var(--surface), var(--bg-2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rc) 35%, transparent);
}
.card-locked .lock-mark{
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-weight: 900;
  font-size: 4rem;
  color: color-mix(in srgb, var(--rc) 60%, var(--text-faint));
  text-shadow: 0 0 22px color-mix(in srgb, var(--rc) 50%, transparent);
}
.card-locked .card-overlay{
  background: linear-gradient(180deg, transparent 55%, rgba(7, 10, 18, .85) 100%);
}
.card-locked .card-name{ color: var(--text-faint); letter-spacing: 3px; }

/* Shimmer des cartes mystère : UNIQUEMENT au survol (CSS pur, ne révèle aucune
   rareté). Pas d'animation au repos → fluide même avec ~900 cartes affichées. */
.card-locked::after{
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  border-radius: inherit; overflow: hidden;
  background: linear-gradient(105deg, transparent 42%, color-mix(in srgb, var(--rc) 22%, transparent) 50%, transparent 58%);
  filter: blur(6px);
  transform: translateX(-120%);
  opacity: 0;
}
.card-locked:hover::after{ opacity: 1; animation: dexLockShimmer 1.1s ease-out; }
@keyframes dexLockShimmer{
  from { transform: translateX(-120%); }
  to { transform: translateX(120%); }
}
/* Pulse neutre du « ? » au survol (réutilise MYSTERY_COLOR via --rc). */
.card-locked:hover .lock-mark{
  transform: scale(1.08);
  text-shadow: 0 0 30px color-mix(in srgb, var(--rc) 70%, transparent);
  transition: transform .25s ease, text-shadow .25s ease;
}

/* Bandeau d'information « aperçu » au-dessus de la grille (pseudo inexistant). */
.dex-preview-note{
  grid-column: 1 / -1;
  background: color-mix(in srgb, var(--neon-purple) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--neon-purple) 40%, var(--border));
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  color: var(--text-dim);
  font-size: .95rem;
  line-height: 1.4;
}

/* ===================== DIVERS ===================== */
.stats-subnote{ margin-top: 8px; font-size: .82rem; color: var(--text-dim); }

/* Badge « slots de collection » : capacité du total de cartes détenues. */
.card-slots{
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}
.card-slots-badge{
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: .85rem;
  font-weight: 600;
  color: var(--neon-1, #6cf);
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .12);
  white-space: nowrap;
}
/* Alerte ≥ 90 % de la capacité : teinte orange/rouge. */
.card-slots-badge.is-near-full{
  color: #ffae42;
  background: rgba(255, 122, 0, .12);
  border-color: rgba(255, 122, 0, .45);
}
.card-slots-hint{
  font-size: .76rem;
  line-height: 1.35;
  color: #ffae42;
}

.no-results{
  text-align: center; color: var(--text-dim); font-size: 1.1rem;
  padding: 46px 24px;
  max-width: 460px;
  margin: 30px auto;
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(28, 34, 58, .45), rgba(15, 20, 36, .4));
  border: 1px dashed color-mix(in srgb, var(--chrome-1) 26%, var(--border));
}
/* Pictogramme décoratif au-dessus du message « aucun résultat » (pas de texte → pas d'i18n) */
.no-results::before{
  content: '🔍';
  display: block;
  font-size: 2.4rem;
  margin-bottom: 12px;
  opacity: .8;
  filter: drop-shadow(0 3px 10px rgba(0, 0, 0, .5));
}

.footer{
  text-align: center;
  color: var(--text-faint);
  border-top: 1px solid var(--border);
  padding: 18px;
  font-size: .95rem;
}
/* Wordmark footer : même signature que le header (« Waifu » garde l'accent lavande). */
.footer-brand{
  font-family: var(--font-ui);
  font-weight: 800; font-size: 1.05em; letter-spacing: .4px;
  color: var(--text-dim);
}
.footer-link{
  color: var(--chrome-1); font-weight: 600; text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--chrome-1) 45%, transparent);
  transition: color .2s ease, border-color .2s ease;
}
.footer-link:hover{ color: var(--chrome-1); border-color: var(--chrome-1); }
.footer-link:focus-visible{ outline: 2px solid var(--chrome-1); outline-offset: 3px; border-radius: 2px; }

/* Tooltip simple (Twitch non configuré) */
.tip-wrap{ position: relative; display: inline-block; }
.tip-wrap[data-tip]:hover::after{
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: .85rem;
  font-weight: 600;
  padding: 7px 11px;
  border-radius: 8px;
  box-shadow: var(--shadow);
  z-index: 40;
}

/* ===================== RESPONSIVE ===================== */

/* Tablette / mobile : la sidebar devient un tiroir coulissant */
@media (max-width: 820px){
  .app{
    display: block;
    min-height: auto;
  }

  /* PERF mobile : le fond fixe (parallaxe) provoque un gros lag au scroll
     sur mobile → on le repasse en défilement normal. */
  body{ background-attachment: scroll; }

  /* Barre supérieure mobile avec le bouton ☰
     (fond quasi-opaque, sans flou : le backdrop-filter sur un élément
     "sticky" force un repaint à chaque frame de scroll = lag). */
  .mobile-topbar{
    display: flex;
    align-items: center;
    gap: 14px;
    position: sticky;
    top: 0;
    z-index: 25;
    margin: -28px -28px 18px;
    padding: 12px 16px;
    background: rgba(11, 15, 26, .96);
    border-bottom: 1px solid var(--border);
  }
  .brand-mobile .brand-logo{ height: 28px; width: 28px; }
  .brand-mobile .brand-title{ font-size: 1.05rem; }

  /* Sidebar = tiroir hors écran par défaut */
  .sidebar{
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: min(320px, 86vw);
    z-index: 50;
    transform: translateX(-100%);
    transition: transform .25s ease;
    border-right: 1px solid var(--border);
    box-shadow: var(--shadow);
  }
  .sidebar.is-open{ transform: translateX(0); }
  .sidebar-close{
    display: block;
    position: absolute;
    top: 12px; right: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-dim);
    width: 34px; height: 34px;
    border-radius: 50%;
    font-size: 1rem;
    cursor: pointer;
  }
  .sidebar-close:hover{ color: var(--text); border-color: var(--chrome-1); }

  /* Les bascules « bureau » n'ont pas de sens en mode tiroir mobile */
  .sidebar-collapse{ display: none; }
  body.sidebar-collapsed .sidebar-expand{ display: none; }
  /* Sur mobile, un repli accidentel ne doit jamais masquer le tiroir */
  body.sidebar-collapsed .sidebar{ display: flex; }
  body.sidebar-collapsed .app{ grid-template-columns: none; }

  .main{ padding: 28px 18px 48px; }
  .grid{ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
}

@media (max-width: 480px){
  .grid{ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
  .user-chip-name{ max-width: 140px; }
  .card-name{ font-size: .95rem; }
  .card-locked .lock-mark{ font-size: 3rem; }
}
@media (max-width: 360px){
  .grid{ grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   Barre de commandes (combats / échanges / boutique)
   Top menu sleek — pilules icône + libellé, thème cyan/violet
   ============================================================ */
/* Menu d'actions VERTICAL dans la sidebar : groupes catégorisés de pilules. */
.dex-cmdbar{
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
  margin: 0;
  padding: 12px;
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(38, 26, 71, .55), rgba(15, 11, 30, .72));
  border: 1px solid var(--border);
  box-shadow:
    0 14px 38px rgba(0, 0, 0, .38),
    inset 0 1px 0 rgba(255, 255, 255, .05);
  backdrop-filter: blur(10px);
}
.actions-note{
  color: var(--text-faint);
  font-size: .92rem;
  font-weight: 600;
  padding: 8px 10px;
  margin-top: 2px;
  text-align: center;
  border-radius: 12px;
  border: 1px dashed var(--border);
  background: rgba(0, 0, 0, .2);
}

/* ============================================================
   BANNIÈRES « HUB » (Combat · Échanges · Boutique · Progression)
   Chaque bannière ouvre un panneau de TUILES (openHub). Image de fond
   optionnelle : déposer assets/images/hub/<clé>.webp (repli = dégradé).
   ============================================================ */
#dexActionsBar{ display: flex; flex-direction: column; gap: 10px; }
.cmd-banner{
  position: relative; display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: 0; padding: 9px 12px; cursor: pointer; text-align: left;
  border: 1px solid var(--border); border-radius: 11px; color: var(--text);
  background: linear-gradient(135deg, var(--surface-2), var(--surface));
  background-size: cover; background-position: center; overflow: hidden;
  transition: transform .12s ease, border-color .15s ease, box-shadow .15s ease;
}
/* Voile sombre pour garder le texte lisible quand une image de fond est posée */
.cmd-banner::before{ content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(90deg, rgba(8, 10, 20, .74), rgba(8, 10, 20, .3)); }
.cmd-banner > *{ position: relative; z-index: 1; }
.cmd-banner:hover{ transform: translateY(-2px); border-color: var(--chrome-1); box-shadow: 0 6px 18px -6px rgba(139, 92, 246, .45); }
.cmd-banner:focus-visible{ outline: 2px solid var(--chrome-1); outline-offset: 2px; }
.cmd-banner-ico{
  font-size: 1.2rem; line-height: 1; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .6));
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: 0 0 auto; border-radius: 9px;
  background: rgba(8, 10, 20, .55); border: 1px solid rgba(255, 255, 255, .10);
}

/* ── 🎨 Icônes SVG inline (logos hubs / tuiles / partage — traits épurés,
   dégradé thématique par hub embarqué dans le SVG) ── */
.dex-ico{ display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.18em; }
.cmd-banner-ico .dex-ico{ width: 19px; height: 19px; }
.hub-panel-ico .dex-ico{
  width: 58px; height: 58px;
  filter: drop-shadow(0 0 14px rgba(0, 229, 255, .25)) drop-shadow(0 2px 6px rgba(0, 0, 0, .65));
}
.hub-title-ico{ display: inline-flex; }
.hub-title-ico .dex-ico{ width: 15px; height: 15px; }
.cmd-banner-label{ flex: 1 1 auto; min-width: 0; font-family: var(--font-ui); font-weight: 700; font-size: .9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 2px 6px rgba(0, 0, 0, .7); }
.cmd-banner-go{ font-size: 1.1rem; opacity: .5; }
.cmd-banner .cmd-badge{ background: var(--neon-pink); color: #fff; font-size: .72rem; font-weight: 800; padding: 2px 7px; border-radius: 999px; }
/* Images de fond (à déposer ; si absentes, le dégradé de base s'affiche).
   Les 5 .webp n'existent PAS encore → références commentées pour éviter des 404 à chaque
   ouverture. Le dégradé de repli (.cmd-banner) s'affiche entre-temps. */
/* TODO webp: décommenter quand l'image existe */ .cmd-banner-battle{ /* background-image: url('../assets/images/hub/combat.webp'); */ }
/* TODO webp: décommenter quand l'image existe */ .cmd-banner-trade{ /* background-image: url('../assets/images/hub/echange.webp'); */ }
/* TODO webp: décommenter quand l'image existe */ .cmd-banner-shop{ /* background-image: url('../assets/images/hub/boutique.webp'); */ }
/* TODO webp: décommenter quand l'image existe */ .cmd-banner-progression{ /* background-image: url('../assets/images/hub/progression.webp'); */ }
/* TODO webp: décommenter quand l'image existe */ .cmd-banner-community{ /* background-image: url('../assets/images/hub/communaute.webp'); */ }

/* ── Panneau d'un hub (modale) : 3 PANNEAUX verticaux réguliers côte à côte. ──
   Combat & Échanges (.hub-panels-art) : artwork dédié en cover, grands panneaux.
   Boutique & Progression : tuile CSS thématique (dégradé 2 tons + motifs) — le webp,
   déclaré EN PREMIER dans background-image, prend le dessus dès qu'il existe.
   Bandeau-label UNIFORME en bas + hover commun (zoom léger, glow, label illuminé). */
.hub-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
/* 4 tuiles (hub Combat + 🃏 Decks) → grille 2×2, panneaux un peu moins hauts */
.hub-grid-4{ grid-template-columns: repeat(2, 1fr); }
.hub-panels-art.hub-grid-4 .hub-tile{ min-height: 220px; }
/* Modale hub : plus large + cadre néon (thème Dex). */
.modal.hub-modal{
  max-width: 760px;
  background: linear-gradient(180deg, #16172e, #101022);
  border: 1px solid #3a2f6b;
  box-shadow: 0 0 34px -6px rgba(130, 90, 230, .45);
}
.hub-tile{
  position: relative; display: block; min-height: 200px; padding: 0; cursor: pointer;
  border: 1px solid var(--border); border-radius: 14px; color: var(--text);
  background-color: #0c0d1a;
  background-image: linear-gradient(160deg, var(--surface-2), var(--surface));
  background-size: cover; background-position: center; overflow: hidden;
  transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.hub-panels-art .hub-tile{ min-height: 300px; }
/* Léger voile pour asseoir la lisibilité (le bandeau fait le reste). */
.hub-tile::before{ content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, rgba(8, 10, 20, .04) 45%, rgba(8, 10, 20, .32)); }
.hub-tile > *{ position: relative; z-index: 1; }
/* HOVER commun : léger zoom + glow de bordure + label illuminé. */
.hub-tile:hover{ transform: translateY(-3px) scale(1.025); border-color: var(--chrome-1); box-shadow: 0 8px 24px -8px rgba(139, 92, 246, .5); }
.hub-tile:focus-visible{ outline: 2px solid var(--chrome-1); outline-offset: 2px; }
.hub-tile:hover .hub-panel-title{ color: #fff; text-shadow: 0 2px 6px rgba(0, 0, 0, .9); }
/* Grande icône centrée (tuiles sans artwork dédié) */
.hub-panel-ico{
  position: absolute; top: 36%; left: 50%; transform: translate(-50%, -50%);
  font-size: 2.8rem; line-height: 1; filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .55));
  transition: transform .2s ease;
}
.hub-tile:hover .hub-panel-ico{ transform: translate(-50%, -50%) scale(1.12); }
/* BANDEAU-LABEL uniforme (bas) : dégradé noir → transparent, titre centré + description. */
.hub-panel-label{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  display: flex; flex-direction: column; gap: 3px; padding: 30px 10px 12px; text-align: center;
  background: linear-gradient(0deg, rgba(4, 6, 14, .92) 0%, rgba(4, 6, 14, .62) 55%, transparent 100%);
  pointer-events: none;
}
.hub-panel-title{ font-weight: 800; font-size: .95rem; line-height: 1.2; text-shadow: 0 2px 6px rgba(0, 0, 0, .9); transition: color .2s ease, text-shadow .2s ease; }
.hub-panel-desc{ font-size: .72rem; font-weight: 600; color: var(--text-dim); line-height: 1.25; text-shadow: 0 1px 4px rgba(0, 0, 0, .9); }
.hub-tile-badge{ position: absolute; top: 8px; right: 8px; z-index: 2; background: var(--neon-pink); color: #fff; font-size: .72rem; font-weight: 800; padding: 2px 7px; border-radius: 999px; }
/* ── Fonds des panneaux : le webp (couche 1, cover) prend le dessus dès qu'il est déposé
   dans assets/images/hub/tiles/ ; en dessous, dégradé THÉMATIQUE 2 tons + motifs CSS
   (radials en coins + fines diagonales) → la tuile fait design même sans asset. ── */
/* Combat & Échanges : artworks présents */
.hub-tile-battle_battle{ background-image: url('../assets/images/hub/tiles/combat.webp'),          linear-gradient(160deg, #7c1f1f, #1d0608); }
.hub-tile-battle_mystery{ background-image: url('../assets/images/hub/tiles/combat-mystere.webp'),  linear-gradient(160deg, #1f3f7c, #060a1d); }
.hub-tile-battle_invites{ background-image: url('../assets/images/hub/tiles/defis.webp'),           linear-gradient(160deg, #6b2f8a, #14061d); }
/* 🃏 Espace Decks : tuile thématique violet nuit (webp optionnel, même patron) */
/* TODO webp: décommenter url(...decks.webp) quand l'image existe (évite un 404) */
.hub-tile-battle_decks{ background-image: /* url('../assets/images/hub/tiles/decks.webp'), */ linear-gradient(160deg, #3f2f8a, #0a061d); }
.hub-tile-trade_mtrade{ background-image: url('../assets/images/hub/tiles/echange-mystere.webp'), linear-gradient(160deg, #7c5a1f, #1d1306); }
.hub-tile-trade_trade{ background-image: url('../assets/images/hub/tiles/echange.webp'),         linear-gradient(160deg, #1f6b7c, #06171d); }
.hub-tile-trade_offers{ background-image: url('../assets/images/hub/tiles/offres.webp'),          linear-gradient(160deg, #2f7c46, #06170c); }
/* Boutique & codes : ambre/or marchand · rose/magenta · rouge corail (ticket) */
.hub-tile-shop_shop{
  background-image: /* TODO webp: décommenter quand l'image existe → url('../assets/images/hub/tiles/boutique.webp'), */
    radial-gradient(circle at 18% 14%, rgba(255, 214, 110, .32), transparent 55%),
    radial-gradient(circle at 86% 92%, rgba(255, 160, 40, .24), transparent 60%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .045) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, #7c5410, #241302);
}
.hub-tile-shop_inventory{
  background-image: /* TODO webp: décommenter quand l'image existe → url('../assets/images/hub/tiles/inventaire.webp'), */
    radial-gradient(circle at 82% 16%, rgba(255, 120, 210, .30), transparent 55%),
    radial-gradient(circle at 14% 90%, rgba(200, 60, 160, .24), transparent 60%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .045) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, #8f2468, #240818);
}
.hub-tile-shop_promo{
  background-image: /* TODO webp: décommenter quand l'image existe → url('../assets/images/hub/tiles/code-promo.webp'), */
    radial-gradient(circle at 20% 88%, rgba(255, 138, 110, .30), transparent 55%),
    radial-gradient(circle at 84% 14%, rgba(255, 90, 70, .24), transparent 60%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .045) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, #a03a2c, #260a06);
}
/* Progression : or/bronze trophée · rose vif cible · vert/teal stats */
.hub-tile-progression_leaderboard{
  background-image: /* TODO webp: décommenter quand l'image existe → url('../assets/images/hub/tiles/classements.webp'), */
    radial-gradient(circle at 50% 12%, rgba(255, 208, 100, .32), transparent 58%),
    radial-gradient(circle at 88% 90%, rgba(200, 130, 40, .24), transparent 60%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .045) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, #8a651a, #221404);
}
.hub-tile-progression_quests{
  background-image: /* TODO webp: décommenter quand l'image existe → url('../assets/images/hub/tiles/quetes.webp'), */
    radial-gradient(circle at 16% 18%, rgba(255, 96, 160, .30), transparent 55%),
    radial-gradient(circle at 86% 88%, rgba(216, 27, 96, .26), transparent 60%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .045) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, #a3164d, #250612);
}
.hub-tile-progression_stats{
  background-image: /* TODO webp: décommenter quand l'image existe → url('../assets/images/hub/tiles/statistiques.webp'), */
    radial-gradient(circle at 84% 18%, rgba(64, 224, 190, .28), transparent 55%),
    radial-gradient(circle at 14% 88%, rgba(20, 160, 130, .24), transparent 60%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .045) 0 2px, transparent 2px 16px),
    linear-gradient(160deg, #0d7a68, #04201c);
}
/* MOBILE : pile verticale, panneaux moins hauts (le bandeau reste en bas). */
@media (max-width: 560px){
  .hub-grid{ grid-template-columns: 1fr; gap: 10px; }
  .hub-tile, .hub-panels-art .hub-tile{ min-height: 112px; }
  .hub-panel-ico{ font-size: 2rem; top: 32%; }
  .hub-panel-label{ padding: 20px 10px 9px; }
  .hub-panel-title{ font-size: .9rem; }
}

/* Groupe de catégorie (Combat · Échanges · …) : chaque bloc a un en-tête + une
   barre d'accent verticale colorée à gauche, héritée via --cmd-accent. */
.cmd-group{
  --cmd-accent: var(--neon-1);
  display: flex; flex-direction: column; align-items: stretch; gap: 7px;
  position: relative;
  padding-left: 10px;
}
.cmd-group::before{
  content: "";
  position: absolute; left: 0; top: 26px; bottom: 2px;
  width: 3px; border-radius: 999px;
  background: linear-gradient(180deg, var(--cmd-accent), transparent 130%);
  opacity: .55;
}
.cmd-group-head{ display: flex; align-items: center; gap: 8px; margin: 0 0 1px 2px; }
.cmd-group-title{
  font-family: var(--font-ui);
  font-size: .66rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--cmd-accent);
  opacity: .85;
}
/* Accent par catégorie (couleur de la barre + du titre) */
.cmd-group:has(.cmd-battle){ --cmd-accent: #00e5ff; }
.cmd-group:has(.cmd-trade){ --cmd-accent: #b14dff; }
.cmd-group:has(.cmd-shop){ --cmd-accent: #ffb347; }
.cmd-group:has(.cmd-community){ --cmd-accent: #8aa0ff; }
.cmd-group:has(.cmd-ranking){ --cmd-accent: #ffd76a; }

/* Ancien séparateur — neutralisé (les groupes portent désormais un en-tête). */
.cmd-sep{ display: none; }

/* Pilule de commande — pleine largeur, puce d'icône + libellé */
.btn-cmd{
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 13px;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(255, 255, 255, .03), rgba(0, 0, 0, .14));
  color: var(--text-dim);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition:
    color .18s ease,
    border-color .18s ease,
    background .18s ease,
    box-shadow .2s ease,
    transform .12s ease;
}
.btn-cmd .cmd-ico{
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.05rem;
  line-height: 1;
  flex: 0 0 auto;
  width: 1.85em; height: 1.85em;
  border-radius: 9px;
  background: rgba(0, 0, 0, .28);
  border: 1px solid rgba(255, 255, 255, .06);
  filter: drop-shadow(0 0 6px rgba(0, 0, 0, .4));
  transition: background .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.btn-cmd .cmd-label{ flex: 1 1 auto; }
.btn-cmd:hover{
  color: var(--text);
  transform: translateX(3px);
}
.btn-cmd:active{ transform: translateX(0); }
.btn-cmd:focus-visible{
  outline: none;
  box-shadow: 0 0 0 2px rgba(0, 229, 255, .55);
}

/* Accent CYAN — actions de combat */
.btn-cmd.cmd-battle:hover{
  border-color: rgba(0, 229, 255, .7);
  background: linear-gradient(180deg, rgba(0, 229, 255, .16), rgba(0, 229, 255, .06));
  box-shadow: 0 6px 20px rgba(0, 229, 255, .35), inset 0 0 14px rgba(0, 229, 255, .12);
}
.btn-cmd.cmd-battle:hover .cmd-ico{ background: rgba(0, 229, 255, .2); border-color: rgba(0, 229, 255, .5); box-shadow: 0 0 12px rgba(0, 229, 255, .4); }
/* Accent VIOLET — échanges */
.btn-cmd.cmd-trade:hover{
  border-color: rgba(177, 77, 255, .7);
  background: linear-gradient(180deg, rgba(177, 77, 255, .18), rgba(177, 77, 255, .06));
  box-shadow: 0 6px 20px rgba(177, 77, 255, .4), inset 0 0 14px rgba(177, 77, 255, .12);
}
.btn-cmd.cmd-trade:hover .cmd-ico{ background: rgba(177, 77, 255, .22); border-color: rgba(177, 77, 255, .5); box-shadow: 0 0 12px rgba(177, 77, 255, .4); }
/* Accent OR — boutique */
.btn-cmd.cmd-shop{
  color: #ffd76a;
  border-color: rgba(255, 152, 0, .35);
  background: linear-gradient(180deg, rgba(255, 152, 0, .12), rgba(255, 152, 0, .04));
}
.btn-cmd.cmd-shop:hover{
  color: #fff;
  border-color: rgba(255, 180, 60, .8);
  background: linear-gradient(180deg, rgba(255, 180, 60, .28), rgba(255, 152, 0, .08));
  box-shadow: 0 6px 20px rgba(255, 180, 60, .45), inset 0 0 14px rgba(255, 180, 60, .15);
}
.btn-cmd.cmd-shop:hover .cmd-ico{ background: rgba(255, 180, 60, .24); border-color: rgba(255, 180, 60, .55); box-shadow: 0 0 12px rgba(255, 180, 60, .4); }
/* Accent VERT — code promo */
.btn-cmd.cmd-promo{
  color: #8af7c8;
  border-color: rgba(0, 230, 150, .3);
  background: linear-gradient(180deg, rgba(0, 230, 150, .12), rgba(0, 230, 150, .04));
}
.btn-cmd.cmd-promo:hover{
  color: #fff;
  border-color: rgba(0, 230, 150, .8);
  background: linear-gradient(180deg, rgba(0, 230, 150, .26), rgba(0, 230, 150, .08));
  box-shadow: 0 6px 20px rgba(0, 230, 150, .4), inset 0 0 14px rgba(0, 230, 150, .14);
}
.btn-cmd.cmd-promo:hover .cmd-ico{ background: rgba(0, 230, 150, .22); border-color: rgba(0, 230, 150, .5); box-shadow: 0 0 12px rgba(0, 230, 150, .4); }
/* Accent BLURPLE — communauté (liaison Discord) */
.btn-cmd.cmd-community{
  color: #aab6ff;
  border-color: rgba(88, 101, 242, .35);
  background: linear-gradient(180deg, rgba(88, 101, 242, .14), rgba(88, 101, 242, .05));
}
.btn-cmd.cmd-community:hover{
  color: #fff;
  border-color: rgba(88, 101, 242, .85);
  background: linear-gradient(180deg, rgba(88, 101, 242, .3), rgba(88, 101, 242, .1));
  box-shadow: 0 6px 20px rgba(88, 101, 242, .45), inset 0 0 14px rgba(88, 101, 242, .16);
}
.btn-cmd.cmd-community:hover .cmd-ico{ background: rgba(88, 101, 242, .26); border-color: rgba(88, 101, 242, .55); box-shadow: 0 0 12px rgba(88, 101, 242, .4); }
/* Accent OR — classements */
.btn-cmd.cmd-ranking{
  color: #ffe08a;
  border-color: rgba(255, 199, 0, .35);
  background: linear-gradient(180deg, rgba(255, 199, 0, .13), rgba(255, 199, 0, .04));
}
.btn-cmd.cmd-ranking:hover{
  color: #fff;
  border-color: rgba(255, 215, 80, .85);
  background: linear-gradient(180deg, rgba(255, 215, 80, .3), rgba(255, 199, 0, .08));
  box-shadow: 0 6px 20px rgba(255, 199, 0, .45), inset 0 0 14px rgba(255, 199, 0, .16);
}
.btn-cmd.cmd-ranking:hover .cmd-ico{ background: rgba(255, 215, 80, .24); border-color: rgba(255, 215, 80, .55); box-shadow: 0 0 12px rgba(255, 199, 0, .4); }

/* ============================================================
   CLASSEMENTS & SAISON (modale 🏆)
   ============================================================ */
.lb-wrap{ display: flex; flex-direction: column; gap: 14px; }

/* --- Bandeau saison --- */
.lb-season-banner{
  border: 1px solid var(--border);
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(255, 199, 0, .08), rgba(0, 0, 0, 0));
  padding: 12px 14px;
}
.lb-season-row{ display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.lb-season-ico{ font-size: 1.2rem; line-height: 1; }
.lb-season-label{ font-weight: 700; color: var(--text); }
.lb-season-active .lb-season-label{
  background: linear-gradient(100deg, #ffe082, #ffc107 60%, #ffb300);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.lb-season-countdown{
  margin-left: auto;
  font-size: .85rem; font-weight: 600;
  color: #ffd76a;
  border: 1px solid rgba(255, 199, 0, .35);
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
}
.lb-season-off .lb-season-label{ color: var(--text-dim); }
.lb-season-winner{
  margin-top: 8px;
  font-size: .85rem;
  color: var(--text-dim);
  border-top: 1px dashed var(--border);
  padding-top: 8px;
}
.lb-season-winner b{ color: var(--text); }

/* --- Pills de sélection --- */
.lb-pills{
  display: flex; flex-wrap: wrap; gap: 8px;
}
.lb-pill{
  display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-size: .9rem; font-weight: 600;
  color: var(--text-dim);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 14px;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s, box-shadow .15s;
}
.lb-pill:hover{ color: var(--text); border-color: var(--chrome-1); }
.lb-pill.is-active{
  color: #0b0820;
  border-color: transparent;
  background: linear-gradient(135deg, var(--neon-1), var(--neon-purple));
  box-shadow: 0 4px 16px rgba(0, 229, 255, .35);
}
.lb-pill-ico{ font-size: .95rem; line-height: 1; }

/* --- Conteneur tableau + états --- */
.lb-table-wrap{ min-height: 160px; }
.lb-loading, .lb-empty, .lb-error{
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 32px 14px; text-align: center;
  color: var(--text-dim);
}
.lb-empty-ico, .lb-error-ico{ font-size: 2rem; opacity: .8; }

/* --- Tableau --- */
.lb-table{
  width: 100%;
  border-collapse: collapse;
  font-size: .92rem;
}
.lb-table thead th{
  text-align: left;
  font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-faint);
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
}
.lb-table td{
  padding: 9px 10px;
  border-bottom: 1px solid rgba(54, 41, 94, .5);
  vertical-align: middle;
}
.lb-table tbody tr:hover{ background: rgba(177, 77, 255, .07); }
.lb-c-rank{ width: 64px; text-align: center; }
.lb-c-val{ width: 84px; text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text); }
.lb-c-name{
  color: var(--text);
  max-width: 0; width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lb-rank-num{ color: var(--text-faint); font-weight: 700; font-variant-numeric: tabular-nums; }
.lb-medal{ font-size: 1.15rem; line-height: 1; }

/* Ligne du joueur connecté : mise en évidence néon */
.lb-row-me td{
  background: linear-gradient(90deg, rgba(0, 229, 255, .14), rgba(177, 77, 255, .08));
  border-bottom-color: rgba(0, 229, 255, .35);
}
.lb-row-me .lb-c-name{ color: #fff; font-weight: 700; }
.lb-you{
  font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: #0b0820;
  background: linear-gradient(135deg, var(--neon-1), var(--neon-purple));
  border-radius: 999px;
  padding: 2px 7px;
  margin-left: 6px;
  vertical-align: middle;
}

.lb-updated{
  margin-top: 10px;
  font-size: .76rem;
  color: var(--text-faint);
  text-align: right;
}

/* --- Responsive mobile --- */
@media (max-width: 560px){
  .lb-pill{ font-size: .82rem; padding: 6px 11px; }
  .lb-table{ font-size: .86rem; }
  .lb-table td{ padding: 8px 6px; }
  .lb-c-rank{ width: 48px; }
  .lb-c-val{ width: 64px; }
  .lb-season-countdown{ margin-left: 0; }
}

/* Accent VERT — quêtes & succès */
.btn-cmd.cmd-quests{
  color: #9bf6c4;
  border-color: rgba(0, 230, 150, .35);
  background: linear-gradient(180deg, rgba(0, 230, 150, .13), rgba(0, 230, 150, .04));
}
.btn-cmd.cmd-quests:hover{
  color: #fff;
  border-color: rgba(60, 240, 170, .85);
  background: linear-gradient(180deg, rgba(60, 240, 170, .3), rgba(0, 230, 150, .08));
  box-shadow: 0 6px 20px rgba(0, 230, 150, .4), inset 0 0 14px rgba(0, 230, 150, .16);
}
.btn-cmd.cmd-quests:hover .cmd-ico{ background: rgba(60, 240, 170, .22); border-color: rgba(60, 240, 170, .5); box-shadow: 0 0 12px rgba(0, 230, 150, .4); }

/* ============================================================
   QUÊTES & SUCCÈS (modale 🎯)
   ============================================================ */
.q-wrap{ display: flex; flex-direction: column; gap: 16px; min-height: 160px; }

/* États chargement / vide / erreur (calqués sur la section Classements). */
.q-loading, .q-empty, .q-error{
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 32px 14px; text-align: center;
  color: var(--text-dim);
}
.q-empty-ico, .q-error-ico{ font-size: 2rem; opacity: .8; }

/* Invite à se connecter (mode public). */
.q-login-note{
  font-size: .88rem; font-weight: 600;
  color: #ffd76a;
  border: 1px solid rgba(255, 199, 0, .35);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 199, 0, .08), rgba(0, 0, 0, 0));
  padding: 10px 14px;
}

/* Titres de section (Succès / Quêtes répétables). */
.q-section-title{
  margin: 4px 0 0;
  font-size: .82rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-faint);
}

/* Grille de cartes de quête — auto-fit responsive. */
.q-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}

/* Carte de quête. */
.q-card{
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  padding: 12px 14px;
  transition: border-color .15s, box-shadow .15s;
}
.q-card:hover{ border-color: var(--chrome-1); }
.q-card-done{
  border-color: rgba(0, 230, 150, .5);
  background: linear-gradient(180deg, rgba(0, 230, 150, .08), rgba(0, 0, 0, 0));
}
.q-card-head{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.q-label{ margin: 0; font-size: .98rem; font-weight: 700; color: var(--text); flex: 1 1 auto; }
.q-desc{ margin: 0; font-size: .84rem; line-height: 1.4; color: var(--text-dim); }
.q-done{ font-size: 1rem; line-height: 1; }

/* Tags Quotidienne / Hebdo. */
.q-tag{
  font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}
.q-tag-daily{ color: #8fe0ff; border: 1px solid rgba(0, 229, 255, .4); background: rgba(0, 229, 255, .08); }
.q-tag-weekly{ color: #d7b4ff; border: 1px solid rgba(177, 77, 255, .4); background: rgba(177, 77, 255, .08); }

/* Barre de progression. */
.q-progress{
  position: relative;
  height: 18px;
  border-radius: 999px;
  background: rgba(54, 41, 94, .55);
  overflow: hidden;
}
.q-progress-fill{
  height: 100%;
  background: linear-gradient(90deg, var(--neon-1), var(--neon-purple));
  border-radius: 999px;
  transition: width .4s ease;
}
.q-progress-fill.is-complete{
  background: linear-gradient(90deg, #00e696, #3cf0aa);
}
.q-progress-label{
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: .72rem; font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
  font-variant-numeric: tabular-nums;
}

/* Récompense (+ pts / waifu colorée par rareté). */
.q-reward{
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: .8rem;
  border-top: 1px dashed var(--border);
  padding-top: 8px;
}
.q-reward-lbl{ color: var(--text-faint); font-weight: 700; text-transform: uppercase; font-size: .68rem; letter-spacing: .04em; }
.q-reward-pts{
  font-weight: 700; color: #ffd76a;
  border: 1px solid rgba(255, 199, 0, .35);
  border-radius: 999px; padding: 2px 9px;
}
.q-reward-waifu{
  font-weight: 700;
  color: var(--rc, var(--text));
  border: 1px solid var(--rc, var(--border));
  border-radius: 999px; padding: 2px 9px;
  background: rgba(255, 255, 255, .03);
}
.q-claimed{
  font-size: .76rem; font-weight: 600;
  color: #9bf6c4;
}

/* Responsive mobile. */
@media (max-width: 560px){
  .q-grid{ grid-template-columns: 1fr; }
  .q-card{ padding: 11px 12px; }
}

/* ============================================================
   STATISTIQUES PUBLIQUES (modale 📊)
   ============================================================ */
/* Accent CYAN/violet — bouton statistiques */
.btn-cmd.cmd-stats{
  color: #8fe9ff;
  border-color: rgba(0, 229, 255, .35);
  background: linear-gradient(180deg, rgba(0, 229, 255, .13), rgba(0, 229, 255, .04));
}
.btn-cmd.cmd-stats:hover{
  color: #fff;
  border-color: rgba(60, 220, 255, .85);
  background: linear-gradient(180deg, rgba(60, 220, 255, .3), rgba(0, 229, 255, .08));
  box-shadow: 0 6px 20px rgba(0, 229, 255, .4), inset 0 0 14px rgba(0, 229, 255, .16);
}
.btn-cmd.cmd-stats:hover .cmd-ico{ background: rgba(60, 220, 255, .22); border-color: rgba(60, 220, 255, .5); box-shadow: 0 0 12px rgba(0, 229, 255, .4); }

.ps-wrap{ display: flex; flex-direction: column; gap: 18px; }

/* États chargement / vide / erreur */
.ps-loading, .ps-empty, .ps-error{
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 32px 14px; text-align: center;
  color: var(--text-dim);
}
.ps-empty-ico, .ps-error-ico{ font-size: 2rem; opacity: .8; }

/* Bandeau saison (cohérent avec les classements) */
.ps-season{
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px solid rgba(255, 199, 0, .4);
  border-radius: 16px;
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(255, 199, 0, .16), transparent 60%),
    linear-gradient(180deg, rgba(255, 199, 0, .1), rgba(0, 0, 0, 0));
  padding: 12px 16px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}
.ps-season-ico{ font-size: 1.3rem; line-height: 1; filter: drop-shadow(0 0 8px rgba(255, 199, 0, .6)); }
.ps-season-label{
  font-family: var(--font-ui);
  font-weight: 700; font-size: 1.02rem;
  background: linear-gradient(100deg, #ffe082, #ffc107 60%, #ffb300);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.ps-season-countdown{
  margin-left: auto;
  font-size: .85rem; font-weight: 700;
  color: #ffd76a;
  border: 1px solid rgba(255, 199, 0, .4);
  border-radius: 999px;
  padding: 4px 11px;
  white-space: nowrap;
  background: rgba(0, 0, 0, .25);
}

/* Grille de cartes hero */
.ps-grid{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.ps-card{
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  text-align: center;
  padding: 18px 12px 15px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(0, 229, 255, .14), transparent 60%),
    linear-gradient(180deg, rgba(177, 77, 255, .08), rgba(0, 0, 0, .14));
  position: relative; overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 8px 22px rgba(0, 0, 0, .28);
  transition: transform .18s ease, box-shadow .2s ease, border-color .18s ease;
}
.ps-card::after{
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--neon-1), var(--neon-purple), transparent);
  opacity: .7;
}
.ps-card:hover{
  transform: translateY(-2px);
  border-color: rgba(0, 229, 255, .4);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 12px 30px rgba(0, 229, 255, .18);
}
.ps-card-ico{
  font-size: 1.35rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.2em; height: 2.2em; margin-bottom: 2px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, rgba(0, 229, 255, .22), rgba(177, 77, 255, .12));
  border: 1px solid rgba(255, 255, 255, .08);
  filter: drop-shadow(0 0 8px rgba(0, 229, 255, .35));
}
.ps-card-num{
  font-family: var(--font-num);
  font-size: 1.8rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(135deg, var(--chrome-1), var(--chrome-2));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.ps-card-lbl{
  font-size: .74rem; font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase; letter-spacing: .05em;
}

/* Mini barre de complétion globale (sous une carte hero) */
.ps-mini-bar{
  position: relative;
  width: 100%;
  height: 17px;
  margin-top: 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .4);
  border: 1px solid var(--border);
  overflow: hidden;
}
.ps-mini-fill{
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--neon-1), var(--neon-purple));
  box-shadow: 0 0 12px rgba(0, 229, 255, .5);
  transition: width .6s cubic-bezier(.22, 1, .36, 1);
}
.ps-mini-lbl{
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: .66rem; font-weight: 800;
  letter-spacing: .02em;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .85);
}

/* Bloc générique (rareté) */
.ps-block{
  border: 1px solid var(--border);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  padding: 16px 18px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
}
.ps-block-title{
  margin: 0 0 14px;
  font-family: var(--font-ui);
  font-size: .88rem; font-weight: 700;
  letter-spacing: .03em;
  color: var(--text);
}

/* Histogramme rareté */
.ps-rar-list{ display: flex; flex-direction: column; gap: 9px; }
.ps-rar-row{ display: flex; align-items: center; gap: 10px; }
.ps-rar-name{
  display: inline-flex; align-items: center; gap: 7px;
  width: 112px; flex: 0 0 112px;
  font-size: .82rem; font-weight: 700;
}
.ps-rar-name .dot{
  width: 10px; height: 10px; border-radius: 50%;
  display: inline-block; flex: 0 0 auto;
  box-shadow: 0 0 7px currentColor;
}
.ps-rar-track{
  position: relative;
  flex: 1 1 auto;
  height: 16px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .42);
  border: 1px solid rgba(255, 255, 255, .04);
  overflow: hidden;
}
.ps-rar-fill{
  height: 100%;
  border-radius: 999px;
  min-width: 3px;
  filter: saturate(1.15);
  box-shadow: 0 0 10px currentColor;
  transition: width .6s cubic-bezier(.22, 1, .36, 1);
}
/* Part du total (%) lue en surimpression au centre de la piste */
.ps-rar-share{
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: .64rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .9);
  pointer-events: none;
}
.ps-rar-row[data-empty="1"]{ opacity: .42; }
.ps-rar-row[data-empty="1"] .ps-rar-share{ display: none; }
.ps-rar-val{
  width: 54px; flex: 0 0 54px; text-align: right;
  font-family: var(--font-num);
  font-size: .8rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* Highlights : waifu la plus collectionnée + collectionneur n°1 */
.ps-highlights{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.ps-highlight{
  position: relative;
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 15px 17px;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  display: flex; flex-direction: column; gap: 7px;
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
}
.ps-highlight::before{
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--rc, var(--neon-purple));
  box-shadow: 0 0 14px var(--rc, var(--neon-purple));
}
.ps-top-waifu{
  --rc: var(--rc, #b14dff);
  border-color: color-mix(in srgb, var(--rc, #b14dff) 55%, var(--border));
  background:
    radial-gradient(130% 120% at 100% 0%, color-mix(in srgb, var(--rc, #b14dff) 18%, transparent), transparent 60%),
    linear-gradient(180deg, var(--surface-2), var(--surface));
}
.ps-most-decorated{
  --rc: #ffd76a;
  border-color: rgba(255, 199, 0, .4);
  background:
    radial-gradient(130% 120% at 100% 0%, rgba(255, 199, 0, .16), transparent 60%),
    linear-gradient(180deg, var(--surface-2), var(--surface));
}
.ps-highlight-lbl{
  font-size: .74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-dim);
}
.ps-highlight-main{
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.ps-hl-name{
  font-family: var(--font-ui);
  font-size: 1.12rem; font-weight: 700;
  color: var(--text);
  text-shadow: 0 0 16px color-mix(in srgb, var(--rc, #b14dff) 40%, transparent);
}
.ps-hl-rarity{
  font-size: .68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 2px 10px;
  background: color-mix(in srgb, currentColor 12%, transparent);
}
.ps-highlight-sub{
  font-size: .85rem; font-weight: 600;
  color: var(--text-dim);
}
/* Pastille chiffrée du highlight (nb de possesseurs / nb de waifus) */
.ps-hl-badge{
  display: inline-flex; align-items: center;
  font-size: .78rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  padding: 3px 11px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--rc, #b14dff) 45%, var(--border));
  background: color-mix(in srgb, var(--rc, #b14dff) 14%, rgba(0, 0, 0, .25));
}
/* Sous-titre explicatif (critère du highlight) — lève toute ambiguïté de libellé */
.ps-highlight-hint{
  font-size: .72rem; font-weight: 500;
  color: var(--text-faint);
  line-height: 1.35;
}

/* Section « Vue d'ensemble » : enveloppe les cartes hero dans un bloc titré */
.ps-block-overview{ padding-bottom: 18px; }
.ps-block-overview .ps-grid{ margin-top: 2px; }

.ps-updated{
  font-size: .74rem;
  color: var(--text-faint);
  text-align: right;
}

/* Responsive mobile */
@media (max-width: 560px){
  .ps-grid{ grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .ps-card-num{ font-size: 1.5rem; }
  .ps-highlights{ grid-template-columns: 1fr; }
  .ps-rar-name{ width: 90px; flex-basis: 90px; font-size: .76rem; }
  .ps-rar-val{ width: 44px; flex-basis: 44px; font-size: .76rem; }
}

/* ----- Modale Inventaire (accès direct « Tes objets ») ----- */
.inv-wrap{ display: flex; flex-direction: column; gap: 14px; }
.inv-intro{ margin: 0; color: var(--text-dim); font-size: .92rem; }
.inv-count{
  align-self: flex-start;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .82rem; font-weight: 800;
  color: var(--text);
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px solid rgba(0, 229, 255, .4);
  background: rgba(0, 229, 255, .1);
  box-shadow: inset 0 0 12px rgba(0, 229, 255, .12);
}
.inv-list{ gap: 10px; }
.inv-note{
  margin: 4px 0 0; font-size: .82rem; color: var(--text-faint); text-align: center;
}
.inv-note b{ color: var(--text-dim); }
.inv-empty{
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 30px 14px; text-align: center; color: var(--text-dim);
}
.inv-empty-ico{ font-size: 2.4rem; opacity: .75; filter: drop-shadow(0 0 12px rgba(0, 229, 255, .35)); }

/* ----- Modale Liaison Discord ----- */
.discord-link-body{ text-align: center; }
.discord-code-row{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 14px 0 16px;
}
.discord-code{
  font-family: var(--font-mono);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: .42em;
  color: var(--text);
  padding: 12px 6px 12px 22px; /* compense le letter-spacing du dernier caractère */
  border: 1px dashed rgba(88, 101, 242, .7);
  border-radius: 14px;
  background: rgba(88, 101, 242, .1);
  text-shadow: 0 0 14px rgba(88, 101, 242, .6);
  user-select: all;
}
.discord-code.is-expired{ opacity: .35; text-decoration: line-through; }
.discord-steps{
  display: inline-block;
  text-align: left;
  margin: 0 auto 10px;
  padding-left: 1.5em;
  line-height: 1.8;
  color: var(--text-dim);
}
.discord-steps strong{ color: var(--text); letter-spacing: .12em; }
.discord-countdown{ margin: 4px 0 2px; color: var(--text-dim); font-weight: 700; }

/* ----- Modale Code promo ----- */
.promo-intro{ color: var(--text-dim); margin: 0 0 14px; text-align: center; }
.promo-form{ display: flex; gap: 10px; flex-wrap: wrap; }
.promo-input{
  flex: 1 1 180px;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 14px;
}
.promo-input:focus{
  outline: none;
  border-color: var(--chrome-1);
  box-shadow: 0 0 0 2px rgba(167, 139, 250, .3);
}
.promo-input::placeholder{ letter-spacing: .5px; text-transform: none; font-weight: 600; color: var(--text-faint); }
.promo-submit{ flex: 0 0 auto; }
.promo-result{ margin-top: 14px; text-align: center; }

/* Petit badge flottant (Défis / Offres) */
.cmd-badge{
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 2px;
  border-radius: 999px; font-size: .72rem; font-weight: 800; line-height: 1;
  background: var(--neon-1); color: #04111a;
  box-shadow: 0 0 10px rgba(0, 229, 255, .6);
}

/* « Défis » qui pulse quand il y a des invitations */
.btn-cmd.has-invites{
  color: var(--text);
  border-color: var(--neon-purple);
  animation: cmdInvitePulse 1.6s ease-in-out infinite;
}
@keyframes cmdInvitePulse{
  0%, 100% { box-shadow: 0 0 0 1px rgba(177, 77, 255, .5), 0 0 10px rgba(177, 77, 255, .30); }
  50%      { box-shadow: 0 0 0 1px rgba(177, 77, 255, .8), 0 0 20px rgba(177, 77, 255, .60); }
}
.btn-action{
  background: linear-gradient(135deg, var(--neon-purple), var(--neon-pink));
  box-shadow: 0 6px 22px rgba(177, 77, 255, .35);
  white-space: nowrap;
  justify-content: center;
}
.btn-action:hover{ filter: brightness(1.1); box-shadow: 0 8px 28px rgba(177, 77, 255, .55); }
/* Variante cyan pour différencier l'échange normal de l'échange mystère */
.btn-action.btn-action-alt{
  background: linear-gradient(135deg, var(--neon-1), #2196f3);
  box-shadow: 0 6px 22px rgba(0, 229, 255, .3);
}
.btn-action.btn-action-alt:hover{ box-shadow: 0 8px 28px rgba(0, 229, 255, .5); }

/* Mobile : le menu reste vertical dans le tiroir latéral. */
@media (max-width: 520px){
  .btn-cmd{ padding: 11px 13px; font-size: .96rem; }
}
.btn-primary{
  background: linear-gradient(135deg, var(--chrome-1), var(--chrome-2));
  box-shadow: 0 6px 20px rgba(139, 92, 246, .3);
  white-space: nowrap;
}
.btn-primary:hover{ filter: brightness(1.08); }
.btn-primary:disabled{ opacity: .55; cursor: not-allowed; }
/* Le clic sur « Sauvegarder » désactivé passe au parent → toast qui EXPLIQUE pourquoi
   (sans ça : clic → rien → « c'est cassé »). */
.dkb-actions .btn:disabled{ pointer-events: none; }

/* ============================================================
   Modale générique
   ============================================================ */
body.modal-open{ overflow: hidden; }
.modal-overlay{
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(4, 7, 16, .72);
  backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  padding: 18px;
  animation: fadeIn .18s ease;
}
@keyframes fadeIn{ from { opacity: 0; } to { opacity: 1; } }
.modal{
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(167, 139, 250, .1), transparent 60%),
    var(--surface);
  border: 1px solid color-mix(in srgb, var(--chrome-1) 16%, var(--border));
  border-radius: var(--radius);
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255, 255, 255, .06);
  width: 100%; max-width: 560px;
  max-height: 88vh; display: flex; flex-direction: column;
  animation: popIn .2s ease;
}
@keyframes popIn{ from { transform: translateY(14px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-head{
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px; border-bottom: 1px solid var(--border);
}
.modal-title{ font-family: var(--font-ui); font-size: 1.25rem; margin: 0; }
.modal-close{
  background: var(--surface-2); border: none; color: var(--text-dim);
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer; font-size: 1rem;
  transition: background .15s, color .15s;
}
.modal-close:hover{ background: var(--neon-pink); color: #fff; }
/* Barre de défilement discrète (tous les modaux) au lieu de celle par défaut du navigateur */
.modal-body{ padding: 20px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--surface-2) transparent; }
.modal-body::-webkit-scrollbar{ width: 9px; }
.modal-body::-webkit-scrollbar-track{ background: transparent; }
.modal-body::-webkit-scrollbar-thumb{
  background: var(--surface-2); border-radius: 999px;
  border: 2px solid transparent; background-clip: padding-box;
}
.modal-body::-webkit-scrollbar-thumb:hover{ background: var(--neon-purple); background-clip: padding-box; }

/* ── Boutique : en-tête + barre de défilement assortis au thème BOIS ── */
.modal.shop-framed .modal-head{
  background: linear-gradient(180deg, #3a281a, #2b1d12);
  border-bottom: 2px solid rgba(138, 99, 54, .6);
  box-shadow: inset 0 1px 0 rgba(255, 210, 140, .08);
  border-radius: var(--radius) var(--radius) 0 0;
}
.modal.shop-framed .modal-title{ color: #f0d9a8; text-shadow: 0 0 12px rgba(255, 200, 90, .22); }
.modal.shop-framed .modal-close{
  background: rgba(28, 18, 10, .85);
  border: 1px solid rgba(138, 99, 54, .7);
  color: #e7d3b0;
}
.modal.shop-framed .modal-close:hover{ background: rgba(138, 99, 54, .92); color: #fff; }
.modal.shop-framed .modal-body{ scrollbar-color: #8a6336 transparent; }
.modal.shop-framed .modal-body::-webkit-scrollbar{ width: 10px; }
.modal.shop-framed .modal-body::-webkit-scrollbar-thumb{
  background: linear-gradient(180deg, #b8893f, #8a6336);
  border-radius: 999px; border: 2px solid transparent; background-clip: padding-box;
}
.modal.shop-framed .modal-body::-webkit-scrollbar-thumb:hover{
  background: #d4a857; border: 2px solid transparent; background-clip: padding-box;
}
.modal-intro{ color: var(--text-dim); line-height: 1.5; margin: 0 0 16px; }
.field-label{ display: block; font-weight: 600; color: var(--text-dim); margin-bottom: 8px; font-size: .95rem; }
.modal-row{ display: flex; gap: 10px; align-items: stretch; }
.modal-row .search{ flex: 1; }
.err-text{ color: var(--neon-pink); font-weight: 600; margin-top: 14px; }

/* Mini spinner (in-modal) */
.mini-spinner{
  width: 28px; height: 28px; margin: 8px auto;
  border: 3px solid var(--surface-2); border-top-color: var(--neon-1);
  border-radius: 50%; animation: spin .8s linear infinite;
}
@keyframes spin{ to { transform: rotate(360deg); } }

/* ============================================================
   Résultat de combat
   ============================================================ */


.battle-verdict.win{ background: rgba(0, 229, 255, .12); color: var(--neon-1); }
.battle-verdict.lose{ background: rgba(244, 67, 54, .12); color: #ff6b6b; }
.battle-verdict.draw{ background: var(--surface-2); color: var(--text-dim); }













.crit{ color: #ffd740; font-weight: 700; }



/* ============================================================
   Échanges (mystère + direct) — PICKER DE CARTES en vignettes.
   Refonte UI : grille de vraies cartes (art + cadre couleur de rareté +
   badge ×N + badge ⚠ dernière copie), barre d'outils (recherche + chips
   de rareté), sélection au clic (glow + ✓). Remplace l'ancien « mur de
   boutons texte » (.trade-pick).
   ============================================================ */
/* Barre d'outils : recherche + chips de rareté (réutilise .chip de la sidebar) */
.trade-toolbar{ display: flex; flex-direction: column; gap: 8px; margin: 0 0 10px; }
.trade-toolbar-search{ width: 100%; }
.trade-toolbar-chips{ display: flex; flex-wrap: wrap; gap: 6px; }

/* Grille de vignettes (scroll interne : les collections font des dizaines de cartes) */
.trade-cards{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px; margin-bottom: 8px; padding: 4px;
  max-height: 46vh; overflow-y: auto; overscroll-behavior: contain;
}
.trade-card{
  position: relative; display: flex; flex-direction: column; gap: 4px;
  padding: 6px 6px 8px; text-align: center; color: var(--text);
  background: var(--surface-2); border: 2px solid var(--rc, var(--border));
  border-radius: 12px; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, opacity .15s ease;
}
.trade-card:hover{ transform: translateY(-2px); box-shadow: 0 0 12px -4px var(--rc, var(--neon-1)); }
.trade-card:disabled{ opacity: .5; cursor: not-allowed; }
.trade-card[hidden]{ display: none !important; } /* filtrage recherche/rareté */
.trade-card-artbox{
  position: relative; aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden;
  background: rgba(0, 0, 0, .35); display: flex; align-items: center; justify-content: center;
}
.trade-card-fallback{ font-size: 1.6rem; font-weight: 800; color: var(--text-muted, #778); }
.trade-card-art{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.trade-card-name{ font-size: .78rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Badge compteur ×N en coin */
.trade-card-count{
  position: absolute; top: 10px; right: 10px; z-index: 2;
  background: rgba(8, 10, 20, .85); border: 1px solid var(--rc, #888); color: #fff;
  font-size: .72rem; font-weight: 800; padding: 1px 6px; border-radius: 999px;
}
/* Badge ⚠ « dernière copie » (tooltip via title — plus de texte long dans la tuile) */
.trade-card-last{
  position: absolute; top: 10px; left: 10px; z-index: 2;
  background: rgba(255, 183, 77, .92); color: #1d1306;
  font-size: .72rem; font-weight: 800; padding: 1px 6px; border-radius: 999px; cursor: help;
}
/* État sélectionné : glow de la rareté + ✓ central */
.trade-card-check{
  position: absolute; top: 34%; left: 50%; transform: translate(-50%, -50%) scale(.6);
  z-index: 3; width: 34px; height: 34px; border-radius: 50%;
  background: var(--rc, var(--neon-1)); color: #fff; font-size: 1.15rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; box-shadow: 0 0 14px var(--rc, var(--neon-1));
  transition: opacity .15s ease, transform .15s ease;
}
.trade-card.is-selected{ transform: translateY(-2px); box-shadow: 0 0 16px -2px var(--rc, var(--neon-1)); }
.trade-card.is-selected .trade-card-check{ opacity: 1; transform: translate(-50%, -50%) scale(1); }
.trade-card.is-selected .trade-card-art{ filter: brightness(.75); }
/* « Aucune carte ne correspond » (recherche/filtre sans résultat) */
.trade-cards-empty{ grid-column: 1 / -1; text-align: center; color: var(--text-dim); padding: 12px 0; }
/* Mobile : grille resserrée fluide */
@media (max-width: 600px){
  .trade-cards{ grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 7px; max-height: 42vh; }
  .trade-card{ padding: 4px 4px 6px; }
  .trade-card-name{ font-size: .7rem; }
}

/* Échange direct : champ pseudo + bouton d'envoi */
.trade-target-label{
  display: block; font-weight: 700; font-size: .9rem;
  color: var(--text-dim); margin: 12px 0 6px;
}
.trade-target{ width: 100%; margin-bottom: 12px; }
.trade-send{ width: 100%; justify-content: center; }
/* Échange direct : pilules de rareté demandée en retour (anti-spoiler) */
.trade-rarity-picks{ display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.trade-rarity-pick{
  background: var(--surface-2); border: 1px solid var(--rc, var(--border));
  color: var(--rc, var(--text)); border-radius: 999px; padding: 7px 14px;
  font-weight: 700; font-size: .9rem; cursor: pointer;
  transition: transform .12s, box-shadow .15s, background .15s;
}
.trade-rarity-pick:hover{ transform: translateY(-2px); background: var(--surface); }
.trade-rarity-pick:disabled{ opacity: .5; cursor: not-allowed; }
.trade-rarity-pick.is-selected{
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--rc, var(--neon-1)), 0 0 14px var(--rc, var(--neon-1));
}
/* Picker « carte à donner » dans une offre reçue */
.offer-give-picks{ margin-top: 8px; }
.offer-give-cancel{ margin-top: 4px; }
.trade-result{ margin-top: 14px; }
.trade-success{
  background: rgba(0, 229, 255, .12); color: var(--neon-1);
  padding: 16px; border-radius: var(--radius-sm); text-align: center;
  line-height: 1.5; margin-bottom: 14px;
}
.trade-queued{
  background: var(--surface-2); color: var(--text-dim);
  padding: 16px; border-radius: var(--radius-sm); text-align: center; line-height: 1.5;
}
/* Échange direct : select « waifu demandée » */
.trade-want{ width: 100%; margin-bottom: 4px; }

/* ============================================================
   Révélation d'un échange réussi (carte reçue brillante)
   ============================================================ */
.trade-reveal{
  display: flex; flex-direction: column; align-items: center;
  gap: 16px; text-align: center;
}
.trade-reveal-title{
  margin: 4px 0 2px; font-size: 1.05rem; font-weight: 800; line-height: 1.4;
  background: linear-gradient(90deg, var(--neon-1), var(--neon-purple));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--neon-1);
  animation: tradeRevealTitle .5s ease-out both;
}
@keyframes tradeRevealTitle{
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
/* Entrée « fait briller » : pop + halo qui pulse autour de la carte reçue */
.trade-reveal-card.cd-head-card{
  width: 100%;
  animation: tradeRevealPop .55s cubic-bezier(.2, .9, .25, 1.2) both,
             tradeRevealGlow 2.4s ease-in-out .55s infinite;
  border-radius: var(--radius-sm);
}
@keyframes tradeRevealPop{
  0%   { opacity: 0; transform: scale(.82) translateY(14px); }
  60%  { opacity: 1; transform: scale(1.03); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes tradeRevealGlow{
  0%, 100% { box-shadow: 0 0 22px -8px var(--rc), 0 0 40px -16px var(--neon-1); }
  50%      { box-shadow: 0 0 40px -4px var(--rc), 0 0 72px -10px var(--neon-purple); }
}
/* Rejoue le shine de l'art à l'apparition de la révélation */
.trade-reveal-card .card-shine::before{ animation: dexShine 1s ease-out .35s; }
.trade-reveal-go{ margin-top: 2px; min-width: 200px; }
@media (max-width: 540px){
  .trade-reveal-card.cd-head-card{ animation: tradeRevealPop .55s ease-out both; }
  .trade-reveal-title{ font-size: .98rem; }
  .trade-reveal-go{ width: 100%; min-width: 0; }
}
@media (prefers-reduced-motion: reduce){
  .trade-reveal-title, .trade-reveal-card.cd-head-card{ animation: none; }
  .trade-reveal-card .card-shine::before{ animation: none; }
  /* Fige les auras / holos / glows de la grille sur leur état statique.
     On cible AUSSI les variantes .in-view (spécificité ≥) pour que le mouvement
     réduit l'emporte sur les anims conditionnées à la visibilité ajoutées pour la perf. */
  .dex-r-legendary, .dex-r-mythic, .dex-r-divine, .dex-r-celestial, .dex-r-legendary.in-view, .dex-r-mythic.in-view, .dex-r-divine.in-view, .dex-r-celestial.in-view{
    animation: none; box-shadow: var(--aura);
  }
  .card-owned.card-secret, .card-owned.card-secret.in-view{ animation: none; }
  .card-secret::after, .card-secret.in-view::after{ animation: none; }
  .badge-secret, .badge-evolved, .in-view .badge-secret, .in-view .badge-evolved{ animation: none; }
  .card-evolved, .card-evolved.in-view{ animation: none; }
  .card-owned.dex-r-mythic.in-view .card-shine::before, .card-owned.dex-r-divine.in-view .card-shine::before, .card-owned.dex-r-celestial.in-view .card-shine::before{ animation: none; }
  .card-locked::after{ animation: none; }
}

/* ============================================================
   Offres d'échange entrantes (📨)
   ============================================================ */
/* Badge de comptage sur le bouton « Offres » */
.offer-badge{
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; margin-left: 4px;
  border-radius: 999px; font-size: .78rem; font-weight: 800; line-height: 1;
  background: var(--neon-1); color: #04111a;
  box-shadow: 0 0 10px rgba(0, 229, 255, .55);
}
.offer-list{ display: flex; flex-direction: column; gap: 12px; }
.offer-card{
  background: var(--surface-2); border: 1px solid var(--border);
  border-left: 4px solid var(--neon-1); border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.offer-card.is-removed{ opacity: .55; }
.offer-body{ line-height: 1.55; }
.offer-line{ margin: 2px 0; }
.offer-gift{ color: var(--text-dim); }
.offer-actions{ display: flex; gap: 10px; margin-top: 10px; }
.offer-actions .btn{ flex: 1; justify-content: center; }
.offer-result:not(:empty){ margin-top: 10px; }
@media (max-width: 520px){
  .offer-actions{ flex-direction: column; }
}
@media (max-width: 520px){
  
  .modal-row{ flex-direction: column; }
}

/* ============================================================
   Waifu ÉVOLUÉE — garde sa couleur de rareté, gagne une aura
   dorée animée + un badge ✦ (haut-centre) + un tag dans le méta.
   ============================================================ */
.card-evolved{
  box-shadow: 0 0 0 1px rgba(255, 215, 106, .55), 0 0 16px rgba(255, 200, 80, .42);
}
/* PERF : le glow doré ne pulse que pour les cartes évoluées visibles. */
.card-evolved.in-view{ animation: evolvedGlow 2.6s ease-in-out infinite; }
@keyframes evolvedGlow{
  0%, 100% { box-shadow: 0 0 0 1px rgba(255, 215, 106, .40), 0 0 12px rgba(255, 200, 80, .32); }
  50%      { box-shadow: 0 0 0 1px rgba(255, 215, 106, .85), 0 0 26px rgba(255, 200, 80, .60); }
}
.badge-evolved{
  position: absolute;
  top: 6px; left: 50%; transform: translateX(-50%);
  z-index: 3;
  font-size: 1rem;
  color: #ffd76a;
  text-shadow: 0 0 8px rgba(255, 215, 106, .95), 0 0 14px rgba(255, 180, 60, .6);
  pointer-events: none;
}
.in-view .badge-evolved{ animation: evolvedSpark 2.2s ease-in-out infinite; }
@keyframes evolvedSpark{
  0%, 100% { opacity: .85; transform: translateX(-50%) scale(1); }
  50%      { opacity: 1;   transform: translateX(-50%) scale(1.18); }
}
.evolved-tag{
  font-size: .62rem;
  font-weight: 700;
  color: #ffd76a;
  text-shadow: 0 0 6px rgba(255, 200, 80, .7);
  white-space: nowrap;
  flex: 0 0 auto;
}
/* Mobile / tactile : on fige les animations (glow + ✦ restent visibles, sans coût/frame).
   Aligné sur la garde des auras (hover:none), (max-width:820px) — voir ~l.839. */
@media (hover: none), (max-width: 820px){
  .card-evolved, .badge-evolved, .card-evolved.in-view, .in-view .badge-evolved{ animation: none; }
}

/* ============================================================
   COMBAT STRATÉGIQUE — constructeur d'équipe
   ============================================================ */

/* Badge élément réutilisable */
.el-badge{
  font-size: .72rem;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  color: #fff;
  background: color-mix(in srgb, var(--el, #b0bec5) 26%, #0b0f1a);
  border: 1px solid var(--el, #b0bec5);
  display: inline-flex; align-items: center; gap: 5px;
}
.el-badge .el-icon{ width: 15px; height: 15px; }
.el-badge .el-emoji{ font-size: .85em; }

/* Compteur chef / sbires */
.tb-counter{ display: flex; gap: 10px; margin-bottom: 12px; }
.tb-cnt{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .82rem;
  font-weight: 700;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
}
.tb-cnt.ok{ color: var(--neon-1); border-color: var(--neon-1); box-shadow: 0 0 12px -4px var(--neon-1); }

/* Liste des copies */
.tb-list{
  display: flex; flex-direction: column; gap: 8px;
  max-height: 42vh; overflow-y: auto;
  padding-right: 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--surface-2) transparent;
}
.tb-list::-webkit-scrollbar{ width: 8px; }
.tb-list::-webkit-scrollbar-thumb{ background: var(--surface-2); border-radius: 999px; }

.tb-card{
  display: flex; align-items: center; gap: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 4px solid var(--rc, #888);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  transition: transform .12s ease, box-shadow .2s ease, border-color .15s ease;
}
.tb-card.is-chef{ box-shadow: 0 0 0 1px var(--rc), 0 0 16px -4px var(--rc); border-color: var(--rc); }
.tb-card.is-sbire{ background: color-mix(in srgb, var(--neon-1) 8%, var(--surface-2)); }
.tb-card-main{ flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.tb-card-name{ font-family: var(--font-ui); font-weight: 700; font-size: .98rem; }
.tb-evolved{ color: #ffd76a; text-shadow: 0 0 8px rgba(255, 215, 106, .9); }
.tb-card-tags{ display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.tb-class{ font-size: .78rem; font-weight: 600; color: var(--text-dim); }
.tb-card-atk{ font-size: .82rem; color: var(--text-faint); }

/* 📊 Lecture d'une carte AVANT de composer (2026-07-29). La vignette ne montrait que
   les noms d'attaques : rien à comparer, donc aucune stratégie possible. Les stats sont
   en chiffres tabulaires pour s'aligner d'une ligne à l'autre — c'est ce qui rend la
   comparaison instantanée. */
.tb-card-stats{
  font-size: .8rem; color: var(--text-secondary);
  font-variant-numeric: tabular-nums; letter-spacing: .2px; margin-top: 2px;
}
.tb-card-passive{ font-size: .8rem; color: #9fd8ff; margin-top: 2px; }
/* 👑 Repère une maîtresse d'un coup d'œil dans la liste : l'or, jamais la couleur de
   rareté — c'est un rôle, pas une qualité de carte. */
.tb-badge-master{
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 7px; border-radius: 999px; font-size: .72rem; font-weight: 700;
  color: #2a1c00; background: linear-gradient(180deg, #ffe08a, #f0a92e);
}

.tb-card-actions{ display: flex; flex-direction: column; gap: 6px; flex: 0 0 auto; }
.tb-btn{
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: .82rem;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  transition: all .15s ease;
  white-space: nowrap;
}
.tb-btn:hover{ color: var(--text); border-color: var(--text-faint); }
.tb-btn-chef.on{
  color: #fff; border-color: var(--r-legendary);
  background: color-mix(in srgb, var(--r-legendary) 30%, var(--surface));
  box-shadow: 0 0 12px -3px var(--r-legendary);
}
.tb-btn-sbire.on{
  color: #fff; border-color: var(--neon-1);
  background: color-mix(in srgb, var(--neon-1) 30%, var(--surface));
  box-shadow: 0 0 12px -3px var(--neon-1);
}
/* Sélection « 4 cartes égales » (refonte Rotation & Élan) */
.tb-card.is-picked{ box-shadow: 0 0 0 1px var(--rc), 0 0 16px -4px var(--rc); border-color: var(--rc); background: color-mix(in srgb, var(--rc) 10%, var(--surface-2)); }
.tb-pos{ display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; flex: 0 0 auto; border-radius: 50%; background: var(--rc, #888); color: #0b0f1a; font-weight: 900; font-size: .82rem; }
.tb-btn-pick.on{ color: #fff; border-color: var(--rc); background: color-mix(in srgb, var(--rc) 32%, var(--surface)); box-shadow: 0 0 12px -3px var(--rc); }
.tb-btn:disabled{ opacity: .4; cursor: default; }

/* 👑 MAÎTRESSE (2026-07-29) — une 5e carte qui ne combat pas et soutient l'équipe.
   Elle se distingue des 4 combattantes par l'OR, jamais par la couleur de rareté :
   c'est un rôle, pas une qualité de carte. Le liseré doré prime donc sur .is-picked. */
.tb-card.is-master{
  border-color: #ffd257;
  box-shadow: 0 0 0 1px #ffd257, 0 0 18px -5px #ffd257;
  background: color-mix(in srgb, #ffd257 9%, var(--surface-2));
}
.tb-pos-master{ background: linear-gradient(180deg, #ffe08a, #f0a92e); color: #3a2700; }
.tb-btn-master.on{
  color: #2a1c00; border-color: #ffd257;
  background: linear-gradient(180deg, #ffd257, #f0a92e);
  box-shadow: 0 0 12px -3px #ffd257;
}
.tb-cnt-master.ok{ color: #ffd257; border-color: #ffd257; box-shadow: 0 0 12px -4px #ffd257; }
.tb-noChef{ font-size: .76rem; color: var(--text-faint); text-align: center; padding: 6px 0; }
/* Note "chef provisoire" (lobby) : visible si aucune Mythique+ dans la collection */
.tb-prov-note{
  font-size: .85rem; padding: 8px 12px; border-radius: var(--radius-sm);
  background: rgba(255, 200, 60, .08); border: 1px solid rgba(255, 200, 60, .28);
  color: #ffd54f;
}



/* ============================================================
   ÉCRAN DE COMBAT ANIMÉ
   ============================================================ */








.cb-card.is-active{
  box-shadow: 0 0 0 2px var(--neon-1), 0 0 18px -2px var(--neon-1);
  transform: translateY(-3px);
  z-index: 2;
}
.cb-card.is-hit{ animation: cbHit .34s ease; }
@keyframes cbHit{
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-5px); filter: brightness(1.6); }
  60% { transform: translateX(4px); }
}










.cb-hpfill.low{ background: linear-gradient(90deg, #f44336, #ff8a65); }


/* Carte ennemie face cachée */



/* Textes flottants */

@keyframes cbFloat{
  0% { transform: translateY(8px) scale(.8); opacity: 0; }
  20% { transform: translateY(-2px) scale(1.1); opacity: 1; }
  100% { transform: translateY(-34px) scale(1); opacity: 0; }
}








.cb-end-actions{
  display: flex; gap: 10px; justify-content: center; margin-top: 4px;
}

@media (max-width: 520px){
  
  
  .tb-card{ flex-direction: column; align-items: stretch; }
  .tb-card-actions{ flex-direction: row; }
}

/* Mobile : on calme l'aura clignotante */
@media (max-width: 820px){
  .cb-card.is-active{ animation: none; }
}

/* ============================================================
   DÉTAIL D'UNE CARTE — exemplaires + attaques par copie
   ============================================================ */
.cd-head{
  border-left: 4px solid var(--rc, var(--neon-1));
  background: linear-gradient(120deg, color-mix(in srgb, var(--rc, var(--neon-1)) 12%, transparent), transparent 70%);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-bottom: 16px;
}
.cd-head-name{
  font-family: var(--font-ui);
  font-weight: 800;
  font-size: 1.2rem;
  margin-bottom: 8px;
}
.cd-head-tags{ display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* ── En-tête « grande carte sous ses effets de rareté » ── */
.cd-head-card{
  border-left: none;
  display: flex;
  gap: 16px;
  align-items: stretch;
  padding: 16px;
  background:
    radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, var(--rc) 20%, transparent), transparent 60%),
    linear-gradient(135deg, color-mix(in srgb, var(--rc) 10%, var(--surface-2)), var(--bg-2));
  border: 1px solid color-mix(in srgb, var(--rc) 45%, transparent);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--rc) 35%, transparent),
    0 0 36px -10px var(--rc),
    inset 0 0 60px -30px var(--rc);
}
/* Détail d'une carte : modale plus large pour profiter de la grande image. */
.modal:has(.cd-head-card){ max-width: 720px; }
.cd-card-art{
  position: relative;
  flex: 0 0 280px;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 2px solid var(--rc);
  box-shadow: 0 0 24px -6px var(--rc), 0 0 48px -12px color-mix(in srgb, var(--rc) 55%, transparent);
  background: linear-gradient(160deg, var(--surface-2), var(--bg-2));
}
.cd-card-art img{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
}
.cd-art-fallback{
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-size: 3rem;
  color: var(--rc); opacity: .5;
}
.cd-card-art .card-shine{ position: absolute; inset: 0; z-index: 2; pointer-events: none; overflow: hidden; }
.cd-card-art .card-shine::before{
  content: ''; position: absolute; top: -60%; left: -75%;
  width: 65%; height: 220%;
  /* Reflet adouci : cœur lumineux discret + dégradé progressif + bords floutés
     (avant : bande blanche nette à .4 d'opacité, trop marquée). */
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.15) 50%, transparent 62%);
  filter: blur(7px);
  transform: rotate(8deg);
  animation: dexShine 3.2s ease-in-out infinite;
}
.cd-card-info{ flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.cd-head-title{ font-size: .92rem; font-style: italic; color: var(--text-dim); margin-top: -4px; }
.cd-secret-tag{
  font-size: .72rem; font-weight: 700;
  color: #d9b8ff;
  background: rgba(0,0,0,.35);
  border: 1px solid var(--neon-purple);
  border-radius: 999px; padding: 3px 10px;
  text-shadow: 0 0 8px var(--neon-purple);
}

/* Halo de rareté du grand visuel : réutilise les classes .dex-r-* */
.cd-head-card.dex-r-legendary .cd-card-art, .cd-head-card.dex-r-mythic .cd-card-art, .cd-head-card.dex-r-divine .cd-card-art{
  animation: dexArtGlow 2.2s ease-in-out infinite;
}
/* (la céleste a son propre scintillement arc-en-ciel : dexStarArtGlow) */
@keyframes dexArtGlow{
  0%, 100% { box-shadow: 0 0 24px -6px var(--rc), 0 0 48px -12px color-mix(in srgb, var(--rc) 55%, transparent); }
  50%      { box-shadow: 0 0 40px -4px var(--rc), 0 0 80px -10px color-mix(in srgb, var(--rc) 60%, transparent); }
}
/* Shimmer holographique secret dans la modale */
.cd-head-card.card-secret .cd-card-art::after{
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%,
    rgba(255,0,128,.18), rgba(0,229,255,.18), rgba(177,77,255,.18), rgba(255,215,64,.18),
    transparent 70%);
  background-size: 300% 300%;
  mix-blend-mode: screen;
  animation: dexHolo 5s linear infinite;
}

/* Barres de statistiques (style overlay) */
.cd-statbars{ display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.cds-row{ display: flex; align-items: center; gap: 8px; }
.cds-l{
  flex: 0 0 34px;
  font-family: var(--font-ui);
  font-size: .62rem; letter-spacing: 1px;
  text-transform: uppercase; color: var(--text-dim);
}
.cds-track{
  flex: 1 1 auto; height: 8px; border-radius: 999px;
  background: rgba(255,255,255,.08);
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.08);
}
.cds-fill{
  display: block; height: 100%; border-radius: 999px;
  transition: width .4s ease;
}
.cds-hp .cds-fill{ background: linear-gradient(90deg, #2e7d32, #4caf50); }
.cds-atk .cds-fill{ background: linear-gradient(90deg, #c62828, #ff5252); }
.cds-def .cds-fill{ background: linear-gradient(90deg, #1565c0, #42a5f5); }
.cds-spd .cds-fill{ background: linear-gradient(90deg, #9e9e9e, #e0e0e0); }
.cds-v{
  flex: 0 0 auto; min-width: 30px; text-align: right;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-weight: 700; font-size: .82rem;
}
.cds-hp .cds-v{ color: #4caf50; }
.cds-atk .cds-v{ color: #ff5252; }
.cds-def .cds-v{ color: #42a5f5; }
.cds-spd .cds-v{ color: #e0e0e0; }

@media (max-width: 560px){
  .cd-head-card{ flex-direction: column; align-items: center; text-align: center; }
  .cd-card-art{ flex-basis: auto; width: 60%; max-width: 200px; }
  .cd-head-tags{ justify-content: center; }
}
@media (hover: none), (max-width: 820px){
  .cd-head-card.dex-r-legendary .cd-card-art, .cd-head-card.dex-r-mythic .cd-card-art, .cd-head-card.dex-r-divine .cd-card-art, .cd-head-card.dex-r-celestial .cd-card-art, .cd-card-art .card-shine::before, .cd-head-card.card-secret .cd-card-art::after{ animation: none; }
}

.cd-count{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .76rem;
  font-weight: 700;
  color: var(--neon-1);
  background: rgba(0, 0, 0, .35);
  border: 1px solid var(--neon-1);
  border-radius: 999px;
  padding: 3px 10px;
}

/* ============================================================
   FICHE CARTE — mise en page « VITRINE » : grand art héros centré
   (nom + rareté en surimpression), stats en tuiles, puces d'info.
   ============================================================ */
.cd-vitrine{ display: flex; flex-direction: column; gap: 16px; align-items: stretch; }
.cd-vitrine .cd-card-art{
  flex: none; width: min(300px, 80%); margin: 0 auto; aspect-ratio: 3 / 4;
}
.cd-hero-badges{
  position: absolute; top: 9px; left: 9px; right: 9px; z-index: 4;
  display: flex; align-items: flex-start; justify-content: space-between;
  pointer-events: none;
}
.cd-rar-badge{
  font-family: var(--font-ui);
  font-size: .6rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: #fff; background: rgba(0,0,0,.55); border-radius: 999px; padding: 3px 10px;
  border: 1px solid color-mix(in srgb, var(--rc) 65%, #fff 35%);
  text-shadow: 0 0 8px var(--rc);
}
.cd-copies-badge{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .62rem; font-weight: 800; color: var(--neon-1);
  background: rgba(0,0,0,.5); border: 1px solid var(--neon-1);
  border-radius: 999px; padding: 3px 10px;
}
.cd-hero-name{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
  padding: 16px 12px 12px; text-align: center; pointer-events: none;
  background: linear-gradient(0deg, rgba(0,0,0,.82), rgba(0,0,0,.4) 55%, transparent);
}
.cd-hero-nm{
  font-family: var(--font-ui);
  font-weight: 900; font-size: 1.4rem; color: #fff; text-shadow: 0 2px 8px #000;
}
.cd-hero-sub{ font-style: italic; color: #cfd8f0; font-size: .82rem; text-shadow: 0 1px 4px #000; }
.cd-hero-name .cd-secret-tag{ display: inline-block; margin-top: 6px; }
/* Stats PV/ATK/DEF/VIT affichées SUR la grande carte (réutilise l'overlay .cstat de
   la grille), en bas, TOUJOURS visibles (pas seulement au survol). */
/* Stats façon OVERLAY WC : rangée de 4 pastilles dans le bandeau bas de la carte
   (réplique overlay-spawn.html : fond teinté rareté, valeurs colorées). */
.cd-wcstats{ display: flex; justify-content: space-around; gap: 4px; margin-top: 9px; }
.cd-wcstat{
  flex: 1; text-align: center; padding: 4px 5px; border-radius: 6px;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  background: color-mix(in srgb, var(--rc) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--rc) 32%, transparent);
}
.cd-wcstat-l{
  font-family: var(--font-ui);
  font-size: .5rem; opacity: .6; text-transform: uppercase; letter-spacing: 1px; color: #fff;
}
.cd-wcstat-v{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .95rem; font-weight: 700; line-height: 1.2;
}
.cd-wcstat-hp{ color: #4caf50; } .cd-wcstat-atk{ color: #f44336; }
.cd-wcstat-def{ color: #42a5f5; } .cd-wcstat-spd{ color: #e0e0e0; }
.cd-meta{ display: flex; flex-direction: column; gap: 12px; }
.cd-stat-tiles{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.cd-tile{
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 9px 6px; text-align: center;
}
.cd-tile-l{
  display: block;
  font-family: var(--font-ui);
  font-size: .56rem; letter-spacing: 1px; color: var(--text-dim);
  font-weight: 700; text-transform: uppercase;
}
.cd-tile-v{
  display: block; margin-top: 3px;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-weight: 900; font-size: 1.05rem;
}
.cd-hp .cd-tile-v{ color: #4caf50; } .cd-atk .cd-tile-v{ color: #ff5252; }
.cd-def .cd-tile-v{ color: #42a5f5; } .cd-spd .cd-tile-v{ color: #e0e0e0; }
.cd-chips{ display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.cd-chips .cd-drop, .cd-chips .cd-evolve-cost{
  margin: 0; font-size: .74rem; padding: 6px 11px; border-radius: 10px;
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
}

.cd-copies{ display: flex; flex-direction: column; gap: 12px; }
.cd-copy{
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.cd-copy.is-evolved{
  border-color: rgba(255, 215, 106, .55);
  box-shadow: 0 0 14px -6px rgba(255, 200, 80, .6);
}
.cd-copy-head{
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.cd-copy-no{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-weight: 800;
  font-size: .95rem;
  color: var(--text);
}
.cd-evolved{
  font-size: .76rem; font-weight: 700;
  color: #ffd76a;
  text-shadow: 0 0 6px rgba(255, 200, 80, .7);
}
.cd-copy-lvl{
  margin-left: auto;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .76rem; font-weight: 700;
  color: var(--r-legendary);
}

.cd-atks{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
/* Attaque = bouton cliquable + panneau de description repliable. */
.cd-atk{
  display: block; overflow: hidden;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  transition: border-color .15s, box-shadow .15s;
}
.cd-atk.is-open{ border-color: color-mix(in srgb, var(--neon-1) 55%, transparent); box-shadow: 0 0 16px -8px var(--neon-1); }
.cd-atk-btn{
  width: 100%; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: none; border: none; color: inherit; font: inherit; text-align: left;
  padding: 9px 12px; cursor: pointer;
}
.cd-atk-btn:hover{ background: color-mix(in srgb, var(--neon-1) 8%, transparent); }
.cd-atk-name{ font-weight: 700; color: var(--text); }
.cd-atk-meta{ display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cd-atk-pow{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .72rem; font-weight: 700; color: #ff8a8a;
}
.cd-atk-fx{
  font-size: .76rem; color: var(--text); font-style: normal;
  background: rgba(255,255,255,.06); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 9px; white-space: nowrap;
}
.cd-atk-caret{ margin-left: auto; color: var(--text-dim); transition: transform .2s; }
.cd-atk.is-open .cd-atk-caret{ transform: rotate(180deg); }
.cd-atk-desc{
  padding: 2px 12px 11px; font-size: .85rem; color: var(--text-dim); line-height: 1.5;
  border-top: 1px solid var(--border); margin-top: 2px; padding-top: 9px;
}
.cd-empty{ color: var(--text-faint); font-size: .9rem; font-style: italic; }

/* ── Carrousel des exemplaires (glisser gauche/droite) ── */
.cd-carousel{ display: flex; flex-direction: column; gap: 10px; outline: none; }
.cd-car-bar{ display: flex; align-items: center; justify-content: center; gap: 14px; }
.cd-car-label{
  font-family: var(--font-ui);
  font-size: .76rem; color: var(--text-dim); min-width: 120px; text-align: center;
}
.cd-car-label b{ color: var(--neon-1); }
.cd-nav{
  width: 36px; height: 36px; flex: 0 0 auto; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  font-size: 1.5rem; line-height: 1; cursor: pointer;
  transition: transform .1s, box-shadow .15s, background .15s;
}
.cd-nav:hover{ background: var(--bg-2); box-shadow: 0 0 14px -4px var(--neon-1); transform: translateY(-1px); }
.cd-nav:active{ transform: scale(.92); }
.cd-viewport{ overflow: hidden; border-radius: var(--radius-sm); }
.cd-track{ display: flex; align-items: stretch; transition: transform .32s cubic-bezier(.4, 0, .2, 1); }
.cd-slide{ flex: 0 0 100%; box-sizing: border-box; }
.cd-dots{ display: flex; gap: 7px; justify-content: center; }
.cd-dot{
  width: 8px; height: 8px; padding: 0; border: none; border-radius: 50%;
  background: var(--border); cursor: pointer; transition: background .15s, transform .15s;
}
.cd-dot.is-active{ background: var(--neon-1); transform: scale(1.35); box-shadow: 0 0 8px var(--neon-1); }
.cd-passive{
  margin-top: 10px;
  font-size: .9rem;
  color: #ffd76a;
}
.cd-passive b{ color: #ffe9a8; }
.cd-note{
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 16px;
  text-align: center;
  line-height: 1.5;
}

/* ============================================================
   ÉCONOMIE — badge de points, notifications, boutique, relâcher
   ============================================================ */

/* --- Badge de points (header / sidebar) --- */
.points-badge{
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, rgba(167, 139, 250, .16), rgba(139, 92, 246, .12));
  border: 1px solid color-mix(in srgb, var(--chrome-1) 42%, transparent);
  box-shadow: 0 6px 18px -8px rgba(139, 92, 246, .45), inset 0 1px 0 rgba(255, 255, 255, .08);
  font-weight: 700;
  color: var(--text);
}
.points-badge-icon{
  font-size: 1.2rem;
  filter: drop-shadow(0 0 6px rgba(167, 139, 250, .7));
}
.points-badge-value{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: 1.25rem;
  font-weight: 900;
  line-height: 1;
  background: linear-gradient(90deg, var(--chrome-1), var(--chrome-2));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  letter-spacing: .5px;
}
.points-badge-label{
  font-size: .8rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .5px;
  line-height: 1;
}

/* --- Notification de gain/perte flottante --- */
.points-gain{
  position: absolute;
  left: 50%;
  top: -6px;
  transform: translate(-50%, 0);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-weight: 800;
  font-size: .95rem;
  white-space: nowrap;
  pointer-events: none;
  z-index: 60;
  animation: pointsGainRise 1.7s ease-out forwards;
}
.points-gain.points-gain-floating{
  position: fixed;
  left: auto;
  right: 18px;
  top: 18px;
  transform: none;
}
.points-gain.is-gain{
  color: #062e15;
  background: linear-gradient(135deg, #5cffb0, #00e5ff);
  box-shadow: 0 4px 18px rgba(0, 229, 170, .5);
}
.points-gain.is-loss{
  color: var(--text);
  background: rgba(28, 36, 64, .92);
  border: 1px solid rgba(177, 77, 255, .55);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .4);
}
.points-gain-reason{
  font-size: .72rem;
  font-weight: 700;
  opacity: .85;
  text-transform: uppercase;
  letter-spacing: .4px;
}
@keyframes pointsGainRise{
  0%   { opacity: 0; transform: translate(-50%, 6px) scale(.9); }
  15%  { opacity: 1; transform: translate(-50%, -10px) scale(1); }
  70%  { opacity: 1; transform: translate(-50%, -34px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -54px) scale(.96); }
}

/* --- Bouton Boutique dans la barre d'actions --- */
.btn-action.btn-action-shop{
  background: linear-gradient(135deg, #ffd76a, #ff9800);
  box-shadow: 0 6px 22px rgba(255, 152, 0, .35);
  color: #2a1c00;
}
.btn-action.btn-action-shop:hover{ box-shadow: 0 8px 28px rgba(255, 180, 60, .55); }

/* --- Boutique (modale) --- */
.shop-head{ margin-bottom: 14px; }
.shop-balance{
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
}
.shop-balance b{
  display: inline-flex; align-items: center; gap: 4px; vertical-align: middle;
  background: linear-gradient(90deg, var(--neon-1), var(--neon-purple));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.shop-note{
  margin: 6px 0 0;
  font-size: .88rem;
  color: var(--text-dim);
}
.shop-note b{ color: var(--neon-1); }
.shop-list{
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.shop-item{
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.shop-item:hover{
  border-color: rgba(0, 229, 255, .5);
  box-shadow: 0 0 16px rgba(0, 229, 255, .18);
}
/* Icône « pièce » des points (image custom, repli ✨ si absente) */
.pts-coin{ width: 1.25em; height: 1.25em; vertical-align: middle; position: relative; top: 0; display: inline-block; object-fit: contain; }
.points-badge-icon .pts-coin{ width: 1.2em; height: 1.2em; }

.shop-item-main{ flex: 1 1 auto; min-width: 0; }
.shop-item-name{
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--text);
}

/* ===== Icône d'objet (image uploadée WCM, sinon emoji) ===== */
/* Pas de cadre ni de fond : juste un halo lumineux pour détacher l'image du fond,
   et image NON rognée (object-fit: contain → on voit l'objet en entier). */
.shop-item-icon{
  flex: 0 0 auto; width: 58px; height: 58px;
  display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 2px 7px rgba(0, 0, 0, .55)) drop-shadow(0 0 9px rgba(170, 130, 255, .22));
}
.shop-item-icon img{ width: 100%; height: 100%; object-fit: contain; display: block; }
.shop-item-icon.emoji{ font-size: 1.9rem; filter: none; }

/* ===== Section « Tes objets » (inventaire possédé) ===== */
.shop-owned{
  margin: 0 0 16px; padding: 12px 14px; border-radius: 12px;
  background: rgba(0, 0, 0, .18); border: 1px solid var(--border);
}
.shop-wood .shop-owned{ background: rgba(28, 18, 10, .5); border-color: rgba(138, 99, 54, .55); }
.shop-owned-title{ font-weight: 800; font-size: .95rem; margin-bottom: 10px; color: var(--text); }
.shop-owned-list{ display: flex; flex-wrap: wrap; gap: 8px; }
.shop-owned-chip{
  display: inline-flex; align-items: center; gap: 7px; padding: 5px 10px 5px 5px;
  border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border);
}
.shop-owned-icon{ width: 30px !important; height: 30px !important; border-radius: 8px; }
.shop-owned-icon.emoji{ font-size: 1rem !important; }
.shop-owned-name{ font-size: .85rem; font-weight: 600; color: var(--text); }
.shop-owned-x{ font-size: .82rem; font-weight: 800; color: var(--gold, #ffce6a); }

/* ===== Animation « achat réussi » ===== */
.shop-item.just-bought{ animation: shopBought .75s ease; }
@keyframes shopBought{
  0%   { box-shadow: 0 0 0 0 rgba(255, 206, 106, 0); }
  25%  { box-shadow: 0 0 26px 4px rgba(255, 206, 106, .65); transform: scale(1.025); border-color: #ffce6a; }
  100% { box-shadow: 0 0 0 0 rgba(255, 206, 106, 0); transform: scale(1); }
}
.shop-buy-pop{
  position: absolute; right: 18px; top: 12px;
  font-weight: 800; font-size: .95rem; color: #ffce6a; pointer-events: none;
  text-shadow: 0 0 10px rgba(255, 206, 106, .6);
  animation: shopBuyPop .9s ease forwards;
}
.shop-item{ position: relative; }
@keyframes shopBuyPop{
  0%   { opacity: 0; transform: translateY(6px); }
  20%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-26px); }
}
@media (prefers-reduced-motion: reduce){
  .shop-item.just-bought{ animation: none; }
  .shop-buy-pop{ animation: none; opacity: 0; }
}
.shop-item-desc{
  margin-top: 4px;
  font-size: .9rem;
  color: var(--text-dim);
  line-height: 1.35;
}
.shop-item-effect{
  margin-top: 4px;
  font-size: .85rem;
  font-weight: 600;
  color: var(--neon-1);
}
/* Ligne d'effet HUMANISÉE (×1,5 capture · 3 essais) */
.shop-item-stats{
  margin-top: 5px;
  font-size: .85rem;
  font-weight: 700;
  color: var(--neon-1);
}
.shop-wood .shop-item-stats{ color: #ffce6a; text-shadow: 0 0 8px rgba(255, 200, 90, .28); }
/* Commandes Twitch COPIABLES sous chaque objet (clic = copie) */
.shop-item-cmd{ margin-top: 8px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.shop-cmd-plat{
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .72rem; font-weight: 700; letter-spacing: .3px;
  color: #c9a7ff;
}
.shop-cmd-copy{
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .76rem; font-weight: 700;
  font-family: var(--font-mono);
  padding: 3px 9px; border-radius: 7px; cursor: pointer;
  background: rgba(145, 71, 255, .14);
  border: 1px solid rgba(145, 71, 255, .45);
  color: #e6d4ff;
  transition: background .15s ease, border-color .15s ease, transform .08s ease;
}
.shop-cmd-copy:hover{ background: rgba(145, 71, 255, .26); border-color: rgba(145, 71, 255, .8); }
.shop-cmd-copy:active{ transform: scale(.96); }
.shop-cmd-copy .shop-cmd-ico{ opacity: .75; font-size: .85em; }
.shop-cmd-copy.copied{
  background: rgba(34, 197, 94, .18); border-color: rgba(34, 197, 94, .7); color: #9cf0bd;
}
/* Variante bois (boutique encadrée) */
.shop-wood .shop-cmd-plat{ color: #e7d3b0; }
.shop-wood .shop-cmd-copy{
  background: rgba(28, 18, 10, .72); border-color: rgba(138, 99, 54, .7); color: #f0dcb6;
}
.shop-wood .shop-cmd-copy:hover{ background: rgba(58, 40, 26, .9); border-color: #b8893f; }
.shop-wood .shop-cmd-copy.copied{ background: rgba(34, 197, 94, .2); border-color: rgba(34, 197, 94, .7); color: #b6f0cd; }
.shop-buy{ flex: 0 0 auto; white-space: nowrap; }
/* Prix + pièce groupés (séparés du mot « Acheter » par le gap du bouton). */
.shop-buy-price{ display: inline-flex; align-items: center; gap: 4px; }
.shop-buy:disabled{
  opacity: .45;
  filter: grayscale(.6);
  cursor: not-allowed;
  box-shadow: none;
}
.shop-toast{
  margin-bottom: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-weight: 700;
  background: linear-gradient(135deg, rgba(0, 229, 170, .22), rgba(0, 229, 255, .18));
  border: 1px solid rgba(0, 229, 170, .5);
  color: var(--text);
  animation: fadeIn .2s ease;
}
.shop-toast.is-error{
  background: rgba(255, 77, 141, .15);
  border-color: rgba(255, 77, 141, .55);
}

/* ===== Boutique : marchand derrière son échoppe ===== */
/* En-tête bord-à-bord : on annule le padding 20px de .modal-body. L'image se rogne
   en haut (object-position) et son BAS se fond, blendant dans la zone bois en dessous
   → le marchand a l'air d'être derrière le comptoir où sont posés les objets. */
.shop-hero{
  margin: -20px -20px 0;
  height: 365px;                 /* calé sur l'image : montre ~10%→~62% (ambiance → comptoir) */
  overflow: hidden;
  /* repli au thème (l'image a son propre fond → sert juste de secours) */
  background: linear-gradient(180deg, var(--bg-2), var(--surface));
  line-height: 0;
  position: relative;
}
.shop-hero-img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Mesuré sur l'image (1024×1536) : surface du comptoir à ~50%, panneau bois à ~53%.
     object-position 20% montre un peu d'ambiance taverne + la tenancière + le comptoir ;
     le fondu (84%) démarre à ~54%, soit DANS le panneau bois → le comptoir dessiné se
     fond dans le bois CSS (deux bois = transition invisible), les objets posés dessus. */
  object-position: center 20%;
  -webkit-mask-image: linear-gradient(to bottom, #000 84%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 84%, transparent 100%);
}
.shop-hero.shop-hero-noimg{ height: 0; }   /* fichier image absent → pas de bande vide */

/* Zone bois : remonte sous le fondu de l'image + bord-à-bord. Planches verticales
   (repeating-linear-gradient) sur un dégradé bois chaud. */
.shop-wood{
  margin: -36px -20px -20px;
  padding: 16px 20px 22px;
  position: relative;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .18) 0 1px, transparent 1px 56px),
    linear-gradient(180deg, #4a3422, #2b1d12);
  border-top: 2px solid rgba(138, 99, 54, .5);
}
.shop-wood .shop-head{ position: relative; margin-bottom: 14px; }
.shop-wood .shop-balance{
  display: inline-block;
  background: rgba(28, 18, 10, .85);
  border: 1px solid rgba(138, 99, 54, .7);
  border-radius: 8px;
  padding: 6px 14px;
  box-shadow: inset 0 1px 0 rgba(255, 210, 140, .08);
}
.shop-wood .shop-note{ color: #d8c4a8; }
.shop-wood .shop-note b{ color: var(--neon-1); }
.shop-wood .shop-item{
  background: linear-gradient(180deg, rgba(74, 52, 34, .92), rgba(52, 36, 22, .94));
  border: 1px solid rgba(138, 99, 54, .55);
  box-shadow: inset 0 1px 0 rgba(255, 210, 140, .07);
}
.shop-wood .shop-item:hover{
  border-color: rgba(0, 229, 255, .5);
  box-shadow: 0 0 16px rgba(0, 229, 255, .18), inset 0 1px 0 rgba(255, 210, 140, .07);
}
.shop-wood .shop-item-desc{ color: #cbb89c; }
@media (max-width: 480px){
  .shop-hero{ height: 260px; }   /* proportionnel : même cadrage (object-position en %) */
  .shop-wood{ margin-top: -30px; }
}

/* ----- Boutique : en-tête (solde + bouton son) + cadre décoratif ----- */
.shop-headrow{ display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.snd-toggle{
  flex: 0 0 auto;
  background: rgba(28, 18, 10, .85);
  border: 1px solid rgba(138, 99, 54, .7);
  border-radius: 8px;
  font-size: 1.05rem; line-height: 1;
  padding: 6px 9px; cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.snd-toggle:hover{ border-color: rgba(0, 229, 255, .55); box-shadow: 0 0 12px rgba(0, 229, 255, .2); }
/* Contrôles à droite de l'entête boutique (langue de voix + bouton son). */
.shop-head-ctrls{ flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
/* Sélecteur de langue PARLÉE par les waifus (indépendant de l'interface). */
.voice-lang{
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  background: rgba(28, 18, 10, .85);
  border: 1px solid rgba(138, 99, 54, .7);
  border-radius: 8px; padding: 4px 8px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.voice-lang:hover{ border-color: rgba(0, 229, 255, .55); box-shadow: 0 0 12px rgba(0, 229, 255, .2); }
.voice-lang-ic{ font-size: 1rem; line-height: 1; }
.voice-lang-sel{
  background: transparent; border: 0; color: #f3e6d2;
  font: inherit; font-size: .9rem; cursor: pointer; outline: none;
  max-width: 140px;
}
.voice-lang-sel option{ background: #1c120a; color: #f3e6d2; }
/* Cadre image autour de la modale boutique : overlay, centre transparent, ne bloque pas les
   clics. Le PNG/WebP (transparent au milieu) est fourni par l'admin ; absent → invisible. */
/* position:relative INDISPENSABLE → le cadre (absolute) se cale sur la MODALE, pas le viewport. */
.modal.shop-framed{ overflow: hidden; }   /* coins arrondis coupés comme les autres modales (le cadre overlay est abandonné) */
/* Cadre en 9-slice (border-image) : les COINS restent intacts, seuls les BORDS s'étirent, et
   le CENTRE est ignoré (la modale apparaît au travers) → robuste au centrage de l'image source.
   Réglages : `inset` = débord hors de la modale · `border-width` = épaisseur rendue du cadre ·
   `border-image-slice` = part de la SOURCE prise pour la bordure · `repeat` = stretch / round. */
/* (Cadre décoratif abandonné : la boutique garde son thème BOIS + Riko en en-tête,
   mais sans frise/overlay. Le wrapper .shop-frame n'est plus inséré côté JS.) */

/* ===== Récompense quotidienne : boîte cadeau (haut-droite) + barre de jours ===== */
/* Cadeau seul (pas de bulle) : juste l'emoji, un peu plus grand, avec sa pastille. */
.daily-gift{
  position: fixed; top: 12px; right: 14px; z-index: 60;
  padding: 4px; border: none; background: none; box-shadow: none; border-radius: 0;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  font-size: 2.4rem; line-height: 1;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .55));
  animation: dgIdle 9s ease-in-out infinite; /* petit coup d'œil de temps en temps */
}
.daily-gift:hover{ filter: drop-shadow(0 0 12px rgba(0, 229, 255, .85)); }
.daily-gift-dot{
  display: none; position: absolute; top: -3px; right: -3px;
  width: 12px; height: 12px; border-radius: 50%;
  background: #ff4d8d; border: 2px solid var(--bg);
}
.daily-gift.available{
  animation: dgWiggle 1.7s ease-in-out infinite;
  filter: drop-shadow(0 0 10px rgba(255, 202, 40, .9)) drop-shadow(0 2px 4px rgba(0, 0, 0, .5));
}
.daily-gift.available .daily-gift-dot{ display: block; animation: dgDot 1.2s ease-in-out infinite; }
@keyframes dgIdle{ 0%, 92%, 100% { transform: rotate(0); } 94% { transform: rotate(-9deg); } 96% { transform: rotate(9deg); } 98% { transform: rotate(-4deg); } }
@keyframes dgWiggle{ 0%, 100% { transform: rotate(0) scale(1); } 20% { transform: rotate(-11deg) scale(1.07); } 40% { transform: rotate(9deg); } 60% { transform: rotate(-6deg); } 80% { transform: rotate(4deg); } }
@keyframes dgDot{ 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: .65; } }
@media (max-width: 480px){ .daily-gift{ font-size: 2rem; top: 10px; right: 10px; } }

.dq-bar{ display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin: 18px 0 10px; }
.dq-cell{
  position: relative; flex: 0 0 auto; width: 66px; padding: 10px 6px 9px;
  border-radius: 14px; text-align: center;
  border: 1px solid var(--border);
  background: linear-gradient(160deg, rgba(255, 255, 255, .05), rgba(0, 0, 0, .18));
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  transition: transform .15s ease;
}
.dq-day{
  font-size: .6rem; font-weight: 800; letter-spacing: .8px; text-transform: uppercase;
  color: var(--text-dim); background: rgba(255, 255, 255, .07);
  padding: 2px 9px; border-radius: 999px;
}
.dq-ico{ font-size: 1.35rem; line-height: 1; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .45)); }
.dq-rw{ font-size: .74rem; font-weight: 700; color: var(--text-dim); white-space: nowrap; }

/* 🎯 HIÉRARCHIE DES SEPT JOURS (revue le 2026-08-06) — UNE SEULE case attire l'œil.
   Retour de l'administrateur : « le J3 est quand même un peu doré, ce qui n'est pas très
   intuitif comme étant DEMAIN. Et le J7 est trop mis en avant. » Mesuré au navigateur avant
   correction : TROIS cases portaient de l'or en même temps — le jour réclamable (bordure
   #ffca28 pleine), « demain » (bordure or .35 + montant #ffd970 + pastille DEMAIN or) et le
   J7 lointain (opacité 1 + bordure or .45 au milieu de verrouillés à .45).
   RÈGLE POSÉE : l'or (#ffca28 / #ffd740) est RÉSERVÉ à la case réclamable MAINTENANT, la
   seule qui soit une ACTION. Les autres états sont de l'information et se taisent :
     réclamé  → vert éteint, coché, opacité .66      (état acquis, plus rien à y faire)
     demain   → neutre, opacité 1, montant lisible   (information, pas appel)
     plus tard→ verrouillé, opacité .45, désaturé
     J7       → teinte ambre discrète + libellé « final » ; son halo ne revient QUE le jour
                où il est lui-même réclamable. */

/* Validé : acquis, donc discret. Le ✓ vert suffit à dire « fait ». */
.dq-cell.dq-done{
  opacity: .66;
  border-color: rgba(0, 229, 170, .26);
  background: linear-gradient(160deg, rgba(0, 229, 170, .07), rgba(0, 0, 0, .16));
}
.dq-cell.dq-done .dq-day{ background: rgba(0, 229, 170, .12); color: #86bfab; }
.dq-cell.dq-done .dq-ico{ filter: none; }
.dq-cell.dq-done .dq-rw{ color: #86bfab; }
/* Aujourd'hui : LE point chaud — seule case dorée, seule surélevée, seule animée. */
.dq-cell.dq-today{
  border-color: #ffca28; transform: translateY(-3px) scale(1.06);
  background: linear-gradient(160deg, rgba(255, 202, 40, .24), rgba(255, 140, 0, .06));
  box-shadow: 0 6px 18px rgba(255, 160, 0, .28);
  animation: dqPulse 1.5s ease-in-out infinite;
}
.dq-cell.dq-today .dq-day{ background: #ffca28; color: #3a2600; }
.dq-cell.dq-today .dq-ico{ font-size: 1.65rem; }
.dq-cell.dq-today .dq-rw{ color: #ffca28; font-weight: 800; }
/* À venir : grisé/verrouillé */
.dq-cell.dq-soon{ opacity: .45; filter: grayscale(.35); }
@keyframes dqPulse{ 0%, 100% { box-shadow: 0 6px 18px rgba(255, 160, 0, .22); } 50% { box-shadow: 0 6px 26px rgba(255, 180, 0, .5); } }
/* DEMAIN (teaser) : seul futur dont le montant est annoncé. Pleinement LISIBLE (opacité 1,
   pas de désaturation) mais sans une trace d'or : c'est une information, pas une action. */
.dq-cell.dq-next{
  opacity: 1; filter: none;
  border-color: rgba(255, 255, 255, .18);
  background: linear-gradient(160deg, rgba(255, 255, 255, .06), rgba(0, 0, 0, .18));
}
.dq-cell.dq-next .dq-rw{ color: var(--text); }
/* Pastille de libellé (DEMAIN / FINAL) : neutre par défaut…
   📏 DIMENSIONNÉE POUR LE PLUS LONG LIBELLÉ, qui est l'anglais « TOMORROW ». La case fait
   66 px de large : avec l'ancien réglage (.58rem / interlettre .6 px / marge 7 px) la
   pastille mesurait 77,6 px et DÉBORDAIT hors de sa tuile — mesuré au navigateur ; défaut
   présent AVANT ce lot, corrigé ici parce qu'il touche la règle même qu'on retouche.
   Corps .5rem, interlettre .2 px, marge 5 px → « TOMORROW » = 62,3 px, soit 3,7 px de jeu.
   Les 4 langues mesurées à 1280 et 375 : demain 44,9 / tomorrow 62,3 / 明日 26,4 /
   demin 38,7 · final 35 / 最終日 34,6 — aucune ne déborde, aucune n'est tronquée.
   `display:inline-block` + `nowrap` : une seule ligne, jamais d'élargissement de la tuile.
   Toute nouvelle valeur de daily_tomorrow / daily_final doit être re-mesurée. */
.dq-sub{
  display: inline-block; white-space: nowrap;
  font-size: .5rem; font-weight: 800; letter-spacing: .2px; text-transform: uppercase;
  color: var(--text-dim); background: rgba(255, 255, 255, .08);
  padding: 1px 5px; border-radius: 999px;
}
/* …dorée UNIQUEMENT dans la case réclamable (cas du J7 quand c'est lui l'action du jour). */
.dq-cell.dq-today .dq-sub{ color: #ffca28; background: rgba(255, 202, 40, .16); }
/* SUSPENSE : montant masqué (« ? ») pour les jours au-delà de demain — muet, sans halo :
   un palier verrouillé ne doit pas se signaler (il était violet lumineux #b9a7e6). */
.dq-mask{
  display: inline-block; font-size: .92rem; font-weight: 900; color: var(--text-dim);
  text-shadow: none;
}
/* J7 = COFFRE MYSTÈRE, palier final du cycle. AU REPOS (ni aujourd'hui ni demain) il doit
   être RECONNAISSABLE sans être un appel : voile ambre à peine posé, pastille « FINAL »,
   « ??? » muet, ZÉRO halo, ZÉRO étoile, ZÉRO animation. Il était auparavant à opacité 1 avec
   une bordure or .45 au milieu de jours verrouillés à .45 — il sautait littéralement aux yeux
   (constaté à la mesure) et volait l'attention due au jour réclamable. */
.dq-cell.dq-gift7{
  opacity: .6; filter: none; overflow: visible;
  border-color: rgba(255, 215, 64, .2);
  background: linear-gradient(160deg, rgba(255, 215, 64, .05), rgba(0, 0, 0, .18));
}
.dq-cell.dq-gift7 .dq-ico{ font-size: 1.45rem; }
.dq-cell.dq-gift7 .dq-day{ background: rgba(255, 215, 64, .12); color: rgba(255, 224, 130, .72); }
.dq-mystery{ font-size: .92rem; font-weight: 900; color: var(--text-dim); letter-spacing: 2px; text-shadow: none; }
/* J7 = DEMAIN : lisible comme les autres « demain » (calme), mais il garde son voile ambre. */
.dq-cell.dq-next.dq-gift7{ opacity: .9; }
/* PLEIN ÉCLAT uniquement quand le coffre est LUI-MÊME réclamable : là, il EST l'action du
   jour — halo doré pulsé, « ??? » lumineux, étoiles. Aucun autre état n'y a droit. */
.dq-cell.dq-today.dq-gift7{
  opacity: 1;
  border-color: #ffd740;
  background: linear-gradient(160deg, rgba(255, 215, 64, .18), rgba(255, 140, 0, .05));
  animation: dqGiftGlow 1.2s ease-in-out infinite;
}
.dq-cell.dq-today .dq-mystery{ color: #ffd740; text-shadow: 0 0 10px rgba(255, 200, 40, .75); }
.dq-cell.dq-today.dq-gift7 .dq-ico{ font-size: 1.65rem; filter: drop-shadow(0 0 6px rgba(255, 215, 64, .65)); }
/* Petites étoiles scintillantes aux coins du coffre — SEULEMENT quand il est réclamable */
.dq-cell.dq-today.dq-gift7::before, .dq-cell.dq-today.dq-gift7::after{
  position: absolute; z-index: 2; font-size: .72rem; color: #ffe082; pointer-events: none;
  text-shadow: 0 0 6px rgba(255, 215, 64, .9);
  animation: dqStar 1.6s ease-in-out infinite;
}
.dq-cell.dq-today.dq-gift7::before{ content: '✦'; top: -6px; left: -5px; }
.dq-cell.dq-today.dq-gift7::after{ content: '✦'; bottom: -4px; right: -5px; animation-delay: .8s; }
@keyframes dqGiftGlow{
  0%, 100% { box-shadow: 0 0 10px rgba(255, 215, 64, .3), 0 0 22px rgba(255, 180, 0, .12); }
  50% { box-shadow: 0 0 18px rgba(255, 215, 64, .6), 0 0 34px rgba(255, 180, 0, .3); }
}
@keyframes dqStar{ 0%, 100% { opacity: .35; transform: scale(.8) rotate(0deg); } 50% { opacity: 1; transform: scale(1.15) rotate(18deg); } }
/* PERF / accessibilité : on fige les pulsations du planning daily (dqPulse/dqGiftGlow/dqStar)
   quand l'utilisateur préfère moins d'animations OU sur mobile/tactile (états visuels conservés). */
@media (prefers-reduced-motion: reduce), (hover: none), (max-width: 820px){
  .dq-cell.dq-today, .dq-cell.dq-today.dq-gift7, .dq-cell.dq-today.dq-gift7::before, .dq-cell.dq-today.dq-gift7::after{ animation: none; }
}
/* Compteur de série : information, pas appel — il était en orange gras 1.05rem juste sous la
   barre et rivalisait de teinte avec la case dorée. Neutralisé ; le 🔥 porte la chaleur. */
.dq-streak{ text-align: center; font-weight: 700; color: var(--text-dim); font-size: .95rem; margin: 8px 0 2px; }

/* --- Bouton « Relâcher » (détail d'une carte) --- */
.cd-release-wrap{
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  text-align: center;
}
.cd-release-btn{
  background: linear-gradient(135deg, var(--neon-purple), var(--neon-1));
  box-shadow: 0 6px 20px rgba(177, 77, 255, .35);
  color: #fff;
  font-weight: 700;
}
.cd-release-btn:hover{ filter: brightness(1.1); box-shadow: 0 8px 26px rgba(0, 229, 255, .5); }
.cd-release-btn:disabled{ opacity: .5; cursor: not-allowed; box-shadow: none; }
.cd-release-result{ margin-top: 10px; }

/* Mobile : la notif flottante reste lisible, sans animation coûteuse */
@media (max-width: 820px){
  .points-gain{ animation-duration: 1.4s; }
}

/* ============================================================
   COMBAT TEMPS RÉEL (Phase 3) — recherche / invitations / lobby
   Thème : cyan #00e5ff · violet #b14dff
   ============================================================ */

/* Badge "Défis" qui pulse quand il y a des invitations */
.btn-action.has-invites{
  border-color: var(--neon-purple);
  box-shadow: 0 0 0 1px var(--neon-purple), 0 0 14px rgba(177, 77, 255, .35);
  animation: rtInvitePulse 1.6s ease-in-out infinite;
}
@keyframes rtInvitePulse{
  0%, 100% { box-shadow: 0 0 0 1px var(--neon-purple), 0 0 10px rgba(177, 77, 255, .30); }
  50%      { box-shadow: 0 0 0 1px var(--neon-purple), 0 0 20px rgba(177, 77, 255, .55); }
}

/* --- Écran d'attente / recherche --- */
.rt-wait{
  text-align: center;
  padding: 18px 8px 6px;
}
.rt-wait-title{
  font-weight: 700;
  font-size: 1.05rem;
  margin: 14px 0 4px;
  color: var(--text);
}
.rt-wait-sub{
  color: var(--text-dim);
  font-size: .92rem;
  margin: 2px 0;
}

/* Spinner néon */
.rt-spinner{
  width: 54px;
  height: 54px;
  margin: 6px auto 0;
  border-radius: 50%;
  border: 4px solid rgba(0, 229, 255, .15);
  border-top-color: var(--neon-1);
  border-right-color: var(--neon-purple);
  animation: rtSpin .9s linear infinite;
}
@keyframes rtSpin{ to { transform: rotate(360deg); } }

/* --- Invitations entrantes (modale "Défis") --- */
.rt-invites{ display: flex; flex-direction: column; gap: 10px; }
.rt-invite{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--neon-purple);
  border-radius: var(--radius-sm);
}
.rt-invite-txt{ font-size: .98rem; }
.rt-invite-actions{ display: flex; gap: 8px; flex-shrink: 0; }
.rt-invite-actions .btn{ padding: 7px 12px; }

/* --- Salon de combat (lobby) --- */
.rt-lobby-head{
  background: linear-gradient(135deg, rgba(0, 229, 255, .08), rgba(177, 77, 255, .08));
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-bottom: 12px;
}
.rt-opp{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 1.05rem;
}
.rt-opp-vs{
  font-weight: 900;
  color: var(--neon-1);
  letter-spacing: 1px;
}
.rt-dot{ font-size: .85rem; font-weight: 600; }
.rt-dot.rt-on{ color: #5cf08a; }
.rt-dot.rt-off{ color: #ff6b6b; }

.rt-ready-line{
  display: flex;
  gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
}
.rt-badge{
  font-size: .85rem;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
}
.rt-badge.on{ color: #5cf08a; border-color: rgba(92, 240, 138, .5); background: rgba(92, 240, 138, .10); }
.rt-badge.off{ color: var(--text-dim); }

/* Équipe verrouillée après "Je suis prêt" */
.rt-locked{
  text-align: center;
  padding: 18px 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.rt-locked-title{ font-weight: 700; color: #5cf08a; font-size: 1.05rem; margin: 0 0 4px; }
.rt-hidden-note{ margin-top: 10px; font-size: .85rem; color: var(--text-faint); }

/* Placeholder "combat actif" (le plateau arrive plus tard) */
.rt-active{
  text-align: center;
  padding: 26px 12px 10px;
  background: radial-gradient(ellipse at top, rgba(177, 77, 255, .12), transparent 70%);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.rt-active-icon{
  font-size: 3rem;
  filter: drop-shadow(0 0 14px rgba(0, 229, 255, .55));
  animation: rtClash 1.2s ease-in-out infinite;
}
@keyframes rtClash{
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}
.rt-active-title{ font-weight: 800; font-size: 1.1rem; margin: 12px 0 4px; color: var(--text); }

/* Combat annulé / terminé */
.rt-ended{ text-align: center; padding: 22px 12px 8px; }
.rt-ended-msg{ font-size: 1.02rem; color: var(--text); margin-bottom: 6px; }

/* Mobile */
@media (max-width: 560px){
  .rt-invite{ flex-direction: column; align-items: stretch; }
  .rt-invite-actions{ justify-content: stretch; }
  .rt-invite-actions .btn{ flex: 1; }
  .rt-active-icon{ font-size: 2.4rem; }
}

/* ============================================================
   PLATEAU DE COMBAT TEMPS RÉEL (Phase 3 — étape 2)
   Thème cyan #00e5ff / violet #b14dff, sombre, fluide.
   ============================================================ */

/* Modale élargie pour le plateau */
.modal.modal-board{ max-width: 920px; }
.modal.modal-board .modal-body{ padding: 14px; }

.bb{
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(177, 77, 255, .14), transparent 60%),
    radial-gradient(120% 70% at 50% 110%, rgba(0, 229, 255, .14), transparent 60%),
    linear-gradient(180deg, #0a0e1c, #0c1326 55%, #0a0e1c);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  overflow: hidden;
}

.bb-side{ display: flex; flex-direction: column; gap: 6px; }
.bb-enemy{ padding-bottom: 2px; }
.bb-me{ padding-top: 2px; }

.bb-side-head{ display: flex; }
.bb-enemy .bb-side-head{ justify-content: flex-start; }
.bb-me .bb-side-head{ justify-content: flex-end; }
.bb-tag{
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-ui); font-weight: 700; font-size: .82rem;
  padding: 4px 12px; border-radius: 999px; letter-spacing: .04em;
}
.bb-tag-enemy{ background: rgba(255, 77, 141, .16); color: #ff8bb3; border: 1px solid rgba(255, 77, 141, .4); }
.bb-tag-me{ background: rgba(0, 229, 255, .14); color: var(--neon-1); border: 1px solid rgba(0, 229, 255, .42); }

/* Badge "outsider" (boost de l'équipe la plus faible) près du tag de camp */
.bb-underdog{
  display: inline-flex; align-items: center; gap: 3px; margin-left: 8px;
  font-family: var(--font-ui); font-weight: 700; font-size: .74rem;
  padding: 3px 10px; border-radius: 999px; cursor: help;
  background: rgba(255, 145, 0, .14); color: #ffb74d; border: 1px solid rgba(255, 145, 0, .45);
  text-shadow: 0 0 8px rgba(255, 145, 0, .5);
}

/* Rangée : banc d'un côté, actif au centre */
.bb-rowwrap{
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
}
.bb-enemy .bb-rowwrap{ grid-template-columns: 1fr auto; }   /* banc à gauche, actif centre-droit */
.bb-me .bb-rowwrap{ grid-template-columns: auto 1fr; }       /* actif, puis banc à droite */
.bb-active-slot{ display: flex; justify-content: center; }
.bb-bench{ display: flex; gap: 8px; flex-wrap: wrap; }
.bb-bench-enemy{ justify-content: flex-start; }
.bb-bench-me{ justify-content: flex-end; }

/* ---- Carte ---- */
.bb-card{
  position: relative;
  border-radius: 14px;
  background:
    radial-gradient(120% 80% at 50% 0%, color-mix(in srgb, var(--rc, #888) 22%, transparent), transparent 62%),
    linear-gradient(160deg, color-mix(in srgb, var(--rc, #888) 14%, #161e3a), #101630);
  border: 1px solid color-mix(in srgb, var(--rc, #888) 45%, transparent);
  box-shadow: var(--aura, 0 0 0 1px color-mix(in srgb, var(--rc, #888) 35%, transparent)), 0 8px 22px -10px #000;
  display: flex; flex-direction: column; align-items: center;
  padding: 7px 7px 8px;
  transition: transform .18s ease, box-shadow .18s ease, opacity .35s ease;
}
.bb-big{ width: 188px; }
.bb-small{ width: 86px; padding: 5px; }

.bb-art-wrap{
  position: relative; width: 100%; aspect-ratio: 1/1;
  border-radius: 10px; overflow: hidden;
  background: linear-gradient(135deg, #182038, #0e1424);
}
.bb-art{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.bb-art-fallback{
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-weight: 800; font-size: 2rem;
  color: color-mix(in srgb, var(--rc, #888) 70%, var(--text-faint));
}
.bb-small .bb-art-fallback{ font-size: 1.3rem; }

.bb-name{
  margin-top: 5px; font-weight: 700; font-size: .9rem; color: var(--text);
  text-align: center; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bb-small .bb-name{ font-size: .72rem; }
.bb-meta{ font-size: .72rem; color: var(--text-dim); margin-top: 1px; text-align: center; }

.bb-crown{
  position: absolute; top: -10px; left: 50%; transform: translateX(-50%);
  font-size: 1.15rem; filter: drop-shadow(0 0 6px rgba(255, 200, 60, .8)); z-index: 3;
}
.bb-small .bb-crown{ font-size: .9rem; top: -8px; }
/* Chef provisoire : astérisque discret accolé à la couronne */
.bb-crown-prov{ cursor: help; }
.bb-prov-star{
  font-style: normal; font-weight: 800; font-size: .8em;
  color: #ffd54f; text-shadow: 0 0 6px rgba(255, 200, 60, .9);
  vertical-align: super;
}
.bb-evo{
  position: absolute; top: 4px; right: 5px; font-size: .95rem; color: var(--neon-1);
  text-shadow: 0 0 8px var(--neon-1); z-index: 3;
}

/* HP bar */
.bb-hpbar{
  position: relative; width: 100%; height: 11px; margin-top: 6px;
  background: rgba(0, 0, 0, .55); border-radius: 999px; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .08);
}
.bb-small .bb-hpbar{ height: 7px; margin-top: 4px; }
.bb-hpfill{
  height: 100%; border-radius: 999px;
  transition: width .55s cubic-bezier(.4, 0, .2, 1), background .3s;
}
.bb-hpfill.high{ background: linear-gradient(90deg, #00e5ff, #5cf08a); }
.bb-hpfill.mid{ background: linear-gradient(90deg, #ffb347, #ffd966); }
.bb-hpfill.low{ background: linear-gradient(90deg, #f44336, #ff8a65); }
.bb-hptxt{
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: .62rem; font-weight: 700; color: #fff; text-shadow: 0 1px 2px #000; letter-spacing: .03em;
}

.bb-status{ display: flex; gap: 3px; min-height: 16px; margin-top: 3px; }
.bb-st{ font-size: .85rem; line-height: 1; filter: drop-shadow(0 0 3px rgba(0,0,0,.6)); }
.bb-small .bb-st{ font-size: .72rem; }

/* Carte face cachée (dos) */
.bb-back{
  background:
    repeating-linear-gradient(45deg, rgba(177, 77, 255, .22) 0 8px, transparent 8px 16px),
    linear-gradient(160deg, #262e5c, #131938);
  border: 1px solid rgba(195, 120, 255, .55);
  box-shadow: inset 0 0 26px -6px var(--neon-purple), 0 8px 22px -10px #000;
}
.bb-back-inner{
  width: 100%; aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center;
  position: relative;
}
.bb-back-mark{ font-size: 2rem; color: var(--neon-purple); opacity: .65; text-shadow: 0 0 14px var(--neon-purple); }
.bb-small .bb-back-mark{ font-size: 1.3rem; }
.bb-back-chef{ position: absolute; top: -8px; left: 50%; transform: translateX(-50%); font-size: 1rem; filter: drop-shadow(0 0 6px rgba(255,200,60,.8)); }

/* Carte K.O. */
.bb-faint{ opacity: .42; filter: grayscale(.85); }
.bb-faint .bb-name::after{ content: ' 💀'; }

/* ---- Bannière de tour ---- */
.bb-banner{
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 8px 14px; border-radius: 999px; margin: 2px auto; min-width: 60%;
  font-family: var(--font-ui); font-weight: 700; font-size: .92rem;
  text-align: center; transition: background .3s, color .3s, box-shadow .3s;
  border: 1px solid var(--border);
}
.bb-banner-mine{
  background: linear-gradient(90deg, rgba(0,229,255,.18), rgba(0,229,255,.06));
  color: var(--neon-1); border-color: rgba(0,229,255,.5);
  box-shadow: 0 0 22px -6px rgba(0,229,255,.55);
  animation: bbBannerPulse 1.8s ease-in-out infinite;
}
.bb-banner-their{
  background: rgba(177,77,255,.1); color: #cba6ff; border-color: rgba(177,77,255,.4);
}
.bb-banner-neutral{ background: var(--surface-2); color: var(--text-dim); }
/* Mort subite : flash de l'event (≈1.2 s) joué par bbPlayEvent */
.bb-banner-sd{
  background: linear-gradient(90deg, rgba(255,193,7,.25), rgba(255,87,34,.18));
  color: #ffd54f; border-color: rgba(255,193,7,.6);
  animation: bbSdFlash .3s ease-in-out 4 alternate;
}
@keyframes bbSdFlash{
  from { box-shadow: 0 0 14px -6px rgba(255,193,7,.4); }
  to   { box-shadow: 0 0 36px -2px rgba(255,193,7,.9); }
}
/* Mort subite : indicateur permanent dans la bannière de tour */
.bb-sd-tag{
  font-size: .72rem; letter-spacing: .06em; white-space: nowrap;
  padding: 2px 8px; border-radius: 999px;
  background: rgba(255,193,7,.16); color: #ffd54f; border: 1px solid rgba(255,193,7,.45);
}
.bb-turnnum{
  font-size: .72rem; color: var(--text-faint); letter-spacing: .08em;
  padding: 2px 8px; border-radius: 999px; background: rgba(0,0,0,.3);
}
@keyframes bbBannerPulse{
  0%, 100% { box-shadow: 0 0 22px -8px rgba(0,229,255,.5); }
  50%      { box-shadow: 0 0 34px -4px rgba(0,229,255,.75); }
}

/* ---- Contrôles d'action ---- */
.bb-actions{
  display: flex; flex-direction: column; gap: 10px; align-items: center;
  margin-top: 4px; min-height: 8px;
}
.bb-actions-empty{ min-height: 0; }
.bb-target-chef{
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font-size: .85rem; color: #ffcc80; margin-bottom: 8px;
  padding: 5px 12px; border-radius: 18px;
  background: rgba(255,152,0,.10); border: 1px solid rgba(255,152,0,.32);
}
.bb-target-chef input{ accent-color: #ff9800; cursor: pointer; }
.bb-atk-row{ display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; width: 100%; }
.bb-atk{
  flex: 1 1 200px; max-width: 320px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  text-align: left; padding: 10px 14px; cursor: pointer;
  background: linear-gradient(135deg, color-mix(in srgb, var(--el, var(--neon-1)) 32%, #16203c), #111a32);
  border: 1px solid color-mix(in srgb, var(--el, var(--neon-1)) 70%, transparent);
  border-radius: var(--radius-sm); color: var(--text);
  transition: transform .14s, box-shadow .18s, filter .15s;
}
.bb-atk:hover:not(:disabled){
  transform: translateY(-2px);
  box-shadow: 0 8px 24px -8px color-mix(in srgb, var(--el, var(--neon-1)) 70%, transparent);
  filter: brightness(1.08);
}
.bb-atk:disabled{ opacity: .5; cursor: default; }
.bb-atk-name{ font-weight: 800; font-size: .98rem; font-family: var(--font-ui); }
.bb-atk-line{ font-size: .8rem; color: var(--text-dim); }
.bb-atk-eff{ font-size: .74rem; color: color-mix(in srgb, var(--el, var(--neon-1)) 80%, #fff); }

/* ===== Refonte combat « Rotation & Élan » : barre d'Élan, Ultime, réactions ===== */
.bb-elan{ display: flex; align-items: center; gap: 8px; width: 100%; max-width: 420px; }
.bb-elan-label{ font-size: .78rem; font-weight: 800; color: #ffd76a; white-space: nowrap; }
.bb-elan-track{ flex: 1; height: 9px; border-radius: 99px; background: rgba(255,255,255,.10); overflow: hidden; border: 1px solid rgba(255,215,106,.25); }
.bb-elan-fill{ height: 100%; border-radius: 99px; background: linear-gradient(90deg, #7a5cff, #ffd76a); transition: width .35s ease; }
.bb-elan-pct{ font-size: .72rem; color: var(--text-dim); min-width: 30px; text-align: right; }
.bb-elan-ready{ font-size: .72rem; font-weight: 800; color: #ffd76a; text-shadow: 0 0 8px #ffd76a; animation: bbElanPulse 1s ease-in-out infinite; }
.bb-elan-full .bb-elan-fill{ background: linear-gradient(90deg, #ffd76a, #fff3b0, #ffd76a); }
@keyframes bbElanPulse{ 0%,100% { opacity: 1; } 50% { opacity: .45; } }
.bb-ult{
  width: 100%; max-width: 420px; padding: 11px 16px; cursor: pointer; font-weight: 900; letter-spacing: 1px;
  font-family: var(--font-ui); color: #3a2a00;
  background: linear-gradient(135deg, #ffe07a, #ffb300, #ffe07a); border: 1px solid #fff3b0;
  border-radius: var(--radius-sm); box-shadow: 0 0 22px -4px rgba(255,193,0,.7);
  animation: bbUltGlow 1.1s ease-in-out infinite;
}
.bb-ult:hover:not(:disabled){ filter: brightness(1.08); transform: translateY(-2px); }
.bb-ult:disabled{ opacity: .55; cursor: default; animation: none; }
@keyframes bbUltGlow{ 0%,100% { box-shadow: 0 0 18px -6px rgba(255,193,0,.6); } 50% { box-shadow: 0 0 30px 0 rgba(255,193,0,.85); } }
.bb-atk-reacready{ border-color: #ffd76a; box-shadow: 0 0 16px -4px rgba(255,215,106,.65); }
.bb-atk-reac{ font-size: .72rem; font-weight: 800; color: #ffe7a0; }
.bb-st-mark{ color: var(--el, #fff); text-shadow: 0 0 6px var(--el, #fff); }
.bb-reaction{ font-weight: 900; font-size: 1.05rem; color: #fff3b0; text-shadow: 0 0 10px #ffd76a, 0 0 4px #fff; letter-spacing: .5px; }

/* Indice "switch volontaire" sous les attaques */
.bb-switch-hint{ font-size: .78rem; color: var(--text-dim); text-align: center; }

/* Sbire du banc cliquable (switch volontaire) : curseur + léger halo */
.bb-card.bb-switchable{
  cursor: pointer;
  box-shadow: 0 0 12px -4px rgba(0, 229, 255, .5), 0 8px 22px -10px #000;
}
.bb-card.bb-switchable:hover{
  transform: translateY(-3px);
  box-shadow: 0 0 18px -2px rgba(0, 229, 255, .65), 0 8px 22px -10px #000;
  border-color: rgba(0, 229, 255, .7);
}

/* Carte qui entre en jeu après un switch (slide + flip réutilisé) */
.bb-switch-in{ animation: bbSwitchIn .6s ease; z-index: 4; }
@keyframes bbSwitchIn{
  0%   { transform: translateY(14px) scale(.92); opacity: .4; }
  60%  { transform: translateY(-4px) scale(1.04); opacity: 1; }
  100% { transform: translateY(0) scale(1); }
}
.bb-float-switch .bb-eff, .bb-float-switch .bb-tag-txt{ color: var(--neon-1); }
.bb-float-switch .bb-tag-txt{ font-size: .72rem; }
.bb-forfeit{ font-size: .85rem; padding: 6px 16px; }
.bb-forfeit-confirm{ background: rgba(244, 67, 54, .18); color: #ff8a80; border-color: rgba(244,67,54,.5); }

/* ---- Effets flottants ---- */
.bb-fx{ position: absolute; inset: 0; pointer-events: none; overflow: visible; z-index: 6; }
.bb-float{
  position: absolute; left: 50%; top: 30%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  font-family: var(--font-ui); font-weight: 800; white-space: nowrap;
  text-shadow: 0 2px 6px #000; animation: bbFloatUp 1.15s ease-out forwards;
}
@keyframes bbFloatUp{
  0%   { opacity: 0; transform: translate(-50%, 8px) scale(.85); }
  18%  { opacity: 1; transform: translate(-50%, -6px) scale(1.08); }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -34px) scale(1); }
}
.bb-dmg{ color: #ff6b6b; font-size: 1.4rem; }
.bb-dmg.big{ font-size: 1.9rem; }
.bb-float-crit .bb-crit{ color: #ffd54f; font-size: .8rem; letter-spacing: .06em; }
.bb-float-crit .bb-dmg{ color: #ff5252; }
.bb-adv{ font-size: .68rem; padding: 1px 6px; border-radius: 999px; }
.bb-adv.up{ color: #5cf08a; background: rgba(92,240,138,.16); }
.bb-adv.down{ color: #9aa6c9; background: rgba(154,166,201,.14); }
.bb-eff{ font-size: 1.6rem; }
.bb-float-heal .bb-eff, .bb-float-heal .bb-tag-txt{ color: #5cf08a; }
.bb-float-burn .bb-dmg{ color: #ff8a65; }
.bb-float-stun .bb-tag-txt, .bb-float-heal .bb-tag-txt{ font-size: .72rem; color: var(--text); }
.bb-ko{ color: #ff5252; font-size: 1.5rem; letter-spacing: .08em; }

/* ---- Animations de carte ---- */
.bb-lunge-down{ animation: bbLungeDown .42s ease; z-index: 5; }
.bb-lunge-up{ animation: bbLungeUp .42s ease; z-index: 5; }
@keyframes bbLungeDown{
  0% { transform: translateY(0); } 45% { transform: translateY(26px) scale(1.05); } 100% { transform: translateY(0); }
}
@keyframes bbLungeUp{
  0% { transform: translateY(0); } 45% { transform: translateY(-26px) scale(1.05); } 100% { transform: translateY(0); }
}
.bb-hit{ animation: bbHit .38s ease; }
@keyframes bbHit{
  0%, 100% { transform: translateX(0); filter: none; }
  20% { transform: translateX(-7px); filter: brightness(1.7) drop-shadow(0 0 10px #fff); }
  40% { transform: translateX(7px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
.bb-fainting{ animation: bbFaint .75s ease forwards; }
@keyframes bbFaint{
  0% { opacity: 1; transform: translateY(0) rotate(0); }
  100% { opacity: .42; transform: translateY(16px) rotate(5deg); }
}
.bb-flip{ animation: bbFlip .6s ease; }
@keyframes bbFlip{
  0% { transform: rotateY(0); }
  50% { transform: rotateY(90deg) scale(1.04); }
  100% { transform: rotateY(0); }
}
.bb-revive{ animation: bbRevive .9s ease; }
@keyframes bbRevive{
  0% { box-shadow: 0 0 0 0 rgba(92,240,138,0); }
  40% { box-shadow: 0 0 30px -4px rgba(92,240,138,.9); }
  100% { box-shadow: var(--aura, none); }
}

/* ============================================================
   POLISH COMBAT (additif) — game-feel « jeu de cartes »
   ============================================================ */

/* Carte ACTIVE (grand format) : aura colorée par l'élément + légère respiration. */
.bb-big:not(.bb-faint){
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--el, var(--rc, #888)) 70%, transparent),
    0 0 26px -6px color-mix(in srgb, var(--el, var(--rc, #888)) 80%, transparent),
    0 10px 26px -10px #000;
  animation: bbActiveBreath 2.6s ease-in-out infinite;
}
@keyframes bbActiveBreath{
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}
.bb-big:not(.bb-faint) .bb-art-wrap::after{
  /* Reflet « holographique » discret qui glisse sur l'art de la carte active. */
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255,255,255,.16) 50%, transparent 62%);
  background-size: 240% 240%; animation: bbHolo 3.4s linear infinite;
}
@keyframes bbHolo{ 0% { background-position: 120% 0; } 100% { background-position: -120% 0; } }

/* CHEF : cadre doré (anneau or) pour bien le distinguer des sbires. */
.bb-card:has(> .bb-crown){
  border-color: rgba(255, 205, 90, .7);
  box-shadow:
    0 0 0 2px rgba(255, 205, 90, .55),
    0 0 22px -6px rgba(255, 205, 90, .65),
    0 8px 22px -10px #000;
}
.bb-big:has(> .bb-crown):not(.bb-faint){
  box-shadow:
    0 0 0 2px rgba(255, 205, 90, .85),
    0 0 30px -5px rgba(255, 205, 90, .8),
    0 10px 26px -10px #000;
}

/* Barre de PV : brillance qui glisse + pulsation rouge quand bas. */
.bb-hpfill{ position: relative; overflow: hidden; }
.bb-hpfill::after{
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.35) 50%, transparent 70%);
  background-size: 200% 100%; animation: bbHpShine 2.8s linear infinite;
}
@keyframes bbHpShine{ 0% { background-position: 120% 0; } 100% { background-position: -120% 0; } }
.bb-hpfill.low{ animation: bbLowPulse 1s ease-in-out infinite; }
@keyframes bbLowPulse{ 0%, 100% { filter: none; } 50% { filter: brightness(1.35); } }

/* Impact plus punchy : léger tremblement du plateau quand une carte encaisse. */
.bb-card.bb-hit::before{
  content: ''; position: absolute; inset: 0; z-index: 6; border-radius: inherit;
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.55), transparent 60%);
  animation: bbImpactFlash .38s ease-out forwards; pointer-events: none;
}
@keyframes bbImpactFlash{ 0% { opacity: .9; transform: scale(.6); } 100% { opacity: 0; transform: scale(1.25); } }

@media (prefers-reduced-motion: reduce){
  .bb-big:not(.bb-faint), .bb-big:not(.bb-faint) .bb-art-wrap::after, .bb-hpfill::after, .bb-hpfill.low, .bb-card.bb-hit::before{ animation: none; }
}

/* ---- Overlay de fin ---- */
.bb-overlay{
  position: absolute; inset: 0; z-index: 20;
  display: flex; align-items: center; justify-content: center;
  background: rgba(4, 7, 16, .82); backdrop-filter: blur(4px);
  animation: fadeIn .25s ease; border-radius: var(--radius);
}
/* CRITIQUE : `display:flex` ci-dessus écrase l'attribut hidden (règle UA display:none
   de spécificité moindre) → sans ceci, le voile de fin assombrit TOUT le combat. */
.bb-overlay[hidden]{ display: none; }
.bb-end-card{
  position: relative; text-align: center; padding: 30px 34px;
  border-radius: var(--radius); min-width: 260px;
  background: linear-gradient(160deg, #131a30, #0c1224);
  border: 1px solid var(--border); box-shadow: var(--shadow);
  animation: popIn .3s ease;
}
.bb-overlay-win .bb-end-card{ border-color: rgba(255,200,60,.55); box-shadow: 0 0 60px -10px rgba(255,200,60,.6); }
.bb-overlay-lose .bb-end-card{ border-color: rgba(244,67,54,.5); }
.bb-end-title{ font-family: var(--font-ui); font-weight: 800; font-size: 2rem; margin-bottom: 8px; }
.bb-overlay-win .bb-end-title{
  color: #ffd54f; text-shadow: 0 0 24px rgba(255,200,60,.7);
  animation: bbWinPulse 1.4s ease-in-out infinite;
}
.bb-overlay-lose .bb-end-title{ color: #ff6b6b; }
.bb-overlay-draw .bb-end-title{ color: var(--text-dim); }
.bb-overlay-cancel .bb-end-title{ color: #ffb347; font-size: 1.5rem; }
@keyframes bbWinPulse{
  0%, 100% { transform: scale(1); text-shadow: 0 0 24px rgba(255,200,60,.6); }
  50% { transform: scale(1.06); text-shadow: 0 0 40px rgba(255,200,60,.9); }
}
.bb-end-sub{ color: var(--text-dim); margin-bottom: 18px; }
.bb-confetti{
  position: absolute; inset: -40px; pointer-events: none;
  background:
    radial-gradient(circle at 20% 10%, #ffd54f 0 3px, transparent 4px),
    radial-gradient(circle at 80% 20%, var(--neon-1) 0 3px, transparent 4px),
    radial-gradient(circle at 50% 5%, var(--neon-purple) 0 3px, transparent 4px),
    radial-gradient(circle at 35% 30%, #5cf08a 0 3px, transparent 4px),
    radial-gradient(circle at 70% 40%, #ff8bb3 0 3px, transparent 4px);
  animation: bbConfetti 1.6s ease-out infinite;
  opacity: .8;
}
@keyframes bbConfetti{
  0% { transform: translateY(-20px); opacity: 0; }
  30% { opacity: .9; }
  100% { transform: translateY(60px); opacity: 0; }
}

/* ---- Toast ---- */
.bb-toast{
  position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%) translateY(10px);
  z-index: 18; padding: 9px 18px; border-radius: 999px;
  background: rgba(244, 67, 54, .92); color: #fff; font-weight: 700; font-size: .85rem;
  box-shadow: 0 8px 24px -8px #000; opacity: 0; pointer-events: none;
  transition: opacity .2s, transform .2s;
}
.bb-toast.show{ opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---- Mobile ---- */
@media (max-width: 760px){
  .modal.modal-board{ max-width: 100%; }
  .bb-big{ width: 150px; }
  .bb-small{ width: 70px; }
  .bb-atk{ flex: 1 1 100%; }
}
@media (max-width: 560px){
  .bb{ padding: 8px; gap: 6px; }
  .bb-rowwrap, .bb-enemy .bb-rowwrap, .bb-me .bb-rowwrap{
    grid-template-columns: 1fr; justify-items: center; gap: 6px;
  }
  /* Ordre : actif d'abord, banc ensuite, en colonne */
  .bb-enemy .bb-active-slot{ order: 1; }
  .bb-enemy .bb-bench{ order: 2; }
  .bb-me .bb-active-slot{ order: 1; }
  .bb-me .bb-bench{ order: 2; }
  .bb-bench-enemy, .bb-bench-me{ justify-content: center; }
  .bb-big{ width: 130px; }
  .bb-small{ width: 62px; }
  .bb-small .bb-name{ font-size: .64rem; }
  .bb-banner{ font-size: .8rem; min-width: 100%; padding: 7px 10px; }
  .bb-end-title{ font-size: 1.6rem; }
}

/* Réduit les animations si demandé */
@media (prefers-reduced-motion: reduce){
  .bb-banner-mine, .bb-overlay-win .bb-end-title, .bb-confetti, .bb-lunge-up, .bb-lunge-down, .bb-hit, .bb-flip, .bb-revive, .bb-fainting, .bb-switch-in, .bb-banner-sd{ animation: none; }
}

/* ============================================================
   SPECTACLE COMBAT (additif) — arène, impacts élémentaires,
   ghost HP, screen-shake, écrans de fin "juteux".
   ============================================================ */

/* ---- 1. Arène : profondeur, étoiles, ligne d'horizon ---- */
.bb{
  background:
    radial-gradient(95% 55% at 50% -8%, rgba(177, 77, 255, .3), transparent 64%),
    radial-gradient(95% 55% at 50% 108%, rgba(0, 229, 255, .24), transparent 64%),
    radial-gradient(140% 95% at 50% 50%, #182347 0%, #101631 62%, #0b0f20 100%);
  border-color: rgba(140, 105, 245, .45);
  box-shadow: inset 0 0 80px -22px rgba(110, 65, 220, .6), 0 10px 40px -18px #000;
}
.bb-arena{ position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; border-radius: inherit; }
.bb-side, .bb-banner, .bb-actions{ position: relative; z-index: 1; }

/* Étoiles : deux nappes de particules qui dérivent (transform only). */
.bb-stars{
  position: absolute; left: 0; right: 0; top: -240px; bottom: 0;
  background-image:
    radial-gradient(2.2px 2.2px at 22% 31%, rgba(255, 255, 255, .95), transparent 100%),
    radial-gradient(1.6px 1.6px at 71% 62%, rgba(0, 229, 255, .95), transparent 100%),
    radial-gradient(2px 2px at 46% 82%, rgba(195, 120, 255, .95), transparent 100%),
    radial-gradient(1.5px 1.5px at 86% 14%, rgba(255, 255, 255, .7), transparent 100%),
    radial-gradient(2px 2px at 9% 71%, rgba(255, 255, 255, .55), transparent 100%),
    radial-gradient(1.5px 1.5px at 58% 8%, rgba(0, 229, 255, .65), transparent 100%);
  background-size: 220px 220px;
  opacity: .85;
  animation: bbStarDrift 70s linear infinite;
}
.bb-stars2{
  background-size: 340px 340px;
  opacity: .55;
  animation: bbStarDrift2 110s linear infinite;
}
@keyframes bbStarDrift{ from { transform: translateY(-220px); } to { transform: translateY(0); } }
@keyframes bbStarDrift2{ from { transform: translateY(-340px); } to { transform: translateY(0); } }

/* Ligne d'horizon lumineuse entre les deux camps. */
.bb-horizon{
  position: absolute; left: 3%; right: 3%; top: 50%; height: 2px;
  background: linear-gradient(90deg,
    transparent, rgba(0, 229, 255, .8) 18%, rgba(205, 140, 255, 1) 50%,
    rgba(0, 229, 255, .8) 82%, transparent);
  box-shadow: 0 0 22px 3px rgba(150, 115, 255, .65);
  opacity: .95;
}
.bb-horizon::after{
  content: ''; position: absolute; left: 6%; right: 6%; top: -20px; height: 42px;
  background: radial-gradient(50% 100% at 50% 50%, rgba(150, 125, 255, .28), transparent 74%);
}

/* ---- 2. Cartes : relief, halo de rareté, liseré de tour, ghost HP ---- */
.bb-card{
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .06) inset,
    0 0 0 1px color-mix(in srgb, var(--rc, #888) 35%, transparent),
    0 6px 14px -6px rgba(0, 0, 0, .8),
    0 14px 34px -14px #000;
}

/* Halo de rareté derrière la carte ACTIVE (z-index:-1 dans la carte). */
.bb-big:not(.bb-faint):not(.bb-back)::after{
  content: ''; position: absolute; inset: -26px -22px; z-index: -1;
  border-radius: 38px; pointer-events: none;
  background: radial-gradient(55% 55% at 50% 50%,
    color-mix(in srgb, var(--rc, #8a7cff) 50%, transparent), transparent 72%);
  opacity: .5;
  animation: bbHaloPulse 3.2s ease-in-out infinite;
}
@keyframes bbHaloPulse{
  0%, 100% { opacity: .38; transform: scale(.96); }
  50%      { opacity: .65; transform: scale(1.05); }
}

/* Carte dont c'est le TOUR : bordure néon pulsée (couleur de rareté). */
.bb-card.bb-turn{
  border-color: color-mix(in srgb, var(--rc, #00e5ff) 80%, #fff);
}
.bb-card.bb-turn .bb-art-wrap::before{
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  border-radius: inherit;
  box-shadow: inset 0 0 18px -6px color-mix(in srgb, var(--rc, #00e5ff) 90%, #fff);
  animation: bbTurnInner 1.6s ease-in-out infinite;
}
@keyframes bbTurnInner{ 0%, 100% { opacity: .35; } 50% { opacity: .9; } }
.bb-big.bb-turn:not(.bb-faint){
  animation: bbActiveBreath 2.6s ease-in-out infinite, bbTurnPulse 1.6s ease-in-out infinite;
}
@keyframes bbTurnPulse{
  0%, 100% {
    box-shadow:
      0 0 0 2px color-mix(in srgb, var(--rc, #00e5ff) 75%, transparent),
      0 0 20px -4px color-mix(in srgb, var(--rc, #00e5ff) 85%, transparent),
      0 10px 26px -10px #000;
  }
  50% {
    box-shadow:
      0 0 0 3px color-mix(in srgb, var(--rc, #00e5ff) 95%, #fff),
      0 0 38px -2px color-mix(in srgb, var(--rc, #00e5ff) 95%, transparent),
      0 10px 26px -10px #000;
  }
}

/* Ghost HP : barre blanche qui se vide "en retard" derrière le fill. */
.bb-hpghost{
  position: absolute; left: 0; top: 0; bottom: 0; width: 0;
  background: rgba(255, 255, 255, .72); border-radius: 999px;
  transition: width .9s cubic-bezier(.3, 0, .2, 1) .35s;
}
.bb-hpfill{ position: relative; z-index: 1; }
.bb-hpfill.high{ background: linear-gradient(90deg, #00e5ff, #3df0a0 60%, #7dffb0); }
.bb-hpfill.mid{ background: linear-gradient(90deg, #ff9d2e, #ffd966); }
.bb-hpfill.low{ background: linear-gradient(90deg, #e53935, #ff7043); }

/* ---- 3. Impacts élémentaires (injectés dans .bb-fx par bbImpact) ---- */
.bb-impact{
  position: absolute; inset: 0; z-index: 7; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  --ic: #fff;
}
.bb-impact::before{
  content: ''; position: absolute; width: 92px; height: 92px; border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--ic) 80%, #fff) 0%,
    color-mix(in srgb, var(--ic) 55%, transparent) 36%, transparent 68%);
  mix-blend-mode: screen;
  animation: bbBurst .5s ease-out forwards;
}
@keyframes bbBurst{
  0%   { opacity: .95; transform: scale(.25); }
  55%  { opacity: .8; }
  100% { opacity: 0; transform: scale(1.7); }
}
.bb-impact::after{
  content: ''; font-size: 2.1rem; line-height: 1;
  text-shadow: 0 0 16px var(--ic), 0 0 4px #000;
  animation: bbImpactEmo .52s ease-out forwards;
}
@keyframes bbImpactEmo{
  0%   { opacity: 0; transform: scale(.4) rotate(-10deg); }
  30%  { opacity: 1; transform: scale(1.3) rotate(4deg); }
  100% { opacity: 0; transform: scale(1) translateY(-12px); }
}
.bb-impact-fire{ --ic: #ff5722; } .bb-impact-fire::after{ content: '🔥'; }
.bb-impact-water{ --ic: #29b6f6; } .bb-impact-water::after{ content: '💧'; }
.bb-impact-lightning{ --ic: #ffc107; } .bb-impact-lightning::after{ content: '⚡'; animation: bbZap .5s steps(2, jump-none) forwards; }
@keyframes bbZap{
  0%   { opacity: 1; transform: scale(1.5) skewX(-12deg); }
  50%  { opacity: .4; transform: scale(1.1) skewX(10deg); }
  100% { opacity: 0; transform: scale(.9); }
}
.bb-impact-ice{ --ic: #4fc3f7; } .bb-impact-ice::after{ content: '❄️'; }
.bb-impact-nature{ --ic: #66bb6a; } .bb-impact-nature::after{ content: '🍃'; }
.bb-impact-dark{ --ic: #7e57c2; } .bb-impact-dark::after{ content: '🌑'; }
.bb-impact-dark::before{
  border-radius: 14px; width: 100%; height: 100%;
  background: radial-gradient(circle, rgba(126, 87, 194, .65), rgba(40, 20, 80, .4) 70%);
  mix-blend-mode: normal;
}
.bb-impact-light{ --ic: #fff176; } .bb-impact-light::after{ content: '🌟'; }
.bb-impact-light::before{
  border-radius: 0;
  background:
    repeating-conic-gradient(from 0deg, rgba(255, 241, 118, .5) 0deg 9deg, transparent 9deg 36deg),
    radial-gradient(circle, rgba(255, 241, 118, .8), transparent 55%);
  -webkit-mask-image: radial-gradient(circle, #000 30%, transparent 72%);
  mask-image: radial-gradient(circle, #000 30%, transparent 72%);
}
.bb-impact-wind{ --ic: #80deea; } .bb-impact-wind::after{ content: '💨'; }
.bb-impact-earth{ --ic: #a1887f; } .bb-impact-earth::after{ content: '🪨'; }
/* Onde bleue spécifique à l'eau (anneau qui s'étend). */
.bb-impact-water::before{
  background: transparent; border: 3px solid var(--ic);
  box-shadow: 0 0 18px var(--ic), inset 0 0 14px var(--ic);
  mix-blend-mode: normal;
  animation: bbRipple .55s ease-out forwards;
}
@keyframes bbRipple{
  0%   { opacity: .95; transform: scale(.22); }
  100% { opacity: 0; transform: scale(1.9); }
}

/* Lisibilité des floats de dégâts (halo néon + contour sombre). */
.bb-dmg{ text-shadow: 0 2px 6px #000, 0 0 14px rgba(255, 82, 82, .85); }
.bb-float-crit .bb-crit{ text-shadow: 0 2px 5px #000, 0 0 12px rgba(255, 213, 79, .9); }

/* ---- 4. Game feel : shake, punch, K.O., entrées ---- */
.bb-shake{ animation: bbShakeK .25s linear; }
@keyframes bbShakeK{
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-6px, 3px); }
  40% { transform: translate(5px, -3px); }
  60% { transform: translate(-4px, -2px); }
  80% { transform: translate(3px, 2px); }
}

/* Réaffirme les anims d'event avec une spécificité > bbActiveBreath/bbTurnPulse
   (sinon la carte active "respirante" ignore lunge/hit/faint/flip). */
.bb-card.bb-lunge-down, .bb-big.bb-turn.bb-lunge-down{ animation: bbLungeDown .42s cubic-bezier(.3, .9, .3, 1); }
.bb-card.bb-lunge-up, .bb-big.bb-turn.bb-lunge-up{ animation: bbLungeUp .42s cubic-bezier(.3, .9, .3, 1); }
.bb-card.bb-hit, .bb-big.bb-turn.bb-hit{ animation: bbHit .38s ease; }
.bb-card.bb-flip, .bb-big.bb-turn.bb-flip{ animation: bbFlip .6s ease; }
.bb-card.bb-switch-in, .bb-big.bb-turn.bb-switch-in{ animation: bbSwitchInGlow .65s cubic-bezier(.2, .9, .3, 1.2); }
.bb-card.bb-fainting, .bb-big.bb-turn.bb-fainting{ animation: bbFaintDrop .7s ease forwards; }

/* Zoom punch de l'attaquant (remplace les keyframes de lunge, + énergiques). */
@keyframes bbLungeDown{
  0%   { transform: translateY(0) scale(1); }
  40%  { transform: translateY(30px) scale(1.12); filter: brightness(1.25); }
  100% { transform: translateY(0) scale(1); }
}
@keyframes bbLungeUp{
  0%   { transform: translateY(0) scale(1); }
  40%  { transform: translateY(-30px) scale(1.12); filter: brightness(1.25); }
  100% { transform: translateY(0) scale(1); }
}

/* K.O. : désaturation + chute / dissolution. */
@keyframes bbFaintDrop{
  0%   { opacity: 1; transform: translateY(0) rotate(0) scale(1); filter: grayscale(0); }
  55%  { opacity: .8; transform: translateY(10px) rotate(4deg) scale(.97); filter: grayscale(.6); }
  100% { opacity: .42; transform: translateY(22px) rotate(7deg) scale(.93); filter: grayscale(.85) blur(1px); }
}

/* Entrée de carte (switch) : slide + sur-brillance. */
@keyframes bbSwitchInGlow{
  0%   { transform: translateY(22px) scale(.86); opacity: .2; filter: brightness(2); }
  55%  { transform: translateY(-6px) scale(1.06); opacity: 1; filter: brightness(1.4); }
  100% { transform: translateY(0) scale(1); filter: brightness(1); }
}

/* ---- 5. Bannière de tour : pilule néon ---- */
.bb-banner{
  gap: 10px; padding: 9px 18px;
  background: linear-gradient(180deg, rgba(20, 26, 50, .9), rgba(12, 16, 34, .9));
  border: 1px solid rgba(124, 92, 226, .35);
  box-shadow: 0 4px 18px -8px #000, inset 0 1px 0 rgba(255, 255, 255, .05);
}
.bb-banner::before{
  content: '⚔️'; font-size: 1rem; line-height: 1;
  filter: drop-shadow(0 0 6px rgba(140, 110, 255, .8));
}
.bb-banner-mine{
  background: linear-gradient(90deg, rgba(46, 213, 115, .22), rgba(0, 229, 255, .1));
  color: #8fffbe; border-color: rgba(46, 213, 115, .65);
  text-shadow: 0 0 12px rgba(46, 213, 115, .55);
  animation: bbBannerPulseG 1.5s ease-in-out infinite;
}
@keyframes bbBannerPulseG{
  0%, 100% { box-shadow: 0 0 16px -8px rgba(46, 213, 115, .55); transform: scale(1); }
  50%      { box-shadow: 0 0 34px -3px rgba(46, 213, 115, .85); transform: scale(1.018); }
}
.bb-banner-their{
  background: linear-gradient(90deg, rgba(177, 77, 255, .16), rgba(177, 77, 255, .04));
  color: #cba6ff; border-color: rgba(177, 77, 255, .45);
  box-shadow: 0 0 18px -8px rgba(177, 77, 255, .5);
}
.bb-turnnum{
  background: rgba(0, 0, 0, .42); border: 1px solid rgba(255, 255, 255, .08);
}

/* ---- 6. Écrans de fin ---- */
.bb-end-card{ overflow: visible; }
.bb-end-title{
  position: relative; z-index: 1;
  animation: bbTitleIn .55s cubic-bezier(.18, 1.5, .4, 1) backwards;
}
.bb-end-sub, .bb-end-card .cb-end-actions{ position: relative; z-index: 1; }
@keyframes bbTitleIn{
  0%   { opacity: 0; transform: scale(.25); }
  100% { opacity: 1; transform: scale(1); }
}
.bb-overlay-win .bb-end-title{
  animation: bbTitleIn .55s cubic-bezier(.18, 1.5, .4, 1) backwards,
             bbWinPulse 1.4s ease-in-out .6s infinite;
}

/* Rayons dorés rotatifs derrière le titre (victoire). */
.bb-end-rays{
  position: absolute; left: 50%; top: 50%; width: 560px; height: 560px;
  transform: translate(-50%, -50%); pointer-events: none; z-index: 0;
  background: repeating-conic-gradient(from 0deg,
    rgba(255, 213, 79, .16) 0deg 11deg, transparent 11deg 30deg);
  -webkit-mask-image: radial-gradient(circle, #000 0%, transparent 68%);
  mask-image: radial-gradient(circle, #000 0%, transparent 68%);
  animation: bbRays 16s linear infinite;
}
@keyframes bbRays{ to { transform: translate(-50%, -50%) rotate(360deg); } }

/* Vignette du chef vainqueur. */
.bb-end-chef{
  position: relative; z-index: 1; width: 92px; height: 92px; margin: 0 auto 12px;
  border-radius: 50%; overflow: hidden;
  border: 3px solid color-mix(in srgb, var(--rc, #ffd54f) 60%, #ffd54f);
  box-shadow: 0 0 26px rgba(255, 200, 60, .6), 0 0 60px -8px color-mix(in srgb, var(--rc, #ffd54f) 80%, transparent);
  background: linear-gradient(135deg, #182038, #0e1424);
  animation: bbChefIn .6s cubic-bezier(.18, 1.5, .4, 1) backwards;
}
.bb-end-chef img{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
.bb-end-chef-fb{
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-weight: 800; font-size: 2rem; color: #ffd54f;
}
@keyframes bbChefIn{
  0%   { opacity: 0; transform: translateY(18px) scale(.5); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Confettis enrichis : deux nappes décalées. */
.bb-confetti{
  background:
    radial-gradient(circle at 20% 10%, #ffd54f 0 3px, transparent 4px),
    radial-gradient(circle at 80% 20%, var(--neon-1) 0 3px, transparent 4px),
    radial-gradient(circle at 50% 5%, var(--neon-purple) 0 3px, transparent 4px),
    radial-gradient(circle at 35% 30%, #5cf08a 0 3px, transparent 4px),
    radial-gradient(circle at 70% 40%, #ff8bb3 0 3px, transparent 4px),
    radial-gradient(circle at 12% 50%, #ffd54f 0 2px, transparent 3px),
    radial-gradient(circle at 92% 60%, #5cf08a 0 2px, transparent 3px),
    radial-gradient(circle at 60% 25%, #ff8bb3 0 2px, transparent 3px);
}
.bb-confetti::after{
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(circle at 28% 18%, var(--neon-1) 0 2px, transparent 3px),
    radial-gradient(circle at 64% 8%, #ffd54f 0 3px, transparent 4px),
    radial-gradient(circle at 44% 45%, #ff8bb3 0 2px, transparent 3px),
    radial-gradient(circle at 84% 35%, var(--neon-purple) 0 2px, transparent 3px);
  animation: bbConfetti 2.1s .6s ease-out infinite;
}

/* Défaite : voile sombre + vignette rouge. */
.bb-overlay-lose{
  background: radial-gradient(110% 110% at 50% 50%, rgba(6, 4, 12, .82) 38%, rgba(130, 10, 22, .72) 100%);
  box-shadow: inset 0 0 170px rgba(244, 67, 54, .42);
}
.bb-overlay-lose .bb-end-title{ text-shadow: 0 0 24px rgba(244, 67, 54, .75); }

/* Égalité : double éclat cyan/violet. */
.bb-overlay-draw .bb-end-title{
  color: #d6dcff;
  text-shadow: -12px 0 26px rgba(0, 229, 255, .6), 12px 0 26px rgba(177, 77, 255, .6);
}

/* ---- 7. Boutons d'attaque : cartes-boutons élémentaires ---- */
.bb-atk{
  position: relative; overflow: hidden;
  border-left: 3px solid color-mix(in srgb, var(--el, var(--neon-1)) 85%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 4px 12px -6px #000;
}
.bb-atk::before{
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .12) 50%, transparent 62%);
  transform: translateX(-130%);
  transition: transform .45s ease;
}
.bb-atk:hover:not(:disabled)::before{ transform: translateX(130%); }
.bb-atk:hover:not(:disabled){
  transform: translateY(-3px) scale(1.02);
  box-shadow:
    0 10px 28px -8px color-mix(in srgb, var(--el, var(--neon-1)) 75%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, .1);
}
.bb-atk-name{ text-shadow: 0 0 12px color-mix(in srgb, var(--el, var(--neon-1)) 55%, transparent); }
.bb-switch-hint{
  padding: 4px 14px; border-radius: 999px;
  background: rgba(0, 229, 255, .07); border: 1px dashed rgba(0, 229, 255, .3);
}

/* ---- 8. Responsive + perfs ---- */
@media (max-width: 760px){
  .bb-stars2{ display: none; }
  .bb-banner{ flex-wrap: wrap; gap: 6px; line-height: 1.35; }
  .bb-banner::before{ display: none; }
  .bb-big:not(.bb-faint):not(.bb-back)::after{ animation: none; opacity: .42; }
  .bb-big.bb-turn:not(.bb-faint){ animation: bbActiveBreath 2.6s ease-in-out infinite; }
  .bb-card.bb-turn{ box-shadow: 0 0 0 2px color-mix(in srgb, var(--rc, #00e5ff) 85%, #fff), 0 0 22px -4px color-mix(in srgb, var(--rc, #00e5ff) 85%, transparent), 0 8px 22px -10px #000; }
  .bb-end-rays{ width: 360px; height: 360px; }
}

@media (prefers-reduced-motion: reduce){
  .bb-stars, .bb-stars2{ display: none; }
  .bb-big:not(.bb-faint):not(.bb-back)::after, .bb-big.bb-turn:not(.bb-faint), .bb-card.bb-turn .bb-art-wrap::before, .bb-shake, .bb-end-rays, .bb-end-title, .bb-end-chef, .bb-overlay-win .bb-end-title, .bb-confetti::after, .bb-banner-mine, .bb-banner::before, .bb-card.bb-lunge-down, .bb-card.bb-lunge-up, .bb-card.bb-hit, .bb-card.bb-flip, .bb-card.bb-switch-in, .bb-card.bb-fainting{ animation: none; }
  .bb-impact{ display: none; }
  .bb-hpghost{ transition: none; }
  .bb-atk::before{ transition: none; }
}

/* ── Musique d'ambiance ── */
.music-ctl{
  position: fixed; bottom: 16px; right: 16px; z-index: 200;
  display: flex; align-items: center; gap: 8px;
  background: rgba(18, 18, 32, .92); border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 999px; padding: 6px 12px 6px 6px; box-shadow: 0 6px 20px rgba(0, 0, 0, .45);
  backdrop-filter: blur(6px);
}
.music-btn{
  width: 38px; height: 38px; border-radius: 50%; border: none; cursor: pointer;
  font-size: 18px; line-height: 1; display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #00e5ff, #b14dff); color: #0a0a12;
  transition: transform .15s ease, box-shadow .2s ease;
}
.music-btn:hover{ transform: scale(1.06); box-shadow: 0 0 16px rgba(0, 229, 255, .5); }
.music-btn.is-on{ box-shadow: 0 0 14px rgba(0, 229, 255, .6); }
.music-btn-sm{ width: 32px; height: 32px; font-size: 15px; background: linear-gradient(135deg, #2b2b44, #3a3a5c); color: #e8e8ff; }
.music-btn-sm.is-on{ background: linear-gradient(135deg, #00e5ff, #b14dff); color: #0a0a12; }
.music-vol{ width: 84px; accent-color: #00e5ff; cursor: pointer; }
@media (max-width: 560px){ .music-vol{ width: 54px; } .music-ctl{ bottom: 12px; right: 12px; } }

/* ── Carte « déjà vue » (relâchée/échangée) : silhouette grisée, non cliquable ── */
.card-seen{ cursor: default; }
.card-seen .card-art{ filter: grayscale(1) brightness(.5) contrast(.95); transition: filter .25s ease, opacity .35s ease; }
.card-seen:hover .card-art{ filter: grayscale(.8) brightness(.62); }
.card-seen .card-seen-veil{ position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(180deg, rgba(8,10,20,.35), rgba(8,10,20,.6)); }
.card-seen .card-overlay{ z-index: 2; }
.card-seen .card-name{ color: var(--text-dim); letter-spacing: 1px; }
.card-seen .rarity-badge{ opacity: .68; }
.card-seen .card-seen-tag{
  font-size: .6rem; font-weight: 700; text-transform: uppercase; letter-spacing: .6px;
  color: var(--text-faint); background: rgba(255,255,255,.06);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px;
}
@media (prefers-reduced-motion: reduce){ .card-seen .card-art{ transition: none; } }

/* ============================================================
   WAIFU TIMER DEX — overlay cadeau gacha (boîte qui tremble puis s'ouvre)
   ============================================================ */
.gift-overlay{
  position: fixed; inset: 0; z-index: 9000; display: none;
  align-items: center; justify-content: center; padding: 20px;
  background: radial-gradient(circle at 50% 40%, rgba(40,18,60,.82), rgba(6,8,18,.94));
  backdrop-filter: none;
  /* Filet de sécurité : sur un écran très court (ou une carte plus haute), la scène est
     défilable VERTICALEMENT au lieu d'être rognée — `margin:auto` sur la scène garde le
     centrage tant qu'il y a la place et évite le rognage du haut propre au centrage flex.
     Jamais de défilement horizontal : la scène est bornée à 100 % de la largeur. */
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
}
.gift-overlay.show{ display: flex; animation: gift-fade .35s ease both; }
@keyframes gift-fade{ from { opacity: 0; } to { opacity: 1; } }
.gift-stage{ position: relative; width: 100%; max-width: 420px; margin: auto; text-align: center; }
/* 📏 MESURÉ en 375×812 : une fois ouverte, la boîte est réduite à néant par `gift-pop`
   (scale 0, opacité 0) mais gardait ses 160 px de HAUTEUR dans la mise en page — la scène
   faisait 823 px pour 812 px d'écran, elle débordait en haut et en bas. La boîte occupe donc
   une CASE dédiée qui se referme, en même temps que le pop, quand la carte apparaît. La
   transition évite le sursaut de 160 px, et la boîte (`overflow: visible`, ancrée en haut)
   continue de se réduire par-dessus. */
.gift-box-slot{
  height: 160px; overflow: visible;
  display: flex; justify-content: center; align-items: flex-start;
  transition: height .5s ease;
}
.gift-box-slot > .gift-box{ flex: 0 0 auto; }
.gift-stage.opened .gift-box-slot{ height: 0; }
/* Repli sans stats : illustration seule, jamais plus large que la scène. */
.gift-fallback-art{
  position: relative; z-index: 1; display: block; margin: 0 auto;
  max-width: 240px; width: 62%; border-radius: 18px;
  box-shadow: 0 0 34px color-mix(in srgb, var(--rc, #ffd76a) 55%, transparent);
}
.gift-glow{
  position: absolute; left: 50%; top: 38%; width: 380px; height: 380px;
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--rc, #ffd278) 55%, transparent), rgba(255,140,200,.18) 46%, transparent 70%);
  animation: gift-glow-pulse 2.4s ease-in-out infinite;
}
@keyframes gift-glow-pulse{ 0%,100% { opacity: .5; transform: translate(-50%,-50%) scale(.9); } 50% { opacity: 1; transform: translate(-50%,-50%) scale(1.14); } }

/* Rayons de lumière tournants derrière la boîte (anticipation). */
.gift-rays{
  position: absolute; left: 50%; top: 38%; width: 460px; height: 460px;
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none; opacity: .55;
  background: conic-gradient(from 0deg,
    transparent 0 16deg, color-mix(in srgb, var(--rc, #ffd278) 40%, transparent) 16deg 20deg,
    transparent 20deg 40deg, color-mix(in srgb, var(--rc, #ffd278) 28%, transparent) 40deg 43deg, transparent 43deg 60deg);
  -webkit-mask: radial-gradient(circle, transparent 28%, #000 42%, transparent 72%);
          mask: radial-gradient(circle, transparent 28%, #000 42%, transparent 72%);
  animation: gift-rays-spin 9s linear infinite;
}
@keyframes gift-rays-spin{ to { transform: translate(-50%,-50%) rotate(360deg); } }

/* Étincelles d'anticipation autour de la boîte (disparaissent à l'ouverture). */
.gift-sparkles{ position: absolute; left: 50%; top: 42%; width: 0; height: 0; pointer-events: none; z-index: 4; transition: opacity .3s ease; }
.gift-stage.opened .gift-sparkles, .gift-stage.opened .gift-rays{ opacity: 0; }
.gsk{
  position: absolute; left: 0; top: 0; font-size: .95rem; opacity: 0;
  transform: translate(var(--x), var(--y)) scale(.4);
  animation: gsk-twinkle 1.5s ease-in-out var(--d, 0s) infinite;
  filter: drop-shadow(0 0 5px rgba(255,225,150,.7));
}
@keyframes gsk-twinkle{
  0%, 100% { opacity: 0; transform: translate(var(--x), var(--y)) scale(.3) rotate(0deg); }
  50% { opacity: 1; transform: translate(var(--x), var(--y)) scale(1) rotate(18deg); }
}

/* Flash blanc à l'ouverture. */
.gift-flash{
  position: absolute; left: 50%; top: 38%; width: 60px; height: 60px; transform: translate(-50%,-50%) scale(0);
  border-radius: 50%; pointer-events: none; z-index: 6; opacity: 0;
  background: radial-gradient(circle, #fff 0 30%, color-mix(in srgb, var(--rc, #ffe6a0) 70%, #fff) 45%, transparent 70%);
}
.gift-flash.go{ animation: gift-flash-go .6s ease-out both; }
@keyframes gift-flash-go{
  0% { opacity: 0; transform: translate(-50%,-50%) scale(0); }
  18% { opacity: 1; transform: translate(-50%,-50%) scale(7); }
  100% { opacity: 0; transform: translate(-50%,-50%) scale(11); }
}

/* Confettis & emojis kawaii. */
.gift-confetti{ position: absolute; left: 0; right: 0; top: 8%; height: 1px; pointer-events: none; z-index: 7; }
.gcf{
  position: absolute; top: 0; border-radius: 2px; opacity: 0;
  animation-name: gcf-fall; animation-timing-function: cubic-bezier(.3,.6,.4,1); animation-fill-mode: forwards;
}
.gcf-emo{ background: none !important; width: auto !important; height: auto !important; font-size: 1.05rem; filter: drop-shadow(0 0 4px rgba(255,210,140,.6)); }
@keyframes gcf-fall{
  0% { opacity: 0; transform: translate(0, -20px) rotate(0deg) scale(.6); }
  12% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx, 0), 340px) rotate(var(--rot, 360deg)) scale(1); }
}

/* La boîte */
.gift-box{
  position: relative; width: 150px; height: 130px; margin: 30px auto 0; z-index: 5;
  transform-origin: 50% 100%; animation: gift-shake 1.45s ease-in-out both;
}
/* Reflet qui balaie la boîte pendant l'attente. */
.gift-glint{
  position: absolute; left: -8px; top: 18px; width: 166px; height: 78px; border-radius: 9px; overflow: hidden;
  pointer-events: none; z-index: 5;
}
.gift-glint::before{
  content: ''; position: absolute; top: -20%; left: -60%; width: 40%; height: 140%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.75), transparent);
  transform: skewX(-18deg); animation: gift-glint-sweep 1.6s ease-in-out infinite;
}
@keyframes gift-glint-sweep{ 0% { left: -60%; } 55%, 100% { left: 130%; } }
.gift-body{
  position: absolute; left: 0; bottom: 0; width: 150px; height: 96px; border-radius: 10px;
  background: linear-gradient(160deg, #ff7ac0, #d4408f); box-shadow: 0 12px 30px rgba(0,0,0,.45), inset 0 -8px 16px rgba(0,0,0,.25);
}
.gift-lid{
  position: absolute; left: -8px; top: 18px; width: 166px; height: 40px; border-radius: 9px;
  background: linear-gradient(160deg, #ff9ad2, #e25aa3); box-shadow: 0 6px 14px rgba(0,0,0,.4);
  transform-origin: 50% 100%; transition: transform .5s cubic-bezier(.5,-0.4,.3,1.4), opacity .5s ease;
  z-index: 3;
}
.gift-ribbon-v{ position: absolute; left: 50%; bottom: 0; width: 22px; height: 96px; transform: translateX(-50%); background: linear-gradient(180deg, #ffe082, #ffb300); z-index: 2; }
.gift-ribbon-h{ position: absolute; left: -8px; top: 22px; width: 166px; height: 30px; background: linear-gradient(180deg, #ffe082, #ffb300); z-index: 2; }
.gift-bow{ position: absolute; left: 50%; top: 2px; transform: translateX(-50%); font-size: 2rem; z-index: 4; transition: transform .5s ease, opacity .5s ease; }
.gift-box.open .gift-lid{ transform: translateY(-44px) rotate(-26deg); opacity: 0; }
.gift-box.open .gift-bow{ transform: translate(-50%, -60px) scale(.4) rotate(40deg); opacity: 0; }
.gift-box.open .gift-glint{ display: none; }
.gift-box.open{ animation: gift-pop .5s ease both; }
/* Tremblement qui s'intensifie (anticipation) avant l'ouverture. */
@keyframes gift-shake{
  0% { transform: rotate(0) scale(1); }
  10% { transform: rotate(-3deg) scale(1.01); }
  20% { transform: rotate(3deg); }
  35% { transform: rotate(-5deg) scale(1.02); }
  50% { transform: rotate(5deg); }
  65% { transform: rotate(-7deg) scale(1.04); }
  80% { transform: rotate(7deg); }
  90% { transform: rotate(-9deg) scale(1.06); }
  100% { transform: rotate(0) scale(1.08); }
}
@keyframes gift-pop{ 0% { transform: scale(1.08); } 35% { transform: scale(1.2); } 100% { transform: scale(0); opacity: 0; } }

/* Révélation de la carte */
.gift-reveal{ position: relative; display: none; margin-top: -40px; }
.gift-reveal.show{ display: block; animation: gift-reveal-in .55s cubic-bezier(.2,.8,.3,1.2) both; }
@keyframes gift-reveal-in{ from { opacity: 0; transform: translateY(24px) scale(.85); } to { opacity: 1; transform: none; } }
.gift-burst{
  position: absolute; left: 50%; top: 30%; width: 280px; height: 280px; transform: translate(-50%,-50%);
  pointer-events: none; z-index: 0;
  background:
    radial-gradient(circle, rgba(255,225,140,.5), transparent 60%),
    conic-gradient(from 0deg, transparent 0 14deg, rgba(255,220,150,.5) 14deg 16deg, transparent 16deg 30deg);
  animation: gift-burst-spin 6s linear infinite;
}
@keyframes gift-burst-spin{ to { transform: translate(-50%,-50%) rotate(360deg); } }
.gift-title{ position: relative; z-index: 1; margin: 0 0 12px; font-size: 1.25rem; color: #ffe08a; text-shadow: 0 2px 10px rgba(0,0,0,.5); }
.gift-reveal .trade-reveal-card, .gift-reveal .reveal-card{
  position: relative; z-index: 1; margin: 0 auto;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--rc, #ffd76a) 60%, transparent), 0 0 28px color-mix(in srgb, var(--rc, #ffd76a) 45%, transparent);
  animation: gift-card-glow 2.2s ease-in-out infinite;
}
@keyframes gift-card-glow{
  0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--rc, #ffd76a) 55%, transparent), 0 0 22px color-mix(in srgb, var(--rc, #ffd76a) 38%, transparent); }
  50% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--rc, #ffd76a) 75%, transparent), 0 0 38px color-mix(in srgb, var(--rc, #ffd76a) 60%, transparent); }
}
.gift-sub{ position: relative; z-index: 1; margin: 12px 0 16px; color: var(--text); font-size: .95rem; }
.gift-sub b{ color: #ffd76a; }
.gift-close{ position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce){
  .gift-overlay.show, .gift-box, .gift-box.open, .gift-reveal.show, .gift-glow, .gift-burst, .gift-rays, .gsk, .gift-flash.go, .gcf, .gift-glint::before, .gift-reveal .trade-reveal-card{ animation: none !important; }
  .gift-box{ transform: none; }
  .gift-box.open .gift-lid, .gift-box.open .gift-bow{ transition: none; opacity: 0; }
  .gift-rays, .gift-sparkles, .gift-confetti, .gift-flash{ display: none; }
  /* Sans le « pop », la boîte reste entièrement dessinée : elle chevaucherait la carte une
     fois sa case refermée. Ici on montre la carte, pas le spectacle → la boîte disparaît. */
  .gift-box-slot{ transition: none; }
  .gift-stage.opened .gift-box{ display: none; }
}

/* ============================================================
   BANNIÈRE WAIFUDORADO / EVENTS GLOBAUX sur le Dex
   ============================================================ */
.dex-event-banner{
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 800;
  display: flex; align-items: center; gap: 9px; padding: 9px 18px; border-radius: 999px;
  font-weight: 700; font-size: .9rem; color: #2a1c00; white-space: nowrap;
  background: linear-gradient(100deg, #ffe082, #ffc107 50%, #ffb300);
  border: 1px solid rgba(255,255,255,.55); box-shadow: 0 8px 26px rgba(255,170,0,.4), inset 0 1px 0 rgba(255,255,255,.6);
  animation: deb-in .5s ease both, deb-float 3.2s ease-in-out infinite 0.5s;
}
.dex-event-banner .deb-ico, .dex-event-banner .deb-spark{ font-size: 1.05rem; }
.dex-event-banner .deb-spark{ animation: deb-spark 1.6s ease-in-out infinite; }
@keyframes deb-in{ from { opacity: 0; transform: translate(-50%, 16px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes deb-float{ 0%,100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, -5px); } }
@keyframes deb-spark{ 0%,100% { opacity: .5; transform: scale(.85); } 50% { opacity: 1; transform: scale(1.15); } }
@media (max-width: 560px){ .dex-event-banner{ font-size: .8rem; padding: 7px 13px; white-space: normal; max-width: 92vw; } }
@media (prefers-reduced-motion: reduce){ .dex-event-banner{ animation: deb-in .4s ease both; } .dex-event-banner .deb-spark{ animation: none; } }

/* ── Favoris (wishlist) : badge ❤️ + coût d'évolution sur la fiche ── */
.badge-fav{
  position: absolute; top: 8px; right: 8px; z-index: 5;
  font-size: .95rem; line-height: 1; pointer-events: none;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.55));
}
/* Si la carte a déjà un badge évènement (✨) en haut-droite, on décale le cœur. */
.card .badge-event ~ .badge-fav{ top: 34px; }
.cd-evolve-cost{
  margin-top: 8px; font-size: .82rem; color: var(--text-dim, #9fb6c6);
  background: rgba(255,255,255,.05); border: 1px solid var(--border, rgba(255,255,255,.1));
  border-radius: 8px; padding: 5px 10px; display: inline-block;
}
.cd-evolve-cost b{ color: #ffd76a; }
.cd-drop{
  margin-top: 8px; margin-right: 6px; font-size: .82rem; color: var(--text-dim, #9fb6c6);
  background: rgba(0, 229, 255, .08); border: 1px solid rgba(0, 229, 255, .35);
  border-radius: 8px; padding: 5px 10px; display: inline-block;
}
.cd-drop b{ color: var(--neon-1, #00e5ff); }
.cd-drop.cd-drop-secret{ background: rgba(255, 77, 141, .1); border-color: rgba(255, 77, 141, .4); color: #ffb3cf; }

/* ===== Révélation plein écran (waifu secrète) — façon Genshin Impact ===== */
.secret-reveal{
  position: fixed; inset: 0; z-index: 99999;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 62% 50%, rgba(24,14,46,.55), rgba(5,3,12,.93));
  opacity: 0; transition: opacity .35s ease; overflow: hidden;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.secret-reveal.show{ opacity: 1; }

/* Balayage lumineux qui arrive depuis la DROITE et couvre l'écran. */
.sr-sweep{
  position: absolute; inset: -10% -10%; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0) 42%, var(--rc,#b14dff) 50%, rgba(255,255,255,.95) 55%, var(--rc,#b14dff) 60%, transparent 72%);
  transform: translateX(115%);
  animation: srSweep 1.05s cubic-bezier(.2,.7,.2,1) forwards;
}
@keyframes srSweep{
  0% { transform: translateX(115%); }
  55% { transform: translateX(0%); }
  100% { transform: translateX(-120%); opacity: 0; }
}

/* Rayons rotatifs derrière la carte. */
.sr-rays{
  position: absolute; left: 50%; top: 50%;
  width: 150vmax; height: 150vmax;
  transform: translate(-50%,-50%) scale(0) rotate(0deg);
  background: repeating-conic-gradient(from 0deg, var(--rc,#b14dff) 0deg 5deg, transparent 5deg 13deg);
  opacity: 0; mix-blend-mode: screen; pointer-events: none;
  animation: srRays 3s ease-out .5s forwards;
}
@keyframes srRays{
  0% { transform: translate(-50%,-50%) scale(0) rotate(0deg); opacity: 0; }
  30% { opacity: .30; }
  100% { transform: translate(-50%,-50%) scale(1) rotate(45deg); opacity: .10; }
}

/* Bloc central : kicker + titre + carte + sous-titre + bouton. */
.sr-stage{
  position: relative; z-index: 2; text-align: center; max-width: 92vw;
  transform: scale(.7); opacity: 0;
  animation: srStage .6s cubic-bezier(.2,.8,.25,1.35) .55s forwards;
}
@keyframes srStage{ to { transform: scale(1); opacity: 1; } }
.sr-kicker{
  font-weight: 900; letter-spacing: 3px; font-size: .78rem; text-transform: uppercase;
  color: var(--rc,#b14dff); text-shadow: 0 0 14px var(--rc,#b14dff); margin-bottom: 6px;
}
.sr-title{ font-size: clamp(1.3rem, 4vw, 1.9rem); font-weight: 900; margin: 0 0 14px; color: #fff; }
.sr-card{ display: inline-block; filter: drop-shadow(0 0 28px var(--rc,#b14dff)); animation: srFloat 4s ease-in-out 1.2s infinite; }
@keyframes srFloat{ 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.sr-sub{ margin-top: 14px; color: #eaf0ff; opacity: .92; }
.sr-close{ margin-top: 18px; }

@media (prefers-reduced-motion: reduce){
  .sr-sweep, .sr-rays, .sr-card{ animation: none !important; }
  .sr-sweep, .sr-rays{ opacity: 0 !important; }
  .sr-stage{ animation: none !important; transform: none !important; opacity: 1 !important; }
  .sr-pt{ animation-duration: .01s !important; opacity: 0 !important; }
}
/* PERF mobile : le backdrop-filter (blur) plein écran + les rayons 150vmax + le flottement
   de la carte font ramer les petits GPU. On retire le blur, on borne les rayons (~120vmin)
   et on coupe srFloat — la révélation reste lisible (sweep/rays/stage intacts). */
@media (hover: none), (max-width: 820px){
  .secret-reveal{ -webkit-backdrop-filter: none; backdrop-filter: none; }
  .sr-rays{ width: 120vmin; height: 120vmin; }
  .sr-card{ animation: none; }
}

/* --- Révélations SPÉCIALES (nao-chan / Geneviève / HESOYAM) --- */
/* Pluie d'emojis thématique */
.sr-particles{ position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; }
.sr-pt{
  position: absolute; top: -12vh; will-change: transform, opacity;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.35));
  animation-name: srFall; animation-timing-function: linear; animation-fill-mode: forwards;
}
@keyframes srFall{
  0%   { transform: translateY(-12vh) translateX(0) rotate(0deg); opacity: 0; }
  10%  { opacity: .95; }
  100% { transform: translateY(112vh) translateX(var(--dx,0)) rotate(var(--rot,360deg)); opacity: .15; }
}
/* Bannière (nom stylisé sous le kicker) */
.sr-banner{
  font-weight: 900; font-size: clamp(1.8rem, 7vw, 3.2rem); line-height: 1; margin: 2px 0 10px;
  letter-spacing: 2px; color: var(--rc, #fff); text-shadow: 0 0 18px var(--rc, #fff), 0 0 38px var(--rc, #fff);
  animation: srBannerPop .6s cubic-bezier(.2,.8,.25,1.6) .5s both;
}
@keyframes srBannerPop{ 0% { transform: scale(.4); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
/* HESOYAM — code triche GTA : vert néon, monospace, fond sombre teinté */
.secret-reveal.sr-hesoyam{ background: radial-gradient(circle at 50% 40%, rgba(10,40,18,.55), rgba(0,0,0,.92)); }
.sr-hesoyam .sr-banner{
  font-family: 'Courier New', monospace; text-transform: uppercase; letter-spacing: 4px;
  -webkit-text-stroke: 1px rgba(0,0,0,.4);
  animation: srBannerPop .5s cubic-bezier(.2,.8,.25,1.6) .5s both, srGlitch 1.6s steps(2) .9s 2;
}
@keyframes srGlitch{ 0%,100% { transform: translate(0,0); } 25% { transform: translate(-2px,1px); } 50% { transform: translate(2px,-1px); } 75% { transform: translate(-1px,-1px); } }
.sr-hesoyam .sr-kicker{ font-family: 'Courier New', monospace; }
/* nao-chan — kawaii rose */
.secret-reveal.sr-nao{ background: radial-gradient(circle at 50% 40%, rgba(60,16,48,.5), rgba(0,0,0,.92)); }
.sr-nao .sr-banner{ letter-spacing: 1px; }
/* Geneviève — royal doré */
.secret-reveal.sr-genevieve{ background: radial-gradient(circle at 50% 40%, rgba(60,46,8,.5), rgba(0,0,0,.92)); }
.sr-genevieve .sr-banner{ font-family: 'Playfair Display', Georgia, serif; letter-spacing: 3px; }
/* Générique festif — toute AUTRE secrète : teinte douce selon la rareté (--rc) */
.secret-reveal.sr-festive{ background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--rc, #b14dff) 18%, rgba(0,0,0,.9)), rgba(0,0,0,.92)); }


/* ============================================================
   COMBAT V2 « ALCHIMIE » (additif — Phase 3)
   Activé par .bb-alch (posé par alchPaint quand engine='alchimie').
   Le plateau v1 (classes bb-*) n'est PAS modifié : les cartes v2
   réutilisent bb-card / bb-hpbar / bb-fx et ajoutent les al-*.
   ============================================================ */

/* ---- Rangée de 4 cartes par camp (active mise en avant) ---- */
.bb-alch .al-row{ display: flex; gap: 10px; justify-content: center; align-items: flex-end; }
.al-card{ width: 116px; padding: 6px 6px 7px; }
.al-card .bb-name{ font-size: .72rem; }
.al-card .bb-hpbar{ height: 9px; }
.al-card .bb-hptxt{ font-size: .56rem; }
.al-card.al-active{ width: 150px; transform: translateY(-4px); z-index: 2; }
.al-row-enemy{ align-items: flex-start; }
.al-row-enemy .al-card.al-active{ transform: translateY(4px); }
.al-card.al-active:not(.bb-faint){
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--el, var(--rc, #888)) 70%, transparent),
    0 0 26px -6px color-mix(in srgb, var(--el, var(--rc, #888)) 80%, transparent),
    0 10px 26px -10px #000;
}

/* Badge de rôle (🛡️ Tank / 🔮 Mage / 🗡️ Assassine / 💚 Soutien) */
.al-role{
  position: absolute; top: 3px; left: 4px; z-index: 3; font-size: .85rem;
  cursor: help; filter: drop-shadow(0 0 4px rgba(0, 0, 0, .85));
}

/* ⚗️ Empreinte élémentaire — l'info stratégique : badge pulsé couleur élément */
.al-mark{
  position: absolute; top: 3px; right: 4px; z-index: 4; font-size: .78rem; cursor: help;
  padding: 1px 5px; border-radius: 999px; line-height: 1.2; white-space: nowrap;
  background: color-mix(in srgb, var(--el, #fff) 26%, rgba(0, 0, 0, .6));
  border: 1px solid color-mix(in srgb, var(--el, #fff) 80%, transparent);
  text-shadow: 0 0 8px var(--el, #fff);
  animation: alMarkPulse 1.5s ease-in-out infinite;
}
@keyframes alMarkPulse{
  0%, 100% { box-shadow: 0 0 6px -2px var(--el, #fff); }
  50%      { box-shadow: 0 0 14px 0 var(--el, #fff); }
}

/* Mini-chips Légère/Lourde (élément du kit ; « ? » = non révélée, brouillard) */
.al-akchips{ display: flex; gap: 4px; margin-top: 3px; }
.al-akchip{
  font-size: .58rem; padding: 1px 5px; border-radius: 999px; white-space: nowrap;
  background: color-mix(in srgb, var(--el, #888) 22%, rgba(0, 0, 0, .5));
  border: 1px solid color-mix(in srgb, var(--el, #888) 55%, transparent);
  color: var(--text);
}
.al-akchip-hidden{ opacity: .55; border-style: dashed; }

/* Cible de combo : l'actif adverse brille quand une SURCHARGE est possible */
.al-combo-target{ border-color: #ffd76a !important; }
.al-combo-target::before{
  content: ''; position: absolute; inset: -3px; border-radius: inherit;
  pointer-events: none; z-index: 2;
  box-shadow: 0 0 18px -2px rgba(255, 215, 106, .85);
  animation: alComboPulse 1s ease-in-out infinite;
}
@keyframes alComboPulse{ 0%, 100% { opacity: .4; } 50% { opacity: 1; } }

/* ---- Head de camp : jauge d'Élan publique + PA bankés + garde ---- */
.al-head{ align-items: center; gap: 10px; flex-wrap: wrap; }
.al-gauge{ display: inline-flex; align-items: center; gap: 5px; font-size: .72rem; color: #ffd76a; }
.al-gauge-track{
  width: 90px; height: 7px; border-radius: 99px; overflow: hidden; display: inline-block;
  background: rgba(255, 255, 255, .10); border: 1px solid rgba(255, 215, 106, .25);
}
.al-gauge-fill{
  display: block; height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, #7a5cff, #ffd76a); transition: width .35s ease;
}
.al-gauge-full .al-gauge-fill{ background: linear-gradient(90deg, #ffd76a, #fff3b0, #ffd76a); }
.al-gauge-full{ text-shadow: 0 0 10px #ffd76a; animation: bbElanPulse 1s ease-in-out infinite; }
.al-gauge-pct{ color: var(--text-dim); }
.al-gauge-ready{ font-weight: 800; }
.al-bank{
  font-size: .68rem; font-weight: 800; color: #9be7ff; padding: 2px 8px; border-radius: 999px;
  background: rgba(0, 229, 255, .12); border: 1px solid rgba(0, 229, 255, .4); white-space: nowrap;
}
.al-guardtag{
  font-size: .68rem; font-weight: 700; color: #b7ffcb; padding: 2px 8px; border-radius: 999px;
  background: rgba(92, 240, 138, .12); border: 1px solid rgba(92, 240, 138, .4); white-space: nowrap;
}

/* ---- Composeur de tour : pips de PA + 5 actions + file + Jouer ---- */
.al-hud{ display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: center; }
.al-pa{ display: inline-flex; align-items: center; gap: 6px; font-weight: 800; font-size: .8rem; color: #9be7ff; }
.al-pip{
  width: 14px; height: 14px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #aef4ff, #00b7d6);
  box-shadow: 0 0 10px -2px #00e5ff; transition: opacity .2s, transform .2s;
}
.al-pip-bank{ background: radial-gradient(circle at 35% 35%, #fff3b0, #d8a200); box-shadow: 0 0 10px -2px #ffd76a; }
.al-pip-spent{ opacity: .18; transform: scale(.8); box-shadow: none; }

.al-actbar{ display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; width: 100%; }
.al-abtn{
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 104px; padding: 8px 10px; cursor: pointer; color: var(--text);
  background: linear-gradient(135deg, color-mix(in srgb, var(--el, var(--neon-1)) 28%, #16203c), #111a32);
  border: 1px solid color-mix(in srgb, var(--el, var(--neon-1)) 60%, transparent);
  border-radius: var(--radius-sm);
  transition: transform .14s, box-shadow .18s, filter .15s;
}
.al-abtn:hover:not(:disabled){
  transform: translateY(-2px);
  box-shadow: 0 8px 22px -8px color-mix(in srgb, var(--el, var(--neon-1)) 70%, transparent);
  filter: brightness(1.08);
}
.al-abtn:disabled{ opacity: .38; cursor: default; }
.al-abtn-name{ font-weight: 800; font-size: .84rem; font-family: var(--font-ui); white-space: nowrap; }
.al-abtn-cost{ font-size: .68rem; color: var(--text-dim); white-space: nowrap; }
.al-abtn-ult{
  background: linear-gradient(135deg, #ffe07a, #ffb300); color: #3a2a00; border-color: #fff3b0;
  box-shadow: 0 0 18px -4px rgba(255, 193, 0, .7);
  animation: bbUltGlow 1.1s ease-in-out infinite;
}
.al-abtn-ult .al-abtn-cost{ color: #6b4d00; }
/* « ⚗️ SURCHARGE ! » : pastille dorée pulsée sur le bouton d'attaque combo */
.al-overload{
  position: absolute; top: -10px; right: -6px; z-index: 2; white-space: nowrap;
  font-size: .6rem; font-weight: 900; color: #3a2a00; padding: 2px 7px; border-radius: 999px;
  background: linear-gradient(135deg, #fff3b0, #ffd76a);
  box-shadow: 0 0 12px -1px rgba(255, 215, 106, .9);
  animation: alComboPulse .9s ease-in-out infinite;
}

.al-switchpick{ display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; align-items: center; }
.al-spick{
  padding: 5px 10px; border-radius: 999px; font-size: .78rem; cursor: pointer; color: var(--text);
  background: rgba(0, 229, 255, .1); border: 1px solid rgba(0, 229, 255, .4);
}
.al-spick:hover{ background: rgba(0, 229, 255, .2); }

.al-queue{
  display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; align-items: center;
  min-height: 30px; width: 100%; max-width: 560px; padding: 6px 10px;
  border-radius: var(--radius-sm); background: rgba(0, 0, 0, .28);
  border: 1px dashed rgba(0, 229, 255, .25);
}
.al-queue-empty-hint{ font-size: .74rem; color: var(--text-faint); }
.al-chip{
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 999px;
  font-size: .78rem; font-weight: 700; cursor: pointer; color: var(--text);
  background: rgba(0, 229, 255, .14); border: 1px solid rgba(0, 229, 255, .45);
}
.al-chip:hover{ background: rgba(244, 67, 54, .18); border-color: rgba(244, 67, 54, .55); }
.al-chip-reac{ color: #ffe7a0; text-shadow: 0 0 8px #ffd76a; }
.al-play{ min-width: 230px; font-weight: 900; letter-spacing: .6px; }
.al-play:disabled{ opacity: .5; }

/* ---- Animations SPECTACLE : flash plein plateau (réaction / ultime) ---- */
.al-flash{
  position: absolute; inset: 0; z-index: 15; pointer-events: none; border-radius: inherit;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(70% 70% at 50% 50%, color-mix(in srgb, var(--fc, #fff) 34%, transparent), transparent 75%);
  animation: alFlashBg 1.45s ease-out forwards;
}
@keyframes alFlashBg{ 0% { opacity: 0; } 8% { opacity: 1; } 70% { opacity: .85; } 100% { opacity: 0; } }
.al-flash-inner{ text-align: center; animation: alFlashIn 1.45s cubic-bezier(.2, .9, .25, 1) forwards; }
@keyframes alFlashIn{
  0%   { transform: scale(.4); opacity: 0; }
  14%  { transform: scale(1.12); opacity: 1; }
  26%  { transform: scale(1); }
  82%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.04); }
}
.al-flash-kicker{
  font-family: var(--font-ui); font-weight: 800; font-size: .85rem;
  letter-spacing: .35em; color: #fff; opacity: .85; text-shadow: 0 0 12px var(--fc, #fff);
}
.al-flash-name{
  font-family: var(--font-ui);
  font-weight: 900; font-size: 2.1rem; color: #fff;
  text-shadow: 0 0 26px var(--fc, #fff), 0 0 8px var(--fc, #fff), 0 2px 4px #000;
}
.al-flash-dmg{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums; font-weight: 900; font-size: 1.5rem;
  color: #ffdada; text-shadow: 0 0 14px #ff5252, 0 2px 4px #000;
}
.al-flash-ult{ background: radial-gradient(70% 70% at 50% 50%, rgba(255, 215, 106, .4), transparent 75%); }
.al-flash-ult .al-flash-name{ color: #fff3b0; }

/* Halo doré de l'attaquante qui lâche son Ultime */
.al-ulting{ animation: alUlting 1.3s ease; z-index: 6; }
@keyframes alUlting{
  0%   { box-shadow: 0 0 0 0 rgba(255, 215, 106, 0); }
  30%  { box-shadow: 0 0 44px 4px rgba(255, 215, 106, .95); transform: translateY(-6px) scale(1.07); }
  100% { box-shadow: 0 0 0 0 rgba(255, 215, 106, 0); }
}
/* Garde : onde verte courte sur la carte active */
.al-guard-anim{ animation: alGuardAnim .68s ease; }
@keyframes alGuardAnim{
  0%   { box-shadow: 0 0 0 0 rgba(92, 240, 138, 0); }
  40%  { box-shadow: 0 0 26px -2px rgba(92, 240, 138, .95); }
  100% { box-shadow: 0 0 0 0 rgba(92, 240, 138, 0); }
}
/* Nom de l'attaque dans le float de dégâts */
.al-hitkind{ font-size: .66rem; color: var(--text-dim); }

/* ---- Mobile ---- */
@media (max-width: 760px){
  .bb-alch .al-row{ gap: 7px; }
  .al-card{ width: 90px; }
  .al-card.al-active{ width: 114px; }
  .al-abtn{ min-width: 88px; padding: 7px 8px; }
  .al-flash-name{ font-size: 1.5rem; }
}
@media (max-width: 560px){
  .bb-alch .al-row{ gap: 5px; }
  .al-card{ width: 72px; padding: 4px; }
  .al-card.al-active{ width: 94px; }
  .al-card .bb-name{ font-size: .58rem; }
  .al-akchip{ font-size: .5rem; padding: 1px 4px; }
  .al-gauge-track{ width: 64px; }
  .al-play{ min-width: 100%; }
  .al-flash-name{ font-size: 1.2rem; }
  .al-flash-dmg{ font-size: 1rem; }
}
@media (prefers-reduced-motion: reduce){
  .al-flash, .al-flash-inner, .al-ulting, .al-guard-anim, .al-mark, .al-overload, .al-combo-target::before, .al-gauge-full, .al-abtn-ult{ animation: none; }
}

/* ============================================================
   BOÎTE À RÉCOMPENSES — célébration inbox (chasse au mot & co.)
   Overlay plein écran AU-DESSUS DE TOUT (z-index > modales/gift), cliquable
   pour fermer, auto-fermé ~6 s. --ibc = couleur du style (or / élément).
   ============================================================ */
.inbox-overlay{
  position: fixed; inset: 0; z-index: 9600; display: none;
  align-items: center; justify-content: center; padding: 20px;
  background: radial-gradient(circle at 50% 42%,
    color-mix(in srgb, var(--ibc, #ffd76a) 16%, rgba(20, 12, 40, .86)),
    rgba(6, 8, 18, .94));
  cursor: pointer; /* tout l'overlay ferme au clic */
  opacity: 0; transition: opacity .3s ease;
}
.inbox-overlay.show{ display: flex; opacity: 1; }
.inbox-stage{ position: relative; width: 100%; max-width: 440px; text-align: center; }

/* Halo + rayons tournants derrière le panneau (teintés --ibc). */
.inbox-glow{
  position: absolute; left: 50%; top: 46%; width: 420px; height: 420px;
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--ibc, #ffd76a) 50%, transparent),
    color-mix(in srgb, var(--ibc, #ffd76a) 18%, transparent) 46%, transparent 70%);
  animation: inbox-glow-pulse 2.4s ease-in-out infinite;
}
@keyframes inbox-glow-pulse{
  0%, 100% { opacity: .5; transform: translate(-50%, -50%) scale(.92); }
  50%      { opacity: 1;  transform: translate(-50%, -50%) scale(1.12); }
}
.inbox-rays{
  position: absolute; left: 50%; top: 46%; width: 520px; height: 520px;
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none; opacity: .5;
  background: conic-gradient(from 0deg,
    transparent 0 16deg, color-mix(in srgb, var(--ibc, #ffd76a) 40%, transparent) 16deg 20deg,
    transparent 20deg 40deg, color-mix(in srgb, var(--ibc, #ffd76a) 26%, transparent) 40deg 43deg, transparent 43deg 60deg);
  -webkit-mask: radial-gradient(circle, transparent 26%, #000 44%, transparent 74%);
          mask: radial-gradient(circle, transparent 26%, #000 44%, transparent 74%);
  animation: inbox-rays-spin 10s linear infinite;
}
@keyframes inbox-rays-spin{ to { transform: translate(-50%, -50%) rotate(360deg); } }

/* Hôte des confettis (réutilise .gcf/gcf-fall du cadeau de fidélité). */
.inbox-confetti-host{ top: 4%; z-index: 7; }

/* Panneau central : anim d'entrée scale+fade + cadre rayonnant teinté. */
.inbox-panel{
  position: relative; z-index: 5; display: inline-block; max-width: 100%;
  padding: 22px 26px 20px; border-radius: 18px; cursor: default;
  background: linear-gradient(170deg, rgba(34, 26, 58, .96), rgba(16, 12, 32, .97));
  border: 1px solid color-mix(in srgb, var(--ibc, #ffd76a) 65%, transparent);
  box-shadow: 0 0 34px color-mix(in srgb, var(--ibc, #ffd76a) 45%, transparent),
              inset 0 1px 0 rgba(255, 255, 255, .12);
  opacity: 0; transform: translateY(26px) scale(.82);
  transition: opacity .45s ease, transform .45s cubic-bezier(.2, .8, .3, 1.25);
  animation: inbox-frame-glow 2.2s ease-in-out infinite;
}
.inbox-overlay.show .inbox-panel{ opacity: 1; transform: none; }
@keyframes inbox-frame-glow{
  0%, 100% { box-shadow: 0 0 26px color-mix(in srgb, var(--ibc, #ffd76a) 38%, transparent), inset 0 1px 0 rgba(255,255,255,.12); }
  50%      { box-shadow: 0 0 46px color-mix(in srgb, var(--ibc, #ffd76a) 62%, transparent), inset 0 1px 0 rgba(255,255,255,.12); }
}
.inbox-title{
  margin: 0 0 10px; font-size: 1.3rem;
  color: color-mix(in srgb, var(--ibc, #ffd76a) 70%, #fff);
  text-shadow: 0 2px 10px rgba(0, 0, 0, .55);
}
.inbox-msg{ margin: 0 0 14px; color: var(--text); font-size: .98rem; line-height: 1.45; }
/* Carte octroyée (brique tradeRevealCardHTML) : centrée + halo de rareté. */
.inbox-panel .trade-reveal-card{
  margin: 0 auto 6px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--rc, #ffd76a) 60%, transparent),
              0 0 28px color-mix(in srgb, var(--rc, #ffd76a) 45%, transparent);
}
/* Repli si la carte n'est pas (encore) au catalogue local : nom seul. */
.inbox-card-mini{
  display: inline-block; margin: 4px auto 8px; padding: 8px 16px; border-radius: 12px;
  font-weight: 700; color: var(--text);
  background: rgba(255, 255, 255, .07);
  border: 1px solid color-mix(in srgb, var(--ibc, #ffd76a) 45%, transparent);
}
.inbox-points{
  margin: 10px 0 4px; font-size: 1.35rem; font-weight: 800; color: #9cff7a;
  text-shadow: 0 0 14px rgba(120, 255, 140, .45);
}
.inbox-points span{ font-size: .85rem; font-weight: 600; color: var(--text-dim); }
.inbox-points .pts-coin{ width: 1.15em; height: 1.15em; vertical-align: -.18em; }
.inbox-close{ margin-top: 14px; }
@media (prefers-reduced-motion: reduce){
  .inbox-overlay, .inbox-panel{ transition: none; }
  .inbox-glow, .inbox-rays, .inbox-panel{ animation: none; }
  .inbox-rays, .inbox-confetti-host{ display: none; }
}
/* PERF mobile : les rayons rotatifs + le pulse de box-shadow du cadre coûtent cher au scroll.
   On les coupe (rayons masqués, plus de pulse), en GARDANT l'entrée transform/opacity du panneau. */
@media (hover: none), (max-width: 820px){
  .inbox-rays{ display: none; }
  .inbox-panel{ animation: none; }
}

/* ============================================================
   🃏 DECKS & PARTAGE (?v=20260704a)
   ------------------------------------------------------------
   1) Bandeau « Mes équipes » du team builder (lobby temps réel)
   2) Profil public (?u=) : en-tête + « Équipe favorite »
   3) Classement : lien vers le profil public
   ============================================================ */

/* ── 1) Bandeau « Mes équipes » ── */
.tbk-band{
  margin: 10px 0 14px; padding: 10px 12px; border-radius: 14px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
}
.tbk-title{ font-weight: 700; font-size: .9rem; margin-bottom: 8px; color: var(--text-dim, #aab); }
.tbk-slots{ display: flex; flex-wrap: wrap; gap: 8px; }
.tbk-slot{ display: flex; align-items: stretch; gap: 4px; min-width: 0; }
.tbk-slot-empty{
  padding: 8px 12px; border-radius: 10px; border: 1px dashed rgba(255, 255, 255, .14);
  color: var(--text-muted, #778); font-size: .82rem; display: flex; align-items: center;
}
.tbk-load{
  display: flex; align-items: center; gap: 8px; padding: 6px 10px; min-width: 0;
  border-radius: 10px; border: 1px solid rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .05); color: inherit; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.tbk-load:hover{ border-color: rgba(255, 255, 255, .35); background: rgba(255, 255, 255, .09); }
.tbk-thumbs{ display: inline-flex; gap: 2px; flex: none; }
.tbk-thumb{
  width: 26px; height: 34px; border-radius: 5px; object-fit: cover; object-position: top;
  background: rgba(0, 0, 0, .35); display: inline-flex; align-items: center; justify-content: center;
}
.tbk-thumb-missing{ color: var(--text-muted, #778); font-weight: 700; font-size: .8rem; }
.tbk-name{ font-size: .84rem; font-weight: 600; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tbk-incomplete{ font-size: .72rem; color: #ffca28; white-space: nowrap; }
.tbk-del{
  border: 1px solid rgba(255, 255, 255, .1); background: rgba(255, 255, 255, .04);
  border-radius: 10px; cursor: pointer; padding: 0 8px; font-size: .85rem; color: var(--text-muted, #778);
}
.tbk-del:hover{ color: #ff8a80; border-color: rgba(255, 138, 128, .5); }
.tbk-saverow{ display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }
.tbk-save-label{ font-size: .84rem; font-weight: 700; }
.tbk-name-input{
  flex: 1 1 150px; min-width: 120px; padding: 7px 10px; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, .14); background: rgba(0, 0, 0, .25);
  color: inherit; font: inherit; font-size: .85rem;
}
.tbk-save{ padding: 6px 10px; font-size: .82rem; }

/* ── 2) Profil public (?u=) ── */
.pp-wrap{
  grid-column: 1 / -1; margin: 0 0 14px; padding: 14px 16px; border-radius: 16px;
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(255, 255, 255, .09);
}
.pp-head{ font-size: .95rem; margin-bottom: 4px; }

/* 👤 Bannière « profil public de X — vue visiteur » (mode ?u=) : contexte
   NON AMBIGU affiché en permanence au-dessus de la grille, pseudo mis en avant. */
.pp-banner{ display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.pp-banner-ico{
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 1.35rem;
  background: color-mix(in srgb, var(--neon-1) 16%, rgba(0, 0, 0, .35));
  border: 1px solid color-mix(in srgb, var(--neon-1) 45%, transparent);
  box-shadow: 0 0 18px -6px var(--neon-1);
}
.pp-banner-main{ flex: 1 1 220px; min-width: 0; }
.pp-banner-title{ font-size: 1.02rem; line-height: 1.35; }
.pp-banner-title .pp-who{
  font-family: var(--font-ui); font-size: 1.02em; letter-spacing: .4px;
  color: var(--neon-1); text-shadow: 0 0 12px color-mix(in srgb, var(--neon-1) 55%, transparent);
}
.pp-banner-tag{
  display: inline-block; margin-left: 6px; padding: 2px 10px; border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .5px; vertical-align: middle;
  color: #ffd76a; background: rgba(255, 215, 106, .10);
  border: 1px solid rgba(255, 215, 106, .45);
  white-space: nowrap;
}
.pp-banner-stats{ margin-top: 4px; font-size: .88rem; color: var(--text-dim); }
.pp-banner-btn{ flex: 0 0 auto; white-space: nowrap; }
.pp-team-head{ margin: 10px 0 10px; font-weight: 700; }
.pp-team-cards{ display: flex; flex-wrap: wrap; gap: 10px; }
.pp-card{
  width: 128px; border-radius: 12px; padding: 8px; text-align: center;
  background: rgba(0, 0, 0, .25);
  border: 1px solid color-mix(in srgb, var(--rc, #888) 55%, transparent);
  box-shadow: 0 0 14px -8px var(--rc, transparent);
}
/* 👑 La MAÎTRESSE d'un deck sauvegardé : liseré doré + bandeau, distincte des 4 combattantes. */
.pp-card-master{
  border-color: #ffd257 !important;
  box-shadow: 0 0 0 1px #ffd257, 0 0 18px -6px #ffd257 !important;
}
.pp-card-crown{
  margin: -2px -2px 6px; padding: 3px 6px; border-radius: 999px;
  font-size: .6rem; font-weight: 800; letter-spacing: .02em; color: #3a2700;
  background: linear-gradient(180deg, #ffe08a, #f0a92e);
}
.pp-card-artbox{
  position: relative; height: 112px; border-radius: 8px; overflow: hidden;
  background: rgba(255, 255, 255, .05); margin-bottom: 6px;
  display: flex; align-items: center; justify-content: center;
}
.pp-card-art{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.pp-card-fallback{ font-size: 1.6rem; font-weight: 800; color: var(--text-muted, #778); }
.pp-card-lock{ font-size: 2rem; font-weight: 800; color: var(--text-muted, #778); }
.pp-card-locked{ border-style: dashed; }
.pp-card-name{ font-size: .82rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-card-meta{ margin: 4px 0; }
.pp-card-atks{ display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.pp-atk{
  font-size: .72rem; padding: 3px 6px; border-radius: 8px;
  background: color-mix(in srgb, var(--el, #667) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--el, #667) 45%, transparent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pp-team-note{ margin: 10px 0 0; font-size: .78rem; color: var(--text-muted, #778); }

/* ============================================================
   🃏 ESPACE « DECKS » (modale « Mes Decks » + visionneuse ?deck=…)
   Les cartes réutilisent .pp-card ; une carte NON découverte par le
   visiteur reprend le style « déjà vue/relâchée » de la grille
   (.card-seen : art grisé + voile) — même classe, même rendu.
   ============================================================ */
/* Silhouette grisée : mêmes valeurs de filtre que .card-seen .card-art (grille) */
.card-seen .pp-card-art{ filter: grayscale(1) brightness(.5) contrast(.95); }
.pp-card.card-seen{ border-color: rgba(255, 255, 255, .18); box-shadow: none; }
.pp-card .card-seen-veil{
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(8, 10, 20, .35), rgba(8, 10, 20, .6));
}
.pp-card .card-seen-tag{ margin-left: 4px; }

/* ─────────────────────────────────────────────────────────────────────────────
   👁 LISIBILITÉ DE « MES DECKS » (2026-08-04) — retour admin : « le visuel est à
   revoir sur certains points », « les informations sur la carte, pas ouf ».
   -----------------------------------------------------------------------------
   CE QUI N'ALLAIT PAS, mesuré au navigateur sur le vrai balisage (decksBodyHTML) :
   1. `.dk-head` était un `flex` + `justify-content:space-between` + `flex-wrap`. Le
      NOM et les 4 boutons se partageaient la MÊME ligne : avec un nom court les
      boutons étaient collés à droite, avec un nom long ils basculaient sous le nom.
      Deux emplacements côte à côte n'avaient donc pas la même mise en page — l'œil
      ne trouvait aucune colonne à suivre. → GRILLE à 2 colonnes fixes : le titre à
      gauche (il tronque), les actions à droite (elles ne bougent JAMAIS).
   2. Le nom du deck (.95rem, poids hérité) pesait exactement autant que « Partager
      ce deck ». Le seul repère de l'écran ne ressortait pas. → titre à 1.05rem/800
      en --text, la ligne d'aide passe en retrait.
   3. Aucune séparation entre l'en-tête et les pastilles : un pâté. → filet + espace.
   4. Les pastilles neutres visaient `var(--text-secondary)`, INEXISTANTE (cf. :root) :
      elles héritaient donc de --text, la couleur du titre. Tout était au même niveau
      de contraste. L'alias est défini, et `.ok` (état NORMAL, « 4/4 », « Maîtresse »)
      s'efface au profit de `.warn`, la seule qui doit alerter.
   ⚠️ Rien ici ne dépend du JS : mêmes classes, même ordre, aucun balisage attendu
   en plus. dex.js n'est pas touché.
   ───────────────────────────────────────────────────────────────────────────── */
.dk-slots{ display: flex; flex-direction: column; gap: 14px; }
.dk-slot{
  padding: 14px 16px; border-radius: 14px;
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(255, 255, 255, .09);
}
.dk-slot-empty{
  border-style: dashed; color: var(--text-muted);
  font-size: .88rem; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 20px 16px;
}
/* 2 colonnes : titre (tronqué) | actions (largeur naturelle, jamais renvoyées à la ligne). */
.dk-head{ display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 10px 12px; }
.dk-name{
  min-width: 0; display: flex; align-items: baseline; gap: 7px;
  font-size: 1.05rem; line-height: 1.35; color: var(--text-dim);
}
.dk-name b{
  font-weight: 800; color: var(--text); letter-spacing: .01em;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dk-actions{ display: inline-flex; align-items: center; gap: 6px; justify-self: end; }
.dk-share{ padding: 6px 10px; font-size: .82rem; white-space: nowrap; }
/* Cible tactile de 32 px minimum (les deux icônes faisaient 26 px de haut). */
.dk-icon{
  background: transparent; border: 1px solid rgba(255, 255, 255, .18); color: var(--text-dim);
  border-radius: 8px; cursor: pointer; font-size: .9rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; min-height: 32px; padding: 0 8px;
  transition: border-color .15s, color .15s, transform .12s;
}
.dk-icon:hover{ color: #fff; border-color: rgba(255, 255, 255, .4); transform: translateY(-1px); }
.dk-icon:disabled{ opacity: .5; cursor: not-allowed; }
.dk-cards{ justify-content: flex-start; }
.dk-footer{ margin-top: 18px; text-align: center; }
.dk-footer .btn{ margin-top: 8px; }
.dk-view-head{ font-size: 1rem; margin-bottom: 12px; }
.dk-login-note{ color: var(--neon-1, #7cf); }
.dk-edit{ padding: 6px 10px; font-size: .82rem; white-space: nowrap; }
/* Étroit : les actions repassent sous le titre, mais ALIGNÉES À GAUCHE sous lui —
   pas « parfois à droite, parfois dessous » selon la longueur du nom. */
@media (max-width: 620px){
  .dk-head{ grid-template-columns: minmax(0, 1fr); }
  .dk-actions{ justify-self: start; flex-wrap: wrap; }
}

/* ── 🛠 Constructeur de deck (espace « Decks ») ── */
.dkb-head{ display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; }
/* ⚠️ Le badge d'emplacement portait --neon-purple. La palette de cette feuille est
   pourtant explicite (cf. :root) : « les --neon-* restent l'identité des CARTES », le
   chrome utilise --chrome-*. Un badge d'interface en néon carte, posé juste au-dessus
   d'une grille de vraies cartes, entrait en concurrence avec elles. Il passe au chrome. */
.dkb-slot-tag{
  font-weight: 800; font-size: .88rem; white-space: nowrap;
  padding: 5px 12px; border-radius: 999px; color: var(--text);
  background: color-mix(in srgb, var(--chrome-2) 22%, transparent);
  border: 1px solid color-mix(in srgb, var(--chrome-1) 45%, transparent);
}
.dkb-name{ flex: 1 1 160px; }
.dkb-count{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums; font-weight: 700; font-size: 1.05rem;
  color: var(--text-dim); white-space: nowrap;
}
/* « 4/4 » atteint : même vert que la pastille `ok` de « Mes Decks », sans la halo néon
   qui faisait baver le chiffre sur le fond sombre. Un seul vocabulaire pour « c'est bon ». */
.dkb-count.ok{ color: #7ee8a2; }
/* N° d'ordre (1-4) sur la vignette sélectionnée — remplace visuellement le ✓ */
.dkb-grid .trade-card[data-pos] .trade-card-check{ opacity: 0; }
.dkb-grid .trade-card[data-pos]::after{
  content: attr(data-pos);
  position: absolute; top: 34%; left: 50%; transform: translate(-50%, -50%);
  z-index: 4; width: 34px; height: 34px; border-radius: 50%;
  background: var(--rc, var(--neon-1)); color: #fff;
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums; font-size: 1.05rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 14px var(--rc, var(--neon-1));
  /* Lisibilité garantie même quand --rc est clair (Céleste = blanc) : liseré + contour du chiffre. */
  border: 2px solid rgba(0, 0, 0, .5);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .9), 0 0 3px rgba(0, 0, 0, .8);
  pointer-events: none;
}
/* Petits tags d'exemplaire (niveau / ✦ évoluée / langue) sous le nom */
.dkb-copy-tags{ display: flex; justify-content: center; gap: 4px; flex-wrap: wrap; }
.dkb-tag{
  font-size: .62rem; font-weight: 700; line-height: 1;
  padding: 2px 6px; border-radius: 999px;
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .14);
  color: var(--text-dim);
}
.dkb-tag-evo{ color: #ffd76a; border-color: rgba(255, 215, 106, .5); }
.dkb-tag-lang{ color: #b388ff; border-color: rgba(179, 136, 255, .5); }
.dkb-tag-passive{ color: #ffe9a8; border-color: rgba(255, 233, 168, .5); cursor: help; }
/* ⚠️ COLLANTE EN BAS (2026-07-30) : avec les vraies cartes (plus hautes que les anciennes
   vignettes), la grille poussait « Sauvegarder » SOUS l'écran — le joueur composait un deck
   complet et ne trouvait aucun bouton pour l'enregistrer. Elle reste désormais toujours
   visible, quelle que soit la hauteur de la grille. */
.dkb-actions{
  position: sticky; bottom: 0; z-index: 12;
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
  margin: 14px -4px -4px; padding: 12px 4px;
  background: linear-gradient(180deg, rgba(12,16,34,0), rgba(12,16,34,.96) 38%);
  border-top: 1px solid rgba(255, 255, 255, .10);
}
@media (max-width: 600px){
  .pp-team-cards.dk-cards{ gap: 7px; }
  .dk-cards .pp-card{ width: calc(50% - 4px); }
}

/* ── 👁 Volet d'inspection du constructeur : voir attaques + passif + stats AVANT de
   choisir. Desktop (> 820px) : colonne latérale collante dans une modale élargie.
   Mobile (≤ 820px) : tiroir fixé en bas d'écran (n'écrase pas la grille). ── */
.modal.modal-deck{ max-width: 900px; }
.dkb{ display: flex; align-items: flex-start; gap: 14px; }
.dkb-main{ flex: 1 1 auto; min-width: 0; }
.dkb-inspect{
  flex: 0 0 264px; position: sticky; top: 0;
  max-height: 72vh; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--surface-2) transparent;
  background: var(--surface-2, rgba(255, 255, 255, .04));
  border: 1px solid var(--border, rgba(255, 255, 255, .14));
  border-radius: 14px; padding: 12px;
}
.dkb-inspect[hidden]{ display: none !important; }
/* 👁 sur chaque vignette (coin haut-gauche) */
.dkb-info{
  position: absolute; top: 4px; left: 4px; z-index: 5;
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; line-height: 1; cursor: pointer;
  background: rgba(6, 10, 22, .72); border: 1px solid rgba(255, 255, 255, .28);
  transition: transform .12s ease, border-color .15s ease;
}
.dkb-info:hover{ transform: scale(1.12); border-color: var(--neon-1); }
/* ═══════════════════════════════════════════════════════════════════════════════
   🃏 SÉLECTEUR DE DECK — VISUEL OFFICIEL DES CARTES
   La grille porte `.bb-skin` : arena-board.css (la feuille du TAPIS) habille alors ses
   `.card` exactement comme en combat — holo par rareté compris. Toutes ses règles sont
   dans `:where(...)` (spécificité NULLE), donc les règles ci-dessous imposent la taille
   et la mise en page sans le moindre !important.
   ═══════════════════════════════════════════════════════════════════════════════ */
.dkb-grid.bb-skin{
  /* Cartes ≥ celles du tapis (182px) : en dessous, les attaques deviennent illisibles. */
  grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
  gap: 14px; max-height: 46vh; align-items: start;
}
/* L'enveloppe cliquable s'effface : la CARTE est le visuel. `align-items:stretch` est
   IMPÉRATIF — avec `center`, l'enveloppe se réduit au contenu et comme tout l'intérieur de
   la carte est en position absolue, la largeur s'effondrait à ~2px. */
.dkb-grid.bb-skin .trade-card{
  background: none; border: 0; padding: 0; gap: 6px; align-items: stretch;
  border-radius: 14px;
}
.dkb-grid.bb-skin .trade-card:hover{ transform: translateY(-3px); box-shadow: none; }
.dkb-grid.bb-skin .cw{ display: block; width: 100%; }
/* Taille pilotée ICI (le tapis, lui, dimensionne en vh pour tenir à l'écran — pas ce qu'on
   veut dans une grille qui défile). La chaîne enveloppe→.cw→.card doit être continue. */
.dkb-grid.bb-skin .card,
.dkb-grid.bb-skin .card.active{
  width: 100%; display: block; cursor: pointer;
  box-shadow: 0 10px 20px -12px #000, 0 0 14px -8px var(--rc, transparent);
}
/* Carte sélectionnée / maîtresse : liseré franc directement sur la carte. */
.dkb-grid.bb-skin .trade-card.is-selected .card{ box-shadow: 0 0 0 3px var(--neon-1), 0 12px 22px -12px #000; }
.dkb-grid.bb-skin .trade-card.is-master .card{ box-shadow: 0 0 0 3px #ffd257, 0 0 20px -6px #ffd257; }
.dkb-grid.bb-skin .trade-card.is-inspected{ outline: none; }
.dkb-grid.bb-skin .trade-card.is-inspected .card{ outline: 2px solid var(--neon-1); outline-offset: 2px; }
/* Attaques LISIBLES : le tapis les met en .5rem/.48rem (calibré pour SA carte de 182px).
   ⚠️ SPÉCIFICITÉ : arena-board.css est chargé APRÈS dex.css, donc à égalité de poids c'est
   LUI qui gagne. Ses règles étant en `:where()` (poids 0) sur `.card.active .cardatks b`
   → (0,3,1) ; on passe donc par l'ID #dkbGrid pour prendre le dessus proprement. */
#dkbGrid .cardatks{ font-size: .6rem; }
#dkbGrid .card.active .cardatks b{ font-size: .64rem; }
#dkbGrid .card.active .cardatks em{ font-size: .6rem; }
#dkbGrid .card.active .cardatks u{ font-size: .58rem; }
#dkbGrid .card.active .nm{ font-size: .86rem; }
#dkbGrid .card.active .rar{ font-size: .6rem; }
#dkbGrid .card.active .hp b{ font-size: 1rem; }
#dkbGrid .card.active .hp i{ font-size: .58rem; }
#dkbGrid .card.active .st{ font-size: .66rem; }
/* Badge d'ordre (1..4) : au-dessus de la carte, pas derrière. */
.dkb-grid.bb-skin .trade-card[data-pos]::after{ z-index: 8; top: 42%; }
/* 👁 et 👑 par-dessus l'illustration. */
.dkb-grid.bb-skin .dkb-info{ z-index: 9; }
.dkb-grid.bb-skin .dkb-crown{ position: relative; z-index: 9; width: 100%; margin: 0; }
.dkb-grid.bb-skin .dkb-copy-tags{ margin-top: -2px; }
@media (max-width: 560px){
  /* 152px minimum : en dessous les noms d'attaques deviennent illisibles sur mobile. */
  .dkb-grid.bb-skin{ grid-template-columns: repeat(auto-fill, minmax(152px, 1fr)); gap: 10px; }
}

/* 🃏 FICHE CARTE — le VISUEL OFFICIEL (carte du tapis) en grand, centré.
   Titre / citation / rareté détaillée passent SOUS la carte (cd-meta). */
.cd-official{ display: flex; flex-direction: column; align-items: center; gap: 14px; }
.cd-official-card{ width: min(300px, 78vw); }
.cd-official.bb-skin .cw{ display: block; width: 100%; }
.cd-official.bb-skin .card,
.cd-official.bb-skin .card.active{
  width: 100%; display: block;
  box-shadow: 0 18px 34px -18px #000, 0 0 22px -8px var(--rc, transparent);
}
/* Grande carte (300px) → le texte du tapis (calibré pour 182px) y paraissait minuscule.
   Même souci de spécificité que la grille : on chaîne `.card.active` pour dépasser
   `:where(...) .card.active .cardatks b` d'arena-board.css, chargé après. */
.cd-official.bb-skin .card.active .cardatks{ font-size: .74rem; }
.cd-official.bb-skin .card.active .cardatks b{ font-size: .78rem; }
.cd-official.bb-skin .card.active .cardatks em{ font-size: .74rem; }
.cd-official.bb-skin .card.active .cardatks u{ font-size: .72rem; }
.cd-official.bb-skin .card.active .nm{ font-size: 1.12rem; }
.cd-official.bb-skin .card.active .rar{ font-size: .74rem; }
.cd-official.bb-skin .card.active .hp b{ font-size: 1.18rem; }
.cd-official.bb-skin .card.active .hp i{ font-size: .68rem; }
.cd-official.bb-skin .card.active .st{ font-size: .84rem; }
.cd-official.bb-skin .card.active .el{ width: 32px; height: 32px; font-size: 17px; }
.cd-official .cd-meta{ width: 100%; text-align: center; }
.cd-official-sub{ font-size: .95rem; font-style: italic; color: var(--text-secondary); }
.cd-official-quote{ margin-top: 4px; font-size: .9rem; color: var(--text-dim); font-style: italic; }
.cd-official .cd-chips{ justify-content: center; margin-top: 10px; }
/* Compteur d'exemplaires (×3) sur la carte officielle — pendant du PV, côté gauche. */
.dkc-copies{
  position: absolute; top: 5px; left: 5px; z-index: 4;
  padding: 1px 6px; border-radius: 999px;
  font-size: .62rem; font-weight: 800; color: #06101c;
  background: linear-gradient(180deg, #9be7ff, #35b6e8);
  box-shadow: 0 0 10px -3px #35b6e8;
}

/* 🃏 « Mes Decks » — RÉSUMÉ compact (plus de cartes : cet écran sert à choisir, pas à admirer).
   Une ligne de pastilles : nombre de cartes, maîtresse, et alerte si le deck est injouable. */
.dk-summary{
  display: flex; flex-wrap: wrap; gap: 7px; align-items: center;
  /* Sépare l'état du deck de son en-tête : sans ce filet, titre, boutons et pastilles
     formaient un seul pâté de 3 lignes sans respiration. */
  margin-top: 12px; padding-top: 11px; border-top: 1px solid rgba(255, 255, 255, .07);
}
.dk-chip{
  padding: 4px 11px; border-radius: 999px;
  font-size: .78rem; font-weight: 600; line-height: 1.3; white-space: nowrap;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12);
  color: var(--text-secondary);
}
/* ok = le deck va bien. C'est l'état NORMAL : il s'annonce, il ne crie pas — plus de
   fond teinté, juste le texte vert. warn garde le fond : c'est la seule qui alerte. */
.dk-chip.ok{ color: #7ee8a2; border-color: rgba(126, 232, 162, .30); background: transparent; }
.dk-chip.warn{ color: #ffc46b; font-weight: 700; border-color: rgba(255, 196, 107, .50); background: rgba(255, 196, 107, .12); }

/* ⚔️ Attaques affichées DIRECTEMENT sur la vignette (plus besoin d'ouvrir l'œil pour composer). */
.dkb-atks{ display: flex; flex-direction: column; gap: 2px; width: 100%; padding: 2px 4px 0; }
.dkb-atks-empty{ font-size: .6rem; color: var(--text-dim); text-align: center; font-style: italic; }
.dkb-atk{
  display: flex; align-items: center; justify-content: space-between; gap: 4px;
  font-size: .6rem; line-height: 1.25; padding: 1px 5px; border-radius: 5px;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .10);
}
.dkb-atk-n{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); }
.dkb-atk-p{ flex: none; font-weight: 800; color: var(--text-primary); font-variant-numeric: tabular-nums; }
/* 👑 VRAI bouton « désigner maîtresse » : chip ÉTIQUETÉE sous les attaques, impossible à rater.
   Un clic bascule la carte en maîtresse, même si elle est déjà dans les 4. */
.dkb-crown{
  display: flex; align-items: center; justify-content: center; gap: 4px;
  width: calc(100% - 8px); margin: 3px 4px 1px; padding: 3px 6px;
  border-radius: 999px; font-size: .62rem; font-weight: 800; line-height: 1.2;
  cursor: pointer; color: #ffd257; letter-spacing: .02em;
  background: rgba(255, 210, 87, .08); border: 1px solid rgba(255, 210, 87, .55);
  transition: transform .12s ease, background .15s ease, color .15s ease;
}
.dkb-crown:hover{ transform: scale(1.04); background: rgba(255, 210, 87, .18); }
.dkb-crown.on{
  background: linear-gradient(180deg, #ffe08a, #f0a92e); border-color: #ffd257;
  color: #3a2700; box-shadow: 0 0 10px -2px #ffd257;
}
.dkb-grid .trade-card.is-inspected, .dkb-slot-thumb.is-inspected{ outline: 2px solid var(--neon-1); outline-offset: 1px; }
/* Contenu du volet */
.dki{ position: relative; display: flex; flex-direction: column; gap: 10px; }
.dki-close{
  position: absolute; top: -4px; right: -4px; z-index: 2;
  width: 28px; height: 28px; border-radius: 50%; font-size: .85rem; cursor: pointer;
  background: rgba(255, 255, 255, .06); border: 1px solid var(--border, rgba(255, 255, 255, .16));
  color: var(--text-dim); transition: color .15s, border-color .15s;
}
.dki-close:hover{ color: #fff; border-color: rgba(255, 255, 255, .45); }
.dki-top{ display: flex; gap: 10px; align-items: flex-start; padding-right: 26px; }
.dki-artbox{
  position: relative; flex: none; width: 74px; height: 96px; border-radius: 10px; overflow: hidden;
  border: 2px solid var(--rc, var(--neon-1)); background: rgba(0, 0, 0, .35);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 12px -6px var(--rc, var(--neon-1));
}
.dki-art{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.dki-id{ min-width: 0; }
.dki-name{ font-weight: 800; line-height: 1.3; margin-bottom: 6px; overflow-wrap: anywhere; }
.dki-tags{ display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.dki-sub{ display: flex; gap: 5px; margin-top: 6px; }
.dki .cd-wcstats{ margin-top: 0; }
.dki .cd-passive{ margin-top: 0; align-self: flex-start; }
.dki-toggle{ width: 100%; }
@media (max-width: 820px){
  .modal.modal-deck{ max-width: 100%; }
  .dkb{ display: block; }
  .dkb-inspect{
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 1400;
    flex: none; max-height: 62vh;
    border-radius: 16px 16px 0 0; border-bottom: none;
    background: var(--surface, #10131f);
    box-shadow: 0 -12px 32px rgba(0, 0, 0, .55);
    padding: 14px 14px calc(14px + env(safe-area-inset-bottom, 0px));
    animation: dkiUp .22s ease;
  }
}
@keyframes dkiUp{ from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
/* Récap du deck en cours : 4 slots + la maîtresse (clic = inspection).
   ⚠️ `flex-wrap: wrap` OBLIGATOIRE (mesuré au navigateur, 2026-08-04) : sans lui, à
   320 px de large (iPhone SE, écran de couverture d'un pliable) les 5 vignettes
   demandent 292 px pour 242 px disponibles — la 5ᵉ, c'est-à-dire la MAÎTRESSE, sortait
   du cadre, sans barre de défilement pour aller la chercher (overflow visible). La
   carte la plus structurante du deck était donc invisible ET inatteignable sur les
   écrans les plus étroits. Elle passe désormais à la ligne. */
.dkb-recap{ display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 10px; }
.dkb-slot-thumb{
  position: relative; flex: none; width: 52px; height: 66px;
  border-radius: 10px; overflow: hidden; padding: 0; cursor: pointer;
  border: 2px solid var(--rc, rgba(255, 255, 255, .18));
  background: rgba(255, 255, 255, .04);
  box-shadow: 0 0 10px -6px var(--rc, transparent);
  transition: transform .12s ease, box-shadow .15s ease;
}
button.dkb-slot-thumb:hover{ transform: translateY(-2px); box-shadow: 0 0 12px -4px var(--rc, var(--neon-1)); }
.dkb-slot-thumb img{ width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.dkb-slot-n{
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--rc, var(--neon-1)); color: #fff;
  font-size: .62rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  /* Idem badge de grille : lisible même sur rareté claire (Céleste). */
  border: 1px solid rgba(0, 0, 0, .5);
  text-shadow: 0 1px 1px rgba(0, 0, 0, .9);
}
.dkb-slot-el{
  position: absolute; right: 3px; bottom: 3px; width: 10px; height: 10px;
  border-radius: 50%; border: 1px solid rgba(0, 0, 0, .45);
}
.dkb-slot-free{
  display: flex; align-items: center; justify-content: center;
  border-style: dashed; cursor: default;
  color: var(--text-muted, #667); font-weight: 800; font-size: .8rem;
}

/* 👑 MAÎTRESSE dans le constructeur (2026-07-30). L'OR distingue le rôle de maîtresse
   de la couleur de rareté — c'est un rôle, pas une qualité de carte. */
.dkb-tag-master{ color: #2a1c00; background: linear-gradient(180deg, #ffe08a, #f0a92e); border-color: #f0a92e; }
/* Liseré doré sur la vignette désignée maîtresse (prime sur .is-selected). */
.trade-card.is-master{ border-color: #ffd257 !important; box-shadow: 0 0 0 1px #ffd257, 0 0 16px -4px #ffd257 !important; }
/* 5ᵉ emplacement du récap : la maîtresse (bordure dorée) + la case vide dorée. */
.dkb-slot-master{ border-color: #ffd257 !important; box-shadow: 0 0 0 1px #ffd257, 0 0 12px -4px #ffd257; }
.dkb-slot-master-free{ border-color: rgba(255, 210, 87, .55); color: #ffd257; }
.dkb-slot-crown{ background: linear-gradient(180deg, #ffe08a, #f0a92e); color: #3a2700; }
/* Boutons du volet d'inspection côte à côte (Ajouter/Retirer + 👑 Maîtresse). */
.dki-btns{ display: flex; gap: 8px; }
.dki-btns .dki-toggle{ flex: 1; }
.dki-master{ flex: 0 0 auto; border-color: #ffd257; color: #ffd257; }
.dki-master.on{ color: #2a1c00; background: linear-gradient(180deg, #ffd257, #f0a92e); border-color: #ffd257; }

/* ── 3) Classement : lien profil ── */
.lb-profile-link{ color: inherit; text-decoration: none; border-bottom: 1px dotted rgba(255, 255, 255, .25); }
.lb-profile-link:hover{ color: var(--chrome-1); border-bottom-color: currentColor; }

/* ============================================================
   ✨ BLOC D — SYSTÈME HOLO PAR PALIER (façon cartes Pokémon).
   Overlay .card-holo injecté par le JS UNIQUEMENT pour les raretés
   ≥ épique (grille, fiche carte, révélation d'échange).
   - ::before = nappe irisée (linéaire + conique, blend screen)
   - ::after  = grain scintillant (feTurbulence SVG inline en data-URI)
   PERF D'ABORD :
   - animations = transform / opacity uniquement (GPU-friendly) ;
   - permanentes RÉSERVÉES aux hautes raretés VISIBLES (.in-view) ;
   - épique/légendaire en grille : statique + réaction au survol ;
   - les effets riches vivent dans la FICHE (1 carte à la fois) ;
   - mobile (pointer coarse / ≤820px) : holo STATIQUE allégé, AUCUN
     grain en grille (pire cas : ~900 tuiles sur un téléphone) ;
   - prefers-reduced-motion : tout statique.
   La lisibilité prime : .card-overlay (nom/badges) est z-index 4,
   au-dessus du holo (z-index 2) — le brillant ne voile jamais le texte.
   ============================================================ */
.card-holo{
  position: absolute; inset: 0; z-index: 2;
  pointer-events: none; border-radius: inherit; overflow: hidden;
}
/* Nappe irisée : reflet holo multicolore, doux, par-dessus l'art. */
.card-holo::before{
  content: ''; position: absolute; inset: -35%;
  background:
    linear-gradient(115deg,
      transparent 18%, rgba(255, 255, 255, .035) 34%,
      rgba(0, 229, 255, .09) 43%, rgba(177, 77, 255, .09) 52%,
      rgba(255, 215, 106, .08) 61%, transparent 80%),
    conic-gradient(from 210deg at 50% 45%,
      rgba(255, 77, 141, .05), rgba(0, 229, 255, .07),
      rgba(177, 77, 255, .06), rgba(108, 255, 138, .05),
      rgba(255, 170, 60, .05), rgba(255, 77, 141, .05));
  mix-blend-mode: screen;
  opacity: .35;
  transform: translate3d(0, 0, 0);
  will-change: transform;
}
/* Grain scintillant : bruit feTurbulence inline (aucune image externe). */
.card-holo::after{
  content: ''; position: absolute; inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 160px 160px;
  mix-blend-mode: overlay;
  opacity: 0;
}

/* ── Paliers ──
   épique     : reflet discret (pas de grain) ;
   légendaire : reflet + grain scintillant ;
   mythique   : foil net + grain + (balayage dexShineLoop déjà en place) ;
   divine     : prisme appuyé + grain dense ;
   céleste    : identité BLANC + AURA CONSERVÉE (dexStarAura) — on la renforce
                d'un voile prismatique subtil + poussière d'étoiles blanche. */
.holo-epic::before{ opacity: .18; }
.holo-legendary::before{ opacity: .24; }
.holo-legendary::after{ opacity: .16; }
.holo-mythic::before{ opacity: .28; }
.holo-mythic::after{ opacity: .22; }
.holo-divine::before{
  opacity: .34;
  background:
    linear-gradient(115deg,
      transparent 14%, rgba(255, 255, 255, .05) 32%,
      rgba(0, 229, 255, .11) 42%, rgba(177, 77, 255, .12) 52%,
      rgba(255, 215, 106, .10) 62%, transparent 84%),
    conic-gradient(from 210deg at 50% 45%,
      rgba(255, 77, 141, .07), rgba(0, 229, 255, .09),
      rgba(177, 77, 255, .08), rgba(108, 255, 138, .06),
      rgba(255, 170, 60, .07), rgba(255, 77, 141, .07));
}
.holo-divine::after{ opacity: .26; }
.holo-celestial::before{
  opacity: .26;
  background:
    linear-gradient(115deg,
      transparent 20%, rgba(255, 255, 255, .10) 44%,
      rgba(255, 255, 255, .06) 52%, transparent 78%),
    conic-gradient(from 210deg at 50% 45%,
      rgba(255, 77, 141, .05), rgba(0, 229, 255, .06),
      rgba(177, 77, 255, .05), rgba(108, 255, 138, .04),
      rgba(255, 215, 106, .05), rgba(255, 77, 141, .05));
}
.holo-celestial::after{ opacity: .30; } /* poussière d'étoiles (grain blanc, blend overlay) */

/* ── Animations GRILLE : hautes raretés VISIBLES uniquement ── */
.card-owned.in-view .holo-mythic::before, .card-owned.in-view .holo-divine::before{ animation: holoDrift 7s ease-in-out infinite; }
.card-owned.in-view .holo-celestial::before{ animation: holoDrift 5.5s ease-in-out infinite; }
.card-owned.in-view .holo-legendary::after{ animation: holoSparkle 3.2s ease-in-out infinite; }
.card-owned.in-view .holo-mythic::after{ animation: holoSparkle 2.6s ease-in-out infinite; }
.card-owned.in-view .holo-divine::after, .card-owned.in-view .holo-celestial::after{ animation: holoSparkle 2.2s ease-in-out infinite; }
/* Épique/légendaire : le reflet ne bouge qu'au survol (grille épurée au repos). */
.card-owned:hover .card-holo::before{ animation: holoDrift 2.4s ease-in-out infinite; }

@keyframes holoDrift{
  0%, 100% { transform: translate3d(-5%, -3%, 0) rotate(.001deg); }
  50%      { transform: translate3d(5%, 3%, 0) rotate(.001deg); }
}
@keyframes holoSparkle{
  0%, 100% { opacity: .12; }
  50%      { opacity: .30; }
}

/* ── FICHE / RÉVÉLATION (1 carte à la fois) : effets pleine gloire ── */
.cd-card-art .card-holo::before, .trade-reveal-card .card-holo::before{ animation: holoDrift 6s ease-in-out infinite; }
.cd-card-art .holo-legendary::after, .cd-card-art .holo-mythic::after, .cd-card-art .holo-divine::after, .cd-card-art .holo-celestial::after, .trade-reveal-card .card-holo::after{ animation: holoSparkle 2.4s ease-in-out infinite; }

/* ── Garde-fous PERF MOBILE (pointer coarse / petite largeur) :
   holo STATIQUE allégé (une seule nappe linéaire, layer non agrandi),
   AUCUN grain dans la grille ; la fiche (1 carte) garde un grain statique. ── */
@media (hover: none), (max-width: 820px){
  .card-holo::before{
    inset: 0;
    background: linear-gradient(115deg,
      transparent 24%, rgba(0, 229, 255, .08) 44%,
      rgba(177, 77, 255, .08) 56%, transparent 78%);
    opacity: .30;
    animation: none !important;
    will-change: auto;
  }
  .card-holo::after{ display: none; }
  .cd-card-art .card-holo::after, .trade-reveal-card .card-holo::after{ display: block; opacity: .32; animation: none !important; }
}
/* Mouvement réduit : tout statique (le liseré garde le rendu, sans animation). */
@media (prefers-reduced-motion: reduce){
  .card-holo::before, .card-holo::after{ animation: none !important; }
}

/* ============================================================
   ✨ BLOC C/D — POLISH GLOBAL : accents lumineux cohérents (subtils),
   hiérarchie sidebar, boutons/badges. AUCUN changement structurel.
   ============================================================ */
/* Titres de section : petite barre dégradée sous le libellé. */
.side-title{
  position: relative; padding-bottom: 7px; margin-bottom: 10px;
  color: var(--text-dim);
}
.side-title::after{
  content: ''; position: absolute; left: 0; bottom: 0;
  width: 34px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--chrome-1), var(--chrome-2));
}
/* Marque : halo lavande discret (repli emoji si le logo ne charge pas). */
.brand-mark{ filter: drop-shadow(0 1px 3px rgba(139, 92, 246, .45)); }
/* Résumé de collection : le compteur principal ressort en lavande douce. */
.stats-summary strong{
  color: var(--chrome-1);
}
.progress-fill{ box-shadow: 0 0 8px rgba(139, 92, 246, .28); }
/* Boutons primaires : ombre douce lavande, sans halo néon. */
.btn-primary:hover{ box-shadow: 0 6px 22px rgba(139, 92, 246, .4); }
/* Champ de recherche actif : liseré lavande discret. */
.search:focus-visible{
  outline: none; border-color: var(--chrome-1);
  box-shadow: 0 0 0 3px rgba(167, 139, 250, .2);
}
/* Tête de modale : filet discret sous le titre. */
.modal-head{
  border-bottom: 1px solid color-mix(in srgb, var(--chrome-1) 20%, var(--border));
  box-shadow: 0 1px 0 color-mix(in srgb, var(--chrome-2) 16%, transparent);
}
/* Bannières de hub : icône en pastille + chevron plus présent au survol. */
.cmd-banner:hover .cmd-banner-go{ opacity: .95; color: var(--chrome-1); }
.cmd-banner:hover .cmd-banner-ico{ border-color: color-mix(in srgb, var(--chrome-1) 55%, transparent); box-shadow: 0 2px 10px -3px rgba(139, 92, 246, .5); }
/* Mobile : pas de glow permanent supplémentaire (coût paint), et le reflet
   qui balaie la barre de progression reste statique (anim infinie inutile). */
@media (hover: none), (max-width: 820px){
  .progress-fill{ box-shadow: none; }
  .progress-fill::after{ animation: none; }
}

/* ============================================================
   🔍 BLOC E — FICHE CARTE (carte sélectionnée) : lisibilité ++.
   Structure JS inchangée (gravures nameL/titleL/quoteL intactes) —
   uniquement du restylage des blocs existants.
   ============================================================ */
/* Grand art un peu plus généreux sur desktop. */
.cd-vitrine .cd-card-art{ width: min(340px, 86%); }
/* Exemplaire (slide du carrousel) : carte posée, mieux détachée. */
.cd-copy{
  background: rgba(255, 255, 255, .035);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 14px;
  padding: 12px 14px;
}
.cd-copy-head{
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.cd-copy-no{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums; font-size: .72rem; font-weight: 800;
  color: var(--text-dim);
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 999px; padding: 3px 9px;
}
.cd-copy-lvl{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .72rem; font-weight: 800;
  color: #ffd76a; background: rgba(255, 215, 106, .08);
  border: 1px solid rgba(255, 215, 106, .45);
  border-radius: 999px; padding: 3px 9px;
}
/* Attaques : lignes « carte » avec icônes d'élément déjà en place. */
.cd-atks{ display: flex; flex-direction: column; gap: 7px; }
.cd-atk{
  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 11px;
  background: rgba(0, 0, 0, .22);
  overflow: hidden;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cd-atk.is-open, .cd-atk:hover{
  border-color: color-mix(in srgb, var(--rc, var(--neon-1)) 55%, transparent);
  box-shadow: 0 0 14px -6px var(--rc, var(--neon-1));
}
.cd-atk-btn{ width: 100%; }
.cd-atk-name{ font-weight: 700; }
/* Passif : chip dorée, cohérente avec le bandeau de grille (cf-passive). */
.cd-passive{
  display: inline-block;
  margin-top: 10px;
  font-size: .86rem;
  color: #ffd76a;
  background: rgba(255, 215, 106, .07);
  border: 1px solid rgba(255, 215, 106, .38);
  border-radius: 999px;
  padding: 5px 12px;
}
/* Identité gravée (carte localisée) : filet discret à gauche. */
.cd-copy-loc{
  border-left: 2px solid rgba(179, 136, 255, .45);
  padding-left: 10px;
}
/* Citation du catalogue dans l'en-tête vitrine (italique, discrète). */
.cd-hero-quote{
  font-size: .8rem; font-style: italic; color: var(--text-dim);
  opacity: .9; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}

/* 👤 Pastille en mode aperçu (?u=) : profil CONSULTÉ, pas une session. */
.user-chip.is-preview{ flex-wrap: wrap; border: 1px dashed rgba(255, 215, 106, .45); border-radius: 12px; padding: 6px 8px; }
.user-chip-preview{
  flex: 1 0 100%; font-size: .68rem; font-weight: 700; letter-spacing: .4px;
  color: #ffd76a; opacity: .95;
}

/* ============================================================
   POLISH — enrichissement visuel doux (build 20260707h)
   Accents décoratifs cohérents (lavande --chrome-*), zéro néon.
   N'affecte ni les cartes (holo/auras/céleste), ni le daily,
   ni le deck builder, ni le logo. Bloc regroupé = audit/rollback simple.
   ============================================================ */

/* Logo de marque : léger halo lavande + réaction douce au survol */
.brand-logo{
  transition: transform .18s ease, box-shadow .2s ease;
}
.brand:hover .brand-logo{
  transform: translateY(-1px) scale(1.04);
  box-shadow: 0 4px 16px -4px rgba(139, 92, 246, .6);
}

/* Titres de section de la sidebar : petit filet lavande en tête (hiérarchie) */
.side-title{
  display: flex;
  align-items: center;
  gap: 9px;
}
.side-title::before{
  content: '';
  width: 3px; height: .95em;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--chrome-1), var(--chrome-2));
  box-shadow: 0 0 8px -1px rgba(139, 92, 246, .55);
  flex: 0 0 auto;
}

/* Pastilles de rareté (sidebar) : liseré discret pour les faire ressortir */
.rarity-stat .dot{ box-shadow: 0 0 6px currentColor, 0 0 0 2px rgba(255, 255, 255, .06); }

/* Bannières de hub : reflet doux au survol (en plus du lift existant) */
.cmd-banner::after{
  content: '';
  position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(120deg, transparent 40%, rgba(167, 139, 250, .12) 50%, transparent 60%);
  opacity: 0;
  transition: opacity .2s ease;
  pointer-events: none;
}
.cmd-banner:hover::after{ opacity: 1; }

/* Le fond fixe (parallaxe lavande) a déjà de la personnalité ; on renforce très
   légèrement la profondeur en haut de page sans virer au néon. Rien sur mobile
   (le fond y est déjà repassé en scroll pour la perf). */

/* Respect strict de prefers-reduced-motion pour TOUTES les nouveautés animées
   de ce build (sheen de progression, pulsation d'état, 2e anneau du spinner). */
@media (prefers-reduced-motion: reduce){
  .progress-fill::after, .state-loading p, .spinner::after{ animation: none; }
  .spinner::after{ display: none; }
}

/* ============================================================
   🎮 REFONTE « GAME UI » (build 20260710b)
   ------------------------------------------------------------
   Objectif : le chrome (panneaux, boutons, sidebar, en-têtes)
   ressemble à une interface de GACHA GAME moderne, plus à un site :
   - langage signature = coins CHANFREINÉS asymétriques (radius
     14px/4px en miroir) sur panneaux, boutons, chips ;
   - RUBANS de titre en dégradé lavande → violet profond
     (clip-path biseauté) sur les modales ;
   - menu de jeu dans la sidebar (hover = slide + barre d'accent) ;
   - boutons de jeu (dégradé, arête basse, éclat balayé au hover) ;
   - tuiles de hub avec équerres décoratives aux coins ;
   - barres HUD carrées à embout lumineux, chiffres en Orbitron.
   GARDE-FOUS : AUCUNE règle ne touche les cartes (.card*, holo-*,
   dex-r-*, dexStarAura, card-fav), ni le daily (dq-*), ni le deck
   builder (dkb-*), ni cd-passive. Anims = transform/opacity ou
   hover uniquement ; coupées sur tactile + reduced-motion.
   Bloc ADDITIF regroupé → audit / rollback simples.
   ============================================================ */
:root{
  /* Coins « tech » asymétriques (grand chanfrein ↔ coin serré) */
  --cut-panel: 18px 5px 18px 5px;
  --cut-btn: 13px 4px 13px 4px;
  --cut-chip: 9px 3px 9px 3px;
  /* Ruban de titre : lavande → violet profond (contraste AA sur blanc) */
  --ribbon-grad: linear-gradient(115deg, #7c3aed, #5b21b6 60%, #3b1478);
  --panel-line: color-mix(in srgb, var(--chrome-1) 30%, var(--border));
}

/* ── 1) EN-TÊTE / MARQUE : plaque de jeu derrière le logo ─────────── */
.sidebar .brand{
  position: relative;
  padding: 11px 13px;
  border-radius: var(--cut-panel);
  background:
    linear-gradient(120deg, rgba(167, 139, 250, .18), rgba(91, 33, 182, .22) 55%, rgba(24, 16, 48, .3)),
    linear-gradient(180deg, rgba(30, 23, 58, .92), rgba(16, 11, 34, .94));
  border: 1px solid color-mix(in srgb, var(--chrome-1) 34%, var(--border));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    inset 0 0 0 1px rgba(0, 0, 0, .28),
    0 8px 22px -12px rgba(0, 0, 0, .8);
}
/* Éclat diagonal figé (façon plaque de menu gacha) */
.sidebar .brand::after{
  content: '';
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg, transparent 52%, rgba(190, 165, 255, .13) 68%, transparent 84%);
}
.sidebar .brand-title{ font-size: 1.34rem; letter-spacing: .6px; }

/* Barre mobile : bandeau à dégradé anglé + filet lumineux dessous */
.mobile-topbar{
  background: linear-gradient(115deg, #1e1638 0%, #140e2b 55%, #170f30 100%);
  border-bottom: 1px solid color-mix(in srgb, var(--chrome-2) 45%, var(--border));
}
.mobile-topbar::after{
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, var(--chrome-1), transparent 65%);
  opacity: .6; pointer-events: none;
}

/* Sidebar : arête droite en dégradé (fond de menu de jeu) */
.sidebar{
  border-right: 1px solid transparent;
  border-image: linear-gradient(180deg,
    color-mix(in srgb, var(--chrome-1) 55%, transparent),
    var(--border) 35%, transparent 96%) 1;
}

/* ── 2) SÉPARATEURS ÉNERGIQUES (sections sidebar + footer) ────────── */
.side-section{ position: relative; border-top: 0; }
.side-section::before{
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg,
    var(--chrome-1), color-mix(in srgb, var(--chrome-2) 45%, transparent) 42%, transparent 92%);
  opacity: .5; pointer-events: none;
}
.stats-bar::before{ display: none; }
.footer{ border-top: 0; position: relative; }
.footer::before{
  content: '';
  position: absolute; top: 0; left: 8%; right: 8%; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--chrome-2) 60%, transparent), transparent);
}

/* ── 3) PANNEAU D'ACTIONS + MENU DE JEU (sidebar) ─────────────────── */
.dex-cmdbar{
  border-radius: var(--cut-panel);
  border: 1px solid var(--panel-line);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .03),
    inset 0 1px 0 rgba(255, 255, 255, .05),
    0 14px 38px rgba(0, 0, 0, .38);
}
.actions-note{ border-radius: var(--cut-chip); }
/* Bannières de commande = items de menu : chanfrein miroir + slide au hover */
.cmd-banner{ border-radius: 3px 12px 3px 12px; }
.cmd-banner:hover{
  transform: translateX(4px);
  border-color: var(--chrome-1);
  box-shadow:
    inset 3px 0 0 0 var(--chrome-1),
    0 6px 18px -6px rgba(139, 92, 246, .5);
}
.cmd-banner-ico{ border-radius: 8px 3px 8px 3px; }
/* Pilules .btn-cmd (Classements / Quêtes / Stats) : même langage */
.btn-cmd{ border-radius: 3px 11px 3px 11px; }
.btn-cmd:hover{ box-shadow: inset 3px 0 0 0 currentColor; }
.btn-cmd .cmd-ico{ border-radius: 7px 3px 7px 3px; }

/* ── 4) BOUTONS DE JEU (.btn) : chanfrein + arête + éclat balayé ──── */
.btn{
  border-radius: var(--cut-btn);
  letter-spacing: .3px;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
/* Éclat qui balaie le bouton au survol (transform only, hover only) */
.btn::after{
  content: '';
  position: absolute; top: -20%; bottom: -20%; left: 0; width: 42%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .3), transparent);
  transform: translateX(-160%) skewX(-18deg);
  transition: transform .5s ease;
  pointer-events: none;
}
.btn:hover::after{ transform: translateX(300%) skewX(-18deg); }
.btn:active{ transform: translateY(2px) scale(.99); }
/* Relief « touche de manette » : arête claire en haut, ombre d'arête en bas */
.btn-twitch{
  box-shadow:
    0 6px 22px rgba(145, 70, 255, .45),
    inset 0 1px 0 rgba(255, 255, 255, .22),
    inset 0 -2px 0 rgba(0, 0, 0, .3);
}
.btn-primary{
  box-shadow:
    0 6px 20px rgba(139, 92, 246, .32),
    inset 0 1px 0 rgba(255, 255, 255, .22),
    inset 0 -2px 0 rgba(0, 0, 0, .3);
}
.btn-action{
  box-shadow:
    0 6px 22px rgba(177, 77, 255, .35),
    inset 0 1px 0 rgba(255, 255, 255, .2),
    inset 0 -2px 0 rgba(0, 0, 0, .3);
}
.btn-logout{
  box-shadow:
    0 5px 18px rgba(226, 59, 78, .38),
    inset 0 1px 0 rgba(255, 255, 255, .18),
    inset 0 -2px 0 rgba(0, 0, 0, .3);
}
.btn-ghost:hover{ background: rgba(167, 139, 250, .07); }

/* ── 5) FILTRES / CHIPS / RECHERCHE : façon options de jeu ────────── */
.chip{ border-radius: var(--cut-chip); }
.chip.is-active{
  box-shadow:
    0 0 0 1px var(--chip-color, var(--chrome-1)),
    0 0 14px -5px var(--chip-color, var(--chrome-1));
}
.search{ border-radius: var(--cut-btn); }
.lang-switch{ border-radius: var(--cut-chip); }
.lang-switch button{ border-radius: 7px 3px 7px 3px; }
.sidebar-collapse, .sidebar-expand, .menu-toggle{ border-radius: var(--cut-btn); }
.user-chip{ border-radius: var(--cut-btn); }
.lb-pill{ border-radius: var(--cut-chip); }


/* ── 6) HUD : badge de points, compteurs, barres à embout lumineux ── */
.points-badge{
  border-radius: 4px 14px 4px 14px;
  background:
    repeating-linear-gradient(115deg, rgba(255, 255, 255, .03) 0 2px, transparent 2px 14px),
    linear-gradient(135deg, rgba(167, 139, 250, .18), rgba(91, 33, 182, .16));
  border: 1px solid color-mix(in srgb, var(--chrome-1) 46%, transparent);
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, .3),
    inset 0 1px 0 rgba(255, 255, 255, .09),
    0 6px 18px -8px rgba(139, 92, 246, .45);
}
.rarity-stat b{
  font-family: var(--font-num); font-variant-numeric: lining-nums tabular-nums;
  font-size: .85em;
  letter-spacing: .4px;
}
/* Barres de progression : piste carrée HUD + embout lumineux */
.progress{ border-radius: 5px; }
.progress-fill{ border-radius: 4px; }
.progress-fill::before, .q-progress-fill::before, .ps-mini-fill::before{
  content: '';
  position: absolute; top: 1px; bottom: 1px; right: 1px; width: 7px;
  border-radius: 3px;
  background: radial-gradient(closest-side at 55% 50%, rgba(255, 255, 255, .95), rgba(255, 255, 255, 0));
  pointer-events: none;
}
.q-progress-fill, .ps-mini-fill{ position: relative; }
.q-progress, .q-progress-fill, .ps-mini-bar, .ps-mini-fill, .ps-rar-track, .ps-rar-fill{ border-radius: 5px; }

/* ── 7) MODALES : ruban de titre biseauté + tête dégradée ─────────── */
.modal{ border-radius: 12px 4px 12px 4px; }
.modal.shop-framed{ border-radius: var(--radius); } /* la boutique BOIS garde son cadre */
.modal:not(.shop-framed) .modal-head{
  background: linear-gradient(180deg, rgba(124, 58, 237, .12), rgba(124, 58, 237, 0));
  border-bottom: 1px solid color-mix(in srgb, var(--chrome-1) 28%, var(--border));
  box-shadow: 0 1px 0 rgba(124, 58, 237, .16);
}
.modal:not(.shop-framed) .modal-title{
  display: inline-flex; align-items: center; gap: 8px;
  max-width: calc(100% - 46px);
  padding: 7px 24px 7px 14px;
  font-size: 1.02rem; letter-spacing: .6px;
  color: #fff;
  background: var(--ribbon-grad);
  border-radius: 6px 0 0 6px;
  clip-path: polygon(0 0, 100% 0, calc(100% - 13px) 100%, 0 100%);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .4);
}

/* ── 8) TUILES DE HUB : cadres + équerres décorées aux coins ──────── */
.modal.hub-modal{ border-radius: 14px 5px 14px 5px; }
.hub-tile{
  border-radius: 4px 16px 4px 16px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05);
}
/* Équerres « tech » aux 4 coins (statiques ; s'illuminent au survol) */
.hub-tile::after{
  content: '';
  position: absolute; inset: 7px; z-index: 1; pointer-events: none;
  background:
    linear-gradient(#d9cbff, #d9cbff) left top / 15px 2px,
    linear-gradient(#d9cbff, #d9cbff) left top / 2px 15px,
    linear-gradient(#d9cbff, #d9cbff) right top / 15px 2px,
    linear-gradient(#d9cbff, #d9cbff) right top / 2px 15px,
    linear-gradient(#d9cbff, #d9cbff) left bottom / 15px 2px,
    linear-gradient(#d9cbff, #d9cbff) left bottom / 2px 15px,
    linear-gradient(#d9cbff, #d9cbff) right bottom / 15px 2px,
    linear-gradient(#d9cbff, #d9cbff) right bottom / 2px 15px;
  background-repeat: no-repeat;
  opacity: .4;
  transition: opacity .2s ease;
}
.hub-tile:hover::after{ opacity: .95; }
.hub-tile:hover{ transform: translateY(-3px) scale(1.03); }
.hub-panel-title{
  font-family: var(--font-ui);
  font-size: .86rem; letter-spacing: .4px;
}
.hub-tile-badge, .cmd-banner .cmd-badge{ border-radius: 6px 2px 6px 2px; }

/* ── 9) ÉCRANS D'ÉTAT / LANDING : panneaux chanfreinés + équerres ─── */
.landing-card{ border-radius: 6px 26px 6px 26px; }
.landing-card::after{
  content: '';
  position: absolute; inset: 9px; z-index: 0; pointer-events: none;
  border-radius: inherit;
  background:
    linear-gradient(#b9a3fb, #b9a3fb) left top / 18px 2px,
    linear-gradient(#b9a3fb, #b9a3fb) left top / 2px 18px,
    linear-gradient(#b9a3fb, #b9a3fb) right bottom / 18px 2px,
    linear-gradient(#b9a3fb, #b9a3fb) right bottom / 2px 18px;
  background-repeat: no-repeat;
  opacity: .5;
}
.state-loading, .state-error{ border-radius: 6px 24px 6px 24px; }
.no-results{ border-radius: 4px 18px 4px 18px; }
.dex-preview-note, .pp-wrap{ border-radius: 4px 16px 4px 16px; }

/* ── 10) GARDES PERF / ACCESSIBILITÉ ──────────────────────────────── */
/* Tactile / mobile : pas d'éclat balayé ni de slide (aucun hover fiable),
   équerres affichées à leur opacité de repos. */
@media (hover: none), (max-width: 820px){
  .btn::after{ display: none; }
  .cmd-banner:hover{ transform: none; }
}
@media (prefers-reduced-motion: reduce){
  .btn::after{ display: none; }
  .cmd-banner, .cmd-banner:hover{ transform: none; }
}
/* Correctif : la barre mobile débordait de 10px de chaque côté (marge -28px
   héritée du padding bureau alors que .main passe à 18px en ≤820px) →
   défilement horizontal parasite. On aligne la marge sur le padding mobile. */
@media (max-width: 820px){
  .mobile-topbar{ margin: -28px -18px 18px; }
}

/* ---- CHOIX DE LA CARTE APRES UN K.O. (2026-07-23) ----
   Le moteur promouvait automatiquement la carte suivante du deck ; le joueur choisit
   desormais. Les cartes eligibles pulsent, un compte a rebours (20 s, aligne sur
   PROMO_TIMEOUT_MS du serveur) indique le delai avant choix automatique. */
#bbMe .bb-card.bb-promotable{
  cursor: pointer;
  border-color: #7cf0a0;
  animation: bbPromoPulse 1.1s ease-in-out infinite;
}
@keyframes bbPromoPulse{
  0%, 100% { box-shadow: 0 0 14px rgba(124, 240, 160, .55); }
  50%      { box-shadow: 0 0 30px rgba(124, 240, 160, .95); }
}
.bb-promo-ask{
  flex: 1 1 100%;
  text-align: center;
  font-weight: 800;
  font-size: .86rem;
  color: #bdf2d4;
  text-shadow: 0 0 12px rgba(124, 240, 160, .5);
}
.bb-promo-ask b{ color: #fff; }
@media (prefers-reduced-motion: reduce){
  #bbMe .bb-card.bb-promotable{ animation: none; }
}

/* ============================================================
   PLAYTEST ADMIN 2026-08-03 — LE SALON DE COMBAT PASSE EN PLEIN ÉCRAN
   ============================================================
   SYMPTÔME (mobile Android/Samsung, capture de l'administrateur) : le combat est
   enfermé dans la modale générique du Dex. Sur un écran de 412×915 la modale
   mesurait 376×805 (overlay `padding:18px` + `max-height:88vh`), soit 331 px de
   viewport JETÉS, et le plateau — que `fitBoard()` met à l'échelle du conteneur —
   se retrouvait réduit à une vignette : cartes minuscules, texte des attaques
   illisible. La référence donnée est le jeu de cartes Pokémon : le plateau occupe
   TOUT l'écran, sans chrome de fenêtre.

   CORRECTIF : quand (et seulement quand) la modale héberge `#bbRoot`, elle occupe
   100 % du viewport, sans marge ni bordure ni coins arrondis. `fitBoard()` calcule
   son échelle sur `window.innerHeight - top - reserve` et sur
   `scene.parentElement.clientWidth` : rendre la boîte hôte plus grande AGRANDIT
   mécaniquement le plateau, sans toucher une seule taille de carte ni de police.

   POURQUOI `100dvh` ET PAS `100vh`. Sur mobile `100vh` vaut la hauteur du viewport
   BARRE D'ADRESSE MASQUÉE : tant qu'elle est visible, le bas de la modale (la barre
   d'attaques, justement) passe sous le pli. `100dvh` suit la hauteur réellement
   visible, exactement comme `window.innerHeight` que lit `fitBoard()` — les deux
   mesures restent d'accord. La ligne `100vh` qui précède est le repli des moteurs
   sans `dvh` (elle est simplement écrasée là où `dvh` existe).

   PÉRIMÈTRE — LA CLASSE EST DÉDIÉE, PAS `.modal` GÉNÉRIQUE. `modal-board` n'est
   posée qu'en un seul endroit (dex.js, `openBattleBoard()`), et `modal-overlay-board`
   au même endroit. Boutique, quêtes, fiche carte, decks, hub : rendu INCHANGÉ.

   POURQUOI L'OVERLAY PORTE AUSSI UNE CLASSE. Le `padding:18px` et le centrage
   `align-items:center` vivent sur `.modal-overlay`, l'ANCÊTRE : sans crochet dessus
   il resterait 18 px de bordure noire tout autour du plein écran. On pose donc la
   classe en JS plutôt que d'écrire `.modal-overlay:has(.modal-board)` — `:has()` est
   utilisé ailleurs dans cette feuille pour du décor, pas pour la géométrie d'un
   combat qui doit tenir sur le navigateur du téléphone de l'administrateur.

   SPÉCIFICITÉ ASSUMÉE (3 classes = 0,3,0). Deux règles écrites AILLEURS visent la
   même boîte et doivent céder :
     · `css/arena-board.css` (feuille GÉNÉRÉE, ne pas y toucher) :
       `body .modal.modal-board{ max-width:min(1580px,94vw); max-height:95vh }`
       → (0,2,1), donc battue par (0,3,0). C'est voulu : sur PC le plein écran est
       strictement PLUS LARGE que 94vw/95vh, donc on n'y perd rien.
     · `dex.css` l.~6450 `.modal{ border-radius:12px 4px 12px 4px }` → (0,1,0).
   Et le bloc est en FIN de feuille : à spécificité égale il gagnerait de toute façon.

   « SUR PC, ÉLARGIS SANS DÉFORMER » : rien n'est étiré ici. `fitBoard()` applique un
   `scale(k)` UNIFORME (`k = min(k_hauteur, k_largeur)`) et le tapis reste borné par
   `.mat{ width:min(1500px,96vw,100%) }` : agrandir la fenêtre ne fait que remplacer
   des bandes noires par du tapis, jamais déformer une carte.
   ============================================================ */
.modal-overlay.modal-overlay-board{
  padding: 0;
  align-items: stretch;
  justify-content: stretch;
  /* Le plateau couvre l'intégralité de l'overlay : le flou de fond ne peut plus être
     vu, mais il resterait une couche de composition plein écran à repeindre à chaque
     frame d'animation du combat. On le coupe (gain net sur mobile). */
  background: #05070f;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.modal-overlay.modal-overlay-board > .modal.modal-board{
  width: 100%;
  max-width: none;
  height: 100vh;        /* repli : moteurs sans unités de viewport dynamiques */
  max-height: 100vh;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  border: none;
  border-radius: 0;
  box-shadow: none;
  /* `popIn` translate+scale une boîte plein écran : on voyait des bandes de fond
     apparaître sur les 4 côtés pendant 200 ms à l'ouverture du combat. */
  animation: none;
}
/* En-tête réduit au strict nécessaire : chaque pixel repris ici est un pixel de
   plateau en plus (fitBoard mesure `scene.getBoundingClientRect().top`). Le ✕ garde
   ses 34 px tactiles et reste en haut à droite, donc atteignable au pouce. */
.modal-overlay.modal-overlay-board > .modal.modal-board > .modal-head{
  flex: 0 0 auto;
  padding: 8px 12px;
}
.modal-overlay.modal-overlay-board > .modal.modal-board > .modal-head .modal-title{
  font-size: .95rem;
  padding: 5px 20px 5px 11px;
}
.modal-overlay.modal-overlay-board > .modal.modal-board > .modal-body{
  flex: 1 1 auto;
  min-height: 0;        /* sans ça un enfant flex refuse de descendre sous son contenu */
  padding: 0;
  /* `overflow-y:auto` fait calculer `overflow-x` à `auto` (règle CSS : un axe non
     `visible` force l'autre). En portrait le tapis déborde LÉGÈREMENT des côtés à
     dessein (cf. arena-board.css) : sans ce `hidden`, ce débord de quelques pixels
     produisait une barre de défilement horizontale et un balayage latéral parasite
     en plein combat. On le rogne au lieu de le faire défiler. */
  overflow-x: hidden;
  overscroll-behavior: contain;   /* pas de « pull-to-refresh » en tirant sur le plateau */
}
/* 📱 MOBILE : L'EN-TÊTE DISPARAÎT PENDANT LE COMBAT (retour admin 2026-08-07, capture
   à l'appui : « la partie du haut "salon de combat" est affichée, ça rend le jeu trop
   petit sur mobile »).
   MESURÉ sur la vraie page à 375×812 (dex.css + arena-board.css chargés) : le bandeau
   pesait 45 px sur 812, soit 5,5 % de la hauteur — et `fitBoard` dimensionne le plateau
   à partir de `scene.getBoundingClientRect().top`, donc ces 45 px sortaient DIRECTEMENT
   de l'échelle du jeu.
   POURQUOI ON PEUT LE SUPPRIMER SANS PIÉGER LE JOUEUR : la classe `.modal-board` n'est
   posée QUE quand le plateau est monté (dex.js, bbMountBoard) — jamais dans le salon
   d'attente, jamais sur les autres modales. Or à ce moment-là le plateau porte ses
   PROPRES sorties : « 🏳 Abandonner » dans sa barre de titre pendant la partie, et
   « Retour » (bbBackBtn → bbCloseAfterEnd) sur l'écran de fin. Le ✕ de l'en-tête était
   d'ailleurs déjà inopérant en combat actif : `dexFermetureCombatBloquee()` l'intercepte
   pour armer le bouton d'abandon. On retirait donc de la hauteur pour un bouton qui ne
   fermait rien.
   ⚠️ On garde le titre pour les lecteurs d'écran (`aria-modal` sans nom accessible
   laisserait la boîte anonyme) : il sort du flux au lieu d'être supprimé. */
@media (max-width: 760px){
  .modal-overlay.modal-overlay-board > .modal.modal-board > .modal-head{
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
  }
}
@media (min-width: 761px){
  .modal-overlay.modal-overlay-board > .modal.modal-board > .modal-head{ padding: 8px 12px; }
}

/* ============================================================================
   🃏 CONSTRUCTEUR DE DECK — CHÂSSIS SOBRE (2026-08-05)
   ----------------------------------------------------------------------------
   RETOUR ADMIN, mot pour mot : « la beauté du deck n'est vraiment pas bonne, on a
   l'impression que c'est un fourre-tout et pas un système de construction de deck ».
   Ce n'est pas une liste de bugs : c'est de la HIÉRARCHIE. Rien ici ne change une
   valeur d'équilibrage, n'ajoute une chaîne à traduire, ni ne touche à dex.js
   (mêmes classes, même ordre, même balisage — les rendus JS restent intacts).

   CE QUI CLOCHAIT, MESURÉ AU NAVIGATEUR SUR LE VRAI BALISAGE (deckBuilderBodyHTML,
   viewport 1280×900) :
     1. RIEN N'ÉTAIT ALIGNÉ SUR RIEN. Les six blocs de la colonne tombaient à x=211,
        mais la GRILLE DE CARTES — l'élément le plus visible de l'écran — tombait à
        x=215 (les 4 px de `padding` de `.trade-cards`), et la barre « Sauvegarder »
        débordait à 207 (son `margin:-4px`). Trois bords gauches différents.
     2. AUCUN RYTHME. Écarts verticaux relevés entre blocs consécutifs :
        10 / 10 / 10 / 0 / 10 px. Le « 0 » collait la seconde ligne d'aide à la barre
        de filtres : deux blocs qui n'ont rien à voir se retrouvaient soudés.
     3. UN CHÂSSIS QUI CRIE PLUS FORT QUE LES CARTES. Sur les 175 éléments qui ne sont
        PAS la carte elle-même : 17 couleurs de bordure, 21 ombres/lueurs distinctes,
        7 langages de coin. Chaque badge apportait sa teinte et son halo.
     4. DEUX ACCENTS QUI SE DISPUTENT LA MÊME CARTE. Une carte choisie recevait un
        anneau CYAN (`--neon-1`, mesuré `rgb(0,229,255) 0 0 0 3px`) tandis que sa
        rareté l'entourait déjà de sa propre couleur. L'œil ne savait plus quoi
        suivre. La maîtresse cumulait de son côté DEUX halos dorés (un sur
        l'enveloppe `.trade-card`, un sur la `.card`).
     5. AUCUNE FRONTIÈRE entre « mon équipe » (le récap des 4 + la maîtresse) et
        « ma collection » (la grille) : les deux flottaient sur le même fond.

   CE QU'ON POSE À LA PLACE — sobre et net, pas décoré :
     · UN rythme unique (`--dkb-rythme`) piloté par un `gap` de flex, plus aucune
       marge à la main ;
     · UN bord gauche unique : la grille est décalée de -4 px pour que le CONTENU
       des cartes tombe exactement sur celui du texte ;
     · TROIS filets seulement (sous l'en-tête, au-dessus des filtres, au-dessus des
       actions) et UNE seule surface remplie : le récap d'équipe. C'est lui la zone
       « mon équipe » ; tout ce qui suit le filet des filtres est « ma collection ».
     · UNE seule couleur d'accent dans la grille : LA RARETÉ. Le cyan disparaît du
       constructeur ; le lavande `--chrome-*` (déjà la couleur du chrome dans cette
       feuille) sert aux affordances d'interface, et l'or reste réservé au RÔLE de
       maîtresse. Trois vocabulaires nets au lieu de six qui se marchent dessus.
     · Les coins reprennent les jetons EXISTANTS (`--cut-panel`, `--cut-chip`) au
       lieu d'inventer un huitième rayon.
   Bloc placé en FIN DE FEUILLE et regroupé : audit et rollback en un seul geste.
   ============================================================================ */

/* ── 1) RYTHME VERTICAL — une seule valeur, partout ───────────────────────── */
/* 12 px : la plus petite valeur qui sépare encore franchement deux blocs. Elle sert
   AUSSI de retrait des deux filets (sous l'en-tête, au-dessus des filtres) : ils
   tombent à la même distance de part et d'autre, ce qui se lit comme une intention.
   ⚠️ POURQUOI PAS 16. Aérer coûte de la hauteur, et cette hauteur est prise SUR LA
   COLLECTION. Mesuré à 1280×900, volet fermé, pour une carte de 332,6 px de haut :
   à 16 px il ne restait que 197,2 px de grille au-dessus de la barre « Sauvegarder »
   (59 % d'une rangée), à 12 px on en a 215,7 (65 %). Référence d'avant : 294 px.
   C'est le prix assumé du châssis aéré : +61 px de hauteur totale (822 → 883). */
.dkb{ --dkb-rythme: 12px; }
.dkb-main{ display: flex; flex-direction: column; gap: var(--dkb-rythme); }
/* Les marges d'origine s'ajoutaient au `gap` et donnaient 10/10/10/0/10 : on les
   remet à zéro, le `gap` devient la SEULE source d'espacement. */
.dkb-main > .dkb-head,
.dkb-main > .dkb-recap,
.dkb-main > .pp-team-note,
.dkb-main > .dkb-toolbar{ margin: 0; }
/* Les DEUX paragraphes d'aide forment un seul propos : ils se resserrent à 6 px
   pour ne pas se lire comme deux sections distinctes. */
.dkb-main > .pp-team-note + .pp-team-note{ margin-top: calc(6px - var(--dkb-rythme)); }
/* Grille : le décalage de -4 px annule son propre `padding` de 4 px. Résultat, le
   bord des CARTES tombe sur le bord du texte, et l'ombre des cartes garde ses 4 px
   de dégagement (sans ce padding, `overflow-y:auto` la trancherait net). */
.dkb-main > .dkb-grid{ margin: 0 -4px; }

/* ── 2) EN-TÊTE : une ligne de titre, pas trois objets en compétition ─────── */
.dkb-head{
  gap: 12px;
  padding-bottom: var(--dkb-rythme);
  border-bottom: 1px solid var(--border);
}
/* Le n° d'emplacement était une pastille lavande PLEINE, posée juste au-dessus
   d'une grille de vraies cartes : elle jouait au badge alors qu'elle ne fait
   qu'étiqueter l'écran. Elle redevient ce qu'elle est — une légende. */
.dkb-slot-tag{
  padding: 0; border: 0; border-radius: 0; background: none;
  color: var(--text-faint);
  font-size: .72rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
/* Le champ « nom de l'équipe » prend au passage le coin des autres champs du site
   (`--cut-btn`, comme `.search`) : il était le seul objet de l'écran en 10 px. */
.dkb-name{ border-radius: var(--cut-btn); }
/* Il mesurait 441 px sur 570 et avalait toute la ligne : on le borne. ⚠️ SUR DESKTOP
   SEULEMENT — mesuré à 375 px, une base de 300 px ne tient pas sur la ligne, et
   `flex-wrap` renvoie alors le champ ET le compteur à la ligne : l'en-tête passait
   de 32 à 109 px de haut. Sous 561 px, on garde `flex:1 1 160px` (règle d'origine),
   qui range l'étiquette, le champ et « 4/4 » sur une seule ligne. */
@media (min-width: 561px){
  .dkb-name{ flex: 0 1 300px; }
}
/* « 4/4 » va se caler à droite : l'en-tête a enfin deux extrémités franches. */
.dkb-count{ margin-left: auto; }

/* ── 3) ZONE « MON ÉQUIPE » : la SEULE surface remplie de l'écran ─────────── */
.dkb-recap{
  gap: 10px; padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--cut-panel);
  background: rgba(255, 255, 255, .04);
}
/* Les vignettes gardent leur liseré de RARETÉ (c'est l'accent) et perdent leur
   halo : cinq halos côte à côte dans un cadre de 90 px, c'était de la buée. */
.dkb-slot-thumb{ border-radius: var(--cut-chip); box-shadow: none; }
button.dkb-slot-thumb:hover{ transform: translateY(-2px); box-shadow: none; }
.dkb-slot-master{ box-shadow: none; }

/* ── 4) LÉGENDE DES RÔLES : deux lignes lisibles, plus un pavé ────────────── */
.dkb-main > .pp-team-note{ font-size: .79rem; line-height: 1.45; color: var(--text-faint); }
/* Les deux règles structurantes (l'ORDRE, la MAÎTRESSE) coulaient dans le même
   paragraphe : une par ligne, chacune avec son emoji en tête de ligne. */
.dkb-role-line{ display: block; }
.dkb-role-line b{ color: var(--text-secondary); font-weight: 700; }
.dkb-master-pick{ margin-top: 7px; padding: 6px 12px; font-size: .8rem; }

/* ── 5) ZONE « MA COLLECTION » : filet d'entrée + une grille qu'on peut PARCOURIR ─ */
/* `.dkb-toolbar` n'existe QUE sur le constructeur : les pickers d'échange, qui
   partagent `.trade-toolbar`, ne sont pas touchés. */
.dkb-toolbar{ padding-top: var(--dkb-rythme); border-top: 1px solid var(--border); }
/* 📏 RECHERCHE ET « FILTRES & TRI » SUR LA MÊME LIGNE (desktop).
   `.trade-toolbar` empile ses deux contrôles en colonne, pleine largeur chacun. Sur un
   téléphone c'est juste ; dans la modale du constructeur, large de 848 px, le champ de
   recherche seul en mange 637 et le bouton replié 137 — les deux tiennent côte à côte,
   et la ligne perdue était payée par la GRILLE, qui est la seule chose qu'on regarde ici.
   MESURÉ (1280×900, deck complet) : haut de la grille 630 → 586 px, soit 44 px rendus ;
   première rangée visible au-dessus de la barre d'actions 134 → 178 px, c'est-à-dire
   43 % → 57 % d'une carte de 309,7 px. Le panneau déplié garde sa pleine largeur
   (`flex-basis:100%` → il passe à la ligne, 848 px mesurés, 24 chips, sans débordement).
   ⚠️ Sous 821 px on ne touche à rien : c'est là que l'empilement est le bon choix, et
   c'est aussi le seuil du volet 👁 (qui rétrécit la colonne de contenu). */
@media (min-width: 821px){
  .dkb-toolbar{ flex-direction: row; align-items: center; flex-wrap: wrap; column-gap: 10px; }
  .dkb-toolbar > .trade-toolbar-search{ flex: 1 1 240px; width: auto; min-width: 0; }
  .dkb-toolbar > .trade-toolbar-chips{ flex: 0 0 auto; }
  .dkb-toolbar > #dkbFilters{ flex: 1 1 100%; }
}
/* ⚠️ DEUX CARTES PAR LIGNE, MESURÉ À 1280×900. Le plancher de 186 px se retournait
   contre la grille dès que le volet 👁 s'ouvrait : la colonne de contenu tombe alors
   à ~555 px, où `auto-fill` ne loge que DEUX pistes (3×186 + 2×14 = 586 > 555). Les
   deux cartes s'étiraient à 266,5 × 432,3 px — on ouvrait une fiche et on perdait la
   moitié de sa collection de vue. À 172 px, la même colonne loge TROIS pistes
   (3×172 + 2×14 = 544 ≤ 555) : 175,7 × 300,5 px mesurés, soit 50 % de cartes
   visibles en plus pendant qu'on compare.
   Volet FERMÉ — l'état par défaut, colonne de 833 px — le compte ne bouge pas :
   4 pistes avec 186 comme avec 172 ((833+14)/(172+14) = 4,55 → 4). Mesuré 195,8 px
   avant / 197,8 px après, les 2 px venant du réalignement de -4 px ci-dessus, pas de
   cette ligne. Elle ne touche donc QUE le cas pathologique, jamais l'écran d'accueil.
   ⚠️ SOUS `min-width:561px` UNIQUEMENT. Le plancher MOBILE (152 px, l. ~5900) vit dans
   un `@media (max-width:560px)` situé PLUS HAUT dans la feuille, à spécificité égale
   (0,2,0) : sans cette condition, la règle de fin de feuille le remplacerait et les
   cartes du téléphone repasseraient à 172 px. */
@media (min-width: 561px){
  .dkb-grid.bb-skin{ grid-template-columns: repeat(auto-fill, minmax(172px, 1fr)); }
}

/* ── 6) UNE SEULE COULEUR D'ACCENT : LA RARETÉ ────────────────────────────── */
/* Carte choisie : l'anneau prend la couleur de la RARETÉ, et non plus le cyan
   générique `--neon-1` (mesuré avant : `rgb(0,229,255) 0 0 0 3px`). */
.dkb-grid.bb-skin .trade-card.is-selected .card{
  box-shadow: 0 0 0 3px var(--rc, var(--chrome-1)), 0 12px 22px -12px #000;
}
/* …et l'ENVELOPPE se tait : elle portait un second halo de rareté (0 0 16px -2px)
   par-dessus l'anneau ci-dessus. Deux fois la même information sur le même objet.
   L'enveloppe est invisible dans cette grille (ni fond ni bordure) : son rayon
   s'aligne quand même sur les autres pastilles, pour n'avoir qu'un seul langage. */
.dkb-grid.bb-skin .trade-card{ border-radius: var(--cut-chip); }
.dkb-grid.bb-skin .trade-card.is-selected{ box-shadow: none; }
/* Le n° d'ordre reste un disque plein à la couleur de rareté ; son halo de 14 px
   bavait sur la carte voisine. Le liseré noir suffit à le détacher. */
.dkb-grid .trade-card[data-pos]::after{ box-shadow: none; }
/* Maîtresse : UN seul halo doré (celui de la carte), plus celui de l'enveloppe. */
.dkb-grid.bb-skin .trade-card.is-master{ box-shadow: none !important; }
/* Inspection (👁) : c'est une affordance d'INTERFACE, pas une qualité de carte —
   elle passe au lavande du chrome et ne concurrence plus la rareté. */
.dkb-grid .trade-card.is-inspected,
.dkb-slot-thumb.is-inspected{ outline-color: var(--chrome-1); }
.dkb-grid.bb-skin .trade-card.is-inspected .card{ outline-color: var(--chrome-1); }
.dkb-info:hover{ border-color: var(--chrome-1); }
/* Les trois petits tags (niveau / ✦ évoluée / langue) apportaient trois liserés de
   trois couleurs. Le TEXTE garde sa couleur, le cadre devient neutre. */
.dkb-tag,
.dkb-tag-evo,
.dkb-tag-lang,
.dkb-tag-passive{ border-color: rgba(255, 255, 255, .14); border-radius: var(--cut-chip); }
/* 👑 au repos : contour seul. Elle ne s'allume qu'une fois DÉSIGNÉE (`.on`, inchangée). */
.dkb-crown{ border-radius: var(--cut-chip); background: transparent; border-color: rgba(255, 210, 87, .38); }
.dkb-crown:hover{ background: rgba(255, 210, 87, .16); }

/* ── 7) BARRE D'ACTIONS COLLANTE ──────────────────────────────────────────── */
/* Elle se fondait vers `rgba(12,16,34,…)`, une couleur que la modale n'a nulle part
   (sa surface est `--surface`) : on voyait un rectangle plus froid glisser sur le
   fond. Et son filet, tiré de bord à bord, dépassait de 4 px des deux côtés. */
.dkb-actions{
  margin: 0 -4px -4px;
  padding: 12px 4px calc(4px + env(safe-area-inset-bottom, 0px));
  justify-content: flex-end;
  border-top: 0;
  background: linear-gradient(180deg, rgba(28, 21, 51, 0), var(--surface) 40%);
}
/* Le filet est dessiné en retrait de 4 px : il tombe pile sur le bord du texte. */
.dkb-actions::before{
  content: ''; position: absolute; left: 4px; right: 4px; top: 0; height: 1px;
  background: var(--border);
}
/* ⚠️ 7 bis) LA BARRE DOIT ALLER JUSQU'AU BORD DU CONTENEUR QUI DÉFILE.
   `.modal-body` porte `padding: 20px` (l. 2481). Avec `bottom: 0`, la barre se colle au
   bord de la BOÎTE DE CONTENU du conteneur, pas à son bord de PADDING : il restait dessous
   une bande de 20 px, hors de la barre mais toujours dans la zone qui défile — et les
   cartes y glissaient À NU sous les boutons.
   MESURÉ (1280×900, grille réelle de 12 cartes, modale qui défile sur 296 px) : bas de la
   barre 825 px, bord du conteneur 845 px, bande de 20,0 px, 8 éléments de carte (noms
   d'attaques, plaques de passif) visibles dedans à l'ouverture. APRÈS : bande 0,0 px,
   plus aucun élément visible sous la barre, à toutes les positions de défilement.
   Le décalage `--dkb-scrollpad` DOIT valoir le padding de `.modal-body` : `bottom` le
   descend jusqu'au bord de padding, le `padding-bottom` de la barre repeint la bande, et
   la marge négative annule la hauteur ajoutée pour que les boutons ne bougent pas. */
.dkb{ --dkb-scrollpad: 20px; }      /* = padding de .modal-body (l. 2481) */
.dkb-actions{
  bottom: calc(-1 * var(--dkb-scrollpad));
  padding-bottom: calc(4px + var(--dkb-scrollpad) + env(safe-area-inset-bottom, 0px));
  margin-bottom: calc(-4px - var(--dkb-scrollpad));
}

/* ── 8) VOLET D'INSPECTION (desktop) ──────────────────────────────────────── */
/* ⚠️ SOUS `min-width:821px` UNIQUEMENT : en dessous, le volet devient un TIROIR
   fixé en bas d'écran, avec `border-radius:16px 16px 0 0`. Ce bloc étant en fin de
   feuille, une règle non conditionnée lui arrondirait les coins du BAS et le
   décollerait visuellement du bord de l'écran. */
@media (min-width: 821px){
  .dkb-inspect{ border-radius: var(--cut-panel); }
}
/* Contenu du volet : même vocabulaire de coins que la grille, et l'imagette perd son
   halo (le liseré de rareté dit déjà tout, dans un panneau de 264 px de large). */
.dki-artbox{ border-radius: var(--cut-chip); box-shadow: none; }
.dkb-atk{ border-radius: var(--cut-chip); }

/* ── 9) ÉTROIT : actions pleine largeur, vignettes d'équipe sur une ligne ─── */
@media (max-width: 560px){
  /* DEUX BOUTONS PLEINE LARGEUR, EMPILÉS — et c'est un choix, pas un accident.
     Mesuré à 375 px (297 px utiles), `.btn` étant en `white-space:nowrap` :
       · deux colonnes égales (`flex:1 1 0`) → 142,5 px chacune, mais
         « 💾 Sauvegarder la sélection » réclame 200 px : le libellé se faisait
         TRANCHER — « auvegarder la séle » ;
       · en le laissant passer à la ligne, le bouton montait à 79,6 px de haut (3 lignes) ;
       · à leur largeur naturelle, retrait réduit à 12 px : 241 + 88 + 10 = 339 > 297,
         donc ils retombent quand même sur deux lignes, avec deux largeurs différentes.
     AVANT, le `justify-content:center` les centrait sur deux lignes de largeurs
     inégales : rien ne tombait droit. Ils s'empilent désormais sur toute la largeur,
     bord à bord avec le reste de la colonne, l'action principale en premier. */
  .dkb-actions .btn{ flex: 1 1 100%; min-width: 0; justify-content: center; }
  /* ⚠️ LES 5 VIGNETTES DOIVENT TENIR SUR UNE LIGNE DANS LE PANNEAU.
     La largeur FIXE de 46 px avait été calculée sur une colonne de 297 px, avant que
     l'étape ① ne devienne un panneau encadré (padding 12 + bordure 1 de chaque côté,
     posé côté dex.js). Il ne reste en réalité que 265,6 px : 5 × 45,1 + 4 × 10 = 265,5,
     soit 0,1 px de marge — et l'arrondi sous-pixel faisait repasser la MAÎTRESSE à la
     ligne. MESURÉ à 375×812 : 2 rangées (4 + 1), panneau du récap à 145 px, étape ① à
     363,6 px. On ne recalcule donc PLUS une largeur en dur : les vignettes se PARTAGENT
     la largeur disponible, quelle qu'elle soit, avec un plafond à la taille voulue.
     APRÈS : 1 rangée (5), vignettes à 42,5 px, récap 78,4 px, étape ① 296,9 px —
     66,7 px rendus à la grille, et le calcul ne repose plus sur une valeur à tenir
     à jour à la main. `nowrap` est sûr ici parce que les vignettes sont compressibles. */
  .dkb-recap{ gap: 8px; flex-wrap: nowrap; }
  .dkb-slot-thumb{ flex: 1 1 0; width: auto; min-width: 0; max-width: 56px; height: 58px; }
}
