/* ══════════════════════════════════════════════════════════════════════════
   IRONBOUND — FX LAYER STYLESHEET
   ──────────────────────────────────────────────────────────────────────────
   Reusable visual-effect components + design tokens for the new game-feel
   layer. Loaded IN ADDITION to /ironbound.css (does not replace it).

   This file is intentionally additive and progressive-enhancement only:
   nothing here is required for the page to function. If the FX JavaScript
   (PixiJS / GSAP) fails to load, these styles still render a static,
   on-brand fallback.

   WHERE USED:
     - ParticleBackground container ............ .fx-bg            (landing + game ambient bg)
     - GlowButton (ember signature CTA) ........ .fx-glow-btn      (primary actions)
     - AnimatedPanel (forged-iron card) ........ .fx-panel         (idle card, info panels)
     - HeroCard ................................ .fx-hero-card     (summon results, future roster)
     - SummonReveal (full-screen reveal) ....... .fx-summon-*      (gacha pull reveal)

   DESIGN BIBLE ALIGNMENT (ratified v1.1):
     ember #E8650A = SIGNATURE, action only (CTAs / active / legendary)
     gold  #D4AF37 = information / structure
     panels are forged iron, NOT glass.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Ember signature (NEW — was missing from the codebase) ── */
  --ember:        #E8650A;
  --ember-bright: #FF8A3D;
  --ember-deep:   #B84A06;
  --ember-glow:   rgba(232,101,10,0.55);
  --ember-glow-soft: rgba(232,101,10,0.18);

  /* ── Faction colors (authoritative — mirror game.js FACTIONS) ── */
  --f-light:   #D4AF37;
  --f-shadow:  #9040D0;
  --f-forest:  #4AAA4A;
  --f-undead:  #6080C0;
  --f-inferno: #D04020;
  --f-void:    #406080;

  /* ── Rarity (Design Bible) ── */
  --r-common:    #909090;
  --r-rare:      #4488FF;
  --r-epic:      #B43CF0;
  --r-legendary: var(--ember);
}

/* ══════════════════════════════════════════════════════════════════════════
   PARTICLE BACKGROUND CONTAINER
   The PixiJS canvas is injected INTO this element by particle-background.js.
   It is a fixed, full-viewport layer that sits BEHIND all page content.
   If Pixi is unavailable, the soft ember-vignette below is the fallback.
   ══════════════════════════════════════════════════════════════════════════ */
.fx-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  /* Fallback ambience when PixiJS does not load: a low ember bloom at the
     bottom (where embers would rise from) so the page never looks flat. */
  background:
    radial-gradient(ellipse 70% 45% at 50% 108%, var(--ember-glow-soft) 0%, transparent 60%),
    radial-gradient(ellipse 90% 80% at 50% 0%, rgba(10,7,18,0.0) 40%, var(--void, #05030A) 100%);
}
.fx-bg canvas { display: block; }

/* ══════════════════════════════════════════════════════════════════════════
   GLOW BUTTON — ember signature CTA (forged plate that wants to ignite)
   Markup:  <a class="fx-glow-btn" data-fx="glow-button">Fight</a>
   The magnetic motion + spring is added by ui-animations.glowButton();
   the visual identity (plate, ember glow, shimmer) lives here so it looks
   correct even without JS.
   ══════════════════════════════════════════════════════════════════════════ */
.fx-glow-btn {
  --gb-glow: var(--ember-glow);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  padding: 0.95em 2.4em;
  border-radius: 3px;
  font-family: 'Cinzel', serif;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  color: #1a0a00;
  /* Molten ember plate */
  background: linear-gradient(180deg, var(--ember-bright) 0%, var(--ember) 45%, var(--ember-deep) 100%);
  border: 1px solid #7a3404;
  box-shadow:
    0 0 22px var(--ember-glow-soft),
    0 4px 16px rgba(0,0,0,0.6),
    inset 0 1px 0 rgba(255,220,180,0.35);
  transition: filter 0.16s ease, box-shadow 0.25s ease, transform 0.12s ease;
  will-change: transform;
  -webkit-tap-highlight-color: transparent;
}
/* Light sweep across the plate on hover */
.fx-glow-btn::after {
  content: '';
  position: absolute;
  top: 0; left: -120%;
  width: 55%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,240,210,0.45), transparent);
  transform: skewX(-20deg);
  pointer-events: none;
}
.fx-glow-btn:hover {
  filter: brightness(1.12);
  box-shadow:
    0 0 42px var(--ember-glow),
    0 0 90px var(--ember-glow-soft),
    0 4px 18px rgba(0,0,0,0.7),
    inset 0 1px 0 rgba(255,220,180,0.5);
}
.fx-glow-btn:hover::after { animation: fxSweep 0.6s ease forwards; }
.fx-glow-btn:active { transform: scale(0.97); }
.fx-glow-btn:focus-visible { outline: 2px solid var(--ember-bright); outline-offset: 3px; }

/* Gold variant — for secondary/structural CTAs that should stay "information"
   colored per the Design Bible (ember reserved for the ONE primary action). */
.fx-glow-btn.is-gold {
  color: #1a0f00;
  background: linear-gradient(180deg, #ECC84A 0%, #D4AF37 45%, #9a7412 100%);
  border-color: #7a5a0a;
  --gb-glow: var(--gold-glow, rgba(212,175,55,0.5));
  box-shadow: 0 0 22px rgba(212,175,55,0.18), 0 4px 16px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,245,200,0.4);
}
.fx-glow-btn.is-gold:hover {
  box-shadow: 0 0 42px rgba(212,175,55,0.6), 0 0 90px rgba(212,175,55,0.18), 0 4px 18px rgba(0,0,0,0.7);
}

@keyframes fxSweep { 0% { left: -120%; } 100% { left: 220%; } }

/* ══════════════════════════════════════════════════════════════════════════
   ANIMATED PANEL — forged-iron card with rune corner ornaments
   Markup:
     <div class="fx-panel" data-fx="panel">
       <span class="fx-corner tl"></span><span class="fx-corner tr"></span>
       <span class="fx-corner bl"></span><span class="fx-corner br"></span>
       ...content...
     </div>
   Entrance motion is applied by ui-animations.revealPanel().
   ══════════════════════════════════════════════════════════════════════════ */
.fx-panel {
  position: relative;
  background: linear-gradient(145deg, rgba(18,13,8,0.96), rgba(8,5,14,0.98));
  border: 1px solid var(--border, rgba(212,175,55,0.14));
  border-radius: 3px;
  padding: 1.2rem 1.3rem;
  overflow: hidden;
  box-shadow: 0 0 50px rgba(0,0,0,0.7), inset 0 0 40px rgba(212,175,55,0.02);
}
/* Forged sheen */
.fx-panel::before {
  content: '';
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(135deg, rgba(212,175,55,0.045) 0%, transparent 55%);
}
/* Iron corner ornaments */
.fx-panel .fx-corner {
  position: absolute; width: 16px; height: 16px; z-index: 2; pointer-events: none;
  border-color: rgba(212,175,55,0.5); border-style: solid;
  transition: border-color 0.3s ease;
}
.fx-panel:hover .fx-corner { border-color: var(--ember); }
.fx-panel .fx-corner.tl { top: -1px; left: -1px;  border-width: 2px 0 0 2px; }
.fx-panel .fx-corner.tr { top: -1px; right: -1px; border-width: 2px 2px 0 0; }
.fx-panel .fx-corner.bl { bottom: -1px; left: -1px;  border-width: 0 0 2px 2px; }
.fx-panel .fx-corner.br { bottom: -1px; right: -1px; border-width: 0 2px 2px 0; }

/* ══════════════════════════════════════════════════════════════════════════
   HERO CARD — rarity-framed portrait (summon results / future roster)
   Markup:
     <div class="fx-hero-card" data-fx="hero-card" data-rarity="legendary" data-faction="inferno">
       <img class="fx-hero-art" src="...">
       <div class="fx-hero-name">Ignis</div>
     </div>
   The rarity colour drives the border + glow; faction tints the backdrop.
   Rarity must be readable in <200ms (Design Bible) — hence the bold frame.
   ══════════════════════════════════════════════════════════════════════════ */
.fx-hero-card {
  --rc: var(--r-common);
  --fc: var(--f-void);
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  border-radius: 4px;
  overflow: hidden;
  border: 1.5px solid var(--rc);
  background:
    radial-gradient(ellipse 90% 60% at 50% 100%, color-mix(in srgb, var(--fc) 22%, transparent) 0%, transparent 70%),
    linear-gradient(160deg, rgba(14,10,20,0.9), rgba(5,3,10,0.98));
  box-shadow: 0 0 0 1px rgba(0,0,0,0.6), 0 8px 24px rgba(0,0,0,0.6),
              0 0 18px color-mix(in srgb, var(--rc) 35%, transparent);
  transition: transform 0.18s ease, box-shadow 0.25s ease;
  will-change: transform;
}
.fx-hero-card[data-rarity="common"]    { --rc: var(--r-common); }
.fx-hero-card[data-rarity="rare"]      { --rc: var(--r-rare); }
.fx-hero-card[data-rarity="epic"]      { --rc: var(--r-epic); }
.fx-hero-card[data-rarity="legendary"] { --rc: var(--r-legendary); }
.fx-hero-card[data-faction="light"]    { --fc: var(--f-light); }
.fx-hero-card[data-faction="shadow"]   { --fc: var(--f-shadow); }
.fx-hero-card[data-faction="forest"]   { --fc: var(--f-forest); }
.fx-hero-card[data-faction="undead"]   { --fc: var(--f-undead); }
.fx-hero-card[data-faction="inferno"]  { --fc: var(--f-inferno); }
.fx-hero-card[data-faction="void"]     { --fc: var(--f-void); }
.fx-hero-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.6), 0 14px 34px rgba(0,0,0,0.7),
              0 0 30px color-mix(in srgb, var(--rc) 60%, transparent);
}
.fx-hero-art {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: top center;
}
.fx-hero-name {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 0.5rem 0.4rem 0.4rem;
  font-family: 'Cinzel', serif;
  font-size: 0.62rem; letter-spacing: 0.12em; text-align: center;
  color: var(--text, #E8D5A3);
  background: linear-gradient(transparent, rgba(3,2,8,0.92));
}
/* Legendary heroes get an ember pulse on the frame */
.fx-hero-card[data-rarity="legendary"] { animation: fxLegendaryFrame 3s ease-in-out infinite; }
@keyframes fxLegendaryFrame {
  0%,100% { box-shadow: 0 0 0 1px rgba(0,0,0,0.6), 0 8px 24px rgba(0,0,0,0.6), 0 0 18px var(--ember-glow-soft); }
  50%     { box-shadow: 0 0 0 1px rgba(0,0,0,0.6), 0 8px 24px rgba(0,0,0,0.6), 0 0 34px var(--ember-glow); }
}

/* ══════════════════════════════════════════════════════════════════════════
   SUMMON REVEAL — full-screen gacha reveal overlay
   The biggest reward moment (Design Bible reward hierarchy: legendary pull =
   full-screen). components.js builds the DOM and ui-animations animates it.
   ══════════════════════════════════════════════════════════════════════════ */
.fx-summon {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at center, rgba(8,4,2,0.82) 0%, rgba(2,1,5,0.96) 70%);
  backdrop-filter: blur(3px);
  padding: 1rem;
}
.fx-summon-stage {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 1.1rem;
  max-width: 92vw;
}
.fx-summon-card { width: min(64vw, 280px); }
.fx-summon-rays {
  position: absolute; inset: -40%;
  background: conic-gradient(from 0deg,
    transparent 0deg, var(--ember-glow-soft) 12deg, transparent 24deg,
    transparent 36deg, var(--ember-glow-soft) 48deg, transparent 60deg);
  filter: blur(2px); opacity: 0.5; pointer-events: none;
  animation: fxRays 14s linear infinite;
}
@keyframes fxRays { to { transform: rotate(360deg); } }
.fx-summon-hint {
  font-family: 'Cinzel', serif; font-size: 0.6rem; letter-spacing: 0.3em;
  text-transform: uppercase; color: var(--text2, #9a865d);
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE-FIRST RESPONSIVE SCALING
   Base styles above target small screens. Bump sizes up on larger viewports.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 700px) {
  .fx-glow-btn { font-size: 0.9rem; padding: 1em 2.8em; }
  .fx-summon-card { width: 280px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   GAME ENHANCEMENT (B) — legendary heroes on the campaign formation bench
   pulse an ember ring so top-tier units read instantly. The .rarity-legendary
   class is added to .avatar-circle by makeFormationUnit() in game.ejs.
   ══════════════════════════════════════════════════════════════════════════ */
.avatar-circle.rarity-legendary { animation: fxEmberRing 2.4s ease-in-out infinite; }
@keyframes fxEmberRing {
  0%,100% { box-shadow: 0 0 14px rgba(232,101,10,0.25), 0 0 0 2px rgba(232,101,10,0.45); }
  50%     { box-shadow: 0 0 24px rgba(232,101,10,0.6),  0 0 0 2px rgba(232,101,10,0.85); }
}

/* ══════════════════════════════════════════════════════════════════════════
   BRANDED LOADER (P1) — the landing→game bridge: the forge igniting.
   Styles the existing #loading-overlay (markup in game.ejs) which previously
   had NO CSS. game.js adds `.hidden` once the first game state arrives, then
   sets display:none — so this just needs the look + a clean fade-out.
   ══════════════════════════════════════════════════════════════════════════ */
#loading-overlay {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;
  background:
    radial-gradient(ellipse 60% 55% at 50% 64%, #190902 0%, transparent 62%),
    var(--void, #05030A);
  transition: opacity 0.45s ease, filter 0.45s ease;
}
#loading-overlay.hidden { opacity: 0; filter: blur(8px); pointer-events: none; }
/* Ember bloom rising from the bottom — the forge fire. */
#loading-overlay::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 46%;
  background: radial-gradient(ellipse 72% 100% at 50% 100%, var(--ember-glow, rgba(232,101,10,0.5)) 0%, transparent 70%);
  pointer-events: none; animation: fxForgeBreath 2.4s ease-in-out infinite;
}
@keyframes fxForgeBreath { 0%,100% { opacity: 0.45; } 50% { opacity: 0.9; } }

#loading-overlay .ov-logo {
  font-family: 'Cinzel Decorative', serif; font-weight: 900;
  font-size: clamp(2.2rem, 9vw, 3.6rem); letter-spacing: 0.14em; position: relative;
  background: linear-gradient(180deg, #FFF1C8 0%, #E8650A 55%, #7a3404 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 18px var(--ember-glow, rgba(232,101,10,0.5)));
  animation: fxLogoIgnite 1.5s ease-out both, fxLogoPulse 2.6s ease-in-out 1.5s infinite;
}
@keyframes fxLogoIgnite {
  0%   { opacity: 0; letter-spacing: 0.5em; filter: brightness(0.2) drop-shadow(0 0 0 transparent); }
  60%  { opacity: 1; }
  100% { opacity: 1; letter-spacing: 0.14em; }
}
@keyframes fxLogoPulse {
  0%,100% { filter: drop-shadow(0 0 14px rgba(232,101,10,0.4)); }
  50%     { filter: drop-shadow(0 0 32px rgba(232,101,10,0.85)); }
}
#loading-overlay .ov-sub {
  font-family: 'Cinzel', serif; font-size: 0.62rem; letter-spacing: 0.42em;
  text-transform: uppercase; color: var(--text2, #8A7A65);
}
#loading-overlay .ov-dots { display: flex; gap: 9px; }
#loading-overlay .ov-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--ember, #E8650A);
  box-shadow: 0 0 10px var(--ember-glow, rgba(232,101,10,0.6));
  animation: fxOvDot 1.1s ease-in-out infinite;
}
#loading-overlay .ov-dot:nth-child(2) { animation-delay: 0.18s; }
#loading-overlay .ov-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes fxOvDot { 0%,100% { transform: scale(0.55); opacity: 0.35; } 50% { transform: scale(1.1); opacity: 1; } }

/* Onboarding (P1): soft ember glow on the tutorial step icon. */
#tutorial-overlay .tut-icon { filter: drop-shadow(0 0 14px rgba(232,101,10,0.45)); }

/* ══════════════════════════════════════════════════════════════════════════
   COMBAT JUICE (P0 #2) — make heavy hits FEEL like they land.
   Heavy = a hit removing >=16% of the target's max HP (flagged in game.js).
   Pairs with screen-shake + hit-stop driven from playBattleAnim().
   ══════════════════════════════════════════════════════════════════════════ */
/* Ember "crit" damage number — bigger, punchier pop (keeps the -50% centering). */
.dmg-num.crit {
  font-size: 1.55rem !important;
  color: var(--ember-bright) !important;
  text-shadow: 0 0 12px var(--ember), 0 0 4px #fff, 0 2px 4px #000;
  z-index: 25;
  animation: fxDmgCrit 0.92s cubic-bezier(0.2,0.9,0.3,1) forwards !important;
}
@keyframes fxDmgCrit {
  0%   { opacity: 0; transform: translateX(-50%) translateY(2px)   scale(0.4); }
  18%  { opacity: 1; transform: translateX(-50%) translateY(-8px)  scale(1.55); }
  35%  { opacity: 1; transform: translateX(-50%) translateY(-12px) scale(1.0); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-52px) scale(1.0); }
}
/* Hard impact flash on the struck unit. */
.fighter-unit.hit-hard .avatar-circle { animation: fxHitHard 0.34s ease !important; }
@keyframes fxHitHard {
  0%   { filter: brightness(3.2) drop-shadow(0 0 10px #fff); transform: scale(1.12); }
  40%  { transform: translateX(5px) scale(1.04); }
  70%  { transform: translateX(-4px); }
  100% { filter: none; transform: none; }
}
/* CSS shake fallback (used only when GSAP is unavailable). */
@keyframes fxArenaShake {
  0%,100% { transform: translate(0,0); }
  20% { transform: translate(-5px,3px); }  40% { transform: translate(5px,-3px); }
  60% { transform: translate(-4px,-2px); } 80% { transform: translate(4px,2px); }
}
.arena-shake { animation: fxArenaShake 0.3s ease; }

/* ── Respect reduced motion: kill the ambient/legendary loops + combat shake ── */
@media (prefers-reduced-motion: reduce) {
  .fx-summon-rays,
  .fx-hero-card[data-rarity="legendary"],
  .avatar-circle.rarity-legendary,
  .fighter-unit.hit-hard .avatar-circle,
  .arena-shake,
  .fx-glow-btn:hover::after { animation: none !important; }
}
