<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SlashClash v2: Crypto Hero Duels</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&family=Rajdhani:wght@400;600;700&display=swap');

:root {
  --gold: #f59e0b;
  --red: #ef4444;
  --green: #10b981;
  --blue: #3b82f6;
  --bg: #04040f;
  --surface: rgba(255,255,255,0.04);
  --border: rgba(255,255,255,0.08);
}
* { margin:0; padding:0; box-sizing:border-box; }
body { background:var(--bg); overflow:hidden; font-family:'Rajdhani',sans-serif; color:#fff; user-select:none; }
#c { display:block; width:100vw; height:100vh; }

/* ── SCAN LINE OVERLAY ── */
body::after {
  content:''; position:fixed; inset:0; pointer-events:none; z-index:200;
  background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.03) 2px, rgba(0,0,0,0.03) 4px);
}

/* ── HUD SHELL ── */
#hud { position:fixed; inset:0; pointer-events:none; display:flex; flex-direction:column; z-index:10; }

/* ── TOP BAR ── */
#top-bar { display:flex; justify-content:space-between; align-items:flex-start; padding:12px 16px 0; gap:8px; }

.hero-panel { display:flex; flex-direction:column; gap:5px; min-width:190px; }
.hero-panel.right { align-items:flex-end; }

.hero-name {
  font-family:'Orbitron',monospace; font-size:13px; font-weight:900;
  letter-spacing:3px; text-transform:uppercase;
  text-shadow: 0 0 12px currentColor;
}
.hero-type-badge {
  font-family:'Share Tech Mono',monospace;
  font-size:10px; letter-spacing:2px; padding:2px 8px; border-radius:2px;
  display:inline-block; border:1px solid currentColor;
}
.hp-bar-wrap {
  width:190px; height:6px; background:rgba(255,255,255,0.08);
  border-radius:0; overflow:hidden; position:relative;
  border:1px solid rgba(255,255,255,0.12);
}
.hp-bar {
  height:100%; border-radius:0;
  transition:width 0.5s cubic-bezier(.4,0,.2,1);
  position:relative;
}
.hp-bar::after {
  content:''; position:absolute; right:0; top:0; bottom:0; width:3px;
  background:rgba(255,255,255,0.6); box-shadow:0 0 6px #fff;
}
.hp-text { font-family:'Share Tech Mono',monospace; font-size:10px; opacity:0.6; }
.stake-text { font-family:'Share Tech Mono',monospace; font-size:10px; color:var(--gold); }

/* ── CENTER HUD ── */
#turn-center {
  flex:1; text-align:center; display:flex; flex-direction:column;
  align-items:center; gap:3px; padding-top:6px;
}
#turn-label { font-family:'Share Tech Mono',monospace; font-size:9px; letter-spacing:4px; opacity:0.4; }
#turn-num { font-family:'Orbitron',monospace; font-size:30px; font-weight:900; line-height:1; }
#streak-badge {
  font-family:'Share Tech Mono',monospace; font-size:10px; letter-spacing:2px;
  padding:2px 10px; border:1px solid var(--gold); color:var(--gold);
  text-shadow:0 0 8px var(--gold); box-shadow:0 0 12px rgba(245,158,11,0.3);
  display:none;
}
#mode-badge {
  font-family:'Share Tech Mono',monospace; font-size:8px; letter-spacing:3px;
  padding:1px 8px; border:1px solid rgba(255,255,255,0.2); opacity:0.5;
  margin-top:2px;
}

/* ── PRICE TICKER ── */
#ticker {
  position:fixed; top:108px; left:50%; transform:translateX(-50%);
  text-align:center; pointer-events:none; z-index:11;
}
#price-label {
  font-family:'Orbitron',monospace; font-size:20px; font-weight:700;
  letter-spacing:2px; text-shadow:0 0 20px currentColor; transition:color 0.4s;
}
#price-delta {
  font-family:'Share Tech Mono',monospace; font-size:11px;
  opacity:0.7; margin-top:1px; transition:color 0.4s;
}
#price-hints {
  font-family:'Share Tech Mono',monospace; font-size:9px;
  opacity:0.4; letter-spacing:1px; margin-top:1px;
}

/* ── PRICE CHART ── */
#chart-wrap {
  position:fixed; top:155px; left:50%; transform:translateX(-50%);
  pointer-events:none; z-index:11;
}
#price-chart { display:block; }

/* ── BOTTOM CTRL ── */
#bottom-ctrl {
  margin-top:auto; padding:0 16px 20px;
  display:flex; flex-direction:column; align-items:center; gap:10px;
  pointer-events:all;
}
#phase-text {
  font-family:'Share Tech Mono',monospace; font-size:9px;
  letter-spacing:4px; opacity:0.4; text-transform:uppercase;
}
#stake-display {
  font-family:'Share Tech Mono',monospace; font-size:11px;
  color:var(--gold); display:flex; gap:24px;
}
#stake-display span { opacity:0.5; margin-right:4px; }

#confidence-row { display:flex; align-items:center; gap:10px; font-size:11px; }
#confidence-row label { font-family:'Share Tech Mono',monospace; font-size:9px; letter-spacing:2px; opacity:0.5; }
#conf-slider {
  -webkit-appearance:none; appearance:none;
  width:100px; height:2px; background:rgba(255,255,255,0.15); outline:none; cursor:pointer;
}
#conf-slider::-webkit-slider-thumb {
  -webkit-appearance:none; width:12px; height:12px; border-radius:0;
  background:var(--gold); cursor:pointer; box-shadow:0 0 8px var(--gold);
}
#conf-val { font-family:'Orbitron',monospace; font-weight:700; color:var(--gold); min-width:14px; font-size:12px; }

#predict-btns { display:flex; gap:12px; }
.predict-btn {
  font-family:'Orbitron',monospace; font-size:13px; font-weight:700;
  letter-spacing:3px; padding:11px 32px; border:1px solid transparent;
  border-radius:0; cursor:pointer; position:relative; overflow:hidden;
  clip-path: polygon(8px 0%, 100% 0%, calc(100% - 8px) 100%, 0% 100%);
  transition:transform 0.1s, box-shadow 0.2s, border-color 0.2s;
}
.predict-btn::after {
  content:''; position:absolute; inset:0;
  background:rgba(255,255,255,0.06); opacity:0; transition:opacity 0.15s;
}
.predict-btn:hover::after { opacity:1; }
.predict-btn:active { transform:scale(0.96); }
#btn-up {
  background:linear-gradient(135deg,#065f46,#059669);
  border-color:#10b981; color:#fff;
  box-shadow:0 0 16px rgba(16,185,129,0.3), inset 0 1px 0 rgba(255,255,255,0.1);
}
#btn-up:hover { box-shadow:0 0 28px rgba(16,185,129,0.6); border-color:#34d399; }
#btn-down {
  background:linear-gradient(135deg,#7f1d1d,#dc2626);
  border-color:#ef4444; color:#fff;
  box-shadow:0 0 16px rgba(239,68,68,0.3), inset 0 1px 0 rgba(255,255,255,0.1);
}
#btn-down:hover { box-shadow:0 0 28px rgba(239,68,68,0.6); border-color:#f87171; }
.predict-btn:disabled { opacity:0.25; cursor:not-allowed; transform:none !important; }

/* ── MULTIPLAYER ROW ── */
#mp-row {
  display:flex; gap:10px; align-items:center;
  font-family:'Share Tech Mono',monospace; font-size:9px;
  letter-spacing:2px; opacity:0.5;
}
#mp-status-dot {
  width:6px; height:6px; border-radius:50%;
  background:#10b981; box-shadow:0 0 6px #10b981;
  animation:blink 1.5s ease-in-out infinite;
}
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.3} }

/* ── LEADERBOARD ── */
#leaderboard {
  position:fixed; bottom:110px; right:14px;
  background:rgba(4,4,15,0.8); border:1px solid var(--border);
  padding:10px 12px; font-size:10px; pointer-events:none; min-width:150px;
  clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,100% 100%,8px 100%,0 calc(100% - 8px));
}
#leaderboard h4 {
  font-family:'Share Tech Mono',monospace; font-size:8px;
  letter-spacing:3px; opacity:0.3; margin-bottom:6px;
}
.lb-row { display:flex; justify-content:space-between; gap:10px; padding:2px 0; font-family:'Share Tech Mono',monospace; }
.lb-win { color:#10b981; } .lb-loss { color:#ef4444; }

/* ── FLASH ── */
#flash { position:fixed; inset:0; pointer-events:none; opacity:0; z-index:50; transition:opacity 0.08s; }

/* ── TOAST ── */
#toast {
  position:fixed; top:48%; left:50%; transform:translate(-50%,-50%);
  font-family:'Orbitron',monospace; font-size:28px; font-weight:900;
  letter-spacing:5px; pointer-events:none; opacity:0; z-index:60;
  text-shadow:0 0 30px currentColor; transition:opacity 0.15s;
  white-space:nowrap;
}

/* ── AI THINKING ── */
#ai-thinking {
  position:fixed; top:50%; left:50%; transform:translate(-50%,-50%);
  font-family:'Share Tech Mono',monospace; font-size:10px;
  letter-spacing:4px; opacity:0; pointer-events:none; z-index:55;
  transition:opacity 0.3s; color:var(--gold);
}

/* ── COMBO POPUP ── */
#combo-popup {
  position:fixed; top:38%; left:50%; transform:translate(-50%,-50%);
  font-family:'Orbitron',monospace; font-size:16px; font-weight:900;
  letter-spacing:4px; pointer-events:none; opacity:0; z-index:62;
  text-shadow:0 0 20px var(--gold); color:var(--gold);
  transition:opacity 0.15s;
}

/* ── OVERLAY ── */
#overlay {
  position:fixed; inset:0; background:rgba(2,2,12,0.92);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  z-index:100; backdrop-filter:blur(12px);
}
#overlay-logo {
  font-family:'Orbitron',monospace; font-size:46px; font-weight:900;
  letter-spacing:6px; margin-bottom:4px;
  background:linear-gradient(135deg,#f59e0b,#ef4444,#f59e0b);
  background-size:200%; -webkit-background-clip:text; -webkit-text-fill-color:transparent;
  animation:shimmer 2s linear infinite, pulse2 2s ease-in-out infinite alternate;
}
@keyframes shimmer { 0%{background-position:0%} 100%{background-position:200%} }
@keyframes pulse2 { from{filter:brightness(0.8)} to{filter:brightness(1.2)} }

#overlay-sub {
  font-family:'Share Tech Mono',monospace; font-size:11px;
  letter-spacing:6px; opacity:0.4; margin-bottom:6px;
}
#overlay-version {
  font-family:'Share Tech Mono',monospace; font-size:8px;
  letter-spacing:3px; opacity:0.25; margin-bottom:24px;
}
#overlay-result {
  font-family:'Orbitron',monospace; font-size:32px; font-weight:900;
  letter-spacing:4px; text-shadow:0 0 30px currentColor; margin-bottom:8px;
  display:none;
}
#overlay-reward {
  font-family:'Share Tech Mono',monospace; font-size:13px;
  color:var(--gold); letter-spacing:3px; margin-bottom:4px; display:none;
}
#overlay-streak-msg {
  font-family:'Share Tech Mono',monospace; font-size:10px;
  color:var(--gold); letter-spacing:2px; margin-bottom:28px; display:none;
}

/* Hero select */
#hero-select { display:flex; gap:10px; margin-bottom:24px; flex-wrap:wrap; justify-content:center; }
.hero-card {
  background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1);
  padding:12px 14px; cursor:pointer; text-align:center;
  transition:border-color 0.2s, background 0.2s, transform 0.2s;
  min-width:82px;
  clip-path:polygon(4px 0%,100% 0%,calc(100% - 4px) 100%,0% 100%);
}
.hero-card:hover { transform:translateY(-3px); border-color:rgba(255,255,255,0.3); }
.hero-card.selected { border-color:var(--gold); background:rgba(245,158,11,0.1); box-shadow:0 0 16px rgba(245,158,11,0.25); }
.hero-card-icon { font-size:24px; margin-bottom:4px; }
.hero-card-name { font-family:'Orbitron',monospace; font-size:9px; font-weight:700; letter-spacing:2px; }
.hero-card-type { font-family:'Share Tech Mono',monospace; font-size:8px; opacity:0.4; margin-top:2px; }
.hero-card-special { font-family:'Share Tech Mono',monospace; font-size:7px; opacity:0.3; margin-top:1px; color:var(--gold); }
.hero-card-adv { font-family:'Share Tech Mono',monospace; font-size:7px; opacity:0.3; margin-top:2px; }

/* Mode select */
#mode-select { display:flex; gap:10px; margin-bottom:20px; }
.mode-btn {
  font-family:'Orbitron',monospace; font-size:9px; font-weight:700;
  letter-spacing:2px; padding:8px 18px; border:1px solid rgba(255,255,255,0.15);
  background:transparent; color:rgba(255,255,255,0.4); cursor:pointer;
  transition:all 0.2s;
}
.mode-btn.active { border-color:var(--gold); color:var(--gold); background:rgba(245,158,11,0.1); }

#enter-btn, #rematch-btn {
  font-family:'Orbitron',monospace; font-size:13px; font-weight:900;
  letter-spacing:4px; padding:13px 48px; border:none;
  background:linear-gradient(135deg,#92400e,#f59e0b,#dc2626);
  background-size:200%; color:#000; cursor:pointer;
  clip-path:polygon(10px 0%,100% 0%,calc(100% - 10px) 100%,0% 100%);
  box-shadow:0 0 30px rgba(245,158,11,0.4);
  transition:transform 0.1s, box-shadow 0.2s, background-position 0.3s;
}
#enter-btn:hover, #rematch-btn:hover {
  transform:scale(1.04); box-shadow:0 0 50px rgba(245,158,11,0.6);
  background-position:100%;
}
#enter-btn:active, #rematch-btn:active { transform:scale(0.97); }
#rematch-btn { display:none; }

/* MP lobby */
#mp-lobby {
  display:none; flex-direction:column; align-items:center; gap:10px;
  margin-bottom:20px;
}
#room-code {
  font-family:'Orbitron',monospace; font-size:28px; font-weight:900;
  letter-spacing:8px; color:var(--gold); text-shadow:0 0 20px var(--gold);
}
#mp-waiting {
  font-family:'Share Tech Mono',monospace; font-size:9px;
  letter-spacing:4px; opacity:0.5;
}
#copy-code {
  font-family:'Share Tech Mono',monospace; font-size:8px;
  letter-spacing:2px; padding:4px 12px; border:1px solid rgba(255,255,255,0.2);
  background:transparent; color:rgba(255,255,255,0.4); cursor:pointer;
  transition:all 0.2s;
}
#copy-code:hover { border-color:var(--gold); color:var(--gold); }

/* ── ABILITY INDICATOR ── */
#ability-bar {
  position:fixed; left:50%; transform:translateX(-50%);
  bottom:170px; display:flex; gap:8px; z-index:12; pointer-events:all;
}
.ability-chip {
  font-family:'Share Tech Mono',monospace; font-size:8px; letter-spacing:2px;
  padding:4px 10px; border:1px solid rgba(255,255,255,0.15);
  background:rgba(4,4,15,0.8); cursor:pointer; color:rgba(255,255,255,0.5);
  transition:all 0.2s; position:relative;
}
.ability-chip.ready { border-color:var(--gold); color:var(--gold); box-shadow:0 0 10px rgba(245,158,11,0.3); }
.ability-chip.used { opacity:0.2; cursor:not-allowed; }
.ability-chip .cd { font-size:7px; opacity:0.5; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="flash"></div>
<div id="toast"></div>
<div id="combo-popup"></div>
<div id="ai-thinking">⟳ AI CALCULATING...</div>

<!-- HUD -->
<div id="hud">
  <div id="top-bar">
    <!-- Player -->
    <div class="hero-panel" id="panel-player">
      <div class="hero-name" id="player-name" style="color:#ef4444;">BULL</div>
      <div class="hero-type-badge" id="player-badge" style="color:#ef4444;border-color:#ef4444;">🔥 FIRE</div>
      <div class="hp-bar-wrap">
        <div class="hp-bar" id="hp-bar-player" style="width:100%;background:linear-gradient(90deg,#ef4444,#f97316);box-shadow:0 0 8px #ef4444;"></div>
      </div>
      <div class="hp-text"><span id="hp-val-player">100</span>/100 HP · <span id="shield-val-player" style="color:#60a5fa;">0 🛡</span></div>
      <div class="stake-text" id="stake-player">⚡ 100 $ARENA</div>
    </div>

    <!-- Center -->
    <div id="turn-center">
      <div id="turn-label">ROUND</div>
      <div id="turn-num">1/5</div>
      <div id="streak-badge">🔥 x2 STREAK</div>
      <div id="mode-badge">VS AI</div>
    </div>

    <!-- AI -->
    <div class="hero-panel right" id="panel-ai">
      <div class="hero-name" id="ai-name" style="color:#3b82f6;">BEAR</div>
      <div class="hero-type-badge" id="ai-badge" style="color:#3b82f6;border-color:#3b82f6;">💧 WATER</div>
      <div class="hp-bar-wrap" style="margin-left:auto;">
        <div class="hp-bar" id="hp-bar-ai" style="width:100%;background:linear-gradient(90deg,#3b82f6,#06b6d4);box-shadow:0 0 8px #3b82f6;"></div>
      </div>
      <div class="hp-text" style="text-align:right;"><span id="hp-val-ai">100</span>/100 HP · <span id="shield-val-ai" style="color:#60a5fa;">0 🛡</span></div>
      <div class="stake-text" style="text-align:right;" id="stake-ai">⚡ 100 $ARENA</div>
    </div>
  </div>

  <!-- Ticker -->
  <div id="ticker">
    <div id="price-label" style="color:#10b981;">BTC $67,420</div>
    <div id="price-delta" style="color:#10b981;">▲ +$0</div>
    <div id="price-hints">RSI: 62 · VOL: +8% · MA20: 66,800</div>
  </div>

  <!-- Chart -->
  <div id="chart-wrap">
    <canvas id="price-chart" width="180" height="44"></canvas>
  </div>

  <!-- Ability bar -->
  <div id="ability-bar"></div>

  <!-- Bottom -->
  <div id="bottom-ctrl">
    <div id="phase-text">PREDICT THE NEXT MOVE</div>
    <div id="stake-display">
      <div><span>STAKE:</span><strong id="disp-stake">100</strong> $ARENA</div>
      <div><span>POT:</span><strong id="disp-pot">200</strong> $ARENA</div>
    </div>
    <div id="confidence-row">
      <label>CONFIDENCE</label>
      <input type="range" id="conf-slider" min="1" max="5" value="3">
      <span id="conf-val">3</span>
    </div>
    <div id="predict-btns">
      <button class="predict-btn" id="btn-up">▲ BULL</button>
      <button class="predict-btn" id="btn-down">▼ BEAR</button>
    </div>
    <div id="mp-row">
      <div id="mp-status-dot"></div>
      <span id="mp-label">2 ONLINE</span>
    </div>
  </div>
</div>

<!-- Leaderboard -->
<div id="leaderboard">
  <h4>HALL OF SLASHERS</h4>
  <div id="lb-list"></div>
</div>

<!-- OVERLAY -->
<div id="overlay">
  <div id="overlay-logo">SLASHCLASH</div>
  <div id="overlay-sub">CRYPTO HERO DUELS</div>
  <div id="overlay-version">v2.0 · 5-ROUND DUEL · HERO ABILITIES</div>
  <div id="overlay-result"></div>
  <div id="overlay-reward"></div>
  <div id="overlay-streak-msg"></div>

  <div id="mode-select">
    <button class="mode-btn active" data-mode="ai">VS AI</button>
    <button class="mode-btn" data-mode="mp">MULTIPLAYER</button>
  </div>

  <div id="mp-lobby">
    <div id="room-code">----</div>
    <div id="mp-waiting">WAITING FOR OPPONENT...</div>
    <button id="copy-code">📋 COPY CODE</button>
  </div>

  <div id="hero-select">
    <div class="hero-card selected" data-type="bull">
      <div class="hero-card-icon">🐂</div>
      <div class="hero-card-name">BULL</div>
      <div class="hero-card-type">FIRE TYPE</div>
      <div class="hero-card-special">⚡ RAMPAGE</div>
      <div class="hero-card-adv">Strong vs Bear</div>
    </div>
    <div class="hero-card" data-type="bear">
      <div class="hero-card-icon">🐻</div>
      <div class="hero-card-name">BEAR</div>
      <div class="hero-card-type">WATER TYPE</div>
      <div class="hero-card-special">🛡 HIBERNATE</div>
      <div class="hero-card-adv">Strong vs Whale</div>
    </div>
    <div class="hero-card" data-type="whale">
      <div class="hero-card-icon">🐋</div>
      <div class="hero-card-name">WHALE</div>
      <div class="hero-card-type">EARTH TYPE</div>
      <div class="hero-card-special">💰 MARKET DUMP</div>
      <div class="hero-card-adv">Strong vs Bull</div>
    </div>
    <div class="hero-card" data-type="ape">
      <div class="hero-card-icon">🦍</div>
      <div class="hero-card-name">APE</div>
      <div class="hero-card-type">AIR TYPE</div>
      <div class="hero-card-special">🚀 MOON SHOT</div>
      <div class="hero-card-adv">Strong vs Bear</div>
    </div>
    <div class="hero-card" data-type="dragon">
      <div class="hero-card-icon">🐉</div>
      <div class="hero-card-name">DRAGON</div>
      <div class="hero-card-type">CHAOS TYPE</div>
      <div class="hero-card-special">🔥 INFERNO</div>
      <div class="hero-card-adv">Glass cannon</div>
    </div>
    <div class="hero-card" data-type="robot">
      <div class="hero-card-icon">🤖</div>
      <div class="hero-card-name">BOT-9</div>
      <div class="hero-card-type">TECH TYPE</div>
      <div class="hero-card-special">🔍 SCAN</div>
      <div class="hero-card-adv">Reads oracle</div>
    </div>
  </div>

  <button id="enter-btn">⚔ ENTER ARENA</button>
  <button id="rematch-btn">↺ REMATCH</button>
</div>

<!-- Three.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<!-- Howler.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.3/howler.min.js"></script>

<script>
'use strict';
// ══════════════════════════════════════════
// HERO DEFINITIONS (6 heroes)
// ══════════════════════════════════════════
const HEROES = {
  bull:   { name:'BULL',   emoji:'🐂', color:0xef4444, pColor:0xff6b35, badge:'🔥 FIRE',   strong:'bear',  weak:'whale', hp:100, special:'RAMPAGE',    specialDesc:'Double damage next hit', specialCD:2 },
  bear:   { name:'BEAR',   emoji:'🐻', color:0x3b82f6, pColor:0x38bdf8, badge:'💧 WATER',  strong:'whale', weak:'ape',   hp:100, special:'HIBERNATE',   specialDesc:'Block 30 damage', specialCD:2 },
  whale:  { name:'WHALE',  emoji:'🐋', color:0x22c55e, pColor:0x4ade80, badge:'🌍 EARTH',  strong:'bull',  weak:'bear',  hp:100, special:'MARKET DUMP', specialDesc:'Drain enemy stake -15%', specialCD:3 },
  ape:    { name:'APE',    emoji:'🦍', color:0xa78bfa, pColor:0xc4b5fd, badge:'💨 AIR',    strong:'bear',  weak:'bull',  hp:100, special:'MOON SHOT',   specialDesc:'50% crit chance', specialCD:2 },
  dragon: { name:'DRAGON', emoji:'🐉', color:0xf97316, pColor:0xfbbf24, badge:'💥 CHAOS',  strong:'whale', weak:'robot', hp:70,  special:'INFERNO',     specialDesc:'AoE +15 burn DoT', specialCD:2 },
  robot:  { name:'BOT-9',  emoji:'🤖', color:0x06b6d4, pColor:0x67e8f9, badge:'⚙ TECH',   strong:'dragon',weak:'bull',  hp:90,  special:'SCAN',        specialDesc:'Reveals AI prediction', specialCD:3 },
};

const BASE_DMG   = 22;
const TYPE_BONUS = 12;
const SELF_SLASH = 14;
const ENTRY_FEE  = 10;
const SLASH_RATIO= 0.7;
const MAX_TURNS  = 5;

// ══════════════════════════════════════════
// GAME STATE
// ══════════════════════════════════════════
let gs = {
  running:false, turn:0,
  playerHP:100, aiHP:100,
  playerShield:0, aiShield:0,
  playerType:'bull', aiType:'bear',
  playerStake:100, aiStake:100,
  streak:0, maxStreak:0,
  price:67420, lastPrice:67420,
  priceHistory:[], pricePoints:[],
  wins:0, losses:0,
  mode:'ai',
  roomCode:null,
  mpOpponentReady:false,
  playerSpecialCD:0, aiSpecialCD:0,
  playerSpecialActive:false,
  burnDot:0, aiDot:0,
  rampageActive:false,
  scanActive:false,
  aiLastPred:null,
};

// ══════════════════════════════════════════
// SOUND (Howler - synthetic beeps)
// ══════════════════════════════════════════
function genTone(freq, dur, type='sine', vol=0.15) {
  try {
    const ctx = new (window.AudioContext || window.webkitAudioContext)();
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    osc.connect(gain); gain.connect(ctx.destination);
    osc.type = type; osc.frequency.setValueAtTime(freq, ctx.currentTime);
    gain.gain.setValueAtTime(vol, ctx.currentTime);
    gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + dur);
    osc.start(); osc.stop(ctx.currentTime + dur);
  } catch(e){}
}
const SFX = {
  slash:  ()=>{ genTone(220,0.15,'sawtooth',0.2); setTimeout(()=>genTone(180,0.1,'sawtooth',0.15),80); },
  hit:    ()=>{ genTone(440,0.08,'square',0.15); },
  miss:   ()=>{ genTone(160,0.2,'sine',0.1); },
  win:    ()=>{ [523,659,784,1047].forEach((f,i)=>setTimeout(()=>genTone(f,0.2,'sine',0.12),i*120)); },
  lose:   ()=>{ [300,250,200].forEach((f,i)=>setTimeout(()=>genTone(f,0.25,'sine',0.1),i*150)); },
  special:()=>{ genTone(880,0.05,'square',0.1); setTimeout(()=>genTone(1100,0.1,'sine',0.15),60); },
  tick:   ()=>{ genTone(600,0.04,'sine',0.06); },
  click:  ()=>{ genTone(800,0.03,'square',0.08); },
};

// ══════════════════════════════════════════
// THREE.JS SCENE
// ══════════════════════════════════════════
const canvas = document.getElementById('c');
const renderer = new THREE.WebGLRenderer({ canvas, antialias:true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.1;

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x04040f);
scene.fog = new THREE.FogExp2(0x04040f, 0.045);

const camera = new THREE.PerspectiveCamera(58, window.innerWidth/window.innerHeight, 0.1, 300);
camera.position.set(0, 6.5, 13);
camera.lookAt(0, 1, 0);

// Lights
scene.add(new THREE.AmbientLight(0x0a0a22, 2));
const dirLight = new THREE.DirectionalLight(0xffffff, 1.0);
dirLight.position.set(4, 12, 6); dirLight.castShadow = true;
dirLight.shadow.mapSize.set(1024,1024);
scene.add(dirLight);

const sp1 = new THREE.SpotLight(0xff4422, 4, 25, Math.PI/5, 0.4, 1.2);
sp1.position.set(-6, 12, 2); scene.add(sp1);
const sp2 = new THREE.SpotLight(0x2244ff, 4, 25, Math.PI/5, 0.4, 1.2);
sp2.position.set(6, 12, 2); scene.add(sp2);

// Dynamic rim lights (change color based on hero types)
const rimLeft = new THREE.PointLight(0xff0000, 2, 8);
rimLeft.position.set(-4, 2, 0); scene.add(rimLeft);
const rimRight = new THREE.PointLight(0x0000ff, 2, 8);
rimRight.position.set(4, 2, 0); scene.add(rimRight);

// ── ARENA ──
// Main floor
const arenaGeo = new THREE.CylinderGeometry(9, 9, 0.18, 72);
const arenaMat = new THREE.MeshStandardMaterial({ color:0x111128, roughness:0.6, metalness:0.5, emissive:0x050520, emissiveIntensity:0.5 });
const arenaFloor = new THREE.Mesh(arenaGeo, arenaMat);
arenaFloor.receiveShadow = true; arenaFloor.position.y = -0.09; scene.add(arenaFloor);

// Hexagonal floor pattern
for (let ring = 1; ring <= 3; ring++) {
  const rGeo = new THREE.TorusGeometry(ring*2.5, 0.02, 4, 72);
  const rMat = new THREE.MeshStandardMaterial({ color:0x222244, emissive:0x111133, emissiveIntensity:1.5, transparent:true, opacity:0.6 });
  const r = new THREE.Mesh(rGeo, rMat);
  r.rotation.x = Math.PI/2; r.position.y = 0.01; scene.add(r);
}

// Outer glow ring
const outerRing = new THREE.Mesh(
  new THREE.TorusGeometry(9, 0.12, 8, 72),
  new THREE.MeshStandardMaterial({ color:0x4444ff, emissive:0x2233cc, emissiveIntensity:3 })
);
outerRing.rotation.x = Math.PI/2; outerRing.position.y = 0.03; scene.add(outerRing);

// Center divider line
const divLine = new THREE.Mesh(
  new THREE.BoxGeometry(0.04, 0.05, 18),
  new THREE.MeshStandardMaterial({ color:0x4444aa, emissive:0x2222ff, emissiveIntensity:2, transparent:true, opacity:0.4 })
);
divLine.position.y = 0.04; scene.add(divLine);

// Arena pillars
for (let i = 0; i < 8; i++) {
  const a = (i/8) * Math.PI * 2;
  const pillar = new THREE.Mesh(
    new THREE.CylinderGeometry(0.12, 0.15, 3.5, 8),
    new THREE.MeshStandardMaterial({ color:0x1a1a3e, roughness:0.3, metalness:0.8, emissive:0x111133, emissiveIntensity:0.5 })
  );
  pillar.position.set(Math.cos(a)*8.5, 1.75, Math.sin(a)*8.5);
  pillar.castShadow = true; scene.add(pillar);
  // Pillar top light
  const pLight = new THREE.Mesh(
    new THREE.SphereGeometry(0.14, 6, 6),
    new THREE.MeshStandardMaterial({ color:0x4444ff, emissive:0x2222ff, emissiveIntensity:4, transparent:true, opacity:0.8 })
  );
  pLight.position.set(Math.cos(a)*8.5, 3.6, Math.sin(a)*8.5); scene.add(pLight);
}

// Floating hex decorations
for (let i = 0; i < 6; i++) {
  const a = (i/6)*Math.PI*2;
  const hexGeo = new THREE.CylinderGeometry(0.4, 0.4, 0.04, 6);
  const hexMat = new THREE.MeshStandardMaterial({ color:0x1a1a44, emissive:0x2222aa, emissiveIntensity:1.5, transparent:true, opacity:0.5 });
  const hex = new THREE.Mesh(hexGeo, hexMat);
  hex.position.set(Math.cos(a)*5.5, 0.02, Math.sin(a)*5.5);
  hex.userData.floatOff = i * 1.2; scene.add(hex);
  scene.userData = scene.userData || {};
  (scene.userData.hexPads = scene.userData.hexPads||[]).push(hex);
}

// ── AMBIENT SPARKS ──
const sparkCount = 400;
const sparkPos = new Float32Array(sparkCount*3);
const sparkVel = new Float32Array(sparkCount*3);
const sparkColors = new Float32Array(sparkCount*3);
for (let i=0;i<sparkCount;i++){
  const a=Math.random()*Math.PI*2, r=7+Math.random()*2.5;
  sparkPos[i*3]=Math.cos(a)*r; sparkPos[i*3+1]=Math.random()*6; sparkPos[i*3+2]=Math.sin(a)*r;
  sparkVel[i*3+1]=0.008+Math.random()*0.018;
  const c=new THREE.Color(); c.setHSL(0.65+Math.random()*0.15, 1, 0.7);
  sparkColors[i*3]=c.r; sparkColors[i*3+1]=c.g; sparkColors[i*3+2]=c.b;
}
const sparkGeo = new THREE.BufferGeometry();
sparkGeo.setAttribute('position',new THREE.BufferAttribute(sparkPos,3));
sparkGeo.setAttribute('color',new THREE.BufferAttribute(sparkColors,3));
const sparkMat = new THREE.PointsMaterial({ size:0.05, vertexColors:true, transparent:true, opacity:0.6 });
scene.add(new THREE.Points(sparkGeo,sparkMat));

// ══════════════════════════════════════════
// HERO BUILDER (improved models)
// ══════════════════════════════════════════
function buildHero(type, side) {
  const cfg = HEROES[type];
  const group = new THREE.Group();

  const C = cfg.color;
  const bodyMat = new THREE.MeshStandardMaterial({ color:C, roughness:0.3, metalness:0.7, emissive:C, emissiveIntensity:0.25 });
  const darkMat = new THREE.MeshStandardMaterial({ color:0x090916, roughness:0.8, metalness:0.2 });
  const glowMat = new THREE.MeshStandardMaterial({ color:cfg.pColor, emissive:cfg.pColor, emissiveIntensity:3, transparent:true, opacity:0.9 });

  // Pelvis
  const pelvis = new THREE.Mesh(new THREE.CylinderGeometry(0.32,0.36,0.28,8),bodyMat);
  pelvis.position.y=0.52; group.add(pelvis);
  // Torso
  const torso = new THREE.Mesh(new THREE.CylinderGeometry(0.36,0.32,0.85,8),bodyMat);
  torso.position.y=1.1; torso.castShadow=true; group.add(torso);
  // Chest plate
  const chest = new THREE.Mesh(new THREE.BoxGeometry(0.55,0.45,0.22),
    new THREE.MeshStandardMaterial({color:C,roughness:0.2,metalness:0.9,emissive:C,emissiveIntensity:0.5}));
  chest.position.set(0,1.18,0.18); group.add(chest);
  // Neck
  const neck = new THREE.Mesh(new THREE.CylinderGeometry(0.14,0.16,0.18,8),bodyMat);
  neck.position.y=1.62; group.add(neck);
  // Head
  const head = new THREE.Mesh(new THREE.SphereGeometry(0.30,16,12),bodyMat);
  head.scale.y=1.08; head.position.y=1.85; head.castShadow=true; group.add(head);
  // Visor
  const visor = new THREE.Mesh(new THREE.BoxGeometry(0.46,0.12,0.1),
    new THREE.MeshStandardMaterial({color:cfg.pColor,emissive:cfg.pColor,emissiveIntensity:4,transparent:true,opacity:0.9}));
  visor.position.set(0,1.9,0.28); group.add(visor);
  // Shoulder pads
  for (let sx of [-1,1]) {
    const shp = new THREE.Mesh(new THREE.SphereGeometry(0.22,8,6),
      new THREE.MeshStandardMaterial({color:C,roughness:0.2,metalness:0.8}));
    shp.scale.set(1,0.7,1); shp.position.set(sx*0.6,1.38,0); group.add(shp);
  }
  // Arms
  for (let ax of [-1,1]) {
    const arm = new THREE.Mesh(new THREE.CylinderGeometry(0.1,0.09,0.65,8),bodyMat);
    arm.position.set(ax*0.58,0.98,0); arm.rotation.z=ax*0.35; arm.castShadow=true; group.add(arm);
    const forearm = new THREE.Mesh(new THREE.CylinderGeometry(0.09,0.07,0.55,8),bodyMat);
    forearm.position.set(ax*0.75,0.62,0); forearm.rotation.z=ax*0.2; group.add(forearm);
    const hand = new THREE.Mesh(new THREE.SphereGeometry(0.1,8,8),bodyMat);
    hand.position.set(ax*0.84,0.36,0); group.add(hand);
  }
  // Legs
  for (let lx of [-1,1]) {
    const thigh = new THREE.Mesh(new THREE.CylinderGeometry(0.14,0.12,0.5,8),bodyMat);
    thigh.position.set(lx*0.21,0.28,0); thigh.castShadow=true; group.add(thigh);
    const shin = new THREE.Mesh(new THREE.CylinderGeometry(0.11,0.09,0.42,8),bodyMat);
    shin.position.set(lx*0.21,0.0,0.04); group.add(shin);
    const foot = new THREE.Mesh(new THREE.BoxGeometry(0.2,0.1,0.32),darkMat);
    foot.position.set(lx*0.21,-0.21,0.06); group.add(foot);
    // Knee gem
    const knee = new THREE.Mesh(new THREE.OctahedronGeometry(0.06),glowMat);
    knee.position.set(lx*0.22,0.1,0.1); group.add(knee);
  }

  // ── TYPE-SPECIFIC WEAPONS ──
  if (type==='bull') {
    const blade = new THREE.Mesh(new THREE.CylinderGeometry(0.03,0.015,1.4,6),
      new THREE.MeshStandardMaterial({color:0xfbbf24,emissive:0xf97316,emissiveIntensity:2.5,metalness:0.95}));
    blade.rotation.z=-0.28; blade.position.set(-1.05,0.95,0); group.add(blade);
    const guard = new THREE.Mesh(new THREE.BoxGeometry(0.28,0.06,0.06),
      new THREE.MeshStandardMaterial({color:0xd97706,metalness:0.9}));
    guard.rotation.z=-0.28; guard.position.set(-0.82,0.72,0); group.add(guard);
  } else if (type==='bear') {
    const blade = new THREE.Mesh(new THREE.BoxGeometry(0.08,1.3,0.06),
      new THREE.MeshStandardMaterial({color:0x60a5fa,emissive:0x3b82f6,emissiveIntensity:2,metalness:0.85}));
    blade.rotation.z=-0.18; blade.position.set(-1.0,0.9,0); group.add(blade);
  } else if (type==='whale') {
    const staff = new THREE.Mesh(new THREE.CylinderGeometry(0.04,0.04,1.5,8),
      new THREE.MeshStandardMaterial({color:0x166534,metalness:0.6}));
    staff.position.set(-1.0,1.0,0); staff.rotation.z=-0.15; group.add(staff);
    const tip = new THREE.Mesh(new THREE.ConeGeometry(0.14,0.4,6),
      new THREE.MeshStandardMaterial({color:0x4ade80,emissive:0x22c55e,emissiveIntensity:2.5}));
    tip.position.set(-1.06,1.72,0); tip.rotation.z=-0.15; group.add(tip);
  } else if (type==='ape') {
    const staff = new THREE.Mesh(new THREE.CylinderGeometry(0.035,0.035,1.6,6),
      new THREE.MeshStandardMaterial({color:0x7c3aed,metalness:0.5}));
    staff.position.set(-1.0,1.05,0); staff.rotation.z=-0.12; group.add(staff);
    const orb = new THREE.Mesh(new THREE.SphereGeometry(0.16,12,8),
      new THREE.MeshStandardMaterial({color:0xc4b5fd,emissive:0xa78bfa,emissiveIntensity:4,transparent:true,opacity:0.92}));
    orb.position.set(-1.06,1.82,0); group.add(orb);
  } else if (type==='dragon') {
    // Dual claws
    for (let cx of [-1,1]) {
      const claw = new THREE.Mesh(new THREE.ConeGeometry(0.06,0.6,4),
        new THREE.MeshStandardMaterial({color:0xfbbf24,emissive:0xef4444,emissiveIntensity:3,metalness:0.9}));
      claw.position.set(cx*0.88,0.42,0.1); claw.rotation.z=cx*(Math.PI/2+0.3); group.add(claw);
    }
    // Wings (simplified)
    for (let wx of [-1,1]) {
      const wing = new THREE.Mesh(new THREE.ConeGeometry(0.6,1.2,3),
        new THREE.MeshStandardMaterial({color:0x7f1d1d,roughness:0.8,transparent:true,opacity:0.7}));
      wing.position.set(wx*1.1,1.2,-0.3); wing.rotation.z=wx*(-0.9); wing.rotation.x=0.3; group.add(wing);
    }
  } else if (type==='robot') {
    // Arm cannon
    const barrel = new THREE.Mesh(new THREE.CylinderGeometry(0.09,0.07,0.9,8),
      new THREE.MeshStandardMaterial({color:0x0e7490,metalness:0.95,roughness:0.1}));
    barrel.rotation.z=Math.PI/2; barrel.position.set(-1.1,0.75,0); group.add(barrel);
    const lens = new THREE.Mesh(new THREE.CircleGeometry(0.06,12),
      new THREE.MeshStandardMaterial({color:0x06b6d4,emissive:0x06b6d4,emissiveIntensity:5}));
    lens.rotation.y=Math.PI/2; lens.position.set(-1.55,0.75,0); group.add(lens);
    // Antenna
    const ant = new THREE.Mesh(new THREE.CylinderGeometry(0.02,0.02,0.4,6),bodyMat);
    ant.position.set(0.1,2.18,0); group.add(ant);
    const antTip = new THREE.Mesh(new THREE.SphereGeometry(0.05,6,6),glowMat);
    antTip.position.set(0.1,2.4,0); group.add(antTip);
  }

  // Particle aura
  const pCount = 160;
  const pPos = new Float32Array(pCount*3);
  for (let i=0;i<pCount;i++){
    pPos[i*3]=(Math.random()-0.5)*1.8; pPos[i*3+1]=Math.random()*2.8; pPos[i*3+2]=(Math.random()-0.5)*1.8;
  }
  const pGeo = new THREE.BufferGeometry();
  pGeo.setAttribute('position',new THREE.BufferAttribute(pPos,3));
  const pMat = new THREE.PointsMaterial({color:cfg.pColor,size:0.055,transparent:true,opacity:0.75});
  const particles = new THREE.Points(pGeo,pMat);
  group.add(particles);
  group.userData.particles = particles;
  group.userData.pPos = pPos;

  // Shield bubble (hidden by default)
  const shieldMesh = new THREE.Mesh(
    new THREE.SphereGeometry(1.2,20,15),
    new THREE.MeshStandardMaterial({color:0x60a5fa,emissive:0x3b82f6,emissiveIntensity:1.5,transparent:true,opacity:0,wireframe:true})
  );
  shieldMesh.position.y=1; group.add(shieldMesh);
  group.userData.shield = shieldMesh;

  // Position
  group.position.set(side==='player'?-3.2:3.2, 0, 0);
  if (side==='ai') group.rotation.y=Math.PI;
  group.userData.side = side;
  group.userData.type = type;
  group.userData.origX = group.position.x;
  group.userData.origY = 0;

  scene.add(group);
  return group;
}

let playerHero=null, aiHero=null;

// ══════════════════════════════════════════
// PRICE CHART (canvas 2D)
// ══════════════════════════════════════════
const chartCanvas = document.getElementById('price-chart');
const chartCtx = chartCanvas.getContext('2d');

function drawPriceChart() {
  const pts = gs.pricePoints;
  chartCtx.clearRect(0,0,180,44);
  if (pts.length < 2) return;
  const mn = Math.min(...pts)-200, mx = Math.max(...pts)+200;
  const range = mx-mn||1;
  const w=180, h=44;
  // Grid line
  chartCtx.strokeStyle='rgba(255,255,255,0.05)'; chartCtx.lineWidth=1;
  chartCtx.beginPath(); chartCtx.moveTo(0,h/2); chartCtx.lineTo(w,h/2); chartCtx.stroke();
  // Fill gradient
  const grad = chartCtx.createLinearGradient(0,0,0,h);
  const last = pts[pts.length-1], prev = pts[pts.length-2]||last;
  const rising = last>=prev;
  grad.addColorStop(0, rising?'rgba(16,185,129,0.25)':'rgba(239,68,68,0.25)');
  grad.addColorStop(1,'rgba(0,0,0,0)');
  chartCtx.beginPath();
  pts.forEach((p,i)=>{ const x=(i/(pts.length-1))*w, y=h-((p-mn)/range)*h; i===0?chartCtx.moveTo(x,y):chartCtx.lineTo(x,y); });
  chartCtx.lineTo(w,h); chartCtx.lineTo(0,h); chartCtx.closePath();
  chartCtx.fillStyle=grad; chartCtx.fill();
  // Line
  chartCtx.strokeStyle=rising?'#10b981':'#ef4444'; chartCtx.lineWidth=1.5;
  chartCtx.beginPath();
  pts.forEach((p,i)=>{ const x=(i/(pts.length-1))*w, y=h-((p-mn)/range)*h; i===0?chartCtx.moveTo(x,y):chartCtx.lineTo(x,y); });
  chartCtx.stroke();
  // Dot at end
  const ex=w, ey=h-((pts[pts.length-1]-mn)/range)*h;
  chartCtx.beginPath(); chartCtx.arc(ex,ey,3,0,Math.PI*2);
  chartCtx.fillStyle=rising?'#10b981':'#ef4444'; chartCtx.fill();
}

// ══════════════════════════════════════════
// ORACLE SIMULATION
// Replace simulatePrice() body with real Polygon API fetch for production:
// const r = await fetch(`https://api.polygon.io/v2/aggs/ticker/X:BTCUSD/prev?apiKey=YOUR_KEY`);
// const d = await r.json(); return { price: d.results[0].c, direction: ... }
// ══════════════════════════════════════════
function simulatePrice() {
  gs.lastPrice = gs.price;
  const bias = gs.priceHistory.filter(x=>x==='up').length > gs.priceHistory.length*0.6 ? -0.02 : 0.02;
  const delta = (Math.random()-0.48+bias) * 900;
  gs.price = Math.max(18000, gs.price+delta);
  const dir = delta>=0?'up':'down';
  gs.priceHistory.push(dir);
  gs.pricePoints.push(gs.price);
  if (gs.pricePoints.length>20) gs.pricePoints.shift();
  return { price:gs.price, direction:dir, delta };
}

function computeHints() {
  const rsi = 38+Math.random()*44;
  const vol = (Math.random()*22-9).toFixed(1);
  const ma = (gs.price*(0.97+Math.random()*0.04)).toFixed(0);
  return { rsi:rsi.toFixed(0), vol, ma };
}

// ══════════════════════════════════════════
// HASH LOCK (PoUW commitment)
// ══════════════════════════════════════════
async function hashPrediction(pred,conf,nonce) {
  const msg=`${pred}:${conf}:${nonce}:${Date.now()}`;
  const enc=new TextEncoder().encode(msg);
  const buf=await crypto.subtle.digest('SHA-256',enc);
  return Array.from(new Uint8Array(buf)).map(b=>b.toString(16).padStart(2,'0')).join('');
}

// ══════════════════════════════════════════
// DAMAGE CALC
// ══════════════════════════════════════════
function calcDamage(attType,defType,correct,conf,special) {
  if (!correct) return 0;
  const mult = 1+(conf-1)*0.15;
  const adv = HEROES[attType].strong===defType;
  const dis = HEROES[attType].weak===defType;
  let base = BASE_DMG;
  if (adv)  base += TYPE_BONUS;
  if (dis)  base -= 6;
  // Special modifiers
  if (special==='RAMPAGE') base *= 2;
  if (special==='MOON SHOT' && Math.random()<0.5) base = Math.round(base*1.8);
  if (special==='INFERNO') base += 18;
  if (attType==='dragon') base = Math.round(base*1.3); // dragon glass cannon bonus
  return Math.round(base*mult);
}

// ══════════════════════════════════════════
// ANIMATIONS
// ══════════════════════════════════════════
let heroAnims = [];
let confettiParticles = [];
let shockwaves = [];

function triggerAttack(hero,dir) { heroAnims.push({hero,type:'lunge',dir,t:0,dur:0.45}); }
function triggerSlash(hero) { heroAnims.push({hero,type:'shake',t:0,dur:0.38}); flashScreen(0xff1100,0.3); }
function triggerHit(hero) { heroAnims.push({hero,type:'reel',t:0,dur:0.3}); }
function triggerWin(hero) { heroAnims.push({hero,type:'victory',t:0,dur:2.0}); spawnConfetti(hero.position,0xf59e0b); }
function triggerDeath(hero) { heroAnims.push({hero,type:'fall',t:0,dur:1.2}); }
function triggerShield(hero) {
  if (hero && hero.userData.shield) {
    hero.userData.shield.material.opacity = 0.22;
    heroAnims.push({hero,type:'shieldpulse',t:0,dur:0.8});
  }
}
function triggerSpecial(hero) {
  heroAnims.push({hero,type:'special',t:0,dur:0.6});
  spawnShockwave(hero.position, HEROES[hero.userData.type].pColor);
}

function spawnShockwave(pos,color) {
  const geo = new THREE.TorusGeometry(0.3,0.06,6,32);
  const mat = new THREE.MeshStandardMaterial({color,emissive:color,emissiveIntensity:4,transparent:true,opacity:0.9});
  const mesh = new THREE.Mesh(geo,mat);
  mesh.position.set(pos.x,0.5,pos.z); mesh.rotation.x=Math.PI/2;
  scene.add(mesh);
  shockwaves.push({mesh,life:1.0,col:color});
}

function updateShockwaves() {
  shockwaves = shockwaves.filter(sw=>{
    sw.life -= 0.04;
    sw.mesh.scale.setScalar(1+(1-sw.life)*8);
    sw.mesh.material.opacity = sw.life*0.8;
    if (sw.life<=0){ scene.remove(sw.mesh); return false; }
    return true;
  });
}

function flashScreen(hex,strength) {
  const fl=document.getElementById('flash');
  const c=new THREE.Color(hex);
  fl.style.background=`rgba(${c.r*255|0},${c.g*255|0},${c.b*255|0},${strength})`;
  fl.style.opacity=1;
  setTimeout(()=>fl.style.opacity=0,110);
}

function spawnConfetti(pos,color) {
  const count=100, positions=new Float32Array(count*3), velocities=[];
  for (let i=0;i<count;i++){
    positions[i*3]=pos.x+(Math.random()-0.5)*0.5;
    positions[i*3+1]=pos.y+2;
    positions[i*3+2]=pos.z+(Math.random()-0.5)*0.5;
    velocities.push({x:(Math.random()-0.5)*0.12,y:0.06+Math.random()*0.1,z:(Math.random()-0.5)*0.12,g:-0.004});
  }
  const geo=new THREE.BufferGeometry();
  geo.setAttribute('position',new THREE.BufferAttribute(positions,3));
  const mat=new THREE.PointsMaterial({color,size:0.12,transparent:true,opacity:1});
  const pts=new THREE.Points(geo,mat); scene.add(pts);
  confettiParticles.push({pts,positions,velocities,life:1.0});
}

function updateConfetti() {
  confettiParticles=confettiParticles.filter(cp=>{
    cp.life-=0.012; cp.pts.material.opacity=cp.life;
    for(let i=0;i<cp.velocities.length;i++){
      const v=cp.velocities[i]; v.y+=v.g;
      cp.positions[i*3]+=v.x; cp.positions[i*3+1]+=v.y; cp.positions[i*3+2]+=v.z;
    }
    cp.pts.geometry.attributes.position.needsUpdate=true;
    if(cp.life<=0){scene.remove(cp.pts);return false;} return true;
  });
}

function showToast(msg,color,duration=1200) {
  const el=document.getElementById('toast');
  el.textContent=msg; el.style.color=color; el.style.opacity=1;
  clearTimeout(el._t); el._t=setTimeout(()=>el.style.opacity=0,duration);
}

function showCombo(msg) {
  const el=document.getElementById('combo-popup');
  el.textContent=msg; el.style.opacity=1;
  clearTimeout(el._t); el._t=setTimeout(()=>el.style.opacity=0,1600);
}

// ══════════════════════════════════════════
// UI UPDATES
// ══════════════════════════════════════════
function updateHPBars() {
  const ph=Math.max(0,gs.playerHP), ah=Math.max(0,gs.aiHP);
  const pmx=HEROES[gs.playerType].hp, amx=HEROES[gs.aiType].hp;
  document.getElementById('hp-bar-player').style.width=(ph/pmx*100)+'%';
  document.getElementById('hp-bar-ai').style.width=(ah/amx*100)+'%';
  document.getElementById('hp-val-player').textContent=ph;
  document.getElementById('hp-val-ai').textContent=ah;
  document.getElementById('shield-val-player').textContent=`${gs.playerShield}🛡`;
  document.getElementById('shield-val-ai').textContent=`${gs.aiShield}🛡`;
  document.getElementById('stake-player').textContent=`⚡${gs.playerStake}$A`;
  document.getElementById('stake-ai').textContent=`⚡${gs.aiStake}$A`;
  document.getElementById('disp-stake').textContent=gs.playerStake;
  document.getElementById('disp-pot').textContent=gs.playerStake+gs.aiStake;
  // HP color shift
  const hpBar=document.getElementById('hp-bar-player');
  if (ph<30) hpBar.style.background='linear-gradient(90deg,#dc2626,#ef4444)';
  else if (ph<60) hpBar.style.background='linear-gradient(90deg,#d97706,#f59e0b)';
}

function updateHeroPanels() {
  const pc=HEROES[gs.playerType], ac=HEROES[gs.aiType];
  const pC=new THREE.Color(pc.color), aC=new THREE.Color(ac.color);
  const pHex=`#${pC.getHexString()}`, aHex=`#${aC.getHexString()}`;
  document.getElementById('player-name').textContent=pc.name;
  document.getElementById('player-name').style.color=pHex;
  document.getElementById('player-badge').textContent=pc.badge;
  document.getElementById('player-badge').style.color=pHex;
  document.getElementById('player-badge').style.borderColor=pHex;
  document.getElementById('ai-name').textContent=ac.name;
  document.getElementById('ai-name').style.color=aHex;
  document.getElementById('ai-badge').textContent=ac.badge;
  document.getElementById('ai-badge').style.color=aHex;
  document.getElementById('ai-badge').style.borderColor=aHex;
  document.getElementById('turn-num').textContent=`${Math.min(gs.turn+1,MAX_TURNS)}/${MAX_TURNS}`;
  document.getElementById('mode-badge').textContent=gs.mode==='ai'?'VS AI':'MULTIPLAYER';
  const sb=document.getElementById('streak-badge');
  if(gs.streak>=2){sb.style.display='inline-block';sb.textContent=`🔥×${gs.streak} STREAK`;}
  else sb.style.display='none';
}

function updatePriceDisplay() {
  const delta=gs.price-gs.lastPrice;
  const rising=delta>=0;
  const color=rising?'#10b981':'#ef4444';
  document.getElementById('price-label').textContent=`BTC $${gs.price.toLocaleString('en',{maximumFractionDigits:0})}`;
  document.getElementById('price-label').style.color=color;
  document.getElementById('price-delta').textContent=`${rising?'▲':'▼'} ${rising?'+':''}$${Math.abs(delta).toFixed(0)}`;
  document.getElementById('price-delta').style.color=color;
  const h=computeHints();
  document.getElementById('price-hints').textContent=`RSI:${h.rsi} · VOL:${h.vol}% · MA20:${h.ma}`;
  drawPriceChart();
}

// ══════════════════════════════════════════
// ABILITIES UI
// ══════════════════════════════════════════
function buildAbilityBar() {
  const bar=document.getElementById('ability-bar');
  bar.innerHTML='';
  const cfg=HEROES[gs.playerType];
  const chip=document.createElement('div');
  chip.className='ability-chip'+(gs.playerSpecialCD===0?' ready':' used');
  chip.id='ability-chip';
  chip.innerHTML=`${cfg.special} <span class="cd">${gs.playerSpecialCD>0?`CD:${gs.playerSpecialCD}`:'READY'}</span>`;
  chip.onclick=()=>activateAbility();
  bar.appendChild(chip);
}

function updateAbilityBar() {
  const chip=document.getElementById('ability-chip');
  if(!chip)return;
  chip.className='ability-chip'+(gs.playerSpecialCD===0&&!gs.playerSpecialActive?' ready':' used');
  chip.innerHTML=`${HEROES[gs.playerType].special} <span class="cd">${gs.playerSpecialCD>0?`CD:${gs.playerSpecialCD}`:(gs.playerSpecialActive?'ACTIVE':'READY')}</span>`;
}

function activateAbility() {
  if (gs.playerSpecialCD>0||!gs.running||gs.playerSpecialActive) return;
  gs.playerSpecialActive=true;
  gs.playerSpecialCD=HEROES[gs.playerType].specialCD;
  SFX.special();
  triggerSpecial(playerHero);
  showToast(`⚡ ${HEROES[gs.playerType].special}!`,'#f59e0b',1500);
  updateAbilityBar();
  // BEAR: HIBERNATE → instant shield
  if (gs.playerType==='bear') { gs.playerShield=30; triggerShield(playerHero); updateHPBars(); }
  // SCAN: reveal AI next prediction
  if (gs.playerType==='robot') { gs.scanActive=true; }
}

// ══════════════════════════════════════════
// AI LOGIC (improved difficulty)
// ══════════════════════════════════════════
function aiDecide() {
  const h=computeHints();
  const rsi=parseFloat(h.rsi);
  // Smart mode: uses recent price history & RSI
  let pred;
  if (gs.priceHistory.length>=3) {
    const last3=gs.priceHistory.slice(-3);
    const upCount=last3.filter(x=>x==='up').length;
    // Mean reversion tendency
    if (upCount>=3) pred='down';
    else if (upCount===0) pred='up';
    else if (rsi>65) pred='down';
    else if (rsi<40) pred='up';
    else pred=Math.random()>0.5?'up':'down';
  } else {
    pred=h.ma?'up':'down';
    if (Math.random()<0.45) pred=Math.random()>0.5?'up':'down';
  }
  gs.aiLastPred=pred;
  return pred;
}

// ══════════════════════════════════════════
// MULTIPLAYER STUB
// Real implementation: use WebSocket/WebRTC + signaling server
// Structure: room codes generated, shared via URL param
// ══════════════════════════════════════════
function initMultiplayerStub() {
  const code=Math.random().toString(36).slice(2,6).toUpperCase();
  gs.roomCode=code;
  document.getElementById('room-code').textContent=code;
  // Simulate opponent joining after 2-4s
  setTimeout(()=>{
    gs.mpOpponentReady=true;
    document.getElementById('mp-waiting').textContent='OPPONENT JOINED · READY!';
    document.getElementById('enter-btn').style.display='inline-block';
    SFX.tick();
  }, 2000+Math.random()*2000);
}

// ══════════════════════════════════════════
// TURN RESOLUTION
// ══════════════════════════════════════════
async function resolveTurn(playerPred) {
  setBtnsEnabled(false);
  document.getElementById('ai-thinking').style.opacity=1;
  SFX.click();

  await delay(600+Math.random()*400);
  document.getElementById('ai-thinking').style.opacity=0;

  const conf=parseInt(document.getElementById('conf-slider').value);
  const nonce=Math.floor(Math.random()*1e9);
  await hashPrediction(playerPred,conf,nonce); // commitment

  // Oracle
  const oracle=simulatePrice();
  const priceDir=oracle.direction;
  const aiPred=aiDecide();
  const playerRight=(playerPred===priceDir);
  const aiRight=(aiPred===priceDir);

  updatePriceDisplay();

  const streakMult=1+Math.max(0,gs.streak-1)*0.18;
  let usedSpecial = gs.playerSpecialActive ? HEROES[gs.playerType].special : null;
  gs.playerSpecialActive=false;

  // Show scan result
  if (gs.scanActive) {
    showCombo(`🔍 AI PREDICTED: ${aiPred.toUpperCase()}!`); gs.scanActive=false;
  }

  // ── PLAYER ──
  if (playerRight) {
    const dmg=Math.round(calcDamage(gs.playerType,gs.aiType,true,conf,usedSpecial)*streakMult);
    const absorbed=Math.min(gs.aiShield,dmg);
    gs.aiShield=Math.max(0,gs.aiShield-absorbed);
    const realDmg=dmg-absorbed;
    gs.aiHP=Math.max(0,gs.aiHP-realDmg);
    gs.streak++; if(gs.streak>gs.maxStreak) gs.maxStreak=gs.streak;
    triggerAttack(playerHero,1);
    triggerHit(aiHero);
    SFX.hit();
    if (absorbed>0) showToast(`${dmg} DMG (${absorbed} BLOCKED)`,absorbed===dmg?'#60a5fa':'#10b981');
    else showToast(`⚔ ${realDmg} SLASH!`,'#10b981');
    flashScreen(0x00ff88,0.15);
    if (gs.streak>=3) showCombo(`🔥 ${gs.streak}× COMBO! ×${(streakMult).toFixed(1)}`);
  } else {
    let selfDmg=SELF_SLASH;
    if (gs.playerShield>0){ const a=Math.min(gs.playerShield,selfDmg); gs.playerShield=Math.max(0,gs.playerShield-a); selfDmg-=a; }
    gs.playerHP=Math.max(0,gs.playerHP-selfDmg);
    const slash=Math.floor(gs.playerStake*0.08);
    gs.playerStake=Math.max(0,gs.playerStake-slash);
    gs.streak=0;
    triggerSlash(playerHero);
    SFX.slash();
    showToast('SELF SLASH','#ef4444');
  }

  // WHALE: MARKET DUMP drains stake
  if (usedSpecial==='MARKET DUMP') { const drain=Math.floor(gs.aiStake*0.15); gs.aiStake=Math.max(0,gs.aiStake-drain); }
  // Dragon: burn DoT
  if (usedSpecial==='INFERNO') { gs.aiDot+=15; }
  // Apply DoT
  if (gs.aiDot>0) { gs.aiHP=Math.max(0,gs.aiHP-5); gs.aiDot=Math.max(0,gs.aiDot-5); }
  if (gs.burnDot>0) { gs.playerHP=Math.max(0,gs.playerHP-5); gs.burnDot=Math.max(0,gs.burnDot-5); }

  // ── AI ──
  await delay(280);
  if (aiRight) {
    const dmg=calcDamage(gs.aiType,gs.playerType,true,3, gs.aiSpecialCD===0?HEROES[gs.aiType].special:null);
    if (gs.aiSpecialCD===0) gs.aiSpecialCD=HEROES[gs.aiType].specialCD;
    const absorbed=Math.min(gs.playerShield,dmg);
    gs.playerShield=Math.max(0,gs.playerShield-absorbed);
    const realDmg=dmg-absorbed;
    gs.playerHP=Math.max(0,gs.playerHP-realDmg);
    triggerAttack(aiHero,-1);
    triggerHit(playerHero);
    SFX.hit();
    await delay(180);
    showToast(`AI −${realDmg} HP`,'#f87171');
  } else {
    const selfDmg=Math.floor(SELF_SLASH*0.65);
    gs.aiHP=Math.max(0,gs.aiHP-selfDmg);
    gs.aiStake=Math.max(0,gs.aiStake-Math.floor(gs.aiStake*0.07));
    triggerSlash(aiHero);
  }

  // AI BEAR: auto-shield if low
  if (gs.aiType==='bear' && gs.aiHP<35 && gs.aiSpecialCD===0) {
    gs.aiShield=30; gs.aiSpecialCD=HEROES.bear.specialCD;
    triggerShield(aiHero);
  }

  // CD tick
  if (gs.playerSpecialCD>0) gs.playerSpecialCD--;
  if (gs.aiSpecialCD>0) gs.aiSpecialCD--;

  gs.turn++;
  updateHPBars(); updateHeroPanels(); updateAbilityBar();

  await delay(700);

  if (gs.playerHP<=0||gs.aiHP<=0||gs.turn>=MAX_TURNS) endDuel();
  else setBtnsEnabled(true);
}

function delay(ms){return new Promise(r=>setTimeout(r,ms));}

// ══════════════════════════════════════════
// DUEL END
// ══════════════════════════════════════════
function endDuel() {
  gs.running=false;
  const won=gs.playerHP>gs.aiHP;
  let reward=0;
  if (won) {
    reward=Math.floor(gs.aiStake*SLASH_RATIO);
    gs.playerStake+=reward; gs.wins++;
    triggerWin(playerHero);
    spawnConfetti(playerHero.position,HEROES[gs.playerType].pColor);
    SFX.win();
    showResultOverlay('VICTORY','#10b981',`+${reward} $ARENA SLASHED`,gs.streak);
  } else {
    const lost=Math.floor(gs.playerStake*SLASH_RATIO);
    gs.playerStake=Math.max(10,gs.playerStake-lost);
    gs.losses++; triggerDeath(playerHero);
    SFX.lose();
    showResultOverlay('DEFEATED','#ef4444',`−${Math.floor(gs.aiStake*SLASH_RATIO)} $ARENA LOST`,gs.streak);
  }
  recordResult(won,gs.streak,gs.maxStreak);
  try{localStorage.setItem('sc_stake',gs.playerStake);}catch(e){}
}

function showResultOverlay(title,color,rewardText,streak) {
  const ov=document.getElementById('overlay');
  const or=document.getElementById('overlay-result');
  const rw=document.getElementById('overlay-reward');
  const st=document.getElementById('overlay-streak-msg');
  or.textContent=title; or.style.color=color; or.style.display='block';
  rw.textContent=rewardText; rw.style.display='block';
  st.textContent=streak>=2?`🔥 ${streak} TURN STREAK BONUS!`:''; st.style.display='block';
  document.getElementById('rematch-btn').style.display='inline-block';
  document.getElementById('enter-btn').style.display='none';
  document.getElementById('hero-select').style.display='flex';
  ov.style.display='flex';
}

// ══════════════════════════════════════════
// LEADERBOARD
// ══════════════════════════════════════════
function loadLB(){try{return JSON.parse(localStorage.getItem('sc_lb')||'[]');}catch{return[];}}
function saveLB(lb){try{localStorage.setItem('sc_lb',JSON.stringify(lb.slice(0,8)));}catch{}}
function recordResult(won,streak,maxStreak){
  const lb=loadLB();
  lb.unshift({won,streak,maxStreak,ts:Date.now()});
  saveLB(lb); renderLB();
}
function renderLB(){
  const lb=loadLB(); const el=document.getElementById('lb-list');
  if(!lb.length){el.innerHTML='<div style="opacity:0.25;font-size:8px;font-family:Share Tech Mono">NO GAMES YET</div>';return;}
  el.innerHTML=lb.slice(0,6).map(e=>`<div class="lb-row"><span class="${e.won?'lb-win':'lb-loss'}">${e.won?'WIN':'LOSS'}</span><span style="opacity:0.4">🔥${e.maxStreak||e.streak}</span></div>`).join('');
}

// ══════════════════════════════════════════
// GAME START
// ══════════════════════════════════════════
function startGame() {
  if(playerHero){scene.remove(playerHero); playerHero=null;}
  if(aiHero){scene.remove(aiHero); aiHero=null;}

  try{const s=localStorage.getItem('sc_stake'); if(s)gs.playerStake=Math.max(10,parseInt(s));}catch{}
  gs.playerStake-=ENTRY_FEE; if(gs.playerStake<0)gs.playerStake=10;

  const types=Object.keys(HEROES);
  gs.aiType=types[Math.floor(Math.random()*types.length)];
  gs.aiStake=100+Math.floor(Math.random()*50);

  const hDef=HEROES[gs.playerType];
  gs.playerHP=hDef.hp; gs.aiHP=HEROES[gs.aiType].hp;
  gs.playerShield=0; gs.aiShield=0;
  gs.turn=0; gs.streak=0; gs.maxStreak=0;
  gs.price=62000+Math.random()*10000; gs.lastPrice=gs.price;
  gs.priceHistory=[]; gs.pricePoints=[gs.price];
  gs.playerSpecialCD=0; gs.aiSpecialCD=0;
  gs.playerSpecialActive=false; gs.scanActive=false; gs.burnDot=0; gs.aiDot=0;
  gs.running=true; gs.aiLastPred=null;

  playerHero=buildHero(gs.playerType,'player');
  aiHero=buildHero(gs.aiType,'ai');

  // Spotlight tint
  const pC=new THREE.Color(HEROES[gs.playerType].color);
  const aC=new THREE.Color(HEROES[gs.aiType].color);
  sp1.color.set(pC); sp2.color.set(aC);
  rimLeft.color.set(pC); rimRight.color.set(aC);

  document.getElementById('overlay').style.display='none';
  updateHPBars(); updateHeroPanels(); updatePriceDisplay();
  buildAbilityBar(); setBtnsEnabled(true);
  updateMPOnline();
}

function setBtnsEnabled(on) {
  document.getElementById('btn-up').disabled=!on;
  document.getElementById('btn-down').disabled=!on;
  document.getElementById('phase-text').textContent=on?'PREDICT THE NEXT MOVE':'RESOLVING...';
}

// ══════════════════════════════════════════
// MULTIPLAYER ONLINE COUNTER (stub)
// ══════════════════════════════════════════
function updateMPOnline() {
  const n=2+Math.floor(Math.random()*18);
  document.getElementById('mp-label').textContent=`${n} ONLINE`;
}
setInterval(updateMPOnline,8000);

// ══════════════════════════════════════════
// ANIMATION LOOP
// ══════════════════════════════════════════
const clock=new THREE.Clock();
let t=0;

function animate() {
  requestAnimationFrame(animate);
  const dt=clock.getDelta(); t+=dt;

  // Arena pulses
  outerRing.material.emissiveIntensity=2+Math.sin(t*2)*0.8;
  if(scene.userData.hexPads) scene.userData.hexPads.forEach((h,i)=>{
    h.position.y=0.02+Math.sin(t*1.2+h.userData.floatOff)*0.04;
    h.material.emissiveIntensity=0.8+Math.sin(t*1.5+i)*0.5;
  });

  // Ambient sparks
  for(let i=0;i<sparkCount;i++){
    sparkPos[i*3+1]+=sparkVel[i*3+1]; if(sparkPos[i*3+1]>7)sparkPos[i*3+1]=0;
  }
  sparkGeo.attributes.position.needsUpdate=true;

  // Hero particles & idle
  for(const hero of [playerHero,aiHero]){
    if(!hero)continue;
    const pp=hero.userData.pPos; if(!pp)continue;
    const pCount=pp.length/3;
    for(let i=0;i<pCount;i++){
      pp[i*3+1]+=0.007; if(pp[i*3+1]>2.8)pp[i*3+1]=0;
    }
    hero.userData.particles.geometry.attributes.position.needsUpdate=true;
    // Idle bob (if not animating)
    const hasAnim=heroAnims.some(a=>a.hero===hero);
    if(!hasAnim) hero.position.y=Math.sin(t*1.4+(hero.userData.side==='ai'?Math.PI:0))*0.055;
    // Shield pulse
    if(hero.userData.shield && hero.userData.shield.material.opacity>0){
      hero.userData.shield.material.opacity=0.12+Math.sin(t*4)*0.08;
      hero.userData.shield.scale.setScalar(1+Math.sin(t*3)*0.04);
    }
  }

  // Hero animations
  heroAnims=heroAnims.filter(a=>{
    a.t+=dt/a.dur;
    if(a.t>=1){
      if(a.hero){ a.hero.position.x=a.hero.userData.origX; a.hero.rotation.z=0; a.hero.rotation.x=0; }
      return false;
    }
    switch(a.type){
      case 'lunge': a.hero.position.x=a.hero.userData.origX+a.dir*Math.sin(a.t*Math.PI)*1.4; break;
      case 'shake': a.hero.position.x=a.hero.userData.origX+Math.sin(a.t*50)*0.14; break;
      case 'reel':  a.hero.position.x=a.hero.userData.origX+Math.sin(a.t*Math.PI)*(-0.4*(a.hero.userData.side==='ai'?-1:1)); break;
      case 'victory': a.hero.position.y=Math.abs(Math.sin(a.t*Math.PI*2.5))*0.5; a.hero.rotation.y=a.t*Math.PI*3; break;
      case 'fall': a.hero.rotation.x=a.t*Math.PI*0.45; a.hero.position.y=-a.t*1.2; break;
      case 'special': a.hero.scale.setScalar(1+Math.sin(a.t*Math.PI)*0.18); break;
      case 'shieldpulse': if(a.hero.userData.shield) a.hero.userData.shield.material.opacity=Math.sin(a.t*Math.PI)*0.35; break;
    }
    return true;
  });

  // Camera sway + zoom on attack
  const attackAnim=heroAnims.find(a=>a.type==='lunge');
  const targetZ=attackAnim?11:13;
  camera.position.x+=(Math.sin(t*0.12)*0.6-camera.position.x)*0.02;
  camera.position.y+=(6.5+Math.sin(t*0.18)*0.25-camera.position.y)*0.02;
  camera.position.z+=(targetZ-camera.position.z)*0.05;
  camera.lookAt(0,1.2,0);

  // Rim light flicker
  rimLeft.intensity=1.8+Math.sin(t*3.1)*0.4;
  rimRight.intensity=1.8+Math.sin(t*2.7+1)*0.4;

  updateConfetti(); updateShockwaves();
  renderer.render(scene,camera);
}
animate();

// ══════════════════════════════════════════
// UI EVENT LISTENERS
// ══════════════════════════════════════════
document.getElementById('conf-slider').addEventListener('input',e=>{
  document.getElementById('conf-val').textContent=e.target.value; SFX.tick();
});
document.getElementById('btn-up').addEventListener('click',()=>{ if(gs.running)resolveTurn('up'); });
document.getElementById('btn-down').addEventListener('click',()=>{ if(gs.running)resolveTurn('down'); });
document.getElementById('enter-btn').addEventListener('click',startGame);
document.getElementById('rematch-btn').addEventListener('click',startGame);

document.querySelectorAll('.hero-card').forEach(card=>{
  card.addEventListener('click',()=>{
    document.querySelectorAll('.hero-card').forEach(c=>c.classList.remove('selected'));
    card.classList.add('selected'); gs.playerType=card.dataset.type; SFX.click();
  });
});

document.querySelectorAll('.mode-btn').forEach(btn=>{
  btn.addEventListener('click',()=>{
    document.querySelectorAll('.mode-btn').forEach(b=>b.classList.remove('active'));
    btn.classList.add('active'); gs.mode=btn.dataset.mode; SFX.click();
    const mpLobby=document.getElementById('mp-lobby');
    if(gs.mode==='mp'){
      mpLobby.style.display='flex';
      document.getElementById('enter-btn').style.display='none';
      initMultiplayerStub();
    } else {
      mpLobby.style.display='none';
      document.getElementById('enter-btn').style.display='inline-block';
    }
  });
});

document.getElementById('copy-code').addEventListener('click',()=>{
  if(gs.roomCode){
    try{navigator.clipboard.writeText(gs.roomCode);}catch{}
    document.getElementById('copy-code').textContent='✓ COPIED!';
    setTimeout(()=>document.getElementById('copy-code').textContent='📋 COPY CODE',1500);
  }
});

window.addEventListener('resize',()=>{
  camera.aspect=window.innerWidth/window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth,window.innerHeight);
});

// ══════════════════════════════════════════
// INIT
// ══════════════════════════════════════════
renderLB();
document.getElementById('overlay-result').style.display='none';
document.getElementById('overlay-reward').style.display='none';
document.getElementById('overlay-streak-msg').style.display='none';
document.getElementById('rematch-btn').style.display='none';
document.getElementById('mp-lobby').style.display='none';
</script>
</body>
</html>