/* Styles de /aventure, des combats, duels, Broyeur et du simulateur d'équilibrage : chargés seulement par les pages qui en ont besoin (voir `aventureCss` dans web/server.js). */
/* --- Combat (/combat) : monstre imposant + retour visuel à chaque tour ---
   Le premier passage était jugé trop timide : le monstre doit être
   nettement plus grand, et le combat moins « mou » — dégâts affichés, barres de PV colorées selon
   l'urgence, petites animations au moment de l'impact. `.custom-emoji` (voir plus haut dans ce
   fichier) utilise des unités `em`, donc un emoji personnalisé Discord grossit avec `font-size`
   exactement comme un emoji unicode classique — un seul réglage pour les deux. Toutes les
   animations ci-dessous sont déjà neutralisées site-wide par la règle
   `@media (prefers-reduced-motion: reduce)` plus haut dans ce fichier — rien à répéter ici. */
.combat-arena { text-align: center; }
.combat-monster-stage {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(110px, 22vw, 170px);
  height: clamp(110px, 22vw, 170px);
  margin: 0 auto 0.5rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(124, 58, 237, 0.22), rgba(124, 58, 237, 0) 70%);
  animation: combat-monster-float 3.5s ease-in-out infinite;
}
.combat-monster-emoji { display: inline-block; font-size: clamp(3.5rem, 10vw, 5.5rem); line-height: 1; }
.combat-monster-name { text-align: center; margin: 0 0 0.25rem; }
@keyframes combat-monster-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}

/* Personnage du joueur dans l'arène, en face du monstre. L'armure ÉQUIPÉE (voir web/routes/combat.js:buildCombatVisual)
   représente le personnage, l'arme ÉQUIPÉE est celle qui « frappe » vers le monstre à chaque attaque,
   et chaque compagnon choisi pour le combat frappe avec elle — silhouette générique (🧑 / 👊) si rien
   n'est équipé. Le vrai enchaînement (l'arme part AVANT que les dégâts ne s'affichent) est piloté par
   web/public/combat-live.js, qui ajoute --swing sur l'ANCIEN état affiché avant de remplacer le
   fragment ; sans JavaScript (ou en secours), cette classe n'est jamais posée et le nouvel état
   s'affiche directement, sans animation de coup. */
.combat-stage-row { display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; }
.combat-vs { font-size: 1.5rem; opacity: 0.6; }
.combat-player-stage {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(90px, 18vw, 140px);
  height: clamp(90px, 18vw, 140px);
  margin: 0 auto 0.5rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(46, 204, 113, 0.18), rgba(46, 204, 113, 0) 70%);
}
.combat-player-armor { display: inline-block; font-size: clamp(2.6rem, 7vw, 4rem); line-height: 1; }
.combat-weapon { position: absolute; right: -0.4rem; bottom: 0.2rem; font-size: clamp(1.4rem, 4vw, 2rem); transform: rotate(-30deg); display: inline-block; }
.combat-weapon--swing { animation: combat-weapon-swing 0.42s ease; }
@keyframes combat-weapon-swing {
  0% { transform: rotate(-30deg) translate(0, 0); }
  45% { transform: rotate(35deg) translate(18px, -6px); }
  100% { transform: rotate(-30deg) translate(0, 0); }
}
.combat-companions { position: absolute; left: -0.6rem; bottom: -0.2rem; display: flex; gap: 0.15rem; }
.combat-companion { display: inline-block; font-size: clamp(1.1rem, 3vw, 1.5rem); }
.combat-companions--swing .combat-companion { animation: combat-companion-swing 0.42s ease; }
@keyframes combat-companion-swing {
  0% { transform: translate(0, 0) rotate(0); }
  50% { transform: translate(14px, -4px) rotate(20deg); }
  100% { transform: translate(0, 0) rotate(0); }
}
/* Le personnage vient d'encaisser la riposte du monstre (turn.taken > 0) — même secousse que le
   monstre lorsqu'il est touché (.combat-monster-stage--hit), rejouée sur ce seul chargement. */
.combat-player-stage--hit { animation: combat-shake 0.5s ease; }
@media (max-width: 700px) {
  .combat-stage-row { flex-direction: column; }
  .combat-vs { display: none; }
}

/* --- Combat, round 2 : le monstre riposte aussi visuellement, coups critiques plus marqués,
   poison animé, victoire/défaite plus franches. Toujours des émojis (voir plus haut : aucune image/
   sprite dans ce projet), toujours neutralisées par @media (prefers-reduced-motion: reduce) plus haut
   dans ce fichier. */

/* Le monstre « fonce » vers le joueur quand il riposte (turn.taken > 0) — posée par
   web/public/combat-live.js un instant APRÈS avoir révélé le nouvel état, pour raconter les deux
   coups du tour dans l'ordre (le tien, puis le sien) plutôt que tout d'un coup. Sans JavaScript (ou
   navigateur trop ancien) : classe jamais posée, juste le flottement habituel — dégradation propre. */
.combat-monster-stage--attack { animation: combat-monster-float 3.5s ease-in-out infinite, combat-monster-lunge 0.5s ease; }
@keyframes combat-monster-lunge {
  0%, 100% { transform: translateX(0) scale(1); }
  50% { transform: translateX(-24px) scale(1.05); }
}

/* Éclat de coup critique (pcrit = le tien contre le monstre, mcrit = celui du monstre contre toi) —
   un simple élément en plus (pas une variante de secousse) pour ne jamais entrer en conflit avec les
   animations --hit/--attack déjà posées sur le même élément (la propriété CSS `animation` ne
   s'additionne pas entre deux classes, la dernière déclarée écraserait l'autre). */
.combat-crit-burst { position: absolute; top: -0.4rem; right: -0.2rem; font-size: 1.6rem; animation: crit-burst 0.6s ease-out; pointer-events: none; }
@keyframes crit-burst {
  0% { opacity: 0; transform: scale(0.4) rotate(-10deg); }
  40% { opacity: 1; transform: scale(1.3) rotate(10deg); }
  100% { opacity: 0; transform: scale(1) rotate(0); }
}

/* Éclat de l'Ultime (amélioration) : SON PROPRE élément, distinct de .combat-crit-burst
   ci-dessus (même raison — l'Ultime et un critique peuvent en théorie coexister sur le même coup,
   chacun garde alors sa propre animation). Plus grand, plus long et centré (contrairement au
   critique posé en coin) : l'Ultime ne peut arriver que 3 fois par combat au maximum, il mérite une
   mise en scène qu'on ne confond pas avec un simple critique. */
.combat-ultimate-burst {
  position: absolute;
  top: 50%;
  left: 50%;
  font-size: 2.4rem;
  transform: translate(-50%, -50%);
  animation: ultimate-burst 0.9s ease-out;
  pointer-events: none;
  filter: drop-shadow(0 0 6px rgba(247, 201, 72, 0.85));
}
@keyframes ultimate-burst {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.3) rotate(-20deg); }
  35% { opacity: 1; transform: translate(-50%, -50%) scale(1.6) rotate(15deg); }
  70% { opacity: 1; transform: translate(-50%, -50%) scale(1.2) rotate(-5deg); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4) rotate(0); }
}
/* Neutralisée par la règle globale @media (prefers-reduced-motion: reduce) tout en haut de cette
   section — rien à répéter ici (même remarque que .dmg-float un peu plus bas dans ce fichier). */

/* Bulles de poison : en boucle tant que le statut dure (active.monster_poison_turns /
   player_poison_turns > 0), aucune mise en scène JS nécessaire — contrairement au coup et à la
   riposte, ce n'est pas un évènement ponctuel du tour. */
.combat-poison-fx { position: absolute; bottom: 0; font-size: 1rem; opacity: 0; animation: poison-bubble 2.4s ease-in-out infinite; pointer-events: none; }
.combat-poison-fx--1 { left: 15%; }
.combat-poison-fx--2 { left: 75%; animation-delay: 1.1s; }
@keyframes poison-bubble {
  0% { opacity: 0; transform: translateY(0) scale(0.7); }
  30% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-2.2rem) scale(1); }
}

/* Flammes de brûlure (migration 25) : même principe que les bulles de poison ci-dessus — statut
   indépendant, mêmes déclencheurs (active.monster_burn_turns / player_burn_turns > 0). */
.combat-burn-fx { position: absolute; bottom: 0; font-size: 1rem; opacity: 0; animation: burn-flicker 2.4s ease-in-out infinite; pointer-events: none; }
.combat-burn-fx--1 { left: 15%; }
.combat-burn-fx--2 { left: 75%; animation-delay: 1.1s; }
@keyframes burn-flicker {
  0% { opacity: 0; transform: translateY(0) scale(0.7); }
  30% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-2.2rem) scale(1); }
}

/* Victoire : le monstre vaincu s'affaisse, confettis autour de lui. Défaite : léger halo rouge qui
   pulse sur tout le panneau. Rejoué à l'affichage de l'écran de fin (pas de tour à attendre : la
   redirection/le fragment livré à ce moment-là EST déjà le nouvel état, voir web/routes/combat.js). */
.combat-monster-stage--defeated { animation: combat-monster-collapse 0.7s ease forwards; }
@keyframes combat-monster-collapse {
  0% { transform: scale(1) rotate(0); opacity: 1; }
  100% { transform: scale(0.75) rotate(8deg) translateY(6px); opacity: 0.55; }
}
.combat-confetti { position: relative; height: 0; text-align: center; }
.combat-confetti span { position: absolute; top: 0; font-size: 1.4rem; opacity: 0; animation: combat-confetti-burst 1.1s ease-out forwards; }
.combat-confetti span:nth-child(1) { left: 50%; margin-left: -70px; }
.combat-confetti span:nth-child(2) { left: 50%; margin-left: -30px; animation-delay: 0.05s; }
.combat-confetti span:nth-child(3) { left: 50%; margin-left: 0; animation-delay: 0.1s; }
.combat-confetti span:nth-child(4) { left: 50%; margin-left: 30px; animation-delay: 0.05s; }
.combat-confetti span:nth-child(5) { left: 50%; margin-left: 60px; }
@keyframes combat-confetti-burst {
  0% { opacity: 0; transform: translateY(0) scale(0.6) rotate(0); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-3.5rem) scale(1.1) rotate(25deg); }
}
.combat-arena--defeat { animation: combat-defeat-vignette 1s ease; border-radius: var(--radius-md); }
@keyframes combat-defeat-vignette {
  0%, 100% { box-shadow: none; }
  30% { box-shadow: inset 0 0 60px rgba(231, 76, 60, 0.55); }
}
/* Le monstre vient d'encaisser un coup (voir web/views/combat.ejs : turn.dmg) — une petite
   secousse par-dessus le flottement continu ci-dessus, sur ce seul chargement de page. */
.combat-monster-stage--hit { animation: combat-monster-float 3.5s ease-in-out infinite, combat-shake 0.5s ease; }
@keyframes combat-shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}

/* Bannière de résumé du dernier tour joué (voir turn dans web/routes/combat.js) — neutre comme
   .banner-info, pas success/error : ce n'est ni une confirmation ni un problème. */
.combat-turn-banner { font-size: 1rem; }

/* Barre de PV : même piste arrondie que .xp-bar, mais couleur variable selon le niveau restant
   (.hp-bar-fill--ok/--mid/--low, calculée dans web/views/combat.ejs) plutôt que la teinte fixe de
   .xp-bar-fill — et overflow visible pour laisser dépasser les nombres flottants ci-dessous. */
.hp-bar { position: relative; width: 100%; height: 10px; background: var(--surface-2); border-radius: 999px; overflow: visible; margin: 0.3rem 0; }
.hp-bar-fill { height: 100%; border-radius: 999px; transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
.hp-bar-fill--ok { background: linear-gradient(90deg, #2ECC71, #58D68D); }
.hp-bar-fill--mid { background: linear-gradient(90deg, #F5B041, #F8C471); }
.hp-bar-fill--low { background: linear-gradient(90deg, #E74C3C, #EC7063); }

/* Contour qui pulse en rouge (dégâts) ou en vert (soin) autour de la ligne de PV concernée, sur ce
   seul chargement de page — même principe que .combat-monster-stage--hit ci-dessus. */
.combat-hp-row--flash-red { animation: combat-flash-red 0.7s ease; border-radius: var(--radius-md); }
.combat-hp-row--flash-green { animation: combat-flash-green 0.7s ease; border-radius: var(--radius-md); }
@keyframes combat-flash-red {
  0%, 100% { box-shadow: none; }
  30% { box-shadow: 0 0 0 4px rgba(231, 76, 60, 0.45); }
}
@keyframes combat-flash-green {
  0%, 100% { box-shadow: none; }
  30% { box-shadow: 0 0 0 4px rgba(46, 204, 113, 0.45); }
}

/* Nombre flottant (« -12 », « +8 ») qui s'élève et s'efface au-dessus de la barre concernée, sur
   ce seul chargement de page — `.hp-bar` ci-dessus lui sert d'ancre (position: relative). */
.dmg-float {
  position: absolute;
  right: 0.5rem;
  top: -0.6rem;
  font-weight: 800;
  font-size: 1.15rem;
  animation: dmg-float-rise 1.2s ease-out forwards;
  pointer-events: none;
}
.dmg-float--enemy, .dmg-float--player { color: #F1948A; }
.dmg-float--heal { color: #7EE2A8; }
/* Compétences spéciales (migration 12). Critique : nombre flottant plus gros et doré. Esquive : le
   monstre glisse de côté au lieu de trembler, et « Esquivé » flotte au-dessus de sa barre de PV. Mêmes
   règles que plus haut : rejoué à chaque remplacement du panneau, neutralisé par prefers-reduced-motion. */
.dmg-float--crit { color: #F7C948; font-size: 1.5rem; }
/* L'Ultime (amélioration) : encore plus marqué que le critique — couleur distincte
   (violet/doré plutôt que jaune) pour ne jamais se confondre avec .dmg-float--crit au premier coup d'œil. */
.dmg-float--ultimate { color: #C79CF7; font-size: 1.7rem; text-shadow: 0 0 6px rgba(199, 156, 247, 0.7); }
.dmg-float--dodge { color: #AED6F1; font-size: 1rem; }
.combat-abilities { text-align: center; margin: 0 0 0.75rem; }
/* --- Le Broyeur (onglet de /shop, migration 14) ---
   Animation affichée UNIQUEMENT quand le membre a au moins un broyage en cours : engrenages qui
   tournent, trémie qui tremble, étincelles et pièces qui s'envolent. Neutralisée comme toutes les
   animations du site par la règle globale @media (prefers-reduced-motion: reduce). */
.grinder-badge { display: inline-block; min-width: 1.2rem; padding: 0 0.35rem; border-radius: 999px; background: var(--accent); color: #fff; font-size: 0.75rem; text-align: center; }
.grinder-machine { position: relative; height: 5.5rem; display: flex; justify-content: center; align-items: center; gap: 0.25rem; margin: 0.75rem 0; font-size: 2.2rem; }
.grinder-gear { display: inline-block; animation: grinder-spin 2.4s linear infinite; }
.grinder-gear--small { font-size: 1.5rem; animation-duration: 1.6s; animation-direction: reverse; }
.grinder-hopper { display: inline-block; font-size: 2.6rem; animation: grinder-shake 0.35s ease-in-out infinite; }
.grinder-spark { position: absolute; top: 55%; font-size: 1rem; opacity: 0; animation: grinder-spark 2.2s ease-out infinite; }
.grinder-spark--1 { left: 42%; }
.grinder-spark--2 { left: 50%; animation-delay: 0.7s; }
.grinder-spark--3 { left: 58%; animation-delay: 1.4s; }
@keyframes grinder-spin { to { transform: rotate(360deg); } }
@keyframes grinder-shake { 0%, 100% { transform: translate(0, 0) rotate(0); } 25% { transform: translate(-2px, 1px) rotate(-2deg); } 75% { transform: translate(2px, -1px) rotate(2deg); } }
@keyframes grinder-spark { 0% { opacity: 0; transform: translateY(0) scale(0.6); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(-3.2rem) scale(1.1); } }
.grinder-status { text-align: center; font-weight: 600; margin: 0 0 1rem; }
.grinder-slots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; }
.grinder-slot { border: 1px dashed var(--line); border-radius: var(--radius-md); padding: 0.75rem; min-height: 5rem; }
.grinder-slot--busy { border-style: solid; background: var(--surface-2); }
.grinder-slot-title { margin: 0 0 0.5rem; overflow-wrap: anywhere; }
.grinder-progress { height: 0.6rem; border-radius: 999px; background: var(--line); overflow: hidden; }
.grinder-progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent), #F7C948); background-size: 200% 100%; animation: grinder-flow 2s linear infinite; }
@keyframes grinder-flow { from { background-position: 0 0; } to { background-position: -200% 0; } }
.grinder-list { display: flex; flex-direction: column; gap: 0.5rem; }
.grinder-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; padding: 0.6rem 0; border-bottom: 1px solid var(--line); }
.grinder-row-name { flex: 1 1 12rem; overflow-wrap: anywhere; }
.grinder-warning { display: block; color: #F7C948; font-size: 0.85rem; }
.grinder-qty input { width: 5.5rem; }
.grinder-confirm { display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer; }
.grinder-boost { display: flex; justify-content: center; flex-wrap: wrap; margin: 0 0 1rem; text-align: center; }
@media (max-width: 700px) {
  .grinder-slots { grid-template-columns: 1fr; }
}

/* Poison en cours et choix de série (migration 13). */
.combat-poison { color: #7EE2A8; font-size: 0.9rem; font-weight: 600; }
.combat-burn { color: #FF9F5A; font-size: 0.9rem; font-weight: 600; }
/* Résistance au feu (migration 28) : immunité totale à la brûlure, teinte bleutée pour
   la distinguer d'un coup d'œil de la brûlure elle-même (orange, ci-dessus). */
.combat-fire-resist { color: #6EC6FF; font-size: 0.9rem; font-weight: 600; }
.combat-choice { margin-top: 1rem; padding: 1rem; border-radius: var(--radius-md); background: var(--surface-2); }
/* Choix de la potion et réduction d'attente entre deux combats. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.combat-potion-form { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; max-width: 100%; }
.combat-potion-pick { min-width: 0; max-width: 100%; }
.combat-potion-pick select { max-width: 100%; min-height: 44px; }
.combat-cooldown { margin-top: 0.75rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
.combat-monster-stage--dodge { animation: combat-monster-float 3.5s ease-in-out infinite, combat-dodge 0.6s ease; }
@keyframes combat-dodge {
  0%, 100% { transform: translateX(0); }
  35% { transform: translateX(-26px) rotate(-6deg); }
  70% { transform: translateX(6px); }
}
@keyframes dmg-float-rise {
  0% { opacity: 0; transform: translateY(0); }
  15% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-28px); }
}



/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   /aventure encore plus vivante.
   Tout est ADDITIF (les animations existantes — flottement, poison, brûlure, confettis, secousses — restent
   telles quelles) et scopé aux classes de /aventure. Neutralisé par @media (prefers-reduced-motion: reduce)
   tout en haut de ce fichier : les animations « forwards » y sautent directement à leur état final, donc
   les surcouches temporaires (flash, évolution) finissent invisibles. ═══════════════════════════════════ */

/* 1) Décor d'arène selon la difficulté du monstre : très faible = prairie claire, faible = forêt, moyen = grotte, fort = volcan, très fort = abîme violet.
      Fond dégradé + particules (feuilles / gouttes / braises) qui montent, derrière le contenu. */
.combat-arena { position: relative; overflow: hidden; isolation: isolate; }
.combat-arena > * { position: relative; z-index: 1; }
.combat-arena::before, .combat-arena::after { content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.combat-arena--tres_faible { background: linear-gradient(180deg, rgba(130, 224, 200, 0.10), rgba(25, 60, 58, 0.22)); }
.combat-arena--faible { background: linear-gradient(180deg, rgba(46, 204, 113, 0.10), rgba(20, 60, 35, 0.22)); }
.combat-arena--moyen { background: linear-gradient(180deg, rgba(93, 173, 226, 0.10), rgba(25, 35, 60, 0.30)); }
.combat-arena--fort { background: linear-gradient(180deg, rgba(231, 76, 60, 0.14), rgba(60, 15, 10, 0.36)); }
.combat-arena--tres_fort { background: linear-gradient(180deg, rgba(155, 89, 182, 0.18), rgba(30, 10, 45, 0.46)); }
/* PERFORMANCE : deux couches de particules (une par pseudo-élément) déplacées par `transform` (carte graphique) plutôt que par `background-position`
   (repeint à chaque image). Chaque couche dépasse l'arène par le bas d'exactement son décalage, qui est un nombre ENTIER de tuiles : boucle invisible. */
.combat-arena--tres_faible { --rise-a: 380px; --rise-b: 540px; }
.combat-arena--faible { --rise-a: 340px; --rise-b: 500px; }
.combat-arena--moyen { --rise-a: 400px; --rise-b: 600px; }
.combat-arena--fort { --rise-a: 300px; --rise-b: 420px; }
.combat-arena--tres_fort { --rise-a: 280px; --rise-b: 400px; }
.combat-arena--tres_faible::before, .combat-arena--faible::before, .combat-arena--moyen::before, .combat-arena--fort::before, .combat-arena--tres_fort::before,
.combat-arena--tres_faible::after, .combat-arena--faible::after, .combat-arena--moyen::after, .combat-arena--fort::after, .combat-arena--tres_fort::after {
  background-repeat: repeat; opacity: 0.55; will-change: transform;
}
.combat-arena--tres_faible::after, .combat-arena--faible::after, .combat-arena--moyen::after, .combat-arena--fort::after, .combat-arena--tres_fort::after {
  bottom: calc(var(--rise-a) * -1); animation: arena-rise-a 22s linear infinite;
}
.combat-arena--tres_faible::before, .combat-arena--faible::before, .combat-arena--moyen::before, .combat-arena--fort::before, .combat-arena--tres_fort::before {
  bottom: calc(var(--rise-b) * -1); animation: arena-rise-b 22s linear infinite;
}
.combat-arena--tres_faible::after { background-image: radial-gradient(circle, rgba(190, 240, 225, 0.8) 0 2px, transparent 3px); background-size: 150px 190px; }
.combat-arena--tres_faible::before { background-image: radial-gradient(circle, rgba(150, 225, 205, 0.55) 0 1.5px, transparent 2.5px); background-size: 230px 270px; }
.combat-arena--tres_faible::before, .combat-arena--tres_faible::after { animation-duration: 28s; opacity: 0.45; }
.combat-arena--faible::after { background-image: radial-gradient(circle, rgba(130, 224, 170, 0.8) 0 2px, transparent 3px); background-size: 130px 170px; }
.combat-arena--faible::before { background-image: radial-gradient(circle, rgba(88, 214, 141, 0.6) 0 1.5px, transparent 2.5px); background-size: 210px 250px; }
.combat-arena--moyen::after { background-image: radial-gradient(circle, rgba(174, 214, 241, 0.8) 0 1.5px, transparent 2.5px); background-size: 160px 200px; }
.combat-arena--moyen::before { background-image: radial-gradient(circle, rgba(133, 193, 233, 0.55) 0 2px, transparent 3px); background-size: 240px 300px; }
.combat-arena--moyen::before, .combat-arena--moyen::after { animation-duration: 30s; }
.combat-arena--fort::after { background-image: radial-gradient(circle, rgba(255, 160, 60, 0.95) 0 2px, transparent 3px); background-size: 110px 150px; }
.combat-arena--fort::before { background-image: radial-gradient(circle, rgba(255, 90, 40, 0.75) 0 1.5px, transparent 2.5px); background-size: 170px 210px; }
.combat-arena--fort::before, .combat-arena--fort::after { animation-duration: 12s; opacity: 0.7; }
.combat-arena--tres_fort::after { background-image: radial-gradient(circle, rgba(200, 140, 240, 0.95) 0 2px, transparent 3px); background-size: 100px 140px; }
.combat-arena--tres_fort::before { background-image: radial-gradient(circle, rgba(140, 80, 200, 0.75) 0 1.5px, transparent 2.5px); background-size: 160px 200px; }
.combat-arena--tres_fort::before, .combat-arena--tres_fort::after { animation-duration: 9s; opacity: 0.75; }
/* Chaque couche remonte d'un nombre ENTIER de tuiles (boucle invisible) : 2 × 170, 2 × 250, etc. */
@keyframes arena-rise-a { to { transform: translate3d(0, calc(var(--rise-a) * -1), 0); } }
@keyframes arena-rise-b { to { transform: translate3d(0, calc(var(--rise-b) * -1), 0); } }
.combat-arena--fort.combat-arena--defeat::after, .combat-arena--faible.combat-arena--defeat::after, .combat-arena--moyen.combat-arena--defeat::after, .combat-arena--tres_faible.combat-arena--defeat::after, .combat-arena--tres_fort.combat-arena--defeat::after,
.combat-arena--fort.combat-arena--defeat::before, .combat-arena--faible.combat-arena--defeat::before, .combat-arena--moyen.combat-arena--defeat::before, .combat-arena--tres_faible.combat-arena--defeat::before, .combat-arena--tres_fort.combat-arena--defeat::before { opacity: 0.2; }

/* 2) Monstres vivants : respiration douce + aura derrière l'emoji, plus marquée selon la difficulté. */
.combat-monster-stage { position: relative; }
.combat-monster-emoji { position: relative; z-index: 1; animation: monster-breathe 3.2s ease-in-out infinite; transform-origin: 50% 90%; }
@keyframes monster-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.045, 0.97); } }
.combat-monster-stage::before {
  content: ''; position: absolute; left: 50%; top: 50%; width: 130%; height: 130%; z-index: 0;
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none; opacity: 0;
}
.combat-monster-stage--tres_faible::before { opacity: 0.4; background: radial-gradient(circle, rgba(150, 225, 205, 0.3), transparent 65%); animation: aura-pulse 4.6s ease-in-out infinite; }
.combat-monster-stage--faible::before { opacity: 0.5; background: radial-gradient(circle, rgba(88, 214, 141, 0.35), transparent 65%); animation: aura-pulse 4s ease-in-out infinite; }
.combat-monster-stage--moyen::before { opacity: 0.65; background: radial-gradient(circle, rgba(93, 173, 226, 0.45), transparent 65%); animation: aura-pulse 3.2s ease-in-out infinite; }
.combat-monster-stage--fort::before { opacity: 0.85; background: radial-gradient(circle, rgba(231, 76, 60, 0.55), rgba(245, 176, 65, 0.18) 45%, transparent 68%); animation: aura-pulse 2.2s ease-in-out infinite; }
.combat-monster-stage--fort .combat-monster-emoji { filter: drop-shadow(0 0 10px rgba(231, 76, 60, 0.75)); }
.combat-monster-stage--tres_fort::before { opacity: 0.95; background: radial-gradient(circle, rgba(155, 89, 182, 0.6), rgba(90, 40, 140, 0.2) 45%, transparent 68%); animation: aura-pulse 1.8s ease-in-out infinite; }
.combat-monster-stage--tres_fort .combat-monster-emoji { filter: drop-shadow(0 0 12px rgba(180, 100, 230, 0.85)); }
@keyframes aura-pulse { 0%, 100% { transform: translate(-50%, -50%) scale(0.92); } 50% { transform: translate(-50%, -50%) scale(1.08); } }
.combat-difficulty-badge { display: inline-block; font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.55rem; border-radius: 999px; margin: 0 0 0.3rem; letter-spacing: 0.03em; }
.combat-difficulty-badge--tres_faible { background: rgba(130, 224, 200, 0.2); color: #A8EBD8; }
.combat-difficulty-badge--faible { background: rgba(46, 204, 113, 0.2); color: #7EE2A8; }
.combat-difficulty-badge--moyen { background: rgba(93, 173, 226, 0.2); color: #AED6F1; }
.combat-difficulty-badge--fort { background: rgba(231, 76, 60, 0.25); color: #F1948A; animation: badge-throb 1.6s ease-in-out infinite; }
.combat-difficulty-badge--tres_fort { background: rgba(155, 89, 182, 0.28); color: #D7A8F0; animation: badge-throb-violet 1.4s ease-in-out infinite; }
@keyframes badge-throb-violet { 0%, 100% { box-shadow: 0 0 0 rgba(155, 89, 182, 0); } 50% { box-shadow: 0 0 12px rgba(155, 89, 182, 0.8); } }
@keyframes badge-throb { 0%, 100% { box-shadow: 0 0 0 rgba(231, 76, 60, 0); } 50% { box-shadow: 0 0 12px rgba(231, 76, 60, 0.7); } }

/* 3) Statuts visibles : halo coloré autour du personnage/monstre tant que le statut dure (les bulles 🫧 et
      flammes 🔥 existent déjà ; PAS d'animation ici : elle écraserait les secousses/esquives portées par les
      mêmes éléments), + étourdissement 💫 qui tourne au-dessus de la tête le tour où on est sonné. */
.combat-status--poison { box-shadow: 0 0 18px 2px rgba(88, 214, 141, 0.55), inset 0 0 14px rgba(88, 214, 141, 0.25); }
.combat-status--burn { box-shadow: 0 0 18px 2px rgba(245, 130, 50, 0.6), inset 0 0 14px rgba(245, 130, 50, 0.28); }
.combat-status--poison.combat-status--burn { box-shadow: 0 0 18px 2px rgba(88, 214, 141, 0.5), 0 0 26px 4px rgba(245, 130, 50, 0.45); }
/* Glace (migration 39) : halo bleu glacé + cristaux qui s'élèvent, statut indépendant du poison et de la brûlure. */
.combat-status--ice { box-shadow: 0 0 18px 2px rgba(93, 173, 226, 0.6), inset 0 0 14px rgba(174, 214, 241, 0.3); }
.combat-status--poison.combat-status--ice, .combat-status--burn.combat-status--ice { box-shadow: 0 0 18px 2px rgba(93, 173, 226, 0.55), 0 0 26px 4px rgba(155, 89, 182, 0.35); }
.combat-status-tag--ice { background: rgba(93, 173, 226, 0.24); color: #AED6F1; }
.combat-ice { color: #AED6F1; font-size: 0.85rem; }
.combat-ice-fx { position: absolute; bottom: 0; font-size: 1rem; opacity: 0; animation: ice-crystal 2.4s ease-in-out infinite; pointer-events: none; }
.combat-ice-fx--1 { left: 15%; }
.combat-ice-fx--2 { left: 75%; animation-delay: 1.1s; }
@keyframes ice-crystal {
  0% { opacity: 0; transform: translateY(0) scale(0.7) rotate(0); }
  30% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-2.2rem) scale(1) rotate(60deg); }
}
.combat-stun-fx { position: absolute; top: -0.4rem; left: 50%; transform: translateX(-50%); font-size: 1.6rem; pointer-events: none; animation: stun-orbit 0.9s linear infinite; z-index: 2; }
@keyframes stun-orbit { 0% { transform: translateX(-50%) rotate(0deg) translateX(0.55rem) rotate(0deg); } 100% { transform: translateX(-50%) rotate(360deg) translateX(0.55rem) rotate(-360deg); } }
.combat-status-tags { display: flex; gap: 0.4rem; justify-content: center; flex-wrap: wrap; margin: 0.4rem 0 0; min-height: 0; }
.combat-status-tag { font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.5rem; border-radius: 999px; animation: tag-pop 0.35s ease-out; }
.combat-status-tag--poison { background: rgba(46, 204, 113, 0.22); color: #7EE2A8; }
.combat-status-tag--burn { background: rgba(245, 130, 50, 0.24); color: #F8C471; }
.combat-status-tag--stun { background: rgba(155, 89, 182, 0.28); color: #D7BDE2; }
@keyframes tag-pop { from { transform: scale(0.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* 4) Ultime spectaculaire : jauge qui brille quand elle est pleine, bouton qui pulse, flash + secousse à l'impact. */
.combat-energy--ready .hp-bar-fill { background: linear-gradient(90deg, #A569BD, #F7C948, #A569BD); background-size: 200% 100%; animation: energy-ready-flow 1.4s linear infinite; box-shadow: 0 0 14px rgba(247, 201, 72, 0.85); }
@keyframes energy-ready-flow { to { background-position: -200% 0; } }
.page-aventure .combat-energy--ready .hp-bar-fill { animation: energy-ready-flow 1.4s linear infinite; }
.btn-ultimate-ready { animation: ultimate-ready-pulse 1.1s ease-in-out infinite; box-shadow: 0 0 0 rgba(247, 201, 72, 0.6); }
@keyframes ultimate-ready-pulse { 0%, 100% { transform: scale(1); box-shadow: 0 0 4px rgba(247, 201, 72, 0.4); } 50% { transform: scale(1.06); box-shadow: 0 0 20px rgba(247, 201, 72, 0.95); } }
.combat-ultimate-flash { position: absolute; inset: 0; z-index: 5; pointer-events: none; background: radial-gradient(circle at 70% 40%, rgba(255, 255, 255, 0.95), rgba(199, 156, 247, 0.6) 40%, transparent 75%); opacity: 0; animation: ultimate-flash 0.8s ease-out; }
@keyframes ultimate-flash { 0% { opacity: 0.95; } 100% { opacity: 0; } }
.combat-arena--ultimate { animation: ultimate-shake 0.6s ease; }
@keyframes ultimate-shake { 0%, 100% { transform: translate(0, 0); } 15% { transform: translate(-6px, 3px); } 30% { transform: translate(6px, -3px); } 45% { transform: translate(-4px, -2px); } 60% { transform: translate(4px, 2px); } 80% { transform: translate(-2px, 1px); } }

/* 5) Victoire : pluie de pièces + titre qui éclate + chiffres qui défilent (voir aventure-fx.js). */
.combat-victory-title { display: block; animation: victory-title-in 0.7s cubic-bezier(0.22, 1.4, 0.36, 1); }
@keyframes victory-title-in { from { transform: scale(0.3); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.combat-coin-rain { position: absolute; inset: 0; z-index: 2; pointer-events: none; overflow: hidden; }
.combat-coin-rain span { position: absolute; top: -2rem; font-size: 1.3rem; opacity: 0; animation: coin-fall 2.4s ease-in forwards; }
@keyframes coin-fall { 0% { transform: translateY(0) rotate(0deg); opacity: 0; } 12% { opacity: 1; } 100% { transform: translateY(20rem) rotate(540deg); opacity: 0; } }
.combat-count-up { font-variant-numeric: tabular-nums; }
/* Défaite : le monstre se dresse, le décor se grise, le titre tremble. */
.combat-arena--defeat .combat-monster-emoji { animation: monster-breathe 3.2s ease-in-out infinite, defeat-loom 1.2s ease-out; }
.combat-arena--defeat { filter: grayscale(0.55) brightness(0.9); }
.combat-defeat-title { display: block; animation: defeat-title-in 0.9s ease-out; }
@keyframes defeat-loom { from { transform: scale(0.8); } to { transform: scale(1); } }
@keyframes defeat-title-in { 0% { transform: translateY(-10px); opacity: 0; } 30% { transform: translateX(-6px); opacity: 1; } 50% { transform: translateX(6px); } 70% { transform: translateX(-3px); } 100% { transform: translateX(0); } }
.combat-skulls { position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 2; }
.combat-skulls span { position: absolute; bottom: -1.5rem; font-size: 1.2rem; opacity: 0; animation: skull-rise 2.6s ease-out forwards; }
@keyframes skull-rise { 0% { transform: translateY(0); opacity: 0; } 20% { opacity: 0.85; } 100% { transform: translateY(-14rem); opacity: 0; } }

/* 6) Évolution d'un compagnon : voile sombre + éclair + anneaux, s'efface tout seul (aucun JS requis). */
.evolve-overlay { position: fixed; inset: 0; z-index: 1000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.6rem; background: rgba(8, 6, 20, 0.86); animation: evolve-overlay 4.2s ease forwards; pointer-events: none; text-align: center; }
.evolve-overlay__emoji { position: relative; font-size: clamp(5rem, 18vw, 8rem); line-height: 1; animation: evolve-emoji 4.2s ease forwards; }
.evolve-overlay__emoji img.custom-emoji { width: 1em; height: 1em; }
.evolve-overlay__emoji::before, .evolve-overlay__emoji::after { content: ''; position: absolute; left: 50%; top: 50%; width: 100%; height: 100%; border: 3px solid rgba(247, 201, 72, 0.9); border-radius: 50%; transform: translate(-50%, -50%) scale(0.4); opacity: 0; animation: evolve-ring 1.6s ease-out 0.5s infinite; }
.evolve-overlay__emoji::after { animation-delay: 1.1s; border-color: rgba(199, 156, 247, 0.9); }
.evolve-overlay__title { font-size: clamp(1.4rem, 5vw, 2.2rem); font-weight: 800; color: #F7C948; text-shadow: 0 0 14px rgba(247, 201, 72, 0.8); animation: evolve-title 4.2s ease forwards; }
.evolve-overlay__sub { color: #D7BDE2; animation: evolve-title 4.2s ease forwards; }
.evolve-overlay::after { content: ''; position: absolute; inset: 0; background: #fff; opacity: 0; animation: evolve-flash 4.2s ease forwards; pointer-events: none; }
@keyframes evolve-overlay { 0% { opacity: 0; visibility: visible; } 8% { opacity: 1; } 88% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; } }
@keyframes evolve-emoji { 0% { transform: scale(0.5); filter: brightness(1); } 25% { transform: scale(1); filter: brightness(1); } 38% { transform: scale(1.15); filter: brightness(6) saturate(0); } 46% { transform: scale(1.3); filter: brightness(9) saturate(0); } 58% { transform: scale(1); filter: brightness(1.4); } 100% { transform: scale(1); filter: brightness(1); } }
@keyframes evolve-flash { 0%, 36% { opacity: 0; } 44% { opacity: 0.95; } 62% { opacity: 0; } 100% { opacity: 0; } }
@keyframes evolve-ring { 0% { transform: translate(-50%, -50%) scale(0.4); opacity: 0.9; } 100% { transform: translate(-50%, -50%) scale(2.1); opacity: 0; } }
@keyframes evolve-title { 0%, 40% { opacity: 0; transform: translateY(10px); } 55% { opacity: 1; transform: none; } 100% { opacity: 1; transform: none; } }

/* 7) Onglet Compétences : jauge par statistique, chiffre qui défile, éclat sur la carte qui vient de monter. */
.skill-meter { display: block; height: 6px; border-radius: 999px; background: var(--line, rgba(255, 255, 255, 0.12)); overflow: hidden; margin: 0.2rem 0 0.15rem; }
.skill-meter > span { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-bright, #a78bfa)); border-radius: 999px; transition: width 0.8s cubic-bezier(0.22, 1, 0.36, 1); }
.skill-card--upgraded { animation: skill-upgraded 1.1s ease-out; position: relative; }
@keyframes skill-upgraded { 0% { box-shadow: 0 0 0 0 rgba(247, 201, 72, 0.9); transform: scale(0.94); } 40% { transform: scale(1.06); } 100% { box-shadow: 0 0 0 22px rgba(247, 201, 72, 0); transform: scale(1); } }
.skill-card--upgraded .equip-card-icon, .skill-card--upgraded .equip-card-name { animation: skill-upgraded-text 1.1s ease-out; }
@keyframes skill-upgraded-text { 0% { color: #F7C948; } 100% { color: inherit; } }

/* 8) Chasse / Broyeur : le compagnon PART le long de la piste au fil du temps et REVIENT chargé (butin). */
.hunt-track { position: relative; padding-top: 1.7rem; }
.hunt-walker { position: absolute; top: 0; font-size: 1.4rem; line-height: 1; transform: translateX(-50%); transition: left 1s linear; animation: hunt-walk 0.8s ease-in-out infinite; }
.hunt-walker img.custom-emoji { width: 1.4rem; height: 1.4rem; }
.hunt-track::before { content: '🏕️'; position: absolute; left: 0; top: 0; font-size: 0.95rem; opacity: 0.7; }
.hunt-track::after { content: '🌲'; position: absolute; right: 0; top: 0; font-size: 0.95rem; opacity: 0.7; }
@keyframes hunt-walk { 0%, 100% { margin-top: 0; } 50% { margin-top: -4px; } }
.hunt-return { animation: hunt-return 0.9s cubic-bezier(0.22, 1.4, 0.36, 1); display: inline-block; }
@keyframes hunt-return { 0% { transform: translateX(60px) scale(0.5); opacity: 0; } 100% { transform: none; opacity: 1; } }
.grinder-gear { display: inline-block; animation: gear-spin 2.4s linear infinite; }
@keyframes gear-spin { to { transform: rotate(360deg); } }

/* 9) Bestiaire : la carte d'un monstre tout juste découvert se RETOURNE (voir aventure-fx.js). */
.badge-item.bestiary-flip { animation: bestiary-flip 1s cubic-bezier(0.22, 1, 0.36, 1); backface-visibility: hidden; }
@keyframes bestiary-flip { 0% { transform: perspective(600px) rotateY(180deg) scale(0.8); opacity: 0.2; } 60% { transform: perspective(600px) rotateY(-12deg) scale(1.08); opacity: 1; box-shadow: 0 0 22px rgba(247, 201, 72, 0.8); } 100% { transform: perspective(600px) rotateY(0deg) scale(1); } }

/* 10) Bouton son (muet par défaut) — voir aventure-fx.js. */
/* Les deux ronds fixes « son » et « effets réduits » sont regroupés dans le menu ⚙️ : voir « .aventure-settings » plus bas. */

/* Garde et boutons de combat fixés en bas sur mobile. */
.combat-player-stage--guard { box-shadow: 0 0 22px 4px rgba(93, 173, 226, 0.65), inset 0 0 16px rgba(93, 173, 226, 0.3); }
.combat-guard-fx { position: absolute; top: -0.6rem; right: -0.6rem; font-size: 2rem; z-index: 2; pointer-events: none; animation: guard-shield-in 0.5s cubic-bezier(0.22, 1.4, 0.36, 1); filter: drop-shadow(0 0 8px rgba(93, 173, 226, 0.9)); }
@keyframes guard-shield-in { from { transform: scale(0.2) rotate(-25deg); opacity: 0; } to { transform: scale(1) rotate(0); opacity: 1; } }
/* Sur petit écran, pendant un combat, la rangée d'actions (Attaquer / Garde / Ultime / Objet / Fuir) reste
   collée en bas de l'écran, à portée du pouce, au lieu de disparaître sous le pli de la page. `position:
   sticky` (et non fixed) : elle reste dans sa section et redevient normale en fin de page. */
@media (max-width: 720px) {
  .combat-arena .combat-actions-row {
    position: sticky; bottom: 0; z-index: 20;
    display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem;
    padding: 0.7rem 0.5rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
    margin: 1rem -0.5rem 0;
    background: linear-gradient(180deg, transparent, var(--surface, #1e1e2e) 28%);
    backdrop-filter: blur(4px);
  }
  .combat-arena .combat-actions-row button { min-height: 44px; }
}

/* onglet Personnage (fiche, statistiques, succès), comparateur d'équipement, avatar dans l'arène. */
.hero-header { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.75rem; }
.hero-avatar { width: 72px; height: 72px; border-radius: 50%; border: 3px solid var(--accent, #7c3aed); object-fit: cover; box-shadow: 0 0 18px rgba(124, 58, 237, 0.45); }
.hero-avatar--none { display: inline-flex; align-items: center; justify-content: center; font-size: 2.4rem; background: var(--surface-2, rgba(255, 255, 255, 0.06)); }
.hero-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 0.6rem; }
.hero-stat { display: flex; flex-direction: column; align-items: center; gap: 0.1rem; padding: 0.6rem 0.4rem; border-radius: var(--radius-md); background: var(--surface-2, rgba(255, 255, 255, 0.05)); text-align: center; }
.hero-stat__icon { font-size: 1.3rem; }
.hero-stat__value { font-size: 1.25rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.hero-stat__label { font-size: 0.72rem; color: var(--text-dim, #a09ab5); }
.equip-diff { display: block; font-size: 0.72rem; font-weight: 700; margin-top: 0.1rem; }
.equip-diff--up { color: #58D68D; }
.equip-diff--down { color: #EC7063; }
.combat-avatar { position: absolute; left: -0.9rem; bottom: -0.3rem; width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--accent, #7c3aed); object-fit: cover; background: var(--surface, #1e1e2e); box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 2; }

/* Simulateur d'équilibrage des monstres (voir shared/combat-simulator.js et monster-simulator.js). */
.balance-box { display: flex; flex-direction: column; gap: 0.25rem; margin: 0.75rem 0; padding: 0.7rem 0.9rem; border-radius: var(--radius-md); background: var(--surface-2, rgba(255, 255, 255, 0.05)); border: 1px solid var(--line, rgba(255, 255, 255, 0.12)); }
.balance-box[hidden] { display: none; }
.balance-row { font-size: 0.88rem; padding-left: 0.5rem; border-left: 3px solid transparent; }
.balance-row--trop-facile { border-left-color: #85929E; }
.balance-row--facile { border-left-color: #58D68D; }
.balance-row--equilibre { border-left-color: #F4D03F; }
.balance-row--difficile { border-left-color: #EB984E; }
.balance-row--trop-dur { border-left-color: #E74C3C; }
.simulate-button { margin-left: 0.5rem; }

/* Jauge de progression d'un succès de combat : même rendu que .skill-meter, classe distincte pour ne
   jamais être confondue avec les jauges de l'onglet Compétences. */
.achievement-meter { display: block; height: 6px; border-radius: 999px; background: var(--line, rgba(255, 255, 255, 0.12)); overflow: hidden; margin: 0.2rem 0 0.15rem; }
.achievement-meter > span { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-bright, #a78bfa)); border-radius: 999px; }

/* donjon à étages et marchand ambulant. */
.combat-dungeon-badge { display: inline-block; font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.55rem; border-radius: 999px; background: rgba(155, 89, 182, 0.28); color: #D7BDE2; letter-spacing: 0.03em; }
.combat-offer { margin: 0.6rem 0; padding: 0.7rem 0.9rem; border-radius: var(--radius-md); border: 1px dashed var(--accent, #7c3aed); background: rgba(124, 58, 237, 0.1); }
.dungeon-panel { margin-top: 1.25rem; padding: 0.9rem 1rem; border-radius: var(--radius-md); border: 1px solid var(--line, rgba(255, 255, 255, 0.14)); background: var(--surface-2, rgba(255, 255, 255, 0.04)); }
/* ───────────── Guide interactif : carte de progression et étapes en accordéon ───────────── */
.page-aventure .guide-hero { margin-bottom: 1rem; border-top: 3px solid var(--accent); }
.page-aventure .guide-hero__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.5rem; }
.page-aventure .guide-hero__rank { font-size: 1.25rem; font-weight: 800; }
.page-aventure .guide-hero__count { font-size: 0.9rem; opacity: 0.85; }
.page-aventure .guide-hero__bar { height: 12px; }
.page-aventure .guide-hero__next { margin: 0.75rem 0 0.5rem; }
.page-aventure .guide-hero__next a { font-weight: 700; color: var(--accent-soft); }
.page-aventure .guide-hero__actions { display: flex; justify-content: flex-end; }
.page-aventure .guide-hero--pop .guide-hero__rank { animation: guide-pop 0.6s ease; }
.page-aventure .guide-hero--complete { border-top-color: #F1C40F; box-shadow: 0 0 18px rgba(241, 196, 15, 0.35); }
.page-aventure .guide-hero--complete .progress-bar__fill { background: linear-gradient(90deg, #F1C40F, #58D68D); }
.page-aventure .guide-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.page-aventure .guide-step { border: 1px solid var(--line); border-radius: var(--radius-md); padding: 0.15rem 0.9rem; background: var(--surface, rgba(255, 255, 255, 0.03)); transition: border-color 0.2s ease, box-shadow 0.2s ease; }
.page-aventure .guide-step--next { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.page-aventure .guide-step--done { border-color: #2ecc71; background: rgba(46, 204, 113, 0.07); }
.page-aventure .guide-step summary { display: flex; align-items: center; gap: 0.6rem; min-height: 44px; cursor: pointer; list-style: none; }
.page-aventure .guide-step summary::-webkit-details-marker { display: none; }
.page-aventure .guide-step summary::after { content: '▾'; margin-left: auto; color: var(--text-dim); transition: transform 0.2s ease; }
.page-aventure .guide-step details:not([open]) summary::after { transform: rotate(-90deg); }
.page-aventure .guide-step summary:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 2px; border-radius: var(--radius-sm); }
.page-aventure .guide-step summary h3 { margin: 0; font-size: 1rem; }
.page-aventure .guide-step__status { font-size: 1.2rem; line-height: 1; }
.page-aventure .guide-step--done .guide-step__status { animation: guide-pop 0.6s ease; }
.page-aventure .guide-step--done summary h3 { text-decoration: line-through; text-decoration-color: rgba(46, 204, 113, 0.6); opacity: 0.85; }
.page-aventure .guide-step details > p, .page-aventure .guide-step details > ul { margin-top: 0; }
.page-aventure .guide-step__cta { display: inline-block; margin: 0.25rem 0.75rem 0.75rem 0; }
.page-aventure .guide-step__tick { display: inline-flex; margin-bottom: 0.75rem; }
@keyframes guide-pop { 0% { transform: scale(0.6); } 60% { transform: scale(1.25); } 100% { transform: scale(1); } }

/* ───────────── Combat : choix du mode et bandeau de mode ─────────────
   Trois façons de combattre (classique, donjon, tour sans fin) présentées en cartes côte à côte, et un bandeau qui rappelle le mode pendant le combat. */
.mode-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.75rem; margin: 0 0 0.75rem; padding: 0.55rem 0.9rem; border-radius: var(--radius-md); border: 1px solid var(--mode-color, var(--line)); background: color-mix(in srgb, var(--mode-color, #7c3aed) 14%, transparent); }
.mode-banner--classic { --mode-color: #5DADE2; }
.mode-banner--dungeon { --mode-color: #E67E22; }
.mode-banner--tower { --mode-color: #AF7AC5; }
.mode-banner__title { font-weight: 800; }
.mode-banner__where { padding: 0.1rem 0.6rem; border-radius: 999px; background: var(--mode-color); color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45); font-size: 0.85rem; }
.mode-banner__dots { margin-left: 0.25rem; }
.mode-banner__next { flex: 1 1 100%; font-size: 0.82rem; opacity: 0.85; }
/* ───────────── Carte de l'Aventure et habillage par catégorie ─────────────
   Navigation en carte (mêmes codes que la carte des biomes : mer sombre, îles colorées, lieux cliquables) et, partout dans la page, la teinte de la catégorie affichée (--theme-color,
   posée par aventure.ejs sur .adv-theme). Couleurs reprises de la palette des biomes. */
.adv-hub { margin: 0 0 1rem; }
.adv-hub__summary { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.4rem 1rem; min-height: 44px; padding: 0.4rem 0.2rem; font-weight: 700; cursor: pointer; list-style: none; }
.adv-hub__summary::-webkit-details-marker { display: none; }
.adv-hub__summary::after { content: '▾'; color: var(--text-dim); transition: transform 0.2s ease; }
.adv-hub:not([open]) .adv-hub__summary::after { transform: rotate(-90deg); }
.adv-hub__summary:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 2px; border-radius: var(--radius-sm); }
.adv-hub__here { flex: 1; text-align: right; font-weight: 600; font-size: 0.88rem; color: var(--text-dim); }
.adv-map { display: block; width: 100%; max-width: min(100%, calc(var(--page-max) * 0.62)); margin: 0.25rem auto 0; background: radial-gradient(ellipse at 50% 40%, rgba(70, 120, 190, 0.26), rgba(40, 70, 130, 0.14)); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.adv-map__bridges { stroke: rgba(255, 255, 255, 0.3); stroke-width: 0.7; stroke-dasharray: 1.6 1.6; stroke-linecap: round; }
.adv-island polygon { fill: color-mix(in srgb, var(--island-color) 62%, #14122a); stroke: rgba(0, 0, 0, 0.5); stroke-width: 0.5; stroke-linejoin: round; transition: filter 0.2s ease; }
.adv-island--current polygon { fill: color-mix(in srgb, var(--island-color) 82%, #14122a); stroke: #fff; stroke-width: 1; }
.adv-island__name { font-size: 2.7px; font-weight: 800; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, 0.7); stroke-width: 0.5px; pointer-events: none; }
.adv-pin { cursor: pointer; text-decoration: none; }
.adv-pin circle { fill: rgba(14, 12, 30, 0.82); stroke: rgba(255, 255, 255, 0.85); stroke-width: 0.5; transition: fill 0.15s ease, stroke-width 0.15s ease; }
.adv-pin:hover circle, .adv-pin:focus-visible circle { fill: rgba(60, 50, 110, 0.95); stroke-width: 0.9; }
.adv-pin:focus-visible { outline: none; }
.adv-pin__emoji { font-size: 3.9px; pointer-events: none; }
.adv-pin__name { font-size: 2.35px; font-weight: 700; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, 0.75); stroke-width: 0.45px; pointer-events: none; }
.adv-pin--current circle { fill: #fff; stroke: #F1C40F; stroke-width: 1; }
@media (prefers-reduced-motion: no-preference) { .adv-pin--current circle { animation: adv-pin-here 1.8s ease-in-out infinite; } }
@keyframes adv-pin-here { 0%, 100% { stroke-width: 1; } 50% { stroke-width: 1.9; } }
.adv-pin__badge circle { fill: #E74C3C; stroke: #fff; stroke-width: 0.3; }
.adv-pin__badge text { font-size: 2.1px; font-weight: 800; fill: #fff; pointer-events: none; }
.adv-pin__badge.is-hidden { display: none; }
/* La carte remplace la rangée de catégories tant qu'elle est ouverte ; repliée (téléphone), la rangée reprend le relais. */
.page-aventure:has(.adv-hub[open]) .groups-nav { display: none; }
.adv-theme { --theme-color: #7C3AED; position: relative; padding-top: 0.15rem; background: radial-gradient(ellipse at 50% -5%, color-mix(in srgb, var(--theme-color) 16%, transparent), transparent 55%); border-radius: var(--radius-md); }
.adv-theme .panel { border-top: 3px solid var(--theme-color); background-image: linear-gradient(180deg, color-mix(in srgb, var(--theme-color) 12%, transparent), transparent 150px); }
.adv-theme .tabs-nav .tabs-nav__item[aria-current="page"] { border-bottom-color: var(--theme-color); }
.adv-theme .tabs-nav .tabs-nav__item[aria-current="page"]::before, .adv-theme .tabs-nav .tabs-nav__item:hover::before { background: var(--theme-color); }
.adv-theme .groups-nav__item[aria-current="true"] { border-color: var(--theme-color); background: color-mix(in srgb, var(--theme-color) 20%, transparent); box-shadow: 0 0 0 1px var(--theme-color); }
.adv-theme .btn-primary { background-image: linear-gradient(135deg, color-mix(in srgb, var(--theme-color) 88%, #fff), color-mix(in srgb, var(--theme-color) 62%, #000)); }
.adv-theme .progress-bar--xp .progress-bar__fill { background: linear-gradient(90deg, var(--theme-color), color-mix(in srgb, var(--theme-color) 55%, #AF7AC5)); }
/* Carte de la tour : on monte de bas en haut, chaque étage est un nœud coloré par la difficulté de son monstre. */
.tower-map-panel { margin-top: 1rem; }
.tower-map { display: block; width: 100%; max-width: 360px; margin: 0.5rem auto 0; background: rgba(20, 18, 40, 0.35); border-radius: var(--radius-md); }
.tower-map__path { stroke: rgba(255, 255, 255, 0.25); stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 2 2.4; }
.tower-node circle { fill: var(--node-color, #5DADE2); stroke: rgba(0, 0, 0, 0.5); stroke-width: 0.6; }
.tower-node--tres_faible { --node-color: #82E0C8; }
.tower-node--faible { --node-color: #58D68D; }
.tower-node--moyen { --node-color: #5DADE2; }
.tower-node--fort { --node-color: #E74C3C; }
.tower-node--tres_fort { --node-color: #AF7AC5; }
.tower-node--done circle { opacity: 0.45; }
.tower-node--palier circle { stroke: #F1C40F; stroke-width: 1.1; }
.tower-node--current circle { stroke: #fff; stroke-width: 1.5; filter: drop-shadow(0 0 3px var(--node-color)); }
.tower-node__num { font-size: 4.4px; font-weight: 800; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, 0.6); stroke-width: 0.5px; pointer-events: none; }
.tower-node__pct { font-size: 3px; font-weight: 700; fill: currentColor; }
.tower-node__tags { font-size: 2.8px; fill: currentColor; opacity: 0.9; }
.tower-node--current .tower-node__pct { font-weight: 800; }
@media (prefers-reduced-motion: no-preference) { .tower-node--current circle { animation: tower-here 1.8s ease-in-out infinite; } }
@keyframes tower-here { 0%, 100% { stroke-width: 1.5; } 50% { stroke-width: 2.4; } }
/* Carte des métiers : la carte des biomes + la liste « qui travaille où ». */
.profession-map__jobs { font-size: 3.4px; pointer-events: none; }
.profession-zones { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.75rem; }
.profession-zone { padding: 0.7rem 0.9rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface, rgba(255, 255, 255, 0.03)); }
.profession-zone:target { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.profession-zone--current { border-color: #fff; }
.profession-zone--locked { opacity: 0.7; }
.profession-zone h3 { margin: 0 0 0.4rem; font-size: 1rem; }
.profession-zone__job { margin-bottom: 0.5rem; }
.profession-zone__materials { list-style: none; margin: 0.25rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; font-size: 0.85rem; }
.profession-zone__material--locked { opacity: 0.55; }
/* Succès de l'Aventure à paliers : une carte par succès, cliquable quand un palier est à récupérer. */
.achievements-category { margin: 1.25rem 0 0.5rem; font-size: 1rem; }
.achievements-claim-all { margin: 0.5rem 0 0.25rem; }
.achievement-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.6rem; }
.achievement-card { margin: 0; }
.achievement-card__button { display: flex; width: 100%; height: 100%; align-items: flex-start; gap: 0.6rem; padding: 0.7rem 0.8rem; text-align: left; color: inherit; font: inherit; background: var(--surface, rgba(255, 255, 255, 0.03)); border: 1px solid var(--line); border-radius: var(--radius-md); cursor: default; transition: transform 0.15s ease, box-shadow 0.15s ease; }
.achievement-card__button:disabled { opacity: 1; }
.achievement-card:not(.achievement-card--unlocked) .achievement-card__button { opacity: 0.7; }
.achievement-card--unlocked .achievement-card__button { border-color: var(--accent-soft); }
.achievement-card--complete .achievement-card__button { border-color: #F1C40F; background: rgba(241, 196, 15, 0.07); }
.achievement-card--claimable .achievement-card__button { cursor: pointer; border-color: #2ecc71; background: rgba(46, 204, 113, 0.1); box-shadow: 0 0 0 1px #2ecc71; }
.achievement-card--claimable .achievement-card__button:hover, .achievement-card--claimable .achievement-card__button:focus-visible { transform: translateY(-2px); box-shadow: 0 0 0 2px #2ecc71, 0 6px 16px rgba(46, 204, 113, 0.25); }
.achievement-card__emoji { font-size: 1.8rem; line-height: 1; flex: 0 0 auto; }
.achievement-card__body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; flex: 1; }
.achievement-card__title { font-weight: 700; }
.achievement-card__tier { font-size: 0.72rem; font-weight: 600; padding: 0.05rem 0.45rem; border-radius: 999px; background: var(--accent); color: #fff; vertical-align: middle; }
.achievement-card__goal { font-size: 0.85rem; overflow-wrap: anywhere; }
:root[data-theme="light"] .achievement-card__claim { color: hsl(145, 63%, 28%); }
.achievement-card__claim { font-weight: 700; color: #58D68D; font-size: 0.88rem; }
@media (prefers-reduced-motion: no-preference) { .achievement-card--claimable .achievement-card__claim { animation: guide-pop 1.6s ease-in-out infinite; } }
.tower-season { margin-top: 1rem; padding: 0.75rem 1rem; border-radius: var(--radius-md); border: 1px solid var(--line); }
.tower-season--claimable { border-color: #F1C40F; background: rgba(241, 196, 15, 0.07); }
.tower-season__list { margin: 0 0 0.5rem; padding-left: 1.2rem; }
.biome-event-banner { margin: 0.4rem 0; padding: 0.4rem 0.7rem; border-radius: var(--radius-md); border: 1px dashed #F1C40F; background: rgba(241, 196, 15, 0.08); font-size: 0.88rem; }
.biome-event { display: inline; }
.daily-order { border-left: 4px solid #F1C40F; }
.daily-order h3 { margin-top: 0; }
.daily-order__form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem; }
.daily-order__qty { max-width: 160px; margin: 0; }
.chain-next { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.5rem 1rem; margin: 0.75rem 0; padding: 0.75rem 1rem; border-radius: var(--radius-md); border: 1px dashed var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.chain-next__button { min-height: 44px; font-size: 1.05rem; }
.chain-next__status { flex: 1 1 100%; margin: 0; text-align: center; }
.chain-next[hidden], .chain-next__status[hidden] { display: none; }
.mode-picker { margin-top: 1.25rem; }
.mode-picker__title { margin: 0 0 0.75rem; }
.mode-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0.9rem; align-items: stretch; }
.mode-card { --mode-color: #5DADE2; display: flex; flex-direction: column; gap: 0.5rem; margin: 0; padding: 0.9rem 1rem; text-align: left; border-radius: var(--radius-md); border: 1px solid var(--mode-color); border-top-width: 4px; background: color-mix(in srgb, var(--mode-color) 9%, transparent); transition: transform 0.2s ease, box-shadow 0.2s ease; }
.mode-card:hover { transform: translateY(-2px); box-shadow: 0 6px 18px color-mix(in srgb, var(--mode-color) 30%, transparent); }
.mode-card--dungeon { --mode-color: #E67E22; }
.mode-card--tower { --mode-color: #AF7AC5; }
.mode-card__head h4 { margin: 0; font-size: 1.1rem; }
.mode-card__pitch { margin: 0; font-size: 0.92rem; }
.mode-card__fact { margin: 0; }
.mode-card__action { margin-top: auto; }
.mode-card__action .btn-primary, .mode-card > form .btn-primary { width: 100%; }
.mode-card__rules { font-size: 0.85rem; }
.mode-card__rules summary { cursor: pointer; font-weight: 600; opacity: 0.85; }
.mode-card .dungeon-panel, .mode-card.dungeon-panel { margin-top: 0; }
:root[data-theme="light"] .mode-card, :root[data-theme="light"] .mode-card.dungeon-panel { border: 1px solid var(--mode-color); border-top-width: 4px; background: color-mix(in srgb, var(--mode-color) 9%, transparent); }
.dungeon-floors { display: flex; gap: 0.35rem; flex-wrap: wrap; }
.dungeon-floor { display: inline-flex; align-items: center; justify-content: center; min-width: 2rem; height: 2rem; padding: 0 0.3rem; border-radius: var(--radius-sm); font-weight: 700; font-size: 0.85rem; background: var(--surface, rgba(255, 255, 255, 0.06)); border: 1px solid var(--line, rgba(255, 255, 255, 0.14)); }
.dungeon-floor--done { background: rgba(46, 204, 113, 0.22); border-color: #2ecc71; color: #7EE2A8; }
.dungeon-floor--current { border-color: var(--accent-bright, #a78bfa); box-shadow: 0 0 10px rgba(167, 139, 250, 0.7); }
.combat-dungeon-result strong { font-weight: 800; }

/* boss de serveur hebdomadaire (onglet Boss). */
.boss-panel--active { border-color: rgba(231, 76, 60, 0.5); }
.boss-stage { text-align: center; }
.boss-emoji { display: inline-block; font-size: clamp(4rem, 14vw, 6.5rem); line-height: 1; filter: drop-shadow(0 0 16px rgba(231, 76, 60, 0.7)); animation: monster-breathe 3.2s ease-in-out infinite; }
.boss-panel--defeated .boss-emoji { filter: grayscale(1) opacity(0.5); animation: none; }
.boss-panel--expired .boss-emoji { filter: grayscale(1) opacity(0.35); animation: none; }
.boss-hp-bar { height: 22px; }
.boss-leaderboard { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.boss-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.4rem 0.6rem; border-radius: var(--radius-sm); background: var(--surface-2, rgba(255, 255, 255, 0.05)); }
.boss-row--me { outline: 2px solid var(--accent, #7c3aed); }
.boss-rank { min-width: 1.6rem; text-align: center; font-weight: 800; }
.boss-avatar { border-radius: 50%; object-fit: cover; }
.boss-name { flex: 1; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.boss-damage { font-variant-numeric: tabular-nums; font-weight: 700; }
.boss-reward { color: #F4D03F; font-weight: 700; font-variant-numeric: tabular-nums; }


/* ───────────── Duels entre membres — tout scopé .page-aventure ───────────── */
.page-aventure .duel-arena { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0.75rem; align-items: center; margin: 0.75rem 0; padding: 0.75rem; border-radius: var(--radius-md); background: radial-gradient(ellipse at 50% 100%, rgba(241, 196, 15, 0.12), rgba(241, 196, 15, 0) 65%), rgba(255, 255, 255, 0.02); }
.page-aventure .duel-fighter { padding: 0.6rem 0.75rem; border-radius: var(--radius-md); background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.08); }
.page-aventure .duel-fighter--me { border-color: rgba(52, 152, 219, 0.5); }
.page-aventure .duel-fighter--foe { border-color: rgba(231, 76, 60, 0.5); }
.page-aventure .duel-name { font-weight: 600; margin-bottom: 0.35rem; overflow-wrap: anywhere; }
/* Duels (« pas assez visuel comme pour les combats de monstres ») : l'arène des duels reprend les classes du combat contre un monstre
   (.combat-player-stage, .combat-weapon, .dmg-float…) ; ci-dessous seulement ce qui est propre au face-à-face. Animations neutralisées
   par la règle globale @media (prefers-reduced-motion: reduce). */
.page-aventure .duel-fighter { text-align: center; }
.page-aventure .duel-stage { margin-bottom: 0.4rem; }
.page-aventure .duel-stage--foe { background: radial-gradient(circle, rgba(231, 76, 60, 0.2), rgba(231, 76, 60, 0) 70%); }
.page-aventure .duel-stage--foe .combat-weapon { right: auto; left: -0.4rem; transform: scaleX(-1) rotate(-30deg); }
.page-aventure .duel-stage--foe .combat-weapon--swing { animation: duel-weapon-swing-foe 0.42s ease; }
.page-aventure .duel-stage--foe .combat-avatar { left: auto; right: -0.9rem; }
.page-aventure .duel-stage--foe .combat-guard-fx { right: auto; left: -0.6rem; }
@keyframes duel-weapon-swing-foe {
  0% { transform: scaleX(-1) rotate(-30deg) translate(0, 0); }
  45% { transform: scaleX(-1) rotate(35deg) translate(18px, -6px); }
  100% { transform: scaleX(-1) rotate(-30deg) translate(0, 0); }
}
/* Le duelliste qui vient de frapper « fonce » vers l'autre (celui de gauche vers la droite, et inversement). */
.page-aventure .duel-stage--lunge { animation: duel-lunge-right 0.5s ease; }
.page-aventure .duel-stage--foe.duel-stage--lunge { animation: duel-lunge-left 0.5s ease; }
@keyframes duel-lunge-right { 0%, 100% { transform: translateX(0) scale(1); } 50% { transform: translateX(22px) scale(1.06); } }
@keyframes duel-lunge-left { 0%, 100% { transform: translateX(0) scale(1); } 50% { transform: translateX(-22px) scale(1.06); } }
/* Duel terminé : le perdant s'affaisse (comme un monstre vaincu). */
.page-aventure .duel-stage--defeated { animation: combat-monster-collapse 0.7s ease forwards; }
.page-aventure .duel-arena--ended .duel-fighter { border-width: 2px; }
.page-aventure .duel-ended { margin-bottom: 0.5rem; }
.page-aventure .duel-energy { height: 6px; }
.page-aventure .duel-energy-fill { background: linear-gradient(90deg, #5DADE2, #AF7AC5); }
.page-aventure .duel-energy--ready { animation: duel-energy-ready 1.4s ease-in-out infinite; }
@keyframes duel-energy-ready { 0%, 100% { box-shadow: 0 0 0 rgba(175, 122, 197, 0); } 50% { box-shadow: 0 0 10px rgba(175, 122, 197, 0.9); } }
.page-aventure .duel-gear { font-size: 0.75rem; opacity: 0.85; margin-top: 0.3rem; }
.page-aventure .duel-vs { font-size: 1.6rem; }
.page-aventure .duel-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.5rem 0; }
.page-aventure .duel-buttons form { margin: 0; }
.page-aventure .duel-log { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.25rem; font-size: 0.9rem; }
.page-aventure .duel-log li { padding: 0.25rem 0.5rem; border-radius: var(--radius-sm); background: rgba(255, 255, 255, 0.03); }
.page-aventure .duel-form { display: grid; gap: 0.6rem; max-width: 32rem; }
@media (max-width: 640px) {
  .page-aventure .duel-arena { grid-template-columns: 1fr; }
  .page-aventure .duel-vs { text-align: center; }
  .page-aventure .duel-buttons .btn-primary, .page-aventure .duel-buttons .btn-secondary { flex: 1 1 100%; }
}

/* ───────────── Aventure : mobile, bandeau du personnage, progression, raretés, effets réduits ─────────────
   Tout scopé .page-aventure (ou des classes propres). Les animations restent neutralisées par @media (prefers-reduced-motion) en haut du fichier ET
   par la classe .reduce-fx (réglage « Réduire les effets » du bouton flottant, mémorisé sur l'appareil — voir web/public/aventure-fx.js). */

/* 1) Barre d'onglets DÉFILANTE sur téléphone (10 onglets : repliés sur 3-4 lignes avant). L'onglet actif est ramené au centre par
      aventure-fx.js:setupTabScroll (déjà présent). Le filet lumineux (::after) n'a pas de sens dans une barre qui défile : masqué. */
@media (max-width: 780px) {
  .page-aventure .tabs-nav {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; gap: 0.25rem;
    scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; scrollbar-width: none; overscroll-behavior-x: contain;
  }
  .page-aventure .tabs-nav::-webkit-scrollbar { display: none; }
  .page-aventure .tabs-nav::after { display: none; }
  .page-aventure .tabs-nav .tabs-nav__item {
    flex: 0 0 auto; white-space: nowrap; scroll-snap-align: center;
    display: inline-flex; align-items: center; gap: 0.3rem; min-height: 44px; padding: 0.55rem 0.85rem;
  }
}

/* 2) Bandeau du personnage : niveau, XP, PV, pièces — au-dessus des onglets, donc visible quel que soit l'onglet. */
.hero-bar { display: grid; grid-template-columns: auto 1.4fr 1.4fr auto; gap: 0.75rem 1rem; align-items: center; margin: 0 0 1rem; padding: 0.7rem 0.9rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface, rgba(255, 255, 255, 0.03)); }
.hero-bar__item { min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.hero-bar__label { font-size: 0.72rem; color: var(--text-dim); display: flex; justify-content: space-between; gap: 0.4rem; white-space: nowrap; }
.hero-bar__num { font-variant-numeric: tabular-nums; }
.hero-bar__level strong, .hero-bar__coins strong { font-size: 1.25rem; line-height: 1.1; }
@media (max-width: 640px) {
  .hero-bar { grid-template-columns: 1fr 1fr; padding: 0.6rem 0.7rem; gap: 0.55rem 0.8rem; }
  .hero-bar__xp, .hero-bar__hp { grid-column: span 2; }
  .hero-bar__level { order: 1; } .hero-bar__coins { order: 2; align-items: flex-end; }
  .hero-bar__xp { order: 3; } .hero-bar__hp { order: 4; }
}

/* 3) Barres de progression génériques (XP, PV du bandeau, amélioration d'équipement). */
.progress-bar { position: relative; height: 8px; border-radius: 999px; background: var(--surface-2, rgba(255, 255, 255, 0.08)); overflow: hidden; }
.progress-bar__fill { height: 100%; border-radius: inherit; background: var(--accent, #7c3aed); transition: width 0.6s ease; }
.progress-bar--xp .progress-bar__fill { background: linear-gradient(90deg, #5DADE2, #AF7AC5); }
.progress-bar--hp .progress-bar__fill { background: linear-gradient(90deg, #E74C3C, #58D68D); }
.progress-bar--upgrade { height: 6px; margin: 0.15rem 0 0.1rem; }
.progress-bar--upgrade .progress-bar__fill { background: linear-gradient(90deg, #F5B041, #F1C40F); }
.progress-bar--ready .progress-bar__fill { background: linear-gradient(90deg, #58D68D, #F1C40F); animation: progress-ready 1.6s ease-in-out infinite; }
@keyframes progress-ready { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.35); } }

/* 4) Raretés VISUELLES des armes/armures (selon le palier d'amélioration payé) : bordure, halo léger et pastilles. Aucun effet sur les statistiques. */
.page-aventure .equip-card--uncommon { border-color: #58D68D; }
.page-aventure .equip-card--rare { border-color: #5DADE2; box-shadow: 0 0 10px rgba(93, 173, 226, 0.25); }
.page-aventure .equip-card--epic { border-color: #AF7AC5; box-shadow: 0 0 12px rgba(175, 122, 197, 0.35); }
.page-aventure .equip-card--legendary { border-color: #F1C40F; box-shadow: 0 0 14px rgba(241, 196, 15, 0.45); }
.tier-pips { display: inline-flex; gap: 0.2rem; justify-content: center; flex-wrap: wrap; }
.tier-pip { width: 8px; height: 8px; border-radius: 50%; border: 1px solid var(--text-dim); background: transparent; }
.tier-pip--on { background: #F1C40F; border-color: #F1C40F; }

/* 5) Arène de duel COMPACTE sur téléphone : deux colonnes (toi | adversaire) avec un « VS » posé entre elles, au lieu de deux blocs empilés
      qui rendaient l'écran très haut. Les visuels sont réduits, les détails d'équipement passent en petits caractères. */
@media (max-width: 640px) {
  .page-aventure .duel-arena { position: relative; grid-template-columns: 1fr 1fr; gap: 0.5rem; padding: 0.5rem; }
  .page-aventure .duel-vs { position: absolute; left: 50%; top: 2.4rem; transform: translateX(-50%); z-index: 3; margin: 0; padding: 0.1rem 0.35rem; font-size: 1rem; border-radius: 999px; background: var(--surface, #1e1e2e); }
  .page-aventure .duel-stage .combat-player-armor { font-size: 2.4rem; }
  .page-aventure .duel-stage .combat-weapon { font-size: 1.3rem; }
  .page-aventure .duel-stage .combat-avatar { width: 28px; height: 28px; }
  .page-aventure .duel-name { font-size: 0.9rem; }
  .page-aventure .duel-gear { font-size: 0.66rem; line-height: 1.25; overflow-wrap: anywhere; }
  .page-aventure .duel-fighter .stat-sub { font-size: 0.72rem; }
  .page-aventure .duel-fighter .combat-status-tag { font-size: 0.62rem; padding: 0.05rem 0.35rem; }
}

/* 6) « Réduire les effets » (réglage de l'appareil) : coupe les animations et transitions de la page Aventure. Les vibrations sont coupées côté JS. */
.reduce-fx .page-aventure *, .reduce-fx .page-aventure *::before, .reduce-fx .page-aventure *::after,
.reduce-fx .combat-arena *, .reduce-fx .evolve-overlay, .reduce-fx .evolve-overlay * { animation: none !important; transition: none !important; }
/* Les deux ronds fixes « son » et « effets réduits » sont regroupés dans le menu ⚙️ : voir « .aventure-settings » plus bas. */

/* 7) Deux sets d'équipement : cartes des deux sets dans l'onglet Équipement, bouton de changement dans le panneau de combat. */
.page-aventure .equipment-sets__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.75rem; }
.page-aventure .equipment-set { padding: 0.75rem; border: 1px solid var(--line); border-radius: var(--radius-md); display: flex; flex-direction: column; gap: 0.3rem; }
.page-aventure .equipment-set h3 { margin: 0 0 0.2rem; font-size: 1rem; }
.page-aventure .equipment-set--active { border-color: var(--accent); box-shadow: 0 0 10px rgba(124, 58, 237, 0.3); }
.page-aventure .equipment-set__line { margin: 0; overflow-wrap: anywhere; }
.page-aventure .combat-set-form { display: inline; margin: 0; }
.page-aventure .combat-set-form button { min-height: 2.6rem; }

/* ───────────── Aventure : bouton ⚙️ unique et son menu ─────────────
   Remplace les deux ronds fixes (effets réduits, son) qui recouvraient contenu et boutons du combat. Ajouté à <body> par aventure-fx.js : donc PAS scopé
   .page-aventure. Les deux boutons gardent leurs classes (.aventure-fx-toggle, .aventure-sound-toggle) : ce sont maintenant des lignes du menu. */
.aventure-settings { position: fixed; right: 0.75rem; bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); z-index: 60; display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem; }
.aventure-settings__fab { order: 2; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--accent, #7c3aed); background: var(--surface, #1e1e2e); color: inherit; font-size: 1.25rem; line-height: 1; cursor: pointer; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4); }
.aventure-settings__fab:hover, .aventure-settings__fab:focus-visible, .aventure-settings.is-open .aventure-settings__fab { border-color: var(--accent-bright, #a78bfa); outline: none; }
.aventure-settings__menu { order: 1; display: none; flex-direction: column; gap: 0.4rem; min-width: 12.5rem; padding: 0.5rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface, #1e1e2e); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); }
.aventure-settings.is-open .aventure-settings__menu { display: flex; }
.aventure-settings__menu .aventure-fx-toggle, .aventure-settings__menu .aventure-sound-toggle { display: flex; align-items: center; gap: 0.6rem; width: 100%; min-height: 44px; padding: 0.5rem 0.75rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: transparent; color: var(--text); font: inherit; font-size: 0.9rem; text-align: left; cursor: pointer; }
.aventure-settings__menu .aventure-fx-toggle:hover, .aventure-settings__menu .aventure-sound-toggle:hover, .aventure-settings__menu .aventure-fx-toggle:focus-visible, .aventure-settings__menu .aventure-sound-toggle:focus-visible { border-color: var(--accent-bright, #a78bfa); outline: none; }
.aventure-settings__menu .aventure-fx-toggle[aria-pressed="true"], .aventure-settings__menu .aventure-sound-toggle[aria-pressed="true"] { border-color: var(--accent, #7c3aed); box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.35); }

/* ───────────── Aventure : mobile, deuxième passe ─────────────
   Écrit d'après la LECTURE du code, sans aucune capture (le bac à sable n'avait pas de navigateur exploitable) : à valider sur téléphone.
   Tout est scopé .page-aventure. Rien ne change au-dessus de 780 px. */

/* 1) Rangée d'actions du combat (≤ 720 px, elle est collée en bas de l'écran) : en GRILLE de deux colonnes au lieu d'un
      flex qui passait à la ligne n'importe comment. « Attaquer » et la potion prennent toute la largeur ; Garde/Ultime, puis Set/Fuir se répartissent
      par deux. Les libellés longs (« Ultime (x2 dégâts) », nom d'une potion) peuvent passer à la ligne au lieu de déborder.
      La règle « min-height: 44px » précédente était ÉCRASÉE par « .page-aventure .combat-actions-row .btn-mod { min-height: 2.6rem } »
      (plus spécifique, 41,6 px) : le sélecteur ci-dessous, avec un élément de plus, reprend le dessus.
      Le padding droit réserve la colonne des deux boutons ronds fixes (effets réduits + son, z-index 60 > 20) qui recouvraient sinon « Fuir »/« Ultime ». */
@media (max-width: 720px) {
  /* Défaut corrigé : « .combat-arena { overflow: hidden } » fait de l'arène le conteneur de défilement de la rangée collée ; or elle ne défile
     pas, donc « position: sticky » n'a JAMAIS collé la rangée en bas de l'écran (vu dans Chromium avec ce CSS). « overflow: clip » découpe pareil mais ne crée
     pas de conteneur de défilement. (Safari < 16 ignore « clip » et garde « hidden » : la rangée reste alors en bas de l'arène, comme avant.) */
  .page-aventure .combat-arena { overflow: clip; }
  .page-aventure .combat-arena .combat-actions-row {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; justify-content: stretch; align-items: stretch;
    padding-right: calc(3.9rem + env(safe-area-inset-right, 0px));
  }
  .page-aventure .combat-arena .combat-actions-row > form { margin: 0; min-width: 0; display: flex !important; }  /* flex : le bouton s'étire à la hauteur de sa ligne de grille (Garde = Ultime sur deux lignes). !important : plusieurs formulaires portent style="display:inline" dans le gabarit. */
  .page-aventure .combat-arena .combat-actions-row > form:first-of-type { grid-column: 1 / -1; }  /* :first-of-type — le 1er ENFANT est le bloc des mini-barres */
  .page-aventure .combat-arena .combat-actions-row > .combat-potion-form { grid-column: 1 / -1; display: flex; flex-wrap: nowrap; align-items: stretch; gap: 0.5rem; }
  .page-aventure .combat-arena .combat-actions-row .combat-potion-pick { flex: 2 1 0; min-width: 0; }
  .page-aventure .combat-arena .combat-actions-row .combat-potion-pick select { width: 100%; }
  .page-aventure .combat-arena .combat-actions-row button { width: 100%; min-height: 44px; white-space: normal; line-height: 1.2; text-align: center; }
  .page-aventure .combat-arena .combat-actions-row .combat-potion-form button { width: auto; flex: 1 1 0; }
}

/* 2) Téléphone (≤ 640 px) : boutons à 44 px partout dans /aventure ; champs à 16 px (en dessous, Safari iOS zoome la page au toucher d'un champ :
      liste des potions, mise d'un duel, quantité) ; petits textes relevés à une taille lisible. Les boutons « button » centrent déjà leur texte. */
@media (max-width: 640px) {
  .page-aventure button.btn-mod, .page-aventure button.btn-mod-danger, .page-aventure button.btn-primary, .page-aventure button.btn-secondary { min-height: 44px; }
  .page-aventure select, .page-aventure textarea,
  .page-aventure input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="range"]) { font-size: 16px; }
  .page-aventure select { min-height: 44px; }
  .page-aventure .hero-bar__label, .page-aventure .hero-stat__label, .page-aventure .equip-diff { font-size: 0.78rem; }
  .page-aventure .duel-gear { font-size: 0.72rem; }
  .page-aventure .duel-fighter .stat-sub { font-size: 0.76rem; }
  .page-aventure .duel-fighter .combat-status-tag { font-size: 0.7rem; }
}

/* 3) Petit écran (≤ 480 px) : la page perdait ~23 % de la largeur en marges (page 1.5rem + panneau 1.1rem de chaque côté). Resserré pour /aventure seulement. */
@media (max-width: 480px) {
  .page-aventure.page-content { padding-left: 0.75rem; padding-right: 0.75rem; padding-top: 2.5rem; }
  .page-aventure .panel { padding: 1rem 0.85rem; }
}

/* 4) Barre d'onglets défilante (≤ 780 px) : dégradé sur le bord droit = indice visuel qu'il reste des onglets hors écran ; le padding de fin
      garde le dernier onglet hors de la zone estompée. */
@media (max-width: 780px) {
  .page-aventure .tabs-nav {
    padding-right: 1.75rem; scroll-padding-inline: 1rem;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 1.75rem), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 1.75rem), transparent);
  }
}

/* ───────────── Aventure : mobile, troisième passe ─────────────
   Sections repliables (Équipement, Compétences, Guide/Bestiaire) et barre d'onglets collée en haut qui se cache en descendant. Tout scopé .page-aventure. */

/* 5) Sections repliables (aventure-fold.js). Le contenu n'est masqué que si le script a posé fold-ready (sans JavaScript : tout reste visible). */
.page-aventure .fold-toggle { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; width: 100%; min-height: 44px; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.page-aventure .fold-toggle::after { content: '▾'; flex: 0 0 auto; color: var(--text-dim); transition: transform 0.2s ease; }
.page-aventure .fold-collapsed .fold-toggle::after { transform: rotate(-90deg); }
.page-aventure .fold-toggle:focus-visible { outline: 2px solid var(--accent, #7c3aed); outline-offset: 4px; border-radius: var(--radius-sm); }
.page-aventure .fold-ready.fold-collapsed { padding-top: 0.4rem; padding-bottom: 0.4rem; margin-bottom: 0.75rem; }  /* liste de sections fermées : compacte */
.page-aventure .fold-ready.fold-collapsed > h2 { margin-bottom: 0; }
.page-aventure .fold-ready.fold-collapsed > :not(h2) { display: none; }

/* 6) Barre d'onglets COLLÉE sous l'en-tête du site (≤ 780 px). La hauteur de l'en-tête est mesurée par aventure-tabbar.js (--aventure-nav-h ; 3.75rem tant que
      le script n'a pas tourné). Elle occupe toute la largeur (marges de page annulées) et se cache sous l'en-tête quand on descend (.tabs-nav--away),
      revient quand on remonte, change d'onglet ou navigue au clavier. Le z-index reste SOUS celui de l'en-tête (10). */
@media (max-width: 780px) {
  .page-aventure .tabs-nav {
    position: sticky; top: var(--aventure-nav-h, 3.75rem); z-index: 8;
    margin-left: -1.5rem; margin-right: -1.5rem; padding-left: 1.5rem;
    background: rgba(8, 7, 12, 0.94); backdrop-filter: blur(8px);
    transition: transform 0.25s ease, opacity 0.25s ease;
  }
  .page-aventure .tabs-nav.tabs-nav--away { transform: translateY(-100%); opacity: 0; pointer-events: none; }
  .page-aventure .tabs-nav.tabs-nav--away:focus-within { transform: none; opacity: 1; pointer-events: auto; }
  /* Un lien vers un panneau (tabs-deep-link.js) doit s'arrêter SOUS l'en-tête ET la barre collés. */
  .page-aventure .tab-panel { scroll-margin-top: calc(var(--aventure-nav-h, 3.75rem) + 3.5rem); }
}
@media (max-width: 480px) {
  .page-aventure .tabs-nav { margin-left: -0.75rem; margin-right: -0.75rem; padding-left: 0.75rem; }
}

/* ───────────── Aventure : visuel, quatrième passe ─────────────
   Mini-barres du combat, cartes de récompense, comparaison d'équipement en barres, outils du bestiaire. Tout scopé .page-aventure. */

/* 7) Mini-barres PV (toi, monstre) et XP au-dessus des boutons de la rangée collée en bas — téléphone seulement (≤ 720 px). Sur ordinateur, l'arène montre déjà tout. */
.page-aventure .combat-mini-bars { display: none; }
@media (max-width: 720px) {
  .page-aventure .combat-arena .combat-mini-bars { display: grid; grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.3rem 0.6rem; margin: 0; }
  .page-aventure .combat-arena .combat-mini-bars--xp { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .page-aventure .combat-mini-bar { min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
  .page-aventure .combat-mini-bar__label { font-size: 0.75rem; line-height: 1.15; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text); font-variant-numeric: tabular-nums; }
  .page-aventure .combat-mini-bars .hp-bar, .page-aventure .combat-mini-bars .progress-bar { height: 7px; margin: 0; }
}

/* 8) Cartes de récompense de l'écran de victoire : pièces, XP, butin (bordure dorée = butin « rare », même définition que « ✨ rare ! »). Décoratives ; le texte de la
      bannière (.combat-reward-text, .sr-only) reste la version lue par les lecteurs d'écran. Animations coupées par « Réduire les effets » et prefers-reduced-motion. */
.page-aventure .combat-reward-cards { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; margin: 0.75rem 0 0.25rem; }
.page-aventure .reward-card { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; min-width: 5.5rem; max-width: 9.5rem; padding: 0.6rem 0.8rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface-2, rgba(255, 255, 255, 0.05)); animation: reward-card-in 0.5s cubic-bezier(0.22, 1.4, 0.36, 1) backwards; }
.page-aventure .reward-card:nth-child(2) { animation-delay: 0.1s; }
.page-aventure .reward-card:nth-child(3) { animation-delay: 0.2s; }
.page-aventure .reward-card:nth-child(4) { animation-delay: 0.3s; }
.page-aventure .reward-card:nth-child(n+5) { animation-delay: 0.4s; }
.page-aventure .reward-card__icon { font-size: 1.7rem; line-height: 1; }
.page-aventure .reward-card__value { font-weight: 800; font-size: 1.15rem; line-height: 1.15; font-variant-numeric: tabular-nums; }
.page-aventure .reward-card__name { font-size: 0.9rem; text-align: center; overflow-wrap: anywhere; }
.page-aventure .reward-card__label { font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-dim); }
.page-aventure .reward-card--coins { border-color: rgba(241, 196, 15, 0.55); }
.page-aventure .reward-card--xp { border-color: rgba(93, 173, 226, 0.55); }
.page-aventure .reward-card--secured { border-color: rgba(88, 214, 141, 0.5); }
.page-aventure .reward-card--rare { border-color: #F1C40F; box-shadow: 0 0 14px rgba(241, 196, 15, 0.45); animation: reward-card-in 0.5s cubic-bezier(0.22, 1.4, 0.36, 1) backwards, reward-rare-glow 1.8s ease-in-out 0.5s 2; }
.page-aventure .reward-card--rare .reward-card__label { color: #F1C40F; }
@keyframes reward-card-in { from { opacity: 0; transform: translateY(12px) scale(0.85); } to { opacity: 1; transform: none; } }
@keyframes reward-rare-glow { 0%, 100% { box-shadow: 0 0 10px rgba(241, 196, 15, 0.3); } 50% { box-shadow: 0 0 22px rgba(241, 196, 15, 0.75); } }

/* 9) Comparaison d'équipement en BARRES avant/après (sous chaque objet non équipé) : barre grise = ce que tu portes, barre colorée = cet objet (verte = mieux, rouge = moins bien).
      Échelle : la plus grande des deux valeurs remplit sa piste. */
.page-aventure .equip-cmp { display: flex; flex-direction: column; gap: 0.35rem; width: 100%; margin-top: 0.45rem; text-align: left; }
.page-aventure .equip-cmp__row { display: flex; flex-direction: column; gap: 0.15rem; }  /* libellé AU-DESSUS des barres : deux cartes par ligne sur téléphone = ~150 px utiles, une colonne de libellé ne laissait que 1 px aux barres (vu dans Chromium) */
.page-aventure .equip-cmp__label { font-size: 0.72rem; line-height: 1.1; color: var(--text-dim); overflow-wrap: anywhere; }
.page-aventure .equip-cmp__bars { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.page-aventure .equip-cmp__line { display: flex; align-items: center; gap: 0.35rem; min-width: 0; }
.page-aventure .equip-cmp__track { flex: 1 1 auto; min-width: 0; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
.page-aventure .equip-cmp__bar { display: block; height: 100%; border-radius: 3px; min-width: 2px; transition: width 0.4s ease; }
.page-aventure .equip-cmp__bar--now { background: #8E8AA3; }
.page-aventure .equip-cmp__bar--up { background: #58D68D; }
.page-aventure .equip-cmp__bar--down { background: #EC7063; }
.page-aventure .equip-cmp__val { flex: 0 0 auto; min-width: 2.9rem; font-size: 0.72rem; font-variant-numeric: tabular-nums; text-align: right; color: var(--text-dim); }
.page-aventure .equip-cmp__val em { font-style: normal; font-weight: 700; }

/* 10) Bestiaire : progression, filtres (Tous / Découverts / À découvrir) et tri (aventure-bestiary.js). */
.page-aventure .bestiary-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; margin: 0 0 1rem; }
.page-aventure .bestiary-tools__progress { flex: 1 1 12rem; min-width: 10rem; display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.8rem; color: var(--text-dim); }
.page-aventure .bestiary-tools__chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.page-aventure .bestiary-chip { min-height: 44px; padding: 0.3rem 0.85rem; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--text); font: inherit; font-size: 0.85rem; cursor: pointer; }
.page-aventure .bestiary-chip[aria-pressed="true"] { border-color: var(--accent, #7c3aed); background: rgba(124, 58, 237, 0.18); }
.page-aventure .bestiary-chip:focus-visible, .page-aventure .bestiary-tools__sort select:focus-visible { outline: 2px solid var(--accent, #7c3aed); outline-offset: 2px; }
.page-aventure .bestiary-tools__sort { display: flex; align-items: center; gap: 0.4rem; font-size: 0.85rem; color: var(--text-dim); }
.page-aventure .bestiary-tools__sort select { min-height: 44px; padding: 0.3rem 0.6rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); font: inherit; font-size: 0.9rem; }
.page-aventure .bestiary-tools__empty { width: 100%; margin: 0; }
.page-aventure .bestiary-hidden { display: none !important; }

/* ───────────── Carte des biomes (section /aventure/carte) ───────────── */
.page-aventure .biome-map { width: 100%; max-width: min(100%, calc(var(--page-max) * 0.58)); display: block; margin: 0.75rem auto 0; background: rgba(70, 120, 190, 0.18); border-radius: var(--radius-md); }
.page-aventure .biome-zone { cursor: pointer; text-decoration: none; }
.page-aventure .biome-zone polygon { stroke: rgba(0, 0, 0, 0.45); stroke-width: 0.5; stroke-linejoin: round; transition: filter 0.15s ease; }
.page-aventure .biome-zone:hover polygon, .page-aventure .biome-zone:focus-visible polygon { filter: brightness(1.15); }
.page-aventure .biome-zone:focus-visible { outline: none; }
.page-aventure .biome-zone:focus-visible polygon { stroke: var(--accent-soft); stroke-width: 1.2; }
.page-aventure .biome-zone--current polygon { stroke: #fff; stroke-width: 1.4; }
.page-aventure .biome-zone--locked polygon { filter: grayscale(0.7) brightness(0.65); }
.page-aventure .biome-zone__emoji { font-size: 5.5px; pointer-events: none; }
.page-aventure .biome-zone__name { font-size: 3px; font-weight: 700; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, 0.7); stroke-width: 0.5px; pointer-events: none; }
.page-aventure .biome-zone__lock { font-size: 2.5px; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, 0.7); stroke-width: 0.45px; pointer-events: none; }
.page-aventure .biome-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; }
.page-aventure .biome-card h3 { margin: 0 0 0.25rem; display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.page-aventure .biome-card--current { border-color: var(--accent); }
.page-aventure .biome-card--locked { opacity: 0.7; }
.page-aventure .biome-badge { font-size: 0.75rem; font-weight: 600; padding: 0.1rem 0.5rem; border-radius: 999px; background: var(--accent); color: #fff; }
.page-aventure .biome-badge--locked { background: transparent; border: 1px solid var(--border); color: var(--text-dim, inherit); }
@media (prefers-reduced-motion: no-preference) { .page-aventure .biome-zone polygon { transition: filter 0.15s ease; } }

/* ───────────── Métiers de récolte (section /aventure/metiers) ───────────── */
.page-aventure .metier-energy { margin: 0.5rem 0 0.35rem; }
.page-aventure .metier-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.page-aventure .metier-hud--empty .progress-bar__fill { background: #E74C3C; }
.page-aventure .progress-bar--energy .progress-bar__fill { background: linear-gradient(90deg, #F5B041, #F7DC6F); }
.page-aventure .metier-live-banner { margin: 0 0 1rem; }
/* Carte d'un métier : bandeau à la couleur de son biome (--metier-color), niveau en pastille, matériaux en grille d'icônes. */
.page-aventure .metier-card { position: relative; overflow: hidden; border-top: 3px solid var(--metier-color, var(--accent)); transition: transform 0.2s ease, box-shadow 0.2s ease; }
.page-aventure .metier-card:not(.metier-card--away):hover { transform: translateY(-2px); box-shadow: 0 6px 18px color-mix(in srgb, var(--metier-color, var(--accent)) 35%, transparent); }
.page-aventure .metier-card__banner { display: flex; align-items: center; gap: 0.7rem; margin: -1rem -1rem 0.6rem; padding: 0.7rem 1rem; background: linear-gradient(135deg, color-mix(in srgb, var(--metier-color, var(--accent)) 38%, transparent), transparent); }
.page-aventure .metier-card__icon { font-size: 2rem; line-height: 1; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35)); }
.page-aventure .metier-card__title { flex: 1; min-width: 0; }
.page-aventure .metier-card__title h3 { margin: 0; }
.page-aventure .metier-card__biome { font-size: 0.78rem; opacity: 0.75; }
.page-aventure .metier-level { font-size: 0.8rem; font-weight: 700; padding: 0.2rem 0.65rem; border-radius: 999px; background: var(--metier-color, var(--accent)); color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45); white-space: nowrap; }
.page-aventure .metier-card .progress-bar--xp .progress-bar__fill { background: linear-gradient(90deg, var(--metier-color, #5DADE2), #AF7AC5); }
.page-aventure .metier-xp-text { margin: 0.25rem 0 0.5rem; }
.page-aventure .metier-card--away { opacity: 0.65; filter: grayscale(0.5); }
.page-aventure .metier-card--just-gathered { border-color: var(--metier-color, var(--accent)); box-shadow: 0 0 0 1px var(--metier-color, var(--accent)); }
.page-aventure .metier-materials { list-style: none; margin: 0 0 0.75rem; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); gap: 0.5rem; font-size: 0.8rem; }
.page-aventure .metier-material { --rank-color: #9AA0A6; display: flex; flex-direction: column; align-items: center; gap: 0.1rem; padding: 0.45rem 0.25rem; text-align: center; border: 1px solid var(--rank-color); border-radius: var(--radius-md); background: color-mix(in srgb, var(--rank-color) 12%, transparent); }
.page-aventure .metier-material--rank1 { --rank-color: #58D68D; }
.page-aventure .metier-material--rank2 { --rank-color: #5DADE2; }
.page-aventure .metier-material--rank3 { --rank-color: #AF7AC5; }
.page-aventure .metier-material--rank4 { --rank-color: #F5B041; }
.page-aventure .metier-material__icon { font-size: 1.5rem; line-height: 1.2; }
.page-aventure .metier-material__icon img { width: 1.5rem; height: 1.5rem; vertical-align: middle; }
.page-aventure .metier-material__name { font-weight: 600; overflow-wrap: anywhere; }
.page-aventure .metier-material__lvl { font-size: 0.7rem; opacity: 0.8; min-height: 1em; }
.page-aventure .metier-material--locked { opacity: 0.5; filter: grayscale(1); border-style: dashed; }
.page-aventure .metier-material--hit { animation: metier-hit 0.7s ease; }
.page-aventure .metier-material--new { animation: metier-unlock 1.6s ease 2; }
.page-aventure .metier-gather-btn { width: 100%; }
.page-aventure .metier-card form { position: relative; }
/* Butin qui s'envole depuis le bouton de récolte. */
.page-aventure .metier-float { position: absolute; left: 0; right: 0; bottom: 100%; display: flex; flex-direction: column-reverse; align-items: center; gap: 0.15rem; pointer-events: none; z-index: 5; }
.page-aventure .metier-float span { font-weight: 800; font-size: 1.05rem; padding: 0.1rem 0.6rem; border-radius: 999px; background: rgba(20, 20, 30, 0.85); color: #fff; opacity: 0; animation: metier-float 1.8s ease-out forwards; }
.page-aventure .metier-float__xp { color: #85C1E9 !important; font-size: 0.9rem !important; }
.page-aventure .metier-float img { width: 1.2em; height: 1.2em; vertical-align: middle; }
/* Passage de niveau : éclat de la couleur du métier. */
.page-aventure .metier-card--levelup { animation: metier-levelup 1.4s ease; }
.page-aventure .metier-burst { position: absolute; left: 50%; top: 2.2rem; width: 0; height: 0; pointer-events: none; }
.page-aventure .metier-burst span { position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 50%; background: var(--metier-color, #F1C40F); box-shadow: 0 0 8px var(--metier-color, #F1C40F); animation: metier-spark 1.3s ease-out forwards; }
@keyframes metier-float { 0% { opacity: 0; transform: translateY(8px) scale(0.8); } 15% { opacity: 1; transform: translateY(0) scale(1.1); } 100% { opacity: 0; transform: translateY(-46px) scale(1); } }
@keyframes metier-hit { 0% { transform: scale(1); } 35% { transform: scale(1.18); box-shadow: 0 0 12px var(--rank-color); } 100% { transform: scale(1); } }
@keyframes metier-unlock { 0%, 100% { box-shadow: 0 0 0 0 transparent; } 50% { box-shadow: 0 0 16px 4px var(--rank-color); transform: scale(1.08); } }
@keyframes metier-levelup { 0% { box-shadow: 0 0 0 0 transparent; } 30% { box-shadow: 0 0 0 4px var(--metier-color), 0 0 28px 8px var(--metier-color); } 100% { box-shadow: 0 0 0 0 transparent; } }
@keyframes metier-spark { 0% { transform: rotate(var(--angle)) translateY(0); opacity: 1; } 100% { transform: rotate(var(--angle)) translateY(-70px); opacity: 0; } }

/* ───────────── Bestiaire : cartes retournables — tout scopé .page-aventure ─────────────
   Recto = carte habituelle ; verso = statistiques du monstre. Les deux faces occupent la MÊME cellule de grille : la carte
   prend la hauteur de la plus haute, sans hauteur fixée. Retournée au survol (souris), au focus clavier, ou par la classe
   .is-flipped (clic/toucher/Entrée/Espace, voir aventure-fx.js). Sans mouvement (prefers-reduced-motion) : simple bascule. */
.page-aventure .bestiary-card { cursor: pointer; padding: 0; perspective: 800px; background: transparent; border: 0; }
.page-aventure .bestiary-card:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 2px; }
.page-aventure .bestiary-card__inner { display: grid; transform-style: preserve-3d; transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1); }
.page-aventure .bestiary-card__face { grid-area: 1 / 1; display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem; border-radius: var(--radius-md); border: 1px solid var(--accent); background: rgba(124, 58, 237, 0.1); backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.page-aventure .bestiary-card__front { justify-content: center; text-align: center; align-items: center; }
.page-aventure .bestiary-card__back { transform: rotateY(180deg); background: rgba(24, 18, 44, 0.96); }
.page-aventure .bestiary-card.is-flipped .bestiary-card__inner, .page-aventure .bestiary-card:focus-visible .bestiary-card__inner { transform: rotateY(180deg); }
@media (hover: hover) { .page-aventure .bestiary-card:hover .bestiary-card__inner { transform: rotateY(180deg); } }
.page-aventure .bestiary-card__hint { margin-top: auto; font-size: 0.7rem; color: var(--text-dim); opacity: 0.8; }
.page-aventure .bestiary-card__tag { font-size: 0.72rem; color: var(--text-dim); margin-bottom: 0.15rem; }
.page-aventure .bestiary-stats { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.15rem; font-size: 0.74rem; text-align: left; }
.page-aventure .bestiary-stats li { display: flex; justify-content: space-between; gap: 0.5rem; }
.page-aventure .bestiary-stats li span { color: var(--text-dim); }
.page-aventure .bestiary-stats li strong { text-align: right; }
.page-aventure .bestiary-stats__resist--immune strong { color: #4cd964; }
.page-aventure .bestiary-stats__resist--vulnerable strong { color: #ff6b6b; }
@media (prefers-reduced-motion: reduce) { .page-aventure .bestiary-card__inner { transition: none; } }

/* Classement des duels, boutons d'action du combat plus lisibles, onglets mobiles sur une seule ligne. */
.page-aventure .duel-ranking { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.page-aventure .duel-ranking li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; padding: 0.4rem 0.6rem; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.page-aventure .duel-ranking li.is-me { border-color: var(--accent); background: rgba(124, 58, 237, 0.12); }
.page-aventure .duel-ranking__pos { min-width: 1.8rem; text-align: center; }
.page-aventure .combat-actions-row { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.page-aventure .combat-actions-row .btn-mod, .page-aventure .combat-actions-row .btn-mod-danger, .page-aventure .combat-actions-row .btn-primary { min-height: 2.6rem; background: rgba(255, 255, 255, 0.05); }
.page-aventure .combat-actions-row .btn-primary { background: var(--accent); }
.page-aventure .combat-actions-row .btn-mod:disabled { opacity: 0.45; cursor: not-allowed; }
.page-aventure .combat-actions-row .btn-mod-danger { background: rgba(231, 76, 60, 0.1); }
@media (max-width: 640px) {
  .page-aventure .tabs-nav { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
  .page-aventure .tabs-nav .tabs-nav__item { flex: 0 0 auto; white-space: nowrap; scroll-snap-align: center; }
  .page-aventure .tabs-nav::after { display: none; }
}
