/* ═════════════════════════════════════════════════════════════════════════════
   FOUDREBATTLE — IDENTITÉ VISUELLE
   ═════════════════════════════════════════════════════════════════════════════

   Direction : une salle de jeu clandestine à la nuit tombée. Feutre sombre,
   laiton patiné, néon électrique. Le site ne copie pas foudremagic.fr — seules
   les cartes gardent leurs codes de rareté, pour qu'un joueur les reconnaisse
   d'un site à l'autre.

   Trois partis pris :
     • le laiton (--or) porte l'identité, l'électrique (--arc) porte l'action ;
     • les angles sont coupés plutôt qu'arrondis : la table, les panneaux et
       les boutons partagent la même encoche en biseau ;
     • le fond n'est jamais uni — grain, halos et vignette donnent la
       profondeur d'une pièce éclairée par une seule lampe.
   ═════════════════════════════════════════════════════════════════════════════ */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* Orage de nuit — voir public/theme.css pour le reste du système */
  --police-titre: 'Bricolage Grotesque', 'Segoe UI', system-ui, sans-serif;
  --police-texte: 'Atkinson Hyperlegible', 'Segoe UI', system-ui, sans-serif;

  /* Matières */
  --nuit: #0d0e26;
  --nuit-2: #121436;
  --feutre: #171a42;
  --feutre-2: #1f2352;
  --panneau: rgba(160, 170, 255, .05);
  --panneau-h: rgba(160, 170, 255, .09);
  --liseré: rgba(160, 170, 255, .15);
  --liseré-fort: rgba(242, 193, 78, .45);

  /* Encres */
  --texte: #f2f1ff;
  --texte-2: #b2b5dd;
  --texte-3: #7b7fad;

  /* Accents */
  --or: #f2c14e;
  --or-vif: #ffd983;
  --arc: #6e8bff;
  --arc-vif: #9db2ff;
  --eclair: #7fe6ff;
  --sang: #ff5c7a;
  --menthe: #4be3a3;

  --coupe: 14px;
  /* profondeur de l'encoche en biseau */
  --ombre: 0 18px 50px rgba(0, 0, 0, .65);
}

/* Encoche partagée par la table, les panneaux et les boutons */
.biseau {
  clip-path: polygon(var(--coupe) 0, 100% 0, 100% calc(100% - var(--coupe)), calc(100% - var(--coupe)) 100%, 0 100%, 0 var(--coupe));
}

html {
  -webkit-font-smoothing: antialiased;
}

body {
  background: var(--nuit);
  color: var(--texte);
  font-family: var(--police-texte);
  font-size: 15px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* Halos + grain : le fond ne doit jamais paraître plat */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(900px 460px at 50% -12%, rgba(110, 139, 255, .16), transparent 68%),
    radial-gradient(620px 420px at 8% 108%, rgba(242, 193, 78, .08), transparent 70%),
    radial-gradient(620px 420px at 92% 108%, rgba(110, 139, 255, .07), transparent 70%);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .55;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

a {
  color: inherit;
}

/* ─────────────────────────────────────────────────────────────────────────────
   NAVIGATION
   ───────────────────────────────────────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 30;
  background: linear-gradient(180deg, rgba(8, 7, 12, .94), rgba(8, 7, 12, .72));
  backdrop-filter: blur(22px);
  border-bottom: 1px solid var(--liseré);
}

.nav::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--or), transparent);
  opacity: .5;
}

.nav-in {
  max-width: 1240px;
  margin: 0 auto;
  padding: 14px 24px;
  display: flex;
  align-items: center;
  gap: 1.4rem;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.06rem;
  letter-spacing: -.02em;
  text-decoration: none;
  text-transform: uppercase;
}

.brand-bolt {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, var(--or), #8a6d3c);
  color: var(--nuit);
  font-size: .9rem;
  clip-path: polygon(50% 0, 100% 32%, 100% 68%, 50% 100%, 0 68%, 0 32%);
  box-shadow: 0 0 18px rgba(242, 193, 78, .5);
}

.brand-accent {
  color: var(--or);
}

.nav-links {
  display: flex;
  gap: .15rem;
}

.nav-link {
  position: relative;
  font-size: .82rem;
  font-weight: 500;
  letter-spacing: .02em;
  text-decoration: none;
  color: var(--texte-3);
  padding: .45rem .85rem;
  transition: color .18s;
}

.nav-link::after {
  content: "";
  position: absolute;
  left: .85rem;
  right: .85rem;
  bottom: .18rem;
  height: 1px;
  background: var(--or);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .22s;
}

.nav-link:hover {
  color: var(--texte-2);
}

.nav-link:hover::after {
  transform: scaleX(1);
}

.nav-link.active {
  color: var(--or-vif);
}

.nav-link.active::after {
  transform: scaleX(1);
}

.nav-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: .7rem;
}

.nav-user {
  display: flex;
  align-items: center;
  gap: .6rem;
}

.nav-avatar {
  width: 32px;
  height: 32px;
  object-fit: cover;
  border: 1px solid var(--liseré-fort);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

.nav-name {
  font-size: .84rem;
  font-weight: 600;
  letter-spacing: .01em;
}

.nav-logout {
  text-decoration: none;
  color: var(--texte-3);
  font-size: .85rem;
  padding: .3rem .55rem;
  border: 1px solid var(--liseré);
  transition: all .18s;
}

.nav-logout:hover {
  color: var(--sang);
  border-color: rgba(224, 82, 79, .45);
}

.btn-twitch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .8rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .55rem 1.15rem;
  color: var(--nuit);
  background: linear-gradient(135deg, var(--or-vif), var(--or));
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  box-shadow: 0 6px 22px rgba(242, 193, 78, .32);
  transition: transform .18s, box-shadow .18s;
}

.btn-twitch:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 30px rgba(242, 193, 78, .5);
}

/* ─────────────────────────────────────────────────────────────────────────────
   STRUCTURE
   ───────────────────────────────────────────────────────────────────────────── */

.wrap {
  position: relative;
  z-index: 1;
  flex: 1;
  max-width: 1240px;
  width: 100%;
  margin: 0 auto;
  padding: 2.4rem 1.5rem 4rem;
}

.foot {
  position: relative;
  z-index: 1;
  max-width: 1240px;
  width: 100%;
  margin: 0 auto;
  padding: 1.2rem 1.5rem;
  border-top: 1px solid var(--liseré);
  font-size: .74rem;
  color: var(--texte-3);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.foot a {
  color: var(--texte-2);
}

/* ── Accueil ── */
.hero {
  text-align: center;
  padding: 3.4rem 0 2.8rem;
}

.hero h1 {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: clamp(2rem, 5.6vw, 3.4rem);
  line-height: 1.04;
  letter-spacing: -.035em;
  text-transform: uppercase;
}

.hero h1 em {
  font-style: normal;
  display: inline-block;
  background: linear-gradient(120deg, var(--or-vif), var(--or) 45%, var(--arc-vif));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 4px 26px rgba(242, 193, 78, .28));
}

.hero p {
  color: var(--texte-2);
  font-size: 1rem;
  max-width: 540px;
  margin: 1.2rem auto 0;
  line-height: 1.75;
}

.hero-cta {
  margin-top: 2rem;
  display: flex;
  gap: .7rem;
  justify-content: center;
  flex-wrap: wrap;
}

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1rem;
  margin-top: 3.4rem;
}

.step {
  position: relative;
  padding: 1.4rem;
  background: linear-gradient(160deg, var(--feutre-2), var(--feutre));
  border: 1px solid var(--liseré);
  clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px);
  transition: border-color .2s, transform .2s;
}

.step:hover {
  border-color: var(--liseré-fort);
  transform: translateY(-3px);
}

.step-n {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .74rem;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  margin-bottom: .85rem;
  color: var(--or);
  border: 1px solid var(--liseré-fort);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

.step h3 {
  font-family: var(--police-titre);
  font-size: .95rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  margin-bottom: .45rem;
}

.step p {
  font-size: .84rem;
  color: var(--texte-3);
  line-height: 1.6;
}

/* ── En-têtes de page ── */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.8rem;
}

.page-title {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.7rem;
  letter-spacing: -.02em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: .7rem;
}

.page-title::before {
  content: "";
  width: 4px;
  height: 1.5rem;
  background: linear-gradient(180deg, var(--or), transparent);
}

.page-sub {
  font-size: .84rem;
  color: var(--texte-3);
  margin-top: .3rem;
  padding-left: 1.4rem;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: .45rem .95rem;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--or-vif);
  border: 1px solid var(--liseré-fort);
  background: rgba(242, 193, 78, .07);
  clip-path: polygon(9px 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%, 0 9px);
}

/* ── Filtres ── */
.filters {
  display: flex;
  gap: .4rem;
  flex-wrap: wrap;
  margin-bottom: 1.6rem;
}

.filter {
  font-family: 'DM Sans', sans-serif;
  font-size: .78rem;
  font-weight: 500;
  padding: .38rem .9rem;
  cursor: pointer;
  color: var(--texte-3);
  background: var(--panneau);
  border: 1px solid transparent;
  transition: all .18s;
}

.filter:hover {
  background: var(--panneau-h);
  color: var(--texte-2);
}

.filter.active {
  color: var(--or-vif);
  border-color: var(--liseré-fort);
  background: rgba(242, 193, 78, .09);
}

/* ── Boutons ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .82rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .68rem 1.5rem;
  cursor: pointer;
  border: 1px solid transparent;
  clip-path: polygon(11px 0, 100% 0, 100% calc(100% - 11px), calc(100% - 11px) 100%, 0 100%, 0 11px);
  transition: transform .18s, box-shadow .18s, background .18s;
}

.btn-primary {
  background: linear-gradient(135deg, var(--or-vif), var(--or));
  color: var(--nuit);
  box-shadow: 0 6px 24px rgba(242, 193, 78, .3);
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 32px rgba(242, 193, 78, .48);
}

.btn-primary:disabled {
  opacity: .45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn-ghost {
  background: var(--panneau);
  border-color: var(--liseré);
  color: var(--texte-2);
}

.btn-ghost:hover {
  background: var(--panneau-h);
  color: var(--texte);
  border-color: var(--liseré-fort);
}

/* ─────────────────────────────────────────────────────────────────────────────
   CARTES DE COLLECTION
   ───────────────────────────────────────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 1.1rem;
}

.card {
  position: relative;
  isolation: isolate;
  padding: 11px;
  border: 1px solid var(--liseré);
  transition: transform .18s, border-color .18s;
}

/* Le biseau vit sur un calque de fond : appliqué à la carte elle-même, son
   clip-path rognait l'illustration agrandie au survol. */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(170deg, var(--feutre-2), var(--nuit-2));
  clip-path: polygon(13px 0, 100% 0, 100% calc(100% - 13px), calc(100% - 13px) 100%, 0 100%, 0 13px);
}

.card:hover {
  transform: translateY(-4px);
  border-color: var(--liseré-fort);
}

.card.selectable {
  cursor: pointer;
}

.card.picked {
  border-color: var(--or);
  box-shadow: 0 0 0 1px var(--or), 0 0 30px rgba(242, 193, 78, .28);
}

.card-img {
  width: 100%;
  aspect-ratio: 450/490;
  object-fit: contain;
  display: block;
  background: #05050a;
}

/* ── Cadre du zoom au survol ──
   La marge négative compense la réserve intérieure : l'illustration peut
   grandir de 35 % sans être rognée, et la carte garde sa taille dans la
   grille. Sans cette réserve, le zoom était coupé net. */
.img-wrap {
  position: relative;
  perspective: 2000px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
  padding: 30px;
  margin: -30px;
  z-index: 0;
}

@media (max-width: 640px) {
  .img-wrap {
    padding: 14px;
    margin: -14px;
  }
}

.img-wrap.is-zoomed,
.card.is-zoomed {
  z-index: 999 !important;
}

/* Texture de « glace fêlée » du foil : c'est elle qui donne le grain
   caractéristique de l'effet de foudremagic.fr, par-dessus l'arc-en-ciel. */
:root {
  --cracked-ice-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='white' fill-opacity='.18'%3E%3Cpolygon points='4,8 22,0 12,18'/%3E%3Cpolygon points='22,0 40,10 12,18'/%3E%3Cpolygon points='12,18 40,10 30,26'/%3E%3Cpolygon points='40,10 58,2 50,20'/%3E%3Cpolygon points='30,26 50,20 42,40'/%3E%3Cpolygon points='50,20 72,12 64,34'/%3E%3Cpolygon points='6,34 26,26 18,50'/%3E%3Cpolygon points='26,26 30,26 18,50'/%3E%3Cpolygon points='18,50 30,26 28,60'/%3E%3Cpolygon points='28,60 42,40 36,74'/%3E%3Cpolygon points='42,40 64,34 56,66'/%3E%3Cpolygon points='56,66 64,34 76,70'/%3E%3Cpolygon points='8,78 28,60 20,92'/%3E%3Cpolygon points='20,92 28,60 36,74'/%3E%3C/g%3E%3Cg fill='white' fill-opacity='.10'%3E%3Cpolygon points='0,24 12,18 6,34'/%3E%3Cpolygon points='58,2 120,0 72,12'/%3E%3Cpolygon points='64,34 120,34 76,70'/%3E%3Cpolygon points='0,92 8,78 0,120'/%3E%3C/g%3E%3C/svg%3E");
}

.foil-stage {
  position: relative;
  display: block;
  line-height: 0;
  width: 100%;
  /* C'est le support qui s'incline : image et reflet bougent d'un bloc. */
  transform-style: preserve-3d;
  will-change: transform;
  backface-visibility: hidden;
  transition: transform .22s cubic-bezier(.2, .9, .2, 1);
}

.foil-stage .card-img {
  transform-style: preserve-3d;
  will-change: transform;
  backface-visibility: hidden;
  transition: transform .22s cubic-bezier(.2, .9, .2, 1), box-shadow .22s cubic-bezier(.2, .9, .2, 1);
  position: relative;
  z-index: 2;
}

.foil {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  /* Repli si le rayon exact n'a pas encore été relevé : mieux vaut un arrondi
     approché qu'un calque franchement carré sur une carte arrondie. */
  border-radius: 10px;
  overflow: hidden;
  isolation: isolate;
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform .22s cubic-bezier(.2, .9, .2, 1), box-shadow .22s cubic-bezier(.2, .9, .2, 1);
  /* Position du reflet, intensité et teinte : alimentées par le pointeur */
  --fx: .55;
  --fy: .35;
  --fstr: .25;
  --fhue: 25deg;
}

.foil::before,
.foil::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  transition: opacity .22s ease-out;
}

/* Foil arc-en-ciel des légendaires holo — même composition que sur
   foudremagic.fr : un halo blanc suivant le pointeur, deux nappes arc-en-ciel
   décalées l'une par rapport à l'autre, et de fines stries. Ce sont les
   décalages différents de chaque nappe qui donnent l'impression de
   profondeur quand la carte s'incline. */
.foil::before {
  z-index: 3;
  opacity: calc(.16 + (var(--fstr) * .32));
  mix-blend-mode: screen;
  background:
    radial-gradient(520px 420px at calc(var(--fx)*100%) calc(var(--fy)*100%), rgba(255, 255, 255, .36), rgba(255, 255, 255, .06) 46%, transparent 74%),
    linear-gradient(105deg, rgba(255, 0, 170, .85), rgba(255, 60, 60, .78), rgba(255, 138, 0, .74), rgba(255, 230, 0, .70), rgba(43, 255, 136, .70), rgba(0, 240, 255, .74), rgba(43, 91, 255, .80), rgba(161, 43, 255, .86), rgba(255, 0, 170, .85)),
    linear-gradient(25deg, rgba(255, 0, 170, .70), rgba(255, 138, 0, .62), rgba(255, 230, 0, .58), rgba(43, 255, 136, .58), rgba(0, 240, 255, .62), rgba(43, 91, 255, .66), rgba(161, 43, 255, .70), rgba(255, 0, 170, .70)),
    repeating-linear-gradient(140deg, rgba(255, 255, 255, .10) 0px, rgba(255, 255, 255, .10) 2px, rgba(255, 255, 255, 0) 8px, rgba(255, 255, 255, 0) 18px);
  background-size: 100% 100%, 240% 240%, 220% 220%, 260% 260%;
  background-position:
    0 0,
    calc((1 - var(--fx))*70%) calc((1 - var(--fy))*70%),
    calc(var(--fx)*55%) calc(var(--fy)*55%),
    calc((1 - var(--fx))*35%) calc((1 - var(--fy))*35%);
  filter: saturate(2.10) contrast(1.06) hue-rotate(var(--fhue));
}

.foil::after {
  z-index: 4;
  opacity: calc(.10 + (var(--fstr) * .55));
  mix-blend-mode: color-dodge;
  background:
    linear-gradient(115deg, transparent 0%, rgba(255, 255, 255, .05) 32%, rgba(255, 255, 255, .26) 48%, rgba(255, 255, 255, .06) 64%, transparent 100%),
    var(--cracked-ice-svg), var(--cracked-ice-svg),
    linear-gradient(110deg, rgba(255, 0, 170, .55), rgba(255, 138, 0, .50), rgba(255, 230, 0, .45), rgba(43, 255, 136, .45), rgba(0, 240, 255, .50), rgba(43, 91, 255, .55), rgba(161, 43, 255, .55), rgba(255, 0, 170, .55)),
    radial-gradient(circle at 18% 30%, rgba(255, 255, 255, .14), transparent 28%),
    radial-gradient(circle at 72% 56%, rgba(255, 255, 255, .12), transparent 30%),
    radial-gradient(circle at 46% 82%, rgba(255, 255, 255, .10), transparent 32%);
  background-size: 240% 240%, 85% 85%, 65% 65%, 190% 190%, 100% 100%, 100% 100%, 100% 100%;
  background-position:
    calc((1 - var(--fx))*70%) calc((1 - var(--fy))*70%),
    calc(var(--fx)*95%) calc(var(--fy)*95%),
    calc((1 - var(--fx))*35%) calc((1 - var(--fy))*35%),
    calc((1 - var(--fx))*55%) calc((1 - var(--fy))*55%),
    0 0, 0 0, 0 0;
  filter: saturate(2.35) contrast(1.06) hue-rotate(var(--fhue));
}

/* Au repos : le foil reste visible, en retrait */
.foil[data-active="0"]::before { opacity: .22; }
.foil[data-active="0"]::after { opacity: .14; mix-blend-mode: overlay; }

.card-img-empty {
  aspect-ratio: 450/490;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--panneau);
  color: var(--texte-3);
  font-size: 1.4rem;
  border: 1px dashed var(--liseré);
}

.card-rarity {
  font-family: var(--police-titre);
  font-size: .6rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  margin: 9px 0 3px;
}

.card-name {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .88rem;
  line-height: 1.25;
}

.card-foot {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin-top: 8px;
  flex-wrap: wrap;
}

.card-qty {
  font-size: .72rem;
  font-weight: 600;
  color: var(--texte-3);
  border: 1px solid var(--liseré);
  padding: .08rem .45rem;
}

.card-event {
  font-size: .62rem;
  font-weight: 700;
  color: var(--or);
  border: 1px solid var(--liseré-fort);
  padding: .08rem .45rem;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Raretés — seuls codes repris de foudremagic.fr, pour la reconnaissance */
.rarity-common {
  border-color: rgba(148, 163, 184, .22);
}

.rarity-rare {
  border-color: rgba(59, 130, 246, .32);
  box-shadow: 0 0 22px rgba(59, 130, 246, .12);
}

.rarity-epic {
  border-color: rgba(168, 85, 247, .32);
  box-shadow: 0 0 24px rgba(168, 85, 247, .14);
}

.rarity-legendary {
  border-color: rgba(245, 158, 11, .38);
  box-shadow: 0 0 30px rgba(245, 158, 11, .16);
}

.rarity-legendary_holo {
  border-color: rgba(34, 211, 238, .38);
  box-shadow: 0 0 34px rgba(34, 211, 238, .14), 0 0 18px rgba(255, 0, 255, .1);
}

.rarity-limited {
  border-color: rgba(255, 255, 255, .42);
  box-shadow: 0 0 26px rgba(0, 0, 0, .9), inset 0 0 40px rgba(0, 0, 0, .8);
}

.rarity-limited_holo {
  border-color: rgba(255, 255, 255, .62);
  box-shadow: 0 0 34px rgba(0, 0, 0, .95), 0 0 22px rgba(255, 255, 255, .18), inset 0 0 44px rgba(0, 0, 0, .85);
}

.rarity-common .card-rarity {
  color: #94a3b8;
}

.rarity-rare .card-rarity {
  color: #60a5fa;
}

.rarity-epic .card-rarity {
  color: #c084fc;
}

.rarity-legendary .card-rarity {
  color: #fbbf24;
}

.rarity-legendary_holo .card-rarity {
  background: linear-gradient(90deg, #22d3ee, #f0abfc);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.rarity-limited .card-rarity {
  color: #d4d4d8;
  text-shadow: 0 0 8px rgba(0, 0, 0, .9);
}

.rarity-limited_holo .card-rarity {
  background: linear-gradient(90deg, #fff, #71717a, #fff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ── Effets permanents des raretés limitées ──
   Le reflet vit sur un calque ::after : appliquer une animation à la carte
   elle-même écraserait celle de son apparition. */
@keyframes tileVoidRim {

  0%,
  100% {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .10);
  }

  50% {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .34);
  }
}

@keyframes tileSilverRim {
  0% {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .45);
  }

  25% {
    box-shadow: inset 0 0 0 1px rgba(113, 113, 122, .5);
  }

  50% {
    box-shadow: inset 0 0 0 1px rgba(228, 228, 231, .6);
  }

  75% {
    box-shadow: inset 0 0 0 1px rgba(63, 63, 70, .5);
  }

  100% {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .45);
  }
}

@keyframes tileSheen {
  0% {
    background-position: 220% 0;
    opacity: 0;
  }

  12% {
    opacity: 1;
  }

  55% {
    opacity: 1;
  }

  100% {
    background-position: -120% 0;
    opacity: 0;
  }
}

.card.rarity-limited::after,
.card.rarity-limited_holo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 42%, rgba(255, 255, 255, .26) 50%, transparent 58%);
  background-size: 220% 100%;
  background-repeat: no-repeat;
  animation: tileSheen 4.5s ease-in-out infinite, tileVoidRim 3.2s ease-in-out infinite;
}

.card.rarity-limited_holo::after {
  background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, .38) 50%, transparent 60%);
  background-size: 220% 100%;
  background-repeat: no-repeat;
  animation: tileSheen 3.2s ease-in-out infinite, tileSilverRim 4s linear infinite;
}

/* ── Foil obsidienne : reflet argenté qui suit la souris au zoom ── */
.foil.foil-void::before {
  opacity: calc(.14 + (var(--fstr) * .5));
  mix-blend-mode: screen;
  background:
    radial-gradient(560px 420px at calc(var(--fx)*100%) calc(var(--fy)*100%), rgba(255, 255, 255, .55), rgba(255, 255, 255, .06) 42%, transparent 72%),
    linear-gradient(105deg, rgba(255, 255, 255, .5), rgba(113, 113, 122, .25), rgba(0, 0, 0, .6), rgba(228, 228, 231, .45), rgba(0, 0, 0, .6), rgba(255, 255, 255, .5));
  background-size: 100% 100%, 240% 240%;
  background-position: 0 0, calc((1 - var(--fx))*70%) calc((1 - var(--fy))*70%);
  filter: saturate(0) contrast(1.2);
}

.foil.foil-void::after {
  opacity: calc(.08 + (var(--fstr) * .42));
  mix-blend-mode: color-dodge;
  background:
    linear-gradient(115deg, transparent 0%, rgba(255, 255, 255, .06) 34%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .06) 66%, transparent 100%),
    var(--cracked-ice-svg),
    radial-gradient(circle at 26% 34%, rgba(255, 255, 255, .16), transparent 30%),
    radial-gradient(circle at 70% 62%, rgba(255, 255, 255, .12), transparent 32%);
  background-size: 240% 240%, 78% 78%, 100% 100%, 100% 100%;
  background-position:
    calc((1 - var(--fx))*70%) calc((1 - var(--fy))*70%),
    calc(var(--fx)*95%) calc(var(--fy)*95%),
    0 0, 0 0;
  filter: saturate(0) contrast(1.15);
}

.foil.foil-void[data-active="0"]::before {
  opacity: .2;
}

.foil.foil-void[data-active="0"]::after {
  opacity: .12;
  mix-blend-mode: overlay;
}

/* ── États ── */
.empty {
  text-align: center;
  padding: 3.6rem 1.2rem;
  color: var(--texte-3);
  background: var(--panneau);
  border: 1px dashed var(--liseré);
}

.empty-icon {
  font-size: 2.4rem;
  margin-bottom: .9rem;
  opacity: .8;
}

.empty h3 {
  font-family: var(--police-titre);
  font-size: 1rem;
  color: var(--texte-2);
  margin-bottom: .5rem;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.alert {
  padding: .9rem 1.2rem;
  font-size: .86rem;
  line-height: 1.55;
  margin-bottom: 1.6rem;
  border-left: 3px solid;
}

.alert-err {
  background: rgba(224, 82, 79, .09);
  border-color: var(--sang);
  color: #f7b3b1;
}

.alert-warn {
  background: rgba(242, 193, 78, .09);
  border-color: var(--or);
  color: var(--or-vif);
}

.foot-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.dot {
  width: 7px;
  height: 7px;
  background: var(--texte-3);
}

.dot.on {
  background: var(--menthe);
  box-shadow: 0 0 10px rgba(74, 222, 128, .8);
}

[hidden] {
  display: none !important;
}

/* ═════════════════════════════════════════════════════════════════════════════
   L'ARÈNE — DES CARTES POSÉES SUR LA TABLE
   ═════════════════════════════════════════════════════════════════════════════

   La table est vue de haut, légèrement inclinée : on est penché au-dessus.
   Les cartes sont posées À PLAT dessus — elles partagent l'inclinaison du
   plateau, donc elles s'y couchent réellement au lieu de se dresser.

   Le compromis à résoudre : à plat, un texte devient illisible. La carte
   survolée ou choisie se redresse donc vers le joueur, comme on soulève une
   vraie carte pour la lire.
   ═════════════════════════════════════════════════════════════════════════════ */

body.en-combat {
  overflow: hidden;
  height: 100vh;
  height: 100dvh;
}

body.en-combat .wrap {
  /* La page est bridée à 1240 px, ce qui convient à la lecture mais étouffe
     la table. Pendant un combat, on rend la largeur disponible au jeu. */
  max-width: min(1760px, 96vw);
  padding: .8rem 1.5rem .6rem;
  /* flex plutôt qu'une hauteur calculée : la barre de navigation change de
     hauteur selon l'écran, et toute constante finit par être fausse.
     « dvh » tient compte des barres mobiles qui apparaissent au défilement. */
  flex: 1;
  min-height: 0;
  height: auto;
  display: flex;
  flex-direction: column;
}

body.en-combat .foot {
  display: none;
}

.bt-forfeit {
  position: relative;
  z-index: 5;
  align-self: center;
}

/* Le conteneur du combat doit s'étirer sur toute la hauteur disponible.
   On vise l'identifiant en plus de la classe : la règle de classe seule ne
   s'appliquait pas et la moitié basse de l'écran restait vide. */
.bt-view,
body.en-combat #battleView {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

body.en-combat #battleLobby {
  flex: 1 1 auto;
  min-height: 0;
}

.bt-scene {
  position: relative;
  flex: 1;
  min-height: 0;
  perspective: 1250px;
  perspective-origin: 50% 18%;
  /* le regard plonge sur la table */
  /* Réserve latérale PROPORTIONNELLE, et c'est le point clé : l'élargissement
     dû à la perspective croît avec la largeur de la table (environ 7 %), donc
     une réserve fixe suffit sur un écran étroit et échoue sur un grand. */
  padding: .5rem clamp(26px, 7%, 130px) 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  will-change: transform;
}

/* ── Le plan de la table ──
   C'est LUI qui porte l'inclinaison : tout ce qu'il contient, feutre comme
   cartes, se couche naturellement dessus. */
.bt-room {
  pointer-events: none;
  /* les clics passent aux cartes */
  position: relative;
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1rem, 3vh, 2.4rem);
  padding: clamp(1.4rem, 4vh, 3.4rem) clamp(1rem, 3vw, 3rem);
  transform-style: preserve-3d;
  transform: rotateX(30deg);
  /* caméra haute : on domine la table */
  transition: transform .6s cubic-bezier(.2, .9, .2, 1);
}

/* Le feutre épouse exactement le plan, sans rotation propre */
.bt-table {
  pointer-events: none;
  position: absolute;
  inset: -22px -6px;
  z-index: 0;
  transform: translateZ(-2px);
  /* juste sous les cartes */
  background:
    radial-gradient(ellipse 55% 42% at 50% 50%, rgba(110, 139, 255, .14), transparent 62%),
    radial-gradient(ellipse 85% 75% at 50% 50%, #1b1728 0%, #141120 42%, #0b0912 76%, #070510 100%);
  border-radius: 26px;
  box-shadow:
    0 0 0 2px rgba(242, 193, 78, .2),
    0 0 0 8px rgba(8, 7, 12, .92),
    0 0 0 9px rgba(242, 193, 78, .12),
    0 30px 70px rgba(0, 0, 0, .9),
    inset 0 0 140px rgba(0, 0, 0, .8);
}

/* Grain du feutre : sans lui, le plateau paraît en plastique */
.bt-table::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: .45;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='4'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23f)' opacity='.5'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

/* Ligne médiane gravée dans le feutre */
.bt-table-line {
  position: absolute;
  left: 6%;
  right: 6%;
  top: 50%;
  height: 2px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, transparent, rgba(242, 193, 78, .45) 18%, rgba(242, 193, 78, .7) 50%, rgba(242, 193, 78, .45) 82%, transparent);
  box-shadow: 0 0 18px rgba(242, 193, 78, .4);
}

.bt-table-line::before,
.bt-table-line::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 14px;
  height: 14px;
  transform: translateY(-50%) rotate(45deg);
  border: 2px solid rgba(242, 193, 78, .5);
  background: rgba(8, 7, 12, .9);
}

.bt-table-line::before {
  left: -7px;
}

.bt-table-line::after {
  right: -7px;
}

.bt-table-glow {
  position: absolute;
  left: 50%;
  top: 46%;
  width: 560px;
  height: 340px;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse, rgba(242, 193, 78, .14), rgba(110, 139, 255, .05) 46%, transparent 72%);
  filter: blur(24px);
  pointer-events: none;
}

/* ── Les deux rangées, posées sur le feutre ── */
.bt-team {
  pointer-events: auto;
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  gap: .9rem;
  transform-style: preserve-3d;
}

.bt-enemy {
  transform: translateZ(2px);
}

.bt-mine {
  transform: translateZ(2px);
}

/* L'assombrissement porte sur les images : un filtre sur la rangée aplatirait
   le contexte 3D et casserait le test de clic. */
.bt-enemy .bt-card img {
  filter: brightness(.88) saturate(.94);
}

/* ── Une carte posée à plat ── */
.bt-card {
  position: relative;
  /* flex: 1 1 0 → les six cartes partagent la ligne à parts égales et ne
     peuvent jamais la déborder, quelle que soit la largeur de la colonne.
     max-width évite qu'elles deviennent énormes sur grand écran. */
  flex: 1 1 0;
  min-width: 0;
  max-width: 150px;
  width: auto;
  transform-style: preserve-3d;
  /* Pivot sur le bord inférieur : en se redressant, la carte reste sous le
     curseur au lieu de lui échapper — sans cela, le survol clignotait. */
  transform-origin: 50% 100%;
  transform: translateZ(3px);
  background: linear-gradient(170deg, var(--feutre-2), var(--nuit-2));
  border: 1px solid var(--liseré);
  padding: 7px;
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  transition: transform .24s cubic-bezier(.25, .8, .3, 1), box-shadow .24s, filter .24s;
  /* Ombre longue et douce : c'est elle qui « pose » la carte sur le feutre */
  box-shadow: 0 10px 22px rgba(0, 0, 0, .75), 0 2px 5px rgba(0, 0, 0, .6);
}

/* Redressement à la lecture : UNIQUEMENT sur la carte sélectionnée.
   Le déclencher au survol créait une boucle sans fin : la carte se relevait,
   sortait de sous le curseur, retombait, se retrouvait de nouveau dessous, et
   repartait — elle clignotait indéfiniment. Elle ne bouge donc plus qu'au
   clic, et redescend dès qu'on la désélectionne. */
.bt-card.selected {
  transform: translateZ(70px) rotateX(-30deg) scale(1.05);
  box-shadow: 0 34px 52px rgba(0, 0, 0, .85), 0 0 30px rgba(242, 193, 78, .28);
  z-index: 20;
}

/* Le survol reste signalé, mais SANS déplacer la carte : bordure, lueur et
   luminosité seulement. Le curseur ne perd jamais le contact. */
.bt-mine .bt-card.jouable:hover:not(.selected),
.bt-card.targetable:hover:not(.selected) {
  border-color: var(--or-vif);
  box-shadow: 0 10px 22px rgba(0, 0, 0, .75), 0 0 28px rgba(242, 193, 78, .45);
  filter: brightness(1.12);
  cursor: pointer;
}

.bt-card.targetable:hover:not(.selected) {
  border-color: #fff;
  box-shadow: 0 10px 22px rgba(0, 0, 0, .75), 0 0 34px rgba(224, 82, 79, .8);
}

/* Ce pavé prolonge visuellement la carte mais ne capte AUCUN clic : débordant
   sur les voisines, il redirigeait les clics vers la mauvaise carte. */
.bt-card::after {
  content: "";
  position: absolute;
  left: -8px;
  right: -8px;
  top: -6px;
  bottom: -14px;
  z-index: -1;
  pointer-events: none;
}

.bt-card.selected {
  border-color: var(--or);
  box-shadow: 0 40px 60px rgba(0, 0, 0, .9), 0 0 42px rgba(242, 193, 78, .5);
}

.bt-card.jouable {
  cursor: pointer;
  border-color: var(--liseré-fort);
}

.bt-card.jouable::before {
  content: "";
  position: absolute;
  inset: -1px;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(242, 193, 78, .5), 0 0 22px rgba(242, 193, 78, .25);
  animation: btPret 2.4s ease-in-out infinite;
}

@keyframes btPret {

  0%,
  100% {
    opacity: .4;
  }

  50% {
    opacity: 1;
  }
}

.bt-card.targetable {
  cursor: crosshair;
  border-color: rgba(224, 82, 79, .75);
  animation: btCible 1.3s ease-in-out infinite;
}

@keyframes btCible {

  0%,
  100% {
    box-shadow: 0 10px 22px rgba(0, 0, 0, .75), 0 0 0 1px rgba(224, 82, 79, .45);
  }

  50% {
    box-shadow: 0 10px 22px rgba(0, 0, 0, .75), 0 0 30px rgba(224, 82, 79, .7), 0 0 0 2px rgba(224, 82, 79, .9);
  }
}

/* Une carte hors combat glisse sur le côté et se ternit */
.bt-card.dead {
  pointer-events: none;
  /* ni sélectionnable, ni ciblable */
  filter: grayscale(1) brightness(.32);
  transform: translateZ(0) rotateZ(-9deg) translateY(10px) scale(.94);
  opacity: .5;
  pointer-events: none;
  box-shadow: 0 4px 10px rgba(0, 0, 0, .6);
}

.bt-card.used {
  filter: brightness(.6) saturate(.5);
}

.bt-card img {
  width: 100%;
  aspect-ratio: 450/490;
  object-fit: contain;
  display: block;
  background: #05050a;
}

.bt-noimg {
  aspect-ratio: 450/490;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .5);
  border: 1px dashed var(--liseré);
  color: var(--texte-3);
  font-size: 1.3rem;
}

.bt-info {
  margin-top: 2px;
}

.bt-cname {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .74rem;
  margin-top: 6px;
  line-height: 1.2;
}

.bt-nums {
  font-size: .66rem;
  color: var(--texte-2);
  margin-top: 3px;
  display: flex;
  gap: .45rem;
}

.bt-eff {
  font-size: .64rem;
  color: var(--or);
  margin-top: 3px;
}

.bt-states {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  flex-wrap: wrap;
  font-size: .6rem;
}

.bt-state {
  padding: 0 5px;
  border: 1px solid var(--liseré);
  color: var(--texte-3);
}

/* ── Vitalité ── */
.bt-hp {
  position: relative;
  height: 16px;
  margin-top: 6px;
  background: linear-gradient(180deg, rgba(0, 0, 0, .85), rgba(0, 0, 0, .6));
  border: 1px solid rgba(255, 255, 255, .14);
  overflow: hidden;
}

.bt-hp span {
  display: block;
  height: 100%;
  background: linear-gradient(180deg, #86efac, #22c55e 55%, #15803d);
  box-shadow: 0 0 12px rgba(74, 222, 128, .55), inset 0 1px 0 rgba(255, 255, 255, .4);
  transition: width .5s cubic-bezier(.2, .9, .2, 1), background .3s;
}

.bt-hp::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(90deg, transparent 0 24%, rgba(0, 0, 0, .55) 24% 25%);
}

.bt-hp b {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .64rem;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .95);
}

.bt-hp.moyen span {
  background: linear-gradient(180deg, #fde68a, #f59e0b 55%, #b45309);
  box-shadow: 0 0 12px rgba(245, 158, 11, .55), inset 0 1px 0 rgba(255, 255, 255, .4);
}

.bt-hp.bas span {
  background: linear-gradient(180deg, #fca5a5, #ef4444 55%, #991b1b);
  box-shadow: 0 0 14px rgba(239, 68, 68, .7), inset 0 1px 0 rgba(255, 255, 255, .4);
  animation: pvCritique 1s ease-in-out infinite;
}

@keyframes pvCritique {

  0%,
  100% {
    filter: brightness(1);
  }

  50% {
    filter: brightness(1.45);
  }
}

/* ── Bandeaux ── */
.bt-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .7rem 1.3rem;
  margin-bottom: .2rem;
  background: linear-gradient(180deg, var(--feutre-2), transparent);
  border-top: 1px solid var(--liseré);
  border-bottom: 1px solid var(--liseré);
}

.bt-side {
  min-width: 150px;
}

.bt-side-me {
  text-align: right;
}

.bt-name {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .96rem;
}

.bt-alive {
  font-size: .72rem;
  color: var(--texte-3);
  margin-top: 2px;
}

.bt-status {
  text-align: center;
}

.bt-turn {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .95rem;
}

.bt-turn.you,
.bt-turn.moi {
  color: var(--or-vif);
}

.bt-timer {
  font-family: var(--police-titre);
  font-size: .8rem;
  color: var(--texte-3);
  margin-left: .4rem;
}

.bt-hint {
  font-size: .78rem;
  color: var(--texte-2);
  margin-top: .3rem;
}

.bt-hint.err {
  color: #fca5a5;
}

.bt-mid {
  flex-shrink: 0;
  text-align: center;
  margin: .4rem 0;
  min-height: 2.4rem;
}

.bt-actions {
  display: flex;
  gap: .5rem;
  justify-content: center;
  flex-wrap: wrap;
}

.bt-log {
  flex-shrink: 0;
  margin-top: .5rem;
  padding: .65rem 1.1rem;
  max-height: 84px;
  overflow-y: auto;
  background: rgba(0, 0, 0, .35);
  border-left: 2px solid var(--liseré-fort);
  font-size: .76rem;
  color: var(--texte-2);
  line-height: 1.6;
}


/* ─────────────────────────────────────────────────────────────────────────────
   MISE EN SCÈNE DES CAPACITÉS
   Canvas plein écran + transformations 3D des cartes.
   Purement décoratif : rien ici n'influence le déroulement du combat.
   ───────────────────────────────────────────────────────────────────────────── */

.fx-canvas {
  position: fixed;
  inset: 0;
  z-index: 9600;
  /* devant la fenêtre d'aperçu */
  pointer-events: none;
  /* Pas de mix-blend-mode : sur un canvas plein écran, il force le navigateur
     à recomposer toute la page à chaque image et divise le nombre d'images par
     trois. Le rendu additif se fait déjà dans le canvas lui-même. */
}

.fx-layer {
  position: fixed;
  inset: 0;
  z-index: 9610;
  pointer-events: none;
  overflow: hidden;
}

/* ── Le plateau devient un espace 3D ── */
.bt-team {
  perspective: 1600px;
  perspective-origin: 50% 50%;
}

.bt-card {
  transform-style: preserve-3d;
}

.bt-card.fx-3d {
  z-index: 500;
  will-change: transform;
}

/* ── Secousse ── */
@keyframes fxShake {

  0%,
  100% {
    transform: translate(0, 0) rotate(0deg);
  }

  15% {
    transform: translate(calc(var(--shake) * -1), calc(var(--shake) * .5)) rotate(-.4deg);
  }

  30% {
    transform: translate(var(--shake), calc(var(--shake) * -.6)) rotate(.5deg);
  }

  45% {
    transform: translate(calc(var(--shake) * -.7), var(--shake)) rotate(-.3deg);
  }

  60% {
    transform: translate(calc(var(--shake) * .6), calc(var(--shake) * -.4)) rotate(.2deg);
  }

  80% {
    transform: translate(calc(var(--shake) * -.3), calc(var(--shake) * .2)) rotate(0deg);
  }
}

.fx-shake {
  animation: fxShake .42s cubic-bezier(.36, .07, .19, .97);
}

/* Aberration chromatique : décale rouge et cyan pendant l'impact */
@keyframes fxAberr {

  0%,
  100% {
    filter: none;
  }

  30% {
    filter: drop-shadow(3px 0 0 rgba(255, 0, 60, .55)) drop-shadow(-3px 0 0 rgba(0, 220, 255, .55)) saturate(1.3);
  }

  60% {
    filter: drop-shadow(-2px 0 0 rgba(255, 0, 60, .4)) drop-shadow(2px 0 0 rgba(0, 220, 255, .4));
  }
}

.fx-aberration {
  animation: fxAberr .26s ease-out;
}

/* Ralenti : le plateau se fige un instant et se teinte */
@keyframes fxSlow {

  0%,
  100% {
    filter: none;
    transform: scale(1);
  }

  40% {
    filter: contrast(1.15) saturate(1.25);
    transform: scale(1.012);
  }
}

.fx-slowmo {
  animation: fxSlow .5s ease-in-out;
}

@keyframes fxFlash {
  0% {
    opacity: 0;
  }

  20% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

.fx-flash {
  position: absolute;
  inset: 0;
  animation: fxFlash ease-out forwards;
}

/* ── Éléments ponctuels ── */
@keyframes fxDome {
  0% {
    transform: translate(-50%, -50%) scale(.2) rotateX(65deg);
    opacity: 0;
  }

  35% {
    opacity: .95;
  }

  100% {
    transform: translate(-50%, -50%) scale(1.35) rotateX(65deg);
    opacity: 0;
  }
}

.fx-dome {
  position: absolute;
  width: 190px;
  height: 190px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(96, 165, 250, .4), rgba(96, 165, 250, .06) 58%, transparent 72%);
  border: 2px solid rgba(191, 219, 254, .9);
  box-shadow: 0 0 40px rgba(96, 165, 250, .7), inset 0 0 40px rgba(147, 197, 253, .5);
  animation: fxDome .95s cubic-bezier(.2, .9, .2, 1) forwards;
}

@keyframes fxCrossBig {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(.3) rotate(-25deg);
  }

  30% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.1) rotate(0deg);
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -90px) scale(.9) rotate(8deg);
  }
}

.fx-cross-big {
  position: absolute;
  width: 46px;
  height: 46px;
  background:
    linear-gradient(#4ade80, #bbf7d0) center/100% 14px no-repeat,
    linear-gradient(#4ade80, #bbf7d0) center/14px 100% no-repeat;
  filter: drop-shadow(0 0 16px rgba(74, 222, 128, .95));
  animation: fxCrossBig .9s ease-out forwards;
}

@keyframes fxTarget {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(2.4) rotate(0deg);
  }

  25% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(.7) rotate(220deg);
  }
}

.fx-target {
  position: absolute;
  width: 130px;
  height: 130px;
  border-radius: 50%;
  border: 3px dashed #fbbf24;
  box-shadow: 0 0 22px rgba(251, 191, 36, .6), inset 0 0 22px rgba(251, 191, 36, .35);
  animation: fxTarget 1.25s ease-out forwards;
}

/* Pièce en volume : deux faces opposées qui tournent ensemble */
@keyframes fxCoin3d {
  0% {
    transform: translate(-50%, 0) rotateX(0deg) scale(.6);
    opacity: 0;
  }

  12% {
    opacity: 1;
  }

  55% {
    transform: translate(-50%, -150px) rotateX(1440deg) scale(1.25);
  }

  92% {
    transform: translate(-50%, -8px) rotateX(2880deg) scale(1);
    opacity: 1;
  }

  100% {
    transform: translate(-50%, -8px) rotateX(2880deg) scale(1);
    opacity: 0;
  }
}

.fx-coin3d {
  position: absolute;
  width: 52px;
  height: 52px;
  transform-style: preserve-3d;
  animation: fxCoin3d 1.05s cubic-bezier(.25, .7, .35, 1) forwards;
  filter: drop-shadow(0 0 22px rgba(250, 204, 21, .9));
}

.fx-coin-face {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid #fde68a;
  backface-visibility: hidden;
}

.fx-coin-a {
  background: radial-gradient(circle at 35% 30%, #fef9c3, #facc15 55%, #a16207);
}

.fx-coin-b {
  background: radial-gradient(circle at 65% 70%, #fde68a, #eab308 55%, #854d0e);
  transform: rotateX(180deg);
}

@keyframes fxOrb {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(.3);
  }

  15% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty))) scale(.2);
  }
}

.fx-orb {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle, #fecaca, #dc2626 60%, transparent);
  filter: drop-shadow(0 0 10px rgba(220, 38, 38, .95));
  animation: fxOrb .8s cubic-bezier(.4, 0, .9, .6) forwards;
}

/* Nombres flottants */
/* Le nombre monte vite, puis MARQUE UNE PAUSE avant de s'effacer : c'est ce
   palier qui permet de le lire quand plusieurs apparaissent d'un coup. */
@keyframes fxNum {
  0% {
    opacity: 0;
    transform: translate(-50%, 10px) scale(.6);
  }

  10% {
    opacity: 1;
    transform: translate(-50%, -18px) scale(1.35);
  }

  18% {
    transform: translate(-50%, -24px) scale(1);
  }

  70% {
    opacity: 1;
    transform: translate(-50%, -34px) scale(1);
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -72px) scale(.95);
  }
}

.fx-num {
  position: absolute;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.35rem;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .95), 0 0 22px currentColor;
  white-space: nowrap;
  animation: fxNum 2.5s cubic-bezier(.2, .9, .2, 1) forwards;
}

.fx-num-dmg {
  color: #fca5a5;
}

.fx-num-heal {
  color: #86efac;
}

.fx-num-buff {
  color: #fcd34d;
  font-size: 1.05rem;
  letter-spacing: .06em;
}

.fx-num-debuff {
  color: #94a3b8;
  font-size: 1.05rem;
}

/* ── États des cartes ── */
@keyframes fxHit {

  0%,
  100% {
    filter: none;
  }

  15% {
    filter: brightness(3) saturate(0) contrast(1.4);
  }

  40% {
    filter: brightness(1.6) saturate(.6);
  }
}

.bt-card.fx-hit {
  animation: fxHit .42s ease-out;
}

@keyframes fxCharge {
  0% {
    box-shadow: 0 0 0 rgba(147, 197, 253, 0);
    filter: none;
  }

  55% {
    box-shadow: 0 0 46px rgba(147, 197, 253, 1), 0 0 90px rgba(96, 165, 250, .7);
    filter: brightness(1.5);
  }

  100% {
    box-shadow: 0 0 0 rgba(147, 197, 253, 0);
    filter: none;
  }
}

.bt-card.fx-charge {
  animation: fxCharge .48s ease-out;
}

.bt-card.fx-glow-blue {
  box-shadow: 0 0 34px rgba(96, 165, 250, .95), inset 0 0 26px rgba(96, 165, 250, .35) !important;
}

.bt-card.fx-glow-green {
  box-shadow: 0 0 34px rgba(74, 222, 128, .95), inset 0 0 26px rgba(74, 222, 128, .35) !important;
}

.bt-card.fx-glow-red {
  box-shadow: 0 0 34px rgba(220, 38, 38, .95), inset 0 0 26px rgba(220, 38, 38, .35) !important;
}

@keyframes fxPoison {

  0%,
  100% {
    filter: none;
  }

  50% {
    filter: hue-rotate(75deg) saturate(2) brightness(.9);
  }
}

.bt-card.fx-poison {
  animation: fxPoison 1.6s ease-in-out;
}

@keyframes fxWeak {
  0% {
    filter: none;
  }

  100% {
    filter: grayscale(.85) brightness(.65) blur(.4px);
  }
}

.bt-card.fx-weak {
  animation: fxWeak 1.5s ease-out;
}

@keyframes fxFury {

  0%,
  100% {
    filter: none;
    box-shadow: none;
  }

  50% {
    filter: saturate(2) brightness(1.45) contrast(1.15);
    box-shadow: 0 0 44px rgba(249, 115, 22, 1);
  }
}

.bt-card.fx-fury {
  animation: fxFury 1.4s ease-in-out;
}

@keyframes fxTaunt {

  0%,
  100% {
    filter: none;
  }

  40% {
    filter: brightness(1.5) saturate(1.6);
  }
}

.bt-card.fx-taunt {
  animation: fxTaunt 1.3s ease-in-out;
}

@keyframes fxRiposte {

  0%,
  100% {
    box-shadow: none;
  }

  50% {
    box-shadow: 0 0 0 3px rgba(244, 114, 182, 1), 0 0 40px rgba(244, 114, 182, .8);
  }
}

.bt-card.fx-riposte {
  animation: fxRiposte 1.2s ease-in-out;
}

@keyframes fxSacrifice {
  0% {
    filter: brightness(1);
  }

  40% {
    filter: brightness(5) saturate(0);
  }

  70% {
    filter: brightness(2);
  }

  100% {
    filter: brightness(1);
  }
}

.bt-card.fx-sacrifice {
  animation: fxSacrifice 1.2s ease-out;
}

@keyframes fxSurvive {

  0%,
  100% {
    box-shadow: none;
    filter: none;
  }

  45% {
    box-shadow: 0 0 0 4px rgba(251, 191, 36, 1), 0 0 50px rgba(251, 191, 36, .85);
    filter: brightness(1.5) saturate(1.4);
  }
}

.bt-card.fx-survive {
  animation: fxSurvive 1.6s ease-in-out;
}

@keyframes fxDodge {

  0%,
  100% {
    opacity: 1;
    filter: none;
  }

  25% {
    opacity: .15;
    filter: blur(4px) hue-rotate(40deg);
  }

  60% {
    opacity: .45;
    filter: blur(1px);
  }
}

.bt-card.fx-dodge {
  animation: fxDodge 1.5s ease-in-out;
}

/* Réglage système respecté : aucune animation si l'utilisateur les refuse */
/* Animations réduites : déclenchées par le réglage du jeu, et non plus par
   celui du système (Windows coupe les animations pour des raisons de
   performance, ce qui figeait les cartes sans que le joueur l'ait voulu). */

  html.anim-reduites .fx-canvas,
  html.anim-reduites .fx-layer {
    display: none;
  }

  html.anim-reduites .bt-card[class*="fx-"] {
    animation: none !important;
  }

  html.anim-reduites .fx-shake,
  html.anim-reduites .fx-aberration,
  html.anim-reduites .fx-slowmo {
    animation: none !important;
  }


/* ═════════════════════════════════════════════════════════════════════════════
   ÉCRAN DE FIN
   Le verdict mérite mieux qu'un mot en haut de page : on arrête le jeu, on
   affiche le bilan, et on propose la suite.
   ═════════════════════════════════════════════════════════════════════════════ */

.fin-overlay {
  position: fixed;
  inset: 0;
  z-index: 9500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: radial-gradient(ellipse at 50% 40%, rgba(12, 10, 20, .82), rgba(4, 3, 8, .96));
  backdrop-filter: blur(14px);
  opacity: 0;
  transition: opacity .45s ease-out;
}

.fin-overlay.visible {
  opacity: 1;
}

.fin-boite {
  position: relative;
  width: 100%;
  max-width: 560px;
  padding: 2.6rem 2.2rem 2rem;
  text-align: center;
  background: linear-gradient(170deg, var(--feutre-2), var(--nuit-2) 70%);
  border: 1px solid var(--liseré-fort);
  clip-path: polygon(26px 0, 100% 0, 100% calc(100% - 26px), calc(100% - 26px) 100%, 0 100%, 0 26px);
  box-shadow: 0 40px 110px rgba(0, 0, 0, .85);
  transform: translateY(26px) scale(.96);
  transition: transform .5s cubic-bezier(.2, .9, .2, 1);
}

.fin-overlay.visible .fin-boite {
  transform: none;
}

/* Lueur derrière la boîte, teintée selon l'issue */
.fin-boite::before {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: -1;
  background: linear-gradient(160deg, var(--or), transparent 55%);
  opacity: .35;
  filter: blur(2px);
  clip-path: inherit;
}

.fin-overlay.perdu .fin-boite::before {
  background: linear-gradient(160deg, var(--sang), transparent 55%);
}

.fin-overlay.nul .fin-boite::before {
  background: linear-gradient(160deg, var(--texte-3), transparent 55%);
}

/* Sceau : un losange frappé au-dessus du verdict */
.fin-sceau {
  /* Le sceau chevauche moins le bord : à -3,4 rem il semblait posé dessus. */
  width: 74px;
  height: 74px;
  margin: -1.6rem auto 1rem;
  display: grid;
  place-items: center;
  font-size: 2rem;
  color: var(--nuit);
  background: linear-gradient(145deg, var(--or-vif), var(--or) 55%, #8a6d3c);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  box-shadow: 0 0 40px rgba(242, 193, 78, .65);
  animation: finSceau .8s cubic-bezier(.2, 1.5, .4, 1) both;
}

.fin-overlay.perdu .fin-sceau {
  background: linear-gradient(145deg, #f7b3b1, var(--sang) 55%, #7f2725);
  box-shadow: 0 0 40px rgba(224, 82, 79, .55);
}

.fin-overlay.nul .fin-sceau {
  background: linear-gradient(145deg, #b9b2c6, var(--texte-3) 55%, #3c3747);
  box-shadow: none;
}

@keyframes finSceau {
  0% {
    transform: rotate(-180deg) scale(0);
    opacity: 0;
  }

  100% {
    transform: rotate(0) scale(1);
    opacity: 1;
  }
}

.fin-verdict {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: clamp(2rem, 6vw, 2.9rem);
  letter-spacing: -.03em;
  text-transform: uppercase;
  background: linear-gradient(120deg, var(--or-vif), var(--or) 60%, #8a6d3c);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: finTexte .6s .15s ease-out both;
}

.fin-overlay.perdu .fin-verdict {
  background: linear-gradient(120deg, #f7b3b1, var(--sang) 60%, #7f2725);
  -webkit-background-clip: text;
}

.fin-overlay.nul .fin-verdict {
  background: linear-gradient(120deg, #cfc9d8, var(--texte-2));
  -webkit-background-clip: text;
}

@keyframes finTexte {
  from {
    opacity: 0;
    transform: translateY(14px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.fin-sous {
  font-size: .88rem;
  color: var(--texte-2);
  margin-top: .5rem;
  animation: finTexte .6s .25s ease-out both;
}

.fin-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .6rem;
  margin: 1.8rem 0 1.4rem;
  animation: finTexte .6s .35s ease-out both;
}

.fin-stat {
  padding: .8rem .4rem;
  background: rgba(0, 0, 0, .4);
  border: 1px solid var(--liseré);
}

.fin-val {
  display: block;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.5rem;
  color: var(--or-vif);
}

.fin-lib {
  display: block;
  font-size: .62rem;
  color: var(--texte-3);
  margin-top: .25rem;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: .05em;
}

@media (max-width: 560px) {
  .fin-stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

.fin-heros {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-align: left;
  padding: .8rem 1rem;
  margin-bottom: 1.6rem;
  background: rgba(242, 193, 78, .06);
  border: 1px solid var(--liseré);
  animation: finTexte .6s .45s ease-out both;
}

.fin-heros img {
  width: 58px;
  aspect-ratio: 450/490;
  object-fit: contain;
  background: #05050a;
  border: 1px solid var(--liseré);
}

.fin-heros-lib {
  font-size: .62rem;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--texte-3);
}

.fin-heros-nom {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .95rem;
  margin-top: 2px;
}

.fin-heros-pv {
  font-size: .76rem;
  color: var(--menthe);
  margin-top: 2px;
}

.fin-actions {
  display: flex;
  gap: .6rem;
  justify-content: center;
  flex-wrap: wrap;
  animation: finTexte .6s .55s ease-out both;
}

/* Animations réduites : déclenchées par le réglage du jeu, et non plus par
   celui du système (Windows coupe les animations pour des raisons de
   performance, ce qui figeait les cartes sans que le joueur l'ait voulu). */

  html.anim-reduites .fin-overlay,
  html.anim-reduites .fin-boite,
  html.anim-reduites .fin-sceau,
  html.anim-reduites .fin-verdict,
  html.anim-reduites .fin-sous,
  html.anim-reduites .fin-stats,
  html.anim-reduites .fin-heros,
  html.anim-reduites .fin-actions {
    animation: none;
    transition: none;
  }


/* ═════════════════════════════════════════════════════════════════════════════
   COMPOSITION DE L'ÉQUIPE (/deck)
   Ces règles manquaient : sans elles, la barre du deck s'affichait en pleine
   largeur et ses cartes paraissaient énormes.
   ═════════════════════════════════════════════════════════════════════════════ */

.deck-bar {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  min-height: 104px;
  padding: .8rem 1rem;
  margin-bottom: 1.4rem;
  background: linear-gradient(180deg, rgba(242, 193, 78, .06), rgba(0, 0, 0, .3));
  border: 1px solid var(--liseré);
  clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
}

.deck-empty {
  font-size: .84rem;
  color: var(--texte-3);
  font-style: italic;
  padding: .6rem;
}

/* Chaque carte retenue : une vignette compacte, cliquable pour la retirer */
.deck-slot {
  position: relative;
  width: 74px;
  padding: 0;
  cursor: pointer;
  background: var(--nuit-2);
  border: 1px solid var(--liseré-fort);
  transition: transform .16s, border-color .16s, box-shadow .16s;
}

.deck-slot img {
  width: 100%;
  aspect-ratio: 450/490;
  object-fit: contain;
  display: block;
  background: #05050a;
}

.deck-slot>span:first-child {
  display: block;
  aspect-ratio: 450/490;
  display: grid;
  place-items: center;
  color: var(--texte-3);
}

.deck-slot:hover {
  transform: translateY(-4px);
  border-color: var(--sang);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .7);
}

/* Croix de retrait, révélée au survol */
.deck-slot::after {
  content: "✕";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 1.3rem;
  color: #fff;
  background: rgba(224, 82, 79, .7);
  opacity: 0;
  transition: opacity .16s;
}

.deck-slot:hover::after {
  opacity: 1;
}

/* Vignettes limitées : on marque la rareté par la bordure et le halo, jamais
   par un ::after — celui-ci est déjà pris par la croix de retrait. */
.deck-slot.rarity-limited,
.deck-slot.rarity-limited_holo {
  border-color: rgba(255, 255, 255, .55);
  box-shadow: 0 0 16px rgba(0, 0, 0, .9), inset 0 0 22px rgba(0, 0, 0, .75);
}

.deck-slot.rarity-limited_holo {
  border-color: rgba(255, 255, 255, .75);
}

.deck-slot.rarity-legendary {
  border-color: rgba(245, 158, 11, .5);
}

.deck-slot.rarity-legendary_holo {
  border-color: rgba(34, 211, 238, .5);
}

.deck-slot.rarity-epic {
  border-color: rgba(168, 85, 247, .45);
}

.deck-slot.rarity-rare {
  border-color: rgba(59, 130, 246, .45);
}

.deck-slot-cost {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 1px 6px;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .68rem;
  color: var(--nuit);
  background: var(--or);
}

/* Carte que le budget ne permet plus de prendre */
.card.unavailable {
  opacity: .34;
  cursor: not-allowed;
  filter: grayscale(.7);
}

.card.unavailable:hover {
  transform: none;
}

/* ── Statistiques et effet, sur chaque carte ── */
.card-stats {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: 7px;
  font-size: .74rem;
  color: var(--texte-2);
}

.card-cost {
  margin-left: auto;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .7rem;
  color: var(--or-vif);
  border: 1px solid var(--liseré-fort);
  padding: 0 6px;
}

/* L'effet de la carte : c'est lui qui décide d'une composition d'équipe */
.card-effect {
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid var(--liseré);
}

.card-effect-nom {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .76rem;
  color: var(--or-vif);
  display: flex;
  align-items: center;
  gap: 5px;
}

.card-effect-nom::before {
  content: "✦";
  font-size: .7rem;
  opacity: .8;
}

.card-effect-desc {
  font-size: .68rem;
  color: var(--texte-3);
  line-height: 1.45;
  margin-top: 3px;
}

.card-effect-cd {
  font-size: .64rem;
  color: var(--texte-3);
  margin-top: 3px;
  font-style: italic;
}

/* ── Merde ou Nutella : le pot mystère ── */
@keyframes fxPot {
  0% {
    transform: translate(-50%, 0) scale(.5) rotate(-8deg);
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  25% {
    transform: translate(-50%, -70px) scale(1.1) rotate(4deg);
  }

  35% {
    transform: translate(-50%, -64px) scale(1.05) rotate(-5deg);
  }

  45% {
    transform: translate(-50%, -70px) scale(1.1) rotate(5deg);
  }

  55% {
    transform: translate(-50%, -64px) scale(1.05) rotate(-4deg);
  }

  70% {
    transform: translate(-50%, -70px) scale(1.12) rotate(3deg);
  }

  100% {
    transform: translate(-50%, -66px) scale(1.08) rotate(0deg);
    opacity: 1;
  }
}

.fx-pot {
  position: absolute;
  width: 62px;
  height: 68px;
  background: linear-gradient(180deg, #8b5a2b 0%, #6b4423 45%, #3d2712 100%);
  border: 2px solid #a97142;
  border-radius: 8px 8px 14px 14px;
  box-shadow: 0 0 26px rgba(139, 90, 43, .75), inset 0 6px 12px rgba(255, 255, 255, .12);
  animation: fxPot 1.2s cubic-bezier(.3, .8, .3, 1) forwards;
}

/* Le couvercle */
.fx-pot::before {
  content: "";
  position: absolute;
  left: -6px;
  right: -6px;
  top: -7px;
  height: 11px;
  background: linear-gradient(180deg, #c68642, #8b5a2b);
  border: 2px solid #a97142;
  border-radius: 5px;
}

.fx-pot-q {
  position: absolute;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.5rem;
  color: #fde68a;
  text-shadow: 0 0 12px rgba(253, 230, 138, .9);
  animation: fxPotQ 1.1s ease-in-out infinite;
}

.fx-pot-q1 {
  left: -26px;
  top: 4px;
}

.fx-pot-q2 {
  right: -26px;
  top: 18px;
  animation-delay: .35s;
}

@keyframes fxPotQ {

  0%,
  100% {
    transform: translateY(0) rotate(-8deg);
    opacity: .65;
  }

  50% {
    transform: translateY(-8px) rotate(8deg);
    opacity: 1;
  }
}

/* Ouverture : le pot éclate */
.fx-pot.ouvert {
  animation: fxPotOuvre .3s ease-out forwards;
}

@keyframes fxPotOuvre {
  0% {
    transform: translate(-50%, -66px) scale(1.08);
  }

  60% {
    transform: translate(-50%, -80px) scale(1.5);
    filter: brightness(2);
  }

  100% {
    transform: translate(-50%, -86px) scale(1.9);
    opacity: 0;
  }
}

/* La carte qui a reçu la « merde » en garde des traces */
@keyframes fxDegoutte {

  0%,
  100% {
    filter: none;
  }

  35% {
    filter: sepia(.85) saturate(1.5) brightness(.72) hue-rotate(-12deg);
  }
}

.bt-card.fx-degoutte {
  animation: fxDegoutte 1.6s ease-in-out;
}

/* ── Pisse ou Jus de Pomme : deux verres identiques ── */
@keyframes fxVerres {
  0% {
    transform: translate(-50%, 0) scale(.5);
    opacity: 0;
  }

  18% {
    opacity: 1;
  }

  30% {
    transform: translate(-50%, -60px) scale(1.05);
  }

  45% {
    transform: translate(-52%, -56px) scale(1.02) rotate(-3deg);
  }

  60% {
    transform: translate(-48%, -60px) scale(1.05) rotate(3deg);
  }

  100% {
    transform: translate(-50%, -58px) scale(1.04) rotate(0);
    opacity: 1;
  }
}

.fx-verres {
  position: absolute;
  display: flex;
  gap: 14px;
  animation: fxVerres 1.1s cubic-bezier(.3, .8, .3, 1) forwards;
}

.fx-verre {
  width: 30px;
  height: 42px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .28) 0 38%, #d4c43a 38%, #b8a52e 100%);
  border: 2px solid rgba(255, 255, 255, .55);
  border-radius: 4px 4px 9px 9px;
  box-shadow: 0 0 20px rgba(212, 196, 58, .65), inset 0 -6px 10px rgba(0, 0, 0, .35);
}

.fx-verres.choisi .fx-verre:first-child {
  animation: fxVerreLeve .3s ease-out forwards;
}

@keyframes fxVerreLeve {
  0% {
    transform: translateY(0) scale(1);
  }

  100% {
    transform: translateY(-26px) scale(1.35);
    filter: brightness(1.8);
  }
}

/* ── Tennis ou Acteur X : la balle ── */
@keyframes fxBalle {
  0% {
    transform: translate(-50%, 0) scale(.4) rotate(0);
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  50% {
    transform: translate(-50%, -80px) scale(1.15) rotate(540deg);
  }

  100% {
    transform: translate(-50%, -40px) scale(1) rotate(1080deg);
    opacity: 1;
  }
}

.fx-balle {
  position: absolute;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f7ffd9, #bef264 55%, #84cc16);
  box-shadow: 0 0 22px rgba(190, 242, 100, .85), inset -4px -4px 8px rgba(0, 0, 0, .25);
  animation: fxBalle .85s cubic-bezier(.3, .7, .4, 1) forwards;
}

/* Les coutures de la balle */
.fx-balle::before,
.fx-balle::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .75);
  border-color: rgba(255, 255, 255, .75) transparent;
}

.fx-balle::after {
  transform: rotate(90deg);
}

/* La carte troublée par l'Acteur X */
@keyframes fxTrouble {

  0%,
  100% {
    filter: none;
  }

  40% {
    filter: saturate(1.6) hue-rotate(-25deg) blur(1.2px) brightness(1.15);
  }
}

.bt-card.fx-trouble {
  animation: fxTrouble 1.5s ease-in-out;
}

/* ═════════════════════════════════════════════════════════════════════════════
   CHOIX DE L'ADVERSAIRE
   Trois plaques gravées plutôt que trois boutons : le choix de la difficulté
   est le premier écran du jeu, il mérite d'être soigné.
   ═════════════════════════════════════════════════════════════════════════════ */

.levels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.1rem;
  margin-top: 1.8rem;
}

.level {
  position: relative;
  overflow: hidden;
  padding: 1.6rem 1.4rem 1.3rem;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: inherit;
  background: linear-gradient(165deg, var(--feutre-2), var(--nuit-2) 75%);
  border: 1px solid var(--liseré);
  clip-path: polygon(20px 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%, 0 20px);
  transition: transform .22s cubic-bezier(.2, .9, .2, 1), border-color .22s, box-shadow .22s;
}

.level:hover {
  transform: translateY(-5px);
  border-color: var(--liseré-fort);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .7);
}

/* Lueur qui balaie la plaque au survol */
.level::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(242, 193, 78, .14) 50%, transparent 60%);
  background-size: 250% 100%;
  background-position: 200% 0;
  transition: background-position .7s ease-out;
}

.level:hover::before {
  background-position: -50% 0;
}

/* Chevrons de difficulté, en haut à droite */
.level::after {
  position: absolute;
  top: 1rem;
  right: 1.2rem;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .9rem;
  letter-spacing: .14em;
  color: var(--liseré-fort);
}

.level[data-level="facile"]::after {
  content: "I";
  color: rgba(74, 222, 128, .55);
}

.level[data-level="normal"]::after {
  content: "II";
  color: rgba(242, 193, 78, .65);
}

.level[data-level="difficile"]::after {
  content: "III";
  color: rgba(224, 82, 79, .7);
}

.level[data-level="facile"]:hover {
  border-color: rgba(74, 222, 128, .45);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .7), 0 0 30px rgba(74, 222, 128, .12);
}

.level[data-level="normal"]:hover {
  border-color: rgba(242, 193, 78, .5);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .7), 0 0 30px rgba(242, 193, 78, .14);
}

.level[data-level="difficile"]:hover {
  border-color: rgba(224, 82, 79, .5);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .7), 0 0 30px rgba(224, 82, 79, .14);
}

.level-name {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.08rem;
  text-transform: uppercase;
  letter-spacing: .01em;
}

.level-desc {
  font-size: .82rem;
  color: var(--texte-3);
  line-height: 1.55;
  margin-top: .5rem;
  min-height: 2.6em;
}

.level-go {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 1.1rem;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .76rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--or-vif);
  opacity: .75;
  transition: opacity .22s, gap .22s;
}

.level:hover .level-go {
  opacity: 1;
  gap: 12px;
}

/* ── Écran de bêta fermée ── */
.beta {
  max-width: 520px;
  margin: 4rem auto;
  text-align: center;
  padding: 3rem 2.2rem 2.4rem;
  background: linear-gradient(170deg, var(--feutre-2), var(--nuit-2) 75%);
  border: 1px solid var(--liseré);
  clip-path: polygon(26px 0, 100% 0, 100% calc(100% - 26px), calc(100% - 26px) 100%, 0 100%, 0 26px);
  box-shadow: 0 34px 90px rgba(0, 0, 0, .75);
}

.beta-sceau {
  width: 74px;
  height: 74px;
  margin: -3.4rem auto 1.4rem;
  display: grid;
  place-items: center;
  font-size: 1.9rem;
  color: var(--nuit);
  background: linear-gradient(145deg, var(--or-vif), var(--or) 55%, #8a6d3c);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  box-shadow: 0 0 36px rgba(242, 193, 78, .55);
}

.beta-titre {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.6rem;
  text-transform: uppercase;
  letter-spacing: -.02em;
  background: linear-gradient(120deg, var(--or-vif), var(--or) 60%, #8a6d3c);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.beta-texte {
  font-size: .92rem;
  color: var(--texte-2);
  line-height: 1.7;
  margin-top: .9rem;
}

.beta-texte b {
  color: var(--texte);
}

.beta-id {
  font-size: .76rem;
  color: var(--texte-3);
  margin-top: .8rem;
}

.beta-id code {
  color: var(--or);
  border: 1px solid var(--liseré);
  padding: 1px 7px;
}

.beta-actions {
  display: flex;
  gap: .6rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 1.8rem;
}

/* Carte étourdie : elle vacille légèrement et se ternit */
.bt-card.etourdie {
  filter: brightness(.72) saturate(.6);
}

.bt-card.etourdie .bt-cname {
  color: var(--texte-3);
}

.etat-etourdi {
  animation: etourdi 1.4s ease-in-out infinite;
  display: inline-block;
}

@keyframes etourdi {

  0%,
  100% {
    transform: rotate(-12deg);
  }

  50% {
    transform: rotate(12deg);
  }
}


/* ═════════════════════════════════════════════════════════════════════════════
   MISE EN PAGE DU COMBAT — journal latéral et abandon dans la barre
   ═════════════════════════════════════════════════════════════════════════════ */

.bt-arene {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 268px;
  gap: 1rem;
  align-items: stretch;
}

/* minmax(0, 1fr) et non 1fr : sans cela, une colonne de grille refuse de
   descendre sous la largeur de son contenu et déborde sur sa voisine. */
.bt-arene>.bt-scene {
  min-width: 0;
}

/* Journal : à droite de la table, lisible sans quitter l'action des yeux */
.bt-journal {
  position: relative;
  z-index: 30;
  /* toujours devant le plateau */
  /* Hauteur imposée par la grille, JAMAIS par le contenu : sans ces trois
     propriétés, chaque ligne ajoutée repoussait la table vers le bas et
     finissait par la sortir de l'écran. */
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(20, 17, 32, .9), rgba(8, 7, 12, .75));
  border: 1px solid var(--liseré);
  clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px);
}

.bt-journal-titre {
  flex-shrink: 0;
  padding: .7rem 1rem .5rem;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .66rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--or);
  border-bottom: 1px solid var(--liseré);
}

.bt-journal .bt-log {
  flex: 1 1 0;
  min-height: 0;
  max-height: none;
  margin: 0;
  padding: .7rem 1rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* le défilement reste dedans */
  background: none;
  border: none;
  font-size: .78rem;
  line-height: 1.65;
  color: var(--texte-2);
}

.bt-journal .bt-log div {
  padding: .2rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, .03);
}

/* La dernière ligne ressort : c'est ce qui vient de se passer */
.bt-journal .bt-log div:last-child {
  color: var(--texte);
  font-weight: 500;
}

.bt-journal .bt-log::-webkit-scrollbar {
  width: 5px;
}

.bt-journal .bt-log::-webkit-scrollbar-thumb {
  background: var(--liseré-fort);
}


/* Abandon, dans la barre du haut */
.bt-forfeit {
  flex-shrink: 0;
  align-self: center;
  margin-left: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .42rem .9rem;
  cursor: pointer;
  background: rgba(224, 82, 79, .08);
  border: 1px solid rgba(224, 82, 79, .32);
  color: #f0a5a3;
  transition: all .16s;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
}

.bt-forfeit::before {
  content: "⚑";
  font-size: .8rem;
}

.bt-forfeit:hover {
  color: #fff;
  border-color: var(--sang);
  background: rgba(224, 82, 79, .28);
  box-shadow: 0 0 18px rgba(224, 82, 79, .3);
}

/* ── Ciblage ── */
/* Seules les cartes atteignables portent la classe : les autres restent
   inertes, ce qui évite de croire qu'on peut les viser. */
.bt-card.targetable::before {
  content: "";
  position: absolute;
  inset: -2px;
  pointer-events: none;
  z-index: 4;
  box-shadow: inset 0 0 0 2px rgba(224, 82, 79, .85), 0 0 26px rgba(224, 82, 79, .4);
  animation: btCibleBord 1.2s ease-in-out infinite;
}

@keyframes btCibleBord {

  0%,
  100% {
    opacity: .55;
  }

  50% {
    opacity: 1;
  }
}

/* La carte qui provoque : seule cible possible, et on le montre */
.bt-card.provocatrice {
  border-color: var(--or) !important;
}

.bt-card.provocatrice::before {
  box-shadow: inset 0 0 0 2px rgba(242, 193, 78, .95), 0 0 34px rgba(242, 193, 78, .55);
}

.bt-card.provocatrice::after {
  content: "🎯 PROVOQUE";
  position: absolute;
  left: 50%;
  top: -10px;
  z-index: 6;
  transform: translate(-50%, -100%);
  padding: .2rem .55rem;
  white-space: nowrap;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .58rem;
  letter-spacing: .08em;
  color: var(--nuit);
  background: linear-gradient(145deg, var(--or-vif), var(--or));
  box-shadow: 0 4px 14px rgba(0, 0, 0, .7);
  pointer-events: none;
  animation: btProvoque 1.4s ease-in-out infinite;
}

@keyframes btProvoque {

  0%,
  100% {
    transform: translate(-50%, -100%) scale(1);
  }

  50% {
    transform: translate(-50%, -108%) scale(1.06);
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   ADAPTATION AUX ÉCRANS
   Quatre paliers. À chacun, trois leviers : la largeur du journal, l'angle de
   la table (la perspective écrase vite sur un écran court) et la taille des
   cartes.
   ═════════════════════════════════════════════════════════════════════════════ */

/* ── Grand écran : journal large à droite ── */
@media (min-width: 1500px) {
  .bt-arene {
    grid-template-columns: minmax(0, 1fr) 320px;
  }

  .bt-card {
    max-width: 158px;
  }
}

/* ── Écran standard (1200–1500) : journal resserré ── */
@media (max-width: 1499px) and (min-width: 1200px) {
  .bt-arene {
    grid-template-columns: minmax(0, 1fr) 250px;
    gap: .9rem;
  }
}

/* ── Écran étroit (1000–1200) : journal encore réduit ── */
@media (max-width: 1199px) and (min-width: 1000px) {
  .bt-arene {
    grid-template-columns: minmax(0, 1fr) 210px;
    gap: .7rem;
  }

  .bt-journal .bt-log {
    font-size: .72rem;
    padding: .55rem .7rem;
  }

  .bt-journal-titre {
    font-size: .6rem;
    padding: .55rem .7rem .4rem;
  }

  .bt-card {
    max-width: 124px;
  }

  .bt-room {
    transform: rotateX(26deg);
  }

  .bt-card.selected {
    transform: translateZ(60px) rotateX(-26deg) scale(1.04);
  }
}

/* ── Sous 1000 px : le journal passe SOUS la table ── */
@media (max-width: 999px) {

  /* Ligne de hauteur FIXE, jamais « auto » : sinon chaque ligne ajoutée au
     journal repousse la table vers le bas jusqu'à la sortir de l'écran. */
  .bt-arene {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) 104px;
    gap: .5rem;
  }

  .bt-journal {
    height: 104px;
  }

  .bt-journal .bt-log {
    font-size: .72rem;
    padding: .5rem .8rem;
  }

  .bt-scene {
    padding: .3rem clamp(14px, 5%, 40px) .5rem;
  }

  .bt-room {
    transform: rotateX(22deg);
  }

  .bt-card {
    max-width: 116px;
  }

  .bt-card.selected {
    transform: translateZ(45px) rotateX(-22deg) scale(1.05);
  }

  .bt-head {
    padding: .5rem .8rem;
  }

  .bt-name {
    font-size: .84rem;
  }

  .bt-side {
    min-width: 0;
  }
}

/* ── Mobile : la table se redresse presque à plat écran ── */
@media (max-width: 700px) {
  body.en-combat .wrap {
    padding: .5rem .6rem .4rem;
  }

  /* Pendant un combat, la navigation se réduit à l'essentiel : chaque ligne
     gagnée sur la barre est une ligne rendue à la table. */
  body.en-combat .nav-in {
    padding: .5rem .7rem;
    gap: .5rem;
  }

  body.en-combat .nav-links {
    display: none;
  }

  body.en-combat .brand {
    font-size: .9rem;
  }

  body.en-combat .nav-name {
    display: none;
  }

  .bt-arene {
    grid-template-rows: minmax(0, 1fr) 76px;
  }

  .bt-scene {
    perspective: 800px;
    padding: .2rem 6px .4rem;
  }

  .bt-room {
    transform: rotateX(14deg);
    gap: .6rem;
    padding: .8rem .4rem;
  }

  .bt-team {
    gap: .3rem;
  }

  .bt-card {
    max-width: 92px;
    padding: 4px;
  }

  .bt-card.selected {
    transform: translateZ(40px) rotateX(-14deg) scale(1.12);
  }

  /* Sur petit écran, on garde l'essentiel : image, nom et vitalité */
  .bt-nums,
  .bt-eff {
    display: none;
  }

  .bt-cname {
    font-size: .6rem;
  }

  .bt-hp {
    height: 13px;
  }

  .bt-hp b {
    font-size: .54rem;
  }

  .bt-states {
    font-size: .52rem;
    gap: 2px;
  }

  .bt-journal {
    height: 100%;
  }

  .bt-journal-titre {
    display: none;
  }

  .bt-head {
    flex-wrap: wrap;
    gap: .4rem;
    padding: .45rem .6rem;
  }

  .bt-status {
    order: 3;
    width: 100%;
  }

  .bt-turn {
    font-size: .84rem;
  }

  .bt-alive {
    font-size: .64rem;
  }

  .bt-forfeit {
    font-size: .62rem;
    padding: .3rem .6rem;
    margin-left: auto;
  }

  .fx-num {
    font-size: 1rem;
  }
}

/* ── Très petit écran : six cartes sur UNE ligne ──
   Les faire passer sur deux lignes doublait la hauteur de chaque camp et
   faisait déborder la page. Mieux vaut des cartes minuscules mais une
   disposition qui tient à l'écran. */
@media (max-width: 430px) {
  .bt-team {
    flex-wrap: nowrap;
    gap: 3px;
  }

  .bt-card {
    max-width: 70px;
    padding: 3px;
  }

  .bt-room {
    transform: rotateX(10deg);
    padding: .5rem .25rem;
    gap: .45rem;
  }

  .bt-card.selected {
    transform: translateZ(30px) rotateX(-10deg) scale(1.35);
  }

  /* À cette taille, seuls l'illustration et la vitalité restent lisibles */
  .bt-cname,
  .bt-states {
    display: none;
  }

  .bt-hp {
    height: 11px;
    margin-top: 3px;
  }

  .bt-hp b {
    font-size: .48rem;
  }

  .bt-hp::before {
    display: none;
  }

  .bt-card.provocatrice::after {
    font-size: .48rem;
    padding: .1rem .3rem;
  }
}

/* ── Écran court (portable 13 pouces, fenêtre réduite) ── */
@media (max-height: 760px) and (min-width: 1000px) {
  .bt-room {
    gap: .6rem;
    padding-top: .6rem;
    padding-bottom: .6rem;
  }

  .bt-card {
    max-width: 118px;
  }

  .bt-log {
    font-size: .72rem;
  }

  .bt-head {
    padding: .45rem 1rem;
  }

  .bt-mid {
    margin: .25rem 0;
    min-height: 2rem;
  }

  .bt-scene {
    padding: .2rem clamp(20px, 6%, 90px) .3rem;
  }
}

/* Écran vraiment court en paysage (1366×650 et proches) : on retire les
   informations secondaires des cartes plutôt que de les rapetisser encore. */
@media (max-height: 680px) and (min-width: 1000px) {
  .bt-eff {
    display: none;
  }

  .bt-nums {
    font-size: .6rem;
  }

  .bt-cname {
    font-size: .68rem;
    margin-top: 4px;
  }

  .bt-card {
    padding: 5px;
  }

  .bt-hp {
    height: 13px;
    margin-top: 4px;
  }

  .bt-hp b {
    font-size: .58rem;
  }

  .bt-room {
    gap: .4rem;
  }
}

/* ── Écran très court (iPhone SE et similaires) ──
   Chaque pixel compte : on rogne les marges plutôt que les cartes. */
@media (max-height: 620px) and (max-width: 700px) {
  body.en-combat .wrap {
    padding: .3rem .4rem .3rem;
  }

  .bt-arene {
    grid-template-rows: minmax(0, 1fr) 60px;
    gap: .3rem;
  }

  .bt-head {
    padding: .3rem .5rem;
    margin-bottom: 0;
  }

  .bt-name {
    font-size: .74rem;
  }

  .bt-alive {
    display: none;
  }

  .bt-turn {
    font-size: .74rem;
  }

  .bt-hint {
    font-size: .66rem;
    margin-top: .1rem;
  }

  .bt-mid {
    margin: .2rem 0;
    min-height: 1.8rem;
  }

  .bt-scene {
    padding: .1rem 4px .2rem;
  }

  .bt-room {
    gap: .3rem;
    padding: .3rem .2rem;
  }

  .bt-journal .bt-log {
    font-size: .64rem;
    padding: .35rem .5rem;
    line-height: 1.45;
  }

  .bt-hp {
    height: 9px;
    margin-top: 2px;
  }

  .bt-hp b {
    font-size: .44rem;
  }

  .bt-forfeit {
    font-size: .56rem;
    padding: .22rem .45rem;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   JET DE JUS — la bouteille, l'explosion, les coulures
   ═════════════════════════════════════════════════════════════════════════════ */

/* La bouteille en vol. Sa trajectoire est pilotée en JavaScript ; ici on ne
   décrit que son apparence et son ombre portée. */
.fx-bouteille {
  position: absolute;
  width: 26px;
  height: 58px;
  transform-origin: 50% 50%;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .7));
}

.fx-bouteille-corps {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 42px;
  background: linear-gradient(100deg, rgba(250, 250, 249, .92) 0 42%, rgba(214, 211, 209, .85) 42% 62%, rgba(255, 255, 255, .95) 62%);
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 5px 5px 8px 8px;
  box-shadow: inset -4px 0 8px rgba(0, 0, 0, .28), inset 4px 0 8px rgba(255, 255, 255, .4);
}

.fx-bouteille-goulot {
  position: absolute;
  left: 50%;
  top: 0;
  width: 10px;
  height: 20px;
  transform: translateX(-50%);
  background: linear-gradient(100deg, rgba(245, 245, 244, .9), rgba(168, 162, 158, .85));
  border: 1px solid rgba(255, 255, 255, .5);
  border-radius: 3px 3px 0 0;
}

/* Le bouchon : ce détail rend la silhouette immédiatement lisible */
.fx-bouteille-goulot::before {
  content: "";
  position: absolute;
  left: -2px;
  right: -2px;
  top: -4px;
  height: 6px;
  background: linear-gradient(180deg, #e5e7eb, #9ca3af);
  border-radius: 2px;
}

.fx-bouteille-etiq {
  position: absolute;
  left: 2px;
  right: 2px;
  bottom: 12px;
  height: 15px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .92), rgba(240, 240, 240, .82));
  border-top: 1px solid rgba(0, 0, 0, .15);
  border-bottom: 1px solid rgba(0, 0, 0, .15);
}

/* Les coulures qui descendent le long de la carte touchée */
.fx-coulures {
  position: absolute;
  overflow: hidden;
  pointer-events: none;
}

.fx-coulure {
  position: absolute;
  top: 0;
  width: var(--w, 3px);
  /* La hauteur est fixée en pixels par le script et l'animation étire la
     coulure avec scaleY. Animer « height: var(--h) » ne fonctionne pas :
     Chrome refuse d'interpoler une variable valant un pourcentage dans une
     image-clé, et la déclaration est ignorée sans erreur. */
  transform-origin: 50% 0;
  transform: scaleY(0);
  background: linear-gradient(180deg, rgba(255, 255, 255, .98), rgba(231, 229, 228, .9) 55%, rgba(168, 162, 158, .6));
  border-radius: 0 0 3px 3px;
  box-shadow: 0 0 10px rgba(255, 255, 255, .7);
  animation: fxCoule ease-out forwards;
}

/* La goutte à l'extrémité donne l'impression de ruissellement */
.fx-coulure::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -3px;
  width: calc(var(--w, 3px) + 3px);
  height: calc(var(--w, 3px) + 4px);
  transform: translateX(-50%);
  background: radial-gradient(circle at 40% 35%, #ffffff, #e7e5e4);
  border-radius: 50%;
  box-shadow: 0 0 8px rgba(255, 255, 255, .7);
}

/* La coulure s'allonge vite, puis STAGNE avant de s'effacer : sans ce palier,
   elle disparaîtrait au moment même où elle devient visible. */
@keyframes fxCoule {
  0% {
    transform: scaleY(0);
    opacity: 0;
  }

  8% {
    opacity: 1;
  }

  45% {
    transform: scaleY(1);
    opacity: 1;
  }

  80% {
    transform: scaleY(1);
    opacity: .9;
  }

  100% {
    transform: scaleY(1);
    opacity: 0;
  }
}

/* La carte trempée garde une teinte ambrée un moment */
/* La carte trempée paraît mouillée : plus lumineuse et légèrement désaturée,
   comme une surface luisante, plutôt que teintée. */
@keyframes fxTrempe {

  0%,
  100% {
    filter: none;
  }

  25% {
    filter: brightness(1.22) saturate(.78) contrast(1.06);
  }

  70% {
    filter: brightness(1.1) saturate(.88);
  }
}

.bt-card.fx-trempe {
  animation: fxTrempe 2s ease-in-out;
}

/* Les étoiles de l'étourdissement, qui tournent au-dessus de la carte */
.fx-etourdi {
  position: absolute;
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
  animation: fxEtourdiTour 1.1s linear infinite;
}

.fx-etourdi span {
  position: absolute;
  font-size: 1.05rem;
  color: #fde68a;
  text-shadow: 0 0 10px rgba(250, 204, 21, .9);
  animation: fxEtourdiFin 2s ease-out forwards;
}

.fx-etourdi span:nth-child(1) {
  transform: translate(-26px, -6px);
}

.fx-etourdi span:nth-child(2) {
  transform: translate(0, -14px);
  animation-delay: .1s;
}

.fx-etourdi span:nth-child(3) {
  transform: translate(26px, -6px);
  animation-delay: .2s;
}

@keyframes fxEtourdiTour {
  from {
    rotate: 0deg;
  }

  to {
    rotate: 360deg;
  }
}

@keyframes fxEtourdiFin {
  0% {
    opacity: 0;
  }

  12% {
    opacity: 1;
  }

  78% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   DUEL EN LIGNE — recherche d'adversaire
   ═════════════════════════════════════════════════════════════════════════════ */

.pvp {
  position: relative;
  overflow: hidden;
  margin: 1.6rem 0 2rem;
  padding: 1.6rem 1.6rem 1.4rem;
  background:
    radial-gradient(ellipse 70% 140% at 12% 50%, rgba(110, 139, 255, .14), transparent 62%),
    linear-gradient(160deg, var(--feutre-2), var(--nuit-2) 78%);
  border: 1px solid var(--liseré-fort);
  clip-path: polygon(22px 0, 100% 0, 100% calc(100% - 22px), calc(100% - 22px) 100%, 0 100%, 0 22px);
}

.pvp-corps {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.4rem;
  flex-wrap: wrap;
}

.pvp-titre {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.25rem;
  text-transform: uppercase;
  letter-spacing: -.01em;
  background: linear-gradient(110deg, var(--or-vif), var(--arc-vif));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.pvp-sous {
  font-size: .86rem;
  color: var(--texte-2);
  margin-top: .35rem;
}

.pvp-action {
  display: flex;
  gap: .6rem;
  flex-wrap: wrap;
}

/* Bandeau de recherche : il n'apparaît que pendant l'attente */
.pvp-etat {
  display: flex;
  align-items: center;
  gap: .8rem;
  margin-top: 1.2rem;
  padding: .7rem 1rem;
  background: rgba(0, 0, 0, .35);
  border-left: 2px solid var(--arc);
  font-size: .84rem;
  color: var(--texte-2);
}

.pvp-chrono {
  margin-left: auto;
  font-family: var(--police-titre);
  font-weight: 700;
  color: var(--or-vif);
}

/* Radar : deux cercles qui se propagent, pour signaler que ça cherche */
.pvp-radar {
  position: relative;
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.pvp-radar::before,
.pvp-radar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--arc-vif);
  animation: pvpRadar 1.8s ease-out infinite;
}

.pvp-radar::after {
  animation-delay: .9s;
}

@keyframes pvpRadar {
  0% {
    transform: scale(.3);
    opacity: 1;
  }

  100% {
    transform: scale(2.4);
    opacity: 0;
  }
}

.pvp-compteur {
  margin-top: .7rem;
  font-size: .76rem;
  color: var(--texte-3);
}

.levels-titre {
  margin: 2.2rem 0 .2rem;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--texte-3);
  display: flex;
  align-items: center;
  gap: .8rem;
}

.levels-titre::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--liseré);
}

@media (max-width: 620px) {
  .pvp {
    padding: 1.2rem 1rem 1rem;
  }

  .pvp-corps {
    flex-direction: column;
    align-items: flex-start;
    gap: .9rem;
  }

  .pvp-action {
    width: 100%;
  }

  .pvp-action .btn {
    flex: 1;
    justify-content: center;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   APERÇU D'UNE CAPACITÉ
   ═════════════════════════════════════════════════════════════════════════════ */

/* Bouton sur la vignette : discret au repos, il se révèle au survol */
.card {
  position: relative;
}

.card-apercu {
  /* Au-dessus de l'illustration agrandie (z-index 999 au survol) : sans cela,
     l'image zoomée passait devant le bouton et le rendait incliquable. */
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1200;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: .26rem .55rem;
  cursor: pointer;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .6rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--or-vif);
  background: rgba(8, 7, 12, .82);
  border: 1px solid var(--liseré-fort);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity .18s, transform .18s, background .18s;
}

.card:hover .card-apercu,
.card-apercu:focus-visible {
  opacity: 1;
  transform: none;
}

/* Survoler le bouton suspend le zoom : l'illustration ne vient plus s'intercaler */
.card:has(.card-apercu:hover) .img-wrap {
  pointer-events: none;
}

.card-apercu {
  pointer-events: auto;
}

.card-apercu:hover {
  background: rgba(242, 193, 78, .22);
  color: #fff;
}

/* Sur écran tactile, il n'y a pas de survol : le bouton reste visible */
@media (hover: none) {
  .card-apercu {
    opacity: 1;
    transform: none;
  }
}

/* ── La fenêtre d'aperçu ── */
.ap-overlay {
  position: fixed;
  inset: 0;
  z-index: 9400;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: radial-gradient(ellipse at 50% 40%, rgba(12, 10, 20, .86), rgba(4, 3, 8, .97));
  backdrop-filter: blur(12px);
  opacity: 0;
  transition: opacity .3s ease-out;
}

.ap-overlay.visible {
  opacity: 1;
}

.ap-boite {
  position: relative;
  width: 100%;
  max-width: 780px;
  padding: 2rem 2rem 1.4rem;
  background: linear-gradient(170deg, var(--feutre-2), var(--nuit-2) 76%);
  border: 1px solid var(--liseré-fort);
  clip-path: polygon(24px 0, 100% 0, 100% calc(100% - 24px), calc(100% - 24px) 100%, 0 100%, 0 24px);
  box-shadow: 0 36px 100px rgba(0, 0, 0, .85);
  transform: translateY(20px) scale(.97);
  transition: transform .35s cubic-bezier(.2, .9, .2, 1);
}

.ap-overlay.visible .ap-boite {
  transform: none;
}

.ap-fermer {
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 3;
  width: 30px;
  height: 30px;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--liseré);
  color: var(--texte-3);
  font-size: .9rem;
  transition: all .16s;
}

.ap-fermer:hover {
  color: var(--sang);
  border-color: rgba(224, 82, 79, .5);
}

.ap-entete {
  text-align: center;
  margin-bottom: 1.2rem;
}

.ap-effet {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.4rem;
  text-transform: uppercase;
  letter-spacing: -.01em;
  background: linear-gradient(115deg, var(--or-vif), var(--or) 55%, var(--arc-vif));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.ap-carte-nom {
  font-size: .78rem;
  color: var(--texte-3);
  margin-top: .2rem;
  letter-spacing: .04em;
}

.ap-desc {
  font-size: .88rem;
  color: var(--texte-2);
  line-height: 1.6;
  margin: .7rem auto 0;
  max-width: 520px;
}

/* La scène : même perspective que l'arène, en plus petit */
.ap-scene {
  perspective: 1400px;
  perspective-origin: 50% 30%;
  padding: .6rem 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 300px;
}

.ap-plateau {
  position: relative;
  width: 100%;
  /* Inclinaison douce et écart généreux : à 26° les deux rangées se
     chevauchaient, la perspective écrasant l'espacement vertical. */
  display: flex;
  flex-direction: column;
  gap: 3.2rem;
  padding: 1.8rem 1rem;
  transform-style: preserve-3d;
  transform: rotateX(16deg);
}

/* Le feutre vit sur un calque PROPRE, en retrait. Porté par le conteneur 3D
   lui-même, il masquait la rangée adverse : un enfant placé en Z négatif passe
   derrière le fond de son parent et disparaît. */
.ap-plateau::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  transform: translateZ(-60px);
  background:
    radial-gradient(ellipse 60% 45% at 50% 50%, rgba(110, 139, 255, .13), transparent 62%),
    radial-gradient(ellipse 85% 75% at 50% 50%, #1b1728, #0b0912 76%);
  border-radius: 20px;
  box-shadow: 0 0 0 1px rgba(242, 193, 78, .18), 0 24px 50px rgba(0, 0, 0, .8), inset 0 0 90px rgba(0, 0, 0, .7);
}

.ap-rangee {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  gap: .7rem;
  transform-style: preserve-3d;
}

.ap-adverse {
  transform: translateZ(-24px);
}

.ap-adverse .ap-carte img {
  filter: brightness(.88) saturate(.94);
}

.ap-carte {
  width: clamp(64px, 9vw, 92px);
  transform: translateZ(3px);
  transition: transform .25s cubic-bezier(.25, .8, .3, 1), box-shadow .25s, filter .25s;
}

.ap-carte .bt-cname {
  font-size: .64rem;
}

.ap-carte .bt-hp {
  height: 12px;
}

.ap-carte .bt-hp b {
  font-size: .52rem;
}

.ap-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: .8rem;
  padding-top: .9rem;
  border-top: 1px solid var(--liseré);
}

.ap-legende {
  font-size: .78rem;
  color: var(--texte-3);
}

.ap-boutons {
  display: flex;
  align-items: center;
  gap: .8rem;
}

.ap-issue {
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .05em;
  color: var(--or-vif);
}

@media (max-width: 640px) {
  .ap-boite {
    padding: 1.5rem 1rem 1rem;
  }

  .ap-scene {
    padding: .6rem 14px;
    min-height: 200px;
  }

  .ap-plateau {
    transform: rotateX(16deg);
    gap: 1rem;
  }

  .ap-effet {
    font-size: 1.1rem;
  }

  .ap-pied {
    justify-content: center;
    text-align: center;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   À QUI DE JOUER — la table le dit d'elle-même
   ═════════════════════════════════════════════════════════════════════════════ */

/* Le camp actif s'éclaire, l'autre s'estompe. On lit la situation d'un coup
   d'œil sans quitter les cartes des yeux. */
.bt-scene[data-tour="moi"] .bt-mine,
.bt-scene[data-tour="adverse"] .bt-enemy {
  filter: none;
}

/* La bascule d'éclairage suit le flux de particules : elle est volontairement
   lente et légèrement retardée, pour que le regard ait le temps de traverser
   la table avec lui. */
.bt-scene .bt-card {
  transition: filter .75s cubic-bezier(.3, .8, .3, 1) .18s;
}

.bt-scene[data-tour="moi"] .bt-enemy .bt-card,
.bt-scene[data-tour="adverse"] .bt-mine .bt-card {
  filter: brightness(.72) saturate(.72);
}

/* Liseré lumineux sous la rangée qui joue */
.bt-scene[data-tour] .bt-team {
  position: relative;
}

.bt-scene[data-tour="moi"] .bt-mine::after,
.bt-scene[data-tour="adverse"] .bt-enemy::after {
  content: "";
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: -14px;
  height: 3px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--or) 18%, var(--or-vif) 50%, var(--or) 82%, transparent);
  box-shadow: 0 0 22px rgba(242, 193, 78, .8);
  animation: tourActif 2.2s ease-in-out infinite;
}

.bt-scene[data-tour="adverse"] .bt-enemy::after {
  bottom: auto;
  top: -14px;
  background: linear-gradient(90deg, transparent, var(--sang) 18%, #f0a5a3 50%, var(--sang) 82%, transparent);
  box-shadow: 0 0 22px rgba(224, 82, 79, .7);
}

@keyframes tourActif {

  0%,
  100% {
    opacity: .5;
    transform: scaleX(.94);
  }

  50% {
    opacity: 1;
    transform: scaleX(1);
  }
}

/* Apparition du liseré : il se déploie depuis le centre, dans le sens du flux */
.bt-scene[data-tour="moi"] .bt-mine::after,
.bt-scene[data-tour="adverse"] .bt-enemy::after {
  animation: tourArrive .55s cubic-bezier(.2, .9, .2, 1), tourActif 2.2s ease-in-out .55s infinite;
}

@keyframes tourArrive {
  0% {
    opacity: 0;
    transform: scaleX(.1);
  }

  60% {
    opacity: 1;
    transform: scaleX(1.04);
  }

  100% {
    opacity: .5;
    transform: scaleX(.94);
  }
}

/* Halo du feutre, teinté selon le camp actif */
.bt-scene[data-tour="moi"] .bt-table-glow {
  background: radial-gradient(ellipse, rgba(242, 193, 78, .2), rgba(110, 139, 255, .05) 46%, transparent 72%);
}

.bt-scene[data-tour="adverse"] .bt-table-glow {
  background: radial-gradient(ellipse, rgba(224, 82, 79, .14), rgba(110, 139, 255, .05) 46%, transparent 72%);
}

.bt-table-glow {
  transition: background .6s ease-out;
}

/* Fin de partie : tout s'éteint, plus aucun camp n'est mis en avant */
.bt-scene[data-tour="fin"] .bt-card {
  filter: brightness(.8) saturate(.7);
}

/* Animations réduites : déclenchées par le réglage du jeu, et non plus par
   celui du système (Windows coupe les animations pour des raisons de
   performance, ce qui figeait les cartes sans que le joueur l'ait voulu). */
  html.anim-reduites .bt-scene[data-tour] .bt-team::after {
    animation: none;
  }


/* ── Le truc sur la table ──
   Objet volontairement pixelisé, comme l'illustration de la carte. */
.fx-truc {
  position: absolute;
  width: 22px;
  height: 62px;
  transform: translate(-50%, -50%) rotate(6deg);
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .12) 0 4px, transparent 4px 8px),
    repeating-linear-gradient(180deg, rgba(0, 0, 0, .1) 0 4px, transparent 4px 8px),
    linear-gradient(100deg, #fbcfe8, #f9a8d4 55%, #db8fb4);
  border-radius: 13px 13px 6px 6px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, .6), inset -4px 0 8px rgba(0, 0, 0, .18);
  animation: trucDandine .5s ease-in-out infinite;
  filter: blur(.6px);
  /* flou léger, comme sur la carte */
}

@keyframes trucDandine {

  0%,
  100% {
    transform: translate(-50%, -50%) rotate(6deg);
  }

  50% {
    transform: translate(-50%, -54%) rotate(-6deg);
  }
}

/* La plongée : rapide, sèche, sans insistance */
.fx-truc.plonge {
  animation: trucPlonge .24s cubic-bezier(.5, 0, .9, .6) forwards;
}

@keyframes trucPlonge {
  0% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  70% {
    transform: translate(-50%, calc(-50% + var(--plonge, 60px))) rotate(0deg) scaleY(.9);
  }

  100% {
    transform: translate(-50%, calc(-50% + var(--plonge, 60px))) rotate(0deg) scaleY(.8);
  }
}

/* La carte encaisse : elle s'écrase puis rebondit */
@keyframes fxEnfonce {
  0% {
    transform: translateZ(3px) scaleY(1);
  }

  25% {
    transform: translateZ(3px) scaleY(.86) translateY(6px);
  }

  55% {
    transform: translateZ(3px) scaleY(1.06) translateY(-3px);
  }

  80% {
    transform: translateZ(3px) scaleY(.97);
  }

  100% {
    transform: translateZ(3px) scaleY(1);
  }
}

.bt-card.fx-enfonce {
  animation: fxEnfonce .6s cubic-bezier(.3, 1.4, .5, 1);
}

/* Le bandeau de censure, qui arrive juste trop tard */
@keyframes fxCensure {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scaleX(.3) rotate(-3deg);
  }

  18% {
    opacity: 1;
    transform: translate(-50%, -50%) scaleX(1.06) rotate(-3deg);
  }

  30% {
    transform: translate(-50%, -50%) scaleX(1) rotate(-3deg);
  }

  85% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

.fx-censure {
  position: absolute;
  z-index: 4;
  padding: .3rem 0;
  text-align: center;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .72rem;
  letter-spacing: .22em;
  color: #fff;
  background: #000;
  border: 1px solid rgba(255, 255, 255, .35);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .85);
  animation: fxCensure 1.2s ease-out forwards;
}

/* ── Tigidigidong : la carte se tortille ── */
@keyframes fxChatouille {

  0%,
  100% {
    transform: translateZ(3px) rotate(0deg);
  }

  15% {
    transform: translateZ(3px) rotate(-3deg) translateX(-4px);
  }

  35% {
    transform: translateZ(3px) rotate(3deg) translateX(4px);
  }

  55% {
    transform: translateZ(3px) rotate(-2.4deg) translateX(-3px);
  }

  75% {
    transform: translateZ(3px) rotate(2deg) translateX(3px);
  }
}

.bt-card.fx-chatouille {
  animation: fxChatouille 1.1s ease-in-out;
}

/* ── Poupée de leurre : une silhouette se dresse devant la carte ── */
@keyframes fxPoupee {
  0% {
    opacity: 0;
    transform: translate(-50%, -30%) scaleY(.2);
  }

  25% {
    opacity: 1;
    transform: translate(-50%, -100%) scaleY(1.06);
  }

  35% {
    transform: translate(-50%, -100%) scaleY(1);
  }

  80% {
    opacity: 1;
    transform: translate(-50%, -100%) scaleY(1);
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -100%) scaleY(1);
  }
}

.fx-poupee {
  position: absolute;
  width: 26px;
  height: 46px;
  transform-origin: 50% 100%;
  background: linear-gradient(180deg, rgba(196, 181, 253, .9), rgba(139, 92, 246, .75));
  border: 1px solid rgba(221, 214, 254, .7);
  border-radius: 13px 13px 4px 4px;
  box-shadow: 0 0 16px rgba(167, 139, 250, .6);
  animation: fxPoupee 1.4s ease-out forwards;
}

/* La tête, qui rend la silhouette lisible d'un coup d'œil */
.fx-poupee::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -9px;
  width: 14px;
  height: 14px;
  transform: translateX(-50%);
  background: rgba(221, 214, 254, .95);
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(167, 139, 250, .7);
}

/* ── Carte du deck qu'on ne possède plus ──
   Elle reste visible et cliquable : la masquer bloquait le joueur avec un
   deck de six cartes fantômes impossibles à retirer. */
.deck-slot-perdue {
  display: grid;
  place-items: center;
  gap: 2px;
  aspect-ratio: 450/490;
  background: rgba(224, 82, 79, .12);
  border-color: rgba(224, 82, 79, .6) !important;
  color: #f0a5a3;
  font-size: 1.4rem;
  animation: slotPerdu 1.6s ease-in-out infinite;
}

@keyframes slotPerdu {

  0%,
  100% {
    box-shadow: 0 0 0 1px rgba(224, 82, 79, .4);
  }

  50% {
    box-shadow: 0 0 0 1px rgba(224, 82, 79, .9), 0 0 18px rgba(224, 82, 79, .45);
  }
}

.deck-slot-perdue .deck-slot-cost {
  background: var(--sang);
  color: #fff;
}

/* Bouton de secours */
.deck-vider {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: -.8rem 0 1.4rem;
  padding: .4rem .9rem;
  cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  font-size: .76rem;
  background: transparent;
  border: 1px solid var(--liseré);
  color: var(--texte-3);
  transition: all .16s;
}

.deck-vider:hover {
  color: var(--sang);
  border-color: rgba(224, 82, 79, .5);
  background: rgba(224, 82, 79, .07);
}

/* Quand des cartes fantômes traînent, le bouton se signale */
.deck-vider.urgent {
  color: #f0a5a3;
  border-color: rgba(224, 82, 79, .5);
  background: rgba(224, 82, 79, .1);
  animation: slotPerdu 1.8s ease-in-out infinite;
}

/* ── Mort subite ──
   Un bandeau permanent explique pourquoi TOUTES les cartes perdent des points
   de vie. Sans lui, le joueur attribue ces pertes à son attaque et croit à
   un bug — c'est exactement ce qui a été signalé. */
.bt-mort-subite {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: .8rem;
  flex-wrap: wrap;
  margin: .4rem 0 0;
  padding: .55rem 1rem;
  background: linear-gradient(90deg, rgba(224, 82, 79, .18), rgba(224, 82, 79, .06));
  border-left: 3px solid var(--sang);
  animation: msPulse 2.4s ease-in-out infinite;
}

.bt-ms-titre {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .76rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #f0a5a3;
  white-space: nowrap;
}

.bt-ms-texte {
  font-size: .78rem;
  color: var(--texte-2);
  line-height: 1.5;
}

.bt-ms-texte b {
  color: #f7b3b1;
}

@keyframes msPulse {

  0%,
  100% {
    box-shadow: inset 0 0 0 rgba(224, 82, 79, 0);
  }

  50% {
    box-shadow: inset 0 0 26px rgba(224, 82, 79, .14);
  }
}

@media (max-width: 700px) {
  .bt-mort-subite {
    padding: .4rem .6rem;
    gap: .4rem;
  }

  .bt-ms-texte {
    font-size: .68rem;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   MORT SUBITE — vignette d'écran
   L'intensité suit les dégâts du tour : discrète au début, oppressante à la
   fin. Trois couches distinctes plutôt qu'un simple dégradé, sinon l'effet
   reste plat.
   ═════════════════════════════════════════════════════════════════════════════ */

.ms-vignette {
  position: fixed;
  inset: 0;
  z-index: 8500;
  pointer-events: none;
  --ms-force: .3;
  --ms-rythme: 2.4s;
}

/* Couche 1 — le cerne rouge, qui respire */
.ms-bord {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 78% 68% at 50% 50%, transparent 52%,
      rgba(224, 82, 79, calc(.22 + var(--ms-force) * .34)) 88%,
      rgba(150, 30, 28, calc(.32 + var(--ms-force) * .38)) 100%);
  animation: msRespire var(--ms-rythme) ease-in-out infinite;
}

@keyframes msRespire {

  0%,
  100% {
    opacity: .62;
    transform: scale(1.015);
  }

  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Couche 2 — un liseré net sur le pourtour, qui donne le côté « cadre » */
.ms-vignette::before {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow:
    inset 0 0 0 2px rgba(224, 82, 79, calc(.25 + var(--ms-force) * .45)),
    inset 0 0 60px rgba(224, 82, 79, calc(.12 + var(--ms-force) * .3));
  animation: msRespire var(--ms-rythme) ease-in-out infinite;
}

/* Couche 3 — un éclat qui balaie le cadre, pour que ça ne soit jamais figé */
.ms-eclair {
  position: absolute;
  inset: -30%;
  background: conic-gradient(from 0deg,
      transparent 0deg, rgba(255, 120, 116, .16) 40deg, transparent 90deg,
      transparent 180deg, rgba(255, 120, 116, .12) 220deg, transparent 270deg);
  opacity: calc(.25 + var(--ms-force) * .45);
  animation: msTourne 7s linear infinite;
  mix-blend-mode: screen;
}

@keyframes msTourne {
  to {
    transform: rotate(360deg);
  }
}

/* ── Entrée : le titre frappe, la vignette se referme sur l'écran ── */
.ms-titre {
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translate(-50%, -50%);
  opacity: 0;
}

.ms-titre span {
  display: block;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: clamp(2rem, 7vw, 4.4rem);
  letter-spacing: .12em;
  color: #fff;
  text-shadow: 0 0 30px rgba(224, 82, 79, .95), 0 6px 40px rgba(0, 0, 0, .9);
  white-space: nowrap;
}

.ms-vignette.declenche .ms-titre {
  animation: msTitre 2.2s cubic-bezier(.2, .9, .2, 1) forwards;
}

@keyframes msTitre {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(2.6);
    filter: blur(14px);
  }

  14% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
    filter: blur(0);
  }

  62% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }

  100% {
    opacity: 0;
    transform: translate(-50%, -56%) scale(1.06);
  }
}

.ms-vignette.declenche .ms-bord {
  animation: msEntree 1.1s cubic-bezier(.2, .9, .2, 1), msRespire var(--ms-rythme) ease-in-out 1.1s infinite;
}

@keyframes msEntree {
  0% {
    opacity: 0;
    transform: scale(1.5);
  }

  45% {
    opacity: 1;
    transform: scale(.985);
  }

  100% {
    opacity: .62;
    transform: scale(1.015);
  }
}

/* ── Battement à chaque tour : le cadre se resserre brièvement ── */
.ms-vignette.battement .ms-bord {
  animation: msBattement .7s ease-out, msRespire var(--ms-rythme) ease-in-out .7s infinite;
}

@keyframes msBattement {
  0% {
    opacity: 1;
    transform: scale(.975);
  }

  40% {
    opacity: .85;
    transform: scale(1.01);
  }

  100% {
    opacity: .62;
    transform: scale(1.015);
  }
}

/* Le bandeau explicatif reste, mais discret : la vignette porte l'alerte */
body.en-mort-subite .bt-mort-subite {
  animation: none;
  opacity: .92;
}

/* Animations réduites : déclenchées par le réglage du jeu, et non plus par
   celui du système (Windows coupe les animations pour des raisons de
   performance, ce qui figeait les cartes sans que le joueur l'ait voulu). */

  html.anim-reduites .ms-bord,
  html.anim-reduites .ms-eclair,
  html.anim-reduites .ms-vignette::before,
  html.anim-reduites .ms-titre {
    animation: none !important;
  }

  html.anim-reduites .ms-titre {
    opacity: 0;
  }


/* ─────────────────────────────────────────────────────────────────────────────
   LISIBILITÉ DU COMBAT
   Attaque colorée, états chiffrés, prévision des dégâts, fiche détaillée,
   bandeau « dernier coup » et page d'aide. Le joueur doit pouvoir deviner
   le résultat d'un coup avant de le jouer.
   ───────────────────────────────────────────────────────────────────────────── */

.haut { color: #86efac; }
.bas { color: #fca5a5; }

/* ── Attaque ── */
.bt-atk {
  font-weight: 700;
  color: var(--texte);
  cursor: help;
}
.bt-atk i {
  font-style: normal;
  font-size: .8em;
  margin-left: 1px;
}
.bt-atk.haut { color: #86efac; }
.bt-atk.bas { color: #fca5a5; }
/* Un modificateur temporaire est souligné : il va disparaître */
.bt-atk.tempo {
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}

.bt-cd {
  display: inline-block;
  padding: 0 4px;
  margin-left: 2px;
  background: rgba(0, 0, 0, .45);
  border: 1px solid var(--liseré);
  color: var(--texte-2);
  font-size: .9em;
}
.bt-eff.recharge { color: var(--texte-3); }

/* ── États chiffrés ── */
.bt-states .etat {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  padding: 0 3px;
  border: 1px solid transparent;
  cursor: help;
  line-height: 1.5;
}
.bt-states .etat i {
  font-style: normal;
  font-weight: 700;
  font-size: .9em;
}
.bt-states .etat.bon {
  background: rgba(74, 222, 128, .1);
  border-color: rgba(74, 222, 128, .28);
  color: #bbf7d0;
}
.bt-states .etat.mauvais {
  background: rgba(224, 82, 79, .12);
  border-color: rgba(224, 82, 79, .32);
  color: #fecaca;
}

/* ── « A joué » ── */
.bt-joue {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  padding: 1px 6px;
  font-size: .56rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: rgba(0, 0, 0, .75);
  border: 1px solid var(--liseré);
  color: var(--texte-2);
  pointer-events: none;
  white-space: nowrap;
}

/* ── Pastille de prévision posée sur une cible ── */
.bt-prev {
  position: absolute;
  top: 34%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  padding: 3px 8px;
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: .95rem;
  white-space: nowrap;
  color: #fff;
  background: rgba(20, 8, 10, .88);
  border: 1px solid rgba(252, 165, 165, .7);
  box-shadow: 0 0 18px rgba(224, 82, 79, .45);
  pointer-events: none;
  animation: btPrev .25s ease-out;
}
.bt-prev.ko {
  background: rgba(127, 29, 29, .95);
  border-color: #fca5a5;
}
.bt-mine .bt-prev {
  border-color: rgba(134, 239, 172, .7);
  box-shadow: 0 0 18px rgba(74, 222, 128, .35);
  background: rgba(6, 30, 16, .88);
}
@keyframes btPrev {
  from { opacity: 0; transform: translate(-50%, -30%); }
  to { opacity: 1; transform: translate(-50%, -50%); }
}

/* ── Actions ── */
.bt-actions .btn small {
  margin-left: .3rem;
  opacity: .75;
  font-weight: 600;
}
.bt-formule {
  display: inline-block;
  margin-left: .4rem;
  padding: 0 .4rem;
  border: 1px solid var(--liseré);
  color: var(--or);
  font-size: .72rem;
}

/* ── Bandeau « dernier coup » ── */
.bt-coup {
  flex-shrink: 0;
  margin: .45rem auto 0;
  max-width: 980px;
  width: 100%;
  padding: .45rem .9rem;
  background: rgba(0, 0, 0, .38);
  border: 1px solid var(--liseré);
  border-left: 3px solid var(--or);
  font-size: .76rem;
  color: var(--texte-2);
  line-height: 1.5;
  min-height: 2.2rem;
}
.bt-coup.vide {
  color: var(--texte-3);
  font-style: italic;
  border-left-color: var(--liseré);
}
.bt-coup.frais { animation: btCoup .5s ease-out; }
@keyframes btCoup {
  from { background: rgba(242, 193, 78, .2); }
  to { background: rgba(0, 0, 0, .38); }
}
.coup-titre { color: var(--texte); }
.coup-calc {
  margin-left: .4rem;
  color: var(--texte-3);
  font-size: .92em;
}
.coup-info { color: var(--texte-3); font-size: .92em; }
.coup-cibles {
  display: flex;
  flex-wrap: wrap;
  gap: .15rem .9rem;
  margin-top: .15rem;
}
.coup-pv { color: #fca5a5; }
.coup-soin { color: #86efac; }
.coup-ko {
  color: #fff;
  background: #b91c1c;
  padding: 0 4px;
}
.c-moi { color: var(--or-vif); }
.c-adv { color: #f0a5a3; }

/* ── Chiffres flottants supplémentaires ── */
.fx-num-bloque {
  color: #bfdbfe;
  font-size: .95rem;
  margin-top: -26px;
}
.fx-num-poison {
  color: #86efac;
  font-size: 1.05rem;
}

/* ── Fiche détaillée ── */
.bt-fiche {
  position: fixed;
  z-index: 9700;
  width: 290px;
  max-width: calc(100vw - 16px);
  max-height: calc(100vh - 16px);
  overflow-y: auto;
  padding: .75rem .85rem;
  background: linear-gradient(170deg, rgba(23, 20, 38, .98), rgba(8, 7, 12, .98));
  border: 1px solid var(--liseré-fort);
  box-shadow: var(--ombre);
  font-size: .78rem;
  color: var(--texte-2);
  line-height: 1.45;
  pointer-events: none;
}
.bt-fiche[hidden] { display: none; }
.fiche-tete {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: .5rem;
  margin-bottom: .35rem;
}
.fiche-tete b {
  font-family: var(--police-titre);
  color: var(--texte);
  font-size: .95rem;
}
.fiche-tete span { font-size: .68rem; color: var(--texte-3); }
.fiche-ligne { margin-top: .2rem; color: var(--texte); }
.fiche-sous {
  font-size: .64rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--texte-3);
  margin-bottom: .1rem;
}
.fiche-prev {
  margin: .2rem 0 .5rem;
  padding: .4rem .55rem;
  background: rgba(224, 82, 79, .1);
  border: 1px solid rgba(224, 82, 79, .35);
  color: var(--texte);
}
.fiche-calc, .fiche-etats {
  list-style: none;
  margin: .2rem 0 0;
  padding: 0 0 0 .6rem;
  border-left: 1px solid var(--liseré);
}
.fiche-calc li.bon, .fiche-etats li.bon { color: #bbf7d0; }
.fiche-calc li.mauvais, .fiche-etats li.mauvais { color: #fecaca; }
.fiche-etats { margin-top: .5rem; }
.fiche-etats li { margin-top: .15rem; }
.fiche-etats li span { margin-right: .25rem; }
.fiche-note {
  margin-top: .2rem;
  font-size: .7rem;
  color: var(--texte-3);
}
.fiche-cap {
  margin-top: .5rem;
  padding-top: .45rem;
  border-top: 1px solid var(--liseré);
}
.fiche-cap b { color: var(--or); }

/* ── Bouton et page d'aide ── */
.bt-aide-btn {
  background: transparent;
  border: 1px solid var(--liseré-fort);
  color: var(--or);
  font: inherit;
  font-size: .75rem;
  padding: .25rem .6rem;
  cursor: pointer;
}
.bt-aide-btn:hover { background: rgba(242, 193, 78, .12); }

.bt-aide {
  position: fixed;
  inset: 0;
  z-index: 9800;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(4, 3, 8, .78);
  backdrop-filter: blur(4px);
}
.bt-aide-boite {
  position: relative;
  width: min(880px, 100%);
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  padding: 1.4rem 1.6rem;
  background: linear-gradient(170deg, var(--feutre-2), var(--nuit-2));
  border: 1px solid var(--liseré-fort);
  box-shadow: var(--ombre);
  color: var(--texte-2);
  font-size: .86rem;
  line-height: 1.55;
}
.bt-aide-boite h2 {
  font-family: var(--police-titre);
  color: var(--texte);
  margin: 0 0 .8rem;
  font-size: 1.3rem;
}
.bt-aide-boite h3 {
  font-family: var(--police-titre);
  color: var(--or);
  font-size: .9rem;
  margin: .6rem 0 .3rem;
}
.bt-aide-boite p { margin: .25rem 0; }
.bt-aide-boite ol { margin: .2rem 0; padding-left: 1.2rem; }
.bt-aide-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: .4rem 1.4rem;
}
.bt-aide-fermer {
  position: absolute;
  top: .6rem;
  right: .8rem;
  background: none;
  border: none;
  color: var(--texte-2);
  font-size: 1.1rem;
  cursor: pointer;
}
.bt-aide-icones {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
}
.bt-aide-icones span {
  padding: .1rem .45rem;
  border: 1px solid var(--liseré);
  font-size: .78rem;
}
.bt-aide-icones .bon { color: #bbf7d0; }
.bt-aide-icones .mauvais { color: #fecaca; }
.bt-aide-astuce {
  margin-top: .8rem !important;
  color: var(--texte-3);
  font-style: italic;
}

/* ─────────────────────────────────────────────────────────────────────────────
   TUTORIEL
   ───────────────────────────────────────────────────────────────────────────── */

.tuto-intro .btn { margin-top: 1.2rem; }
.tuto-plan {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: .6rem;
  margin-top: 1rem;
}
.tuto-plan-item {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .7rem .9rem;
  background: var(--panneau);
  border: 1px solid var(--liseré);
}
.tuto-plan-item b {
  font-family: var(--police-titre);
  color: var(--or);
  font-size: 1.2rem;
}

/* Invitation dans le salon de combat */
.tuto-banniere {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin: 0 0 1rem;
  padding: .8rem 1rem;
  background: linear-gradient(100deg, rgba(242, 193, 78, .16), rgba(110, 139, 255, .1));
  border: 1px solid var(--liseré-fort);
  color: var(--texte);
  text-decoration: none;
  transition: background .2s;
}
.tuto-banniere:hover { background: linear-gradient(100deg, rgba(242, 193, 78, .24), rgba(110, 139, 255, .16)); }
.tuto-banniere-ico { font-size: 1.6rem; }
.tuto-banniere-texte { flex: 1; font-size: .88rem; color: var(--texte-2); }
.tuto-banniere-texte b { color: var(--texte); margin-right: .3rem; }
.tuto-banniere-go { color: var(--or); font-weight: 600; white-space: nowrap; }
.tuto-banniere.discrete {
  padding: .4rem .8rem;
  background: transparent;
  border-color: var(--liseré);
}
.tuto-banniere.discrete .tuto-banniere-ico,
.tuto-banniere.discrete .tuto-banniere-texte { display: none; }
.tuto-banniere.discrete .tuto-banniere-go { font-size: .82rem; }
.tuto-banniere.discrete .tuto-banniere-go::before { content: "Revoir les règles · "; color: var(--texte-3); font-weight: 400; }

/* Élément mis en évidence par le coach */
.tuto-focus {
  outline: 2px solid var(--or-vif) !important;
  outline-offset: 2px;
  animation: tutoFocus 1.4s ease-in-out infinite;
}
.bt-card.tuto-focus { clip-path: none; }
@keyframes tutoFocus {
  0%, 100% { outline-color: rgba(240, 205, 142, .95); box-shadow: 0 0 0 0 rgba(240, 205, 142, .0); }
  50% { outline-color: rgba(240, 205, 142, .35); box-shadow: 0 0 22px 2px rgba(240, 205, 142, .35); }
}

/* Coach */
.coach {
  position: fixed;
  /* À droite, par-dessus le journal : à gauche, il masquait la première carte */
  right: .8rem;
  top: 8.4rem;
  z-index: 9650;
  width: min(340px, calc(100vw - 2rem));
  background: linear-gradient(170deg, rgba(30, 26, 46, .98), rgba(10, 9, 16, .98));
  border: 1px solid var(--liseré-fort);
  box-shadow: var(--ombre), 0 0 30px rgba(242, 193, 78, .12);
  color: var(--texte-2);
  font-size: .84rem;
  line-height: 1.55;
}
.coach[hidden] { display: none; }
.coach.pulse { animation: coachPulse .5s ease-out; }
@keyframes coachPulse {
  from { transform: translateY(8px); opacity: .4; }
  to { transform: none; opacity: 1; }
}
.coach-tete {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .45rem .8rem;
  border-bottom: 1px solid var(--liseré);
}
.coach-ico { font-size: 1.1rem; }
.coach-etape {
  flex: 1;
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--texte-3);
}
.coach-reduire {
  background: none;
  border: none;
  color: var(--texte-2);
  cursor: pointer;
  font-size: 1rem;
  transition: transform .2s;
}
.coach.reduit .coach-reduire { transform: rotate(180deg); }
.coach.reduit .coach-corps { display: none; }
.coach-corps {
  padding: .7rem .9rem .85rem;
  max-height: 46vh;
  overflow-y: auto;
}
.coach-titre {
  font-family: var(--police-titre);
  color: var(--texte);
  font-size: 1.02rem;
  margin: 0 0 .35rem;
}
.coach-texte b { color: var(--texte); }
.coach-actions {
  margin-top: .7rem;
  display: flex;
  justify-content: flex-end;
}
.coach-consigne {
  font-size: .76rem;
  color: var(--or);
}
.coach-attente {
  margin-top: .5rem;
  font-size: .76rem;
  color: var(--texte-3);
  display: flex;
  align-items: center;
  gap: .4rem;
}
.coach-attente[hidden] { display: none; }
.coach-point {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sang);
  animation: tutoFocus 1s infinite;
}

.tuto-bilan {
  text-align: left;
  margin: 1rem auto;
  max-width: 460px;
  padding-left: 0;
  list-style: none;
  font-size: .86rem;
  color: var(--texte-2);
}
.tuto-bilan li { margin: .3rem 0; }

@media (max-width: 760px) {
  .coach {
    left: .5rem;
    right: .5rem;
    top: auto;
    width: auto;
    bottom: .5rem;
    width: auto;
    font-size: .78rem;
  }
  .coach-corps { max-height: 34vh; }
  .bt-coup { font-size: .68rem; padding: .35rem .6rem; }
  .coup-calc { display: block; margin-left: 0; }
  .bt-prev { font-size: .72rem; padding: 2px 4px; }
  .tuto-banniere { flex-wrap: wrap; }
}

/* Cinq liens ne tiennent plus sur un téléphone : la barre défile
   horizontalement au lieu d'élargir toute la page. */
@media (max-width: 640px) {
  .nav-links {
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-link { white-space: nowrap; padding: .45rem .55rem; }
}

/* Le halo de la table mesure 560 px : sur téléphone, il élargissait toute la
   page (défaut antérieur) et poussait hors écran les éléments fixés comme le
   coach du tutoriel ou la fiche des cartes. */
@media (max-width: 640px) {
  .bt-table-glow { width: 100%; max-width: 560px; }
  html, body { overflow-x: clip; }
}

/* ═════════════════════════════════════════════════════════════════════════════
   VACCIN PFIZER (Wheatley) — la seringue, le signal 5G, la carte connectée
   ═════════════════════════════════════════════════════════════════════════════ */

/* La seringue est ancrée à la pointe de son aiguille (bord droit), que le
   script pose sur la cible : la rotation se fait autour de ce point, si bien
   que l'aiguille vise la carte quel que soit l'angle. */
.fx-seringue {
  position: absolute;
  width: 112px;
  height: 22px;
  transform-origin: 100% 50%;
  transform: translate(-100%, -50%) rotate(var(--angle, 0deg)) scale(var(--echelle, 1)) translateX(-46px);
  opacity: 0;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .6));
  animation: seringueArrive .3s cubic-bezier(.2, .9, .3, 1) forwards;
  pointer-events: none;
}
@keyframes seringueArrive {
  to { opacity: 1; transform: translate(-100%, -50%) rotate(var(--angle, 0deg)) scale(var(--echelle, 1)) translateX(0); }
}
/* La piqûre : l'aiguille s'enfonce d'un coup sec */
.fx-seringue.pique {
  animation: none;
  opacity: 1;
  transition: transform .12s cubic-bezier(.5, 0, .9, .5);
  transform: translate(-100%, -50%) rotate(var(--angle, 0deg)) scale(var(--echelle, 1)) translateX(16px);
}
.fx-seringue.retrait {
  transition: transform .3s ease-in, opacity .3s ease-in;
  transform: translate(-100%, -50%) rotate(var(--angle, 0deg)) scale(var(--echelle, 1)) translateX(-40px);
  opacity: 0;
}

/* Le piston, à gauche : une tige et un appui pour le pouce */
.fx-seringue-piston {
  position: absolute;
  left: 0;
  top: 50%;
  width: 34px;
  height: 4px;
  transform: translateY(-50%);
  background: linear-gradient(180deg, #f1f5f9, #94a3b8);
  border-radius: 2px;
  transition: transform .65s cubic-bezier(.45, 0, .2, 1);
}
.fx-seringue-piston::before {
  content: "";
  position: absolute;
  left: -3px;
  top: -7px;
  width: 5px;
  height: 18px;
  background: linear-gradient(90deg, #e2e8f0, #64748b);
  border-radius: 2px;
}
.fx-seringue.injecte .fx-seringue-piston { transform: translate(26px, -50%); }

/* Le corps transparent, le liquide bleu et la petite étiquette */
.fx-seringue-corps {
  position: absolute;
  left: 30px;
  top: 2px;
  width: 58px;
  height: 18px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .55), rgba(226, 232, 240, .25));
  border: 1px solid rgba(255, 255, 255, .75);
  border-radius: 4px;
  overflow: hidden;
  box-shadow: inset 0 2px 4px rgba(255, 255, 255, .5);
}
.fx-seringue-liquide {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 92%;
  background: linear-gradient(180deg, #7fd3ff, #1d8fe0);
  box-shadow: 0 0 10px rgba(63, 180, 255, .8);
  transition: width .65s cubic-bezier(.45, 0, .2, 1);
}
.fx-seringue.injecte .fx-seringue-liquide { width: 6%; }
.fx-seringue-etiq {
  position: absolute;
  left: 4px;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  font: 800 7px/1 "Bricolage Grotesque", sans-serif;
  letter-spacing: .12em;
  text-align: center;
  color: #0b3a66;
  text-shadow: 0 0 2px rgba(255, 255, 255, .9);
}

/* L'aiguille, fine et brillante, jusqu'à la pointe (bord droit) */
.fx-seringue-aiguille {
  position: absolute;
  right: 0;
  top: 50%;
  width: 26px;
  height: 2px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, #cbd5e1, #ffffff 60%, #e2e8f0);
  border-radius: 0 2px 2px 0;
}
.fx-seringue-aiguille::before {
  content: "";
  position: absolute;
  left: -4px;
  top: -3px;
  width: 6px;
  height: 8px;
  background: #94a3b8;
  border-radius: 1px;
}

/* L'indicateur de réseau qui sort d'une carte vaccinée */
.fx-reseau {
  position: absolute;
  transform: translate(-50%, -100%);
  display: flex;
  align-items: flex-end;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 8px;
  background: rgba(6, 30, 52, .82);
  border: 1px solid rgba(63, 180, 255, .7);
  box-shadow: 0 0 16px rgba(63, 180, 255, .55);
  color: #dff4ff;
  font: 800 12px/1 "Bricolage Grotesque", sans-serif;
  animation: reseauMonte 1.5s ease-out forwards;
  pointer-events: none;
}
.fx-reseau.premier { font-size: 14px; }
.fx-reseau .barres { display: flex; align-items: flex-end; gap: 2px; height: 12px; }
.fx-reseau .barres i { width: 3px; background: rgba(159, 226, 255, .25); border-radius: 1px; }
.fx-reseau .barres i:nth-child(1) { height: 25%; }
.fx-reseau .barres i:nth-child(2) { height: 50%; }
.fx-reseau .barres i:nth-child(3) { height: 75%; }
.fx-reseau .barres i:nth-child(4) { height: 100%; }
.fx-reseau .barres i.on { background: #3fb4ff; box-shadow: 0 0 6px #3fb4ff; }
@keyframes reseauMonte {
  0% { opacity: 0; transform: translate(-50%, -80%) scale(.7); }
  15% { opacity: 1; transform: translate(-50%, -110%) scale(1.05); }
  75% { opacity: 1; transform: translate(-50%, -130%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -150%) scale(.95); }
}

/* Le chiffre flottant des nanoparticules, et « Pfizer love » */
.fx-num-nano {
  color: #9fe2ff;
  -webkit-text-stroke-color: rgba(4, 30, 56, .95);
  font-size: 1.15rem;
  white-space: nowrap;
}

/* Une carte connectée : un liseré bleu qui pulse, comme une diode réseau */
.bt-card.connectee {
  box-shadow: 0 0 0 2px rgba(63, 180, 255, .55), 0 0 18px rgba(63, 180, 255, .35);
  animation: connecteePulse 1.8s ease-in-out infinite;
}
@keyframes connecteePulse {
  50% { box-shadow: 0 0 0 2px rgba(127, 211, 255, .9), 0 0 28px rgba(63, 180, 255, .6); }
}
.bt-card.fx-5g { filter: brightness(1.15) saturate(1.2); }

/* Animations réduites : la seringue apparaît sans bouger, le liseré reste
   fixe — l'information est conservée, seul le mouvement disparaît. */
html.anim-reduites .fx-seringue,
html.anim-reduites .fx-reseau { animation: none; opacity: 1; }
html.anim-reduites .bt-card.connectee { animation: none; }

/* « Pfizer love » : une ligne au-dessus du chiffre de dégâts, qui apparaît
   au même instant au même endroit. Le décalage passe par la marge, pour ne
   pas toucher à l'animation de montée portée par la transformation. */
.fx-num-slogan {
  margin-top: -2.1rem;
  color: #dff4ff;
  font-size: 1.2rem;
  font-style: italic;
  -webkit-text-stroke: 1px rgba(4, 30, 56, .9);
  text-shadow: 0 2px 12px rgba(0, 0, 0, .95), 0 0 20px rgba(63, 180, 255, .9);
}
