/* styles/vitality.css
   The Vitality HUD — persistent payment-as-character readout.
   Lives top-right (mirrored opposite to wayfinding overlay).
   Hidden by default; revealVitality() adds .revealed when the
   amount tile lands in its Foundry slot.

   Diegetic over chrome: small, mono, ledger-like. Not WoW. */

#vitality-hud {
  position: fixed;
  /* Moved down + right-anchored. The original top:4vh collided with
     the Foundry timer at top:3vh, right:4vw. Now sits BELOW the
     Foundry timer with a wider horizontal clearance — works for
     Foundry and stays out of the wayfinding-overlay zone in every
     other biome (wayfinding lives top-left at top:3vh). */
  top: 13vh;
  right: 1.5vw;
  z-index: var(--z-hud);
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Narrower than before — dropped the "Payment Vitality" chrome
     eyebrow + tightened layout, so the HUD takes ~13rem instead of
     the previous 16.25rem. Cap at 22vw for narrow viewports. */
  width: min(13rem, 22vw);
  padding: 8px 12px 10px 12px;
  background: rgba(10, 14, 22, 0.78);
  border: 1px solid rgba(184, 224, 255, 0.22);
  border-radius: 2px;
  font-family: var(--mono);
  pointer-events: none;          /* never eats clicks */
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 1200ms ease, transform 1200ms ease;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
}
#vitality-hud.revealed {
  opacity: 1;
  transform: translateY(0);
}

/* Inherit scaffold + beat-mode fades from the wayfinding system so the
   HUD breathes in concert with the rest of the orientation chrome. */
body[data-scaffold-level="0"] #vitality-hud.revealed { opacity: 0.55; }
body[data-scaffold-level="1"] #vitality-hud.revealed { opacity: 0.75; }
body[data-scaffold-level="2"] #vitality-hud.revealed { opacity: 0.95; }
body[data-scaffold-level="3"] #vitality-hud.revealed { opacity: 1;    }
body.beat-prose #vitality-hud.revealed { opacity: 0.4; }

/* Hide the HUD entirely while the player is placing tiles in the
   Foundry — the HUD's top-right zone competes with the data-tile row
   at narrow viewports. 02_gateway.js toggles body.foundry-placing on
   placement start; removes it on resolution (success or timeout). */
body.foundry-placing #vitality-hud {
  opacity: 0 !important;
  pointer-events: none;
}

/* Stakes label — the "what am I playing for" scenario name now serves
   as the HUD's top row (the old "Payment Vitality" chrome eyebrow was
   dropped to save vertical space and clear the Foundry timer). Mono
   caps, warm-amber, fits in one line. */
.vh-stakes {
  font-family: var(--mono);
  font-size: 0.55rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 200, 120, 0.82);
  /* Truncate gracefully if a long scenario name overflows. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vh-stakes[hidden] { display: none; }

/* Row: mini-card + numeric values */
.vh-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Mini-card glyph — extends .payment-card from base.css so it gets all
   the damage-condition variants for free. Sized down + position reset. */
.vh-card {
  width: 28px;
  height: 18px;
  flex: 0 0 28px;
  border-width: 1px;
  border-radius: 2px;
}
/* The scratch + corner-notch pseudo elements scale with the smaller card. */

.vh-values {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.vh-current {
  /* Slightly tightened (0.95 → 0.88rem) for the compact HUD frame. */
  font-size: 0.88rem;
  letter-spacing: 0.05em;
  color: rgba(255, 200, 160, 0.95);
  text-shadow: 0 0 12px rgba(255, 144, 80, 0.35);
  transition: color 600ms ease, text-shadow 600ms ease;
}
.vh-of {
  font-size: 0.58rem;
  letter-spacing: 0.22em;
  /* Contrast lifted to 0.78 alpha — yields ~6.3:1 on the HUD's
     rgba(10,14,22,0.78) background, exceeding WCAG AA's 4.5:1 floor
     for normal text. Earlier 0.5 alpha rendered at ~4.0:1 (fail). */
  color: rgba(190, 210, 220, 0.78);
  text-transform: uppercase;
}

/* Bar — transform: scaleX (GPU composited, not width). */
.vh-bar {
  position: relative;
  height: 3px;
  background: rgba(184, 224, 255, 0.12);
  border-radius: 2px;
  overflow: hidden;
}
.vh-bar-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(184, 224, 255, 0.85) 0%,
    rgba(184, 224, 255, 0.95) 100%);
  transform-origin: left center;
  transform: scaleX(1);
  transition: transform 600ms cubic-bezier(0.4, 0, 0.2, 1),
              background 600ms ease;
  box-shadow: 0 0 10px rgba(184, 224, 255, 0.4);
}

/* Color thresholds — the bar warms then turns urgent. */
#vitality-hud.health-mid .vh-bar-fill {
  background: linear-gradient(90deg,
    rgba(255, 200, 120, 0.85) 0%,
    rgba(255, 168, 100, 0.95) 100%);
  box-shadow: 0 0 12px rgba(255, 168, 100, 0.5);
}
#vitality-hud.health-mid .vh-current {
  color: rgba(255, 220, 168, 0.95);
}
#vitality-hud.health-low .vh-bar-fill {
  background: linear-gradient(90deg,
    rgba(255, 130, 90, 0.95) 0%,
    rgba(255, 72, 68, 1) 100%);
  box-shadow: 0 0 14px rgba(255, 72, 68, 0.6);
}
#vitality-hud.health-low .vh-current {
  color: rgba(255, 180, 160, 1);
  text-shadow: 0 0 14px rgba(255, 80, 60, 0.5);
}

/* Damage shake — tiny translateY jitter, not screen-shake. */
@keyframes vh-shake-small {
  0%, 100% { transform: translateY(0); }
  25%      { transform: translateY(-1px); }
  60%      { transform: translateY(1px); }
}
@keyframes vh-shake-critical {
  0%, 100% { transform: translateY(0) translateX(0); }
  10%      { transform: translateY(-2px) translateX(-1px); }
  30%      { transform: translateY(1px)  translateX(2px); }
  55%      { transform: translateY(-1px) translateX(-2px); }
  80%      { transform: translateY(2px)  translateX(1px); }
}
#vitality-hud.shake-small.revealed     { animation: vh-shake-small    240ms ease-in-out 1; }
#vitality-hud.shake-critical.revealed  { animation: vh-shake-critical 320ms ease-in-out 1; }

/* Brief flicker on critical hit — the protagonist's presence wobbles. */
#vitality-hud.shake-critical .vh-card {
  animation: vh-card-flicker 320ms steps(3, jump-none) 1;
}
@keyframes vh-card-flicker {
  0%, 100% { opacity: 1; }
  20%      { opacity: 0.4; }
  60%      { opacity: 0.7; }
}

/* Ledger row — Trust + Friction badges. Hidden until first run completes
   (revealLedger() un-hides). Tiny mono pair, warm gold, subordinate to
   €value + bar. Updates pulse softly on change. */
.vh-ledger {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 0.5rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(200, 152, 88, 0.70);
}
.vh-ledger[hidden] { display: none; }
.vh-trust    { color: rgba(184, 224, 255, 0.78); }
.vh-friction { color: rgba(255, 168, 100, 0.78); }
.vh-trust b, .vh-friction b {
  font-weight: 700;
  color: rgba(255, 244, 208, 0.95);
  margin-left: 4px;
  letter-spacing: 0.04em;
  font-size: 0.62rem;
}
@keyframes vh-ledger-pulse {
  0%   { transform: translateY(0); opacity: 0.7; }
  40%  { transform: translateY(-1px); opacity: 1; }
  100% { transform: translateY(0); opacity: 1; }
}
.vh-ledger.vh-pulse { animation: vh-ledger-pulse 600ms ease-out 1; }
@media (prefers-reduced-motion: reduce) {
  .vh-ledger.vh-pulse { animation: none; }
}

/* Fee-fall flash — a "−€1.10" hovers below the HUD then drifts down. */
.vh-flash-host {
  position: absolute;
  left: 14px;
  right: 14px;
  top: 100%;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.vh-fee-flash {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  font-family: var(--mono);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  color: rgba(255, 130, 90, 0.95);
  text-shadow: 0 0 12px rgba(255, 130, 90, 0.6);
  animation: vh-fee-fall 1800ms ease-out forwards;
}
/* Critical severity — bigger, brighter, with a tiny shake on entry.
   Per the damage-number pattern spec for "critical hit" feedback. */
.vh-fee-flash.critical {
  font-size: 1.15rem;
  color: rgba(255, 180, 160, 1);
  text-shadow:
    0 0 16px rgba(255, 80, 60, 0.9),
    0 0 4px  rgba(255, 130, 90, 0.7);
  animation:
    vh-fee-fall 1800ms ease-out forwards,
    vh-fee-shake 220ms ease-in-out 1;
  letter-spacing: 0.12em;
}
.vh-fee-flash.critical .vh-fee-source {
  color: rgba(255, 200, 180, 0.85);
  letter-spacing: 0.38em;
  font-size: 0.6rem;
}
@keyframes vh-fee-shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-2px); }
  60%      { transform: translateX(2px); }
}
.vh-fee-source {
  font-size: 0.5rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(255, 168, 100, 0.55);
  margin-top: 1px;
}
@keyframes vh-fee-fall {
  0%   { opacity: 0; transform: translateY(-6px); }
  18%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(28px); }
}

/* ---------------------------------------------------------------------
   WAITING-ROOM AGING MIRROR
   While the player decides at the Waiting Room, money does NOT leave
   (so vitality.deductValue is not called), but the in-scene card ages.
   Mirror that aging onto the HUD's mini-card so the two breathe in
   concert. ID-prefixed selector outranks the .payment-card damage
   filters from base.css, which is correct: the Waiting context is the
   "loudest" visual signal here.
--------------------------------------------------------------------- */

body[data-waiting-aged="1"] #vitality-hud .vh-card {
  filter: saturate(0.7) brightness(0.95);
}
body[data-waiting-aged="2"] #vitality-hud .vh-card {
  filter: saturate(0.4) brightness(0.85);
}
body[data-waiting-aged="3"] #vitality-hud .vh-card {
  filter: saturate(0.2) brightness(0.75);
}

/* ---------------------------------------------------------------------
   DIEGETIC HUD — payment-condition mirrors the HUD chrome (C10)
   ---------------------------------------------------------------------
   The Intent's wear (pristine → scuffed → worn → battered) already
   affects .payment-card visuals via base.css. Extend the cue to the
   HUD's value text + bar fill so the chrome breathes with the
   protagonist. Pristine stays bright; battered reads as visibly tired.
   Smooth transition so condition shifts don't snap. */
#vitality-hud .vh-bar-fill,
#vitality-hud .vh-current,
#vitality-hud .vh-of {
  transition: filter 1200ms ease, color 600ms ease, text-shadow 600ms ease;
}
body[data-payment-condition="scuffed"]  #vitality-hud .vh-bar-fill,
body[data-payment-condition="scuffed"]  #vitality-hud .vh-current,
body[data-payment-condition="scuffed"]  #vitality-hud .vh-of {
  filter: saturate(0.88) brightness(0.96);
}
body[data-payment-condition="worn"]     #vitality-hud .vh-bar-fill,
body[data-payment-condition="worn"]     #vitality-hud .vh-current,
body[data-payment-condition="worn"]     #vitality-hud .vh-of {
  filter: saturate(0.65) brightness(0.90);
}
body[data-payment-condition="battered"] #vitality-hud .vh-bar-fill,
body[data-payment-condition="battered"] #vitality-hud .vh-current,
body[data-payment-condition="battered"] #vitality-hud .vh-of {
  filter: saturate(0.40) brightness(0.78);
}

@media (prefers-reduced-motion: reduce) {
  #vitality-hud .vh-bar-fill,
  #vitality-hud .vh-current,
  #vitality-hud .vh-of { transition-duration: 200ms; }
}

/* ---------------------------------------------------------------------
   MICROPARTICLE EXFILTRATION
   Tiny dust motes that drift FROM the card TOWARD the fee collector.
   Body-attached so they can travel across the whole viewport. CSS vars
   --dx / --dy carry per-spark direction.
--------------------------------------------------------------------- */

.payment-spark {
  position: fixed;
  z-index: 31;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 200, 160, 0.85);
  box-shadow: 0 0 6px rgba(255, 144, 80, 0.7);
  pointer-events: none;
  animation: payment-spark-drift 1400ms cubic-bezier(0.4, 0, 0.6, 1) forwards;
  --dx: 0px;
  --dy: -40px;
}
@keyframes payment-spark-drift {
  0%   { opacity: 0;    transform: translate(0, 0)              scale(0.6); }
  20%  { opacity: 0.85; }
  60%  { opacity: 0.6;  }
  100% { opacity: 0;    transform: translate(var(--dx), var(--dy)) scale(0.2); }
}

/* ---------------------------------------------------------------------
   REDUCED MOTION
   Shorten + simplify all transitions/animations. Skip sparks entirely
   (the JS already skips emitting them when reducedMotion is true).
--------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  #vitality-hud         { transition-duration: 300ms; }
  .vh-bar-fill          { transition-duration: 200ms; }
  .vh-fee-flash         { animation-duration: 700ms; }
  #vitality-hud.shake-small.revealed,
  #vitality-hud.shake-critical.revealed { animation: none; }
  #vitality-hud.shake-critical .vh-card { animation: none; }
  .vh-fee-flash.critical { animation: vh-fee-fall 700ms ease-out forwards; }
  .payment-spark        { animation-duration: 500ms; }
}
