// React + ReactDOM são UMD globals (carregados via CDN no index.html)
const { useState, useEffect } = React;

/* ─── BRAND ASSETS ──────────────────────────────────────────────── */
const LOGO_SRC = "./assets/logo.png";
const CLOSED_PACK_SRC = "./assets/pack.jpg";
const BRAND_GREEN  = "#7bc843";
const BRAND_PURPLE = "#8844cc";
const BRAND_GREEN_GLOW  = "rgba(123,200,67,0.4)";
const BRAND_PURPLE_GLOW = "rgba(136,68,204,0.4)";

/* ─── GLOBAL STYLES ─────────────────────────────────────────────── */
const GlobalStyle = React.memo(() => (
  <style>{`
    @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;700;900&family=Share+Tech+Mono&family=Rajdhani:wght@300;400;500;600;700&display=swap');
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    :root {
      --red: #8844cc; --red-dark: #4a1880; --red-glow: rgba(136,68,204,0.35);
      --cyan: #7bc843; --cyan-dim: rgba(123,200,67,0.12); --cyan-glow: rgba(123,200,67,0.3);
      --purple: #8844cc; --purple-dim: rgba(136,68,204,0.12); --purple-glow: rgba(136,68,204,0.3);
      --bg: #000000; --bg2: #080808; --bg3: #101010;
      --panel: rgba(4,4,4,0.97); --border: rgba(255,255,255,0.14); --border-purple: rgba(136,68,204,0.4); --border-red: rgba(136,68,204,0.4);
      --text: #e0e0e0; --text-dim: rgba(255,255,255,0.42); --text-bright: #ffffff;
      --gold: #b0b0b0; --gold-dim: rgba(180,180,180,0.1);
      --mono: 'Share Tech Mono', monospace; --display: 'Orbitron', sans-serif; --body: 'Rajdhani', sans-serif;
    }
    html, body { height:100%; background:var(--bg); color:var(--text); font-family:var(--body); overflow-x:hidden; }
    #root { height:100%; }
    ::-webkit-scrollbar { width:3px; } ::-webkit-scrollbar-track { background:var(--bg); } ::-webkit-scrollbar-thumb { background:linear-gradient(var(--purple),var(--cyan)); }
    input, textarea, select {
      background:rgba(0,0,0,0.55); border:1px solid var(--border); color:var(--text);
      font-family:var(--body); font-size:15px; padding:10px 14px; width:100%;
      outline:none; border-radius:2px; transition:border-color .2s, box-shadow .2s;
    }
    input:focus, textarea:focus, select:focus { border-color:var(--cyan); box-shadow:0 0 12px var(--cyan-glow), 0 0 4px var(--purple-glow); }
    input::placeholder { color:var(--text-dim); }
    select option { background:var(--bg2); }
    @keyframes flicker { 0%,100%{opacity:1;} 91%{opacity:.98;} 92%{opacity:.84;} 93%{opacity:.98;} }
    @keyframes pulse-red { 0%,100%{box-shadow:0 0 8px var(--purple-glow);} 50%{box-shadow:0 0 22px var(--purple-glow),0 0 40px rgba(136,68,204,.12);} }
    @keyframes pulse-cyan { 0%,100%{box-shadow:0 0 8px var(--cyan-glow);} 50%{box-shadow:0 0 22px var(--cyan-glow),0 0 36px rgba(255,255,255,.1);} }
    @keyframes slideUp { from{transform:translateY(24px);opacity:0;} to{transform:translateY(0);opacity:1;} }
    @keyframes glitch { 0%,100%{transform:none;} 20%{transform:skewX(1deg) translateX(2px);} 40%{transform:skewX(-1deg) translateX(-2px);} 60%{transform:none;} }
    @keyframes xp-pop { 0%{transform:translate(-50%,-50%) scale(1);opacity:1;} 100%{transform:translate(-50%,-100%) scale(1.4);opacity:0;} }
    @keyframes scanpulse { 0%,100%{opacity:.04;} 50%{opacity:.08;} }
    @keyframes brand-pulse {
      0%,100%{filter:drop-shadow(0 0 8px rgba(123,200,67,0.4)) drop-shadow(0 0 16px rgba(136,68,204,0.3));}
      50%{filter:drop-shadow(0 0 16px rgba(123,200,67,0.7)) drop-shadow(0 0 32px rgba(136,68,204,0.5));}
    }
    @keyframes rankup { 0%{transform:scale(0.7);opacity:0;} 60%{transform:scale(1.08);} 100%{transform:scale(1);opacity:1;} }
    @keyframes pack-float { 0%,100%{transform:translateY(0) rotate(-1deg);} 50%{transform:translateY(-10px) rotate(1deg);} }
    @keyframes pack-shake { 0%,100%{transform:rotate(0deg);} 20%{transform:rotate(-3deg);} 40%{transform:rotate(3deg);} 60%{transform:rotate(-2deg);} 80%{transform:rotate(2deg);} }
    @keyframes tear-top { 0%{clip-path:polygon(0 0,100% 0,100% 52%,0 52%);transform:translate(0,0) rotate(0);opacity:1;} 100%{clip-path:polygon(0 0,100% 0,100% 52%,0 52%);transform:translate(-70px,-130px) rotate(-24deg);opacity:0;} }
    @keyframes tear-bot { 0%{clip-path:polygon(0 48%,100% 48%,100% 100%,0 100%);transform:translate(0,0) rotate(0);opacity:1;} 100%{clip-path:polygon(0 48%,100% 48%,100% 100%,0 100%);transform:translate(35px,110px) rotate(10deg);opacity:0;} }
    @keyframes pack-float { 0%,100%{transform:translateY(0) rotate(-0.5deg);} 50%{transform:translateY(-10px) rotate(0.5deg);} }
    @keyframes pack-shake { 0%,100%{transform:rotate(0) scale(1);} 15%{transform:rotate(-6deg) scale(1.03);} 35%{transform:rotate(6deg) scale(1.03);} 55%{transform:rotate(-3deg);} 75%{transform:rotate(3deg);} }
    @keyframes pack-float-glow { 0%,100%{opacity:0.3;} 50%{opacity:0.8;} }
    @keyframes holo-grid { 0%,100%{opacity:0.05;} 50%{opacity:0.13;} }
    @keyframes holo-rgb { 0%,100%{background-position:0% 50%;} 50%{background-position:100% 50%;} }
    @keyframes dummy-tear { 0%{transform:translateY(0) rotate(0deg);opacity:1;} 100%{transform:translateY(-120px) rotate(-15deg);opacity:0;} }
    @keyframes tear-bottom { 0%{transform:translateY(0);opacity:1;} 100%{transform:translateY(60px);opacity:0;} }
    @keyframes card-reveal { 0%{transform:scale(0.6) rotateY(90deg);opacity:0;} 60%{transform:scale(1.08) rotateY(-5deg);} 100%{transform:scale(1) rotateY(0deg);opacity:1;} }
    @keyframes float-anim { 0%,100%{transform:rotateY(10deg) rotateX(-6deg) translateY(0px);} 50%{transform:rotateY(14deg) rotateX(-4deg) translateY(-9px);} }
    @keyframes holo-sweep { 0%{background-position:200% center;} 100%{background-position:-200% center;} }
    @keyframes confetti-fall { 0%{transform:translateY(-20px) rotate(0deg);opacity:1;} 100%{transform:translateY(80px) rotate(720deg);opacity:0;} }
    @keyframes shine-sweep { 0%{left:-100%;} 100%{left:200%;} }
    @keyframes pulse-green { 0%,100%{opacity:1;box-shadow:0 0 6px #22c55e;} 50%{opacity:0.3;box-shadow:0 0 2px #22c55e;} }
    @keyframes pulse-purple { 0%,100%{opacity:1;} 50%{opacity:0.35;} }
    @keyframes bounce-in { 0%{transform:scale(0);opacity:0;} 60%{transform:scale(1.15);} 80%{transform:scale(0.95);} 100%{transform:scale(1);opacity:1;} }
  `}</style>
));

/* ─── HELPERS ────────────────────────────────────────────────────── */
const uid = () => Math.random().toString(36).slice(2,9);
const now = () => new Date().toISOString();

/* ─── SCORING SYSTEM ─────────────────────────────────────────────── */
const SCORE_TIERS = [
  { correct:0, multiplier:0,    label:"NO REWARD",  pack:null },
  { correct:1, multiplier:1.0,  label:"BREAK EVEN", pack:"BRONZE" },
  { correct:2, multiplier:1.5,  label:"NICE ONE",   pack:"SILVER" },
  { correct:3, multiplier:2.0,  label:"GREAT PLAY", pack:"GOLD" },
  { correct:4, multiplier:2.5,  label:"PERFECT!",   pack:"PLATINUM" },
];
const PACK_CONFIG = {
  BRONZE: {
    label:"BRONZE", cardLabel:"Common", stars:1,
    color1:"#e8a050", color2:"#7a3800", color3:"#f0b96e",
    glow:"rgba(200,110,30,0.85)",
    bgGrad:"linear-gradient(160deg,#1a0800,#3d1500 35%,#7a3000 65%,#1a0800)",
    frameFilter:"sepia(0.6) hue-rotate(350deg) saturate(2.2) brightness(0.88)",
    frameGlow:"rgba(220,130,40,0.75)", shimmer:"rgba(220,150,60,0.4)",
    shadow:"0 0 36px rgba(200,110,30,0.8),0 0 70px rgba(200,110,30,0.3),0 20px 40px rgba(0,0,0,0.9)",
    fx:[],
    shine:"rgba(255,200,120,0.5)", border:"#c07030", stripe1:"#ff9040",
    packBg:"linear-gradient(145deg,#1a0c00 0%,#3d1a00 25%,#7a3800 45%,#c87020 60%,#7a3800 75%,#3d1a00 90%,#1a0c00 100%)",
    cardBg:"linear-gradient(160deg,#1a0800 0%,#4a1800 40%,#8a3000 70%,#1a0800 100%)",
  },
  SILVER: {
    label:"SILVER", cardLabel:"Uncommon", stars:2,
    color1:"#d0d0d0", color2:"#484848", color3:"#f0f0f0",
    glow:"rgba(200,200,200,0.75)",
    bgGrad:"linear-gradient(160deg,#0a0a0a,#1e1e1e 35%,#484848 65%,#0a0a0a)",
    frameFilter:"brightness(1.1) saturate(0.35) contrast(1.05)",
    frameGlow:"rgba(200,200,200,0.65)", shimmer:"rgba(255,255,255,0.45)",
    shadow:"0 0 36px rgba(200,200,200,0.55),0 0 70px rgba(200,200,200,0.2),0 20px 40px rgba(0,0,0,0.9)",
    fx:["diagonal"],
    shine:"rgba(255,255,255,0.4)", border:"#b0b0b0", stripe1:"#e0e0e0",
    packBg:"linear-gradient(145deg,#101010 0%,#282828 30%,#606060 50%,#909090 60%,#606060 75%,#282828 90%,#101010 100%)",
    cardBg:"linear-gradient(160deg,#0a0a0a 0%,#1e1e1e 40%,#484848 70%,#0a0a0a 100%)",
  },
  GOLD: {
    label:"GOLD", cardLabel:"Rare", stars:3,
    color1:"#ffd700", color2:"#705500", color3:"#ffe566",
    glow:"rgba(255,210,0,0.95)",
    bgGrad:"linear-gradient(160deg,#100a00,#2e1a00 35%,#705500 65%,#100a00)",
    frameFilter:"sepia(0.5) saturate(3.5) brightness(1.15) hue-rotate(5deg)",
    frameGlow:"rgba(255,200,0,0.85)", shimmer:"rgba(255,240,100,0.45)",
    shadow:"0 0 36px rgba(255,210,0,0.85),0 0 70px rgba(255,210,0,0.3),0 20px 40px rgba(0,0,0,0.9)",
    fx:["diagonal"],
    shine:"rgba(255,240,100,0.5)", border:"#c8a800", stripe1:"#ffd700",
    packBg:"linear-gradient(145deg,#100a00 0%,#3d2a00 25%,#906000 45%,#ffd700 60%,#906000 75%,#3d2a00 90%,#100a00 100%)",
    cardBg:"linear-gradient(160deg,#100a00 0%,#2e1a00 40%,#705500 70%,#100a00 100%)",
  },
  PLATINUM: {
    label:"PLATINUM", cardLabel:"Ultra Rare", stars:4,
    color1:"#c0b0ff", color2:"#3a1890", color3:"#e0d4ff",
    glow:"rgba(160,130,255,0.95)",
    bgGrad:"linear-gradient(160deg,#06001a,#16084a 35%,#3a1890 65%,#06001a)",
    frameFilter:"hue-rotate(238deg) saturate(2.5) brightness(1.2)",
    frameGlow:"rgba(160,130,255,0.9)", shimmer:"rgba(200,180,255,0.5)",
    shadow:"0 0 50px rgba(160,130,255,0.95),0 0 90px rgba(160,130,255,0.4),0 20px 40px rgba(0,0,0,0.9)",
    fx:["diagonal","holo","rainbow"],
    shine:"rgba(200,180,255,0.5)", border:"#9070e0", stripe1:"#c0b0ff",
    packBg:"linear-gradient(145deg,#06001a 0%,#16084a 25%,#3a1890 45%,#c0b0ff 60%,#3a1890 75%,#16084a 90%,#06001a 100%)",
    cardBg:"linear-gradient(160deg,#06001a 0%,#16084a 40%,#3a1890 70%,#06001a 100%)",
  },
};
const calcScore = (entry, correctAnswers) => {
  if(!entry?.answers || !correctAnswers) return {correct:0, tier:SCORE_TIERS[0]};
  const questions = entry.questions || [];
  let correct = 0;
  questions.forEach(q => {
    if(correctAnswers[q.id] && entry.answers[q.id] === correctAnswers[q.id]) correct++;
  });
  const tier = SCORE_TIERS[Math.min(correct, SCORE_TIERS.length-1)];
  return {correct, tier};
};
const calcReward = (cost, multiplier) => Math.round(cost * multiplier);

/* ─── XP / RANK SYSTEM ───────────────────────────────────────────── */
const RANKS = [
  { name:"GHOST",      min:0,     color:"#3a4450" },
  { name:"RECRUIT",    min:100,   color:"#5a6a7a" },
  { name:"OPERATIVE",  min:300,   color:"#7a8a9a" },
  { name:"SPECIALIST", min:700,   color:"#ffffff" },
  { name:"SERGEANT",   min:1200,  color:"#ffffff" },
  { name:"LIEUTENANT", min:2000,  color:"#a0b8cc" },
  { name:"CAPTAIN",    min:3200,  color:"#e0e0e0" },
  { name:"COMMANDER",  min:5000,  color:"#8844cc" },
  { name:"COLONEL",    min:7500,  color:"#8844cc" },
  { name:"GENERAL",    min:11000, color:"#ffffff" },
  { name:"PHANTOM",    min:16000, color:"#ffffff" },
];
const getRank = (xp=0) => { let r=RANKS[0]; for(const rank of RANKS){if(xp>=rank.min)r=rank;} return r; };
const getNextRank = (xp=0) => { const i=RANKS.findIndex(r=>r.name===getRank(xp).name); return i<RANKS.length-1?RANKS[i+1]:null; };
const getXPProgress = (xp=0) => { const c=getRank(xp); const n=getNextRank(xp); if(!n)return 100; return Math.round(((xp-c.min)/(n.min-c.min))*100); };
const XP_DIFF = { EASY:100, MED:100, HARD:100, EXPERT:100 };
const XP_CLAIM = 50;

/* ─── ARENA IMAGES ───────────────────────────────────────────────── */
const ARENA_IMAGES = {
  ar1: "https://images.unsplash.com/photo-1542396601-dca920ea2807?w=480&auto=format&fit=crop&q=75",
  ar2: "https://images.unsplash.com/photo-1518770660439-4636190af475?w=480&auto=format&fit=crop&q=75",
  ar3: "https://images.unsplash.com/photo-1563986768494-4dee2763ff3f?w=480&auto=format&fit=crop&q=75",
};
const FALLBACK_IMG = "https://images.unsplash.com/photo-1477346611705-65d1883cee1e?w=480&auto=format&fit=crop&q=75";

/* ─── STATIC DATA ────────────────────────────────────────────────── */
const INITIAL_AVATARS = [
  {id:"a1",src:"./assets/avatar-a1.jpg"},
  {id:"a2",src:"./assets/avatar-a2.jpg"},
  {id:"a3",src:"./assets/avatar-a3.jpg"},
  {id:"a4",src:"./assets/avatar-a4.jpg"},
  {id:"a5",src:"./assets/avatar-a5.jpg"},
  {id:"a6",src:"./assets/avatar-a6.jpg"},
  {id:"a7",src:"./assets/avatar-a7.jpg"},
  {id:"a8",src:"./assets/avatar-a8.jpg"}
];

const INITIAL_ARENAS = [
  {id:"ar1",name:"SHADOW OPS",color:"#8844cc",desc:"High-risk infiltration challenges",active:true},
  {id:"ar2",name:"CIPHER GATE", color:"#ffffff",desc:"Intelligence & decryption trials",active:true},
  {id:"ar3",name:"WARZONE ALPHA",color:"#8844cc",desc:"Combat strategy arena",active:true},
];
const INITIAL_CHALLENGES = [
  {id:"ch1",arenaId:"ar1",name:"DARK PASSAGE",desc:"Navigate the enemy compound undetected.",    cost:50,reward:200,difficulty:"HARD",  active:true},
  {id:"ch2",arenaId:"ar1",name:"SILENT BLADE", desc:"Eliminate targets silently in 3 minutes.", cost:30,reward:120,difficulty:"MED",   active:true},
  {id:"ch3",arenaId:"ar2",name:"DECODE ALPHA", desc:"Decrypt the 5-layer cipher in time.",      cost:40,reward:160,difficulty:"HARD",  active:true},
  {id:"ch4",arenaId:"ar2",name:"DATA BREACH",  desc:"Extract intel from secured server.",        cost:20,reward:80, difficulty:"EASY",  active:true},
  {id:"ch5",arenaId:"ar3",name:"SIEGE MODE",   desc:"Hold the position for 5 waves.",            cost:60,reward:250,difficulty:"EXPERT",active:true},
];

/* ─── ODDS-API.IO INTEGRATION ───────────────────────────────────── */
// ── App URL ────────────────────────────────────────────────────
const APP_URL = "https://dfuse.gg";

// ── Language System ─────────────────────────────────────────────
const LANG = {
  en: {
    // Nav
    myCards:"MY CARDS", ranking:"RANKING", dailyReward:"DAILY REWARD",
    claimNow:"CLAIM NOW", claimed:"✓ CLAIMED", nextClaim:"next claim in",
    // Lobby
    activeArenas:"ACTIVE ARENAS", available:"AVAILABLE", tapToEnter:"TAP TO ENTER →",
    operations:"OPERATIONS", entry:"ENTRY", rewardMax:"REWARD (MAX)", xp:"XP",
    joinOp:"JOIN OP", viewResult:"VIEW RESULT", closed:"CLOSED", noCoins:"NO COINS",
    // Challenge
    lockIn:"LOCK IN", picks:"PICKS", tapToChange:"TAP ANY TO CHANGE",
    // Result
    betterLuck:"Better luck next time!", congrats:"Congratulations, go check your prize!",
    dareToPick:"Dare to pick!", goodLuck:"Good luck, you gonna need it!",
    // Cards
    saveCollection:"✦ SAVE TO COLLECTION", dragRotate:"← DRAG TO ROTATE →",
    noCardsYet:"NO CARDS YET", completeEarn:"Complete challenges to earn card packs",
    // Auth
    username:"AGENT ID / USERNAME", password:"ACCESS CODE", authenticate:"AUTHENTICATE",
    createAccount:"CREATE ACCOUNT →", forgotCode:"FORGOT CODE?",
    enterCallsign:"enter callsign",
    googleSignIn:"Sign in with Google", googleSignUp:"Sign up with Google",
    authRequired:"AUTHENTICATION REQUIRED", newAgentReg:"NEW AGENT REGISTRATION",
    allFieldsRequired:"ALL FIELDS REQUIRED",
    invalidCredentials:"INVALID CREDENTIALS — ACCESS DENIED",
    codesDoNotMatch:"CODES DO NOT MATCH",
    codeMin6:"CODE MIN 6 CHARACTERS",
    usernameMin3:"USERNAME MIN 3 CHARACTERS",
    confirmCode:"CONFIRM CODE", repeatCode:"repeat code",
    passwordPlaceholder:"min 6 characters",
    selectAvatar:"SELECT AVATAR",
    enlistNow:"ENLIST NOW", enlisting:"ENLISTING...",
    backToLogin:"← BACK TO LOGIN",
    emailConfirm:(email)=>`Confirmation email sent to ${email}. Confirm it and log back in.`,
    // How to play
    howToPlay:"HOW TO PLAY",
    leaderboardTitle:"RANKING",
    howToPlayBtn:"HELP",
  },
  pt: {
    // Nav
    myCards:"MINHAS CARTAS", ranking:"RANKING", dailyReward:"RECOMPENSA DIÁRIA",
    claimNow:"RESGATAR", claimed:"✓ RESGATADO", nextClaim:"próximo em",
    // Lobby
    activeArenas:"ARENAS ATIVAS", available:"DISPONÍVEL", tapToEnter:"ENTRAR →",
    operations:"OPERAÇÕES", entry:"ENTRADA", rewardMax:"RECOMPENSA (MÁX)", xp:"XP",
    joinOp:"ENTRAR", viewResult:"VER RESULTADO", closed:"FECHADO", noCoins:"SEM MOEDAS",
    // Challenge
    lockIn:"CONFIRMAR", picks:"PICKS", tapToChange:"TOQUE PARA ALTERAR",
    // Result
    betterLuck:"Mais sorte da próxima vez!", congrats:"Parabéns, confira seu prêmio!",
    dareToPick:"Tem coragem de escolher?", goodLuck:"Boa sorte, vai precisar!",
    // Cards
    saveCollection:"✦ SALVAR NA COLEÇÃO", dragRotate:"← ARRASTE PARA GIRAR →",
    noCardsYet:"SEM CARTAS AINDA", completeEarn:"Complete desafios para ganhar card packs",
    // Auth
    username:"NOME DE USUÁRIO", password:"SENHA", authenticate:"ENTRAR",
    createAccount:"CRIAR CONTA →", forgotCode:"ESQUECI A SENHA",
    enterCallsign:"seu nome de usuário",
    googleSignIn:"Entrar com Google", googleSignUp:"Registrar com Google",
    authRequired:"AUTENTICAÇÃO NECESSÁRIA", newAgentReg:"NOVO REGISTRO DE AGENTE",
    allFieldsRequired:"TODOS OS CAMPOS OBRIGATÓRIOS",
    invalidCredentials:"CREDENCIAIS INVÁLIDAS — ACESSO NEGADO",
    codesDoNotMatch:"AS SENHAS NÃO COINCIDEM",
    codeMin6:"SENHA MÍNIMO 6 CARACTERES",
    usernameMin3:"USUÁRIO MÍNIMO 3 CARACTERES",
    confirmCode:"CONFIRMAR SENHA", repeatCode:"repetir senha",
    passwordPlaceholder:"mín 6 caracteres",
    selectAvatar:"SELECIONAR AVATAR",
    enlistNow:"CADASTRAR AGORA", enlisting:"CADASTRANDO...",
    backToLogin:"← VOLTAR AO LOGIN",
    emailConfirm:(email)=>`Email de confirmação enviado para ${email}. Confirma e voltas a entrar.`,
    // How to play
    howToPlay:"COMO JOGAR",
    leaderboardTitle:"RANKING",
    howToPlayBtn:"AJUDA",
  }
};

const useLang = () => {
  const [lang, setLang] = React.useState(()=>localStorage.getItem("dfuse_lang")||"en");
  const setLanguage = (l) => { setLang(l); localStorage.setItem("dfuse_lang", l); };
  return { lang, t: LANG[lang]||LANG.en, setLanguage };
};


// ── Supabase config ─────────────────────────────────────────────
// Replace with your Supabase project URL and anon key
const SUPABASE_URL  = "https://muhicevtpfnulmcbtynd.supabase.co";
const SUPABASE_ANON = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im11aGljZXZ0cGZudWxtY2J0eW5kIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Nzg0MTQzNzYsImV4cCI6MjA5Mzk5MDM3Nn0.p1YIgh8uiRYh4X4FdR0pHFOyIFXC6PRfKXXHP79rmWE";

// Tiny Supabase client (no npm needed)
const sb = (() => {
  const h = (path, opts={}) => fetch(`${SUPABASE_URL}${path}`, {
    ...opts,
    headers: {
      "apikey": SUPABASE_ANON,
      "Authorization": `Bearer ${sb._token||SUPABASE_ANON}`,
      "Content-Type": "application/json",
      "Prefer": opts.prefer||"",
      ...(opts.headers||{})
    }
  }).then(async r => {
    const d = await r.json().catch(()=>({}));
    if(!r.ok) throw new Error(d.message||d.error||r.status);
    return d;
  });

  return {
    _token: null,
    auth: {
      signUp: ({email,password,username,redirectTo}) =>
        fetch(`${SUPABASE_URL}/auth/v1/signup?redirect_to=${encodeURIComponent(redirectTo||APP_URL)}`, {
          method:"POST", headers:{"apikey":SUPABASE_ANON,"Content-Type":"application/json"},
          body: JSON.stringify({email, password, data:{username}})
        }).then(r=>r.json()),
      signIn: ({email,password}) =>
        fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=password`, {
          method:"POST", headers:{"apikey":SUPABASE_ANON,"Content-Type":"application/json"},
          body: JSON.stringify({email, password})
        }).then(r=>r.json()),
      signOut: () =>
        fetch(`${SUPABASE_URL}/auth/v1/logout`, {
          method:"POST", headers:{"apikey":SUPABASE_ANON,"Authorization":`Bearer ${sb._token}`}
        }),
      // OAuth: redireciona para o provider (Google), Supabase trata do callback
      // e devolve ao APP_URL com #access_token=... no hash.
      signInWithOAuth: ({provider, redirectTo}) => {
        window.location.href = `${SUPABASE_URL}/auth/v1/authorize?provider=${provider}&redirect_to=${encodeURIComponent(redirectTo||APP_URL)}`;
      },
      // Busca dados do user a partir do access_token (usado pelo hash handler)
      getUser: (token) =>
        fetch(`${SUPABASE_URL}/auth/v1/user`, {
          headers:{"apikey":SUPABASE_ANON, "Authorization":`Bearer ${token}`}
        }).then(r=>r.json()),
    },
    from: (table) => ({
      select: (cols="*", opts={}) => h(`/rest/v1/${table}?select=${cols}${opts.filter?`&${opts.filter}`:""}`),
      insert: (data, opts={}) => h(`/rest/v1/${table}`, {method:"POST", prefer:"return=representation", body:JSON.stringify(data)}),
      update: (data, filter) => h(`/rest/v1/${table}?${filter}`, {method:"PATCH", prefer:"return=representation", body:JSON.stringify(data)}),
      upsert: (data) => h(`/rest/v1/${table}`, {method:"POST", prefer:"resolution=merge-duplicates,return=representation", body:JSON.stringify(data)}),
      delete: (filter) => h(`/rest/v1/${table}?${filter}`, {method:"DELETE"}),
    }),
    rpc: (fn, params={}) => h(`/rest/v1/rpc/${fn}`, {method:"POST", body:JSON.stringify(params)}),
  };
})();

// ── PandaScore API ────────────────────────────────────────────
// Worker proxies PandaScore to avoid CORS — deploy dfuse-proxy-worker.js
const WORKER_URL = "https://white-union-eba6.mucegarcia.workers.dev";

const pandaFetch = async (path) => {
  const r = await fetch(`${WORKER_URL}/panda${path}`);
  if(!r.ok) throw new Error(`PandaScore ${r.status}`);
  return await r.json();
};




const TBD_NAMES = ["tbd","tbc","tba","to be determined","to be confirmed","?","team a","team b","unknown"];
const isTBD = (name="") => TBD_NAMES.includes(name.trim().toLowerCase()) || name.trim().length === 0;

const abbrev = (name="") => {
  const words = name.trim().split(/\s+/);
  if(words.length===1) return name.slice(0,4).toUpperCase();
  return words.map(w=>w[0]).join("").slice(0,4).toUpperCase();
};

// Normalise PandaScore match to internal format
const normaliseEvent = (ev) => {
  const opps = ev.opponents||[];
  const tA = opps[0]?.opponent||{};
  const tB = opps[1]?.opponent||{};
  return {
    id:        String(ev.id),
    matchId:   String(ev.id),
    tId:       String(ev.serie_id||ev.tournament_id||""),
    teamA:     { id:String(tA.id||""), name:tA.name||"TBD", abbr:abbrev(tA.name||""), flag:"" },
    teamB:     { id:String(tB.id||""), name:tB.name||"TBD", abbr:abbrev(tB.name||""), flag:"" },
    startTime: ev.scheduled_at||ev.begin_at||new Date().toISOString(),
    format:    ev.match_type==="best_of"?`BO${ev.number_of_games||3}`:"BO3",
    tournament:{ id:String(ev.tournament_id||""), name:ev.tournament?.name||ev.league?.name||"Unknown" },
    league:    ev.league?.name||"",
    serie:     ev.serie?.full_name||ev.serie?.name||"",
    betUrl:    null,
    odds:      null,
  };
};

const FALLBACK_MATCHES = [
  {id:"m1",tId:"t1",teamA:{id:"navi",name:"Natus Vincere",abbr:"NAVI",flag:"🇺🇦"},teamB:{id:"vitality",name:"Team Vitality",abbr:"VIT",flag:"🇫🇷"},startTime:new Date(Date.now()+5*3600000).toISOString(),format:"BO3",tournament:{id:"t1",name:"BLAST Premier Series"},betUrl:null,odds:null},
  {id:"m2",tId:"t1",teamA:{id:"faze",name:"FaZe Clan",abbr:"FaZe",flag:"🌍"},teamB:{id:"g2",name:"G2 Esports",abbr:"G2",flag:"🇪🇸"},startTime:new Date(Date.now()+8*3600000).toISOString(),format:"BO3",tournament:{id:"t1",name:"BLAST Premier Series"},betUrl:null,odds:null},
  {id:"m3",tId:"t1",teamA:{id:"liquid",name:"Team Liquid",abbr:"TL",flag:"🇺🇸"},teamB:{id:"spirit",name:"Team Spirit",abbr:"SPRT",flag:"🇷🇺"},startTime:new Date(Date.now()+11*3600000).toISOString(),format:"BO3",tournament:{id:"t1",name:"BLAST Premier Series"},betUrl:null,odds:null},
];
const FALLBACK_TOURNAMENTS = [
  {id:"counter-strike-blast-premier-series",name:"BLAST Premier Series"},
  {id:"counter-strike-esl-challenger-league-europe",name:"ESL Challenger League Europe"},
];

const MARKET_TEMPLATES = [
  {id:"match_winner",   name:"Match Winner",               q:(m)=>`Who wins the series?`,                  a:(m)=>[m.teamA.name,m.teamB.name], type:"team"},
  {id:"map1_winner",    name:"Map 1 Winner",               q:(m)=>`Who wins Map 1?`,                       a:(m)=>[m.teamA.name,m.teamB.name], type:"team"},
  {id:"map2_winner",    name:"Map 2 Winner",               q:(m)=>`Who wins Map 2?`,                       a:(m)=>[m.teamA.name,m.teamB.name], type:"team"},
  {id:"total_maps",     name:"Total Maps Over/Under 2.5",  q:(m)=>`Will the series go to 3 maps?`,         a:()=>["Yes — 3 maps","No — 2 maps"],type:"yes_no"},
  {id:"map1_ot",        name:"Map 1 Overtime",             q:(m)=>`Will Map 1 go to overtime?`,            a:()=>["Yes","No"],                  type:"yes_no"},
  {id:"map1_pistol",    name:"Map 1 Pistol Round (CT)",    q:(m)=>`Who wins the CT pistol on Map 1?`,      a:(m)=>[m.teamA.name,m.teamB.name], type:"team"},
  {id:"map1_rounds_ou", name:"Map 1 Rounds O/U 26.5",      q:(m)=>`Map 1 — Over or Under 26.5 rounds?`,   a:()=>["Over 26.5","Under 26.5"],   type:"over_under"},
  {id:"first_blood",    name:"Map 1 First Blood",          q:(m)=>`Who draws first blood on Map 1?`,       a:(m)=>[m.teamA.name,m.teamB.name], type:"team"},
  {id:"map1_half1",     name:"Map 1 First Half Winner",    q:(m)=>`Who leads after first half on Map 1?`,  a:(m)=>[m.teamA.name,m.teamB.name], type:"team"},
  {id:"correct_score",  name:"Correct Score",              q:(m)=>`What will the final series score be?`,  a:()=>["2 — 0","2 — 1"],            type:"select"},
];

const buildQuestionPool = (matchesWithMarkets) => {
  const pool = [];
  for(const m of matchesWithMarkets){
    for(const mktId of (m.markets||[])){
      const tmpl = MARKET_TEMPLATES.find(t=>t.id===mktId);
      if(!tmpl) continue;
      pool.push({
        id:`${m.id}_${mktId}`,
        matchId:m.id,
        matchLabel:`${m.teamA.name} vs ${m.teamB.name}`,
        marketName:tmpl.name,
        question:tmpl.q(m),
        answers:tmpl.a(m),
        type:tmpl.type,
      });
    }
  }
  return pool;
};
const pickRandom = (pool,n=4) => [...pool].sort(()=>Math.random()-.5).slice(0,Math.min(n,pool.length));

const fmtTime = (iso) => new Date(iso).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"});

const fmtCountdown = (iso) => {
  const diff = new Date(iso)-new Date();
  if(diff<=0) return "STARTED";
  const h=Math.floor(diff/3600000), m=Math.floor((diff%3600000)/60000);
  return `${h}h ${m}m`;
};

const ADMIN_USER = {id:"admin",username:"admin",email:"admin@dfuse.gg",avatarId:"a8",coins:999999,isAdmin:true,joined:now(),lastClaim:null,xp:16000};

/* ─── ATOMS ──────────────────────────────────────────────────────── */
const Scanlines = React.memo(() => (
  <div style={{position:"fixed",inset:0,pointerEvents:"none",zIndex:9999,
    background:"repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,0,0,0.033) 2px,rgba(0,0,0,0.033) 4px)",
    animation:"flicker 9s infinite",willChange:"opacity",transform:"translateZ(0)"}}/>
));
const GridBg = React.memo(() => (
  <div style={{position:"fixed",inset:0,pointerEvents:"none",zIndex:0,
    backgroundImage:"linear-gradient(rgba(255,255,255,0.033) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,0.033) 1px,transparent 1px)",
    backgroundSize:"40px 40px",animation:"scanpulse 4s infinite",willChange:"opacity",transform:"translateZ(0)"}}/>
));
const Corner = ({pos}) => {
  const t=pos.includes("top"),l=pos.includes("left");
  return <div style={{position:"absolute",[t?"top":"bottom"]:5,[l?"left":"right"]:5,width:14,height:14,
    borderTop:t?"1.5px solid var(--cyan)":"none",borderBottom:!t?"1.5px solid var(--cyan)":"none",
    borderLeft:l?"1.5px solid var(--cyan)":"none",borderRight:!l?"1.5px solid var(--cyan)":"none"}}/>;
};

const Panel = ({children,style={}}) => (
  <div style={{background:"var(--panel)",border:"1px solid var(--border)",position:"relative",padding:"16px 14px",animation:"slideUp .3s ease",...style}}>
    <Corner pos="top-left"/><Corner pos="top-right"/><Corner pos="bottom-left"/><Corner pos="bottom-right"/>
    {children}
  </div>
);
const Btn = ({children,onClick,variant="primary",style={},disabled=false,size="md"}) => {
  const base={fontFamily:"var(--display)",fontWeight:700,letterSpacing:"0.1em",border:"none",
    cursor:disabled?"not-allowed":"pointer",opacity:disabled?.5:1,transition:"all .15s",textTransform:"uppercase",
    display:"flex",alignItems:"center",justifyContent:"center",gap:7,
    ...(size==="sm"?{padding:"5px 12px",fontSize:9}:{padding:"11px 18px",fontSize:11})};
  const V={
    primary:{background:"var(--purple)",color:"#fff",animation:"pulse-red 3s infinite"},
    secondary:{background:"transparent",color:"var(--cyan)",border:"1px solid var(--cyan)",animation:"pulse-cyan 3s infinite"},
    ghost:{background:"rgba(255,255,255,0.04)",color:"var(--text)",border:"1px solid var(--border)"},
    danger:{background:"var(--purple)",color:"#fff",border:"1px solid var(--border-purple)"},
    gold:{background:"var(--purple)",color:"#fff",animation:"pulse-red 3s infinite"},
    google:{background:"rgba(255,255,255,0.06)",color:"var(--text-bright)",border:"1px solid var(--border)",fontFamily:"var(--body)",fontWeight:600,letterSpacing:"0.06em",fontSize:13,textTransform:"uppercase"},
  };
  return <button onClick={disabled?undefined:onClick} style={{...base,...V[variant],...style}}>{children}</button>;
};
const Field = ({label,value,onChange,type="text",placeholder=""}) => (
  <div style={{marginBottom:13}}>
    {label&&<div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:5,letterSpacing:"0.15em"}}>{label}</div>}
    <input type={type} value={value} onChange={e=>onChange(e.target.value)} placeholder={placeholder}/>
  </div>
);
const CoinBadge = ({amount,size="md"}) => (
  <span style={{display:"inline-flex",alignItems:"center",gap:4,fontFamily:"var(--mono)",
    fontSize:size==="sm"?11:14,color:"var(--text-bright)",background:"rgba(255,255,255,0.05)",
    border:"1px solid rgba(255,255,255,0.14)",padding:size==="sm"?"2px 7px":"4px 10px",borderRadius:2}}>
    ◈ {typeof amount==="number"?amount.toLocaleString():amount}
  </span>
);
const DiffBadge = ({diff}) => {
  const m={EASY:["#6a7a8a","#080808"],MED:["#ffffff","#060606"],HARD:["#8844cc","#0a0404"],EXPERT:["#ffffff","#1a1a1a"]};
  const [fg,bg]=m[diff]||["#888","#111"];
  return <span style={{fontFamily:"var(--mono)",fontSize:9,color:fg,background:bg,border:`1px solid ${fg}`,padding:"2px 7px",letterSpacing:"0.1em"}}>{diff}</span>;
};

const XPFloater = ({amount,onDone}) => {
  useEffect(()=>{const t=setTimeout(onDone,950);return()=>clearTimeout(t);},[]);
  return (
    <div style={{position:"fixed",top:"50%",left:"50%",pointerEvents:"none",zIndex:99999,
      fontFamily:"var(--display)",fontWeight:900,fontSize:24,color:"var(--cyan)",
      textShadow:"0 0 24px var(--cyan-glow)",animation:"xp-pop .95s ease forwards",whiteSpace:"nowrap"}}>
      +{amount} XP
    </div>
  );
};

const RankBar = ({xp}) => {
  const rank=getRank(xp); const next=getNextRank(xp); const pct=getXPProgress(xp);
  return (
    <div>
      <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:6}}>
        <span style={{fontFamily:"var(--display)",fontSize:11,fontWeight:700,color:rank.color,letterSpacing:"0.1em"}}>
          {rank.icon} {rank.name}
        </span>
        <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)"}}>
          {xp.toLocaleString()} XP{next?` / ${next.min.toLocaleString()}`:" · MAX"}
        </span>
      </div>
      <div style={{height:3,background:"rgba(255,255,255,0.06)",overflow:"hidden"}}>
        <div style={{height:"100%",width:`${pct}%`,background:`linear-gradient(90deg,var(--cyan),${rank.color})`,transition:"width 1s ease"}}/>
      </div>
    </div>
  );
};

const Toast = ({msg,type="info",onDone}) => {
  useEffect(()=>{const t=setTimeout(onDone,2800);return()=>clearTimeout(t);},[]);
  const c={info:"var(--cyan)",success:"var(--cyan)",error:"var(--purple)",warn:"var(--text)"};
  return (
    <div style={{position:"fixed",top:16,left:"50%",transform:"translateX(-50%)",zIndex:99998,
      maxWidth:320,width:"90vw",background:"var(--bg3)",border:`1px solid ${c[type]}`,
      padding:"10px 16px",fontFamily:"var(--mono)",fontSize:12,color:c[type],
      animation:"slideUp .25s ease",boxShadow:`0 0 20px ${c[type]}44`,display:"flex",alignItems:"center",gap:10}}>
      <span>{type==="success"?"✓":type==="error"?"✗":type==="warn"?"⚠":"ℹ"}</span>{msg}
    </div>
  );
};

const TopBar = ({user,onProfile,onAdmin,avatars,onMyCards,myCardsCount=0,onHowTo,lang,setLanguage}) => {
  const rank=getRank(user.xp||0);
  const av=avatars.find(a=>a.id===user.avatarId);
  return (
    <div style={{position:"fixed",top:0,left:0,right:0,zIndex:100,maxWidth:480,margin:"0 auto",
      background:"rgba(0,0,0,0.96)",borderBottom:"1px solid var(--border)",
      display:"flex",alignItems:"center",justifyContent:"space-between",
      padding:"7px 12px",backdropFilter:"blur(10px)",height:50}}>
      <img src={LOGO_SRC} alt="DFUSE" style={{height:28,display:"block",flexShrink:0}}/>
      <div style={{display:"flex",alignItems:"center",gap:8,minWidth:0}}>
        <CoinBadge amount={user.coins} size="sm"/>
        {user.isAdmin&&(
          <button onClick={onAdmin} style={{background:"none",border:"none",cursor:"pointer",
            color:"var(--text-dim)",fontSize:15,padding:2,flexShrink:0,lineHeight:1}}>⚙</button>
        )}
        <div style={{display:"flex",alignItems:"center",gap:5,flexShrink:0}}>
          {/* Lang toggle button */}
          <button onClick={()=>setLanguage(lang==="en"?"pt":"en")} style={{
            background:"rgba(255,255,255,0.06)",border:"1px solid var(--border)",
            cursor:"pointer",width:26,height:26,fontSize:14,color:"var(--text-bright)",
            display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0,padding:0}}>
            {lang==="en"?"🇬🇧":"🇧🇷"}
          </button>
          {/* How to play */}
          <button onClick={onHowTo} style={{
            background:"rgba(255,255,255,0.06)",border:"1px solid var(--border)",
            cursor:"pointer",color:"var(--text-bright)",fontFamily:"var(--display)",
            fontSize:12,fontWeight:700,width:26,height:26,
            display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}>?</button>
          {/* Profile button */}
          <button onClick={onProfile} style={{
            display:"flex",alignItems:"center",gap:6,
            background:"rgba(255,255,255,0.06)",border:"1px solid var(--border)",
            cursor:"pointer",padding:"3px 7px 3px 4px",flexShrink:0,
          }}>
            <div style={{width:26,height:26,flexShrink:0,
              background:"var(--cyan-dim)",border:"1px solid var(--border)",
              display:"flex",alignItems:"center",justifyContent:"center",fontSize:14}}>
              {av?.src ? <img src={av.src} style={{width:"100%",height:"100%",objectFit:"cover"}}/> : "👤"}
            </div>
            <div style={{textAlign:"left",minWidth:0}}>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-bright)",
                overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:70}}>
                {user.username.toUpperCase()}
              </div>
              <div style={{fontFamily:"var(--mono)",fontSize:7,color:rank.color,whiteSpace:"nowrap"}}>
                {rank.icon} {rank.name}
              </div>
            </div>
          </button>
        </div>
      </div>
    </div>
  );
};

/* ─── AUTH ───────────────────────────────────────────────────────── */
const AuthHeader = ({lang,setLanguage}) => (
  <div style={{textAlign:"center",marginBottom:26}}>
    {setLanguage&&<div style={{position:"absolute",top:16,right:16}}>
      <button onClick={()=>setLanguage(lang==="en"?"pt":"en")}
        style={{background:"rgba(255,255,255,0.07)",border:"1px solid var(--border)",borderRadius:4,
          padding:"4px 10px",cursor:"pointer",fontFamily:"var(--mono)",fontSize:11,color:"var(--text-dim)"}}>
        {lang==="en"?"🇬🇧 EN":"🇧🇷 PT"}
      </button>
    </div>}
    <img src={LOGO_SRC} alt="DFUSE"
      style={{width:240,display:"block",margin:"0 auto"}}/>
    <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",letterSpacing:"0.3em",marginTop:10}}>DARE TO PICK!</div>
    <div style={{height:1,background:"linear-gradient(90deg,transparent,var(--cyan),transparent)",marginTop:10}}/>
  </div>
);

const GoogleBtn = ({label,onToast}) => (
  <Btn variant="google" onClick={()=>{
    try { sb.auth.signInWithOAuth({provider:"google", redirectTo:APP_URL}); }
    catch(e) { onToast(e.message||"Google sign-in failed","error"); }
  }}
    style={{width:"100%",marginBottom:14,borderRadius:2,gap:10,letterSpacing:"0.01em",fontSize:14}}>
    <svg width="16" height="16" viewBox="0 0 48 48">
      <path fill="rgba(136,68,204,0.9)" d="M24 9.5c3.2 0 5.9 1.1 8.1 2.9l6-6C34.5 3.1 29.6 1 24 1 14.9 1 7.1 6.7 3.8 14.6l7 5.4C12.5 13.7 17.8 9.5 24 9.5z"/>
      <path fill="var(--cyan)" d="M46.5 24.5c0-1.6-.1-3.1-.4-4.5H24v8.5h12.7c-.6 3-2.3 5.5-4.8 7.2l7.4 5.7c4.3-4 6.9-9.9 7.2-16.9z"/>
      <path fill="rgba(136,68,204,0.65)" d="M10.8 28.6A14.6 14.6 0 0 1 9.5 24c0-1.6.3-3.2.8-4.6l-7-5.4A23.9 23.9 0 0 0 0 24c0 3.9.9 7.5 2.5 10.8l8.3-6.2z"/>
      <path fill="rgba(136,68,204,0.75)" d="M24 47c5.6 0 10.3-1.8 13.7-4.9l-7.4-5.7c-1.9 1.3-4.3 2.1-6.9 2.1-6.2 0-11.5-4.2-13.2-9.9l-8.3 6.2C7.1 41.3 14.9 47 24 47z"/>
    </svg>
    {label}
  </Btn>
);
const Divider = () => (
  <div style={{display:"flex",alignItems:"center",gap:10,marginBottom:14}}>
    <div style={{flex:1,height:1,background:"var(--border)"}}/>
    <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)"}}>OR</span>
    <div style={{flex:1,height:1,background:"var(--border)"}}/>
  </div>
);

const LoginScreen = ({users,onLogin,onGo,onToast,lang="en",setLanguage}) => {
  const [u,setU]=useState(""); const [p,setP]=useState(""); const [err,setErr]=useState(""); const [loading,setLoading]=useState(false);
  const t = LANG[lang]||LANG.en;
  const submit=async()=>{
    if(!u||!p) return setErr(t.allFieldsRequired);
    setLoading(true); setErr("");

    // ── Local fallback (no Supabase configured) ───────────────
    if(SUPABASE_URL.includes("YOUR_PROJECT")) {
      const found = users.find(x=>x.username.toLowerCase()===u.toLowerCase()&&x.password===p);
      setLoading(false);
      if(found) onLogin(found, null);
      else setErr(t.invalidCredentials);
      return;
    }

    // ── Supabase auth ─────────────────────────────────────────
    try {
      // Try login with username — attempt both email domains
      let res = null;
      const attempts = u.includes("@")
        ? [u]
        : [`${u.toLowerCase()}@dfuse.gg`, `${u.toLowerCase()}@dfuse.app`];
      for(const email of attempts){
        res = await sb.auth.signIn({email, password:p});
        if(res.access_token) break;
      }
      if(res.error||!res.access_token) {
        setErr(t.invalidCredentials);
      } else {
        sb._token = res.access_token;
        const profile = await sb.from("profiles").select("*", {filter:`id=eq.${res.user.id}`}).then(d=>d[0]);
        onLogin({...profile, id:profile.id, isAdmin:profile.is_admin, avatarId:profile.avatar_id, lastClaim:profile.last_claim}, res.access_token);
      }
    } catch(e) { setErr(e.message||"Login failed"); }
    finally { setLoading(false); }
  };
  return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",justifyContent:"center",padding:"20px 18px",position:"relative",zIndex:1}}>
      <AuthHeader lang={lang} setLanguage={setLanguage}/>
      <Panel>
        <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",marginBottom:14,letterSpacing:"0.2em"}}>▶ {t.authRequired}</div>
        <GoogleBtn label={t.googleSignIn} onToast={onToast}/>
        <Divider/>
        {err&&<div style={{fontFamily:"var(--mono)",fontSize:11,color:"var(--purple)",marginBottom:12,padding:"8px 10px",border:"1px solid var(--border-purple)",background:"rgba(136,68,204,0.07)"}}>{err}</div>}
        <Field label={t.username} value={u} onChange={setU} placeholder={t.enterCallsign}/>
        <Field label={t.password} value={p} onChange={setP} type="password" placeholder="••••••••"/>
        <Btn onClick={submit} disabled={loading} style={{width:"100%",marginTop:4}}>{loading?"...":t.authenticate}</Btn>
        <div style={{display:"flex",justifyContent:"space-between",marginTop:14}}>
          <button onClick={()=>onGo("recovery")} style={{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--mono)",fontSize:10,color:"var(--text-dim)"}}>{t.forgotCode}</button>
          <button onClick={()=>onGo("signup")} style={{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--mono)",fontSize:10,color:"var(--cyan)"}}>{t.createAccount}</button>
        </div>
      </Panel>

    </div>
  );
};

const SignupScreen = ({onSignup,onGo,onToast,avatars,lang="en",setLanguage}) => {
  const [u,setU]=useState(""); const [p,setP]=useState(""); const [p2,setP2]=useState("");
  const [email,setEmail]=useState(""); const [avatar,setAvatar]=useState("a1"); const [err,setErr]=useState("");
  const [loading,setLoading]=useState(false);
  const t = LANG[lang]||LANG.en;
  const submit=async()=>{
    if(!u||!p||!email)return setErr(t.allFieldsRequired);
    if(p!==p2)return setErr(t.codesDoNotMatch);
    if(p.length<6)return setErr(t.codeMin6);
    if(u.length<3)return setErr(t.usernameMin3);
    setLoading(true); setErr("");

    // ── Local fallback ────────────────────────────────────────
    if(SUPABASE_URL.includes("YOUR_PROJECT")) {
      setLoading(false);
      onSignup({id:uid(),username:u.toLowerCase(),password:p,email,avatarId:avatar,coins:0,isAdmin:false,joined:now(),lastClaim:null,xp:0}, null);
      return;
    }

    // ── Supabase ──────────────────────────────────────────────
    try {
      const res = await sb.auth.signUp({email: email.toLowerCase(), password:p, username: u.toLowerCase(), redirectTo: APP_URL});
      if(res.error || res.code) { setErr(res.error?.message||res.msg||res.message||"Sign up failed"); return; }
      if(!res.access_token) {
        // Email confirmation required — vai voltar via hash callback
        onToast(t.emailConfirm(email), "success");
        onGo("login");
        return;
      }
      sb._token = res.access_token;
      await sb.from("profiles").update({avatar_id: avatar}, `id=eq.${res.user.id}`);
      const profile = await sb.from("profiles").select("*", {filter:`id=eq.${res.user.id}`}).then(d=>d[0]);
      onSignup({...profile, id:profile.id, isAdmin:false, avatarId:avatar, lastClaim:null}, res.access_token);
    } catch(e) { setErr(e.message||"Sign up failed"); }
    finally { setLoading(false); }
  };
  return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",justifyContent:"center",padding:"30px 18px",position:"relative",zIndex:1}}>
      <AuthHeader lang={lang} setLanguage={setLanguage}/>
      <Panel>
        <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",marginBottom:14,letterSpacing:"0.2em"}}>▶ {t.newAgentReg}</div>
        <GoogleBtn label={t.googleSignUp} onToast={onToast}/>
        <Divider/>
        {err&&<div style={{fontFamily:"var(--mono)",fontSize:11,color:"var(--purple)",marginBottom:12,padding:"8px 10px",border:"1px solid var(--border-purple)",background:"rgba(136,68,204,0.07)"}}>{err}</div>}
        <Field label={t.username} value={u} onChange={setU} placeholder={t.enterCallsign}/>
        <Field label="EMAIL" value={email} onChange={setEmail} type="email" placeholder="secure@email.com"/>
        <Field label={t.password} value={p} onChange={setP} type="password" placeholder={t.passwordPlaceholder}/>
        <Field label={t.confirmCode} value={p2} onChange={setP2} type="password" placeholder={t.repeatCode}/>
        <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:8,letterSpacing:"0.15em"}}>{t.selectAvatar}</div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:7,marginBottom:16}}>
          {avatars.map(a=>(
            <button key={a.id} onClick={()=>setAvatar(a.id)} style={{
              background:avatar===a.id?"rgba(255,255,255,0.14)":"rgba(0,0,0,0.38)",
              border:`1px solid ${avatar===a.id?"var(--cyan)":"var(--border)"}`,
              borderRadius:2,padding:"8px 4px",cursor:"pointer",
              display:"flex",flexDirection:"column",alignItems:"center",gap:2,
              boxShadow:avatar===a.id?"0 0 10px var(--cyan-glow)":"none"}}>
              <span style={{fontSize:22}}>{a.src?<img src={a.src} style={{width:"100%",height:"100%",objectFit:"cover"}}/>:""}</span>
              <span style={{fontFamily:"var(--mono)",fontSize:7,color:avatar===a.id?"var(--cyan)":"var(--text-dim)"}}>{a.label}</span>
            </button>
          ))}
        </div>
        <Btn onClick={submit} disabled={loading} style={{width:"100%"}}>{loading?t.enlisting:t.enlistNow}</Btn>
        <div style={{textAlign:"center",marginTop:12}}>
          <button onClick={()=>onGo("login")} style={{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--mono)",fontSize:10,color:"var(--text-dim)"}}>{t.backToLogin}</button>
        </div>
      </Panel>
    </div>
  );
};

const RecoveryScreen = ({onGo,onToast}) => {
  const [email,setEmail]=useState(""); const [sent,setSent]=useState(false);
  return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",justifyContent:"center",padding:"20px 18px",position:"relative",zIndex:1}}>
      <AuthHeader/>
      <Panel>
        <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",marginBottom:14,letterSpacing:"0.2em"}}>▶ ACCESS CODE RECOVERY</div>
        {!sent?(<>
          <div style={{fontFamily:"var(--body)",fontSize:13,color:"var(--text-dim)",marginBottom:16}}>Enter your registered email. Recovery protocol will be dispatched.</div>
          <Field label="REGISTERED EMAIL" value={email} onChange={setEmail} type="email" placeholder="your@email.com"/>
          <Btn onClick={()=>{setSent(true);onToast("Recovery protocol initiated","info");}} style={{width:"100%"}}>SEND RECOVERY</Btn>
        </>):(
          <div style={{fontFamily:"var(--mono)",fontSize:12,color:"var(--cyan)",textAlign:"center",padding:"20px 0"}}>
            ✓ RECOVERY INITIATED<br/><span style={{color:"var(--text-dim)",fontSize:10,display:"block",marginTop:8}}>CHECK YOUR SECURE CHANNEL</span>
          </div>
        )}
        <div style={{textAlign:"center",marginTop:14}}>
          <button onClick={()=>onGo("login")} style={{background:"none",border:"none",cursor:"pointer",fontFamily:"var(--mono)",fontSize:10,color:"var(--text-dim)"}}>← BACK TO LOGIN</button>
        </div>
      </Panel>
    </div>
  );
};

/* ─── LOBBY ──────────────────────────────────────────────────────── */
const ArenaCard = ({arena,challenges,idx,onEnter}) => {
  const count=challenges.filter(c=>c.arenaId===arena.id&&c.active).length;
  const img=arena.imageUrl||ARENA_IMAGES[arena.id]||FALLBACK_IMG;
  return (
    <div onClick={()=>onEnter(arena)} style={{
      position:"relative",height:172,overflow:"hidden",cursor:"pointer",
      border:`1px solid ${arena.color}44`,animation:`slideUp ${0.28+idx*0.1}s ease`,
    }}>
      <img src={img} alt={arena.name} style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",filter:"brightness(0.35) saturate(1.3)"}}/>
      <div style={{position:"absolute",inset:0,background:`linear-gradient(140deg,${arena.color}26 0%,transparent 55%,rgba(0,0,0,0.65) 100%)`}}/>
      <div style={{position:"absolute",inset:0,background:"linear-gradient(to bottom,transparent 50%,rgba(0,0,0,0.55) 100%)"}}/>
      <div style={{position:"absolute",top:0,left:0,right:0,height:1,background:`linear-gradient(90deg,transparent,${arena.color},transparent)`}}/>
      <div style={{position:"absolute",bottom:0,left:0,right:0,height:1,background:`linear-gradient(90deg,transparent,${arena.color}66,transparent)`}}/>
      {["top-left","top-right","bottom-left","bottom-right"].map(p=><Corner key={p} pos={p}/>)}
      <div style={{position:"absolute",inset:0,padding:"14px 16px",display:"flex",flexDirection:"column",justifyContent:"space-between"}}>
        <div>
          
          <div style={{fontFamily:"var(--display)",fontSize:20,fontWeight:900,color:"#fff",letterSpacing:"0.05em",textShadow:`0 0 18px ${arena.color}99`}}>{arena.name}</div>
        </div>
        <div>
          <div style={{fontFamily:"var(--body)",fontSize:12,color:"rgba(255,255,255,0.6)",marginBottom:10}}>{arena.desc}</div>
          <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:arena.color,border:`1px solid ${arena.color}55`,padding:"3px 9px"}}>
              {count} OPERATION{count!==1?"S":""}
            </div>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"rgba(255,255,255,0.85)"}}>TAP TO ENTER →</div>
          </div>
        </div>
      </div>
    </div>
  );
};

const LobbyScreen = ({user,arenas,challenges,onEnterArena,onProfile,onAdmin,onClaim,dailyDrop,avatars,onMyCards,myCardsCount=0,onShowRanks,onLeaderboard,onHowTo,lang,setLanguage}) => {
  const t = LANG[lang]||LANG.en;
  const today=new Date().toDateString();
  const canClaim=!user.lastClaim||new Date(user.lastClaim).toDateString()!==today;
  const activeArenas=arenas.filter(a=>a.active);
  return (
    <div style={{minHeight:"100dvh",position:"relative",zIndex:1}}>
      <TopBar user={user} onProfile={onProfile} onAdmin={user.isAdmin?onAdmin:null} avatars={avatars} onMyCards={onMyCards} myCardsCount={myCardsCount} onHowTo={onHowTo} lang={lang} setLanguage={setLanguage}/>
      <div style={{paddingTop:58,padding:"58px 14px 24px"}}>
        {/* XP + MY CARDS row */}
        <div style={{display:"flex",alignItems:"stretch",gap:8,marginBottom:14}}>
          {/* XP section — full width left side */}
          <div onClick={onShowRanks} style={{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",gap:4,padding:"6px 10px",
            background:"rgba(255,255,255,0.03)",border:"1px solid var(--border)",minWidth:0,cursor:"pointer"}}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
              {(()=>{const r=getRank(user.xp||0),nxt=getNextRank(user.xp||0);return(<>
                <span style={{fontFamily:"var(--display)",fontSize:11,fontWeight:700,color:r.color,letterSpacing:"0.08em",whiteSpace:"nowrap"}}>{r.icon} {r.name}</span>
                <span style={{fontFamily:"var(--mono)",fontSize:8,color:"#ffffff",whiteSpace:"nowrap"}}>{(user.xp||0).toLocaleString()} XP{nxt?` — ${nxt.min.toLocaleString()}`:" · MAX"}</span>
              </>);})()}
            </div>
            <div style={{height:3,background:"rgba(255,255,255,0.07)",borderRadius:2,overflow:"hidden"}}>
              <div style={{height:"100%",width:`${getXPProgress(user.xp||0)}%`,
                background:`linear-gradient(90deg,var(--cyan),${getRank(user.xp||0).color})`,
                transition:"width 1s ease"}}/>
            </div>
          </div>
          {/* MY CARDS — tall button on right */}
          <div style={{display:"flex",flexDirection:"column",gap:4,flexShrink:0}}>
            <button onClick={onMyCards} style={{
              display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:1,
              background:"rgba(136,68,204,0.18)",border:"1px solid rgba(136,68,204,0.5)",
              cursor:"pointer",padding:"4px 10px",
              fontFamily:"var(--mono)",fontWeight:700,letterSpacing:"0.08em",color:"var(--purple)"}}>
              <span style={{fontSize:9,whiteSpace:"nowrap"}}>{t.myCards}</span>
              {myCardsCount>0
                ? <span style={{background:"var(--purple)",color:"#fff",borderRadius:10,
                    padding:"0 5px",fontSize:9,fontWeight:900}}>{myCardsCount}</span>
                : <span style={{fontSize:8,opacity:0.3}}>—</span>}
            </button>
            <button onClick={onLeaderboard} style={{
              display:"flex",alignItems:"center",justifyContent:"center",
              background:"rgba(123,200,67,0.12)",border:"1px solid rgba(123,200,67,0.4)",
              cursor:"pointer",padding:"4px 10px",
              fontFamily:"var(--mono)",fontSize:9,fontWeight:700,
              letterSpacing:"0.06em",color:"var(--cyan)",whiteSpace:"nowrap"}}>
              {t.ranking}
            </button>
          </div>
        </div>
        {dailyDrop>0&&(
          <Panel style={{marginBottom:14}}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
              <div>
                <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.15em"}}>{t.dailyReward}</div>
                <div style={{display:"flex",alignItems:"center",gap:10,marginTop:4}}>
                  <CoinBadge amount={dailyDrop}/>
                  <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)"}}>+{XP_CLAIM} XP</span>
                </div>
                {!canClaim&&user.lastClaim&&(()=>{
                  const [tick,setTick]=React.useState(0);
                  React.useEffect(()=>{const t=setInterval(()=>setTick(n=>n+1),1000);return()=>clearInterval(t);},[]);
                  const next=new Date(user.lastClaim);
                  next.setDate(next.getDate()+1);
                  next.setHours(0,0,0,0);
                  const diff=Math.max(0,next-new Date());
                  const h=Math.floor(diff/3600000);
                  const m=Math.floor((diff%3600000)/60000);
                  const s=Math.floor((diff%60000)/1000);
                  const pad=n=>String(n).padStart(2,"0");
                  return(
                    <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.35)",marginTop:4,letterSpacing:"0.08em"}}>
                      {t.nextClaim} <span style={{color:"var(--purple)",fontWeight:700}}>{pad(h)}:{pad(m)}:{pad(s)}</span>
                    </div>
                  );
                })()}
              </div>
              <Btn onClick={canClaim?onClaim:null} disabled={!canClaim} variant={canClaim?"gold":"ghost"} size="sm">
                {canClaim?t.claimNow:t.claimed}
              </Btn>
            </div>
          </Panel>
        )}
        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.22em",marginBottom:10}}>
          ▶ {t.activeArenas} — {activeArenas.length} {t.available}
        </div>
        <div style={{display:"flex",flexDirection:"column",gap:10}}>
          {activeArenas.map((arena,i)=>(
            <ArenaCard key={arena.id} arena={arena} challenges={challenges} idx={i} onEnter={onEnterArena}/>
          ))}
        </div>
      </div>
    </div>
  );
};

/* ─── ARENA ──────────────────────────────────────────────────────── */
const ArenaScreen = ({arena,challenges,user,onBack,onJoin,onViewResult,entries=[],lang="en"}) => {
  const t = LANG[lang]||LANG.en;
  const ops=challenges.filter(c=>c.arenaId===arena.id&&c.active);
  const img=arena.imageUrl||ARENA_IMAGES[arena.id]||FALLBACK_IMG;
  return (
    <div style={{minHeight:"100dvh",position:"relative",zIndex:1}}>
      <div style={{position:"relative",height:210,overflow:"hidden"}}>
        <img src={img} alt={arena.name} style={{width:"100%",height:"100%",objectFit:"cover",filter:"brightness(0.3) saturate(1.3)"}}/>
        <div style={{position:"absolute",inset:0,background:`linear-gradient(160deg,${arena.color}26 0%,transparent 50%,rgba(0,0,0,0.92) 100%)`}}/>
        <div style={{position:"absolute",bottom:0,left:0,right:0,height:70,background:"linear-gradient(to bottom,transparent,var(--bg))"}}/>
        <div style={{position:"absolute",top:0,left:0,right:0,height:1,background:`linear-gradient(90deg,transparent,${arena.color},transparent)`}}/>
        <button onClick={onBack} style={{position:"absolute",top:14,left:14,background:"rgba(0,0,0,0.65)",
          border:"1px solid var(--border)",color:"var(--text)",cursor:"pointer",
          width:36,height:36,fontSize:18,display:"flex",alignItems:"center",justifyContent:"center",borderRadius:2}}>←</button>
        <div style={{position:"absolute",top:14,right:14}}><CoinBadge amount={user.coins} size="sm"/></div>
        <div style={{position:"absolute",bottom:22,left:16,right:16}}>
          
          <div style={{fontFamily:"var(--display)",fontSize:24,fontWeight:900,color:"#fff",textShadow:`0 0 22px ${arena.color}77`,lineHeight:1}}>{arena.name}</div>
          <div style={{fontFamily:"var(--body)",fontSize:12,color:"rgba(255,255,255,0.5)",marginTop:3}}>{arena.desc}</div>
        </div>
      </div>
      <div style={{padding:"14px 14px"}}>
        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.22em",marginBottom:12}}>
          ▶ {t.available} {t.operations} — {ops.length}
          {(()=>{const hasNew=ops.some(ch=>!entries.find(e=>e.userId===user.id&&e.challengeId===ch.id)&&!(ch.entryDeadline&&new Date(ch.entryDeadline)<new Date()));
            return hasNew?<span style={{display:"inline-block",width:7,height:7,borderRadius:"50%",
              background:"#22c55e",marginLeft:6,verticalAlign:"middle",
              animation:"pulse-green 1.2s ease-in-out infinite",boxShadow:"0 0 6px #22c55e"}}/>:null;
          })()}
        </div>
        {ops.length===0&&(
          <div style={{textAlign:"center",padding:"50px 20px",display:"flex",flexDirection:"column",alignItems:"center",gap:16}}>
            <div style={{fontFamily:"var(--mono)",fontSize:12,color:"var(--text-dim)"}}>NO ACTIVE OPERATIONS</div>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"rgba(255,255,255,0.25)"}}>CHECK BACK LATER</div>
            <Btn onClick={onBack} variant="ghost" style={{marginTop:8}}>← BACK TO ARENAS</Btn>
          </div>
        )}
        <div style={{display:"flex",flexDirection:"column",gap:10}}>
          {ops.map((ch,i)=>{
            const entry=entries.find(e=>e.userId===user.id&&e.challengeId===ch.id);
            const pastDeadline=ch.entryDeadline&&new Date(ch.entryDeadline)<new Date();
            const canEnter=!entry&&!pastDeadline&&user.coins>=ch.cost;
            const mCount=(ch.matches||[]).length;
            return (
              <Panel key={ch.id} style={{animation:`slideUp ${0.18+i*0.08}s ease`}}>
                <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:8}}>
                  <div style={{flex:1,marginRight:10}}>
                    <div style={{fontFamily:"var(--display)",fontSize:12,fontWeight:700,color:"var(--text-bright)",marginBottom:3}}>{ch.name}</div>
                    <div style={{fontFamily:"var(--body)",fontSize:12,color:"var(--text-dim)",marginBottom:4}}>{ch.desc}</div>
                    {mCount>0&&(
                      <div style={{display:"flex",gap:6,flexWrap:"wrap",marginBottom:4}}>
                        {(ch.matches||[]).map(m=>(
                          <span key={m.id} style={{fontFamily:"var(--mono)",fontSize:8,
                            color:"var(--text-dim)",border:"1px solid var(--border)",padding:"1px 6px"}}>
                            {m.teamA.abbr} vs {m.teamB.abbr}
                          </span>
                        ))}
                      </div>
                    )}
                    {ch.entryDeadline&&(
                      <div style={{fontFamily:"var(--mono)",fontSize:8,
                        color:"var(--purple)",
                        animation:pastDeadline?undefined:"pulse-purple 1.5s ease-in-out infinite"}}>
                        {pastDeadline?"⛔ ENTRY CLOSED":"⏱ CLOSES: "}{!pastDeadline&&fmtCountdown(ch.entryDeadline)}
                      </div>
                    )}
                  </div>

                </div>
                <div style={{height:1,background:"var(--border)",margin:"10px 0"}}/>
                <div style={{display:"flex",alignItems:"center",justifyContent:"space-between"}}>
                  <div style={{display:"flex",gap:12,alignItems:"center"}}>
                    <div>
                      <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.75)",marginBottom:3}}>{t.entry}</div>
                      <CoinBadge amount={ch.cost} size="sm"/>
                    </div>
                    <div>
                      <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.75)",marginBottom:3}}>{t.rewardMax}</div>
                      <CoinBadge amount={Math.round(ch.cost*2.5)} size="sm"/>
                    </div>
                    <div>
                      <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.75)",marginBottom:3}}>XP</div>
                      <span style={{fontFamily:"var(--mono)",fontSize:11,color:"var(--cyan)"}}>+{XP_DIFF["MED"]}</span>
                    </div>
                  </div>
                  {entry ? (
                    entry.locked && ch.correctAnswers && !entry.collected ? (
                      <Btn onClick={()=>onViewResult&&onViewResult(ch)} variant="secondary" size="sm">
                        {t.viewResult}
                      </Btn>
                    ) : entry.collected ? (
                      <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",padding:"3px 8px",border:"1px solid var(--border)"}}>DONE ✓</span>
                    ) : (
                      <Btn onClick={()=>onJoin(ch)} variant="ghost" size="sm">
                        {entry.locked?"🔒 VIEW":"CONTINUE"}
                      </Btn>
                    )
                  ) : (
                    <Btn onClick={()=>canEnter&&onJoin(ch)}
                      disabled={!canEnter}
                      variant="primary" size="sm">
                      {pastDeadline?t.closed:user.coins<ch.cost?t.noCoins:t.joinOp}
                    </Btn>
                  )}
                </div>
              </Panel>
            );
          })}
        </div>
      </div>
    </div>
  );
};

/* ─── PROFILE ────────────────────────────────────────────────────── */
const ProfileScreen = ({user,onBack,onUpdate,onLogout,avatars}) => {
  const [avatar,setAvatar]=useState(user.avatarId);
  const rank=getRank(user.xp||0);
  return (
    <div style={{minHeight:"100dvh",position:"relative",zIndex:1}}>
      <div style={{position:"sticky",top:0,zIndex:100,background:"rgba(0,0,0,0.96)",borderBottom:"1px solid var(--border)",
        display:"flex",alignItems:"center",gap:12,padding:"10px 14px",backdropFilter:"blur(8px)"}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700}}>AGENT PROFILE</div>
      </div>
      <div style={{padding:"16px 14px"}}>
        <div style={{textAlign:"center",marginBottom:18,animation:"slideUp .3s ease"}}>
          <div style={{width:90,height:90,margin:"0 auto 10px",background:"var(--cyan-dim)",border:"2px solid var(--cyan)",
            display:"flex",alignItems:"center",justifyContent:"center",fontSize:44,boxShadow:"0 0 22px var(--cyan-glow)"}}>
            {(()=>{const av2=avatars.find(a=>a.id===user.avatarId);return av2?.src?<img src={av2.src} style={{width:"100%",height:"100%",objectFit:"cover",borderRadius:1}}/>:"👤";})()}
          </div>
          <div style={{fontFamily:"var(--display)",fontSize:18,fontWeight:700,color:"var(--text-bright)"}}>{user.username.toUpperCase()}</div>
          <div style={{fontFamily:"var(--mono)",fontSize:10,color:rank.color,marginTop:3}}>
            {rank.icon} {rank.name}{user.isAdmin&&<span style={{color:"var(--purple)",marginLeft:8}}>· ADMIN</span>}
          </div>
        </div>
        <Panel style={{marginBottom:14}}>
          <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",letterSpacing:"0.15em",marginBottom:10}}>RANK PROGRESSION</div>
          <RankBar xp={user.xp||0}/>
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10,marginTop:14}}>
            <div>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:3}}>TOTAL XP</div>
              <div style={{fontFamily:"var(--display)",fontSize:16,color:"var(--cyan)",fontWeight:700}}>{(user.xp||0).toLocaleString()}</div>
            </div>
            <div>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:3}}>COINS</div>
              <CoinBadge amount={user.coins}/>
            </div>
          </div>
        </Panel>
        <Panel style={{marginBottom:14}}>
          {[["EMAIL",user.email],["MEMBER SINCE",new Date(user.joined).toLocaleDateString()],["STATUS","ACTIVE"]].map(([k,v])=>(
            <div key={k} style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"7px 0",borderBottom:"1px solid var(--border)"}}>
              <span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.1em"}}>{k}</span>
              <span style={{fontFamily:"var(--mono)",fontSize:11,color:k==="STATUS"?"var(--text-bright)":"var(--text)"}}>{v}</span>
            </div>
          ))}
        </Panel>
        <Panel style={{marginBottom:14}}>
          <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:10,letterSpacing:"0.15em"}}>CHANGE AVATAR</div>
          <div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:7,marginBottom:12}}>
            {avatars.map(a=>(
              <button key={a.id} onClick={()=>setAvatar(a.id)} style={{
                background:avatar===a.id?"rgba(255,255,255,0.14)":"rgba(0,0,0,0.38)",
                border:`1px solid ${avatar===a.id?"var(--cyan)":"var(--border)"}`,
                borderRadius:2,padding:"7px 4px",cursor:"pointer",
                display:"flex",flexDirection:"column",alignItems:"center",gap:2}}>
                <span style={{fontSize:20}}>{a.src?<img src={a.src} style={{width:"100%",height:"100%",objectFit:"cover"}}/>:""}</span>
                <span style={{fontFamily:"var(--mono)",fontSize:7,color:avatar===a.id?"var(--cyan)":"var(--text-dim)"}}>{a.label}</span>
              </button>
            ))}
          </div>
          <Btn onClick={()=>onUpdate({avatarId:avatar})} variant="secondary" style={{width:"100%"}}>SAVE AVATAR</Btn>
        </Panel>
        <Btn onClick={onLogout} variant="danger" style={{width:"100%"}}>LOGOUT / DISCONNECT</Btn>
      </div>
    </div>
  );
};

/* ─── CONFIRM MODAL ──────────────────────────────────────────────── */
const ConfirmModal = ({title,body,onConfirm,onCancel,confirmLabel="CONFIRM",danger=false}) => (
  <div style={{position:"fixed",inset:0,zIndex:9000,background:"rgba(0,0,0,0.85)",
    display:"flex",alignItems:"center",justifyContent:"center",padding:20}}>
    <div style={{background:"var(--bg3)",border:`1px solid ${danger?"var(--border-purple)":"var(--border)"}`,
      width:"100%",maxWidth:360,padding:"22px 20px",position:"relative",animation:"slideUp .25s ease"}}>
      <Corner pos="top-left"/><Corner pos="top-right"/><Corner pos="bottom-left"/><Corner pos="bottom-right"/>
      <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:danger?"var(--purple)":"var(--cyan)",
        letterSpacing:"0.1em",marginBottom:10}}>{title}</div>
      <div style={{fontFamily:"var(--body)",fontSize:14,color:"var(--text-dim)",marginBottom:20,lineHeight:1.5}}>{body}</div>
      <div style={{display:"flex",gap:10}}>
        <Btn onClick={onCancel} variant="ghost" style={{flex:1}}>CANCEL</Btn>
        <Btn onClick={onConfirm} variant={danger?"danger":"primary"} style={{flex:1}}>{confirmLabel}</Btn>
      </div>
    </div>
  </div>
);

/* ─── ADMIN CHALLENGE CREATOR ────────────────────────────────────── */
const AdminChallengeCreator = ({arenas, onCreate, onCancel}) => {
  const [step, setStep] = useState(1);
  const [arenaId, setArenaId] = useState(arenas[0]?.id||"");
  const [name, setName] = useState(""); const [desc, setDesc] = useState("");
  const [cost, setCost] = useState("100");
  // Sticker config
  const [stickerCharName, setStickerCharName] = useState("");
  const [stickerBg, setStickerBg] = useState(null);
  const [stickerMain, setStickerMain] = useState(null);
  const [stickerFrame, setStickerFrame] = useState(null);
  const [previewTier, setPreviewTier] = useState("GOLD");
  const [stickerSplit, setStickerSplit] = useState(55);
  // Step 2 — odds-api.io state
  const [searchQuery, setSearchQuery]               = useState("");
  const [searchResults, setSearchResults]           = useState([]);
  const [selectedTournament, setSelectedTournament] = useState(null);
  const [gridMatches, setGridMatches]               = useState([]);
  const [loadingGrid, setLoadingGrid]               = useState(false);
  const [gridError, setGridError]                   = useState(null);
  const [selectedMatchIds, setSelectedMatchIds]     = useState([]);
  const [marketsPerMatch, setMarketsPerMatch]       = useState({});
  const [currentMarketMatch, setCurrentMarketMatch] = useState(0);

  // When a tournament is selected, load its upcoming matches from PandaScore
  useEffect(()=>{
    if(!selectedTournament) return;
    setLoadingGrid(true); setGridError(null); setGridMatches([]);
    pandaFetch(selectedTournament.seriesId
        ? `/csgo/matches/upcoming?sort=begin_at&page[size]=50&filter[serie_id]=${selectedTournament.seriesId}`
        : `/csgo/matches/upcoming?sort=begin_at&page[size]=50&filter[tournament_id]=${selectedTournament.id}`)
      .then(data=>{
        const events = Array.isArray(data) ? data : [];
        const matches = events
          .filter(e=>e.opponents?.length===2)
          .map(normaliseEvent)
          .filter(m=>!isTBD(m.teamA.name)&&!isTBD(m.teamB.name));
        setGridMatches(matches);
        if(matches.length===0) setGridError("No upcoming matches found for this tournament.");
      })
      .catch(err=>setGridError(err.message))
      .finally(()=>setLoadingGrid(false));
  },[selectedTournament]);

  const handleSearch = () => {
    if(!searchQuery.trim()) return;
    setLoadingGrid(true); setGridError(null); setSearchResults([]);
    setSelectedTournament(null); setGridMatches([]);
    const term = searchQuery.trim().toLowerCase();
    // Search PandaScore tournaments for CS2 (tier S/A)
    pandaFetch(`/csgo/tournaments/upcoming?sort=begin_at&page[size]=50&filter[tier]=s`)
      .then(data=>{
        const tours = Array.isArray(data) ? data : [];
        const filtered = tours.filter(t=>
          t.name?.toLowerCase().includes(term)||
          t.serie?.full_name?.toLowerCase().includes(term)||
          t.league?.name?.toLowerCase().includes(term)
        );
        const results = filtered.map(t=>({
          id: String(t.id),
          name: `${t.league?.name||""} — ${t.serie?.full_name||t.name||""}`.trim(),
          count: t.matches_count||null
        }));
        setSearchResults(results);
        if(results.length===0){
          // Try series instead of tournaments
          return pandaFetch(`/csgo/series/upcoming?sort=begin_at&page[size]=50&filter[tier]=s`)
            .then(series=>{
              const sl = Array.isArray(series)?series:[];
              const sf = sl.filter(s=>
                s.full_name?.toLowerCase().includes(term)||
                s.league?.name?.toLowerCase().includes(term)
              );
              const sr = sf.map(s=>({
                id: String(s.id),
                seriesId: String(s.id),
                name: `${s.league?.name||""} — ${s.full_name||s.name||""}`.trim(),
                count: null
              }));
              setSearchResults(sr);
              if(sr.length===0) setGridError(`No Tier S CS2 tournament found for "${searchQuery}".`);
            });
        }
      })
      .catch(err=>setGridError(err.message))
      .finally(()=>setLoadingGrid(false));
  };

  const selectedMatches = gridMatches.filter(m=>selectedMatchIds.includes(m.id));
  const entryDeadline = selectedMatches.length
    ? selectedMatches.reduce((min,m)=>m.startTime<min?m.startTime:min, selectedMatches[0].startTime)
    : null;
  const toggleMarket = (matchId, mktId) => setMarketsPerMatch(prev=>{
    const cur = prev[matchId]||[];
    return {...prev,[matchId]: cur.includes(mktId)?cur.filter(x=>x!==mktId):[...cur,mktId]};
  });

  const totalQuestions = selectedMatches.reduce((s,m)=>(marketsPerMatch[m.id]||[]).length+s,0);

  const handleCreate = () => {
    const matchesWithMarkets = selectedMatches.map(m=>({...m, markets:marketsPerMatch[m.id]||[]}));
    const questionPool = buildQuestionPool(matchesWithMarkets);
    const deadline = matchesWithMarkets.length
      ? matchesWithMarkets.reduce((min,m)=>m.startTime<min?m.startTime:min, matchesWithMarkets[0].startTime)
      : null;
    onCreate({
      id:uid(), arenaId, name:name.toUpperCase(), desc, cost:parseInt(cost),
      difficulty:"MED", active:true,
      matches:matchesWithMarkets, questionPool, entryDeadline:deadline,
      sticker:{ charName:stickerCharName||name.toUpperCase(), bg:stickerBg, main:stickerMain, frame:stickerFrame },
    });
  };

  const stepLabel = ["","BASIC INFO","SELECT MATCHES","CONFIGURE MARKETS","REVIEW"];

  return (
    <div style={{animation:"slideUp .3s ease"}}>
      <div style={{display:"flex",gap:0,marginBottom:16,border:"1px solid var(--border)"}}>
        {[1,2,3,4].map(s=>(
          <div key={s} style={{flex:1,padding:"6px 0",textAlign:"center",
            fontFamily:"var(--mono)",fontSize:8,letterSpacing:"0.1em",
            background:step===s?"var(--purple)":step>s?"rgba(136,68,204,0.12)":"transparent",
            color:step===s?"#fff":step>s?"var(--purple)":"var(--text-dim)",
            borderRight:s<4?"1px solid var(--border)":"none"}}>
            {s === step ? stepLabel[s] : s}
          </div>
        ))}
      </div>

      {step===1&&(
        <Panel style={{marginBottom:12}}>
          <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:12,letterSpacing:"0.15em"}}>STEP 1 — BASIC INFO</div>
          <div style={{marginBottom:12}}>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:6,letterSpacing:"0.12em"}}>ARENA</div>
            <select value={arenaId} onChange={e=>setArenaId(e.target.value)}>
              {arenas.map(a=><option key={a.id} value={a.id}>{a.name}</option>)}
            </select>
          </div>
          <Field label="CHALLENGE NAME" value={name} onChange={setName} placeholder="GRAND SLAM"/>
          <Field label="DESCRIPTION" value={desc} onChange={setDesc} placeholder="Pick the outcomes..."/>
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10}}>
            <Field label="ENTRY COST" value={cost} onChange={setCost}/>

          </div>
          <div style={{marginBottom:14}}>

          </div>
          <Btn onClick={()=>{if(!name||!cost)return;setStep(2);}} style={{width:"100%"}}>NEXT — SELECT MATCHES →</Btn>
        </Panel>
      )}

      {step===2&&(
        <Panel style={{marginBottom:12}}>
          {/* ── HEADER ── */}
          <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:14}}>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",letterSpacing:"0.15em"}}>STEP 2 — CS2 MATCHES</div>
            {selectedTournament&&!loadingGrid&&(
              <span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)",border:"1px solid var(--border)",padding:"2px 7px"}}>◉ ODDS-API LIVE</span>
            )}
          </div>

          {/* ── SEARCH BOX ── */}
          {!selectedTournament&&(
            <div style={{marginBottom:14}}>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:6,letterSpacing:"0.12em"}}>SEARCH COMPETITION</div>
              <div style={{display:"flex",gap:8}}>
                <input
                  value={searchQuery}
                  onChange={e=>setSearchQuery(e.target.value)}
                  onKeyDown={e=>e.key==="Enter"&&handleSearch()}
                  placeholder="ex: ESL, BLAST, PGL, IEM..."
                  style={{flex:1}}
                />
                <Btn onClick={handleSearch} disabled={loadingGrid||!searchQuery.trim()} style={{flexShrink:0,padding:"10px 14px"}}>
                  {loadingGrid?"...":"SEARCH"}
                </Btn>
              </div>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginTop:6}}>
                Enter the competition name and press SEARCH ou Enter
              </div>
            </div>
          )}

          {/* ── ERROR ── */}
          {gridError&&(
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--purple)",marginBottom:12,
              padding:"8px 10px",border:"1px solid var(--border-purple)",background:"rgba(136,68,204,0.06)",lineHeight:1.5}}>
              ⚠ {gridError}
            </div>
          )}

          {/* ── LOADING ── */}
          {loadingGrid&&(
            <div style={{textAlign:"center",padding:"24px 0"}}>
              <div style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--cyan)",marginBottom:8,letterSpacing:"0.15em"}}>
                {selectedTournament?"LOADING MATCHES...":"SEARCHING..."}
              </div>
              <div style={{height:2,background:"var(--border)",overflow:"hidden"}}>
                <div style={{height:"100%",width:"60%",background:"var(--cyan)",animation:"pulse-cyan 1.5s infinite"}}/>
              </div>
            </div>
          )}

          {/* ── SEARCH RESULTS: pick tournament ── */}
          {!loadingGrid&&searchResults.length>0&&!selectedTournament&&(
            <div style={{marginBottom:14}}>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:8,letterSpacing:"0.15em"}}>
                {searchResults.length} COMPETITION{searchResults.length!==1?"S":""} FOUND — SELECT ONE
              </div>
              <div style={{display:"flex",flexDirection:"column",gap:6,maxHeight:240,overflowY:"auto"}}>
                {searchResults.map(t=>(
                  <div key={t.id} onClick={()=>{ setSelectedTournament(t); setGridError(null); }}
                    style={{padding:"10px 14px",border:"1px solid var(--border)",
                      background:"rgba(0,0,0,0.35)",cursor:"pointer",
                      display:"flex",alignItems:"center",justifyContent:"space-between",
                      transition:"all .15s"}}
                    onMouseEnter={e=>{e.currentTarget.style.borderColor="var(--cyan)";e.currentTarget.style.background="rgba(255,255,255,0.07)";}}
                    onMouseLeave={e=>{e.currentTarget.style.borderColor="var(--border)";e.currentTarget.style.background="rgba(0,0,0,0.35)";}}>
                    <div style={{fontFamily:"var(--body)",fontSize:14,fontWeight:600,color:"var(--text-bright)"}}>{t.name}</div>
                    <div style={{display:"flex",alignItems:"center",gap:8}}>
                      {t.count>0&&<span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)"}}>{t.count} matches</span>}
                      <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)"}}>SELECT →</span>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* ── SELECTED TOURNAMENT + MATCHES ── */}
          {selectedTournament&&!loadingGrid&&(
            <>
              <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",
                padding:"8px 12px",background:"rgba(255,255,255,0.07)",border:"1px solid var(--cyan)",marginBottom:12}}>
                <div>
                  <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:2}}>COMPETITION</div>
                  <div style={{fontFamily:"var(--body)",fontSize:14,fontWeight:600,color:"var(--text-bright)"}}>{selectedTournament.name}</div>
                </div>
                <button onClick={()=>{ setSelectedTournament(null); setGridMatches([]); setSelectedMatchIds([]); setGridError(null); }}
                  style={{background:"none",border:"1px solid var(--border)",color:"var(--text-dim)",
                    cursor:"pointer",padding:"4px 10px",fontFamily:"var(--mono)",fontSize:9}}>
                  ✕ CHANGE
                </button>
              </div>

              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:8,letterSpacing:"0.15em"}}>
                MATCHES — {gridMatches.length} FOUND · {selectedMatchIds.length} SELECTED
              </div>
              <div style={{display:"flex",flexDirection:"column",gap:7,marginBottom:14,maxHeight:320,overflowY:"auto"}}>
                {gridMatches.map(m=>{
                  const sel=selectedMatchIds.includes(m.id);
                  return (
                    <div key={m.id} onClick={()=>setSelectedMatchIds(prev=>
                      prev.includes(m.id)?prev.filter(x=>x!==m.id):[...prev,m.id]
                    )} style={{
                      padding:"10px 12px",border:`1px solid ${sel?"var(--cyan)":"var(--border)"}`,
                      background:sel?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.3)",cursor:"pointer",
                      display:"flex",justifyContent:"space-between",alignItems:"center",
                      boxShadow:sel?"0 0 10px var(--cyan-glow)":"none",flexShrink:0}}>
                      <div style={{flex:1,minWidth:0}}>
                        <div style={{fontFamily:"var(--display)",fontSize:11,color:"var(--text-bright)",fontWeight:700}}>
                          {m.teamA.name} <span style={{color:"var(--text-dim)",fontWeight:400,fontSize:9}}>vs</span> {m.teamB.name}
                        </div>
                        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginTop:3}}>
                          {m.format} · {fmtTime(m.startTime)} · <span style={{color:"var(--cyan)"}}>{fmtCountdown(m.startTime)}</span>
                        </div>
                      </div>
                      <div style={{width:18,height:18,border:`1px solid ${sel?"var(--cyan)":"var(--border)"}`,
                        background:sel?"var(--cyan)":"transparent",display:"flex",alignItems:"center",justifyContent:"center",
                        fontSize:11,color:"var(--bg)",flexShrink:0,marginLeft:10}}>
                        {sel&&"✓"}
                      </div>
                    </div>
                  );
                })}
              </div>
            </>
          )}

          {/* ── ENTRY DEADLINE ── */}
          {selectedMatches.length>0&&(()=>{
            const deadline = selectedMatches.reduce((min,m)=>m.startTime<min?m.startTime:min, selectedMatches[0].startTime);
            return (
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",marginBottom:14,
                padding:"8px 10px",border:"1px solid var(--border)",background:"rgba(0,0,0,0.3)"}}>
                ⏱ ENTRY DEADLINE: <span style={{color:"var(--text-bright)"}}>{fmtTime(deadline)}</span>
                <span style={{color:"var(--purple)",marginLeft:8}}>({fmtCountdown(deadline)})</span>
              </div>
            );
          })()}

          <div style={{display:"flex",gap:10}}>
            <Btn onClick={()=>setStep(1)} variant="ghost" style={{flex:1}}>← BACK</Btn>
            <Btn onClick={()=>{if(!selectedMatchIds.length||loadingGrid)return;setCurrentMarketMatch(0);setStep(3);}}
              disabled={!selectedMatchIds.length||loadingGrid} style={{flex:2}}>
              CONFIGURE MARKETS →
            </Btn>
          </div>
        </Panel>
      )}

      {step===3&&(()=>{
        const match = selectedMatches[currentMarketMatch];
        const selMkts = marketsPerMatch[match?.id]||[];
        return (
          <Panel style={{marginBottom:12}}>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:4,letterSpacing:"0.15em"}}>STEP 3 — BETTING MARKETS</div>
            <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:12}}>Match {currentMarketMatch+1}/{selectedMatches.length}</div>
            <div style={{padding:"10px 12px",background:"rgba(0,0,0,0.4)",border:"1px solid var(--border)",marginBottom:12}}>
              <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>
                {match.teamA.flag} {match.teamA.name} <span style={{color:"var(--text-dim)",fontSize:10}}>vs</span> {match.teamB.name} {match.teamB.flag}
              </div>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginTop:3}}>{match.format} · {fmtTime(match.startTime)}</div>
            </div>
            <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:8,letterSpacing:"0.1em"}}>SELECT QUESTION TYPES FOR THIS MATCH</div>
            <div style={{display:"flex",flexDirection:"column",gap:6,marginBottom:14,maxHeight:280,overflowY:"auto"}}>
              {MARKET_TEMPLATES.map(mkt=>{
                const on = selMkts.includes(mkt.id);
                return (
                  <div key={mkt.id} onClick={()=>toggleMarket(match.id,mkt.id)} style={{
                    padding:"8px 12px",border:`1px solid ${on?"var(--cyan)":"var(--border)"}`,
                    background:on?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.25)",cursor:"pointer",
                    display:"flex",justifyContent:"space-between",alignItems:"center"}}>
                    <div>
                      <div style={{fontFamily:"var(--body)",fontSize:13,color:on?"var(--text-bright)":"var(--text)"}}>{mkt.name}</div>
                      <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginTop:2}}>{mkt.a(match).join(" · ")}</div>
                    </div>
                    <div style={{width:16,height:16,border:`1px solid ${on?"var(--cyan)":"var(--border)"}`,
                      background:on?"var(--cyan)":"transparent",display:"flex",alignItems:"center",justifyContent:"center",
                      fontSize:10,color:"var(--bg)",flexShrink:0}}>{on&&"✓"}</div>
                  </div>
                );
              })}
            </div>
            <div style={{display:"flex",gap:10}}>
              <Btn onClick={()=>currentMarketMatch>0?setCurrentMarketMatch(p=>p-1):setStep(2)} variant="ghost" style={{flex:1}}>← BACK</Btn>
              <Btn onClick={()=>{if(currentMarketMatch<selectedMatches.length-1){setCurrentMarketMatch(p=>p+1);}else{setStep(4);}}} style={{flex:2}}>
                {currentMarketMatch<selectedMatches.length-1?"NEXT MATCH →":"REVIEW →"}
              </Btn>
            </div>
          </Panel>
        );
      })()}

      {step==="stickerPreview"&&(
        <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"fixed",inset:0,zIndex:999,overflow:"hidden"}}>
          {/* Header */}
          <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
            <button onClick={()=>setStep(4)} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
            <div style={{flex:1,fontFamily:"var(--mono)",fontSize:10,color:"var(--cyan)",letterSpacing:"0.15em"}}>STICKER PREVIEW</div>
          </div>
          {/* Tier tabs */}
          <div style={{display:"flex",borderBottom:"1px solid var(--border)",flexShrink:0}}>
            {["BRONZE","SILVER","GOLD","PLATINUM"].map(tier=>{
              const cfg2=PACK_CONFIG[tier];
              return (
                <button key={tier} onClick={()=>setPreviewTier(tier)}
                  style={{flex:1,padding:"9px 3px",background:previewTier===tier?cfg2.color1+"20":"transparent",
                    border:"none",borderBottom:`2px solid ${previewTier===tier?cfg2.color1:"transparent"}`,
                    cursor:"pointer",fontFamily:"var(--mono)",fontSize:10,
                    color:previewTier===tier?cfg2.color1:"rgba(255,255,255,0.3)",transition:"all 0.2s"}}>
                  {PACK_CONFIG[tier].label}
                </button>
              );
            })}
          </div>
          {/* Card preview — full height centered */}
          <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden"}}>
            <StickerCard
              packType={previewTier}
              challenge={{name:name.toUpperCase()||"CHALLENGE", sticker:{charName:stickerCharName||name.toUpperCase()||"PLAYER",bg:stickerBg,main:stickerMain,frame:stickerFrame}}}
            />
          </div>

          <div style={{padding:"0 16px 16px",flexShrink:0}}>
            <Btn onClick={()=>setStep(4)} style={{width:"100%"}}>← BACK TO REVIEW</Btn>
          </div>
        </div>
      )}

      {step===4&&(
        <Panel style={{marginBottom:12}}>
          <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:14,letterSpacing:"0.15em"}}>STEP 4 — STICKER & REVIEW</div>

          {/* ── STICKER SETUP ── */}
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.15em",marginBottom:10}}>STICKER CONFIG</div>

          {/* Character name */}
          <div style={{marginBottom:10}}>
            <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)",marginBottom:5,letterSpacing:"0.12em"}}>CHARACTER NAME</div>
            <input value={stickerCharName} onChange={e=>setStickerCharName(e.target.value)}
              placeholder="e.g. S. FAKER"
              style={{background:"rgba(0,0,0,0.55)",border:"1px solid var(--border)",color:"var(--text)",
                fontFamily:"var(--body)",fontSize:15,padding:"10px 14px",width:"100%",outline:"none"}}/>
            <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginTop:4}}>
              Appears at bottom of sticker. Description uses challenge name automatically.
            </div>
          </div>

          {/* Image uploads */}
          {[
            ["BACKGROUND IMAGE","Any scene/stadium/abstract","stickerBg",setStickerBg,stickerBg],
            ["MAIN ILLUSTRATION","PNG with transparent bg — character/player","stickerMain",setStickerMain,stickerMain],
            ["FRAME / BORDER","PNG transparent — use light grey #e8e8e8 base","stickerFrame",setStickerFrame,stickerFrame],
          ].map(([label,hint,key,setter,val])=>(
            <div key={key} style={{marginBottom:10}}>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:val?"var(--cyan)":"var(--text-dim)",
                letterSpacing:"0.12em",marginBottom:5}}>{val?"✓ ":""}{label}</div>
              <div style={{display:"flex",alignItems:"center",gap:8}}>
                <label style={{flex:1,cursor:"pointer"}}>
                  <div style={{background:"rgba(255,255,255,0.08)",border:"1px solid var(--border)",
                    color:val?"var(--cyan)":"var(--text-dim)",fontFamily:"var(--mono)",fontSize:9,
                    padding:"8px 12px",letterSpacing:"0.1em",textAlign:"center"}}>
                    {val?"CHANGE IMAGE":"UPLOAD IMAGE ↑"}
                  </div>
                  <input type="file" accept="image/*" style={{display:"none"}}
                    onChange={e=>{
                      const file=e.target.files[0]; if(!file)return;
                      const reader=new FileReader();
                      reader.onload=ev=>setter(ev.target.result);
                      reader.readAsDataURL(file);
                    }}/>
                </label>
                {val&&<button onClick={()=>setter(null)} style={{background:"none",border:"1px solid rgba(136,68,204,0.3)",
                  color:"rgba(136,68,204,0.7)",fontFamily:"var(--mono)",fontSize:9,padding:"8px 10px",cursor:"pointer"}}>✕</button>}
              </div>
              {!val&&<div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginTop:3}}>{hint}</div>}
            </div>
          ))}


          {/* ── STICKER PREVIEW BUTTON → dedicated screen ── */}
          <div style={{height:1,background:"var(--border)",margin:"14px 0"}}/>
          <Btn onClick={()=>setStep("stickerPreview")} variant="ghost" style={{width:"100%",marginBottom:14}}>
            👁 PREVIEW STICKER CARD →
          </Btn>
          <div style={{height:1,background:"var(--border)",margin:"0 0 14px"}}/>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.15em",marginBottom:10}}>CHALLENGE SUMMARY</div>
          {[
            ["CHALLENGE",name],["ARENA",arenas.find(a=>a.id===arenaId)?.name||"-"],
            ["ENTRY COST",`◈${cost}`],
            ["MATCHES",`${selectedMatches.length} match${selectedMatches.length!==1?"es":""}`],
            ["QUESTION POOL",`${totalQuestions} potential questions (4 picked per player)`],
            ["ENTRY DEADLINE",entryDeadline?fmtTime(entryDeadline):"—"],
          ].map(([k,v])=>(
            <div key={k} style={{display:"flex",justifyContent:"space-between",padding:"7px 0",borderBottom:"1px solid var(--border)"}}>
              <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",letterSpacing:"0.1em"}}>{k}</span>
              <span style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--text-bright)"}}>{v}</span>
            </div>
          ))}
          <div style={{marginTop:12,marginBottom:14}}>
            {selectedMatches.map(m=>(
              <div key={m.id} style={{display:"flex",justifyContent:"space-between",padding:"5px 0",borderBottom:"1px solid rgba(255,255,255,0.04)"}}>
                <span style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--text)"}}>{m.teamA.abbr} vs {m.teamB.abbr}</span>
                <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)"}}>{(marketsPerMatch[m.id]||[]).length} markets</span>
              </div>
            ))}
          </div>
          {totalQuestions<4&&(
            <div style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--purple)",marginBottom:12,
              padding:"8px 10px",border:"1px solid var(--border-purple)",background:"rgba(136,68,204,0.07)"}}>
              ⚠ Select at least 4 markets total to guarantee 4 questions per player.
            </div>
          )}
          <div style={{display:"flex",gap:10}}>
            <Btn onClick={()=>setStep(3)} variant="ghost" style={{flex:1}}>← BACK</Btn>
            <Btn onClick={handleCreate} style={{flex:2}}>CREATE CHALLENGE</Btn>
          </div>
        </Panel>
      )}

      <Btn onClick={onCancel} variant="ghost" style={{width:"100%",marginTop:4}}>CANCEL</Btn>
    </div>
  );
};

/* ─── SWIPE CARD ─────────────────────────────────────────────────── */
const SwipeCard = ({question, index, total, onAnswer, onReset, answeredOption}) => {
  const [dragX, setDragX] = useState(0);
  const [dragging, setDragging] = useState(false);
  const [startX, setStartX] = useState(0);
  const [exiting, setExiting] = useState(null); // "left"|"right"|null
  const THRESHOLD = 72;
  const cardRef = React.useRef(null);

  // Native touch listeners — bypass React passive event issues
  React.useEffect(() => {
    const el = cardRef.current;
    if(!el) return;
    let sx = 0, active = false;
    const onTS = (e) => { sx = e.touches[0].clientX; active = true; };
    const onTM = (e) => {
      if(!active) return;
      const dx = e.touches[0].clientX - sx;
      if(Math.abs(dx) > 6) e.preventDefault(); // prevent scroll on horiz swipe
      setDragX(dx);
    };
    const onTE = () => {
      active = false;
      setDragX(prev => {
        if(prev < -THRESHOLD) { setTimeout(()=>commit("left"),0); return prev; }
        if(prev > THRESHOLD)  { setTimeout(()=>commit("right"),0); return prev; }
        return 0;
      });
      setDragging(false);
    };
    el.addEventListener("touchstart", onTS, {passive:true});
    el.addEventListener("touchmove",  onTM, {passive:false});
    el.addEventListener("touchend",   onTE, {passive:true});
    return () => {
      el.removeEventListener("touchstart", onTS);
      el.removeEventListener("touchmove",  onTM);
      el.removeEventListener("touchend",   onTE);
    };
  }, [question.id, exiting]);

  // Answered state — compact card with color of chosen option
  if(answeredOption && !exiting) {
    const isA = answeredOption === question.answers[0];
    const color = isA ? "var(--cyan)" : "var(--purple)";
    const colorBg = isA ? "rgba(255,255,255,0.07)" : "rgba(136,68,204,0.07)";
    const colorBorder = isA ? "rgba(255,255,255,0.2)" : "rgba(136,68,204,0.22)";
    return (
      <div onClick={onReset} style={{
        background:colorBg, border:`1px solid ${colorBorder}`, borderRadius:4,
        padding:"11px 16px", cursor:"pointer",
        display:"flex", justifyContent:"space-between", alignItems:"center",
        position:"relative", overflow:"hidden",
      }}>
        <div style={{position:"absolute",left:0,top:0,bottom:0,width:3,background:color,borderRadius:"4px 0 0 4px"}}/>
        <div style={{paddingLeft:10,flex:1,minWidth:0}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:3,letterSpacing:"0.1em"}}>{question.marketName}</div>
          <div style={{fontFamily:"var(--body)",fontSize:13,color:"var(--text-dim)",lineHeight:1.3}}>{question.question}</div>
        </div>
        <div style={{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:3,flexShrink:0,marginLeft:12}}>
          <div style={{fontFamily:"var(--display)",fontSize:11,fontWeight:700,color,textAlign:"right",lineHeight:1.3,maxWidth:120}}>{answeredOption}</div>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.08em"}}>✎ CHANGE</div>
        </div>
      </div>
    );
  }

  const commit = (dir) => {
    // swipe LEFT → answers[0] (left/cyan option)
    // swipe RIGHT → answers[1] (right/red option)
    const choice = dir==="left" ? question.answers[0] : question.answers[1];
    setExiting(dir);
    setTimeout(()=>onAnswer(question.id, choice), 310);
  };

  // Touch handled by native listeners above (useEffect)
  const onTouchStart = () => {};
  const onTouchMove  = () => {};
  const onTouchEnd   = () => {};

  const progress = Math.min(Math.abs(dragX) / THRESHOLD, 1);
  const goLeft  = dragX < 0;
  const goRight = dragX > 0;

  const cardTransform = exiting==="left"
    ? "translateX(-115%)"
    : exiting==="right"
    ? "translateX(115%)"
    : `translateX(${dragX}px)`;
  const cardTransition = dragging ? "none" : "transform 0.3s ease";

  return (
    <div style={{position:"relative",touchAction:"pan-y",userSelect:"none",WebkitUserSelect:"none",cursor:"grab"}}>

      {/* ── Background: LEFT side = cyan (answers[0]) ── */}
      <div style={{
        position:"absolute",inset:0,borderRadius:4,zIndex:0,
        background:`rgba(255,255,255,${goLeft ? progress*0.18 : 0})`,
        border:`1px solid rgba(255,255,255,${goLeft ? progress*0.6 : 0})`,
        display:"flex",alignItems:"center",justifyContent:"flex-start",padding:"0 22px",
        transition:dragging?"none":"all 0.2s",
      }}>
        <div style={{display:"flex",flexDirection:"column",gap:4,opacity:goLeft?Math.max(0,(progress-0.2)/0.8):0.35,transition:dragging?"none":"opacity 0.2s"}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)",letterSpacing:"0.15em"}}>← PICK THIS</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--cyan)",letterSpacing:"0.04em",lineHeight:1.3,maxWidth:130}}>{question.answers[0]}</div>
        </div>
      </div>

      {/* ── Background: RIGHT side = red (answers[1]) ── */}
      <div style={{
        position:"absolute",inset:0,borderRadius:4,zIndex:0,
        background:`rgba(136,68,204,${goRight ? progress*0.18 : 0})`,
        border:`1px solid rgba(136,68,204,${goRight ? progress*0.6 : 0})`,
        display:"flex",alignItems:"center",justifyContent:"flex-end",padding:"0 22px",
        transition:dragging?"none":"all 0.2s",
      }}>
        <div style={{display:"flex",flexDirection:"column",gap:4,alignItems:"flex-end",opacity:goRight?Math.max(0,(progress-0.2)/0.8):0.35,transition:dragging?"none":"opacity 0.2s"}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--purple)",letterSpacing:"0.15em"}}>PICK THIS →</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--purple)",letterSpacing:"0.04em",lineHeight:1.3,maxWidth:130,textAlign:"right"}}>{question.answers[1]}</div>
        </div>
      </div>

      {/* ── The sliding card ── */}
      <div
        ref={cardRef}
        style={{position:"relative",zIndex:1,transform:cardTransform,transition:cardTransition}}
        onTouchStart={onTouchStart} onTouchMove={onTouchMove} onTouchEnd={onTouchEnd}
      >
        {/* Progress stripe at bottom */}
        <div style={{position:"absolute",bottom:0,left:0,right:0,height:2,zIndex:5,overflow:"hidden",borderRadius:"0 0 4px 4px"}}>
          {goLeft&&<div style={{position:"absolute",right:0,top:0,bottom:0,width:`${progress*100}%`,background:"var(--cyan)",transition:dragging?"none":"width 0.1s"}}/>}
          {goRight&&<div style={{position:"absolute",left:0,top:0,bottom:0,width:`${progress*100}%`,background:"var(--purple)",transition:dragging?"none":"width 0.1s"}}/>}
        </div>

        <div style={{background:"var(--bg3)",border:"1px solid rgba(255,255,255,0.07)",borderRadius:4,overflow:"hidden",cursor:"grab"}}>
          {/* Meta bar */}
          <div style={{background:"rgba(0,0,0,0.55)",padding:"6px 12px",borderBottom:"1px solid rgba(255,255,255,0.06)",
            display:"flex",justifyContent:"space-between",alignItems:"center"}}>
            <span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.1em"}}>{question.matchLabel}</span>
            <span style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.25)",border:"1px solid rgba(255,255,255,0.08)",padding:"2px 7px"}}>{index+1}/{total}</span>
          </div>

          {/* Market */}
          <div style={{padding:"6px 12px 2px"}}>
            <span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.1em",background:"rgba(255,255,255,0.04)",border:"1px solid rgba(255,255,255,0.07)",padding:"2px 8px"}}>
              {question.marketName}
            </span>
          </div>

          {/* Question */}
          <div style={{padding:"8px 12px 10px",fontFamily:"var(--body)",fontSize:15,fontWeight:600,color:"var(--text-bright)",lineHeight:1.3,minHeight:38,display:"flex",alignItems:"center"}}>
            {question.question}
          </div>

          {/* Options footer */}
          <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",borderTop:"1px solid rgba(255,255,255,0.06)"}}>
            <div style={{padding:"8px 12px",borderRight:"1px solid rgba(255,255,255,0.06)",
              background:`rgba(255,255,255,${goLeft?progress*0.12:0.03})`,transition:dragging?"none":"background 0.15s",
              display:"flex",flexDirection:"column",gap:3,alignItems:"center",
              cursor:"pointer"}}
              onClick={()=>commit("left")}>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",letterSpacing:"0.12em"}}>← SWIPE</div>
              <div style={{fontFamily:"var(--body)",fontSize:11,fontWeight:600,color:"var(--text-bright)",textAlign:"center",lineHeight:1.2}}>{question.answers[0]}</div>
            </div>
            <div style={{padding:"12px 14px",
              background:`rgba(136,68,204,${goRight?progress*0.12:0.03})`,transition:dragging?"none":"background 0.15s",
              display:"flex",flexDirection:"column",gap:5,alignItems:"center",
              cursor:"pointer"}}
              onClick={()=>commit("right")}>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--purple)",letterSpacing:"0.12em"}}>SWIPE →</div>
              <div style={{fontFamily:"var(--body)",fontSize:11,fontWeight:600,color:"var(--text-bright)",textAlign:"center",lineHeight:1.2}}>{question.answers[1]}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

/* ─── CHALLENGE PLAY SCREEN ──────────────────────────────────────── */
const ChallengePlayScreen = ({challenge, user, entry, onSubmit, onBack, lang="en"}) => {
  const t = LANG[lang]||LANG.en;
  const cardAreaRef = React.useRef(null);
  const [questions] = useState(()=> entry?.questions || pickRandom(challenge.questionPool||[], 4));
  const [answers, setAnswers] = useState(entry?.answers||{});
  const [phase, setPhase] = useState(entry?.locked?"locked":"play");
  const deadline = challenge.entryDeadline;
  const pastDeadline = deadline && new Date(deadline) < new Date();
  const answeredCount = Object.keys(answers).length;
  const allAnswered = questions.every(q=>answers[q.id]);

  const handleAnswer = (qId, choice) => {
    setAnswers(prev=>{
      const next = {...prev, [qId]:choice};
      if(Object.keys(next).length===questions.length)
        setTimeout(()=>setPhase("review"), 350);
      return next;
    });
  };

  const handleReset = (qId) => {
    setAnswers(prev=>{ const n={...prev}; delete n[qId]; return n; });
    setPhase("play");
  };

  const Dots = () => (
    <div style={{display:"flex",justifyContent:"center",gap:8,padding:"12px 0 4px"}}>
      {questions.map(q=>(
        <div key={q.id} style={{
          width:answers[q.id]?9:7, height:answers[q.id]?9:7, borderRadius:"50%",
          background:answers[q.id]?"var(--cyan)":"rgba(255,255,255,0.1)",
          border:answers[q.id]?"none":"1px solid rgba(255,255,255,0.18)",
          transition:"all 0.25s",
        }}/>
      ))}
    </div>
  );

  /* ── LOCKED VIEW ── */
  if(phase==="locked") return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1,fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>{challenge.name}</div>
        <span style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--purple)",border:"1px solid rgba(136,68,204,0.45)",padding:"3px 8px"}}>🔒 LOCKED</span>
      </div>
      <div style={{padding:"14px 16px"}}>
        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em",marginBottom:10}}>YOUR PICKS</div>
        {questions.map(q=>{
          const ans=entry?.answers?.[q.id]||"—";
          const isA=ans===q.answers[0];
          const c=isA?"var(--cyan)":"var(--purple)";
          return(
            <div key={q.id} style={{display:"flex",justifyContent:"space-between",alignItems:"center",
              padding:"10px 14px",marginBottom:7,background:"rgba(0,0,0,0.3)",border:"1px solid var(--border)",position:"relative",overflow:"hidden"}}>
              <div style={{position:"absolute",left:0,top:0,bottom:0,width:3,background:c}}/>
              <div style={{flex:1,paddingLeft:10,minWidth:0}}>
                <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)",marginBottom:2}}>{q.marketName} · {q.matchLabel}</div>
                <div style={{fontFamily:"var(--body)",fontSize:13,color:"var(--text)",lineHeight:1.3}}>{q.question}</div>
              </div>
              <div style={{fontFamily:"var(--display)",fontSize:10,fontWeight:700,color:c,marginLeft:12,flexShrink:0,textAlign:"right",maxWidth:110,lineHeight:1.3}}>{ans}</div>
            </div>
          );
        })}
      </div>
      {/* Share picks */}
      <div style={{padding:"12px 16px 20px",display:"flex",flexDirection:"column",gap:8,borderTop:"1px solid var(--border)"}}>
        <ShareBtn
          label="SHARE MY PICKS"
          message="Look at my picks on DFUSE! Dare to pick too?"
          captureRef={cardAreaRef}
        />
      </div>
    </div>
  );

  /* ── REVIEW VIEW ── */
  if(phase==="review") return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10}}>
        <button onClick={()=>setPhase("play")} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>REVIEW PICKS</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>{challenge.name}</div>
        </div>
      </div>
      <div style={{padding:"14px 16px"}}>
        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em",marginBottom:10}}>
          {questions.length} PICKS — TAP ANY TO CHANGE
        </div>
        {questions.map(q=>{
          const ans=answers[q.id];
          const color=ans===q.answers[0]?"var(--cyan)":"var(--purple)";
          return(
            <div key={q.id} onClick={()=>{handleReset(q.id);}}
              style={{display:"flex",justifyContent:"space-between",alignItems:"center",
                padding:"13px 14px",marginBottom:8,background:"rgba(0,0,0,0.35)",
                border:"1px solid var(--border)",cursor:"pointer",position:"relative",overflow:"hidden"}}>
              <div style={{position:"absolute",left:0,top:0,bottom:0,width:3,background:color}}/>
              <div style={{flex:1,paddingLeft:10,minWidth:0}}>
                <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:3}}>{q.marketName} · {q.matchLabel}</div>
                <div style={{fontFamily:"var(--body)",fontSize:13,color:"var(--text)",lineHeight:1.3}}>{q.question}</div>
              </div>
              <div style={{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:3,marginLeft:12,flexShrink:0}}>
                <div style={{fontFamily:"var(--display)",fontSize:11,fontWeight:700,color,textAlign:"right",maxWidth:110,lineHeight:1.3}}>{ans}</div>
                <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)"}}>✎ CHANGE</div>
              </div>
            </div>
          );
        })}
      </div>
      {!pastDeadline&&(
        <div style={{padding:"16px",borderTop:"1px solid var(--border)"}}>
          <Btn onClick={()=>onSubmit({questions,answers,locked:true,submittedAt:now()})}
            style={{width:"100%",fontSize:12,padding:"16px",letterSpacing:"0.12em"}}>
            🔒 {t.lockIn} — {questions.length} {t.picks}
          </Btn>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",textAlign:"center",marginTop:10}}>
            Cannot be changed after locking
          </div>
        </div>
      )}
    </div>
  );

  /* ── PLAY VIEW ── */
  return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1,overflow:"hidden"}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>CHALLENGE</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>{challenge.name}</div>
        </div>
        <div style={{fontFamily:"var(--mono)",fontSize:11,color:"var(--cyan)",fontWeight:700,
          background:"rgba(255,255,255,0.08)",border:"1px solid var(--border)",padding:"4px 10px"}}>
          {answeredCount}/{questions.length}
        </div>
      </div>

      <Dots/>

      <div style={{flex:1,padding:"10px 16px 20px",display:"flex",flexDirection:"column",gap:10,overflowY:"auto",WebkitOverflowScrolling:"touch"}}>
        {questions.map((q,i)=>(
          <SwipeCard
            key={q.id}
            question={q}
            index={i}
            total={questions.length}
            onAnswer={handleAnswer}
            onReset={()=>handleReset(q.id)}
            answeredOption={answers[q.id]||null}
          />
        ))}
      </div>

      {answeredCount===0&&!pastDeadline&&(
        <div style={{padding:"8px 16px 14px",textAlign:"center",flexShrink:0}}>
          <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",letterSpacing:"0.1em"}}>
            swipe left or right · or tap an option
          </div>
        </div>
      )}

      {allAnswered&&!pastDeadline&&(
        <div style={{padding:"12px 16px 20px",borderTop:"1px solid var(--border)",flexShrink:0}}>
          <Btn onClick={()=>setPhase("review")} style={{width:"100%",fontSize:12,padding:"16px"}}>
            REVIEW PICKS →
          </Btn>
        </div>
      )}

      {pastDeadline&&(
        <div style={{padding:"12px 16px",textAlign:"center",flexShrink:0}}>
          <div style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--purple)"}}>⛔ ENTRY CLOSED</div>
        </div>
      )}
    </div>
  );
};

/* ─── STICKER PACK ───────────────────────────────────────────────── */
const Confetti = ({colors}) => {
  const pieces = React.useMemo(()=>Array.from({length:20},(_,i)=>({
    id:i, x:Math.random()*100, delay:Math.random()*0.7,
    w:4+Math.random()*7, h:2+Math.random()*4,
    color:colors[i%colors.length], dur:0.9+Math.random()*0.6,
  })),[]);
  return (
    <div style={{position:"absolute",inset:0,pointerEvents:"none",overflow:"hidden",zIndex:20}}>
      {pieces.map(p=>(
        <div key={p.id} style={{
          position:"absolute",left:`${p.x}%`,top:"-15px",
          width:p.w,height:p.h,background:p.color,borderRadius:1,
          animation:`confetti-fall ${p.dur}s ${p.delay}s ease-in forwards`,
        }}/>
      ))}
    </div>
  );
};

const PackHalf = ({cfg, side}) => {
  const isTop = side==="top";
  return (
    <div style={{
      width:"100%", height:isTop?"500%":"100%",
      background:cfg.packBg,
      border:`2px solid ${cfg.border}`,
      borderBottom:isTop?"none":"",borderTop:!isTop?"none":"",
      borderRadius:isTop?"6px 6px 0 0":"0 0 6px 6px",
      position:"relative",overflow:"hidden",
    }}>
      {/* Diagonal stripes  style */}
      <div style={{position:"absolute",inset:0,overflow:"hidden"}}>
        <div style={{position:"absolute",top:"-40%",left:"-20%",right:"-20%",bottom:"-40%",
          backgroundImage:`repeating-linear-gradient(60deg,transparent,transparent 28px,${cfg.stripe1}12 28px,${cfg.stripe1}12 30px)`}}/>
      </div>
      {/* Shine sweep */}
      <div style={{position:"absolute",inset:0,overflow:"hidden"}}>
        <div style={{position:"absolute",top:0,bottom:0,width:"45%",
          background:`linear-gradient(90deg,transparent,${cfg.shine},transparent)`,
          animation:"shine-sweep 2.2s ease-in-out infinite"}}/>
      </div>
      {/* Edge glow */}
      <div style={{position:"absolute",left:0,top:0,bottom:0,width:2,background:`linear-gradient(180deg,transparent,${cfg.color1},transparent)`,opacity:0.6}}/>
      <div style={{position:"absolute",right:0,top:0,bottom:0,width:2,background:`linear-gradient(180deg,transparent,${cfg.color1},transparent)`,opacity:0.6}}/>
      {isTop ? (
        <>
          <div style={{position:"absolute",top:14,left:0,right:0,display:"flex",flexDirection:"column",alignItems:"center",gap:5}}>
            <img src={LOGO_SRC} alt="DFUSE"
              style={{width:110,display:"block",}}/>
            <div style={{width:48,height:2,background:`linear-gradient(90deg,transparent,${cfg.color1},transparent)`}}/>
          </div>
          <div style={{position:"absolute",bottom:0,left:0,right:0,height:8,
            backgroundImage:`repeating-linear-gradient(90deg,transparent,transparent 6px,${cfg.color1}55 6px,${cfg.color1}55 7px)`,opacity:0.7}}/>
        </>
      ) : (
        <>
          <div style={{position:"absolute",top:"22%",left:0,right:0,display:"flex",justifyContent:"center",gap:5}}>
            {[...Array(cfg.stars)].map((_,i)=>(
              <div key={i} style={{fontSize:14,color:cfg.color1,fontFamily:"serif",lineHeight:1}}>&#9733;</div>
            ))}
          </div>
          <div style={{position:"absolute",bottom:14,left:0,right:0,textAlign:"center"}}>
            <span style={{fontFamily:"var(--mono)",fontSize:7,letterSpacing:"0.15em",
              color:cfg.color1,background:`${cfg.color1}18`,border:`1px solid ${cfg.color1}44`,padding:"3px 8px"}}>
              {cfg.label}
            </span>
          </div>
        </>
      )}
    </div>
  );
};

const StickerCard = ({packType, challenge}) => {
  const cfg = PACK_CONFIG[packType];
  const sticker = challenge?.sticker || {};
  const W=260, H=364, r=12;
  const split = 85;
  const sp = Math.round(H * split / 100); // 309px — character shows 85% height

  const sceneRef = React.useRef(null);
  const cardRef  = React.useRef(null);
  const MAX_RY=20, MAX_RX=16;

  React.useEffect(()=>{
    const scene=sceneRef.current, card=cardRef.current;
    if(!scene||!card) return;
    let dragging=false, ox=0, oy=0;
    const applyTilt=(ry,rx)=>{ card.style.animation="none"; card.style.transition="none"; card.style.transform=`rotateY(${ry}deg) rotateX(${-rx}deg)`; };
    const resetTilt=()=>{ dragging=false; card.style.transition="transform 0.65s cubic-bezier(.22,.61,.36,1)"; card.style.transform="rotateY(10deg) rotateX(-6deg)";
      setTimeout(()=>{ card.style.animation="float-anim 4s ease-in-out infinite"; card.style.transition=""; },700); };
    const onMD=(e)=>{ dragging=true; ox=e.clientX||e.touches?.[0]?.clientX||0; oy=e.clientY||e.touches?.[0]?.clientY||0; };
    const onMM=(e)=>{ if(!dragging)return; const cx=e.clientX||e.touches?.[0]?.clientX||ox; const cy=e.clientY||e.touches?.[0]?.clientY||oy; applyTilt(Math.max(-MAX_RY,Math.min(MAX_RY,(cx-ox)/2.5)),Math.max(-MAX_RX,Math.min(MAX_RX,(cy-oy)/3))); };
    const onMU=()=>{ if(dragging)resetTilt(); };
    scene.addEventListener("mousedown",onMD); scene.addEventListener("mousemove",onMM); scene.addEventListener("mouseup",onMU); scene.addEventListener("mouseleave",onMU);
    scene.addEventListener("touchstart",onMD,{passive:false}); scene.addEventListener("touchmove",(e)=>{ onMM(e); e.preventDefault(); },{passive:false}); scene.addEventListener("touchend",onMU);
    return()=>{ scene.removeEventListener("mousedown",onMD); scene.removeEventListener("mousemove",onMM); scene.removeEventListener("mouseup",onMU); scene.removeEventListener("mouseleave",onMU); };
  },[packType]);

  const stars4 = Array.from({length:4},(_,i)=>(
    <span key={i} style={{fontSize:12,color:i<cfg.stars?cfg.color3:"rgba(255,255,255,0.14)"}}>★</span>
  ));

  return (
    <div ref={sceneRef} style={{width:W,height:H,perspective:"500px",cursor:"grab",userSelect:"none",WebkitUserSelect:"none",flexShrink:0}}>
      <div ref={cardRef} style={{width:W,height:H,position:"relative",borderRadius:r,
        transformStyle:"preserve-3d",transform:"rotateY(10deg) rotateX(-6deg)",
        animation:"float-anim 4s ease-in-out infinite",
        boxShadow:cfg.shadow}}>

        {/* Z:0 — base gradient */}
        <div style={{position:"absolute",inset:0,borderRadius:r,transform:"translateZ(0px)",background:cfg.bgGrad}}/>

        {/* Z:4 — background image */}
        <div style={{position:"absolute",inset:0,borderRadius:r,overflow:"hidden",transform:"translateZ(4px)",display:"flex",alignItems:"center",justifyContent:"center"}}>
          {sticker.bg
            ? <img src={sticker.bg} style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",objectPosition:"center",opacity:0.95}}/>
            : <div style={{fontFamily:"var(--mono)",fontSize:9,color:"rgba(255,255,255,0.08)",textAlign:"center",lineHeight:1.8}}>BG<br/>NOT SET</div>}
        </div>

        {/* Z:6 — diagonal stripes */}
        {cfg.fx.includes("diagonal")&&(
          <div style={{position:"absolute",inset:0,overflow:"hidden",pointerEvents:"none",borderRadius:r,transform:"translateZ(6px)"}}>
            <div style={{position:"absolute",top:"-60%",left:"-30%",right:"-30%",bottom:"-60%",
              background:`repeating-linear-gradient(50deg,transparent,transparent 20px,${cfg.color1}09 20px,${cfg.color1}09 22px)`}}/>
          </div>
        )}

        {/* Z:6 — holo grid (PLATINUM) — static opacity, NO animation (animated opacity breaks preserve-3d) */}
        {cfg.fx.includes("holo")&&(
          <div style={{position:"absolute",inset:0,pointerEvents:"none",borderRadius:r,transform:"translateZ(6px)",opacity:0.09,
            backgroundImage:"linear-gradient(rgba(255,255,255,1) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,1) 1px,transparent 1px)",
            backgroundSize:"16px 16px"}}/>
        )}

        {/* Z:6 — rainbow (PLATINUM) — NO mix-blend-mode to preserve 3D context */}
        {cfg.fx.includes("rainbow")&&(
          <div style={{position:"absolute",inset:0,pointerEvents:"none",opacity:0.07,borderRadius:r,transform:"translateZ(6px)",
            background:"linear-gradient(135deg,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)",
            backgroundSize:"200% 200%",animation:"holo-rgb 4s linear infinite"}}/>
        )}

        {/* Z:10 — glow orb */}
        <div style={{position:"absolute",width:221,height:221,borderRadius:"50%",pointerEvents:"none",
          top:`calc(42% - 110px)`,left:`calc(50% - 110px)`,
          animation:"gorb 2.5s infinite",
          background:`radial-gradient(circle,${cfg.glow},transparent 66%)`}}/>

        {/* Z:28 — main illustration, clip-path to show only top portion */}
        {sticker.main
          ? <div style={{position:"absolute",inset:0,pointerEvents:"none",transform:"translateZ(28px)"}}>
              <img src={sticker.main} style={{
                position:"absolute",top:"50%",left:"50%",
                transform:"translate(-50%,-50%) scale(0.88)",
                width:W,height:H,
                objectFit:"cover",objectPosition:"center top",
                clipPath:`polygon(0 0,${W}px 0,${W}px ${sp}px,0 ${sp}px)`,
                WebkitMaskImage:`linear-gradient(to bottom, black 0%, black ${Math.round(sp*0.72)}px, transparent ${sp}px)`,
                maskImage:`linear-gradient(to bottom, black 0%, black ${Math.round(sp*0.72)}px, transparent ${sp}px)`}}/>
            </div>
          : <div style={{position:"absolute",top:66,left:47,right:47,bottom:80,
              border:"1.5px dashed rgba(255,255,255,0.1)",borderRadius:6,
              pointerEvents:"none",display:"flex",flexDirection:"column",
              alignItems:"center",justifyContent:"center",gap:6,transform:"translateZ(28px)"}}>
              <div style={{fontFamily:"var(--display)",fontSize:22,fontWeight:900,color:cfg.color3,textShadow:`0 0 18px ${cfg.glow}`}}>DF</div>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.2)",letterSpacing:"0.1em"}}>MAIN NOT SET</div>
            </div>}

        {/* Z:20 — frame — covers bottom seam of main */}
        <div style={{position:"absolute",inset:0,pointerEvents:"none",borderRadius:r,transform:"translateZ(20px)"}}>
          {sticker.frame
            ? <img src={sticker.frame} style={{position:"absolute",top:0,left:0,width:W,height:H,display:"block",borderRadius:r,
                filter:`${cfg.frameFilter} drop-shadow(0 0 10px ${cfg.frameGlow}) drop-shadow(0 0 20px ${cfg.frameGlow}66)`}}/>
            : <>
                <div style={{position:"absolute",inset:3,borderRadius:r-2,border:`2px solid ${cfg.color3}`,opacity:0.7,
                  boxShadow:`0 0 10px ${cfg.frameGlow},inset 0 0 8px ${cfg.frameGlow}55`}}/>
                <div style={{position:"absolute",top:3,left:3,right:3,height:3,borderRadius:"10px 10px 0 0",background:cfg.color1,opacity:0.9}}/>
                <div style={{position:"absolute",bottom:3,left:3,right:3,height:3,borderRadius:"0 0 10px 10px",background:cfg.color1,opacity:0.9}}/>
                <div style={{position:"absolute",top:49,left:10,right:10,height:1,background:cfg.color3,opacity:0.5}}/>
                <div style={{position:"absolute",bottom:64,left:10,right:10,height:1,background:cfg.color3,opacity:0.5}}/>
                {[["top","left"],["top","right"],["bottom","left"],["bottom","right"]].map(([v,h])=>(
                  <div key={v+h} style={{position:"absolute",[v]:6,[h]:6,width:14,height:14,
                    [`border${v[0].toUpperCase()+v.slice(1)}`]:`2px solid ${cfg.color3}`,
                    [`border${h[0].toUpperCase()+h.slice(1)}`]:`2px solid ${cfg.color3}`,opacity:0.85}}/>
                ))}
              </>}
        </div>

        {/* Z:34 — shimmer sweep */}
        <div style={{position:"absolute",inset:0,overflow:"hidden",pointerEvents:"none",borderRadius:r,transform:"translateZ(34px)"}}>
          <div style={{position:"absolute",top:0,bottom:0,width:"22%",
            background:`linear-gradient(90deg,transparent,${cfg.shimmer},transparent)`,
            animation:`shine-sweep ${packType==="PLATINUM"?"2.2s":"4s"} 1s ease-in-out infinite`}}/>
        </div>

        {/* Z:38 — UI: badge top-left, stars top-right, name+desc bottom */}
        <div style={{position:"absolute",inset:0,pointerEvents:"none",transform:"translateZ(38px)"}}>
          <div style={{position:"absolute",top:0,left:0,right:0,height:49,display:"flex",alignItems:"center",justifyContent:"space-between",padding:"0 14px"}}>
            <div style={{fontFamily:"var(--mono)",fontSize:9,fontWeight:700,letterSpacing:"0.14em",
              padding:"2px 8px",borderRadius:2,border:`1px solid ${cfg.color1}66`,
              color:cfg.color1,background:"rgba(0,0,0,0.65)"}}>
              {cfg.cardLabel.toUpperCase()}
            </div>
            <div style={{display:"flex",gap:2}}>{stars4}</div>
          </div>
          {/* Bottom — individual elements with drop shadows */}
          <div style={{position:"absolute",bottom:18,left:0,right:0,
            display:"flex",flexDirection:"column",alignItems:"center",gap:2,pointerEvents:"none"}}>
            <img src={LOGO_SRC} alt="DFUSE" style={{width:52,display:"block",opacity:0.9,
              filter:"drop-shadow(0 1px 6px rgba(0,0,0,1)) drop-shadow(0 0 10px rgba(0,0,0,0.9))"}}/>
            <div style={{fontFamily:"var(--display)",fontSize:18,fontWeight:900,letterSpacing:"0.1em",
              textAlign:"center",color:cfg.color3,
              textShadow:`0 0 12px ${cfg.glow}, 0 2px 8px rgba(0,0,0,1), 0 0 2px rgba(0,0,0,1)`}}>
              {sticker.charName||"PLAYER"}
            </div>
            {challenge?.name&&<div style={{fontFamily:"var(--body)",fontSize:11,fontWeight:500,
              color:"rgba(255,255,255,0.85)",textAlign:"center",letterSpacing:"0.06em",
              textShadow:"0 1px 6px rgba(0,0,0,1), 0 0 2px rgba(0,0,0,1)"}}>
              {challenge.name}
            </div>}
          </div>
        </div>

      </div>
    </div>
  );
};


const StickerPack = ({packType, challenge, onOpen}) => {
  const [stage, setStage] = useState(0); // 0=closed 1=tearing 2=hero
  const cfg = PACK_CONFIG[packType];
  const confColors = {
    BRONZE:  ["#e8a050","#cd7020","#ffd89b"],
    SILVER:  ["#d8d8d8","#fff","#888"],
    GOLD:    ["#ffd700","#ffe566","#a07800"],
    PLATINUM:["#c0b0ff","#8060d0","#e0d4ff","#fff"],
  }[packType]||["#fff"];

  const TIER_FILTER = {
    BRONZE:  "sepia(0.9) hue-rotate(350deg) saturate(2.2) brightness(0.85)",
    SILVER:  "brightness(1.0) saturate(0.85)",
    GOLD:    "sepia(1) hue-rotate(5deg) saturate(3.5) brightness(1.0)",
    PLATINUM:"sepia(0.6) hue-rotate(230deg) saturate(2.8) brightness(1.05)",
  }[packType]||"none";

  const open = () => {
    if(stage!==0) return;
    setStage(1); // shake + tear
    setTimeout(()=>{ setStage(2); onOpen&&onOpen(); }, 750);
  };

  const W=280, H=392;
  const imgStyle = {
    width:W, height:H, display:"block",
    mixBlendMode:"multiply",
    filter:TIER_FILTER,
    borderRadius:10,
  };

  return (
    <div style={{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"space-between",padding:"12px 0 16px",overflow:"hidden"}}>
      {stage<=1 && (
        <>
          {/* Pack visual */}
          <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",width:"100%"}}>
            {/* Outer wrapper — position:relative but NO filter (filter creates stacking context
                 that traps mix-blend-mode:screen of the logo inside it) */}
            <div style={{position:"relative",width:W,height:H,
              animation:stage===0?"pack-float 3.5s ease-in-out infinite":"pack-shake 0.4s ease-in-out"}}
              onClick={open}>

              {/* Pack halves — filter here, SEPARATE from logo */}
              <div style={{position:"absolute",inset:0,
                filter:`drop-shadow(0 0 50px ${cfg.glow}) drop-shadow(0 0 100px ${cfg.glow}44)`}}>

                {/* Bottom half — drops down */}
                <div style={{position:"absolute",inset:0,clipPath:`polygon(0 48%,${W}px 48%,${W}px 100%,0 100%)`,
                  animation:stage===1?"tear-bot 0.55s ease-out forwards":"none",overflow:"hidden"}}>
                  <img src={CLOSED_PACK_SRC} style={imgStyle}/>
                </div>

                {/* Top half — flies up-left */}
                <div style={{position:"absolute",inset:0,clipPath:`polygon(0 0,${W}px 0,${W}px 52%,0 52%)`,
                  animation:stage===1?"tear-top 0.55s ease-out forwards":"none",overflow:"hidden"}}>
                  <img src={CLOSED_PACK_SRC} style={imgStyle}/>
                </div>

                {/* Perforated tear line */}
                {stage===0&&<div style={{position:"absolute",top:"calc(50% - 1px)",left:0,right:0,height:2,zIndex:3,
                  pointerEvents:"none",
                  background:`repeating-linear-gradient(90deg,${cfg.color1}bb,${cfg.color1}bb 4px,transparent 4px,transparent 8px)`,
                  boxShadow:`0 0 5px ${cfg.color1}`}}/>}
              </div>

              {/* LOGO — sibling of the filter div, composites against page background directly.
                  mix-blend-mode:screen: black→transparent, coloured text→visible */}
              <div style={{position:"absolute",top:"14%",left:"50%",transform:"translateX(-50%)",
                textAlign:"center",whiteSpace:"nowrap",zIndex:10,pointerEvents:"none",
                animation:stage===1?"tear-top 0.55s ease-out forwards":"none"}}>
                <img src={LOGO_SRC} alt="DFUSE" style={{width:165,display:"block",
                  filter:"drop-shadow(0 2px 4px rgba(0,0,0,0.95)) drop-shadow(0 0 12px rgba(0,0,0,0.9)) drop-shadow(0 0 2px rgba(0,0,0,1))"}}/>
                <div style={{height:1.5,marginTop:4,background:`linear-gradient(90deg,transparent,${cfg.color1},transparent)`}}/>
              </div>
            </div>
          </div>
          {/* Label */}
          <div style={{textAlign:"center",flexShrink:0}}>
            <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:900,letterSpacing:"0.2em",color:cfg.color1,marginBottom:5}}>{cfg.label} PACK</div>
            <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)",letterSpacing:"0.12em"}}>
              {stage===1?"OPENING...":"TAP TO OPEN ↑"}
            </div>
          </div>
        </>
      )}

      {stage===2 && (
        <div style={{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"space-between",padding:"10px 0 14px",position:"relative",overflow:"hidden",width:"100%"}}>
          <Confetti colors={confColors}/>
          <div style={{fontFamily:"var(--display)",fontSize:10,letterSpacing:"0.25em",color:cfg.color3,textShadow:`0 0 14px ${cfg.glow}`,textTransform:"uppercase",flexShrink:0,animation:"bounce-in 0.5s ease forwards"}}>
            NEW STICKER UNLOCKED
          </div>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.3)",letterSpacing:"0.1em",flexShrink:0}}>
            ← DRAG TO ROTATE →
          </div>
          <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",width:"100%",animation:"card-reveal 0.8s cubic-bezier(.22,.61,.36,1) forwards"}}>
            <StickerCard packType={packType} challenge={challenge}/>
          </div>
          <div style={{padding:"0 16px",width:"100%",flexShrink:0}}>
            <button onClick={onOpen}
              style={{width:"100%",background:`linear-gradient(135deg,${cfg.color1},${cfg.color2||cfg.color1}88)`,
                border:`1px solid ${cfg.color1}`,color:"#000",padding:"14px",cursor:"pointer",
                fontFamily:"var(--display)",fontWeight:900,fontSize:12,letterSpacing:"0.15em",
                boxShadow:`0 0 24px ${cfg.glow},0 0 48px ${cfg.glow}44`}}>
              ✦ SAVE TO COLLECTION
            </button>
          </div>
        </div>
      )}
    </div>
  );
};


/* ─── RESULT SCREEN ──────────────────────────────────────────────── */
const ResultScreen = ({challenge, entry, correctAnswers, onBack, onCollect, onSaveCard, onGoMyCards, onToast}) => {
  const resultRef = React.useRef(null);
  const {correct, tier} = calcScore(entry, correctAnswers);
  const reward = calcReward(challenge.cost, tier.multiplier);
  const gained = reward - challenge.cost;
  const pack = tier.pack;
  const [phase, setPhase] = useState("result"); // result | pack | done
  const cfg = pack ? PACK_CONFIG[pack] : null;

  React.useEffect(()=>{
    if(!onToast) return;
    if(correct===0) onToast("Better luck next time!","info");
    else            onToast("Congratulations, go check your prize!","success");
  },[]);

  const scoreColors = ["rgba(255,255,255,0.4)","#cd7f32","#c0c0c0","#ffd700","#b0c4ff"];
  const scoreColor = scoreColors[correct] || scoreColors[0];

  // ── PACK PHASE — full screen, no scroll wrapper ──────────────────
  if(phase==="pack") return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>YOU EARNED</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:cfg?.color3||"var(--text-bright)"}}>
            +◈{reward} · {cfg?.label||""} PACK
          </div>
        </div>
      </div>
      <StickerPack packType={pack} challenge={challenge} onOpen={()=>{
        // Save card to user collection then go to done
        onSaveCard&&onSaveCard({
          id:uid(), packType:pack, challenge,
          savedAt:now(),
        });
        setPhase("done");
      }}/>
    </div>
  );

  // ── DONE PHASE — full screen ──────────────────────────────────────
  if(phase==="done") return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>SAVED TO COLLECTION</div>
          <div style={{fontFamily:"var(--display)",fontSize:12,fontWeight:700,color:PACK_CONFIG[pack]?.color3||"var(--text-bright)"}}>
            {pack} STICKER
          </div>
        </div>
        <Btn onClick={onGoMyCards} size="sm" style={{letterSpacing:"0.08em"}}>
          MY CARDS →
        </Btn>
      </div>
      <div ref={resultRef} style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden"}}>
        <StickerCard packType={pack} challenge={challenge}/>
      </div>
      <div style={{padding:"0 16px 20px",flexShrink:0,display:"flex",flexDirection:"column",gap:8}}>
        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.3)",textAlign:"center",letterSpacing:"0.1em",padding:"8px 0"}}>
          ← DRAG TO ROTATE →
        </div>
        <ShareBtn
          label="SHARE MY RESULT"
          message="I nailed it on DFUSE! Can you beat my score?"
          captureRef={resultRef}
        />
        <Btn onClick={onGoMyCards} style={{width:"100%",padding:"12px",fontSize:11,letterSpacing:"0.1em"}}>
          VIEW MY CARDS →
        </Btn>
        <Btn onClick={onBack} variant="ghost" style={{width:"100%"}}>
          BACK TO ARENA
        </Btn>
      </div>
    </div>
  );

  return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      {/* Header */}
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>RESULT</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>{challenge.name}</div>
        </div>
      </div>

      <div style={{flex:1,overflowY:"auto",padding:"20px 16px"}}>
        {phase==="result"&&(
          <div style={{animation:"slideUp 0.4s ease"}}>
            {/* Score hero */}
            <div style={{textAlign:"center",marginBottom:24}}>
              <div style={{fontFamily:"var(--display)",fontSize:64,fontWeight:900,color:scoreColor,
                lineHeight:1,textShadow:`0 0 30px ${scoreColor}88`,animation:"bounce-in 0.6s ease"}}>
                {correct}/{(entry?.questions||[]).length}
              </div>
              <div style={{fontFamily:"var(--mono)",fontSize:10,color:scoreColor,letterSpacing:"0.25em",marginTop:4}}>
                {tier.label}
              </div>
              <div style={{height:1,background:`linear-gradient(90deg,transparent,${scoreColor}66,transparent)`,margin:"14px 0"}}/>
            </div>

            {/* Score breakdown */}
            <div style={{marginBottom:20}}>
              {(entry?.questions||[]).map(q=>{
                const myAns = entry?.answers?.[q.id];
                const correct_ans = correctAnswers?.[q.id];
                const isRight = myAns && correct_ans && myAns===correct_ans;
                const hasResult = !!correct_ans;
                return(
                  <div key={q.id} style={{display:"flex",alignItems:"center",gap:10,
                    padding:"9px 14px",marginBottom:6,background:"rgba(0,0,0,0.3)",
                    border:`1px solid ${hasResult?(isRight?"rgba(255,255,255,0.25)":"rgba(136,68,204,0.2)"):"var(--border)"}`,
                    position:"relative",overflow:"hidden"}}>
                    <div style={{position:"absolute",left:0,top:0,bottom:0,width:3,
                      background:hasResult?(isRight?"var(--cyan)":"var(--purple)"):"var(--border)"}}/>
                    <div style={{fontSize:14,flexShrink:0}}>
                      {hasResult?(isRight?"✓":"✗"):"—"}
                    </div>
                    <div style={{flex:1,minWidth:0,paddingLeft:4}}>
                      <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)",marginBottom:2}}>
                        {q.marketName}
                      </div>
                      <div style={{fontFamily:"var(--body)",fontSize:12,color:"var(--text)",lineHeight:1.3}}>
                        {q.question}
                      </div>
                      <div style={{display:"flex",gap:8,marginTop:3,flexWrap:"wrap"}}>
                        <span style={{fontFamily:"var(--mono)",fontSize:8,
                          color:isRight?"var(--cyan)":"var(--purple)",
                          background:isRight?"rgba(255,255,255,0.08)":"rgba(136,68,204,0.08)",
                          border:`1px solid ${isRight?"rgba(255,255,255,0.2)":"rgba(136,68,204,0.2)"}`,
                          padding:"1px 6px"}}>Your: {myAns||"—"}</span>
                        {correct_ans&&!isRight&&(
                          <span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)",
                            background:"rgba(255,255,255,0.06)",border:"1px solid rgba(255,255,255,0.15)",
                            padding:"1px 6px"}}>✓ {correct_ans}</span>
                        )}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>

            {/* Reward box */}
            <div style={{background:"rgba(0,0,0,0.5)",border:`1px solid ${scoreColor}44`,
              padding:"16px",marginBottom:16,position:"relative",overflow:"hidden"}}>
              <div style={{position:"absolute",top:0,left:0,right:0,height:2,
                background:`linear-gradient(90deg,transparent,${scoreColor},transparent)`}}/>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.6)",letterSpacing:"0.2em",marginBottom:12}}>REWARD SUMMARY</div>
              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:10,marginBottom:tier.multiplier>0?14:0}}>
                <div style={{textAlign:"center"}}>
                  <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.75)",marginBottom:4}}>ENTRY</div>
                  <div style={{fontFamily:"var(--display)",fontSize:14,fontWeight:700,color:"rgba(255,255,255,0.75)"}}>◈{challenge.cost}</div>
                </div>
                <div style={{textAlign:"center"}}>
                  <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.75)",marginBottom:4}}>RETURN</div>
                  <div style={{fontFamily:"var(--display)",fontSize:14,fontWeight:700,color:reward>0?"var(--cyan)":"var(--text-dim)"}}>
                    ◈{reward}
                  </div>
                </div>
                <div style={{textAlign:"center"}}>
                  <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.75)",marginBottom:4}}>PROFIT</div>
                  <div style={{fontFamily:"var(--display)",fontSize:14,fontWeight:700,
                    color:gained>0?"var(--cyan)":gained===0?"var(--text)":"var(--purple)"}}>
                    {gained>0?"+":""}◈{gained}
                  </div>
                </div>
              </div>
              {pack&&(
                <div style={{display:"flex",alignItems:"center",gap:10,padding:"10px",
                  background:cfg?`${cfg.color1}11`:"transparent",
                  border:`1px solid ${cfg?.color1}33`,borderRadius:2}}>
                  <div style={{width:18,height:18,borderRadius:"50%",background:cfg?.color1,boxShadow:`0 0 10px ${cfg?.glow}`,flexShrink:0}}></div>
                  <div>
                    <div style={{fontFamily:"var(--display)",fontSize:9,fontWeight:700,
                      color:cfg?.color3,letterSpacing:"0.12em"}}>+ {pack} STICKER PACK</div>
                    <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)",marginTop:2}}>
                      1 exclusive sticker inside
                    </div>
                  </div>
                </div>
              )}
            </div>

            {/* CTA */}
            {pack?(
              <Btn onClick={()=>{ onCollect&&onCollect(reward); setPhase("pack"); }}
                style={{width:"100%",padding:"16px",fontSize:12,letterSpacing:"0.12em"}}>
                COLLECT & OPEN PACK
              </Btn>
            ):(
              <Btn onClick={()=>{ onCollect&&onCollect(0); onBack(); }}
                variant="ghost" style={{width:"100%",padding:"14px",fontSize:11}}>
                BACK TO ARENA
              </Btn>
            )}
          </div>
        )}


      </div>
    </div>
  );
};

/* ─── ADMIN PANEL ────────────────────────────────────────────────── */
const AdminPanel = ({users,arenas,challenges,entries,dailyDrop,avatars,onBack,onSetDailyDrop,onAdHocDrop,onCreateArena,onToggleArena,onDeleteArena,onCreateChallenge,onToggleChallenge,onDeleteChallenge,onGradeChallenge}) => {
  const [tab,setTab]=useState("dashboard");
  const [dropAmt,setDropAmt]=useState(String(dailyDrop));
  const [adUser,setAdUser]=useState(""); const [adAmt,setAdAmt]=useState(""); const [adMsg,setAdMsg]=useState("");
  const [aName,setAName]=useState(""); const [aDesc,setADesc]=useState("");  const [aColor,setAColor]=useState("#ffffff"); const [aImage,setAImage]=useState(null);
    const [showCreator,setShowCreator]=useState(false);
  const [gradingCh,setGradingCh]=useState(null);
  const [fetchStatus,setFetchStatus]=useState(null);
  const [gradeAnswers,setGradeAnswers]=useState({}); // {questionId: correctAnswer}

  const handleArenaImageUpload=(e)=>{
    const file=e.target.files[0];
    if(!file)return;
    const reader=new FileReader();
    reader.onload=(ev)=>setAImage(ev.target.result);
    reader.readAsDataURL(file);
  };

  const TABS=[{id:"dashboard",l:"DASHBOARD"},{id:"drop",l:"REWARDS"},{id:"arenas",l:"ARENAS"},{id:"challenges",l:"CHALLENGES"},{id:"players",l:"PLAYERS"}];
  return (
    <div style={{minHeight:"100dvh",position:"relative",zIndex:1}}>
      <div style={{position:"sticky",top:0,zIndex:100,background:"rgba(0,0,0,0.98)",borderBottom:"1px solid var(--border-purple)",padding:"10px 14px",backdropFilter:"blur(8px)"}}>
        <div style={{display:"flex",alignItems:"center",gap:10,marginBottom:8}}>
          <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
          <div style={{fontFamily:"var(--display)",fontSize:12,fontWeight:700,color:"var(--purple)"}}>⚙ BACKOFFICE</div>
        </div>
        <div style={{display:"flex",gap:6,overflowX:"auto",paddingBottom:2}}>
          {TABS.map(t=>(
            <button key={t.id} onClick={()=>setTab(t.id)} style={{
              background:tab===t.id?"var(--purple)":"transparent",border:`1px solid ${tab===t.id?"var(--purple)":"var(--border)"}`,
              color:tab===t.id?"#fff":"var(--text-dim)",padding:"4px 10px",cursor:"pointer",
              fontFamily:"var(--mono)",fontSize:8,letterSpacing:"0.1em",whiteSpace:"nowrap"}}>{t.l}</button>
          ))}
        </div>
      </div>
      <div style={{padding:"14px"}}>
        {tab==="dashboard"&&(
          <div style={{animation:"slideUp .3s ease"}}>
            <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10,marginBottom:14}}>
              {[["PLAYERS",users.length,"var(--cyan)"],["ARENAS",arenas.filter(a=>a.active).length,"var(--purple)"],
                ["ACTIVE CHALLENGES",challenges.filter(c=>c.active).length,"var(--text-bright)"],["DAILY REWARD",`◈${dailyDrop}`,"var(--text-bright)"]].map(([k,v,c])=>(
                <Panel key={k} style={{padding:"12px 14px"}}>
                  <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)",letterSpacing:"0.15em"}}>{k}</div>
                  <div style={{fontFamily:"var(--display)",fontSize:22,fontWeight:700,color:c,marginTop:4}}>{v}</div>
                </Panel>
              ))}
            </div>
            <Panel>
              <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:10,letterSpacing:"0.15em"}}>RECENT AGENTS</div>
              {users.slice(-5).reverse().map(u=>(
                <div key={u.id} style={{display:"flex",alignItems:"center",gap:10,padding:"7px 0",borderBottom:"1px solid var(--border)"}}>
                  <span style={{fontSize:18}}>{avatars.find(a=>a.id===u.avatarId)?.emoji||"👤"}</span>
                  <div style={{flex:1}}>
                    <div style={{fontFamily:"var(--mono)",fontSize:11,color:"var(--text-bright)"}}>{u.username}</div>
                    <div style={{fontFamily:"var(--mono)",fontSize:8,color:getRank(u.xp||0).color}}>{getRank(u.xp||0).icon} {getRank(u.xp||0).name} · {(u.xp||0).toLocaleString()} XP</div>
                  </div>
                  <CoinBadge amount={u.coins} size="sm"/>
                </div>
              ))}
            </Panel>
          </div>
        )}
        {tab==="drop"&&(
          <div style={{animation:"slideUp .3s ease"}}>
            <Panel style={{marginBottom:14}}>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:12,letterSpacing:"0.15em"}}>◈ DAILY REWARD CONFIG</div>
              <div style={{fontFamily:"var(--body)",fontSize:12,color:"var(--text-dim)",marginBottom:12}}>
                Agents receive coins + <span style={{color:"var(--cyan)"}}>+{XP_CLAIM} XP</span> per daily claim.
              </div>
              <Field label="COINS PER DAY (0 = disabled)" value={dropAmt} onChange={setDropAmt}/>
              <Btn onClick={()=>onSetDailyDrop(parseInt(dropAmt)||0)} style={{width:"100%"}}>UPDATE DROP</Btn>
            </Panel>
            <Panel>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--purple)",marginBottom:12,letterSpacing:"0.15em"}}>⚡ MANUAL REWARD</div>
              <div style={{marginBottom:10}}>
                <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:6,letterSpacing:"0.12em"}}>TARGET</div>
                <select value={adUser} onChange={e=>setAdUser(e.target.value)}>
                  <option value="">ALL AGENTS (broadcast)</option>
                  {users.filter(u=>!u.isAdmin).map(u=><option key={u.id} value={u.id}>{u.username}</option>)}
                </select>
              </div>
              <Field label="AMOUNT" value={adAmt} onChange={setAdAmt}/>
              <Field label="NOTE (optional)" value={adMsg} onChange={setAdMsg} placeholder="reason"/>
              <Btn onClick={()=>{onAdHocDrop(adUser||null,parseInt(adAmt)||0,adMsg);setAdAmt("");setAdMsg("");setAdUser("");}} variant="danger" style={{width:"100%"}}>EXECUTE DROP</Btn>
            </Panel>
          </div>
        )}
        {tab==="arenas"&&(
          <div style={{animation:"slideUp .3s ease"}}>
            <Panel style={{marginBottom:14}}>
              <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:12,letterSpacing:"0.15em"}}>+ CREATE ARENA</div>
              <Field label="NAME" value={aName} onChange={setAName} placeholder="PHANTOM ZONE"/>
              <Field label="DESCRIPTION" value={aDesc} onChange={setADesc}/>
              <Field label="COLOR (hex)" value={aColor} onChange={setAColor}/>
              <div style={{marginBottom:13}}>
                <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--cyan)",marginBottom:5,letterSpacing:"0.15em"}}>ARENA IMAGE</div>
                <label style={{display:"flex",alignItems:"center",justifyContent:"center",gap:10,
                  border:"1px dashed var(--border)",background:"rgba(0,0,0,0.4)",
                  padding:"10px 14px",cursor:"pointer",fontFamily:"var(--mono)",fontSize:11,color:"var(--text-dim)"}}>
                  <span>📁</span>
                  {aImage?"IMAGE LOADED — TAP TO REPLACE":"UPLOAD ARENA IMAGE"}
                  <input type="file" accept="image/*" onChange={handleArenaImageUpload} style={{display:"none"}}/>
                </label>
                {aImage&&(
                  <div style={{marginTop:8,position:"relative",height:90,overflow:"hidden",border:`1px solid ${aColor}55`}}>
                    <img src={aImage} alt="preview" style={{width:"100%",height:"100%",objectFit:"cover",filter:"brightness(0.5)"}}/>
                    <button onClick={()=>setAImage(null)} style={{position:"absolute",top:5,right:5,background:"var(--purple)",border:"none",color:"#fff",cursor:"pointer",padding:"2px 7px",fontFamily:"var(--mono)",fontSize:9}}>✕ REMOVE</button>
                  </div>
                )}
              </div>
              <Btn onClick={()=>{if(!aName)return;onCreateArena({id:uid(),name:aName.toUpperCase(),desc:aDesc,color:aColor,imageUrl:aImage||null,active:true});setAName("");setADesc("");setAColor("#ffffff");setAImage(null);}} style={{width:"100%"}}>CREATE ARENA</Btn>
            </Panel>
            <div style={{display:"flex",flexDirection:"column",gap:8}}>
              {arenas.map(a=>(
                <Panel key={a.id} style={{padding:"10px 14px"}}>
                  <div style={{display:"flex",alignItems:"center",gap:10}}>
                    <div style={{flex:1}}>
                      <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)"}}>{a.code}</div>
                      <div style={{fontFamily:"var(--display)",fontSize:12,color:a.color}}>{a.name}</div>
                    </div>
                    <div style={{display:"flex",gap:6}}>
                    <Btn onClick={()=>onToggleArena(a.id)} variant={a.active?"ghost":"secondary"} size="sm">{a.active?"DISABLE":"ENABLE"}</Btn>
                    <Btn onClick={()=>onDeleteArena(a.id)} variant="danger" size="sm">DEL</Btn>
                  </div>
                  </div>
                </Panel>
              ))}
            </div>
          </div>
        )}
        {tab==="challenges"&&(
          <div style={{animation:"slideUp .3s ease"}}>
            {gradingCh ? (
              // GRADING INTERFACE
              <div>
                <div style={{display:"flex",alignItems:"center",gap:10,marginBottom:14}}>
                  <button onClick={()=>{setGradingCh(null);setGradeAnswers({});setFetchStatus(null);}} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:18}}>←</button>
                  <div>
                    <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.15em"}}>SCORE — {gradingCh.name}</div>
                    <div style={{fontFamily:"var(--display)",fontSize:12,color:"var(--text-bright)"}}>{gradingCh.name}</div>
                  </div>
                </div>

                {/* ── FETCH RESULTS button ── */}
                <div style={{marginBottom:14}}>
                  <Btn onClick={async()=>{
                    setFetchStatus("loading");
                    try {
                      const questions = (gradingCh.questionPool||[]).slice(0,8);
                      const teamPairs = [...new Set(questions.map(q=>`${q.teamA?.name||q.answers[0]}|${q.teamB?.name||q.answers[1]}`))];
                      const pandaResults = {};

                      for(const pair of teamPairs){
                        const [tA,tB] = pair.split("|");
                        try {
                          const fuzzyT = (a,b) => {
                            a=(a||"").toLowerCase().replace(/team |esports/g,"").trim();
                            b=(b||"").toLowerCase().replace(/team |esports/g,"").trim();
                            return a.includes(b)||b.includes(a)||a.slice(0,4)===b.slice(0,4);
                          };
                          const matches = await pandaFetch(
                            `/csgo/matches/past?sort=-scheduled_at&page[size]=50&filter[status]=finished&search[name]=${encodeURIComponent(tA)}`
                          );
                          const cutoff = new Date(); cutoff.setDate(cutoff.getDate()-60);
                          const found = Array.isArray(matches) && matches.find(m=>{
                            if(m.status!=="finished") return false;
                            const d=m.scheduled_at||m.begin_at||m.original_scheduled_at;
                            if(d && new Date(d)<cutoff) return false;
                            const names=(m.opponents||[]).map(o=>o.opponent?.name||"");
                            return names.some(n=>fuzzyT(n,tA)) && names.some(n=>fuzzyT(n,tB));
                          });
                          if(found) pandaResults[pair]=found;
                          else console.log("PandaScore: no recent match for",tA,"vs",tB);
                        } catch(e){ console.warn("PandaScore error:",e.message); }
                      }

                      const filled = {...gradeAnswers};
                      let autoFilled = 0;

                      for(const q of questions){
                        const tA=q.teamA?.name||q.answers[0];
                        const tB=q.teamB?.name||q.answers[1];
                        const fuzzy=(a,b)=>{
                          a=(a||"").toLowerCase().replace(/team |esports/g,"").trim();
                          b=(b||"").toLowerCase().replace(/team |esports/g,"").trim();
                          return a.includes(b)||b.includes(a);
                        };
                        const pairKey=Object.keys(pandaResults).find(k=>{
                          const [ka,kb]=k.split("|");
                          return (fuzzy(ka,tA)||fuzzy(tA,ka))&&(fuzzy(kb,tB)||fuzzy(tB,kb));
                        });
                        if(!pairKey) continue;
                        const match=pandaResults[pairKey];
                        const winnerId=match.winner_id;
                        const opps=match.opponents||[];
                        const winnerName=opps.find(o=>o.opponent?.id===winnerId)?.opponent?.name;
                        if(!winnerName) continue;
                        const winnerIsA=fuzzy(q.answers[0],winnerName);
                        const scores=match.results||[];
                        const sA=scores[0]?.score??0, sB=scores[1]?.score??0;
                        const games=match.games||[];
                        const marketLow=(q.marketName||"").toLowerCase();

                        if(marketLow.includes("match winner")){
                          filled[q.id]=winnerIsA?q.answers[0]:q.answers[1]; autoFilled++;
                        } else if(marketLow.includes("map 1 winner")&&games[0]?.winner_id){
                          const mn=opps.find(o=>o.opponent?.id===games[0].winner_id)?.opponent?.name;
                          if(mn){filled[q.id]=fuzzy(q.answers[0],mn)?q.answers[0]:q.answers[1];autoFilled++;}
                        } else if(marketLow.includes("map 2 winner")&&games[1]?.winner_id){
                          const mn=opps.find(o=>o.opponent?.id===games[1].winner_id)?.opponent?.name;
                          if(mn){filled[q.id]=fuzzy(q.answers[0],mn)?q.answers[0]:q.answers[1];autoFilled++;}
                        } else if(marketLow.includes("total maps")){
                          const total=sA+sB;
                          const ans=q.answers.find(a=>(total>=3&&a.toLowerCase().includes("yes"))||(total<3&&a.toLowerCase().includes("no")));
                          if(ans){filled[q.id]=ans;autoFilled++;}
                        } else if(marketLow.includes("overtime")&&games[0]){
                          const rc=games[0].round_count??games[0].rounds_played??null;
                          if(rc!==null){const ans=rc>30?q.answers.find(a=>a.toLowerCase()==="yes"):q.answers.find(a=>a.toLowerCase()==="no");if(ans){filled[q.id]=ans;autoFilled++;}}
                        } else if(marketLow.includes("rounds")&&games[0]){
                          const rc=games[0].round_count??games[0].rounds_played??null;
                          if(rc!==null){const ans=rc>26.5?q.answers.find(a=>a.toLowerCase().includes("over")):q.answers.find(a=>a.toLowerCase().includes("under"));if(ans){filled[q.id]=ans;autoFilled++;}}
                        }
                      }

                      setGradeAnswers(filled);
                      setFetchStatus(autoFilled>0
                        ? `✓ Auto-filled ${autoFilled}/${questions.length} answers from PandaScore. Review and complete the rest.`
                        : "No matching finished matches found on PandaScore (Tier S only). Fill manually below."
                      );
                    } catch(e){
                      setFetchStatus("PandaScore error: "+e.message+". Fill manually below.");
                    }
                  }} variant="secondary" style={{width:"100%",marginBottom:6}}>
                    ⟳ FETCH RESULTS FROM PANDASCORE
                  </Btn>
                  {fetchStatus&&(
                    <div style={{fontFamily:"var(--mono)",fontSize:8,padding:"6px 10px",
                      background: fetchStatus==="loading"?"rgba(255,255,255,0.04)":
                        fetchStatus.includes("error")||fetchStatus.includes("No completed")?"rgba(136,68,204,0.1)":"rgba(123,200,67,0.1)",
                      border:`1px solid ${fetchStatus.includes("error")||fetchStatus.includes("No completed")?"rgba(136,68,204,0.3)":"rgba(123,200,67,0.3)"}`,
                      color:fetchStatus==="loading"?"var(--text-dim)":
                        fetchStatus.includes("error")||fetchStatus.includes("No completed")?"var(--purple)":"var(--cyan)"}}>
                      {fetchStatus==="loading"?"Fetching results...":fetchStatus}
                    </div>
                  )}
                </div>

                <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",marginBottom:10,letterSpacing:"0.12em"}}>
                  MANUAL RESULTS — select correct answer for each question:
                </div>
                {(gradingCh.questionPool||[]).slice(0,8).map((q,i)=>(                  <Panel key={q.id} style={{marginBottom:10,padding:"10px 14px"}}>
                    <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)",marginBottom:4}}>{q.marketName} · {q.matchLabel}</div>
                    <div style={{fontFamily:"var(--body)",fontSize:13,color:"var(--text-bright)",marginBottom:10,lineHeight:1.3}}>{q.question}</div>
                    <div style={{display:"flex",flexDirection:"column",gap:7}}>
                      {q.answers.map(opt=>{
                        const sel=gradeAnswers[q.id]===opt;
                        return(
                          <button key={opt} onClick={()=>setGradeAnswers(prev=>({...prev,[q.id]:opt}))} style={{
                            background:sel?"rgba(123,200,67,0.14)":"rgba(0,0,0,0.35)",
                            border:`1px solid ${sel?"var(--cyan)":"var(--border)"}`,
                            color:sel?"var(--cyan)":"var(--text)",padding:"8px 12px",cursor:"pointer",
                            fontFamily:"var(--body)",fontSize:13,textAlign:"left",
                            display:"flex",alignItems:"center",gap:8}}>
                            <div style={{width:14,height:14,border:`1px solid ${sel?"var(--cyan)":"var(--border)"}`,
                              background:sel?"var(--cyan)":"transparent",borderRadius:"50%",flexShrink:0,
                              display:"flex",alignItems:"center",justifyContent:"center",fontSize:8,color:"var(--bg)"}}>
                              {sel&&"✓"}
                            </div>
                            {opt}
                          </button>
                        );
                      })}
                    </div>
                  </Panel>
                ))}
                <Btn onClick={()=>{
                  const answered=Object.keys(gradeAnswers).length;
                  const total=(gradingCh.questionPool||[]).slice(0,8).length;
                  if(answered<total){showToast(`Answer all ${total} questions first`,"error");return;}
                  onGradeChallenge(gradingCh.id,gradeAnswers);
                  setGradingCh(null);setGradeAnswers({});setFetchStatus(null);setFetchStatus(null);
                }} style={{width:"100%",marginTop:4}}>
                  ✓ PUBLISH RESULTS
                </Btn>
              </div>
            ) : !showCreator ? (
              <>
                <Btn onClick={()=>setShowCreator(true)} style={{width:"100%",marginBottom:14}}>+ CREATE CHALLENGE</Btn>
                <div style={{display:"flex",flexDirection:"column",gap:8}}>
                  {challenges.map(ch=>{
                    const arena=arenas.find(a=>a.id===ch.arenaId);
                    const mCount=(ch.matches||[]).length;
                    const entryCount=(entries||[]).filter(e=>e.challengeId===ch.id&&e.locked).length;
                    return (
                      <Panel key={ch.id} style={{padding:"10px 14px"}}>
                        <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start"}}>
                          <div style={{flex:1,marginRight:8}}>
                            <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)"}}>{arena?.code}</div>
                            <div style={{fontFamily:"var(--display)",fontSize:11,color:"var(--text-bright)"}}>{ch.name}</div>
                            <div style={{display:"flex",gap:7,marginTop:4,alignItems:"center",flexWrap:"wrap"}}>
            
                              <span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)"}}>◈{ch.cost} entry · up to ◈{Math.round(ch.cost*2.5)}</span>
                              {mCount>0&&<span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)"}}>{mCount} matches</span>}
                              {entryCount>0&&<span style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)"}}>{entryCount} players</span>}
                              {ch.graded&&<span style={{fontFamily:"var(--mono)",fontSize:8,color:"#00ff88",border:"1px solid #00ff8855",padding:"1px 5px"}}>SCORED</span>}
                            </div>
                          </div>
                          <div style={{display:"flex",gap:6,flexShrink:0}}>
                            {ch.active&&!ch.graded&&(
                              <Btn onClick={()=>{setGradingCh(ch);setGradeAnswers(ch.correctAnswers||{});}} variant="secondary" size="sm">SCORE</Btn>
                            )}
                            <div style={{display:"flex",gap:6}}>
                              <Btn onClick={()=>onToggleChallenge(ch.id)} variant={ch.active?"ghost":"secondary"} size="sm">{ch.active?"OFF":"ON"}</Btn>
                              <Btn onClick={()=>onDeleteChallenge(ch.id)} variant="danger" size="sm">DEL</Btn>
                            </div>
                          </div>
                        </div>
                      </Panel>
                    );
                  })}
                </div>
              </>
            ) : (
              <AdminChallengeCreator
                arenas={arenas}
                onCreate={(ch)=>{onCreateChallenge(ch);setShowCreator(false);}}
                onCancel={()=>setShowCreator(false)}
              />
            )}
          </div>
        )}
        {tab==="players"&&(
          <div style={{animation:"slideUp .3s ease",display:"flex",flexDirection:"column",gap:8}}>
            {users.map(u=>(
              <Panel key={u.id} style={{padding:"10px 14px"}}>
                <div style={{display:"flex",alignItems:"center",gap:10}}>
                  <span style={{fontSize:22}}>{avatars.find(a=>a.id===u.avatarId)?.emoji||"👤"}</span>
                  <div style={{flex:1}}>
                    <div style={{fontFamily:"var(--mono)",fontSize:11,color:"var(--text-bright)"}}>{u.username}{u.isAdmin&&<span style={{color:"var(--purple)",fontSize:8,marginLeft:6}}>ADMIN</span>}</div>
                    <div style={{fontFamily:"var(--mono)",fontSize:8,color:getRank(u.xp||0).color}}>{getRank(u.xp||0).icon} {getRank(u.xp||0).name} · {(u.xp||0).toLocaleString()} XP</div>
                  </div>
                  <CoinBadge amount={u.coins} size="sm"/>
                </div>
              </Panel>
            ))}
          </div>
        )}

      </div>
    </div>
  );
};

/* ─── ROOT APP ───────────────────────────────────────────────────── */

/* ─── MY CARDS SCREEN ───────────────────────────────────────────── */
const MyCardsScreen = ({cards, onBack, lang="en"}) => {
  const t = LANG[lang]||LANG.en;
  const [selected, setSelected] = useState(null);
  const tierOrder = {PLATINUM:0, GOLD:1, SILVER:2, BRONZE:3};
  const sorted = [...(cards||[])].sort((a,b)=>(tierOrder[a.packType]??9)-(tierOrder[b.packType]??9));

  if(selected) return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={()=>setSelected(null)} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1,fontFamily:"var(--display)",fontSize:12,fontWeight:700,color:"var(--text-bright)"}}>
          {selected.challenge?.sticker?.charName||selected.challenge?.name||"STICKER"}
        </div>
        <div style={{fontFamily:"var(--mono)",fontSize:9,color:PACK_CONFIG[selected.packType]?.color1,
          border:`1px solid ${PACK_CONFIG[selected.packType]?.color1}44`,padding:"3px 8px"}}>
          {selected.packType}
        </div>
      </div>
      <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden"}}>
        <StickerCard packType={selected.packType} challenge={selected.challenge}/>
      </div>
      <div style={{padding:"8px 16px 20px",flexShrink:0,fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.3)",textAlign:"center",letterSpacing:"0.1em"}}>
        ← DRAG TO ROTATE →
      </div>
    </div>
  );

  return (
    <div style={{minHeight:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:1}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>COLLECTION</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>MY CARDS</div>
        </div>
        <div style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--cyan)",background:"rgba(255,255,255,0.07)",border:"1px solid var(--border)",padding:"4px 10px"}}>
          {sorted.length}
        </div>
      </div>

      {sorted.length===0 ? (
        <div style={{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:16,padding:24}}>
          <img src={LOGO_SRC} alt="DFUSE" style={{width:120,opacity:0.2,display:"block",margin:"0 auto"}}/>
          <div style={{fontFamily:"var(--display)",fontSize:13,color:"rgba(255,255,255,0.3)",letterSpacing:"0.15em"}}>{t.noCardsYet}</div>
          <div style={{fontFamily:"var(--mono)",fontSize:9,color:"rgba(255,255,255,0.2)",textAlign:"center",lineHeight:1.6}}>{t.completeEarn}</div>
        </div>
      ) : (
        <div style={{flex:1,overflowY:"auto",padding:"16px"}}>
          {["PLATINUM","GOLD","SILVER","BRONZE"].map(tier=>{
            const tierCards=sorted.filter(c=>c.packType===tier);
            if(!tierCards.length)return null;
            const cfg2=PACK_CONFIG[tier];
            return (
              <div key={tier} style={{marginBottom:24}}>
                <div style={{fontFamily:"var(--mono)",fontSize:8,color:cfg2.color1,letterSpacing:"0.2em",marginBottom:10,display:"flex",alignItems:"center",gap:8}}>
                  <span>{cfg2.label}</span><span style={{color:"rgba(255,255,255,0.2)"}}>·</span>
                  <span style={{color:"rgba(255,255,255,0.3)"}}>{tierCards.length}</span>
                </div>
                <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10}}>
                  {tierCards.map(card=>{
                    const sticker=card.challenge?.sticker||{};
                    return (
                      <div key={card.id} onClick={()=>setSelected(card)}
                        style={{background:"rgba(255,255,255,0.04)",border:`1px solid ${cfg2.color1}33`,borderRadius:8,overflow:"hidden",cursor:"pointer",boxShadow:`0 0 12px ${cfg2.glow}33`}}>
                        <div style={{height:140,position:"relative",overflow:"hidden",background:cfg2.cardBg}}>
                          {sticker.bg&&<img src={sticker.bg} style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",opacity:0.7}}/>}
                          {sticker.main&&<img src={sticker.main} style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",objectPosition:"center top"}}/>}
                          {!sticker.main&&<div style={{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center"}}>
                            <div style={{fontFamily:"var(--display)",fontSize:22,fontWeight:900,color:cfg2.color3,textShadow:`0 0 12px ${cfg2.glow}`,opacity:0.6}}>DF</div>
                          </div>}
                          <div style={{position:"absolute",bottom:0,left:0,right:0,height:40,background:"linear-gradient(0deg,rgba(0,0,0,0.9),transparent)"}}/>
                          <div style={{position:"absolute",top:6,left:6,fontFamily:"var(--mono)",fontSize:7,color:cfg2.color1,background:"rgba(0,0,0,0.75)",border:`1px solid ${cfg2.color1}55`,padding:"1px 5px",letterSpacing:"0.1em"}}>
                            {cfg2.cardLabel.toUpperCase()}
                          </div>
                        </div>
                        <div style={{padding:"8px 10px"}}>
                          <div style={{fontFamily:"var(--display)",fontSize:11,fontWeight:700,color:cfg2.color3,letterSpacing:"0.08em",lineHeight:1.2,marginBottom:2,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>
                            {sticker.charName||card.challenge?.name||"PLAYER"}
                          </div>
                          <div style={{fontFamily:"var(--mono)",fontSize:7,color:"rgba(255,255,255,0.35)",letterSpacing:"0.06em",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>
                            {card.challenge?.name||""}
                          </div>
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

/* ─── SHARE HELPER ───────────────────────────────────────────────── */
const shareToWhatsapp = async (message, captureRef) => {
  const fullMsg = `${message}\n${APP_URL}`;

  const sendWhatsapp = () => {
    window.open(`https://wa.me/?text=${encodeURIComponent(fullMsg)}`,"_blank","noopener,noreferrer");
  };

  // Try to capture screenshot
  if(captureRef?.current && window.html2canvas) {
    try {
      const canvas = await window.html2canvas(captureRef.current, {
        backgroundColor:"#000000",
        scale:2,
        useCORS:true,
        allowTaint:true,
        logging:false,
        ignoreElements:(el)=>el.tagName==="SCRIPT"
      });
      
      // Try Web Share API with image (works on mobile HTTPS)
      canvas.toBlob(async(blob)=>{
        try {
          const file = new File([blob],"dfuse.png",{type:"image/png"});
          if(navigator.canShare && navigator.canShare({files:[file]})){
            await navigator.share({files:[file], text:fullMsg, title:"DFUSE"});
          } else if(navigator.share){
            await navigator.share({text:fullMsg, title:"DFUSE", url:APP_URL});
          } else {
            sendWhatsapp();
          }
        } catch(e){
          // User cancelled share or not supported — fallback
          if(e.name!=="AbortError") sendWhatsapp();
        }
      },"image/png",0.92);
    } catch(e){
      sendWhatsapp();
    }
  } else if(navigator.share){
    try {
      await navigator.share({text:fullMsg, title:"DFUSE", url:APP_URL});
    } catch(e){
      if(e.name!=="AbortError") sendWhatsapp();
    }
  } else {
    sendWhatsapp();
  }
};

const ShareBtn = ({label, message, captureRef, style={}}) => (
  <button
    onClick={()=>shareToWhatsapp(message, captureRef)}
    style={{
      display:"flex",alignItems:"center",justifyContent:"center",gap:8,
      background:"#25D366",border:"none",cursor:"pointer",
      padding:"12px 16px",width:"100%",
      fontFamily:"var(--mono)",fontSize:11,fontWeight:700,
      letterSpacing:"0.1em",color:"#000",...style}}>
    <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
      <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347z"/>
      <path d="M12 0C5.373 0 0 5.373 0 12c0 2.125.558 4.122 1.528 5.855L0 24l6.335-1.508A11.945 11.945 0 0012 24c6.627 0 12-5.373 12-12S18.627 0 12 0zm0 21.818a9.818 9.818 0 01-5.006-1.369l-.36-.214-3.728.888.92-3.633-.236-.374A9.818 9.818 0 012.182 12C2.182 6.57 6.57 2.182 12 2.182S21.818 6.57 21.818 12 17.43 21.818 12 21.818z"/>
    </svg>
    {label}
  </button>
);


/* ─── LANGUAGE SELECTOR ──────────────────────────────────────────── */
const LangSelector = ({lang, setLanguage}) => (
  <select
    value={lang}
    onChange={e=>setLanguage(e.target.value)}
    style={{background:"rgba(255,255,255,0.07)",border:"1px solid var(--border)",
      color:"var(--text)",fontFamily:"var(--mono)",fontSize:9,padding:"4px 6px",
      cursor:"pointer",letterSpacing:"0.06em",outline:"none"}}>
    <option value="en">🇬🇧 EN</option>
    <option value="pt">🇧🇷 PT</option>
  </select>
);

/* ─── HOW TO PLAY SCREEN ─────────────────────────────────────────── */
const HowToPlayScreen = ({onBack, lang}) => {
  const t = LANG[lang]||LANG.en;
  const sections = lang==="pt" ? [
    { title:"O QUE É O DFUSE?", items:[
      "DFUSE é uma plataforma de picks de esports — você escolhe os resultados antes dos jogos.",
      "Não é apostas — é habilidade. Quanto mais você acerta, mais moedas e XP ganha.",
      "Complete desafios, suba de rank e colecione figurinhas exclusivas dos jogos.",
    ]},
    { title:"COMO FUNCIONA?", items:[
      "Escolha uma arena e entre em um desafio antes do prazo de inscrição.",
      "Você paga uma entrada em moedas e faz seus picks.",
      "Confirme seus picks com o botão CONFIRMAR. Após isso, não é possível alterar.",
      "Aguarde os resultados. Quando o admin publicar, você vê automaticamente o seu placar.",
    ]},
    { title:"RECOMPENSAS", items:[
      "0/4 acertos → sem recompensa.",
      "1/4 acertos → reembolso + 🥉 card pack BRONZE.",
      "2/4 acertos → 1.5× moedas + 🥈 card pack SILVER.",
      "3/4 acertos → 2× moedas + 🥇 card pack GOLD.",
      "4/4 acertos → 2.5× moedas + 💎 card pack PLATINUM.",
      
    ]},
    { title:"MOEDAS & XP", items:[
      "Comece com 0 moedas — faça o claim diário para receber 100 moedas e 50 XP.",
      "Cada desafio participado dá +100 XP, independente do resultado.",
      "Use moedas para entrar nos desafios. Ganhe mais acertando os picks.",
      "XP acumulado aumenta seu rank: Ghost → Recruit → Operative → ... → Phantom.",
    ]},
    { title:"FIGURINHAS", items:[
      "Ao vencer moedas em um desafio, você recebe um card pack temático.",
      "Abra o pack e desbloqueie uma figurinha exclusiva do desafio.",
      "Gire a figurinha em 3D antes de salvar na sua coleção.",
      "Veja todas as suas figurinhas em MY CARDS.",
    ]},
    { title:"DICAS", items:[
      
      "Faça o claim diário todos os dias para acumular moedas.",
      
      "Partilhe seus picks com amigos e desafie-os a bater você.",
    ]},
  ] : [
    { title:"WHAT IS DFUSE?", items:[
      "DFUSE is an esports picks platform — predict match outcomes before games happen.",
      "It's not gambling — it's skill. The more you get right, the more coins and XP you earn.",
      "Complete challenges, climb the ranks and collect exclusive match sticker cards.",
    ]},
    { title:"HOW DOES IT WORK?", items:[
      "Pick an arena and join a challenge before the entry deadline.",
      "Pay an entry fee in coins and make your picks.",
      "Lock in your picks. After locking, no changes are allowed.",
      "Wait for results. When the admin publishes scores, you see your result instantly.",
    ]},
    { title:"REWARDS", items:[
      "0/4 correct → no reward.",
      "1/4 correct → refund + 🥉 BRONZE card pack.",
      "2/4 correct → 1.5× coins + 🥈 SILVER card pack.",
      "3/4 correct → 2× coins + 🥇 GOLD card pack.",
      "4/4 correct → 2.5× coins + 💎 PLATINUM card pack.",
    ]},
    { title:"COINS & XP", items:[
      "Start with 0 coins — do your daily claim for 100 coins and 50 XP.",
      "Each challenge gives +100 XP regardless of result.",
      "Spend coins to enter challenges. Win more by getting picks right.",
      "XP builds your rank: Ghost → Recruit → Operative → ... → Phantom.",
    ]},
    { title:"STICKER CARDS", items:[
      "Win a reward and you get a themed card pack.",
      "Open the pack and reveal an exclusive match sticker card.",
      "Spin the card in 3D before saving it to your collection.",
      "View all your cards in MY CARDS.",
    ]},
    { title:"TIPS", items:[
      
      "Claim your daily reward every day to stack coins.",
      
      "Share your picks with friends and challenge them to beat your score.",
    ]},
  ];

  return (
    <div style={{height:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",overflow:"hidden"}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>DFUSE</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>{t.howToPlay}</div>
        </div>
        <img src={LOGO_SRC} alt="DFUSE" style={{height:24,display:"block"}}/>
      </div>

      <div style={{flex:1,overflowY:"auto",padding:"16px 14px 32px",display:"flex",flexDirection:"column",gap:20,minHeight:0}}>
        {sections.map((s,i)=>(
          <div key={i}>
            <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)",letterSpacing:"0.2em",marginBottom:10,
              borderBottom:"1px solid rgba(123,200,67,0.2)",paddingBottom:5}}>
              {s.title}
            </div>
            <div style={{display:"flex",flexDirection:"column",gap:7}}>
              {s.items.map((item,j)=>(
                <div key={j} style={{display:"flex",gap:10,alignItems:"flex-start"}}>
                  <span style={{color:"var(--purple)",fontWeight:900,flexShrink:0,marginTop:1}}>▸</span>
                  <span style={{fontFamily:"var(--body)",fontSize:13,color:"rgba(255,255,255,0.75)",lineHeight:1.5}}>{item}</span>
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};


/* ─── LEADERBOARD SCREEN ─────────────────────────────────────────── */
const LeaderboardScreen = ({currentUser, users, myCards, onBack}) => {
  const [search, setSearch] = useState("");

  // Sort all users by XP descending
  const ranked = [...users]
    .filter(u=>!u.isAdmin)
    .sort((a,b)=>(b.xp||0)-(a.xp||0))
    .map((u,i)=>({...u, pos:i+1}));

  const myPos = ranked.find(u=>u.id===currentUser.id)?.pos||1;

  const filtered = search.trim()
    ? ranked.filter(u=>u.username.toLowerCase().includes(search.toLowerCase()))
    : ranked;

  const cardCount = (userId) => myCards.filter(c=>c.userId===userId||userId===currentUser.id&&c).length;
  // For demo: show myCards count for current user, 0 for others (real app would have per-user cards)
  const getCards = (u) => u.id===currentUser.id ? myCards.length : (u.cardCount||0);

  const Row = ({u, highlight=false}) => {
    const rank = getRank(u.xp||0);
    const av = u.avatarId;
    const isMe = u.id===currentUser.id;
    const cards = getCards(u);
    const medal = u.pos===1?"🥇":u.pos===2?"🥈":u.pos===3?"🥉":null;

    return (
      <div style={{
        display:"flex",alignItems:"center",gap:10,padding:"10px 12px",
        background: highlight
          ? `linear-gradient(90deg,rgba(123,200,67,0.12),rgba(136,68,204,0.08))`
          : isMe ? "rgba(123,200,67,0.06)" : "rgba(255,255,255,0.02)",
        border: highlight
          ? "1px solid rgba(123,200,67,0.4)"
          : isMe ? "1px solid rgba(123,200,67,0.2)" : "1px solid rgba(255,255,255,0.05)",
        borderRadius:2,
      }}>
        {/* Position */}
        <div style={{width:28,flexShrink:0,textAlign:"center"}}>
          {medal
            ? <span style={{fontSize:16}}>{medal}</span>
            : <span style={{fontFamily:"var(--mono)",fontSize:10,color:"rgba(255,255,255,0.35)"}}>#{u.pos}</span>}
        </div>

        {/* Username + rank */}
        <div style={{flex:1,minWidth:0}}>
          <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:1}}>
            <span style={{fontFamily:"var(--display)",fontSize:12,fontWeight:700,
              color: highlight?"var(--cyan)":isMe?"var(--cyan)":"var(--text-bright)",
              letterSpacing:"0.06em",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>
              {u.username.toUpperCase()}
            </span>
            {isMe&&<span style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--cyan)",
              border:"1px solid rgba(123,200,67,0.5)",padding:"1px 4px",flexShrink:0}}>YOU</span>}
          </div>
          <div style={{display:"flex",alignItems:"center",gap:5}}>
            <span style={{fontFamily:"var(--mono)",fontSize:8,color:rank.color,letterSpacing:"0.06em"}}>
              {rank.icon} {rank.name}
            </span>
            <span style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.25)"}}>·</span>
            <span style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.35)"}}>
              {(u.xp||0).toLocaleString()} XP
            </span>
          </div>
        </div>

        {/* Cards count */}
        <div style={{textAlign:"center",flexShrink:0,minWidth:44}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.35)",marginBottom:1}}>CARDS</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,
            color:cards>0?"var(--purple)":"rgba(255,255,255,0.2)"}}>{cards}</div>
        </div>
      </div>
    );
  };

  const myEntry = ranked.find(u=>u.id===currentUser.id)||{...currentUser,pos:ranked.length+1};

  return (
    <div style={{height:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",overflow:"hidden"}}>
      {/* Header */}
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>GLOBAL RANKING</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>RANKING</div>
        </div>
        <div style={{fontFamily:"var(--mono)",fontSize:9,color:"var(--text-dim)"}}>
          {ranked.length} PLAYERS
        </div>
      </div>

      {/* Current user pinned at top — only for non-admin players */}
      {!currentUser.isAdmin&&(
        <div style={{padding:"10px 14px",borderBottom:"1px solid var(--border)",flexShrink:0,
          background:"rgba(0,0,0,0.4)"}}>
          <div style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--text-dim)",letterSpacing:"0.2em",marginBottom:6}}>YOUR POSITION</div>
          <Row u={myEntry} highlight={true}/>
        </div>
      )}

      {/* Search */}
      <div style={{padding:"10px 14px",borderBottom:"1px solid var(--border)",flexShrink:0}}>
        <input
          value={search} onChange={e=>setSearch(e.target.value)}
          placeholder="Search player..."
          style={{width:"100%",background:"rgba(255,255,255,0.04)",border:"1px solid var(--border)",
            color:"var(--text-bright)",fontFamily:"var(--mono)",fontSize:11,padding:"7px 10px",
            outline:"none",letterSpacing:"0.04em"}}/>
      </div>

      {/* Ranking list */}
      <div style={{flex:1,overflowY:"auto",padding:"10px 14px",minHeight:0,display:"flex",flexDirection:"column",gap:4}}>
        {filtered.length===0
          ? <div style={{textAlign:"center",padding:40,fontFamily:"var(--mono)",fontSize:10,color:"rgba(255,255,255,0.2)"}}>
              NO PLAYERS FOUND
            </div>
          : filtered.map(u=><Row key={u.id} u={u}/>)}
      </div>
    </div>
  );
};


/* ─── RANKS SCREEN ───────────────────────────────────────────────── */
const RanksScreen = ({user, onBack}) => {
  const currentRank = getRank(user.xp||0);
  const nextRank    = getNextRank(user.xp||0);
  const progress    = getXPProgress(user.xp||0);

  return (
    <div style={{height:"100dvh",display:"flex",flexDirection:"column",background:"var(--bg)",position:"relative",zIndex:9999,overflow:"hidden"}}>
      <div style={{padding:"12px 14px",borderBottom:"1px solid var(--border)",display:"flex",alignItems:"center",gap:10,flexShrink:0}}>
        <button onClick={onBack} style={{background:"none",border:"none",cursor:"pointer",color:"var(--text)",fontSize:20}}>←</button>
        <div style={{flex:1}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--text-dim)",letterSpacing:"0.2em"}}>PROGRESSION</div>
          <div style={{fontFamily:"var(--display)",fontSize:13,fontWeight:700,color:"var(--text-bright)"}}>RANK SYSTEM</div>
        </div>
      </div>

      <div style={{flex:1,overflowY:"auto",padding:"16px 14px 24px",minHeight:0}}>

        {/* Current status */}
        <div style={{background:"rgba(255,255,255,0.04)",border:`1px solid ${currentRank.color}44`,padding:"14px",marginBottom:16}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",letterSpacing:"0.2em",marginBottom:8}}>YOUR STATUS</div>
          <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:8}}>
            <div style={{fontFamily:"var(--display)",fontSize:18,fontWeight:900,color:currentRank.color,letterSpacing:"0.1em"}}>
              {currentRank.icon} {currentRank.name}
            </div>
            <div style={{fontFamily:"var(--mono)",fontSize:11,color:"rgba(255,255,255,0.7)"}}>
              {(user.xp||0).toLocaleString()} XP
            </div>
          </div>
          <div style={{height:4,background:"rgba(255,255,255,0.08)",borderRadius:2,overflow:"hidden",marginBottom:6}}>
            <div style={{height:"100%",width:`${progress}%`,background:`linear-gradient(90deg,var(--cyan),${currentRank.color})`,transition:"width 0.8s ease"}}/>
          </div>
          {nextRank
            ? <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",textAlign:"right"}}>
                {(nextRank.min-(user.xp||0)).toLocaleString()} XP until <span style={{color:nextRank.color}}>{nextRank.name}</span>
              </div>
            : <div style={{fontFamily:"var(--mono)",fontSize:8,color:"var(--cyan)",textAlign:"right",letterSpacing:"0.1em"}}>MAX RANK REACHED</div>}
        </div>

        {/* XP Sources */}
        <div style={{background:"rgba(255,255,255,0.03)",border:"1px solid var(--border)",padding:"14px",marginBottom:16}}>
          <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",letterSpacing:"0.2em",marginBottom:12}}>HOW TO EARN XP</div>
          <div style={{display:"flex",flexDirection:"column",gap:8}}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"8px 10px",background:"rgba(123,200,67,0.08)",border:"1px solid rgba(123,200,67,0.2)"}}>
              <div>
                <div style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--text-bright)",fontWeight:700}}>DAILY CLAIM</div>
                <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",marginTop:2}}>100 coins + {XP_CLAIM} XP</div>
              </div>
              <div style={{fontFamily:"var(--display)",fontSize:16,fontWeight:900,color:"var(--cyan)"}}>+{XP_CLAIM}</div>
            </div>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"8px 10px",background:"rgba(136,68,204,0.12)",border:"1px solid rgba(136,68,204,0.35)"}}>
              <div>
                <div style={{fontFamily:"var(--mono)",fontSize:10,color:"var(--text-bright)",fontWeight:700}}>CHALLENGE PARTICIPATION</div>
                <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",marginTop:2}}>Per challenge joined — more picks correct = higher reward</div>
              </div>
              <div style={{fontFamily:"var(--display)",fontSize:16,fontWeight:900,color:"var(--purple)"}}>+{XP_DIFF["MED"]}</div>
            </div>
          </div>
        </div>

        {/* All Ranks */}
        <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",letterSpacing:"0.2em",marginBottom:10}}>ALL RANKS</div>
        <div style={{display:"flex",flexDirection:"column",gap:6}}>
          {RANKS.map((rank,i)=>{
            const next = RANKS[i+1];
            const isCurrent = rank.name === currentRank.name;
            const isUnlocked = (user.xp||0) >= rank.min;
            return (
              <div key={rank.name} style={{
                display:"flex",alignItems:"center",gap:12,padding:"10px 12px",
                background: isCurrent ? `${rank.color}18` : "rgba(255,255,255,0.02)",
                border: `1px solid ${isCurrent ? rank.color+"66" : "rgba(255,255,255,0.07)"}`,
                opacity: isUnlocked ? 1 : 0.4,
              }}>
                <div style={{width:3,alignSelf:"stretch",background:rank.color,flexShrink:0,borderRadius:2}}/>
                <div style={{flex:1,minWidth:0}}>
                  <div style={{display:"flex",alignItems:"center",gap:6}}>
                    <span style={{fontFamily:"var(--display)",fontSize:12,fontWeight:900,color:rank.color,letterSpacing:"0.08em"}}>{rank.name}</span>
                    {isCurrent && <span style={{fontFamily:"var(--mono)",fontSize:7,color:"var(--cyan)",border:"1px solid var(--cyan)",padding:"1px 5px",letterSpacing:"0.1em"}}>CURRENT</span>}
                  </div>
                  <div style={{fontFamily:"var(--mono)",fontSize:8,color:"rgba(255,255,255,0.4)",marginTop:2}}>
                    {rank.min.toLocaleString()} XP{next ? ` — ${(next.min-1).toLocaleString()} XP` : " +"}
                  </div>
                </div>
                <div style={{fontFamily:"var(--mono)",fontSize:9,color:isUnlocked?"var(--cyan)":"rgba(255,255,255,0.2)",flexShrink:0}}>
                  {isUnlocked ? "✓" : `${(rank.min-(user.xp||0)).toLocaleString()} to go`}
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};


function App() {
  const [screen,setScreen]=useState("login");
  const [myCards,setMyCards]=useState([]);
  const [showRanks,setShowRanks]=useState(false);
  const [showLeaderboard,setShowLeaderboard]=useState(false);
  const [showHowTo,setShowHowTo]=useState(false);
  const [lang,setLang]=React.useState(()=>localStorage.getItem("dfuse_lang")||"en");
  const t=LANG[lang]||LANG.en;
  const setLanguage=(l)=>{setLang(l);localStorage.setItem("dfuse_lang",l);};
  const [currentUser,setCurrentUser]=useState(null);
  const [selectedArena,setSelectedArena]=useState(null);
  const [toast,setToast]=useState(null);
  const [xpFloater,setXpFloater]=useState(null);
  const [users,setUsers]=useState([]);
  const [arenas,setArenas]=useState(INITIAL_ARENAS);
  const [challenges,setChallenges]=useState(INITIAL_CHALLENGES);
  const [dailyDrop,setDailyDrop]=useState(100);
  const [avatars,setAvatars]=useState(INITIAL_AVATARS);
  const [entries,setEntries]=useState([]);
  const [selectedChallenge,setSelectedChallenge]=useState(null);
  const [viewingResult,setViewingResult]=useState(null); // {entry, challenge}

  const showToast=(msg,type="info")=>setToast({msg,type,id:uid()});
  const showXP=(amt)=>setXpFloater({amt,id:uid()});

  const updateUser=(id,changes)=>{
    setUsers(prev=>prev.map(u=>u.id===id?{...u,...changes}:u));
    if(currentUser?.id===id) setCurrentUser(prev=>({...prev,...changes}));
    // Persiste no Supabase (fire-and-forget)
    if(sb._token && id) {
      const dbChanges={};
      if(changes.coins    !==undefined) dbChanges.coins     = changes.coins;
      if(changes.xp       !==undefined) dbChanges.xp        = changes.xp;
      if(changes.lastClaim!==undefined) dbChanges.last_claim= changes.lastClaim;
      if(changes.avatarId !==undefined) dbChanges.avatar_id = changes.avatarId;
      if(changes.username !==undefined) dbChanges.username   = changes.username;
      if(Object.keys(dbChanges).length>0)
        sb.from("profiles").update(dbChanges,`id=eq.${id}`).catch(e=>console.warn("updateUser:",e.message));
    }
  };

  const loadUserData = async (userId, token) => {
    if(token) sb._token = token;
    try {
      const [profile, entriesData, cardsData] = await Promise.all([
        sb.from("profiles").select("*", {filter:`id=eq.${userId}`}).then(d=>Array.isArray(d)?d[0]:null),
        sb.from("entries").select("*", {filter:`user_id=eq.${userId}`}),
        sb.from("cards").select("*", {filter:`user_id=eq.${userId}`}),
      ]);
      if(profile) {
        setCurrentUser(prev=>({...prev,...profile,id:profile.id,isAdmin:profile.is_admin,avatarId:profile.avatar_id,lastClaim:profile.last_claim}));
        localStorage.setItem("dfuse_user", JSON.stringify({...profile,isAdmin:profile.is_admin}));
      }
      if(Array.isArray(entriesData)) setEntries(entriesData.map(e=>({...e,userId:e.user_id,challengeId:e.challenge_id})));
      if(Array.isArray(cardsData))   setMyCards(cardsData.map(c=>({...c,packType:c.pack_type})));
    } catch(e) { console.warn("loadUserData:", e.message); }
  };

  const handleLogin = (user, token) => {
    sb._token = token;
    localStorage.setItem("dfuse_token", token);
    localStorage.setItem("dfuse_user", JSON.stringify(user));
    setCurrentUser(user);
    setScreen("lobby");
    showToast(`Welcome back, ${user.username.toUpperCase()}`,"success");
    loadUserData(user.id, token);
  };

  const handleSignup = (user, token) => {
    sb._token = token;
    localStorage.setItem("dfuse_token", token);
    localStorage.setItem("dfuse_user", JSON.stringify(user));
    setCurrentUser(user);
    setScreen("lobby");
    showToast("Account created! Dare to pick!","success");
    loadUserData(user.id, token);
  };

  const handleLogout = () => {
    sb._token = null;
    localStorage.removeItem("dfuse_token");
    localStorage.removeItem("dfuse_user");
    setCurrentUser(null);
    setScreen("login");
  };

  // Carrega arenas, challenges e utilizadores do Supabase
  const loadGameData = async () => {
    try {
      const [arenasData, challengesData] = await Promise.all([
        sb.from("arenas").select("*"),
        sb.from("challenges").select("*"),
      ]);
      if(Array.isArray(arenasData))
        setArenas(arenasData.map(a=>({...a, desc:a.description})));
      if(Array.isArray(challengesData))
        setChallenges(challengesData.map(c=>({...c, arenaId:c.arena_id, desc:c.description, correctAnswers:c.correct_answers})));
    } catch(e) { console.warn("loadGameData:", e.message); }
    // Configurações (dailyDrop etc.)
    try {
      const configData = await sb.from("config").select("*");
      if(Array.isArray(configData)) {
        const drop = configData.find(c=>c.key==="daily_drop");
        if(drop) setDailyDrop(Number(drop.value));
      }
    } catch(e) { console.warn("loadConfig:", e.message); }
    // Utilizadores reais
    try {
      const profilesData = await sb.from("profiles").select("*");
      if(Array.isArray(profilesData) && profilesData.length > 0)
        setUsers(profilesData.map(p=>({...p, isAdmin:p.is_admin, avatarId:p.avatar_id, lastClaim:p.last_claim})));
    } catch(e) { console.warn("loadProfiles:", e.message); }
  };

  // Auto-restore session + handle OAuth / email-confirm callback
  React.useEffect(()=>{
    loadGameData();
    (async () => {
      // 1a) PKCE flow: Supabase redireciona com ?code= na query string
      const urlParams = new URLSearchParams(window.location.search);
      const pkceCode = urlParams.get("code");
      if(pkceCode) {
        try { window.history.replaceState(null, "", window.location.pathname); } catch(_){}
        try {
          const res = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=pkce`, {
            method:"POST",
            headers:{"apikey":SUPABASE_ANON,"Content-Type":"application/json"},
            body: JSON.stringify({auth_code: pkceCode})
          }).then(r=>r.json());
          if(!res.access_token) throw new Error(res.msg || res.error_description || "Email confirmation failed");
          sb._token = res.access_token;
          const userInfo = await sb.auth.getUser(res.access_token);
          if(!userInfo?.id) throw new Error("Auth callback: user not found");
          const profile = await sb.from("profiles").select("*", {filter:`id=eq.${userInfo.id}`}).then(d=>Array.isArray(d)?d[0]:null);
          if(!profile) throw new Error("Profile not found after auth");
          const userObj = {...profile, id:profile.id, isAdmin:profile.is_admin, avatarId:profile.avatar_id, lastClaim:profile.last_claim, email:userInfo.email};
          localStorage.setItem("dfuse_token", res.access_token);
          localStorage.setItem("dfuse_user", JSON.stringify(userObj));
          setCurrentUser(userObj);
          setScreen("lobby");
          showToast(`Welcome, ${(profile.username||"agent").toUpperCase()}`, "success");
          loadUserData(userInfo.id, res.access_token);
          return;
        } catch(e) {
          showToast(e.message || "Email confirmation failed", "error");
          return;
        }
      }

      // 1b) Implicit flow: Supabase devolve tokens no hash
      //    #access_token=...&refresh_token=...&token_type=bearer&expires_in=3600
      //    Também pode haver erro: #error=...&error_description=...
      const hash = window.location.hash || "";
      if(hash.includes("access_token=") || hash.includes("error=")) {
        const params = new URLSearchParams(hash.replace(/^#/, ""));
        const accessToken = params.get("access_token");
        const errDesc     = params.get("error_description") || params.get("error");

        // Limpa o hash imediatamente para evitar reprocessar em reloads
        try { window.history.replaceState(null, "", window.location.pathname + window.location.search); } catch(_){}

        if(errDesc) {
          showToast(decodeURIComponent(errDesc.replace(/\+/g," ")), "error");
          return;
        }
        if(accessToken) {
          try {
            sb._token = accessToken;
            const userInfo = await sb.auth.getUser(accessToken);
            if(!userInfo?.id) throw new Error("Auth callback: user not found");
            // O trigger handle_new_user já criou o profile (com username = metadata.username
            // ou fallback split_part(email,'@',1) para Google).
            const profile = await sb.from("profiles").select("*", {filter:`id=eq.${userInfo.id}`}).then(d=>Array.isArray(d)?d[0]:null);
            if(!profile) throw new Error("Profile not found after auth");
            const userObj = {...profile, id:profile.id, isAdmin:profile.is_admin, avatarId:profile.avatar_id, lastClaim:profile.last_claim, email:userInfo.email};
            localStorage.setItem("dfuse_token", accessToken);
            localStorage.setItem("dfuse_user", JSON.stringify(userObj));
            setCurrentUser(userObj);
            setScreen("lobby");
            showToast(`Welcome, ${(profile.username||"agent").toUpperCase()}`, "success");
            loadUserData(userInfo.id, accessToken);
            return;
          } catch(e) {
            showToast(e.message || "Auth callback failed", "error");
            return;
          }
        }
      }

      // 2) Sem callback — tenta restaurar sessão do localStorage
      const token = localStorage.getItem("dfuse_token");
      const user  = localStorage.getItem("dfuse_user");
      if(token && user) {
        const u = JSON.parse(user);
        sb._token = token;
        setCurrentUser(u);
        setScreen("lobby");
        loadUserData(u.id, token);
      }
    })();
  },[]);

  const handleClaim=()=>{
    const newXP=(currentUser.xp||0)+XP_CLAIM;
    updateUser(currentUser.id,{coins:currentUser.coins+dailyDrop,lastClaim:now(),xp:newXP});
    showToast(`+${dailyDrop} coins · +${XP_CLAIM} XP claimed!`,"success");
    showXP(XP_CLAIM);
  };
  const handleJoin=(ch)=>{
    const existing = entries.find(e=>e.userId===currentUser.id&&e.challengeId===ch.id);
    if(existing){
      // Player already has picks — just navigate, show "good luck"
      setSelectedChallenge(ch);
      setScreen("challenge");
      showToast("Good luck, you gonna need it!","info");
      return;
    }
    if(currentUser.coins<ch.cost)return showToast("INSUFFICIENT COINS — ENTRY DENIED","error");
    updateUser(currentUser.id,{coins:currentUser.coins-ch.cost});
    setSelectedChallenge(ch);
    setScreen("challenge");
    showToast("Dare to pick!","success");
  };
  const handleSubmitEntry=(ch, submission)=>{
    const xpGain=XP_DIFF["MED"];
    const existing = entries.find(e=>e.userId===currentUser.id&&e.challengeId===ch.id);
    const entryId = existing?.id || uid();
    if(existing){
      setEntries(prev=>prev.map(e=>e.id===existing.id?{...e,...submission}:e));
    } else {
      setEntries(prev=>[...prev,{id:entryId,userId:currentUser.id,challengeId:ch.id,...submission}]);
    }
    updateUser(currentUser.id,{xp:(currentUser.xp||0)+xpGain});
    showXP(xpGain);
    // Persiste no Supabase
    sb.from("entries").upsert({
      id:entryId, user_id:currentUser.id, challenge_id:ch.id,
      questions:submission.questions, answers:submission.answers,
      locked:submission.locked, submitted_at:submission.submittedAt,
    }).catch(e=>console.warn("submitEntry:",e.message));
    showToast("Good luck, you gonna need it!","success");
    setScreen("arena");
  };
  const handleViewResult=(ch)=>{
    const entry=entries.find(e=>e.userId===currentUser.id&&e.challengeId===ch.id);
    setSelectedChallenge(ch);
    setViewingResult({entry,challenge:ch});
    setScreen("result");
  };
  const handleSaveCard=(card)=>{
    setMyCards(prev=>[...prev, card]);
    sb.from("cards").insert({
      id:card.id, user_id:currentUser.id,
      pack_type:card.packType, challenge:card.challenge, saved_at:card.savedAt,
    }).catch(e=>console.warn("saveCard:",e.message));
    showToast("Sticker saved to collection!","success");
  };

  const handleCollectReward=(ch, reward)=>{
    if(reward>0) updateUser(currentUser.id,{coins:currentUser.coins+reward});
    const entry=entries.find(e=>e.userId===currentUser.id&&e.challengeId===ch.id);
    setEntries(prev=>prev.map(e=>
      e.userId===currentUser.id&&e.challengeId===ch.id ? {...e,collected:true} : e
    ));
    if(entry) sb.from("entries").update({collected:true},`id=eq.${entry.id}`).catch(e=>console.warn("collect:",e.message));
  };
  const handleAdHocDrop=(userId,amount,msg)=>{
    if(!amount)return showToast("Enter a valid amount","error");
    if(userId){
      const t=users.find(u=>u.id===userId);
      updateUser(userId,{coins:(t?.coins||0)+amount});
      showToast(`Dropped ◈${amount} to ${t?.username}`,"success");
    } else {
      setUsers(prev=>prev.map(u=>u.isAdmin?u:{...u,coins:u.coins+amount}));
      if(currentUser&&!currentUser.isAdmin) setCurrentUser(prev=>({...prev,coins:prev.coins+amount}));
      sb.rpc("increment_all_coins",{amount}).catch(e=>console.warn("broadcast:",e.message));
      showToast(`Broadcast ◈${amount} to ALL agents`,"success");
    }
  };

  return (
    <div style={{maxWidth:480,margin:"0 auto",minHeight:"100dvh",position:"relative",background:"var(--bg)",overflow:"hidden"}}>
      <GlobalStyle/>
      <Scanlines/><GridBg/>
      {toast&&<Toast key={toast.id} msg={toast.msg} type={toast.type} onDone={()=>setToast(null)}/>}
      {xpFloater&&<XPFloater key={xpFloater.id} amount={xpFloater.amt} onDone={()=>setXpFloater(null)}/>}
      {screen==="login"&&<LoginScreen users={users} onLogin={handleLogin} onGo={setScreen} onToast={showToast} lang={lang} setLanguage={setLanguage}/>}
      {screen==="signup"&&<SignupScreen onSignup={handleSignup} onGo={setScreen} onToast={showToast} avatars={avatars} lang={lang} setLanguage={setLanguage}/>}
      {screen==="recovery"&&<RecoveryScreen onGo={setScreen} onToast={showToast}/>}
      {showHowTo&&(
        <div style={{position:"fixed",inset:0,zIndex:9999}}>
          <HowToPlayScreen onBack={()=>setShowHowTo(false)} lang={lang}/>
        </div>
      )}
      {showLeaderboard&&currentUser&&(
        <div style={{position:"fixed",inset:0,zIndex:9999}}>
          <LeaderboardScreen currentUser={currentUser} users={users} myCards={myCards} onBack={()=>setShowLeaderboard(false)}/>
        </div>
      )}
      {showRanks&&currentUser&&(
        <div style={{position:"fixed",inset:0,zIndex:9999}}>
          <RanksScreen user={currentUser} onBack={()=>setShowRanks(false)}/>
        </div>
      )}
      {screen==="mycards"&&currentUser&&(
        <MyCardsScreen cards={myCards} onBack={()=>setScreen("lobby")} lang={lang}/>
      )}
      {screen==="lobby"&&currentUser&&(
        <LobbyScreen user={currentUser} arenas={arenas} challenges={challenges} dailyDrop={dailyDrop}
          onEnterArena={(a)=>{setSelectedArena(a);setScreen("arena");}}
          onProfile={()=>setScreen("profile")} onAdmin={()=>setScreen("admin")} onClaim={handleClaim} avatars={avatars} onMyCards={()=>setScreen("mycards")} myCardsCount={myCards.length} onShowRanks={()=>setShowRanks(true)} onLeaderboard={()=>setShowLeaderboard(true)} onHowTo={()=>setShowHowTo(true)} lang={lang} setLanguage={setLanguage}/>
      )}
      {screen==="arena"&&currentUser&&selectedArena&&(
        <ArenaScreen arena={selectedArena} challenges={challenges} user={currentUser}
          entries={entries} onBack={()=>setScreen("lobby")} onJoin={handleJoin}
          onViewResult={handleViewResult} lang={lang}/>
      )}
      {screen==="profile"&&currentUser&&(
        <ProfileScreen user={currentUser} onBack={()=>setScreen("lobby")}
          onUpdate={(ch)=>{updateUser(currentUser.id,ch);showToast("Profile updated","success");}} onLogout={handleLogout} avatars={avatars}/>
      )}
      {screen==="challenge"&&currentUser&&selectedChallenge&&(()=>{
        const existingEntry = entries.find(e=>e.userId===currentUser.id&&e.challengeId===selectedChallenge.id);
        return (
          <ChallengePlayScreen
            challenge={selectedChallenge}
            user={currentUser}
            entry={existingEntry}
            onSubmit={(sub)=>handleSubmitEntry(selectedChallenge,sub)}
            onBack={()=>setScreen("arena")}
          />
        );
      })()}
      {screen==="result"&&currentUser&&selectedChallenge&&viewingResult&&(
        <ResultScreen
          challenge={selectedChallenge}
          entry={viewingResult.entry}
          correctAnswers={selectedChallenge.correctAnswers||null}
          onBack={()=>setScreen("arena")}
          onSaveCard={handleSaveCard}
          onGoMyCards={()=>setScreen("mycards")}
          onCollect={(reward)=>handleCollectReward(selectedChallenge,reward)} onToast={showToast}
        />
      )}
      {screen==="admin"&&currentUser?.isAdmin&&(
        <AdminPanel users={users} arenas={arenas} challenges={challenges} entries={entries} dailyDrop={dailyDrop} avatars={avatars}
          onBack={()=>setScreen("lobby")} onSetDailyDrop={(v)=>{setDailyDrop(v);sb.from("config").upsert({key:"daily_drop",value:String(v)}).catch(e=>console.warn("dailyDrop:",e.message));showToast(`Daily drop → ◈${v}`,"success");}}
          onAdHocDrop={handleAdHocDrop}
          onCreateArena={async (a)=>{
            try {
              await sb.from("arenas").insert({id:a.id,name:a.name,color:a.color,description:a.desc||"",active:a.active});
              setArenas(prev=>[...prev,a]); showToast("Arena created","success");
            } catch(e){ showToast("Failed to save arena","error"); }
          }}
          onToggleArena={async (id)=>{
            const arena=arenas.find(a=>a.id===id); if(!arena) return;
            try {
              await sb.from("arenas").update({active:!arena.active},`id=eq.${id}`);
              setArenas(prev=>prev.map(a=>a.id===id?{...a,active:!a.active}:a));
            } catch(e){ showToast("Failed to update arena","error"); }
          }}
          onDeleteArena={async (id)=>{
            try {
              await sb.from("arenas").delete(`id=eq.${id}`);
              setArenas(prev=>prev.filter(a=>a.id!==id));
              setChallenges(prev=>prev.filter(c=>c.arenaId!==id));
            } catch(e){ showToast("Failed to delete arena","error"); }
          }}
          onCreateChallenge={async (c)=>{
            try {
              await sb.from("challenges").insert({id:c.id,arena_id:c.arenaId,name:c.name,description:c.desc||"",cost:c.cost,reward:c.reward,difficulty:c.difficulty,active:c.active});
              setChallenges(prev=>[...prev,c]); showToast("Operation created","success");
            } catch(e){ showToast("Failed to save challenge","error"); }
          }}
          onToggleChallenge={async (id)=>{
            const ch=challenges.find(c=>c.id===id); if(!ch) return;
            try {
              await sb.from("challenges").update({active:!ch.active},`id=eq.${id}`);
              setChallenges(prev=>prev.map(c=>c.id===id?{...c,active:!c.active}:c));
            } catch(e){ showToast("Failed to update challenge","error"); }
          }}
          onDeleteChallenge={async (id)=>{
            try {
              await sb.from("challenges").delete(`id=eq.${id}`);
              setChallenges(prev=>prev.filter(c=>c.id!==id));
            } catch(e){ showToast("Failed to delete challenge","error"); }
          }}
          onGradeChallenge={(chId,answers)=>{
            setChallenges(prev=>prev.map(c=>c.id===chId?{...c,correctAnswers:answers,graded:true}:c));
            sb.from("challenges").update({correct_answers:answers,graded:true},`id=eq.${chId}`).catch(e=>console.warn("grade:",e.message));
            showToast("Challenge graded! Players can now see results.","success");
          }}/>
      )}
    </div>
  );
}

// ── Mount ───────────────────────────────────────────────────────
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
