/* ==========================================================
   battle.css — JRPG 橫向 ATB 戰鬥 Prototype
   Desktop 16:9 + 手機橫向為主要支援目標。
   使用 percentage / clamp() / CSS custom properties，
   避免寫死單一解析度的 px 座標。
   ========================================================== */

* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  background: #000;
  color: #fff;
  font-family: "Segoe UI", "Noto Sans TC", -apple-system, BlinkMacSystemFont, sans-serif;
  overflow: hidden;
  -webkit-user-select: none;
  user-select: none;
}

img {
  -webkit-user-drag: none;
  user-drag: none;
}

[hidden] {
  display: none !important;
}

button {
  font-family: inherit;
  cursor: pointer;
}

/* ---------- Root layout ---------- */

#battle-root {
  position: relative;
  width: 100vw;
  height: 100vh; /* fallback */
  height: 100dvh;
  overflow: hidden;
  background: #000;
}

#orientation-warning {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  background: #05050a;
  font-size: clamp(16px, 4vw, 26px);
  line-height: 1.6;
}

#battle-viewport {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

/* ---------- Battle Stage (~76%) ---------- */

#battle-stage {
  position: relative;
  flex: 1 1 76%;
  min-height: 0;
  overflow: hidden;
  background-size: cover;
  background-position: center bottom;
  background-color: #1b1b28;
  transition: filter 0.15s ease;
}

.stage-dimmed {
  filter: brightness(0.55);
}

.fx-stage-shake {
  animation: stageShakeAnim 0.3s ease-in-out;
}

@keyframes stageShakeAnim {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-6px, 3px); }
  40% { transform: translate(5px, -3px); }
  60% { transform: translate(-4px, 2px); }
  80% { transform: translate(3px, -2px); }
}

#unit-layer {
  position: absolute;
  inset: 0;
}

.unit {
  position: absolute;
  left: var(--pos-x, 50%);
  bottom: clamp(6%, 9%, 16%);
  transform: translate(-50%, var(--pos-y-offset, 0px));
  width: clamp(90px, 15vw, 220px);
}

.unit-sprite {
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
  filter: none;
}

.unit-enemy {
  cursor: default;
}

.unit.target-selectable {
  cursor: pointer;
}

.unit.target-selectable .unit-sprite {
  animation: targetPulse 1s ease-in-out infinite;
}

@keyframes targetPulse {
  0%, 100% { filter: drop-shadow(0 0 6px #fff59d); }
  50% { filter: drop-shadow(0 0 16px #ffee58) drop-shadow(0 0 26px #ffee58); }
}

.unit.fx-lunge-go {
  transform: translate(calc(-50% + var(--lunge-x, 0px)), var(--pos-y-offset, 0px));
  transition: transform 0.13s ease-out;
}

.unit.fx-lunge-back {
  transform: translate(-50%, var(--pos-y-offset, 0px));
  transition: transform 0.16s ease-in;
}

.unit.fx-shake {
  animation: unitShakeAnim 0.26s ease-in-out;
}

@keyframes unitShakeAnim {
  0%, 100% { margin-left: 0; }
  20% { margin-left: -6px; }
  40% { margin-left: 6px; }
  60% { margin-left: -4px; }
  80% { margin-left: 4px; }
}

.unit.fx-flash-white .unit-sprite {
  animation: flashWhiteAnim 0.16s ease-in-out;
}

@keyframes flashWhiteAnim {
  0%, 100% { filter: none; }
  50% { filter: brightness(2.6) saturate(0); }
}

.unit.fx-clockup-flash .unit-sprite {
  animation: clockUpFlashAnim 0.6s ease-in-out;
}

@keyframes clockUpFlashAnim {
  0%, 100% { filter: none; }
  20%, 60% { filter: brightness(2) saturate(0.3) drop-shadow(0 0 14px #7ecbff); }
}

.unit.fx-death {
  animation: deathAnimKeyframes 0.4s ease forwards;
}

@keyframes deathAnimKeyframes {
  0% { opacity: 1; transform: translate(-50%, var(--pos-y-offset, 0px)) scale(1); }
  100% { opacity: 0; transform: translate(-50%, var(--pos-y-offset, 0px)) scale(1.08); }
}

.unit.fx-dead-hidden {
  visibility: hidden;
  pointer-events: none;
}

.fx-afterimage {
  position: absolute;
  inset: 0;
  opacity: 0.45;
  filter: brightness(1.6) hue-rotate(190deg) saturate(0.4);
  animation: afterimageFadeAnim 0.32s ease-out forwards;
  pointer-events: none;
}

@keyframes afterimageFadeAnim {
  0% { opacity: 0.45; }
  100% { opacity: 0; }
}

/* Hit effect：白色+淡藍色 radial flash（無素材時的 fallback 做法） */
.hit-effect {
  position: absolute;
  left: 50%;
  top: 38%;
  width: 46%;
  min-width: 90px;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, #ffffff 0%, #bfe3ff 35%, rgba(191, 227, 255, 0) 70%);
  animation: hitEffectPopAnim 0.26s ease-out forwards;
  pointer-events: none;
  z-index: 5;
}

@keyframes hitEffectPopAnim {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.3); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); }
}

/* Damage number */
.dmg-number {
  position: absolute;
  left: calc(50% + var(--dmg-jitter, 0px));
  top: 18%;
  transform: translate(-50%, 0);
  font-weight: 800;
  font-size: clamp(18px, 3.4vw, 28px);
  color: #fff;
  text-shadow: 0 2px 4px #000, 0 0 8px #000;
  animation: dmgFloatAnim 0.9s ease-out forwards;
  pointer-events: none;
  z-index: 6;
  white-space: nowrap;
}

.dmg-number--big {
  font-size: clamp(30px, 6vw, 48px);
  color: #ffe082;
}

@keyframes dmgFloatAnim {
  0% { opacity: 0; transform: translate(-50%, 0) scale(0.8); }
  15% { opacity: 1; transform: translate(-50%, -6px) scale(1.05); }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -46px) scale(1); }
}

/* Clock Up 文字 / 速度線 */
.clockup-label {
  position: absolute;
  left: 50%;
  top: 36%;
  transform: translate(-50%, -50%);
  font-size: clamp(20px, 4.5vw, 38px);
  font-weight: 900;
  color: #bfe3ff;
  text-shadow: 0 0 12px #4fc3f7, 0 2px 4px #000;
  letter-spacing: 2px;
  animation: clockupLabelPopAnim 0.6s ease-out forwards;
  pointer-events: none;
  z-index: 6;
  white-space: nowrap;
}

@keyframes clockupLabelPopAnim {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.7); }
  20% { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
  70% { opacity: 1; }
  100% { opacity: 0; }
}

.clockup-lines {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(100deg, transparent 0 18px, rgba(160, 220, 255, 0.35) 18px 20px);
  animation: clockupLinesSweepAnim 0.6s linear forwards;
  pointer-events: none;
  mix-blend-mode: screen;
  z-index: 4;
}

@keyframes clockupLinesSweepAnim {
  0% { transform: translateX(-30%); opacity: 0; }
  15% { opacity: 0.9; }
  100% { transform: translateX(30%); opacity: 0; }
}

/* 大型衝擊爆點 (Rider Kick 命中) */
.impact-burst {
  position: absolute;
  left: 50%;
  top: 38%;
  width: 60%;
  min-width: 160px;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 8;
  background:
    radial-gradient(circle, #ffffff 0%, #ffffff 10%, rgba(255, 255, 255, 0) 32%),
    radial-gradient(circle, rgba(255, 82, 82, 0) 0%, #ff5252 22%, rgba(255, 82, 82, 0) 55%),
    radial-gradient(circle, rgba(68, 138, 255, 0) 0%, #448aff 38%, rgba(68, 138, 255, 0) 72%);
  animation: impactBurstAnim 0.42s ease-out forwards;
}

@keyframes impactBurstAnim {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.6); }
}

/* ---------- 敵人名牌 (名稱 + HP bar，位於 Sprite 上方) ---------- */

.nameplate {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: 8px;
  width: clamp(90px, 15vw, 170px);
  text-align: center;
  font-size: clamp(10px, 1.7vh, 13px);
  font-weight: 700;
  text-shadow: 0 1px 3px #000;
  transition: opacity 0.3s ease;
}

.nameplate .bar-track {
  height: 8px;
  margin-top: 3px;
}

.nameplate.nameplate-defeated {
  opacity: 0;
}

/* ---------- CUT-IN layer (Full Screen Overlay, 與 viewport 對齊，不受 battle-stage 版位限制) ---------- */

#cutin-layer {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh; /* fallback */
  width: 100dvw;
  height: 100dvh;
  z-index: 500; /* 高於 Battle Stage / HUD / Command Menu / Enemy UI / Damage Number(<=30) */
  overflow: hidden;
  background: #000; /* 避免圖片載入/動畫過程出現透明區域 */
  display: flex;
  align-items: center;
  justify-content: center;
}

#cutin-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform: translateX(100%) scale(1);
  opacity: 0;
  visibility: visible;
  display: block;
  filter: none;
  transition: filter 0.17s ease;
  z-index: 1; /* 黑底背景(#cutin-layer 本身)=0 < 圖片=1 < 技名文字=2 < 白閃=5 */
}

/* 技名淡出後，1100 ~ 1300ms：CUT-IN 圖片由右側快速滑入 */
.cutin-slide-in {
  animation: cutinSlideInAnim 0.2s cubic-bezier(.16, .84, .24, 1) forwards;
}

@keyframes cutinSlideInAnim {
  0% { transform: translateX(100%) scale(1); opacity: 0; }
  100% { transform: translateX(0) scale(1); opacity: 1; }
}

/* 1300 ~ 4300ms：圖片完整可見，停留 3000ms，極緩慢推近，不要快速晃動/縮放
   注意：.cutin-slide-in 跟 .cutin-scale-hold 都會設定 `animation` 這個 shorthand，
   兩個 class 同時存在於 #cutin-img 時，cascade 只會生效其中一個（後者蓋掉前者），
   等於直接切斷 .cutin-slide-in 用 forwards fill 撐住的 opacity:1。
   所以這裡的 keyframes 必須「自己」把 opacity 也鎖在 1，
   不能只處理 transform，否則圖片會在切換動畫的瞬間變回 #cutin-img 基礎規則的 opacity:0
   （這正是先前「3 秒黑畫面、圖片完全不可見」bug 的根本原因）。 */
.cutin-scale-hold {
  animation: cutinScaleHoldAnim 3s ease-in-out forwards;
}

@keyframes cutinScaleHoldAnim {
  0% { transform: translateX(0) scale(1); opacity: 1; }
  100% { transform: translateX(0) scale(1.035); opacity: 1; }
}

/* 4300 ~ 4470ms：準備進入命中，畫面稍微增亮 */
.cutin-brighten {
  filter: brightness(1.18) contrast(1.05);
}

/* 白閃後快速消失 */
.cutin-hide-out {
  animation: cutinHideOutAnim 0.15s ease-in forwards;
}

@keyframes cutinHideOutAnim {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

.cutin-white-flash {
  position: absolute;
  inset: 0;
  background: #fff;
  z-index: 5;
  animation: cutinFlashAnim 0.12s ease-out;
}

@keyframes cutinFlashAnim {
  0% { opacity: 0; }
  35% { opacity: 1; }
  100% { opacity: 0; }
}

#cutin-text {
  position: absolute;
  left: 6%;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  text-align: left;
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.15s ease-in; /* STEP 3：技名畫面快速淡出 (950 ~ 1100ms) */
}

/* 技名淡出後整段（含 CUT-IN 圖片展示與回戰場後）都不再顯示 */
#cutin-text.cutin-title-fade-out {
  opacity: 0;
}

#cutin-text .cutin-line1,
#cutin-text .cutin-line2 {
  opacity: 0;
  transform: translateX(-18px);
  transition: opacity 0.25s ease-out, transform 0.25s ease-out, letter-spacing 0.25s ease-out;
}

#cutin-text .cutin-line1 {
  font-size: clamp(20px, 4.2vw, 34px);
  font-weight: 800;
  color: #fff;
  letter-spacing: 10px;
}

#cutin-text .cutin-line2 {
  font-size: clamp(28px, 6.5vw, 54px);
  font-weight: 900;
  color: #ffd54f;
  letter-spacing: 8px;
  text-shadow: 0 0 16px #ff8f00;
}

/* KABUTO 於 300ms、RIDER KICK 於 400ms 由 JS 個別加上這個 class 觸發進場 */
#cutin-text .cutin-line1.text-line-show,
#cutin-text .cutin-line2.text-line-show {
  opacity: 1;
  transform: translateX(0);
}

#cutin-text .cutin-line1.text-line-show {
  letter-spacing: 3px;
}

#cutin-text .cutin-line2.text-line-show {
  letter-spacing: 2px;
}

/* ---------- HUD (~24%) ---------- */

#battle-hud {
  position: relative;
  flex: 1 1 24%;
  min-height: 92px;
  display: flex;
  align-items: center;
  gap: clamp(8px, 2vw, 20px);
  padding: clamp(8px, 1.6vh, 16px) clamp(10px, 2vw, 22px);
  background: linear-gradient(180deg, #0d0d16 0%, #06060b 100%);
  border-top: 1px solid #ffffff22;
}

#hud-ally {
  flex: 1 1 55%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
}

#hud-ally-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

#hud-portrait {
  flex: 0 0 auto;
  width: clamp(32px, 5vh, 52px);
  height: clamp(32px, 5vh, 52px);
  border-radius: 8px;
  border: 2px solid #ffffff88;
  background-size: 240% auto;
  background-position: 50% 4%;
  background-repeat: no-repeat;
  background-color: #222;
}

#hud-ally-name {
  font-size: clamp(14px, 2.2vh, 20px);
  font-weight: 800;
  letter-spacing: 1px;
}

#hud-guard-indicator {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid #8ec7ff;
  color: #8ec7ff;
  font-size: clamp(10px, 1.5vh, 12px);
  font-weight: 800;
  letter-spacing: 1px;
}

.bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: clamp(10px, 1.6vh, 13px);
  font-variant-numeric: tabular-nums;
}

.bar-label {
  flex: 0 0 auto;
  width: 20px;
  font-weight: 800;
  opacity: 0.8;
}

.bar-track {
  flex: 1 1 auto;
  height: 11px;
  background: #1c1c26;
  border: 1px solid #ffffff2b;
  border-radius: 6px;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  width: 0%;
  border-radius: 6px;
  transition: width 0.25s ease;
}

#hud-hp-fill {
  background: linear-gradient(90deg, #43a047, #9ccc65);
}

#hud-en-fill {
  background: linear-gradient(90deg, #1e88e5, #64b5f6);
}

#hud-atb-fill {
  background: linear-gradient(90deg, #ffb300, #ffe082);
}

.bar-text {
  flex: 0 0 auto;
  min-width: 64px;
  text-align: right;
  opacity: 0.85;
}

/* ---------- 指令 / 技能面板 ---------- */

#hud-commands {
  position: relative;
  flex: 1 1 45%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
}

.cmd-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  width: 100%;
  max-width: 320px;
  margin-left: auto;
}

.commands-hidden {
  visibility: hidden;
}

.cmd-btn {
  min-height: 44px;
  padding: 10px 6px;
  font-size: clamp(13px, 1.9vh, 16px);
  font-weight: 800;
  letter-spacing: 1px;
  border-radius: 8px;
  border: 2px solid #ffffff40;
  background: #16162a;
  color: #fff;
}

.cmd-btn:active {
  background: #262646;
}

.cmd-btn:disabled {
  opacity: 0.35;
  pointer-events: none;
}

/* Skill Menu 永遠不能超出 viewport：改用 position:fixed 直接對齊螢幕右下角，
   不依賴 #hud-commands 的實際框高（那個框高只由「有在文件流內」的 cmd-grid 決定，
   絕對定位的舊版 top:50%/translateY(-50%) 完全不受它保護，矮螢幕下會被
   #battle-root 的 overflow:hidden 裁掉）。max-height 是最後一道防線，
   保證面板本身永遠不會比可視高度還高。 */
#skill-menu {
  position: fixed;
  right: 8px;
  bottom: 8px;
  top: auto;
  transform: none;
  width: 100%;
  max-width: 320px;
  max-height: calc(100vh - 16px); /* fallback */
  max-height: calc(100dvh - 16px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: #0d0d16ee;
  border: 1px solid #ffffff33;
  border-radius: 10px;
  padding: 10px;
  box-sizing: border-box;
  z-index: 40;
}

/* 只有這個列表會捲動；未來技能變多也一樣，返回按鈕永遠固定在它外面 */
.skill-list {
  flex: 1 1 auto;
  min-height: 0; /* 關鍵：避免 flex child 把 panel 撐出 viewport */
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.skill-btn {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  font-size: clamp(12px, 1.8vh, 15px);
  font-weight: 700;
  border-radius: 8px;
  border: 1px solid #ffffff40;
  background: #1a1a2e;
  color: #fff;
  flex: 0 0 auto;
}

.skill-btn:disabled {
  opacity: 0.35;
  pointer-events: none;
}

.skill-cost {
  opacity: 0.75;
  font-weight: 600;
}

.skill-btn--back {
  background: transparent;
  border-style: dashed;
  justify-content: center;
  flex: 0 0 auto; /* 永遠固定在 .skill-list 外面，不受捲動影響、永遠完整可見 */
}

#item-toast {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 10px);
  transform: translateX(-50%);
  background: #000000cc;
  border: 1px solid #ffffff55;
  padding: 8px 16px;
  border-radius: 6px;
  font-size: clamp(12px, 1.8vh, 14px);
  white-space: nowrap;
  z-index: 10;
}

/* ---------- Victory / Defeat ---------- */

#result-overlay {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  background: rgba(0, 0, 0, 0.74);
}

#result-title {
  font-size: clamp(36px, 9vw, 76px);
  font-weight: 900;
  letter-spacing: 6px;
}

.result-victory #result-title {
  color: #ffd54f;
  text-shadow: 0 0 24px #ff9800;
}

.result-defeat #result-title {
  color: #ff5252;
  text-shadow: 0 0 24px #b71c1c;
}

#result-restart {
  min-height: 48px;
  padding: 12px 34px;
  font-size: clamp(14px, 2vw, 18px);
  font-weight: 800;
  border-radius: 8px;
  border: 2px solid #fff;
  background: #16162a;
  color: #fff;
  letter-spacing: 1px;
}

#result-restart:active {
  background: #262646;
}

/* ---------- 小螢幕高度保護 ---------- */

@media (max-height: 420px) {
  #battle-hud {
    min-height: 78px;
  }
  .bar-row {
    gap: 5px;
  }
}
