// ============================================================= // MAIN APP — POKEMON ADVANCE // ============================================================= const { useState: useAppState, useEffect: useAppEffect } = React; function App() { const [state, setStateRaw] = useAppState(() => { const s = GameEngine.loadState(); GameEngine.refillIfNeeded(s); return s; }); const [view, setView] = useAppState("home"); // home | packs | collection | battles | onboarding const [showSplash, setShowSplash] = useAppState(true); // Persist on every change useAppEffect(() => { GameEngine.saveState(state); }, [state]); // Auto-refill check on visibility useAppEffect(() => { function onVis() { const s = { ...state }; if (GameEngine.refillIfNeeded(s)) setStateRaw(s); } document.addEventListener("visibilitychange", onVis); return () => document.removeEventListener("visibilitychange", onVis); }, [state]); function setState(updater) { setStateRaw(prev => typeof updater === "function" ? updater(prev) : updater); } useAppEffect(() => { const t = setTimeout(() => setShowSplash(false), 1900); return () => clearTimeout(t); }, []); if (showSplash) return ; if (!state.welcomed) return setState(s => ({...s, welcomed:true}))}/>; if (view === "packs") return setView("home")}/>; if (view === "collection") return setView("home")}/>; if (view === "battles") return setView("home")}/>; return setView("packs")} onOpenCollection={() => setView("collection")} onOpenBattles={() => setView("battles")} />; } function Splash() { return (
Cartas Pokemon · Amongus
POKÉMON ADVANCE
CARGANDO ENTRENADOR...
); } function Onboarding({ state, setState, onDone }) { const [step, setStep] = useAppState(0); const [name, setName] = useAppState(state.trainerName && state.trainerName !== "FRANCO" ? state.trainerName : ""); const steps = [ { eyebrow:"BIENVENIDO", title:"Hola entrenador", body:"Bienvenido a CARTAS POKEMON, un juego donde cada 10 horas puedes abrir 6 sobres, coleccionar cartas de las primeras generaciones, y combatir contra entrenadores NPC para ganar medallas.", cta:"COMENZAR", }, { eyebrow:"REGISTRO", title:"¿Cuál es tu nombre?", body:"Este nombre aparecerá en tu Pokédex y en las batallas.", cta:"CONFIRMAR", input:true, }, { eyebrow:"REGALO DE INICIO", title:"Recibe tu sobre inaugural", body:"Empieza con un sobre regalo. Cada 10 horas tendrás 6 sobres frescos esperando.", cta:"¡VAMOS!", }, ]; function next() { if (step === 1) setState(s => ({...s, trainerName: (name || "ENTRENADOR").toUpperCase().slice(0,12)})); if (step < steps.length - 1) setStep(step + 1); else { // Grant gift starter cards setState(s => { const next = {...s}; const gift = [ DEX_BY_ID[4], // Charmander DEX_BY_ID[7], // Squirtle DEX_BY_ID[1], // Bulbasaur DEX_BY_ID[25], // Pikachu DEX_BY_ID[133],// Eevee ]; GameEngine.addCardsToCollection(next, gift); return next; }); onDone(); } } const s = steps[step]; return (
{s.eyebrow}

{s.title}

{s.body}

{s.input && ( setName(e.target.value)} maxLength={12} placeholder="Tu nombre..." autoFocus style={{ fontFamily:"var(--font-sans)", fontSize:24, fontWeight:700, textAlign:"center", letterSpacing:"0.1em", background:"var(--bg-inset)", border:"1px solid var(--accent-cyan)", color:"#fff", padding:"14px 20px", borderRadius:2, width:"100%", maxWidth:300, marginBottom:24, outline:"none", boxShadow:"0 0 12px var(--accent-cyan-glow)", textTransform:"uppercase", }} /> )}
{steps.map((_,i) => (
))}
); } // Mount const root = ReactDOM.createRoot(document.getElementById("root")); root.render();