<?php
ob_start();
require_once __DIR__ . '/../includes/config.php';
require_once __DIR__ . '/../includes/square.php';
ob_end_clean();
// Prevent Cloudflare Rocket Loader from deferring our scripts (breaks DOMContentLoaded listener)
header('Cache-Control: no-transform');
$_appVersion = '1.0.2';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
  <link rel="icon" type="image/svg+xml" href="/favicon.svg">
  <link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="theme-color" content="#0a0a12">

<!-- ═══ PRIMARY SEO ═══════════════════════════════════════════ -->
<title>TomTomGames — Buy Game Tokens | VBlink777, Fire Kirin, Milky Way &amp; More</title>
<meta name="description" content="TomTomGames is your trusted token portal for top fish table and skill games. Buy tokens instantly for VBlink777, Fire Kirin, Milky Way, Ultra Panda, Panda Master, Noble777 &amp; eGame99. Fast deposits, secure payments, 24/7 support.">
<meta name="keywords" content="buy game tokens, fish table games, VBlink777 tokens, Fire Kirin tokens, Milky Way game, Ultra Panda game, Panda Master tokens, Noble777, eGame99, online skill games, token portal, game credits">
<meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
<meta name="author" content="TomTomGames">
<link rel="canonical" href="https://tomtomgames.com/">

<!-- ═══ OPEN GRAPH (Facebook, Discord, iMessage) ═══════════════ -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://tomtomgames.com/">
<meta property="og:title" content="TomTomGames — Buy Game Tokens Instantly">
<meta property="og:description" content="The fastest way to buy tokens for VBlink777, Fire Kirin, Milky Way, Ultra Panda, Panda Master, Noble777 &amp; eGame99. Secure payments, instant delivery.">
<meta property="og:image" content="https://tomtomgames.com/assets/img/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:site_name" content="TomTomGames">
<meta property="og:locale" content="en_US">

<!-- ═══ TWITTER / X CARD ══════════════════════════════════════ -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="TomTomGames — Buy Game Tokens Instantly">
<meta name="twitter:description" content="Buy tokens for Fish Table games — VBlink777, Fire Kirin, Milky Way &amp; more. Fast, secure, 24/7.">
<meta name="twitter:image" content="https://tomtomgames.com/assets/img/og-image.png">

<!-- ═══ STRUCTURED DATA (JSON-LD Schema) ═══════════════════════ -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://tomtomgames.com/#organization",
      "name": "TomTomGames",
      "url": "https://tomtomgames.com",
      "logo": {
        "@type": "ImageObject",
        "url": "https://tomtomgames.com/assets/img/logo-icon.svg"
      },
      "contactPoint": {
        "@type": "ContactPoint",
        "contactType": "customer support",
        "availableLanguage": "English"
      },
      "sameAs": []
    },
    {
      "@type": "WebSite",
      "@id": "https://tomtomgames.com/#website",
      "url": "https://tomtomgames.com",
      "name": "TomTomGames",
      "description": "Token portal for fish table and skill games including VBlink777, Fire Kirin, Milky Way, Ultra Panda, Panda Master, Noble777 and eGame99.",
      "publisher": {"@id": "https://tomtomgames.com/#organization"},
      "potentialAction": {
        "@type": "SearchAction",
        "target": "https://tomtomgames.com/?q={search_term_string}",
        "query-input": "required name=search_term_string"
      }
    },
    {
      "@type": "WebApplication",
      "@id": "https://tomtomgames.com/#app",
      "name": "TomTomGames Token Portal",
      "url": "https://tomtomgames.com",
      "applicationCategory": "GameApplication",
      "operatingSystem": "Web, iOS, Android",
      "description": "Buy and manage game tokens for popular fish table games. Supports VBlink777, Fire Kirin, Milky Way, Ultra Panda, Panda Master, Noble777, and eGame99.",
      "offers": {
        "@type": "AggregateOffer",
        "priceCurrency": "USD",
        "lowPrice": "5",
        "highPrice": "500",
        "offerCount": "6"
      },
      "featureList": [
        "Instant token delivery",
        "Secure Square payments",
        "24/7 support chat",
        "Multiple game platforms supported",
        "Mobile-first design"
      ]
    },
    {
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "What games does TomTomGames support?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "TomTomGames supports VBlink777, Fire Kirin, Milky Way, Ultra Panda, Panda Master, Noble777, and eGame99 fish table and skill game platforms."
          }
        },
        {
          "@type": "Question",
          "name": "How do I buy game tokens?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Create an account, select your game platform, choose a token package (5 to 100+ tokens), and pay securely by credit card, Venmo, Cash App, Chime, or Zelle. Tokens are credited to your account instantly after payment."
          }
        },
        {
          "@type": "Question",
          "name": "How fast are tokens delivered?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Card payments are processed instantly. Manual payments via Venmo, Zelle, Cash App, or Chime are credited within minutes after we confirm receipt."
          }
        },
        {
          "@type": "Question",
          "name": "Is TomTomGames safe?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Yes. All card transactions are processed through Square, a PCI-compliant payment processor. We never store your full card details."
          }
        }
      ]
    }
  ]
}
</script>

<!-- ═══ PWA / APP META ════════════════════════════════════════ -->
<link rel="manifest" href="/manifest.json">
<link href="https://fonts.googleapis.com/css2?family=Exo+2:wght@400;600;700;900&family=Rajdhani:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --bg:#0a0a12;--bg2:#10101e;--bg3:#181828;--card:#1a1a2e;
  --border:rgba(255,255,255,0.07);--gold:#f0c040;--gold2:#ffdc73;
  --cyan:#00e5ff;--purple:#9b5de5;--green:#00e676;--red:#ff4444;
  --yellow:#ffd60a;--text:#e8e8f0;--text2:#8888aa;
  --radius:16px;--rsm:10px;
  /* ── Typography Scale ── */
  --fs-xs:11px;--fs-sm:13px;--fs-base:15px;--fs-md:16px;
  --fs-lg:18px;--fs-xl:20px;--fs-2xl:24px;--fs-3xl:28px;
  --lh:1.6;--lh-tight:1.3;
  --glow-gold:0 0 20px rgba(240,192,64,0.4);
  --max:480px;--nav-h:64px
}
html{-webkit-tap-highlight-color:transparent}
body{background:var(--bg);color:var(--text);font-family:'Rajdhani',sans-serif;font-size:17px;min-height:100dvh;overflow-x:hidden;-webkit-overflow-scrolling:touch}
body::before{content:'';position:fixed;inset:0;background-image:linear-gradient(rgba(0,229,255,0.03) 1px,transparent 1px),linear-gradient(90deg,rgba(0,229,255,0.03) 1px,transparent 1px);background-size:40px 40px;pointer-events:none;z-index:0}

/* AUTH */
.auth-screen{display:flex;flex-direction:column;min-height:100vh;min-height:100dvh;background:var(--bg);padding:40px 24px 32px;max-width:var(--max);margin:0 auto;width:100%}
.auth-logo{text-align:center;margin-bottom:36px}
.auth-logo-text{font-family:'Exo 2',sans-serif;font-weight:900;font-size:32px;display:flex;align-items:center;justify-content:center;gap:12px}.auth-logo-text span{background:linear-gradient(135deg,var(--gold),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.auth-logo-sub{font-size:15px;color:var(--text2);margin-top:4px;letter-spacing:1px}
.auth-tabs{display:flex;margin-bottom:24px;background:var(--bg3);border-radius:var(--rsm);padding:4px}
.auth-tab{flex:1;padding:11px;border:none;background:none;color:var(--text2);font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;border-radius:8px;cursor:pointer;transition:all .2s;letter-spacing:.5px}
.auth-tab.active{background:linear-gradient(135deg,rgba(240,192,64,.15),rgba(0,229,255,.08));color:var(--gold)}

/* MAIN */
#main-app{display:none;flex-direction:column;min-height:100vh;max-width:var(--max);margin:0 auto;position:relative;z-index:1;padding-bottom:0}
.topbar{position:sticky;top:0;z-index:100;background:rgba(10,10,18,.96);backdrop-filter:blur(12px);border-bottom:1px solid var(--border);padding:0 16px;height:58px;display:flex;align-items:center;justify-content:space-between}
.topbar-logo{font-family:'Exo 2',sans-serif;font-weight:900;font-size:18px;display:flex;align-items:center;gap:7px;letter-spacing:.5px}.topbar-logo span{background:linear-gradient(135deg,var(--gold),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.topbar-right{display:flex;align-items:center;gap:10px}
.token-badge{background:linear-gradient(135deg,#1a1a2e,#252540);border:1px solid var(--gold);border-radius:20px;padding:4px 12px;display:flex;align-items:center;gap:5px;font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;color:var(--gold2);box-shadow:var(--glow-gold)}
.avatar-btn{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--purple),var(--cyan));border:none;cursor:pointer;font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;color:#fff;display:flex;align-items:center;justify-content:center}

/* PAGES */
.page{display:none;padding:16px;padding-bottom:84px}
/* ─── TOKEN COIN ──────────────────────────────────────────── */
.token-coin{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;flex-shrink:0}
.token-coin svg{display:block}

.page.active{display:block}
.page.active{display:block;animation:fadeUp .2s ease}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}

/* NAV */
.navbar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:var(--max);height:var(--nav-h);background:rgba(10,10,18,.98);backdrop-filter:blur(16px);border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-around;z-index:100;padding-bottom:env(safe-area-inset-bottom)}
.nav-btn{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;border:none;background:none;color:var(--text2);cursor:pointer;padding:8px 4px;transition:color .2s;font-family:'Rajdhani',sans-serif;font-weight:600;font-size:12px;letter-spacing:.5px}
.nav-btn svg{width:21px;height:21px}
.nav-btn.active{color:var(--gold)}
.nav-btn.active svg{filter:drop-shadow(0 0 5px rgba(240,192,64,.6))}

/* SECTION TITLE */
.section-title{font-family:'Exo 2',sans-serif;font-weight:700;font-size:18px;margin-bottom:16px;display:flex;align-items:center;gap:8px}
.section-title span{background:linear-gradient(135deg,var(--gold),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}

/* CARDS */
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:18px;margin-bottom:14px}

/* HERO BALANCE */
.hero-balance{background:linear-gradient(135deg,#1a1228,#121a28);border:1px solid rgba(240,192,64,.2);border-radius:var(--radius);padding:22px 20px;text-align:center;margin-bottom:20px;position:relative;overflow:hidden;box-shadow:0 0 0 1px rgba(240,192,64,.15),0 8px 32px rgba(0,0,0,.4)}
.hero-balance::before{content:'';position:absolute;top:-50px;right:-50px;width:160px;height:160px;background:radial-gradient(circle,rgba(240,192,64,.12) 0%,transparent 70%)}
.balance-label{font-size:13px;font-weight:700;color:var(--text2);letter-spacing:2px;text-transform:uppercase;margin-bottom:6px}
.balance-amount{font-family:'Exo 2',sans-serif;font-weight:900;font-size:48px;color:var(--gold);line-height:1;text-shadow:var(--glow-gold)}
.balance-unit{font-size:15px;color:var(--text2);margin-top:2px;letter-spacing:1px}
.balance-alias{margin-top:12px;font-size:15px;color:var(--text2)}
.balance-alias strong{color:var(--cyan)}

/* PLATFORM GRID */
.platform-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.platform-card{background:linear-gradient(145deg,#1a1a2e,#111120);border:1px solid var(--border);border-radius:14px;padding:14px 10px 12px;text-align:center;cursor:pointer;transition:all .2s;text-decoration:none;display:flex;flex-direction:column;align-items:center;gap:8px;position:relative;overflow:hidden}
.platform-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--p-color);box-shadow:0 0 10px var(--p-color)}
.platform-card:active{transform:scale(.96)}
.platform-img-wrap{width:58px;height:58px;border-radius:14px;overflow:hidden;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.3);border:1px solid rgba(255,255,255,.08)}
.platform-img-wrap img{width:58px;height:58px;object-fit:cover}
.platform-name{font-family:'Exo 2',sans-serif;font-weight:700;font-size:14px;color:var(--text)}
.play-btn{font-size:12px;color:var(--text2);font-weight:600;letter-spacing:.5px}

/* ─── PAYMENT FORM (milkyswipe style) ─── */
.pay-form{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);overflow:visible;margin-bottom:14px}
.pay-form-header{background:linear-gradient(135deg,#0d1a2e,#0a1220);padding:16px 18px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;border-radius:var(--radius) var(--radius) 0 0}
.pay-form-icon{width:36px;height:36px;border-radius:10px;background:linear-gradient(135deg,var(--gold),#d4a017);display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}
.pay-form-title{font-family:'Exo 2',sans-serif;font-weight:700;font-size:17px;color:var(--text)}
.pay-form-sub{font-size:14px;color:var(--text2);margin-top:1px}
.pay-form-body{padding:18px}

/* Package pills */
.pkg-scroll{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;margin-bottom:18px;-webkit-overflow-scrolling:touch;scrollbar-width:none;touch-action:pan-x}
.pkg-scroll::-webkit-scrollbar{display:none}
.pkg-pill{flex-shrink:0;background:var(--bg3);border:1.5px solid var(--border);border-radius:30px;padding:8px 16px;cursor:pointer;transition:all .2s;text-align:center;min-width:72px}
.pkg-pill.popular{border-color:var(--gold)}
.pkg-pill.selected{background:linear-gradient(135deg,rgba(240,192,64,.15),rgba(0,229,255,.08));border-color:var(--gold);box-shadow:0 0 12px rgba(240,192,64,.2)}
.pkg-pill-tokens{font-family:'Exo 2',sans-serif;font-weight:900;font-size:17px;color:var(--gold2)}
.pkg-pill-price{font-size:13px;color:var(--text2);font-weight:600;margin-top:1px}
.pkg-pill.popular .pkg-pill-tokens::after{content:' ★';font-size:12px;color:var(--gold)}

/* Amount display */
.amount-display{background:var(--bg3);border:1px solid var(--border);border-radius:var(--rsm);padding:14px 16px;margin-bottom:14px;display:flex;align-items:center;justify-content:space-between}
.amount-display-label{font-size:14px;color:var(--text2);font-weight:700;text-transform:uppercase;letter-spacing:1px}
.amount-display-value{font-family:'Exo 2',sans-serif;font-weight:900;font-size:22px;color:var(--gold)}

/* Form fields */
.fg{margin-bottom:14px}
.fg label{display:block;font-size:13px;font-weight:700;color:var(--text2);letter-spacing:1px;text-transform:uppercase;margin-bottom:7px}
.fi{width:100%;background:var(--bg3);border:1.5px solid var(--border);border-radius:var(--rsm);padding:13px 14px;color:var(--text);font-family:'Rajdhani',sans-serif;font-size:17px;font-weight:500;outline:none;transition:border-color .2s;-webkit-appearance:none;appearance:none}
.fi:focus{border-color:var(--cyan);box-shadow:0 0 0 3px rgba(0,229,255,.08)}
.fi-select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M0 0l6 8 6-8z' fill='%238888aa'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 14px center;padding-right:36px}
.fi-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* Custom token amount */
.custom-amt-row{background:linear-gradient(135deg,rgba(240,192,64,.06),rgba(0,229,255,.03));border:1.5px dashed rgba(240,192,64,.3);border-radius:var(--rsm);padding:12px 14px;margin-top:8px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.custom-amt-label{font-size:13px;font-weight:700;color:var(--gold);letter-spacing:.5px;margin-bottom:6px}
.custom-amt-input-wrap{display:flex;align-items:center;background:var(--bg3);border:1.5px solid rgba(240,192,64,.3);border-radius:8px;overflow:hidden}
.custom-amt-dollar{padding:0 10px;font-family:'Exo 2',sans-serif;font-weight:700;font-size:18px;color:var(--gold);background:rgba(240,192,64,.08);border-right:1px solid rgba(240,192,64,.2)}
.custom-amt-input{background:transparent;border:none;padding:10px 12px;color:var(--text);font-family:'Exo 2',sans-serif;font-size:18px;font-weight:700;width:110px;outline:none;-moz-appearance:textfield}
.custom-amt-input::-webkit-outer-spin-button,.custom-amt-input::-webkit-inner-spin-button{-webkit-appearance:none}
.custom-amt-input::placeholder{color:var(--text2);font-size:15px;font-weight:400}
.custom-amt-equiv{font-size:15px;color:var(--text2);white-space:nowrap}
.custom-amt-equiv strong{color:var(--gold2);font-family:'Exo 2',sans-serif;font-size:18px}

/* Order summary box */
.order-summary{background:linear-gradient(135deg,#1a1228,#0d1820);border:1px solid rgba(240,192,64,.2);border-radius:var(--rsm);padding:14px 16px;margin-bottom:16px}
.order-summary-row{display:flex;justify-content:space-between;align-items:center;padding:4px 0}
.order-summary-label{font-size:14px;color:var(--text2);font-weight:600;letter-spacing:.5px}
.order-summary-val{font-size:15px;color:var(--text);font-weight:600}
.order-summary-divider{height:1px;background:rgba(255,255,255,.08);margin:8px 0}
.order-summary-total{font-family:'Exo 2',sans-serif;font-weight:900;font-size:24px;color:var(--gold)}

/* Payment method tabs */
.pay-method-tabs{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-bottom:16px}
.pmt{background:var(--bg3);border:1.5px solid var(--border);border-radius:var(--rsm);padding:10px 4px;text-align:center;cursor:pointer;transition:all .2s}
.pmt.active{border-color:var(--cyan);background:rgba(0,229,255,.06)}
.pmt-icon{font-size:20px;display:block;margin-bottom:3px}
.pmt-label{font-size:11px;font-weight:700;color:var(--text2);letter-spacing:.3px;line-height:1.2}
.pmt.active .pmt-label{color:var(--cyan)}

/* Card container */
#card-container{background:#fff;border:1.5px solid var(--border);border-radius:var(--rsm);padding:4px;margin-bottom:14px;min-height:90px;overflow:hidden}

/* Manual pay instructions */
.manual-box{background:linear-gradient(135deg,rgba(0,229,255,.04),rgba(0,0,0,.2));border:1px solid rgba(0,229,255,.15);border-radius:var(--rsm);padding:14px;margin-bottom:14px}
.manual-box-title{font-weight:700;font-size:15px;color:var(--cyan);margin-bottom:8px;display:flex;align-items:center;gap:6px}
.manual-step{display:flex;gap:10px;margin-bottom:8px;align-items:flex-start}
.manual-step-num{width:20px;height:20px;border-radius:50%;background:var(--cyan);color:#000;font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}
.manual-step-text{font-size:15px;color:var(--text);line-height:1.5}
.manual-step-text strong{color:var(--gold2)}
.manual-step-text .handle{background:rgba(240,192,64,.1);border:1px solid rgba(240,192,64,.3);border-radius:6px;padding:1px 8px;font-family:'Exo 2',sans-serif;font-weight:700;color:var(--gold);font-size:15px;letter-spacing:.5px}

/* Buttons */
.btn{width:100%;padding:15px;border:none;border-radius:var(--rsm);font-family:'Exo 2',sans-serif;font-weight:700;font-size:16px;letter-spacing:1px;cursor:pointer;transition:all .2s;text-transform:uppercase;display:flex;align-items:center;justify-content:center;gap:8px}
.btn:active{transform:scale(.98)}
.btn-gold{background:linear-gradient(135deg,var(--gold),#d4a017);color:#000;box-shadow:0 4px 20px rgba(240,192,64,.4)}
.btn-outline{background:transparent;border:1.5px solid var(--gold);color:var(--gold)}
.btn-cyan{background:linear-gradient(135deg,var(--cyan),#0099cc);color:#000;box-shadow:0 4px 20px rgba(0,229,255,.3)}
.btn-danger{background:linear-gradient(135deg,var(--red),#cc0000);color:#fff}
.btn-green{background:linear-gradient(135deg,var(--green),#00aa55);color:#000}

/* Alerts */
.alert{padding:12px 14px;border-radius:var(--rsm);margin-bottom:14px;font-weight:600;font-size:15px;display:none;line-height:1.4}
.alert.show{display:block}
.alert-error{background:rgba(255,68,68,.1);border:1px solid rgba(255,68,68,.3);color:var(--red)}
.alert-success{background:rgba(0,230,118,.1);border:1px solid rgba(0,230,118,.3);color:var(--green)}
.alert-info{background:rgba(0,229,255,.08);border:1px solid rgba(0,229,255,.2);color:var(--cyan)}

/* Divider */
.divider{display:flex;align-items:center;gap:10px;margin:18px 0;color:var(--text2);font-size:13px;font-weight:700;letter-spacing:1px}
.divider::before,.divider::after{content:'';flex:1;height:1px;background:var(--border)}

/* Cashout items */
.cashout-item{background:var(--bg3);border:1px solid var(--border);border-radius:var(--rsm);padding:13px 14px;margin-bottom:8px;display:flex;align-items:center;justify-content:space-between;gap:8px}
.badge{display:inline-block;font-size:12px;font-weight:700;padding:3px 9px;border-radius:20px;letter-spacing:.3px}
.badge-pending{background:rgba(255,214,10,.15);color:var(--yellow)}
.badge-approved{background:rgba(0,230,118,.15);color:var(--green)}
.badge-rejected{background:rgba(255,68,68,.15);color:var(--red)}
.badge-completed{background:rgba(0,229,255,.15);color:var(--cyan)}

/* Profile */
.profile-header{text-align:center;padding:20px 0 14px}
.profile-avatar{width:76px;height:76px;border-radius:50%;background:linear-gradient(135deg,var(--purple),var(--cyan));display:flex;align-items:center;justify-content:center;font-family:'Exo 2',sans-serif;font-weight:900;font-size:30px;margin:0 auto 10px;border:3px solid var(--gold);box-shadow:var(--glow-gold)}

/* Modal */
.modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:200;align-items:flex-end;backdrop-filter:blur(4px)}
.modal-overlay.show{display:flex}
.modal-sheet{background:var(--bg2);border-radius:22px 22px 0 0;border-top:1px solid var(--border);padding:20px;width:100%;max-width:var(--max);margin:0 auto;max-height:90dvh;overflow-y:auto;animation:slideUp .3s ease}
@keyframes slideUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
.modal-handle{width:40px;height:4px;background:var(--border);border-radius:2px;margin:0 auto 18px}

/* Spinner */
.spinner{width:18px;height:18px;border:2px solid rgba(255,255,255,.2);border-top-color:currentColor;border-radius:50%;animation:spin .8s linear infinite;display:inline-block;flex-shrink:0}
@keyframes spin{to{transform:rotate(360deg)}}

/* Order ref badge */
.ref-badge{background:rgba(240,192,64,.1);border:1px solid rgba(240,192,64,.3);border-radius:8px;padding:10px 14px;margin-bottom:14px;font-size:15px;color:var(--text2)}
.ref-badge strong{color:var(--gold2);font-family:'Exo 2',sans-serif}

/* ─── PROFILE TABS ───────────────────────────────────── */
.form-label{font-size:13px;font-weight:700;color:var(--text2);letter-spacing:1px;text-transform:uppercase;margin-bottom:6px;display:block}
.profile-tabs{display:flex;flex-wrap:wrap;gap:3px;background:var(--bg3);border-radius:var(--rsm);padding:4px;margin-bottom:14px}
.profile-tab{flex:1 1 calc(25% - 3px);min-width:72px;padding:10px 4px;border:none;background:none;color:var(--text2);font-family:'Exo 2',sans-serif;font-weight:700;font-size:13px;border-radius:8px;cursor:pointer;transition:all .2s;text-align:center}
.profile-tab.active{background:linear-gradient(135deg,rgba(240,192,64,.15),rgba(0,229,255,.08));color:var(--gold)}
.profile-tab-panel{display:none}
.profile-tab-panel.active{display:block;animation:fadeUp .2s ease}

/* ─── SAVED CARD CHIP ────────────────────────────────── */
.saved-card-chip{background:linear-gradient(135deg,#1c1c3a,#2d1b69);border-radius:16px;padding:20px;margin-bottom:12px;position:relative;overflow:hidden;border:1px solid rgba(255,255,255,.1)}
.saved-card-chip::before{content:'';position:absolute;top:-40px;right:-40px;width:140px;height:140px;border-radius:50%;background:rgba(255,255,255,.04)}
.saved-card-chip-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px}
.saved-card-brand{font-family:'Exo 2',sans-serif;font-weight:900;font-size:18px;color:#fff;letter-spacing:2px;text-transform:uppercase}
.saved-card-number{font-family:'Courier New',monospace;font-size:18px;font-weight:700;color:#fff;letter-spacing:4px;margin-bottom:20px}
.saved-card-bottom{display:flex;justify-content:space-between;color:#fff}

/* ─── PAYMENT PROCESSING OVERLAY ─────────────────────── */
@keyframes rotateRing{to{transform:rotate(360deg)}}
@keyframes pulseIcon{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}
@keyframes stepFadeIn{from{opacity:0;transform:translateX(-8px)}to{opacity:1;transform:translateX(0)}}
@keyframes successBurst{0%{transform:scale(.5);opacity:0}60%{transform:scale(1.1)}100%{transform:scale(1);opacity:1}}

.pay-proc-ring{width:110px;height:110px;position:relative;margin-bottom:28px;flex-shrink:0}
.pay-proc-spinner{position:absolute;inset:0;border-radius:50%;border:3px solid rgba(240,192,64,.15);border-top-color:var(--gold);border-right-color:var(--gold);animation:rotateRing 1s linear infinite}
.pay-proc-icon{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:40px;animation:pulseIcon 2s ease infinite}
.pay-proc-title{font-family:'Exo 2',sans-serif;font-weight:900;font-size:24px;color:var(--text);margin-bottom:8px;text-align:center}
.pay-proc-sub{font-size:15px;color:var(--text2);margin-bottom:32px;text-align:center}
.pay-proc-steps{display:flex;flex-direction:column;gap:10px;width:100%;max-width:260px}
.pay-proc-step{font-size:15px;font-weight:600;color:rgba(255,255,255,.2);padding:8px 14px;border-radius:8px;transition:all .4s;display:flex;align-items:center;gap:8px}
.pay-proc-step.active{color:var(--text);background:rgba(240,192,64,.08);border-left:3px solid var(--gold);animation:stepFadeIn .3s ease}
.pay-proc-step.done{color:var(--green);background:rgba(0,230,118,.06)}

/* ─── PAYMENT RESULT OVERLAY ─────────────────────────── */
.pay-result-wrap{text-align:center;width:100%;max-width:380px}
.pay-result-icon{font-size:80px;margin-bottom:20px;display:block;animation:successBurst .5s ease}
.pay-result-title{font-family:'Exo 2',sans-serif;font-weight:900;font-size:28px;margin-bottom:8px}
.pay-result-title.success{background:linear-gradient(135deg,var(--gold),var(--green));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.pay-result-title.error{color:var(--red)}
.pay-result-title.pending{color:var(--gold)}
.pay-balance-bump{font-family:'Exo 2',sans-serif;font-weight:900;font-size:56px;color:var(--gold);line-height:1;margin:12px 0;text-shadow:0 0 30px rgba(240,192,64,.5)}
.pay-result-detail{background:rgba(255,255,255,.04);border:1px solid var(--border);border-radius:12px;padding:14px;margin:16px 0;font-size:15px;color:var(--text2);line-height:1.8;text-align:left}
.pay-result-detail strong{color:var(--text)}
.pay-result-btns{display:flex;flex-direction:column;gap:10px;margin-top:20px}

/* ─── GAME ALIAS CARDS ────────────────────────────────── */
.game-alias-card{background:var(--card);border:1px solid var(--border);border-radius:var(--rsm);padding:12px 14px;margin-bottom:10px;display:flex;align-items:center;gap:12px}
.game-alias-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.game-alias-name{font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;color:var(--text);margin-bottom:5px}
.game-alias-input{width:100%;background:var(--bg3);border:1px solid var(--border);border-radius:8px;padding:8px 12px;color:var(--text);font-family:'Rajdhani',sans-serif;font-size:15px;outline:none;transition:border-color .15s;box-sizing:border-box}
.game-alias-input:focus{border-color:var(--cyan)}
.game-alias-input::placeholder{color:var(--text2)}

/* ─── ACTIVITY DASHBOARD ──────────────────────────────── */
.activity-ftab{background:var(--bg3);border:1px solid var(--border);color:var(--text2);border-radius:20px;padding:6px 14px;font-family:'Exo 2',sans-serif;font-weight:700;font-size:14px;cursor:pointer;white-space:nowrap;transition:all .15s;flex-shrink:0}
.activity-ftab.active{background:rgba(240,192,64,.12);border-color:rgba(240,192,64,.35);color:var(--gold)}
.activity-card{background:var(--bg3);border:1px solid var(--border);border-radius:var(--rsm);padding:12px 14px;margin-bottom:8px;display:flex;gap:12px;align-items:flex-start;transition:border-color .2s}
.activity-card:hover{border-color:rgba(255,255,255,.12)}
.activity-icon{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:17px;flex-shrink:0}
.activity-body{flex:1;min-width:0}
.activity-title{font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;color:var(--text);margin-bottom:2px}
.activity-meta{font-size:13px;color:var(--text2)}
.activity-status{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;border-radius:4px;padding:2px 7px;margin-top:4px}
.ac-pending{background:rgba(240,192,64,.12);color:var(--gold)}
.ac-locked{background:rgba(0,229,255,.1);color:var(--cyan)}
.ac-completed,.ac-sent,.ac-approved{background:rgba(0,230,118,.1);color:var(--green)}
.ac-rejected,.ac-failed,.ac-deleted{background:rgba(255,68,68,.1);color:var(--red)}
.ac-new{background:rgba(240,192,64,.15);color:var(--gold)}
.ac-read{background:rgba(255,255,255,.06);color:var(--text2)}
.activity-amount{font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;text-align:right;flex-shrink:0}
.summary-pill{background:var(--bg3);border:1px solid var(--border);border-radius:8px;padding:6px 12px;font-size:14px;font-family:'Exo 2',sans-serif;font-weight:700;white-space:nowrap}

/* ─── CASHOUT REQUEST CARDS ───────────────────────────── */
.co-card{background:var(--card);border:1px solid var(--border);border-radius:var(--rsm);padding:14px;margin-bottom:10px;transition:border-color .2s}
.co-card.pending{border-color:rgba(240,192,64,.25)}
.co-card.locked{border-color:rgba(0,229,255,.25);background:linear-gradient(135deg,rgba(0,229,255,.03),var(--card))}
.co-card.sent,.co-card.approved{border-color:rgba(0,230,118,.25)}
.co-card.rejected{border-color:rgba(255,68,68,.2);opacity:.75}
.co-card.deleted{opacity:.45}
.co-status-pill{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;border-radius:4px;padding:3px 8px;margin-left:8px}
.co-status-pending{background:rgba(240,192,64,.12);color:var(--gold)}
.co-status-locked{background:rgba(0,229,255,.1);color:var(--cyan)}
.co-status-sent,.co-status-approved{background:rgba(0,230,118,.1);color:var(--green)}
.co-status-rejected{background:rgba(255,68,68,.1);color:var(--red)}
.co-status-deleted{background:rgba(255,255,255,.05);color:var(--text2)}
.co-edit-row{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}

/* ─── REFERRAL STYLES ─────────────────────────────────── */
.ref-share-btn{border-radius:8px;padding:8px 14px;font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap;transition:opacity .15s}
.ref-share-btn:hover{opacity:.8}
.ref-status-pending{color:var(--gold)}
.ref-status-verified{color:var(--green)}
.ref-status-denied{color:var(--red)}

/* ─── PLATFORM ACCOUNTS ───────────────────────────────── */
.pa-card{background:var(--bg3);border:1px solid var(--border);border-radius:var(--rsm);padding:14px;margin-bottom:10px}
.pa-card.approved{border-color:rgba(0,230,118,.3);background:rgba(0,230,118,.03)}
.pa-card.pending{border-color:rgba(240,192,64,.2)}
.pa-card.denied{border-color:rgba(255,68,68,.2);opacity:.75}
.pa-cred-box{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:10px 14px;margin-top:10px;font-family:monospace;font-size:15px}
.pa-cred-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}
.pa-cred-label{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--text2)}
.pa-cred-val{font-size:15px;font-weight:700;color:var(--green)}
.pa-cred-pass{filter:blur(4px);transition:filter .2s;cursor:pointer;user-select:all}
.pa-cred-pass:hover,.pa-cred-pass.revealed{filter:none}
/* Onboarding modal */
#onboarding-modal{position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:900;display:flex;align-items:center;justify-content:center;padding:20px}
.onboarding-box{background:var(--bg3);border:1px solid rgba(240,192,64,.3);border-radius:16px;padding:28px 24px;max-width:420px;width:100%;text-align:center}
.onboarding-title{font-family:'Exo 2',sans-serif;font-weight:900;font-size:22px;color:var(--gold);margin-bottom:10px}
.onboarding-sub{font-size:15px;color:var(--text2);margin-bottom:24px;line-height:1.6}

/* ─── BROADCAST STYLES ────────────────────────────────── */
.bc-card{background:var(--card);border:1px solid var(--border);border-radius:var(--rsm);margin-bottom:12px;overflow:hidden;transition:border-color .2s}
.bc-card.unread{border-color:rgba(240,192,64,.3);background:linear-gradient(135deg,rgba(240,192,64,.04),var(--card))}
.bc-header{padding:14px 16px 10px;display:flex;gap:10px;align-items:flex-start}
.bc-avatar{width:38px;height:38px;border-radius:50%;background:linear-gradient(135deg,var(--gold),#d4a017);display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}
.bc-subject{font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;color:var(--text)}
.bc-meta{font-size:13px;color:var(--text2);margin-top:2px}
.bc-body{padding:0 16px 12px;font-size:15px;color:var(--text2);line-height:1.6;white-space:pre-wrap}
.bc-footer{padding:8px 16px;border-top:1px solid var(--border);display:flex;gap:10px;align-items:center}
.bc-reply-wrap{padding:0 16px 14px;display:none}
.bc-reply-wrap.open{display:block}
.bc-replies-list{max-height:220px;overflow-y:auto;margin-bottom:10px}
.bc-reply-row{display:flex;gap:8px;margin-bottom:8px}
.bc-reply-bubble{background:var(--bg3);border:1px solid var(--border);border-radius:8px;padding:8px 12px;flex:1}
.bc-reply-who{font-size:13px;font-weight:700;color:var(--cyan);margin-bottom:3px}
.bc-reply-who.admin{color:var(--gold)}
.bc-reply-msg{font-size:15px;color:var(--text)}

/* ─── CHAT STYLES ─────────────────────────────────────── */
@keyframes pulse2{from{opacity:.5}to{opacity:1}}
@keyframes dotBounce{0%,60%,100%{transform:translateY(0)}30%{transform:translateY(-6px)}}

.chat-header-avatar{width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,var(--gold),#d4a017);display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:var(--glow-gold)}
.chat-status-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--green);margin-right:4px;animation:pulse2 2s ease infinite alternate}

/* Quick reply chips */
.chat-quick-replies{display:flex;flex-wrap:wrap;gap:8px;padding:8px 14px 4px;flex-shrink:0}
.chat-chip{background:rgba(240,192,64,.08);border:1px solid rgba(240,192,64,.25);border-radius:20px;padding:7px 14px;color:var(--gold);font-family:'Exo 2',sans-serif;font-weight:600;font-size:14px;cursor:pointer;transition:all .15s;white-space:nowrap}
.chat-chip:active{background:rgba(240,192,64,.18);transform:scale(.97)}

/* Loading dots */
.chat-loading{display:flex;justify-content:center;align-items:center;padding:30px;color:var(--text2);font-size:15px}
.chat-loading-dots{display:flex;gap:5px}
.chat-loading-dots span{width:8px;height:8px;border-radius:50%;background:var(--text2);animation:dotBounce 1.2s ease infinite}
.chat-loading-dots span:nth-child(2){animation-delay:.2s}
.chat-loading-dots span:nth-child(3){animation-delay:.4s}

/* Send button pulse when has text */
.chat-send-btn.has-text{background:linear-gradient(135deg,var(--cyan),#0088cc);box-shadow:0 0 16px rgba(0,229,255,.35)}
#page-chat{display:none;flex-direction:column;padding:0;padding-bottom:0;position:fixed;top:0;left:0;right:0;bottom:var(--nav-h);max-width:var(--max);margin:0 auto;overflow:hidden;z-index:10}
#page-chat.active{display:flex}
.chat-header{display:flex;align-items:center;gap:12px;padding:12px 16px;background:rgba(16,16,30,.98);border-bottom:1px solid var(--border);flex-shrink:0}
.chat-header-avatar{width:40px;height:40px;border-radius:50%;background:linear-gradient(135deg,var(--gold),#d4a017);display:flex;align-items:center;justify-content:center;font-family:'Exo 2',sans-serif;font-weight:900;font-size:18px;color:#000;flex-shrink:0;box-shadow:var(--glow-gold)}
.chat-header-name{font-family:'Exo 2',sans-serif;font-weight:700;font-size:16px;color:var(--text)}
.chat-header-status{font-size:13px;color:var(--green);font-weight:600;margin-top:2px}
.chat-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:8px;-webkit-overflow-scrolling:touch;padding-bottom:8px}
.chat-loading{color:var(--text2);font-size:15px;text-align:center;padding:20px}
.chat-bubble-wrap{display:flex;flex-direction:column;max-width:78%}
.chat-bubble-wrap.mine{align-self:flex-end;align-items:flex-end}
.chat-bubble-wrap.theirs{align-self:flex-start;align-items:flex-start}
.chat-bubble{padding:10px 14px;border-radius:18px;font-size:15px;line-height:1.45;word-break:break-word;position:relative}
.chat-bubble.mine{background:linear-gradient(135deg,var(--gold),#d4a017);color:#000;border-bottom-right-radius:4px;font-weight:500}
.chat-bubble.theirs{background:var(--card);color:var(--text);border:1px solid var(--border);border-bottom-left-radius:4px}
.chat-time{font-size:12px;color:var(--text2);margin-top:3px;padding:0 4px}
.chat-date-divider{text-align:center;font-size:13px;color:var(--text2);font-weight:700;letter-spacing:.5px;margin:8px 0;display:flex;align-items:center;gap:8px}
.chat-date-divider::before,.chat-date-divider::after{content:'';flex:1;height:1px;background:var(--border)}
.chat-input-bar{display:flex;gap:8px;padding:10px 12px;background:rgba(10,10,18,.98);border-top:1px solid var(--border);flex-shrink:0;padding-bottom:calc(10px + env(safe-area-inset-bottom));padding-bottom:max(10px,calc(10px + env(safe-area-inset-bottom)))}
.chat-input{flex:1;background:var(--bg3);border:1.5px solid var(--border);border-radius:24px;padding:10px 16px;color:var(--text);font-family:'Rajdhani',sans-serif;font-size:16px;line-height:1.6;outline:none;transition:border-color .2s}
.chat-input:focus{border-color:var(--cyan)}
.chat-send-btn{width:42px;height:42px;border-radius:50%;background:linear-gradient(135deg,var(--gold),#d4a017);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .2s;color:#000}
.chat-send-btn:active{transform:scale(.93)}
.chat-send-btn svg{stroke:#000}
.chat-nav-badge{position:absolute;top:4px;right:14px;background:var(--red);color:#fff;font-size:11px;font-weight:700;min-width:16px;height:16px;border-radius:8px;display:flex;align-items:center;justify-content:center;padding:0 4px}
.chat-empty{text-align:center;padding:40px 20px;color:var(--text2);flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}
.chat-empty-icon{font-size:52px;margin-bottom:14px}
.chat-empty-text{font-size:15px;line-height:1.7}
.chat-sender-label{font-size:12px;font-weight:700;color:var(--text2);letter-spacing:.5px;text-transform:uppercase;margin-bottom:3px;padding:0 4px}

/* ── Responsive Typography ─────────────────────────────── */
/* Tablet (≥768px) */
@media (min-width: 768px) {
  body { font-size: 17px; }
  .card { font-size: 16px; padding: 22px; }
  .page-title { font-size: 26px !important; }
  .card-title { font-size: 18px; }
  .btn { font-size: 16px; padding: 14px 24px; }
  .activity-item { font-size: 15px; }
}
/* Desktop (≥1200px) */
@media (min-width: 1200px) {
  body { font-size: 18px; }
  .card { font-size: 17px; padding: 24px; }
  .page-title { font-size: 28px !important; }
  .btn { font-size: 17px; }
}
</style>
</head>
<body>

<!-- AUTH -->
<!-- ONBOARDING MODAL -->
<div id="onboarding-overlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.88);z-index:200;overflow-y:auto;padding:20px;-webkit-overflow-scrolling:touch">
  <div style="max-width:440px;margin:0 auto;background:var(--card);border:1px solid rgba(240,192,64,.25);border-radius:18px;padding:28px 24px;position:relative;top:10%">
    <div id="ob-step1">
      <div style="text-align:center;margin-bottom:20px">
        <div style="font-size:52px;margin-bottom:10px">🎮</div>
        <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:22px;color:var(--gold);margin-bottom:8px">Welcome to TomTomGames!</div>
        <div style="font-size:14px;color:var(--text2);line-height:1.7">Do you already have a username/login<br>on any of our game platforms?</div>
      </div>
      <div style="display:flex;flex-direction:column;gap:10px">
        <button class="btn btn-gold" onclick="obShowStep2()" style="font-size:15px;padding:14px">✅ Yes — I have existing logins</button>
        <button class="btn" onclick="obShowStep2()" style="background:rgba(0,229,255,.07);border:1px solid rgba(0,229,255,.2);color:var(--cyan);padding:14px;font-size:15px">🆕 No — I want to request new logins</button>
        <button onclick="obDismiss()" style="background:none;border:none;color:var(--text2);font-size:14px;cursor:pointer;margin-top:2px;padding:8px">Skip for now →</button>
      </div>
    </div>
    <div id="ob-step2" style="display:none">
      <div style="display:flex;align-items:center;gap:10px;margin-bottom:18px">
        <button onclick="document.getElementById('ob-step2').style.display='none';document.getElementById('ob-step1').style.display='block';" style="background:none;border:none;color:var(--cyan);cursor:pointer;font-size:22px;padding:0;line-height:1">←</button>
        <div>
          <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:17px">Request Game Accounts</div>
          <div style="font-size:14px;color:var(--text2);margin-top:2px">Select platforms — our team will create your logins</div>
        </div>
      </div>
      <div id="ob-platforms-list" style="margin-bottom:14px;max-height:300px;overflow-y:auto"></div>
      <div id="ob-alert" class="alert" style="margin-bottom:10px"></div>
      <div style="display:flex;gap:8px">
        <button class="btn btn-gold" onclick="obSubmitRequests()" style="flex:1">📨 Submit Requests</button>
        <button class="btn btn-outline" onclick="obDismiss()" style="width:80px;font-size:15px">Done</button>
      </div>
    </div>
  </div>
</div>

<div id="auth-screen" class="auth-screen" style="display:flex">
  <div class="auth-logo">
    <div class="auth-logo-text" style="display:flex;align-items:center;justify-content:center;gap:12px"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48" style="display:inline-block;vertical-align:middle;flex-shrink:0"><defs><linearGradient id="al1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#f0c040"/><stop offset="100%" stop-color="#ff6b35"/></linearGradient><linearGradient id="al2" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#00e5ff"/><stop offset="100%" stop-color="#7b2fbe"/></linearGradient><filter id="agl"><feGaussianBlur stdDeviation="1.5" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge></filter></defs><rect x="6" y="16" width="36" height="22" rx="11" fill="url(#al1)" filter="url(#agl)"/><rect x="12" y="23" width="8" height="3" rx="1.5" fill="rgba(0,0,0,0.45)"/><rect x="15" y="20" width="3" height="8" rx="1.5" fill="rgba(0,0,0,0.45)"/><circle cx="32" cy="22" r="2.2" fill="#e63946" opacity=".9"/><circle cx="36" cy="25" r="2.2" fill="#2ec4b6" opacity=".9"/><circle cx="32" cy="28" r="2.2" fill="#7b2fbe" opacity=".9"/><circle cx="28" cy="25" r="2.2" fill="#f4a261" opacity=".9"/><rect x="21" y="24" width="6" height="3" rx="1.5" fill="rgba(0,0,0,0.3)"/><rect x="8" y="30" width="8" height="7" rx="4" fill="url(#al2)" opacity=".7"/><rect x="32" y="30" width="8" height="7" rx="4" fill="url(#al2)" opacity=".7"/><rect x="14" y="13" width="8" height="5" rx="2.5" fill="url(#al1)" opacity=".8"/><rect x="26" y="13" width="8" height="5" rx="2.5" fill="url(#al1)" opacity=".8"/><circle cx="24" cy="7" r="2" fill="#f0c040" opacity=".9"/><circle cx="39" cy="10" r="1.2" fill="#00e5ff" opacity=".8"/><circle cx="9" cy="10" r="1.2" fill="#f0c040" opacity=".7"/></svg><span>TomTomGames</span></div>
    <div class="auth-logo-sub">YOUR ULTIMATE GAMING PORTAL</div>
  </div>
  <div class="auth-tabs">
    <button class="auth-tab active" onclick="switchTab('login')">LOGIN</button>
    <button class="auth-tab" onclick="switchTab('register')">CREATE ACCOUNT</button>
  </div>
  <div id="tab-login">
    <div id="login-alert" class="alert"></div>
    <!-- Unverified notice (hidden by default) -->
    <div id="login-unverified-box" style="display:none;background:rgba(255,214,10,.08);border:1px solid rgba(255,214,10,.25);border-radius:10px;padding:14px;margin-bottom:14px">
      <div style="font-size:15px;color:#ffd60a;font-weight:700;margin-bottom:6px">📧 Email Not Verified</div>
      <div style="font-size:14px;color:#cccc88;line-height:1.6;margin-bottom:10px">Check your inbox for the verification link, or resend it below.</div>
      <div id="login-resend-alert" class="alert" style="margin-bottom:8px"></div>
      <button class="btn btn-outline" onclick="resendFromLogin()" id="login-resend-btn" style="padding:10px;font-size:14px">Resend Verification Email</button>
    </div>
    <div class="fg"><label>Username</label><input class="fi" id="login-user" type="text" placeholder="your_username" autocomplete="username" autocapitalize="none"></div>
    <div class="fg"><label>Password</label><input class="fi" id="login-pass" type="password" placeholder="••••••••" autocomplete="current-password"></div>
    <button class="btn btn-gold" onclick="doLogin()" style="margin-top:6px" id="login-btn">LOGIN</button>
  </div>
  <div id="tab-register" style="display:none">
    <!-- FORM STATE -->
    <div id="reg-form-state">
      <div id="reg-alert" class="alert"></div>
      <div class="fg"><label>Username</label><input class="fi" id="reg-user" type="text" placeholder="choose_a_username" autocapitalize="none" autocomplete="username"></div>
      <div class="fg"><label>Your Display Name <span style="font-size:15px;color:var(--text2);font-weight:400">— what you want to be known as</span></label><input class="fi" id="reg-alias" type="text" placeholder="e.g. LuckyAce, GameKing22..." autocomplete="nickname"></div>
      <div class="fg">
        <label>Email Address <span style="color:var(--red)">*</span></label>
        <input class="fi" id="reg-email" type="email" placeholder="your@email.com" autocomplete="email">
        <div style="font-size:15px;color:var(--text2);margin-top:5px">📧 Required — we'll send a verification link</div>
      </div>
      <div class="fg"><label>Password</label><input class="fi" id="reg-pass" type="password" placeholder="Min 6 characters" autocomplete="new-password"></div>
      <button class="btn btn-gold" onclick="doRegister()" style="margin-top:6px" id="reg-btn">CREATE ACCOUNT</button>
    </div>
    <!-- VERIFY PENDING STATE (shown after registration) -->
    <div id="reg-pending-state" style="display:none">
      <div style="text-align:center;padding:12px 0 20px">
        <div style="font-size:52px;margin-bottom:16px">📧</div>
        <div style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:20px;color:var(--gold);margin-bottom:10px">Check Your Email!</div>
        <p style="font-size:14px;color:var(--text2);line-height:1.7;margin-bottom:6px">
          We sent a verification link to:<br>
          <strong style="color:var(--cyan)" id="reg-pending-email">—</strong>
        </p>
        <p style="font-size:15px;color:var(--text2);line-height:1.6;margin-bottom:24px">
          Open the email and click the link to activate your account. Check your spam folder if you don't see it.
        </p>
        <div style="background:rgba(0,229,255,.06);border:1px solid rgba(0,229,255,.15);border-radius:10px;padding:14px;margin-bottom:20px;font-size:15px;color:var(--text2);text-align:left;line-height:1.7">
          <strong style="color:var(--cyan)">Steps:</strong><br>
          1. Open your email inbox<br>
          2. Find email from <strong style="color:var(--text)">noreply@tomtomgames.com</strong><br>
          3. Click <strong style="color:var(--gold)">VERIFY MY ACCOUNT</strong><br>
          4. You'll be automatically logged in ✅
        </div>
        <div id="resend-alert" class="alert" style="margin-bottom:12px"></div>
        <button class="btn btn-outline" onclick="resendVerify()" id="resend-btn" style="margin-bottom:10px">Resend Verification Email</button>
        <button class="btn" onclick="showRegForm()" style="background:none;color:var(--text2);font-size:15px;padding:8px">← Use different email</button>
      </div>
    </div>
  </div>
</div>

<!-- MAIN APP -->
<div id="main-app" style="display:none">
  <div class="topbar">
    <div class="topbar-logo" style="display:flex;align-items:center;gap:8px"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="32" height="32" style="display:inline-block;vertical-align:middle;flex-shrink:0"><defs><linearGradient id="li1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#f0c040"/><stop offset="100%" stop-color="#ff6b35"/></linearGradient><linearGradient id="li2" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#00e5ff"/><stop offset="100%" stop-color="#7b2fbe"/></linearGradient></defs><rect x="6" y="16" width="36" height="22" rx="11" fill="url(#li1)"/><rect x="12" y="23" width="8" height="3" rx="1.5" fill="rgba(0,0,0,0.45)"/><rect x="15" y="20" width="3" height="8" rx="1.5" fill="rgba(0,0,0,0.45)"/><circle cx="32" cy="22" r="2.2" fill="#e63946" opacity=".9"/><circle cx="36" cy="25" r="2.2" fill="#2ec4b6" opacity=".9"/><circle cx="32" cy="28" r="2.2" fill="#7b2fbe" opacity=".9"/><circle cx="28" cy="25" r="2.2" fill="#f4a261" opacity=".9"/><rect x="21" y="24" width="6" height="3" rx="1.5" fill="rgba(0,0,0,0.3)"/><rect x="8" y="30" width="8" height="7" rx="4" fill="url(#li2)" opacity=".7"/><rect x="32" y="30" width="8" height="7" rx="4" fill="url(#li2)" opacity=".7"/><rect x="14" y="13" width="8" height="5" rx="2.5" fill="url(#li1)" opacity=".8"/><rect x="26" y="13" width="8" height="5" rx="2.5" fill="url(#li1)" opacity=".8"/></svg><span>TomTomGames</span></div>
    <div class="topbar-right">
      <div class="token-badge" id="header-tokens-wrap"><span id="header-tokens">0</span></div>
      <button class="avatar-btn" id="avatar-btn" onclick="showPage('profile')">?</button>
    </div>
  </div>

  <!-- HOME -->
  <div class="page active" id="page-home">
    <div class="hero-balance">
      <div class="balance-label">YOUR TOKENS</div>
      <div class="balance-amount" id="home-balance">0</div>
      <div class="balance-unit">TOKENS</div>
      <div class="balance-alias">Playing as <strong id="home-alias">—</strong></div>
      <div style="display:flex;gap:10px;margin-top:16px">
        <button class="btn btn-gold" style="flex:1;padding:12px" onclick="showPage('buy')">BUY</button>
        <button class="btn btn-outline" style="flex:1;padding:12px" onclick="showPage('cashout')">💸 CASH OUT</button>
      </div>
    </div>
    <div class="section-title"><span>PLAY NOW</span></div>
    <div class="platform-grid" id="platform-grid"></div>
    <div id="platform-alias-toast" style="position:fixed;bottom:80px;left:50%;transform:translateX(-50%) translateY(10px);background:rgba(0,0,0,.88);color:#fff;font-size:14px;font-weight:700;padding:10px 18px;border-radius:24px;white-space:nowrap;opacity:0;transition:opacity .3s,transform .3s;pointer-events:none;z-index:999;border:1px solid rgba(0,229,255,.25)"></div>
  </div>

  <!-- ═══ BUY TOKENS (milkyswipe style) ═══ -->
  <div class="page" id="page-buy">
    <div class="section-title"><span>BUY TOKENS</span></div>

    <div id="buy-alert" class="alert"></div>

    <!-- Payment Form Card -->
    <div class="pay-form">
      <div class="pay-form-header">
        <div class="pay-form-icon" id="buy-form-icon" style="font-size:0"><!-- coin --></div>
        <div>
          <div class="pay-form-title">Token Purchase</div>
          <div class="pay-form-sub">$1 = 1 Token · All payments secure</div>
        </div>
      </div>
      <div class="pay-form-body">

        <!-- 1. Select Platform -->
        <div class="fg">
          <label>1. Select Your Gaming Platform</label>
          <select class="fi fi-select" id="buy-platform" onchange="updatePayForm();prefillBuyAlias()">
            <option value="">— Choose Platform —</option>
          </select>
        </div>

        <!-- 2. Game Alias -->
        <div class="fg">
          <label>2. Your In-Game Username / Alias</label>
          <input class="fi" id="buy-alias" type="text" placeholder="e.g. LuckyAce777" oninput="updatePayForm()" onblur="saveAliasFromBuyPage()">
        </div>

        <!-- 3. Token Package -->
        <div class="fg">
          <label>3. Select Token Package <span style="color:var(--text2);font-weight:400;font-size:15px">($1 = 1 Token)</span></label>
          <div style="position:relative">
            <button id="pkg-prev" onclick="pkgScroll(-1)" style="display:none;position:absolute;left:-10px;top:50%;transform:translateY(-50%);z-index:2;background:var(--bg3);border:1px solid var(--border);color:var(--text);border-radius:50%;width:28px;height:28px;font-size:14px;cursor:pointer;line-height:1;padding:0">‹</button>
            <div class="pkg-scroll" id="pkg-scroll"></div>
            <button id="pkg-next" onclick="pkgScroll(1)" style="display:none;position:absolute;right:-10px;top:50%;transform:translateY(-50%);z-index:2;background:var(--bg3);border:1px solid var(--border);color:var(--text);border-radius:50%;width:28px;height:28px;font-size:14px;cursor:pointer;line-height:1;padding:0">›</button>
          </div>
          <!-- Custom amount row -->
          <div class="custom-amt-row" id="custom-pkg-row">
            <div class="custom-amt-wrap">
              <div class="custom-amt-label">✏️ Custom Amount</div>
              <div class="custom-amt-input-wrap">
                <span class="custom-amt-dollar">$</span>
                <input class="custom-amt-input" id="custom-amt" type="number" min="1" max="500" step="1"
                  placeholder="Enter amount" oninput="selectCustomPkg(this.value)">
              </div>
            </div>
            <div class="custom-amt-equiv" id="custom-amt-equiv" style="display:none">
              = <strong id="custom-token-count">0</strong> Tokens
            </div>
          </div>
        </div>

        <!-- Amount / Order Summary display -->
        <div class="order-summary" id="order-summary" style="display:none">
          <div class="order-summary-row">
            <span class="order-summary-label">Package</span>
            <span class="order-summary-val" id="summary-pkg">—</span>
          </div>
          <div class="order-summary-row">
            <span class="order-summary-label">Tokens</span>
            <span class="order-summary-val" style="color:var(--gold2)" id="summary-tokens">0</span>
          </div>
          <div class="order-summary-divider"></div>
          <div class="order-summary-row">
            <span class="order-summary-label" style="font-weight:700;color:var(--text)">Total Due</span>
            <span class="order-summary-total" id="summary-total">$0.00</span>
          </div>
        </div>

        <!-- 4. Payment Method -->
        <div class="fg">
          <label>4. Payment Method</label>
          <div class="pay-method-tabs" id="manual-payment-btns">
            <!-- Populated dynamically by buildPaymentMethods() -->
            <div class="pmt active" onclick="selectPMT(this,'card')" title="Credit/Debit Card">
              <span class="pmt-icon">💳</span><span class="pmt-label">Card</span>
            </div>
          </div>
        </div>

        <!-- CARD fields (Square Web Payments) -->
        <div id="section-card">
          <div class="fg">
            <label>Card Details <span style="font-size:14px;color:var(--green);font-weight:400" id="card-ready-label"></span></label>
            <div id="card-container"></div>
          </div>
          <div class="fi-row">
            <div class="fg">
              <label>First Name</label>
              <input class="fi" id="card-first-name" type="text" placeholder="First" autocomplete="given-name">
            </div>
            <div class="fg">
              <label>Last Name</label>
              <input class="fi" id="card-last-name" type="text" placeholder="Last" autocomplete="family-name">
            </div>
          </div>
          <div class="fg">
            <label>Billing Address</label>
            <input class="fi" id="card-address" type="text" placeholder="Street address" autocomplete="street-address" style="margin-bottom:8px">
            <div style="display:grid;grid-template-columns:1fr 60px 90px;gap:8px">
              <input class="fi" id="card-city" type="text" placeholder="City" autocomplete="address-level2">
              <input class="fi" id="card-state" type="text" placeholder="ST" maxlength="2" autocomplete="address-level1" style="text-transform:uppercase">
              <input class="fi" id="card-zip" type="text" placeholder="ZIP" maxlength="10" autocomplete="postal-code">
            </div>
          </div>
          <div class="fg">
            <label>Email for Receipt</label>
            <input class="fi" id="card-email" type="email" placeholder="your@email.com" autocomplete="email">
          </div>
        </div>

        <!-- MANUAL payment instructions -->
        <div id="section-manual" style="display:none">
          <div class="manual-box" id="manual-box"></div>
          <div class="ref-badge" id="ref-badge" style="display:none">
            📋 Reference: <strong id="ref-platform">—</strong> | Player: <strong id="ref-alias">—</strong> | Include this in your payment note!
          </div>
        </div>

        <!-- Save billing checkbox -->
        <div id="save-billing-wrap" style="display:flex;align-items:center;gap:10px;margin-bottom:14px;padding:10px 14px;background:rgba(0,229,255,.04);border:1px solid rgba(0,229,255,.12);border-radius:var(--rsm)">
          <input type="checkbox" id="save-billing-cb" style="width:16px;height:16px;accent-color:var(--cyan);cursor:pointer" checked>
          <label for="save-billing-cb" style="font-size:15px;color:var(--text2);cursor:pointer;line-height:1.4">
            Save billing info for faster checkout next time
          </label>
        </div>

        <!-- Submit -->
        <button class="btn btn-gold" id="pay-submit-btn" onclick="submitPayment()">
          COMPLETE PURCHASE
        </button>
        <div style="display:flex;align-items:center;justify-content:center;gap:8px;margin-top:10px">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#8888aa" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
          <p style="font-size:15px;color:var(--text2)">256-bit SSL · Secured by Square</p>
        </div>

      </div>
    </div>
  </div>

  <!-- CASHOUT -->
  <div class="page" id="page-cashout">
    <div class="section-title"><span>CASH OUT</span></div>
    <div class="pay-form">
      <div class="pay-form-header">
        <div class="pay-form-icon">💸</div>
        <div>
          <div class="pay-form-title">Cashout Request</div>
          <div class="pay-form-sub">Request withdrawal of your token balance</div>
        </div>
      </div>
      <div class="pay-form-body">
        <div style="display:flex;align-items:center;justify-content:space-between;background:var(--bg3);border:1px solid rgba(240,192,64,.2);border-radius:var(--rsm);padding:14px;margin-bottom:16px">
          <div>
            <div style="font-size:15px;color:var(--text2);font-weight:700;letter-spacing:1px;text-transform:uppercase">Available Balance</div>
            <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:28px;color:var(--gold)"><span id="cashout-balance">0</span> <span style="font-size:14px;color:var(--text2)">TOKENS</span></div>
          </div>
          <span style="font-size:36px">💰</span>
        </div>
        <div id="cashout-alert" class="alert"></div>

        <!-- Payout Method Selector -->
        <div class="fg">
          <label>Send Payment To
            <a onclick="showPage('profile');setTimeout(()=>{switchProfileTab('payout',document.querySelector('.profile-tab[onclick*=payout]'))},100)"
              style="font-size:15px;color:var(--cyan);cursor:pointer;margin-left:8px;font-weight:400">+ Manage Methods</a>
          </label>
          <div id="cashout-payout-list" style="margin-bottom:8px">
            <div style="color:var(--text2);font-size:15px;padding:10px;text-align:center">Loading payout methods...</div>
          </div>
          <div id="cashout-no-payout" style="display:none;background:rgba(240,192,64,.07);border:1px solid rgba(240,192,64,.2);border-radius:8px;padding:12px;font-size:15px;color:var(--gold);text-align:center">
            No payout method saved. <a onclick="showPage('profile');setTimeout(()=>{switchProfileTab('payout',document.querySelector('[onclick*=payout]'))},100)" style="cursor:pointer;text-decoration:underline">Add one in your profile →</a>
          </div>
        </div>

        <div class="fg"><label>Select Platform</label><select class="fi fi-select" id="cashout-platform" onchange="prefillCashoutAlias(this.value)"><option value="">— Choose Platform —</option></select></div>
        <div class="fg"><label>Your In-Game Alias / Username</label><input class="fi" id="cashout-alias" type="text" placeholder="Your alias on that platform" onblur="saveCashoutAlias()"></div>
        <div class="fg"><label>Tokens to Cash Out</label><input class="fi" id="cashout-tokens" type="number" min="1" placeholder="Enter amount (min: 1)"></div>
        <button class="btn btn-cyan" onclick="submitCashout()">💸 SUBMIT CASHOUT REQUEST</button>
        <p style="text-align:center;font-size:15px;color:var(--text2);margin-top:10px">Cashouts are reviewed and paid out within a few minutes</p>
      </div>
    </div>
    <div class="divider">MY CASHOUT REQUESTS</div>
    <div id="cashout-history">
      <div style="color:var(--text2);font-size:15px;text-align:center;padding:20px">Loading your requests...</div>
    </div>
  </div>

  <!-- PROFILE -->
  <div class="page" id="page-profile">
    <!-- Profile header -->
    <div class="profile-header">
      <div class="profile-avatar" id="profile-avatar">?</div>
      <div style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:22px;color:var(--text)" id="profile-username">—</div>
      <div style="color:var(--text2);font-size:14px;margin-top:2px" id="profile-alias">—</div>
    </div>
    <!-- Balance card -->
    <div class="card" style="margin-bottom:10px;background:linear-gradient(135deg,#1a1228,#121a28);border-color:rgba(240,192,64,.2)">
      <div style="display:flex;justify-content:space-between;align-items:center">
        <div>
          <div style="font-size:15px;color:var(--text2);font-weight:700;letter-spacing:1px;text-transform:uppercase;margin-bottom:4px">Token Balance</div>
          <div style="display:flex;align-items:center;gap:6px" id="profile-tokens"><span style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:28px;color:var(--gold)">0</span></div>
        </div>
        <button class="btn btn-gold" style="width:auto;padding:10px 18px;font-size:15px" onclick="showPage('buy')">BUY</button>
      </div>
    </div>
    <!-- Profile tabs -->
    <div class="profile-tabs" id="profile-tabs">
      <button class="profile-tab active" onclick="switchProfileTab('activity',this)">Activity</button>
      <button class="profile-tab" onclick="switchProfileTab('games',this)">🎮 Games</button>
      <button class="profile-tab" onclick="switchProfileTab('logins',this)">🔑 Logins</button>
      <button class="profile-tab" onclick="switchProfileTab('payout',this)">💸 Payout</button>
      <button class="profile-tab" onclick="switchProfileTab('referrals',this)">🎁 Refer</button>
      <button class="profile-tab" onclick="switchProfileTab('billing',this)">Billing</button>
      <button class="profile-tab" onclick="switchProfileTab('account',this)">Account</button>
    </div>
    <!-- TAB: ACTIVITY -->
    <div class="profile-tab-panel active" id="ptab-activity">

      <!-- Filter tabs -->
      <div style="display:flex;gap:6px;margin-bottom:14px;overflow-x:auto;padding-bottom:2px">
        <button class="activity-ftab active" onclick="filterActivity('all',this)">All</button>
        <button class="activity-ftab" onclick="filterActivity('purchases',this)">💳 Purchases</button>
        <button class="activity-ftab" onclick="filterActivity('cashouts',this)">💸 Cashouts</button>
        <button class="activity-ftab" onclick="filterActivity('broadcasts',this)">📢 News</button>
      </div>

      <!-- Status summary bar -->
      <div id="activity-summary" style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px"></div>

      <!-- Live feed -->
      <div id="activity-feed">
        <div style="text-align:center;padding:24px;color:var(--text2);font-size:15px">
          <span class="spinner" style="border-top-color:var(--gold)"></span>
        </div>
      </div>

      <button class="btn btn-outline" onclick="showPage('cashout')" style="margin-top:12px;width:100%">💸 Request Cash Out</button>
    </div>

    <!-- TAB: PLATFORM LOGINS -->
    <!-- TAB: LOGINS / PLATFORM ACCOUNTS -->
    <div class="profile-tab-panel" id="ptab-logins">
      <div style="font-size:14px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px">Platform Logins</div>
      <div style="font-size:14px;color:var(--text2);margin-bottom:14px;line-height:1.5">Your game platform accounts. Approved logins show your credentials below. Tap password to reveal.</div>

      <!-- Accounts list - shows all requests + approved credentials -->
      <div id="platform-logins-list">
        <div style="text-align:center;padding:20px;color:var(--text2);font-size:15px">Loading...</div>
      </div>

      <!-- Request new account -->
      <div class="card" style="margin-top:14px">
        <div class="card-title" style="font-size:15px">➕ Request Platform Account</div>
        <div style="font-size:14px;color:var(--text2);margin-bottom:10px">Don't have a login for a platform? Request one and our team will set it up for you.</div>
        <div id="req-platform-alert" class="alert" style="margin-bottom:8px"></div>
        <select class="fi fi-select" id="req-platform-slug" style="width:100%;margin-bottom:10px">
          <option value="">— Select Platform —</option>
        </select>
        <button class="btn btn-gold" onclick="requestPlatformLogin()" style="width:100%">📨 REQUEST ACCOUNT</button>
      </div>
    </div>

    <!-- TAB: REFERRALS -->
    <div class="profile-tab-panel" id="ptab-referrals">
      <div style="text-align:center;padding:16px 0 20px">
        <div style="font-size:36px;margin-bottom:8px">🎁</div>
        <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:18px;color:var(--gold)">Refer &amp; Earn Tokens!</div>
        <div style="font-size:15px;color:var(--text2);margin-top:6px;line-height:1.6">Share your referral link. Earn tokens for every friend who joins and gets verified.</div>
      </div>

      <!-- Referral link -->
      <div class="card" style="margin-bottom:12px;border-color:rgba(240,192,64,.2)">
        <div style="font-size:15px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px">Your Referral Link</div>
        <div style="display:flex;gap:8px;align-items:center">
          <input class="fi" id="referral-link-input" type="text" readonly style="flex:1;font-size:14px;cursor:pointer" onclick="this.select()">
          <button onclick="copyReferralLink()" style="background:rgba(240,192,64,.1);border:1px solid rgba(240,192,64,.25);color:var(--gold);border-radius:8px;padding:10px 14px;font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap">📋 Copy</button>
        </div>
        <div id="ref-copy-msg" style="font-size:15px;color:var(--green);margin-top:6px;display:none">✓ Copied to clipboard!</div>
      </div>

      <!-- Stats -->
      <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:14px">
        <div class="card" style="text-align:center;padding:12px 8px">
          <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:22px;color:var(--gold)" id="ref-count">0</div>
          <div style="font-size:14px;color:var(--text2);text-transform:uppercase;letter-spacing:.5px">Referrals</div>
        </div>
        <div class="card" style="text-align:center;padding:12px 8px">
          <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:22px;color:var(--green)" id="ref-earned">0</div>
          <div style="font-size:14px;color:var(--text2);text-transform:uppercase;letter-spacing:.5px">Tokens Earned</div>
        </div>
        <div class="card" style="text-align:center;padding:12px 8px">
          <div style="font-family:'Exo 2',sans-serif;font-weight:900;font-size:16px;color:var(--cyan)" id="ref-tier">—</div>
          <div style="font-size:14px;color:var(--text2);text-transform:uppercase;letter-spacing:.5px">Current Tier</div>
        </div>
      </div>

      <!-- Next tier progress -->
      <div id="ref-next-tier" style="margin-bottom:14px;display:none">
        <div class="card" style="padding:12px 14px">
          <div style="font-size:14px;color:var(--text2);margin-bottom:6px" id="ref-next-label">Next tier progress</div>
          <div style="background:rgba(255,255,255,.08);border-radius:4px;height:6px;overflow:hidden">
            <div id="ref-progress-bar" style="height:6px;border-radius:4px;background:linear-gradient(90deg,var(--gold),var(--cyan));transition:width .5s"></div>
          </div>
        </div>
      </div>

      <!-- Social share -->
      <div class="card" style="margin-bottom:12px">
        <div style="font-size:14px;font-weight:700;color:var(--text2);margin-bottom:6px;text-transform:uppercase;letter-spacing:1px">Share &amp; Earn Bonus Tokens</div>
        <div style="font-size:14px;color:var(--text2);margin-bottom:12px;line-height:1.5">Share your referral link anywhere — Reddit, Twitter/X, a forum, your blog. Paste the link to your post below and we'll try to verify it automatically.</div>
        <div style="display:flex;gap:8px;align-items:center;margin-bottom:6px">
          <input class="fi" id="share-url-input" type="url" placeholder="https://reddit.com/r/gaming/comments/…" style="flex:1;font-size:14px">
          <button onclick="submitShareUrl()" style="background:var(--gold);border:none;color:#000;border-radius:8px;padding:10px 16px;font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap">🔍 Submit</button>
        </div>
        <div style="font-size:13px;color:var(--text2)">Public posts (Reddit, forums, blogs) verify instantly. Facebook/Instagram/TikTok need manual review.</div>
        <div id="ref-share-alert" class="alert" style="margin-top:8px"></div>
        <div id="ref-shares-list" style="margin-top:10px"></div>
      </div>

      <!-- Tiers list -->
      <div class="card">
        <div style="font-size:14px;font-weight:700;color:var(--text2);margin-bottom:10px;text-transform:uppercase;letter-spacing:1px">Referral Tiers</div>
        <div id="ref-tiers-list"></div>
      </div>

      <!-- My referrals -->
      <div class="card" style="margin-top:12px">
        <div style="font-size:14px;font-weight:700;color:var(--text2);margin-bottom:10px;text-transform:uppercase;letter-spacing:1px">My Referrals</div>
        <div id="ref-list"></div>
      </div>
    </div>

    <!-- TAB: PAYOUT METHODS -->
    <div class="profile-tab-panel" id="ptab-payout">
      <div style="font-size:14px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px">Payout Methods</div>
      <div style="font-size:14px;color:var(--text2);margin-bottom:14px;line-height:1.5">Where to send your cashout payments. The default method is used automatically.</div>
      <div id="payout-methods-list"></div>
      <!-- Add Method Form -->
      <div class="card" style="margin-top:12px">
        <div class="card-title" style="font-size:15px">➕ Add Payout Method</div>
        <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:8px">
          <div>
            <label style="font-size:15px;color:var(--text2);font-weight:700;display:block;margin-bottom:4px">Type</label>
            <select class="fi" id="payout-type-new" style="font-size:15px">
              <option value="">Loading...</option>
            </select>
          </div>
          <div>
            <label style="font-size:15px;color:var(--text2);font-weight:700;display:block;margin-bottom:4px">Label</label>
            <input class="fi" id="payout-label-new" type="text" placeholder="e.g. My Venmo" style="font-size:15px">
          </div>
        </div>
        <div style="margin-bottom:10px">
          <label style="font-size:15px;color:var(--text2);font-weight:700;display:block;margin-bottom:4px">Handle / Phone / Email</label>
          <input class="fi" id="payout-handle-new" type="text" placeholder="e.g. @username, phone, or email">
        </div>
        <div id="payout-add-alert" class="alert" style="margin-bottom:8px"></div>
        <button class="btn btn-gold" onclick="addPayoutMethod()" style="width:100%">💾 SAVE METHOD</button>
      </div>
    </div>

    <!-- TAB: PLATFORM ACCOUNTS -->
    <!-- TAB: GAMES -->
    <div class="profile-tab-panel" id="ptab-games">
      <div style="font-size:14px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px">Your Game Aliases</div>
      <div style="font-size:14px;color:var(--text2);margin-bottom:14px;line-height:1.5">Save your in-game username for each platform. Your alias auto-fills when you buy tokens.</div>
      <div id="game-aliases-list"><div style="color:var(--text2);text-align:center;padding:20px;font-size:15px">Loading games...</div></div>
      <div id="game-aliases-alert" class="alert" style="margin-top:10px"></div>
      <button class="btn btn-gold" onclick="saveAllAliases()" style="margin-top:12px">💾 SAVE ALL ALIASES</button>
    </div>
    <!-- TAB: BILLING -->
    <div class="profile-tab-panel" id="ptab-billing">
      <!-- Saved card display -->
      <div id="saved-card-display" style="display:none">
        <div class="saved-card-chip">
          <div class="saved-card-chip-top">
            <span class="saved-card-brand" id="saved-card-brand">VISA</span>
            <span id="saved-card-dots">💳</span>
          </div>
          <div class="saved-card-number" id="saved-card-number">···· ···· ···· ····</div>
          <div class="saved-card-bottom">
            <div><div style="font-size:15px;color:rgba(255,255,255,.5);margin-bottom:2px">CARD HOLDER</div><div id="saved-card-name" style="font-size:15px;font-weight:700">—</div></div>
            <div style="text-align:right"><div style="font-size:15px;color:rgba(255,255,255,.5);margin-bottom:2px">EXPIRES</div><div id="saved-card-exp" style="font-size:15px;font-weight:700">—</div></div>
          </div>
        </div>
        <button class="btn btn-danger" onclick="clearSavedCard()" style="margin-top:10px;padding:10px;font-size:14px">🗑 Remove Saved Card</button>
      </div>
      <!-- Billing form -->
      <div id="billing-form-section">
        <div style="font-size:14px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:1px;margin-bottom:12px">Billing Information</div>
        <div id="billing-alert" class="alert" style="margin-bottom:12px"></div>
        <div class="fi-row" style="margin-bottom:10px">
          <div><label class="form-label">First Name</label><input class="fi" id="p-first" type="text" placeholder="First" autocomplete="given-name"></div>
          <div><label class="form-label">Last Name</label><input class="fi" id="p-last" type="text" placeholder="Last" autocomplete="family-name"></div>
        </div>
        <div class="fg"><label class="form-label">Email</label><input class="fi" id="p-email" type="email" placeholder="your@email.com" autocomplete="email"></div>
        <div class="fg"><label class="form-label">Street Address</label><input class="fi" id="p-address" type="text" placeholder="123 Main St" autocomplete="street-address"></div>
        <div style="display:grid;grid-template-columns:1fr 60px 90px;gap:8px;margin-bottom:10px">
          <div><label class="form-label">City</label><input class="fi" id="p-city" type="text" placeholder="City" autocomplete="address-level2"></div>
          <div><label class="form-label">ST</label><input class="fi" id="p-state" type="text" placeholder="TX" maxlength="2" autocomplete="address-level1" style="text-transform:uppercase"></div>
          <div><label class="form-label">ZIP</label><input class="fi" id="p-zip" type="text" placeholder="75001" maxlength="10" autocomplete="postal-code"></div>
        </div>
        <button class="btn btn-cyan" onclick="saveBillingProfile()" style="margin-bottom:8px">💾 SAVE BILLING INFO</button>
        <button class="btn" onclick="clearAllBilling()" style="background:rgba(255,68,68,.08);border:1px solid rgba(255,68,68,.2);color:var(--red);font-size:14px;padding:10px">🗑 Clear All Saved Info</button>
      </div>
    </div>
    <!-- TAB: ACCOUNT -->
    <div class="profile-tab-panel" id="ptab-account">
      <div style="font-size:14px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:1px;margin-bottom:12px">Account Info</div>
      <div class="card" style="margin-bottom:10px">
        <div style="display:flex;flex-direction:column;gap:10px">
          <div style="display:flex;justify-content:space-between"><span style="color:var(--text2);font-size:15px">Username</span><span id="acct-username" style="font-weight:700;color:var(--text)">—</span></div>
          <div style="display:flex;justify-content:space-between"><span style="color:var(--text2);font-size:15px">Alias</span><span id="acct-alias" style="font-weight:700;color:var(--cyan)">—</span></div>
          <div style="display:flex;justify-content:space-between"><span style="color:var(--text2);font-size:15px">Email</span><span id="acct-email" style="font-weight:700;font-size:15px">—</span></div>
          <div style="display:flex;justify-content:space-between"><span style="color:var(--text2);font-size:15px">Member Since</span><span id="acct-joined" style="font-weight:700;color:var(--text2);font-size:14px">—</span></div>
        </div>
      </div>
      <button class="btn btn-outline" onclick="showPage('buy')" style="margin-bottom:8px">Buy Tokens</button>
      <button class="btn btn-outline" onclick="showPage('cashout')" style="margin-bottom:8px">💸 Cash Out</button>
      <button class="btn btn-outline" onclick="showPage('chat')" style="margin-bottom:8px">💬 Contact Support</button>
      <button class="btn btn-danger" onclick="doLogout()" style="margin-top:4px">LOG OUT</button>
    </div>
  </div>

  <!-- ONBOARDING MODAL -->
  <div id="onboarding-modal" style="display:none">
    <div class="onboarding-box" id="onboarding-step-1">
      <div style="font-size:48px;margin-bottom:12px">🎮</div>
      <div class="onboarding-title">Welcome to TomTomGames!</div>
      <div class="onboarding-sub">Do you already have a login account on any of our game platforms?</div>
      <div style="display:flex;gap:10px;justify-content:center">
        <button class="btn btn-gold" onclick="onboardingHasAccount()" style="flex:1;max-width:160px">Yes, I do</button>
        <button class="btn btn-outline" onclick="onboardingNoAccount()" style="flex:1;max-width:160px">No, not yet</button>
      </div>
    </div>
    <div class="onboarding-box" id="onboarding-step-2" style="display:none">
      <div style="font-size:40px;margin-bottom:12px">📋</div>
      <div class="onboarding-title">Request Platform Login</div>
      <div class="onboarding-sub">Select which platform you want an account created on. Our team will set it up and send you your login details.</div>
      <div id="onboarding-alert" class="alert" style="margin-bottom:12px"></div>
      <div class="fg" style="margin-bottom:14px;text-align:left">
        <label style="font-size:14px;font-weight:700;color:var(--text2);display:block;margin-bottom:6px">Select Platform</label>
        <select class="fi fi-select" id="onboarding-platform" style="width:100%">
          <option value="">— Choose a platform —</option>
        </select>
      </div>
      <div style="display:flex;gap:10px">
        <button class="btn btn-gold" onclick="onboardingRequestAccount()" style="flex:1">Request Account</button>
        <button class="btn btn-outline" onclick="onboardingDone()" style="flex:1">Skip for now</button>
      </div>
    </div>
    <div class="onboarding-box" id="onboarding-step-3" style="display:none">
      <div style="font-size:48px;margin-bottom:12px">✅</div>
      <div class="onboarding-title">Request Submitted!</div>
      <div class="onboarding-sub" id="onboarding-confirm-text">Your account request has been sent. You can see the status in your Profile under Games.</div>
      <div style="display:flex;gap:10px;justify-content:center">
        <button class="btn btn-gold" onclick="onboardingRequestAnother()" style="flex:1;max-width:160px">+ Another Platform</button>
        <button class="btn btn-outline" onclick="onboardingDone()" style="flex:1;max-width:160px">Go to Home</button>
      </div>
    </div>
  </div>

  <!-- BROADCASTS PAGE -->
  <div class="page" id="page-broadcasts">
    <div class="section-title"><span>📢 NEWS &amp; ANNOUNCEMENTS</span></div>
    <div id="broadcasts-list">
      <div style="color:var(--text2);text-align:center;padding:32px;font-size:15px">Loading...</div>
    </div>
  </div>

  <!-- CHAT PAGE -->
  <div class="page" id="page-chat">
    <div class="chat-header">
      <div class="chat-header-avatar">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" width="20" height="20"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
      </div>
      <div style="flex:1">
        <div class="chat-header-name">TomTomGames Support</div>
        <div class="chat-header-status" id="chat-status-text">
          <span class="chat-status-dot"></span> We reply within minutes
        </div>
      </div>
      <div id="chat-typing-indicator" style="display:none;font-size:15px;color:var(--cyan);font-weight:600"></div>
    </div>
    <div class="chat-messages" id="chat-messages">
      <div class="chat-loading">Loading messages...</div>
    </div>
    <div class="chat-quick-replies" id="chat-quick-replies" style="display:none">
      <button class="chat-chip" onclick="quickReply('I need help with my tokens')">&#127918; Token issue</button>
      <button class="chat-chip" onclick="quickReply('I have a cashout question')">&#128184; Cashout help</button>
      <button class="chat-chip" onclick="quickReply('I need help with my account')">&#128100; Account help</button>
      <button class="chat-chip" onclick="quickReply('I have a payment question')">&#128179; Payment help</button>
    </div>
    <div class="chat-input-bar">
      <input class="chat-input" id="chat-input" type="text" placeholder="Type your message to support..." maxlength="1000"
        onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendChatMsg();}">
      <button class="chat-send-btn" onclick="sendChatMsg()" id="chat-send-btn" title="Send message">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" width="18" height="18"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
      </button>
    </div>
  </div>

  <nav class="navbar">
    <button class="nav-btn active" data-page="home" onclick="showPage('home')">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>HOME
    </button>
    <button class="nav-btn" data-page="buy" onclick="showPage('buy')">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>BUY
    </button>
    <button class="nav-btn" data-page="cashout" onclick="showPage('cashout')">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>CASH OUT
    </button>
    <button class="nav-btn chat-nav-btn" data-page="chat" onclick="showPage('chat')" style="position:relative">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
      <span class="chat-nav-badge" id="chat-nav-badge" style="display:none"></span>
      SUPPORT
    </button>
    <button class="nav-btn" data-page="broadcasts" onclick="showPage('broadcasts')" style="position:relative">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 11.5 19.79 19.79 0 0 1 1.61 2.84 2 2 0 0 1 3.58 1H6.5a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.5a16 16 0 0 0 5.54 5.54l.86-.87a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21 15.5"/><path d="m22 2-7 7"/><path d="M15 2h7v7"/></svg>
      <span class="chat-nav-badge" id="broadcast-nav-badge" style="display:none"></span>
      NEWS
    </button>
    <button class="nav-btn" data-page="profile" onclick="showPage('profile')">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><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>PROFILE
    </button>
  </nav>
  <div id="copyright-footer" style="position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:var(--max);text-align:center;padding-bottom:calc(var(--nav-h) + 2px);pointer-events:none;z-index:99">
    <span style="font-size:11px;color:rgba(255,255,255,.18);font-family:'Exo 2',sans-serif;letter-spacing:.3px">&copy; 2026 TomTomGames.com, a division of TomTom Enterprises &nbsp;&middot;&nbsp; v<?= $_appVersion ?></span>
  </div>
</div>

<!-- SUCCESS MODAL -->
<div class="modal-overlay" id="success-modal">
  <div class="modal-sheet">
    <div class="modal-handle"></div>
    <div style="text-align:center;padding:16px 0 8px">
      <div style="font-size:56px;margin-bottom:14px" id="modal-icon">🎉</div>
      <div style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:20px;color:var(--text);margin-bottom:16px" id="modal-title">Tokens Added!</div>
      <div id="modal-card-content"></div>
      <button class="btn btn-gold" style="margin-top:20px" id="modal-action-btn">AWESOME!</button>
    </div>
  </div>
</div>

<!-- PAYMENT PROCESSING OVERLAY -->
<div id="pay-processing-overlay" style="display:none;position:fixed;inset:0;background:rgba(5,5,15,.96);z-index:500;flex-direction:column;align-items:center;justify-content:center;gap:0;backdrop-filter:blur(8px)">
  <div class="pay-proc-ring">
    <div class="pay-proc-spinner"></div>
    <div class="pay-proc-icon" id="pay-proc-icon">🔒</div>
  </div>
  <div class="pay-proc-title" id="pay-proc-title">Processing Payment</div>
  <div class="pay-proc-sub" id="pay-proc-sub">Please wait — do not close the app</div>
  <div class="pay-proc-steps" id="pay-proc-steps">
    <div class="pay-proc-step active" id="step-1">🔐 Securing connection</div>
    <div class="pay-proc-step" id="step-2">💳 Authorizing card</div>
    <div class="pay-proc-step" id="step-3">✅ Confirming payment</div>
    <div class="pay-proc-step" id="step-4">Crediting tokens</div>
  </div>
</div>

<!-- PAYMENT SUCCESS OVERLAY (replaces old modal) -->
<div id="pay-success-overlay" style="display:none;position:fixed;inset:0;background:rgba(5,5,15,.97);z-index:501;flex-direction:column;align-items:center;justify-content:center;padding:32px;backdrop-filter:blur(8px)">
  <div class="pay-result-wrap" id="pay-result-wrap"><!-- filled by JS --></div>
</div>

<!-- Square SDK loads async — won't block app startup -->
<script src="<?= \SquarePayment::sdkUrl() ?>"></script>
<script>
const CFG = {
  sqAppId:  '<?= SQUARE_APP_ID ?>',
  sqLocId:  '<?= SQUARE_LOCATION_ID ?>',
  sqEnv:    '<?= SQUARE_ENV ?>',
  packages: <?= TOKEN_PACKAGES ?>,
  platforms: [], // loaded dynamically from /api/platforms.php
  pay: {
    venmo:   '<?= PAY_VENMO ?>',
    chime:   '<?= PAY_CHIME ?>',
    cashapp: '<?= PAY_CASHAPP ?>',
    zelle:   '<?= PAY_ZELLE ?>',
  }
};

let S = { user:null, pkg:null, method:'card', sqCard:null };

async function doLogin() {
  const btn=document.getElementById('login-btn'); const al=document.getElementById('login-alert');
  const u=document.getElementById('login-user').value.trim(); const p=document.getElementById('login-pass').value;
  if (!u||!p){showAlert(al,'Please fill in all fields.','error');return;}
  document.getElementById('login-unverified-box').style.display='none';
  btn.innerHTML='<span class="spinner"></span>'; btn.disabled=true;
  try {
    const d=await api('/api/login.php',{username:u,password:p});
    console.log('Login response:', JSON.stringify(d));
    if(d.success){
      if (d.user && d.user.is_admin == 1) {
        window.location.href = '/admin/';
        return;
      }
      console.log('Login success, calling showApp...');
      S.user=d.user; showApp();
    } else if(d.unverified) {
      // Show unverified box with resend option
      hideAlert(al);
      S._unverifiedEmail = d.email || '';
      document.getElementById('login-unverified-box').style.display='block';
    } else {
      showAlert(al,d.error||'Login failed.','error');
    }
  } catch{showAlert(al,'Network error.','error');}
  btn.innerHTML='LOGIN'; btn.disabled=false;
}

// ─── INIT ──────────────────────────────────────────────────
window.addEventListener('DOMContentLoaded', function() {
  // Load platforms and payment methods dynamically, then build UI
  Promise.all([
    fetch('/api/platforms.php?action=list').then(r=>r.json()).catch(()=>({success:false})),
    fetch('/api/payment_settings.php?action=list').then(r=>r.json()).catch(()=>({success:false}))
  ]).then(function(results) {
    if (results[0].success) CFG.platforms = results[0].platforms;
    if (results[1].success) CFG.payMethods = results[1].methods;
    try { buildPlatforms(); }        catch(e) {}
    try { buildPkgPills(); }         catch(e) {}
    try { buildCashoutPlatforms(); } catch(e) {}
    try { buildPaymentMethods(); }   catch(e) {}
  }).catch(function() {
    try { buildPlatforms(); }        catch(e) {}
    try { buildPkgPills(); }         catch(e) {}
    try { buildCashoutPlatforms(); } catch(e) {}
  });

  fetch('/api/me.php')
    .then(function(r) { return r.json(); })
    .then(function(d) {
      if (d && d.success && d.user) {
        if (d.user.is_admin == 1) {
          window.location.href = '/admin/';
        } else {
          S.user = d.user; showApp();
        }
      } else showAuth();
    })
    .catch(function() { showAuth(); });
});

function api(url, body) {
  const opts = { method: body ? 'POST' : 'GET', headers: { 'Content-Type': 'application/json' } };
  if (body) opts.body = JSON.stringify(body);
  return fetch(url, opts).then(r => r.json());
}

function showApp() {
  var auth = document.getElementById('auth-screen');
  var app  = document.getElementById('main-app');
  if (auth) auth.setAttribute('style', 'display:none');
  if (app)  app.setAttribute('style', 'display:block;min-height:100vh;');
  // Rebuild dynamic UI now that app is visible (covers race where me.php resolves before data fetches)
  if (CFG.platforms && CFG.platforms.length) {
    try { buildPlatforms(); buildCashoutPlatforms(); } catch(e) {}
  }
  if (CFG.payMethods && CFG.payMethods.length) {
    try { buildPaymentMethods(); } catch(e) {}
  }
  try { updateUI(); }           catch(e) { console.warn('updateUI err:', e); }
  try { loadCashoutHistory(); } catch(e) { console.warn('cashout err:', e); }
  try { pollChatBadge(); }      catch(e) { console.warn('badge err:', e); }
  // Load aliases for auto-prefill on buy page
  api('/api/game_aliases.php?action=get').then(d => {
    if (d.success) savedAliases = d.aliases || {};
  }).catch(() => {});
  loadCashoutMethodTypes();
  setTimeout(pollBroadcastBadge, 1000);
  setInterval(pollBroadcastBadge, 60000);
  setTimeout(checkOnboarding, 1500);
  // Inject coin into static elements
  setTimeout(function() {
    var bfi = document.getElementById('buy-form-icon');
    if (bfi) bfi.innerHTML = tokenCoin(48);
  }, 100);
}
function showAuth() {
  var auth = document.getElementById('auth-screen');
  var app  = document.getElementById('main-app');
  if (app)  app.setAttribute('style', 'display:none;');
  if (auth) auth.setAttribute('style', 'display:flex');
}
function switchTab(t) {
  document.getElementById('tab-login').style.display    = t === 'login'    ? 'block' : 'none';
  document.getElementById('tab-register').style.display = t === 'register' ? 'block' : 'none';
  document.querySelectorAll('.auth-tab').forEach((el,i) =>
    el.classList.toggle('active',(i===0&&t==='login')||(i===1&&t==='register'))
  );
}
function showPage(n) {
  document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
  document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active'));
  document.getElementById('page-'+n)?.classList.add('active');
  document.querySelector(`.nav-btn[data-page="${n}"]`)?.classList.add('active');
  const _cr=document.getElementById('copyright-footer'); if(_cr) _cr.style.display=n==='home'?'block':'none';
  if (n === 'buy') { updatePayForm(); initBuyPageBilling(); setTimeout(initSquare, 150); }
  if (n === 'broadcasts') { loadBroadcasts_player(); }
  if (n === 'cashout') {
    updateUI();
    loadCashoutHistory();
    loadCashoutPayoutMethods();
    // Prefill alias for currently selected platform if any
    const pid = document.getElementById('cashout-platform')?.value;
    if (pid) prefillCashoutAlias(pid);
  }
  if (n === 'profile') { loadActivityDashboard(); switchProfileTab('activity', document.querySelector('.profile-tab')); }
  if (n === 'chat') {
    // Clear badge when opening chat
    document.getElementById('chat-nav-badge').style.display = 'none';
    initChat();
    setTimeout(scrollChat, 100);
  }
}

function setText(id, val) { var el=document.getElementById(id); if(el) el.textContent=val; }
function displayName(u) { return u ? (u.alias || u.username || '?') : '?'; }
function updateUI() {
  if (!S.user) return;
  const t    = parseFloat(S.user.tokens) || 0;
  const name = displayName(S.user);
  const init = name.charAt(0).toUpperCase();
  const setHTML = (id, html) => { const el=document.getElementById(id); if(el) el.innerHTML=html; };
  setText('home-alias',       name);
  setText('cashout-balance',  t);
  setText('profile-username', name);
  setText('profile-alias',    S.user.username ? '@' + S.user.username : '');
  setText('avatar-btn',       init);
  setText('profile-avatar',   init);
  setHTML('header-tokens',  t + '&nbsp;' + tokenCoin(18));
  setHTML('home-balance',   '<span style="font-family:\'Exo 2\',sans-serif">' + t + '</span>');
  setHTML('profile-tokens', t + '&nbsp;' + tokenCoin(24));
}
async function refreshUser() {
  const d = await api('/api/me.php');
  if (d.success) { S.user = d.user; updateUI(); }
}

// ─── PLATFORMS ─────────────────────────────────────────────
function openPlatform(slug, url, aliasParam) {
  const alias = savedAliases[slug] || '';
  let launchUrl = url;
  if (alias && aliasParam) {
    const sep = url.includes('?') ? '&' : '?';
    launchUrl = url + sep + encodeURIComponent(aliasParam) + '=' + encodeURIComponent(alias);
  }
  window.open(launchUrl, '_blank', 'noopener');
  if (alias) {
    navigator.clipboard?.writeText(alias).catch(() => {});
    const t = document.getElementById('platform-alias-toast');
    if (t) {
      t.textContent = '📋 "' + alias + '" copied — paste into login';
      t.style.opacity = '1'; t.style.transform = 'translateY(0)';
      clearTimeout(t._timer);
      t._timer = setTimeout(() => { t.style.opacity='0'; t.style.transform='translateY(10px)'; }, 3000);
    }
  }
}

function buildPlatforms() {
  if (!CFG.platforms || !CFG.platforms.length) return;

  const grid = document.getElementById('platform-grid');
  if (grid) {
    grid.innerHTML = CFG.platforms.map(p => `
    <div class="platform-card" style="--p-color:${p.color};cursor:pointer"
         data-slug="${escHtml(p.id)}" data-url="${escHtml(p.url)}" data-param="${escHtml(p.alias_param||'')}">
      <div class="platform-img-wrap">
        <img src="/assets/img/${p.id}.svg" alt="${escHtml(p.name)}" onerror="this.style.display='none'">
      </div>
      <div class="platform-name">${escHtml(p.name)}</div>
      <div class="play-btn">TAP TO PLAY →</div>
    </div>`).join('');
    grid.querySelectorAll('.platform-card[data-slug]').forEach(card => {
      card.addEventListener('click', () =>
        openPlatform(card.dataset.slug, card.dataset.url, card.dataset.param));
    });
  }

  // Populate selects — clear dynamic options first to prevent duplicates on re-call
  const buySel = document.getElementById('buy-platform');
  if (buySel) {
    while (buySel.options.length > 1) buySel.remove(1);
    CFG.platforms.forEach(p => {
      const o = document.createElement('option');
      o.value = p.id; o.textContent = p.name; buySel.appendChild(o);
    });
  }
}
function buildCashoutPlatforms() {
  const sel = document.getElementById('cashout-platform');
  if (!sel) return;
  while (sel.options.length > 1) sel.remove(1);
  CFG.platforms.forEach(p => {
    const o = document.createElement('option'); o.value = p.id; o.textContent = p.name; sel.appendChild(o);
  });
}

// ─── TOKEN PACKAGES ────────────────────────────────────────
function pkgScroll(dir) {
  const el = document.getElementById('pkg-scroll');
  if (el) el.scrollBy({ left: dir * 160, behavior: 'smooth' });
}

function initPkgScrollMouse() {
  const el = document.getElementById('pkg-scroll');
  if (!el) return;

  // Show/hide arrows based on scroll position
  const prev = document.getElementById('pkg-prev');
  const next = document.getElementById('pkg-next');
  function updateArrows() {
    if (!prev || !next) return;
    const canLeft  = el.scrollLeft > 4;
    const canRight = el.scrollLeft < el.scrollWidth - el.clientWidth - 4;
    prev.style.display = canLeft  ? 'block' : 'none';
    next.style.display = canRight ? 'block' : 'none';
  }
  el.addEventListener('scroll', updateArrows, { passive: true });
  setTimeout(updateArrows, 100);

  // Mouse wheel → horizontal scroll
  el.addEventListener('wheel', e => {
    if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
      e.preventDefault();
      el.scrollBy({ left: e.deltaY * 1.5, behavior: 'auto' });
    }
  }, { passive: false });

  // Click-drag scroll
  let down = false, startX = 0, startScroll = 0, moved = false;
  el.addEventListener('mousedown', e => {
    down = true; moved = false;
    startX = e.pageX; startScroll = el.scrollLeft;
    el.style.cursor = 'grabbing'; el.style.userSelect = 'none';
  });
  document.addEventListener('mousemove', e => {
    if (!down) return;
    const dx = e.pageX - startX;
    if (Math.abs(dx) > 4) moved = true;
    el.scrollLeft = startScroll - dx;
  });
  document.addEventListener('mouseup', () => {
    if (!down) return;
    down = false;
    el.style.cursor = 'grab'; el.style.userSelect = '';
    // If the mouse barely moved, let the click on the pill go through
    if (!moved) el.style.cursor = '';
  });
  el.style.cursor = 'grab';
}

function buildPkgPills() {
  const container = document.getElementById('pkg-scroll');
  container.innerHTML = CFG.packages.map((pkg, i) => `
    <div class="pkg-pill${pkg.popular?' popular':''}" onclick="selectPkg(${i},this)">
      <div class="pkg-pill-tokens">${pkg.tokens}</div>
      <div class="pkg-pill-price">$${pkg.price}</div>
    </div>`).join('');
  const popularIdx = CFG.packages.findIndex(p => p.popular);
  const idx = popularIdx >= 0 ? popularIdx : 0;
  selectPkg(idx, container.querySelectorAll('.pkg-pill')[idx]);
  initPkgScrollMouse();
}
function selectPkg(i, el) {
  S.pkg = CFG.packages[i]; S.customPkg = false;
  document.querySelectorAll('.pkg-pill').forEach(p => p.classList.remove('selected'));
  el?.classList.add('selected');
  const ci = document.getElementById('custom-amt');
  if (ci) ci.value = '';
  document.getElementById('custom-amt-equiv').style.display = 'none';
  updateOrderSummary();
}
function selectCustomPkg(val) {
  const amt = parseInt(val);
  if (!amt || amt < 1) {
    document.getElementById('custom-amt-equiv').style.display = 'none';
    S.pkg = null; S.customPkg = false; updateOrderSummary(); return;
  }
  document.querySelectorAll('.pkg-pill').forEach(p => p.classList.remove('selected'));
  S.customPkg = true;
  S.pkg = { tokens: amt, price: amt, label: amt + ' Tokens (Custom)', popular: false };
  document.getElementById('custom-token-count').textContent = amt;
  document.getElementById('custom-amt-equiv').style.display = 'flex';
  updateOrderSummary();
}
function updateOrderSummary() {
  const el = document.getElementById('order-summary');
  if (!S.pkg) { el.style.display='none'; return; }
  document.getElementById('summary-pkg').textContent    = S.pkg.label || S.pkg.tokens+' Tokens';
  const sumTok = document.getElementById('summary-tokens'); if(sumTok) sumTok.innerHTML = S.pkg.tokens + '&nbsp;' + tokenCoin(18);
  document.getElementById('summary-total').textContent  = '$'+S.pkg.price+'.00';
  el.style.display = 'block';
}
function updateAmountDisplay() { updateOrderSummary(); }
function updatePayForm() {
  updateAmountDisplay();
  const alias = document.getElementById('buy-alias').value.trim();
  const platformId = document.getElementById('buy-platform').value;
  document.getElementById('ref-alias').textContent    = alias || '—';
  document.getElementById('ref-platform').textContent = platformId ? CFG.platforms.find(p=>p.id===platformId)?.name : '—';
  if (S.method !== 'card') renderManualInstructions();
}

// ─── PAYMENT METHOD ────────────────────────────────────────
function selectPMT(el, method) {
  document.querySelectorAll('.pmt').forEach(m => m.classList.remove('active'));
  el.classList.add('active');
  S.method = method;
  document.getElementById('section-card').style.display   = method === 'card' ? 'block' : 'none';
  document.getElementById('section-manual').style.display = method !== 'card' ? 'block' : 'none';
  if (method !== 'card') renderManualInstructions();
}

function renderManualInstructions() {
  const method = S.method;
  const pkg    = S.pkg;
  const alias  = document.getElementById('buy-alias').value.trim();
  const platformId = document.getElementById('buy-platform').value;
  const platformName = platformId ? CFG.platforms.find(p => p.id === platformId)?.name || platformId : '(your platform)';
  const amt    = pkg ? `$${pkg.price}.00` : '(select a package)';
  const handle = CFG.pay[method] || '—';

  const iconMap = { venmo:'💙', chime:'🟢', cashapp:'💚', zelle:'💜' };
  const nameMap = {
    venmo: (CFG.payLabels&&CFG.payLabels.venmo)||'Venmo',
    chime: (CFG.payLabels&&CFG.payLabels.chime)||'Chime',
    cashapp:(CFG.payLabels&&CFG.payLabels.cashapp)||'Cash App',
    zelle: (CFG.payLabels&&CFG.payLabels.zelle)||'Zelle',
  };

  document.getElementById('manual-box').innerHTML = `
    <div class="manual-box-title">${iconMap[method]} ${nameMap[method]} Instructions</div>
    <div class="manual-step">
      <div class="manual-step-num">1</div>
      <div class="manual-step-text">Open your <strong>${nameMap[method]}</strong> app and send <strong>${amt}</strong> to <span class="handle">${handle}</span></div>
    </div>
    <div class="manual-step">
      <div class="manual-step-num">2</div>
      <div class="manual-step-text">In the <strong>note/memo</strong>, include: <strong>${platformName}</strong> — <strong>${alias || 'your alias'}</strong></div>
    </div>
    <div class="manual-step">
      <div class="manual-step-num">3</div>
      <div class="manual-step-text">Click <strong>Submit Request</strong> below. We'll verify your payment and credit your tokens within a few hours.</div>
    </div>`;

  const refBadge = document.getElementById('ref-badge');
  if (alias && platformId) { refBadge.style.display = 'block'; }
  else { refBadge.style.display = 'none'; }
}

// ─── SQUARE ────────────────────────────────────────────────
async function initSquare() {
  if (!window.Square) {
    console.warn('Square SDK not loaded — card unavailable');
    document.getElementById('card-container').innerHTML =
      '<div style="color:#ff6666;font-size:14px;padding:8px">Card form unavailable. Please refresh the page.</div>';
    return;
  }
  try {
    // Destroy existing instance before re-attaching
    if (S.sqCard) {
      try { await S.sqCard.destroy(); } catch(e) {}
      S.sqCard = null;
    }
    // Clear container so Square has a clean div to inject into
    var container = document.getElementById('card-container');
    container.innerHTML = '';

    var pay = window.Square.payments(CFG.sqAppId, CFG.sqLocId);
    S.sqCard = await pay.card({
      style: {
        '.input-container'         : { borderColor: '#dddddd', borderRadius: '8px' },
        '.input-container.is-focus': { borderColor: '#0095d9' },
        'input'                    : { color: '#1a1a2e', fontSize: '16px' },
        'input::placeholder'       : { color: '#aaaaaa' },
      }
    });
    await S.sqCard.attach('#card-container');
    console.log('Square card attached OK');
    var lbl = document.getElementById('card-ready-label');
    if (lbl) lbl.textContent = '✓ Ready';
  } catch(e) {
    console.error('Square init error:', e);
    document.getElementById('card-container').innerHTML =
      '<div style="color:#ff9999;font-size:14px;padding:8px">Card form error: ' + e.message + '</div>';
  }
}

// ─── SUBMIT PAYMENT ────────────────────────────────────────
// ─── PAYMENT PROCESSING OVERLAY ──────────────────────────
const PROC_STEPS = ['step-1','step-2','step-3','step-4'];
let procTimer = null;

function showProcessingOverlay() {
  const ov = document.getElementById('pay-processing-overlay');
  ov.style.display = 'flex';
  PROC_STEPS.forEach(s => {
    const el = document.getElementById(s);
    el.classList.remove('active','done');
  });
  document.getElementById('pay-proc-icon').textContent = '🔒';
  document.getElementById('pay-proc-title').textContent = 'Processing Payment';
  document.getElementById('pay-proc-sub').textContent = 'Please wait — do not close the app';
  // Animate steps
  let i = 0;
  procTimer = setInterval(() => {
    if (i > 0) document.getElementById(PROC_STEPS[i-1]).classList.replace('active','done');
    if (i < PROC_STEPS.length) {
      document.getElementById(PROC_STEPS[i]).classList.add('active');
      i++;
    } else { clearInterval(procTimer); }
  }, 700);
}

function hideProcessingOverlay() {
  clearInterval(procTimer);
  document.getElementById('pay-processing-overlay').style.display = 'none';
}

function showPayResult(type, data) {
  hideProcessingOverlay();
  const ov = document.getElementById('pay-success-overlay');
  const wrap = document.getElementById('pay-result-wrap');
  ov.style.display = 'flex';

  if (type === 'success') {
    const newBal = parseFloat(S.user?.tokens || 0);
    wrap.innerHTML = `
      <span class="pay-result-icon">🎉</span>
      <div class="pay-result-title success">Payment Approved!</div>
      <div class="pay-balance-bump">+${data.tokens_added}&nbsp;${tokenCoin(28)}</div>
      <div style="font-size:14px;color:var(--text2);margin-bottom:4px">New Balance</div>
      <div style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:26px;color:var(--gold2);margin-bottom:16px">${data.new_balance !== undefined ? data.new_balance : parseFloat(S.user?.tokens||0)} Tokens</div>
      <div class="pay-result-detail">
        <strong>Amount charged:</strong> $${data.amount || ''}<br>
        <strong>Platform:</strong> ${data.platform || ''}<br>
        <strong>Game alias:</strong> <span style="color:var(--cyan)">${data.alias || ''}</span><br>
        ${data.card ? `<strong>Card:</strong> ${data.card}` : ''}
      </div>
      <div class="pay-result-btns">
        <button class="btn btn-gold" onclick="closePayResult();showPage('home')">🎰 PLAY NOW!</button>
        <button class="btn btn-outline" onclick="closePayResult();showPage('buy')" style="padding:10px;font-size:15px">Buy More Tokens</button>
      </div>`;
  } else if (type === 'manual') {
    wrap.innerHTML = `
      <span class="pay-result-icon">⏳</span>
      <div class="pay-result-title pending">Request Submitted!</div>
      <div style="font-size:14px;color:var(--text2);margin:12px 0 4px">Tokens pending — awaiting payment confirmation</div>
      <div style="display:flex;align-items:center;justify-content:center;gap:8px;font-family:'Exo 2',sans-serif;font-weight:900;font-size:40px;color:var(--gold);margin-bottom:4px">${data.tokens}${tokenCoin(36)}</div>
      <div style="font-size:14px;color:var(--text2);margin-bottom:16px">will be added to your account once payment is received</div>
      <div class="pay-result-detail">
        Order <strong style="color:var(--cyan)">#${data.purchase_id}</strong> received.<br><br>
        <strong style="color:var(--gold)">📲 Next steps:</strong><br>
        1. Send <strong>$${data.amount}</strong> via <strong>${data.method}</strong><br>
        2. Include your order # <strong style="color:var(--cyan)">#${data.purchase_id}</strong> in the memo<br>
        3. Tokens are credited <strong>within a few minutes</strong> after we confirm receipt<br><br>
        <span style="color:var(--text2);font-size:14px">⚠️ Your token balance will not change until payment is verified by our team.</span>
      </div>
      <div class="pay-result-btns">
        <button class="btn btn-gold" onclick="closePayResult();showPage('home')">GOT IT — HOME</button>
        <button class="btn btn-outline" onclick="closePayResult();showPage('chat')" style="padding:10px;font-size:15px">💬 Contact Support</button>
      </div>`;
  } else {
    wrap.innerHTML = `
      <span class="pay-result-icon">❌</span>
      <div class="pay-result-title error">Payment Failed</div>
      <div class="pay-result-detail">${data.error || 'Your payment could not be processed. Please check your card details and try again.'}</div>
      <div class="pay-result-btns">
        <button class="btn btn-gold" onclick="closePayResult()">TRY AGAIN</button>
        <button class="btn btn-outline" onclick="closePayResult();showPage('chat')" style="padding:10px;font-size:15px">💬 Contact Support</button>
      </div>`;
  }
}

function closePayResult() {
  document.getElementById('pay-success-overlay').style.display = 'none';
}

async function submitPayment() {
  const btn = document.getElementById('pay-submit-btn');
  const al  = document.getElementById('buy-alert');

  const platformId   = document.getElementById('buy-platform').value;
  const gameAlias    = document.getElementById('buy-alias').value.trim();
  const platformName = platformId ? CFG.platforms.find(p=>p.id===platformId)?.name || platformId : '';

  if (!platformId)     { showAlert(al, 'Please select a gaming platform.', 'error'); return; }
  if (!gameAlias)      { showAlert(al, 'Please enter your in-game alias.', 'error'); return; }
  if (!S.pkg)          { showAlert(al, 'Please select a token package or enter a custom amount.', 'error'); return; }
  if (S.pkg.price < 1) { showAlert(al, 'Minimum purchase is $1.', 'error'); return; }

  const billing = {
    first_name: (document.getElementById('card-first-name')?.value || '').trim(),
    last_name:  (document.getElementById('card-last-name')?.value  || '').trim(),
    address:    (document.getElementById('card-address')?.value    || '').trim(),
    city:       (document.getElementById('card-city')?.value       || '').trim(),
    state:      (document.getElementById('card-state')?.value      || '').trim().toUpperCase(),
    zip:        (document.getElementById('card-zip')?.value        || '').trim(),
    email:      (document.getElementById('card-email')?.value      || '').trim(),
  };

  if (S.method === 'card') {
    if (!billing.first_name || !billing.last_name) { showAlert(al, 'Please enter the name on your card.', 'error'); return; }
    if (!billing.zip) { showAlert(al, 'Billing ZIP code is required.', 'error'); return; }
  }

  btn.disabled = true;
  hideAlert(al);

  // ── Card tokenize BEFORE showing overlay (Square SDK needs DOM visible)
  let sourceId = '';
  if (S.method === 'card') {
    if (!S.sqCard) { showAlert(al,'Card form not ready. Please refresh.','error'); btn.disabled=false; return; }
    try {
      const result = await S.sqCard.tokenize();
      if (result.status !== 'OK') {
        showAlert(al, result.errors?.[0]?.message || 'Card declined. Check your card details.', 'error');
        btn.disabled=false; return;
      }
      sourceId = result.token;
    } catch { showAlert(al,'Payment error. Try again.','error'); btn.disabled=false; return; }
  }

  // ── Show full-screen processing overlay
  showProcessingOverlay();

  try {
    const d = await api('/api/purchase.php', {
      source_id:   sourceId,
      tokens:      S.pkg.tokens,
      price_cents: S.pkg.price * 100,
      method:      S.method,
      platform_id: platformId,
      game_alias:  gameAlias,
      player_name: S.user?.alias || '',
      is_custom:   S.customPkg || false,
      billing,
    });

    // Mark all steps done
    PROC_STEPS.forEach(s => {
      const el = document.getElementById(s);
      el.classList.remove('active');
      el.classList.add('done');
    });
    await new Promise(r => setTimeout(r, 600)); // brief pause for visual satisfaction

    if (d.success) {
      // Update local token balance immediately from API response
      if (d.new_balance !== undefined && S.user) {
        S.user.tokens = d.new_balance;
        updateUI();
      }
      await refreshUser(); // then sync full user object from server
      // Auto-save billing if checkbox checked
      const saveCb = document.getElementById('save-billing-cb');
      if (saveCb?.checked && billing.first_name && S.method === 'card') {
        const cardBrand = d.card_brand || '';
        const cardLast4 = d.card_last4 || '';
        await api('/api/billing.php?action=save', { ...billing, card_brand: cardBrand, card_last4: cardLast4 });
      }
      // Auto-save game alias for this platform
      if (gameAlias && platformId) {
        savedAliases[platformId] = gameAlias;
        api('/api/game_aliases.php?action=save', { platform_slug: platformId, alias: gameAlias }).catch(()=>{});
      }
      // Reset form
      const ci = document.getElementById('custom-amt');
      if (ci) ci.value = '';
      document.getElementById('custom-amt-equiv').style.display = 'none';
      document.getElementById('order-summary').style.display = 'none';

      if (d.manual) {
        // Manual payment (Venmo, Zelle, Cash App, Chime) — pending admin approval
        const methodLabels = { venmo:'Venmo', chime:'Chime', cashapp:'Cash App', zelle:'Zelle' };
        showPayResult('manual', {
          tokens:      S.pkg.tokens,
          amount:      (S.pkg.price).toFixed(2),
          method:      (CFG.payLabels && CFG.payLabels[S.method]) || methodLabels[S.method] || S.method,
          purchase_id: d.purchase_id,
        });
      } else {
        // Card payment — tokens credited immediately
        const newBalance = d.new_balance !== undefined ? parseFloat(d.new_balance) : parseFloat(S.user?.tokens || 0);
        showPayResult('success', {
          tokens_added: d.tokens_added || S.pkg.tokens,
          new_balance:  newBalance,
          amount:       (S.pkg.price).toFixed(2),
          platform:     platformName,
          alias:        gameAlias,
          card:         d.card_brand ? d.card_brand + ' ····' + d.card_last4 : null,
        });
      }
    } else {
      showPayResult('error', { error: d.error || 'Payment failed.' });
    }
  } catch {
    hideProcessingOverlay();
    showAlert(al, 'Network error. Please try again.', 'error');
  }

  btn.disabled = false;
}

// ─── PROFILE TABS ─────────────────────────────────────────
function switchProfileTab(name, btn) {
  document.querySelectorAll('.profile-tab').forEach(b => b.classList.remove('active'));
  document.querySelectorAll('.profile-tab-panel').forEach(p => p.classList.remove('active'));
  btn?.classList.add('active');
  document.getElementById('ptab-'+name)?.classList.add('active');
  if (name === 'billing')  loadBillingProfile();
  if (name === 'account')  populateAccount();
  if (name === 'games')    loadGameAliases();
  if (name === 'payout')   { loadPayoutMethods(); loadCashoutMethodTypes(); }
  if (name === 'activity') loadActivityDashboard();
  if (name === 'referrals') loadReferralDashboard();
  if (name === 'logins')   { loadPlatformLogins(); populatePlatformSelect('req-platform-slug'); }
  if (name === 'logins')   loadPlatformLogins();
}

// ─── BROADCASTS (PLAYER) ───────────────────────────────────
async function loadBroadcasts_player() {
  const el = document.getElementById('broadcasts-list');
  const d  = await api('/api/broadcast.php?action=list');
  if (!d.success || !d.broadcasts.length) {
    el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text2)"><div style="font-size:40px;margin-bottom:12px">📢</div><div style="font-size:14px">No announcements yet.</div><div style="font-size:14px;margin-top:4px">Check back later for news and updates.</div></div>';
    return;
  }
  el.innerHTML = d.broadcasts.map(b => {
    const unread = parseInt(b.is_read) === 0;
    return `<div class="bc-card${unread?' unread':''}" id="bc-card-${b.id}">
      <div class="bc-header">
        <div class="bc-avatar">📢</div>
        <div style="flex:1;min-width:0">
          <div style="display:flex;align-items:center;gap:8px">
            <div class="bc-subject">${escHtml(b.subject)}</div>
            ${unread?'<span style="font-size:15px;font-weight:700;color:var(--gold);background:rgba(240,192,64,.15);border:1px solid rgba(240,192,64,.3);border-radius:4px;padding:2px 6px">NEW</span>':''}
          </div>
          <div class="bc-meta">From <strong>${escHtml(b.sender_name)}</strong> · ${(b.sent_at||'').substring(0,16)}</div>
        </div>
      </div>
      <div class="bc-body">${escHtml(b.message)}</div>
      <div class="bc-footer">
        <button onclick="toggleBcReplies(${b.id})" style="background:none;border:none;color:var(--cyan);font-size:14px;font-weight:700;cursor:pointer;padding:0">
          💬 ${b.reply_count} repl${parseInt(b.reply_count)!==1?'ies':'y'}
        </button>
        <span style="color:var(--text2);font-size:15px">👁 ${b.read_count} read</span>
      </div>
      <div class="bc-reply-wrap" id="bc-replies-${b.id}">
        <div class="bc-replies-list" id="bc-rlist-${b.id}"></div>
        <div style="display:flex;flex-direction:column;gap:8px">
          <textarea id="bc-rinput-${b.id}" rows="3" placeholder="Write a reply..." style="width:100%;box-sizing:border-box;background:var(--bg3);border:1px solid var(--border);border-radius:10px;padding:12px 14px;color:var(--text);font-family:'Rajdhani',sans-serif;font-size:14px;resize:none;outline:none;transition:border-color .15s" onfocus="this.style.borderColor='var(--cyan)'" onblur="this.style.borderColor=''" onkeydown="if(event.key==='Enter'&&event.ctrlKey){event.preventDefault();playerBcReply(${b.id});}"></textarea>
          <div style="display:flex;justify-content:space-between;align-items:center">
            <span style="font-size:15px;color:var(--text2)">Ctrl+Enter to send</span>
            <button class="btn btn-gold" onclick="playerBcReply(${b.id})" style="padding:10px 20px;font-size:15px">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" width="14" height="14" style="margin-right:5px"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>SEND REPLY
            </button>
          </div>
        </div>
      </div>
    </div>`;
  }).join('');
  // Mark all as read
  d.broadcasts.forEach(b => {
    if (!parseInt(b.is_read)) {
      api('/api/broadcast.php?action=mark_read',{broadcast_id:b.id}).catch(()=>{});
    }
  });
  pollBroadcastBadge();
}

async function toggleBcReplies(id) {
  const wrap = document.getElementById('bc-replies-'+id);
  const isOpen = wrap.classList.contains('open');
  wrap.classList.toggle('open', !isOpen);
  if (!isOpen) await loadBcReplies_player(id);
}

async function loadBcReplies_player(id) {
  const el = document.getElementById('bc-rlist-'+id);
  el.innerHTML = '<div style="color:var(--text2);font-size:14px;padding:8px">Loading...</div>';
  const d = await api('/api/broadcast.php?action=replies&broadcast_id='+id);
  if (!d.success||!d.replies.length) { el.innerHTML='<div style="color:var(--text2);font-size:14px;padding:8px;text-align:center">No replies yet — be the first!</div>'; return; }
  el.innerHTML = d.replies.map(r => {
    const isAdm = parseInt(r.is_admin);
    return `<div class="bc-reply-row">
      <div style="width:28px;height:28px;border-radius:50%;background:${isAdm?'linear-gradient(135deg,#f0c040,#d4a017)':'linear-gradient(135deg,#7b2fbe,#457b9d)'};display:flex;align-items:center;justify-content:center;font-family:'Exo 2',sans-serif;font-weight:700;font-size:14px;color:#fff;flex-shrink:0">${(r.username||'?').charAt(0).toUpperCase()}</div>
      <div class="bc-reply-bubble">
        <div class="bc-reply-who${isAdm?' admin':''}">${escHtml(r.username)}${isAdm?' 🔑':''} <span style="font-weight:400;color:var(--text2)">· ${(r.created_at||'').substring(11,16)}</span></div>
        <div class="bc-reply-msg">${escHtml(r.message)}</div>
      </div>
    </div>`;
  }).join('');
}

async function playerBcReply(id) {
  const input = document.getElementById('bc-rinput-'+id);
  const msg   = input.value.trim();
  if (!msg) return;
  input.value = '';
  input.style.borderColor = '';
  const d = await api('/api/broadcast.php?action=reply',{broadcast_id:id,message:msg});
  if (d.success) {
    await loadBcReplies_player(id);
    // Update reply count
    const card = document.getElementById('bc-card-'+id);
    if (card) {
      const btn = card.querySelector('.bc-footer button');
      if (btn) {
        const current = parseInt(btn.textContent.match(/\d+/)?.[0]||0) + 1;
        btn.textContent = `💬 ${current} repl${current!==1?'ies':'y'}`;
      }
    }
  }
}

async function pollBroadcastBadge() {
  try {
    const d = await api('/api/broadcast.php?action=unread_count');
    const badge = document.getElementById('broadcast-nav-badge');
    if (badge) badge.style.display = d.count > 0 ? 'block' : 'none';
  } catch(e) {}
}
const PAYOUT_ICONS = { venmo:'💙', cashapp:'💚', zelle:'💜', chime:'🟢', bank:'🏦', other:'💰' };
const PAYOUT_LABELS = { venmo:'Venmo', cashapp:'Cash App', zelle:'Zelle', chime:'Chime', bank:'Bank Transfer', other:'Other' };
let payoutMethods = [];

function prefillCashoutAlias(platformId) {
  const input = document.getElementById('cashout-alias');
  if (!input) return;
  input.value = (platformId && savedAliases[platformId]) ? savedAliases[platformId] : '';
}

function saveCashoutAlias() {
  const platformId = document.getElementById('cashout-platform')?.value;
  const alias      = document.getElementById('cashout-alias')?.value.trim();
  if (!platformId || !alias || !S.user) return;
  savedAliases[platformId] = alias;
  api('/api/game_aliases.php?action=save', { platform_slug: platformId, alias }).catch(() => {});
}

async function loadPayoutMethods() {
  const el = document.getElementById('payout-methods-list');
  const d  = await api('/api/payout_methods.php?action=list');
  payoutMethods = d.success ? (d.methods || []) : [];
  renderPayoutMethodsList(el, payoutMethods);
}

async function loadCashoutPayoutMethods() {
  const el   = document.getElementById('cashout-payout-list');
  const noEl = document.getElementById('cashout-no-payout');
  const d    = await api('/api/payout_methods.php?action=list');
  payoutMethods = d.success ? (d.methods || []) : [];
  if (!payoutMethods.length) {
    if (el) el.innerHTML = '';
    if (noEl) noEl.style.display = 'block';
    return;
  }
  if (noEl) noEl.style.display = 'none';
  if (el) {
    el.innerHTML = payoutMethods.map(m => {
      const on = parseInt(m.admin_enabled);
      const bg     = on && parseInt(m.is_default) ? 'rgba(0,229,255,.07)' : 'var(--bg3)';
      const border = on && parseInt(m.is_default) ? 'rgba(0,229,255,.25)' : 'var(--border)';
      const badge  = !on
        ? '<span style="font-size:13px;font-weight:700;color:var(--text2);border:1px solid var(--border);border-radius:4px;padding:2px 7px;white-space:nowrap">UNAVAILABLE</span>'
        : parseInt(m.is_default) ? '<span style="font-size:14px;font-weight:700;color:var(--cyan);border:1px solid rgba(0,229,255,.2);border-radius:4px;padding:2px 7px">DEFAULT</span>' : '';
      return `
      <label style="display:flex;align-items:center;gap:10px;background:${bg};border:1px solid ${border};border-radius:8px;padding:10px 12px;margin-bottom:6px;cursor:${on?'pointer':'not-allowed'};opacity:${on?'1':'0.45'}">
        <input type="radio" name="cashout-payout" value="${m.id}" ${on && parseInt(m.is_default)?'checked':''} ${!on?'disabled':''} style="accent-color:var(--cyan)">
        <span style="font-size:18px">${PAYOUT_ICONS[m.method_type]||'💰'}</span>
        <div style="flex:1;min-width:0">
          <div style="font-weight:700;font-size:15px">${escHtml(m.label)}</div>
          <div style="font-size:14px;color:var(--text2)">${escHtml(m.account_handle)}</div>
        </div>
        ${badge}
      </label>`;
    }).join('');
  }
}

function renderPayoutMethodsList(el) {
  if (!el) return;
  if (!payoutMethods.length) {
    el.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:16px">No payout methods saved yet.</div>';
    return;
  }
  el.innerHTML = payoutMethods.map(m => {
    const on = parseInt(m.admin_enabled);
    const bg     = on && parseInt(m.is_default) ? 'rgba(0,229,255,.07)' : 'var(--bg3)';
    const border = on && parseInt(m.is_default) ? 'rgba(0,229,255,.25)' : 'var(--border)';
    return `
    <div style="display:flex;align-items:center;gap:10px;background:${bg};border:1px solid ${border};border-radius:10px;padding:12px 14px;margin-bottom:8px;opacity:${on?'1':'0.45'}">
      <span style="font-size:22px">${PAYOUT_ICONS[m.method_type]||'💰'}</span>
      <div style="flex:1;min-width:0">
        <div style="font-weight:700;font-size:14px">${escHtml(m.label)}
          ${!on
            ? '<span style="font-size:13px;font-weight:700;color:var(--text2);border:1px solid var(--border);border-radius:4px;padding:2px 6px;margin-left:6px">DISABLED BY ADMIN</span>'
            : parseInt(m.is_default) ? '<span style="font-size:14px;font-weight:700;color:var(--cyan);border:1px solid rgba(0,229,255,.2);border-radius:4px;padding:2px 7px;margin-left:6px">DEFAULT</span>' : ''}
        </div>
        <div style="font-size:14px;color:var(--text2)">${PAYOUT_LABELS[m.method_type]||m.method_type} · ${escHtml(m.account_handle)}</div>
      </div>
      <div style="display:flex;gap:6px;flex-shrink:0">
        ${on && !parseInt(m.is_default)?`<button onclick="setDefaultPayout(${m.id})" style="background:rgba(0,229,255,.08);border:1px solid rgba(0,229,255,.2);color:var(--cyan);border-radius:6px;padding:5px 10px;font-size:15px;font-weight:700;cursor:pointer;border:none">Set Default</button>`:''}
        <button onclick="deletePayoutMethod(${m.id})" style="background:rgba(255,68,68,.08);border:1px solid rgba(255,68,68,.2);color:var(--red);border-radius:6px;padding:5px 10px;font-size:15px;font-weight:700;cursor:pointer">✕</button>
      </div>
    </div>`;
  }).join('');
}

async function addPayoutMethod() {
  const al     = document.getElementById('payout-add-alert');
  const type   = document.getElementById('payout-type-new').value;
  const label  = document.getElementById('payout-label-new').value.trim();
  const handle = document.getElementById('payout-handle-new').value.trim();
  if (!label || !handle) { showAlert(al,'Please fill in all fields.','error'); return; }
  const d = await api('/api/payout_methods.php?action=add', { method_type:type, label, account_handle:handle, is_default: payoutMethods.length===0 ? 1 : 0 });
  if (d.success) {
    document.getElementById('payout-label-new').value = '';
    document.getElementById('payout-handle-new').value = '';
    showAlert(al,'✓ Payout method saved!','success');
    setTimeout(() => { al.className='alert'; al.textContent=''; }, 3000);
    loadPayoutMethods();
  } else showAlert(al, d.error||'Error saving','error');
}

async function setDefaultPayout(id) {
  const d = await api('/api/payout_methods.php?action=set_default', { id });
  if (d.success) { loadPayoutMethods(); loadCashoutPayoutMethods(); }
}

async function deletePayoutMethod(id) {
  if (!confirm('Remove this payout method?')) return;
  const d = await api('/api/payout_methods.php?action=delete', { id });
  if (d.success) { loadPayoutMethods(); loadCashoutPayoutMethods(); }
}

function getSelectedPayoutId() {
  const sel = document.querySelector('input[name="cashout-payout"]:checked');
  return sel ? parseInt(sel.value) : null;
}


// ─── TOKEN COIN SVG ────────────────────────────────────────
function tokenCoin(size) {
  size = size || 22;
  const s = size, r = s/2, ri = r*0.72, sh = r*0.14;
  const id = 'tcg' + Math.random().toString(36).slice(2,6);
  return `<svg width="${s}" height="${s+Math.round(sh*1.5)}" viewBox="0 0 ${s} ${s+Math.round(sh*1.5)}" style="display:inline-block;vertical-align:middle;flex-shrink:0" aria-label="token">
    <defs>
      <radialGradient id="cf${id}" cx="42%" cy="38%" r="58%">
        <stop offset="0%" stop-color="#ffe87a"/>
        <stop offset="50%" stop-color="#f0c040"/>
        <stop offset="100%" stop-color="#c8900a"/>
      </radialGradient>
      <radialGradient id="ce${id}" cx="50%" cy="50%" r="50%">
        <stop offset="65%" stop-color="#b07a18"/>
        <stop offset="100%" stop-color="#7a5008"/>
      </radialGradient>
    </defs>
    <ellipse cx="${r}" cy="${r+sh*1.5}" rx="${ri*0.7}" ry="${sh*0.6}" fill="rgba(0,0,0,0.18)"/>
    <circle cx="${r}" cy="${r+sh}" r="${ri}" fill="url(#ce${id})"/>
    <circle cx="${r}" cy="${r}" r="${ri}" fill="url(#cf${id})"/>
    <circle cx="${r}" cy="${r}" r="${ri}" fill="none" stroke="#ffe87a" stroke-width="${s*0.04}" opacity="0.55"/>
    <circle cx="${r}" cy="${r}" r="${ri*0.73}" fill="none" stroke="#c8900a" stroke-width="${s*0.025}" opacity="0.4"/>
    <text x="${r}" y="${r+s*0.1}" font-family="'Exo 2',sans-serif" font-weight="900" font-size="${s*0.42}px" fill="#7a5008" text-anchor="middle" opacity="0.9">T</text>
    <ellipse cx="${r*0.6}" cy="${r*0.55}" rx="${ri*0.28}" ry="${ri*0.15}" fill="rgba(255,255,220,0.38)" transform="rotate(-28 ${r*0.6} ${r*0.55})"/>
  </svg>`;
}

// Replace all 🪙 emoji in text nodes with coin SVG
function coinify(el) {
  if (!el) return;
  el.innerHTML = el.innerHTML.replace(/🪙/g, tokenCoin(20));
}

// ─── ONBOARDING MODAL ─────────────────────────────────────
let obSelectedPlatforms = new Set();

function showOnboardingIfNeeded() {
  if (!S.user) return;
  // Show once: only for verified players who haven't completed onboarding
  if (S.user.email_verified && !parseInt(S.user.onboarding_done||0) && !S.user.is_admin) {
    setTimeout(() => {
      document.getElementById('onboarding-overlay').style.display = 'block';
      obLoadPlatforms();
    }, 800);
  }
}

async function obLoadPlatforms() {
  const d = await api('/api/platforms.php?action=list').catch(()=>({success:false}));
  if (!d.success) return;
  // Also load existing requests to skip already-requested ones
  const existing = await api('/api/platform_accounts.php?action=my_accounts').catch(()=>({accounts:[]}));
  const existingSlugs = new Set((existing.accounts||[]).filter(a=>['pending','approved'].includes(a.status)).map(a=>a.platform_slug));
  const el = document.getElementById('ob-platforms-list');
  if (!el || !d.platforms.length) return;
  el.innerHTML = d.platforms.filter(p => !existingSlugs.has(p.id)).map(p => `
    <label style="display:flex;align-items:center;gap:10px;padding:10px 12px;background:var(--bg3);border:1px solid var(--border);border-radius:8px;margin-bottom:6px;cursor:pointer" id="ob-plat-${p.id}">
      <input type="checkbox" value="${p.id}" data-name="${escHtml(p.name)}"
        onchange="obTogglePlatform('${p.id}',this.checked,'ob-plat-${p.id}')"
        style="accent-color:var(--gold);width:16px;height:16px;flex-shrink:0">
      <div style="width:10px;height:10px;border-radius:50%;background:${p.color};flex-shrink:0"></div>
      <span style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:14px">${escHtml(p.name)}</span>
    </label>`).join('') || '<div style="color:var(--text2);text-align:center;padding:12px;font-size:15px">No platforms available to request.</div>';
}

function obTogglePlatform(id, checked, labelId) {
  if (checked) obSelectedPlatforms.add(id);
  else obSelectedPlatforms.delete(id);
  const lbl = document.getElementById(labelId);
  if (lbl) lbl.style.borderColor = checked ? 'rgba(240,192,64,.4)' : 'var(--border)';
}

function obShowStep2() {
  document.getElementById('ob-step1').style.display = 'none';
  document.getElementById('ob-step2').style.display = 'block';
  obLoadPlatforms();
}

function obRequestNew() {
  obShowStep2();
}

async function obSubmitRequests() {
  const al = document.getElementById('ob-alert');
  if (obSelectedPlatforms.size === 0) { showAlert(al,'Select at least one platform.','error'); return; }
  let ok = 0;
  for (const slug of obSelectedPlatforms) {
    const name = document.querySelector(`input[value="${slug}"]`)?.dataset.name || slug;
    const d = await api('/api/platform_accounts.php?action=request', { platform_slug: slug, platform_name: name });
    if (d.success) ok++;
  }
  if (ok > 0) {
    showAlert(al, `✓ ${ok} request${ok>1?'s':''} submitted! Our team will create your accounts shortly.`, 'success');
    await api('/api/platform_accounts.php?action=skip_onboarding', {});
    setTimeout(obDismiss, 2500);
  } else showAlert(al, 'Something went wrong. Try again.', 'error');
}

async function obDismiss() {
  document.getElementById('onboarding-overlay').style.display = 'none';
  await api('/api/platform_accounts.php?action=skip_onboarding', {}).catch(()=>{});
  if (S.user) S.user.onboarding_done = 1;
}

function obSkip() { obDismiss(); }

// ─── PLATFORM LOGINS (Profile tab) ────────────────────────
async function loadPlatformLogins() {
  const el = document.getElementById('platform-logins-list');
  if (!el) return;
  el.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:16px">Loading...</div>';
  const d = await api('/api/platform_accounts.php?action=my_accounts');
  if (!d.success) { el.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:16px">Unable to load.</div>'; return; }

  // Populate request dropdown - exclude already requested/approved
  const existing = new Set(d.accounts.filter(a=>['pending','approved'].includes(a.status)).map(a=>a.platform_slug));
  const sel = document.getElementById('req-platform-slug');
  if (sel && CFG.platforms.length) {
    sel.innerHTML = '<option value="">— Select Platform —</option>' +
      CFG.platforms.filter(p => !existing.has(p.id)).map(p =>
        `<option value="${p.id}" data-name="${escHtml(p.name)}">${escHtml(p.name)}</option>`
      ).join('');
  }

  if (!d.accounts.length) {
    el.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:20px">No platform account requests yet.<br><span style="font-size:15px">Use the form below to request one.</span></div>';
    return;
  }

  const STATUS_INFO = {
    pending:  { icon:'⏳', label:'Awaiting Approval',   cls:'ac-pending', msg:'Our team will review and create your account shortly.' },
    approved: { icon:'✅', label:'Account Ready',        cls:'ac-completed', msg:'' },
    denied:   { icon:'❌', label:'Request Denied',       cls:'ac-failed', msg:'Contact support for more info.' },
    deleted:  { icon:'🗑', label:'Deleted',              cls:'ac-failed', msg:'' },
  };

  el.innerHTML = d.accounts.map(a => {
    const si = STATUS_INFO[a.status] || STATUS_INFO.pending;
    const canDelete = a.status === 'pending';
    const showCreds = a.status === 'approved' && a.provided_username;
    return `<div class="activity-card" style="margin-bottom:10px;flex-direction:column;gap:0">
      <div style="display:flex;gap:12px;align-items:flex-start;width:100%">
        <div class="activity-icon" style="background:rgba(240,192,64,.1)">${si.icon}</div>
        <div style="flex:1;min-width:0">
          <div class="activity-title">${escHtml(a.display_name||a.platform_slug)}</div>
          <span class="activity-status ${si.cls}">${si.label}</span>
          ${a.admin_note ? `<div style="font-size:15px;color:var(--gold);margin-top:4px">📝 ${escHtml(a.admin_note)}</div>` : ''}
          ${si.msg ? `<div style="font-size:15px;color:var(--text2);margin-top:4px">${si.msg}</div>` : ''}
        </div>
        ${canDelete ? `<button onclick="deletePlatformRequest(${a.id})" style="background:none;border:none;color:var(--red);cursor:pointer;font-size:18px;padding:0;flex-shrink:0">✕</button>` : ''}
      </div>
      ${showCreds ? `
      <div style="margin-top:12px;background:rgba(0,229,255,.06);border:1px solid rgba(0,229,255,.2);border-radius:8px;padding:12px 14px;width:100%">
        <div style="font-size:15px;font-weight:700;color:var(--cyan);margin-bottom:8px;letter-spacing:.5px">🔑 YOUR LOGIN CREDENTIALS</div>
        <div style="display:grid;grid-template-columns:auto 1fr;gap:6px 12px;font-size:15px">
          <span style="color:var(--text2)">Username:</span>
          <span style="font-weight:700;color:var(--text);font-family:monospace">${escHtml(a.provided_username)}</span>
          <span style="color:var(--text2)">Password:</span>
          <span style="font-weight:700;color:var(--gold);font-family:monospace;cursor:pointer" onclick="this.style.filter='none'" style="filter:blur(5px)" title="Tap to reveal">${escHtml(a.provided_password)}</span>
        </div>
        <div style="font-size:14px;color:var(--text2);margin-top:8px">⚠️ Keep your credentials secure. Tap password to reveal.</div>
        ${a.player_url ? `<a href="${escHtml(a.player_url)}" target="_blank" class="btn btn-gold" style="display:block;text-align:center;margin-top:10px;padding:8px;font-size:15px;text-decoration:none">▶ Play ${escHtml(a.display_name)}</a>` : ''}
      </div>` : ''}
    </div>`;
  }).join('');
}

async function requestPlatformAccount() {
  const sel  = document.getElementById('req-platform-slug');
  const al   = document.getElementById('req-platform-alert');
  const slug = sel?.value;
  const name = sel?.options[sel.selectedIndex]?.dataset.name || slug;
  if (!slug) { showAlert(al,'Select a platform.','error'); return; }
  const d = await api('/api/platform_accounts.php?action=request', { platform_slug: slug, platform_name: name });
  if (d.success) {
    showAlert(al,'✓ Request submitted! We\'ll create your account shortly.','success');
    setTimeout(() => { al.className='alert'; al.textContent=''; }, 3500);
    loadPlatformLogins();
  } else showAlert(al, d.error||'Request failed','error');
}

async function deletePlatformRequest(id) {
  if (!confirm('Cancel this account request?')) return;
  const d = await api('/api/platform_accounts.php?action=delete_request', { id });
  if (d.success) loadPlatformLogins();
}
let cashoutMethodTypes = [];

// ─── REFERRAL SYSTEM ──────────────────────────────────────
let _refData = null;

// Capture ?ref= code from URL on page load
const _urlRef = new URLSearchParams(window.location.search).get('ref') || '';

async function loadReferralDashboard() {
  const d = await api('/api/referrals.php?action=status');
  if (!d.success) {
    const inp = document.getElementById('referral-link-input');
    if (inp) inp.placeholder = d.error || 'Please log in to see your referral link';
    return;
  }
  _refData = d;

  // Referral link — build URL defensively
  const inp = document.getElementById('referral-link-input');
  if (inp) {
    const code = d.referral_code || '';
    const url  = code
      ? (d.referral_url || ('https://tomtomgames.com/?ref=' + code))
      : '';
    inp.value = url;
    inp.placeholder = code ? '' : 'Generating your referral link...';
    // If no code yet, retry in 2 seconds
    if (!code) setTimeout(loadReferralDashboard, 2000);
  }

  // Stats
  setText('ref-count',  d.verified_count || 0);
  setText('ref-earned', d.total_earned   || 0);
  setText('ref-tier',   d.current_tier?.name || '—');

  // Next tier progress
  if (d.next_tier) {
    const nextEl   = document.getElementById('ref-next-tier');
    const labelEl  = document.getElementById('ref-next-label');
    const barEl    = document.getElementById('ref-progress-bar');
    const curr     = d.current_tier?.min_referrals || 0;
    const next     = d.next_tier.min_referrals;
    const count    = d.verified_count || 0;
    const pct      = Math.min(100, Math.round(((count - curr) / (next - curr)) * 100));
    if (nextEl) nextEl.style.display = 'block';
    if (labelEl) labelEl.textContent = `${count}/${next} referrals to ${d.next_tier.name} (+${d.next_tier.tokens_per_ref} tokens/ref)`;
    if (barEl)   barEl.style.width   = pct + '%';
  }

  // Tiers list
  const tiersEl = document.getElementById('ref-tiers-list');
  if (tiersEl) {
    const tiers = await api('/api/referrals.php?action=tiers');
    if (tiers.success) {
      tiersEl.innerHTML = (tiers.tiers || []).map(t => `
        <div style="display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--border)">
          <div style="flex:1">
            <div style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px;color:${d.current_tier?.id==t.id?'var(--gold)':'var(--text)'}">${escHtml(t.name)} ${d.current_tier?.id==t.id?'★':''}</div>
            <div style="font-size:15px;color:var(--text2)">${escHtml(t.description||'')}</div>
          </div>
          <div style="text-align:right;font-size:14px">
            <div style="font-weight:700;color:var(--green)">${t.tokens_per_ref} tokens/ref</div>
            ${t.bonus_tokens>0?'<div style="color:var(--gold);font-size:15px">+'+t.bonus_tokens+' bonus</div>':''}
            <div style="color:var(--text2);font-size:14px">${t.min_referrals} referrals</div>
          </div>
        </div>`).join('') || '<div style="color:var(--text2);font-size:15px">No tiers configured.</div>';
    }
  }

  // My referrals list
  const refListEl = document.getElementById('ref-list');
  if (refListEl) {
    const refs = d.referrals || [];
    if (!refs.length) {
      refListEl.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:12px">No referrals yet. Share your link!</div>';
    } else {
      refListEl.innerHTML = refs.map(r => `
        <div style="display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--border)">
          <div style="flex:1">
            <div style="font-size:15px;font-weight:700">${escHtml(r.alias||r.username)}</div>
            <div style="font-size:15px;color:var(--text2)">${(r.created_at||'').substring(0,10)}</div>
          </div>
          <div style="text-align:right">
            <div class="ref-status-${r.status}" style="font-size:15px;font-weight:700;text-transform:uppercase">${r.status}</div>
            ${r.tokens_awarded>0?'<div style="color:var(--green);font-size:15px">+'+r.tokens_awarded+' tokens</div>':''}
          </div>
        </div>`).join('');
    }
  }

  // Social shares
  const sharesList = document.getElementById('ref-shares-list');
  if (sharesList) {
    const shares = d.social_shares || [];
    if (!shares.length) {
      sharesList.innerHTML = '';
    } else {
      sharesList.innerHTML = '<div style="font-size:13px;font-weight:700;color:var(--text2);margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px">Your Submitted Shares</div>' +
        shares.map(s => {
          const autoTag  = parseInt(s.auto_verified) ? ' <span style="font-size:12px;background:rgba(0,255,128,.1);border:1px solid rgba(0,255,128,.2);color:var(--green);border-radius:4px;padding:1px 5px">⚡ auto</span>' : '';
          const urlFrag  = s.share_url
            ? `<div style="margin-top:3px"><a href="${escHtml(s.share_url)}" target="_blank" rel="noopener" style="color:var(--cyan);font-size:12px;word-break:break-all">${escHtml(s.share_url.length>60?s.share_url.substring(0,60)+'…':s.share_url)}</a></div>`
            : '';
          return `<div style="padding:8px 0;border-bottom:1px solid var(--border)">
            <div style="font-size:14px"><strong>${escHtml(s.platform)}</strong> — <span class="ref-status-${s.status}">${s.status}</span>${autoTag}${s.status==='approved'?' <span style="color:var(--green)">+'+s.bonus_tokens+' tokens</span>':''}</div>
            ${urlFrag}
          </div>`;
        }).join('');
    }
  }
}

function copyReferralLink() {
  const inp = document.getElementById('referral-link-input');
  if (!inp) return;
  inp.select();
  navigator.clipboard?.writeText(inp.value).catch(() => {});
  document.execCommand('copy');
  const msg = document.getElementById('ref-copy-msg');
  if (msg) { msg.style.display='block'; setTimeout(()=>msg.style.display='none', 2000); }
}

async function submitShareUrl() {
  const al  = document.getElementById('ref-share-alert');
  const inp = document.getElementById('share-url-input');
  const url = inp?.value.trim();
  if (!url) { showAlert(al, 'Please paste the URL of your post.', 'error'); return; }
  showAlert(al, '🔍 Checking your post…', 'info');
  const d = await api('/api/referrals.php?action=submit_share', { url });
  if (d.success) {
    showAlert(al, d.message, d.auto_verified ? 'success' : 'info');
    if (inp) inp.value = '';
    loadReferralDashboard();
  } else {
    showAlert(al, d.error || 'Error submitting share.', 'error');
  }
}

// Pass referral code during registration
function getUrlRefCode() { return _urlRef; }

// ─── PLATFORM LOGINS (unified) ───────────────────────────
async function loadPlatformLogins() {
  const el = document.getElementById('platform-logins-list');
  if (!el) return;
  el.innerHTML = '<div style="text-align:center;padding:16px;color:var(--text2);font-size:15px"><span class="spinner" style="border-top-color:var(--gold)"></span></div>';
  try {
    const d = await api('/api/platform_accounts.php?action=list');
    if (!d.success || !d.accounts.length) {
      el.innerHTML = '<div style="text-align:center;padding:20px;color:var(--text2);font-size:15px">No platform account requests yet. Request one below!</div>';
      return;
    }
    el.innerHTML = d.accounts.map(a => buildLoginCard(a)).join('');
  } catch(e) {
    el.innerHTML = '<div style="color:var(--red);text-align:center;padding:16px;font-size:15px">Unable to load. Try again.</div>';
  }
}

function buildLoginCard(a) {
  const statusLabel = { pending:'⏳ Request Pending', approved:'✅ Account Ready', denied:'❌ Request Denied', deleted:'🗑 Deleted' };
  const statusCls   = { pending:'ac-pending', approved:'ac-completed', denied:'ac-failed', deleted:'ac-failed' };
  const note = a.admin_note ? `<div style="font-size:15px;color:var(--gold);margin-top:6px;padding:6px 8px;background:rgba(240,192,64,.07);border-radius:6px">📝 ${escHtml(a.admin_note)}</div>` : '';

  let creds = '';
  if (a.status === 'approved' && a.platform_username) {
    const passHtml = a.platform_password
      ? `<div class="pa-cred-row">
           <span class="pa-cred-label">Password</span>
           <span class="pa-cred-val pa-cred-pass" onclick="this.classList.toggle('revealed')" title="Tap to reveal">${escHtml(a.platform_password)}</span>
         </div>
         <div style="font-size:14px;color:var(--text2);margin-top:3px">Tap password to reveal · Keep this safe!</div>`
      : '';
    creds = `<div class="pa-cred-box">
      <div class="pa-cred-row"><span class="pa-cred-label">Username</span><span class="pa-cred-val">${escHtml(a.platform_username)}</span></div>
      ${passHtml}
    </div>`;
  }

  const pendingMsg = a.status === 'pending'
    ? '<div style="font-size:15px;color:var(--text2);margin-top:8px;padding:8px;background:rgba(255,255,255,.03);border-radius:6px">Our team is setting up your account. Your login credentials will appear here once ready.</div>'
    : '';

  return `<div class="pa-card ${a.status}" style="margin-bottom:10px">
    <div style="display:flex;align-items:center;justify-content:space-between;gap:10px">
      <div>
        <div style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:15px">${escHtml(a.platform_name || a.platform_slug)}</div>
        <div style="font-size:15px;color:var(--text2);margin-top:2px">${(a.requested_at||'').substring(0,10)}</div>
        <span class="activity-status ${statusCls[a.status]||'ac-pending'}">${statusLabel[a.status]||a.status}</span>
      </div>
      ${a.status === 'pending' ? '<div style="font-size:15px;color:var(--text2);text-align:right">Pending<br>review</div>' : ''}
    </div>
    ${note}${creds}${pendingMsg}
  </div>`;
}

async function requestPlatformLogin() {
  const al   = document.getElementById('req-platform-alert');
  const slug = document.getElementById('req-platform-slug')?.value;
  if (!slug) { showAlert(al, 'Please select a platform.', 'error'); return; }
  const platName = CFG.platforms.find(p => p.id === slug)?.name || slug;
  const d = await api('/api/platform_accounts.php?action=request', { platform_slug: slug });
  if (d.success) {
    showAlert(al, `✓ Request submitted for ${platName}! Check back here once approved.`, 'success');
    setTimeout(() => { al.className='alert'; al.textContent=''; }, 4000);
    document.getElementById('req-platform-slug').value = '';
    loadPlatformLogins();
  } else {
    showAlert(al, d.error || 'Error submitting request.', 'error');
  }
}

function populatePlatformSelect(selId) {
  const sel = document.getElementById(selId);
  if (!sel || !CFG.platforms.length) return;
  sel.querySelectorAll('option:not([value=""])').forEach(o => o.remove());
  CFG.platforms.forEach(p => {
    const o = document.createElement('option');
    o.value = p.id; o.textContent = p.name;
    sel.appendChild(o);
  });
}

// ─── ONBOARDING FLOW ──────────────────────────────────────
function showOnboarding() {
  const modal = document.getElementById('onboarding-modal');
  if (!modal) return;
  populatePlatformSelect('onboarding-platform');
  modal.style.display = 'flex';
}
function hideOnboarding() { const m=document.getElementById('onboarding-modal'); if(m)m.style.display='none'; }
function showOnboardingStep(n) {
  [1,2,3].forEach(i => { const el=document.getElementById('onboarding-step-'+i); if(el) el.style.display=i===n?'block':'none'; });
}
function onboardingHasAccount() {
  api('/api/platform_accounts.php?action=dismiss_onboarding',{}).catch(()=>{});
  hideOnboarding();
}
function onboardingNoAccount() { showOnboardingStep(2); }
function onboardingRequestAnother() {
  const al=document.getElementById('onboarding-alert'); if(al){al.className='alert';al.textContent='';}
  document.getElementById('onboarding-platform').value='';
  showOnboardingStep(2);
}
async function onboardingRequestAccount() {
  const al=document.getElementById('onboarding-alert');
  const slug=document.getElementById('onboarding-platform')?.value;
  if (!slug) { showAlert(al,'Please select a platform.','error'); return; }
  const platName=CFG.platforms.find(p=>p.id===slug)?.name||slug;
  const d=await api('/api/platform_accounts.php?action=request',{platform_slug:slug});
  if (d.success) {
    const ct=document.getElementById('onboarding-confirm-text');
    if (ct) ct.textContent=`Request for ${platName} submitted! Find your login details in Profile → Accounts once approved.`;
    showOnboardingStep(3);
  } else showAlert(al, d.error||'Error','error');
}
async function onboardingDone() {
  api('/api/platform_accounts.php?action=dismiss_onboarding',{}).catch(()=>{});
  hideOnboarding();
}
async function checkOnboarding() {
  if (!S.user || S.user.is_admin) return;
  try {
    const d=await api('/api/platform_accounts.php?action=check_onboarding');
    if (d.success && d.needs_onboarding) showOnboarding();
  } catch(e){}
}

async function loadCashoutMethodTypes() {
  try {
    const d = await api('/api/cashout_method_types.php?action=list');
    if (!d.success) return;
    cashoutMethodTypes = d.types || [];
    // Populate the payout type selector
    const sel = document.getElementById('payout-type-new');
    if (sel) {
      sel.innerHTML = cashoutMethodTypes.map(t =>
        `<option value="${escHtml(t.slug)}">${escHtml(t.icon)} ${escHtml(t.label)}</option>`
      ).join('');
    }
    // Update PAYOUT_ICONS and PAYOUT_LABELS from live data
    cashoutMethodTypes.forEach(t => {
      PAYOUT_ICONS[t.slug]  = t.icon;
      PAYOUT_LABELS[t.slug] = t.label;
    });
  } catch(e) { /* use defaults */ }
}

// Also load on app init so icons/labels are available everywhere
function populateAccount() {
  const u = S.user;
  if (!u) return;
  document.getElementById('acct-username').textContent = u.username || '—';
  document.getElementById('acct-alias').textContent    = u.alias    || '—';
  document.getElementById('acct-email').textContent    = u.email    || 'Not set';
  document.getElementById('acct-joined').textContent   = (u.created_at||'').substring(0,10);
}

// ─── DYNAMIC PAYMENT METHODS ──────────────────────────────
function buildPaymentMethods() {
  const methods   = CFG.payMethods || [];
  const container = document.getElementById('manual-payment-btns');
  if (!container) return;

  // Check if card is enabled from payMethods (or default to enabled if no card entry)
  const cardSetting = methods.find(m => m.method_key === 'card');
  const cardEnabled = cardSetting ? parseInt(cardSetting.is_enabled) : 1;
  const manualMethods = methods.filter(m => m.method_key !== 'card' && parseInt(m.is_enabled));

  let html = '';

  // Card button — only show if enabled
  if (cardEnabled) {
    html += `<div class="pmt" onclick="selectPMT(this,'card')" title="Credit/Debit Card">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="22" height="22"><rect x="1" y="4" width="22" height="16" rx="2"/><line x1="1" y1="10" x2="23" y2="10"/></svg>
      <span>Card</span>
    </div>`;
  }

  const iconMap = { venmo:'💙', chime:'🟢', cashapp:'💚', zelle:'💜' };
  manualMethods.forEach(m => {
    html += `<div class="pmt" onclick="selectPMT(this,'${m.method_key}')" title="${escHtml(m.label)}">
      <span style="font-size:20px">${iconMap[m.method_key]||'💰'}</span>
      <span>${escHtml(m.label)}</span>
    </div>`;
  });

  container.innerHTML = html;

  // If card is disabled and current method is card, switch to first available
  if (!cardEnabled && S.method === 'card') {
    const firstManual = manualMethods[0];
    if (firstManual) {
      const firstBtn = container.querySelector('.pmt');
      if (firstBtn) selectPMT(firstBtn, firstManual.method_key);
    }
    // Also hide the card section entirely
    const cardSection = document.getElementById('section-card');
    if (cardSection) cardSection.style.display = 'none';
    const manSection = document.getElementById('section-manual');
    if (manSection) manSection.style.display = 'block';
  }

  // If no methods at all, show message
  if (!cardEnabled && !manualMethods.length) {
    container.innerHTML = '<div style="font-size:15px;color:var(--red);padding:8px">No payment methods are currently available. Please contact support.</div>';
  }

  // Update CFG.pay handles from DB
  methods.forEach(m => {
    if (CFG.pay && m.handle) CFG.pay[m.method_key] = m.handle;
    if (!CFG.payLabels) CFG.payLabels = {};
    CFG.payLabels[m.method_key] = m.label;
    if (m.instructions) {
      if (!CFG.payInstructions) CFG.payInstructions = {};
      CFG.payInstructions[m.method_key] = m.instructions;
    }
  });
}

// Save alias from buy page back to profile
async function saveAliasFromBuyPage() {
  const platformId = document.getElementById('buy-platform')?.value;
  const alias      = document.getElementById('buy-alias')?.value.trim();
  if (!platformId || !alias || !S.user) return;
  savedAliases[platformId] = alias;
  await api('/api/game_aliases.php?action=save', { platform_slug: platformId, alias });
}
let savedAliases = {}; // { platform_slug: alias }

async function loadGameAliases() {
  const el = document.getElementById('game-alias-list') || document.getElementById('game-aliases-list');
  try {
    const [aliasRes, platRes] = await Promise.all([
      api('/api/game_aliases.php?action=get'),
      api('/api/platforms.php?action=list')
    ]);
    if (aliasRes.success) savedAliases = aliasRes.aliases || {};
    const platforms = platRes.success ? platRes.platforms : CFG.platforms;
    renderGameAliasList(platforms);
  } catch(e) {
    if (el) el.innerHTML = '<div style="color:var(--text2);text-align:center;padding:16px;font-size:15px">Could not load games.</div>';
  }
}

function renderGameAliasList(platforms) {
  const el = document.getElementById('game-aliases-list');
  if (!el) return;
  if (!platforms || !platforms.length) {
    el.innerHTML = '<div style="color:var(--text2);text-align:center;padding:16px;font-size:15px">No games configured yet.</div>';
    return;
  }
  el.innerHTML = platforms.map(p => `
    <div class="game-alias-card">
      <div class="game-alias-dot" style="background:${p.color};box-shadow:0 0 8px ${p.color}"></div>
      <div style="flex:1;min-width:0">
        <div class="game-alias-name">${escHtml(p.name)}</div>
        <input class="game-alias-input" id="alias-${p.id}"
          type="text" maxlength="100"
          placeholder="Your in-game username..."
          value="${escHtml(savedAliases[p.id] || '')}"
          onchange="saveOneAlias('${p.id}',this.value)">
      </div>
    </div>`).join('');
}

async function saveOneAlias(slug, alias) {
  savedAliases[slug] = alias.trim();
  await api('/api/game_aliases.php?action=save', { platform_slug: slug, alias: alias.trim() });
}

async function saveAllAliases() {
  const al = document.getElementById('game-aliases-alert');
  const aliases = {};
  (CFG.platforms || []).forEach(p => {
    const el = document.getElementById('alias-' + p.id);
    if (el) aliases[p.id] = el.value.trim();
  });
  // Also grab any inputs by the alias-* pattern
  document.querySelectorAll('[id^="alias-"]').forEach(el => {
    const slug = el.id.replace('alias-', '');
    aliases[slug] = el.value.trim();
  });
  savedAliases = {...savedAliases, ...aliases};
  const d = await api('/api/game_aliases.php?action=save_all', { aliases });
  if (d.success) {
    showAlert(al, '✓ All aliases saved!', 'success');
    setTimeout(() => hideAlert(al), 3000);
  } else {
    showAlert(al, 'Save failed. Try again.', 'error');
  }
}

// Auto-prefill alias on buy page when platform changes
function prefillBuyAlias() {
  const platformId = document.getElementById('buy-platform')?.value;
  const aliasInput = document.getElementById('buy-alias');
  if (platformId && aliasInput && savedAliases[platformId]) {
    aliasInput.value = savedAliases[platformId];
  } else if (aliasInput && platformId && !savedAliases[platformId]) {
    aliasInput.value = '';
  }
}

function escHtml(s) { return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }
async function loadBillingProfile() {
  const d = await api('/api/billing.php?action=get');
  if (d.success && d.billing) {
    const b = d.billing;
    // Show saved card chip if card on file
    if (b.card_last4) {
      document.getElementById('saved-card-brand').textContent  = b.card_brand || 'CARD';
      document.getElementById('saved-card-number').textContent = '···· ···· ···· ' + b.card_last4;
      document.getElementById('saved-card-name').textContent   = [b.first_name, b.last_name].filter(Boolean).join(' ') || '—';
      const exp = (b.card_exp_month && b.card_exp_year) ? b.card_exp_month + '/' + b.card_exp_year.slice(-2) : '—';
      document.getElementById('saved-card-exp').textContent = exp;
      document.getElementById('saved-card-display').style.display = 'block';
    } else {
      document.getElementById('saved-card-display').style.display = 'none';
    }
    // Fill form fields
    setVal('p-first',   b.first_name);
    setVal('p-last',    b.last_name);
    setVal('p-email',   b.email);
    setVal('p-address', b.address);
    setVal('p-city',    b.city);
    setVal('p-state',   b.state);
    setVal('p-zip',     b.zip);
    // Also pre-fill buy form
    prefillBuyForm(b);
  } else {
    document.getElementById('saved-card-display').style.display = 'none';
  }
}

function prefillBuyForm(b) {
  if (!b) return;
  setVal('card-first-name', b.first_name);
  setVal('card-last-name',  b.last_name);
  setVal('card-address',    b.address);
  setVal('card-city',       b.city);
  setVal('card-state',      b.state);
  setVal('card-zip',        b.zip);
  setVal('card-email',      b.email);
}

function setVal(id, val) {
  const el = document.getElementById(id);
  if (el && val) el.value = val;
}

async function saveBillingProfile() {
  const al = document.getElementById('billing-alert');
  const data = {
    first_name: (document.getElementById('p-first')?.value   || '').trim(),
    last_name:  (document.getElementById('p-last')?.value    || '').trim(),
    email:      (document.getElementById('p-email')?.value   || '').trim(),
    address:    (document.getElementById('p-address')?.value || '').trim(),
    city:       (document.getElementById('p-city')?.value    || '').trim(),
    state:      (document.getElementById('p-state')?.value   || '').trim().toUpperCase(),
    zip:        (document.getElementById('p-zip')?.value     || '').trim(),
  };
  const d = await api('/api/billing.php?action=save', data);
  if (d.success) {
    showAlert(al, 'Billing info saved!', 'success');
    prefillBuyForm(data);
  } else showAlert(al, d.error || 'Save failed.', 'error');
}

async function clearSavedCard() {
  if (!confirm('Remove saved card info?')) return;
  const d = await api('/api/billing.php?action=clear_card', {});
  if (d.success) {
    document.getElementById('saved-card-display').style.display = 'none';
    // Clear card fields in buy form
    ['card-first-name','card-last-name'].forEach(id => { const el=document.getElementById(id); if(el) el.value=''; });
  }
}

async function clearAllBilling() {
  if (!confirm('Clear all saved billing information? This cannot be undone.')) return;
  const d = await api('/api/billing.php?action=clear_all', {});
  if (d.success) {
    loadBillingProfile();
    ['p-first','p-last','p-email','p-address','p-city','p-state','p-zip'].forEach(id => {
      const el=document.getElementById(id); if(el) el.value='';
    });
    const al = document.getElementById('billing-alert');
    showAlert(al, 'All billing info cleared.', 'success');
  }
}

// Auto-load billing when going to buy page
async function initBuyPageBilling() {
  const d = await api('/api/billing.php?action=get');
  if (d.success && d.billing) prefillBuyForm(d.billing);
}

// ─── CASHOUT ───────────────────────────────────────────────
async function submitCashout() {
  const al       = document.getElementById('cashout-alert');
  const pid      = document.getElementById('cashout-platform').value;
  const alias    = document.getElementById('cashout-alias').value.trim();
  const toks     = parseFloat(document.getElementById('cashout-tokens').value);
  const payoutId = getSelectedPayoutId();

  if (!payoutId)       { showAlert(al,'Please select a payout method above.','error'); return; }
  if (!pid)            { showAlert(al,'Please select a platform.','error'); return; }
  if (!alias)          { showAlert(al,'Please enter your in-game alias.','error'); return; }
  if (!toks || toks<1) { showAlert(al,'Enter a valid token amount.','error'); return; }

  // Get payout method details
  const pm = payoutMethods.find(m => m.id == payoutId);

  try {
    const d = await api('/api/cashout.php', {
      platform_id:       pid,
      alias,
      tokens:            toks,
      payout_method_id:  payoutId,
      payout_method_type: pm ? pm.method_type : '',
      payout_handle:     pm ? pm.account_handle : '',
    });
    if (d.success) {
      showAlert(al, '✓ Request created! Review and submit to admin when ready.', 'success');
      S.user.tokens = d.new_balance; updateUI();
      document.getElementById('cashout-tokens').value = '';
      document.getElementById('cashout-alias').value  = '';
      // Reload list and scroll to it
      await loadCashoutHistory();
      setTimeout(() => {
        const hist = document.getElementById('cashout-history');
        if (hist) hist.scrollIntoView({behavior:'smooth', block:'start'});
        // Briefly highlight the first (newest) card
        const first = hist?.querySelector('.co-card');
        if (first) { first.style.boxShadow='0 0 0 2px var(--gold)'; setTimeout(()=>first.style.boxShadow='',2000); }
      }, 200);
    } else showAlert(al, d.error||'Request failed.','error');
  } catch { showAlert(al,'Network error.','error'); }
}

async function loadCashoutHistory() {
  const el = document.getElementById('cashout-history');
  if (!el) return;
  try {
    const d = await api('/api/cashout.php?action=list');
    if (!d.success || !d.requests.length) {
      el.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:20px">No cashout requests yet. Submit one above.</div>';
      return;
    }
    el.innerHTML = d.requests.map(r => buildCashoutCard(r)).join('');
  } catch(e) {
    el.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:16px">Unable to load requests.</div>';
  }
}

function buildCashoutCard(r) {
  const editable = r.status === 'pending';
  const locked   = r.status === 'locked';
  const statusLabel = { pending:'⏳ Pending', locked:'🔒 Sent to Admin', sent:'✅ Sent', approved:'✅ Sent', rejected:'❌ Denied', deleted:'🗑 Deleted' };
  const payout   = r.payout_handle ? `<div style="font-size:15px;color:var(--cyan);margin-top:2px">${escHtml(r.payout_handle)}</div>` : '';
  const adminNote= r.admin_note ? `<div style="font-size:15px;color:var(--gold);margin-top:4px;padding:6px 8px;background:rgba(240,192,64,.07);border-radius:6px">📝 ${escHtml(r.admin_note)}</div>` : '';
  const actionBtns = editable ? `
    <div class="co-edit-row">
      <input class="fi" id="co-edit-tokens-${r.id}" type="number" min="1" value="${r.tokens}"
        style="width:90px;padding:7px 10px;font-size:15px" placeholder="Tokens">
      <input class="fi" id="co-edit-alias-${r.id}" type="text" value="${escHtml(r.alias||'')}"
        style="flex:1;min-width:100px;padding:7px 10px;font-size:15px" placeholder="Game alias">
      <button onclick="updateCashoutRequest(${r.id})"
        style="background:rgba(0,229,255,.1);border:1px solid rgba(0,229,255,.25);color:var(--cyan);border-radius:8px;padding:7px 12px;font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap">
        ✏️ Update
      </button>
      <button onclick="deleteCashoutRequest(${r.id})"
        style="background:rgba(255,68,68,.08);border:1px solid rgba(255,68,68,.2);color:var(--red);border-radius:8px;padding:7px 12px;font-size:14px;font-weight:700;cursor:pointer">
        🗑
      </button>
      <button onclick="lockCashoutRequest(${r.id})"
        style="background:rgba(240,192,64,.1);border:1px solid rgba(240,192,64,.25);color:var(--gold);border-radius:8px;padding:7px 12px;font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap">
        🔒 Submit to Admin
      </button>
    </div>` : '';
  const lockNote = locked ? `<div style="font-size:15px;color:var(--cyan);margin-top:8px;padding:7px 10px;background:rgba(0,229,255,.06);border-radius:6px;border:1px solid rgba(0,229,255,.15)">🔒 This request has been submitted to our team. They will process it shortly.</div>` : '';

  return `<div class="co-card ${r.status}" id="co-card-${r.id}">
    <div style="display:flex;align-items:flex-start;justify-content:space-between;gap:10px">
      <div style="flex:1;min-width:0">
        <div style="display:flex;align-items:center;flex-wrap:wrap;gap:4px;margin-bottom:4px">
          <span style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:16px;color:var(--gold)">${r.tokens}</span>
          <span style="margin-left:2px">${tokenCoin(18)}</span>
          <span class="co-status-pill co-status-${r.status}">${statusLabel[r.status]||r.status}</span>
        </div>
        <div style="font-size:14px;color:var(--text2)">${escHtml(r.platform_name||r.platform_id)} · <span style="color:var(--cyan)">${escHtml(r.alias||'')}</span></div>
        ${payout}
        ${adminNote}
        ${lockNote}
      </div>
      <div style="text-align:right;flex-shrink:0">
        <div style="font-size:15px;color:var(--text2)">${(r.created_at||'').substring(0,10)}</div>
        <div style="font-size:14px;color:var(--text2);margin-top:2px">#${r.id}</div>
      </div>
    </div>
    ${actionBtns}
  </div>`;
}

async function updateCashoutRequest(id) {
  const tokens = parseFloat(document.getElementById('co-edit-tokens-'+id)?.value||0);
  const alias  = document.getElementById('co-edit-alias-'+id)?.value.trim();
  if (!tokens||tokens<1) { showAlert(document.getElementById('cashout-alert'),'Enter a valid token amount.','error'); return; }
  const d = await api('/api/cashout.php?action=update&id='+id+'&tokens='+tokens+'&alias='+encodeURIComponent(alias));
  if (d.success) {
    showAlert(document.getElementById('cashout-alert'),'✓ Request updated!','success');
    setTimeout(()=>{ const al=document.getElementById('cashout-alert'); if(al){al.className='alert';al.textContent='';} }, 3000);
    loadCashoutHistory();
  } else showAlert(document.getElementById('cashout-alert'), d.error||'Update failed','error');
}

async function deleteCashoutRequest(id) {
  if (!confirm('Cancel this cashout request?\n\nYour tokens will be returned to your balance immediately.')) return;
  const d = await api('/api/cashout.php?action=delete&id='+id);
  if (d.success) {
    if (d.new_balance !== undefined && S.user) { S.user.tokens = d.new_balance; updateUI(); }
    const card = document.getElementById('co-card-'+id);
    if (card) { card.style.transition='opacity .3s'; card.style.opacity='0'; setTimeout(()=>card.remove(), 300); }
    showAlert(document.getElementById('cashout-alert'),'✓ Request cancelled. Tokens returned.','success');
    setTimeout(()=>{ const al=document.getElementById('cashout-alert'); if(al){al.className='alert';al.textContent='';} }, 3000);
  } else showAlert(document.getElementById('cashout-alert'), d.error||'Delete failed','error');
}

async function lockCashoutRequest(id) {
  if (!confirm('Submit this cashout request to our team for processing?\n\nYou won\'t be able to edit it after this.')) return;
  const d = await api('/api/cashout.php?action=lock&id='+id);
  if (d.success) {
    loadCashoutHistory();
    showAlert(document.getElementById('cashout-alert'),'✓ Submitted! Our team will process it shortly.','success');
    setTimeout(()=>{ const al=document.getElementById('cashout-alert'); if(al){al.className='alert';al.textContent='';} }, 4000);
  } else showAlert(document.getElementById('cashout-alert'), d.error||'Error','error');
}

// ─── PLAYER ACTIVITY DASHBOARD ────────────────────────────
let activityData  = null;
let activityFilter = 'all';
let activityPollTimer = null;

async function loadProfileHistory() {
  // Renamed alias kept for compatibility
  await loadActivityDashboard();
}

async function loadActivityDashboard() {
  const feed = document.getElementById('activity-feed');
  const sumEl = document.getElementById('activity-summary');
  if (!feed) return;
  try {
    const d = await api('/api/my_activity.php?action=all');
    if (!d.success) throw new Error('Failed');
    activityData = d;
    renderActivitySummary(d, sumEl);
    renderActivityFeed(activityFilter);
    // Poll for real-time updates every 15s while profile is open
    clearTimeout(activityPollTimer);
    activityPollTimer = setTimeout(async () => {
      const fresh = await api('/api/my_activity.php?action=all').catch(()=>null);
      if (fresh?.success) { activityData = fresh; renderActivitySummary(fresh, sumEl); renderActivityFeed(activityFilter); }
    }, 15000);
  } catch(e) {
    feed.innerHTML = '<div style="color:var(--text2);font-size:15px;text-align:center;padding:20px">Unable to load activity.</div>';
  }
}

function filterActivity(filter, btn) {
  activityFilter = filter;
  document.querySelectorAll('.activity-ftab').forEach(b => b.classList.remove('active'));
  if (btn) btn.classList.add('active');
  renderActivityFeed(filter);
}

function renderActivitySummary(d, el) {
  if (!el) return;
  const purchases = d.purchases || [];
  const cashouts  = d.cashouts  || [];
  const pending_p = purchases.filter(p => p.status === 'pending').length;
  const pending_c = cashouts.filter(c => c.status === 'pending' || c.status === 'locked').length;
  const total_spent = purchases.filter(p => p.status !== 'failed').reduce((s,p) => s + (p.amount_cents/100), 0);
  const total_cashed = cashouts.filter(c => c.status === 'sent' || c.status === 'approved').reduce((s,c) => s + parseFloat(c.tokens||0), 0);
  const pills = [
    total_spent > 0   ? `<div class="summary-pill">💳 $${total_spent.toFixed(2)} purchased</div>` : '',
    total_cashed > 0  ? `<div class="summary-pill" style="color:var(--green)">💸 ${total_cashed} tokens cashed out</div>` : '',
    pending_p > 0     ? `<div class="summary-pill" style="color:var(--gold);border-color:rgba(240,192,64,.3)">⏳ ${pending_p} purchase${pending_p>1?'s':''} pending</div>` : '',
    pending_c > 0     ? `<div class="summary-pill" style="color:var(--cyan);border-color:rgba(0,229,255,.2)">⏳ ${pending_c} cashout${pending_c>1?'s':''} in review</div>` : '',
  ].filter(Boolean).join('');
  el.innerHTML = pills;
}

function renderActivityFeed(filter) {
  const feed = document.getElementById('activity-feed');
  if (!feed || !activityData) return;
  const items = buildActivityItems(activityData, filter);
  if (!items.length) {
    const labels = {all:'activity', purchases:'purchases', cashouts:'cashout requests', broadcasts:'announcements'};
    feed.innerHTML = `<div style="text-align:center;padding:28px;color:var(--text2);font-size:15px">No ${labels[filter]||filter} yet.</div>`;
    return;
  }
  feed.innerHTML = items.map(renderActivityCard).join('');
}

function buildActivityItems(d, filter) {
  let items = [];

  if (filter === 'all' || filter === 'purchases') {
    (d.purchases||[]).forEach(p => items.push({ _type:'purchase', _ts: p.created_at, ...p }));
  }
  if (filter === 'all' || filter === 'cashouts') {
    (d.cashouts||[]).forEach(c => items.push({ _type:'cashout', _ts: c.created_at, ...c }));
  }
  if (filter === 'all' || filter === 'broadcasts') {
    (d.broadcasts||[]).forEach(b => items.push({ _type:'broadcast', _ts: b.sent_at, ...b }));
  }

  // Sort newest first
  items.sort((a,b) => new Date(b._ts) - new Date(a._ts));

  // For 'all', interleave with date dividers
  if (filter === 'all') {
    const grouped = []; let lastDate = '';
    items.forEach(item => {
      const dt = (item._ts||'').substring(0,10);
      if (dt !== lastDate) {
        lastDate = dt;
        const d0 = new Date(dt+'T00:00:00'), now = new Date();
        now.setHours(0,0,0,0);
        const diff = Math.round((now-d0)/86400000);
        const label = diff===0?'Today':diff===1?'Yesterday':d0.toLocaleDateString('en-US',{month:'short',day:'numeric'});
        grouped.push({ _type:'divider', label });
      }
      grouped.push(item);
    });
    return grouped;
  }
  return items;
}

const PMT_ICON = { card:'💳', venmo:'💙', cashapp:'💚', zelle:'💜', chime:'🟢' };

function renderActivityCard(item) {
  if (item._type === 'divider') {
    return `<div style="font-size:15px;font-weight:700;color:var(--text2);letter-spacing:1px;text-transform:uppercase;padding:10px 0 6px;border-bottom:1px solid var(--border);margin-bottom:6px">${item.label}</div>`;
  }

  if (item._type === 'purchase') {
    const statusMap = { completed:'✅ Completed', pending:'⏳ Awaiting Payment', failed:'❌ Failed', approved:'✅ Approved' };
    const statusClass = { completed:'ac-completed', pending:'ac-pending', failed:'ac-failed', approved:'ac-completed' };
    const icon  = PMT_ICON[item.payment_method] || '💳';
    const amt   = item.amount_cents ? '$'+(item.amount_cents/100).toFixed(2) : '';
    const card  = item.card_last4 ? `${item.card_brand||'Card'} ····${item.card_last4}` : '';
    const note  = item.admin_note ? `<div style="font-size:15px;color:var(--gold);margin-top:4px">📝 ${escHtml(item.admin_note)}</div>` : '';
    return `<div class="activity-card">
      <div class="activity-icon" style="background:rgba(0,230,118,.1)">${icon}</div>
      <div class="activity-body">
        <div class="activity-title">Token Purchase · ${item.tokens} ${tokenCoin(14)}</div>
        <div class="activity-meta">${pname(item.platform_id)}${item.game_alias?' · '+escHtml(item.game_alias):''}</div>
        ${card?`<div class="activity-meta">${card}</div>`:''}
        <span class="activity-status ${statusClass[item.status]||'ac-pending'}">${statusMap[item.status]||item.status}</span>
        ${note}
      </div>
      <div class="activity-amount">
        <div style="color:var(--green)">${amt}</div>
        <div style="font-size:14px;color:var(--text2);font-weight:400;margin-top:2px">${(item.created_at||'').substring(0,10)}</div>
      </div>
    </div>`;
  }

  if (item._type === 'cashout') {
    const statusMap = {
      pending:'⏳ Draft — not submitted',
      locked:'🔒 Submitted to admin',
      sent:'✅ Payment Sent',
      approved:'✅ Payment Sent',
      rejected:'❌ Denied',
      deleted:'🗑 Deleted'
    };
    const statusClass = { pending:'ac-pending', locked:'ac-locked', sent:'ac-completed', approved:'ac-completed', rejected:'ac-failed', deleted:'ac-failed' };
    const payout = item.payout_handle ? `<div class="activity-meta">${escHtml(item.payout_handle)}</div>` : '';
    const note   = item.admin_note ? `<div style="font-size:15px;color:var(--gold);margin-top:4px">📝 ${escHtml(item.admin_note)}</div>` : '';
    const canEdit = item.status === 'pending';
    return `<div class="activity-card" style="${item.status==='pending'?'border-color:rgba(240,192,64,.2)':item.status==='locked'?'border-color:rgba(0,229,255,.15)':''}">
      <div class="activity-icon" style="background:rgba(240,192,64,.1)">💸</div>
      <div class="activity-body">
        <div class="activity-title">Cashout Request · ${item.tokens} ${tokenCoin(14)}</div>
        <div class="activity-meta">${escHtml(item.platform_name||item.platform_id)}${item.alias?' · '+escHtml(item.alias):''}</div>
        ${payout}
        <span class="activity-status ${statusClass[item.status]||'ac-pending'}">${statusMap[item.status]||item.status}</span>
        ${note}
        ${canEdit?`<div style="margin-top:8px"><button onclick="showPage('cashout')" style="background:none;border:none;color:var(--cyan);font-size:15px;font-weight:700;cursor:pointer;padding:0">✏️ Edit on Cashout page →</button></div>`:''}
      </div>
      <div class="activity-amount">
        <div style="font-size:14px;color:var(--text2);font-weight:400;margin-top:2px">${(item.created_at||'').substring(0,10)}</div>
        <div style="font-size:14px;color:var(--text2)">#${item.id}</div>
      </div>
    </div>`;
  }

  if (item._type === 'broadcast') {
    const isNew = !parseInt(item.is_read);
    return `<div class="activity-card" style="${isNew?'border-color:rgba(240,192,64,.2)':''}">
      <div class="activity-icon" style="background:rgba(240,192,64,.08)">📢</div>
      <div class="activity-body">
        <div class="activity-title">${escHtml(item.subject)}</div>
        <div class="activity-meta">From ${escHtml(item.sender)} · ${(item.sent_at||'').substring(0,10)}</div>
        <div style="font-size:14px;color:var(--text2);margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px">${escHtml(item.message)}</div>
        ${isNew?'<span class="activity-status ac-new">● New</span>':'<span class="activity-status ac-read">Read</span>'}
        ${parseInt(item.replied)?'<span class="activity-status ac-locked" style="margin-left:4px">Replied</span>':''}
      </div>
      <div>
        <button onclick="showPage('broadcasts')" style="background:none;border:none;color:var(--cyan);font-size:15px;font-weight:700;cursor:pointer;padding:0;white-space:nowrap">View →</button>
      </div>
    </div>`;
  }
  return '';
}

function pname(id) {
  return CFG.platforms?.find(p=>p.id===id)?.name || id || '—';
}

// ─── AUTH ──────────────────────────────────────────────────

async function resendFromLogin() {
  const btn=document.getElementById('login-resend-btn');
  const al=document.getElementById('login-resend-alert');
  const email=S._unverifiedEmail;
  if(!email){showAlert(al,'Please register first.','error');return;}
  btn.innerHTML='<span class="spinner"></span>'; btn.disabled=true;
  try {
    const d=await api('/api/resend_verify.php',{email});
    if(d.success) showAlert(al,'Verification email resent! Check your inbox.','success');
    else showAlert(al,d.error||'Could not resend.','error');
  } catch{showAlert(al,'Network error.','error');}
  btn.innerHTML='Resend Verification Email'; btn.disabled=false;
}

async function doRegister() {
  const btn=document.getElementById('reg-btn'); const al=document.getElementById('reg-alert');
  const u=document.getElementById('reg-user').value.trim();
  const alias=document.getElementById('reg-alias').value.trim();
  const email=document.getElementById('reg-email').value.trim();
  const p=document.getElementById('reg-pass').value;
  if(!u||!alias||!p){showAlert(al,'Username, alias and password are required.','error');return;}
  if(!email){showAlert(al,'Email address is required for account verification.','error');return;}
  btn.innerHTML='<span class="spinner"></span>'; btn.disabled=true;
  try {
    const d=await api('/api/register.php',{username:u,alias,email,password:p,referral_code:getUrlRefCode()});
    if(d.success){
      // Show pending verification state
      document.getElementById('reg-pending-email').textContent = d.email || email;
      S._pendingEmail = d.email || email;
      showPendingState();
      if (d.mail_warning) {
        // Email failed to send - show resend option prominently
        showAlert(document.getElementById('pending-alert')||al,
          'Account created! We had trouble sending the verification email. Use the Resend button below.','error');
      }
    } else {
      showAlert(al,d.error||'Registration failed.','error');
    }
  } catch{showAlert(al,'Network error.','error');}
  btn.innerHTML='CREATE ACCOUNT'; btn.disabled=false;
}

function showPendingState() {
  document.getElementById('reg-form-state').style.display='none';
  document.getElementById('reg-pending-state').style.display='block';
}

function showRegForm() {
  document.getElementById('reg-form-state').style.display='block';
  document.getElementById('reg-pending-state').style.display='none';
}

async function resendVerify() {
  const btn=document.getElementById('resend-btn');
  const al=document.getElementById('resend-alert');
  const email=S._pendingEmail;
  if(!email){showAlert(al,'No email found. Please register again.','error');return;}
  btn.innerHTML='<span class="spinner"></span>'; btn.disabled=true;
  try {
    const d=await api('/api/resend_verify.php',{email});
    if(d.success) showAlert(al,'Verification email resent! Check your inbox.','success');
    else showAlert(al,d.error||'Could not resend.','error');
  } catch{showAlert(al,'Network error.','error');}
  btn.innerHTML='Resend Verification Email'; btn.disabled=false;
}

async function doLogout() {
  try { await fetch('/api/logout.php'); } catch(e) {}
  S.user = null;
  S.pkg  = null;
  // Clear any cached state
  if (window._refData) window._refData = null;
  showAuth();
}

// ─── HELPERS ──────────────────────────────────────────────
function showAlert(el,msg,type){el.textContent=msg;el.className='alert show alert-'+type;}
function hideAlert(el){el.className='alert';}
function showModal(id){document.getElementById(id).classList.add('show');}
function closeModal(id){document.getElementById(id).classList.remove('show');}
document.addEventListener('keydown',e=>{if(e.key==='Enter'){const t=document.getElementById('tab-login');if(t&&t.style.display!=='none')doLogin();}});

// ─── CHAT ─────────────────────────────────────────────────
let chatState = { lastId: 0, polling: null, initialized: false };

function initChat() {
  // Load/reload messages every time chat opens
  loadChatMessages(true);
  if (chatState.initialized) return;
  chatState.initialized = true;
  // Auto-refresh every 3s while chat is open
  chatState.polling = setInterval(() => {
    if (document.getElementById('page-chat').classList.contains('active')) {
      loadChatMessages(false);
    }
    pollChatBadge();
  }, 3000);
}

async function loadChatMessages(scrollToBottom) {
  try {
    const d = await api('/api/chat.php?action=messages&since=' + chatState.lastId);
    if (!d.success) return;
    const container = document.getElementById('chat-messages');
    const quickReplies = document.getElementById('chat-quick-replies');

    if (d.messages.length === 0 && chatState.lastId === 0) {
      container.innerHTML = '<div class="chat-empty">' +
        '<div class="chat-empty-icon">&#128172;</div>' +
        '<div class="chat-empty-text">Have a question about tokens,<br>a cashout, or your account?<br>' +
        '<strong style="color:var(--gold)">Send us a message below!</strong></div></div>';
      if (quickReplies) quickReplies.style.display = 'flex';
      return;
    }

    if (d.messages.length > 0) {
      if (quickReplies) quickReplies.style.display = 'none';
      const emptyEl = container.querySelector('.chat-empty, .chat-loading');
      if (emptyEl) emptyEl.remove();

      let lastDate = '';
      d.messages.forEach(msg => {
        // Skip if bubble already in DOM
        if (container.querySelector('[data-id="' + msg.id + '"]')) return;
        const msgDate = msg.created_at.substring(0,10);
        if (msgDate !== lastDate) {
          lastDate = msgDate;
          const div = document.createElement('div');
          div.className = 'chat-date-divider';
          div.textContent = formatChatDate(msgDate);
          container.appendChild(div);
        }
        const bubble = buildBubble(msg);
        // Animate new incoming admin messages
        if (msg.sender === 'admin' && chatState.lastId > 0) {
          bubble.style.animation = 'fadeUp .3s ease';
        }
        container.appendChild(bubble);
        chatState.lastId = Math.max(chatState.lastId, parseInt(msg.id));
      });

      if (scrollToBottom) scrollChat();
      else {
        const near = container.scrollHeight - container.scrollTop - container.clientHeight < 160;
        if (near) scrollChat();
      }
    }
  } catch(e) { console.warn('Chat poll error', e); }
}

function buildBubble(msg) {
  const isMine = msg.sender === 'user';
  const wrap = document.createElement('div');
  wrap.className = 'chat-bubble-wrap ' + (isMine ? 'mine' : 'theirs');
  wrap.dataset.id = msg.id;
  const time = msg.created_at.substring(11,16);
  const senderLabel = isMine ? '' : '<div class="chat-sender-label">Support</div>';
  wrap.innerHTML = senderLabel +
    '<div class="chat-bubble ' + (isMine ? 'mine' : 'theirs') + '">' + escHtml(msg.message) + '</div>' +
    '<div class="chat-time">' + time + '</div>';
  return wrap;
}

function scrollChat() {
  const c = document.getElementById('chat-messages');
  if (c) { c.scrollTop = c.scrollHeight; }
}

function onChatInput() {
  const btn = document.getElementById('chat-send-btn');
  const input = document.getElementById('chat-input');
  if (btn) btn.classList.toggle('has-text', input.value.trim().length > 0);
}

function quickReply(text) {
  const input = document.getElementById('chat-input');
  if (input) {
    input.value = text;
    input.focus();
    onChatInput();
  }
}

async function sendChatMsg() {
  const input = document.getElementById('chat-input');
  const btn   = document.getElementById('chat-send-btn');
  const msg   = input.value.trim();
  if (!msg) return;
  input.value = '';
  if (btn) btn.classList.remove('has-text');

  const container = document.getElementById('chat-messages');
  const quickReplies = document.getElementById('chat-quick-replies');
  const emptyEl = container.querySelector('.chat-empty, .chat-loading');
  if (emptyEl) emptyEl.remove();
  if (quickReplies) quickReplies.style.display = 'none';

  // Optimistic bubble
  const tempBubble = buildBubble({
    id: 'temp_' + Date.now(), sender: 'user', message: msg,
    created_at: new Date().toISOString().replace('T',' ').substring(0,19)
  });
  tempBubble.style.opacity = '0.65';
  container.appendChild(tempBubble);
  scrollChat();

  try {
    const d = await api('/api/chat.php?action=send', { message: msg });
    if (d.success) {
      tempBubble.style.opacity = '1';
      tempBubble.dataset.id = d.id;
      chatState.lastId = Math.max(chatState.lastId, d.id);
    } else {
      tempBubble.remove();
    }
  } catch { tempBubble.remove(); }
}

async function pollChatBadge() {
  try {
    const d = await api('/api/chat.php?action=unread');
    const badge = document.getElementById('chat-nav-badge');
    if (d.success && d.count > 0) {
      badge.textContent = d.count > 9 ? '9+' : d.count;
      badge.style.display = 'flex';
    } else {
      badge.style.display = 'none';
    }
  } catch(e) {}
}

function formatChatDate(dateStr) {
  const d = new Date(dateStr + 'T00:00:00');
  const today = new Date(); today.setHours(0,0,0,0);
  const diff = Math.round((today - d) / 86400000);
  if (diff === 0) return 'Today';
  if (diff === 1) return 'Yesterday';
  return d.toLocaleDateString('en-US', {month:'short', day:'numeric'});
}

function escHtml(s) {
  return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br>');
}

</script>
</body>
<!-- v<?= $_appVersion ?> --></html>
