/* ===== 배틀 애니메이션 뷰 (battle-view.js가 사용) =====
   index.html(공용 CSS 변수 테마)과 snap-mon.html(변수 없는 고정 다크 테마)
   양쪽 모두에서 동일하게 보이도록, 이 파일은 사이트 테마 변수에 의존하지 않고
   자체적으로 완결된 다크 "게임 화면" 팔레트를 사용합니다. */

/* ===== 리포트에 삽입되는 요소 (재생 버튼 / 대결 구도 표시) =====
   이 두 클래스는 메인 앱이 렌더한 리포트 DOM 안(호스트 페이지 테마 위)에 삽입된다.
   과거엔 메인 style.css의 .btn-tts / .battle-matchup-title에 의존했으나, script-movie
   서비스로 분리하면서 메인 CSS 의존을 끊고 여기서 자기완결적으로 정의한다. 호스트에
   테마 변수(--surface2 등)가 있으면(index.html) 그 값으로 페이지와 어우러지고, 없으면
   (snap-mon.html) fallback 값으로 그대로 보이도록 CSS 변수 fallback을 함께 준다. */
.btn-battle-play {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: var(--surface2, rgba(255, 255, 255, 0.08));
  border: 1px solid var(--border, #3a3a5c);
  border-radius: var(--radius-sm, 8px);
  color: var(--text2, #d8d8ff);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
  margin-left: 12px;
  font-family: inherit;
  white-space: nowrap;
}
.btn-battle-play:hover {
  background: var(--surface, rgba(255, 255, 255, 0.16));
  color: var(--text, #fff);
  border-color: var(--accent, #7a7aff);
}

/* 배틀 대결 구도 표시 (배틀상세 헤더 바로 위) */
.battle-matchup-title {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--accent2, #b7b7ff);
  background: var(--surface2, rgba(255, 255, 255, 0.06));
  border: 1px solid var(--border, #3a3a5c);
  border-radius: var(--radius-sm, 8px);
  padding: 6px 12px;
  margin: 20px 0 -4px;
  text-align: center;
}

.battle-overlay {
  position: fixed;
  inset: 0;
  z-index: 10500;
  background: rgba(6, 6, 16, 0.86);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: battle-overlay-fadein 0.2s ease;
  font-family: inherit;
  /* 가로모드에서 카메라 컷아웃/제스처 내비게이션 바가 좌우로 걸리는 기기에서
     콘텐츠가 그 밑에 깔려 가려지지 않도록, 안전영역만큼 안쪽으로 띄운다.
     viewport-fit=cover가 없는 페이지(예: 데스크톱 웹)에서는 env()가 0이 되어
     기존 동작과 동일하다. */
  box-sizing: border-box;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
    env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

@keyframes battle-overlay-fadein {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.battle-stage {
  position: relative;
  width: min(960px, 97vw);
  height: min(600px, 84vh);
  background: linear-gradient(180deg, #1b1e2f 0%, #11131f 60%, #0b0c14 100%);
  border: 1px solid #3a3a5c;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  opacity: 0;
  transform: scale(0.97);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.battle-stage.battle-stage-visible {
  opacity: 1;
  transform: scale(1);
}

.battle-side {
  position: absolute;
  /* 폰 세로/가로, 태블릿, PC 등 화면 폭과 높이 비율이 제각각인 환경에서 모두 자연스럽게
     보이도록, 폭 기준 breakpoint 대신 vmin(가로/세로 중 더 짧은 쪽 기준) 기반 유동값을
     쓴다 - 세로 모드에서는 폭이, 가로 모드에서는 높이가 자동으로 기준이 되어 방향이
     바뀌어도 비율이 일관되게 유지된다. 대사 캡션(.battle-caption)이 긴 텍스트로 여러 줄이
     되면 아래에서부터 높이가 늘어나므로, 캡션이 최대로 늘어나도 겹치지 않을 만큼 여유를 둔다. */
  bottom: clamp(78px, 29vmin, 178px);
  display: flex;
  flex-wrap: wrap;
  gap: clamp(6px, 3vmin, 24px);
  align-items: flex-end;
  /* 한 진영에 여러 마리(2:2 이상)가 붙어도 반대 진영 쪽으로 넘어가 겹치지 않도록,
     세로모드처럼 폭이 좁을 때는 진영당 폭을 화면의 절반 아래로 제한한다. 폭이 넘치는
     인원은 아래로 줄바꿈된다(battle-mon-el의 스프라이트 크기는 js가 --battle-scale로
     팀 인원수에 맞춰 같이 줄인다). 좌우 여백(left/right)을 6%→4%로, 진영 폭을 42%→47%로
     넓혀 스프라이트를 키울 여유를 최대한 확보했다(폭이 가장 좁은 세로모드 폰 기준으로도
     1마리 대결에서 반대 진영과 닿지 않는 한도까지 계산해서 정함, computeBattleScale 참고). */
  max-width: 47%;
}
.battle-side-left  { left: 4%; justify-content: flex-start; }
.battle-side-right { right: 4%; flex-direction: row-reverse; justify-content: flex-start; }

.battle-mon {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition: transform 0.12s ease;
}

/* 대결 종료 후 승리/패배 표시 */
.battle-mon-badge {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%) scale(0.6);
  padding: 3px 10px;
  border-radius: 999px;
  font-size: clamp(10px, 2.8vmin, 14px);
  font-weight: 800;
  white-space: nowrap;
  z-index: 5;
  opacity: 0;
  animation: battle-badge-pop 0.4s ease forwards;
  animation-delay: 0.1s;
}
@keyframes battle-badge-pop {
  0%   { opacity: 0; transform: translateX(-50%) scale(0.4); }
  70%  { opacity: 1; transform: translateX(-50%) scale(1.15); }
  100% { opacity: 1; transform: translateX(-50%) scale(1); }
}
.battle-mon-winner .battle-mon-badge {
  background: linear-gradient(180deg, #ffe27a, #f5b83d);
  color: #4a2e00;
  box-shadow: 0 0 14px rgba(255, 210, 90, 0.7);
}
.battle-mon-winner .battle-sprite,
.battle-mon-winner .battle-sprite-placeholder {
  filter: drop-shadow(0 8px 10px rgba(0, 0, 0, 0.45)) drop-shadow(0 0 12px rgba(255, 210, 90, 0.85));
}
.battle-mon-loser .battle-mon-badge {
  background: rgba(60, 60, 70, 0.9);
  color: #d8d8ff;
  border: 1px solid #3a3a5c;
}
.battle-mon-loser .battle-sprite,
.battle-mon-loser .battle-sprite-placeholder {
  filter: grayscale(0.85) brightness(0.6);
  opacity: 0.7;
}
/* 이미지 없이 ❔로 표시되는 플레이스홀더(.battle-sprite-placeholder도 .battle-sprite
   클래스를 같이 갖고 있음)는 좌우반전 대상에서 제외한다 - 실제 스프라이트 이미지(<img>)만
   좌우로 뒤집는다. */
.battle-side-right .battle-mon img.battle-sprite {
  transform: scaleX(-1);
}

/* --battle-scale: js가 팀 인원수(computeBattleTeams 기준 가장 인원이 많은 진영)에 맞춰
   .battle-stage에 세팅하는 값(1이면 기존과 동일 크기). 2:2 이상 팀전에서 스프라이트가
   진영 폭(.battle-side의 max-width: 47%)을 넘어 반대 진영과 겹치지 않도록 인원이
   늘어날수록 함께 줄어든다(computeBattleScale 참고).
   기준 계수를 29vmin→43vmin으로 올려 1마리 대결(scale=1) 스프라이트를 약 1.5배 키웠다
   (기존엔 너무 작다는 피드백). 세로모드 폭이 가장 좁은 기기(약 360px)에서도 1마리 대결
   기준 좌우 스프라이트가 서로 겹치지 않는 한도 안에서 최대치를 잡은 값이라, 정확히
   2배까지는 못 키웠다 - 그 이상은 화면 폭상 반대 진영과 겹친다. */
.battle-sprite {
  width: clamp(74px, calc(43vmin * var(--battle-scale, 1)), 300px);
  height: clamp(74px, calc(43vmin * var(--battle-scale, 1)), 300px);
  object-fit: contain;
  filter: drop-shadow(0 8px 10px rgba(0, 0, 0, 0.45));
}
.battle-sprite-placeholder {
  width: clamp(74px, calc(43vmin * var(--battle-scale, 1)), 300px);
  height: clamp(74px, calc(43vmin * var(--battle-scale, 1)), 300px);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(31px, calc(18vmin * var(--battle-scale, 1)), 126px);
  background: rgba(255, 255, 255, 0.06);
  border: 1px dashed #3a3a5c;
  border-radius: 12px;
}

/* ===== 배틀 시작 인트로 (battle-view.js의 runIntro) =====
   이미지 로딩 시간을 벌면서 대결이 시작됨을 분명히 보여주기 위한 연출. 각 진영은
   바깥에서 미끄러져 들어오며(battle-mon-intro-in), 중앙에는 "VS"가 잠깐 나타났다
   사라진다. */
.battle-mon-intro-in {
  animation: battle-mon-slide-in-left 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.battle-side-right .battle-mon-intro-in {
  animation-name: battle-mon-slide-in-right;
}
@keyframes battle-mon-slide-in-left {
  0%   { opacity: 0; transform: translateX(-60px) scale(0.85); }
  100% { opacity: 1; transform: translateX(0) scale(1); }
}
@keyframes battle-mon-slide-in-right {
  0%   { opacity: 0; transform: translateX(60px) scale(0.85); }
  100% { opacity: 1; transform: translateX(0) scale(1); }
}

.battle-vs-badge {
  position: absolute;
  left: 50%;
  top: 38%;
  transform: translate(-50%, -50%) scale(0.4);
  font-size: clamp(32px, 10vmin, 64px);
  font-weight: 900;
  font-style: italic;
  color: #fff;
  text-shadow: 0 0 16px rgba(108, 99, 255, 0.9), 0 4px 10px rgba(0, 0, 0, 0.5);
  opacity: 0;
  z-index: 20;
  pointer-events: none;
  animation: battle-vs-pop 2s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes battle-vs-pop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.3); }
  25%  { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  40%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  80%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); }
}

.battle-mon-label {
  font-size: clamp(11px, 3.2vmin, 16px);
  font-weight: 700;
  color: #d8d8ff;
  background: rgba(0, 0, 0, 0.35);
  padding: clamp(2px, 0.6vmin, 4px) clamp(6px, 2vmin, 10px);
  border-radius: 999px;
}

.battle-effect-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* 스프라이트를 키운 만큼(위 .battle-sprite 참고) 피격 이펙트도 같은 비율로 키워서
   커진 몬스터 위에서 이펙트가 상대적으로 작아 보이지 않게 한다. */
.battle-effect-pop {
  position: absolute;
  font-size: clamp(65px, 21vmin, 142px);
  line-height: 1;
  animation: battle-effect-pop 0.85s ease forwards;
  filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.35));
}
.battle-effect-pop img {
  width: clamp(115px, 37vmin, 250px);
  height: clamp(115px, 37vmin, 250px);
  object-fit: contain;
}
@keyframes battle-effect-pop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.3); }
  35%  { opacity: 1; transform: translate(-50%, -50%) scale(1.2); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1); }
}

.battle-caption {
  position: absolute;
  left: clamp(12px, 3vmin, 26px);
  right: clamp(12px, 3vmin, 26px);
  bottom: clamp(10px, 3vmin, 22px);
  min-height: clamp(36px, 10vmin, 52px);
  background: rgba(10, 10, 20, 0.85);
  border: 1px solid #3a3a5c;
  border-radius: 10px;
  padding: clamp(8px, 2.4vmin, 14px) clamp(10px, 3.2vmin, 18px);
  color: #f2f2ff;
  font-size: clamp(11px, 3vmin, 16px);
  font-weight: 600;
  line-height: 1.4;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.battle-caption-visible {
  opacity: 1;
  transform: translateY(0);
}

.battle-close-btn,
.battle-replay-btn {
  position: absolute;
  top: 10px;
  padding: 6px 12px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid #3a3a5c;
  border-radius: 8px;
  color: #d8d8ff;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.battle-close-btn:hover,
.battle-replay-btn:hover {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.battle-close-btn { right: 10px; }
.battle-replay-btn { right: 96px; }
.battle-replay-btn.hidden { display: none; }

.battle-speed-group {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  gap: 4px;
}
.battle-speed-btn {
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid #3a3a5c;
  border-radius: 8px;
  color: #d8d8ff;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.battle-speed-btn:hover {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.battle-speed-btn.active {
  background: #5757ff;
  border-color: #7a7aff;
  color: #fff;
}

/* 공격 시 앞으로 튀어나가는 연출 (좌측 진영은 오른쪽으로, 우측 진영은 왼쪽으로) */
@keyframes battle-lunge-right { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(22px); } }
@keyframes battle-lunge-left  { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-22px); } }
.battle-lunge-right { animation: battle-lunge-right 0.65s ease; }
.battle-lunge-left  { animation: battle-lunge-left 0.65s ease; }

/* 피격 시 흔들림 - 상성 결과에 따라 진폭 차등 */
@keyframes battle-shake-big {
  0%, 100% { transform: translateX(0); filter: brightness(1); }
  20% { transform: translateX(-16px); filter: brightness(2.2) saturate(0); }
  40% { transform: translateX(14px); }
  60% { transform: translateX(-10px); }
  80% { transform: translateX(6px); }
}
@keyframes battle-shake-mid {
  0%, 100% { transform: translateX(0); filter: brightness(1); }
  25% { transform: translateX(-9px); filter: brightness(1.6) saturate(0.2); }
  50% { transform: translateX(8px); }
  75% { transform: translateX(-4px); }
}
@keyframes battle-shake-small {
  0%, 100% { transform: translateX(0); }
  30% { transform: translateX(-4px); }
  60% { transform: translateX(3px); }
}
.battle-shake-big   { animation: battle-shake-big 0.5s ease; }
.battle-shake-mid   { animation: battle-shake-mid 0.5s ease; }
.battle-shake-small { animation: battle-shake-small 0.5s ease; }
