/* Actor motion: the painted enemy sprite moves, its HUD (name, HP, intent) never does.
   Idle breath / weight shift, attack wind-up → strike → recover, hit recoil + flash, death.
   Loaded last; replaces the 1px actorIdle bob, the whole-card hitShake and the scale-only lunge. */

/* ---- idle: breath from the feet + a slow weight shift. Bigger threats breathe slower and deeper. */
#game .enemy .portrait img { transform-origin: 50% 100%; animation: actorBreath 3.8s ease-in-out infinite; }
#game .enemy:nth-child(2) .portrait img { animation-delay: -1.3s; }
#game .enemy:nth-child(3) .portrait img { animation-delay: -2.5s; }
#game .enemy.miniboss .portrait img,
#game .enemy.boss .portrait img { animation-name: actorBreathHeavy; animation-duration: 5.2s; }
/* Beasts pant, even the guardian hound. */
#game .enemy.enemy[data-enemy=wolf] .portrait img,
#game .enemy.enemy[data-enemy=tyrs_hound] .portrait img { animation-name: actorPant; animation-duration: 1.9s; }
#game .enemy.stunned .portrait img { animation: actorDazed 2.4s ease-in-out infinite; }

@keyframes actorBreath {
  0%, 100% { transform: scale(var(--actor-scale, 1)) scale(1, 1) skewX(0deg); }
  35%      { transform: scale(var(--actor-scale, 1)) scale(.994, 1.016) skewX(-.5deg); }
  70%      { transform: scale(var(--actor-scale, 1)) scale(1.004, .994) skewX(.4deg); }
}
@keyframes actorPant {
  0%, 100% { transform: scale(var(--actor-scale, 1)) scale(1, 1); }
  40%      { transform: scale(var(--actor-scale, 1)) scale(1.012, .985) translateY(.4%); }
  60%      { transform: scale(var(--actor-scale, 1)) scale(.996, 1.01); }
}
@keyframes actorBreathHeavy {
  0%, 100% { transform: scale(var(--actor-scale, 1)) scale(1, 1) rotate(0deg); }
  40%      { transform: scale(var(--actor-scale, 1)) scale(.99, 1.024) rotate(-.35deg); }
  75%      { transform: scale(var(--actor-scale, 1)) scale(1.006, .992) rotate(.25deg); }
}
@keyframes actorDazed {
  0%, 100% { transform: scale(var(--actor-scale, 1)) rotate(-1.4deg); }
  50%      { transform: scale(var(--actor-scale, 1)) rotate(1.4deg) translateY(.6%); }
}

/* ---- attack: rear back (anticipation) → strike toward the hero → overshoot → settle.
   The strike peak (~38%) meets the slash VFX contact in battle-view.enemyAct. */
#game .enemy.lunge { animation: none; }
#game .enemy.lunge .portrait img { animation: actorAttack .56s cubic-bezier(.3, 0, .2, 1), actorBreath 3.8s ease-in-out infinite .56s; }
#game .enemy.boss.lunge .portrait img,
#game .enemy.miniboss.lunge .portrait img { animation: actorAttackHeavy .68s cubic-bezier(.3, 0, .2, 1), actorBreathHeavy 5.2s ease-in-out infinite .68s; }
@keyframes actorAttack {
  0%   { transform: scale(var(--actor-scale, 1)); }
  30%  { transform: scale(var(--actor-scale, 1)) translateY(-4%) rotate(-3deg) scale(.96, 1.05); filter: brightness(1.08); }
  40%  { transform: scale(var(--actor-scale, 1)) translateY(8%) rotate(2deg) scale(1.12, .93); filter: brightness(1.3); }
  58%  { transform: scale(var(--actor-scale, 1)) translateY(5%) rotate(1deg) scale(1.06, .97); }
  78%  { transform: scale(var(--actor-scale, 1)) translateY(-1%) scale(.99, 1.015); }
  100% { transform: scale(var(--actor-scale, 1)); }
}
@keyframes actorAttackHeavy {
  0%   { transform: scale(var(--actor-scale, 1)); }
  34%  { transform: scale(var(--actor-scale, 1)) translateY(-3%) rotate(-2deg) scale(.97, 1.04); filter: brightness(1.12); }
  44%  { transform: scale(var(--actor-scale, 1)) translateY(5%) rotate(1.5deg) scale(1.07, .95); filter: brightness(1.35); }
  64%  { transform: scale(var(--actor-scale, 1)) translateY(3%) scale(1.03, .98); }
  100% { transform: scale(var(--actor-scale, 1)); }
}

/* ---- hit: knocked back away from the board, white-hot flash, squash on recovery. HUD stays still. */
#game .enemy.hit { animation: none; }
#game .enemy.hit .portrait img,
#game .enemy.lit-hit.hit .portrait img { animation: actorRecoil .42s cubic-bezier(.2, .7, .3, 1), actorFlash .32s ease-out, actorBreath 3.8s ease-in-out infinite .42s; }
#game .enemy.boss.hit .portrait img,
#game .enemy.miniboss.hit .portrait img { animation: actorRecoilHeavy .42s cubic-bezier(.2, .7, .3, 1), actorFlash .32s ease-out, actorBreathHeavy 5.2s ease-in-out infinite .42s; }
#game .enemy.stunned.hit .portrait img { animation: actorRecoil .42s cubic-bezier(.2, .7, .3, 1), actorFlash .32s ease-out, actorDazed 2.4s ease-in-out infinite .42s; }
@keyframes actorRecoil {
  0%   { transform: scale(var(--actor-scale, 1)); }
  16%  { transform: scale(var(--actor-scale, 1)) translateY(-4%) rotate(-3deg) scale(.95, 1.04); }
  45%  { transform: scale(var(--actor-scale, 1)) translateY(1%) rotate(1deg) scale(1.04, .96); }
  72%  { transform: scale(var(--actor-scale, 1)) scale(.99, 1.01); }
  100% { transform: scale(var(--actor-scale, 1)); }
}
@keyframes actorRecoilHeavy {
  0%   { transform: scale(var(--actor-scale, 1)); }
  18%  { transform: scale(var(--actor-scale, 1)) translateY(-1.6%) rotate(-1.2deg) scale(.98, 1.015); }
  50%  { transform: scale(var(--actor-scale, 1)) translateY(.5%) scale(1.015, .985); }
  100% { transform: scale(var(--actor-scale, 1)); }
}
/* Only the first frame is set: the flash eases back into each kind's own drop-shadow filter. */
@keyframes actorFlash { 0% { filter: brightness(2.3) saturate(.35) drop-shadow(0 0 8px #ffd7a8); } }

/* ---- death: flare, stagger back, sink and burn away (embers come from ActorFX.dissolve). */
#game .enemy.dead { opacity: 1; transform: none; pointer-events: none; }
#game .enemy.dead .portrait img { animation: actorDeath .9s cubic-bezier(.4, 0, .7, 1) forwards !important; }
#game .enemy.dead .enemy-hud,
#game .enemy.dead .intent { opacity: 0; transition: opacity .2s; }
#game .enemy.dead { visibility: hidden; transition: visibility 0s .95s; }
@keyframes actorDeath {
  0%   { transform: scale(var(--actor-scale, 1)); filter: brightness(2.6) saturate(.3); opacity: 1; }
  22%  { transform: scale(var(--actor-scale, 1)) translateY(-2%) rotate(-4deg); filter: brightness(1.4) sepia(.4); opacity: 1; }
  100% { transform: scale(var(--actor-scale, 1)) translateY(6%) rotate(7deg) scale(.92, .86); filter: brightness(.35) sepia(1) blur(1.5px); opacity: 0; }
}

/* ---- ground under elites/bosses: a soft light pool only; the old expanding outline rings are retired. */
#game .enemy .ground-aura { border: 0; box-shadow: none; animation: none; background: radial-gradient(ellipse, var(--aura) 0%, transparent 68%); opacity: calc(var(--strength) * .55); }
#game .enemy .ground-aura i, #game .enemy .ground-aura::after { display: none; }

/* ---- persistent auras (js/aura-fx.js): back canvas under the sprite, embers above it. */
#game .enemy .portrait .aura-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
#game .enemy .portrait .aura-back { z-index: 0; }
#game .enemy .portrait img { z-index: 1; }
#game .enemy .portrait .aura-front { z-index: 2; mix-blend-mode: screen; }
/* Charging: the figure itself heats up, pulsing toward the release. */
#game .enemy.charging .portrait img { filter: drop-shadow(0 0 6px #ff5a2acc) drop-shadow(0 6px 4px #000a); }
#game .enemy.charging .intent { animation: intentAlarm 1.1s ease-in-out infinite; }
@keyframes intentAlarm { 50% { color: #ffd2a8; text-shadow: 0 0 8px #ff6a2a, 0 1px 3px #000; } }

/* ---- floating numbers: the forged icon family, same colour as the number. */
#game .float .ui-icon { width: 1em; height: 1em; vertical-align: -.14em; margin: 0 .12em; stroke-width: 2.2; filter: drop-shadow(0 1px 0 #000) drop-shadow(0 0 3px #000); }
#game .float.board-act { color: #d8c6ff; font-size: calc(var(--u) * 4.4); }
#game .float.stone-act { color: #e3d2b4; font-size: calc(var(--u) * 4.4); }
#game .b-player .bar.mana.drained { animation: manaDrained .6s ease-out; }
@keyframes manaDrained { 0% { filter: brightness(2) saturate(.4); } 40% { filter: brightness(.6); } 100% { filter: none; } }

@media (prefers-reduced-motion: reduce) {
  #game .enemy .portrait .aura-canvas { display: none; }
  #game .enemy.charging .intent, #game .b-player .bar.mana.drained { animation: none !important; }
  #game .enemy .portrait img,
  #game .enemy.lunge .portrait img,
  #game .enemy.hit .portrait img,
  #game .enemy.stunned .portrait img { animation: none !important; transform: scale(var(--actor-scale, 1)); }
  #game .enemy.dead .portrait img { animation: none !important; opacity: 0; }
  #game .enemy.dead { transition: none; }
}

/* ---- Camp guide (js/camp-guide.js): above the modal, same forged coach look as battle. */
#game .coach-layer.camp-coach { z-index: 60; }
#game .camp-coach .coach-step { display: block; margin-bottom: .2em; font: 600 max(10px, calc(var(--u) * 2.2))/1 var(--font-ui); letter-spacing: .14em; color: #e9c77e; }
#game .camp-coach .coach-skip { position: absolute; right: calc(var(--u) * 3); bottom: calc(var(--u) * 3); pointer-events: auto; background: none; border: 0; color: #cdbf9f; font: 600 max(12px, calc(var(--u) * 2.8)) var(--font-ui); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
#game .camp-panel { position: relative; }
#game .camp-panel .camp-help { position: absolute; top: calc(var(--u) * 4.2); right: calc(var(--u) * 15); width: calc(var(--u) * 7.5); height: calc(var(--u) * 7.5); min-width: 30px; min-height: 30px; border-radius: 50%; border: 1px solid #b89a5c; background: #0c1413; color: #f0d79b; font: 700 max(14px, calc(var(--u) * 3.6))/1 var(--font-title); cursor: pointer; }
#game .camp-panel section > h3 { margin-top: calc(var(--u) * 4); }
/* Map: Camp has something worth doing (affordable upgrade or an unequipped relic). */
#game .icon-btn.has-notice { position: relative; }
#game .icon-btn.has-notice::after { content: ''; position: absolute; top: 3px; right: 3px; width: 9px; height: 9px; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #ffe7a6, #e0952e 60%, #8a4d10); box-shadow: 0 0 6px #ffb54a, 0 0 0 1.5px #1a120a; animation: noticePulse 2.4s ease-in-out infinite; }
@keyframes noticePulse { 50% { box-shadow: 0 0 12px #ffcf6a, 0 0 0 1.5px #1a120a; } }
@media (prefers-reduced-motion: reduce) { #game .icon-btn.has-notice::after { animation: none; } }

/* ---- impact feel: hit-stop holds every CSS animation; camera kick after it. */
#game.hitstop *, #game.hitstop *::before, #game.hitstop *::after { animation-play-state: paused !important; }
#screen-battle.camera-kick, #fx-layer.camera-kick { animation: cameraKick .32s cubic-bezier(.2, .8, .3, 1); }
@keyframes cameraKick { 0% { translate: var(--kick-x, 0) var(--kick-y, 0); } 35% { translate: calc(var(--kick-x, 0) * -.35) calc(var(--kick-y, 0) * -.35); } 100% { translate: 0 0; } }

/* ---- lightning lights the scene: flicker pool at the strike + sky flash + lit actors. */
#screen-battle > .scene-light { position: absolute; inset: 0; z-index: 6; pointer-events: none; opacity: 0; mix-blend-mode: screen;
  background: radial-gradient(circle at var(--lx) var(--ly), var(--light) 0, color-mix(in srgb, var(--light) 45%, transparent) 14%, transparent 52%),
              linear-gradient(180deg, color-mix(in srgb, var(--light) 28%, transparent), transparent 55%); }
#screen-battle > .scene-light.flicker { animation: lightningFlicker .52s linear; }
@keyframes lightningFlicker { 0% { opacity: calc(var(--power) * .95); } 9% { opacity: calc(var(--power) * .2); } 17% { opacity: calc(var(--power) * .85); } 30% { opacity: calc(var(--power) * .3); } 42% { opacity: calc(var(--power) * .5); } 100% { opacity: 0; } }
#screen-battle .battle-art.sky-flash { animation: skyFlash .52s linear; }
@keyframes skyFlash { 0% { filter: brightness(2.1) contrast(1.15) saturate(.6); } 10% { filter: brightness(1.1); } 18% { filter: brightness(1.8) contrast(1.1) saturate(.7); } 45% { filter: brightness(1.15); } 100% { filter: none; } }
#game .enemy .portrait.storm-lit { animation: stormLit .52s linear; }
@keyframes stormLit { 0% { filter: brightness(2) saturate(.55); } 10% { filter: brightness(1.1); } 18% { filter: brightness(1.7) saturate(.7); } 100% { filter: none; } }
@media (prefers-reduced-motion: reduce) {
  #screen-battle.camera-kick, #fx-layer.camera-kick, #screen-battle > .scene-light.flicker, #screen-battle .battle-art.sky-flash, #game .enemy .portrait.storm-lit { animation: none !important; }
}

/* ---- frame-by-frame actor animations (js/actor-anim.js): the idle PNG hides while frames play. */
#game .enemy .portrait .actor-flip { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }
#game .enemy.flip-playing .portrait img { visibility: hidden; }

/* ---- painted reward icons (G.art): XP, coin, stars. Same box as the line glyphs, a little larger to read as objects. */
#game img.ui-art { object-fit: contain; fill: none; stroke: none; filter: drop-shadow(0 1px 2px #000a); }
#game .ui-art-xp, #game .ui-art-coin { transform: scale(1.18); } /* same round medallion family, same scale */
#game .ui-art-star { filter: drop-shadow(0 0 4px #f5c35e88) drop-shadow(0 1px 2px #000a); }
#game .ui-art-starEmpty { opacity: .9; }

/* ---- boss sky bolt under the HUD (BattleView.boltBehindHud): above the sprite and aura, below the HP bar. */

/* ---- combo bolt: in front of the sprite and aura, under the enemy HUD (z 3). */
#game .enemy > .bolt-layer { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; mix-blend-mode: screen; }
/* ---- charging surge: the silhouette heats red and throbs twice. */
#game .enemy.charge-surge .portrait img { animation: chargeSurge 1.3s ease-in-out; }
@keyframes chargeSurge { 0%, 100% { filter: drop-shadow(0 0 0 #ff4a1a00); } 25%, 70% { filter: brightness(1.12) drop-shadow(0 0 7px #ff5a24) drop-shadow(0 0 16px #ff3a1088); } 48% { filter: brightness(1.04) drop-shadow(0 0 4px #ff5a24aa); } }
@media (prefers-reduced-motion: reduce) { #game .enemy.charge-surge .portrait img { animation: none !important; } }
