/* COMBAT-MOTION-001. Source Default262:2230 -> Variant2 262:2268.
   Whole original gold/black knife, rather than enlarged turn icon art.
   The stage fills the existing primary battlefield without adding a strip.
   It is an authored viewport adaptation of Figma's402x750 plane.
   Quick/Gentle numerical curves below are explicitly candidate substitutes;
   no measured prototype total time or extracted spring is claimed. */

.combat-exchange-stage {
  position: relative;
  flex: none;
  min-width: 0;
  min-height: calc(224px + var(--mori-head-room, 24px));
  height: calc(var(--mori-field-height, 300px) + var(--mori-head-room, 24px));
  overflow: hidden;
  isolation: isolate;
}

.combat-exchange-stage > .fighters { z-index: 0; }
.combat-exchange-stage > .zone-columns { z-index: 4; }

.combat-motion {
  --cm-quick: cubic-bezier(.16, 1, .3, 1);
  --cm-gentle: cubic-bezier(.4, 0, .2, 1);
  position: absolute;
  z-index: 2;
  inset: 0;
  min-width: 0;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  contain: layout paint;
  isolation: isolate;
}

.combat-motion__preload { display: none; }

.combat-motion__exit,
.combat-motion__plane,
.combat-motion__grain,
.combat-motion__figures,
.combat-motion__red-wash {
  position: absolute;
  inset: 0;
}

.combat-motion__exit {
  animation: cm-slide-left var(--cm-exit) var(--cm-gentle) var(--cm-exit-at) both;
  will-change: transform;
}

.combat-motion__plane {
  overflow: hidden;
  background: #0f0f0f;
  transform-origin: 50% 50%;
  animation: cm-dissolve var(--cm-entry) var(--cm-quick) both;
  will-change: transform, opacity;
}

.combat-motion__grain {
  background: url("assets/mori/combat/scene-background.png") 50% 28% / 100% auto no-repeat;
  opacity: .5;
}

.combat-motion__plane::after {
  position: absolute;
  z-index: 7;
  inset: 0;
  content: "";
  background: linear-gradient(0deg, rgb(15 15 15 / .62), transparent 24% 84%, rgb(15 15 15 / .48));
  pointer-events: none;
}

/* Same full-size figures and slots as the primary field. This layer replaces
   their visual surface during exchange; it is not another pair of miniatures.
   Blur stays here, leaving live HP, summary, controls and heading sharp. */
.combat-motion__figures {
  z-index: 1;
  top: auto;
  left: 16px;
  right: 16px;
  bottom: 0;
  height: 300px;
  display: grid;
  grid-template-columns: minmax(0, 135px) minmax(0, 135px);
  justify-content: space-between;
  opacity: .9;
  filter: blur(5px);
}

.combat-motion__figure {
  position: relative;
  width: 135px;
  height: 300px;
  transform: scale(var(--mori-figure-scale, 1));
  transform-origin: center bottom;
  justify-self: center;
}

.combat-motion__body { position: absolute; top: 0; height: auto; }
.combat-motion__figure--self .combat-motion__body { left: 14.84px; width: 109.389px; }
.combat-motion__figure--opponent .combat-motion__body { left: 1.5px; width: 132px; }

.combat-motion__goggles {
  position: absolute;
  left: 56.557532px;
  top: 13.9px;
  width: 28.996px;
  height: auto;
}

.combat-motion__horizon {
  position: absolute;
  z-index: 2;
  left: 7%;
  right: 7%;
  top: 61%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(211 154 22 / .28) 25% 75%, transparent);
  opacity: .6;
}

/* Source noise is near opaque: layer opacity is an authored rendering choice,
   rather than pretending source fill65% is the exported PNG alpha. */
.combat-motion__red-wash {
  z-index: 3;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 46%;
  opacity: 0;
  animation: cm-red-wash var(--cm-traverse) var(--cm-quick) var(--cm-action-at) both;
  will-change: opacity;
}

.combat-motion__red-wash[data-impact="false"] { display: none; }

/* The first152/368 of Default56 sits off the left edge. All five source tracks
   share uniform width-scaled coordinate units; Y is not squeezed to fit the
   shorter field. Rotation is a delta from already-baked native Default56. */
.combat-motion__blade-path {
  position: absolute;
  z-index: 5;
  left: -37.810945%;
  top: 53%;
  width: 91.542289%;
  aspect-ratio: 368 / 108;
  transform: translate3d(var(--cm-start-x), var(--cm-start-y), 0) rotate(var(--cm-start-angle));
  transform-origin: 50% 50%;
  animation: cm-knife-traverse var(--cm-traverse) var(--cm-quick) var(--cm-action-at) both;
  will-change: transform;
}

.combat-motion__blade {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 2px 2px rgb(0 0 0 / .6)) drop-shadow(0 0 8px rgb(211 154 22 / .22));
}

.combat-motion__wake {
  position: absolute;
  left: -42%;
  top: 41%;
  width: 84%;
  height: 26%;
  background: linear-gradient(90deg, transparent, rgb(211 154 22 / .05) 20%, rgb(211 154 22 / .38) 85%, transparent);
  transform-origin: right center;
  opacity: 0;
  filter: blur(5px);
  animation: cm-gold-wake var(--cm-traverse) var(--cm-quick) var(--cm-action-at) both;
  will-change: opacity, transform;
}

.combat-motion__residual {
  position: absolute;
  z-index: 4;
  top: 45%;
  width: 38%;
  height: 37%;
  background-position: center;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  opacity: 0;
  filter: blur(4px);
  animation: cm-hp-residual var(--cm-traverse) var(--cm-gentle) var(--cm-action-at) both;
  will-change: transform, opacity;
}

.combat-motion__residual--self { left: 5%; background-image: url("assets/mori/combat/hp-left-red.png"); }
.combat-motion__residual--opponent { right: 5%; background-image: url("assets/mori/combat/hp-right-red.png"); }
.combat-motion__residual[data-loss="0"] { display: none; }

.combat-motion__damage {
  position: absolute;
  z-index: 8;
  top: 7%;
  width: 44%;
  color: #f2dcaa;
  font: 600 clamp(18px, 5.5vw, 25px) / 1.1 "Playfair Display", serif;
  font-variant-numeric: tabular-nums;
  letter-spacing: .015em;
  text-align: center;
  white-space: nowrap;
  text-shadow: 0 1px 1px #080808, 0 2px 8px #080808;
  opacity: 0;
  animation: cm-hp-float var(--cm-traverse) var(--cm-quick) var(--cm-action-at) both;
  will-change: opacity, transform;
}

.combat-motion__damage--self { left: 3%; color: #efd8bc; }
.combat-motion__damage--opponent { right: 3%; }
.combat-motion__damage[data-loss="0"] { color: #c9c4bb; }

@keyframes cm-dissolve {
  from { opacity: 0; transform: scale(.987); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes cm-knife-traverse {
  from { transform: translate3d(var(--cm-start-x), var(--cm-start-y), 0) rotate(var(--cm-start-angle)); }
  to { transform: translate3d(var(--cm-end-x), var(--cm-end-y), 0) rotate(var(--cm-end-angle)); }
}

@keyframes cm-red-wash {
  0% { opacity: 0; }
  42% { opacity: .84; }
  100% { opacity: .84; }
}

@keyframes cm-gold-wake {
  0% { opacity: 0; transform: scaleX(.58); }
  16% { opacity: .6; transform: scaleX(1); }
  58% { opacity: .23; transform: scaleX(1.18); }
  100% { opacity: 0; transform: scaleX(1.22); }
}

@keyframes cm-hp-residual {
  0% { opacity: 0; transform: translateY(3px); }
  22% { opacity: .34; transform: translateY(0); }
  66% { opacity: .12; transform: translateY(-3px); }
  100% { opacity: 0; transform: translateY(-5px); }
}

@keyframes cm-hp-float {
  0% { opacity: 0; transform: translateY(6px); }
  18% { opacity: 1; transform: translateY(0); }
  82%, 100% { opacity: 1; transform: translateY(-6px); }
}

@keyframes cm-slide-left {
  0% { transform: translate3d(0, 0, 0); }
  34% { transform: translate3d(-32%, 0, 0); }
  68% { transform: translate3d(-65%, 0, 0); }
  100% { transform: translate3d(-110%, 0, 0); }
}

@media (min-width: 720px) {
  .combat-motion__figures {
    left: 28px;
    right: 28px;
    grid-template-columns: minmax(0, 164px) minmax(0, 164px);
  }
  .combat-motion__damage { font-size: 25px; }
}

@media (max-height: 640px) {
  .combat-motion__damage { top: 5%; font-size: 19px; }
}

/* Immediate CSS fallback while the shared app motion gate catches up. No
   decorative fragment survives off/reduce, and no pause/resume is introduced. */
.combat-motion:not([data-motion="on"]) .combat-motion__exit { display: none; }

@media (prefers-reduced-motion: reduce) {
  .combat-motion__exit { display: none; }
}
