<!DOCTYPE html>
<html lang="no">
<head>
    <link rel="icon" type="image/png" href="/logo.png">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Spillsenteret</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
    background:
        radial-gradient(circle at 12% -10%, rgba(99,102,241,0.18), transparent 45%),
        radial-gradient(circle at 90% 10%, rgba(236,72,153,0.10), transparent 50%),
        radial-gradient(circle at 50% 110%, rgba(34,211,238,0.10), transparent 55%),
        #0d0d1d;
    color:#e2e8f0;
    font-family:'Inter','Segoe UI',system-ui,-apple-system,sans-serif;
    min-height:100vh;
    overflow-x:hidden;
    display:flex;
    -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;
}
::selection{background:rgba(129,140,248,0.4);color:#fff}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(129,140,248,0.18);border-radius:8px}
::-webkit-scrollbar-thumb:hover{background:rgba(129,140,248,0.32)}

/* === Sidebar === */
.sidebar{
    position:fixed;left:0;top:0;bottom:0;
    width:60px;
    background:linear-gradient(180deg,rgba(15,15,35,0.85),rgba(10,10,25,0.85));
    backdrop-filter:blur(14px);
    -webkit-backdrop-filter:blur(14px);
    border-right:1px solid rgba(255,255,255,0.06);
    display:flex;flex-direction:column;align-items:center;
    padding:14px 0;
    z-index:100;
    gap:6px;
}
.sidebar-logo{display:none}
.sidebar-logo img{display:none}
.sidebar-btn{
    width:42px;height:42px;
    border-radius:12px;
    display:flex;align-items:center;justify-content:center;
    color:rgba(255,255,255,0.4);
    cursor:pointer;
    transition:background .2s,color .2s,transform .15s;
    text-decoration:none;
    border:none;background:transparent;
    position:relative;
}
.sidebar-btn::before{
    content:'';position:absolute;left:-14px;top:8px;bottom:8px;width:3px;
    border-radius:0 3px 3px 0;background:#818cf8;
    transform:scaleY(0);transition:transform .2s;
}
.sidebar-btn svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.sidebar-btn:hover{
    background:rgba(255,255,255,0.06);
    color:rgba(255,255,255,0.9);
    transform:translateY(-1px);
}
.sidebar-btn.active{
    background:linear-gradient(135deg,rgba(99,102,241,0.22),rgba(139,92,246,0.18));
    color:#a5b4fc;
    box-shadow:0 4px 14px rgba(99,102,241,0.25);
}
.sidebar-btn.active::before{transform:scaleY(1)}
.sidebar-spacer{flex:1}

/* === Main Layout === */
.main-wrap{
    margin-left:60px;
    flex:1;
    display:flex;flex-direction:column;
    min-height:100vh;
}

/* === Top Navbar === */
.topbar{
    position:sticky;top:0;
    height:60px;
    background:rgba(15,15,35,0.6);
    backdrop-filter:blur(20px) saturate(160%);
    -webkit-backdrop-filter:blur(20px) saturate(160%);
    border-bottom:1px solid rgba(255,255,255,0.06);
    display:flex;align-items:center;
    padding:0 24px;
    z-index:90;
    gap:16px;
}
.topbar-brand{
    display:flex;align-items:center;
    user-select:none;
    text-decoration:none;
}
.topbar-brand img{
    height:38px;border-radius:10px;
    filter:brightness(1.1);
    box-shadow:0 2px 8px rgba(0,0,0,0.3);
}
.topbar-brand-text{
    font-size:18px;font-weight:800;
    color:#fff;margin-left:12px;
    letter-spacing:.3px;
    white-space:nowrap;
    background:linear-gradient(135deg,#fff 0%,#cbd5e1 100%);
    -webkit-background-clip:text;
    -webkit-text-fill-color:transparent;
    background-clip:text;
}
.topbar-brand-text span{
    background:linear-gradient(135deg,#818cf8,#c084fc);
    -webkit-background-clip:text;
    -webkit-text-fill-color:transparent;
    background-clip:text;
}
.search-wrap{
    flex:1;max-width:520px;
    margin:0 auto;
    position:relative;
}
.search-wrap svg{
    position:absolute;left:14px;top:50%;transform:translateY(-50%);
    width:16px;height:16px;
    color:rgba(255,255,255,0.3);
    pointer-events:none;
}
.search-input{
    width:100%;
    height:40px;
    background:rgba(255,255,255,0.04);
    border:1px solid rgba(255,255,255,0.08);
    border-radius:12px;
    padding:0 14px 0 40px;
    color:#e2e8f0;
    font-size:14px;
    outline:none;
    transition:border-color .2s,background .2s,box-shadow .2s;
}
.search-input::placeholder{color:rgba(255,255,255,0.3)}
.search-input:focus{
    border-color:rgba(129,140,248,0.5);
    background:rgba(255,255,255,0.07);
    box-shadow:0 0 0 4px rgba(129,140,248,0.12);
}
.topbar-right{
    display:flex;align-items:center;gap:8px;
}
.topbar-icon{
    width:38px;height:38px;border-radius:11px;
    display:flex;align-items:center;justify-content:center;
    color:rgba(255,255,255,0.45);font-size:16px;
    cursor:pointer;transition:background .2s,color .2s,transform .15s;
    background:transparent;border:none;
}
.topbar-icon:hover{background:rgba(255,255,255,0.06);color:#fff;transform:translateY(-1px)}
#topbarShopBtn:hover{background:rgba(255,255,255,0.06);color:rgba(255,255,255,0.8)}
.analytics-link{
    font-size:11px;font-weight:700;letter-spacing:1.5px;
    text-transform:uppercase;color:rgba(255,255,255,0.4);
    text-decoration:none;padding:6px 12px;border-radius:8px;
    transition:background .2s,color .2s;
}
.analytics-link:hover{background:rgba(255,255,255,0.06);color:rgba(255,255,255,0.8)}

/* === Account Button === */
.account-btn{
    display:flex;align-items:center;gap:6px;
    background:rgba(129,140,248,0.12);border:1px solid rgba(129,140,248,0.2);
    border-radius:10px;padding:5px 14px;cursor:pointer;
    color:#818cf8;font-size:13px;font-weight:600;
    transition:background .2s,border-color .2s;
}
.account-btn:hover{background:rgba(129,140,248,0.2);border-color:rgba(129,140,248,0.4)}
.account-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.account-btn .user-name{max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* === Auth Modal === */
.modal-overlay{
    position:fixed;inset:0;background:rgba(0,0,0,0.6);
    backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
    display:none;align-items:center;justify-content:center;
    z-index:1000;
}
.modal-overlay.open{display:flex}
.modal{
    background:#1e1e3a;border:1px solid rgba(255,255,255,0.08);
    border-radius:16px;padding:32px;width:380px;max-width:90vw;
    box-shadow:0 24px 60px rgba(0,0,0,0.5);
}
.modal h2{color:#fff;font-size:20px;font-weight:700;margin-bottom:4px;text-align:center}
.modal .modal-sub{color:rgba(255,255,255,0.4);font-size:13px;text-align:center;margin-bottom:24px}
.modal label{display:block;font-size:12px;font-weight:600;color:rgba(255,255,255,0.5);margin-bottom:4px;letter-spacing:.5px}
.modal input[type=text],.modal input[type=password]{
    width:100%;height:40px;background:rgba(255,255,255,0.06);
    border:1px solid rgba(255,255,255,0.1);border-radius:10px;
    padding:0 14px;color:#e2e8f0;font-size:14px;outline:none;
    margin-bottom:14px;transition:border-color .2s;
}
.modal input:focus{border-color:rgba(129,140,248,0.5)}
.modal .modal-btn{
    width:100%;height:42px;border:none;border-radius:10px;
    background:linear-gradient(135deg,#4f46e5,#7c3aed);
    color:#fff;font-size:14px;font-weight:700;cursor:pointer;
    transition:opacity .2s;letter-spacing:.5px;
}
.modal .modal-btn:hover{opacity:.9}
.modal .modal-toggle{
    text-align:center;margin-top:16px;font-size:13px;color:rgba(255,255,255,0.4);
}
.modal .modal-toggle a{color:#818cf8;cursor:pointer;text-decoration:none;font-weight:600}
.modal .modal-toggle a:hover{text-decoration:underline}
.modal .modal-error{color:#ff5577;font-size:12px;text-align:center;margin-bottom:10px;min-height:16px}
.modal .modal-close{
    position:absolute;top:12px;right:14px;background:none;border:none;
    color:rgba(255,255,255,0.3);font-size:20px;cursor:pointer;line-height:1;
}
.modal .modal-close:hover{color:#fff}
.modal-wrap{position:relative}

/* === Shop Tabs === */
.shop-tab{
    padding:8px 16px;border:none;border-radius:10px 10px 0 0;
    background:rgba(255,255,255,0.04);color:rgba(255,255,255,0.45);
    font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;
    transition:all .2s;border-bottom:2px solid transparent;
}
.shop-tab:hover{background:rgba(255,255,255,0.08);color:rgba(255,255,255,0.7)}
.shop-tab.active{background:rgba(129,140,248,0.15);color:#818cf8;border-bottom-color:#818cf8}

/* === Shop Item Cards === */
.shop-item{
    display:flex;align-items:center;gap:14px;padding:12px 16px;
    background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);
    border-radius:12px;transition:all .2s;cursor:default;position:relative;overflow:hidden;
}
.shop-item:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12)}
.shop-item .item-icon{
    width:42px;height:42px;border-radius:10px;display:flex;align-items:center;justify-content:center;
    font-size:20px;flex-shrink:0;
}
.shop-item .item-info{flex:1;min-width:0}
.shop-item .item-name{font-size:13px;font-weight:700;color:#fff;display:flex;align-items:center;gap:8px}
.shop-item .item-desc{font-size:11px;color:rgba(255,255,255,0.35);margin-top:2px}
.shop-item .item-rarity{
    font-size:9px;font-weight:800;letter-spacing:1px;text-transform:uppercase;
    padding:2px 7px;border-radius:6px;display:inline-block;
}
.rarity-common{background:rgba(156,163,175,0.15);color:#9ca3af}
.rarity-uncommon{background:rgba(74,222,128,0.12);color:#4ade80}
.rarity-rare{background:rgba(96,165,250,0.12);color:#60a5fa}
.rarity-epic{background:rgba(168,85,247,0.12);color:#a855f7}
.rarity-legendary{background:rgba(251,191,36,0.12);color:#fbbf24}
.rarity-mythic{background:rgba(236,72,153,0.12);color:#ec4899}
.rarity-divine{background:rgba(255,215,0,0.15);color:#ffd700}
.rarity-celestial{background:rgba(0,255,200,0.15);color:#00ffc8}
.rarity-eternal{background:rgba(255,100,255,0.15);color:#ff64ff}
.rarity-godlike{background:rgba(255,60,60,0.15);color:#ff4040}
.rarity-transcendent{background:rgba(10,0,20,0.4);color:#8844cc;text-shadow:0 0 8px rgba(100,0,200,0.6);border:1px solid rgba(100,0,200,0.3)}
.shop-item.legendary-glow{
    border-color:rgba(251,191,36,0.25);
    box-shadow:0 0 20px rgba(251,191,36,0.06);
}
.shop-item.epic-glow{
    border-color:rgba(168,85,247,0.2);
}
.shop-item.mythic-glow{
    border-color:rgba(236,72,153,0.3);
    box-shadow:0 0 24px rgba(236,72,153,0.1),0 0 60px rgba(236,72,153,0.04);
    animation:mythicPulse 2s ease-in-out infinite;
}
@keyframes mythicPulse{0%,100%{box-shadow:0 0 24px rgba(236,72,153,0.1)}50%{box-shadow:0 0 32px rgba(236,72,153,0.18)}}

/* === Spin Wheel === */
.wheel-container{text-align:center;margin-bottom:28px;padding:24px;background:rgba(255,255,255,0.02);border:1px solid rgba(255,255,255,0.06);border-radius:16px}
.wheel-canvas-wrap{position:relative;display:inline-block;margin:16px 0}
.wheel-pointer{position:absolute;top:-10px;left:50%;transform:translateX(-50%);font-size:28px;z-index:2;filter:drop-shadow(0 2px 6px rgba(0,0,0,0.5))}
.wheel-spin-btn{
    background:linear-gradient(135deg,#4f46e5,#7c3aed);color:#fff;border:none;border-radius:12px;
    padding:12px 32px;font-size:14px;font-weight:800;cursor:pointer;transition:all .2s;
}
.wheel-spin-btn:hover{opacity:.85;transform:scale(1.03)}
.wheel-spin-btn:disabled{background:rgba(255,255,255,0.06);color:rgba(255,255,255,0.3);cursor:default;transform:none}
.wheel-cooldown{color:rgba(255,255,255,0.35);font-size:12px;margin-top:8px}

/* === Chest Cards === */
.chest-card{
    display:flex;align-items:center;gap:14px;padding:16px 20px;
    background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);
    border-radius:14px;transition:all .2s;
}
.chest-card:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12)}
.chest-emoji{font-size:36px}
.chest-info{flex:1}
.chest-name{font-size:14px;font-weight:700;color:#fff;display:flex;align-items:center;gap:8px}
.chest-desc{font-size:11px;color:rgba(255,255,255,0.35);margin-top:3px}
.chest-odds{font-size:10px;color:rgba(255,255,255,0.25);margin-top:4px}

/* === Chest Reveal Overlay === */
.chest-reveal-overlay{
    position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);
    z-index:10000;display:flex;align-items:center;justify-content:center;
    animation:fadeIn .3s;
}
.chest-reveal-box{
    background:rgba(20,20,35,0.95);border:1px solid rgba(255,255,255,0.1);border-radius:20px;
    padding:40px 50px;text-align:center;animation:popIn .3s;
}
@keyframes popIn{from{transform:scale(0.8);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
.shop-item .item-actions{flex-shrink:0;display:flex;align-items:center;gap:8px}
.shop-btn{
    border:none;border-radius:8px;padding:7px 16px;font-size:11px;font-weight:700;
    cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:5px;white-space:nowrap;
}
.shop-btn-buy{background:linear-gradient(135deg,#4f46e5,#7c3aed);color:#fff}
.shop-btn-buy:hover{opacity:.85;transform:scale(1.03)}
.shop-btn-buy:disabled{background:rgba(255,255,255,0.06);color:rgba(255,255,255,0.25);cursor:default;transform:none}
.shop-btn-equip{background:rgba(129,140,248,0.15);color:#818cf8;border:1px solid rgba(129,140,248,0.25)}
.shop-btn-equip:hover{background:rgba(129,140,248,0.25)}
.shop-btn-equipped{background:rgba(74,222,128,0.15);color:#4ade80;cursor:default}
.shop-btn-unequip{background:rgba(255,68,68,0.1);color:#ff6b6b;font-size:10px;padding:5px 10px}
.shop-btn-unequip:hover{background:rgba(255,68,68,0.2)}
.shop-owned-check{color:#4ade80;font-weight:700;font-size:13px;margin-right:4px}

@media(max-width:600px){
    #shopPreview{display:none !important}
    .modal[style*="720px"]{max-width:95vw !important}
}
@keyframes rainbowShift{0%{background-position:0% 50%}100%{background-position:200% 50%}}

/* === Casino === */
.casino-btn{
    background:linear-gradient(135deg,#f59e0b,#d97706);color:#fff;border:none;
    border-radius:8px;padding:8px 18px;font-size:12px;font-weight:800;cursor:pointer;
    transition:all .15s;letter-spacing:0.5px;
}
.casino-btn:hover{opacity:.85;transform:scale(1.03)}
.casino-btn:disabled{opacity:.3;cursor:default;transform:none}
.casino-btn-green{background:linear-gradient(135deg,#22c55e,#16a34a)}
.mine-cell{
    width:100%;aspect-ratio:1;border:none;border-radius:6px;cursor:pointer;
    font-size:16px;font-weight:700;transition:all .15s;
    background:rgba(255,255,255,0.06);color:transparent;
}
.mine-cell:hover:not(:disabled){background:rgba(255,255,255,0.12)}
.mine-cell.revealed-safe{background:rgba(74,222,128,0.2);color:#4ade80;cursor:default}
.mine-cell.revealed-mine{background:rgba(239,68,68,0.2);color:#ef4444;cursor:default}
.tower-row{display:flex;gap:6px;margin-bottom:4px}
.tower-door{
    flex:1;padding:12px 8px;border:none;border-radius:8px;cursor:pointer;
    font-size:13px;font-weight:700;transition:all .15s;
    background:rgba(129,140,248,0.1);color:#818cf8;
}
.tower-door:hover:not(:disabled){background:rgba(129,140,248,0.2)}
.tower-door.safe{background:rgba(74,222,128,0.2);color:#4ade80;cursor:default}
.tower-door.danger{background:rgba(239,68,68,0.2);color:#ef4444;cursor:default}
.tower-door:disabled{cursor:default;opacity:0.5}
@keyframes bjDeal{0%{transform:translateY(-30px) rotate(-12deg);opacity:0}100%{transform:translateY(0) rotate(0);opacity:1}}
.bj-card{transition:transform .15s}
.bj-card:hover{transform:translateY(-2px)}

/* === Logged-in dropdown === */
.user-dropdown{
    position:absolute;top:48px;right:0;
    background:#1e1e3a;border:1px solid rgba(255,255,255,0.08);
    border-radius:12px;padding:8px 0;min-width:180px;
    box-shadow:0 12px 40px rgba(0,0,0,0.5);
    display:none;z-index:200;
}
.user-dropdown.open{display:block}
.user-dropdown .dd-item{
    padding:10px 18px;font-size:13px;color:rgba(255,255,255,0.7);
    cursor:pointer;transition:background .15s;
    display:flex;align-items:center;gap:8px;
}
.user-dropdown .dd-item:hover{background:rgba(255,255,255,0.05);color:#fff}
.user-dropdown .dd-item.danger{color:#ff5577}
.user-dropdown .dd-header{
    padding:12px 18px 8px;font-size:11px;font-weight:700;
    color:rgba(255,255,255,0.3);letter-spacing:1px;text-transform:uppercase;
    border-bottom:1px solid rgba(255,255,255,0.06);margin-bottom:4px;
}

/* === Content === */
.content{
    padding:28px 28px 40px;
    flex:1;
}
.section-title{
    font-size:18px;font-weight:700;
    color:#fff;
    margin-bottom:20px;
    display:flex;align-items:center;gap:10px;
}
.section-title::before{
    content:'';width:4px;height:20px;
    background:#818cf8;border-radius:4px;
}

/* === Game Grid (Playhop style) === */
.games-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(240px,1fr));
    gap:16px;
}

/* === Card === */
.game-card{
    --accent:#818cf8;
    position:relative;
    border-radius:16px;
    overflow:hidden;
    text-decoration:none;color:inherit;
    background:linear-gradient(135deg,#1d1d38,#16162d);
    border:1px solid rgba(255,255,255,0.06);
    transition:transform .25s cubic-bezier(.2,.8,.2,1),box-shadow .3s,border-color .25s;
    cursor:pointer;
    aspect-ratio:16/10;
    display:block;
    isolation:isolate;
}
.game-card::after{
    content:'';position:absolute;inset:0;
    border-radius:16px;
    background:linear-gradient(135deg,color-mix(in srgb,var(--accent) 30%,transparent),transparent 60%);
    opacity:0;transition:opacity .3s;pointer-events:none;mix-blend-mode:screen;z-index:2;
}
.game-card:hover{
    transform:translateY(-6px) scale(1.02);
    box-shadow:0 20px 50px rgba(0,0,0,0.55), 0 0 0 1px color-mix(in srgb,var(--accent) 50%,transparent);
    border-color:color-mix(in srgb,var(--accent) 50%,transparent);
}
.game-card:hover::after{opacity:.35}

.preview-wrap{
    position:absolute;inset:0;
    overflow:hidden;background:#11112a;
}
.preview-canvas{width:100%;height:100%;display:block;object-fit:cover;transition:transform .4s}
.game-card:hover .preview-canvas{transform:scale(1.06)}
.preview-overlay{
    position:absolute;inset:0;
    background:linear-gradient(0deg,rgba(10,10,25,0.92) 0%,rgba(10,10,25,0.35) 45%,transparent 70%);
    pointer-events:none;
}

/* Card info overlay at bottom */
.card-info{
    position:absolute;bottom:0;left:0;right:0;
    padding:12px 16px;
    z-index:3;
    display:flex;align-items:flex-end;justify-content:space-between;
}
.card-title{
    font-size:14px;font-weight:800;letter-spacing:2px;
    color:#fff;
    text-transform:uppercase;
    text-shadow:0 2px 10px rgba(0,0,0,0.7);
}
.card-tag{
    font-size:9px;font-weight:600;letter-spacing:1px;
    text-transform:uppercase;
    color:var(--accent);
    margin-top:4px;
    opacity:.85;
}
.card-best{
    font-size:11px;color:rgba(255,255,255,0.7);
    text-shadow:0 1px 4px rgba(0,0,0,0.7);
    background:rgba(0,0,0,0.35);
    backdrop-filter:blur(6px);
    padding:3px 8px;border-radius:8px;
    border:1px solid rgba(255,255,255,0.06);
}
.card-best span{color:var(--accent);font-weight:700}

/* Play button on hover */
.card-play{display:none}

/* Category badge */
.card-badge{display:none}

/* Per-game accents */
.fell{--accent:#44bbdd}
.dodge{--accent:#dd5533}
.hit{--accent:#dd3366}
.rise{--accent:#bb8844}
.hexfall{--accent:#44bb88}
.beat{--accent:#ff44aa}
.volley{--accent:#44ddff}
.dash{--accent:#ff4466}
.rush{--accent:#ff6644}
.climb{--accent:#ff44aa}
.swerve{--accent:#44ff88}
.spin{--accent:#dd66ff}
.drop{--accent:#ff5577}
.territory{--accent:#44ff88}
.impostor{--accent:#ef4444}
.maze{--accent:#44dd88}
.chain{--accent:#ff8844}
.swap{--accent:#ffaa00}
.flick{--accent:#ff6633}
.pop{--accent:#ff66bb}
.nebula{--accent:#9aaaff}
.arena{--accent:#ffcc44}

/* === Footer === */
.footer{
    text-align:center;padding:20px;
    font-size:11px;letter-spacing:2px;color:rgba(255,255,255,0.15);font-weight:600;
}

/* === Responsive === */
@media(max-width:900px){
    .games-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
}
@media(max-width:640px){
    .sidebar{width:0;display:none}
    .main-wrap{margin-left:0}
    .topbar-brand{font-size:16px}
    .content{padding:16px 12px 32px}
    .games-grid{grid-template-columns:repeat(2,1fr);gap:10px}
    .search-wrap{max-width:none}
}
</style>
<link rel="stylesheet" href="assets/ux-polish.css">
<script defer src="assets/i18n.js"></script>
<script defer src="assets/ux-polish.js"></script>
</head>
<body>

<!-- Ban Overlay (shown when user is banned) -->
<div id="banOverlay" style="display:none;position:fixed;inset:0;z-index:99999;background:#0a0a14;display:none;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:40px">
    <div style="font-size:72px;margin-bottom:20px">??</div>
    <h1 style="font-size:36px;font-weight:900;color:#ef4444;letter-spacing:4px;margin-bottom:12px">BANNED</h1>
    <p style="font-size:16px;color:rgba(255,255,255,0.5);max-width:400px;line-height:1.6" id="banReasonText">Your account has been banned from Spillsenteret.</p>
    <p style="font-size:13px;color:rgba(255,255,255,0.2);margin-top:24px">Contact an administrator to appeal.</p>
</div>

<!-- Sidebar -->
<nav class="sidebar">
    <button class="sidebar-btn active" data-category="all" title="All games">
        <svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg>
    </button>
    <button class="sidebar-btn" data-category="popular" title="Popular">
        <svg viewBox="0 0 24 24"><path d="M12 2c.5 3.5 4 6 4 10a4 4 0 1 1-8 0c0-4 3.5-6.5 4-10z"/><path d="M10 15.5c0 1.1.9 2 2 2s2-.9 2-2c0-2-2-3-2-3s-2 1-2 3z"/></svg>
    </button>
    <button class="sidebar-btn" data-category="action" title="Action">
        <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M12 2v4M12 18v4M2 12h4M18 12h4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg>
    </button>
    <button class="sidebar-btn" data-category="platform" title="Platform">
        <svg viewBox="0 0 24 24"><path d="M4 17h6M10 13h4M14 9h6"/><circle cx="7" cy="7" r="2"/><path d="M7 9v4"/></svg>
    </button>
    <button class="sidebar-btn" data-category="arcade" title="Arcade">
        <svg viewBox="0 0 24 24"><rect x="2" y="6" width="20" height="12" rx="3"/><circle cx="8" cy="12" r="2"/><path d="M15 10v4M13 12h4"/></svg>
    </button>
    <button class="sidebar-btn" data-category="racing" title="Racing">
        <svg viewBox="0 0 24 24"><path d="M12 2L4 8l3 12h10l3-12L12 2z"/><path d="M12 2v20M4 8h16"/></svg>
    </button>
    <button class="sidebar-btn" data-category="rhythm" title="Rhythm">
        <svg viewBox="0 0 24 24"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>
    </button>
    <button class="sidebar-btn" data-category="builder" title="Builder">
        <svg viewBox="0 0 24 24"><path d="M3 21h18M5 21V10l7-5 7 5v11M9 21v-6h6v6M9 11h2M13 11h2"/></svg>
    </button>
    <div class="sidebar-spacer"></div>
    <button class="sidebar-btn" data-category="scoreboard" title="Leaderboard" onclick="openScoreboard()">
        <svg viewBox="0 0 24 24"><path d="M8 21h8M12 17v4M17 4H7a2 2 0 0 0-2 2v4c0 2.5 2 4.5 4.5 5h5c2.5-.5 4.5-2.5 4.5-5V6a2 2 0 0 0-2-2z"/><path d="M5 10c-1.5 0-3-1-3-3V6h3M19 10c1.5 0 3-1 3-3V6h-3"/></svg>
    </button>
    <button class="sidebar-btn" data-category="casino" title="Casino" onclick="openCasino()">
        <svg viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
    </button>
    <button class="sidebar-btn" data-category="shop" title="Shop" onclick="openShop()">
        <svg viewBox="0 0 24 24"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
    </button>
    <a href="analytics/" class="sidebar-btn" title="Stats">
        <svg viewBox="0 0 24 24"><path d="M18 20V10M12 20V4M6 20v-6"/></svg>
    </a>
</nav>

<!-- Main -->
<div class="main-wrap">
    <!-- Top Navbar -->
    <header class="topbar">
        <a href="/" class="topbar-brand"><img src="logo.png" alt="Spillsenteret"><span class="topbar-brand-text"><span>spill</span>senteret</span></a>
        <div class="search-wrap">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
            <input type="text" class="search-input" placeholder="Search games..." id="searchInput">
        </div>
        <div class="topbar-right">
            <button class="lang-switch" id="langToggleBtn" data-i18n-skip="true" type="button" onclick="window.SCi18n&&SCi18n.toggle()" aria-label="Toggle language">
                <span class="lang-no">NO</span><span class="lang-en">EN</span>
            </button>
            <a href="analytics/" class="analytics-link">Stats</a>
            <div id="topbarCoins" style="display:flex;align-items:center;gap:4px;color:#ffd700;font-weight:700;font-size:13px;cursor:pointer" onclick="openShop()" title="Shop">
                <svg width="16" height="16" viewBox="0 0 24 24" style="flex-shrink:0"><defs><radialGradient id="gcTop" cx="40%" cy="35%"><stop offset="0%" stop-color="#ffe066"/><stop offset="50%" stop-color="#ffd700"/><stop offset="100%" stop-color="#b8860b"/></radialGradient></defs><circle cx="12" cy="12" r="10" fill="url(#gcTop)"/><circle cx="12" cy="12" r="6.5" fill="none" stroke="#b8860b" stroke-width="1.2" opacity=".5"/><ellipse cx="10" cy="9" rx="4" ry="3" fill="rgba(255,255,255,0.18)"/></svg>
                <span id="topbarCoinCount">0</span>
            </div>
            <button id="topbarShopBtn" style="width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,0.4);cursor:pointer;background:transparent;border:none;transition:background .2s,color .2s" onclick="openShop()" title="Shop">
                <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z"/><line x1="3" y1="6" x2="21" y2="6"/><path d="M16 10a4 4 0 01-8 0"/></svg>
            </button>
            <div style="position:relative" id="accountWrap">
                <button class="account-btn" id="accountBtn">
                    <svg viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span class="user-name" id="accountLabel">Log in</span>
                </button>
                <div class="user-dropdown" id="userDropdown">
                    <div class="dd-header" id="ddUsername"></div>
                    <div class="dd-item" onclick="showProfile()">My profile</div>
                    <div class="dd-item" onclick="openShop()">Shop <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-.1em"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.7 13.4a2 2 0 002 1.6h9.7a2 2 0 002-1.6L23 6H6"/></svg></div>
                    <div class="dd-item" onclick="showScores()">My scores</div>
                    <div class="dd-item danger" onclick="logoutUser()">Log out</div>
                </div>
            </div>
        </div>
    </header>

    <!-- Content -->
    <main class="content">
        <div class="section-title" id="sectionTitle">All games</div>

        <div class="games-grid" id="gamesGrid">
            <a href="collapse/" class="game-card fell" data-name="fell" data-category="popular action">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="fell"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Survival</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">FELL</div><div class="card-tag">Survival / Reflex</div></div>
                    <span class="card-best" id="best-fell"></span>
                </div>
            </a>

            <a href="rise/" class="game-card rise" data-name="rise" data-category="popular platform">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="rise"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Platform</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">RISE</div><div class="card-tag">Platform</div></div>
                    <span class="card-best" id="best-rise"></span>
                </div>
            </a>

            <a href="swerve/" class="game-card swerve" data-name="swerve" data-category="popular racing">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="swerve"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Racing</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">SWERVE</div><div class="card-tag">Racing / Reflex</div></div>
                    <span class="card-best" id="best-swerve"></span>
                </div>
            </a>

            <a href="dash/" class="game-card dash" data-name="dash" data-category="popular action">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="dash"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Runner</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">DASH</div><div class="card-tag">Runner / Reflex</div></div>
                    <span class="card-best" id="best-dash"></span>
                </div>
            </a>

            <a href="dodge/" class="game-card dodge" data-name="dodge" data-category="action">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="dodge"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Action</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">DODGE</div><div class="card-tag">Bullet Hell</div></div>
                    <span class="card-best" id="best-dodge"></span>
                </div>
            </a>

            <a href="hit/" class="game-card hit" data-name="hit" data-category="action arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="hit"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Reflex</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">HIT</div><div class="card-tag">Reflex / Aim</div></div>
                    <span class="card-best" id="best-hit"></span>
                </div>
            </a>

            <a href="spin/" class="game-card spin" data-name="spin" data-category="action arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="spin"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Timing</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">SPIN</div><div class="card-tag">Timing / Survival</div></div>
                    <span class="card-best" id="best-spin"></span>
                </div>
            </a>

            <a href="climb/" class="game-card climb" data-name="climb" data-category="platform">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="climb"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Platform</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">CLIMB</div><div class="card-tag">Platform / Reflex</div></div>
                    <span class="card-best" id="best-climb"></span>
                </div>
            </a>

            <a href="rush/" class="game-card rush" data-name="rush" data-category="platform">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="rush"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Speedrun</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">RUSH</div><div class="card-tag">Speedrun / Platform</div></div>
                    <span class="card-best" id="best-rush"></span>
                </div>
            </a>

            <a href="drop/" class="game-card drop" data-name="drop" data-category="action">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="drop"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Survival</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">DROP</div><div class="card-tag">Survival / Speed</div></div>
                    <span class="card-best" id="best-drop"></span>
                </div>
            </a>

            <a href="hexfall/" class="game-card hexfall" data-name="hexfall" data-category="action arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="hexfall"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Precision</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">HEXFALL</div><div class="card-tag">Survival / Precision</div></div>
                    <span class="card-best" id="best-hexfall"></span>
                </div>
            </a>

            <a href="beat/" class="game-card beat" data-name="beat" data-category="rhythm arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="beat"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Rhythm</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">BEAT</div><div class="card-tag">Rhythm / Keyboard</div></div>
                    <span class="card-best" id="best-beat"></span>
                </div>
            </a>

            <a href="volley/" class="game-card volley" data-name="volley" data-category="arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="volley"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Arcade</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">VOLLEY</div><div class="card-tag">Arcade / Versus</div></div>
                    <span class="card-best" id="best-volley"></span>
                </div>
            </a>

            <a href="territory/" class="game-card territory" data-name="territory" data-category="popular action arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="territory"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Territory</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">TERRITORY</div><div class="card-tag">Territory / Multiplayer</div></div>
                    <span class="card-best" id="best-territory"></span>
                </div>
            </a>

            <a href="impostor/" class="game-card impostor" data-name="impostor" data-category="popular arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="impostor"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Party</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">IMPOSTOR</div><div class="card-tag">Online Multiplayer</div></div>
                    <span class="card-best" id="best-impostor"></span>
                </div>
            </a>

            <a href="maze/" class="game-card maze" data-name="maze" data-category="action arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="maze"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Maze</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">MAZE</div><div class="card-tag">Maze / Survival</div></div>
                    <span class="card-best" id="best-maze"></span>
                </div>
            </a>

            <a href="chain/" class="game-card chain" data-name="chain" data-category="action arcade">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="chain"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Physics</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">CHAIN</div><div class="card-tag">Physics / Co-op</div></div>
                    <span class="card-best" id="best-chain"></span>
                </div>
            </a>
            <a href="pop/" class="game-card pop" data-name="pop" data-category="strategy tower defense">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="pop"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Strategy</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">POP</div><div class="card-tag">Tower Defense</div></div>
                    <span class="card-best" id="best-pop"></span>
                </div>
            </a>
            <a href="farm/" class="game-card farm" data-name="farm" data-category="tycoon idle">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="farm"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Tycoon</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">FARM</div><div class="card-tag">Tycoon / Idle</div></div>
                    <span class="card-best" id="best-farm"></span>
                </div>
            </a>
            <a href="cafe/" class="game-card cafe" data-name="cafe" data-category="tycoon idle">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="cafe"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Tycoon</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">CAF�</div><div class="card-tag">Tycoon / Idle</div></div>
                    <span class="card-best" id="best-cafe"></span>
                </div>
            </a>
            <a href="arena/" class="game-card arena" data-name="arena" data-category="popular strategy">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="arena"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Strategy</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">ARENA</div><div class="card-tag">Chess + Card arena</div></div>
                    <span class="card-best" id="best-arena"></span>
                </div>
            </a>
            <a href="nebula/" class="game-card nebula" data-name="nebula" data-category="arcade action">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="nebula"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Spaceship</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">NEBULA</div><div class="card-tag">Asteroids / Flash hunt</div></div>
                    <span class="card-best" id="best-nebula"></span>
                </div>
            </a>
            <a href="aster/" class="game-card aster" data-name="aster" data-category="arcade multiplayer"><div class="preview-wrap"><canvas class="preview-canvas" data-preview="aster"></canvas><div class="preview-overlay"></div></div><div class="card-badge">1v1</div><div class="card-play"></div><div class="card-info"><div><div class="card-title">ASTER</div><div class="card-tag">Asteroids 1v1</div></div><span class="card-best" id="best-aster"></span></div></a>
            <a href="runner/" class="game-card runner" data-name="runner" data-category="arcade reflex"><div class="preview-wrap"><canvas class="preview-canvas" data-preview="runner"></canvas><div class="preview-overlay"></div></div><div class="card-badge">Endless</div><div class="card-play"></div><div class="card-info"><div><div class="card-title">RUNNER</div><div class="card-tag">Jump</div></div><span class="card-best" id="best-runner"></span></div></a>
            <a href="swap/" class="game-card swap" data-name="swap" data-category="action reflex">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="swap"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Reflex</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">SWAP</div><div class="card-tag">Reflex / Strategy</div></div>
                    <span class="card-best" id="best-swap"></span>
                </div>
            </a>

            <a href="flick/" class="game-card flick" data-name="flick" data-category="action reflex">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="flick"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Reflex</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">FLICK</div><div class="card-tag">Reaction / Speed</div></div>
                    <span class="card-best" id="best-flick"></span>
                </div>
            </a>

            <a href="crossy/" class="game-card crossy" data-name="crossy" data-category="arcade action">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="crossy"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Arcade</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">CROSSY</div><div class="card-tag">Hop / Dodge</div></div>
                    <span class="card-best" id="best-crossy"></span>
                </div>
            </a>

            <a href="metro/" class="game-card metro" data-name="metro" data-category="popular builder">
                <div class="preview-wrap"><canvas class="preview-canvas" data-preview="metro"></canvas><div class="preview-overlay"></div></div>
                <div class="card-badge">Builder</div>
                <div class="card-play"></div>
                <div class="card-info">
                    <div><div class="card-title">METROPOLIS</div><div class="card-tag">City Builder</div></div>
                    <span class="card-best" id="best-metro"></span>
                </div>
            </a>

        </div>

        <!-- Shop Page (hidden by default) -->
        <div id="shopPage" style="display:none">
            <div style="display:flex;align-items:center;gap:12px;margin-bottom:6px;flex-wrap:wrap">
                <button onclick="closeShop()" style="background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);color:rgba(255,255,255,0.6);border-radius:8px;padding:6px 14px;font-size:12px;font-weight:700;cursor:pointer;display:flex;align-items:center;gap:6px">? Back</button>
                <h2 style="font-size:22px;font-weight:800;color:#fff;margin:0">Shop</h2>
                <div style="margin-left:auto;display:flex;align-items:center;gap:6px;background:rgba(255,215,0,0.1);border:1px solid rgba(255,215,0,0.2);border-radius:10px;padding:8px 16px">
                    <svg width="16" height="16" viewBox="0 0 24 24" style="flex-shrink:0"><defs><radialGradient id="gcShop" cx="40%" cy="35%"><stop offset="0%" stop-color="#ffe066"/><stop offset="50%" stop-color="#ffd700"/><stop offset="100%" stop-color="#b8860b"/></radialGradient></defs><circle cx="12" cy="12" r="10" fill="url(#gcShop)"/><circle cx="12" cy="12" r="6.5" fill="none" stroke="#b8860b" stroke-width="1.2" opacity=".5"/><ellipse cx="10" cy="9" rx="4" ry="3" fill="rgba(255,255,255,0.18)"/></svg>
                    <span id="shopCoins" style="color:#ffd700;font-weight:800;font-size:17px">0</span>
                </div>
            </div>
            <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 16px">Buy items to customize your profile</p>

            <!-- Category Tabs -->
            <div id="shopTabs" style="display:flex;gap:6px;margin-bottom:20px;overflow-x:auto;padding-bottom:4px">
                <button class="shop-tab active" data-tab="all" onclick="setShopTab('all')">All</button>
                <button class="shop-tab" data-tab="border" onclick="setShopTab('border')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.1em"><rect x="3" y="3" width="18" height="18" rx="2"/><rect x="7" y="7" width="10" height="10" rx="1"/></svg> Borders</button>
                <button class="shop-tab" data-tab="title" onclick="setShopTab('title')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.1em"><path d="M20.6 11.5L11.5 2.5a2 2 0 00-1.4-.6H4a2 2 0 00-2 2v6.1c0 .5.2 1 .6 1.4l9 9a2 2 0 002.8 0l6.2-6.2a2 2 0 000-2.7z"/><circle cx="7.5" cy="7.5" r="1.5" fill="currentColor"/></svg> Titles</button>
                <button class="shop-tab" data-tab="nameColor" onclick="setShopTab('nameColor')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.1em"><circle cx="12" cy="12" r="10"/><circle cx="8" cy="9" r="1.5" fill="#ff44aa" stroke="none"/><circle cx="12" cy="7" r="1.5" fill="#44ddff" stroke="none"/><circle cx="16" cy="9" r="1.5" fill="#ffd700" stroke="none"/><circle cx="9" cy="15" r="1.5" fill="#44ff88" stroke="none"/></svg> Colors</button>
                <button class="shop-tab" data-tab="badge" onclick="setShopTab('badge')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.1em"><circle cx="12" cy="8" r="6"/><path d="M8.2 13L7 22l5-3 5 3-1.2-9"/></svg> Badges</button>
                <button class="shop-tab" data-tab="chest" onclick="setShopTab('chest')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.1em"><rect x="3" y="8" width="18" height="13" rx="2"/><path d="M12 8v13M3 12h18"/><path d="M7 8V6a5 5 0 0110 0v2"/></svg> Chests</button>
                <button class="shop-tab" data-tab="rebirth" onclick="setShopTab('rebirth')" style="color:#fde047" title="Rebirth - reset coins for permanent perks"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.1em"><path d="M21 12a9 9 0 11-3-6.7"/><path d="M21 4v5h-5"/></svg> Rebirth</button>
            </div>

            <!-- Daily Wheel Section -->
            <div id="wheelSection" style="margin-bottom:28px">
                <div class="wheel-container">
                    <h3 style="margin:0 0 4px;font-size:16px;color:#fff;font-weight:800"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.15em"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3"/><path d="M12 2v7M12 15v7M2 12h7M15 12h7"/></svg> Daily Wheel</h3>
                    <p style="margin:0 0 12px;font-size:11px;color:rgba(255,255,255,0.35)">Spin once every 24 hours - free!</p>
                    <div class="wheel-canvas-wrap">
                        <div class="wheel-pointer">?</div>
                        <canvas id="wheelCanvas" width="260" height="260"></canvas>
                    </div>
                    <div><button class="wheel-spin-btn" id="wheelSpinBtn" onclick="spinWheelUI()">SPIN!</button></div>
                    <div class="wheel-cooldown" id="wheelCooldown"></div>
                </div>
            </div>

            <!-- Shop Layout: Preview + Items -->
            <div style="display:flex;gap:24px;align-items:flex-start">
                <!-- Live Preview -->
                <div id="shopPreview" style="width:220px;flex-shrink:0;position:sticky;top:80px">
                    <div style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:20px">
                        <div style="font-size:10px;font-weight:700;letter-spacing:1.5px;color:rgba(255,255,255,0.3);text-transform:uppercase;margin-bottom:12px;text-align:center">Preview</div>
                        <div id="shopPreviewCard" style="background:rgba(255,255,255,0.03);border:2px solid rgba(255,255,255,0.1);border-radius:14px;padding:24px 16px;text-align:center;transition:all .3s">
                            <div id="shopPreviewBadge" style="font-size:36px;margin-bottom:8px">??</div>
                            <div id="shopPreviewName" style="font-size:18px;font-weight:800;color:#fff;transition:color .3s">User</div>
                            <div id="shopPreviewTitle" style="font-size:10px;font-weight:700;letter-spacing:2px;color:rgba(255,255,255,0.35);text-transform:uppercase;margin-top:4px;min-height:14px"></div>
                        </div>
                        <div style="font-size:10px;color:rgba(255,255,255,0.2);margin-top:10px;text-align:center">Hover an item<br>to see a preview</div>
                    </div>
                </div>

                <!-- Items Grid -->
                <div id="shopItems" style="flex:1;display:grid;gap:10px;align-content:start"></div>
            </div>
        </div>

        <!-- Scoreboard Page (hidden by default) -->
        <div id="scoreboardPage" style="display:none">
            <div style="display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap">
                <button onclick="closeScoreboard()" style="background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);color:rgba(255,255,255,0.6);border-radius:8px;padding:6px 14px;font-size:12px;font-weight:700;cursor:pointer;display:flex;align-items:center;gap:6px">? Back</button>
                <h2 style="font-size:22px;font-weight:800;color:#fff;margin:0"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-.15em"><path d="M8 21h8M12 17v4"/><path d="M7 4h10v5a5 5 0 01-10 0z"/><path d="M7 7H4v1a3 3 0 003 3m10-4h3v1a3 3 0 01-3 3"/></svg> Leaderboard</h2>
            </div>
            <!-- Scoreboard Tabs -->
            <div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap">
                <button class="shop-tab active" id="sbTabPersonal" onclick="switchScoreboardTab('personal')">My results</button>
                <button class="shop-tab" id="sbTabRecords" onclick="switchScoreboardTab('records')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.1em"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 010 20M12 2a15 15 0 000 20"/></svg> World records</button>
                <button class="shop-tab" id="sbTabFriends" onclick="switchScoreboardTab('friends')">?? Friends</button>
                <button class="shop-tab" id="sbTabSchool" onclick="switchScoreboardTab('school')">?? School records</button>
                <button class="shop-tab" id="sbTabCoins" onclick="switchScoreboardTab('coins')">?? Top coins</button>
            </div>
            <div id="scoreboardPersonal">
                <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 20px">Your best results across all games</p>
                <div id="scoreboardTitle" style="text-align:center;margin-bottom:16px;font-size:14px;font-weight:800;color:#fbbf24;min-height:20px"></div>
                <div id="scoreboardGrid" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px"></div>
            </div>
            <div id="scoreboardRecords" style="display:none">
                <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 20px">The best players from around the world</p>
                <div id="recordsLoading" style="text-align:center;padding:40px;color:rgba(255,255,255,0.3)">Loading world records�</div>
                <div id="recordsGrid" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px"></div>
            </div>
            <div id="scoreboardSchool" style="display:none">
                <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 12px">Which school has the most records?</p>
                <div id="schoolLeaderboard" style="display:flex;flex-direction:column;gap:8px"></div>
                <p style="color:rgba(255,255,255,0.25);font-size:11px;margin-top:16px">Set your school in your profile to represent!</p>
            </div>
            <div id="scoreboardCoins" style="display:none">
                <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 12px">Who has the most coins?</p>
                <div id="coinsLeaderboard" style="display:flex;flex-direction:column;gap:8px"></div>
            </div>
            <div id="scoreboardFriends" style="display:none">
                <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 12px">Add friends by username to see their scores side by side.</p>
                <div style="display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap">
                    <input id="friendInput" placeholder="Friend's username..." maxlength="32"
                        style="flex:1;min-width:180px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.1);color:#fff;border-radius:8px;padding:9px 14px;font-size:13px;outline:none">
                    <button onclick="addFriendFromInput()" style="background:linear-gradient(135deg,#6366f1,#8b5cf6);border:none;color:#fff;padding:9px 18px;border-radius:8px;font-weight:800;font-size:12px;letter-spacing:1px;cursor:pointer">+ ADD</button>
                </div>
                <div id="friendsList" style="display:flex;flex-direction:column;gap:8px;margin-bottom:18px"></div>
                <h3 style="font-size:13px;font-weight:800;letter-spacing:2px;color:rgba(255,255,255,0.5);margin:18px 0 10px">FRIENDS LEADERBOARD</h3>
                <div id="friendsLoading" style="text-align:center;padding:30px;color:rgba(255,255,255,0.3);display:none">Loading friends' scores�</div>
                <div id="friendsLeaderboard" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px"></div>
            </div>
        </div>

        <!-- Casino Page (hidden by default) -->
        <div id="casinoPage" style="display:none">
            <div style="display:flex;align-items:center;gap:12px;margin-bottom:6px;flex-wrap:wrap">
                <button onclick="closeCasino()" style="background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);color:rgba(255,255,255,0.6);border-radius:8px;padding:6px 14px;font-size:12px;font-weight:700;cursor:pointer;display:flex;align-items:center;gap:6px">? Back</button>
                <h2 style="font-size:22px;font-weight:800;color:#fff;margin:0"><svg width="24" height="24" viewBox="0 0 24 24" style="vertical-align:-.18em"><defs><radialGradient id="gcCasinoChip" cx="50%" cy="40%"><stop offset="0%" stop-color="#fde68a"/><stop offset="55%" stop-color="#fbbf24"/><stop offset="100%" stop-color="#92400e"/></radialGradient></defs><circle cx="12" cy="12" r="10.5" fill="url(#gcCasinoChip)" stroke="#78350f" stroke-width="0.6"/><circle cx="12" cy="12" r="6" fill="#1c1917"/><path d="M12 4l1 2.5h2.5L13.5 8l1 2.5L12 9l-2.5 1.5 1-2.5L8 6.5h2.5z" fill="#fbbf24"/><path d="M12 1.5v2M22.5 12h-2M12 22.5v-2M1.5 12h2" stroke="#78350f" stroke-width="2" stroke-linecap="round"/><path d="M19 5l-1.4 1.4M19 19l-1.4-1.4M5 19l1.4-1.4M5 5l1.4 1.4" stroke="#78350f" stroke-width="2" stroke-linecap="round"/></svg> Casino</h2>
                <div style="margin-left:auto;display:flex;align-items:center;gap:6px;background:rgba(255,215,0,0.1);border:1px solid rgba(255,215,0,0.2);border-radius:10px;padding:8px 16px">
                    <svg width="16" height="16" viewBox="0 0 24 24" style="flex-shrink:0"><defs><radialGradient id="gcCasino" cx="40%" cy="35%"><stop offset="0%" stop-color="#ffe066"/><stop offset="50%" stop-color="#ffd700"/><stop offset="100%" stop-color="#b8860b"/></radialGradient></defs><circle cx="12" cy="12" r="10" fill="url(#gcCasino)"/><circle cx="12" cy="12" r="6.5" fill="none" stroke="#b8860b" stroke-width="1.2" opacity=".5"/><ellipse cx="10" cy="9" rx="4" ry="3" fill="rgba(255,255,255,0.18)"/></svg>
                    <span id="casinoCoins" style="color:#ffd700;font-weight:800;font-size:17px">0</span>
                </div>
            </div>
            <p style="color:rgba(255,255,255,0.4);font-size:12px;margin:0 0 20px">Bet your coins - win or lose!</p>

            <!-- Casino Games Grid -->
            <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px">

                <!-- Coinflip -->
                <div id="coinflipCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24"><defs><radialGradient id="gcFlip" cx="40%" cy="35%"><stop offset="0%" stop-color="#ffe066"/><stop offset="50%" stop-color="#ffd700"/><stop offset="100%" stop-color="#b8860b"/></radialGradient></defs><circle cx="12" cy="12" r="10" fill="url(#gcFlip)"/><circle cx="12" cy="12" r="6.5" fill="none" stroke="#b8860b" stroke-width="1.2" opacity=".5"/><ellipse cx="10" cy="9" rx="4" ry="3" fill="rgba(255,255,255,0.18)"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Coinflip</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 16px">50/50 chance - double or nothing</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="cfBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                    </div>
                    <div style="display:flex;gap:8px">
                        <button class="casino-btn" onclick="playCoinflip('heads')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-.15em"><path d="M2 20h20L19 8l-5 5-2-8-2 8-5-5z"/></svg> Heads</button>
                        <button class="casino-btn" onclick="playCoinflip('tails')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M4 9h16M4 15h16M10 3l-2 18M16 3l-2 18"/></svg> Tails</button>
                    </div>
                    <div id="cfResult" style="margin-top:12px;font-size:14px;font-weight:700;min-height:20px"></div>
                </div>

                <!-- Mines -->
                <div id="minesCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="13" r="8"/><path d="M15.5 5.5l2-4M17.5 1.5l1.5 1.5"/><path d="M14.2 7.8l1.3-2.3"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Mines</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 16px">Reveal tiles without hitting mines. Cash out when you want!</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:8px">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="minesBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Mines:</span>
                        <select id="minesCount" style="background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 8px;border-radius:8px;font-size:12px">
                            <option value="3">3</option><option value="5" selected>5</option><option value="8">8</option><option value="12">12</option>
                        </select>
                    </div>
                    <div style="display:flex;gap:6px;flex-wrap:wrap">
                        <button class="casino-btn" id="minesStartBtn" onclick="startMines()">SOLO</button>
                        <button class="casino-btn" id="minesMultiBtn" onclick="startMinesMulti()" style="background:linear-gradient(135deg,#6366f1,#4f46e5)">?? MULTIPLAYER</button>
                    </div>
                    <button class="casino-btn casino-btn-green" id="minesCashBtn" onclick="cashOutMines()" style="display:none">CASH OUT</button>
                    <div id="minesGrid" style="display:grid;grid-template-columns:repeat(5,1fr);gap:4px;margin-top:12px"></div>
                    <div id="minesMulti" style="margin-top:8px;font-size:13px;color:#fbbf24;font-weight:700;min-height:18px"></div>
                    <div id="minesMultiConfirm" style="display:none;margin-top:8px"><button class="casino-btn" onclick="confirmMinesPlacement()" style="background:linear-gradient(135deg,#16a34a,#15803d)">? CONFIRM PLACEMENT</button></div>
                </div>

                <!-- Tower -->
                <div id="towerCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#818cf8" stroke-width="2" stroke-linecap="round"><path d="M6 22V4l6-2 6 2v18"/><path d="M6 10h12M6 16h12"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Tower</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 16px">Climb upward - pick the right door on each floor!</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="towerBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                    </div>
                    <button class="casino-btn" id="towerStartBtn" onclick="startTower()">START</button>
                    <button class="casino-btn casino-btn-green" id="towerCashBtn" onclick="cashOutTower()" style="display:none">CASH OUT</button>
                    <div id="towerGrid" style="margin-top:12px"></div>
                    <div id="towerMulti" style="margin-top:8px;font-size:13px;color:#fbbf24;font-weight:700;min-height:18px"></div>
                </div>

                <!-- Chicken Road -->
                <div id="chickenCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M14 7l3-1M11 11c-3 1-5 4-5 8h12c0-4-2-7-5-8"/><circle cx="13" cy="7.5" r=".7" fill="#fbbf24"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Chicken Road</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 12px">Cross the road, lane by lane. Each safe lane raises your multi - cars hide in some!</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:8px;flex-wrap:wrap">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="crBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5);margin-left:6px">Risk:</span>
                        <select id="crDifficulty" style="background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 8px;border-radius:8px;font-size:12px;font-weight:700">
                            <option value="easy">Easy (1/8)</option>
                            <option value="medium" selected>Medium (2/8)</option>
                            <option value="hard">Hard (3/8)</option>
                            <option value="daredevil">Daredevil (4/8)</option>
                        </select>
                    </div>
                    <button class="casino-btn" id="crStartBtn" onclick="startChicken()">START</button>
                    <button class="casino-btn casino-btn-green" id="crCashBtn" onclick="cashOutChicken()" style="display:none">CASH OUT</button>
                    <div id="crBoard" style="margin-top:12px"></div>
                    <div id="crMulti" style="margin-top:8px;font-size:13px;color:#fbbf24;font-weight:700;min-height:18px"></div>
                </div>

                <!-- Roulette -->
                <div id="rouletteCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="5"/><path d="M12 2v4M12 18v4M2 12h4M18 12h4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Roulette</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 16px">Bet on color, number or row - spin the wheel!</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:8px;flex-wrap:wrap">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="rouletteBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                    </div>
                    <div style="margin-bottom:10px">
                        <span style="font-size:11px;color:rgba(255,255,255,0.4);display:block;margin-bottom:6px">Pick a bet:</span>
                        <div style="display:flex;gap:6px;flex-wrap:wrap" id="rouletteBets">
                            <button class="casino-btn" style="background:linear-gradient(135deg,#dc2626,#b91c1c);font-size:11px;padding:6px 12px" onclick="spinRoulette('red')">?? Red (2x)</button>
                            <button class="casino-btn" style="background:linear-gradient(135deg,#1a1a2e,#111);font-size:11px;padding:6px 12px" onclick="spinRoulette('black')">? Black (2x)</button>
                            <button class="casino-btn" style="background:linear-gradient(135deg,#16a34a,#15803d);font-size:11px;padding:6px 12px" onclick="spinRoulette('green')">?? Green (14x)</button>
                            <button class="casino-btn" style="background:linear-gradient(135deg,#6366f1,#4f46e5);font-size:11px;padding:6px 12px" onclick="spinRoulette('1st12')">1-12 (3x)</button>
                            <button class="casino-btn" style="background:linear-gradient(135deg,#6366f1,#4f46e5);font-size:11px;padding:6px 12px" onclick="spinRoulette('2nd12')">13-24 (3x)</button>
                            <button class="casino-btn" style="background:linear-gradient(135deg,#6366f1,#4f46e5);font-size:11px;padding:6px 12px" onclick="spinRoulette('3rd12')">25-36 (3x)</button>
                        </div>
                    </div>
                    <div style="margin:12px 0;text-align:center"><canvas id="rouletteCanvas" width="260" height="260" style="max-width:100%;border-radius:50%"></canvas></div>
                    <div id="rouletteResult" style="font-size:14px;font-weight:700;min-height:20px;text-align:center"></div>
                </div>

                <!-- Dice -->
                <div id="diceCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="3"/><circle cx="8" cy="8" r="1" fill="#fbbf24"/><circle cx="16" cy="8" r="1" fill="#fbbf24"/><circle cx="8" cy="16" r="1" fill="#fbbf24"/><circle cx="16" cy="16" r="1" fill="#fbbf24"/><circle cx="12" cy="12" r="1" fill="#fbbf24"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Dice</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 16px">Roll 1-100. Bet over or under your target.</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:8px;flex-wrap:wrap">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="diceBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Target:</span>
                        <input type="number" id="diceTarget" min="2" max="98" value="50" style="width:60px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                    </div>
                    <div id="diceMultis" style="display:flex;gap:10px;font-size:11px;color:rgba(255,255,255,0.5);margin-bottom:10px">
                        <span>Under <b id="diceUnderMulti" style="color:#4ade80">1.98x</b></span>
                        <span>Over <b id="diceOverMulti" style="color:#4ade80">1.98x</b></span>
                    </div>
                    <div style="display:flex;gap:8px">
                        <button class="casino-btn" onclick="rollDice('under')">ROLL UNDER</button>
                        <button class="casino-btn" onclick="rollDice('over')">ROLL OVER</button>
                    </div>
                    <div id="diceRollNum" style="margin-top:12px;font-size:32px;font-weight:900;color:#fbbf24;text-align:center;min-height:42px;font-variant-numeric:tabular-nums"></div>
                    <div id="diceResult" style="font-size:14px;font-weight:700;min-height:20px;text-align:center"></div>
                </div>

                <!-- Slots -->
                <div id="slotsCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px">
                    <div style="font-size:28px;margin-bottom:8px"><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#a855f7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M9 5v14M15 5v14"/><circle cx="6" cy="12" r="1.5" fill="#a855f7"/><circle cx="12" cy="12" r="1.5" fill="#a855f7"/><circle cx="18" cy="12" r="1.5" fill="#a855f7"/></svg></div>
                    <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0 0 4px">Slots</h3>
                    <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0 0 16px">Match 3 symbols! Bigger wins for rarer matches.</p>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:12px">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="slotsBet" min="10" value="10" style="width:80px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                    </div>
                    <div id="slotsReels" style="display:flex;gap:8px;justify-content:center;background:rgba(0,0,0,0.4);border:1px solid rgba(255,255,255,0.08);border-radius:12px;padding:14px;margin-bottom:12px">
                        <div class="slot-reel" id="slotReel0" style="width:64px;height:64px;display:flex;align-items:center;justify-content:center;font-size:42px;background:rgba(255,255,255,0.04);border-radius:8px">??</div>
                        <div class="slot-reel" id="slotReel1" style="width:64px;height:64px;display:flex;align-items:center;justify-content:center;font-size:42px;background:rgba(255,255,255,0.04);border-radius:8px">??</div>
                        <div class="slot-reel" id="slotReel2" style="width:64px;height:64px;display:flex;align-items:center;justify-content:center;font-size:42px;background:rgba(255,255,255,0.04);border-radius:8px">??</div>
                    </div>
                    <button class="casino-btn" id="slotsSpinBtn" onclick="spinSlots()" style="width:100%;background:linear-gradient(135deg,#a855f7,#7c3aed)">SPIN</button>
                    <div id="slotsResult" style="margin-top:10px;font-size:14px;font-weight:700;min-height:20px;text-align:center"></div>
                    <div style="margin-top:6px;font-size:10px;color:rgba(255,255,255,0.3);text-align:center">3x??=50x � 3x?=20x � 3x??=10x � 3x same=5x � 2 match=1.5x</div>
                </div>

                <!-- Blackjack -->
                <div id="blackjackCard" style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:16px;padding:24px;grid-column:span 2">
                    <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px">
                        <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#f87171" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="13" height="18" rx="2"/><rect x="7" y="6" width="13" height="15" rx="2" fill="rgba(248,113,113,0.15)"/><path d="M13.5 11l-2 3 2 3 2-3z"/></svg>
                        <div style="flex:1">
                            <h3 style="color:#fff;font-size:16px;font-weight:800;margin:0">Blackjack</h3>
                            <p style="font-size:11px;color:rgba(255,255,255,0.35);margin:0">Beat the dealer to 21. Double, Split, Insure, Surrender � full table rules.</p>
                        </div>
                        <div style="font-size:10px;color:rgba(255,255,255,0.4);text-align:right;line-height:1.3">
                            <div>BJ pays <b style="color:#fbbf24">3:2</b></div>
                            <div>Insurance <b>2:1</b></div>
                            <div>Dealer hits soft 17</div>
                        </div>
                    </div>
                    <div style="display:flex;gap:8px;align-items:center;margin-bottom:12px;flex-wrap:wrap">
                        <span style="font-size:12px;color:rgba(255,255,255,0.5)">Bet:</span>
                        <input type="number" id="bjBet" min="10" value="50" style="width:90px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:6px 10px;border-radius:8px;font-size:13px;font-weight:700;text-align:center">
                        <button class="casino-btn" onclick="bjBetMod(0.5)" style="padding:4px 10px;font-size:11px;background:rgba(255,255,255,0.06)">�</button>
                        <button class="casino-btn" onclick="bjBetMod(2)" style="padding:4px 10px;font-size:11px;background:rgba(255,255,255,0.06)">2�</button>
                        <button class="casino-btn" onclick="bjBetMax()" style="padding:4px 10px;font-size:11px;background:rgba(255,255,255,0.06)">MAX</button>
                    </div>
                    <div id="bjBoard" style="display:none;background:linear-gradient(180deg,rgba(34,84,52,0.4),rgba(20,50,32,0.4));border:1px solid rgba(34,197,94,0.18);border-radius:14px;padding:16px;margin-bottom:10px">
                        <div style="font-size:10px;letter-spacing:1.5px;color:rgba(255,255,255,0.5);margin-bottom:6px;display:flex;justify-content:space-between"><span>DEALER</span><span id="bjDealerVal" style="color:#fff">?</span></div>
                        <div id="bjDealerCards" style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px;min-height:74px"></div>
                        <div id="bjHandsWrap" style="display:flex;flex-direction:column;gap:10px"></div>
                    </div>
                    <div id="bjButtons" style="display:flex;gap:6px;flex-wrap:wrap">
                        <button class="casino-btn" id="bjStartBtn" onclick="startBlackjack()" style="background:linear-gradient(135deg,#16a34a,#15803d)">DEAL</button>
                        <button class="casino-btn" id="bjHitBtn" onclick="hitBlackjack()" style="display:none;background:linear-gradient(135deg,#16a34a,#15803d)">HIT</button>
                        <button class="casino-btn" id="bjStandBtn" onclick="standBlackjack()" style="display:none;background:linear-gradient(135deg,#dc2626,#b91c1c)">STAND</button>
                        <button class="casino-btn" id="bjDoubleBtn" onclick="doubleBlackjack()" style="display:none;background:linear-gradient(135deg,#a855f7,#7c3aed)">DOUBLE</button>
                        <button class="casino-btn" id="bjSplitBtn" onclick="splitBlackjack()" style="display:none;background:linear-gradient(135deg,#f59e0b,#d97706)">SPLIT</button>
                        <button class="casino-btn" id="bjSurrenderBtn" onclick="surrenderBlackjack()" style="display:none;background:rgba(255,255,255,0.08);color:rgba(255,255,255,0.7)">SURRENDER</button>
                        <button class="casino-btn" id="bjInsureBtn" onclick="insureBlackjack()" style="display:none;background:linear-gradient(135deg,#0ea5e9,#0284c7)">INSURANCE</button>
                        <button class="casino-btn" id="bjDeclineInsBtn" onclick="declineInsuranceBlackjack()" style="display:none;background:rgba(255,255,255,0.08);color:rgba(255,255,255,0.7)">NO INSURANCE</button>
                    </div>
                    <div id="bjResult" style="margin-top:10px;font-size:14px;font-weight:700;min-height:20px;text-align:center"></div>
                </div>
            </div>
        </div>

        <div class="footer">Spillsenteret &copy; 2026</div>
    </main>
</div>

<!-- Chat Panel (floating) -->
<div id="chatPanel" style="position:fixed;bottom:16px;right:16px;width:340px;max-height:480px;background:#12122a;border:1px solid rgba(255,255,255,0.08);border-radius:16px;box-shadow:0 12px 40px rgba(0,0,0,0.5);z-index:200;display:none;flex-direction:column;overflow:hidden">
    <div style="padding:12px 16px;border-bottom:1px solid rgba(255,255,255,0.06);display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none" onclick="toggleChatMinimize()">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#818cf8" stroke-width="2" stroke-linecap="round"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>
        <span style="font-size:13px;font-weight:700;color:#fff;flex:1">Chat</span>
        <span id="chatOnlineCount" style="font-size:11px;color:rgba(255,255,255,0.3)">0 online</span>
        <button id="chatNotifBtn" onclick="event.stopPropagation();enableChatNotifications()" style="background:rgba(129,140,248,0.12);border:1px solid rgba(129,140,248,0.25);color:#a5b4fc;font-size:10px;font-weight:700;padding:3px 8px;border-radius:6px;cursor:pointer">?? Enable notifications</button>
        <button onclick="event.stopPropagation();closeChatPanel()" style="background:none;border:none;color:rgba(255,255,255,0.3);font-size:16px;cursor:pointer;line-height:1">&times;</button>
    </div>
    <!-- Chat Tabs -->
    <div style="display:flex;border-bottom:1px solid rgba(255,255,255,0.06)">
        <button class="chat-tab active" id="chatTabGlobal" onclick="switchChatTab('global')" style="flex:1;padding:8px;border:none;background:transparent;color:#818cf8;font-size:11px;font-weight:700;cursor:pointer;border-bottom:2px solid #818cf8">Global</button>
        <button class="chat-tab" id="chatTabDm" onclick="switchChatTab('dm')" style="flex:1;padding:8px;border:none;background:transparent;color:rgba(255,255,255,0.4);font-size:11px;font-weight:700;cursor:pointer;border-bottom:2px solid transparent">DM</button>
        <button class="chat-tab" id="chatTabOnline" onclick="switchChatTab('online')" style="flex:1;padding:8px;border:none;background:transparent;color:rgba(255,255,255,0.4);font-size:11px;font-weight:700;cursor:pointer;border-bottom:2px solid transparent">Online</button>
    </div>
    <!-- Chat Content -->
    <div id="chatContent" style="flex:1;overflow-y:auto;padding:8px 12px;max-height:300px;min-height:200px">
        <div id="chatMessages" style="display:flex;flex-direction:column;gap:4px"></div>
        <div id="chatDmView" style="display:none">
            <div id="chatDmSelect" style="padding:12px 0;font-size:12px;color:rgba(255,255,255,0.4)">Pick a player from the Online tab to send a DM</div>
            <div id="chatDmMessages" style="display:flex;flex-direction:column;gap:4px"></div>
        </div>
        <div id="chatOnlineView" style="display:none">
            <div id="guestNickBanner" style="display:none;padding:10px 12px;margin-bottom:8px;background:rgba(129,140,248,0.08);border:1px solid rgba(129,140,248,0.2);border-radius:10px">
                <div style="font-size:11px;color:#a5b4fc;font-weight:700;margin-bottom:6px">You're playing as a guest</div>
                <div style="display:flex;gap:6px">
                    <input type="text" id="guestNickInput" maxlength="20" placeholder="Choose nickname" style="flex:1;background:rgba(0,0,0,0.3);border:1px solid rgba(255,255,255,0.1);color:#fff;padding:6px 10px;border-radius:6px;font-size:12px;outline:none">
                    <button onclick="saveGuestNick()" style="background:#7c3aed;border:none;color:#fff;padding:6px 12px;border-radius:6px;font-size:11px;font-weight:700;cursor:pointer">Save</button>
                </div>
            </div>
            <div id="chatOnlineList" style="display:flex;flex-direction:column;gap:4px"></div>
        </div>
    </div>
    <!-- Chat Input -->
    <div id="chatInputWrap" style="padding:8px 12px;border-top:1px solid rgba(255,255,255,0.06);display:flex;gap:6px">
        <input type="text" id="chatInput" placeholder="Write a message..." maxlength="200" style="flex:1;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);color:#e2e8f0;padding:8px 12px;border-radius:8px;font-size:12px;outline:none">
        <button onclick="sendChatMessage()" style="background:#818cf8;border:none;color:#fff;padding:8px 14px;border-radius:8px;font-size:12px;font-weight:700;cursor:pointer">Send</button>
    </div>
</div>

<!-- Chat Toggle Button -->
<button id="chatToggle" style="position:fixed;bottom:16px;right:16px;width:48px;height:48px;border-radius:50%;background:linear-gradient(135deg,#4f46e5,#7c3aed);border:none;color:#fff;font-size:20px;cursor:pointer;box-shadow:0 4px 16px rgba(79,70,229,0.4);z-index:199;display:flex;align-items:center;justify-content:center;transition:transform .2s" onclick="openChatPanel()">
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>
</button>

<script>
// === Search filter ===
document.getElementById('searchInput').addEventListener('input',function(){
    const q=this.value.toLowerCase();
    document.querySelectorAll('.game-card').forEach(c=>{
        const name=c.dataset.name||'';
        const title=c.querySelector('.card-title')?.textContent.toLowerCase()||'';
        const tag=c.querySelector('.card-tag')?.textContent.toLowerCase()||'';
        c.style.display=(name.includes(q)||title.includes(q)||tag.includes(q))?'':'none';
    });
});

// === Sidebar category filter ===
const categoryLabels={all:'All games',popular:'Popular',action:'Action',platform:'Platform',arcade:'Arcade',racing:'Racing',rhythm:'Rhythm',builder:'Builder'};
document.querySelectorAll('.sidebar-btn[data-category]').forEach(btn=>{
    btn.addEventListener('click',()=>{
        if(btn.dataset.category==='shop'||btn.dataset.category==='scoreboard'||btn.dataset.category==='casino')return;
        closeShop();closeScoreboard();closeCasino();
        document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
        btn.classList.add('active');
        const cat=btn.dataset.category;
        document.getElementById('sectionTitle').textContent=categoryLabels[cat]||'All games';
        document.querySelectorAll('.game-card').forEach(c=>{
            if(cat==='all'){c.style.display='';return;}
            const cats=(c.dataset.category||'').split(' ');
            c.style.display=cats.includes(cat)?'':'none';
        });
        document.getElementById('searchInput').value='';
    });
});

// === High scores ===
const scores={
    fell:parseFloat(localStorage.getItem('collapse_highscore'))||0,
    dodge:parseFloat(localStorage.getItem('dodge_highscore'))||0,
    hit:parseFloat(localStorage.getItem('hit_highscore'))||0,
    rise:parseFloat(localStorage.getItem('rise_highscore'))||0,
    hexfall:parseFloat(localStorage.getItem('hexfall_highscore'))||0,
    beat:parseFloat(localStorage.getItem('beat_highscore'))||0,
    volley:parseFloat(localStorage.getItem('volley_highscore'))||0,
    dash:parseFloat(localStorage.getItem('dash_highscore'))||0,
    climb:parseFloat(localStorage.getItem('climb_highscore'))||0,
    swerve:parseFloat(localStorage.getItem('swerve_highscore'))||0,
    spin:parseFloat(localStorage.getItem('spin_highscore'))||0,
    drop:parseFloat(localStorage.getItem('drop_highscore'))||0,
    rush:parseFloat(localStorage.getItem('rush_highscore'))||0,
    territory:parseFloat(localStorage.getItem('territory_highscore'))||0,
    maze:parseFloat(localStorage.getItem('maze_highscore'))||0,
    chain:parseFloat(localStorage.getItem('chain_highscore'))||0,
    swap:parseFloat(localStorage.getItem('swap_highscore'))||0,
    flick:parseFloat(localStorage.getItem('flick_highscore'))||0,
    crossy:parseFloat(localStorage.getItem('crossy_highscore'))||0,
    pop:parseFloat(localStorage.getItem('pop_highscore'))||0,
    arena:parseInt(localStorage.getItem('arena_trophies'))||0,
    nebula:parseInt(localStorage.getItem('nebula_highscore'))||0,
    metro:parseInt(localStorage.getItem('metro_highscore'))||0,
};
if(scores.fell>0)document.getElementById('best-fell').innerHTML='Best: <span>'+scores.fell.toFixed(1)+'s<\/span>';
if(scores.dodge>0)document.getElementById('best-dodge').innerHTML='Best: <span>'+scores.dodge.toFixed(1)+'s<\/span>';
if(scores.hit>0)document.getElementById('best-hit').innerHTML='Best: <span>'+Math.round(scores.hit)+'<\/span>';
if(scores.rise>0)document.getElementById('best-rise').innerHTML='Best: <span>'+Math.round(scores.rise)+'m<\/span>';
if(scores.hexfall>0)document.getElementById('best-hexfall').innerHTML='Best: <span>'+scores.hexfall.toFixed(1)+'s<\/span>';
if(scores.beat>0)document.getElementById('best-beat').innerHTML='Best: <span>'+Math.round(scores.beat)+'<\/span>';
if(scores.volley>0)document.getElementById('best-volley').innerHTML='Best: <span>'+scores.volley+' sets<\/span>';
if(scores.dash>0)document.getElementById('best-dash').innerHTML='Best: <span>'+Math.round(scores.dash)+'m<\/span>';
if(scores.rush>0)document.getElementById('best-rush').innerHTML='Best: <span>'+scores.rush+'<\/span>';
if(scores.climb>0)document.getElementById('best-climb').innerHTML='Best: <span>'+Math.round(scores.climb)+'m<\/span>';
if(scores.swerve>0)document.getElementById('best-swerve').innerHTML='Best: <span>'+Math.round(scores.swerve)+'m<\/span>';
if(scores.spin>0)document.getElementById('best-spin').innerHTML='Best: <span>'+scores.spin.toFixed(1)+'s<\/span>';
if(scores.drop>0)document.getElementById('best-drop').innerHTML='Best: <span>'+Math.round(scores.drop)+'m<\/span>';
if(scores.territory>0)document.getElementById('best-territory').innerHTML='Best: <span>'+scores.territory+'%<\/span>';
if(scores.maze>0)document.getElementById('best-maze').innerHTML='Best: <span>'+Math.round(scores.maze)+'<\/span>';
if(scores.chain>0)document.getElementById('best-chain').innerHTML='Best: <span>'+Math.round(scores.chain)+'m<\/span>';
if(scores.swap>0)document.getElementById('best-swap').innerHTML='Best: <span>'+Math.round(scores.swap)+'<\/span>';
if(scores.flick>0)document.getElementById('best-flick').innerHTML='Best: <span>'+Math.round(scores.flick)+'<\/span>';
if(scores.crossy>0)document.getElementById('best-crossy').innerHTML='Best: <span>'+Math.round(scores.crossy)+' rows<\/span>';
if(scores.pop>0)document.getElementById('best-pop').innerHTML='Best: <span>'+Math.round(scores.pop)+'<\/span>';
if(scores.arena>0)document.getElementById('best-arena').innerHTML='Best: <span>&#9734; '+scores.arena+'<\/span>';
if(scores.nebula>0)document.getElementById('best-nebula').innerHTML='Best: <span>'+Math.round(scores.nebula)+'<\/span>';
if(scores.metro>0)document.getElementById('best-metro').innerHTML='Best: <span>'+scores.metro.toLocaleString()+' pop<\/span>';

// === Preview animations (enhanced) ===
const previews=document.querySelectorAll('.preview-canvas'),pCtxs=[];
previews.forEach(c=>{
    const r=c.parentElement.getBoundingClientRect();
    c.width=Math.round(r.width);c.height=Math.round(r.height);
    pCtxs.push({canvas:c,ctx:c.getContext('2d'),type:c.dataset.preview,t:0,visible:true});
});

// Only animate visible cards
const previewObserver=new IntersectionObserver(entries=>{
    entries.forEach(e=>{
        const p=pCtxs.find(p=>p.canvas===e.target);
        if(p)p.visible=e.isIntersecting;
    });
},{threshold:0});
previews.forEach(c=>previewObserver.observe(c));

function animPreviews(now){
    const t=now/1000;
    for(const p of pCtxs){
        if(!p.visible)continue;
        const c=p.canvas,x=p.ctx,w=c.width,h=c.height;

        if(p.type==='fell'){
            // Dark cavern with collapsing grid tiles and glowing player
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#0e0a06');bg.addColorStop(1,'#1a1208');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            const cols=14,rows=7,tw=w/cols,th=h/rows;
            for(let r=0;r<rows;r++)for(let c2=0;c2<cols;c2++){
                const seed=(r*cols+c2)*17.3+t*.7;
                const gone=Math.sin(seed)>.65;
                const falling=Math.sin(seed+1)>.8;
                if(gone)continue;
                const yOff=falling?Math.pow(Math.max(0,Math.sin(seed*2)),2)*40:0;
                const alpha=falling?.3:.7;
                x.fillStyle=falling?`rgba(60,35,15,${alpha})`:`rgba(75,60,45,${alpha})`;
                x.beginPath();
                x.roundRect(c2*tw+1.5,r*th+1.5+yOff,tw-3,th-3,2);
                x.fill();
                if(!falling){x.fillStyle='rgba(100,80,60,0.3)';x.fillRect(c2*tw+2,r*th+2,tw-4,2);}
            }
            // Falling dust particles
            for(let i=0;i<8;i++){
                const dx=((i*73+t*30)%w),dy=((i*51+t*45)%h);
                x.fillStyle='rgba(180,150,100,0.15)';x.beginPath();x.arc(dx,dy,1.5,0,Math.PI*2);x.fill();
            }
            // Gems with glow
            for(let i=0;i<3;i++){
                const gx=w*(.2+i*.3)+Math.sin(t+i*2)*15,gy=h*(.3+i*.15)+Math.cos(t*1.2+i)*8;
                const gc=['#44ddff','#44ff88','#ffd700'][i];
                x.fillStyle=gc+'44';x.beginPath();x.arc(gx,gy,8,0,Math.PI*2);x.fill();
                x.fillStyle=gc+'88';x.beginPath();
                x.save();x.translate(gx,gy);x.rotate(t*2+i);
                x.moveTo(0,-5);x.lineTo(4,0);x.lineTo(0,5);x.lineTo(-4,0);x.closePath();
                x.fill();x.restore();
            }
            const px=w*.5+Math.sin(t*1.3)*w*.2,py=h*.45+Math.cos(t*1.7)*h*.15;
            x.shadowColor='#88ddff';x.shadowBlur=16;
            x.fillStyle='#aaeeff';x.beginPath();x.arc(px,py,5,0,Math.PI*2);x.fill();
            x.shadowBlur=0;
            x.fillStyle='rgba(136,221,255,0.1)';x.beginPath();x.arc(px,py,22,0,Math.PI*2);x.fill();
            // Spotlight from player
            const grad=x.createRadialGradient(px,py,0,px,py,w*.25);
            grad.addColorStop(0,'rgba(136,221,255,0.06)');grad.addColorStop(1,'transparent');
            x.fillStyle=grad;x.fillRect(0,0,w,h);

        }else if(p.type==='dodge'){
            // Bullet hell with grid, glowing projectiles, slow-mo ring
            const bg=x.createRadialGradient(w/2,h/2,0,w/2,h/2,w*.6);
            bg.addColorStop(0,'#0a0a18');bg.addColorStop(1,'#050510');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            x.globalAlpha=.04;x.strokeStyle='#8888ff';x.lineWidth=.5;
            for(let g=0;g<w;g+=25){x.beginPath();x.moveTo(g,0);x.lineTo(g,h);x.stroke();}
            for(let g=0;g<h;g+=25){x.beginPath();x.moveTo(0,g);x.lineTo(w,g);x.stroke();}
            x.globalAlpha=1;
            const colors=['#ff5544','#ff5544','#ffaa22','#ffaa22','#44ddff','#44ddff','#ff44aa','#ff44aa','#44ff88','#ff6644'];
            for(let i=0;i<12;i++){
                const bx=((i*97+t*65*(1+i*.2))%(w+40))-20;
                const by=h*.1+i*(h*.07)+Math.sin(t*2.5+i*1.3)*12;
                const ci=i%colors.length;
                x.shadowColor=colors[ci];x.shadowBlur=10;
                x.fillStyle=colors[ci];x.beginPath();x.arc(bx,by,3.5,0,Math.PI*2);x.fill();
                // Longer trail
                x.globalAlpha=.2;x.beginPath();x.arc(bx-8,by,2.5,0,Math.PI*2);x.fill();
                x.globalAlpha=.1;x.beginPath();x.arc(bx-14,by,2,0,Math.PI*2);x.fill();
                x.globalAlpha=.05;x.beginPath();x.arc(bx-20,by,1.5,0,Math.PI*2);x.fill();
                x.globalAlpha=1;x.shadowBlur=0;
            }
            const dpx=w*.42+Math.sin(t*1.5)*w*.18,dpy=h*.52+Math.cos(t*2)*h*.18;
            x.shadowColor='#fff';x.shadowBlur=14;
            x.fillStyle='#fff';x.beginPath();x.arc(dpx,dpy,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            // Slow-mo ring with pulsing
            const ringR=18+Math.sin(t*3)*4;
            x.strokeStyle='rgba(100,150,255,0.2)';x.lineWidth=2;
            x.beginPath();x.arc(dpx,dpy,ringR,0,Math.PI*2);x.stroke();
            x.strokeStyle='rgba(100,150,255,0.08)';x.lineWidth=1;
            x.beginPath();x.arc(dpx,dpy,ringR+6,0,Math.PI*2);x.stroke();
            // Danger zone flash
            if(Math.sin(t*4)>.8){
                x.fillStyle='rgba(255,50,50,0.03)';x.fillRect(0,0,w,h);
            }

        }else if(p.type==='hit'){
            // Aim trainer with crosshair and flying targets
            const bg=x.createRadialGradient(w/2,h/2,0,w/2,h/2,w*.6);
            bg.addColorStop(0,'#0c0c1a');bg.addColorStop(1,'#060610');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            for(let i=0;i<6;i++){
                const tx=w*.1+((i*163+t*45)%(w*.85)),ty=h*.15+i*(h*.12)+Math.sin(t*1.1+i*2.5)*15;
                const tr=7+i*1.2;const vis=Math.sin(t*.8+i*3.2)>-.2;if(!vis)continue;
                const isGold=i===2;
                x.shadowColor=isGold?'#ffd700':'#ff3355';x.shadowBlur=8;
                x.fillStyle=isGold?'#ffd700':'#ff3355';x.globalAlpha=.85;
                x.beginPath();x.arc(tx,ty,tr,0,Math.PI*2);x.fill();
                x.strokeStyle='rgba(255,255,255,0.4)';x.lineWidth=1.5;x.stroke();
                x.globalAlpha=1;x.shadowBlur=0;
            }
            const chx=w*.5+Math.sin(t*1.4)*w*.25,chy=h*.5+Math.cos(t*1.8)*h*.25;
            x.strokeStyle='rgba(255,255,255,0.5)';x.lineWidth=1;
            x.beginPath();x.arc(chx,chy,8,0,Math.PI*2);x.stroke();
            x.beginPath();x.moveTo(chx-14,chy);x.lineTo(chx-4,chy);x.stroke();
            x.beginPath();x.moveTo(chx+4,chy);x.lineTo(chx+14,chy);x.stroke();
            x.beginPath();x.moveTo(chx,chy-14);x.lineTo(chx,chy-4);x.stroke();
            x.beginPath();x.moveTo(chx,chy+4);x.lineTo(chx,chy+14);x.stroke();

        }else if(p.type==='rise'){
            // Rising cavern with crumbling platforms
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#22180e');bg.addColorStop(1,'#0e0a06');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Walls with texture
            x.fillStyle='rgba(50,38,28,0.6)';
            for(let i=0;i<9;i++){const wy=i*h/8-((t*18)%(h/8));
                x.fillRect(0,wy,10+Math.sin(i*2.7)*6,h/8);
                x.fillRect(w-10-Math.sin(i*2.7+1)*6,wy,10+Math.sin(i*2.7+1)*6,h/8);}
            // Wall glow
            x.fillStyle='rgba(180,130,60,0.04)';x.fillRect(0,0,14,h);x.fillRect(w-14,0,14,h);
            // Platforms with crack details
            for(let i=0;i<6;i++){
                const py3=h*.85-i*(h*.14)-((t*16)%(h*.14)),pw=35+i*6;
                const plx=w*.2+Math.sin(i*2.2)*w*.25;
                const crack=Math.sin(t*2+i*4)>.7;
                x.fillStyle=crack?'rgba(90,70,45,0.4)':'rgba(140,110,70,0.7)';
                x.shadowColor=crack?'transparent':'rgba(140,110,70,0.2)';x.shadowBlur=crack?0:4;
                x.beginPath();x.roundRect(plx,py3,pw,5,2);x.fill();x.shadowBlur=0;
                x.fillStyle='rgba(160,130,90,0.4)';x.fillRect(plx,py3,pw,2);
                // Crack lines
                if(crack){x.strokeStyle='rgba(60,45,25,0.5)';x.lineWidth=0.8;
                    x.beginPath();x.moveTo(plx+pw*.3,py3);x.lineTo(plx+pw*.5,py3+5);x.stroke();}
            }
            // Dust particles rising
            for(let i=0;i<6;i++){
                const dx=w*.15+((i*71)%(w*.7)),dy=h-((t*25+i*60)%h);
                x.fillStyle=`rgba(180,150,100,${0.08+Math.sin(t+i)*0.04})`;
                x.beginPath();x.arc(dx,dy,1,0,Math.PI*2);x.fill();
            }
            const rpx=w*.45+Math.sin(t*1.8)*w*.12,rpy=h*.3+Math.abs(Math.sin(t*3))*(-22);
            x.shadowColor='#cc9955';x.shadowBlur=14;
            x.fillStyle='#ddaa66';x.beginPath();x.arc(rpx,rpy,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            // Player trail
            x.fillStyle='rgba(220,170,100,0.1)';x.beginPath();x.arc(rpx,rpy+8,4,0,Math.PI*2);x.fill();
            x.fillStyle='rgba(220,170,100,0.05)';x.beginPath();x.arc(rpx,rpy+14,3,0,Math.PI*2);x.fill();

        }else if(p.type==='hexfall'){
            // Hex grid with collapsing tiles
            const bg=x.createRadialGradient(w/2,h/2,0,w/2,h/2,w*.6);
            bg.addColorStop(0,'#0c0c20');bg.addColorStop(1,'#060612');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            const HR=10;
            for(let q=-5;q<=5;q++)for(let r=-4;r<=4;r++){
                if(Math.abs(q)+Math.abs(r)+Math.abs(-q-r)>8)continue;
                const hx=w*.5+HR*(1.5*q),hy=h*.5+(HR*(Math.sqrt(3)/2*q+Math.sqrt(3)*r))*.55;
                const seed=q*7+r*13;if(Math.sin(seed+t*.5)>.55)continue;
                const cracking=Math.sin(seed+t*.7+2)>.4;
                x.beginPath();for(let i=0;i<6;i++){const a=Math.PI/180*(60*i-30);
                    const method=i===0?'moveTo':'lineTo';
                    x[method](hx+HR*.85*Math.cos(a),hy+HR*.85*Math.sin(a)*.55);}x.closePath();
                x.fillStyle=cracking?'rgba(45,75,60,0.6)':'rgba(35,110,80,0.7)';x.fill();
                x.strokeStyle='rgba(100,200,150,0.1)';x.lineWidth=.5;x.stroke();
            }
            const hpx=w*.5+Math.sin(t*1.2)*w*.18,hpy=h*.45+Math.cos(t*1.5)*h*.15;
            x.shadowColor='#55ddaa';x.shadowBlur=10;
            x.fillStyle='#66eebb';x.beginPath();x.arc(hpx,hpy,5,0,Math.PI*2);x.fill();x.shadowBlur=0;

        }else if(p.type==='beat'){
            // Rhythm lanes with diamond notes falling
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#08081a');bg.addColorStop(1,'#050510');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            for(let i=0;i<3;i++){
                const lx=w*(.25+i*.25);
                x.fillStyle='rgba(255,255,255,0.02)';x.fillRect(lx-10,0,20,h);
                // Lane glow at bottom
                const lGrd=x.createLinearGradient(0,h*.7,0,h);
                lGrd.addColorStop(0,'transparent');lGrd.addColorStop(1,['rgba(255,68,170,0.05)','rgba(68,255,136,0.05)','rgba(255,170,34,0.05)'][i]);
                x.fillStyle=lGrd;x.fillRect(lx-10,0,20,h);
            }
            // Hit zone with glow
            const zoneY=h*.82;
            x.strokeStyle='rgba(255,255,255,0.2)';x.lineWidth=2;
            x.beginPath();x.moveTo(w*.12,zoneY);x.lineTo(w*.88,zoneY);x.stroke();
            const zGrd=x.createLinearGradient(0,zoneY-6,0,zoneY+6);
            zGrd.addColorStop(0,'transparent');zGrd.addColorStop(0.5,'rgba(255,255,255,0.04)');zGrd.addColorStop(1,'transparent');
            x.fillStyle=zGrd;x.fillRect(w*.12,zoneY-6,w*.76,12);
            const nc=['#ff44aa','#44ff88','#ffaa22'];
            for(let i=0;i<3;i++){
                const lx=w*(.25+i*.25);
                // Multiple notes per lane with glow
                for(let n=0;n<3;n++){
                    const ny=((t*55+i*47+n*120)%(h+30))-15;
                    x.fillStyle=nc[i];x.globalAlpha=.9;
                    x.save();x.translate(lx,ny);x.rotate(Math.PI/4);
                    x.shadowColor=nc[i];x.shadowBlur=8;
                    x.fillRect(-6,-6,12,12);x.restore();x.shadowBlur=0;
                    // Note trail
                    x.globalAlpha=.15;
                    x.save();x.translate(lx,ny-8);x.rotate(Math.PI/4);
                    x.fillRect(-4,-4,8,8);x.restore();
                    x.globalAlpha=1;
                }
                // Zone hit markers
                x.fillStyle=nc[i];x.globalAlpha=.4;
                x.shadowColor=nc[i];x.shadowBlur=6;
                x.beginPath();x.arc(lx,zoneY,8,0,Math.PI*2);x.fill();x.shadowBlur=0;
                x.globalAlpha=1;
            }
            // Hit flash
            if(Math.sin(t*8)>.85){
                const fi=Math.floor(t*3)%3;
                const lx=w*(.25+fi*.25);
                x.fillStyle=nc[fi]+'22';x.fillRect(lx-12,0,24,h);
            }

        }else if(p.type==='arena'){
            // Lane-based card arena preview (chess + clash royale style)
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#1a1430');bg.addColorStop(1,'#0a0820');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Two towers per side
            const tw=10,th=h*0.16;
            x.fillStyle='#3b82f6';x.fillRect(w*0.12-tw/2,h*0.18,tw,th);x.fillRect(w*0.88-tw/2,h*0.18,tw,th);
            x.fillStyle='#ef4444';x.fillRect(w*0.12-tw/2,h*0.66,tw,th);x.fillRect(w*0.88-tw/2,h*0.66,tw,th);
            // Lane lines
            x.strokeStyle='rgba(255,255,255,0.08)';x.lineWidth=1;
            x.setLineDash([3,4]);
            x.beginPath();x.moveTo(0,h*0.5);x.lineTo(w,h*0.5);x.stroke();
            x.setLineDash([]);
            // Marching units
            for(let i=0;i<5;i++){
                const lane=i%2?w*0.12:w*0.88;
                const u=((t*0.4+i*0.2)%1);
                const y=h*0.18+th+u*(h*0.66-h*0.18-th);
                const team=i%2;
                x.fillStyle=team?'#3b82f6':'#ef4444';
                x.shadowColor=team?'#3b82f6':'#ef4444';x.shadowBlur=6;
                x.beginPath();x.arc(lane+(team?-1:1)*8,team?y:h-y+h*0.35,4,0,Math.PI*2);x.fill();
                x.shadowBlur=0;
            }
            // Card hand at bottom
            x.fillStyle='rgba(255,255,255,0.08)';
            for(let i=0;i<4;i++){x.fillRect(w*0.5-40+i*22,h-22,18,18);}
        }else if(p.type==='nebula'){
            // Asteroid field with ship + glowing blinks
            x.fillStyle='#02021a';x.fillRect(0,0,w,h);
            // Stars
            for(let i=0;i<25;i++){const sx=(i*73.7+t*8)%w,sy=(i*41.3)%h;x.fillStyle='rgba(255,255,255,'+(0.3+Math.sin(t*2+i)*0.3)+')';x.fillRect(sx,sy,1,1);}
            // Asteroids drifting
            for(let i=0;i<4;i++){
                const ax=(w*0.2+i*w*0.22+Math.sin(t*0.3+i)*20),ay=(h*0.3+Math.cos(t*0.4+i*1.7)*h*0.3);
                x.strokeStyle='#7788aa';x.fillStyle='#222230';x.lineWidth=1.4;
                x.beginPath();const sides=7;for(let k=0;k<sides;k++){const ang=k/sides*Math.PI*2,rr=10+(k%2)*5;if(k===0)x.moveTo(ax+Math.cos(ang)*rr,ay+Math.sin(ang)*rr);else x.lineTo(ax+Math.cos(ang)*rr,ay+Math.sin(ang)*rr);}
                x.closePath();x.fill();x.stroke();
            }
            // Blinks (glowing dots that pulse)
            for(let i=0;i<6;i++){
                const bx=w*(0.15+i*0.13),by=h*(0.25+(i%3)*0.22);
                const pulse=Math.sin(t*3+i*1.2);if(pulse<-0.2)continue;
                const r=3+pulse*2.5;
                x.fillStyle='#ffee44';x.shadowColor='#ffee44';x.shadowBlur=10;
                x.beginPath();x.arc(bx,by,r,0,Math.PI*2);x.fill();x.shadowBlur=0;
            }
            // Player ship
            const sa=t*0.6,sx2=w*0.5+Math.cos(sa)*30,sy2=h*0.5+Math.sin(sa)*15;
            x.save();x.translate(sx2,sy2);x.rotate(sa+Math.PI/2);
            x.strokeStyle='#88ffff';x.fillStyle='rgba(136,255,255,0.15)';x.lineWidth=2;
            x.beginPath();x.moveTo(0,-9);x.lineTo(7,7);x.lineTo(-7,7);x.closePath();x.fill();x.stroke();
            x.restore();
        }else if(p.type==='volley'){
            // Neon pong with smooth ball movement
            const bg=x.createLinearGradient(0,0,w,0);
            bg.addColorStop(0,'#060812');bg.addColorStop(.5,'#080a16');bg.addColorStop(1,'#060812');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Center line
            x.setLineDash([4,6]);x.strokeStyle='rgba(255,255,255,0.08)';x.lineWidth=1.5;
            x.beginPath();x.moveTo(w/2,0);x.lineTo(w/2,h);x.stroke();x.setLineDash([]);
            // Side glow
            const lgrd=x.createLinearGradient(0,0,w*.15,0);
            lgrd.addColorStop(0,'rgba(68,221,255,0.04)');lgrd.addColorStop(1,'transparent');
            x.fillStyle=lgrd;x.fillRect(0,0,w*.15,h);
            const rgrd=x.createLinearGradient(w*.85,0,w,0);
            rgrd.addColorStop(0,'transparent');rgrd.addColorStop(1,'rgba(255,68,102,0.04)');
            x.fillStyle=rgrd;x.fillRect(w*.85,0,w*.15,h);
            // Paddles with glow
            const ph2=h*.3;
            const py2=h/2+Math.sin(t*1.8)*h*.28;
            const ay2=h/2+Math.sin(t*1.8+.4)*h*.24;
            x.shadowColor='#44ddff';x.shadowBlur=10;
            x.fillStyle='#44ddff';x.beginPath();x.roundRect(8,py2-ph2/2,5,ph2,3);x.fill();
            x.shadowColor='#ff4466';
            x.fillStyle='#ff4466';x.beginPath();x.roundRect(w-13,ay2-ph2/2,5,ph2,3);x.fill();
            x.shadowBlur=0;
            // Ball with trail
            const bx2=w/2+Math.sin(t*2.5)*w*.38;
            const by4=h/2+Math.cos(t*3.2)*h*.32;
            x.globalAlpha=.06;x.fillStyle='#fff';x.beginPath();x.arc(bx2-18,by4-9,3,0,Math.PI*2);x.fill();
            x.globalAlpha=.1;x.beginPath();x.arc(bx2-12,by4-6,3.5,0,Math.PI*2);x.fill();
            x.globalAlpha=.2;x.beginPath();x.arc(bx2-6,by4-3,4,0,Math.PI*2);x.fill();
            x.globalAlpha=1;
            x.shadowColor='#fff';x.shadowBlur=10;
            x.fillStyle='#fff';x.beginPath();x.arc(bx2,by4,4.5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            // Score indicators
            x.fillStyle='rgba(68,221,255,0.2)';x.font='bold 16px sans-serif';x.textAlign='center';
            x.fillText('3',w*.25,h*.15);
            x.fillStyle='rgba(255,68,102,0.2)';
            x.fillText('2',w*.75,h*.15);

        }else if(p.type==='dash'){
            // Neon runner with parallax city
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#0f0f2a');bg.addColorStop(.6,'#1a1a35');bg.addColorStop(1,'#16213e');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            const gy=h*.72;
            // Stars
            for(let i=0;i<10;i++){
                const sx=((i*79)%w),sy=((i*37)%(gy*.5));
                x.fillStyle=`rgba(255,255,255,${0.1+Math.sin(t*2+i)*0.08})`;
                x.beginPath();x.arc(sx,sy,0.8,0,Math.PI*2);x.fill();
            }
            // City silhouette (parallax layers)
            x.fillStyle='#0d0d25';
            const farBldgs=[.05,.15,.28,.38,.48,.58,.68,.78,.88,.95];
            for(let i=0;i<farBldgs.length;i++){
                const bw=w*.04;const bh=h*(.1+Math.sin(i*1.7)*.08);
                x.fillRect(farBldgs[i]*w-((t*4)%w*.08),gy-bh,bw,bh+4);
            }
            x.fillStyle='#151530';
            const bldgs=[.1,.18,.25,.35,.42,.52,.58,.68,.75,.85,.92];
            const bHts=[.2,.35,.28,.4,.22,.32,.38,.25,.42,.3,.2];
            for(let i=0;i<bldgs.length;i++){
                const bw=w*.06;x.fillRect(bldgs[i]*w-((t*8)%w*.12),gy-h*bHts[i],bw,h*bHts[i]+10);
                // Window lights
                x.fillStyle='rgba(255,180,50,0.12)';
                for(let wy=0;wy<3;wy++){
                    if(Math.sin(i*3+wy*7)>.3) x.fillRect(bldgs[i]*w-((t*8)%w*.12)+2,gy-h*bHts[i]+8+wy*12,2,2);
                }
                x.fillStyle='#151530';
            }
            // Ground
            x.fillStyle='#16213e';x.fillRect(0,gy,w,h-gy);
            x.strokeStyle='#0f3460';x.lineWidth=2;
            x.beginPath();x.moveTo(0,gy);x.lineTo(w,gy);x.stroke();
            // Neon ground reflection
            x.fillStyle='rgba(233,69,96,0.04)';x.fillRect(0,gy,w,h-gy);
            // Speed lines with glow
            x.globalAlpha=.12;x.strokeStyle='#e94560';x.lineWidth=1.5;
            for(let i=0;i<5;i++){
                const ly=gy-10-i*10;x.beginPath();
                const sx=((t*140+i*80)%w)-w*.2;
                x.moveTo(sx,ly);x.lineTo(sx+25+i*5,ly);x.stroke();
            }
            x.globalAlpha=1;
            // Player with afterimage
            const px=w*.28,py=gy-14+Math.sin(t*6)*4;
            x.fillStyle='rgba(233,69,96,0.15)';x.beginPath();x.roundRect(px-8,py-11,12,12,2);x.fill();
            x.fillStyle='rgba(233,69,96,0.3)';x.beginPath();x.roundRect(px-4,py-12,12,12,2);x.fill();
            x.fillStyle='#e94560';x.shadowColor='#e94560';x.shadowBlur=12;
            x.beginPath();x.roundRect(px-6,py-12,12,12,2);x.fill();x.shadowBlur=0;
            // Obstacles with glow
            for(let i=0;i<3;i++){
                const sx=((px+80+i*100+t*70)%w);
                x.fillStyle='rgba(233,69,96,0.8)';x.shadowColor='#e94560';x.shadowBlur=4;
                x.beginPath();
                x.moveTo(sx,gy);x.lineTo(sx+8,gy);x.lineTo(sx+4,gy-14);x.closePath();x.fill();
                x.shadowBlur=0;
            }

        }else if(p.type==='rush'){
            // Mountain speedrun with platforms ascending
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#060408');bg.addColorStop(1,'#120c0a');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Platforms
            for(let i=0;i<7;i++){
                const py4=h*.88-i*(h*.12)-((t*22)%(h*.12));
                const pw4=28+i*5;
                const plx4=w*.15+Math.sin(i*2.1)*w*.3;
                x.fillStyle='rgba(255,102,68,0.6)';
                x.beginPath();x.roundRect(plx4,py4,pw4,5,2);x.fill();
                x.fillStyle='rgba(255,140,100,0.3)';x.fillRect(plx4,py4,pw4,2);
            }
            // Summit goal
            x.fillStyle='rgba(255,220,68,0.5)';x.fillRect(w*.15,h*.06,w*.7,3);
            x.font='bold 8px sans-serif';x.textAlign='center';
            x.fillStyle='rgba(255,220,68,0.6)';x.fillText('SUMMIT',w/2,h*.04+2);
            // Player
            const rpx2=w*.42+Math.sin(t*1.8)*w*.15,rpy2=h*.45+Math.abs(Math.sin(t*3))*(-28);
            x.shadowColor='#ff6644';x.shadowBlur=10;
            x.fillStyle='#fff';x.beginPath();x.arc(rpx2,rpy2,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            // Ghost trail
            x.globalAlpha=.12;x.fillStyle='#ff6644';
            x.beginPath();x.arc(rpx2,rpy2+6,4,0,Math.PI*2);x.fill();
            x.beginPath();x.arc(rpx2,rpy2+12,3,0,Math.PI*2);x.fill();
            x.globalAlpha=1;

        }else if(p.type==='climb'){
            // Wall-jump corridor with spikes
            const bg=x.createLinearGradient(w/2,0,w/2,h);
            bg.addColorStop(0,'#06060c');bg.addColorStop(1,'#0a0a14');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Walls
            x.fillStyle='#1a1a2e';x.fillRect(0,0,16,h);x.fillRect(w-16,0,16,h);
            x.fillStyle='#44bbdd';x.fillRect(15,0,2,h);
            x.fillStyle='#ff4466';x.fillRect(w-17,0,2,h);
            // Spikes
            for(let i=0;i<5;i++){
                const sy3=((i*h*.22+t*35)%h);const side=i%2===0;
                x.fillStyle=side?'#44bbdd':'#ff4466';x.globalAlpha=.7;
                x.beginPath();
                x.moveTo(side?16:w-16,sy3);x.lineTo(side?32:w-32,sy3-5);x.lineTo(side?16:w-16,sy3-10);
                x.fill();x.globalAlpha=1;
            }
            // Player bouncing between walls
            const wallPhase=Math.sin(t*2);
            const cx2=wallPhase>0?28:w-28;
            const cy=h*.45+Math.sin(t*3.2)*h*.22;
            x.shadowColor='#fff';x.shadowBlur=8;
            x.fillStyle='#fff';x.beginPath();x.arc(cx2,cy,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            // Trail
            x.globalAlpha=.1;x.fillStyle='#fff';
            x.beginPath();x.arc(wallPhase>0?w-28:28,cy+15,4,0,Math.PI*2);x.fill();
            x.globalAlpha=1;

        }else if(p.type==='swerve'){
            // 3-lane highway with traffic
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#0a0a14');bg.addColorStop(1,'#0c0c18');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            const rw2=w*.52,rl=(w-rw2)/2;
            x.fillStyle='#151528';
            x.beginPath();x.roundRect(rl,0,rw2,h,0);x.fill();
            // Road markers
            x.fillStyle='rgba(255,255,255,0.06)';
            x.fillRect(rl+rw2/3,0,1,h);x.fillRect(rl+rw2*2/3,0,1,h);
            for(let i=0;i<5;i++){
                const ly=((i*h*.22+t*80)%h);
                x.fillStyle='rgba(255,255,255,0.08)';x.fillRect(w/2-1,ly,2,18);
            }
            // Player
            x.shadowColor='#44ff88';x.shadowBlur=8;
            x.fillStyle='#44ff88';
            x.beginPath();x.roundRect(w/2-6,h*.72,12,18,3);x.fill();x.shadowBlur=0;
            // Traffic
            const trafficColors=['#ff4466','#ff8844','#ffcc22'];
            for(let i=0;i<3;i++){
                const lane=rl+12+(i*(rw2/3));
                const oy=((i*157+t*75)%h);
                x.fillStyle=trafficColors[i];x.globalAlpha=.8;
                x.beginPath();x.roundRect(lane,oy,10,18,3);x.fill();x.globalAlpha=1;
            }

        }else if(p.type==='spin'){
            // Orbital with rotating player and incoming threats
            const bg=x.createRadialGradient(w/2,h/2,0,w/2,h/2,w*.5);
            bg.addColorStop(0,'#0a0a18');bg.addColorStop(1,'#050510');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            const cx3=w/2,cy3=h/2,or=Math.min(w,h)*.28;
            // Orbit ring
            x.strokeStyle='rgba(200,100,255,0.08)';x.lineWidth=1.5;
            x.beginPath();x.arc(cx3,cy3,or,0,Math.PI*2);x.stroke();
            x.strokeStyle='rgba(200,100,255,0.04)';
            x.beginPath();x.arc(cx3,cy3,or+8,0,Math.PI*2);x.stroke();
            // Core
            x.shadowColor='#ff4466';x.shadowBlur=12;
            x.fillStyle='#ff4466';x.beginPath();x.arc(cx3,cy3,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            x.fillStyle='rgba(255,68,102,0.08)';x.beginPath();x.arc(cx3,cy3,14,0,Math.PI*2);x.fill();
            // Orbiting player
            const sa=t*2.2;
            x.shadowColor='#fff';x.shadowBlur=8;
            x.fillStyle='#fff';x.beginPath();x.arc(cx3+Math.cos(sa)*or,cy3+Math.sin(sa)*or,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            // Incoming threats
            for(let i=0;i<4;i++){
                const ta=i*1.6+t*.6;const maxD=or*2.5;
                const td=maxD-((t*50+i*60)%maxD);
                x.fillStyle='#ff8844';x.globalAlpha=.5+td/maxD*.3;x.shadowColor='#ff8844';x.shadowBlur=4;
                x.beginPath();x.arc(cx3+Math.cos(ta)*td,cy3+Math.sin(ta)*td,3,0,Math.PI*2);x.fill();
                x.shadowBlur=0;x.globalAlpha=1;
            }

        }else if(p.type==='drop'){
            // Platforms scrolling up with gaps to fall through
            x.fillStyle='#08080e';x.fillRect(0,0,w,h);
            for(let i=0;i<5;i++){
                const py2=((i*h*.22+t*35)%h);
                const gx2=w*.15+Math.sin(i*2.8+1)*w*.2,gw2=w*.22;
                x.fillStyle='#ff5577';x.globalAlpha=.7;
                x.shadowColor='#ff5577';x.shadowBlur=4;
                if(gx2>0){x.beginPath();x.roundRect(0,py2,gx2,5,0);x.fill();}
                const rightX=gx2+gw2;
                if(rightX<w){x.beginPath();x.roundRect(rightX,py2,w-rightX,5,0);x.fill();}
                x.shadowBlur=0;x.globalAlpha=1;
            }
            // Gap highlight
            x.fillStyle='rgba(255,85,119,0.05)';
            for(let i=0;i<5;i++){
                const py2=((i*h*.22+t*35)%h);
                const gx2=w*.15+Math.sin(i*2.8+1)*w*.2,gw2=w*.22;
                x.fillRect(gx2,py2-2,gw2,9);
            }
            const dpx2=w*.5+Math.sin(t*2)*w*.18,dpy2=h*.28;
            x.shadowColor='#fff';x.shadowBlur=8;
            x.fillStyle='#fff';x.beginPath();x.arc(dpx2,dpy2,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
        }else if(p.type==='territory'){
            // Grid territory game preview
            x.fillStyle='#08080e';x.fillRect(0,0,w,h);
            // Grid lines with glow
            x.strokeStyle='rgba(255,255,255,0.03)';x.lineWidth=0.5;
            const cs=w/12;
            for(let i=0;i<=12;i++){x.beginPath();x.moveTo(i*cs,0);x.lineTo(i*cs,h);x.stroke();}
            for(let i=0;i<=8;i++){x.beginPath();x.moveTo(0,i*cs);x.lineTo(w,i*cs);x.stroke();}
            // Territory zones - animated growing
            const zones=[
                {cx:w*.25,cy:h*.35,r:w*.12,color:'rgba(68,255,136,0.15)',border:'#44ff88'},
                {cx:w*.7,cy:h*.55,r:w*.1,color:'rgba(255,68,102,0.15)',border:'#ff4466'},
                {cx:w*.5,cy:h*.75,r:w*.08,color:'rgba(68,136,255,0.15)',border:'#4488ff'},
            ];
            zones.forEach((z,i)=>{
                const pulse=z.r+Math.sin(t*1.5+i)*5;
                // Outer glow
                const grd=x.createRadialGradient(z.cx,z.cy,0,z.cx,z.cy,pulse+10);
                grd.addColorStop(0,z.color);grd.addColorStop(0.8,z.color);grd.addColorStop(1,'transparent');
                x.fillStyle=grd;x.beginPath();x.arc(z.cx,z.cy,pulse+10,0,Math.PI*2);x.fill();
                // Territory fill
                x.fillStyle=z.color;
                x.beginPath();x.arc(z.cx,z.cy,pulse,0,Math.PI*2);x.fill();
                x.strokeStyle=z.border;x.lineWidth=1.5;x.globalAlpha=0.5;x.stroke();x.globalAlpha=1;
            });
            // Snake trails
            zones.forEach((z,i)=>{
                const trailLen=8;
                x.strokeStyle=z.border;x.lineWidth=2.5;x.globalAlpha=0.6;
                x.lineCap='round';x.lineJoin='round';
                x.beginPath();
                for(let j=0;j<trailLen;j++){
                    const tx=z.cx+Math.sin(t*1.8+i*2.5+j*0.4)*z.r*.7;
                    const ty=z.cy+Math.cos(t*2.2+i*1.7+j*0.3)*z.r*.7;
                    j===0?x.moveTo(tx,ty):x.lineTo(tx,ty);
                }
                x.stroke();x.globalAlpha=1;
            });
            // Snake heads with glow
            zones.forEach((z,i)=>{
                const hx=z.cx+Math.sin(t*1.8+i*2.5)*z.r*.6;
                const hy=z.cy+Math.cos(t*2.2+i*1.7)*z.r*.6;
                x.shadowColor=z.border;x.shadowBlur=12;
                x.fillStyle=z.border;x.beginPath();x.arc(hx,hy,5,0,Math.PI*2);x.fill();
                x.shadowBlur=0;
                // Eyes
                x.fillStyle='#fff';x.beginPath();x.arc(hx+2,hy-1,1.5,0,Math.PI*2);x.fill();
            });
        }else if(p.type==='impostor'){
            // Impostor online multiplayer preview - suspicion theme
            const bg=x.createRadialGradient(w/2,h/2,0,w/2,h/2,w*.6);
            bg.addColorStop(0,'#0c0816');bg.addColorStop(1,'#06040a');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Subtle grid pattern
            x.strokeStyle='rgba(129,140,248,0.03)';x.lineWidth=0.5;
            for(let i=0;i<w;i+=20){x.beginPath();x.moveTo(i,0);x.lineTo(i,h);x.stroke();}
            for(let i=0;i<h;i+=20){x.beginPath();x.moveTo(0,i);x.lineTo(w,i);x.stroke();}
            // Ring of players with connections
            const cx=w/2,cy=h/2,r=Math.min(w,h)*0.3;
            const pCount=6;
            const pColors=['#818cf8','#818cf8','#ef4444','#818cf8','#818cf8','#818cf8'];
            // Connection lines
            x.strokeStyle='rgba(129,140,248,0.06)';x.lineWidth=1;
            for(let i=0;i<pCount;i++){
                const a1=(i/pCount)*Math.PI*2-Math.PI/2+Math.sin(t*0.3)*0.08;
                const a2=((i+1)/pCount)*Math.PI*2-Math.PI/2+Math.sin(t*0.3)*0.08;
                x.beginPath();
                x.moveTo(cx+r*Math.cos(a1),cy+r*Math.sin(a1));
                x.lineTo(cx+r*Math.cos(a2),cy+r*Math.sin(a2));
                x.stroke();
            }
            // Player circles
            for(let i=0;i<pCount;i++){
                const a=(i/pCount)*Math.PI*2-Math.PI/2+Math.sin(t*0.3)*0.08;
                const px=cx+r*Math.cos(a);
                const py=cy+r*Math.sin(a);
                const isImp=i===2;
                // Outer glow for impostor (subtle)
                if(isImp && Math.sin(t*2)>0.3){
                    x.fillStyle='rgba(239,68,68,0.08)';x.beginPath();x.arc(px,py,18,0,Math.PI*2);x.fill();
                }
                x.beginPath();x.arc(px,py,10,0,Math.PI*2);
                x.fillStyle=isImp?'rgba(239,68,68,0.25)':'rgba(129,140,248,0.15)';
                x.fill();
                x.strokeStyle=pColors[i];
                x.lineWidth=isImp?2:1.5;x.stroke();
                // Mini face
                x.fillStyle=pColors[i];
                x.beginPath();x.arc(px-2.5,py-1.5,1.2,0,Math.PI*2);x.fill();
                x.beginPath();x.arc(px+2.5,py-1.5,1.2,0,Math.PI*2);x.fill();
            }
            // Animated question marks floating
            for(let i=0;i<3;i++){
                const qx=w*(.2+i*.3)+Math.sin(t*1.5+i*2)*12;
                const qy=h*.25+Math.cos(t+i)*8;
                x.fillStyle=`rgba(255,255,255,${0.06+Math.sin(t*2+i)*0.03})`;
                x.font='bold 14px sans-serif';x.textAlign='center';x.textBaseline='middle';
                x.fillText('?',qx,qy);
            }
            // Center question mark
            x.fillStyle=`rgba(255,255,255,${0.08+Math.sin(t*2)*0.04})`;
            x.font='bold 28px sans-serif';x.textAlign='center';x.textBaseline='middle';
            x.fillText('?',cx,cy+Math.sin(t*2)*3);
        }else if(p.type==='maze'){
            // Maze preview with glowing player navigating
            const bg=x.createRadialGradient(w/2,h/2,0,w/2,h/2,w*.6);
            bg.addColorStop(0,'#060d08');bg.addColorStop(1,'#040806');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Draw mini maze walls
            const gs=7,cw=w/(gs+2),ch=h/(gs+2);
            x.strokeStyle='rgba(68,221,136,0.25)';x.lineWidth=1.5;
            for(let r=0;r<gs;r++)for(let c2=0;c2<gs;c2++){
                const mx=cw*(c2+1),my=ch*(r+1);
                const seed=r*gs+c2;
                if((seed*7+3)%4===0){x.beginPath();x.moveTo(mx,my);x.lineTo(mx+cw,my);x.stroke();}
                if((seed*11+5)%5===0){x.beginPath();x.moveTo(mx+cw,my);x.lineTo(mx+cw,my+ch);x.stroke();}
            }
            // Outer walls
            x.strokeStyle='rgba(68,221,136,0.35)';x.lineWidth=2;
            x.strokeRect(cw,ch,gs*cw,gs*ch);
            // Barrier creeping from top
            const by=ch+((Math.sin(t*0.3)+1)/2)*gs*ch*0.4;
            const grad=x.createLinearGradient(0,ch,0,by);
            grad.addColorStop(0,'rgba(255,0,0,0.2)');grad.addColorStop(1,'rgba(255,50,50,0.05)');
            x.fillStyle=grad;x.fillRect(cw,ch,gs*cw,by-ch);
            // Player ball
            const px2=cw*2+Math.sin(t*1.1)*(gs-2)*cw*0.4+gs*cw*0.3;
            const py2=ch*2+Math.cos(t*0.9)*(gs-2)*ch*0.3+gs*ch*0.3;
            x.shadowColor='#44aaff';x.shadowBlur=10;
            x.fillStyle='#44aaff';x.beginPath();x.arc(px2,py2,4,0,Math.PI*2);x.fill();
            x.shadowBlur=0;
            // Exit glow
            const ex=cw*(gs),ey=ch*(gs);
            x.fillStyle='rgba(68,221,136,0.3)';x.beginPath();x.arc(ex,ey,6,0,Math.PI*2);x.fill();
            x.fillStyle='#44dd88';x.beginPath();x.arc(ex,ey,3,0,Math.PI*2);x.fill();
        }else if(p.type==='chain'){
            // Two chained balls rising
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#0c0808');bg.addColorStop(1,'#060404');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // Platforms
            for(let i=0;i<5;i++){
                const py3=h*.85-i*(h*.17)-((t*12)%(h*.17)),pw=30+i*5;
                const plx=w*.15+Math.sin(i*2.1)*w*.3;
                x.fillStyle='rgba(140,110,70,0.6)';x.fillRect(plx,py3,pw,4);
            }
            // Ball A (orange)
            const ax=w*.35+Math.sin(t*1.3)*w*.1,ay=h*.45+Math.sin(t*0.9)*h*.12;
            x.shadowColor='#ff6644';x.shadowBlur=8;
            x.fillStyle='#ff6644';x.beginPath();x.arc(ax,ay,6,0,Math.PI*2);x.fill();
            // Ball B (blue)
            const bx=w*.65+Math.sin(t*1.1+1)*w*.1,by=h*.4+Math.cos(t*0.8)*h*.1;
            x.shadowColor='#44aaff';x.shadowBlur=8;
            x.fillStyle='#44aaff';x.beginPath();x.arc(bx,by,6,0,Math.PI*2);x.fill();
            x.shadowBlur=0;
            // Chain
            x.strokeStyle='rgba(255,150,80,0.5)';x.lineWidth=1.5;
            x.beginPath();
            for(let i=0;i<=8;i++){const ct=i/8;const cx2=ax+(bx-ax)*ct;const cy2=ay+(by-ay)*ct+Math.sin(ct*Math.PI)*12;if(i===0)x.moveTo(cx2,cy2);else x.lineTo(cx2,cy2);}
            x.stroke();
        }else if(p.type==='swap'){
            x.fillStyle='#06080c';x.fillRect(0,0,w,h);
            const y0=h*0.35,y1=h*0.65;
            x.strokeStyle='rgba(255,170,0,0.1)';x.lineWidth=1;x.setLineDash([4,4]);
            x.beginPath();x.moveTo(0,y0);x.lineTo(w,y0);x.stroke();
            x.beginPath();x.moveTo(0,y1);x.lineTo(w,y1);x.stroke();x.setLineDash([]);
            const active2=Math.floor(t/1.2)%2;
            const ay2=active2===0?y0:y1,gy2=active2===0?y1:y0;
            x.fillStyle='rgba(255,170,0,0.12)';x.beginPath();x.arc(w/2,gy2,5,0,Math.PI*2);x.fill();
            x.shadowColor='#ffaa00';x.shadowBlur=6;x.fillStyle='#ffaa00';
            x.beginPath();x.arc(w/2,ay2,5,0,Math.PI*2);x.fill();x.shadowBlur=0;
            for(let i=0;i<2;i++){
                const ox=((t*40+i*60)%w);const lane2=i%2===0?y0:y1;
                x.fillStyle='rgba(255,68,68,0.2)';x.fillRect(ox-8,lane2-5,16,10);
            }
        }else if(p.type==='flick'){
            // Directional reaction
            x.fillStyle='#06080c';x.fillRect(0,0,w,h);
            x.strokeStyle='rgba(255,102,51,0.08)';x.lineWidth=2;
            x.beginPath();x.arc(w/2,h/2,20,0,Math.PI*2);x.stroke();
            const dirs3=['?','?','?','?'];const dpos=[[w/2,h*0.2],[w/2,h*0.8],[w*0.15,h/2],[w*0.85,h/2]];
            const active3=Math.floor(t*2)%4;
            x.font='bold 14px sans-serif';x.textAlign='center';x.textBaseline='middle';
            for(let i=0;i<4;i++){
                x.fillStyle=i===active3?'rgba(255,102,51,0.6)':'rgba(255,102,51,0.08)';
                x.fillText(dirs3[i],dpos[i][0],dpos[i][1]);
            }
        }else if(p.type==='pop'){
            // Tower defense: bubbles flowing along path, towers shoot
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#1a3a5a');bg.addColorStop(1,'#0a1830');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // grass patches
            x.fillStyle='rgba(60,140,80,0.18)';
            for(let i=0;i<8;i++){const gx=(i*53+17)%w,gy=(i*37+11)%h;x.beginPath();x.arc(gx,gy,14,0,Math.PI*2);x.fill();}
            // path: zig-zag
            const pts=[[0,h*.25],[w*.35,h*.25],[w*.35,h*.7],[w*.7,h*.7],[w*.7,h*.4],[w,h*.4]];
            x.strokeStyle='#3a2818';x.lineWidth=14;x.lineCap='round';x.lineJoin='round';
            x.beginPath();x.moveTo(pts[0][0],pts[0][1]);for(let i=1;i<pts.length;i++)x.lineTo(pts[i][0],pts[i][1]);x.stroke();
            x.strokeStyle='#5a4028';x.lineWidth=10;x.beginPath();x.moveTo(pts[0][0],pts[0][1]);for(let i=1;i<pts.length;i++)x.lineTo(pts[i][0],pts[i][1]);x.stroke();
            // segment lengths
            const segs=[];let total=0;
            for(let i=1;i<pts.length;i++){const dx=pts[i][0]-pts[i-1][0],dy=pts[i][1]-pts[i-1][1];const len=Math.hypot(dx,dy);segs.push({a:pts[i-1],b:pts[i],len});total+=len;}
            function ptAt(d){d=((d%total)+total)%total;for(const s of segs){if(d<=s.len){const k=d/s.len;return[s.a[0]+(s.b[0]-s.a[0])*k,s.a[1]+(s.b[1]-s.a[1])*k];}d-=s.len;}return pts[pts.length-1];}
            // bubbles
            const colors=['#ff5544','#ff9844','#ffd844','#44dd66','#44aadd','#dd44dd'];
            for(let i=0;i<10;i++){
                const off=(t*45+i*22)%total;
                const [bx,by]=ptAt(off);
                const c=colors[i%colors.length];
                x.shadowColor=c;x.shadowBlur=8;
                x.fillStyle=c;x.beginPath();x.arc(bx,by,7,0,Math.PI*2);x.fill();
                x.shadowBlur=0;
                x.fillStyle='rgba(255,255,255,0.4)';x.beginPath();x.arc(bx-2,by-2,2,0,Math.PI*2);x.fill();
            }
            // towers
            const towers=[[w*.18,h*.55,'#44ff88'],[w*.55,h*.45,'#ff66cc'],[w*.85,h*.7,'#88aaff']];
            towers.forEach((tw_,ti)=>{
                const [tx_,ty_,col]=tw_;
                // base
                x.fillStyle='#2a3a55';x.beginPath();x.arc(tx_,ty_,9,0,Math.PI*2);x.fill();
                x.strokeStyle=col;x.lineWidth=2;x.stroke();
                // barrel rotating to nearest bubble
                const ang=t*1.5+ti*1.7;
                x.save();x.translate(tx_,ty_);x.rotate(ang);
                x.fillStyle=col;x.fillRect(0,-2,12,4);
                x.restore();
                // muzzle flash
                if(Math.sin(t*6+ti*2)>.7){
                    x.fillStyle=col;x.globalAlpha=.5;
                    x.beginPath();x.arc(tx_+Math.cos(ang)*14,ty_+Math.sin(ang)*14,4,0,Math.PI*2);x.fill();
                    x.globalAlpha=1;
                }
            });
        }else if(p.type==='farm'){
            // Farm grid with growing crops
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#5fa84e');bg.addColorStop(1,'#2d5a3a');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            const cols=4,rows=3,gap=4,pad=8;
            const tw=(w-pad*2-gap*(cols-1))/cols,th=(h-pad*2-gap*(rows-1))/rows;
            const icons=['??','??','??','??','??'];
            x.textAlign='center';x.textBaseline='middle';
            for(let r=0;r<rows;r++)for(let c=0;c<cols;c++){
                const px=pad+c*(tw+gap),py=pad+r*(th+gap);
                x.fillStyle='#3e2a18';x.fillRect(px,py,tw,th);
                x.fillStyle='rgba(0,0,0,0.3)';x.fillRect(px,py+th-3,tw,3);
                const phase=(t*0.4+r*0.7+c*0.5)%2;
                if(phase>0.2){
                    const grow=Math.min(1,(phase-0.2)/1.0);
                    const ripe=phase>1.2;
                    x.font=`${Math.floor(Math.min(tw,th)*0.5*grow)}px sans-serif`;
                    if(ripe){x.shadowColor='#ffe066';x.shadowBlur=8;}
                    x.fillText(icons[(r*cols+c)%icons.length],px+tw/2,py+th/2+2);
                    x.shadowBlur=0;
                }
            }
            // floating coin
            const cx=w*.5+Math.sin(t*1.2)*w*.2,cy=h*.4-(t*15)%80;
            x.fillStyle='#ffd866';x.font='bold 14px sans-serif';
            x.shadowColor='#ffd866';x.shadowBlur=6;
            x.fillText('+$',cx,cy);x.shadowBlur=0;
        }else if(p.type==='cafe'){
            // Cafe with steaming cup and stations
            const bg=x.createLinearGradient(0,0,0,h);
            bg.addColorStop(0,'#6e3a1f');bg.addColorStop(1,'#2a1408');
            x.fillStyle=bg;x.fillRect(0,0,w,h);
            // counter
            x.fillStyle='#3a2418';x.fillRect(0,h*0.65,w,h*0.35);
            x.fillStyle='#5a3a22';x.fillRect(0,h*0.65,w,3);
            // stations
            const items=['?','??','??','??'];
            x.textAlign='center';x.textBaseline='middle';
            for(let i=0;i<items.length;i++){
                const sx=w*(0.15+i*0.235),sy=h*0.45;
                // base
                x.fillStyle='#1f1308';x.fillRect(sx-18,sy-2,36,18);
                // progress
                const prog=(t*0.5+i*0.3)%1;
                x.fillStyle='#ffaa66';x.fillRect(sx-16,sy+12,32*prog,3);
                // icon
                x.font='22px sans-serif';
                x.fillText(items[i],sx,sy);
                // steam
                if(items[i]==='?'||items[i]==='??'){
                    for(let j=0;j<3;j++){
                        const off=(t*30+j*40)%80;
                        x.globalAlpha=Math.max(0,0.4-off/80);
                        x.fillStyle='#fff';x.beginPath();
                        x.arc(sx+Math.sin(off*0.1)*4,sy-15-off,2,0,Math.PI*2);x.fill();
                    }
                    x.globalAlpha=1;
                }
            }
            // floating coin
            const cox=w*.5+Math.sin(t*1.4)*w*.25,coy=h*.25-(t*12)%60;
            x.fillStyle='#ffd866';x.font='bold 14px sans-serif';
            x.shadowColor='#ffd866';x.shadowBlur=6;
            x.fillText('+$',cox,coy);x.shadowBlur=0;
        }else if(p.type==='runner'){
            const bg=x.createLinearGradient(0,0,0,h);bg.addColorStop(0,'#88ccff');bg.addColorStop(1,'#cc9966');x.fillStyle=bg;x.fillRect(0,0,w,h);
            x.fillStyle='#cc9966';x.fillRect(0,h*0.7,w,h*0.3);
            const jy=Math.max(0,Math.sin(t*3))*h*0.3;
            x.fillStyle='#3a2200';x.fillRect(w*0.3,h*0.7-30-jy,20,30);
            const ox=((t*150)%w);x.fillStyle='#226633';x.fillRect(ox,h*0.7-25,15,25);
        }else if(p.type==='crossy'){
            // Crossy: chicken hopping across road/river/grass strips
            const stripeH=h/5;
            // grass top
            x.fillStyle='#5cbf63';x.fillRect(0,0,w,stripeH);
            // road
            x.fillStyle='#2a2a2a';x.fillRect(0,stripeH,w,stripeH);
            x.strokeStyle='#fbbf24';x.lineWidth=2;x.setLineDash([8,8]);
            x.beginPath();x.moveTo(0,stripeH*2-2);x.lineTo(w,stripeH*2-2);x.stroke();x.setLineDash([]);
            // river
            x.fillStyle='#2c80c8';x.fillRect(0,stripeH*2,w,stripeH);
            // rail
            x.fillStyle='#5d4e3c';x.fillRect(0,stripeH*3,w,stripeH);
            x.strokeStyle='#aaa';x.lineWidth=1.5;
            x.beginPath();x.moveTo(0,stripeH*3+6);x.lineTo(w,stripeH*3+6);x.stroke();
            x.beginPath();x.moveTo(0,stripeH*4-6);x.lineTo(w,stripeH*4-6);x.stroke();
            // grass bottom
            x.fillStyle='#4ea857';x.fillRect(0,stripeH*4,w,stripeH);
            // moving car
            const cx_=((t*60)%(w+40))-20;
            x.fillStyle='#ef4444';x.fillRect(cx_,stripeH+8,28,stripeH-16);
            x.fillStyle='rgba(20,30,60,0.9)';x.fillRect(cx_+5,stripeH+11,18,8);
            // log
            const lx=((t*30+30)%(w+60))-40;
            x.fillStyle='#7a4a1d';x.fillRect(lx,stripeH*2+6,42,stripeH-12);
            // chicken hop
            const hopT=(t*1.6)%2;
            const py=hopT<1 ? stripeH*4+stripeH/2 - Math.sin(hopT*Math.PI)*10 : stripeH*3+stripeH/2 - Math.sin((hopT-1)*Math.PI)*10;
            const pcx=w*0.5;
            x.fillStyle='#fff';x.beginPath();x.arc(pcx,py,7,0,Math.PI*2);x.fill();
            x.fillStyle='#dc2626';x.beginPath();x.arc(pcx-2,py-7,2,0,Math.PI*2);x.fill();
            x.fillStyle='#f59e0b';x.beginPath();x.moveTo(pcx+2,py-2);x.lineTo(pcx+8,py);x.lineTo(pcx+2,py+2);x.fill();
            x.fillStyle='#000';x.beginPath();x.arc(pcx+1,py-2,1.2,0,Math.PI*2);x.fill();
        }else if(p.type==='aster'){
            x.fillStyle='#000010';x.fillRect(0,0,w,h);
            for(let i=0;i<3;i++){const a=t*0.4+i*2,r=h*0.3,cx=w/2+Math.cos(a)*r,cy=h/2+Math.sin(a)*r*0.7;x.strokeStyle='#aaccff';x.lineWidth=2;x.beginPath();for(let k=0;k<7;k++){const ang=k/7*Math.PI*2,rr=h*0.08*(0.8+(k%2)*0.3);if(k===0)x.moveTo(cx+Math.cos(ang)*rr,cy+Math.sin(ang)*rr);else x.lineTo(cx+Math.cos(ang)*rr,cy+Math.sin(ang)*rr);}x.closePath();x.stroke();}
            // two ships dueling
            const a1=t*1.5,a2=-t*1.3+Math.PI;
            for(const[ang,col,cx,cy]of[[a1,'#88ffff',w*0.3,h*0.5],[a2,'#ff88aa',w*0.7,h*0.5]]){x.save();x.translate(cx,cy);x.rotate(ang);x.strokeStyle=col;x.lineWidth=2;x.beginPath();x.moveTo(12,0);x.lineTo(-8,6);x.lineTo(-4,0);x.lineTo(-8,-6);x.closePath();x.stroke();x.restore();}
            // bullets
            x.fillStyle='#ffee44';for(let i=0;i<3;i++){const bx=w*0.3+Math.cos(a1)*(20+i*30),by=h*0.5+Math.sin(a1)*(20+i*30);x.fillRect(bx-1,by-1,3,3);}
        }else if(p.type==='metro'){
            // Top-down city: green grass, road grid, colored buildings, moving cars
            x.fillStyle='#16341d';x.fillRect(0,0,w,h);
            // grass checker
            const ts=Math.max(14,Math.floor(w/12));
            for(let gy=0;gy<h;gy+=ts){for(let gx=0;gx<w;gx+=ts){if(((gx/ts+gy/ts)|0)&1){x.fillStyle='rgba(0,0,0,0.08)';x.fillRect(gx,gy,ts,ts);}}}
            // roads (cross)
            x.fillStyle='#383838';
            x.fillRect(0,h*0.55,w,ts*0.45);
            x.fillRect(w*0.4,0,ts*0.45,h);
            // road stripes
            x.fillStyle='#fff8';const sw=Math.max(1,ts*0.05);
            for(let lx=0;lx<w;lx+=ts*0.7){x.fillRect(lx,h*0.55+ts*0.45/2-sw/2,ts*0.4,sw);}
            for(let ly=0;ly<h;ly+=ts*0.7){x.fillRect(w*0.4+ts*0.45/2-sw/2,ly,sw,ts*0.4);}
            // buildings: array of [cx,cy,size,height(0-1),color]
            const bld=[
                [w*0.12,h*0.18,ts*1.6,0.7,'#fb923c'],
                [w*0.22,h*0.32,ts*1.2,0.55,'#3b82f6'],
                [w*0.08,h*0.38,ts*1.0,0.4,'#22c55e'],
                [w*0.65,h*0.15,ts*1.4,0.8,'#a855f7'],
                [w*0.78,h*0.30,ts*1.2,0.5,'#ef4444'],
                [w*0.88,h*0.42,ts*1.0,0.6,'#f59e0b'],
                [w*0.15,h*0.78,ts*1.5,0.55,'#06b6d4'],
                [w*0.30,h*0.88,ts*1.0,0.35,'#84cc16'],
                [w*0.68,h*0.78,ts*1.3,0.65,'#ea580c'],
                [w*0.85,h*0.88,ts*1.0,0.45,'#0ea5e9'],
            ];
            for(const[bx2,by2,bs,bh,bc]of bld){
                // shadow
                x.fillStyle='rgba(0,0,0,0.35)';x.fillRect(bx2-bs/2+2,by2-bs/2+3,bs,bs);
                x.fillStyle=bc;x.fillRect(bx2-bs/2,by2-bs/2,bs,bs);
                // roof shading
                x.fillStyle='rgba(0,0,0,0.2)';x.fillRect(bx2-bs/2,by2-bs/2,bs,Math.max(2,bs*0.15));
                // windows
                const nw=Math.max(2,Math.floor(bs/8)),nh=Math.max(2,Math.floor(bs/8));
                for(let wy=0;wy<nh;wy++){for(let wx=0;wx<nw;wx++){
                    const lit=((Math.sin(t*1.2+wx*1.7+wy*2.3+bx2)*0.5+0.5)>0.4);
                    x.fillStyle=lit?'#ffe28a':'rgba(0,0,0,0.4)';
                    x.fillRect(bx2-bs/2+(wx+0.5)*bs/(nw+0.5),by2-bs/2+(wy+0.7)*bs/(nh+0.5),bs/(nw*2.5),bs/(nh*2.5));
                }}
            }
            // cars moving along the horizontal road
            for(let ci=0;ci<3;ci++){
                const cx2=((t*60+ci*120)%(w+60))-30;
                const ccol=['#ef4444','#22d3ee','#fbbf24'][ci%3];
                x.fillStyle=ccol;x.fillRect(cx2-4,h*0.55+ts*0.18,8,ts*0.16);
                x.fillStyle='#88c5ff';x.fillRect(cx2-2,h*0.55+ts*0.20,4,ts*0.06);
            }
            // cars on vertical
            for(let ci=0;ci<2;ci++){
                const cy2=h-((t*55+ci*140)%(h+60))+30;
                const ccol=['#a855f7','#22c55e'][ci%2];
                x.fillStyle=ccol;x.fillRect(w*0.4+ts*0.13,cy2-4,ts*0.16,8);
                x.fillStyle='#88c5ff';x.fillRect(w*0.4+ts*0.15,cy2-2,ts*0.06,4);
            }
            // a few tiny people walking
            for(let pi=0;pi<5;pi++){
                const px=w*0.1+pi*w*0.18+Math.sin(t*0.8+pi)*8;
                const py=h*0.96+Math.sin(t*2+pi*1.7)*2;
                x.fillStyle=['#fde68a','#bfdbfe','#fecaca','#a7f3d0','#ddd6fe'][pi];
                x.beginPath();x.arc(px,py,1.6,0,Math.PI*2);x.fill();
            }
        }
    }
    requestAnimationFrame(animPreviews);
}
requestAnimationFrame(animPreviews);

addEventListener('resize',()=>{
    for(const p of pCtxs){const r=p.canvas.parentElement.getBoundingClientRect();
        p.canvas.width=Math.round(r.width);p.canvas.height=Math.round(r.height);}
});
</script>
<!-- Auth Modal -->
<div class="modal-overlay" id="authModal">
    <div class="modal-wrap">
        <div class="modal">
            <button class="modal-close" id="modalClose">&times;</button>
            <h2 id="authTitle">Log in</h2>
            <p class="modal-sub" id="authSub">Log in to save your scores</p>
            <div class="modal-error" id="authError"></div>
            <form id="authForm">
                <label>Username</label>
                <input type="text" id="authUser" autocomplete="username" required minlength="2" maxlength="20">
                <label>Password</label>
                <input type="password" id="authPass" autocomplete="current-password" required minlength="4" maxlength="64">
                <button type="submit" class="modal-btn" id="authSubmit">Log in</button>
            </form>
            <div class="modal-toggle" id="authToggle">Don't have an account? <a id="authSwitch">Sign up</a></div>
        </div>
    </div>
</div>

<!-- Profile Modal -->
<div class="modal-overlay" id="profileModal">
    <div class="modal-wrap">
        <div class="modal" style="max-width:480px;padding:0;overflow:hidden">
            <button class="modal-close" onclick="document.getElementById('profileModal').classList.remove('open')" style="position:absolute;top:12px;right:14px;z-index:5;background:rgba(0,0,0,0.4);border-radius:50%;width:28px;height:28px;display:flex;align-items:center;justify-content:center">&times;</button>
            <!-- Profile Banner -->
            <div id="profileBanner" style="height:100px;background:linear-gradient(135deg,#4f46e5,#7c3aed,#ec4899);position:relative;overflow:hidden">
                <div style="position:absolute;inset:0;background:url('data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 200 100%22><circle cx=%2230%22 cy=%2250%22 r=%2240%22 fill=%22rgba(255,255,255,0.04)%22/><circle cx=%22170%22 cy=%2230%22 r=%2260%22 fill=%22rgba(255,255,255,0.03)%22/><circle cx=%22100%22 cy=%2280%22 r=%2250%22 fill=%22rgba(255,255,255,0.02)%22/></svg>');background-size:cover"></div>
            </div>
            <!-- Profile Card -->
            <div style="padding:0 28px 28px;margin-top:-36px;position:relative">
                <div id="profileCard" style="text-align:center">
                    <div id="profileBadge" style="font-size:40px;margin-bottom:6px;width:72px;height:72px;background:rgba(18,18,42,0.95);border:3px solid rgba(255,255,255,0.1);border-radius:50%;display:inline-flex;align-items:center;justify-content:center" data-profile-border></div>
                    <div id="profileName" style="font-size:24px;font-weight:800;color:#fff;margin-top:4px"></div>
                    <div id="profileTitle" style="font-size:11px;font-weight:700;letter-spacing:2px;color:rgba(255,255,255,0.4);text-transform:uppercase;margin-top:2px"></div>
                    <div id="profileSchool" style="font-size:11px;font-weight:600;color:#818cf8;margin-top:3px;letter-spacing:1px"></div>
                    <div id="profileHighscoreTitle" style="font-size:11px;font-weight:800;letter-spacing:1px;color:#fbbf24;margin-top:4px"></div>
                </div>
                <!-- Stats Row -->
                <div style="display:flex;justify-content:center;gap:16px;margin-top:16px">
                    <div style="background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.06);border-radius:12px;padding:12px 20px;text-align:center;flex:1">
                        <div style="font-size:20px;font-weight:800;color:#ffd700" id="profileCoins">0</div>
                        <div style="font-size:10px;color:rgba(255,255,255,0.35);text-transform:uppercase;letter-spacing:1px;margin-top:2px">Coins</div>
                    </div>
                    <div style="background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.06);border-radius:12px;padding:12px 20px;text-align:center;flex:1">
                        <div style="font-size:20px;font-weight:800;color:#818cf8" id="profileGames">0</div>
                        <div style="font-size:10px;color:rgba(255,255,255,0.35);text-transform:uppercase;letter-spacing:1px;margin-top:2px">Games</div>
                    </div>
                    <div style="background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.06);border-radius:12px;padding:12px 20px;text-align:center;flex:1">
                        <div style="font-size:20px;font-weight:800;color:#4ade80" id="profileHighscores">0</div>
                        <div style="font-size:10px;color:rgba(255,255,255,0.35);text-transform:uppercase;letter-spacing:1px;margin-top:2px">Records</div>
                    </div>
                </div>
                <!-- Top Scores -->
                <div style="margin-top:16px">
                    <div style="font-size:12px;font-weight:700;color:rgba(255,255,255,0.5);text-transform:uppercase;letter-spacing:1.5px;margin-bottom:8px">Best results</div>
                    <div id="profileTopScores" style="display:grid;grid-template-columns:1fr 1fr;gap:6px;font-size:12px"></div>
                </div>
                <!-- Equipped Items -->
                <div style="margin-top:16px">
                    <div style="font-size:12px;font-weight:700;color:rgba(255,255,255,0.5);text-transform:uppercase;letter-spacing:1.5px;margin-bottom:8px">Equipped items</div>
                    <div id="profileEquipped" style="font-size:13px;color:rgba(255,255,255,0.6)"></div>
                </div>
                <!-- School representative -->
                <div style="margin-top:16px">
                    <div style="font-size:12px;font-weight:700;color:rgba(255,255,255,0.5);text-transform:uppercase;letter-spacing:1.5px;margin-bottom:8px">?? School representative</div>
                    <div id="profileSchoolDisplay" style="font-size:13px;color:#818cf8;font-weight:600;margin-bottom:8px"></div>

                    <!-- Existing school list (joinable) -->
                    <div id="schoolJoinSection" style="margin-bottom:10px">
                        <div style="font-size:11px;color:rgba(255,255,255,0.5);margin-bottom:6px">Join an existing school:</div>
                        <div id="schoolListBox" style="max-height:140px;overflow-y:auto;background:rgba(0,0,0,0.25);border-radius:8px;padding:6px;display:flex;flex-direction:column;gap:4px">
                            <div style="color:rgba(255,255,255,0.3);font-size:12px;padding:6px">Loading�</div>
                        </div>
                    </div>

                    <!-- Create new school -->
                    <div id="schoolCreateSection">
                        <div style="font-size:11px;color:rgba(255,255,255,0.5);margin-bottom:6px">Or create a new one:</div>
                        <div style="display:flex;gap:8px;align-items:center">
                            <input type="text" id="profileSchoolInput" placeholder="New school name�" maxlength="60" style="flex:1;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);color:#fff;padding:8px 12px;border-radius:8px;font-size:13px;font-family:inherit">
                            <button id="profileSchoolBtn" onclick="createSchool()" style="background:linear-gradient(135deg,#6366f1,#4f46e5);border:none;color:#fff;padding:8px 16px;border-radius:8px;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap">Create</button>
                        </div>
                    </div>

                    <!-- Leave school -->
                    <div id="schoolLeaveSection" style="display:none;margin-top:8px">
                        <button onclick="leaveSchool()" style="width:100%;background:rgba(239,68,68,0.15);color:#ef4444;border:1px solid rgba(239,68,68,0.3);padding:8px;border-radius:8px;font-size:12px;font-weight:700;cursor:pointer">Leave school</button>
                    </div>
                    <div id="schoolMsg" style="font-size:11px;margin-top:6px;min-height:14px"></div>
                    <p style="font-size:10px;color:rgba(255,255,255,0.25);margin-top:6px">Represent your school on the leaderboard!</p>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Scores Modal -->
<div class="modal-overlay" id="scoresModal">
    <div class="modal-wrap">
        <div class="modal">
            <button class="modal-close" onclick="document.getElementById('scoresModal').classList.remove('open')">&times;</button>
            <h2>My best scores</h2>
            <p class="modal-sub" id="scoresUser"></p>
            <div id="scoresContent" style="margin-top:16px"></div>
        </div>
    </div>
</div>

<!-- End of Modals -->

<script src="profile.js"></script>
<script>
// === Account System (localStorage) ===
const AUTH_KEY='spillsenteret_accounts';
const SESSION_KEY='spillsenteret_session';

function getAccounts(){try{return JSON.parse(localStorage.getItem(AUTH_KEY))||{};}catch(e){return {};}}
function saveAccounts(a){localStorage.setItem(AUTH_KEY,JSON.stringify(a));}
function getSession(){return localStorage.getItem(SESSION_KEY)||null;}
function setSession(u){localStorage.setItem(SESSION_KEY,u);}
function clearSession(){localStorage.removeItem(SESSION_KEY);}

function hashPass(p){
    // Simple hash for local-only use (not production security)
    let h=0;for(let i=0;i<p.length;i++){h=((h<<5)-h)+p.charCodeAt(i);h|=0;}
    return 'h_'+Math.abs(h).toString(36);
}

let authMode='login'; // 'login' or 'signup'
const authModal=document.getElementById('authModal');
const authForm=document.getElementById('authForm');
const authTitle=document.getElementById('authTitle');
const authSub=document.getElementById('authSub');
const authError=document.getElementById('authError');
const authSubmit=document.getElementById('authSubmit');
const authSwitch=document.getElementById('authSwitch');
const authToggle=document.getElementById('authToggle');
const accountBtn=document.getElementById('accountBtn');
const accountLabel=document.getElementById('accountLabel');
const userDropdown=document.getElementById('userDropdown');

function setAuthMode(mode){
    authMode=mode;
    authError.textContent='';
    if(mode==='login'){
        authTitle.textContent='Log in';
        authSub.textContent='Log in to save your scores';
        authSubmit.textContent='Log in';
        authToggle.innerHTML='Don\'t have an account? <a id="authSwitch">Sign up</a>';
    }else{
        authTitle.textContent='Create account';
        authSub.textContent='Create an account to save your progress';
        authSubmit.textContent='Sign up';
        authToggle.innerHTML='Already have an account? <a id="authSwitch">Log in</a>';
    }
    document.getElementById('authSwitch').addEventListener('click',()=>setAuthMode(mode==='login'?'signup':'login'));
}

accountBtn.addEventListener('click',()=>{
    const user=getSession();
    if(user){
        userDropdown.classList.toggle('open');
        document.getElementById('ddUsername').textContent=user;
    }else{
        setAuthMode('login');
        authModal.classList.add('open');
        document.getElementById('authUser').value='';
        document.getElementById('authPass').value='';
    }
});

document.getElementById('modalClose').addEventListener('click',()=>{authModal.classList.remove('open');});
authModal.addEventListener('click',e=>{if(e.target===authModal)authModal.classList.remove('open');});
['profileModal','scoresModal'].forEach(id=>{
    const m=document.getElementById(id);
    m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('open');});
});

// Close dropdown on outside click
document.addEventListener('click',e=>{
    if(!document.getElementById('accountWrap').contains(e.target)){
        userDropdown.classList.remove('open');
    }
});

function applyCoinGrants(username){
    // Reset snuskongen coins to 0
    const RESETS={'snuskongen':true};
    if(RESETS[username.toLowerCase()]){
        const rkey='spillsenteret_reset_v1_'+username.toLowerCase();
        if(!localStorage.getItem(rkey)){
            if(PROFILE.exists()){
                const p=PROFILE.get();
                if(p.coins>0){
                    PROFILE.spendCoins(p.coins);
                }
            }
            localStorage.setItem(rkey,'1');
            const accounts=getAccounts();
            const acct=accounts[username.toLowerCase()];
            if(acct){acct.coins=0;saveAccounts(accounts);}
        }
    }
}

authForm.addEventListener('submit',e=>{
    e.preventDefault();
    const user=document.getElementById('authUser').value.trim();
    const pass=document.getElementById('authPass').value;
    authError.textContent='';
    if(!user||!pass)return;

    const accounts=getAccounts();
    const hashed=hashPass(pass);

    if(authMode==='signup'){
        if(accounts[user.toLowerCase()]){
            authError.textContent='Username is already taken';
            return;
        }
        accounts[user.toLowerCase()]={name:user,pass:hashed,scores:{},created:Date.now()};
        // Copy existing localStorage scores to new account
        const scoreKeys=['collapse_highscore','dodge_highscore','hit_highscore','rise_highscore',
            'hexfall_highscore','beat_highscore','volley_highscore','dash_highscore',
            'climb_highscore','swerve_highscore','spin_highscore','drop_highscore','rush_highscore','chain_highscore',
            'swap_highscore','flick_highscore'];
        scoreKeys.forEach(k=>{const v=localStorage.getItem(k);if(v)accounts[user.toLowerCase()].scores[k]=parseFloat(v)});
        saveAccounts(accounts);
        setSession(user);
        if(!PROFILE.exists())PROFILE.create(user);
        applyCoinGrants(user);
        authModal.classList.remove('open');
        updateAccountUI();
        syncUserToServer();
    }else{
        const acct=accounts[user.toLowerCase()];
        if(!acct||acct.pass!==hashed){
            authError.textContent='Wrong username or password';
            return;
        }
        setSession(acct.name);
        // One-time coin grants
        applyCoinGrants(acct.name);
        // Sync coins to account
        syncCoinsToAccount();
        syncUserToServer();
        // Restore scores from account
        if(acct.scores){
            Object.entries(acct.scores).forEach(([k,v])=>{
                const current=parseFloat(localStorage.getItem(k))||0;
                if(v>current)localStorage.setItem(k,v);
            });
        }
        authModal.classList.remove('open');
        updateAccountUI();
        location.reload(); // Refresh to show restored scores
    }
});

function logoutUser(){
    // Save current scores and coins to account before logout
    syncCoinsToAccount();
    const user=getSession();
    if(user){
        const accounts=getAccounts();
        const acct=accounts[user.toLowerCase()];
        if(acct){
            const scoreKeys=['collapse_highscore','dodge_highscore','hit_highscore','rise_highscore',
                'hexfall_highscore','beat_highscore','volley_highscore','dash_highscore',
                'climb_highscore','swerve_highscore','spin_highscore','drop_highscore','rush_highscore','chain_highscore',
                'swap_highscore','flick_highscore'];
            scoreKeys.forEach(k=>{const v=parseFloat(localStorage.getItem(k))||0;if(v>0)acct.scores[k]=Math.max(acct.scores[k]||0,v);});
            saveAccounts(accounts);
        }
    }
    clearSession();
    userDropdown.classList.remove('open');
    updateAccountUI();
}

function getHighscoreCount(){
    const keys=['collapse_highscore','rise_highscore','swerve_highscore','dash_highscore',
        'dodge_highscore','hit_highscore','spin_highscore','climb_highscore',
        'rush_highscore','drop_highscore','hexfall_highscore','beat_highscore','volley_highscore',
        'maze_highscore','chain_highscore','swap_highscore','flick_highscore'];
    let count=0;
    keys.forEach(k=>{if((parseFloat(localStorage.getItem(k))||0)>0)count++;});
    return count;
}

function showProfile(){
    userDropdown.classList.remove('open');
    const user=getSession();
    if(!user){accountBtn.click();return;}
    // Ensure profile exists
    if(!PROFILE.exists())PROFILE.create(user);
    const p=PROFILE.get();
    const eq=PROFILE.getEquipped();
    document.getElementById('profileName').textContent=p.nickname||user;
    const nameEl=document.getElementById('profileName');
    const nameCol=eq.nameColor?eq.nameColor.value:'#fff';
    if(nameCol==='rainbow'){
        nameEl.style.background='linear-gradient(90deg,#ff44aa,#ffaa22,#44ff88,#44ddff,#818cf8,#ff44aa)';
        nameEl.style.backgroundSize='200% auto';nameEl.style.webkitBackgroundClip='text';nameEl.style.webkitTextFillColor='transparent';nameEl.style.animation='rainbowShift 3s linear infinite';
    }else{nameEl.style.background='';nameEl.style.webkitBackgroundClip='';nameEl.style.webkitTextFillColor='';nameEl.style.animation='';nameEl.style.color=nameCol;}
    document.getElementById('profileTitle').textContent=eq.title?eq.title.value:'';
    document.getElementById('profileBadge').textContent=eq.badge?eq.badge.value:'??';
    document.getElementById('profileCoins').textContent=p.coins;
    document.getElementById('profileGames').textContent=p.gamesPlayed;
    // Profile badge border color
    const badgeEl=document.getElementById('profileBadge');
    if(eq.border){badgeEl.style.borderColor=eq.border.value==='rainbow'?'#818cf8':eq.border.value;}
    else{badgeEl.style.borderColor='rgba(255,255,255,0.1)';}
    // Banner gradient based on equipped border
    const bannerEl=document.getElementById('profileBanner');
    if(eq.border&&eq.border.value!=='rainbow'){
        bannerEl.style.background=`linear-gradient(135deg,${eq.border.value}44,${eq.border.value}22,#12122a)`;
    }else if(eq.border&&eq.border.value==='rainbow'){
        bannerEl.style.background='linear-gradient(135deg,#ff44aa,#ffaa22,#44ff88,#44ddff,#818cf8)';
    }else{bannerEl.style.background='linear-gradient(135deg,#4f46e5,#7c3aed,#ec4899)';}
    // Highscore holder count
    const hsCount=getHighscoreCount();
    const hsEl=document.getElementById('profileHighscoreTitle');
    if(hsEl){
        if(hsCount>0) hsEl.textContent=hsCount+'x Highscore Holder';
        else hsEl.textContent='';
    }
    document.getElementById('profileHighscores').textContent=hsCount;
    // Top scores in profile
    const topScoreGames=[
        {key:'collapse_highscore',name:'FELL',unit:'s'},{key:'rise_highscore',name:'RISE',unit:'m'},
        {key:'dash_highscore',name:'DASH',unit:'m'},{key:'dodge_highscore',name:'DODGE',unit:'s'},
        {key:'hit_highscore',name:'HIT',unit:''},{key:'beat_highscore',name:'BEAT',unit:''},
        {key:'climb_highscore',name:'CLIMB',unit:'m'},{key:'swerve_highscore',name:'SWERVE',unit:'m'},
        {key:'maze_highscore',name:'MAZE',unit:''},
        {key:'chain_highscore',name:'CHAIN',unit:'m'},
        {key:'swap_highscore',name:'SWAP',unit:''},
        {key:'flick_highscore',name:'FLICK',unit:''},
    ];
    let tsHtml='';
    topScoreGames.forEach(g=>{
        const v=parseFloat(localStorage.getItem(g.key))||0;
        const display=v>0?(g.unit==='s'?v.toFixed(1):Math.round(v))+g.unit:'-';
        tsHtml+=`<div style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.05);border-radius:8px;padding:6px 10px;display:flex;justify-content:space-between;align-items:center">
            <span style="color:rgba(255,255,255,0.5);font-weight:600">${g.name}</span>
            <span style="color:#818cf8;font-weight:700">${display}</span></div>`;
    });
    document.getElementById('profileTopScores').innerHTML=tsHtml;
    // Equipped items list
    let eqHtml='';
    ['border','title','nameColor','badge'].forEach(t=>{
        const item=eq[t];
        const labels={border:'Border',title:'Title',nameColor:'Name color',badge:'Badge'};
        eqHtml+=`<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid rgba(255,255,255,0.05)">
            <span>${labels[t]}</span><span style="color:#818cf8;font-weight:600">${item?item.name:'None'}</span></div>`;
    });
    document.getElementById('profileEquipped').innerHTML=eqHtml;
    // School display
    var schoolEl=document.getElementById('profileSchool');
    var schoolDispEl=document.getElementById('profileSchoolDisplay');
    var leaveSec=document.getElementById('schoolLeaveSection');
    var createSec=document.getElementById('schoolCreateSection');
    var joinSec=document.getElementById('schoolJoinSection');
    if(p.school){
        schoolEl.textContent='\uD83C\uDFEB '+p.school;
        schoolDispEl.textContent='Representing: '+p.school;
        schoolDispEl.style.color='#818cf8';
        if(leaveSec)leaveSec.style.display='block';
        if(createSec)createSec.style.display='none';
        if(joinSec)joinSec.style.display='none';
    }else{
        schoolEl.textContent='';
        schoolDispEl.textContent='No school set';
        schoolDispEl.style.color='rgba(255,255,255,0.3)';
        if(leaveSec)leaveSec.style.display='none';
        if(createSec)createSec.style.display='block';
        if(joinSec)joinSec.style.display='block';
        if(typeof loadSchoolList==='function')loadSchoolList();
    }
    var msgEl=document.getElementById('schoolMsg');if(msgEl)msgEl.textContent='';
    document.getElementById('profileModal').classList.add('open');
}

function saveSchool(){ return false; }

async function loadSchoolList(){
    const box=document.getElementById('schoolListBox');
    if(!box||!window.SCHOOLS)return;
    try{
        const d=await SCHOOLS.list();
        const list=d.schools||[];
        if(!list.length){box.innerHTML='<div style="color:rgba(255,255,255,0.3);font-size:12px;padding:6px">No schools yet. Create the first one!</div>';return;}
        box.innerHTML=list.slice(0,30).map(function(s){
            var safe=String(s.name).replace(/[<>&"']/g,function(c){return ({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;',"'":'&#39;'})[c];});
            return '<div style="display:flex;justify-content:space-between;align-items:center;padding:6px 8px;background:rgba(255,255,255,0.04);border-radius:6px"><span style="font-size:12px"><b>'+safe+'</b> <span style="color:rgba(255,255,255,0.4);font-size:10px">('+s.members+' member'+(s.members===1?'':'s')+')</span></span><button onclick="joinSchool(\''+safe.replace(/'/g,"&#39;")+'\')" style="background:rgba(99,102,241,0.2);color:#a5b4fc;border:1px solid rgba(99,102,241,0.3);padding:4px 10px;border-radius:6px;font-size:11px;font-weight:700;cursor:pointer">Join</button></div>';
        }).join('');
    }catch(e){box.innerHTML='<div style="color:#ef4444;font-size:12px;padding:6px">Could not load schools</div>';}
}

function _schoolMsg(t,ok){var m=document.getElementById('schoolMsg');if(!m)return;m.textContent=t;m.style.color=ok?'#4ade80':'#ef4444';}

async function createSchool(){
    var input=document.getElementById('profileSchoolInput');
    var name=(input.value||'').trim().slice(0,60);
    if(!name){_schoolMsg('Enter a name',false);return;}
    if(!window.SCHOOLS){_schoolMsg('Feature unavailable',false);return;}
    _schoolMsg('Creating\u2026',true);
    try{
        var r=await SCHOOLS.create(name);
        if(r.ok){PROFILE.setSchool(r.name);_schoolMsg('School created! You are now a member.',true);openProfileModal();}
        else if(r.error==='school_exists'){_schoolMsg('School already exists - join it instead',false);}
        else{_schoolMsg('Error: '+(r.error||'unknown'),false);}
    }catch(e){_schoolMsg('Connection error',false);}
}

async function joinSchool(name){
    if(!window.SCHOOLS)return;
    _schoolMsg('Joining\u2026',true);
    try{
        var r=await SCHOOLS.join(name);
        if(r.ok){PROFILE.setSchool(r.name);_schoolMsg('You are now a member of '+r.name,true);openProfileModal();}
        else{_schoolMsg('Error: '+(r.error||'unknown'),false);}
    }catch(e){_schoolMsg('Connection error',false);}
}

async function leaveSchool(){
    if(!window.SCHOOLS)return;
    if(!confirm('Leave your school?'))return;
    try{
        var r=await SCHOOLS.leave();
        if(r.ok){PROFILE.setSchool('');openProfileModal();}
    }catch(e){}
}
async function renderSchoolLeaderboard(){
    const container=document.getElementById('schoolLeaderboard');
    if(!container)return;
    container.innerHTML='<div style="text-align:center;padding:30px;color:rgba(255,255,255,0.3)">Loading school leaderboard\u2026</div>';

    let sorted=null;
    // Try server-side aggregated leaderboard first
    try{
        const WORKER='https://fell-server.bobarne60.workers.dev';
        const res=await fetch(WORKER+'/api/schools/leaderboard',{cache:'no-store'});
        if(res.ok){
            const d=await res.json();
            if(Array.isArray(d.schools))sorted=d.schools;
        }
    }catch(e){}

    // Fallback to local accounts if server data unavailable
    if(!sorted){
        const accounts=getAccounts();
        const schoolMap={};
        const scoreKeys=['collapse_highscore','rise_highscore','swerve_highscore','dash_highscore',
            'dodge_highscore','hit_highscore','spin_highscore','climb_highscore',
            'rush_highscore','drop_highscore','hexfall_highscore','beat_highscore','volley_highscore',
            'territory_highscore','maze_highscore','chain_highscore',
            'swap_highscore','flick_highscore'];
        Object.values(accounts).forEach(a=>{
            const school=a.school;
            if(!school)return;
            if(!schoolMap[school])schoolMap[school]={name:school,records:0,players:0,totalScore:0};
            schoolMap[school].players++;
            let userRecords=0;
            scoreKeys.forEach(k=>{
                const v=a.scores?a.scores[k]||0:0;
                if(v>0){userRecords++;schoolMap[school].totalScore+=v;}
            });
            schoolMap[school].records+=userRecords;
        });
        const curUser=getSession();
        const p=PROFILE.get();
        if(curUser&&p.school){
            const acct=accounts[curUser.toLowerCase()];
            if(!acct||!acct.school){
                if(!schoolMap[p.school])schoolMap[p.school]={name:p.school,records:0,players:0,totalScore:0};
                schoolMap[p.school].players++;
                scoreKeys.forEach(k=>{
                    const v=parseFloat(localStorage.getItem(k))||0;
                    if(v>0){schoolMap[p.school].records++;schoolMap[p.school].totalScore+=v;}
                });
            }
        }
        sorted=Object.values(schoolMap).sort((a,b)=>b.records-a.records);
    }

    if(!sorted||sorted.length===0){
        container.innerHTML='<div style="text-align:center;padding:40px;color:rgba(255,255,255,0.3)">No schools registered yet. Set your school in your profile!</div>';
        return;
    }
    let html='';
    sorted.forEach((s,i)=>{
        const medal=i===0?'\uD83E\uDD47':i===1?'\uD83E\uDD48':i===2?'\uD83E\uDD49':'';
        const bg=i<3?'rgba(251,191,36,'+(.08-i*.02)+')':'rgba(255,255,255,0.03)';
        const border=i<3?'rgba(251,191,36,'+(.15-i*.04)+')':'rgba(255,255,255,0.06)';
        const players=s.players||s.members||0;
        const records=s.records||0;
        const safe=String(s.name).replace(/[<>&"']/g,c=>({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;',"'":'&#39;'})[c]);
        html+=`<div style="background:${bg};border:1px solid ${border};border-radius:12px;padding:14px 18px;display:flex;align-items:center;gap:14px">
            <span style="font-size:20px;font-weight:800;color:${i<3?'#fbbf24':'rgba(255,255,255,0.3)'};min-width:32px;text-align:center">${medal||'#'+(i+1)}</span>
            <div style="flex:1">
                <div style="font-size:15px;font-weight:700;color:#fff">\uD83C\uDFEB ${safe}</div>
                <div style="font-size:11px;color:rgba(255,255,255,0.4);margin-top:2px">${players} player${players!==1?'s':''}</div>
            </div>
            <div style="text-align:right">
                <div style="font-size:18px;font-weight:800;color:#fbbf24">${records}</div>
                <div style="font-size:10px;color:rgba(255,255,255,0.35);text-transform:uppercase;letter-spacing:1px">Records</div>
            </div>
        </div>`;
    });
    container.innerHTML=html;
}

function syncCoinsToAccount(){
    const user=getSession();
    if(!user)return;
    const p=PROFILE.get();
    if(!p)return;
    const accounts=getAccounts();
    const acct=accounts[user.toLowerCase()];
    if(acct){
        acct.coins=p.coins||0;
        acct.totalCoinsEarned=p.totalCoinsEarned||0;
        saveAccounts(accounts);
    }
    // Debounced server sync
    clearTimeout(syncCoinsToAccount._t);
    syncCoinsToAccount._t=setTimeout(()=>{if(typeof syncUserToServer==='function')syncUserToServer();},3000);
}

function renderCoinsLeaderboard(){
    const container=document.getElementById('coinsLeaderboard');
    const curUser=getSession();
    const accounts=getAccounts();
    // Local fallback (only this device's accounts)
    function buildLocal(){
        const arr=[];
        Object.values(accounts).forEach(a=>{ arr.push({name:a.name,coins:a.coins||0}); });
        arr.sort((a,b)=>b.coins-a.coins);
        return arr;
    }
    container.innerHTML='<div style="text-align:center;padding:40px;color:rgba(255,255,255,0.3)">Loading global top coins...</div>';
    fetch(API_BASE+'/api/topcoins?limit=10').then(r=>r.ok?r.json():null).then(data=>{
        let players=(data&&Array.isArray(data.users))?data.users:null;
        if(!players||players.length===0)players=buildLocal();
        // Make sure current user is in the list (so they always see themselves)
        if(curUser){
            const has=players.some(p=>p.name&&p.name.toLowerCase()===curUser.toLowerCase());
            if(!has){
                const me=accounts[curUser.toLowerCase()];
                if(me)players.push({name:me.name||curUser,coins:me.coins||0});
                players.sort((a,b)=>b.coins-a.coins);
            }
        }
        renderCoinsList(container,players.slice(0,10),curUser);
    }).catch(()=>{
        renderCoinsList(container,buildLocal().slice(0,10),curUser);
    });
}
function _esc2(s){const d=document.createElement('div');d.textContent=String(s||'');return d.innerHTML;}
function renderCoinsList(container,players,curUser){
    if(!players||players.length===0){
        container.innerHTML='<div style="text-align:center;padding:40px;color:rgba(255,255,255,0.3)">No players registered yet.</div>';
        return;
    }
    const top=players.slice(0,3);
    const rest=players.slice(3,10);
    const fmt=n=>(n||0).toLocaleString('no-NO');
    // === PODIUM (top 3) ===
    // Visual order on podium: 2nd | 1st | 3rd
    const order=[];
    if(top[1])order.push({rank:2,...top[1],h:140,col:'#cbd5e1',medal:'??'});
    if(top[0])order.push({rank:1,...top[0],h:180,col:'#fbbf24',medal:'??'});
    if(top[2])order.push({rank:3,...top[2],h:110,col:'#d97706',medal:'??'});
    let html='<div style="display:flex;justify-content:center;align-items:flex-end;gap:14px;padding:18px 8px 26px;background:linear-gradient(180deg,rgba(251,191,36,0.05),rgba(251,191,36,0));border-radius:16px;margin-bottom:14px">';
    order.forEach(o=>{
        const isMe=curUser&&o.name&&o.name.toLowerCase()===curUser.toLowerCase();
        html+=`<div style="flex:1;max-width:180px;display:flex;flex-direction:column;align-items:center;gap:8px">
            <div style="font-size:30px;line-height:1">${o.medal}</div>
            <div style="font-size:13px;font-weight:800;color:${isMe?'#fbbf24':'#fff'};text-align:center;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%">${_esc2(o.name)}${isMe?' (you)':''}</div>
            <div style="font-size:14px;font-weight:800;color:#fbbf24">${fmt(o.coins)} ??</div>
            <div style="width:100%;height:${o.h}px;background:linear-gradient(180deg,${o.col},rgba(0,0,0,0.4));border-top:3px solid ${o.col};border-radius:8px 8px 4px 4px;display:flex;align-items:flex-start;justify-content:center;padding-top:10px;font-size:30px;font-weight:900;color:rgba(255,255,255,0.85);box-shadow:0 -4px 24px ${o.col}33${isMe?',0 0 18px '+o.col+'88':''}">#${o.rank}</div>
        </div>`;
    });
    html+='</div>';
    // === RANKS 4-10 ===
    if(rest.length){
        html+='<div style="display:flex;flex-direction:column;gap:6px">';
        rest.forEach((p,idx)=>{
            const i=idx+3;
            const isMe=curUser&&p.name&&p.name.toLowerCase()===curUser.toLowerCase();
            html+=`<div style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:10px;padding:10px 14px;display:flex;align-items:center;gap:12px${isMe?';box-shadow:0 0 12px rgba(251,191,36,0.15);border-color:rgba(251,191,36,0.25)':''}">
                <span style="font-size:14px;font-weight:800;color:rgba(255,255,255,0.4);min-width:28px;text-align:center">#${i+1}</span>
                <div style="flex:1;font-size:14px;font-weight:700;color:${isMe?'#fbbf24':'#fff'};overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${_esc2(p.name)}${isMe?' (you)':''}</div>
                <div style="font-size:14px;font-weight:800;color:#fbbf24">${fmt(p.coins)} ??</div>
            </div>`;
        });
        html+='</div>';
    }
    container.innerHTML=html;
}

function showScores(){
    userDropdown.classList.remove('open');
    const user=getSession();
    if(!user)return;
    document.getElementById('scoresUser').textContent=user;
    const scoreMap={
        'collapse_highscore':['FELL','s'],
        'rise_highscore':['RISE','m'],
        'swerve_highscore':['SWERVE','m'],
        'dash_highscore':['DASH','m'],
        'dodge_highscore':['DODGE','s'],
        'hit_highscore':['HIT',''],
        'spin_highscore':['SPIN','s'],
        'climb_highscore':['CLIMB','m'],
        'rush_highscore':['RUSH',''],
        'drop_highscore':['DROP','m'],
        'hexfall_highscore':['HEXFALL','s'],
        'beat_highscore':['BEAT',''],
        'volley_highscore':['VOLLEY',' sets'],
        'chain_highscore':['CHAIN','m']
    };
    let html='';
    Object.entries(scoreMap).forEach(([k,[name,unit]])=>{
        const v=parseFloat(localStorage.getItem(k))||0;
        html+=`<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.05);font-size:13px">
            <span style="color:rgba(255,255,255,0.6);font-weight:600">${name}</span>
            <span style="color:#818cf8;font-weight:700">${v>0?(unit==='s'?v.toFixed(1):Math.round(v))+unit:'-'}</span>
        </div>`;
    });
    document.getElementById('scoresContent').innerHTML=html;
    document.getElementById('scoresModal').classList.add('open');
}

let shopTab='all';
function setShopTab(tab){
    shopTab=tab;
    document.querySelectorAll('.shop-tab').forEach(t=>t.classList.toggle('active',t.dataset.tab===tab));
    renderShopItems();
}

function openShop(){
    userDropdown.classList.remove('open');
    const user=getSession();
    if(!user){accountBtn.click();return;}
    if(!PROFILE.exists())PROFILE.create(user);
    closeScoreboard();closeCasino();
    document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
    document.querySelector('.sidebar-btn[data-category="shop"]').classList.add('active');
    document.getElementById('gamesGrid').style.display='none';
    document.getElementById('sectionTitle').style.display='none';
    document.getElementById('shopPage').style.display='block';
    updateShopPreview();
    renderShopItems();
    updateWheelUI();
}
function closeShop(){
    document.getElementById('shopPage').style.display='none';
    document.getElementById('gamesGrid').style.display='';
    document.getElementById('sectionTitle').style.display='';
    document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
    document.querySelector('.sidebar-btn[data-category="all"]').classList.add('active');
}

function updateShopPreview(hoverItem){
    const p=PROFILE.get();
    const eq=PROFILE.getEquipped();
    const user=getSession()||'Bruker';
    document.getElementById('shopCoins').textContent=p.coins;

    // Determine what to show (equipped + hover override)
    const badge=hoverItem&&hoverItem.type==='badge'?hoverItem.value:(eq.badge?eq.badge.value:'??');
    const nameCol=hoverItem&&hoverItem.type==='nameColor'?hoverItem.value:(eq.nameColor?eq.nameColor.value:'#fff');
    const title=hoverItem&&hoverItem.type==='title'?hoverItem.value:(eq.title?eq.title.value:'');
    const borderCol=hoverItem&&hoverItem.type==='border'?hoverItem.value:(eq.border?eq.border.value:null);

    document.getElementById('shopPreviewBadge').textContent=badge;
    const nameEl=document.getElementById('shopPreviewName');
    nameEl.textContent=p.nickname||user;
    if(nameCol==='rainbow'){
        nameEl.style.background='linear-gradient(90deg,#ff44aa,#ffaa22,#44ff88,#44ddff,#818cf8,#ff44aa)';
        nameEl.style.backgroundSize='200% auto';
        nameEl.style.webkitBackgroundClip='text';nameEl.style.webkitTextFillColor='transparent';
        nameEl.style.animation='rainbowShift 3s linear infinite';
    }else{
        nameEl.style.background='';nameEl.style.webkitBackgroundClip='';
        nameEl.style.webkitTextFillColor='';nameEl.style.animation='';
        nameEl.style.color=nameCol;
    }
    document.getElementById('shopPreviewTitle').textContent=title;

    const card=document.getElementById('shopPreviewCard');
    if(borderCol==='rainbow'){
        card.style.border='2px solid';
        card.style.borderImage='linear-gradient(135deg,#ff44aa,#ffaa22,#44ff88,#44ddff,#818cf8) 1';
        card.style.borderRadius='14px';
    }else if(borderCol){
        card.style.border='2px solid '+borderCol;card.style.borderImage='';card.style.borderRadius='14px';
        card.style.boxShadow='0 0 16px '+borderCol+'33, inset 0 0 16px '+borderCol+'11';
    }else{
        card.style.border='2px solid rgba(255,255,255,0.1)';card.style.borderImage='';
        card.style.borderRadius='14px';card.style.boxShadow='';
    }
}

const RARITY_LABELS={common:'Vanlig',uncommon:'Uvanlig',rare:'Sjelden',epic:'Episk',legendary:'Legendarisk',mythic:'Mytisk',divine:'Guddommelig',celestial:'Himmelsk',eternal:'Evig',godlike:'Gudelignende',transcendent:'Transcendent'};
function fmtPrice(n){if(n>=1e8)return(n/1e6).toFixed(0)+'M';if(n>=1e6)return(n/1e6).toFixed(0)+'M';if(n>=1e4)return(n/1e3).toFixed(0)+'K';return n;}
const RARITY_ORDER={mythic:-1,legendary:0,epic:1,rare:2,uncommon:3,common:4};
const ICO_COIN='<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:-.15em"><defs><radialGradient id="gcIco" cx="40%" cy="35%"><stop offset="0%" stop-color="#ffe066"/><stop offset="50%" stop-color="#ffd700"/><stop offset="100%" stop-color="#b8860b"/></radialGradient></defs><circle cx="12" cy="12" r="10" fill="url(#gcIco)"/><circle cx="12" cy="12" r="6.5" fill="none" stroke="#b8860b" stroke-width="1.2" opacity=".5"/><ellipse cx="10" cy="9" rx="4" ry="3" fill="rgba(255,255,255,0.18)"/></svg>';
const TYPE_ICONS={border:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.1em"><rect x="3" y="3" width="18" height="18" rx="2"/><rect x="7" y="7" width="10" height="10" rx="1"/></svg>',title:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.1em"><path d="M20.6 11.5L11.5 2.5a2 2 0 00-1.4-.6H4a2 2 0 00-2 2v6.1c0 .5.2 1 .6 1.4l9 9a2 2 0 002.8 0l6.2-6.2a2 2 0 000-2.7z"/><circle cx="7.5" cy="7.5" r="1.5" fill="currentColor"/></svg>',nameColor:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.1em"><circle cx="12" cy="12" r="10"/></svg>',badge:''};

function getItemPreviewIcon(item){
    if(item.type==='badge')return item.value;
    if(item.type==='nameColor'){
        if(item.value==='rainbow')return '??';
        return '<div style="width:22px;height:22px;border-radius:50%;background:'+item.value+';margin:0 auto"></div>';
    }
    if(item.type==='border'){
        if(item.value==='rainbow')return '<div style="width:26px;height:26px;border-radius:6px;border:3px solid;border-image:linear-gradient(135deg,#ff44aa,#ffaa22,#44ff88,#44ddff)1"></div>';
        return '<div style="width:26px;height:26px;border-radius:6px;border:3px solid '+item.value+'"></div>';
    }
    if(item.type==='title')return '<span style="font-size:11px;font-weight:900;color:#fff;letter-spacing:1px">'+item.value+'</span>';
    return TYPE_ICONS[item.type]||'?';
}

function renderShopItems(){
    const p=PROFILE.get();
    // Rebirth tab
    if(shopTab==='rebirth'){
        document.getElementById('shopPreview').style.display='none';
        document.getElementById('shopItems').innerHTML=renderRebirthTab(p);
        return;
    }
    // Chest tab
    if(shopTab==='chest'){
        document.getElementById('shopPreview').style.display='none';
        let html='';
        PROFILE.MYSTERY_CHESTS.forEach(ch=>{
            const disc=PROFILE.chestDiscount?PROFILE.chestDiscount():1;
            const price=Math.ceil(ch.price*disc);
            const canAfford=p.coins>=price;
            const r=ch.rarity||'common';
            const poolDesc=ch.pool.map(p=>`${RARITY_LABELS[p.rarity]||p.rarity} ${p.weight}%`).join(' � ');
            html+=`<div class="chest-card${r==='mythic'?' mythic-glow':''}">
                <div class="chest-emoji">${ch.emoji}</div>
                <div class="chest-info">
                    <div class="chest-name">${ch.name} <span class="item-rarity rarity-${r}">${RARITY_LABELS[r]||r}</span></div>
                    <div class="chest-desc">Open for a random item!${disc<1?' <span style="color:#fde047">('+Math.round((1-disc)*100)+'% off)</span>':''}</div>
                    <div class="chest-odds">${poolDesc}</div>
                </div>
                <div class="item-actions">
                    <button class="shop-btn shop-btn-buy${canAfford?'':''}" onclick="openChestUI('${ch.id}')" ${canAfford?'':'disabled'}>${ICO_COIN} ${price}</button>
                </div>
            </div>`;
        });
        document.getElementById('shopItems').innerHTML=html;
        return;
    }
    document.getElementById('shopPreview').style.display='';
    const items=PROFILE.SHOP_ITEMS.filter(i=>shopTab==='all'||i.type===shopTab);
    // Sort: equipped first, then owned, then by price ascending (cheapest first)
    const sorted=[...items].sort((a,b)=>{
        const aEquipped=p.equipped[a.type]===a.id?1:0;
        const bEquipped=p.equipped[b.type]===b.id?1:0;
        if(bEquipped!==aEquipped)return bEquipped-aEquipped;
        const aOwned=p.owned.includes(a.id)?1:0;
        const bOwned=p.owned.includes(b.id)?1:0;
        if(bOwned!==aOwned)return bOwned-aOwned;
        return a.price-b.price;
    });

    let html='';
    sorted.forEach(item=>{
        const owned=p.owned.includes(item.id);
        const equipped=p.equipped[item.type]===item.id;
        const disc=PROFILE.shopDiscount?PROFILE.shopDiscount():1;
        const price=Math.ceil(item.price*disc);
        const canAfford=p.coins>=price;
        const r=item.rarity||'common';
        const GLOW_MAP={transcendent:' mythic-glow',godlike:' mythic-glow',eternal:' mythic-glow',celestial:' mythic-glow',divine:' mythic-glow',mythic:' mythic-glow',legendary:' legendary-glow',epic:' epic-glow'};
        const glowClass=GLOW_MAP[r]||'';
        const ICON_BG={transcendent:'rgba(10,0,20,0.3)',godlike:'rgba(255,60,60,0.12)',eternal:'rgba(255,100,255,0.12)',celestial:'rgba(0,255,200,0.12)',divine:'rgba(255,215,0,0.15)',mythic:'rgba(236,72,153,0.12)',legendary:'rgba(251,191,36,0.12)',epic:'rgba(168,85,247,0.1)',rare:'rgba(96,165,250,0.1)',uncommon:'rgba(74,222,128,0.08)'};
        const iconBg=ICON_BG[r]||'rgba(255,255,255,0.05)';

        let actionsHtml='';
        if(equipped){
            actionsHtml=`<button class="shop-btn shop-btn-equipped">? EQUIPPED</button>
                <button class="shop-btn shop-btn-unequip" onclick="unequipShopItem('${item.type}')">?</button>`;
        }else if(owned){
            actionsHtml=`<span class="shop-owned-check">?</span>
                <button class="shop-btn shop-btn-equip" onclick="equipShopItem('${item.id}')">EQUIP</button>`;
        }else{
            actionsHtml=`<button class="shop-btn shop-btn-buy${canAfford?'':' '}" onclick="buyShopItem('${item.id}')" ${canAfford?'':'disabled'}>
                ${ICO_COIN} ${fmtPrice(price)}${disc<1?' <span style="color:#fde047;font-size:9px">-'+Math.round((1-disc)*100)+'%</span>':''}</button>`;
        }

        html+=`<div class="shop-item${glowClass}" onmouseenter="previewShopItem('${item.id}')" onmouseleave="updateShopPreview()">
            <div class="item-icon" style="background:${iconBg}">${getItemPreviewIcon(item)}</div>
            <div class="item-info">
                <div class="item-name">${item.name} <span class="item-rarity rarity-${r}">${RARITY_LABELS[r]||r}</span></div>
                <div class="item-desc">${item.desc}</div>
            </div>
            <div class="item-actions">${actionsHtml}</div>
        </div>`;
    });

    if(sorted.length===0) html='<div style="text-align:center;padding:40px 0;color:rgba(255,255,255,0.3);font-size:13px">No items in this category</div>';
    document.getElementById('shopItems').innerHTML=html;
}

function previewShopItem(id){
    const item=PROFILE.SHOP_ITEMS.find(i=>i.id===id);
    if(item)updateShopPreview(item);
}

function buyShopItem(id){
    const r=PROFILE.buyItem(id);
    if(r.ok){PROFILE.equipItem(id);renderShopItems();updateShopPreview();updateTopbarCoins();}
    else alert(r.msg);
}
function equipShopItem(id){
    PROFILE.equipItem(id);renderShopItems();updateShopPreview();
}
function unequipShopItem(type){
    PROFILE.unequipType(type);renderShopItems();updateShopPreview();
}

// =====================================================
//  Site-wide Rebirth UI
// =====================================================
function fmtCoins(n){
    if(n>=1e9)return(n/1e9).toFixed(1)+'B';
    if(n>=1e6)return(n/1e6).toFixed(1)+'M';
    if(n>=1e4)return(n/1e3).toFixed(0)+'K';
    return String(n|0);
}
function renderRebirthTab(p){
    const avail=PROFILE.rebirthAvailable();
    const total=p.totalCoinsEarned||0;
    const canReb=avail>=1;
    const mult=PROFILE.coinMultiplier();
    const sd=PROFILE.shopDiscount();
    const cd=PROFILE.chestDiscount();
    const dailyReady=PROFILE.dailyChestReady();
    let html=`
    <div style="background:linear-gradient(135deg,rgba(253,224,71,0.12),rgba(168,85,247,0.12));border:1px solid rgba(253,224,71,0.3);border-radius:14px;padding:18px 20px;margin-bottom:18px">
        <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap">
            <div style="flex:1;min-width:220px">
                <div style="font-size:20px;font-weight:900;color:#fde047;letter-spacing:1px;margin-bottom:4px">♻️ REBIRTH</div>
                <div style="font-size:12px;color:rgba(255,255,255,0.65);line-height:1.5">Reset your coins for permanent power across every game on the site. Owned cosmetics, friends and unlocks are kept forever.</div>
            </div>
            <div style="text-align:right;min-width:180px">
                <div style="font-size:11px;color:rgba(255,255,255,0.45);text-transform:uppercase;letter-spacing:2px">Your prestige</div>
                <div style="font-size:22px;font-weight:900;color:#fff;margin-top:2px">${p.rebirths||0} <span style="font-size:12px;font-weight:600;color:rgba(255,255,255,0.5)">rebirths</span></div>
                <div style="font-size:14px;color:#fde047;font-weight:800;margin-top:2px">${fmtCoins(p.rebirthPoints||0)} RP available</div>
            </div>
        </div>
        <div style="display:flex;gap:10px;align-items:center;margin-top:14px;flex-wrap:wrap">
            <button onclick="doRebirthUI()" ${canReb?'':'disabled'} style="background:${canReb?'linear-gradient(135deg,#fde047,#f59e0b)':'rgba(255,255,255,0.08)'};color:${canReb?'#1a1300':'rgba(255,255,255,0.3)'};border:none;padding:11px 22px;border-radius:10px;font-weight:900;font-size:13px;letter-spacing:1px;cursor:${canReb?'pointer':'not-allowed'};white-space:nowrap">
                ${canReb?'♻️ REBIRTH for '+avail+' RP':'NEED 100 EARNED ('+fmtCoins(total)+')'}
            </button>
            <div style="flex:1;min-width:160px;font-size:11px;color:rgba(255,255,255,0.45)">
                Total earned this rebirth: <b style="color:#fff">${fmtCoins(total)}</b><br>
                Active multipliers: <b style="color:#22d3ee">×${mult.toFixed(2)} coins</b>${sd<1?' · <b style="color:#fde047">-'+Math.round((1-sd)*100)+'% shop</b>':''}${cd<1?' · <b style="color:#fde047">-'+Math.round((1-cd)*100)+'% chests</b>':''}
            </div>
        </div>
    </div>`;
    // Daily chest button (if perk unlocked).
    const dailyLvl=PROFILE.perkLevel('daily_chest');
    if(dailyLvl>0){
        html+=`<div style="background:rgba(34,211,238,0.08);border:1px solid rgba(34,211,238,0.3);border-radius:12px;padding:12px 16px;margin-bottom:14px;display:flex;align-items:center;gap:12px">
            <div style="font-size:28px">🎁</div>
            <div style="flex:1">
                <div style="font-weight:800;color:#fff;font-size:13px">Daily Spoils <span style="color:#22d3ee;font-size:11px;margin-left:6px">Lv ${dailyLvl}</span></div>
                <div style="font-size:11px;color:rgba(255,255,255,0.5)">${dailyReady?'Your free chest is ready!':'Claim again in 24h after last claim.'}</div>
            </div>
            <button onclick="claimDailyChestUI()" ${dailyReady?'':'disabled'} style="background:${dailyReady?'linear-gradient(135deg,#22d3ee,#0891b2)':'rgba(255,255,255,0.08)'};color:${dailyReady?'#001520':'rgba(255,255,255,0.3)'};border:none;padding:9px 18px;border-radius:8px;font-weight:800;font-size:11px;letter-spacing:1px;cursor:${dailyReady?'pointer':'not-allowed'}">${dailyReady?'CLAIM':'WAITING'}</button>
        </div>`;
    }
    // Perks grid.
    html+=`<div style="font-size:12px;color:rgba(255,255,255,0.45);text-transform:uppercase;letter-spacing:2px;margin:18px 0 10px">Permanent perks · Spend RP</div>`;
    html+=`<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px">`;
    PROFILE.REBIRTH_PERKS.forEach(perk=>{
        const lvl=PROFILE.perkLevel(perk.id);
        const maxed=lvl>=perk.maxLvl;
        const cost=maxed?0:perk.cost(lvl);
        const canAfford=(p.rebirthPoints||0)>=cost;
        const pct=Math.min(100,(lvl/perk.maxLvl)*100);
        html+=`<div style="background:${maxed?'rgba(34,197,94,0.08)':'rgba(255,255,255,0.04)'};border:1px solid ${maxed?'rgba(34,197,94,0.3)':'rgba(255,255,255,0.08)'};border-radius:10px;padding:12px 14px;display:flex;flex-direction:column;gap:8px">
            <div style="display:flex;gap:10px;align-items:flex-start">
                <div style="font-size:22px;flex-shrink:0">${perk.emoji}</div>
                <div style="flex:1;min-width:0">
                    <div style="font-weight:800;color:#fff;font-size:13px">${perk.name}</div>
                    <div style="font-size:10px;color:#fde047;letter-spacing:1px;margin-top:1px">Lv ${lvl} / ${perk.maxLvl}</div>
                </div>
            </div>
            <div style="font-size:11px;color:rgba(255,255,255,0.55);line-height:1.4">${perk.desc}</div>
            <div style="height:4px;background:rgba(0,0,0,0.3);border-radius:2px;overflow:hidden"><div style="width:${pct}%;height:100%;background:linear-gradient(90deg,#fde047,#f59e0b)"></div></div>
            <button onclick="buyRebirthPerkUI('${perk.id}')" ${maxed||!canAfford?'disabled':''} style="background:${maxed?'rgba(34,197,94,0.2)':canAfford?'linear-gradient(135deg,#a855f7,#7c3aed)':'rgba(255,255,255,0.06)'};color:${maxed?'#86efac':canAfford?'#fff':'rgba(255,255,255,0.3)'};border:none;padding:7px 12px;border-radius:6px;font-weight:800;font-size:11px;letter-spacing:1px;cursor:${maxed||!canAfford?'not-allowed':'pointer'}">${maxed?'✓ MAX':cost+' RP'}</button>
        </div>`;
    });
    html+=`</div>`;
    return html;
}
function doRebirthUI(){
    const p=PROFILE.get();
    const avail=PROFILE.rebirthAvailable();
    if(avail<1){alert('You need at least 100 total coins earned to rebirth.');return;}
    if(!confirm('Rebirth?\n\nYou will:\n  • Earn '+avail+' Rebirth Points (RP)\n  • Lose all current coins ('+(p.coins||0)+')\n  • Keep all owned items, friends, perks, badges\n\nProceed?')) return;
    const r=PROFILE.doRebirth();
    if(r.ok){
        renderShopItems();updateShopPreview();updateTopbarCoins();
        alert('Rebirth complete! +'+r.earned+' RP earned. Spend it on perks below.');
    } else { alert(r.msg||'Could not rebirth'); }
}
function buyRebirthPerkUI(id){
    const r=PROFILE.buyRebirthPerk(id);
    if(r.ok){renderShopItems();}
    else alert(r.msg||'Could not buy perk');
}
function claimDailyChestUI(){
    const r=PROFILE.claimDailyChest();
    if(!r.ok){alert(r.msg||'Not ready');return;}
    updateTopbarCoins();renderShopItems();
    if(r.type==='item') alert('Daily chest: got '+r.item.name+'!');
    else alert('Daily chest: +'+r.amount+' coins!');
}
function updateTopbarCoins(){
    const p=PROFILE.get();
    document.getElementById('topbarCoinCount').textContent=p.coins;
}

// === Spin Wheel ===
let wheelAngle=0, wheelSpinning=false;
function drawWheel(){
    const canvas=document.getElementById('wheelCanvas');
    if(!canvas)return;
    const ctx=canvas.getContext('2d');
    const cx=130,cy=130,r=120;
    const prizes=PROFILE.WHEEL_PRIZES;
    const sliceAngle=2*Math.PI/prizes.length;
    ctx.clearRect(0,0,260,260);
    ctx.save();
    ctx.translate(cx,cy);
    ctx.rotate(wheelAngle);
    prizes.forEach((p,i)=>{
        const a=i*sliceAngle;
        ctx.beginPath();ctx.moveTo(0,0);
        ctx.arc(0,0,r,a,a+sliceAngle);
        ctx.closePath();
        ctx.fillStyle=p.color;ctx.fill();
        ctx.strokeStyle='rgba(0,0,0,0.3)';ctx.lineWidth=2;ctx.stroke();
        ctx.save();
        ctx.rotate(a+sliceAngle/2);
        ctx.textAlign='center';ctx.fillStyle='#fff';ctx.font='bold 11px sans-serif';
        ctx.shadowColor='rgba(0,0,0,0.5)';ctx.shadowBlur=4;
        ctx.fillText(p.label,r*0.6,4);
        ctx.restore();
    });
    ctx.restore();
}

function updateWheelUI(){
    const btn=document.getElementById('wheelSpinBtn');
    const cd=document.getElementById('wheelCooldown');
    if(!btn)return;
    if(PROFILE.canSpinWheel()){
        btn.disabled=false;btn.textContent='SPIN!';
        cd.textContent='';
    }else{
        btn.disabled=true;btn.textContent='WAITING...';
        const p=PROFILE.get();
        const ms=(p.lastDailySpin||0)+86400000-Date.now();
        const h=Math.floor(ms/3600000);
        const m=Math.floor((ms%3600000)/60000);
        cd.textContent=`Next spin in ${h}h ${m}m`;
    }
    drawWheel();
}

function spinWheelUI(){
    if(wheelSpinning||!PROFILE.canSpinWheel())return;
    wheelSpinning=true;
    const btn=document.getElementById('wheelSpinBtn');
    btn.disabled=true;
    const prizes=PROFILE.WHEEL_PRIZES;
    const prize=PROFILE.pickWeightedRandom(prizes);
    const idx=prizes.indexOf(prize);
    const sliceAngle=2*Math.PI/prizes.length;
    // Target: land on prize index (top = -PI/2, pointer at top)
    const targetAngle=2*Math.PI - (idx*sliceAngle + sliceAngle/2) - Math.PI/2;
    const totalSpin=4*2*Math.PI + targetAngle; // 4 full rotations + target
    const startAngle=wheelAngle;
    const duration=3500;
    const startTime=performance.now();
    function animateSpin(now){
        const elapsed=now-startTime;
        const t=Math.min(elapsed/duration,1);
        // Ease-out cubic
        const ease=1-Math.pow(1-t,3);
        wheelAngle=startAngle+totalSpin*ease;
        drawWheel();
        if(t<1){requestAnimationFrame(animateSpin);}
        else{
            wheelSpinning=false;
            PROFILE.markWheelSpun();
            // Award prize
            if(prize.type==='coins'){
                PROFILE.addCoins(prize.amount);
                showWheelResult(`${ICO_COIN} You got ${prize.amount} coins!`);
            }else if(prize.type==='chest'){
                const result=PROFILE.openChest(prize.chestId);
                if(result&&result.type==='item'){
                    showWheelResult(`${getItemPreviewIcon(result.item)} You got: ${result.item.name}!`);
                }else if(result&&result.type==='coins'){
                    showWheelResult(`${ICO_COIN} All items owned - you got ${result.amount} coins!`);
                }
            }
            updateShopPreview();renderShopItems();updateTopbarCoins();
            updateWheelUI();
        }
    }
    requestAnimationFrame(animateSpin);
}

function showWheelResult(msg){
    const overlay=document.createElement('div');
    overlay.className='chest-reveal-overlay';
    overlay.onclick=()=>overlay.remove();
    overlay.innerHTML=`<div class="chest-reveal-box">
        <div style="font-size:40px;margin-bottom:16px"><svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#fbbf24" stroke-width="2" stroke-linecap="round"><path d="M12 2l2 7h7l-5.7 4.2 2.2 6.8L12 16l-5.5 4 2.2-6.8L3 9h7z"/></svg></div>
        <div style="font-size:18px;font-weight:800;color:#fff;margin-bottom:8px">${msg}</div>
        <div style="font-size:12px;color:rgba(255,255,255,0.4);margin-top:12px">Click to close</div>
    </div>`;
    document.body.appendChild(overlay);
}

// === Mystery Chest UI ===
function openChestUI(chestId){
    const chest=PROFILE.MYSTERY_CHESTS.find(c=>c.id===chestId);
    if(!chest)return;
    const p=PROFILE.get();
    const disc=PROFILE.chestDiscount?PROFILE.chestDiscount():1;
    const price=Math.ceil(chest.price*disc);
    if(p.coins<price){alert('Not enough coins!');return;}
    PROFILE.spendCoins(price);
    const result=PROFILE.openChest(chestId);
    updateShopPreview();renderShopItems();updateTopbarCoins();
    // Show reveal overlay
    const overlay=document.createElement('div');
    overlay.className='chest-reveal-overlay';
    overlay.onclick=()=>overlay.remove();
    let content='';
    if(result&&result.type==='item'){
        const it=result.item;
        content=`<div style="font-size:50px;margin-bottom:12px">${chest.emoji}</div>
            <div style="font-size:12px;color:rgba(255,255,255,0.4);margin-bottom:16px;text-transform:uppercase;letter-spacing:2px">You got...</div>
            <div style="font-size:32px;margin-bottom:8px">${getItemPreviewIcon(it)}</div>
            <div style="font-size:20px;font-weight:800;color:#fff">${it.name}</div>
            <div style="margin-top:6px"><span class="item-rarity rarity-${it.rarity}" style="font-size:11px;padding:3px 10px">${RARITY_LABELS[it.rarity]||it.rarity}</span></div>
            <div style="font-size:11px;color:rgba(255,255,255,0.35);margin-top:8px">${it.desc}</div>
            <div style="font-size:12px;color:rgba(255,255,255,0.3);margin-top:16px">Click to close</div>`;
    }else if(result&&result.type==='coins'){
        content=`<div style="font-size:50px;margin-bottom:12px">${chest.emoji}</div>
            <div style="font-size:12px;color:rgba(255,255,255,0.4);margin-bottom:16px;text-transform:uppercase;letter-spacing:2px">All items owned!</div>
            <div style="font-size:36px;margin-bottom:8px">${ICO_COIN}</div>
            <div style="font-size:20px;font-weight:800;color:#ffd700">+${result.amount} coins</div>
            <div style="font-size:12px;color:rgba(255,255,255,0.3);margin-top:16px">Click to close</div>`;
    }
    overlay.innerHTML=`<div class="chest-reveal-box">${content}</div>`;
    document.body.appendChild(overlay);
}

// === Global Scoreboard ===
function openScoreboard(){
    userDropdown.classList.remove('open');
    closeShop();closeCasino();
    document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
    document.querySelector('.sidebar-btn[data-category="scoreboard"]').classList.add('active');
    document.getElementById('gamesGrid').style.display='none';
    document.getElementById('sectionTitle').style.display='none';
    document.getElementById('shopPage').style.display='none';
    document.getElementById('casinoPage').style.display='none';
    document.getElementById('scoreboardPage').style.display='block';
    renderScoreboard();
}
function closeScoreboard(){
    document.getElementById('scoreboardPage').style.display='none';
    document.getElementById('gamesGrid').style.display='';
    document.getElementById('sectionTitle').style.display='';
    document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
    document.querySelector('.sidebar-btn[data-category="all"]').classList.add('active');
}
function renderScoreboard(){
    const hsCount=getHighscoreCount();
    const titleEl=document.getElementById('scoreboardTitle');
    if(hsCount>0) titleEl.innerHTML='<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><circle cx="12" cy="8" r="6"/><path d="M8.2 13L7 22l5-3 5 3-1.2-9"/></svg> '+hsCount+'x Highscore Holder';
    else titleEl.textContent='';
    const games=[
        {key:'collapse_highscore',name:'FELL',unit:'s',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.15em"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><path d="M14 14h7v7h-7z" stroke-dasharray="3 2"/></svg>',color:'#ff6b6b',higher:true},
        {key:'rise_highscore',name:'RISE',unit:'m',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M12 19V5M5 12l7-7 7 7"/></svg>',color:'#4ade80',higher:true},
        {key:'swerve_highscore',name:'SWERVE',unit:'m',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M4 20C8 10 16 20 20 4"/></svg>',color:'#fbbf24',higher:true},
        {key:'dash_highscore',name:'DASH',unit:'m',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M13 4L5 12l8 8"/><path d="M5 12h14"/></svg>',color:'#60a5fa',higher:true},
        {key:'dodge_highscore',name:'DODGE',unit:'s',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M13 2L3 14h9l-1 8 10-12h-9z"/></svg>',color:'#f97316',higher:true},
        {key:'hit_highscore',name:'HIT',unit:'',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.15em"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>',color:'#a855f7',higher:true},
        {key:'spin_highscore',name:'SPIN',unit:'s',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M21 12a9 9 0 11-6.2-8.6"/><path d="M21 3v5h-5"/></svg>',color:'#818cf8',higher:true},
        {key:'climb_highscore',name:'CLIMB',unit:'m',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M4 17h6M10 13h4M14 9h6"/><circle cx="7" cy="7" r="2"/></svg>',color:'#34d399',higher:true},
        {key:'rush_highscore',name:'RUSH',unit:'',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M5 12h14M12 5l7 7-7 7"/></svg>',color:'#fb923c',higher:true},
        {key:'drop_highscore',name:'DROP',unit:'m',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M12 5v14M5 12l7 7 7-7"/></svg>',color:'#38bdf8',higher:true},
        {key:'hexfall_highscore',name:'HEXFALL',unit:'s',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" style="vertical-align:-.15em"><path d="M12 2l8.7 5v10L12 22l-8.7-5V7z"/></svg>',color:'#c084fc',higher:true},
        {key:'beat_highscore',name:'BEAT',unit:'',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>',color:'#ff44aa',higher:true},
        {key:'volley_highscore',name:'VOLLEY',unit:' sets',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="vertical-align:-.15em"><circle cx="12" cy="12" r="10"/><path d="M12 2a15 15 0 010 20M2 12c3-3 6-4 10-4s7 1 10 4"/></svg>',color:'#fcd34d',higher:true},
        {key:'coin_highscore',name:'COINS',unit:'',icon:'<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:-.15em"><defs><radialGradient id="gcSb" cx="40%" cy="35%"><stop offset="0%" stop-color="#ffe066"/><stop offset="50%" stop-color="#ffd700"/><stop offset="100%" stop-color="#b8860b"/></radialGradient></defs><circle cx="12" cy="12" r="10" fill="url(#gcSb)"/><circle cx="12" cy="12" r="6.5" fill="none" stroke="#b8860b" stroke-width="1.2" opacity=".5"/><ellipse cx="10" cy="9" rx="4" ry="3" fill="rgba(255,255,255,0.18)"/></svg>',color:'#ffd700',higher:true},
    ];
    let html='';
    games.forEach(g=>{
        const v=parseFloat(localStorage.getItem(g.key))||0;
        const display=v>0?(g.unit==='s'?v.toFixed(1):Math.round(v))+g.unit:'-';
        html+=`<div style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:14px;padding:20px;text-align:center;transition:all .2s;position:relative;overflow:hidden">
            <div style="position:absolute;top:0;left:0;right:0;height:3px;background:${g.color};opacity:0.6"></div>
            <div style="font-size:28px;margin-bottom:8px">${g.icon}</div>
            <div style="font-size:14px;font-weight:800;color:#fff;letter-spacing:1px">${g.name}</div>
            <div style="font-size:28px;font-weight:900;color:${g.color};margin:10px 0">${display}</div>
            <div style="font-size:10px;color:rgba(255,255,255,0.25);text-transform:uppercase;letter-spacing:1px">Personal best</div>
        </div>`;
    });
    document.getElementById('scoreboardGrid').innerHTML=html;
}

// === Casino ===
function openCasino(){
    userDropdown.classList.remove('open');
    const user=getSession();
    if(!user){accountBtn.click();return;}
    if(!PROFILE.exists())PROFILE.create(user);
    closeShop();closeScoreboard();
    document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
    document.querySelector('.sidebar-btn[data-category="casino"]').classList.add('active');
    document.getElementById('gamesGrid').style.display='none';
    document.getElementById('sectionTitle').style.display='none';
    document.getElementById('casinoPage').style.display='block';
    updateCasinoCoins();
    // Force redraw of roulette wheel (canvas may not have rendered while hidden)
    try{ if(typeof drawRouletteWheel==='function') drawRouletteWheel(0,0,-1); }catch(e){}
}
function closeCasino(){
    document.getElementById('casinoPage').style.display='none';
    document.getElementById('gamesGrid').style.display='';
    document.getElementById('sectionTitle').style.display='';
    document.querySelectorAll('.sidebar-btn[data-category]').forEach(b=>b.classList.remove('active'));
    document.querySelector('.sidebar-btn[data-category="all"]').classList.add('active');
}
function updateCasinoCoins(){
    const p=PROFILE.get();
    document.getElementById('casinoCoins').textContent=p.coins;
    updateTopbarCoins();
    // Track peak coins for highscore
    if(p.coins>(parseFloat(localStorage.getItem('coin_highscore'))||0)){
        localStorage.setItem('coin_highscore',p.coins);
    }
}

// --- Coinflip ---
function playCoinflip(choice){
    const bet=parseInt(document.getElementById('cfBet').value)||0;
    if(bet<10){document.getElementById('cfResult').innerHTML='<span style="color:#ef4444">Min bet: 10</span>';return;}
    const p=PROFILE.get();
    if(p.coins<bet){document.getElementById('cfResult').innerHTML='<span style="color:#ef4444">Not enough coins!</span>';return;}
    PROFILE.spendCoins(bet);
    const result=Math.random()<0.5?'heads':'tails';
    const won=result===choice;
    if(won){
        PROFILE.casinoWin(bet*2, bet);
        document.getElementById('cfResult').innerHTML=`<span style="color:#4ade80">${result==='heads'?'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-.15em"><path d="M2 20h20L19 8l-5 5-2-8-2 8-5-5z"/></svg> Heads':'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M4 9h16M4 15h16M10 3l-2 18M16 3l-2 18"/></svg> Tails'} - You won ${bet} coins!</span>`;
    }else{
        document.getElementById('cfResult').innerHTML=`<span style="color:#ef4444">${result==='heads'?'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-.15em"><path d="M2 20h20L19 8l-5 5-2-8-2 8-5-5z"/></svg> Heads':'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="vertical-align:-.15em"><path d="M4 9h16M4 15h16M10 3l-2 18M16 3l-2 18"/></svg> Tails'} - You lost ${bet} coins!</span>`;
    }
    updateCasinoCoins();
}

// --- Mines ---
let minesState=null;
function startMines(){
    const bet=parseInt(document.getElementById('minesBet').value)||0;
    if(bet<10){return;}
    const p=PROFILE.get();
    if(p.coins<bet){return;}
    const mineCount=parseInt(document.getElementById('minesCount').value)||5;
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    // Generate grid 5x5
    const totalCells=25;
    const mines=new Set();
    while(mines.size<mineCount)mines.add(Math.floor(Math.random()*totalCells));
    minesState={bet,mines,revealed:new Set(),mineCount,totalCells,gameOver:false};
    document.getElementById('minesStartBtn').style.display='none';
    document.getElementById('minesMultiBtn').style.display='none';
    document.getElementById('minesCashBtn').style.display='';
    minesMultiMode=false;
    renderMinesGrid();
}
function renderMinesGrid(){
    const g=document.getElementById('minesGrid');
    if(!minesState){g.innerHTML='';return;}
    const s=minesState;
    let html='';
    for(let i=0;i<s.totalCells;i++){
        const revealed=s.revealed.has(i);
        const isMine=s.mines.has(i);
        if(s.gameOver){
            if(isMine)html+=`<button class="mine-cell revealed-mine" disabled><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2"><circle cx="11" cy="13" r="8"/><path d="M15.5 5.5l2-4M17.5 1.5l1.5 1.5"/></svg></button>`;
            else if(revealed)html+=`<button class="mine-cell revealed-safe" disabled><svg width="16" height="16" viewBox="0 0 24 24" fill="#44ddff" stroke="#0891b2" stroke-width="1"><path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7z"/></svg></button>`;
            else html+=`<button class="mine-cell" disabled>?</button>`;
        }else if(revealed){
            html+=`<button class="mine-cell revealed-safe" disabled><svg width="16" height="16" viewBox="0 0 24 24" fill="#44ddff" stroke="#0891b2" stroke-width="1"><path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7z"/></svg></button>`;
        }else{
            html+=`<button class="mine-cell" onclick="clickMine(${i})">?</button>`;
        }
    }
    g.innerHTML=html;
    // Show multiplier
    const safe=s.totalCells-s.mineCount;
    const revCount=s.revealed.size;
    const multi=revCount===0?1:calcMinesMulti(s.totalCells,s.mineCount,revCount);
    document.getElementById('minesMulti').textContent=revCount>0?`Multiplier: ${multi.toFixed(2)}x - ${Math.floor(s.bet*multi)} coins`:'';
}
function calcMinesMulti(total,mines,revealed){
    // Fair multiplier: product of (total-i)/(total-mines-i) for i=0..revealed-1 with 0.97 house edge
    let m=1;
    for(let i=0;i<revealed;i++) m*=(total-i)/(total-mines-i);
    return m*0.97;
}
function clickMine(idx){
    if(!minesState||minesState.gameOver)return;
    if(minesState.revealed.has(idx))return;
    if(minesState.mines.has(idx)){
        // Hit mine - lose
        minesState.gameOver=true;
        minesState.revealed.add(idx);
        renderMinesGrid();
        document.getElementById('minesCashBtn').style.display='none';
        document.getElementById('minesStartBtn').style.display='';
        document.getElementById('minesMultiBtn').style.display='';
        document.getElementById('minesMulti').innerHTML='<span style="color:#ef4444">?? BOOM! You lost!</span>';
        minesMultiMode=false;
        updateCasinoCoins();
        return;
    }
    minesState.revealed.add(idx);
    renderMinesGrid();
    // Check if all safe revealed
    const safeCount=minesState.totalCells-minesState.mineCount;
    if(minesState.revealed.size>=safeCount)cashOutMines();
}
function cashOutMines(){
    if(minesMultiMode&&minesWS){cashOutMinesOnline();return;}
    if(!minesState||minesState.gameOver)return;
    const multi=calcMinesMulti(minesState.totalCells,minesState.mineCount,minesState.revealed.size);
    const win=Math.floor(minesState.bet*multi);
    PROFILE.casinoWin(win, minesState.bet);
    minesState.gameOver=true;
    renderMinesGrid();
    document.getElementById('minesCashBtn').style.display='none';
    document.getElementById('minesStartBtn').style.display='';
    document.getElementById('minesMultiBtn').style.display='';
    document.getElementById('minesMulti').innerHTML=`<span style="color:#4ade80">Cashed out ${win} coins!</span>`;
    updateCasinoCoins();
}

// --- Online Multiplayer Mines ---
let minesMultiMode=false;
let minesWS=null;
let minesMultiRole=null;
let minesMultiOpponent='';
let minesPlacementPhase=false;
let minesPlacedByPlayer=new Set();

function startMinesMulti(){
    const p=PROFILE.get();
    if(!p)return;
    const wsUrl=API_BASE.replace('https://','wss://').replace('http://','ws://')+'/api/mines/ws';
    minesWS=new WebSocket(wsUrl);
    minesMultiMode=true;
    document.getElementById('minesStartBtn').style.display='none';
    document.getElementById('minesMultiBtn').style.display='none';
    document.getElementById('minesCashBtn').style.display='none';
    document.getElementById('minesMultiConfirm').style.display='none';
    document.getElementById('minesMulti').innerHTML='<span style="color:#818cf8">? Searching for opponent...</span>';
    document.getElementById('minesGrid').innerHTML='';
    minesWS.onopen=()=>{minesWS.send(JSON.stringify({type:'join_queue',name:p.name}));};
    minesWS.onmessage=(e)=>{try{handleMinesMultiMsg(JSON.parse(e.data));}catch(ex){}};
    minesWS.onclose=()=>{resetMinesMultiUI();};
    minesWS.onerror=()=>{document.getElementById('minesMulti').innerHTML='<span style="color:#ef4444">Connection error!</span>';resetMinesMultiUI();};
}
function handleMinesMultiMsg(msg){
    switch(msg.type){
    case 'queued':
        document.getElementById('minesMulti').innerHTML='<span style="color:#818cf8">? Waiting for opponent... <a href="#" onclick="cancelMinesQueue();return false" style="color:#ef4444;text-decoration:underline">Cancel</a></span>';
        break;
    case 'matched':
        minesMultiRole=msg.role;
        minesMultiOpponent=msg.opponent;
        if(msg.role==='placer'){
            minesPlacedByPlayer=new Set();
            minesPlacementPhase=true;
            document.getElementById('minesMulti').innerHTML='<span style="color:#818cf8">?? Place 5 mines against <b>'+msg.opponent+'</b></span>';
            document.getElementById('minesMultiConfirm').style.display='none';
            renderMinesGridPlacement();
        }else{
            document.getElementById('minesMulti').innerHTML='<span style="color:#fbbf24">? <b>'+msg.opponent+'</b> is placing mines...</span>';
            document.getElementById('minesGrid').innerHTML='';
        }
        break;
    case 'start_guessing':{
        const bet=parseInt(document.getElementById('minesBet').value)||10;
        const p=PROFILE.get();
        if(p&&p.coins>=bet){PROFILE.spendCoins(bet);updateCasinoCoins();}
        minesState={bet,mines:new Set(),revealed:new Set(),mineCount:5,totalCells:25,gameOver:false};
        document.getElementById('minesCashBtn').style.display='';
        document.getElementById('minesMulti').innerHTML='<span style="color:#4ade80">?? Your turn! Reveal cells. Against <b>'+minesMultiOpponent+'</b></span>';
        renderMinesGridOnline();
        break;
    }
    case 'mines_placed':
        document.getElementById('minesMulti').innerHTML='<span style="color:#fbbf24">? <b>'+minesMultiOpponent+'</b> is playing now...</span>';
        document.getElementById('minesGrid').innerHTML='';
        document.getElementById('minesMultiConfirm').style.display='none';
        minesPlacementPhase=false;
        break;
    case 'tile_revealed':
        if(minesMultiRole==='guesser'&&minesState){
            minesState.revealed=new Set(msg.revealed);
            renderMinesGridOnline();
            document.getElementById('minesMulti').innerHTML='<span style="color:#4ade80">'+msg.multiplier.toFixed(2)+'x - '+Math.floor(minesState.bet*msg.multiplier)+' coins</span>';
        }else{
            document.getElementById('minesMulti').innerHTML='<span style="color:#fbbf24">'+minesMultiOpponent+' revealed '+msg.revealed.length+'/20 - '+msg.multiplier.toFixed(2)+'x</span>';
        }
        break;
    case 'game_result':
        if(msg.hit){
            if(minesMultiRole==='guesser'){
                if(minesState){minesState.gameOver=true;minesState.mines=new Set(msg.mines);minesState.revealed=new Set(msg.revealed);}
                document.getElementById('minesMulti').innerHTML='<span style="color:#ef4444">?? BOOM! You hit a mine!</span>';
            }else{
                document.getElementById('minesMulti').innerHTML='<span style="color:#4ade80">?? '+minesMultiOpponent+' hit a mine! You won!</span>';
            }
        }else{
            const multi=msg.multiplier;
            if(minesMultiRole==='guesser'){
                const win=Math.floor(minesState.bet*multi);
                PROFILE.casinoWin(win, minesState.bet);updateCasinoCoins();
                if(minesState){minesState.gameOver=true;minesState.mines=new Set(msg.mines);minesState.revealed=new Set(msg.revealed);}
                document.getElementById('minesMulti').innerHTML='<span style="color:#4ade80">?? Cashed out '+win+' coins! ('+multi.toFixed(2)+'x)</span>';
            }else{
                document.getElementById('minesMulti').innerHTML='<span style="color:#ef4444">'+minesMultiOpponent+' cashed out at '+multi.toFixed(2)+'x!</span>';
            }
        }
        renderMinesGridFinal(msg.mines,msg.revealed);
        document.getElementById('minesCashBtn').style.display='none';
        closeMinesWS();
        resetMinesMultiUI();
        break;
    case 'opponent_left':
        document.getElementById('minesMulti').innerHTML='<span style="color:#ef4444">Opponent left the game!</span>';
        if(minesMultiRole==='guesser'&&minesState&&!minesState.gameOver){PROFILE.casinoWin(minesState.bet, minesState.bet);updateCasinoCoins();}
        closeMinesWS();
        resetMinesMultiUI();
        break;
    }
}
function renderMinesGridOnline(){
    const g=document.getElementById('minesGrid');
    let html='';
    for(let i=0;i<25;i++){
        if(minesState.revealed.has(i)){
            html+='<button class="mine-cell revealed-safe" disabled><svg width="16" height="16" viewBox="0 0 24 24" fill="#44ddff" stroke="#0891b2" stroke-width="1"><path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7z"/></svg></button>';
        }else{
            html+='<button class="mine-cell" onclick="clickMineOnline('+i+')">?</button>';
        }
    }
    g.innerHTML=html;
}
function clickMineOnline(idx){
    if(!minesWS||!minesState||minesState.gameOver)return;
    if(minesState.revealed.has(idx))return;
    minesWS.send(JSON.stringify({type:'reveal_tile',index:idx}));
}
function cashOutMinesOnline(){
    if(!minesWS||!minesState||minesState.gameOver)return;
    if(minesState.revealed.size===0)return;
    minesWS.send(JSON.stringify({type:'cashout'}));
}
function renderMinesGridFinal(mines,revealed){
    const g=document.getElementById('minesGrid');
    const mineSet=new Set(mines),revSet=new Set(revealed);
    let html='';
    for(let i=0;i<25;i++){
        if(mineSet.has(i))html+='<button class="mine-cell revealed-mine" disabled><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2"><circle cx="11" cy="13" r="8"/><path d="M15.5 5.5l2-4M17.5 1.5l1.5 1.5"/></svg></button>';
        else if(revSet.has(i))html+='<button class="mine-cell revealed-safe" disabled><svg width="16" height="16" viewBox="0 0 24 24" fill="#44ddff" stroke="#0891b2" stroke-width="1"><path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7z"/></svg></button>';
        else html+='<button class="mine-cell" disabled>?</button>';
    }
    g.innerHTML=html;
}
function renderMinesGridPlacement(){
    const g=document.getElementById('minesGrid');
    let html='';
    for(let i=0;i<25;i++){
        if(minesPlacedByPlayer.has(i))html+='<button class="mine-cell revealed-mine" onclick="toggleMinePlacement('+i+')">??</button>';
        else html+='<button class="mine-cell" onclick="toggleMinePlacement('+i+')">?</button>';
    }
    g.innerHTML=html;
    const remaining=5-minesPlacedByPlayer.size;
    if(remaining<=0){
        document.getElementById('minesMultiConfirm').style.display='';
        document.getElementById('minesMulti').innerHTML='<span style="color:#4ade80">All mines placed! Click confirm.</span>';
    }else{
        document.getElementById('minesMultiConfirm').style.display='none';
        document.getElementById('minesMulti').innerHTML='<span style="color:#818cf8">?? Place mines ('+remaining+' left) against <b>'+minesMultiOpponent+'</b></span>';
    }
}
function toggleMinePlacement(idx){
    if(!minesPlacementPhase)return;
    if(minesPlacedByPlayer.has(idx))minesPlacedByPlayer.delete(idx);
    else{if(minesPlacedByPlayer.size>=5)return;minesPlacedByPlayer.add(idx);}
    renderMinesGridPlacement();
}
function confirmMinesPlacement(){
    if(minesPlacedByPlayer.size!==5||!minesWS)return;
    minesWS.send(JSON.stringify({type:'place_mines',mines:[...minesPlacedByPlayer]}));
}
function cancelMinesQueue(){
    if(minesWS){minesWS.send(JSON.stringify({type:'leave'}));closeMinesWS();}
    resetMinesMultiUI();
    document.getElementById('minesMulti').innerHTML='';
}
function closeMinesWS(){
    if(minesWS){try{minesWS.close();}catch(e){}minesWS=null;}
}
function resetMinesMultiUI(){
    minesMultiRole=null;minesMultiOpponent='';minesPlacementPhase=false;
    setTimeout(()=>{
        minesMultiMode=false;
        document.getElementById('minesStartBtn').style.display='';
        document.getElementById('minesMultiBtn').style.display='';
        document.getElementById('minesMultiConfirm').style.display='none';
    },2000);
}

// --- Tower ---
let towerState=null;
const TOWER_FLOORS=8;
const TOWER_DOORS=3;
function startTower(){
    const bet=parseInt(document.getElementById('towerBet').value)||0;
    if(bet<10)return;
    const p=PROFILE.get();
    if(p.coins<bet)return;
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    // Generate floors: each floor has one danger door
    const floors=[];
    for(let i=0;i<TOWER_FLOORS;i++){
        const danger=Math.floor(Math.random()*TOWER_DOORS);
        floors.push({danger,chosen:null});
    }
    towerState={bet,floors,currentFloor:0,gameOver:false};
    document.getElementById('towerStartBtn').style.display='none';
    document.getElementById('towerCashBtn').style.display='';
    renderTower();
}
function renderTower(){
    const g=document.getElementById('towerGrid');
    if(!towerState){g.innerHTML='';return;}
    const s=towerState;
    let html='';
    // Render top to bottom
    for(let f=TOWER_FLOORS-1;f>=0;f--){
        const floor=s.floors[f];
        const multi=calcTowerMulti(f+1);
        html+=`<div style="display:flex;align-items:center;gap:8px;margin-bottom:4px">
            <span style="font-size:10px;color:rgba(255,255,255,0.25);width:40px;text-align:right">${multi.toFixed(1)}x</span>
            <div class="tower-row" style="flex:1">`;
        for(let d=0;d<TOWER_DOORS;d++){
            const isCurrent=f===s.currentFloor&&!s.gameOver;
            const isChosen=floor.chosen===d;
            const isDanger=floor.danger===d;
            if(f<s.currentFloor||s.gameOver){
                // Past floor or game over
                if(isChosen&&isDanger)html+=`<button class="tower-door danger" disabled>??</button>`;
                else if(isChosen)html+=`<button class="tower-door safe" disabled>?</button>`;
                else if(s.gameOver&&isDanger)html+=`<button class="tower-door danger" disabled>??</button>`;
                else html+=`<button class="tower-door" disabled>${f<s.currentFloor?'�':'?'}</button>`;
            }else if(isCurrent){
                html+=`<button class="tower-door" onclick="pickTowerDoor(${f},${d})">?</button>`;
            }else{
                html+=`<button class="tower-door" disabled>?</button>`;
            }
        }
        html+=`</div></div>`;
    }
    g.innerHTML=html;
    const multi=calcTowerMulti(s.currentFloor);
    document.getElementById('towerMulti').textContent=s.currentFloor>0&&!s.gameOver?
        `Level ${s.currentFloor}/${TOWER_FLOORS} - ${multi.toFixed(2)}x - ${Math.floor(s.bet*multi)} coins`:'';
}
function calcTowerMulti(floor){
    // Each floor survived: multiply by DOORS/(DOORS-1) with 0.97 house edge
    return Math.pow(TOWER_DOORS/(TOWER_DOORS-1),floor)*0.97;
}
function pickTowerDoor(floor,door){
    if(!towerState||towerState.gameOver||floor!==towerState.currentFloor)return;
    towerState.floors[floor].chosen=door;
    if(door===towerState.floors[floor].danger){
        // Hit danger
        towerState.gameOver=true;
        renderTower();
        document.getElementById('towerCashBtn').style.display='none';
        document.getElementById('towerStartBtn').style.display='';
        document.getElementById('towerMulti').innerHTML='<span style="color:#ef4444">?? Wrong door! You lost!</span>';
        updateCasinoCoins();
        return;
    }
    towerState.currentFloor++;
    if(towerState.currentFloor>=TOWER_FLOORS){
        cashOutTower();return;
    }
    renderTower();
}
function cashOutTower(){
    if(!towerState||towerState.gameOver)return;
    const multi=calcTowerMulti(towerState.currentFloor);
    const win=Math.floor(towerState.bet*multi);
    PROFILE.casinoWin(win, towerState.bet);
    towerState.gameOver=true;
    renderTower();
    document.getElementById('towerCashBtn').style.display='none';
    document.getElementById('towerStartBtn').style.display='';
    document.getElementById('towerMulti').innerHTML=`<span style="color:#4ade80">Cashed out ${win} coins!</span>`;
    updateCasinoCoins();
}

// --- Chicken Road ---
let chickenState=null;
const CR_LANES=40; // many lanes so absurd multipliers are reachable
const CR_RISK={easy:1/8, medium:2/8, hard:3/8, daredevil:4/8};
function calcChickenMulti(lanesCrossed, p){
    if(lanesCrossed<=0) return 1;
    return Math.pow(1/(1-p), lanesCrossed) * 0.97;
}
function startChicken(){
    const bet=parseInt(document.getElementById('crBet').value)||0;
    if(bet<10)return;
    const p=PROFILE.get();
    if(p.coins<bet)return;
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    const diff=document.getElementById('crDifficulty').value;
    const hazardP=CR_RISK[diff];
    // Pre-roll hazard for each lane
    const lanes=[];
    for(let i=0;i<CR_LANES;i++){
        lanes.push({hazard: Math.random()<hazardP, revealed:false, carColor: pickCarColor()});
    }
    chickenState={bet, hazardP, diff, lanes, currentLane:0, gameOver:false};
    document.getElementById('crStartBtn').style.display='none';
    document.getElementById('crCashBtn').style.display='';
    openChickenFullscreen();
    renderChicken();
}
function pickCarColor(){
    const c=['#ef4444','#fbbf24','#22d3ee','#a855f7','#22c55e','#f97316','#ec4899','#60a5fa'];
    return c[Math.floor(Math.random()*c.length)];
}
function ensureChickenFullscreenDom(){
    if(document.getElementById('chickenFullscreen'))return;
    const div=document.createElement('div');
    div.id='chickenFullscreen';
    div.style.cssText='position:fixed;inset:0;z-index:1200;background:#0a0e16;display:none;flex-direction:column;backdrop-filter:blur(2px)';
    div.innerHTML=`
        <div style="display:flex;align-items:center;gap:14px;padding:14px 22px;background:linear-gradient(180deg,rgba(15,20,30,0.95),rgba(15,20,30,0.6));border-bottom:1px solid rgba(255,255,255,0.08);flex-wrap:wrap">
            <div style="font-size:22px;font-weight:900;letter-spacing:2px;color:#fbbf24">?? CHICKEN ROAD</div>
            <div style="display:flex;gap:10px;align-items:center;flex:1;min-width:200px;flex-wrap:wrap">
                <span id="cfBet" style="font-size:13px;color:rgba(255,255,255,0.6);font-weight:700"></span>
                <span id="cfLane" style="font-size:13px;color:rgba(255,255,255,0.6);font-weight:700"></span>
                <span id="cfMulti" style="font-size:18px;font-weight:900;color:#4ade80"></span>
                <span id="cfWin" style="font-size:13px;font-weight:800;color:#fbbf24"></span>
            </div>
            <button id="cfCashBtn" class="casino-btn casino-btn-green" style="padding:10px 20px;margin:0">CASH OUT</button>
            <button id="cfQuitBtn" style="background:rgba(255,255,255,0.08);border:1px solid rgba(255,255,255,0.15);color:#fff;border-radius:8px;padding:8px 14px;font-weight:700;cursor:pointer">? Close</button>
        </div>
        <div id="cfRoadWrap" style="flex:1;overflow:hidden;position:relative">
            <canvas id="cfCanvas" style="position:absolute;inset:0;width:100%;height:100%;display:block"></canvas>
            <div id="cfMessage" style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:28px;font-weight:900;letter-spacing:3px;text-shadow:0 4px 16px rgba(0,0,0,0.8);pointer-events:none;text-align:center;display:none"></div>
        </div>
        <div style="padding:12px 22px;background:rgba(15,20,30,0.95);border-top:1px solid rgba(255,255,255,0.08);display:flex;gap:12px;justify-content:center;align-items:center;flex-wrap:wrap">
            <button id="cfStepBtn" class="casino-btn" style="padding:14px 36px;font-size:16px;margin:0">? STEP FORWARD</button>
            <span style="font-size:11px;color:rgba(255,255,255,0.4)">SPACE / ? = step � ESC = quit</span>
        </div>
    `;
    document.body.appendChild(div);
    document.getElementById('cfCashBtn').onclick=cashOutChicken;
    document.getElementById('cfStepBtn').onclick=crossChickenLane;
    document.getElementById('cfQuitBtn').onclick=()=>{
        if(chickenState && !chickenState.gameOver){
            // Treat as cash out (or refund if no progress)
            cashOutChicken();
        }
        closeChickenFullscreen();
    };
    document.addEventListener('keydown',(e)=>{
        const fs=document.getElementById('chickenFullscreen');
        if(!fs||fs.style.display==='none')return;
        if(e.key===' '||e.key==='ArrowRight'||e.key==='Enter'){
            if(chickenState && !chickenState.gameOver) crossChickenLane();
            else if(chickenState && chickenState.gameOver) closeChickenFullscreen();
            e.preventDefault();
        } else if(e.key==='Escape'){
            if(chickenState && !chickenState.gameOver) cashOutChicken();
            closeChickenFullscreen();
            e.preventDefault();
        } else if(e.key==='c'||e.key==='C'){
            if(chickenState && !chickenState.gameOver && chickenState.currentLane>0) cashOutChicken();
        }
    });
    addEventListener('resize',()=>{ if(chickenState) sizeChickenCanvas(); });
}
function sizeChickenCanvas(){
    const c=document.getElementById('cfCanvas');
    if(!c)return;
    const wrap=document.getElementById('cfRoadWrap');
    const dpr=Math.min(2,window.devicePixelRatio||1);
    c.width=wrap.clientWidth*dpr;
    c.height=wrap.clientHeight*dpr;
    const ctx=c.getContext('2d');
    ctx.setTransform(dpr,0,0,dpr,0,0);
}
function openChickenFullscreen(){
    ensureChickenFullscreenDom();
    const fs=document.getElementById('chickenFullscreen');
    fs.style.display='flex';
    sizeChickenCanvas();
}
function closeChickenFullscreen(){
    const fs=document.getElementById('chickenFullscreen');
    if(fs)fs.style.display='none';
}
// Animation state for chicken road
const _crAnim={chickenX:0, targetX:0, t:0, carY:0};
function renderChicken(){
    // Update bottom card mini status
    const g=document.getElementById('crBoard');
    if(g){
        if(!chickenState){g.innerHTML='';}
        else{
            const s=chickenState;
            const cm=calcChickenMulti(s.currentLane, s.hazardP);
            g.innerHTML=`<div style="font-size:12px;color:rgba(255,255,255,0.55);text-align:center;padding:8px">
                Lane ${s.currentLane}/${CR_LANES} � ${cm.toFixed(2)}x � ${Math.floor(s.bet*cm).toLocaleString('no-NO')} ??
                ${s.gameOver?' � '+(s.lanes[s.currentLane]&&s.lanes[s.currentLane].hazard?'<span style=\"color:#ef4444\">SQUASHED</span>':'<span style=\"color:#4ade80\">CASHED</span>'):''}
            </div>`;
        }
    }
    const mEl=document.getElementById('crMulti');
    if(mEl && chickenState){
        const cm=calcChickenMulti(chickenState.currentLane, chickenState.hazardP);
        mEl.textContent = (chickenState.currentLane>0 && !chickenState.gameOver) ?
            `Lane ${chickenState.currentLane}/${CR_LANES} - ${cm.toFixed(2)}x - ${Math.floor(chickenState.bet*cm)} coins`:'';
    }
    drawChickenScene(true);
}
function drawChickenScene(reset){
    if(!chickenState)return;
    const c=document.getElementById('cfCanvas');
    if(!c)return;
    const ctx=c.getContext('2d');
    const wrap=document.getElementById('cfRoadWrap');
    const W=wrap.clientWidth, H=wrap.clientHeight;
    const s=chickenState;
    // Layout: lanes are vertical strips going right. Camera scrolls so chicken stays roughly 1/3 from left.
    const laneW=Math.max(120,Math.min(180,W/6));
    const startPad=laneW*0.6;
    const targetX = startPad + s.currentLane*laneW;
    if(reset||Math.abs(_crAnim.chickenX-targetX)>1500) _crAnim.chickenX=Math.max(0,targetX-laneW);
    _crAnim.targetX=targetX;
    // Update header
    document.getElementById('cfBet').textContent='Bet: '+s.bet.toLocaleString('no-NO')+' ??';
    document.getElementById('cfLane').textContent='Lane '+s.currentLane+' / '+CR_LANES;
    const cm=calcChickenMulti(s.currentLane, s.hazardP);
    document.getElementById('cfMulti').textContent=cm.toFixed(2)+'x';
    document.getElementById('cfWin').textContent='= '+Math.floor(s.bet*cm).toLocaleString('no-NO')+' ??';
    document.getElementById('cfCashBtn').style.display=(s.gameOver||s.currentLane===0)?'none':'';
    document.getElementById('cfStepBtn').style.display=s.gameOver?'none':'';
    if(!_crAnim.raf){
        _crAnim.last=performance.now();
        const tick=(now)=>{
            const dt=Math.min(0.05,(now-_crAnim.last)/1000); _crAnim.last=now; _crAnim.t+=dt;
            // Smooth camera/chicken-x toward target
            _crAnim.chickenX+=(_crAnim.targetX-_crAnim.chickenX)*Math.min(1,dt*8);
            // Death car animation
            if(s.gameOver && s.lanes[s.currentLane] && s.lanes[s.currentLane].hazard){
                _crAnim.carY = Math.min(_crAnim.carY+dt*900, H*0.45);
            }
            paint();
            if(document.getElementById('chickenFullscreen').style.display!=='none'){
                _crAnim.raf=requestAnimationFrame(tick);
            } else { _crAnim.raf=null; }
        };
        _crAnim.raf=requestAnimationFrame(tick);
    }
    function paint(){
        // Sky gradient
        const sky=ctx.createLinearGradient(0,0,0,H*0.55);
        sky.addColorStop(0,'#1a2540'); sky.addColorStop(1,'#3a2a4a');
        ctx.fillStyle=sky; ctx.fillRect(0,0,W,H*0.55);
        // Distant skyline
        ctx.fillStyle='rgba(20,15,30,0.55)';
        for(let i=0;i<20;i++){
            const bx=((i*97 + Math.floor(_crAnim.chickenX*0.05)%200)%(W+200))-100;
            const bh=30+((i*13)%80);
            ctx.fillRect(bx,H*0.55-bh,40,bh);
        }
        // Road background (asphalt)
        ctx.fillStyle='#1f2329'; ctx.fillRect(0,H*0.55,W,H*0.45);
        // Camera offset so chicken sits ~1/3 from left
        const camX = _crAnim.chickenX - W*0.32;
        // Compute visible lanes
        const firstLane=Math.max(0,Math.floor((camX-startPad)/laneW));
        const lastLane=Math.min(CR_LANES-1, Math.floor((camX+W-startPad)/laneW)+1);
        // Lane stripes
        ctx.save();
        for(let i=firstLane;i<=lastLane;i++){
            const lx=startPad+i*laneW-camX;
            // Lane separator line
            ctx.fillStyle='rgba(255,255,255,0.12)';
            for(let dy=H*0.58;dy<H;dy+=22){
                ctx.fillRect(lx-2,dy,4,12);
            }
            // Lane state coloring
            const lane=s.lanes[i];
            if(lane.revealed){
                ctx.fillStyle = lane.hazard ? 'rgba(220,38,38,0.18)' : 'rgba(34,197,94,0.14)';
                ctx.fillRect(lx, H*0.55, laneW, H*0.45);
            }
            // Multi label above each lane
            const mc = calcChickenMulti(i+1, s.hazardP);
            const labelY=H*0.55-22;
            const isCur=(i===s.currentLane && !s.gameOver);
            ctx.fillStyle=isCur?'#fde047':'rgba(255,255,255,0.55)';
            ctx.font='bold '+(isCur?16:13)+'px system-ui,sans-serif';
            ctx.textAlign='center'; ctx.textBaseline='bottom';
            const mtxt = mc>=1000? mc.toExponential(2) : mc.toFixed(mc<10?2:mc<100?1:0)+'x';
            ctx.fillText(mtxt, lx+laneW/2, labelY);
            ctx.fillStyle='rgba(255,255,255,0.3)';
            ctx.font='bold 10px system-ui,sans-serif';
            ctx.fillText('#'+(i+1), lx+laneW/2, labelY-16);
            // Cars in revealed-hazard lanes (parked) or animated for the death car
            if(lane.revealed && lane.hazard && i!==s.currentLane){
                drawCar(ctx, lx+laneW/2, H*0.74, lane.carColor);
            }
        }
        ctx.restore();
        // Animated cars whizzing across between lanes (visual flair)
        // Static parked cars on far edges only (just skyline / decoration)
        // Chicken
        const cx = startPad + s.currentLane*laneW + laneW/2 - camX;
        // Use animated chickenX position for smooth movement during step
        const chickenDrawX = _crAnim.chickenX - camX + (laneW/2 - laneW*0.5);
        let cy = H*0.78;
        // Hop animation
        const hop = (Math.abs(_crAnim.chickenX-_crAnim.targetX)>2) ? Math.sin(performance.now()/60)*8 : 0;
        cy += hop;
        if(s.gameOver && s.lanes[s.currentLane].hazard){
            // Ouch state: chicken flat
            drawSquishedChicken(ctx, chickenDrawX, cy);
            // Death car
            drawDeathCar(ctx, chickenDrawX, H*0.78 - (H*0.45 - _crAnim.carY), s.lanes[s.currentLane].carColor);
        } else {
            drawChicken(ctx, chickenDrawX, cy, s.gameOver);
        }
        // Message overlay
        const msg=document.getElementById('cfMessage');
        if(s.gameOver){
            msg.style.display='block';
            if(s.lanes[s.currentLane] && s.lanes[s.currentLane].hazard){
                msg.innerHTML='<div style="color:#ef4444">?? SQUASHED!</div><div style="font-size:14px;color:rgba(255,255,255,0.6);margin-top:6px">Bet lost - press ESC to close</div>';
            } else {
                const win=Math.floor(s.bet*cm);
                msg.innerHTML=`<div style="color:#4ade80">?? CASHED OUT!</div><div style="font-size:18px;color:#fbbf24;margin-top:6px">+${win.toLocaleString('no-NO')} ?? (${cm.toFixed(2)}x)</div><div style="font-size:13px;color:rgba(255,255,255,0.5);margin-top:6px">Press ESC to close</div>`;
            }
        } else {
            msg.style.display='none';
        }
    }
}
function drawChicken(ctx,x,y,dead){
    ctx.save();
    // Shadow
    ctx.fillStyle='rgba(0,0,0,0.35)';
    ctx.beginPath(); ctx.ellipse(x,y+34,28,8,0,0,Math.PI*2); ctx.fill();
    // Body
    ctx.fillStyle=dead?'#aaa':'#fff';
    ctx.beginPath(); ctx.ellipse(x,y,26,30,0,0,Math.PI*2); ctx.fill();
    // Head
    ctx.beginPath(); ctx.arc(x+10,y-22,16,0,Math.PI*2); ctx.fill();
    // Beak
    ctx.fillStyle='#f59e0b';
    ctx.beginPath(); ctx.moveTo(x+24,y-22); ctx.lineTo(x+38,y-18); ctx.lineTo(x+24,y-14); ctx.closePath(); ctx.fill();
    // Comb
    ctx.fillStyle='#dc2626';
    ctx.beginPath(); ctx.arc(x+4,y-36,4,0,Math.PI*2); ctx.fill();
    ctx.beginPath(); ctx.arc(x+10,y-38,4,0,Math.PI*2); ctx.fill();
    ctx.beginPath(); ctx.arc(x+16,y-36,4,0,Math.PI*2); ctx.fill();
    // Eye
    ctx.fillStyle='#000';
    ctx.beginPath(); ctx.arc(x+14,y-22,2.4,0,Math.PI*2); ctx.fill();
    // Legs
    ctx.strokeStyle='#f59e0b'; ctx.lineWidth=3; ctx.lineCap='round';
    ctx.beginPath(); ctx.moveTo(x-6,y+22); ctx.lineTo(x-6,y+34); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(x+8,y+22); ctx.lineTo(x+8,y+34); ctx.stroke();
    ctx.restore();
}
function drawSquishedChicken(ctx,x,y){
    ctx.save();
    ctx.fillStyle='#bbb';
    ctx.beginPath(); ctx.ellipse(x,y+24,38,8,0,0,Math.PI*2); ctx.fill();
    ctx.fillStyle='#dc2626';
    ctx.beginPath(); ctx.ellipse(x,y+28,42,5,0,0,Math.PI*2); ctx.fill();
    // X eyes off to the side
    ctx.strokeStyle='#000'; ctx.lineWidth=3;
    ctx.beginPath(); ctx.moveTo(x+12,y+18); ctx.lineTo(x+22,y+28); ctx.moveTo(x+22,y+18); ctx.lineTo(x+12,y+28); ctx.stroke();
    ctx.restore();
}
function drawCar(ctx,x,y,color){
    ctx.save();
    ctx.fillStyle='rgba(0,0,0,0.4)';
    ctx.fillRect(x-44,y+22,88,5);
    // Body
    ctx.fillStyle=color||'#dc2626';
    roundRectFill(ctx,x-44,y-12,88,32,8);
    // Roof
    roundRectFill(ctx,x-30,y-26,60,18,6);
    // Windows
    ctx.fillStyle='rgba(20,30,60,0.85)';
    ctx.fillRect(x-26,y-24,56,14);
    // Wheels
    ctx.fillStyle='#111';
    ctx.beginPath(); ctx.arc(x-26,y+22,8,0,Math.PI*2); ctx.fill();
    ctx.beginPath(); ctx.arc(x+26,y+22,8,0,Math.PI*2); ctx.fill();
    // Headlight
    ctx.fillStyle='#fde047';
    ctx.fillRect(x-46,y-2,4,8);
    ctx.fillRect(x+42,y-2,4,8);
    ctx.restore();
}
function drawDeathCar(ctx,x,y,color){
    drawCar(ctx,x,y,color);
}
function roundRectFill(ctx,x,y,w,h,r){
    ctx.beginPath();
    ctx.moveTo(x+r,y); ctx.lineTo(x+w-r,y); ctx.quadraticCurveTo(x+w,y,x+w,y+r);
    ctx.lineTo(x+w,y+h-r); ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h);
    ctx.lineTo(x+r,y+h); ctx.quadraticCurveTo(x,y+h,x,y+h-r);
    ctx.lineTo(x,y+r); ctx.quadraticCurveTo(x,y,x+r,y);
    ctx.closePath(); ctx.fill();
}
function crossChickenLane(){
    if(!chickenState||chickenState.gameOver)return;
    const s=chickenState;
    const lane=s.lanes[s.currentLane];
    lane.revealed=true;
    if(lane.hazard){
        s.gameOver=true;
        _crAnim.carY=0;
        renderChicken();
        document.getElementById('crCashBtn').style.display='none';
        document.getElementById('crStartBtn').style.display='';
        document.getElementById('crMulti').innerHTML='<span style="color:#ef4444">?? SQUASHED! Bet lost.</span>';
        updateCasinoCoins();
        return;
    }
    s.currentLane++;
    if(s.currentLane>=CR_LANES){
        cashOutChicken();
        return;
    }
    renderChicken();
}
function cashOutChicken(){
    if(!chickenState||chickenState.gameOver)return;
    const s=chickenState;
    if(s.currentLane<=0){
        // No lanes crossed � refund bet
        PROFILE.casinoWin(s.bet, s.bet);
        s.gameOver=true;
        document.getElementById('crCashBtn').style.display='none';
        document.getElementById('crStartBtn').style.display='';
        document.getElementById('crMulti').innerHTML='<span style="color:rgba(255,255,255,0.6)">Cancelled - bet refunded.</span>';
        updateCasinoCoins();
        renderChicken();
        return;
    }
    const multi=calcChickenMulti(s.currentLane, s.hazardP);
    const win=Math.floor(s.bet*multi);
    PROFILE.casinoWin(win, s.bet);
    s.gameOver=true;
    renderChicken();
    document.getElementById('crCashBtn').style.display='none';
    document.getElementById('crStartBtn').style.display='';
    document.getElementById('crMulti').innerHTML=`<span style="color:#4ade80">?? Made it! +${win} coins (${multi.toFixed(2)}x)</span>`;
    updateCasinoCoins();
}

// --- Roulette ---
const ROULETTE_NUMBERS=[
    {n:0,c:'green'},{n:32,c:'red'},{n:15,c:'black'},{n:19,c:'red'},{n:4,c:'black'},{n:21,c:'red'},{n:2,c:'black'},
    {n:25,c:'red'},{n:17,c:'black'},{n:34,c:'red'},{n:6,c:'black'},{n:27,c:'red'},{n:13,c:'black'},{n:36,c:'red'},
    {n:11,c:'black'},{n:30,c:'red'},{n:8,c:'black'},{n:23,c:'red'},{n:10,c:'black'},{n:5,c:'red'},{n:24,c:'black'},
    {n:16,c:'red'},{n:33,c:'black'},{n:1,c:'red'},{n:20,c:'black'},{n:14,c:'red'},{n:31,c:'black'},{n:9,c:'red'},
    {n:22,c:'black'},{n:18,c:'red'},{n:29,c:'black'},{n:7,c:'red'},{n:28,c:'black'},{n:12,c:'red'},{n:35,c:'black'},
    {n:3,c:'red'},{n:26,c:'black'}
];
let rouletteSpinning=false;
const rCvs=document.getElementById('rouletteCanvas');
const rCtx=rCvs.getContext('2d');
const RW=rCvs.width,RH=rCvs.height,RCX=RW/2,RCY=RH/2;
const RSLOTS=ROULETTE_NUMBERS.length;
const RSLOT_ANG=Math.PI*2/RSLOTS;
const R_OUTER=RW/2-4,R_INNER=R_OUTER*0.55,R_BALL_TRACK=R_OUTER*0.88;
let rWheelAngle=0;
function drawRouletteWheel(ballAngle,ballR,highlight){
    rCtx.clearRect(0,0,RW,RH);
    // Outer ring
    rCtx.save();rCtx.translate(RCX,RCY);rCtx.rotate(rWheelAngle);
    rCtx.beginPath();rCtx.arc(0,0,R_OUTER,0,Math.PI*2);rCtx.fillStyle='#1a1a2e';rCtx.fill();
    rCtx.lineWidth=2;rCtx.strokeStyle='#c9a84c';rCtx.stroke();
    // Slots
    for(let i=0;i<RSLOTS;i++){
        const a0=i*RSLOT_ANG-Math.PI/2;
        const a1=a0+RSLOT_ANG;
        const slot=ROULETTE_NUMBERS[i];
        rCtx.beginPath();rCtx.moveTo(0,0);rCtx.arc(0,0,R_OUTER-2,a0,a1);rCtx.closePath();
        let fill=slot.c==='red'?'#b91c1c':slot.c==='green'?'#15803d':'#111';
        if(highlight===i){fill=slot.c==='red'?'#ef4444':slot.c==='green'?'#22c55e':'#333';}
        rCtx.fillStyle=fill;rCtx.fill();
        rCtx.lineWidth=0.5;rCtx.strokeStyle='#c9a84c55';rCtx.stroke();
        // Number text
        const aMid=a0+RSLOT_ANG/2;
        const tr=R_OUTER*0.78;
        rCtx.save();rCtx.translate(Math.cos(aMid)*tr,Math.sin(aMid)*tr);rCtx.rotate(aMid+Math.PI/2);
        rCtx.fillStyle='#fff';rCtx.font='bold 9px sans-serif';rCtx.textAlign='center';rCtx.textBaseline='middle';
        rCtx.fillText(slot.n,0,0);rCtx.restore();
    }
    // Inner circle
    rCtx.beginPath();rCtx.arc(0,0,R_INNER,0,Math.PI*2);
    const ig=rCtx.createRadialGradient(0,0,R_INNER*0.2,0,0,R_INNER);
    ig.addColorStop(0,'#2a2a3e');ig.addColorStop(1,'#111');
    rCtx.fillStyle=ig;rCtx.fill();
    rCtx.lineWidth=2;rCtx.strokeStyle='#c9a84c';rCtx.stroke();
    // Spokes
    for(let i=0;i<8;i++){const a=i*Math.PI/4;rCtx.beginPath();rCtx.moveTo(Math.cos(a)*R_INNER*0.3,Math.sin(a)*R_INNER*0.3);rCtx.lineTo(Math.cos(a)*R_INNER*0.9,Math.sin(a)*R_INNER*0.9);rCtx.strokeStyle='#c9a84c44';rCtx.lineWidth=1;rCtx.stroke();}
    // Center dot
    rCtx.beginPath();rCtx.arc(0,0,6,0,Math.PI*2);rCtx.fillStyle='#c9a84c';rCtx.fill();
    rCtx.restore();
    // Ball (drawn in world space, not wheel-rotated)
    if(ballR>0){
        rCtx.save();rCtx.translate(RCX,RCY);
        const bx=Math.cos(ballAngle)*ballR;
        const by=Math.sin(ballAngle)*ballR;
        rCtx.beginPath();rCtx.arc(bx,by,5,0,Math.PI*2);
        rCtx.fillStyle='#eee';rCtx.fill();
        rCtx.shadowColor='#fff';rCtx.shadowBlur=8;
        rCtx.beginPath();rCtx.arc(bx,by,5,0,Math.PI*2);rCtx.fill();rCtx.shadowBlur=0;
        // Highlight
        rCtx.beginPath();rCtx.arc(bx-1.5,by-1.5,2,0,Math.PI*2);rCtx.fillStyle='rgba(255,255,255,0.6)';rCtx.fill();
        rCtx.restore();
    }
    // Pointer triangle at top
    rCtx.save();rCtx.translate(RCX,RCY);
    rCtx.beginPath();rCtx.moveTo(0,-R_OUTER+1);rCtx.lineTo(-7,-R_OUTER-10);rCtx.lineTo(7,-R_OUTER-10);rCtx.closePath();
    rCtx.fillStyle='#ffd700';rCtx.fill();rCtx.strokeStyle='#b8860b';rCtx.lineWidth=1;rCtx.stroke();
    rCtx.restore();
}
// Initial draw
drawRouletteWheel(0,0,-1);

function spinRoulette(betType){
    if(rouletteSpinning)return;
    const bet=parseInt(document.getElementById('rouletteBet').value)||0;
    if(bet<10){document.getElementById('rouletteResult').innerHTML='<span style="color:#ef4444">Min bet: 10</span>';return;}
    const p=PROFILE.get();
    if(p.coins<bet){document.getElementById('rouletteResult').innerHTML='<span style="color:#ef4444">Not enough coins!</span>';return;}
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    rouletteSpinning=true;
    document.getElementById('rouletteResult').textContent='';
    document.querySelectorAll('#rouletteBets button').forEach(b=>b.disabled=true);
    // Pick result
    const resultIdx=Math.floor(Math.random()*RSLOTS);
    const result=ROULETTE_NUMBERS[resultIdx];
    // Target angle: the slot should end up under the pointer (top = -PI/2)
    const targetSlotAngle=resultIdx*RSLOT_ANG+RSLOT_ANG/2;
    // Wheel spins clockwise multiple full rotations + lands so pointer aligns with slot
    const fullSpins=4+Math.floor(Math.random()*3);
    // Calculate correct final angle: slot center must align with pointer at top (-PI/2)
    const targetFinal=((Math.PI*2-targetSlotAngle)%(Math.PI*2)+Math.PI*2)%(Math.PI*2);
    let wheelEnd=targetFinal-((rWheelAngle%(Math.PI*2))+Math.PI*2)%(Math.PI*2);
    if(wheelEnd<0)wheelEnd+=Math.PI*2;
    wheelEnd+=fullSpins*Math.PI*2;
    // Ball spins counter-clockwise, starts fast, slows, settles into the winning slot
    const ballSpins=5+Math.floor(Math.random()*3);
    // Ball starts on outer track and spirals into pocket
    let startTime=null;
    const SPIN_DURATION=4000+Math.random()*1000;
    const wheelStart=rWheelAngle;
    function animateSpin(ts){
        if(!startTime)startTime=ts;
        const elapsed=ts-startTime;
        const t=Math.min(elapsed/SPIN_DURATION,1);
        // Ease out cubic
        const ease=1-Math.pow(1-t,3);
        // Wheel rotation
        rWheelAngle=wheelStart+wheelEnd*ease;
        // Ball: spins opposite direction, slows down, spirals inward at end
        const ballTotalAngle=ballSpins*Math.PI*2;
        const ballAng=-ballTotalAngle*ease-Math.PI/2; // starts at top
        // Ball radius: stays on track until ~80%, then spirals into pocket
        let ballR;
        if(t<0.75) ballR=R_BALL_TRACK;
        else{
            const settleT=(t-0.75)/0.25;
            const settleEase=settleT*settleT;
            // Target pocket position in world space
            const pocketR=R_OUTER*0.72;
            ballR=R_BALL_TRACK+(pocketR-R_BALL_TRACK)*settleEase;
        }
        // Determine which slot is under pointer for highlight
        let hlIdx=-1;
        if(t>0.9){
            const normAngle=(-rWheelAngle+Math.PI/2)%(Math.PI*2);
            const adj=(normAngle+Math.PI*2)%(Math.PI*2);
            hlIdx=Math.floor(adj/RSLOT_ANG)%RSLOTS;
        }
        drawRouletteWheel(ballAng,ballR,hlIdx);
        if(t<1){
            requestAnimationFrame(animateSpin);
        }else{
            // Final position: highlight result
            drawRouletteWheel(ballAng,R_OUTER*0.72,resultIdx);
            // Calculate win
            let multi=0;
            if(betType==='red'&&result.c==='red')multi=2;
            else if(betType==='black'&&result.c==='black')multi=2;
            else if(betType==='green'&&result.c==='green')multi=14;
            else if(betType==='1st12'&&result.n>=1&&result.n<=12)multi=3;
            else if(betType==='2nd12'&&result.n>=13&&result.n<=24)multi=3;
            else if(betType==='3rd12'&&result.n>=25&&result.n<=36)multi=3;
            if(multi>0){
                const win=Math.floor(bet*multi);
                PROFILE.casinoWin(win, bet);
                document.getElementById('rouletteResult').innerHTML=`<span style="color:#4ade80">${result.n} ${result.c==='red'?'??':result.c==='green'?'??':'?'} - You won ${win} coins! (${multi}x)</span>`;
            }else{
                document.getElementById('rouletteResult').innerHTML=`<span style="color:#ef4444">${result.n} ${result.c==='red'?'??':result.c==='green'?'??':'?'} - You lost ${bet} coins!</span>`;
            }
            updateCasinoCoins();
            rouletteSpinning=false;
            document.querySelectorAll('#rouletteBets button').forEach(b=>b.disabled=false);
        }
    }
    requestAnimationFrame(animateSpin);
}

// --- Dice (1-100 over/under) ---
function _diceUpdateMultis(){
    const t=Math.max(2,Math.min(98,parseInt(document.getElementById('diceTarget').value)||50));
    // House edge ~2%: payout = (98 / winChance%)
    const under=document.getElementById('diceUnderMulti');
    const over=document.getElementById('diceOverMulti');
    if(under) under.textContent=(98/(t-1)).toFixed(2)+'x';
    if(over)  over.textContent =(98/(100-t)).toFixed(2)+'x';
}
document.addEventListener('input',e=>{ if(e.target&&e.target.id==='diceTarget')_diceUpdateMultis(); });
function rollDice(direction){
    const bet=parseInt(document.getElementById('diceBet').value)||0;
    const target=Math.max(2,Math.min(98,parseInt(document.getElementById('diceTarget').value)||50));
    const resEl=document.getElementById('diceResult');
    const numEl=document.getElementById('diceRollNum');
    if(bet<10){resEl.innerHTML='<span style="color:#ef4444">Min bet: 10</span>';return;}
    const p=PROFILE.get();
    if(p.coins<bet){resEl.innerHTML='<span style="color:#ef4444">Not enough coins!</span>';return;}
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    const final=1+Math.floor(Math.random()*100);
    // Animate roll
    let frames=0; const total=22;
    const tick=()=>{
        frames++;
        if(frames<total){
            numEl.textContent=1+Math.floor(Math.random()*100);
            numEl.style.color='#fbbf24';
            setTimeout(tick,40+frames*4);
        }else{
            numEl.textContent=final;
            const won=(direction==='under'&&final<target)||(direction==='over'&&final>target);
            if(won){
                const multi=direction==='under'?(98/(target-1)):(98/(100-target));
                const winAmt=Math.floor(bet*multi);
                PROFILE.casinoWin(winAmt, bet);
                numEl.style.color='#4ade80';
                resEl.innerHTML=`<span style="color:#4ade80">Rolled ${final} - Won ${winAmt} coins! (${multi.toFixed(2)}x)</span>`;
            }else{
                numEl.style.color='#ef4444';
                resEl.innerHTML=`<span style="color:#ef4444">Rolled ${final} - Lost ${bet} coins</span>`;
            }
            updateCasinoCoins();
        }
    };
    tick();
}
_diceUpdateMultis();

// --- Slots (3-reel) ---
const SLOT_SYMBOLS=[
    {s:'??',w:1},   // jackpot - 50x
    {s:'?',w:3},   // 20x
    {s:'??',w:5},   // 10x
    {s:'7??',w:6},   // 5x same
    {s:'??',w:9},
    {s:'??',w:9},
    {s:'??',w:9},
];
const SLOT_PAYOUT={'??':50,'?':20,'??':10,'7??':7};
function _slotPick(){
    const total=SLOT_SYMBOLS.reduce((a,b)=>a+b.w,0);
    let r=Math.random()*total;
    for(const sym of SLOT_SYMBOLS){ r-=sym.w; if(r<=0) return sym.s; }
    return SLOT_SYMBOLS[SLOT_SYMBOLS.length-1].s;
}
let _slotsSpinning=false;
function spinSlots(){
    if(_slotsSpinning)return;
    const bet=parseInt(document.getElementById('slotsBet').value)||0;
    const resEl=document.getElementById('slotsResult');
    if(bet<10){resEl.innerHTML='<span style="color:#ef4444">Min bet: 10</span>';return;}
    const p=PROFILE.get();
    if(p.coins<bet){resEl.innerHTML='<span style="color:#ef4444">Not enough coins!</span>';return;}
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    _slotsSpinning=true;
    document.getElementById('slotsSpinBtn').disabled=true;
    resEl.textContent='';
    const reels=[document.getElementById('slotReel0'),document.getElementById('slotReel1'),document.getElementById('slotReel2')];
    const finals=[_slotPick(),_slotPick(),_slotPick()];
    const stops=[600,900,1200];
    reels.forEach((el,i)=>{
        const iv=setInterval(()=>{ el.textContent=_slotPick(); }, 60);
        setTimeout(()=>{
            clearInterval(iv);
            el.textContent=finals[i];
            el.style.transition='transform .15s';
            el.style.transform='scale(1.15)';
            setTimeout(()=>el.style.transform='scale(1)',150);
            if(i===2){
                // Resolve
                let multi=0;
                if(finals[0]===finals[1]&&finals[1]===finals[2]){
                    multi=SLOT_PAYOUT[finals[0]]||5;
                } else if(finals[0]===finals[1]||finals[1]===finals[2]||finals[0]===finals[2]){
                    multi=1.5;
                }
                const win=Math.floor(bet*multi);
                if(win>0){
                    PROFILE.casinoWin(win, bet);
                    resEl.innerHTML=`<span style="color:#4ade80">${finals.join(' ')} - Won ${win} coins! (${multi}x)</span>`;
                }else{
                    resEl.innerHTML=`<span style="color:#ef4444">${finals.join(' ')} - No match. Lost ${bet} coins</span>`;
                }
                updateCasinoCoins();
                _slotsSpinning=false;
                document.getElementById('slotsSpinBtn').disabled=false;
            }
        }, stops[i]);
    });
}

// --- Blackjack (advanced: split, double, insurance, surrender, multi-hand) ---
let bjState=null;
const BJ_SUITS=['?','?','?','?'];
function _bjMakeShoe(decks=6){
    const d=[];
    for(let k=0;k<decks;k++) for(let s=0;s<4;s++) for(let r=1;r<=13;r++) d.push({r,s:BJ_SUITS[s]});
    for(let i=d.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[d[i],d[j]]=[d[j],d[i]];}
    return d;
}
function _bjValue(cards){
    let total=0,aces=0;
    for(const c of cards){
        if(c.hidden) continue;
        if(c.r===1){total+=11;aces++;}
        else if(c.r>=10){total+=10;}
        else total+=c.r;
    }
    while(total>21&&aces>0){total-=10;aces--;}
    return total;
}
function _bjIsSoft(cards){
    let total=0,aces=0;
    for(const c of cards){
        if(c.hidden)continue;
        if(c.r===1){total+=11;aces++;}
        else if(c.r>=10) total+=10;
        else total+=c.r;
    }
    // soft if at least one ace counted as 11 (no demotion needed)
    while(total>21&&aces>0){total-=10;aces--;}
    return aces>0;
}
function _bjCardHTML(c,opts){
    opts=opts||{};
    if(c && c.hidden){
        return `<div class="bj-card bj-back" style="display:inline-flex;width:46px;height:64px;background:linear-gradient(135deg,#4f46e5,#7c3aed);border-radius:8px;border:2px solid rgba(255,255,255,0.2);align-items:center;justify-content:center;color:#fff;font-size:20px;box-shadow:0 4px 10px rgba(0,0,0,0.4);${opts.anim?'animation:bjDeal .3s ease-out':''}">?</div>`;
    }
    const map={1:'A',11:'J',12:'Q',13:'K'};
    const r=map[c.r]||c.r;
    const red=(c.s==='?'||c.s==='?');
    const color=red?'#dc2626':'#1c1917';
    return `<div class="bj-card" style="display:inline-flex;flex-direction:column;width:46px;height:64px;background:#fff;color:${color};border-radius:8px;border:1px solid rgba(0,0,0,0.2);padding:4px 5px;justify-content:space-between;font-family:Georgia,serif;font-weight:800;box-shadow:0 4px 10px rgba(0,0,0,0.4);${opts.anim?'animation:bjDeal .3s ease-out':''}">
        <span style="font-size:13px;line-height:1">${r}<br><span style="font-size:11px">${c.s}</span></span>
        <span style="font-size:18px;text-align:right;line-height:1">${c.s}</span>
    </div>`;
}
function _bjRender(showHole,animLastDealer,animLastPlayer){
    const dEl=document.getElementById('bjDealerCards');
    const pWrap=document.getElementById('bjHandsWrap');
    const dvEl=document.getElementById('bjDealerVal');
    if(!bjState||!dEl||!pWrap)return;
    const dealer=bjState.dealer;
    let dHTML='';
    for(let i=0;i<dealer.length;i++){
        const c=(i===1&&!showHole)?{hidden:true}:dealer[i];
        const isLast=(i===dealer.length-1);
        dHTML+=_bjCardHTML(c,{anim:isLast&&animLastDealer});
    }
    dEl.innerHTML=dHTML;
    if(showHole){
        dvEl.textContent=_bjValue(dealer)+(_bjIsSoft(dealer)?' (soft)':'');
    } else {
        // show only first card value
        const upVal=_bjValue([dealer[0]]);
        dvEl.textContent=upVal+'+?';
    }
    // Hands
    let html='';
    for(let h=0;h<bjState.hands.length;h++){
        const hand=bjState.hands[h];
        const isActive=(h===bjState.activeHand && !bjState.done && !bjState.insuranceQuestion);
        const v=_bjValue(hand.cards);
        const soft=_bjIsSoft(hand.cards);
        const status=hand.bust?'BUST':(hand.surrendered?'SURRENDER':(hand.stood?'STAND':(v===21?'21':'')));
        const statusColor=hand.bust?'#ef4444':(v===21?'#fbbf24':(hand.stood?'#94a3b8':'#4ade80'));
        const label=bjState.hands.length>1?`HAND ${h+1}`:'YOU';
        html+=`<div style="border:${isActive?'2px solid #fbbf24':'1px solid rgba(255,255,255,0.06)'};border-radius:10px;padding:8px 10px;background:${isActive?'rgba(251,191,36,0.06)':'rgba(0,0,0,0.18)'};transition:all .2s">
            <div style="display:flex;justify-content:space-between;align-items:center;font-size:10px;letter-spacing:1.5px;color:rgba(255,255,255,0.5);margin-bottom:6px">
                <span>${label} <span style="color:#fff;font-weight:700">$${hand.bet}${hand.doubled?' (DBL)':''}</span></span>
                <span style="color:${statusColor};font-weight:800">${v}${soft?' (soft)':''} ${status?'� '+status:''}</span>
            </div>
            <div style="display:flex;gap:6px;flex-wrap:wrap;min-height:70px">${hand.cards.map((c,i)=>_bjCardHTML(c,{anim:isActive&&animLastPlayer&&i===hand.cards.length-1})).join('')}</div>
        </div>`;
    }
    pWrap.innerHTML=html;
}
function _bjShowButtons(opts){
    const ids=['bjStartBtn','bjHitBtn','bjStandBtn','bjDoubleBtn','bjSplitBtn','bjSurrenderBtn','bjInsureBtn','bjDeclineInsBtn'];
    for(const id of ids){
        const el=document.getElementById(id);
        if(el) el.style.display=opts[id]?'':'none';
    }
}
function bjBetMod(f){
    const el=document.getElementById('bjBet');
    let v=Math.max(10,Math.floor((parseInt(el.value)||10)*f));
    el.value=v;
}
function bjBetMax(){
    const p=PROFILE.get();
    document.getElementById('bjBet').value=Math.max(10,Math.floor(p.coins));
}
function _bjActiveHand(){ return bjState.hands[bjState.activeHand]; }
function _bjUpdateActions(){
    const hand=_bjActiveHand();
    const v=_bjValue(hand.cards);
    const isFirstAction=hand.cards.length===2&&!hand.doubled&&!hand.fromSplit_skipDouble;
    const canDouble=isFirstAction && PROFILE.get().coins>=hand.bet;
    const isPair=hand.cards.length===2 && _bjCardRank(hand.cards[0])===_bjCardRank(hand.cards[1]);
    const canSplit=isPair && bjState.hands.length<4 && PROFILE.get().coins>=hand.bet;
    const canSurrender=isFirstAction && bjState.hands.length===1 && !hand.fromSplit_skipDouble;
    _bjShowButtons({
        bjHitBtn:!hand.bust && v<21,
        bjStandBtn:!hand.bust && v<21,
        bjDoubleBtn:canDouble && v<21,
        bjSplitBtn:canSplit,
        bjSurrenderBtn:canSurrender,
    });
}
function _bjCardRank(c){ return c.r>=10?10:c.r; }
function startBlackjack(){
    const bet=parseInt(document.getElementById('bjBet').value)||0;
    const resEl=document.getElementById('bjResult');
    if(bet<10){resEl.innerHTML='<span style="color:#ef4444">Min bet: 10</span>';return;}
    const p=PROFILE.get();
    if(p.coins<bet){resEl.innerHTML='<span style="color:#ef4444">Not enough coins!</span>';return;}
    PROFILE.spendCoins(bet);
    updateCasinoCoins();
    const deck=_bjMakeShoe(6);
    bjState={
        deck, baseBet:bet,
        hands:[{cards:[deck.pop(),deck.pop()], bet, doubled:false, stood:false, bust:false, surrendered:false}],
        activeHand:0,
        dealer:[deck.pop(),deck.pop()],
        done:false,
        insurance:0,
        insuranceQuestion:false
    };
    document.getElementById('bjBoard').style.display='block';
    resEl.textContent='';
    _bjRender(false,true,true);
    // Insurance offer if dealer up-card is Ace
    if(bjState.dealer[0].r===1){
        bjState.insuranceQuestion=true;
        _bjShowButtons({bjInsureBtn:true,bjDeclineInsBtn:true});
        resEl.innerHTML='<span style="color:#0ea5e9">Dealer shows an Ace. Insurance? (� bet, pays 2:1)</span>';
        return;
    }
    _bjPostDealCheck();
}
function insureBlackjack(){
    if(!bjState||!bjState.insuranceQuestion)return;
    const cost=Math.floor(bjState.baseBet/2);
    const p=PROFILE.get();
    if(p.coins<cost){document.getElementById('bjResult').innerHTML='<span style="color:#ef4444">Not enough coins for insurance</span>';return declineInsuranceBlackjack();}
    PROFILE.spendCoins(cost);
    updateCasinoCoins();
    bjState.insurance=cost;
    bjState.insuranceQuestion=false;
    document.getElementById('bjResult').innerHTML='<span style="color:#0ea5e9">Insurance taken: '+cost+' coins.</span>';
    _bjPostDealCheck();
}
function declineInsuranceBlackjack(){
    if(!bjState||!bjState.insuranceQuestion)return;
    bjState.insuranceQuestion=false;
    document.getElementById('bjResult').textContent='';
    _bjPostDealCheck();
}
function _bjPostDealCheck(){
    // Check dealer blackjack (only matters now if insurance offered, but always check)
    const dealerBJ=_bjValue(bjState.dealer)===21;
    const playerBJ=_bjValue(bjState.hands[0].cards)===21;
    if(dealerBJ){
        // Reveal hole, settle
        bjState.done=true;
        _bjRender(true,false,false);
        let msg='', net=0;
        const baseBet=bjState.baseBet;
        // Insurance pays 2:1 (return the half-bet stake at 3x total)
        if(bjState.insurance>0){
            const ipay=bjState.insurance*3;
            PROFILE.casinoWin(ipay, bjState.insurance);
            net+=ipay-bjState.insurance;
        } else {
            net-=0; // no insurance
        }
        if(playerBJ){
            // push on main bet
            PROFILE.casinoWin(baseBet, baseBet);
            msg=`<span style="color:#fbbf24">Both blackjack � push. ${bjState.insurance>0?'Insurance won 2:1.':''}</span>`;
        } else {
            msg=`<span style="color:#ef4444">Dealer blackjack. Lost ${baseBet} coins.${bjState.insurance>0?' Insurance saved you '+(bjState.insurance*2)+'.':''}</span>`;
        }
        document.getElementById('bjResult').innerHTML=msg;
        _bjShowButtons({bjStartBtn:true});
        updateCasinoCoins();
        return;
    }
    if(bjState.insurance>0){
        // Insurance lost
        document.getElementById('bjResult').innerHTML='<span style="color:rgba(255,255,255,0.6)">No dealer blackjack � insurance lost.</span>';
    }
    if(playerBJ){
        // Auto-stand on natural
        bjState.hands[0].stood=true;
        _bjFinishDealer();
        return;
    }
    _bjUpdateActions();
}
function hitBlackjack(){
    if(!bjState||bjState.done)return;
    const hand=_bjActiveHand();
    if(hand.bust||hand.stood)return;
    hand.cards.push(bjState.deck.pop());
    const v=_bjValue(hand.cards);
    if(v>21) hand.bust=true;
    if(hand.fromSplit_skipDouble){/* keep flag */}
    _bjRender(false,false,true);
    if(hand.bust||v===21){
        _bjAdvanceHand();
    } else {
        _bjUpdateActions();
    }
}
function standBlackjack(){
    if(!bjState||bjState.done)return;
    const hand=_bjActiveHand();
    if(hand.bust)return;
    hand.stood=true;
    _bjAdvanceHand();
}
function doubleBlackjack(){
    if(!bjState||bjState.done)return;
    const hand=_bjActiveHand();
    if(hand.cards.length!==2||hand.doubled)return;
    const p=PROFILE.get();
    if(p.coins<hand.bet){document.getElementById('bjResult').innerHTML='<span style="color:#ef4444">Not enough coins to double</span>';return;}
    PROFILE.spendCoins(hand.bet);
    updateCasinoCoins();
    hand.bet*=2;
    hand.doubled=true;
    hand.cards.push(bjState.deck.pop());
    if(_bjValue(hand.cards)>21) hand.bust=true;
    else hand.stood=true;
    _bjRender(false,false,true);
    _bjAdvanceHand();
}
function splitBlackjack(){
    if(!bjState||bjState.done)return;
    const hand=_bjActiveHand();
    if(hand.cards.length!==2)return;
    if(_bjCardRank(hand.cards[0])!==_bjCardRank(hand.cards[1]))return;
    if(bjState.hands.length>=4)return;
    const p=PROFILE.get();
    if(p.coins<hand.bet){document.getElementById('bjResult').innerHTML='<span style="color:#ef4444">Not enough coins to split</span>';return;}
    PROFILE.spendCoins(hand.bet);
    updateCasinoCoins();
    const second=hand.cards.pop();
    const newHand={cards:[second,bjState.deck.pop()],bet:hand.bet,doubled:false,stood:false,bust:false,surrendered:false,fromSplit_skipDouble:false};
    hand.cards.push(bjState.deck.pop());
    // Aces: only one card after split, then auto-stand
    const isAces=hand.cards[0].r===1;
    if(isAces){ hand.stood=true; newHand.stood=true; }
    bjState.hands.splice(bjState.activeHand+1,0,newHand);
    _bjRender(false,false,false);
    if(isAces) _bjAdvanceHand();
    else _bjUpdateActions();
}
function surrenderBlackjack(){
    if(!bjState||bjState.done)return;
    const hand=_bjActiveHand();
    if(hand.cards.length!==2||bjState.hands.length>1)return;
    hand.surrendered=true;
    hand.stood=true;
    // Refund half
    PROFILE.casinoWin(Math.floor(hand.bet/2), Math.floor(hand.bet/2));
    updateCasinoCoins();
    bjState.done=true;
    _bjRender(true,false,false);
    document.getElementById('bjResult').innerHTML='<span style="color:rgba(255,255,255,0.6)">Surrendered � recovered '+Math.floor(hand.bet/2)+' coins.</span>';
    _bjShowButtons({bjStartBtn:true});
}
function _bjAdvanceHand(){
    bjState.activeHand++;
    if(bjState.activeHand>=bjState.hands.length){
        _bjFinishDealer();
    } else {
        _bjRender(false,false,false);
        _bjUpdateActions();
    }
}
function _bjFinishDealer(){
    bjState.done=true;
    _bjShowButtons({});
    // Only deal dealer cards if at least one hand isn't bust/surrendered
    const anyAlive=bjState.hands.some(h=>!h.bust && !h.surrendered);
    if(anyAlive){
        // Reveal hole and animate hits
        _bjRender(true,true,false);
        let i=0;
        const drawNext=()=>{
            const dv=_bjValue(bjState.dealer);
            const soft=_bjIsSoft(bjState.dealer);
            // Dealer hits soft 17
            if(dv<17||(dv===17&&soft)){
                bjState.dealer.push(bjState.deck.pop());
                _bjRender(true,true,false);
                setTimeout(drawNext,420);
            } else {
                _bjSettle();
            }
        };
        setTimeout(drawNext,420);
    } else {
        _bjRender(true,false,false);
        _bjSettle();
    }
}
function _bjSettle(){
    const dv=_bjValue(bjState.dealer);
    let totalNet=0;
    let lines=[];
    for(let i=0;i<bjState.hands.length;i++){
        const h=bjState.hands[i];
        if(h.surrendered){continue;}
        const pv=_bjValue(h.cards);
        const label=bjState.hands.length>1?`H${i+1} `:'';
        if(h.bust){
            lines.push(`<span style="color:#ef4444">${label}Bust -${h.bet}</span>`);
            totalNet-=h.bet;
        } else if(pv===21 && h.cards.length===2 && !h.fromSplit_skipDouble && bjState.hands.length===1){
            // Natural BJ pays 3:2
            const pay=Math.floor(h.bet*2.5);
            PROFILE.casinoWin(pay, h.bet);
            lines.push(`<span style="color:#fbbf24">${label}BLACKJACK +${pay-h.bet}</span>`);
            totalNet+=pay-h.bet;
        } else if(dv>21||pv>dv){
            const pay=h.bet*2;
            PROFILE.casinoWin(pay, h.bet);
            lines.push(`<span style="color:#4ade80">${label}Win +${h.bet}</span>`);
            totalNet+=h.bet;
        } else if(pv===dv){
            PROFILE.casinoWin(h.bet, h.bet);
            lines.push(`<span style="color:rgba(255,255,255,0.7)">${label}Push</span>`);
        } else {
            lines.push(`<span style="color:#ef4444">${label}Lose -${h.bet}</span>`);
            totalNet-=h.bet;
        }
    }
    const totalLine=`<div style="margin-top:4px;font-weight:800;color:${totalNet>0?'#4ade80':totalNet<0?'#ef4444':'#fff'}">Net ${totalNet>=0?'+':''}${totalNet} coins</div>`;
    document.getElementById('bjResult').innerHTML=lines.join(' � ')+totalLine;
    _bjShowButtons({bjStartBtn:true});
    updateCasinoCoins();
}

function updateAccountUI(){
    const user=getSession();
    if(user){
        accountLabel.textContent=user;
        accountBtn.style.background='rgba(129,140,248,0.2)';
        if(typeof PROFILE!=='undefined'&&PROFILE.exists())updateTopbarCoins();
    }else{
        accountLabel.textContent='Log in';
        accountBtn.style.background='';
    }
}
updateAccountUI();
authSwitch.addEventListener('click',()=>setAuthMode('signup'));

// === World Records + Chat System ===
const API_BASE='https://fell-server.bobarne60.workers.dev';

// --- Sync user profile to server (for admin panel) ---
let _syncBusy=false;
async function syncUserToServer(){
    const user=getSession();
    if(!user||_syncBusy)return;
    _syncBusy=true;
    const p=PROFILE.get();
    if(!p){_syncBusy=false;return;}
    try{
        const res=await fetch(API_BASE+'/api/user/sync',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({
            name:user.toLowerCase(),displayName:user,coins:p.coins||0,totalCoinsEarned:p.totalCoinsEarned||0,
            school:p.school||'',gamesPlayed:p.gamesPlayed||0,owned:p.owned||[],created:p.created
        })});
        if(!res.ok){_syncBusy=false;return;}
        const data=await res.json();
        if(data.banned){
            showBanScreen(data.banReason||'');
            _syncBusy=false;
            return;
        }
        // Admin set coins directly
        if(typeof data.setCoins==='number'){
            const target=data.setCoins;
            const cur=PROFILE.get().coins||0;
            if(target!==cur){
                const diff=target-cur;
                if(diff>0)PROFILE.addCoins(diff);
                else{const pp=PROFILE.get();pp.coins=target;PROFILE.save(pp);}
                syncCoinsToAccount();
                if(typeof updateCasinoCoins==='function')updateCasinoCoins();
            }
        }
    }catch(e){}
    _syncBusy=false;
}

function showBanScreen(reason){
    const overlay=document.getElementById('banOverlay');
    if(!overlay)return;
    overlay.style.display='flex';
    const txt=document.getElementById('banReasonText');
    if(txt)txt.textContent=reason?'Reason: '+reason:'Your account has been banned from Spillsenteret.';
}

// Sync all local accounts to server on first visit so admin sees everyone
function syncAllAccountsToServer(){
    try{
        const accounts=getAccounts();
        const arr=[];
        for(const key in accounts){
            const a=accounts[key];
            arr.push({name:key,displayName:a.name||key,coins:a.coins||0,totalCoinsEarned:a.totalCoinsEarned||0,
                school:a.school||'',gamesPlayed:a.gamesPlayed||0,owned:a.owned||[],created:a.created||Date.now()});
        }
        if(arr.length>0){
            fetch(API_BASE+'/api/user/sync',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({users:arr})}).catch(()=>{});
        }
    }catch(e){}
}

// Auto-sync every 10 seconds
if(getSession()){
    setTimeout(syncUserToServer,1000);
    setInterval(syncUserToServer,10000);
    // Bulk sync all known accounts once
    setTimeout(syncAllAccountsToServer,2000);
}

// --- Scoreboard Tabs ---
function switchScoreboardTab(tab){
    const pEl=document.getElementById('scoreboardPersonal'),rEl=document.getElementById('scoreboardRecords'),sEl=document.getElementById('scoreboardSchool'),cEl=document.getElementById('scoreboardCoins'),fEl=document.getElementById('scoreboardFriends');
    const pTab=document.getElementById('sbTabPersonal'),rTab=document.getElementById('sbTabRecords'),sTab=document.getElementById('sbTabSchool'),cTab=document.getElementById('sbTabCoins'),fTab=document.getElementById('sbTabFriends');
    pEl.style.display='none';rEl.style.display='none';sEl.style.display='none';cEl.style.display='none';if(fEl)fEl.style.display='none';
    pTab.classList.remove('active');rTab.classList.remove('active');sTab.classList.remove('active');cTab.classList.remove('active');if(fTab)fTab.classList.remove('active');
    if(tab==='records'){
        rEl.style.display='block';rTab.classList.add('active');
        fetchWorldRecords();
    }else if(tab==='school'){
        sEl.style.display='block';sTab.classList.add('active');
        renderSchoolLeaderboard();
    }else if(tab==='coins'){
        cEl.style.display='block';cTab.classList.add('active');
        syncCoinsToAccount();
        renderCoinsLeaderboard();
    }else if(tab==='friends'){
        fEl.style.display='block';fTab.classList.add('active');
        renderFriendsTab();
    }else{
        pEl.style.display='block';pTab.classList.add('active');
    }
}

const RECORD_GAMES=[
    {key:'fell',name:'FELL',unit:'s',color:'#ff6b6b'},
    {key:'rise',name:'RISE',unit:'m',color:'#4ade80'},
    {key:'swerve',name:'SWERVE',unit:'m',color:'#fbbf24'},
    {key:'dash',name:'DASH',unit:'m',color:'#60a5fa'},
    {key:'dodge',name:'DODGE',unit:'s',color:'#f97316'},
    {key:'hit',name:'HIT',unit:'',color:'#a855f7'},
    {key:'spin',name:'SPIN',unit:'s',color:'#818cf8'},
    {key:'climb',name:'CLIMB',unit:'m',color:'#34d399'},
    {key:'rush',name:'RUSH',unit:'',color:'#fb923c'},
    {key:'drop',name:'DROP',unit:'m',color:'#38bdf8'},
    {key:'hexfall',name:'HEXFALL',unit:'s',color:'#c084fc'},
    {key:'beat',name:'BEAT',unit:'',color:'#ff44aa'},
    {key:'volley',name:'VOLLEY',unit:' sets',color:'#fcd34d'},
    {key:'territory',name:'TERRITORY',unit:'%',color:'#22d3ee'},
    {key:'slash',name:'SLASH',unit:'',color:'#fb7185'},
    {key:'orbit',name:'ORBIT',unit:'s',color:'#a78bfa'},
    {key:'maze',name:'MAZE',unit:'',color:'#44dd88'},
    {key:'drift',name:'DRIFT',unit:'m',color:'#00c8ff'},
    {key:'pulse',name:'PULSE',unit:'',color:'#c832ff'},
    {key:'swap',name:'SWAP',unit:'',color:'#ffaa00'},
    {key:'flick',name:'FLICK',unit:'',color:'#ff6633'},
];

async function fetchWorldRecords(){
    const loading=document.getElementById('recordsLoading'),grid=document.getElementById('recordsGrid');
    loading.style.display='block';grid.innerHTML='';
    try{
        const res=await fetch(API_BASE+'/api/records');
        if(!res.ok)throw 0;
        const data=await res.json();
        loading.style.display='none';
        renderWorldRecords(data);
    }catch(e){loading.textContent='Could not load world records';}
}

function renderWorldRecords(data){
    const grid=document.getElementById('recordsGrid');
    let html='';
    RECORD_GAMES.forEach(g=>{
        const records=(data[g.key]||[]).slice(0,5);
        let rows='';
        if(!records.length){
            rows='<div style="padding:12px 0;text-align:center;font-size:11px;color:rgba(255,255,255,0.2)">No records yet</div>';
        }else{
            const medals=['??','??','??'];
            records.forEach((r,i)=>{
                const medal=i<3?medals[i]:`<span style="color:rgba(255,255,255,0.3)">#${i+1}</span>`;
                const val=g.unit==='s'?parseFloat(r.score).toFixed(1):Math.round(r.score);
                rows+=`<div style="display:flex;align-items:center;gap:8px;padding:6px 0;${i<records.length-1?'border-bottom:1px solid rgba(255,255,255,0.04)':''}">
                    <span style="width:24px;text-align:center;font-size:13px">${medal}</span>
                    <span style="flex:1;font-size:12px;color:#e2e8f0;font-weight:600">${_esc(r.name)}</span>
                    <span style="font-size:13px;font-weight:800;color:${g.color}">${val}${g.unit}</span>
                </div>`;
            });
        }
        html+=`<div style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:14px;padding:16px;position:relative;overflow:hidden">
            <div style="position:absolute;top:0;left:0;right:0;height:3px;background:${g.color};opacity:0.6"></div>
            <div style="font-size:14px;font-weight:800;color:#fff;letter-spacing:1px;margin-bottom:10px">${g.name}</div>
            ${rows}
        </div>`;
    });
    grid.innerHTML=html;
}

function _esc(s){const d=document.createElement('div');d.textContent=s;return d.innerHTML;}

async function submitWorldRecord(game,score){
    const user=getSession();if(!user)return;
    try{await fetch(API_BASE+'/api/records',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({game,name:user,score})});}catch(e){}
}

// --- Friends ---
function addFriendFromInput(){
    const input=document.getElementById('friendInput');
    if(!input)return;
    const name=input.value.trim();
    if(!name){return;}
    const user=getSession();
    if(user && name.toLowerCase()===user.toLowerCase()){
        alert("You can't add yourself as a friend.");
        return;
    }
    if(!PROFILE.exists()){
        if(user) PROFILE.create(user);
    }
    const res=PROFILE.addFriend(name);
    if(!res.ok){alert(res.reason||'Could not add friend');return;}
    input.value='';
    renderFriendsTab();
}

function removeFriendByName(name){
    if(!confirm('Remove '+name+' from friends?'))return;
    PROFILE.removeFriend(name);
    renderFriendsTab();
}

async function renderFriendsTab(){
    const listEl=document.getElementById('friendsList');
    const lbEl=document.getElementById('friendsLeaderboard');
    const loadingEl=document.getElementById('friendsLoading');
    if(!listEl||!lbEl)return;
    const user=getSession();
    if(!user){
        listEl.innerHTML='<div style="padding:14px;text-align:center;color:rgba(255,255,255,0.4);font-size:13px">Log in to manage friends.</div>';
        lbEl.innerHTML='';return;
    }
    if(!PROFILE.exists())PROFILE.create(user);
    const friends=PROFILE.getFriends();

    // Render friends list
    if(!friends.length){
        listEl.innerHTML='<div style="padding:14px;text-align:center;color:rgba(255,255,255,0.4);font-size:13px;background:rgba(255,255,255,0.02);border:1px dashed rgba(255,255,255,0.08);border-radius:10px">No friends added yet. Type a username above and hit ADD.</div>';
    }else{
        listEl.innerHTML=friends.map(f=>`
            <div style="display:flex;align-items:center;gap:10px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:10px;padding:10px 14px">
                <div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#8b5cf6,#ec4899);display:flex;align-items:center;justify-content:center;font-weight:800;color:#fff">${_esc(f.charAt(0).toUpperCase())}</div>
                <div style="flex:1;font-weight:700;color:#e2e8f0">${_esc(f)}</div>
                <button onclick="removeFriendByName('${_esc(f)}')" style="background:rgba(239,68,68,0.15);border:1px solid rgba(239,68,68,0.3);color:#fca5a5;padding:5px 12px;border-radius:7px;font-weight:700;font-size:11px;letter-spacing:1px;cursor:pointer">REMOVE</button>
            </div>`).join('');
    }

    // Render friend leaderboard (filter world records to me + friends)
    if(!friends.length){
        lbEl.innerHTML='<div style="padding:24px;text-align:center;color:rgba(255,255,255,0.3);font-size:12px;grid-column:1/-1">Add friends to see this leaderboard.</div>';
        return;
    }
    loadingEl.style.display='block';
    lbEl.innerHTML='';
    let data={};
    try{
        const res=await fetch(API_BASE+'/api/records');
        if(res.ok)data=await res.json();
    }catch(e){}
    loadingEl.style.display='none';

    const meKey=user.toLowerCase();
    const include=new Set([meKey,...friends.map(f=>f.toLowerCase())]);
    let html='';
    RECORD_GAMES.forEach(g=>{
        const all=data[g.key]||[];
        const filtered=all.filter(r=>r&&include.has(String(r.name||'').toLowerCase()))
                         .sort((a,b)=>(b.score||0)-(a.score||0))
                         .slice(0,8);
        let rows='';
        if(!filtered.length){
            rows='<div style="padding:12px 0;text-align:center;font-size:11px;color:rgba(255,255,255,0.2)">No friend scores yet</div>';
        }else{
            const medals=['??','??','??'];
            filtered.forEach((r,i)=>{
                const medal=i<3?medals[i]:`<span style="color:rgba(255,255,255,0.3)">#${i+1}</span>`;
                const val=g.unit==='s'?parseFloat(r.score).toFixed(1):Math.round(r.score);
                const isMe=String(r.name||'').toLowerCase()===meKey;
                const nameStyle=isMe?'color:#fbbf24;font-weight:800':'color:#e2e8f0;font-weight:600';
                rows+=`<div style="display:flex;align-items:center;gap:8px;padding:6px 0;${i<filtered.length-1?'border-bottom:1px solid rgba(255,255,255,0.04)':''}">
                    <span style="width:24px;text-align:center;font-size:13px">${medal}</span>
                    <span style="flex:1;font-size:12px;${nameStyle}">${_esc(r.name)}${isMe?' (you)':''}</span>
                    <span style="font-size:13px;font-weight:800;color:${g.color}">${val}${g.unit}</span>
                </div>`;
            });
        }
        html+=`<div style="background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);border-radius:14px;padding:16px;position:relative;overflow:hidden">
            <div style="position:absolute;top:0;left:0;right:0;height:3px;background:${g.color};opacity:0.6"></div>
            <div style="font-size:14px;font-weight:800;color:#fff;letter-spacing:1px;margin-bottom:10px">${g.name}</div>
            ${rows}
        </div>`;
    });
    lbEl.innerHTML=html;
}

// --- Chat System ---
let chatTab='global',chatDmTarget=null,chatPollTimer=null,chatLastTs=0,chatDmLastTs=0,heartbeatTimer=null,chatPanelOpen=false,notifEnabled=false;
function _tabSid(){
    let s=sessionStorage.getItem('tab_sid');
    if(!s){s='s_'+Math.random().toString(36).slice(2,12)+Date.now().toString(36);sessionStorage.setItem('tab_sid',s);}
    return s;
}
function _notify(title,body){
    if(!notifEnabled||document.hasFocus()&&chatPanelOpen)return;
    try{const n=new Notification(title,{body,icon:'/favicon.ico',silent:false});setTimeout(()=>n.close(),6000);n.onclick=()=>{window.focus();openChatPanel();n.close();};}catch(e){}
}
function enableChatNotifications(){
    if(!('Notification' in window)){alert('Your browser does not support notifications');return;}
    Notification.requestPermission().then(p=>{
        notifEnabled=(p==='granted');
        localStorage.setItem('chat_notif',notifEnabled?'1':'0');
        const btn=document.getElementById('chatNotifBtn');
        if(btn)btn.textContent=notifEnabled?'?? Notifications on':'?? Enable notifications';
    });
}
// Init notification state on load
if('Notification' in window&&Notification.permission==='granted'&&localStorage.getItem('chat_notif')!=='0')notifEnabled=true;
window.addEventListener('DOMContentLoaded',()=>{
    const b=document.getElementById('chatNotifBtn');
    if(b&&notifEnabled){b.textContent='?? Notifications on';b.style.color='#4ade80';}
});

function openChatPanel(){
    document.getElementById('chatPanel').style.display='flex';
    document.getElementById('chatToggle').style.display='none';
    chatPanelOpen=true;
    if(!chatPollTimer)startChatPolling();
    if(chatTab==='global')fetchGlobalChat();
    if(chatTab==='online')fetchOnlineUsers();
}
function closeChatPanel(){
    document.getElementById('chatPanel').style.display='none';
    document.getElementById('chatToggle').style.display='flex';
    chatPanelOpen=false;
    if(chatPollTimer){clearInterval(chatPollTimer);chatPollTimer=null;}
}
function toggleChatMinimize(){
    const c=document.getElementById('chatContent'),w=document.getElementById('chatInputWrap');
    const h=c.style.display==='none';
    c.style.display=h?'':'none';w.style.display=h?'':'none';
}
function switchChatTab(tab){
    chatTab=tab;
    ['global','dm','online'].forEach(t=>{
        const btn=document.getElementById('chatTab'+t.charAt(0).toUpperCase()+t.slice(1));
        btn.style.color=t===tab?'#818cf8':'rgba(255,255,255,0.4)';
        btn.style.borderBottom=t===tab?'2px solid #818cf8':'2px solid transparent';
    });
    document.getElementById('chatMessages').style.display=tab==='global'?'':'none';
    document.getElementById('chatDmView').style.display=tab==='dm'?'':'none';
    document.getElementById('chatOnlineView').style.display=tab==='online'?'':'none';
    document.getElementById('chatInputWrap').style.display=tab==='online'?'none':'';
    if(tab==='global')fetchGlobalChat();
    if(tab==='dm'&&chatDmTarget)fetchDmChat();
    if(tab==='online')fetchOnlineUsers();
}
async function sendChatMessage(){
    const inp=document.getElementById('chatInput'),text=inp.value.trim();
    if(!text)return;
    let user=getSession();
    if(!user&&window.SPILL_PRESENCE&&window.SPILL_PRESENCE.getName)user=window.SPILL_PRESENCE.getName();
    if(!user){inp.value='';return;}
    inp.value='';
    const body={name:user,text,type:chatTab==='dm'&&chatDmTarget?'dm':'global'};
    if(body.type==='dm')body.to=chatDmTarget;
    try{
        await fetch(API_BASE+'/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});
        if(chatTab==='global')fetchGlobalChat();
        else if(chatTab==='dm')fetchDmChat();
    }catch(e){}
}
async function fetchGlobalChat(){
    try{
        const res=await fetch(API_BASE+'/api/chat?since='+chatLastTs);
        if(!res.ok)return;const msgs=await res.json();
        if(msgs.length){chatLastTs=msgs[msgs.length-1].ts;renderChatMsgs(msgs,'chatMessages',true);}
    }catch(e){}
}
async function fetchDmChat(){
    if(!chatDmTarget)return;const user=getSession();if(!user)return;
    try{
        const res=await fetch(API_BASE+'/api/chat/dm?user1='+encodeURIComponent(user)+'&user2='+encodeURIComponent(chatDmTarget));
        if(!res.ok)return;const msgs=await res.json();
        renderChatMsgs(msgs,'chatDmMessages',false);
    }catch(e){}
}
function renderChatMsgs(msgs,cid,append){
    const c=document.getElementById(cid),me=getSession();
    if(!append)c.innerHTML='';
    msgs.forEach(m=>{
        const own=m.name===me;
        const d=document.createElement('div');
        d.style.cssText='padding:6px 10px;border-radius:10px;font-size:12px;max-width:85%;'+(own?'margin-left:auto;background:rgba(129,140,248,0.15);':'background:rgba(255,255,255,0.05);');
        d.innerHTML='<span style="font-weight:700;color:'+(own?'#818cf8':'#e2e8f0')+';font-size:11px">'+_esc(m.name)+'</span><br><span style="color:rgba(255,255,255,0.7)">'+_esc(m.text)+'</span>';
        c.appendChild(d);
    });
    const p=c.closest('#chatContent');if(p)p.scrollTop=p.scrollHeight;
}
async function fetchOnlineUsers(){
    // Show guest banner if not logged in
    try {
      const isGuest = window.SPILL_PRESENCE && window.SPILL_PRESENCE.isGuest && window.SPILL_PRESENCE.isGuest();
      const banner = document.getElementById('guestNickBanner');
      if (banner) {
        banner.style.display = isGuest ? 'block' : 'none';
        if (isGuest) {
          const input = document.getElementById('guestNickInput');
          if (input && !input.value) input.value = window.SPILL_PRESENCE.getName() || '';
        }
      }
    } catch(_) {}
    try{
        const res=await fetch(API_BASE+'/api/online');if(!res.ok)return;
        const data=await res.json();
        let users=data.users||[];
        // Backwards compat: server may return ['name', ...] or [{name, games, tabs}, ...]
        users = users.map(u => typeof u === 'string' ? { name: u, games: [], tabs: 1 } : u);
        const sessions=data.sessionCount||users.length;
        document.getElementById('chatOnlineCount').textContent=sessions+' online'+(users.length?' ('+users.length+' names)':'');
        const list=document.getElementById('chatOnlineList'),me=getSession()||(window.SPILL_PRESENCE&&window.SPILL_PRESENCE.getName());
        if(!users.length){list.innerHTML='<div style="padding:16px;text-align:center;font-size:12px;color:rgba(255,255,255,0.2)">'+sessions+' tab(s) connected</div>';return;}
        list.innerHTML=users.map(u=>{
          const name=u.name||'Anonymous';
          const games=(u.games||[]).filter(g=>g&&g!=='home');
          const gameLabel=games.length?games.map(g=>g.toUpperCase()).join(', '):'Home';
          const dot=games.length?'#fbbf24':'#4ade80';
          const isMe=name===me;
          return '<div style="display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:8px;background:rgba(255,255,255,0.03)">'+
            '<div style="width:8px;height:8px;border-radius:50%;background:'+dot+'"></div>'+
            '<div style="flex:1;min-width:0"><div style="font-size:12px;font-weight:600;color:#e2e8f0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+_esc(name)+'</div>'+
            '<div style="font-size:10px;color:rgba(255,255,255,0.4)">'+_esc(gameLabel)+(u.tabs>1?' � '+u.tabs+' tabs':'')+'</div></div>'+
            (isMe?'<span style="font-size:10px;color:rgba(255,255,255,0.2)">you</span>':'<button onclick="startDm(\''+_esc(name).replace(/\x27/g,"\\x27")+'\')" style="background:rgba(129,140,248,0.15);border:1px solid rgba(129,140,248,0.2);color:#818cf8;padding:4px 10px;border-radius:6px;font-size:10px;font-weight:700;cursor:pointer">DM</button>')+
          '</div>';
        }).join('');
    }catch(e){}
}
function saveGuestNick(){
    const v=document.getElementById('guestNickInput').value;
    if(window.SPILL_PRESENCE&&window.SPILL_PRESENCE.setGuestName(v)){fetchOnlineUsers();}
    else{alert('Enter a valid nickname');}
}
function startDm(name){
    chatDmTarget=name;switchChatTab('dm');
    document.getElementById('chatDmSelect').innerHTML='<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px"><span style="font-size:12px;color:#818cf8;font-weight:700">Chat with '+_esc(name)+'</span><button onclick="chatDmTarget=null;switchChatTab(\'dm\')" style="background:none;border:none;color:rgba(255,255,255,0.3);font-size:14px;cursor:pointer">&times;</button></div>';
    fetchDmChat();
}
function startChatPolling(){
    chatPollTimer=setInterval(()=>{
        if(chatTab==='global')fetchGlobalChat();
        else if(chatTab==='dm'&&chatDmTarget)fetchDmChat();
        fetchOnlineUsers();
    },5000);
}
function stopChatPolling(){
    if(chatPollTimer){clearInterval(chatPollTimer);chatPollTimer=null;}
}
function startHeartbeat(){
    const user=getSession()||'Anonymous';
    const ping=()=>fetch(API_BASE+'/api/online',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:user,sid:_tabSid()})}).catch(()=>{});
    ping();if(heartbeatTimer)clearInterval(heartbeatTimer);
    heartbeatTimer=setInterval(ping,30000);
}
// Always-on heartbeat: every tab counts as online
startHeartbeat();
// Background poll for new chat messages ? notification when panel closed/unfocused
let _chatNotifSeen=Date.now();
setInterval(async()=>{
    if(chatPanelOpen&&document.hasFocus())return;
    try{
        const res=await fetch(API_BASE+'/api/chat?since='+_chatNotifSeen);
        if(!res.ok)return;const msgs=await res.json();
        if(!msgs.length)return;
        _chatNotifSeen=msgs[msgs.length-1].ts;
        const me=getSession();
        const others=msgs.filter(m=>m.name!==me);
        if(others.length){
            const last=others[others.length-1];
            _notify('?? '+last.name,last.text);
        }
    }catch(e){}
},10000);
document.getElementById('chatInput').addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();sendChatMessage();}});

// --- Auto-submit records on page load ---
(function checkAndSubmitRecords(){
    const user=getSession();if(!user)return;
    const sub=JSON.parse(localStorage.getItem('submitted_records')||'{}');
    const keys=[
        {ls:'fell_highscore',g:'fell'},{ls:'rise_highscore',g:'rise'},{ls:'swerve_highscore',g:'swerve'},
        {ls:'dash_highscore',g:'dash'},{ls:'dodge_highscore',g:'dodge'},{ls:'hit_highscore',g:'hit'},
        {ls:'spin_highscore',g:'spin'},{ls:'climb_highscore',g:'climb'},{ls:'rush_highscore',g:'rush'},
        {ls:'drop_highscore',g:'drop'},{ls:'hexfall_highscore',g:'hexfall'},{ls:'beat_highscore',g:'beat'},
        {ls:'volley_highscore',g:'volley'},{ls:'territory_highscore',g:'territory'},
        {ls:'slash_highscore',g:'slash'},{ls:'orbit_highscore',g:'orbit'},
    ];
    keys.forEach(k=>{
        const s=parseFloat(localStorage.getItem(k.ls))||0;
        if(s>0&&s>(sub[k.g]||0)){
            fetch(API_BASE+'/api/records',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({game:k.g,name:user,score:s})})
            .then(()=>{sub[k.g]=s;localStorage.setItem('submitted_records',JSON.stringify(sub));}).catch(()=>{});
        }
    });
})();
</script>
<script src="analytics/tracker.js" data-game="home"></script>
</body>
</html>

