← Deckbuilder results

Deckbuilder

Qwen 3.6 35b a3b · 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 75,090 bytes · SHA-256 52778915f3a2
<!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>
<style>
  @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700;900&family=Crimson+Text:ital,wght@0,400;0,600;1,400&display=swap');

  :root {
    --bg-dark: #0a0a12;
    --bg-panel: #12121e;
    --bg-card: #1a1a2e;
    --gold: #d4a843;
    --gold-dim: #8a6d2b;
    --hp-red: #c0392b;
    --hp-red-dark: #7b241c;
    --energy-blue: #3498db;
    --energy-blue-dim: #1a5276;
    --block-silver: #bdc3c7;
    --block-silver-dim: #7f8c8d;
    --attack-red: #e74c3c;
    --defense-blue: #2980b9;
    --other-purple: #8e44ad;
    --other-green: #27ae60;
    --burn-yellow: #f39c12;
    --poison-green: #2ecc71;
    --void-purple: #6c3483;
    --text-primary: #ecf0f1;
    --text-secondary: #95a5a6;
    --text-gold: #f1c40f;
    --border-etched: #2c2c3e;
    --shadow-glow: 0 0 20px rgba(212, 168, 67, 0.3);
  }

  * { margin: 0; padding: 0; box-sizing: border-box; }

  body {
    background: var(--bg-dark);
    color: var(--text-primary);
    font-family: 'Crimson Text', Georgia, serif;
    overflow: hidden;
    height: 100vh;
    width: 100vw;
    user-select: none;
  }

  h1, h2, h3, .title-font { font-family: 'Cinzel', serif; }

  /* ===== SCREENS ===== */
  .screen {
    display: none;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0; left: 0;
  }
  .screen.active { display: flex; }

  /* ===== MAIN MENU ===== */
  #main-menu {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: radial-gradient(ellipse at center, #1a1a2e 0%, #0a0a12 70%);
    position: relative;
  }
  #main-menu::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url("data:image/svg+xml,%3Csvg width='60' height='60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 0L60 30L30 60L0 30Z' fill='none' stroke='%23ffffff08' stroke-width='0.5'/%3E%3C/svg%3E");
    opacity: 0.3;
  }
  .menu-title {
    font-size: 3.5rem;
    font-weight: 900;
    color: var(--gold);
    text-shadow: 0 0 30px rgba(212,168,67,0.5), 0 2px 4px rgba(0,0,0,0.8);
    letter-spacing: 0.15em;
    margin-bottom: 0.3em;
    z-index: 1;
    text-align: center;
  }
  .menu-subtitle {
    font-size: 1.2rem;
    color: var(--text-secondary);
    margin-bottom: 2.5em;
    z-index: 1;
    font-style: italic;
  }
  .class-select {
    display: flex;
    gap: 1.5rem;
    z-index: 1;
    flex-wrap: wrap;
    justify-content: center;
  }
  .class-card {
    width: 220px;
    padding: 1.5rem 1rem;
    background: linear-gradient(180deg, #1a1a2e 0%, #0f0f1a 100%);
    border: 2px solid var(--border-etched);
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.3s ease;
    text-align: center;
    position: relative;
    overflow: hidden;
  }
  .class-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--class-accent);
    opacity: 0.6;
  }
  .class-card:hover {
    border-color: var(--class-accent);
    transform: translateY(-8px);
    box-shadow: 0 12px 40px rgba(0,0,0,0.5), 0 0 20px var(--class-glow);
  }
  .class-icon {
    width: 80px; height: 80px;
    margin: 0 auto 1rem;
    border-radius: 50%;
    border: 2px solid var(--class-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--class-bg);
  }
  .class-name {
    font-family: 'Cinzel', serif;
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--class-accent);
    margin-bottom: 0.5rem;
  }
  .class-theme {
    font-size: 0.95rem;
    color: var(--text-secondary);
    margin-bottom: 0.8rem;
    font-style: italic;
  }
  .class-stats {
    font-size: 0.8rem;
    color: var(--text-secondary);
    line-height: 1.6;
  }
  .class-stats span {
    color: var(--text-primary);
    font-weight: 600;
  }

  /* ===== COMBAT SCREEN ===== */
  #combat-screen {
    flex-direction: column;
    background: radial-gradient(ellipse at 50% 30%, #1a1a2e 0%, #0a0a12 60%);
    position: relative;
  }
  #combat-screen::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='50' cy='50' r='0.5' fill='%23ffffff05'/%3E%3C/svg%3E");
    pointer-events: none;
  }

  /* Top HUD Bar */
  .hud-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.8rem 1.5rem;
    background: linear-gradient(180deg, rgba(18,18,30,0.95) 0%, transparent 100%);
    z-index: 10;
    border-bottom: 1px solid var(--border-etched);
  }
  .hud-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    font-weight: 700;
  }
  .hud-icon {
    width: 24px; height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .hud-gold { color: var(--gold); }
  .hud-floor { color: var(--text-gold); }
  .hud-enemy-hp { color: var(--hp-red); }

  /* Combat Arena */
  .combat-arena {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    z-index: 5;
    padding: 1rem;
  }

  /* Enemy Display */
  .enemy-area {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
  }
  .enemy-sprite {
    width: 160px;
    height: 180px;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .enemy-sprite svg {
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 0 15px rgba(108, 52, 131, 0.4));
    transition: all 0.3s;
  }
  .enemy-sprite.hit svg {
    animation: enemyHit 0.3s ease;
  }
  @keyframes enemyHit {
    0%, 100% { transform: translateX(0); filter: drop-shadow(0 0 15px rgba(108, 52, 131, 0.4)); }
    25% { transform: translateX(-8px); filter: brightness(2) drop-shadow(0 0 20px rgba(231, 76, 60, 0.6)); }
    50% { transform: translateX(8px); filter: brightness(1.5); }
    75% { transform: translateX(-4px); }
  }
  .enemy-name {
    font-family: 'Cinzel', serif;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--text-gold);
    margin-bottom: 0.4rem;
    text-shadow: 0 0 10px rgba(241, 196, 15, 0.3);
  }
  .enemy-hp-bar {
    width: 200px;
    height: 16px;
    background: #1a1a2e;
    border: 1px solid var(--border-etched);
    border-radius: 8px;
    overflow: hidden;
    position: relative;
  }
  .enemy-hp-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--hp-red-dark), var(--hp-red));
    border-radius: 8px;
    transition: width 0.5s ease;
    position: relative;
  }
  .enemy-hp-fill::after {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 50%;
    background: linear-gradient(180deg, rgba(255,255,255,0.15), transparent);
    border-radius: 8px 8px 0 0;
  }
  .enemy-hp-text {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    font-family: 'Cinzel', serif;
    color: white;
    text-shadow: 0 1px 2px rgba(0,0,0,0.8);
  }
  .enemy-status-effects {
    display: flex;
    gap: 0.3rem;
    margin-top: 0.4rem;
    min-height: 20px;
  }
  .status-icon {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.65rem;
    font-weight: 700;
    border: 1px solid rgba(255,255,255,0.2);
  }
  .status-burn { background: var(--burn-yellow); color: #000; }
  .status-poison { background: var(--poison-green); color: #000; }
  .status-stun { background: var(--block-silver); color: #000; }
  .status-silence { background: var(--void-purple); color: #fff; }

  /* Player Stats (above hand) */
  .player-stats {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    padding: 0.6rem 1.5rem;
    background: linear-gradient(0deg, rgba(18,18,30,0.95) 0%, transparent 100%);
    width: 100%;
    justify-content: center;
    z-index: 10;
  }
  .stat-bar-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
  }
  .stat-bar-label {
    font-family: 'Cinzel', serif;
    font-size: 0.7rem;
    color: var(--text-secondary);
    font-weight: 600;
  }
  .stat-bar {
    width: 180px;
    height: 14px;
    background: #1a1a2e;
    border: 1px solid var(--border-etched);
    border-radius: 7px;
    overflow: hidden;
    position: relative;
  }
  .stat-bar-fill {
    height: 100%;
    border-radius: 7px;
    transition: width 0.4s ease;
    position: relative;
  }
  .stat-bar-fill::after {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 50%;
    background: linear-gradient(180deg, rgba(255,255,255,0.12), transparent);
    border-radius: 7px 7px 0 0;
  }
  .stat-bar-text {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6rem;
    font-weight: 700;
    font-family: 'Cinzel', serif;
    color: white;
    text-shadow: 0 1px 2px rgba(0,0,0,0.8);
  }
  .hp-fill { background: linear-gradient(90deg, var(--hp-red-dark), var(--hp-red)); }
  .energy-fill { background: linear-gradient(90deg, var(--energy-blue-dim), var(--energy-blue)); }
  .block-display {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    color: var(--block-silver);
  }
  .block-icon {
    width: 20px; height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* Energy Pips */
  .energy-pips {
    display: flex;
    gap: 0.3rem;
    align-items: center;
  }
  .energy-pip {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--energy-blue);
    background: transparent;
    transition: all 0.3s;
  }
  .energy-pip.filled {
    background: var(--energy-blue);
    box-shadow: 0 0 8px rgba(52, 152, 219, 0.5);
  }
  .energy-pip.spent {
    background: var(--energy-blue-dim);
    border-color: var(--block-silver-dim);
    box-shadow: none;
  }

  /* Hand Area */
  .hand-area {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 0.5rem;
    padding: 1rem 1rem 0.5rem;
    min-height: 220px;
    z-index: 20;
    position: relative;
    flex-wrap: nowrap;
  }

  /* Cards */
  .card {
    width: 130px;
    height: 190px;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.25s ease;
    position: relative;
    flex-shrink: 0;
    transform-origin: bottom center;
  }
  .card:hover {
    transform: translateY(-20px) scale(1.05);
    z-index: 30;
  }
  .card.selected {
    transform: translateY(-30px) scale(1.08);
    z-index: 35;
  }
  .card.unplayable {
    opacity: 0.55;
    filter: grayscale(0.3);
  }
  .card.unplayable:hover {
    transform: translateY(-10px) scale(1.02);
  }
  .card-inner {
    width: 100%;
    height: 100%;
    border-radius: 10px;
    overflow: hidden;
    position: relative;
    border: 2px solid var(--border-etched);
  }
  .card-type-attack .card-inner { border-color: var(--attack-red); box-shadow: 0 0 10px rgba(231,76,60,0.2); }
  .card-type-defense .card-inner { border-color: var(--defense-blue); box-shadow: 0 0 10px rgba(41,128,185,0.2); }
  .card-type-other .card-inner { border-color: var(--other-purple); box-shadow: 0 0 10px rgba(142,68,173,0.2); }

  .card-cost {
    position: absolute;
    top: -6px;
    left: -6px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--energy-blue), var(--energy-blue-dim));
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: 0.9rem;
    color: white;
    border: 2px solid var(--energy-blue);
    box-shadow: 0 0 10px rgba(52,152,219,0.4);
    z-index: 2;
  }
  .card-art {
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .card-art-bg {
    position: absolute;
    inset: 0;
    opacity: 0.15;
  }
  .card-type-attack .card-art-bg { background: linear-gradient(135deg, var(--attack-red), transparent); }
  .card-type-defense .card-art-bg { background: linear-gradient(135deg, var(--defense-blue), transparent); }
  .card-type-other .card-art-bg { background: linear-gradient(135deg, var(--other-purple), transparent); }
  .card-art-icon {
    width: 60px;
    height: 60px;
    position: relative;
    z-index: 1;
    opacity: 0.7;
  }
  .card-art-placeholder {
    width: 50px;
    height: 50px;
    position: relative;
    z-index: 1;
    opacity: 0.4;
    border: 2px dashed rgba(255,255,255,0.3);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .card-art-placeholder svg {
    width: 24px;
    height: 24px;
    opacity: 0.5;
  }
  .card-info {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0.5rem;
    background: linear-gradient(0deg, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.4) 70%, transparent 100%);
    text-align: center;
  }
  .card-name {
    font-family: 'Cinzel', serif;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--text-gold);
    margin-bottom: 0.15rem;
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
  }
  .card-stats {
    font-size: 0.65rem;
    color: var(--text-secondary);
    font-weight: 600;
  }
  .card-ability {
    font-size: 0.58rem;
    color: var(--text-secondary);
    font-style: italic;
    margin-top: 0.15rem;
    line-height: 1.3;
    max-height: 2.6em;
    overflow: hidden;
  }

  /* Bottom Controls */
  .controls {
    display: flex;
    justify-content: center;
    gap: 1rem;
    padding: 0.8rem 1.5rem 1rem;
    background: linear-gradient(0deg, rgba(18,18,30,0.95) 0%, transparent 100%);
    z-index: 10;
  }
  .btn {
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: 1rem;
    padding: 0.7rem 2rem;
    border: 2px solid var(--border-etched);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    position: relative;
    overflow: hidden;
  }
  .btn::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 50%;
    background: linear-gradient(180deg, rgba(255,255,255,0.08), transparent);
  }
  .btn-primary {
    background: linear-gradient(180deg, #2c2c3e, #1a1a2e);
    color: var(--text-gold);
    border-color: var(--gold-dim);
  }
  .btn-primary:hover {
    background: linear-gradient(180deg, #3c3c4e, #2a2a3e);
    border-color: var(--gold);
    box-shadow: 0 0 15px rgba(212,168,67,0.3);
    transform: translateY(-2px);
  }
  .btn-end-turn {
    background: linear-gradient(180deg, var(--hp-red-dark), #5a1a15);
    color: white;
    border-color: var(--hp-red);
  }
  .btn-end-turn:hover {
    background: linear-gradient(180deg, var(--hp-red), #7b241c);
    box-shadow: 0 0 15px rgba(231,76,60,0.3);
    transform: translateY(-2px);
  }
  .btn-shop {
    background: linear-gradient(180deg, #2c2c3e, #1a1a2e);
    color: var(--gold);
    border-color: var(--gold-dim);
  }
  .btn-shop:hover {
    background: linear-gradient(180deg, #3c3c4e, #2a2a3e);
    border-color: var(--gold);
    box-shadow: 0 0 15px rgba(212,168,67,0.3);
    transform: translateY(-2px);
  }
  .btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    transform: none !important;
    box-shadow: none !important;
  }

  /* ===== SHOP SCREEN ===== */
  #shop-screen {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: radial-gradient(ellipse at center, #1a1a2e 0%, #0a0a12 70%);
  }
  .shop-title {
    font-size: 2.5rem;
    font-weight: 900;
    color: var(--gold);
    text-shadow: 0 0 30px rgba(212,168,67,0.5);
    margin-bottom: 0.5rem;
  }
  .shop-subtitle {
    color: var(--text-secondary);
    font-style: italic;
    margin-bottom: 2rem;
  }
  .shop-gold-display {
    font-family: 'Cinzel', serif;
    font-size: 1.3rem;
    color: var(--gold);
    margin-bottom: 1.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .shop-cards {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: 2rem;
    max-width: 900px;
  }
  .shop-card {
    width: 180px;
    cursor: pointer;
    transition: all 0.25s;
    position: relative;
  }
  .shop-card:hover {
    transform: translateY(-10px);
  }
  .shop-card-inner {
    width: 100%;
    border-radius: 10px;
    overflow: hidden;
    border: 2px solid var(--border-etched);
    background: var(--bg-card);
  }
  .shop-card-cost {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--energy-blue), var(--energy-blue-dim));
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: 0.9rem;
    color: white;
    border: 2px solid var(--energy-blue);
    z-index: 2;
  }
  .shop-card-owned {
    position: absolute;
    top: 8px;
    right: 8px;
    background: rgba(0,0,0,0.7);
    color: var(--text-secondary);
    font-size: 0.65rem;
    padding: 2px 6px;
    border-radius: 4px;
    font-family: 'Cinzel', serif;
    z-index: 2;
  }
  .shop-card-art {
    width: 100%;
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
  }
  .shop-card-info {
    padding: 0.7rem;
    text-align: center;
  }
  .shop-card-name {
    font-family: 'Cinzel', serif;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-gold);
    margin-bottom: 0.2rem;
  }
  .shop-card-ability {
    font-size: 0.65rem;
    color: var(--text-secondary);
    font-style: italic;
    line-height: 1.3;
  }
  .shop-card-price {
    font-family: 'Cinzel', serif;
    font-size: 0.75rem;
    color: var(--gold);
    margin-top: 0.3rem;
    font-weight: 700;
  }
  .shop-actions {
    display: flex;
    gap: 1rem;
  }

  /* ===== VICTORY / DEFEAT SCREENS ===== */
  #victory-screen, #defeat-screen {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: radial-gradient(ellipse at center, #1a1a2e 0%, #0a0a12 70%);
  }
  #victory-screen { background: radial-gradient(ellipse at center, #1a2a1e 0%, #0a0a12 70%); }
  .end-title {
    font-size: 3rem;
    font-weight: 900;
    margin-bottom: 1rem;
    text-shadow: 0 0 30px currentColor;
  }
  .end-subtitle {
    font-size: 1.2rem;
    color: var(--text-secondary);
    font-style: italic;
    margin-bottom: 2rem;
  }
  .end-stats {
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    color: var(--text-secondary);
    margin-bottom: 2rem;
    text-align: center;
    line-height: 2;
  }
  .end-stats span { color: var(--text-gold); font-weight: 700; }

  /* ===== COMBAT LOG ===== */
  .combat-log {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 100;
  }
  .log-entry {
    font-family: 'Cinzel', serif;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--text-gold);
    text-shadow: 0 0 10px rgba(212,168,67,0.5), 0 2px 4px rgba(0,0,0,0.8);
    opacity: 0;
    animation: logFloat 2s ease forwards;
    white-space: nowrap;
  }
  .log-entry.damage { color: var(--hp-red); text-shadow: 0 0 10px rgba(231,76,60,0.5); }
  .log-entry.heal { color: var(--other-green); text-shadow: 0 0 10px rgba(39,174,96,0.5); }
  .log-entry.block { color: var(--block-silver); text-shadow: 0 0 10px rgba(189,195,199,0.5); }
  .log-entry.energy { color: var(--energy-blue); text-shadow: 0 0 10px rgba(52,152,219,0.5); }
  .log-entry.gold { color: var(--gold); text-shadow: 0 0 10px rgba(212,168,67,0.5); }
  .log-entry.status { color: var(--burn-yellow); text-shadow: 0 0 10px rgba(243,156,18,0.5); }

  @keyframes logFloat {
    0% { opacity: 0; transform: translateY(20px); }
    15% { opacity: 1; transform: translateY(0); }
    70% { opacity: 1; transform: translateY(-10px); }
    100% { opacity: 0; transform: translateY(-30px); }
  }

  /* Damage number popup */
  .damage-popup {
    position: absolute;
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: 1.5rem;
    pointer-events: none;
    z-index: 200;
    animation: damagePop 1s ease forwards;
  }
  @keyframes damagePop {
    0% { opacity: 1; transform: translateY(0) scale(0.5); }
    30% { transform: translateY(-20px) scale(1.2); }
    100% { opacity: 0; transform: translateY(-60px) scale(0.8); }
  }

  /* ===== FLOOR TRANSITION ===== */
  .floor-transition {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.9);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 500;
    animation: fadeIn 0.5s ease;
  }
  .floor-transition-title {
    font-size: 2.5rem;
    font-weight: 900;
    color: var(--gold);
    text-shadow: 0 0 30px rgba(212,168,67,0.5);
    margin-bottom: 0.5rem;
  }
  .floor-transition-sub {
    font-size: 1.1rem;
    color: var(--text-secondary);
    font-style: italic;
  }

  @keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  /* ===== TURN INDICATOR ===== */
  .turn-indicator {
    position: absolute;
    top: 80px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-gold);
    text-shadow: 0 0 10px rgba(241,196,15,0.3);
    opacity: 0.7;
    z-index: 10;
    pointer-events: none;
  }

  /* ===== SCROLLBAR ===== */
  ::-webkit-scrollbar { width: 6px; }
  ::-webkit-scrollbar-track { background: var(--bg-dark); }
  ::-webkit-scrollbar-thumb { background: var(--border-etched); border-radius: 3px; }

  /* ===== RESPONSIVE ===== */
  @media (max-width: 768px) {
    .menu-title { font-size: 2rem; }
    .class-card { width: 180px; padding: 1rem; }
    .card { width: 100px; height: 150px; }
    .card-name { font-size: 0.6rem; }
    .card-ability { font-size: 0.5rem; }
    .hand-area { gap: 0.3rem; }
    .shop-cards { gap: 1rem; }
    .shop-card { width: 150px; }
  }
</style>
</head>
<body>

<!-- ===== SVG DEFS ===== -->
<svg style="display:none" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <!-- Card Backs -->
    <pattern id="back-bastion" width="20" height="20" patternUnits="userSpaceOnUse">
      <rect width="20" height="20" fill="#1a1a2e"/>
      <path d="M10 0L20 10L10 20L0 10Z" fill="none" stroke="#8a6d2b" stroke-width="0.5" opacity="0.3"/>
      <circle cx="10" cy="10" r="3" fill="none" stroke="#8a6d2b" stroke-width="0.5" opacity="0.3"/>
    </pattern>
    <pattern id="back-wither" width="16" height="16" patternUnits="userSpaceOnUse">
      <rect width="16" height="16" fill="#1a1a2e"/>
      <path d="M8 2C12 6 12 10 8 14C4 10 4 6 8 2Z" fill="none" stroke="#6c3483" stroke-width="0.5" opacity="0.3"/>
    </pattern>
    <pattern id="back-shroud" width="12" height="12" patternUnits="userSpaceOnUse">
      <rect width="12" height="12" fill="#1a1a2e"/>
      <circle cx="6" cy="6" r="4" fill="none" stroke="#2980b9" stroke-width="0.5" opacity="0.3"/>
    </pattern>

    <!-- Bastion Card Frame -->
    <g id="frame-bastion">
      <rect width="130" height="190" rx="10" fill="#1a1a2e" stroke="#8a6d2b" stroke-width="2"/>
      <rect x="4" y="4" width="122" height="182" rx="7" fill="none" stroke="#d4a843" stroke-width="0.5" opacity="0.5"/>
      <path d="M65 12L72 20L65 18L58 20Z" fill="#d4a843" opacity="0.6"/>
      <path d="M65 178L72 170L65 172L58 170Z" fill="#d4a843" opacity="0.6"/>
      <line x1="20" y1="80" x2="110" y2="80" stroke="#8a6d2b" stroke-width="0.5" opacity="0.3"/>
    </g>

    <!-- Wither Card Frame -->
    <g id="frame-wither">
      <rect width="130" height="190" rx="10" fill="#1a1a2e" stroke="#6c3483" stroke-width="2"/>
      <rect x="4" y="4" width="122" height="182" rx="7" fill="none" stroke="#8e44ad" stroke-width="0.5" opacity="0.5"/>
      <path d="M65 8C68 14 72 16 65 22C58 16 62 14 65 8Z" fill="#8e44ad" opacity="0.5"/>
      <path d="M65 168C68 162 72 160 65 166C58 160 62 162 65 168Z" fill="#8e44ad" opacity="0.5"/>
      <line x1="20" y1="80" x2="110" y2="80" stroke="#6c3483" stroke-width="0.5" opacity="0.3"/>
    </g>

    <!-- Shroud Card Frame -->
    <g id="frame-shroud">
      <rect width="130" height="190" rx="10" fill="#1a1a2e" stroke="#2980b9" stroke-width="2"/>
      <rect x="4" y="4" width="122" height="182" rx="7" fill="none" stroke="#3498db" stroke-width="0.5" opacity="0.5"/>
      <circle cx="65" cy="14" r="4" fill="none" stroke="#3498db" stroke-width="0.5" opacity="0.5"/>
      <circle cx="65" cy="176" r="4" fill="none" stroke="#3498db" stroke-width="0.5" opacity="0.5"/>
      <line x1="20" y1="80" x2="110" y2="80" stroke="#2980b9" stroke-width="0.5" opacity="0.3"/>
    </g>

    <!-- Bastion Card Back -->
    <g id="cardback-bastion">
      <rect width="130" height="190" rx="10" fill="url(#back-bastion)" stroke="#8a6d2b" stroke-width="2"/>
      <rect x="8" y="8" width="114" height="174" rx="6" fill="none" stroke="#d4a843" stroke-width="1" opacity="0.4"/>
      <path d="M65 40L80 65L65 90L50 65Z" fill="none" stroke="#d4a843" stroke-width="1.5" opacity="0.5"/>
      <circle cx="65" cy="65" r="10" fill="none" stroke="#d4a843" stroke-width="1" opacity="0.4"/>
      <circle cx="65" cy="65" r="4" fill="#d4a843" opacity="0.3"/>
      <text x="65" y="155" text-anchor="middle" fill="#d4a843" font-family="Cinzel" font-size="8" opacity="0.5">BASTION</text>
    </g>

    <!-- Wither Card Back -->
    <g id="cardback-wither">
      <rect width="130" height="190" rx="10" fill="url(#back-wither)" stroke="#6c3483" stroke-width="2"/>
      <rect x="8" y="8" width="114" height="174" rx="6" fill="none" stroke="#8e44ad" stroke-width="1" opacity="0.4"/>
      <path d="M65 35C75 50 75 80 65 95C55 80 55 50 65 35Z" fill="none" stroke="#8e44ad" stroke-width="1.5" opacity="0.5"/>
      <path d="M65 35L60 50L65 45L70 50Z" fill="#8e44ad" opacity="0.3"/>
      <text x="65" y="155" text-anchor="middle" fill="#8e44ad" font-family="Cinzel" font-size="8" opacity="0.5">WITHER</text>
    </g>

    <!-- Shroud Card Back -->
    <g id="cardback-shroud">
      <rect width="130" height="190" rx="10" fill="url(#back-shroud)" stroke="#2980b9" stroke-width="2"/>
      <rect x="8" y="8" width="114" height="174" rx="6" fill="none" stroke="#3498db" stroke-width="1" opacity="0.4"/>
      <circle cx="65" cy="65" r="20" fill="none" stroke="#3498db" stroke-width="1" opacity="0.4"/>
      <circle cx="65" cy="65" r="12" fill="none" stroke="#3498db" stroke-width="0.8" opacity="0.3"/>
      <circle cx="65" cy="65" r="5" fill="#3498db" opacity="0.2"/>
      <text x="65" y="155" text-anchor="middle" fill="#3498db" font-family="Cinzel" font-size="8" opacity="0.5">SHROUD</text>
    </g>

    <!-- Enemy Sprites -->
    <g id="enemy-goblin">
      <rect width="160" height="180" fill="none"/>
      <ellipse cx="80" cy="140" rx="35" ry="20" fill="#2d5a27"/>
      <rect x="55" y="80" width="50" height="60" rx="10" fill="#3a7a32"/>
      <circle cx="68" cy="65" r="18" fill="#4a8a42"/>
      <circle cx="92" cy="65" r="18" fill="#4a8a42"/>
      <circle cx="68" cy="60" r="6" fill="#c0392b"/>
      <circle cx="92" cy="60" r="6" fill="#c0392b"/>
      <circle cx="68" cy="60" r="3" fill="#000"/>
      <circle cx="92" cy="60" r="3" fill="#000"/>
      <path d="M65 75L72 72L80 78L88 72L95 75" fill="none" stroke="#2d5a27" stroke-width="2"/>
      <path d="M55 80L40 60L50 75Z" fill="#3a7a32"/>
      <path d="M105 80L120 60L110 75Z" fill="#3a7a32"/>
    </g>

    <g id="enemy-rat">
      <ellipse cx="80" cy="130" rx="40" ry="25" fill="#4a3728"/>
      <ellipse cx="80" cy="120" rx="30" ry="20" fill="#5a4738"/>
      <circle cx="60" cy="100" r="15" fill="#5a4738"/>
      <circle cx="55" cy="96" r="4" fill="#c0392b"/>
      <circle cx="65" cy="96" r="4" fill="#c0392b"/>
      <circle cx="55" cy="96" r="2" fill="#000"/>
      <circle cx="65" cy="96" r="2" fill="#000"/>
      <path d="M60 108L63 105L66 108L69 105L72 108" fill="none" stroke="#3a2718" stroke-width="1.5"/>
      <path d="M45 100L35 85L42 95Z" fill="#5a4738"/>
      <path d="M115 100L125 85L118 95Z" fill="#5a4738"/>
      <path d="M110 130L130 140L120 135Z" fill="#4a3728"/>
    </g>

    <g id="enemy-vampire">
      <ellipse cx="80" cy="150" rx="30" ry="15" fill="#1a1a2e"/>
      <rect x="55" y="70" width="50" height="80" rx="8" fill="#2c2c3e"/>
      <circle cx="80" cy="55" r="22" fill="#3a3a4e"/>
      <circle cx="70" cy="50" r="5" fill="#c0392b"/>
      <circle cx="90" cy="50" r="5" fill="#c0392b"/>
      <circle cx="70" cy="50" r="2.5" fill="#000"/>
      <circle cx="90" cy="50" r="2.5" fill="#000"/>
      <path d="M72 65L75 62L78 65L81 62L84 65L87 62L90 65" fill="none" stroke="#c0392b" stroke-width="1.5"/>
      <path d="M60 35L55 15L65 30Z" fill="#2c2c3e"/>
      <path d="M100 35L105 15L95 30Z" fill="#2c2c3e"/>
      <path d="M55 70L35 50L45 70Z" fill="#2c2c3e"/>
      <path d="M105 70L125 50L115 70Z" fill="#2c2c3e"/>
    </g>

    <g id="enemy-ogre">
      <ellipse cx="80" cy="155" rx="45" ry="18" fill="#3a3a3a"/>
      <rect x="45" y="60" width="70" height="90" rx="12" fill="#4a4a4a"/>
      <circle cx="80" cy="45" r="28" fill="#5a5a5a"/>
      <circle cx="68" cy="40" r="6" fill="#c0392b"/>
      <circle cx="92" cy="40" r="6" fill="#c0392b"/>
      <circle cx="68" cy="40" r="3" fill="#000"/>
      <circle cx="92" cy="40" r="3" fill="#000"/>
      <path d="M65 60L72 55L80 62L88 55L95 60" fill="none" stroke="#3a3a3a" stroke-width="2"/>
      <path d="M45 60L25 40L35 55Z" fill="#4a4a4a"/>
      <path d="M115 60L135 40L125 55Z" fill="#4a4a4a"/>
      <rect x="55" y="70" width="15" height="20" rx="3" fill="#3a3a3a" opacity="0.5"/>
      <rect x="90" y="70" width="15" height="20" rx="3" fill="#3a3a3a" opacity="0.5"/>
    </g>

    <g id="enemy-voidwarrior">
      <ellipse cx="80" cy="150" rx="35" ry="15" fill="#2c1a4a"/>
      <rect x="50" y="55" width="60" height="90" rx="10" fill="#3c2a5a"/>
      <circle cx="80" cy="40" r="25" fill="#4c3a6a"/>
      <circle cx="70" cy="35" r="5" fill="#6c3483"/>
      <circle cx="90" cy="35" r="5" fill="#6c3483"/>
      <circle cx="70" cy="35" r="2.5" fill="#9b59b6"/>
      <circle cx="90" cy="35" r="2.5" fill="#9b59b6"/>
      <path d="M68 52L75 48L80 52L85 48L92 52" fill="none" stroke="#6c3483" stroke-width="1.5"/>
      <path d="M50 55L30 35L40 50Z" fill="#3c2a5a"/>
      <path d="M110 55L130 35L120 50Z" fill="#3c2a5a"/>
      <circle cx="80" cy="85" r="12" fill="none" stroke="#6c3483" stroke-width="1" opacity="0.5"/>
      <circle cx="80" cy="85" r="6" fill="#6c3483" opacity="0.3"/>
    </g>

    <g id="enemy-cultist">
      <ellipse cx="80" cy="150" rx="30" ry="12" fill="#1a0a2a"/>
      <path d="M50 140L55 50L105 50L110 140Z" fill="#2a1a3a"/>
      <circle cx="80" cy="40" r="20" fill="#3a2a4a"/>
      <path d="M60 25L80 10L100 25" fill="none" stroke="#4a3a5a" stroke-width="2"/>
      <circle cx="72" cy="38" r="4" fill="#6c3483"/>
      <circle cx="88" cy="38" r="4" fill="#6c3483"/>
      <circle cx="72" cy="38" r="2" fill="#9b59b6"/>
      <circle cx="88" cy="38" r="2" fill="#9b59b6"/>
      <path d="M72 50L76 47L80 50L84 47L88 50" fill="none" stroke="#6c3483" stroke-width="1"/>
      <path d="M65 55L55 40L62 50Z" fill="#2a1a3a"/>
      <path d="M95 55L105 40L98 50Z" fill="#2a1a3a"/>
    </g>

    <!-- Boss Sprites -->
    <g id="boss-gatekeeper">
      <ellipse cx="80" cy="160" rx="50" ry="18" fill="#2a2a2a"/>
      <rect x="35" y="40" width="90" height="110" rx="15" fill="#3a3a3a"/>
      <circle cx="80" cy="30" r="30" fill="#4a4a4a"/>
      <circle cx="68" cy="25" r="7" fill="#c0392b"/>
      <circle cx="92" cy="25" r="7" fill="#c0392b"/>
      <circle cx="68" cy="25" r="3.5" fill="#000"/>
      <circle cx="92" cy="25" r="3.5" fill="#000"/>
      <path d="M60 45L68 40L75 46L82 40L89 46L96 40L104 45" fill="none" stroke="#c0392b" stroke-width="2"/>
      <path d="M50 10L30 0L55 8Z" fill="#5a5a5a"/>
      <path d="M110 10L130 0L105 8Z" fill="#5a5a5a"/>
      <rect x="50" y="55" width="60" height="40" rx="5" fill="none" stroke="#c0392b" stroke-width="1.5" opacity="0.5"/>
      <circle cx="80" cy="75" r="10" fill="none" stroke="#c0392b" stroke-width="1" opacity="0.4"/>
      <path d="M35 40L15 20L25 40Z" fill="#3a3a3a"/>
      <path d="M125 40L145 20L135 40Z" fill="#3a3a3a"/>
    </g>

    <g id="boss-corrupted">
      <ellipse cx="80" cy="155" rx="45" ry="15" fill="#1a1a2e"/>
      <rect x="40" y="45" width="80" height="105" rx="12" fill="#2a2a3e"/>
      <circle cx="80" cy="35" r="28" fill="#3a3a4e"/>
      <circle cx="68" cy="30" r="6" fill="#e74c3c"/>
      <circle cx="92" cy="30" r="6" fill="#e74c3c"/>
      <circle cx="68" cy="30" r="3" fill="#000"/>
      <circle cx="92" cy="30" r="3" fill="#000"/>
      <path d="M65 48L72 43L80 48L88 43L95 48" fill="none" stroke="#e74c3c" stroke-width="2"/>
      <path d="M55 10L45 -5L60 5Z" fill="#4a4a5e"/>
      <path d="M105 10L115 -5L100 5Z" fill="#4a4a5e"/>
      <circle cx="80" cy="70" r="15" fill="none" stroke="#e74c3c" stroke-width="1.5" opacity="0.5"/>
      <circle cx="80" cy="70" r="8" fill="#e74c3c" opacity="0.2"/>
      <path d="M40 45L20 25L30 40Z" fill="#2a2a3e"/>
      <path d="M120 45L140 25L130 40Z" fill="#2a2a3e"/>
    </g>

    <g id="boss-voidlord">
      <ellipse cx="80" cy="155" rx="55" ry="15" fill="#0a0a1a"/>
      <rect x="30" y="35" width="100" height="115" rx="15" fill="#1a1a2e"/>
      <circle cx="80" cy="25" r="32" fill="#2a2a3e"/>
      <circle cx="65" cy="20" r="7" fill="#6c3483"/>
      <circle cx="95" cy="20" r="7" fill="#6c3483"/>
      <circle cx="65" cy="20" r="3.5" fill="#9b59b6"/>
      <circle cx="95" cy="20" r="3.5" fill="#9b59b6"/>
      <path d="M60 38L70 32L80 38L90 32L100 38" fill="none" stroke="#6c3483" stroke-width="2"/>
      <path d="M50 5L40 -10L55 0Z" fill="#3a3a4e"/>
      <path d="M110 5L120 -10L105 0Z" fill="#3a3a4e"/>
      <circle cx="80" cy="60" r="18" fill="none" stroke="#6c3483" stroke-width="1.5" opacity="0.4"/>
      <circle cx="80" cy="60" r="10" fill="#6c3483" opacity="0.15"/>
      <circle cx="80" cy="60" r="4" fill="#6c3483" opacity="0.3"/>
      <path d="M30 35L10 15L20 30Z" fill="#1a1a2e"/>
      <path d="M130 35L150 15L140 30Z" fill="#1a1a2e"/>
      <path d="M30 35L10 15L15 25Z" fill="none" stroke="#6c3483" stroke-width="0.5" opacity="0.3"/>
      <path d="M130 35L150 15L145 25Z" fill="none" stroke="#6c3483" stroke-width="0.5" opacity="0.3"/>
    </g>
  </defs>
</svg>

<!-- ===== MAIN MENU ===== -->
<div id="main-menu" class="screen active">
  <h1 class="menu-title">SHADOWS OF AETHELGARD</h1>
  <p class="menu-subtitle">The Void consumes all. Only you can stand against it.</p>
  <div class="class-select">
    <div class="class-card" onclick="selectClass('bastion')" style="--class-accent: #d4a843; --class-bg: #2a2a1e; --class-glow: rgba(212,168,67,0.3);">
      <div class="class-icon">
        <svg width="50" height="50" viewBox="0 0 50 50">
          <path d="M25 5L35 15L35 35L25 45L15 35L15 15Z" fill="none" stroke="#d4a843" stroke-width="2"/>
          <path d="M25 12L30 18L25 24L20 18Z" fill="#d4a843" opacity="0.6"/>
          <line x1="25" y1="24" x2="25" y2="38" stroke="#d4a843" stroke-width="2"/>
        </svg>
      </div>
      <div class="class-name">The Bastion</div>
      <div class="class-theme">Immovable Object</div>
      <div class="class-stats">
        HP: <span>35</span><br>
        Energy: <span>3</span><br>
        Style: Defense &amp; Block
      </div>
    </div>
    <div class="class-card" onclick="selectClass('wither')" style="--class-accent: #8e44ad; --class-bg: #2a1a2e; --class-glow: rgba(142,68,173,0.3);">
      <div class="class-icon">
        <svg width="50" height="50" viewBox="0 0 50 50">
          <path d="M25 8C32 18 32 32 25 42C18 32 18 18 25 8Z" fill="none" stroke="#8e44ad" stroke-width="2"/>
          <path d="M25 15C29 22 29 30 25 37C21 30 21 22 25 15Z" fill="#8e44ad" opacity="0.4"/>
          <circle cx="25" cy="25" r="4" fill="#8e44ad" opacity="0.6"/>
        </svg>
      </div>
      <div class="class-name">The Wither</div>
      <div class="class-theme">Rot and Burn</div>
      <div class="class-stats">
        HP: <span>28</span><br>
        Energy: <span>3</span><br>
        Style: Burn &amp; Debuffs
      </div>
    </div>
    <div class="class-card" onclick="selectClass('shroud')" style="--class-accent: #3498db; --class-bg: #1a2a3a; --class-glow: rgba(52,152,219,0.3);">
      <div class="class-icon">
        <svg width="50" height="50" viewBox="0 0 50 50">
          <circle cx="25" cy="25" r="18" fill="none" stroke="#3498db" stroke-width="2"/>
          <circle cx="25" cy="25" r="10" fill="none" stroke="#3498db" stroke-width="1.5" opacity="0.6"/>
          <circle cx="25" cy="25" r="4" fill="#3498db" opacity="0.5"/>
          <path d="M25 7L28 15L25 12L22 15Z" fill="#3498db" opacity="0.4"/>
        </svg>
      </div>
      <div class="class-name">The Shroud</div>
      <div class="class-theme">Shadow and Speed</div>
      <div class="class-stats">
        HP: <span>30</span><br>
        Energy: <span>3</span><br>
        Style: Speed &amp; Crit
      </div>
    </div>
  </div>
</div>

<!-- ===== COMBAT SCREEN ===== -->
<div id="combat-screen" class="screen">
  <div class="hud-top">
    <div class="hud-item hud-gold">
      <svg class="hud-icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="none" stroke="#d4a843" stroke-width="2"/><text x="12" y="16" text-anchor="middle" fill="#d4a843" font-size="12" font-weight="bold" font-family="Cinzel">$</text></svg>
      <span id="hud-gold">0</span>
    </div>
    <div class="hud-item hud-floor">
      <span id="hud-floor">Floor 1</span>
    </div>
    <div class="hud-item hud-enemy-hp">
      <svg class="hud-icon" viewBox="0 0 24 24"><path d="M12 21C12 21 4 15 4 9C4 5.5 7 3 12 3C17 3 20 5.5 20 9C20 15 12 21 12 21Z" fill="none" stroke="#c0392b" stroke-width="2"/><circle cx="12" cy="9" r="3" fill="#c0392b" opacity="0.5"/></svg>
      <span id="hud-enemy-hp">20 / 20</span>
    </div>
  </div>

  <div class="turn-indicator" id="turn-indicator">Your Turn</div>

  <div class="combat-arena">
    <div class="enemy-area" id="enemy-area">
      <div class="enemy-name" id="enemy-name">Goblin</div>
      <div class="enemy-hp-bar">
        <div class="enemy-hp-fill" id="enemy-hp-fill" style="width:100%"></div>
        <div class="enemy-hp-text" id="enemy-hp-text">20 / 20</div>
      </div>
      <div class="enemy-status-effects" id="enemy-status"></div>
      <div class="enemy-sprite" id="enemy-sprite"></div>
    </div>
  </div>

  <div class="player-stats">
    <div class="stat-bar-container">
      <div class="stat-bar-label">HP</div>
      <div class="stat-bar">
        <div class="stat-bar-fill hp-fill" id="player-hp-fill" style="width:100%"></div>
        <div class="stat-bar-text" id="player-hp-text">35 / 35</div>
      </div>
    </div>
    <div class="stat-bar-container">
      <div class="stat-bar-label">Energy</div>
      <div class="energy-pips" id="energy-pips"></div>
    </div>
    <div class="block-display">
      <svg class="block-icon" viewBox="0 0 24 24"><path d="M12 2L4 7V12C4 17.5 8 22 12 23C16 22 20 17.5 20 12V7L12 2Z" fill="none" stroke="#bdc3c7" stroke-width="2"/></svg>
      <span id="player-block">0</span>
    </div>
  </div>

  <div class="hand-area" id="hand-area"></div>

  <div class="controls">
    <button class="btn btn-end-turn" id="btn-end-turn" onclick="endTurn()">End Turn</button>
    <button class="btn btn-shop" id="btn-shop" onclick="openShop()" style="display:none">Visit Shop</button>
  </div>

  <div class="combat-log" id="combat-log"></div>
</div>

<!-- ===== SHOP SCREEN ===== -->
<div id="shop-screen" class="screen">
  <h2 class="shop-title">The Dark Market</h2>
  <p class="shop-subtitle">Spend your gold wisely, hero.</p>
  <div class="shop-gold-display">
    <svg width="28" height="28" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="none" stroke="#d4a843" stroke-width="2"/><text x="12" y="16" text-anchor="middle" fill="#d4a843" font-size="12" font-weight="bold" font-family="Cinzel">$</text></svg>
    <span id="shop-gold">0</span> Gold
  </div>
  <div class="shop-cards" id="shop-cards"></div>
  <div class="shop-actions">
    <button class="btn btn-primary" onclick="closeShop()">Leave Shop</button>
  </div>
</div>

<!-- ===== VICTORY SCREEN ===== -->
<div id="victory-screen" class="screen">
  <h2 class="end-title" style="color: var(--other-green);">VICTORY</h2>
  <p class="end-subtitle">The Void Lord has been vanquished. Aethelgard is saved.</p>
  <div class="end-stats" id="victory-stats"></div>
  <button class="btn btn-primary" onclick="location.reload()">Play Again</button>
</div>

<!-- ===== DEFEAT SCREEN ===== -->
<div id="defeat-screen" class="screen">
  <h2 class="end-title" style="color: var(--hp-red);">DEFEAT</h2>
  <p class="end-subtitle">The Void claims another soul...</p>
  <div class="end-stats" id="defeat-stats"></div>
  <button class="btn btn-primary" onclick="location.reload()">Try Again</button>
</div>

<script>
// ===== CARD DATABASE =====
const ALL_CARDS = {
  // Bastion
  'BA-A01': { id:'BA-A01', name:'Slam', type:'attack', cost:2, atk:3, def:0, ability:'Deals 3 damage. If you have 30+ HP, draw 1 card.', class:'bastion' },
  'BA-A02': { id:'BA-A02', name:'Earthquake', type:'attack', cost:3, atk:4, def:0, ability:'Deals 4 damage to all enemies.', class:'bastion' },
  'BA-A03': { id:'BA-A03', name:'Stone Fist', type:'attack', cost:1, atk:2, def:0, ability:'Deals 2 damage.', class:'bastion' },
  'BA-A04': { id:'BA-A04', name:'Boulder', type:'attack', cost:4, atk:6, def:0, ability:'Deals 6 damage.', class:'bastion' },
  'BA-D01': { id:'BA-D01', name:'Shield Wall', type:'defense', cost:0, atk:0, def:4, ability:'Gain 4 Defense this turn.', class:'bastion' },
  'BA-D02': { id:'BA-D02', name:'Iron Skin', type:'defense', cost:2, atk:0, def:5, ability:'Gain 5 permanent Defense. Discard 1 card.', class:'bastion' },
  'BA-D03': { id:'BA-D03', name:'Stand Firm', type:'defense', cost:1, atk:0, def:2, ability:'Gain 2 Defense. Blocks 1 extra damage.', class:'bastion' },
  'BA-D04': { id:'BA-D04', name:'Taunt', type:'defense', cost:2, atk:0, def:3, ability:'Gain 3 Defense. Stun 1 enemy for 1 turn.', class:'bastion' },
  'BA-U01': { id:'BA-U01', name:'Search', type:'other', cost:2, atk:0, def:0, ability:'Draw 1 card. Discard hand if > 5 cards.', class:'bastion' },
  'BA-U02': { id:'BA-U02', name:'Repair', type:'other', cost:3, atk:0, def:0, ability:'Heal 6 HP.', class:'bastion' },
  'BA-U03': { id:'BA-U03', name:'Rally', type:'other', cost:1, atk:0, def:0, ability:'Draw 1 card. Gain 1 Energy.', class:'bastion' },
  'BA-U04': { id:'BA-U04', name:'Loot', type:'other', cost:1, atk:0, def:0, ability:'Gain 5 Gold.', class:'bastion' },
  // Wither
  'WI-A01': { id:'WI-A01', name:'Fireball', type:'attack', cost:2, atk:3, def:0, ability:'Deals 3 damage. Apply 1 Burn.', class:'wither' },
  'WI-A02': { id:'WI-A02', name:'Inferno', type:'attack', cost:3, atk:4, def:0, ability:'Deals 4 damage. Applies 3 Burn.', class:'wither' },
  'WI-A03': { id:'WI-A03', name:'Ember', type:'attack', cost:1, atk:2, def:0, ability:'Deals 2 damage. Applies 1 Burn.', class:'wither' },
  'WI-A04': { id:'WI-A04', name:'Pyre', type:'attack', cost:4, atk:5, def:0, ability:'Deals 5 damage. All enemies take 1 damage next turn.', class:'wither' },
  'WI-D01': { id:'WI-D01', name:'Scorch Shield', type:'defense', cost:2, atk:0, def:3, ability:'Gain 3 Defense. Block 1 Burn damage.', class:'wither' },
  'WI-D02': { id:'WI-D02', name:'Heat Resist', type:'defense', cost:1, atk:0, def:1, ability:'Gain 1 Defense. Gain 1 Energy.', class:'wither' },
  'WI-D03': { id:'WI-D03', name:'Smoke', type:'defense', cost:2, atk:0, def:4, ability:'Gain 4 Defense. Block 1 Burn damage.', class:'wither' },
  'WI-D04': { id:'WI-D04', name:'Endure', type:'defense', cost:3, atk:0, def:2, ability:'Gain 2 Defense. Heal 2 HP.', class:'wither' },
  'WI-U01': { id:'WI-U01', name:'Poison', type:'other', cost:2, atk:0, def:0, ability:'Apply 1 Poison to target.', class:'wither' },
  'WI-U02': { id:'WI-U02', name:'Burn', type:'other', cost:3, atk:0, def:0, ability:'Deal 3 damage + 2 Burn to all enemies.', class:'wither' },
  'WI-U03': { id:'WI-U03', name:'Slow', type:'other', cost:1, atk:0, def:0, ability:'Draw 1 card. Stun target for 1 turn.', class:'wither' },
  'WI-U04': { id:'WI-U04', name:'Wither', type:'other', cost:2, atk:0, def:0, ability:'Heal 5 HP. Reduce enemy Attack by 1.', class:'wither' },
  // Shroud
  'SH-A01': { id:'SH-A01', name:'Backstab', type:'attack', cost:2, atk:4, def:0, ability:'Deals 4 damage. +1 if target has no Defense.', class:'shroud' },
  'SH-A02': { id:'SH-A02', name:'Shadow Bolt', type:'attack', cost:3, atk:5, def:0, ability:'Deals 5 damage. Target cannot block.', class:'shroud' },
  'SH-A03': { id:'SH-A03', name:'Silence', type:'attack', cost:1, atk:3, def:0, ability:'Deals 3 damage. Target loses ability to use cards.', class:'shroud' },
  'SH-A04': { id:'SH-A04', name:'Vengeance', type:'attack', cost:3, atk:6, def:0, ability:'Deals 6 damage. Gain 2 Energy.', class:'shroud' },
  'SH-D01': { id:'SH-D01', name:'Blur', type:'defense', cost:3, atk:0, def:2, ability:'Gain 2 Defense. Ignore next attack.', class:'shroud' },
  'SH-D02': { id:'SH-D02', name:'Step', type:'defense', cost:2, atk:0, def:3, ability:'Gain 3 Defense. Gain 1 Energy.', class:'shroud' },
  'SH-D03': { id:'SH-D03', name:'Evasion', type:'defense', cost:1, atk:0, def:1, ability:'Gain 1 Defense. Skip enemy action.', class:'shroud' },
  'SH-D04': { id:'SH-D04', name:'Phantom', type:'defense', cost:2, atk:0, def:4, ability:'Gain 4 Defense. Ghost form for 1 turn.', class:'shroud' },
  'SH-U01': { id:'SH-U01', name:'Dash', type:'other', cost:1, atk:0, def:0, ability:'Gain 1 Energy. Skip enemy attack.', class:'shroud' },
  'SH-U02': { id:'SH-U02', name:'Teleport', type:'other', cost:2, atk:0, def:0, ability:'Move to back row. Deal 2 damage.', class:'shroud' },
  'SH-U03': { id:'SH-U03', name:'Hide', type:'other', cost:2, atk:0, def:0, ability:'Gain 1 Defense. Discard 1 card. Draw 2.', class:'shroud' },
  'SH-U04': { id:'SH-U04', name:'Assassinate', type:'other', cost:3, atk:8, def:0, ability:'Deal 8 damage. Cannot be blocked.', class:'shroud' },
};

// ===== ENEMY DEFINITIONS =====
const ENEMY_TYPES = {
  floor1: [
    { id:'goblin', name:'Goblin', hp:20, dmg:3, svg:'enemy-goblin' },
    { id:'rat', name:'Rat', hp:18, dmg:4, svg:'enemy-rat' },
  ],
  floor2: [
    { id:'vampire', name:'Vampire Knight', hp:30, dmg:5, svg:'enemy-vampire' },
    { id:'ogre', name:'Ogre', hp:35, dmg:6, svg:'enemy-ogre' },
  ],
  floor3: [
    { id:'voidwarrior', name:'Void Warrior', hp:40, dmg:8, svg:'enemy-voidwarrior' },
    { id:'cultist', name:'Cultist', hp:35, dmg:10, svg:'enemy-cultist' },
  ],
  bosses: [
    { id:'boss-gatekeeper', name:'The Gatekeeper', hp:80, dmg:15, svg:'boss-gatekeeper', boss:true, mechanic:'gatekeeper' },
    { id:'boss-corrupted', name:'The Corrupted', hp:80, dmg:15, svg:'boss-corrupted', boss:true, mechanic:'corrupted' },
    { id:'boss-voidlord', name:'The Void Lord', hp:80, dmg:15, svg:'boss-voidlord', boss:true, mechanic:'voidlord' },
  ]
};

// ===== GAME STATE =====
var game = {
  class: null,
  floor: 1,
  room: 0,
  totalRooms: 12, // 9 regular + 3 bosses
  hero: {
    hp: 35, maxHp: 35,
    energy: 3, maxEnergy: 5,
    gold: 0,
    deck: [],
    hand: [],
    discard: [],
    inventory: {}, // cardId -> count
    permanentDefense: 0,
    block: 0,
  },
  enemy: null,
  turn: 'player', // 'player' or 'enemy'
  isBossFight: false,
  stats: { cardsPlayed: 0, damageDealt: 0, goldEarned: 0, roomsCleared: 0 },
  shopAvailable: false,
  skipEnemyAction: false,
};

// ===== CLASS CONFIG =====
const CLASS_CONFIG = {
  bastion: { startHp: 35, startEnergy: 3, startDeck: ['BA-A01','BA-A02','BA-A03','BA-A04','BA-D01','BA-D02','BA-D03','BA-D04','BA-U01','BA-U02','BA-U03','BA-U04'] },
  wither: { startHp: 28, startEnergy: 3, startDeck: ['WI-A01','WI-A02','WI-A03','WI-A04','WI-D01','WI-D02','WI-D03','WI-D04','WI-U01','WI-U02','WI-U03','WI-U04'] },
  shroud: { startHp: 30, startEnergy: 3, startDeck: ['SH-A01','SH-A02','SH-A03','SH-A04','SH-D01','SH-D02','SH-D03','SH-D04','SH-U01','SH-U02','SH-U03','SH-U04'] },
};

// ===== UTILITY =====
function shuffle(arr) {
  const a = [...arr];
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

function showScreen(id) {
  document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
  document.getElementById(id).classList.add('active');
}

function addLog(text, type = '') {
  const log = document.getElementById('combat-log');
  const entry = document.createElement('div');
  entry.className = `log-entry ${type}`;
  entry.textContent = text;
  log.appendChild(entry);
  setTimeout(() => entry.remove(), 2000);
}

function addDamagePopup(value, targetEl, color = '#e74c3c') {
  const popup = document.createElement('div');
  popup.className = 'damage-popup';
  popup.textContent = value;
  popup.style.color = color;
  popup.style.left = targetEl.getBoundingClientRect().left + targetEl.offsetWidth/2 - 20 + 'px';
  popup.style.top = targetEl.getBoundingClientRect().top + 'px';
  document.body.appendChild(popup);
  setTimeout(() => popup.remove(), 1000);
}

// ===== CLASS SELECTION =====
function selectClass(cls) {
  game.class = cls;
  const cfg = CLASS_CONFIG[cls];
  game.hero.maxHp = cfg.startHp;
  game.hero.hp = cfg.startHp;
  game.hero.maxEnergy = 5;
  game.hero.energy = cfg.startEnergy;
  game.hero.deck = shuffle([...cfg.startDeck, ...cfg.startDeck]); // 2 copies of each starter
  game.hero.discard = [];
  game.hero.inventory = {};
  game.hero.permanentDefense = 0;
  game.hero.block = 0;
  game.hero.gold = 0;
  game.floor = 1;
  game.room = 0;
  game.stats = { cardsPlayed: 0, damageDealt: 0, goldEarned: 0, roomsCleared: 0 };
  game.shopAvailable = false;
  game.skipEnemyAction = false;

  showScreen('combat-screen');
  startCombat();
}

// ===== COMBAT =====
function startCombat() {
  game.hero.block = 0;
  game.hero.energy = game.hero.maxEnergy;
  game.hero.permanentDefense = 0;
  game.skipEnemyAction = false;
  game.turn = 'player';

  // Determine enemy
  if (game.room % 3 === 2) {
    // Boss fight
    const bossIdx = Math.floor(game.room / 3);
    const bossDef = ENEMY_TYPES.bosses[bossIdx];
    game.enemy = Object.assign({}, bossDef, {
      currentHp: Number(bossDef.hp),
      maxHp: Number(bossDef.hp),
      currentDmg: Number(bossDef.dmg),
      block: 0,
      statusEffects: {},
      isBoss: true,
      mechanicState: {},
    });
    game.isBossFight = true;
  } else {
    const floorKey = 'floor' + game.floor;
    const types = ENEMY_TYPES[floorKey];
    const def = types[Math.floor(Math.random() * types.length)];
    game.enemy = Object.assign({}, def, {
      currentHp: Number(def.hp),
      maxHp: Number(def.hp),
      currentDmg: Number(def.dmg),
      block: 0,
      statusEffects: {},
      isBoss: false,
      mechanicState: {},
    });
    game.isBossFight = false;
  }

  // Discard hand and refresh deck
  game.hero.discard = [...game.hero.hand, ...game.hero.discard];
  game.hero.hand = [];
  drawCards(4);

  updateHUD();
  updateEnergyPips();
  renderEnemy();
  renderHand();
  updateTurnIndicator();
  document.getElementById('btn-shop').style.display = 'none';
  document.getElementById('btn-end-turn').disabled = false;
}

function drawCards(count) {
  let drawn = 0;
  while (drawn < count && game.hero.deck.length > 0) {
    if (game.hero.hand.length >= 5 + (game.class === 'shroud' ? 1 : 0)) break;
    if (game.hero.deck.length === 0) {
      game.hero.deck = shuffle(game.hero.discard);
      game.hero.discard = [];
    }
    game.hero.hand.push(game.hero.deck.pop());
    drawn++;
  }
  return drawn;
}

function updateHUD() {
  // Gold
  document.getElementById('hud-gold').textContent = game.hero.gold;

  // Floor
  document.getElementById('hud-floor').textContent = `Floor ${game.floor}`;

  // Enemy HP
  const hpPct = Math.max(0, (game.enemy.currentHp / game.enemy.maxHp) * 100);
  document.getElementById('enemy-hp-fill').style.width = hpPct + '%';
  document.getElementById('enemy-hp-text').textContent = `${Math.max(0, game.enemy.currentHp)} / ${game.enemy.maxHp}`;
  document.getElementById('hud-enemy-hp').textContent = `${Math.max(0, game.enemy.currentHp)} / ${game.enemy.maxHp}`;

  // Player HP
  const hpPct2 = Math.max(0, (game.hero.hp / game.hero.maxHp) * 100);
  document.getElementById('player-hp-fill').style.width = hpPct2 + '%';
  document.getElementById('player-hp-text').textContent = `${Math.max(0, game.hero.hp)} / ${game.hero.maxHp}`;

  // Block
  document.getElementById('player-block').textContent = game.hero.block;
}

function updateEnergyPips() {
  const container = document.getElementById('energy-pips');
  container.innerHTML = '';
  for (let i = 0; i < game.hero.maxEnergy; i++) {
    const pip = document.createElement('div');
    pip.className = 'energy-pip';
    if (i < game.hero.energy) {
      pip.classList.add('filled');
    }
    container.appendChild(pip);
  }
}

function updateTurnIndicator() {
  const el = document.getElementById('turn-indicator');
  if (game.turn === 'player') {
    el.textContent = 'Your Turn';
    el.style.color = 'var(--text-gold)';
  } else {
    el.textContent = 'Enemy Turn';
    el.style.color = 'var(--hp-red)';
  }
}

function renderEnemy() {
  const sprite = document.getElementById('enemy-sprite');
  sprite.innerHTML = `<svg viewBox="0 0 160 180">${game.enemy.svg ? `<use href="#${game.enemy.svg}"/>` : ''}</svg>`;
  document.getElementById('enemy-name').textContent = game.enemy.name;
  renderEnemyStatus();
}

function renderEnemyStatus() {
  const container = document.getElementById('enemy-status');
  container.innerHTML = '';
  for (const [type, count] of Object.entries(game.enemy.statusEffects)) {
    if (count <= 0) continue;
    const icon = document.createElement('div');
    icon.className = `status-icon status-${type.toLowerCase()}`;
    icon.textContent = count;
    icon.title = `${type}: ${count} turns`;
    container.appendChild(icon);
  }
}

function renderHand() {
  const container = document.getElementById('hand-area');
  container.innerHTML = '';
  game.hero.hand.forEach((cardId, idx) => {
    const card = ALL_CARDS[cardId];
    const canPlay = game.turn === 'player' && card.cost <= game.hero.energy;
    const div = document.createElement('div');
    div.className = `card card-type-${card.type} ${canPlay ? '' : 'unplayable'}`;
    div.dataset.idx = idx;
    div.onclick = () => playCard(idx);

    const frameId = `frame-${card.class}`;
    const backId = `cardback-${card.class}`;

    div.innerHTML = `
      <div class="card-inner">
        <div class="card-cost">${card.cost}</div>
        <div class="card-art">
          <div class="card-art-bg"></div>
          <svg class="card-art-placeholder" viewBox="0 0 50 50">
            <use href="#${backId}"/>
          </svg>
        </div>
        <div class="card-info">
          <div class="card-name">${card.name}</div>
          <div class="card-stats">${card.type === 'attack' ? `⚔ ${card.atk}` : card.type === 'defense' ? `🛡 ${card.def}` : '✦ Other'}</div>
          <div class="card-ability">${card.ability}</div>
        </div>
      </div>
    `;
    container.appendChild(div);
  });
}

// ===== CARD PLAY =====
function playCard(handIdx) {
  if (game.turn !== 'player') return;
  const cardId = game.hero.hand[handIdx];
  const card = ALL_CARDS[cardId];
  if (card.cost > game.hero.energy) return;

  // Pay energy
  game.hero.energy -= card.cost;
  updateEnergyPips();

  // Execute card effect
  executeCardEffect(card, handIdx);

  // Move card to discard
  game.hero.discard.push(game.hero.hand.splice(handIdx, 1)[0]);
  game.stats.cardsPlayed++;

  updateHUD();
  renderHand();

  // Check if enemy is dead
  if (game.enemy.currentHp <= 0) {
    setTimeout(() => enemyDefeated(), 600);
  }
}

function executeCardEffect(card, handIdx) {
  const enemy = game.enemy;

  if (card.type === 'attack') {
    let damage = card.atk;

    // Backstab bonus
    if (card.id === 'SH-A01' && enemy.currentHp > 0 && enemy.currentHp <= enemy.maxHp) {
      // Check if target has no armor - simplified: always +1 for this prototype
      damage += 1;
    }

    // Shadow Bolt: target cannot block (handled in damage calculation)
    if (card.id === 'SH-A02') {
      enemy.block = Math.max(0, enemy.block); // no effect on enemy
    }

    // Deal damage
    if (enemy.currentHp > 0) {
      let blocked = 0;
      if (card.id !== 'SH-U04') { // Assassinate cannot be blocked
        blocked = Math.min(enemy.block, damage);
        enemy.block -= blocked;
      }
      const actualDmg = damage - blocked;
      enemy.currentHp -= actualDmg;
      game.stats.damageDealt += actualDmg;
      addLog(`Dealt ${actualDmg} damage!`, 'damage');
      addDamagePopup(actualDmg, document.getElementById('enemy-sprite'), '#e74c3c');

      // Hit animation
      const sprite = document.getElementById('enemy-sprite');
      sprite.classList.remove('hit');
      void sprite.offsetWidth;
      sprite.classList.add('hit');
    }

    // Status effects
    if (card.id === 'WI-A01') {
      enemy.statusEffects['Burn'] = (enemy.statusEffects['Burn'] || 0) + 1;
      addLog('Applied 1 Burn!', 'status');
    }
    if (card.id === 'WI-A02') {
      enemy.statusEffects['Burn'] = (enemy.statusEffects['Burn'] || 0) + 3;
      addLog('Applied 3 Burn!', 'status');
    }
    if (card.id === 'WI-A03') {
      enemy.statusEffects['Burn'] = (enemy.statusEffects['Burn'] || 0) + 1;
      addLog('Applied 1 Burn!', 'status');
    }
    if (card.id === 'BA-D04') {
      enemy.statusEffects['Stun'] = (enemy.statusEffects['Stun'] || 0) + 1;
      addLog('Stunned enemy!', 'status');
    }
    if (card.id === 'WI-U01') {
      enemy.statusEffects['Poison'] = (enemy.statusEffects['Poison'] || 0) + 1;
      addLog('Applied 1 Poison!', 'status');
    }
    if (card.id === 'WI-U03') {
      enemy.statusEffects['Stun'] = (enemy.statusEffects['Stun'] || 0) + 1;
      addLog('Stunned enemy!', 'status');
    }
    if (card.id === 'SH-A03') {
      enemy.statusEffects['Silence'] = (enemy.statusEffects['Silence'] || 0) + 1;
      addLog('Silenced enemy!', 'status');
    }

    // Pyre: all enemies take 1 damage next turn (handled at start of next player turn)
    if (card.id === 'WI-A04') {
      enemy.mechanicState['pyreNextTurn'] = true;
    }

  } else if (card.type === 'defense') {
    let blockGain = card.def;
    game.hero.block += blockGain;
    addLog(`Gained ${blockGain} Block!`, 'block');

    // Iron Skin: permanent defense + discard
    if (card.id === 'BA-D02') {
      game.hero.permanentDefense += blockGain;
      // Discard 1 random card
      if (game.hero.hand.length > 0) {
        const discardIdx = Math.floor(Math.random() * game.hero.hand.length);
        game.hero.discard.push(game.hero.hand.splice(discardIdx, 1)[0]);
        addLog('Discarded 1 card.', 'block');
      }
    }

    // Stand Firm: blocks 1 extra
    if (card.id === 'BA-D03') {
      game.hero.block += 1;
      addLog('Extra block!', 'block');
    }

    // Heat Resist: gain energy
    if (card.id === 'WI-D02') {
      game.hero.energy = Math.min(game.hero.maxEnergy, game.hero.energy + 1);
      updateEnergyPips();
      addLog('+1 Energy!', 'energy');
    }

    // Step: gain energy
    if (card.id === 'SH-D02') {
      game.hero.energy = Math.min(game.hero.maxEnergy, game.hero.energy + 1);
      updateEnergyPips();
      addLog('+1 Energy!', 'energy');
    }

    // Evasion: skip enemy action
    if (card.id === 'SH-D03') {
      game.skipEnemyAction = true;
      addLog('Enemy action skipped!', 'energy');
    }

    // Phantom: ghost form (skip next attack)
    if (card.id === 'SH-D04') {
      game.skipEnemyAction = true;
      addLog('Ghost form - next attack ignored!', 'energy');
    }

    // Scorch Shield / Smoke: block burn damage (passive, handled in damage calc)

  } else if (card.type === 'other') {
    if (card.id === 'BA-U01') {
      // Search: draw 1, discard if > 5
      drawCards(1);
      if (game.hero.hand.length > 5) {
        while (game.hero.hand.length > 5) {
          game.hero.discard.push(game.hero.hand.pop());
        }
        addLog('Hand discarded (too large).', 'block');
      }
      addLog('Drew 1 card!', 'energy');
    }
    if (card.id === 'BA-U02') {
      const heal = Math.min(6, game.hero.maxHp - game.hero.hp);
      game.hero.hp += heal;
      addLog(`Healed ${heal} HP!`, 'heal');
      addDamagePopup(`+${heal}`, document.getElementById('player-hp-fill'), '#2ecc71');
    }
    if (card.id === 'BA-U03') {
      drawCards(1);
      game.hero.energy = Math.min(game.hero.maxEnergy, game.hero.energy + 1);
      updateEnergyPips();
      addLog('+1 Energy, drew 1 card!', 'energy');
    }
    if (card.id === 'BA-U04') {
      game.hero.gold += 5;
      game.stats.goldEarned += 5;
      addLog('+5 Gold!', 'gold');
    }
    if (card.id === 'WI-U02') {
      let dmg = 3;
      if (enemy.currentHp > 0) {
        let blocked = Math.min(enemy.block, dmg);
        enemy.block -= blocked;
        enemy.currentHp -= (dmg - blocked);
        game.stats.damageDealt += (dmg - blocked);
        addLog(`Dealt ${dmg - blocked} damage!`, 'damage');
        addDamagePopup(dmg - blocked, document.getElementById('enemy-sprite'), '#e74c3c');
      }
      enemy.statusEffects['Burn'] = (enemy.statusEffects['Burn'] || 0) + 2;
      addLog('Applied 2 Burn to all enemies!', 'status');
    }
    if (card.id === 'WI-U04') {
      const heal = Math.min(5, game.hero.maxHp - game.hero.hp);
      game.hero.hp += heal;
      game.enemy.currentDmg = Math.max(1, game.enemy.currentDmg - 1);
      addLog(`Healed ${heal} HP. Enemy ATK -1.`, 'heal');
    }
    if (card.id === 'SH-U01') {
      game.hero.energy = Math.min(game.hero.maxEnergy, game.hero.energy + 1);
      updateEnergyPips();
      game.skipEnemyAction = true;
      addLog('+1 Energy. Enemy attack skipped!', 'energy');
    }
    if (card.id === 'SH-U02') {
      let dmg = 2;
      if (enemy.currentHp > 0) {
        enemy.currentHp -= dmg;
        game.stats.damageDealt += dmg;
        addLog(`Dealt ${dmg} damage!`, 'damage');
        addDamagePopup(dmg, document.getElementById('enemy-sprite'), '#e74c3c');
      }
    }
    if (card.id === 'SH-U03') {
      game.hero.block += 1;
      if (game.hero.hand.length > 0) {
        game.hero.discard.push(game.hero.hand.splice(Math.floor(Math.random() * game.hero.hand.length), 1)[0]);
      }
      drawCards(2);
      addLog('+1 Block. Discarded 1, drew 2!', 'block');
    }
    if (card.id === 'SH-U04') {
      let dmg = 8;
      if (enemy.currentHp > 0) {
        enemy.currentHp -= dmg;
        game.stats.damageDealt += dmg;
        addLog(`Dealt ${dmg} damage!`, 'damage');
        addDamagePopup(dmg, document.getElementById('enemy-sprite'), '#e74c3c');
      }
    }
  }

  // Update HUD after card play
  updateHUD();
  renderEnemyStatus();
}

// ===== END TURN =====
function endTurn() {
  if (game.turn !== 'player') return;
  game.turn = 'enemy';
  updateTurnIndicator();

  // Process burn/poison DoTs on enemy
  processDoT(game.enemy, 'enemy');

  // Pyre damage from WI-A04
  if (game.enemy.mechanicState['pyreNextTurn']) {
    game.enemy.currentHp -= 1;
    game.enemy.mechanicState['pyreNextTurn'] = false;
    addLog('Pyre burns the enemy!', 'status');
    if (game.enemy.currentHp <= 0) {
      setTimeout(() => enemyDefeated(), 400);
      return;
    }
  }

  // Boss mechanics - Gatekeeper
  if (game.enemy.mechanicState['gatekeeper'] && game.enemy.currentHp < 20) {
    game.enemy.mechanicState['gatekeeper'] = false;
  }
  if (game.enemy.mechanicState['gatekeeper']) {
    game.enemy.block += 5;
    addLog('Gatekeeper blocks 5 damage!', 'block');
  }

  // Boss mechanics - Corrupted
  if (game.enemy.mechanicState['corrupted'] && game.hero.energy < 3) {
    const extraDmg = 20;
    const actualDmg = Math.max(0, extraDmg - game.hero.block - game.hero.permanentDefense);
    game.hero.hp -= actualDmg;
    game.hero.block = Math.max(0, game.hero.block - extraDmg);
    addLog(`Corrupted deals ${extraDmg} burst!`, 'damage');
    addDamagePopup(extraDmg, document.getElementById('player-hp-fill'), '#e74c3c');
  }

  // Boss mechanics - Void Lord regen
  if (game.enemy.mechanicState['voidlord']) {
    const regen = 10;
    game.enemy.currentHp = Math.min(game.enemy.maxHp, game.enemy.currentHp + regen);
    addLog(`Void Lord regenerates ${regen} HP!`, 'heal');
    updateHUD();
  }

  // Enemy action
  setTimeout(() => {
    if (game.skipEnemyAction) {
      game.skipEnemyAction = false;
      addLog('Enemy action skipped!', 'energy');
      startNewTurn();
      return;
    }

    if (game.enemy.statusEffects['Stun'] && game.enemy.statusEffects['Stun'] > 0) {
      game.enemy.statusEffects['Stun']--;
      addLog(`${game.enemy.name} is stunned!`, 'status');
      startNewTurn();
      return;
    }

    if (game.enemy.statusEffects['Silence'] && game.enemy.statusEffects['Silence'] > 0) {
      game.enemy.statusEffects['Silence']--;
      addLog(`${game.enemy.name} is silenced!`, 'status');
      startNewTurn();
      return;
    }

    // Boss special attacks
    if (game.enemy.isBoss) {
      resolveBossAttack();
    } else {
      resolveEnemyAttack();
    }
  }, 800);
}

function resolveEnemyAttack() {
  const enemy = game.enemy;
  if (enemy.currentHp <= 0) return;

  const rawDmg = enemy.currentDmg;

  // Check if attack should be ignored (Blur, Phantom, etc.)
  if (game.skipEnemyAction) {
    game.skipEnemyAction = false;
    addLog('Attack ignored!', 'block');
    startNewTurn();
    return;
  }

  // Cannot be blocked check (Assassinate effect - already handled)
  const blockAmount = game.hero.block + game.hero.permanentDefense;
  const actualDmg = Math.max(0, rawDmg - blockAmount);

  game.hero.block = Math.max(0, game.hero.block - rawDmg);
  game.hero.permanentDefense = Math.max(0, game.hero.permanentDefense - Math.max(0, rawDmg - game.hero.block));

  game.hero.hp -= actualDmg;
  addLog(`${enemy.name} deals ${actualDmg} damage!`, 'damage');
  addDamagePopup(actualDmg, document.getElementById('player-hp-fill'), '#e74c3c');

  updateHUD();

  if (game.hero.hp <= 0) {
    setTimeout(() => playerDefeated(), 500);
    return;
  }

  setTimeout(() => startNewTurn(), 600);
}

function resolveBossAttack() {
  const enemy = game.enemy;
  if (enemy.currentHp <= 0) return;

  let rawDmg = enemy.currentDmg;

  // Gatekeeper special: blocks 5 per turn until HP < 20
  if (enemy.mechanicState['gatekeeper'] && enemy.block > 0) {
    const blocked = Math.min(enemy.block, rawDmg);
    enemy.block -= blocked;
    rawDmg -= blocked;
    addLog(`Gatekeeper blocks ${blocked}!`, 'block');
  }

  // Corrupted special: if player has < 3 energy, deal 20 extra
  if (enemy.mechanicState['corrupted'] && game.hero.energy < 3) {
    rawDmg += 20;
    addLog('Corrupted burst attacks!', 'damage');
  }

  // Void Lord special: cannot be blocked
  if (enemy.mechanicState['voidlord']) {
    game.hero.hp -= rawDmg;
    addLog(`Void Lord deals ${rawDmg} (unblockable)!`, 'damage');
    addDamagePopup(rawDmg, document.getElementById('player-hp-fill'), '#6c3483');
    updateHUD();
    if (game.hero.hp <= 0) {
      setTimeout(() => playerDefeated(), 500);
      return;
    }
    setTimeout(() => startNewTurn(), 600);
    return;
  }

  const blockAmount = game.hero.block;
  const actualDmg = Math.max(0, rawDmg - blockAmount);
  game.hero.block = Math.max(0, game.hero.block - rawDmg);
  game.hero.hp -= actualDmg;
  addLog(`${enemy.name} deals ${actualDmg} damage!`, 'damage');
  addDamagePopup(actualDmg, document.getElementById('player-hp-fill'), '#e74c3c');

  updateHUD();

  if (game.hero.hp <= 0) {
    setTimeout(() => playerDefeated(), 500);
    return;
  }

  setTimeout(() => startNewTurn(), 600);
}

function processDoT(target, targetType) {
  if (targetType === 'enemy') {
    // Burn
    if (target.statusEffects['Burn'] && target.statusEffects['Burn'] > 0) {
      const burnDmg = target.statusEffects['Burn'];
      target.currentHp -= burnDmg;
      addLog(`${burnDmg} Burn damage!`, 'status');
      addDamagePopup(burnDmg, document.getElementById('enemy-sprite'), '#f39c12');
      target.statusEffects['Burn']--;
      if (target.currentHp <= 0) {
        setTimeout(() => enemyDefeated(), 400);
      }
    }
    // Poison
    if (target.statusEffects['Poison'] && target.statusEffects['Poison'] > 0) {
      const poisonDmg = target.statusEffects['Poison'];
      target.currentHp -= poisonDmg;
      addLog(`${poisonDmg} Poison damage!`, 'status');
      addDamagePopup(poisonDmg, document.getElementById('enemy-sprite'), '#2ecc71');
      target.statusEffects['Poison']--;
      if (target.currentHp <= 0) {
        setTimeout(() => enemyDefeated(), 400);
      }
    }
  }
}

function startNewTurn() {
  game.turn = 'player';
  game.hero.energy = Math.min(game.hero.maxEnergy, game.hero.energy + 1);
  updateEnergyPips();

  // Draw cards
  drawCards(4);
  renderHand();
  updateHUD();
  updateTurnIndicator();
  document.getElementById('btn-shop').style.display = 'none';
  document.getElementById('btn-end-turn').disabled = false;
}

// ===== ENEMY DEFEATED =====
function enemyDefeated() {
  const goldReward = game.enemy.isBoss ? 15 : 5;
  game.hero.gold += goldReward;
  game.stats.goldEarned += goldReward;
  game.stats.roomsCleared++;
  addLog(`${game.enemy.name} defeated! +${goldReward} Gold`, 'gold');

  if (game.isBossFight) {
    game.floor++;
    if (game.floor > 3) {
      setTimeout(() => showVictory(), 1000);
      return;
    }
    // Floor transition
    showFloorTransition(`Floor ${game.floor}`, getFloorDescription(game.floor));
    setTimeout(() => {
      game.room++;
      startCombat();
    }, 2000);
  } else {
    game.room++;
    if (game.room >= game.totalRooms) {
      setTimeout(() => showVictory(), 1000);
      return;
    }
    // Show shop after rooms 1 and 4 (between boss fights)
    if (game.room === 1 || game.room === 4) {
      setTimeout(() => openShop(), 800);
    } else {
      setTimeout(() => startCombat(), 1000);
    }
  }
}

function getFloorDescription(floor) {
  const descs = {
    1: 'Goblins and rats lurk in the shadows.',
    2: 'Vampire Knights and Ogres guard the path.',
    3: 'The Void Warriors and Cultists await.',
  };
  return descs[floor] || '';
}

function showFloorTransition(title, subtitle) {
  const el = document.createElement('div');
  el.className = 'floor-transition';
  el.innerHTML = `
    <div class="floor-transition-title">${title}</div>
    <div class="floor-transition-sub">${subtitle}</div>
  `;
  document.body.appendChild(el);
  setTimeout(() => {
    el.style.opacity = '0';
    el.style.transition = 'opacity 0.5s';
    setTimeout(() => el.remove(), 500);
  }, 1800);
}

// ===== SHOP =====
function openShop() {
  showScreen('shop-screen');
  document.getElementById('shop-gold').textContent = game.hero.gold;

  const container = document.getElementById('shop-cards');
  container.innerHTML = '';

  // Generate 3 random cards from the player's class
  const classCards = Object.values(ALL_CARDS).filter(c => c.class === game.class);
  const available = classCards.filter(c => (game.hero.inventory[c.id] || 0) < 5);
  const shopCards = shuffle(available).slice(0, 3);

  if (shopCards.length === 0) {
    container.innerHTML = '<p style="color:var(--text-secondary); font-style:italic;">No cards available. You own all copies.</p>';
  }

  shopCards.forEach(card => {
    const owned = game.hero.inventory[card.id] || 0;
    const cost = Math.min(50, card.cost + owned); // Cost scaling
    const div = document.createElement('div');
    div.className = 'shop-card';
    div.onclick = () => buyCard(card.id);

    const frameId = `frame-${card.class}`;

    div.innerHTML = `
      <div class="shop-card-inner">
        <div class="shop-card-cost">${cost}</div>
        <div class="shop-card-owned">Owned: ${owned}/5</div>
        <div class="shop-card-art">
          <svg viewBox="0 0 130 120">
            <use href="#${frameId}"/>
          </svg>
        </div>
        <div class="shop-card-info">
          <div class="shop-card-name">${card.name}</div>
          <div class="shop-card-ability">${card.ability}</div>
          <div class="shop-card-price">${cost} Gold</div>
        </div>
      </div>
    `;
    container.appendChild(div);
  });
}

function buyCard(cardId) {
  const card = ALL_CARDS[cardId];
  const owned = game.hero.inventory[cardId] || 0;
  const cost = Math.min(50, card.cost + owned);

  if (game.hero.gold < cost) {
    addLog('Not enough gold!', 'damage');
    return;
  }
  if (owned >= 5) return;

  game.hero.gold -= cost;
  game.hero.inventory[cardId] = owned + 1;
  game.hero.deck.push(cardId);

  document.getElementById('shop-gold').textContent = game.hero.gold;
  addLog(`Bought ${card.name}!`, 'gold');
  openShop(); // Refresh shop
}

function closeShop() {
  showScreen('combat-screen');
  startCombat();
}

// ===== VICTORY / DEFEAT =====
function showVictory() {
  showScreen('victory-screen');
  document.getElementById('victory-stats').innerHTML = `
    Class: <span>${game.class.charAt(0).toUpperCase() + game.class.slice(1)}</span><br>
    Rooms Cleared: <span>${game.stats.roomsCleared}</span><br>
    Damage Dealt: <span>${game.stats.damageDealt}</span><br>
    Gold Earned: <span>${game.stats.goldEarned}</span><br>
    Cards Played: <span>${game.stats.cardsPlayed}</span>
  `;
}

function playerDefeated() {
  showScreen('defeat-screen');
  document.getElementById('defeat-stats').innerHTML = `
    Class: <span>${game.class.charAt(0).toUpperCase() + game.class.slice(1)}</span><br>
    Floor Reached: <span>${game.floor}</span><br>
    Rooms Cleared: <span>${game.stats.roomsCleared}</span><br>
    Damage Dealt: <span>${game.stats.damageDealt}</span><br>
    Cards Played: <span>${game.stats.cardsPlayed}</span>
  `;
}

// ===== INIT =====
// Auto-select first class for testing if needed
// selectClass('bastion');
</script>
</body>
</html>
<!-- agent-meta {"model":"qwen/qwen3.6-35b-a3b","provider":"lmstudio","persona":"full","sessionId":"ad2ad3aa-665f-4510-a40e-24144a71df97","tokensIn":1926234,"tokensOut":56345,"tokensTotal":1982579,"turns":40,"toolCalls":39,"failedToolCalls":1,"timestamp":"2026-07-21T02:41:29.164Z"} -->