← Deckbuilder results

Deckbuilder

Gemini 3.7 Flash · full

Initial view of Deckbuilder

Reviews & generation details

Reviews

No human review yet. Unreviewed does not mean unsuccessful.

Generation context

Imported historical artifact. Its exact original instructions and lineage are not known.

Generation prompt · exact text unavailable

See the current prompt for reference. It may differ from the instructions used to generate this artifact.

Inspect original source 87,351 bytes · SHA-256 60ef9f4fed93
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadows of Aethelgard</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@500;700;900&family=MedievalSharp&family=Metamorphous&display=swap" rel="stylesheet">
<style>
:root {
  --bg-dark: #08070c;
  --bg-panel: rgba(18, 15, 26, 0.85);
  --gold-glow: #d4af37;
  --gold-bright: #ffd700;
  --metal-dark: #2a2634;
  --metal-border: #4a4358;
  --metal-highlight: #786d8d;
  
  --atk-color: #ff4747;
  --atk-glow: rgba(255, 71, 71, 0.4);
  --atk-grad: linear-gradient(135deg, #3d1414, #1f0b0b);
  
  --def-color: #4da6ff;
  --def-glow: rgba(77, 166, 255, 0.4);
  --def-grad: linear-gradient(135deg, #14283d, #0b151f);
  
  --oth-color: #b05cff;
  --oth-glow: rgba(176, 92, 255, 0.4);
  --oth-grad: linear-gradient(135deg, #2d143d, #14081f);
  
  --energy-orb: #38bdf8;
  --hp-bar: #ef4444;
  --block-bar: #3b82f6;
  --font-gothic: 'Cinzel', serif;
  --font-body: 'MedievalSharp', cursive, serif;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  user-select: none;
  -webkit-user-select: none;
}

body {
  background-color: var(--bg-dark);
  color: #e5e0d8;
  font-family: var(--font-gothic);
  overflow: hidden;
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Background Atmosphere */
#world-bg {
  position: fixed;
  inset: 0;
  background: radial-gradient(circle at 50% 40%, #1a1226 0%, #0c0814 60%, #030206 100%);
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.fog-layer {
  position: absolute;
  inset: -50%;
  background: radial-gradient(ellipse at center, rgba(147, 51, 234, 0.08) 0%, transparent 70%);
  animation: fogFloat 25s infinite alternate linear;
}

@keyframes fogFloat {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(4%, 3%) scale(1.1); }
  100% { transform: translate(-3%, -2%) scale(1.05); }
}

/* APP CONTAINER */
#game-container {
  position: relative;
  width: 1280px;
  height: 720px;
  background: rgba(10, 8, 15, 0.6);
  border: 2px solid #322b40;
  box-shadow: 0 0 50px rgba(0, 0, 0, 0.9), inset 0 0 100px rgba(0, 0, 0, 0.8);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: 1;
}

/* SCREENS */
.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  z-index: 10;
  transition: opacity 0.4s ease;
}
.screen.hidden {
  opacity: 0;
  pointer-events: none;
}

/* MAIN MENU SCREEN */
#screen-menu {
  justify-content: center;
  align-items: center;
  background: radial-gradient(circle, rgba(28, 18, 48, 0.95), rgba(6, 4, 10, 0.98));
  text-align: center;
  padding: 40px;
}
.game-title {
  font-size: 54px;
  font-weight: 900;
  letter-spacing: 6px;
  color: #f7e6c4;
  text-shadow: 0 0 20px #d4af37, 0 0 40px #7928ca;
  margin-bottom: 8px;
}
.game-subtitle {
  font-family: var(--font-body);
  font-size: 20px;
  color: #a79cb8;
  letter-spacing: 3px;
  margin-bottom: 40px;
}
.class-select-container {
  display: flex;
  gap: 24px;
  margin-bottom: 30px;
}
.class-card {
  width: 250px;
  background: linear-gradient(180deg, rgba(35, 29, 50, 0.9), rgba(16, 13, 24, 0.95));
  border: 2px solid var(--metal-border);
  border-radius: 8px;
  padding: 20px 16px;
  cursor: pointer;
  transition: all 0.25s ease;
  position: relative;
  overflow: hidden;
}
.class-card:hover, .class-card.selected {
  transform: translateY(-8px);
  border-color: var(--gold-glow);
  box-shadow: 0 10px 25px rgba(212, 175, 55, 0.25);
}
.class-card.selected::before {
  content: 'SELECTED';
  position: absolute;
  top: 10px;
  right: -25px;
  background: var(--gold-glow);
  color: #111;
  font-size: 10px;
  font-weight: 900;
  padding: 2px 30px;
  transform: rotate(45deg);
}
.class-icon {
  width: 80px;
  height: 80px;
  margin: 0 auto 12px;
}
.class-name {
  font-size: 20px;
  font-weight: 700;
  color: #ffeedd;
  margin-bottom: 6px;
}
.class-tagline {
  font-family: var(--font-body);
  font-size: 13px;
  color: #d4af37;
  margin-bottom: 12px;
}
.class-stats {
  font-size: 12px;
  color: #b7b0c8;
  text-align: left;
  line-height: 1.6;
  border-top: 1px solid rgba(255,255,255,0.1);
  padding-top: 10px;
}

/* BUTTONS */
.btn-gothic {
  background: linear-gradient(180deg, #3d354d 0%, #1f1a29 100%);
  border: 1.5px solid var(--metal-highlight);
  color: #eeddcc;
  padding: 12px 36px;
  font-family: var(--font-gothic);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 2px;
  cursor: pointer;
  border-radius: 4px;
  box-shadow: 0 4px 10px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.2);
  transition: all 0.2s ease;
  text-transform: uppercase;
}
.btn-gothic:hover:not(:disabled) {
  background: linear-gradient(180deg, #53486a 0%, #2b243b 100%);
  border-color: var(--gold-glow);
  color: #fff;
  box-shadow: 0 0 15px rgba(212, 175, 55, 0.4);
  transform: translateY(-2px);
}
.btn-gothic:active:not(:disabled) {
  transform: translateY(1px);
}
.btn-gothic:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  filter: grayscale(0.8);
}
.btn-gold {
  background: linear-gradient(180deg, #a67c1e 0%, #5f440b 100%);
  border-color: var(--gold-bright);
  color: #fff8e7;
}
.btn-gold:hover:not(:disabled) {
  background: linear-gradient(180deg, #c99829 0%, #7e5c12 100%);
  box-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
}

/* TOP HUD BAR */
#top-bar {
  height: 52px;
  background: linear-gradient(180deg, rgba(20, 16, 30, 0.95), rgba(12, 9, 18, 0.9));
  border-bottom: 1.5px solid var(--metal-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  z-index: 20;
}
.hud-section {
  display: flex;
  align-items: center;
  gap: 20px;
}
.hud-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 1px;
}
.hud-icon {
  width: 22px;
  height: 22px;
  fill: currentColor;
}
.hud-gold { color: #facc15; }
.hud-floor { color: #c084fc; }
.hud-room { color: #94a3b8; }
.hud-deck-view {
  background: rgba(255,255,255,0.06);
  padding: 4px 12px;
  border-radius: 4px;
  border: 1px solid var(--metal-border);
  cursor: pointer;
  transition: 0.2s;
  font-size: 12px;
  color: #ddd;
}
.hud-deck-view:hover {
  border-color: var(--gold-glow);
  background: rgba(212, 175, 55, 0.15);
}

/* MAIN PLAY AREA LAYOUT */
#combat-layout {
  flex: 1;
  display: grid;
  grid-template-columns: 310px 1fr 220px;
  grid-template-rows: 1fr 60px;
  position: relative;
  overflow: hidden;
}

/* LEFT: PLAYER HAND & HERO HUD */
#player-column {
  background: rgba(14, 11, 20, 0.7);
  border-right: 1px solid rgba(74, 67, 88, 0.5);
  display: flex;
  flex-direction: column;
  padding: 12px;
  gap: 8px;
  overflow: hidden;
}
.hero-compact-card {
  background: rgba(24, 19, 36, 0.85);
  border: 1px solid var(--metal-border);
  border-radius: 6px;
  padding: 10px;
  display: flex;
  gap: 12px;
  align-items: center;
}
.hero-avatar {
  width: 54px;
  height: 54px;
  border-radius: 6px;
  border: 1.5px solid var(--gold-glow);
  background: #110d1c;
  overflow: hidden;
  flex-shrink: 0;
}
.hero-vitals {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hero-name-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  font-weight: 700;
  color: #ffeedd;
}
.bar-wrap {
  width: 100%;
  height: 10px;
  background: #181424;
  border-radius: 5px;
  border: 1px solid #3b334a;
  overflow: hidden;
  position: relative;
}
.bar-fill {
  height: 100%;
  transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.bar-fill.hp { background: linear-gradient(90deg, #dc2626, #ef4444); }
.bar-fill.def { background: linear-gradient(90deg, #2563eb, #60a5fa); }
.bar-text {
  font-size: 10px;
  font-family: var(--font-body);
  color: #ccc;
  display: flex;
  justify-content: space-between;
}
.status-pill-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  min-height: 18px;
}
.status-pill {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 3px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  animation: pulse 1.5s infinite alternate;
}
.status-pill.burn { background: #7c2d12; color: #fed7aa; border: 1px solid #f97316; }
.status-pill.poison { background: #14532d; color: #bbf7d0; border: 1px solid #22c55e; }
.status-pill.stun { background: #581c87; color: #f3e8ff; border: 1px solid #a855f7; }
.status-pill.silence { background: #374151; color: #e5e7eb; border: 1px solid #9ca3af; }
.status-pill.ghost { background: #1e293b; color: #93c5fd; border: 1px solid #38bdf8; }

/* HAND OF CARDS */
.hand-header {
  font-size: 11px;
  letter-spacing: 1.5px;
  color: #9f96b0;
  display: flex;
  justify-content: space-between;
  padding: 0 4px;
}
#hand-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  padding-right: 4px;
}
#hand-container::-webkit-scrollbar {
  width: 4px;
}
#hand-container::-webkit-scrollbar-thumb {
  background: var(--metal-border);
  border-radius: 2px;
}

/* CARD COMPONENT */
.aethel-card {
  width: 100%;
  height: 94px;
  border-radius: 6px;
  position: relative;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.2, 0, 0, 1);
  display: flex;
  padding: 6px 8px;
  gap: 8px;
  box-shadow: 0 4px 10px rgba(0,0,0,0.5);
  border: 1.5px solid transparent;
  flex-shrink: 0;
}
.aethel-card:hover {
  transform: translateX(6px) scale(1.02);
  z-index: 5;
}
.aethel-card.unplayable {
  opacity: 0.5;
  filter: grayscale(0.7);
  cursor: not-allowed;
}
.aethel-card.unplayable:hover {
  transform: none;
}
.aethel-card.selected-for-action {
  border-color: var(--gold-bright) !important;
  box-shadow: 0 0 15px rgba(255, 215, 0, 0.6) !important;
  transform: translateX(10px) scale(1.04);
}

/* Card Types Colors */
.card-type-Attack {
  background: var(--atk-grad);
  border-color: #8f2d2d;
}
.card-type-Attack:hover {
  box-shadow: 0 0 14px var(--atk-glow);
  border-color: var(--atk-color);
}
.card-type-Defense {
  background: var(--def-grad);
  border-color: #275685;
}
.card-type-Defense:hover {
  box-shadow: 0 0 14px var(--def-glow);
  border-color: var(--def-color);
}
.card-type-Other {
  background: var(--oth-grad);
  border-color: #6d2c94;
}
.card-type-Other:hover {
  box-shadow: 0 0 14px var(--oth-glow);
  border-color: var(--oth-color);
}

.card-art-box {
  width: 70px;
  height: 100%;
  border-radius: 4px;
  overflow: hidden;
  background: #000;
  border: 1px solid rgba(255,255,255,0.15);
  flex-shrink: 0;
  position: relative;
}
.card-details {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
}
.card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.card-title {
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-cost-badge {
  background: radial-gradient(circle, #0284c7, #0369a1);
  color: #fff;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 900;
  border: 1.5px solid #7dd3fc;
  box-shadow: 0 0 8px rgba(56, 189, 248, 0.6);
  flex-shrink: 0;
}
.card-desc {
  font-family: var(--font-body);
  font-size: 11px;
  color: #cbd5e1;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 10px;
  color: #94a3b8;
}
.card-stat-pill {
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 700;
  font-size: 10px;
}
.stat-atk { background: rgba(239, 68, 68, 0.25); color: #fca5a5; }
.stat-def { background: rgba(59, 130, 246, 0.25); color: #93c5fd; }

/* CENTER: ARENA / ENEMY DISPLAY / COMBAT LOG */
#center-column {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background: radial-gradient(circle at 50% 60%, rgba(30, 21, 48, 0.4) 0%, rgba(9, 7, 15, 0.8) 80%);
}

#combat-arena {
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-around;
  position: relative;
}

.entity-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}

/* HERO SPRITE STAGE */
.hero-stage {
  width: 180px;
}
.hero-sprite-box {
  width: 150px;
  height: 190px;
  position: relative;
  filter: drop-shadow(0 10px 15px rgba(0,0,0,0.8));
  transition: transform 0.2s ease;
}
.hero-sprite-box.hero-attack {
  animation: heroLunge 0.4s ease;
}
.hero-sprite-box.hero-hit {
  animation: hitShake 0.4s ease;
}
@keyframes heroLunge {
  0% { transform: translateX(0); }
  50% { transform: translateX(45px) scale(1.05); }
  100% { transform: translateX(0); }
}
@keyframes hitShake {
  0%, 100% { transform: translateX(0); filter: brightness(1); }
  20% { transform: translateX(-12px); filter: brightness(2) drop-shadow(0 0 10px #ff0000); }
  40% { transform: translateX(10px); }
  60% { transform: translateX(-6px); }
  80% { transform: translateX(4px); }
}

/* ENEMY SPRITE STAGE */
.enemy-stage {
  width: 280px;
}
.enemy-intent-banner {
  background: rgba(18, 14, 26, 0.9);
  border: 1px solid #78350f;
  color: #fde047;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  box-shadow: 0 0 12px rgba(234, 179, 8, 0.2);
  animation: floatSmall 2s infinite ease-in-out;
}
@keyframes floatSmall {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
.enemy-sprite-box {
  width: 200px;
  height: 220px;
  position: relative;
  filter: drop-shadow(0 12px 20px rgba(0,0,0,0.9));
  transition: transform 0.2s ease;
}
.enemy-sprite-box.enemy-attack {
  animation: enemyLunge 0.4s ease;
}
.enemy-sprite-box.enemy-hit {
  animation: hitShake 0.4s ease;
}
@keyframes enemyLunge {
  0% { transform: translateX(0); }
  50% { transform: translateX(-45px) scale(1.05); }
  100% { transform: translateX(0); }
}

.enemy-hud {
  width: 100%;
  background: rgba(18, 13, 27, 0.85);
  border: 1px solid var(--metal-border);
  border-radius: 6px;
  padding: 8px 12px;
  margin-top: 10px;
}
.enemy-name-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}
.enemy-name {
  font-size: 15px;
  font-weight: 700;
  color: #fca5a5;
}
.boss-tag {
  background: #7f1d1d;
  border: 1px solid #ef4444;
  color: #fee2e2;
  font-size: 9px;
  font-weight: 900;
  padding: 1px 6px;
  border-radius: 3px;
  letter-spacing: 1px;
}

/* FLOATING COMBAT TEXT */
.floating-text {
  position: absolute;
  font-size: 24px;
  font-weight: 900;
  pointer-events: none;
  animation: floatUpFade 1s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;
  z-index: 100;
  text-shadow: 0 2px 4px #000, 0 0 10px currentColor;
}
@keyframes floatUpFade {
  0% { opacity: 0; transform: translateY(0) scale(0.6); }
  20% { opacity: 1; transform: translateY(-15px) scale(1.2); }
  100% { opacity: 0; transform: translateY(-55px) scale(0.9); }
}

/* COMBAT LOG OVERLAY */
#combat-log-box {
  width: 100%;
  height: 65px;
  background: rgba(10, 7, 16, 0.75);
  border: 1px solid rgba(74, 67, 88, 0.4);
  border-radius: 4px;
  padding: 6px 12px;
  overflow-y: auto;
  font-family: var(--font-body);
  font-size: 12px;
  color: #cbd5e1;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
#combat-log-box::-webkit-scrollbar {
  width: 4px;
}
#combat-log-box::-webkit-scrollbar-thumb {
  background: var(--metal-border);
}
.log-entry {
  line-height: 1.2;
}
.log-player { color: #93c5fd; }
.log-enemy { color: #fca5a5; }
.log-status { color: #fde047; }
.log-system { color: #c084fc; font-weight: 700; }

/* RIGHT COLUMN: ENERGY & SHOP & CONTROLS */
#right-column {
  background: rgba(14, 11, 20, 0.7);
  border-left: 1px solid rgba(74, 67, 88, 0.5);
  display: flex;
  flex-direction: column;
  padding: 16px 12px;
  justify-content: space-between;
  align-items: center;
}

/* ENERGY ORB */
.energy-orb-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.energy-orb {
  width: 86px;
  height: 86px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #7dd3fc 0%, #0284c7 50%, #0f172a 100%);
  border: 3px solid #38bdf8;
  box-shadow: 0 0 25px rgba(56, 189, 248, 0.5), inset 0 0 15px rgba(255,255,255,0.4);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  animation: orbPulse 3s infinite alternate ease-in-out;
}
@keyframes orbPulse {
  0% { box-shadow: 0 0 15px rgba(56, 189, 248, 0.4); }
  100% { box-shadow: 0 0 30px rgba(56, 189, 248, 0.8), 0 0 50px rgba(56, 189, 248, 0.2); }
}
.energy-value {
  font-size: 32px;
  font-weight: 900;
  color: #fff;
  line-height: 1;
  text-shadow: 0 2px 8px #000;
}
.energy-max {
  font-size: 11px;
  color: #bae6fd;
  letter-spacing: 1px;
}

/* ACTIONS MENU IN RIGHT COLUMN */
.side-actions {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.shop-card-preview {
  background: rgba(22, 17, 33, 0.9);
  border: 1px dashed var(--gold-glow);
  border-radius: 6px;
  padding: 10px 8px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s ease;
}
.shop-card-preview:hover {
  background: rgba(45, 33, 20, 0.8);
  border-style: solid;
  transform: translateY(-2px);
  box-shadow: 0 4px 15px rgba(212, 175, 55, 0.3);
}
.shop-preview-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--gold-bright);
  margin-bottom: 4px;
}
.shop-preview-sub {
  font-size: 10px;
  font-family: var(--font-body);
  color: #a8a29e;
}

/* BOTTOM CONTROL BAR */
#bottom-bar {
  grid-column: 1 / -1;
  height: 60px;
  background: linear-gradient(0deg, rgba(14, 10, 22, 0.95), rgba(20, 16, 30, 0.9));
  border-top: 1.5px solid var(--metal-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
}
.turn-status-indicator {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: #cbd5e1;
  display: flex;
  align-items: center;
  gap: 10px;
}
.turn-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 10px #22c55e;
}
.turn-dot.enemy {
  background: #ef4444;
  box-shadow: 0 0 10px #ef4444;
}

/* SHOP MODAL */
#shop-modal {
  position: absolute;
  inset: 0;
  background: rgba(4, 3, 8, 0.88);
  backdrop-filter: blur(6px);
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
#shop-modal.active {
  opacity: 1;
  pointer-events: auto;
}
.shop-panel {
  width: 900px;
  max-height: 90%;
  background: linear-gradient(180deg, #1f182c 0%, #100b19 100%);
  border: 2px solid var(--gold-glow);
  border-radius: 10px;
  padding: 24px;
  box-shadow: 0 0 40px rgba(0,0,0,0.9), 0 0 20px rgba(212, 175, 55, 0.3);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.shop-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1.5px solid rgba(212, 175, 55, 0.4);
  padding-bottom: 12px;
}
.shop-title {
  font-size: 24px;
  font-weight: 900;
  color: var(--gold-bright);
  letter-spacing: 2px;
}
.shop-tabs {
  display: flex;
  gap: 8px;
}
.shop-tab-btn {
  padding: 6px 14px;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--metal-border);
  color: #cbd5e1;
  font-size: 11px;
  font-family: var(--font-gothic);
  border-radius: 4px;
  cursor: pointer;
  transition: 0.2s;
}
.shop-tab-btn.active, .shop-tab-btn:hover {
  background: rgba(212, 175, 55, 0.2);
  border-color: var(--gold-glow);
  color: #fff;
}
.shop-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  overflow-y: auto;
  max-height: 420px;
  padding-right: 6px;
}
.shop-grid::-webkit-scrollbar {
  width: 6px;
}
.shop-grid::-webkit-scrollbar-thumb {
  background: var(--gold-glow);
  border-radius: 3px;
}
.shop-item-card {
  background: rgba(27, 21, 38, 0.9);
  border: 1.5px solid var(--metal-border);
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 8px;
  transition: all 0.2s;
}
.shop-item-card:hover {
  border-color: var(--gold-bright);
  transform: translateY(-2px);
}
.shop-item-card.maxed {
  opacity: 0.5;
  filter: grayscale(0.8);
}
.shop-item-info {
  display: flex;
  gap: 10px;
}
.shop-buy-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid rgba(255,255,255,0.08);
  padding-top: 8px;
}
.shop-owned-count {
  font-size: 11px;
  color: #94a3b8;
}

/* DECK VIEWER MODAL */
#deck-modal {
  position: absolute;
  inset: 0;
  background: rgba(4, 3, 8, 0.9);
  backdrop-filter: blur(6px);
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
#deck-modal.active {
  opacity: 1;
  pointer-events: auto;
}
.deck-panel {
  width: 900px;
  max-height: 85%;
  background: linear-gradient(180deg, #1f182c 0%, #100b19 100%);
  border: 2px solid #6366f1;
  border-radius: 10px;
  padding: 24px;
  box-shadow: 0 0 40px rgba(0,0,0,0.9);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* WIN & GAME OVER SCREENS */
#screen-victory, #screen-gameover {
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 40px;
}
#screen-victory {
  background: radial-gradient(circle, rgba(28, 48, 30, 0.96), rgba(4, 12, 6, 0.98));
}
#screen-gameover {
  background: radial-gradient(circle, rgba(48, 12, 12, 0.96), rgba(12, 4, 4, 0.98));
}
.end-title {
  font-size: 56px;
  font-weight: 900;
  letter-spacing: 4px;
  margin-bottom: 12px;
}
.end-title.vic {
  color: #86efac;
  text-shadow: 0 0 30px #22c55e, 0 0 60px #16a34a;
}
.end-title.loss {
  color: #fca5a5;
  text-shadow: 0 0 30px #ef4444, 0 0 60px #991b1b;
}
.end-subtitle {
  font-family: var(--font-body);
  font-size: 20px;
  color: #e2e8f0;
  max-width: 600px;
  margin-bottom: 30px;
  line-height: 1.5;
}

/* UTILITY HELPERS */
.flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
</head>
<body>

<div id="world-bg">
  <div class="fog-layer"></div>
</div>

<div id="game-container">
  <!-- TOP BAR HUD -->
  <header id="top-bar">
    <div class="hud-section">
      <div class="hud-item hud-gold">
        <svg class="hud-icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="#facc15" stroke="#713f12" stroke-width="2"/><text x="12" y="16" font-size="12" font-weight="bold" fill="#713f12" text-anchor="middle">G</text></svg>
        <span id="hud-gold-text">0 Gold</span>
      </div>
      <div class="hud-item hud-floor">
        <span>Floor <strong id="hud-floor-num">1</strong> / 3</span>
      </div>
      <div class="hud-item hud-room">
        <span>Room <strong id="hud-room-num">1</strong> / 4</span>
      </div>
    </div>
    
    <div class="hud-section">
      <button class="hud-deck-view" onclick="game.toggleDeckModal(true)">View Deck (<span id="hud-deck-count">12</span>)</button>
      <button class="hud-deck-view" onclick="game.toggleShopModal(true)">Gold Shop</button>
      <button class="hud-deck-view" onclick="game.abandonRun()">Main Menu</button>
    </div>
  </header>

  <!-- COMBAT & GAMEPLAY AREA -->
  <main id="combat-layout">
    <!-- LEFT: HERO STATUS & HAND -->
    <section id="player-column">
      <div class="hero-compact-card">
        <div class="hero-avatar" id="hero-portrait-slot"></div>
        <div class="hero-vitals">
          <div class="hero-name-row">
            <span id="hero-name-label">The Bastion</span>
            <span id="hero-def-badge" style="color:#60a5fa; font-weight:bold;">Def: 0</span>
          </div>
          <div class="bar-wrap">
            <div id="hero-hp-bar" class="bar-fill hp" style="width: 100%;"></div>
          </div>
          <div class="bar-text">
            <span>HP: <strong id="hero-hp-val">35</strong>/<span id="hero-maxhp-val">35</span></span>
            <span>Hand Limit: <strong id="hero-handlim-val">4</strong></span>
          </div>
          <div class="status-pill-list" id="hero-status-list"></div>
        </div>
      </div>

      <div class="hand-header">
        <span>HAND CARDS (<span id="hand-count-text">0</span>)</span>
        <span style="color:#60a5fa; font-size:10px;">Click card to play</span>
      </div>

      <div id="hand-container">
        <!-- Cards rendered here dynamically -->
      </div>
    </section>

    <!-- CENTER: ARENA WITH HERO & ENEMY ANIMATIONS & COMBAT LOG -->
    <section id="center-column">
      <div id="combat-arena">
        <!-- HERO SPRITE STAGE -->
        <div class="entity-stage hero-stage">
          <div class="hero-sprite-box" id="hero-sprite-container">
            <!-- Hero SVG dynamically drawn based on class & state -->
          </div>
        </div>

        <!-- VS DIVIDER / INTENT -->
        <div style="display:flex; flex-direction:column; align-items:center; opacity:0.6;">
          <span style="font-size: 20px; font-weight:900; color:#d4af37;">VS</span>
        </div>

        <!-- ENEMY SPRITE STAGE -->
        <div class="entity-stage enemy-stage">
          <div class="enemy-intent-banner" id="enemy-intent-box">
            <span>⚔️ Intent: Attack 3 DMG</span>
          </div>
          <div class="enemy-sprite-box" id="enemy-sprite-container">
            <!-- Enemy SVG dynamically rendered -->
          </div>
          
          <div class="enemy-hud">
            <div class="enemy-name-row">
              <span class="enemy-name" id="enemy-name-text">Void Goblin</span>
              <span id="enemy-boss-badge" class="boss-tag" style="display:none;">BOSS</span>
            </div>
            <div class="bar-wrap" style="margin-bottom: 4px;">
              <div id="enemy-hp-bar" class="bar-fill hp" style="width: 100%;"></div>
            </div>
            <div class="bar-text">
              <span>HP: <strong id="enemy-hp-val">20</strong>/<span id="enemy-maxhp-val">20</span></span>
              <span style="color:#60a5fa;">Def: <strong id="enemy-def-val">0</strong></span>
            </div>
            <div class="status-pill-list" id="enemy-status-list" style="margin-top:4px;"></div>
          </div>
        </div>
      </div>

      <!-- COMBAT MESSAGE LOG -->
      <div id="combat-log-box">
        <div class="log-entry log-system">Welcome to Shadows of Aethelgard. Cleanse the Void.</div>
      </div>
    </section>

    <!-- RIGHT: ENERGY ORB & SHOP SHORTCUT -->
    <section id="right-column">
      <div class="energy-orb-container">
        <div class="energy-orb">
          <div class="energy-value" id="energy-val">3</div>
          <div class="energy-max">/ <span id="energy-max-val">5</span> MAX</div>
        </div>
        <span style="font-size:11px; color:#93c5fd; letter-spacing:1px;">+1 Energy / Turn</span>
      </div>

      <div class="side-actions">
        <div class="shop-card-preview" onclick="game.toggleShopModal(true)">
          <div class="shop-preview-title">🛒 REINFORCEMENTS</div>
          <div class="shop-preview-sub">Buy new cards for Gold</div>
        </div>

        <div style="background: rgba(20,15,30,0.8); border:1px solid var(--metal-border); border-radius:6px; padding:10px; text-align:center;">
          <div style="font-size:11px; color:#a79cb8; margin-bottom:4px;">Floor Boss Objective</div>
          <div id="floor-boss-brief" style="font-size:11px; color:#fde047; font-weight:bold;">Floor 1: The Gatekeeper</div>
        </div>
      </div>
    </section>

    <!-- BOTTOM CONTROL BAR -->
    <footer id="bottom-bar">
      <div class="turn-status-indicator">
        <div class="turn-dot" id="turn-dot"></div>
        <span id="turn-status-label">PLAYER TURN</span>
      </div>

      <div style="display:flex; gap:16px;">
        <button id="btn-end-turn" class="btn-gothic btn-gold" onclick="game.endTurn()">End Turn</button>
      </div>
    </footer>
  </main>

  <!-- SCREEN: MAIN MENU / CLASS SELECT -->
  <div id="screen-menu" class="screen">
    <h1 class="game-title">SHADOWS OF AETHELGARD</h1>
    <p class="game-subtitle">DESCENT INTO THE CORRUPTED REALM</p>

    <div class="class-select-container">
      <!-- BASTION -->
      <div class="class-card selected" id="card-bastion" onclick="game.selectClass('Bastion')">
        <div class="class-icon" id="bastion-icon-svg"></div>
        <div class="class-name">THE BASTION</div>
        <div class="class-tagline">Immovable Object</div>
        <div class="class-stats">
          <div>HP: <strong>35</strong> | Energy: <strong>3</strong></div>
          <div>Style: High Defense, High Block, AoE</div>
        </div>
      </div>

      <!-- WITHER -->
      <div class="class-card" id="card-wither" onclick="game.selectClass('Wither')">
        <div class="class-icon" id="wither-icon-svg"></div>
        <div class="class-name">THE WITHER</div>
        <div class="class-tagline">Rot and Burn</div>
        <div class="class-stats">
          <div>HP: <strong>30</strong> | Energy: <strong>5</strong></div>
          <div>Style: Status Burn, Poison & Debuffs</div>
        </div>
      </div>

      <!-- SHROUD -->
      <div class="class-card" id="card-shroud" onclick="game.selectClass('Shroud')">
        <div class="class-icon" id="shroud-icon-svg"></div>
        <div class="class-name">THE SHROUD</div>
        <div class="class-tagline">Shadow and Speed</div>
        <div class="class-stats">
          <div>HP: <strong>30</strong> | Energy: <strong>5</strong></div>
          <div>Style: High Speed, Evasion, Assassinate</div>
        </div>
      </div>
    </div>

    <button class="btn-gothic btn-gold" style="font-size:18px; padding:14px 48px;" onclick="game.startRun()">DESCEND INTO THE VOID</button>
  </div>

  <!-- SCREEN: VICTORY -->
  <div id="screen-victory" class="screen hidden">
    <h1 class="end-title vic">THE VOID HAS FALLEN</h1>
    <p class="end-subtitle">You have conquered the Void Lord on Floor 3 and reclaimed Aethelgard from eternal darkness. Your legacy is etched into the stone.</p>
    <button class="btn-gothic btn-gold" onclick="game.abandonRun()">RETURN TO SANCTUARY</button>
  </div>

  <!-- SCREEN: GAME OVER -->
  <div id="screen-gameover" class="screen hidden">
    <h1 class="end-title loss">CONSUMED BY SHADOWS</h1>
    <p class="end-subtitle">Your resolve was shattered by the horrors of the abyss. The Void claims another hero of Aethelgard.</p>
    <button class="btn-gothic btn-gold" onclick="game.abandonRun()">TRY AGAIN</button>
  </div>

  <!-- MODAL: GOLD CARD SHOP -->
  <div id="shop-modal">
    <div class="shop-panel">
      <div class="shop-header">
        <div>
          <div class="shop-title">GOLD CARD SHOP</div>
          <div style="font-size:12px; color:#cbd5e1; font-family:var(--font-body);">Upgrade and expand your battle deck. Cost scales with owned copies.</div>
        </div>
        <div style="display:flex; align-items:center; gap:16px;">
          <div class="hud-item hud-gold" style="font-size:18px;">
            <span>Current Gold: <strong id="shop-gold-display">0</strong></span>
          </div>
          <button class="btn-gothic" style="padding:6px 16px;" onclick="game.toggleShopModal(false)">Close</button>
        </div>
      </div>

      <div class="shop-tabs">
        <button class="shop-tab-btn active" id="tab-all" onclick="game.filterShop('ALL')">All Classes</button>
        <button class="shop-tab-btn" id="tab-bastion" onclick="game.filterShop('BA')">Bastion Cards</button>
        <button class="shop-tab-btn" id="tab-wither" onclick="game.filterShop('WI')">Wither Cards</button>
        <button class="shop-tab-btn" id="tab-shroud" onclick="game.filterShop('SH')">Shroud Cards</button>
      </div>

      <div class="shop-grid" id="shop-items-grid">
        <!-- Shop items dynamically rendered -->
      </div>
    </div>
  </div>

  <!-- MODAL: DECK VIEWER -->
  <div id="deck-modal">
    <div class="deck-panel">
      <div class="shop-header">
        <div>
          <div class="shop-title" style="color:#818cf8;">HERO DECK INSPECTION</div>
          <div style="font-size:12px; color:#cbd5e1; font-family:var(--font-body);">Showing all cards in your current deck pool (<span id="deck-view-count">0</span> cards).</div>
        </div>
        <button class="btn-gothic" style="padding:6px 16px;" onclick="game.toggleDeckModal(false)">Close</button>
      </div>

      <div class="shop-grid" id="deck-items-grid" style="max-height:460px;">
        <!-- Current deck cards rendered here -->
      </div>
    </div>
  </div>
</div>

<script>
/* =========================================================================
   SHADOWS OF AETHELGARD - FULL ENGINE & GAMEPLAY LOGIC
   ========================================================================= */

// --- 1. SVG GENERATORS FOR CARD FRAMES & CARD BACKS ---
const SVG_ASSETS = {
  getCardFrameSVG(deckType, cardType) {
    // Unique Card Frame per Deck Type (Bastion: Fortified Stone, Wither: Fiery Thorn, Shroud: Shadow Blade)
    let primaryColor = "#64748b";
    let accentColor = "#94a3b8";
    let frameTitle = "BASTION";
    let runePath = "";
    
    if (deckType === "BA") { // Bastion
      primaryColor = "#44403c";
      accentColor = "#d97706";
      frameTitle = "BASTION";
      runePath = `<polygon points="20,8 32,16 32,32 20,40 8,32 8,16" fill="#78350f" stroke="#f59e0b" stroke-width="1.5"/>
                  <path d="M14 24 L26 24 M20 14 L20 34" stroke="#fef08a" stroke-width="2"/>`;
    } else if (deckType === "WI") { // Wither
      primaryColor = "#450a0a";
      accentColor = "#ea580c";
      frameTitle = "WITHER";
      runePath = `<circle cx="20" cy="24" r="14" fill="#7c2d12" stroke="#f97316" stroke-width="1.5"/>
                  <path d="M14 28 Q20 12 26 28 Q20 34 14 28 Z" fill="#ef4444"/>`;
    } else if (deckType === "SH") { // Shroud
      primaryColor = "#2e1065";
      accentColor = "#a855f7";
      frameTitle = "SHROUD";
      runePath = `<polygon points="20,10 32,24 20,38 8,24" fill="#4c1d95" stroke="#c084fc" stroke-width="1.5"/>
                  <circle cx="20" cy="24" r="4" fill="#38bdf8"/>`;
    }

    // Return Frame Overlay SVG with clear Art Placeholder
    return `
      <svg width="100%" height="100%" viewBox="0 0 140 190" xmlns="http://www.w3.org/2000/svg">
        <defs>
          <linearGradient id="frameGrad-${deckType}-${Math.floor(Math.random()*10000)}" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stop-color="${primaryColor}" stop-opacity="0.95"/>
            <stop offset="100%" stop-color="#0a0812" stop-opacity="0.98"/>
          </linearGradient>
        </defs>
        <!-- Border & Background -->
        <rect x="2" y="2" width="136" height="186" rx="8" fill="${primaryColor}" stroke="${accentColor}" stroke-width="2.5"/>
        <rect x="6" y="6" width="128" height="178" rx="6" fill="#120e1a" stroke="#2a2438" stroke-width="1"/>
        
        <!-- Header Ribbon -->
        <rect x="12" y="10" width="116" height="18" rx="3" fill="#1c1626" stroke="${accentColor}" stroke-width="1"/>
        <text x="70" y="23" font-size="9" font-family="'Cinzel', serif" font-weight="900" fill="${accentColor}" text-anchor="middle" letter-spacing="1.5">${frameTitle}</text>
        
        <!-- Main Card Image Placeholder Box -->
        <rect x="14" y="34" width="112" height="74" rx="4" fill="#1e1b29" stroke="${accentColor}" stroke-width="1.5" stroke-dasharray="4,3"/>
        <text x="70" y="68" font-size="10" font-family="'Cinzel', serif" fill="${accentColor}" text-anchor="middle" font-weight="bold" opacity="0.9">✦ ART SLOT ✦</text>
        <text x="70" y="82" font-size="8" font-family="sans-serif" fill="#94a3b8" text-anchor="middle" opacity="0.7">[Card Image Placeholder]</text>
        
        <!-- Bottom Rune & Details Box -->
        <g transform="translate(50, 120)">
          ${runePath}
        </g>
        
        <!-- Corner Ornaments -->
        <circle cx="10" cy="10" r="3" fill="${accentColor}"/>
        <circle cx="130" cy="10" r="3" fill="${accentColor}"/>
        <circle cx="10" cy="180" r="3" fill="${accentColor}"/>
        <circle cx="130" cy="180" r="3" fill="${accentColor}"/>
      </svg>
    `;
  },

  getCardBackSVG(deckType) {
    let mainColor = "#334155";
    let glowColor = "#94a3b8";
    let crest = "";

    if (deckType === "BA") {
      mainColor = "#44403c";
      glowColor = "#d97706";
      crest = `
        <polygon points="40,25 60,25 70,55 50,85 30,55" fill="#292524" stroke="#d97706" stroke-width="2"/>
        <line x1="50" y1="28" x2="50" y2="80" stroke="#d97706" stroke-width="2"/>
        <line x1="36" y1="45" x2="64" y2="45" stroke="#d97706" stroke-width="2"/>
      `;
    } else if (deckType === "WI") {
      mainColor = "#450a0a";
      glowColor = "#ef4444";
      crest = `
        <circle cx="50" cy="55" r="24" fill="#1c0606" stroke="#ef4444" stroke-width="2"/>
        <path d="M50 35 C58 45 62 55 50 72 C38 55 42 45 50 35 Z" fill="#b91c1c" stroke="#fca5a5" stroke-width="1"/>
      `;
    } else if (deckType === "SH") {
      mainColor = "#2e1065";
      glowColor = "#a855f7";
      crest = `
        <polygon points="50,28 72,55 50,82 28,55" fill="#1e0b36" stroke="#c084fc" stroke-width="2"/>
        <polygon points="50,38 62,55 50,72 38,55" fill="none" stroke="#c084fc" stroke-width="1"/>
      `;
    }

    return `
      <svg width="100%" height="100%" viewBox="0 0 100 140" xmlns="http://www.w3.org/2000/svg">
        <rect width="100" height="140" rx="6" fill="${mainColor}" stroke="${glowColor}" stroke-width="2"/>
        <rect x="5" y="5" width="90" height="130" rx="4" fill="none" stroke="#110d1c" stroke-width="2"/>
        <line x1="5" y1="5" x2="95" y2="135" stroke="rgba(255,255,255,0.05)" stroke-width="1"/>
        <line x1="95" y1="5" x2="5" y2="135" stroke="rgba(255,255,255,0.05)" stroke-width="1"/>
        <g id="crest">${crest}</g>
      </svg>
    `;
  },

  getCardIllustrationSVG(card) {
    // Generate inline thematic card illustration placeholder
    const cardId = card.id || card.ID || "";
    const cardType = card.type || card.Type || "Attack";
    const isAtk = cardType === "Attack";
    const isDef = cardType === "Defense";
    
    let artColor = isAtk ? "#ef4444" : (isDef ? "#38bdf8" : "#c084fc");
    let icon = "";

    if (cardId.includes("A01") || cardId.includes("A03")) {
      icon = `<path d="M15 50 L45 20 L55 30 L25 60 Z" fill="${artColor}" stroke="#fff" stroke-width="1.5"/><line x1="12" y1="53" x2="18" y2="59" stroke="#fff" stroke-width="2"/>`;
    } else if (cardId.includes("A02") || cardId.includes("A04")) {
      icon = `<circle cx="35" cy="35" r="18" fill="none" stroke="${artColor}" stroke-width="3"/><path d="M25 35 L45 35 M35 25 L35 45" stroke="#fff" stroke-width="2"/>`;
    } else if (isDef) {
      icon = `<path d="M20 20 L50 20 L50 42 Q35 56 20 42 Z" fill="${artColor}" opacity="0.8" stroke="#fff" stroke-width="1.5"/>`;
    } else {
      icon = `<polygon points="35,15 52,45 18,45" fill="${artColor}" opacity="0.8" stroke="#fff" stroke-width="1.5"/><circle cx="35" cy="35" r="6" fill="#fff"/>`;
    }

    return `
      <svg width="100%" height="100%" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg">
        <rect width="70" height="70" fill="#0d0a14"/>
        <g transform="translate(0, 0)">${icon}</g>
      </svg>
    `;
  },

  getClassAvatarSVG(className) {
    if (className === "Bastion") {
      return `
        <svg viewBox="0 0 100 100" width="100%" height="100%">
          <rect width="100" height="100" fill="#1c1917"/>
          <polygon points="50,15 80,30 80,65 50,85 20,65 20,30" fill="#44403c" stroke="#d97706" stroke-width="3"/>
          <rect x="42" y="32" width="16" height="36" fill="#d97706"/>
          <rect x="32" y="42" width="36" height="16" fill="#d97706"/>
        </svg>
      `;
    } else if (className === "Wither") {
      return `
        <svg viewBox="0 0 100 100" width="100%" height="100%">
          <rect width="100" height="100" fill="#180404"/>
          <circle cx="50" cy="45" r="28" fill="#450a0a" stroke="#ef4444" stroke-width="3"/>
          <path d="M35 55 Q50 25 65 55 Q50 75 35 55 Z" fill="#f97316"/>
          <circle cx="42" cy="40" r="4" fill="#fef08a"/>
          <circle cx="58" cy="40" r="4" fill="#fef08a"/>
        </svg>
      `;
    } else { // Shroud
      return `
        <svg viewBox="0 0 100 100" width="100%" height="100%">
          <rect width="100" height="100" fill="#0f0728"/>
          <path d="M50 15 Q75 40 75 75 L25 75 Q25 40 50 15 Z" fill="#2e1065" stroke="#a855f7" stroke-width="3"/>
          <ellipse cx="40" cy="50" rx="6" ry="3" fill="#c084fc"/>
          <ellipse cx="60" cy="50" rx="6" ry="3" fill="#c084fc"/>
        </svg>
      `;
    }
  },

  getHeroSpriteSVG(className, state = "idle") {
    // High polish character SVG representations with 3 visual classes
    if (className === "Bastion") {
      return `
        <svg viewBox="0 0 160 200" width="100%" height="100%">
          <defs>
            <radialGradient id="bastionAura" cx="50%" cy="50%" r="50%">
              <stop offset="0%" stop-color="#d97706" stop-opacity="0.3"/>
              <stop offset="100%" stop-color="#000" stop-opacity="0"/>
            </radialGradient>
          </defs>
          <ellipse cx="80" cy="185" rx="55" ry="12" fill="#000" opacity="0.6"/>
          <!-- Greatshield -->
          <path d="M25 60 L65 50 L60 170 L25 150 Z" fill="#44403c" stroke="#d97706" stroke-width="3"/>
          <line x1="45" y1="55" x2="42" y2="160" stroke="#f59e0b" stroke-width="2"/>
          <!-- Armor Body -->
          <polygon points="65,65 115,65 125,140 55,140" fill="#292524" stroke="#78716c" stroke-width="2"/>
          <!-- Helmet -->
          <rect x="75" y="30" width="30" height="35" rx="5" fill="#57534e" stroke="#d97706" stroke-width="2"/>
          <line x1="80" y1="45" x2="100" y2="45" stroke="#fef08a" stroke-width="3"/>
          <!-- Heavy Warhammer -->
          <line x1="120" y1="120" x2="145" y2="40" stroke="#a8a29e" stroke-width="4"/>
          <rect x="135" y="30" width="22" height="20" rx="2" fill="#d97706" stroke="#fff" stroke-width="1.5"/>
        </svg>
      `;
    } else if (className === "Wither") {
      return `
        <svg viewBox="0 0 160 200" width="100%" height="100%">
          <ellipse cx="80" cy="185" rx="45" ry="10" fill="#000" opacity="0.6"/>
          <!-- Dark Cultist Robes -->
          <path d="M50 65 L110 65 L135 180 L25 180 Z" fill="#450a0a" stroke="#ef4444" stroke-width="2"/>
          <!-- Hood -->
          <path d="M80 20 Q110 40 105 75 Q80 85 55 75 Q50 40 80 20 Z" fill="#1c0606" stroke="#f97316" stroke-width="2"/>
          <circle cx="70" cy="52" r="3" fill="#fde047"/>
          <circle cx="90" cy="52" r="3" fill="#fde047"/>
          <!-- Flame Staff -->
          <line x1="40" y1="180" x2="35" y2="25" stroke="#78350f" stroke-width="4"/>
          <circle cx="35" cy="22" r="14" fill="#f97316" opacity="0.8"/>
          <circle cx="35" cy="22" r="7" fill="#fef08a"/>
        </svg>
      `;
    } else { // Shroud
      return `
        <svg viewBox="0 0 160 200" width="100%" height="100%">
          <ellipse cx="80" cy="185" rx="45" ry="10" fill="#000" opacity="0.6"/>
          <!-- Cloak & Daggers -->
          <path d="M60 55 L100 55 L125 175 L35 175 Z" fill="#2e1065" stroke="#a855f7" stroke-width="2"/>
          <!-- Mask -->
          <circle cx="80" cy="45" r="22" fill="#1e1b4b" stroke="#c084fc" stroke-width="2"/>
          <ellipse cx="73" cy="45" rx="5" ry="2" fill="#38bdf8"/>
          <ellipse cx="87" cy="45" rx="5" ry="2" fill="#38bdf8"/>
          <!-- Dual Void Daggers -->
          <polygon points="120,90 145,55 140,50 115,85" fill="#38bdf8" stroke="#fff" stroke-width="1.5"/>
          <polygon points="40,90 15,55 20,50 45,85" fill="#38bdf8" stroke="#fff" stroke-width="1.5"/>
        </svg>
      `;
    }
  },

  getEnemySpriteSVG(enemy) {
    if (enemy.isBoss) {
      if (enemy.bossId === 1) { // The Gatekeeper
        return `
          <svg viewBox="0 0 200 220" width="100%" height="100%">
            <ellipse cx="100" cy="205" rx="70" ry="15" fill="#000" opacity="0.7"/>
            <!-- Huge Stone Golem Gatekeeper -->
            <polygon points="40,50 160,50 180,180 20,180" fill="#1e293b" stroke="#64748b" stroke-width="4"/>
            <rect x="60" y="30" width="80" height="40" rx="4" fill="#0f172a" stroke="#94a3b8" stroke-width="3"/>
            <!-- Runes -->
            <circle cx="80" cy="50" r="6" fill="#38bdf8"/>
            <circle cx="120" cy="50" r="6" fill="#38bdf8"/>
            <line x1="100" y1="70" x2="100" y2="150" stroke="#38bdf8" stroke-width="3"/>
            <!-- Spikes -->
            <polygon points="30,40 45,10 60,40" fill="#475569"/>
            <polygon points="140,40 155,10 170,40" fill="#475569"/>
          </svg>
        `;
      } else if (enemy.bossId === 2) { // The Corrupted
        return `
          <svg viewBox="0 0 200 220" width="100%" height="100%">
            <ellipse cx="100" cy="205" rx="70" ry="15" fill="#000" opacity="0.7"/>
            <!-- Tendril Abomination -->
            <circle cx="100" cy="110" r="65" fill="#4a044e" stroke="#c026d3" stroke-width="4"/>
            <circle cx="80" cy="90" r="14" fill="#facc15" stroke="#000" stroke-width="2"/>
            <circle cx="80" cy="90" r="5" fill="#000"/>
            <circle cx="120" cy="95" r="10" fill="#facc15" stroke="#000" stroke-width="2"/>
            <circle cx="120" cy="95" r="4" fill="#000"/>
            <circle cx="100" cy="140" r="8" fill="#facc15"/>
            <!-- Teeth -->
            <polygon points="75,130 85,150 95,130 105,150 115,130 125,150" fill="#fef08a"/>
          </svg>
        `;
      } else { // The Void Lord
        return `
          <svg viewBox="0 0 200 220" width="100%" height="100%">
            <ellipse cx="100" cy="205" rx="80" ry="15" fill="#000" opacity="0.8"/>
            <!-- Ultimate Void Entity -->
            <path d="M50 40 Q100 10 150 40 Q180 120 150 190 Q100 210 50 190 Q20 120 50 40 Z" fill="#090514" stroke="#a855f7" stroke-width="4"/>
            <!-- Crown of Void Horns -->
            <polygon points="70,40 50,5 90,30" fill="#7e22ce"/>
            <polygon points="130,40 150,5 110,30" fill="#7e22ce"/>
            <polygon points="100,30 100,-5 105,30" fill="#c084fc"/>
            <!-- Void Eye -->
            <ellipse cx="100" cy="100" rx="30" ry="15" fill="#6b21a8" stroke="#f43f5e" stroke-width="3"/>
            <circle cx="100" cy="100" r="9" fill="#000"/>
          </svg>
        `;
      }
    }

    // Standard Enemies per Floor
    if (enemy.floor === 1) { // Void Goblin / Rat
      return `
        <svg viewBox="0 0 160 180" width="100%" height="100%">
          <ellipse cx="80" cy="165" rx="45" ry="10" fill="#000" opacity="0.6"/>
          <circle cx="80" cy="90" r="38" fill="#14532d" stroke="#4ade80" stroke-width="2"/>
          <!-- Pointy Ears -->
          <polygon points="45,80 15,50 55,65" fill="#166534" stroke="#4ade80" stroke-width="1.5"/>
          <polygon points="115,80 145,50 105,65" fill="#166534" stroke="#4ade80" stroke-width="1.5"/>
          <!-- Red glowing eyes -->
          <circle cx="68" cy="85" r="5" fill="#ef4444"/>
          <circle cx="92" cy="85" r="5" fill="#ef4444"/>
          <!-- Dagger -->
          <line x1="120" y1="130" x2="135" y2="90" stroke="#94a3b8" stroke-width="3"/>
        </svg>
      `;
    } else if (enemy.floor === 2) { // Vampire Knight / Ogre
      return `
        <svg viewBox="0 0 180 200" width="100%" height="100%">
          <ellipse cx="90" cy="185" rx="55" ry="12" fill="#000" opacity="0.6"/>
          <polygon points="50,60 130,60 145,170 35,170" fill="#312e81" stroke="#818cf8" stroke-width="3"/>
          <rect x="70" y="30" width="40" height="35" rx="4" fill="#1e1b4b" stroke="#e11d48" stroke-width="2"/>
          <line x1="78" y1="45" x2="102" y2="45" stroke="#f43f5e" stroke-width="3"/>
          <!-- Greatsword -->
          <line x1="140" y1="170" x2="155" y2="25" stroke="#cbd5e1" stroke-width="4"/>
          <rect x="145" y="45" width="20" height="6" fill="#f59e0b"/>
        </svg>
      `;
    } else { // Void Warrior / Cultist
      return `
        <svg viewBox="0 0 180 200" width="100%" height="100%">
          <ellipse cx="90" cy="185" rx="60" ry="12" fill="#000" opacity="0.7"/>
          <path d="M45 60 L135 60 L155 175 L25 175 Z" fill="#1e1035" stroke="#c084fc" stroke-width="3"/>
          <circle cx="90" cy="45" r="22" fill="#0f051d" stroke="#a855f7" stroke-width="2"/>
          <polygon points="90,20 100,5 105,25" fill="#c084fc"/>
          <circle cx="82" cy="45" r="4" fill="#a855f7"/>
          <circle cx="98" cy="45" r="4" fill="#a855f7"/>
        </svg>
      `;
    }
  }
};

// --- 2. CARD DATABASE (THE 36 CORE CARDS) ---
const CARD_DB = [
  // --- CLASS 1: THE BASTION (BA) ---
  { id: "BA-A01", deckType: "BA", name: "Slam", type: "Attack", cost: 2, atk: 3, def: 0, rarity: "Common", desc: "Deals 3 damage. If you have 30 HP, draw 1 card." },
  { id: "BA-A02", deckType: "BA", name: "Earthquake", type: "Attack", cost: 3, atk: 4, def: 0, rarity: "Common", desc: "Deals 4 damage to all enemies." },
  { id: "BA-A03", deckType: "BA", name: "Stone Fist", type: "Attack", cost: 1, atk: 2, def: 0, rarity: "Common", desc: "Deals 2 damage." },
  { id: "BA-A04", deckType: "BA", name: "Boulder", type: "Attack", cost: 4, atk: 6, def: 0, rarity: "Common", desc: "Deals 6 damage. Heavy impact." },
  { id: "BA-D01", deckType: "BA", name: "Shield Wall", type: "Defense", cost: 0, atk: 0, def: 4, rarity: "Common", desc: "Gain 4 Defense for this turn." },
  { id: "BA-D02", deckType: "BA", name: "Iron Skin", type: "Defense", cost: 2, atk: 0, def: 5, rarity: "Common", desc: "Gain 5 Defense permanently. Discard 1 card." },
  { id: "BA-D03", deckType: "BA", name: "Stand Firm", type: "Defense", cost: 1, atk: 0, def: 2, rarity: "Common", desc: "Gain 2 Defense. Blocks 1 incoming damage." },
  { id: "BA-D04", deckType: "BA", name: "Taunt", type: "Defense", cost: 2, atk: 0, def: 3, rarity: "Common", desc: "Gain 3 Defense. Stun 1 enemy for 1 turn." },
  { id: "BA-U01", deckType: "BA", name: "Search", type: "Other", cost: 2, atk: 0, def: 0, rarity: "Common", desc: "Draw 1 card. Discard hand if > 5 cards." },
  { id: "BA-U02", deckType: "BA", name: "Repair", type: "Other", cost: 3, atk: 0, def: 0, rarity: "Common", desc: "Heal 6 HP." },
  { id: "BA-U03", deckType: "BA", name: "Rally", type: "Other", cost: 1, atk: 0, def: 0, rarity: "Common", desc: "Draw 1 card. Gain 1 Energy." },
  { id: "BA-U04", deckType: "BA", name: "Loot", type: "Other", cost: 2, atk: 0, def: 0, rarity: "Common", desc: "Gain 5 Gold." },

  // --- CLASS 2: THE WITHER (WI) ---
  { id: "WI-A01", deckType: "WI", name: "Fireball", type: "Attack", cost: 2, atk: 3, def: 0, rarity: "Common", desc: "Deals 3 damage. Apply 1 Burn to target." },
  { id: "WI-A02", deckType: "WI", name: "Inferno", type: "Attack", cost: 3, atk: 4, def: 0, rarity: "Common", desc: "Deals 4 damage. Applies 3 Burn." },
  { id: "WI-A03", deckType: "WI", name: "Ember", type: "Attack", cost: 1, atk: 2, def: 0, rarity: "Common", desc: "Deals 2 damage. Deals 1 damage every turn (Burn)." },
  { id: "WI-A04", deckType: "WI", name: "Pyre", type: "Attack", cost: 4, atk: 5, def: 0, rarity: "Common", desc: "Deals 5 damage. Apply 1 Burn next turn." },
  { id: "WI-D01", deckType: "WI", name: "Scorch Shield", type: "Defense", cost: 2, atk: 0, def: 3, rarity: "Common", desc: "Gain 3 Defense. Block 1 Burn damage." },
  { id: "WI-D02", deckType: "WI", name: "Heat Resist", type: "Defense", cost: 1, atk: 0, def: 1, rarity: "Common", desc: "Gain 1 Defense. Gain 1 Energy." },
  { id: "WI-D03", deckType: "WI", name: "Smoke", type: "Defense", cost: 2, atk: 0, def: 4, rarity: "Common", desc: "Gain 4 Defense. Block 1 Burn damage." },
  { id: "WI-D04", deckType: "WI", name: "Endure", type: "Defense", cost: 3, atk: 0, def: 2, rarity: "Common", desc: "Gain 2 Defense. Heal 2 HP." },
  { id: "WI-U01", deckType: "WI", name: "Poison", type: "Other", cost: 2, atk: 0, def: 0, rarity: "Common", desc: "Apply 1 Poison to target." },
  { id: "WI-U02", deckType: "WI", name: "Burn", type: "Other", cost: 3, atk: 0, def: 0, rarity: "Common", desc: "Deal 3 damage + 2 Burn to all enemies." },
  { id: "WI-U03", deckType: "WI", name: "Slow", type: "Other", cost: 1, atk: 0, def: 0, rarity: "Common", desc: "Draw 1 card. Target Stunned next turn." },
  { id: "WI-U04", deckType: "WI", name: "Wither", type: "Other", cost: 2, atk: 0, def: 0, rarity: "Common", desc: "Heal 5 HP. Reduce enemy Attack by 1." },

  // --- CLASS 3: THE SHROUD (SH) ---
  { id: "SH-A01", deckType: "SH", name: "Backstab", type: "Attack", cost: 2, atk: 4, def: 0, rarity: "Common", desc: "Deals 4 damage (+1 extra damage if enemy has no Armor)." },
  { id: "SH-A02", deckType: "SH", name: "Shadow Bolt", type: "Attack", cost: 3, atk: 5, def: 0, rarity: "Common", desc: "Deals 5 damage. Target cannot block (Pierces)." },
  { id: "SH-A03", deckType: "SH", name: "Silence", type: "Attack", cost: 1, atk: 3, def: 0, rarity: "Common", desc: "Deals 3 damage. Silences enemy abilities." },
  { id: "SH-A04", deckType: "SH", name: "Vengeance", type: "Attack", cost: 3, atk: 6, def: 0, rarity: "Common", desc: "Deals 6 damage. Gain 2 Energy." },
  { id: "SH-D01", deckType: "SH", name: "Blur", type: "Defense", cost: 3, atk: 0, def: 2, rarity: "Common", desc: "Gain 2 Defense. Ignore next attack completely." },
  { id: "SH-D02", deckType: "SH", name: "Step", type: "Defense", cost: 2, atk: 0, def: 3, rarity: "Common", desc: "Gain 3 Defense. Gain 1 Energy." },
  { id: "SH-D03", deckType: "SH", name: "Evasion", type: "Defense", cost: 1, atk: 0, def: 1, rarity: "Common", desc: "Gain 1 Defense. Skip enemy next action." },
  { id: "SH-D04", deckType: "SH", name: "Phantom", type: "Defense", cost: 2, atk: 0, def: 4, rarity: "Common", desc: "Gain 4 Defense. Enter Ghost form for 1 turn." },
  { id: "SH-U01", deckType: "SH", name: "Dash", type: "Other", cost: 1, atk: 0, def: 0, rarity: "Common", desc: "Gain 1 Energy. Skip enemy attack." },
  { id: "SH-U02", deckType: "SH", name: "Teleport", type: "Other", cost: 2, atk: 0, def: 0, rarity: "Common", desc: "Move to back row. Deal 2 direct damage." },
  { id: "SH-U03", deckType: "SH", name: "Hide", type: "Other", cost: 2, atk: 0, def: 0, rarity: "Common", desc: "Gain 1 Defense. Discard 1 card. Draw 2 cards." },
  { id: "SH-U04", deckType: "SH", name: "Assassinate", type: "Other", cost: 3, atk: 8, def: 0, rarity: "Common", desc: "Deal 8 damage. Cannot be blocked this turn." }
];

// --- 3. MAIN GAME STATE CONTROLLER ---
class GameEngine {
  constructor() {
    this.selectedClass = "Bastion";
    this.player = null;
    this.enemy = null;
    this.currentFloor = 1;
    this.currentRoom = 1; // 1-3 normal encounters, 4 is Floor Boss
    this.isPlayerTurn = true;
    this.isProcessing = false;
    this.shopFilter = "ALL";
    
    this.initMenuIcons();
  }

  initMenuIcons() {
    document.getElementById("bastion-icon-svg").innerHTML = SVG_ASSETS.getClassAvatarSVG("Bastion");
    document.getElementById("wither-icon-svg").innerHTML = SVG_ASSETS.getClassAvatarSVG("Wither");
    document.getElementById("shroud-icon-svg").innerHTML = SVG_ASSETS.getClassAvatarSVG("Shroud");
  }

  selectClass(className) {
    this.selectedClass = className;
    document.querySelectorAll(".class-card").forEach(c => c.classList.remove("selected"));
    document.getElementById(`card-${className.toLowerCase()}`).classList.add("selected");
  }

  startRun() {
    // Class starter stats per GDD
    let hp = 30;
    let maxEnergy = 5;
    let startEnergy = 3;
    let handSize = 4;
    let prefix = "BA";

    if (this.selectedClass === "Bastion") {
      hp = 35;
      startEnergy = 3;
      prefix = "BA";
    } else if (this.selectedClass === "Wither") {
      hp = 30;
      startEnergy = 5;
      prefix = "WI";
    } else if (this.selectedClass === "Shroud") {
      hp = 30;
      startEnergy = 5;
      prefix = "SH";
    }

    // Build Starter Deck (12 unique class cards)
    const starterCards = CARD_DB.filter(c => c.deckType === prefix);
    const deck = starterCards.map(c => ({ ...c }));

    this.player = {
      className: this.selectedClass,
      hp: hp,
      maxHp: hp,
      energy: startEnergy,
      maxEnergy: maxEnergy,
      defense: 0,
      permanentDefense: 0,
      handSize: handSize,
      gold: 0,
      deck: deck,
      hand: [],
      discardPile: [],
      inventory: {}, // Map of cardId -> count owned
      status: {
        burn: 0,
        poison: 0,
        stun: false,
        silence: false,
        ghost: false,
        ignoreNextAttack: false
      }
    };

    // Initialize inventory count
    starterCards.forEach(c => {
      this.player.inventory[c.id] = 1;
    });

    this.currentFloor = 1;
    this.currentRoom = 1;

    // Switch screen
    document.getElementById("screen-menu").classList.add("hidden");
    document.getElementById("screen-victory").classList.add("hidden");
    document.getElementById("screen-gameover").classList.add("hidden");

    this.log(`Descending into Floor 1 of Aethelgard as ${this.selectedClass}...`, "log-system");
    this.setupEncounter();
  }

  abandonRun() {
    document.getElementById("screen-menu").classList.remove("hidden");
    document.getElementById("screen-victory").classList.add("hidden");
    document.getElementById("screen-gameover").classList.add("hidden");
    this.toggleShopModal(false);
    this.toggleDeckModal(false);
  }

  setupEncounter() {
    const isBoss = (this.currentRoom === 4);
    let enemyName = "";
    let enemyHp = 20;
    let enemyDmg = 3;

    if (!isBoss) {
      if (this.currentFloor === 1) {
        enemyHp = 20;
        enemyDmg = 3;
        enemyName = Math.random() > 0.5 ? "Void Goblin" : "Shadow Rat";
      } else if (this.currentFloor === 2) {
        enemyHp = 30;
        enemyDmg = 5;
        enemyName = Math.random() > 0.5 ? "Vampire Knight" : "Void Ogre";
      } else {
        enemyHp = 40;
        enemyDmg = 8;
        enemyName = Math.random() > 0.5 ? "Void Warrior" : "Dusk Cultist";
      }
    } else {
      // Boss Encounters
      enemyHp = (this.currentFloor === 3) ? 40 : 80;
      enemyDmg = 15;
      if (this.currentFloor === 1) enemyName = "The Gatekeeper";
      else if (this.currentFloor === 2) enemyName = "The Corrupted";
      else enemyName = "The Void Lord";
    }

    this.enemy = {
      name: enemyName,
      hp: enemyHp,
      maxHp: enemyHp,
      damage: enemyDmg,
      defense: 0,
      floor: this.currentFloor,
      isBoss: isBoss,
      bossId: isBoss ? this.currentFloor : null,
      status: {
        burn: 0,
        poison: 0,
        stun: false,
        silence: false,
        skipNextTurn: false,
        delayedPyre: false
      }
    };

    // Update Floor Boss Goal text
    const bossNames = ["Floor 1: The Gatekeeper (Shield Master)", "Floor 2: The Corrupted (Energy Siphon)", "Floor 3: The Void Lord (Regen Beast)"];
    document.getElementById("floor-boss-brief").textContent = bossNames[this.currentFloor - 1];

    // Reset Turn Defense
    this.player.defense = this.player.permanentDefense;
    
    // Draw initial hand
    this.reshuffleDiscardIntoDeck();
    this.player.hand = [];
    this.drawCards(this.player.handSize);

    this.isPlayerTurn = true;
    this.isProcessing = false;
    this.updateHUD();
    this.renderHand();
    this.renderSprites();
    this.log(`Encounter started: ${this.enemy.name} (${this.enemy.hp} HP)!`, isBoss ? "log-enemy" : "log-system");
  }

  reshuffleDiscardIntoDeck() {
    if (this.player.discardPile.length > 0) {
      this.player.deck.push(...this.player.discardPile);
      this.player.discardPile = [];
    }
  }

  drawCards(count) {
    for (let i = 0; i < count; i++) {
      if (this.player.hand.length >= 5) break; // Hard hand limit in UI
      if (this.player.deck.length === 0) {
        this.reshuffleDiscardIntoDeck();
      }
      if (this.player.deck.length > 0) {
        // Draw random card from deck pool
        const randIndex = Math.floor(Math.random() * this.player.deck.length);
        const card = this.player.deck.splice(randIndex, 1)[0];
        this.player.hand.push(card);
      }
    }
  }

  // --- CARD PLAY RESOLUTION ---
  playCard(index) {
    if (!this.isPlayerTurn || this.isProcessing) return;
    const card = this.player.hand[index];
    if (!card) return;

    if (this.player.energy < card.cost) {
      this.showFloatingText("Not Enough Energy!", "#ef4444", "player");
      return;
    }

    // Silence check for abilities
    if (this.player.status.silence && card.type === "Other") {
      this.showFloatingText("Silenced!", "#9ca3af", "player");
      return;
    }

    this.player.energy -= card.cost;
    // Remove from hand and move to discard
    this.player.hand.splice(index, 1);
    this.player.discardPile.push(card);

    // Hero attack animation
    const heroBox = document.getElementById("hero-sprite-container");
    heroBox.classList.add("hero-attack");
    setTimeout(() => heroBox.classList.remove("hero-attack"), 400);

    this.log(`You played [${card.name}] (Cost ${card.cost} Energy)`, "log-player");
    this.resolveCardEffect(card);

    this.updateHUD();
    this.renderHand();

    // Check if enemy died immediately
    if (this.enemy.hp <= 0) {
      this.handleEnemyDeath();
    }
  }

  resolveCardEffect(card) {
    // 1. Attack Type
    if (card.type === "Attack") {
      let dmg = card.atk;
      let bypassDefense = false;

      // Special Card Logic
      if (card.id === "BA-A01") { // Slam: If 30 HP, draw 1
        if (this.player.hp >= 30) this.drawCards(1);
      } else if (card.id === "WI-A01") { // Fireball: 1 Burn
        this.enemy.status.burn += 1;
      } else if (card.id === "WI-A02") { // Inferno: 3 Burn
        this.enemy.status.burn += 3;
      } else if (card.id === "WI-A03") { // Ember: 1 continuous Burn
        this.enemy.status.burn += 1;
      } else if (card.id === "WI-A04") { // Pyre: Burn next turn
        this.enemy.status.delayedPyre = true;
      } else if (card.id === "SH-A01") { // Backstab: +1 dmg if target has no armor
        if (this.enemy.defense <= 0) dmg += 1;
      } else if (card.id === "SH-A02") { // Shadow Bolt: Cannot block
        bypassDefense = true;
      } else if (card.id === "SH-A03") { // Silence: Target loses abilities
        this.enemy.status.silence = true;
      } else if (card.id === "SH-A04") { // Vengeance: Gain 2 Energy
        this.player.energy = Math.min(this.player.maxEnergy, this.player.energy + 2);
      }

      this.dealDamageToEnemy(dmg, bypassDefense);
    }
    // 2. Defense Type
    else if (card.type === "Defense") {
      if (card.def > 0) {
        if (card.id === "BA-D02") { // Iron Skin: permanent defense, discard 1
          this.player.permanentDefense += card.def;
          this.player.defense += card.def;
          if (this.player.hand.length > 0) {
            const discarded = this.player.hand.pop();
            this.player.discardPile.push(discarded);
            this.log(`Iron Skin permanently hardened! Discarded ${discarded.name}.`, "log-player");
          }
        } else {
          this.player.defense += card.def;
        }
      }

      if (card.id === "BA-D04") { // Taunt: Stun 1 enemy
        this.enemy.status.stun = true;
        this.log(`Enemy is Taunted & Stunned for 1 turn!`, "log-status");
      } else if (card.id === "WI-D02" || card.id === "SH-D02") { // Heat Resist / Step: Gain 1 Energy
        this.player.energy = Math.min(this.player.maxEnergy, this.player.energy + 1);
      } else if (card.id === "WI-D04") { // Endure: Heal 2 HP
        this.player.hp = Math.min(this.player.maxHp, this.player.hp + 2);
      } else if (card.id === "SH-D01") { // Blur: Ignore next attack
        this.player.status.ignoreNextAttack = true;
      } else if (card.id === "SH-D03") { // Evasion: Skip enemy action
        this.enemy.status.skipNextTurn = true;
      } else if (card.id === "SH-D04") { // Phantom: Ghost form
        this.player.status.ghost = true;
      }
      this.showFloatingText(`+${card.def} DEF`, "#38bdf8", "player");
    }
    // 3. Other / Utility Type
    else if (card.type === "Other") {
      if (card.id === "BA-U01") { // Search: Draw 1, discard if > 5
        this.drawCards(1);
        while (this.player.hand.length > 5) {
          this.player.discardPile.push(this.player.hand.pop());
        }
      } else if (card.id === "BA-U02") { // Repair: Heal 6 HP
        this.player.hp = Math.min(this.player.maxHp, this.player.hp + 6);
        this.showFloatingText("+6 HP", "#4ade80", "player");
      } else if (card.id === "BA-U03") { // Rally: Draw 1, Gain 1 Energy
        this.drawCards(1);
        this.player.energy = Math.min(this.player.maxEnergy, this.player.energy + 1);
      } else if (card.id === "BA-U04") { // Loot: Gain 5 Gold
        this.player.gold += 5;
        this.showFloatingText("+5 Gold", "#facc15", "player");
      } else if (card.id === "WI-U01") { // Poison: Apply 1 Poison
        this.enemy.status.poison += 1;
        this.showFloatingText("+1 Poison", "#22c55e", "enemy");
      } else if (card.id === "WI-U02") { // Burn: 3 dmg + 2 Burn
        this.dealDamageToEnemy(3, false);
        this.enemy.status.burn += 2;
      } else if (card.id === "WI-U03") { // Slow: Draw 1, Stun enemy
        this.drawCards(1);
        this.enemy.status.stun = true;
      } else if (card.id === "WI-U04") { // Wither: Heal 5, reduce enemy atk
        this.player.hp = Math.min(this.player.maxHp, this.player.hp + 5);
        this.enemy.damage = Math.max(1, this.enemy.damage - 1);
        this.showFloatingText("+5 HP", "#4ade80", "player");
      } else if (card.id === "SH-U01") { // Dash: Gain 1 Energy, Skip enemy
        this.player.energy = Math.min(this.player.maxEnergy, this.player.energy + 1);
        this.enemy.status.skipNextTurn = true;
      } else if (card.id === "SH-U02") { // Teleport: 2 direct dmg
        this.dealDamageToEnemy(2, true);
      } else if (card.id === "SH-U03") { // Hide: +1 Def, Discard 1, Draw 2
        this.player.defense += 1;
        if (this.player.hand.length > 0) this.player.discardPile.push(this.player.hand.pop());
        this.drawCards(2);
      } else if (card.id === "SH-U04") { // Assassinate: 8 damage unblockable
        this.dealDamageToEnemy(8, true);
      }
    }
  }

  dealDamageToEnemy(dmg, bypassDefense = false) {
    let finalDamage = dmg;
    
    // Boss 1 unique mechanic: Blocks 5 damage per turn until HP < 20
    if (this.enemy.isBoss && this.enemy.bossId === 1 && this.enemy.hp >= 20 && !bypassDefense) {
      finalDamage = Math.max(0, dmg - 5);
      this.log(`The Gatekeeper's stone bulwark absorbed 5 damage!`, "log-enemy");
    }

    if (!bypassDefense && this.enemy.defense > 0) {
      if (this.enemy.defense >= finalDamage) {
        this.enemy.defense -= finalDamage;
        this.showFloatingText(`Blocked (${finalDamage})`, "#60a5fa", "enemy");
        finalDamage = 0;
      } else {
        finalDamage -= this.enemy.defense;
        this.enemy.defense = 0;
      }
    }

    if (finalDamage > 0) {
      this.enemy.hp -= finalDamage;
      this.showFloatingText(`-${finalDamage}`, "#ef4444", "enemy");
      
      const enemyBox = document.getElementById("enemy-sprite-container");
      enemyBox.classList.add("enemy-hit");
      setTimeout(() => enemyBox.classList.remove("enemy-hit"), 400);
    }
  }

  // --- TURN CYCLE & ENEMY RESOLUTION ---
  endTurn() {
    if (!this.isPlayerTurn || this.isProcessing) return;
    this.isPlayerTurn = false;
    this.isProcessing = true;
    this.updateHUD();

    document.getElementById("turn-dot").classList.add("enemy");
    document.getElementById("turn-status-label").textContent = "ENEMY ACTION";
    document.getElementById("btn-end-turn").disabled = true;

    // 1. Resolve Player End-Of-Turn Status (Poison / Burn)
    if (this.player.status.poison > 0) {
      this.player.hp -= this.player.status.poison;
      this.log(`Poison inflicted ${this.player.status.poison} damage on you!`, "log-status");
      this.showFloatingText(`-${this.player.status.poison} Poison`, "#22c55e", "player");
    }
    if (this.player.status.burn > 0) {
      this.player.hp -= this.player.status.burn;
      this.log(`Burn scorched you for ${this.player.status.burn} damage!`, "log-status");
      this.showFloatingText(`-${this.player.status.burn} Burn`, "#f97316", "player");
    }

    if (this.player.hp <= 0) {
      this.handleGameOver();
      return;
    }

    // 2. Enemy Step
    setTimeout(() => {
      this.resolveEnemyTurn();
    }, 800);
  }

  resolveEnemyTurn() {
    if (this.enemy.hp <= 0) return;

    // Apply Enemy Statuses (Burn / Poison)
    if (this.enemy.status.poison > 0) {
      this.enemy.hp -= this.enemy.status.poison;
      this.log(`${this.enemy.name} took ${this.enemy.status.poison} Poison damage!`, "log-status");
      this.showFloatingText(`-${this.enemy.status.poison} Poison`, "#22c55e", "enemy");
    }
    if (this.enemy.status.burn > 0) {
      this.enemy.hp -= this.enemy.status.burn;
      this.log(`${this.enemy.name} took ${this.enemy.status.burn} Burn damage!`, "log-status");
      this.showFloatingText(`-${this.enemy.status.burn} Burn`, "#f97316", "enemy");
    }
    if (this.enemy.status.delayedPyre) {
      this.enemy.hp -= 1;
      this.enemy.status.delayedPyre = false;
      this.showFloatingText("-1 Pyre", "#ea580c", "enemy");
    }

    // Boss 3 Unique: +10 HP per turn Regen
    if (this.enemy.isBoss && this.enemy.bossId === 3) {
      this.enemy.hp = Math.min(this.enemy.maxHp + 40, this.enemy.hp + 10);
      this.log(`The Void Lord regenerated +10 HP from the Nether!`, "log-enemy");
      this.showFloatingText("+10 Regen", "#a855f7", "enemy");
    }

    // Check if DoT killed enemy
    if (this.enemy.hp <= 0) {
      this.handleEnemyDeath();
      return;
    }

    // Check Stuns or Skips
    if (this.enemy.status.stun) {
      this.log(`${this.enemy.name} is STUNNED and cannot act!`, "log-status");
      this.enemy.status.stun = false;
      this.finishEnemyTurn();
      return;
    }
    if (this.enemy.status.skipNextTurn) {
      this.log(`${this.enemy.name}'s attack was avoided!`, "log-status");
      this.enemy.status.skipNextTurn = false;
      this.finishEnemyTurn();
      return;
    }

    // Boss 2 Unique Attack: Deals 20 damage if Player Energy < 3
    let incomingDamage = this.enemy.damage;
    if (this.enemy.isBoss && this.enemy.bossId === 2) {
      if (this.player.energy < 3) {
        incomingDamage = 20;
        this.log(`The Corrupted feeds on low energy! Deals 20 Cataclysmic Damage!`, "log-enemy");
      }
    }

    // Enemy Animation
    const enemyBox = document.getElementById("enemy-sprite-container");
    enemyBox.classList.add("enemy-attack");
    setTimeout(() => enemyBox.classList.remove("enemy-attack"), 400);

    // Apply Damage to Player (Block Math: Incoming - Defense)
    if (this.player.status.ghost) {
      this.log(`You are in Ghost form! Attack passed right through.`, "log-player");
      this.showFloatingText("Ghosted!", "#38bdf8", "player");
      this.player.status.ghost = false;
    } else if (this.player.status.ignoreNextAttack) {
      this.log(`Blur evaded the enemy strike!`, "log-player");
      this.showFloatingText("Dodged!", "#38bdf8", "player");
      this.player.status.ignoreNextAttack = false;
    } else {
      let finalDmg = incomingDamage;
      if (this.player.defense > 0) {
        if (this.player.defense >= finalDmg) {
          this.player.defense -= finalDmg;
          this.showFloatingText(`Blocked (${finalDmg})`, "#60a5fa", "player");
          finalDmg = 0;
        } else {
          finalDmg -= this.player.defense;
          this.player.defense = 0;
        }
      }

      if (finalDmg > 0) {
        this.player.hp -= finalDmg;
        this.showFloatingText(`-${finalDmg}`, "#ef4444", "player");
        this.log(`${this.enemy.name} strikes for ${finalDmg} damage!`, "log-enemy");
        
        const heroBox = document.getElementById("hero-sprite-container");
        heroBox.classList.add("hero-hit");
        setTimeout(() => heroBox.classList.remove("hero-hit"), 400);
      }
    }

    if (this.player.hp <= 0) {
      this.handleGameOver();
      return;
    }

    setTimeout(() => {
      this.finishEnemyTurn();
    }, 600);
  }

  finishEnemyTurn() {
    // 3. Start Next Player Turn: Recover 1 Energy (if < max), reset temp defense, draw up to hand size
    this.player.energy = Math.min(this.player.maxEnergy, this.player.energy + 1);
    this.player.defense = this.player.permanentDefense; // Retain permanent defense (e.g. Iron Skin)
    this.player.status.silence = false;

    // Draw cards up to hand limit
    const needed = this.player.handSize - this.player.hand.length;
    if (needed > 0) {
      this.drawCards(needed);
    }

    this.isPlayerTurn = true;
    this.isProcessing = false;
    document.getElementById("turn-dot").classList.remove("enemy");
    document.getElementById("turn-status-label").textContent = "PLAYER TURN";
    document.getElementById("btn-end-turn").disabled = false;

    this.updateHUD();
    this.renderHand();
    this.renderSprites();
  }

  handleEnemyDeath() {
    const goldReward = this.enemy.isBoss ? 15 : 5;
    this.player.gold += goldReward;
    this.log(`${this.enemy.name} was vanquished! Gained +${goldReward} Gold.`, "log-system");
    this.showFloatingText(`+${goldReward} Gold`, "#facc15", "player");

    setTimeout(() => {
      if (this.enemy.isBoss && this.currentFloor === 3) {
        // WIN CONDITION: Defeated Boss 3
        this.handleVictory();
      } else {
        // Advance Room or Floor
        if (this.currentRoom >= 4) {
          // Boss slain -> next floor
          this.currentFloor += 1;
          this.currentRoom = 1;
          this.log(`FLOOR CLEARED! Descending to Floor ${this.currentFloor}...`, "log-system");
        } else {
          this.currentRoom += 1;
        }
        this.setupEncounter();
      }
    }, 1200);
  }

  handleGameOver() {
    this.log("You have perished in the darkness.", "log-enemy");
    document.getElementById("screen-gameover").classList.remove("hidden");
  }

  handleVictory() {
    this.log("VICTORY! The Void Lord is defeated!", "log-system");
    document.getElementById("screen-victory").classList.remove("hidden");
  }

  // --- 4. SHOP & ECONOMY SYSTEM ---
  toggleShopModal(open) {
    const modal = document.getElementById("shop-modal");
    if (open) {
      modal.classList.add("active");
      this.renderShopGrid();
    } else {
      modal.classList.remove("active");
    }
  }

  toggleDeckModal(open) {
    const modal = document.getElementById("deck-modal");
    if (open) {
      modal.classList.add("active");
      this.renderDeckGrid();
    } else {
      modal.classList.remove("active");
    }
  }

  filterShop(category) {
    this.shopFilter = category;
    document.querySelectorAll(".shop-tab-btn").forEach(b => b.classList.remove("active"));
    if (category === "ALL") document.getElementById("tab-all").classList.add("active");
    else if (category === "BA") document.getElementById("tab-bastion").classList.add("active");
    else if (category === "WI") document.getElementById("tab-wither").classList.add("active");
    else if (category === "SH") document.getElementById("tab-shroud").classList.add("active");
    this.renderShopGrid();
  }

  getCardPurchaseCost(cardId) {
    const owned = this.player.inventory[cardId] || 0;
    // Per GDD: If you own 3 copies, cost for 4th is 10 Gold. Base is 1 Gold.
    // Scaling formula: Cost = Base + (Count * 1). If count == 3 -> 10 Gold.
    if (owned >= 3) return 10;
    return Math.min(50, 1 + owned);
  }

  buyCard(cardId) {
    const cardData = CARD_DB.find(c => c.id === cardId);
    if (!cardData) return;

    const owned = this.player.inventory[cardId] || 0;
    if (owned >= 5) {
      this.showFloatingText("Max 5 Copies!", "#ef4444", "player");
      return;
    }

    const cost = this.getCardPurchaseCost(cardId);
    if (this.player.gold < cost) {
      this.showFloatingText("Not Enough Gold!", "#ef4444", "player");
      return;
    }

    // Execute Transaction
    this.player.gold -= cost;
    this.player.inventory[cardId] = owned + 1;
    this.player.deck.push({ ...cardData });

    this.log(`Purchased [${cardData.name}] for ${cost} Gold. (Total: ${this.player.inventory[cardId]}/5)`, "log-player");
    this.updateHUD();
    this.renderShopGrid();
  }

  renderShopGrid() {
    document.getElementById("shop-gold-display").textContent = `${this.player.gold} G`;
    const container = document.getElementById("shop-items-grid");
    container.innerHTML = "";

    const filtered = CARD_DB.filter(c => {
      if (this.shopFilter === "ALL") return true;
      return c.deckType === this.shopFilter;
    });

    filtered.forEach(card => {
      const owned = this.player.inventory[card.id] || 0;
      const cost = this.getCardPurchaseCost(card.id);
      const isMaxed = owned >= 5;
      const canAfford = this.player.gold >= cost && !isMaxed;

      const itemEl = document.createElement("div");
      itemEl.className = `shop-item-card ${isMaxed ? 'maxed' : ''}`;
      itemEl.innerHTML = `
        <div class="shop-item-info">
          <div style="width:50px; height:65px; flex-shrink:0;">
            ${SVG_ASSETS.getCardFrameSVG(card.deckType, card.type)}
          </div>
          <div style="flex:1;">
            <div style="font-size:13px; font-weight:700; color:#fff;">${card.name}</div>
            <div style="font-size:10px; color:#94a3b8; margin-bottom:4px;">Cost: ${card.cost} Energy | ${card.type}</div>
            <div style="font-family:var(--font-body); font-size:11px; color:#cbd5e1; line-height:1.2;">${card.desc}</div>
          </div>
        </div>
        <div class="shop-buy-row">
          <span class="shop-owned-count">Owned: <strong>${owned}</strong>/5</span>
          <button class="btn-gothic ${canAfford ? 'btn-gold' : ''}" style="padding:4px 12px; font-size:11px;" 
            ${!canAfford ? 'disabled' : ''} onclick="game.buyCard('${card.id}')">
            ${isMaxed ? 'MAX LIMIT' : `Buy (${cost} Gold)`}
          </button>
        </div>
      `;
      container.appendChild(itemEl);
    });
  }

  renderDeckGrid() {
    const container = document.getElementById("deck-items-grid");
    container.innerHTML = "";
    document.getElementById("deck-view-count").textContent = this.player.deck.length + this.player.hand.length + this.player.discardPile.length;

    // Group cards by ID
    const cardMap = {};
    [...this.player.deck, ...this.player.hand, ...this.player.discardPile].forEach(c => {
      if (!cardMap[c.id]) cardMap[c.id] = { card: c, count: 0 };
      cardMap[c.id].count++;
    });

    Object.values(cardMap).forEach(item => {
      const card = item.card;
      const itemEl = document.createElement("div");
      itemEl.className = "shop-item-card";
      itemEl.innerHTML = `
        <div class="shop-item-info">
          <div style="width:48px; height:66px; flex-shrink:0; border-radius:4px; overflow:hidden; box-shadow:0 2px 6px rgba(0,0,0,0.5);" title="Card Back: ${card.deckType}">
            ${SVG_ASSETS.getCardBackSVG(card.deckType)}
          </div>
          <div style="flex:1;">
            <div style="font-size:13px; font-weight:700; color:#fff;">${card.name}</div>
            <div style="font-size:10px; color:#94a3b8; margin-bottom:4px;">Energy: ${card.cost} | ${card.type}</div>
            <div style="font-family:var(--font-body); font-size:11px; color:#cbd5e1; line-height:1.2;">${card.desc}</div>
          </div>
        </div>
        <div class="shop-buy-row">
          <span class="shop-owned-count" style="color:#d4af37;">Copies in deck: <strong>${item.count}</strong></span>
        </div>
      `;
      container.appendChild(itemEl);
    });
  }

  // --- 5. UI & HUD RENDERING ---
  updateHUD() {
    if (!this.player) return;

    // Top Bar
    document.getElementById("hud-gold-text").textContent = `${this.player.gold} Gold`;
    document.getElementById("hud-floor-num").textContent = this.currentFloor;
    document.getElementById("hud-room-num").textContent = this.currentRoom;
    document.getElementById("hud-deck-count").textContent = this.player.deck.length;

    // Hero Info
    document.getElementById("hero-name-label").textContent = this.player.className;
    document.getElementById("hero-hp-val").textContent = Math.max(0, this.player.hp);
    document.getElementById("hero-maxhp-val").textContent = this.player.maxHp;
    document.getElementById("hero-def-badge").textContent = `Def: ${this.player.defense}`;
    
    const hpPct = Math.max(0, Math.min(100, (this.player.hp / this.player.maxHp) * 100));
    document.getElementById("hero-hp-bar").style.width = `${hpPct}%`;
    document.getElementById("hero-handlim-val").textContent = this.player.handSize;

    // Hero Statuses
    const heroStatusBox = document.getElementById("hero-status-list");
    heroStatusBox.innerHTML = "";
    if (this.player.status.burn > 0) heroStatusBox.innerHTML += `<span class="status-pill burn">🔥 Burn (${this.player.status.burn})</span>`;
    if (this.player.status.poison > 0) heroStatusBox.innerHTML += `<span class="status-pill poison">🧪 Poison (${this.player.status.poison})</span>`;
    if (this.player.status.ghost) heroStatusBox.innerHTML += `<span class="status-pill ghost">👻 Ghost</span>`;
    if (this.player.status.ignoreNextAttack) heroStatusBox.innerHTML += `<span class="status-pill ghost">⚡ Blur</span>`;

    // Energy Orb
    document.getElementById("energy-val").textContent = this.player.energy;
    document.getElementById("energy-max-val").textContent = this.player.maxEnergy;

    // Enemy Info
    if (this.enemy) {
      document.getElementById("enemy-name-text").textContent = this.enemy.name;
      document.getElementById("enemy-boss-badge").style.display = this.enemy.isBoss ? "inline-block" : "none";
      document.getElementById("enemy-hp-val").textContent = Math.max(0, this.enemy.hp);
      document.getElementById("enemy-maxhp-val").textContent = this.enemy.maxHp;
      document.getElementById("enemy-def-val").textContent = this.enemy.defense;

      const enemyHpPct = Math.max(0, Math.min(100, (this.enemy.hp / this.enemy.maxHp) * 100));
      document.getElementById("enemy-hp-bar").style.width = `${enemyHpPct}%`;

      // Intent Box
      let intentText = `⚔️ Intent: Attack ${this.enemy.damage} DMG`;
      if (this.enemy.isBoss && this.enemy.bossId === 2 && this.player.energy < 3) {
        intentText = `⚠️ Intent: VOID CATACLYSM 20 DMG!`;
      } else if (this.enemy.status.stun) {
        intentText = `💫 Intent: STUNNED (Cannot Act)`;
      } else if (this.enemy.status.skipNextTurn) {
        intentText = `💨 Intent: EVADED (Skipping Action)`;
      }
      document.getElementById("enemy-intent-box").innerHTML = intentText;

      // Enemy Statuses
      const enemyStatusBox = document.getElementById("enemy-status-list");
      enemyStatusBox.innerHTML = "";
      if (this.enemy.status.burn > 0) enemyStatusBox.innerHTML += `<span class="status-pill burn">🔥 Burn (${this.enemy.status.burn})</span>`;
      if (this.enemy.status.poison > 0) enemyStatusBox.innerHTML += `<span class="status-pill poison">🧪 Poison (${this.enemy.status.poison})</span>`;
      if (this.enemy.status.stun) enemyStatusBox.innerHTML += `<span class="status-pill stun">💫 Stunned</span>`;
    }
  }

  renderHand() {
    const container = document.getElementById("hand-container");
    container.innerHTML = "";
    document.getElementById("hand-count-text").textContent = this.player.hand.length;

    this.player.hand.forEach((card, index) => {
      const isPlayable = this.player.energy >= card.cost && this.isPlayerTurn && !this.isProcessing;
      const cardEl = document.createElement("div");
      cardEl.className = `aethel-card card-type-${card.type} ${!isPlayable ? 'unplayable' : ''}`;
      
      const statLabel = card.type === "Attack" 
        ? `<span class="card-stat-pill stat-atk">⚔️ ${card.atk} ATK</span>`
        : (card.type === "Defense" ? `<span class="card-stat-pill stat-def">🛡️ ${card.def} DEF</span>` : `<span class="card-stat-pill" style="background:rgba(168,85,247,0.25); color:#d8b4fe;">✨ OTHER</span>`);

      cardEl.innerHTML = `
        <div class="card-art-box">
          ${SVG_ASSETS.getCardIllustrationSVG(card)}
        </div>
        <div class="card-details">
          <div class="card-head">
            <span class="card-title">${card.name}</span>
            <div class="card-cost-badge">${card.cost}</div>
          </div>
          <div class="card-desc">${card.desc}</div>
          <div class="card-footer">
            ${statLabel}
            <span style="font-size:9px; color:#94a3b8;">${card.deckType}</span>
          </div>
        </div>
      `;

      cardEl.onclick = () => this.playCard(index);
      container.appendChild(cardEl);
    });
  }

  renderSprites() {
    if (!this.player || !this.enemy) return;
    document.getElementById("hero-portrait-slot").innerHTML = SVG_ASSETS.getClassAvatarSVG(this.player.className);
    document.getElementById("hero-sprite-container").innerHTML = SVG_ASSETS.getHeroSpriteSVG(this.player.className);
    document.getElementById("enemy-sprite-container").innerHTML = SVG_ASSETS.getEnemySpriteSVG(this.enemy);
  }

  showFloatingText(text, color, target) {
    const parent = document.getElementById(target === "player" ? "hero-sprite-container" : "enemy-sprite-container");
    if (!parent) return;

    const el = document.createElement("div");
    el.className = "floating-text";
    el.textContent = text;
    el.style.color = color;
    el.style.left = "50%";
    el.style.top = "40%";
    el.style.transform = "translateX(-50%)";

    parent.appendChild(el);
    setTimeout(() => el.remove(), 1000);
  }

  log(msg, styleClass = "") {
    const box = document.getElementById("combat-log-box");
    const entry = document.createElement("div");
    entry.className = `log-entry ${styleClass}`;
    entry.textContent = msg;
    box.appendChild(entry);
    box.scrollTop = box.scrollHeight;
  }
}

// Global initialization
let game;
window.addEventListener("DOMContentLoaded", () => {
  game = new GameEngine();
});
</script>
</body>
</html>
<!-- agent-meta {"model":"google/gemini-3.7-flash","provider":"openrouter","persona":"full","sessionId":"49041d0b-f9b5-458d-8bf0-58844ef7478f","tokensIn":1635236,"tokensOut":41548,"tokensTotal":1676784,"cost":0.2862292125000001,"turns":30,"toolCalls":29,"failedToolCalls":0,"timestamp":"2026-08-15T15:32:46.191Z"} -->