/* status_fx.css — sustained whole-screen status auras (IT33).
 * One full-viewport overlay holding a stacking layer per effect. Layers are
 * GPU-cheap (box-shadow / gradient / filter on transform+opacity), never
 * intercept input, and sit above the game pane but below modals. Nothing is
 * shown unless status_fx.js adds `.active` to a layer.
 *
 * Tier 1 (Phase 1): low_hp / healing / protected / berserk — derived front-end.
 * Tier 2 (Phase 2): burning / drowning / entangled / poisoned / stunned /
 *   crit_shock — backend status_fx list or combat_events. */

#status-fx-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;   /* never block clicks */
  z-index: 60;            /* above game pane, below dialogs/cinematic */
  overflow: hidden;
}

.fx-layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.3s ease;
  will-change: opacity;
}
.fx-layer.active { opacity: 1; }

/* ---------------- Tier 1 (derived front-end, Phase 1) ---------------- */

/* low_hp — red edge pulse (vignette). Urgency rises as a steady heartbeat. */
.fx-low_hp.active { animation: fxLowHp 1.05s ease-in-out infinite; }
@keyframes fxLowHp {
  0%, 100% { box-shadow: inset 0 0 110px 35px rgba(200, 20, 20, 0.14); }
  50%      { box-shadow: inset 0 0 160px 65px rgba(210, 25, 25, 0.52); }
}

/* healing — soft green inner glow, gentle breathe. */
.fx-healing.active { animation: fxHealing 2.2s ease-in-out infinite; }
@keyframes fxHealing {
  0%, 100% { box-shadow: inset 0 0 90px 30px rgba(60, 210, 110, 0.10); }
  50%      { box-shadow: inset 0 0 140px 55px rgba(70, 230, 130, 0.30); }
}

/* protected — steady cool-blue rim, very slow shimmer (defensive, calm). */
.fx-protected.active { animation: fxProtected 3.4s ease-in-out infinite; }
@keyframes fxProtected {
  0%, 100% { box-shadow: inset 0 0 70px 22px rgba(70, 150, 240, 0.16); }
  50%      { box-shadow: inset 0 0 95px 34px rgba(90, 170, 255, 0.28); }
}

/* berserk — hot red edge throb, faster + harder than low_hp (aggressive). */
.fx-berserk.active { animation: fxBerserk 0.7s ease-in-out infinite; }
@keyframes fxBerserk {
  0%, 100% { box-shadow: inset 0 0 80px 26px rgba(230, 40, 30, 0.16); }
  50%      { box-shadow: inset 0 0 120px 44px rgba(240, 60, 40, 0.40); }
}

/* ---------------- Tier 2 (backend status_fx / combat_events, Phase 2) ---- */

/* burning — rapid orange/red flicker vignette.
   steps(2, end) gives a harsh flicker-of-fire look. */
.fx-burning.active { animation: fxBurning 0.28s steps(2, end) infinite; }
@keyframes fxBurning {
  0%   { box-shadow: inset 0 0 120px 45px rgba(240, 110, 20, 0.34); }
  50%  { box-shadow: inset 0 0 150px 60px rgba(255, 140, 30, 0.48); }
  100% { box-shadow: inset 0 0 110px 40px rgba(230, 90, 15, 0.30); }
}

/* drowning — deep blue tint + closing vignette + slight blur/desaturation.
   Slow breath-hold pulse; transition:opacity already on .fx-layer. */
.fx-drowning.active {
  background: radial-gradient(ellipse at center,
              rgba(20, 70, 130, 0.12) 0%, rgba(10, 40, 90, 0.55) 100%);
  backdrop-filter: blur(1.5px) saturate(0.8);
  -webkit-backdrop-filter: blur(1.5px) saturate(0.8);
  animation: fxDrowning 4s ease-in-out infinite;
}
@keyframes fxDrowning {
  0%, 100% { opacity: 0.85; }
  50%      { opacity: 1; }
}

/* entangled — sickly green drip vignette (webbed / ooze-slowed). */
.fx-entangled.active {
  box-shadow: inset 0 -80px 90px -20px rgba(70, 150, 50, 0.40),
              inset 0 0 80px 30px rgba(60, 130, 45, 0.20);
}

/* poisoned — desaturated green tint with a slow sickly pulse. */
.fx-poisoned.active {
  background: radial-gradient(ellipse at center,
              rgba(50, 120, 30, 0.08) 0%, rgba(30, 80, 15, 0.40) 100%);
  animation: fxPoisoned 2.6s ease-in-out infinite;
}
@keyframes fxPoisoned {
  0%, 100% { opacity: 0.80; }
  50%      { opacity: 1; }
}

/* stunned — brief grey-white flash then a dim desaturating fog. */
.fx-stunned.active {
  background: rgba(200, 200, 220, 0.18);
  animation: fxStunned 0.8s ease-out forwards;
}
@keyframes fxStunned {
  0%   { background: rgba(230, 230, 240, 0.55); opacity: 1; }
  60%  { background: rgba(200, 200, 220, 0.22); opacity: 1; }
  100% { background: rgba(180, 180, 200, 0.14); opacity: 1; }
}

/* crit_shock — brief white-hot full-screen flash on a critical hit.
   One-shot: status_fx.js clears .active after CRIT_SHOCK_MS (500ms).
   fast-in / slow-fade: the hit lands instantly, the afterglow lingers. */
.fx-crit_shock { transition: opacity 0.05s ease-in; }
.fx-crit_shock.active {
  background: rgba(255, 255, 255, 0.55);
  animation: fxCritShock 0.5s ease-out forwards;
}
@keyframes fxCritShock {
  0%   { background: rgba(255, 255, 240, 0.70); opacity: 1; }
  25%  { background: rgba(255, 240, 200, 0.45); opacity: 1; }
  100% { background: rgba(255, 220, 180, 0.00); opacity: 0; }
}

/* Accessibility: drop ALL motion to a static tint.
   crit_shock fades in 0.3s instead of flashing. */
@media (prefers-reduced-motion: reduce) {
  .fx-layer { animation: none !important; transition: opacity 0.3s ease; }
  .fx-low_hp.active    { box-shadow: inset 0 0 140px 55px rgba(205, 25, 25, 0.34); }
  .fx-healing.active   { box-shadow: inset 0 0 120px 45px rgba(70, 220, 125, 0.22); }
  .fx-protected.active { box-shadow: inset 0 0 85px 30px rgba(85, 165, 250, 0.24); }
  .fx-berserk.active   { box-shadow: inset 0 0 110px 40px rgba(235, 55, 40, 0.30); }
  .fx-burning.active   { box-shadow: inset 0 0 140px 55px rgba(245, 125, 25, 0.40); }
  .fx-drowning.active  { backdrop-filter: blur(1px) saturate(0.75); }
  .fx-poisoned.active  { background: rgba(50, 120, 30, 0.22); }
  .fx-stunned.active   { background: rgba(200, 200, 220, 0.20); }
  .fx-crit_shock.active { background: rgba(255, 250, 220, 0.30); }
}
