/* BattleShow — overlay visual layer v0.4
   Безопасный слой: не меняет боевую логику, только внешний вид OBS-арены. */

:root {
  --bs-gold: #f3c76a;
  --bs-gold-soft: rgba(243, 199, 106, 0.38);
  --bs-panel: rgba(12, 14, 20, 0.78);
  --bs-panel-strong: rgba(10, 12, 18, 0.92);
  --bs-red: #ff5a4a;
  --bs-green: #7ee37e;
  --bs-blue: #6fb8ff;
  --bs-purple: #c3a9ff;
}

#arena {
  isolation: isolate;
}


/* Центральный таймер до овертайма.
   Он живёт отдельно от логики боя и помогает визуально контролировать темп playback. */
.battle-timer {
  position: absolute;
  top: 0;
  left: 50%;
  width: 78px;
  height: 38px;
  transform: translateX(-50%);
  z-index: 12;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #f4ead5;
  font-size: 25px;
  line-height: 1;
  font-weight: 900;
  letter-spacing: 1px;
  text-shadow:
    0 2px 0 rgba(0,0,0,0.95),
    0 0 10px rgba(243,199,106,0.22);
  background:
    linear-gradient(to bottom, rgba(20,23,31,0.92), rgba(8,10,15,0.90));
  border: 1px solid rgba(243,199,106,0.38);
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,0.035),
    0 6px 18px rgba(0,0,0,0.26);
  pointer-events: none;
}

.battle-timer::after {
  content: "OVERTIME";
  position: absolute;
  left: 50%;
  bottom: -13px;
  transform: translateX(-50%);
  color: rgba(244,234,213,0.62);
  font-size: 8px;
  line-height: 1;
  font-weight: 800;
  letter-spacing: 1px;
}

.battle-timer--warning {
  color: #ffd36d;
  border-color: rgba(255,211,109,0.56);
  text-shadow:
    0 2px 0 rgba(0,0,0,0.95),
    0 0 12px rgba(255,211,109,0.42);
}

.battle-timer--overtime {
  color: #ff4a3d;
  border-color: rgba(255,74,61,0.72);
  text-shadow:
    0 2px 0 rgba(0,0,0,0.95),
    0 0 14px rgba(255,74,61,0.55);
  animation: bsOvertimeTimerPulse 820ms ease-in-out infinite;
}

.battle-timer--overtime::after {
  color: rgba(255,74,61,0.88);
}

@keyframes bsOvertimeTimerPulse {
  0%, 100% {
    transform: translateX(-50%) scale(1);
  }

  50% {
    transform: translateX(-50%) scale(1.055);
  }
}

/* Лёгкая “сборка” сцены при появлении боя */
#arena[style*="display: block"] .battle-stage {
  animation: bsStageIntro 380ms ease-out both;
}

@keyframes bsStageIntro {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.992);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Улучшаем читаемость HUD поверх любого фона */
.hp-frame,
.nameplate,
.effect-item,
.status-pill {
  backdrop-filter: blur(3px);
}

.hp-frame {
  border-color: rgba(243, 199, 106, 0.46);
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,0.045),
    0 6px 18px rgba(0,0,0,0.26),
    0 0 16px rgba(243,199,106,0.05);
}

.hp {
  box-shadow: inset 0 0 12px rgba(255,255,255,0.08);
}

.nameplate {
  border-color: rgba(243, 199, 106, 0.36);
}

/* Idle-анимация персонажей. Это не спрайты, а безопасная CSS-заготовка. */
.character {
  width: 200px;
  height: 262px;
  object-fit: contain;
  object-position: center bottom;
  animation: bsIdle 2200ms ease-in-out infinite;
  will-change: transform, filter;
}

.side.left .character {
  --idle-x: 10px;
  --idle-rot: -3deg;
  --face-x: 1;
}

.side.right .character {
  --idle-x: -10px;
  --idle-rot: 3deg;
  --face-x: -1;
}

@keyframes bsIdle {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0)) scaleX(var(--face-x, 1)) scale(var(--skin-scale, 1));
  }

  50% {
    transform: translateX(calc(var(--idle-x, 0) + var(--skin-x, 0px))) translateY(calc(-3px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0)) scaleX(var(--face-x, 1)) scale(var(--skin-scale, 1));
  }
}

.character.hit-left,
.character.hit-right,
.character.hurt,
.character.blocked {
  animation: none;
}

/* Усиливаем читаемость всплывающего урона */
.combat-text {
  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.75));
}

/* Первый вариант информативного боевого фида.
   Он специально небольшой, чтобы не мешать арене на стриме. */
.battle-feed {
  position: absolute;
  left: 50%;
  bottom: 12px;
  width: 330px;
  max-height: 72px;
  transform: translateX(-50%);
  z-index: 14;
  display: none;
  flex-direction: column-reverse;
  gap: 4px;
  pointer-events: none;
}

.battle-feed.is-debug-visible {
  display: flex;
}

.battle-feed__item {
  min-height: 20px;
  padding: 4px 10px;
  border: 1px solid rgba(243, 199, 106, 0.22);
  background:
    linear-gradient(90deg, rgba(243,199,106,0.10), rgba(12,14,20,0.70) 22%, rgba(12,14,20,0.70) 78%, rgba(243,199,106,0.10)),
    var(--bs-panel);
  color: #f3ead6;
  font-size: 11px;
  line-height: 1.1;
  font-weight: 700;
  letter-spacing: 0.15px;
  text-align: center;
  text-shadow: 0 1px 0 rgba(0,0,0,0.95);
  box-shadow: 0 5px 14px rgba(0,0,0,0.22);
  backdrop-filter: blur(3px);
  opacity: 0;
  transform: translateY(8px) scale(0.98);
  animation: bsFeedItem 3600ms ease forwards;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.battle-feed__item--damage,
.battle-feed__item--crit {
  color: #ffd36d;
}

.battle-feed__item--crit {
  border-color: rgba(255, 90, 74, 0.42);
  color: #ff8b7f;
}

.battle-feed__item--regen {
  color: var(--bs-green);
}

.battle-feed__item--block,
.battle-feed__item--shield {
  color: var(--bs-blue);
}

.battle-feed__item--status {
  color: var(--bs-purple);
}

@keyframes bsFeedItem {
  0% {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
  }

  10%, 78% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }

  100% {
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
  }
}

/* Подготовка к будущим двум OBS-сценам.
   Пока можно вручную добавить body class="scene-compact" в index.html для компактной версии. */
body.scene-compact .battle-feed {
  display: none;
}

body.scene-compact .arena-ui {
  top: 12px;
}

body.scene-compact .side {
  transform: scale(0.88);
  transform-origin: bottom center;
}

/* Сценическое воспроизведение удара: теперь это не залипающие transition-состояния,
   а короткие keyframe-анимации. После удаления класса персонаж всегда возвращается в idle. */
.character.windup-left,
.character.windup-right,
.character.attack-left,
.character.attack-right,
.character.impact-target,
.character.impact-strong,
.character.evade-target {
  animation: none;
}

.character.attack-left {
  animation: bsAttackLeft 285ms cubic-bezier(.18,.82,.22,1) both;
  filter: drop-shadow(0 0 13px rgba(243, 199, 106, 0.55)) brightness(1.08);
  z-index: 4;
}

.character.attack-right {
  animation: bsAttackRight 285ms cubic-bezier(.18,.82,.22,1) both;
  filter: drop-shadow(0 0 13px rgba(243, 199, 106, 0.55)) brightness(1.08);
  z-index: 4;
}

@keyframes bsAttackLeft {
  0% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  34% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 10px)) translateY(calc(1px + var(--skin-y, 0px))) rotate(-5deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 0.99));
  }

  62% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 104px)) translateY(calc(-5px + var(--skin-y, 0px))) rotate(4deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.09));
  }

  100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }
}

@keyframes bsAttackRight {
  0% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  34% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 10px)) translateY(calc(1px + var(--skin-y, 0px))) rotate(5deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 0.99));
  }

  62% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 104px)) translateY(calc(-5px + var(--skin-y, 0px))) rotate(-4deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.09));
  }

  100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }
}

.side.left .character.impact-target {
  animation: bsImpactLeft 180ms ease-out both;
}

.side.right .character.impact-target {
  animation: bsImpactRight 180ms ease-out both;
}

.side.left .character.impact-strong {
  animation: bsImpactStrongLeft 220ms ease-out both;
}

.side.right .character.impact-strong {
  animation: bsImpactStrongRight 220ms ease-out both;
}

.character.impact-target {
  filter: brightness(0.78) saturate(1.25) drop-shadow(0 0 8px rgba(255,255,255,0.10));
}

.character.impact-strong {
  filter: brightness(0.68) saturate(1.55) drop-shadow(0 0 14px rgba(255, 90, 74, 0.52));
}

@keyframes bsImpactLeft {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  35% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 20px)) translateY(calc(-2px + var(--skin-y, 0px))) rotate(-7deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 0.96));
  }

  65% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 7px)) translateY(calc(1px + var(--skin-y, 0px))) rotate(2deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.01));
  }
}

@keyframes bsImpactRight {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  35% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 20px)) translateY(calc(-2px + var(--skin-y, 0px))) rotate(7deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 0.96));
  }

  65% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 7px)) translateY(calc(1px + var(--skin-y, 0px))) rotate(-2deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.01));
  }
}

@keyframes bsImpactStrongLeft {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  28% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 30px)) translateY(calc(-5px + var(--skin-y, 0px))) rotate(-10deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 0.92));
  }

  60% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 11px)) translateY(calc(2px + var(--skin-y, 0px))) rotate(4deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.03));
  }
}

@keyframes bsImpactStrongRight {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  28% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 30px)) translateY(calc(-5px + var(--skin-y, 0px))) rotate(10deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 0.92));
  }

  60% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 11px)) translateY(calc(2px + var(--skin-y, 0px))) rotate(-4deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.03));
  }
}

.side.left .character.evade-target {
  animation: bsEvadeLeft 220ms ease-out both;
}

.side.right .character.evade-target {
  animation: bsEvadeRight 220ms ease-out both;
}

@keyframes bsEvadeLeft {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  42% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) - 42px)) translateY(calc(-7px + var(--skin-y, 0px))) rotate(-9deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.02));
    filter: brightness(1.18) opacity(0.84);
  }
}

@keyframes bsEvadeRight {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  42% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px) + 42px)) translateY(calc(-7px + var(--skin-y, 0px))) rotate(9deg) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1.02));
    filter: brightness(1.18) opacity(0.84);
  }
}

/* HUD clarity layer: читаемость HP, отложенная потеря здоровья и состояния опасности. */
.hp-bar {
  isolation: isolate;
}

.hp-lag {
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  background: linear-gradient(to bottom, rgba(255, 214, 105, 0.82), rgba(220, 119, 45, 0.82));
  box-shadow: inset 0 0 10px rgba(255, 222, 122, 0.22);
  transition: width 620ms cubic-bezier(.16,.84,.3,1);
}

.hp {
  z-index: 1;
}


.hp-frame--damaged {
  animation: bsHudDamage 420ms ease-out both;
}

.hp-frame--healed {
  animation: bsHudHeal 420ms ease-out both;
}

@keyframes bsHudDamage {
  0% {
    transform: translateX(0);
    box-shadow: 0 0 0 rgba(255,90,74,0), 0 6px 18px rgba(0,0,0,0.26);
  }

  20% {
    transform: translateX(-3px);
  }

  42% {
    transform: translateX(3px);
    box-shadow: 0 0 18px rgba(255,90,74,0.30), 0 6px 18px rgba(0,0,0,0.26);
  }

  70% {
    transform: translateX(-1px);
  }

  100% {
    transform: translateX(0);
    box-shadow: 0 6px 18px rgba(0,0,0,0.26);
  }
}

@keyframes bsHudHeal {
  0% {
    box-shadow: 0 0 0 rgba(126,227,126,0), 0 6px 18px rgba(0,0,0,0.26);
  }

  45% {
    box-shadow: 0 0 18px rgba(126,227,126,0.28), 0 6px 18px rgba(0,0,0,0.26);
  }

  100% {
    box-shadow: 0 6px 18px rgba(0,0,0,0.26);
  }
}

.hp-state-low .hp-frame,
.hp-frame.hp-state-low {
  border-color: rgba(255, 190, 80, 0.66);
}

.hp-state-critical .hp-frame,
.hp-frame.hp-state-critical {
  border-color: rgba(255, 90, 74, 0.82);
  animation: bsCriticalHp 920ms ease-in-out infinite;
}

.hp-state-empty .character {
  filter: grayscale(0.82) brightness(0.68);
}

@keyframes bsCriticalHp {
  0%, 100% {
    box-shadow: 0 6px 18px rgba(0,0,0,0.26), 0 0 8px rgba(255,90,74,0.10);
  }

  50% {
    box-shadow: 0 6px 18px rgba(0,0,0,0.26), 0 0 18px rgba(255,90,74,0.34);
  }
}

.hp-state-critical .character {
  filter: drop-shadow(0 0 10px rgba(255,90,74,0.18));
}

.effect-bar {
  min-height: 0 !important;
  display: none !important;
}

/* Постоянные статусы бойца: вертикальная колонка у внешнего края персонажа.
   Игрок смотрит вправо, значит его "спина" слева. Бот смотрит влево — его "спина" справа. */
.status-layer .fighter-status-stack {
  position: absolute !important;
  top: 16px !important;
  display: flex !important;
  flex-direction: column !important;
  flex-wrap: nowrap !important;
  gap: 6px !important;
  width: max-content !important;
  z-index: 12 !important;
  pointer-events: none !important;
}

.side.left .status-layer .fighter-status-stack {
  left: -24px !important;
  right: auto !important;
  align-items: flex-start !important;
}

.side.right .status-layer .fighter-status-stack {
  right: -24px !important;
  left: auto !important;
  align-items: flex-end !important;
}

.fighter-status-item {
  position: relative;
  width: max-content;
  min-width: 0;
  height: 20px;
  display: inline-flex !important;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  padding: 0;
  border: 0 !important;
  border-radius: 0;
  background: transparent !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
}

.fighter-status-icon {
  width: 18px;
  height: 18px;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.90));
}

.fighter-status-value {
  min-width: 12px;
  padding-left: 0;
  font-size: 13px;
  font-weight: 900;
  line-height: 1;
  text-align: left;
  color: rgba(255, 247, 223, 0.96);
  text-shadow:
    0 1px 2px rgba(0,0,0,0.98),
    0 0 4px rgba(0,0,0,0.82);
}

.fighter-status-item--shield .fighter-status-value {
  color: var(--bs-blue);
}

.fighter-status-item--bleed .fighter-status-value {
  color: var(--bs-red);
}

.fighter-status-item--blind .fighter-status-value {
  color: var(--bs-purple);
}

/* Защита от старых текстовых подписей, если они остались в DOM после предыдущей версии. */
.fighter-status-stack .effect-label,
.fighter-status-stack .effect-name,
.fighter-status-stack .effect-text,
.fighter-status-stack .status-label,
.fighter-status-stack [data-effect-label] {
  display: none !important;
}

/* Оглушённый пропуск хода: без крупного текста поверх персонажа. */
.character.stun-skip {
  animation: bsStunSkip 420ms ease-in-out both;
  filter: saturate(0.72) brightness(0.82) drop-shadow(0 0 13px rgba(195,169,255,0.42));
}

@keyframes bsStunSkip {
  0%, 100% {
    transform: translateX(calc(var(--idle-x, 0px) + var(--skin-x, 0px))) translateY(calc(0px + var(--skin-y, 0px))) rotate(var(--idle-rot, 0deg)) scaleX(var(--face-x, 1)) scale(calc(var(--skin-scale, 1) * 1));
  }

  25% {
    transform: translateX(calc(var(--idle-x, 0px) - 4px)) translateY(1px) rotate(-2deg) scale(0.99);
  }

  50% {
    transform: translateX(calc(var(--idle-x, 0px) + 4px)) translateY(-1px) rotate(2deg) scale(0.99);
  }

  75% {
    transform: translateX(calc(var(--idle-x, 0px) - 3px)) translateY(1px) rotate(-1deg) scale(0.995);
  }
}

/* Bobby/base attack VFX layer.
   Эффект удара размещается не в центре модели цели, а ближе к центру арены,
   слегка заступая на половину противника. */
.side.left .character {
  --idle-x: -24px;
  --idle-rot: 0deg;
  --face-x: 1;
}

.side.right .character {
  --idle-x: 24px;
  --idle-rot: 0deg;
  --face-x: -1;
}

.attack-effects-layer {
  position: absolute;
  inset: 0;
  z-index: 7;
  pointer-events: none;
  overflow: hidden;
}

.attack-effect {
  position: absolute;
  bottom: 122px;
  width: 120px;
  height: 75px;
  object-fit: contain;
  opacity: 0;
  pointer-events: none;
  filter:
    drop-shadow(0 2px 2px rgba(0,0,0,0.72))
    drop-shadow(0 0 8px rgba(255,230,170,0.10));
  will-change: transform, opacity;
}

.attack-effect--target-opponent {
  left: 47%;
  transform-origin: 58% 50%;
  animation: bsAttackEffectToOpponent 430ms cubic-bezier(.16,.82,.24,1) both;
}

.attack-effect--target-player {
  right: 47%;
  transform-origin: 42% 50%;
  animation: bsAttackEffectToPlayer 430ms cubic-bezier(.16,.82,.24,1) both;
}

.attack-effect--crit {
  bottom: 104px;
  width: 120px;
  height: 120px;
  filter:
    drop-shadow(0 2px 2px rgba(0,0,0,0.76))
    drop-shadow(0 0 12px rgba(255,120,90,0.18));
}

@keyframes bsAttackEffectToOpponent {
  0% {
    opacity: 0;
    transform: translateX(-32px) scale(0.74, 0.82);
  }

  18% {
    opacity: 0.95;
  }

  58% {
    opacity: 0.92;
    transform: translateX(10px) scale(1.0);
  }

  100% {
    opacity: 0;
    transform: translateX(48px) scale(1.08, 0.94);
  }
}

@keyframes bsAttackEffectToPlayer {
  0% {
    opacity: 0;
    transform: translateX(32px) scaleX(-1) scaleY(0.82) scale(0.74);
  }

  18% {
    opacity: 0.95;
  }

  58% {
    opacity: 0.92;
    transform: translateX(-10px) scaleX(-1) scaleY(1) scale(1.0);
  }

  100% {
    opacity: 0;
    transform: translateX(-48px) scaleX(-1) scaleY(0.94) scale(1.08);
  }
}
