Spaces:
Running
Running
| // --- GAME DATA & CONFIGURATION --- | |
| const PERSONAS = { | |
| farmer: { | |
| id: 'farmer', | |
| name: 'Ramesh', | |
| age: 38, | |
| role: 'Cotton Farmer', | |
| location: 'Vidarbha, Maharashtra', | |
| description: 'You own 3 acres. Rain is your boss. One bad season can destroy 10 years of work.', | |
| img: 'http://static.photos/agriculture/640x360/12', | |
| stats: { income: 4000, stability: 30, safety: 20, debt: 20, scamRisk: 40, wealth: 10 }, | |
| startMoney: 15000, | |
| difficulty: 'Hard', | |
| special: 'monsoon_risk' | |
| }, | |
| woman: { | |
| id: 'woman', | |
| name: 'Sunita', | |
| age: 32, | |
| role: 'Tailoring & Home Manager', | |
| location: 'Ranchi, Jharkhand', | |
| description: 'You run a sewing business and manage a home of 5. Money mixes too easily. Can you keep them separate?', | |
| img: 'http://static.photos/people/640x360/45', | |
| stats: { income: 12000, stability: 50, safety: 40, debt: 10, scamRisk: 30, wealth: 20 }, | |
| startMoney: 8000, | |
| businessStartCash: 5000, | |
| difficulty: 'Medium', | |
| special: 'separation_wallets' // Enables dual wallet UI | |
| }, | |
| student: { | |
| id: 'student', | |
| name: 'Aman', | |
| age: 19, | |
| role: 'Engineering Student', | |
| location: 'Kota, Rajasthan', | |
| description: 'Your parents send money. Your friends spend money. FOMO is your enemy. Today habits build your future.', | |
| img: 'http://static.photos/education/640x360/88', | |
| stats: { income: 5000, stability: 80, safety: 10, debt: 0, scamRisk: 60, wealth: 5 }, | |
| startMoney: 2000, | |
| difficulty: 'Easy', | |
| special: 'impulse_control' | |
| }, | |
| young_adult: { | |
| id: 'young_adult', | |
| name: 'Rohit', | |
| age: 24, | |
| role: 'IT Support', | |
| location: 'Bangalore, Karnataka', | |
| description: 'You got a credit card. You got a salary. You have no idea how tax works. Welcome to the golden handcuffs.', | |
| img: 'http://static.photos/technology/640x360/33', | |
| stats: { income: 35000, stability: 60, safety: 30, debt: 30, scamRisk: 50, wealth: 15 }, | |
| startMoney: 5000, | |
| difficulty: 'Medium', | |
| special: 'lifestyle_inflation' | |
| } | |
| }; | |
| const SCENARIOS = { | |
| common: [ | |
| { | |
| id: 'c1', | |
| text: "You get a message on WhatsApp: 'Your SBI account is suspended. Click here to verify.'", | |
| type: 'scam', | |
| choices: [ | |
| { text: "Click link immediately (Panic)", effect: { money: -5000, safety: -20, scamRisk: +30 }, result: "SCAM! Your bank account is drained. You lose βΉ5,000." }, | |
| { text: "Ignore and block", effect: { safety: +5, scamRisk: -5 }, result: "Smart move. You check the real app. Everything is fine." }, | |
| { text: "Call customer care", effect: { safety: +10, stability: +5 }, result: "It takes 20 minutes, but you confirm it was fake." } | |
| ] | |
| }, | |
| { | |
| id: 'c2', | |
| text: "A wedding invitation arrives from a distant relative. Gift expectations are high.", | |
| type: 'social', | |
| choices: [ | |
| { text: "Take a small loan for a good gift", effect: { money: +2000, debt: +15, stability: -10 }, result: "You look respectable at the wedding, but the loan EMI starts next month." }, | |
| { text: "Give what you can afford", effect: { money: -1000, stability: +5 }, result: "You give a modest gift. Nobody cares, but you are debt-free." }, | |
| { text: "Make an excuse and don't go", effect: { stability: -5, money: 0 }, result: "You save money but your mother is upset with you." } | |
| ] | |
| }, | |
| { | |
| id: 'c3', | |
| text: "A sudden fever hits the house. You need medicines fast.", | |
| type: 'shock', | |
| choices: [ | |
| { text: "Buy generic medicines from pharmacy", effect: { money: -500, safety: +10 }, result: "Effective and cheap. Health improves." }, | |
| { text: "Go to private hospital immediately", effect: { money: -3000, safety: +15, stability: -5 }, result: "Great care, but expensive. Your wallet hurts." }, | |
| { text: "Wait and see if it passes", effect: { safety: -20, stability: -5 }, result: "Condition worsens. You end up paying double later." } | |
| ] | |
| } | |
| ], | |
| farmer: [ | |
| { | |
| id: 'f1', | |
| text: "The monsoon is delayed. You have enough water for only 2 more weeks.", | |
| type: 'crisis', | |
| choices: [ | |
| { text: "Buy a diesel pump set on loan (βΉ15k)", effect: { money: +15000, debt: +30, safety: +10 }, result: "The pump saves the crop, but now you owe the money lender heavily." }, | |
| { text: "Pray and wait for rain", effect: { safety: -20, stability: -10 }, result: "Rain comes late. Crop yield is reduced by 40%.", shockResult: { money: -10000 } }, | |
| { text: "Sell the calf early to buy water", effect: { money: -500, wealth: -10, safety: +5 }, result: "You save the crop, but lost a future asset." } | |
| ] | |
| }, | |
| { | |
| id: 'f_insurance', | |
| text: "An agent offers 'Pradhan Mantri Fasal Bima Yojana' for βΉ2,000. It covers crop failure.", | |
| type: 'decision', | |
| choices: [ | |
| { text: "Buy Insurance (βΉ2,000)", effect: { money: -2000, tags: ['insured_crop'] }, result: "You feel lighter. If disaster strikes, you won't lose everything." }, | |
| { text: "Save the money (Keep βΉ2,000)", effect: { money: 0, tags: ['uninsured_crop'] }, result: "You keep the cash today. But you are exposed to nature's fury.", karmaConsequence: 'drought_check' } | |
| ] | |
| }, | |
| { | |
| id: 'f_drought', | |
| text: "A severe drought hits the region. Crops are failing everywhere.", | |
| type: 'crisis', | |
| requiredTags: ['uninsured_crop'], // Only if they didn't buy insurance | |
| choices: [ | |
| { text: "Accept the loss", effect: { money: -40000, stability: -40, safety: -20 }, result: "Years of work gone. You have to take a massive loan to survive next season." } | |
| ] | |
| }, | |
| { | |
| id: 'f_drought_safe', | |
| text: "A severe drought hits the region. Crops are failing everywhere.", | |
| type: 'crisis', | |
| requiredTags: ['insured_crop'], // Only if insured | |
| choices: [ | |
| { text: "Claim Insurance", effect: { money: +30000, stability: +10 }, result: "Insurance payout arrives! You survive the drought without falling into debt." } | |
| ] | |
| } | |
| ], | |
| woman: [ | |
| { | |
| id: 'w1', | |
| text: "A customer orders 10 blouses for a festival, asks to pay 'later'.", | |
| type: 'business', | |
| choices: [ | |
| { text: "Accept (Need the work)", effect: { tags: ['mixed_wallets'] }, result: "She doesn't pay for 3 months. Your business cash flow stops because you used home money for groceries.", shockResult: { businessCash: -5000 } }, | |
| { text: "Demand 50% advance", effect: { businessCash: +1000, stability: +10 }, result: "She agrees. You have money to buy materials immediately." }, | |
| { text: "Refuse politely", effect: { money: 0, stability: -5 }, result: "You lose the work, but keep your dignity and safety." } | |
| ] | |
| }, | |
| { | |
| id: 'w2', | |
| text: "Groceries are running low. You have βΉ2,000 in business cash and βΉ500 in home cash.", | |
| type: 'routine', | |
| choices: [ | |
| { text: "Pay from Business Cash (Easy)", effect: { businessCash: -1500, tags: ['mixed_wallets'], stability: -5 }, result: "Groceries bought. But now you can't buy fabric for the next order." }, | |
| { text: "Pay from Home Cash (Tight)", effect: { money: -500, wealth: +5, tags: ['separated_wallets'] }, result: "You skip a meal or two, but your business capital is safe." } | |
| ] | |
| }, | |
| { | |
| id: 'w3', | |
| text: "Big order! 50 school uniforms. Need βΉ5,000 fabric immediately.", | |
| type: 'business', | |
| choices: [ | |
| { text: "Use business savings", effect: { businessCash: -5000, money: +10000, tags: ['separated_wallets'] }, result: "You complete the order, make profit, and business grows." }, | |
| { text: "Borrow from local lender", effect: { money: +5000, debt: +20 }, result: "You pay high interest. Profit is eaten up by the loan.", shockResult: { stability: -10 } } | |
| ] | |
| } | |
| ], | |
| student: [ | |
| { | |
| id: 's1', | |
| text: "Friends are going to Goa for the weekend. You don't have the money.", | |
| type: 'social', | |
| choices: [ | |
| { text: "Borrow from Parents (Lie about fees)", effect: { money: 5000, debt: +20, stability: -10, scamRisk: +10, tags: ['habitual_liar'] }, result: "Fun trip. But you start a habit of lying for money." }, | |
| { text: "Use 'Buy Now Pay Later' app", effect: { money: 5000, debt: +30, safety: -10, tags: ['credit_addict'] }, result: "Instant approval. Now you owe the app + high interest." }, | |
| { text: "Stay back and study", effect: { wealth: +10, stability: +5, tags: ['focused'] }, result: "FOMO hits hard, but your grades improve." } | |
| ] | |
| }, | |
| { | |
| id: 's2', | |
| text: "You see a YouTube video: 'Turn βΉ500 into βΉ50,000 with Crypto'.", | |
| type: 'scam', | |
| choices: [ | |
| { text: "Invest immediately", effect: { money: -500, wealth: -10, tags: ['crypto_gambler'] }, result: "It's a rug pull. Your money is gone in seconds.", karmaConsequence: 'future_loan_rejection' }, | |
| { text: "Watch full video, then research", effect: { scamRisk: -10 }, result: "You find comments calling it a scam. You dodged a bullet." } | |
| ] | |
| }, | |
| { | |
| id: 's3', | |
| text: "Flash sale on sneakers! 70% OFF for 1 hour.", | |
| type: 'social', | |
| choices: [ | |
| { text: "Buy Now!", effect: { money: -2000, tags: ['impulse_buyer'] }, result: "They look cool. But you eat instant noodles for two weeks." }, | |
| { text: "Ignore", effect: { wealth: +5 }, result: "Resisting feels good. Your savings stay intact." } | |
| ] | |
| } | |
| ], | |
| young_adult: [ | |
| { | |
| id: 'y1', | |
| text: "Salary credited! Bank offers a pre-approved personal loan for 'Travel'.", | |
| type: 'credit', | |
| choices: [ | |
| { text: "Take the loan (Trip to Europe)", effect: { money: 100000, debt: +40, stability: -20 }, result: "Instagram photos look great. The EMI is 40% of your salary." }, | |
| { text: "Start a SIP (Mutual Fund) instead", effect: { money: -10000, wealth: +20, stability: +10, tags: ['investor'] }, result: "Not exciting today, but your future self will thank you." }, | |
| { text: "Buy a new iPhone on EMI", effect: { money: -10000, debt: +20, wealth: -5 }, result: "You look cool. Asset value drops immediately." } | |
| ] | |
| }, | |
| { | |
| id: 'y2', | |
| text: "Company announces layoffs. You have 6 months of expenses saved.", | |
| type: 'shock', | |
| choices: [ | |
| { text: "Panic and look for job now", effect: { stability: -10 }, result: "You survive the cut, but the stress was unnecessary." }, | |
| { text: "Relax, you have a fund", effect: { stability: +20, safety: +20 }, result: "You are laid off, but you survive 4 months comfortably without panic." }, | |
| { text: "Invest savings in stock market", effect: { wealth: -20, safety: -30 }, result: "Market crashes the next week. You lose your safety net.", shockResult: { money: -20000, stability: -20 } } | |
| ] | |
| }, | |
| { | |
| id: 'y_loan_reject', | |
| text: "You apply for a home loan to buy a flat.", | |
| type: 'finance', | |
| requiredTags: ['credit_addict', 'crypto_gambler', 'habitual_liar'], | |
| choices: [ | |
| { text: "Submit Application", effect: { stability: -20 }, result: "REJECTED. Your credit score is ruined by past impulsive decisions and 'Buy Now Pay Later' apps." } | |
| ] | |
| } | |
| ] | |
| }; | |
| // --- STATE MANAGEMENT --- | |
| class GameState { | |
| constructor() { | |
| this.reset(); | |
| } | |
| reset() { | |
| this.personaId = null; | |
| this.month = 1; | |
| this.year = 1; | |
| this.money = 0; | |
| this.businessCash = 0; // For Sunita | |
| this.stats = { stability: 50, safety: 50, debt: 0, scamRisk: 0, wealth: 20 }; | |
| this.karmaTags = []; // "Invisible Future Meter" tags | |
| this.history = []; | |
| this.currentScenario = null; | |
| this.gameOver = false; | |
| } | |
| loadPersona(id) { | |
| const p = PERSONAS[id]; | |
| this.personaId = id; | |
| this.money = p.startMoney; | |
| this.businessCash = p.businessStartCash || 0; | |
| this.stats = { ...p.stats }; | |
| this.month = 1; | |
| this.year = 1; | |
| this.gameOver = false; | |
| this.karmaTags = []; | |
| } | |
| nextTurn() { | |
| this.month++; | |
| if (this.month > 12) { | |
| this.month = 1; | |
| this.year++; | |
| } | |
| // Passive Income/Expense | |
| const persona = PERSONAS[this.personaId]; | |
| // Dual Wallet Income Logic | |
| if (persona.special === 'separation_wallets') { | |
| this.businessCash += persona.income; | |
| } else { | |
| this.money += persona.income; | |
| } | |
| // Debt Interest Effect (Compounding) | |
| if (this.stats.debt > 50) { | |
| this.money -= 2000; | |
| this.stats.stability -= 2; | |
| } | |
| // Game Over Condition (10 Years or Bankruptcy) | |
| if (this.year > 10 || (this.money < -20000 && this.businessCash < -20000)) { | |
| this.gameOver = true; | |
| return 'end'; | |
| } | |
| return 'continue'; | |
| } | |
| applyEffect(effect) { | |
| if (!effect) return; | |
| // Financials | |
| if (effect.money) this.money += effect.money; | |
| if (effect.businessCash) this.businessCash += effect.businessCash; | |
| // Stats | |
| if (effect.stability) this.updateStat('stability', effect.stability); | |
| if (effect.safety) this.updateStat('safety', effect.safety); | |
| if (effect.debt) this.updateStat('debt', effect.debt); | |
| if (effect.scamRisk) this.updateStat('scamRisk', effect.scamRisk); | |
| if (effect.wealth) this.updateStat('wealth', effect.wealth); | |
| // Karma Tags (The Invisible Hand) | |
| if (effect.tags) { | |
| effect.tags.forEach(tag => { | |
| if (!this.karmaTags.includes(tag)) { | |
| this.karmaTags.push(tag); | |
| } | |
| }); | |
| } | |
| // Clamp stats 0-100 | |
| for (let key in this.stats) { | |
| this.stats[key] = Math.max(0, Math.min(100, this.stats[key])); | |
| } | |
| } | |
| updateStat(key, value) { | |
| this.stats[key] += value; | |
| } | |
| getScenario() { | |
| // 1. Check for Karma-triggered specific events first | |
| // If user has tags ['uninsured_crop'], prioritize drought event | |
| if (this.karmaTags.includes('uninsured_crop') && Math.random() > 0.6) { | |
| return SCENARIOS.farmer.find(s => s.id === 'f_drought'); | |
| } | |
| if (this.karmaTags.includes('insured_crop') && Math.random() > 0.6) { | |
| return SCENARIOS.farmer.find(s => s.id === 'f_drought_safe'); | |
| } | |
| if (this.personaId === 'young_adult' && (this.karmaTags.includes('credit_addict') || this.karmaTags.includes('crypto_gambler')) && Math.random() > 0.7) { | |
| return SCENARIOS.young_adult.find(s => s.id === 'y_loan_reject'); | |
| } | |
| // 2. Standard Logic: 30% Common, 70% Persona Specific | |
| const pool = Math.random() > 0.3 ? SCENARIOS[this.personaId] : SCENARIOS.common; | |
| const available = pool.filter(s => { | |
| if (!s.requiredTags) return true; | |
| // If scenario requires tags, check if player has ANY of them | |
| return s.requiredTags.some(tag => this.karmaTags.includes(tag)); | |
| }); | |
| return available.length > 0 ? available[Math.floor(Math.random() * available.length)] : pool[Math.floor(Math.random() * pool.length)]; | |
| } | |
| } | |
| const state = new GameState(); | |
| // --- GAME LOGIC --- | |
| const mainContent = document.getElementById('main-content'); | |
| function initGame() { | |
| renderHome(); | |
| } | |
| function renderHome() { | |
| mainContent.innerHTML = ` | |
| <div class="animate-enter text-center mb-10"> | |
| <h1 class="text-4xl md:text-6xl font-extrabold text-white mb-2 tracking-tight">PAISA YUDDH</h1> | |
| <p class="text-xl text-primary font-bold uppercase">The Financial Survival Game of Bharat</p> | |
| <p class="text-slate-400 mt-2 max-w-lg mx-auto">You don't learn money. You survive with it. <br>No reset button. No right answers. Only consequences.</p> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 animate-enter" style="animation-delay: 0.1s;"> | |
| <persona-card id="farmer"></persona-card> | |
| <persona-card id="woman"></persona-card> | |
| <persona-card id="student"></persona-card> | |
| <persona-card id="young_adult"></persona-card> | |
| </div> | |
| `; | |
| } | |
| window.selectPersona = (id) => { | |
| state.loadPersona(id); | |
| document.dispatchEvent(new Event('state-update')); | |
| renderGameInterface(); | |
| startTurn(); | |
| }; | |
| function renderGameInterface() { | |
| mainContent.innerHTML = ` | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 animate-enter"> | |
| <!-- Left: Story & Interaction --> | |
| <div class="flex flex-col gap-6"> | |
| <div id="scenario-container" class="glass-panel p-6 rounded-xl border-l-4 border-primary min-h-[300px] flex flex-col justify-center relative overflow-hidden"> | |
| <div id="scenario-bg" class="absolute inset-0 opacity-10 pointer-events-none bg-cover bg-center" style="background-image: url('http://static.photos/abstract/640x360');"></div> | |
| <div class="relative z-10"> | |
| <!-- Content loads here --> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right: Invisible Future Meter --> | |
| <div class="glass-panel p-6 rounded-xl flex flex-col"> | |
| <h3 class="text-white font-bold mb-4 border-b border-slate-700 pb-2 flex items-center gap-2"> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#f97316" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg> | |
| Invisible Future Meter | |
| </h3> | |
| <p class="text-xs text-slate-400 mb-6">You don't see the numbers, you feel the effects. These hidden stats determine your fate.</p> | |
| <stat-meter label="Stability"></stat-meter> | |
| <stat-meter label="Safety"></stat-meter> | |
| <stat-meter label="Debt Load"></stat-meter> | |
| <stat-meter label="Scam Risk"></stat-meter> | |
| <stat-meter label="Wealth Path"></stat-meter> | |
| </div> | |
| </div> | |
| `; | |
| } | |
| function startTurn() { | |
| const turnResult = state.nextTurn(); | |
| if (turnResult === 'end') { | |
| renderEndScreen(); | |
| return; | |
| } | |
| const scenario = state.getScenario(); | |
| state.currentScenario = scenario; | |
| renderScenario(scenario); | |
| } | |
| function renderScenario(scenario) { | |
| const container = document.getElementById('scenario-container'); | |
| const containerContent = container.querySelector('.relative.z-10'); | |
| // Update background based on type | |
| const bgType = scenario.type === 'scam' ? 'technology' : scenario.type === 'crisis' ? 'nature' : 'abstract'; | |
| document.getElementById('scenario-bg').style.backgroundImage = `url('http://static.photos/${bgType}/640x360/${Math.floor(Math.random()*100)}')`; | |
| let iconColor = 'text-primary'; | |
| if(scenario.type === 'scam') iconColor = 'text-purple-500'; | |
| if(scenario.type === 'crisis') iconColor = 'text-red-500'; | |
| containerContent.innerHTML = ` | |
| <div class="animate-enter"> | |
| <div class="text-xs font-bold uppercase tracking-widest mb-3 ${iconColor} flex items-center gap-2"> | |
| <span class="w-2 h-2 rounded-full bg-current"></span> Life Event: ${scenario.type} | |
| </div> | |
| <h2 class="text-xl md:text-2xl text-white font-bold mb-6 leading-relaxed"> | |
| ${scenario.text} | |
| </h2> | |
| <div class="flex flex-col gap-3 mt-4"> | |
| ${scenario.choices.map((choice, idx) => ` | |
| <button onclick="handleChoice(${idx})" | |
| class="text-left p-4 bg-slate-800/80 hover:bg-slate-700 border border-slate-600 rounded-lg transition-all hover:border-primary group focus:outline-none focus:ring-2 focus:ring-primary"> | |
| <div class="text-white font-medium group-hover:text-primary flex justify-between items-center"> | |
| <span>${choice.text}</span> | |
| <i data-feather="chevron-right" class="opacity-0 group-hover:opacity-100 transition-opacity" width="16"></i> | |
| </div> | |
| </button> | |
| `).join('')} | |
| </div> | |
| </div> | |
| `; | |
| feather.replace(); | |
| } | |
| window.handleChoice = (idx) => { | |
| const choice = state.currentScenario.choices[idx]; | |
| state.applyEffect(choice.effect); | |
| let resultText = choice.result; | |
| // Handle Shock Results (Random consequence) | |
| if (choice.shockResult && Math.random() > 0.5) { | |
| state.applyEffect(choice.shockResult); | |
| const shockMsg = choice.shockResult.text || "Unexpected financial hit due to previous risks!"; | |
| resultText += `<br><br><div class="bg-red-900/30 border border-red-500/30 p-3 rounded text-red-200 text-sm font-bold mt-2">β οΈ SHOCK: ${shockMsg}</div>`; | |
| } | |
| // Check for Karma Consequences (The "Aha!" moment) | |
| if (choice.karmaConsequence === 'drought_check' && Math.random() > 0.4) { | |
| // Triggered if they didn't buy insurance previously and bad luck strikes | |
| resultText += `<br><br><div class="bg-red-900/30 border border-red-500/30 p-3 rounded text-red-200 text-sm font-bold mt-2">π KARMA: The drought you feared has arrived next season!</div>`; | |
| } | |
| renderResult(resultText); | |
| // Visual Feedback: Karma Positive | |
| const container = document.getElementById('scenario-container'); | |
| if (choice.effect && choice.effect.tags && choice.effect.tags.includes('separated_wallets')) { | |
| container.classList.add('karma-positive'); | |
| setTimeout(() => container.classList.remove('karma-positive'), 2000); | |
| } | |
| document.dispatchEvent(new Event('state-update')); | |
| }; | |
| function renderResult(text) { | |
| const container = document.getElementById('scenario-container'); | |
| const containerContent = container.querySelector('.relative z-10'); | |
| containerContent.innerHTML = ` | |
| <div class="animate-enter text-center py-8"> | |
| <div class="text-6xl mb-6">π²</div> | |
| <h3 class="text-2xl text-white font-bold mb-4">The Outcome</h3> | |
| <div class="text-slate-300 text-lg leading-relaxed mb-8">${text}</div> | |
| <button onclick="startTurn()" class="bg-primary hover:bg-orange-600 text-white font-bold py-3 px-8 rounded-full shadow-lg shadow-orange-500/30 transition-all transform hover:scale-105 active:scale-95"> | |
| Next Month <i data-feather="arrow-right" class="inline ml-2 align-middle" style="width:16px;"></i> | |
| </button> | |
| </div> | |
| `; | |
| feather.replace(); | |
| } | |
| function renderEndScreen() { | |
| const title = state.money < 0 ? "FINANCIAL RUIN" : | |
| state.stats.wealth > 60 ? "FINANCIAL WARRIOR" : "SURVIVED"; | |
| const color = state.money < 0 ? "text-red-500" : "text-green-500"; | |
| // Analyze Karma | |
| const badHabits = state.karmaTags.filter(t => ['crypto_gambler', 'credit_addict', 'habitual_liar', 'mixed_wallets'].includes(t)); | |
| const goodHabits = state.karmaTags.filter(t => ['investor', 'separated_wallets', 'focused', 'insured_crop'].includes(t)); | |
| mainContent.innerHTML = ` | |
| <div class="animate-enter glass-panel p-8 rounded-xl text-center max-w-2xl mx-auto mt-10"> | |
| <div class="text-5xl mb-4">${state.money < 0 ? 'π' : 'π'}</div> | |
| <h1 class="text-4xl font-bold ${color} mb-2">${title}</h1> | |
| <p class="text-slate-400 mb-8">10 Years have passed in the life of ${PERSONAS[state.personaId].name}</p> | |
| <div class="grid grid-cols-2 gap-4 mb-8"> | |
| <div class="bg-slate-800 p-4 rounded border border-slate-700"> | |
| <div class="text-sm text-slate-400">Final Net Worth</div> | |
| <div class="text-2xl font-bold text-white">βΉ${(state.money + (state.businessCash || 0)).toLocaleString()}</div> | |
| </div> | |
| <div class="bg-slate-800 p-4 rounded border border-slate-700"> | |
| <div class="text-sm text-slate-400">Wealth Score</div> | |
| <div class="text-2xl font-bold text-white">${state.stats.wealth}/100</div> | |
| </div> | |
| </div> | |
| <div class="bg-slate-800 p-6 rounded text-left mb-8 border border-slate-700"> | |
| <h4 class="font-bold text-white mb-4 text-lg flex items-center gap-2"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a10 10 0 1 0 10 10H12V2z"></path></svg> | |
| Behavioral Analysis | |
| </h4> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <div class="text-xs uppercase text-slate-500 font-bold mb-2">Strengths</div> | |
| ${goodHabits.length > 0 ? | |
| goodHabits.map(h => `<div class="text-green-400 text-sm flex items-center gap-2"><span>β</span> ${h.replace('_', ' ')}</div>`).join('') : | |
| <div class="text-slate-500 text-sm italic">No significant financial habits formed.</div> | |
| } | |
| </div> | |
| <div> | |
| <div class="text-xs uppercase text-slate-500 font-bold mb-2">Risks Detected</div> | |
| ${badHabits.length > 0 ? | |
| badHabits.map(h => `<div class="text-red-400 text-sm flex items-center gap-2"><span>β </span> ${h.replace('_', ' ')}</div>`).join('') : | |
| <div class="text-slate-500 text-sm italic">Clean financial record.</div> | |
| } | |
| </div> | |
| </div> | |
| </div> | |
| <button onclick="location.reload()" class="bg-slate-700 hover:bg-slate-600 text-white font-bold py-3 px-8 rounded-full border border-slate-500 transition-colors"> | |
| Play Again | |
| </button> | |
| </div> | |
| `; | |
| } | |
| // Init | |
| window.onload = () => { | |
| feather.replace(); | |
| initGame(); | |
| }; |