/* 3D battle scene (js/85-world.js, built from src/world/). Active when <html> has .has-world;
   without WebGL the class is never added and the SVG/CSS scene above stays as the fallback. */

/* the canvas fills the whole window behind the 1600×900 stage */
.world-canvas { position: absolute; left: 0; top: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.has-world .stage-wrap { background: #070912; }
.has-world .stage { background: transparent; }
.world-dom { position: absolute; inset: 0; transform-origin: 0 0; pointer-events: none; }
.world-dom > * { pointer-events: auto; }
.world-dom > .bullets, .world-dom > .fx { pointer-events: none; }

/* old 2D scene: replaced by the 3D world */
.has-world .bg, .has-world .timestop, .has-world .slowmo { display: none; }
.has-world .actor svg, .has-world .actor .shadow { visibility: hidden; }
.has-world .actor { transition: none; }
.has-world .stage.is-knockback #enemy { transition: none; }
.has-world .slash, .has-world .hitring, .has-world .guard, .has-world .windup, .has-world .kb-lines, .has-world .boltfly { display: none; }
.has-world .actor .tag { color: rgba(200,208,230,.55); text-shadow: 0 1px 2px #000; }

/* bullets: the 3D slug replaces the CSS one; the label (.n) stays and rides on the slug */
.has-world .air { top: 445px; transition: opacity .3s; }
.has-world .stage.is-hit .air, .has-world .air.flying { transition: opacity .3s; }
.has-world .air .slug, .has-world .air .trail { display: none; }
.has-world .air .n { text-shadow: 0 1px 0 #000, 0 0 8px rgba(0,0,0,.9); }

/* damage numbers: heavier, inked, with a snap-in overshoot */
.has-world .dmg { -webkit-text-stroke: 1.5px rgba(8,6,12,.95); paint-order: stroke fill; text-shadow: 0 3px 0 #000, 0 0 22px rgba(230,176,75,.55); }
.has-world .dmg.pop { animation: pop3d 1.1s cubic-bezier(.2,.9,.3,1) forwards; }
@keyframes pop3d {
  0% { opacity: 0; transform: translateY(14px) scale(.4) rotate(-8deg); }
  9% { opacity: 1; transform: translateY(-4px) scale(1.35) rotate(3deg); }
  20% { transform: translateY(0) scale(1) rotate(0deg); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-50px) scale(.92); }
}
.has-world .dmg.block { font-style: italic; letter-spacing: .04em; text-shadow: 0 3px 0 #000, 0 0 26px rgba(95,227,255,.85); }
.has-world .dmg.hurt { text-shadow: 0 3px 0 #000, 0 0 24px rgba(229,72,77,.75); }
/* parry and hit numbers sit above her plate, clear of her face and the blade; they leave sooner */
.has-world .dmg.block { margin-top: -165px; }
.has-world .dmg.hurt { margin-top: -150px; }
.has-world .dmg.pop.block, .has-world .dmg.pop.hurt { animation-duration: .75s; }

/* the 2D time-stop vignette is now a grade in the 3D post pass */
.has-world .stage.is-timestop .phase .main { text-shadow: 0 0 22px rgba(95,227,255,.55), 0 2px 0 #000; }

/* kill cam: after the last hit (or the player's fall) the result overlay waits a beat so the moment is seen */
.has-world .stage.kill-cam #overlay.show { animation: worldKillIn .35s .75s both; }
.has-world .stage.kill-cam.kill-lose #overlay.show { animation-delay: 1.05s; }
/* her victory pose raises the gun through the plate above her head: the plate steps aside */
.has-world #player .phud { transition: opacity .2s; }
.has-world .stage.kill-cam:not(.kill-lose) #player .phud { opacity: 0; }
@keyframes worldKillIn { from { opacity: 0; visibility: hidden; } to { opacity: 1; visibility: visible; } }
