๐ŸŽฎArcadeLab

Survive Your Finances

by MagicLion67
2538 lines61.0 KB
โ–ถ Play
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Survive Your Finances</title>

<style>
    * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }

    body {
        font-family: Arial, Helvetica, sans-serif;
        background:
            radial-gradient(circle at top left, #183b67 0%, transparent 35%),
            radial-gradient(circle at bottom right, #102f4d 0%, transparent 35%),
            #07111f;
        color: #f5f7fa;
        min-height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 20px;
    }

    .game {
        width: 100%;
        max-width: 1050px;
        min-height: 700px;
        background: rgba(10, 24, 40, 0.97);
        border: 1px solid rgba(255,255,255,0.08);
        border-radius: 24px;
        overflow: hidden;
        box-shadow: 0 25px 80px rgba(0,0,0,0.45);
    }

    .topbar {
        padding: 18px 25px;
        background: rgba(255,255,255,0.035);
        border-bottom: 1px solid rgba(255,255,255,0.07);
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 15px;
        flex-wrap: wrap;
    }

    .brand {
        font-weight: 900;
        letter-spacing: 1px;
    }

    .stats {
        display: flex;
        gap: 10px;
        flex-wrap: wrap;
    }

    .stat {
        padding: 9px 14px;
        border-radius: 12px;
        background: rgba(255,255,255,0.07);
        font-size: 14px;
    }

    .stat strong {
        color: #67e8f9;
    }

    .progress-wrap {
        width: 100%;
        height: 6px;
        background: rgba(255,255,255,0.08);
    }

    .progress {
        height: 100%;
        width: 0%;
        background: linear-gradient(90deg, #22d3ee, #60a5fa);
        transition: width .4s ease;
    }

    .screen {
        padding: 55px;
        min-height: 630px;
        display: none;
        animation: fade .35s ease;
    }

    .screen.active {
        display: block;
    }

    @keyframes fade {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
    }

    .center {
        text-align: center;
    }

    .emoji-big {
        font-size: 70px;
        margin-bottom: 15px;
    }

    h1 {
        font-size: clamp(38px, 7vw, 72px);
        line-height: .95;
        margin-bottom: 20px;
        font-weight: 950;
    }

    h2 {
        font-size: 34px;
        margin-bottom: 12px;
    }

    h3 {
        margin-bottom: 8px;
    }

    .subtitle {
        color: #aebdce;
        font-size: 17px;
        line-height: 1.6;
        max-width: 720px;
        margin: 0 auto 30px;
    }

    .highlight {
        color: #67e8f9;
    }

    .income-card {
        margin: 30px auto;
        max-width: 430px;
        padding: 30px;
        border-radius: 22px;
        background: linear-gradient(135deg, rgba(34,211,238,.12), rgba(96,165,250,.08));
        border: 1px solid rgba(103,232,249,.2);
    }

    .income {
        font-size: 52px;
        font-weight: 900;
        color: #67e8f9;
    }

    .btn {
        border: none;
        border-radius: 13px;
        padding: 14px 22px;
        font-size: 15px;
        font-weight: 800;
        cursor: pointer;
        transition: .2s;
        color: white;
        background: linear-gradient(135deg, #0891b2, #2563eb);
        box-shadow: 0 8px 20px rgba(37,99,235,.22);
    }

    .btn:hover {
        transform: translateY(-2px);
        filter: brightness(1.1);
    }

    .btn:disabled {
        opacity: .4;
        cursor: not-allowed;
        transform: none;
    }

    .btn.secondary {
        background: rgba(255,255,255,.08);
        box-shadow: none;
    }

    .btn.danger {
        background: linear-gradient(135deg, #dc2626, #b91c1c);
    }

    .btn.success {
        background: linear-gradient(135deg, #059669, #047857);
    }

    .round-label {
        display: inline-block;
        padding: 8px 13px;
        border-radius: 999px;
        background: rgba(34,211,238,.1);
        color: #67e8f9;
        font-size: 13px;
        font-weight: 800;
        margin-bottom: 15px;
        letter-spacing: .5px;
    }

    .grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 16px;
        margin: 25px 0;
    }

    .card {
        background: rgba(255,255,255,.045);
        border: 1px solid rgba(255,255,255,.08);
        border-radius: 18px;
        padding: 20px;
    }

    .card:hover {
        border-color: rgba(103,232,249,.25);
    }

    .card-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 13px;
    }

    .amount {
        color: #67e8f9;
        font-weight: 900;
    }

    input[type="number"] {
        width: 100%;
        padding: 13px;
        border-radius: 10px;
        border: 1px solid rgba(255,255,255,.1);
        background: #081827;
        color: white;
        font-size: 16px;
        outline: none;
    }

    input[type="number"]:focus {
        border-color: #22d3ee;
    }

    .budget-total {
        position: sticky;
        bottom: 10px;
        padding: 18px;
        border-radius: 16px;
        background: rgba(7,17,31,.95);
        border: 1px solid rgba(255,255,255,.1);
        margin-top: 10px;
        backdrop-filter: blur(10px);
    }

    .budget-line {
        display: flex;
        justify-content: space-between;
        margin-bottom: 8px;
    }

    .remaining.good {
        color: #34d399;
    }

    .remaining.bad {
        color: #fb7185;
    }

    .choices {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 15px;
        margin: 20px 0;
    }

    .choice {
        border: 1px solid rgba(255,255,255,.1);
        background: rgba(255,255,255,.04);
        color: white;
        border-radius: 17px;
        padding: 20px;
        text-align: left;
        cursor: pointer;
        transition: .2s;
    }

    .choice:hover {
        transform: translateY(-3px);
        border-color: #22d3ee;
    }

    .choice.selected {
        border-color: #22d3ee;
        background: rgba(34,211,238,.12);
        box-shadow: 0 0 0 2px rgba(34,211,238,.08);
    }

    .choice .icon {
        font-size: 32px;
        margin-bottom: 10px;
    }

    .choice .price {
        color: #67e8f9;
        font-weight: 900;
        margin-top: 10px;
    }

    .choice small {
        display: block;
        color: #91a2b6;
        margin-top: 7px;
        line-height: 1.4;
    }

    .category {
        margin-top: 28px;
    }

    .category h3 {
        color: #dbeafe;
    }

    .feedback {
        margin-top: 20px;
        padding: 18px;
        border-radius: 15px;
        background: rgba(255,255,255,.05);
        border-left: 4px solid #22d3ee;
        line-height: 1.5;
    }

    .feedback.good {
        border-left-color: #34d399;
    }

    .feedback.bad {
        border-left-color: #fb7185;
    }

    .feedback.warning {
        border-left-color: #fbbf24;
    }

    .emergency-box {
        margin: 25px 0;
        padding: 25px;
        border-radius: 20px;
        background: linear-gradient(135deg, rgba(220,38,38,.12), rgba(251,191,36,.05));
        border: 1px solid rgba(248,113,113,.2);
    }

    .emergency-amount {
        font-size: 48px;
        font-weight: 950;
        color: #fb7185;
        margin: 10px 0;
    }

    .balance-board {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 12px;
        margin: 25px 0;
    }

    .balance-item {
        padding: 18px;
        border-radius: 15px;
        background: rgba(255,255,255,.05);
    }

    .balance-item span {
        display: block;
        color: #92a3b7;
        font-size: 12px;
        margin-bottom: 6px;
    }

    .balance-item strong {
        font-size: 20px;
    }

    .sorting {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 20px;
        margin-top: 25px;
    }

    .sort-zone {
        min-height: 280px;
        padding: 18px;
        border-radius: 18px;
        border: 2px dashed rgba(255,255,255,.13);
        background: rgba(255,255,255,.025);
    }

    .sort-zone h3 {
        text-align: center;
        margin-bottom: 15px;
    }

    .sort-items {
        display: flex;
        flex-direction: column;
        gap: 10px;
    }

    .sort-btn {
        padding: 13px;
        border: 1px solid rgba(255,255,255,.08);
        border-radius: 11px;
        background: rgba(255,255,255,.05);
        color: white;
        cursor: pointer;
        text-align: left;
    }

    .sort-btn:hover {
        border-color: #22d3ee;
    }

    .sort-btn.used {
        opacity: .35;
        pointer-events: none;
    }

    .final-score {
        font-size: 78px;
        font-weight: 950;
        color: #67e8f9;
        margin: 10px 0;
    }

    .rank {
        font-size: 28px;
        font-weight: 900;
        margin: 10px 0 25px;
    }

    .score-breakdown {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: 10px;
        margin: 25px 0;
    }

    .score-box {
        background: rgba(255,255,255,.05);
        padding: 15px 8px;
        border-radius: 14px;
    }

    .score-box span {
        display: block;
        font-size: 11px;
        color: #94a3b8;
        margin-bottom: 7px;
    }

    .score-box strong {
        font-size: 22px;
    }

    .lesson-list {
        text-align: left;
        max-width: 650px;
        margin: 25px auto;
        display: grid;
        gap: 10px;
    }

    .lesson {
        padding: 15px;
        border-radius: 13px;
        background: rgba(255,255,255,.05);
    }

    .nav {
        display: flex;
        justify-content: flex-end;
        gap: 10px;
        margin-top: 25px;
    }

    .nav.center {
        justify-content: center;
    }

    .mini {
        color: #91a2b6;
        font-size: 13px;
    }

    .hidden {
        display: none !important;
    }

    @media (max-width: 800px) {
        .screen {
            padding: 30px 20px;
        }

        .grid,
        .choices,
        .sorting {
            grid-template-columns: 1fr;
        }

        .balance-board {
            grid-template-columns: repeat(2, 1fr);
        }

        .score-breakdown {
            grid-template-columns: repeat(2, 1fr);
        }

        h2 {
            font-size: 28px;
        }
    }
</style>
</head>

<body>

<div class="game">

    <div class="topbar">
        <div class="brand">๐Ÿ’ธ SURVIVE YOUR FINANCES</div>

        <div class="stats">
            <div class="stat">๐Ÿ’ฐ <strong id="moneyTop">RM2,500</strong></div>
            <div class="stat">โญ <strong id="pointsTop">0</strong></div>
            <div class="stat">๐Ÿ“ <strong id="roundTop">START</strong></div>
        </div>
    </div>

    <div class="progress-wrap">
        <div class="progress" id="progress"></div>
    </div>


    <!-- INTRO -->

    <section class="screen active" id="intro">
        <div class="center">

            <div class="emoji-big">๐Ÿ’ธ</div>

            <div class="round-label">FINANCE SIMULATION GAME</div>

            <h1>
                SURVIVE YOUR<br>
                <span class="highlight">FINANCES</span>
            </h1>

            <p class="subtitle">
                Can you survive a month with
                <strong>RM2,500</strong>?
                Make smart choices, manage your money,
                and survive the month.
            </p>

            <div class="income-card">
                <div class="mini">MONTHLY INCOME</div>
                <div class="income">RM2,500</div>
                <p class="mini">Your financial survival challenge begins now.</p>
            </div>

            <button class="btn" onclick="startGame()">
                โ–ถ START GAME
            </button>

        </div>
    </section>


    <!-- HOW TO PLAY -->

    <section class="screen" id="how">
        <div class="center">

            <div class="round-label">HOW TO PLAY ๐ŸŽฎ</div>

            <h2>Six Moves. One Month.</h2>

            <p class="subtitle">
                Every decision changes your financial outcome.
            </p>

            <div class="grid">

                <div class="card">
                    <h3>01 ๐Ÿ’ฐ</h3>
                    <p>Receive your RM2,500 monthly income.</p>
                </div>

                <div class="card">
                    <h3>02 ๐Ÿงพ</h3>
                    <p>Build a monthly budget.</p>
                </div>

                <div class="card">
                    <h3>03 ๐Ÿ›๏ธ</h3>
                    <p>Make lifestyle and spending choices.</p>
                </div>

                <div class="card">
                    <h3>04 ๐Ÿšจ</h3>
                    <p>Face unexpected financial emergencies.</p>
                </div>

                <div class="card">
                    <h3>05 ๐Ÿง </h3>
                    <p>Manage your remaining money wisely.</p>
                </div>

                <div class="card">
                    <h3>06 ๐Ÿ†</h3>
                    <p>Collect points and become the Financial Master.</p>
                </div>

            </div>

            <div class="feedback">
                ๐Ÿ’ก <strong>Remember:</strong> Every choice has a consequence.
            </div>

            <div class="nav center">
                <button class="btn" onclick="showScreen('month')">
                    CONTINUE โ†’
                </button>
            </div>

        </div>
    </section>


    <!-- MONTH -->

    <section class="screen" id="month">
        <div class="center">

            <div class="round-label">YOUR NEW MONTH BEGINS ๐Ÿ’ฐ</div>

            <h2>You've Got RM2,500.</h2>

            <p class="subtitle">
                Your goal is simple:
                <strong>survive the month without unnecessary debt.</strong>
            </p>

            <div class="balance-board">

                <div class="balance-item">
                    <span>MONTHLY INCOME</span>
                    <strong>RM2,500</strong>
                </div>

                <div class="balance-item">
                    <span>STARTING BALANCE</span>
                    <strong>RM2,500</strong>
                </div>

                <div class="balance-item">
                    <span>GOAL</span>
                    <strong>Survive</strong>
                </div>

                <div class="balance-item">
                    <span>ROUNDS</span>
                    <strong>4</strong>
                </div>

            </div>

            <div class="feedback">
                ๐Ÿ  Prioritise <strong>needs</strong> โ†’ ๐Ÿ’ต Save consistently โ†’
                ๐Ÿ›ก๏ธ Protect yourself with an <strong>emergency fund</strong>.
            </div>

            <div class="nav center">
                <button class="btn" onclick="showScreen('round1')">
                    START ROUND 1 โ†’
                </button>
            </div>

        </div>
    </section>


    <!-- ROUND 1 -->

    <section class="screen" id="round1">

        <div class="round-label">ROUND 1 / 4 โ€” BUILD YOUR BUDGET ๐Ÿงพ</div>

        <h2>Build Your Monthly Budget</h2>

        <p class="subtitle" style="margin-left:0">
            You have <strong>RM2,500</strong>.
            Allocate every ringgit carefully.
            Your total must equal exactly RM2,500.
        </p>

        <div class="grid">

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿ  Rent</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="rent" min="0" value="700" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿš Food</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="food" min="0" value="300" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐ŸšŒ Transportation</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="transport" min="0" value="150" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿ’ก Bills</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="bills" min="0" value="150" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿ›๏ธ Wants</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="wants" min="0" value="200" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿ’ต Savings</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="savings" min="0" value="500" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿ›ก๏ธ Emergency Fund</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="emergency" min="0" value="500" oninput="updateBudget()">
            </div>

            <div class="card">
                <div class="card-title">
                    <span>๐Ÿ“ฑ Phone / Data</span>
                    <span class="amount">RM</span>
                </div>
                <input type="number" id="phone" min="0" value="0" oninput="updateBudget()">
            </div>

        </div>

        <div class="budget-total">

            <div class="budget-line">
                <span>Total Allocated</span>
                <strong id="budgetTotal">RM2,500</strong>
            </div>

            <div class="budget-line">
                <span>Remaining</span>
                <strong id="budgetRemaining" class="remaining good">RM0</strong>
            </div>

        </div>

        <div id="budgetFeedback" class="feedback hidden"></div>

        <div class="nav">
            <button class="btn" id="budgetBtn" onclick="submitBudget()">
                SUBMIT BUDGET
            </button>
        </div>

    </section>


    <!-- ROUND 2 -->

    <section class="screen" id="round2">

        <div class="round-label">ROUND 2 / 4 โ€” CHOOSE YOUR LIFESTYLE ๐Ÿ›๏ธ</div>

        <h2>Your Budget Affects Your Lifestyle</h2>

        <p class="subtitle" style="margin-left:0">
            Choose ONE option from each category.
            Expensive choices may feel good now...
            but they leave less room for savings and emergencies.
        </p>

        <!-- FOOD -->

        <div class="category">

            <h3>๐Ÿ” FOOD</h3>

            <div class="choices">

                <button class="choice" onclick="chooseLifestyle('food', 300, this)">
                    <div class="icon">๐Ÿณ</div>
                    <strong>Cook at Home</strong>
                    <small>Affordable and controlled spending.</small>
                    <div class="price">RM300</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('food', 500, this)">
                    <div class="icon">๐Ÿœ</div>
                    <strong>Eat at Cafรฉs</strong>
                    <small>Convenient but more expensive.</small>
                    <div class="price">RM500</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('food', 800, this)">
                    <div class="icon">๐Ÿ›ต</div>
                    <strong>Food Delivery</strong>
                    <small>Maximum convenience, maximum cost.</small>
                    <div class="price">RM800</div>
                </button>

            </div>

        </div>


        <!-- TRANSPORT -->

        <div class="category">

            <h3>๐Ÿš— TRANSPORT</h3>

            <div class="choices">

                <button class="choice" onclick="chooseLifestyle('transport', 100, this)">
                    <div class="icon">๐ŸšŒ</div>
                    <strong>Public Transport</strong>
                    <small>Cheap and budget-friendly.</small>
                    <div class="price">RM100</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('transport', 250, this)">
                    <div class="icon">๐Ÿ๏ธ</div>
                    <strong>Motorcycle</strong>
                    <small>More flexible, moderate cost.</small>
                    <div class="price">RM250</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('transport', 500, this)">
                    <div class="icon">๐Ÿš—</div>
                    <strong>Car</strong>
                    <small>Convenient but costly.</small>
                    <div class="price">RM500</div>
                </button>

            </div>

        </div>


        <!-- ENTERTAINMENT -->

        <div class="category">

            <h3>๐ŸŽฌ ENTERTAINMENT</h3>

            <div class="choices">

                <button class="choice" onclick="chooseLifestyle('entertainment', 0, this)">
                    <div class="icon">๐ŸŒณ</div>
                    <strong>Free Activities</strong>
                    <small>Park, games, friends and chill.</small>
                    <div class="price">RM0</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('entertainment', 150, this)">
                    <div class="icon">๐ŸŽฌ</div>
                    <strong>Movie + Cafรฉ</strong>
                    <small>A little fun without going crazy.</small>
                    <div class="price">RM150</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('entertainment', 400, this)">
                    <div class="icon">๐Ÿ›๏ธ</div>
                    <strong>Shopping</strong>
                    <small>Fun now, painful later.</small>
                    <div class="price">RM400</div>
                </button>

            </div>

        </div>


        <!-- PHONE -->

        <div class="category">

            <h3>๐Ÿ“ฑ PHONE / DATA</h3>

            <div class="choices">

                <button class="choice" onclick="chooseLifestyle('phone', 30, this)">
                    <div class="icon">๐Ÿ“ถ</div>
                    <strong>Basic Plan</strong>
                    <small>Enough for calls, texts and normal data.</small>
                    <div class="price">RM30</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('phone', 60, this)">
                    <div class="icon">๐Ÿ“ฑ</div>
                    <strong>Unlimited Plan</strong>
                    <small>More data and more convenience.</small>
                    <div class="price">RM60</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('phone', 100, this)">
                    <div class="icon">๐Ÿ”ฅ</div>
                    <strong>Premium Plan</strong>
                    <small>Extra services you may not actually need.</small>
                    <div class="price">RM100</div>
                </button>

            </div>

        </div>


        <!-- SHOPPING -->

        <div class="category">

            <h3>๐Ÿ‘• SHOPPING</h3>

            <div class="choices">

                <button class="choice" onclick="chooseLifestyle('shopping', 0, this)">
                    <div class="icon">๐Ÿšซ</div>
                    <strong>No Shopping</strong>
                    <small>Protect your money this month.</small>
                    <div class="price">RM0</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('shopping', 100, this)">
                    <div class="icon">๐Ÿ‘•</div>
                    <strong>Small Treat</strong>
                    <small>One small purchase.</small>
                    <div class="price">RM100</div>
                </button>

                <button class="choice" onclick="chooseLifestyle('shopping', 300, this)">
                    <div class="icon">๐Ÿ›’</div>
                    <strong>Shopping Spree</strong>
                    <small>Enjoy now... worry later.</small>
                    <div class="price">RM300</div>
                </button>

            </div>

        </div>

        <div id="lifestyleFeedback" class="feedback hidden"></div>

        <div class="nav">
            <button class="btn" onclick="finishRound2()">
                LOCK IN MY LIFESTYLE โ†’
            </button>
        </div>

    </section>


    <!-- ROUND 3 -->

    <section class="screen" id="round3">

        <div class="round-label">ROUND 3 / 4 โ€” LIFE HAPPENS ๐Ÿšจ</div>

        <h2>Unexpected Expenses!</h2>

        <p class="subtitle" style="margin-left:0">
            Your financial plan is about to be tested.
            Choose carefully because emergencies affect your final score.
        </p>

        <div class="balance-board">

            <div class="balance-item">
                <span>SAVINGS</span>
                <strong id="r3Savings">RM0</strong>
            </div>

            <div class="balance-item">
                <span>EMERGENCY FUND</span>
                <strong id="r3Emergency">RM0</strong>
            </div>

            <div class="balance-item">
                <span>DEBT</span>
                <strong id="r3Debt">RM0</strong>
            </div>

            <div class="balance-item">
                <span>POINTS</span>
                <strong id="r3Points">0</strong>
            </div>

        </div>

        <div id="emergencyArea"></div>

    </section>


    <!-- ROUND 4 -->

    <section class="screen" id="round4">

        <div class="round-label">ROUND 4 / 4 โ€” NEED OR WANT? ๐Ÿค”</div>

        <h2>Test Your Financial Brain</h2>

        <p class="subtitle" style="margin-left:0">
            For each item, decide whether it is a
            <strong>NEED</strong> or a <strong>WANT</strong>.
        </p>

        <div id="sortingArea" class="sorting"></div>

        <div class="feedback">
            ๐Ÿ’ก <strong>Tip:</strong> Needs are essential for living.
            Wants improve your lifestyle but can usually be delayed.
        </div>

        <div class="nav">
            <button class="btn" id="finishSortBtn" onclick="finishRound4()" disabled>
                FINISH ROUND โ†’
            </button>
        </div>

    </section>


    <!-- FINAL -->

    <section class="screen" id="final">

        <div class="center">

            <div class="round-label">FINAL CHECKPOINT ๐Ÿ“Š</div>

            <h2 id="finalTitle">Did You Survive?</h2>

            <p class="subtitle">
                Let's see how well you managed your RM2,500.
            </p>

            <div class="final-score">
                <span id="finalScore">0</span>
                <span style="font-size:28px">/100</span>
            </div>

            <div class="rank" id="finalRank"></div>

            <div class="balance-board">

                <div class="balance-item">
                    <span>TOTAL SPENDING</span>
                    <strong id="finalSpending">RM0</strong>
                </div>

                <div class="balance-item">
                    <span>SAVINGS</span>
                    <strong id="finalSavings">RM0</strong>
                </div>

                <div class="balance-item">
                    <span>EMERGENCY FUND</span>
                    <strong id="finalEmergency">RM0</strong>
                </div>

                <div class="balance-item">
                    <span>DEBT</span>
                    <strong id="finalDebt">RM0</strong>
                </div>

            </div>

            <h3>๐Ÿ† SCORE BREAKDOWN</h3>

            <div class="score-breakdown">

                <div class="score-box">
                    <span>BUDGET</span>
                    <strong id="scoreBudget">0</strong>/20
                </div>

                <div class="score-box">
                    <span>NEEDS/WANTS</span>
                    <strong id="scoreNeeds">0</strong>/20
                </div>

                <div class="score-box">
                    <span>SAVINGS</span>
                    <strong id="scoreSavings">0</strong>/20
                </div>

                <div class="score-box">
                    <span>EMERGENCY</span>
                    <strong id="scoreEmergency">0</strong>/20
                </div>

                <div class="score-box">
                    <span>DECISIONS</span>
                    <strong id="scoreDecision">0</strong>/20
                </div>

            </div>

            <div id="finalMessage" class="feedback"></div>

            <div class="lesson-list">

                <div class="lesson">
                    ๐Ÿ’ฐ <strong>Budget before spending.</strong>
                </div>

                <div class="lesson">
                    ๐Ÿ  <strong>Prioritise needs over wants.</strong>
                </div>

                <div class="lesson">
                    ๐Ÿ’ต <strong>Save consistently.</strong>
                </div>

                <div class="lesson">
                    ๐Ÿ›ก๏ธ <strong>Build an emergency fund.</strong>
                </div>

                <div class="lesson">
                    ๐Ÿง  <strong>Think through the consequences.</strong>
                </div>

            </div>

            <button class="btn" onclick="location.reload()">
                โ†ป PLAY AGAIN
            </button>

        </div>

    </section>

</div>


<script>

/* =========================================================
   GAME STATE
========================================================= */

const game = {

    income: 2500,

    budget: {
        rent: 0,
        food: 0,
        transport: 0,
        bills: 0,
        wants: 0,
        savings: 0,
        emergency: 0,
        phone: 0
    },

    lifestyle: {
        food: 0,
        transport: 0,
        entertainment: 0,
        phone: 0,
        shopping: 0
    },

    savings: 0,
    emergency: 0,
    debt: 0,

    points: 0,

    budgetScore: 0,
    savingsScore: 0,
    emergencyScore: 0,
    decisionScore: 0,
    needsScore: 0,

    emergenciesCompleted: 0,

    emergencyIndex: 0,

    sortCorrect: 0,

    sorted: 0
};


/* =========================================================
   SCREEN CONTROL
========================================================= */

const screens = [
    "intro",
    "how",
    "month",
    "round1",
    "round2",
    "round3",
    "round4",
    "final"
];

function showScreen(id) {

    document.querySelectorAll(".screen").forEach(screen => {
        screen.classList.remove("active");
    });

    document.getElementById(id).classList.add("active");

    updateTopBar(id);

    window.scrollTo({
        top: 0,
        behavior: "smooth"
    });
}


function updateTopBar(id) {

    document.getElementById("moneyTop").textContent =
        "RM" + Math.max(0, calculateRemainingMoney()).toLocaleString();

    document.getElementById("pointsTop").textContent =
        game.points;

    let roundText = "START";

    if (id === "round1") roundText = "ROUND 1";
    if (id === "round2") roundText = "ROUND 2";
    if (id === "round3") roundText = "ROUND 3";
    if (id === "round4") roundText = "ROUND 4";
    if (id === "final") roundText = "FINAL";

    document.getElementById("roundTop").textContent = roundText;

    let percentage = 0;

    if (id === "how") percentage = 8;
    if (id === "month") percentage = 15;
    if (id === "round1") percentage = 25;
    if (id === "round2") percentage = 50;
    if (id === "round3") percentage = 72;
    if (id === "round4") percentage = 88;
    if (id === "final") percentage = 100;

    document.getElementById("progress").style.width = percentage + "%";
}


/* =========================================================
   START
========================================================= */

function startGame() {
    showScreen("how");
}


/* =========================================================
   ROUND 1 โ€” BUDGET
========================================================= */

function updateBudget() {

    const fields = [
        "rent",
        "food",
        "transport",
        "bills",
        "wants",
        "savings",
        "emergency",
        "phone"
    ];

    let total = 0;

    fields.forEach(id => {

        let value = Number(document.getElementById(id).value);

        if (value < 0 || isNaN(value)) {
            value = 0;
        }

        total += value;
    });

    const remaining = 2500 - total;

    document.getElementById("budgetTotal").textContent =
        "RM" + total.toLocaleString();

    document.getElementById("budgetRemaining").textContent =
        "RM" + Math.abs(remaining).toLocaleString();

    document.getElementById("budgetRemaining").className =
        "remaining " + (remaining >= 0 ? "good" : "bad");

    const btn = document.getElementById("budgetBtn");

    btn.disabled = total !== 2500;

    if (total === 2500) {
        btn.textContent = "SUBMIT BUDGET โœ“";
    } else if (total > 2500) {
        btn.textContent = "OVER BUDGET";
    } else {
        btn.textContent = "RM" + remaining.toLocaleString() + " LEFT";
    }
}


function submitBudget() {

    const fields = [
        "rent",
        "food",
        "transport",
        "bills",
        "wants",
        "savings",
        "emergency",
        "phone"
    ];

    let total = 0;

    fields.forEach(id => {

        game.budget[id] =
            Math.max(0, Number(document.getElementById(id).value) || 0);

        total += game.budget[id];
    });

    if (total !== 2500) {
        return;
    }

    game.savings = game.budget.savings;
    game.emergency = game.budget.emergency;

    /* Budget scoring */

    let score = 0;

    if (game.budget.savings >= 400) score += 8;
    else if (game.budget.savings >= 250) score += 5;
    else if (game.budget.savings >= 100) score += 3;

    if (game.budget.emergency >= 400) score += 7;
    else if (game.budget.emergency >= 200) score += 5;
    else if (game.budget.emergency > 0) score += 2;

    if (game.budget.wants <= 250) score += 5;
    else if (game.budget.wants <= 400) score += 3;

    game.budgetScore = Math.min(20, score);

    game.points += game.budgetScore;

    const feedback = document.getElementById("budgetFeedback");

    feedback.classList.remove("hidden");

    if (game.budgetScore >= 16) {

        feedback.className = "feedback good";

        feedback.innerHTML =
            "๐Ÿ”ฅ <strong>Excellent budget!</strong><br>" +
            "You prioritised savings, emergency protection and controlled your wants." +
            "<br><strong>+" + game.budgetScore + " points</strong>";

    } else if (game.budgetScore >= 10) {

        feedback.className = "feedback warning";

        feedback.innerHTML =
            "๐Ÿ‘ <strong>Not bad!</strong><br>" +
            "Your budget is workable, but there is still room to improve your financial protection." +
            "<br><strong>+" + game.budgetScore + " points</strong>";

    } else {

        feedback.className = "feedback bad";

        feedback.innerHTML =
            "โš ๏ธ <strong>Risky budget.</strong><br>" +
            "You may struggle when an unexpected expense appears." +
            "<br><strong>+" + game.budgetScore + " points</strong>";
    }

    const btn = document.getElementById("budgetBtn");

    btn.textContent = "CONTINUE โ†’";

    btn.onclick = function() {
        showScreen("round2");
        updateTopBar("round2");
    };
}


/* =========================================================
   ROUND 2 โ€” LIFESTYLE
========================================================= */

const lifestyleChoices = {
    food: null,
    transport: null,
    entertainment: null,
    phone: null,
    shopping: null
};


function chooseLifestyle(category, amount, element) {

    lifestyleChoices[category] = amount;

    const parent = element.parentElement;

    parent.querySelectorAll(".choice").forEach(btn => {
        btn.classList.remove("selected");
    });

    element.classList.add("selected");

    calculateLifestyleFeedback();
}


function calculateLifestyleTotal() {

    return Object.values(lifestyleChoices)
        .reduce((sum, value) => sum + (value || 0), 0);
}


function calculateLifestyleFeedback() {

    const selected = Object.values(lifestyleChoices)
        .filter(value => value !== null);

    if (selected.length === 0) return;

    const total = calculateLifestyleTotal();

    const feedback = document.getElementById("lifestyleFeedback");

    feedback.classList.remove("hidden");

    const baseSpending =
        game.budget.rent +
        game.budget.bills;

    const remaining =
        2500 -
        baseSpending -
        total;

    if (remaining >= 700) {

        feedback.className = "feedback good";

        feedback.innerHTML =
            "๐ŸŸข <strong>Comfortable lifestyle.</strong><br>" +
            "Estimated money remaining after your current choices: " +
            "<strong>RM" + remaining.toLocaleString() + "</strong>.";

    } else if (remaining >= 400) {

        feedback.className = "feedback warning";

        feedback.innerHTML =
            "๐ŸŸก <strong>Be careful.</strong><br>" +
            "Your lifestyle is manageable, but unexpected expenses could reduce your savings.";

    } else {

        feedback.className = "feedback bad";

        feedback.innerHTML =
            "๐Ÿ”ด <strong>Danger zone!</strong><br>" +
            "Your lifestyle choices are eating up a large part of your monthly money.";
    }
}


function finishRound2() {

    const categories = Object.keys(lifestyleChoices);

    const missing = categories.filter(
        category => lifestyleChoices[category] === null
    );

    if (missing.length > 0) {

        alert(
            "You haven't chosen everything yet!\n\n" +
            "Complete all 5 lifestyle categories."
        );

        return;
    }

    game.lifestyle = {
        ...lifestyleChoices
    };

    const lifestyleTotal = calculateLifestyleTotal();

    /*
        Decision score:
        Lower lifestyle cost = better protection.
    */

    let score = 0;

    if (lifestyleTotal <= 500) score = 20;
    else if (lifestyleTotal <= 750) score = 16;
    else if (lifestyleTotal <= 1000) score = 12;
    else if (lifestyleTotal <= 1250) score = 8;
    else score = 5;

    game.decisionScore += score;

    game.points += score;

    showScreen("round3");

    prepareRound3();
}


/* =========================================================
   ROUND 3 โ€” EMERGENCIES
========================================================= */

const emergencies = [

    {
        icon: "๐Ÿ๏ธ",
        title: "Your motorcycle suddenly breaks down.",
        amount: 350,
        options: [
            {
                title: "USE EMERGENCY FUND",
                type: "emergency",
                points: 10,
                lesson: "Excellent! This is exactly why an emergency fund exists."
            },
            {
                title: "USE SAVINGS",
                type: "savings",
                points: 5,
                lesson: "You solved the problem, but your long-term savings are reduced."
            },
            {
                title: "BORROW MONEY",
                type: "borrow",
                points: -5,
                lesson: "The problem is solved now, but debt creates a future obligation."
            }
        ]
    },

    {
        icon: "๐Ÿฅ",
        title: "You receive an unexpected medical bill.",
        amount: 500,
        options: [
            {
                title: "USE EMERGENCY FUND",
                type: "emergency",
                points: 10,
                lesson: "Good decision. Your emergency fund protects you from unexpected medical costs."
            },
            {
                title: "CUT WANTS + USE CASH",
                type: "cash",
                points: 7,
                lesson: "Smart adjustment. You sacrificed wants instead of creating debt."
            },
            {
                title: "USE CREDIT / BORROW",
                type: "borrow",
                points: -5,
                lesson: "Borrowing can help immediately, but debt may follow you into the next month."
            }
        ]
    },

    {
        icon: "๐Ÿ“ฑ",
        title: "Your phone screen breaks and you need it for university.",
        amount: 300,
        options: [
            {
                title: "USE EMERGENCY FUND",
                type: "emergency",
                points: 9,
                lesson: "Your emergency fund protects you from unexpected essential repairs."
            },
            {
                title: "USE SAVINGS",
                type: "savings",
                points: 5,
                lesson: "You avoided debt, but your savings took a hit."
            },
            {
                title: "BUY A NEW PHONE ON CREDIT",
                type: "borrow",
                points: -6,
                lesson: "Buying on credit creates debt for something that could potentially be repaired."
            }
        ]
    },

    {
        icon: "๐Ÿ ",
        title: "Your landlord requires an unexpected RM300 repair contribution.",
        amount: 300,
        options: [
            {
                title: "USE EMERGENCY FUND",
                type: "emergency",
                points: 9,
                lesson: "Good use of emergency protection for an unexpected essential expense."
            },
            {
                title: "CUT ENTERTAINMENT + PAY",
                type: "cash",
                points: 7,
                lesson: "You adjusted your lifestyle instead of borrowing."
            },
            {
                title: "BORROW MONEY",
                type: "borrow",
                points: -5,
                lesson: "Debt solves the immediate issue but reduces your future financial flexibility."
            }
        ]
    }

];


function prepareRound3() {

    game.emergencyIndex = 0;

    renderEmergency();
}


function renderEmergency() {

    const area = document.getElementById("emergencyArea");

    if (game.emergencyIndex >= emergencies.length) {

        finishRound3();

        return;
    }

    const e = emergencies[game.emergencyIndex];

    document.getElementById("r3Savings").textContent =
        "RM" + Math.max(0, game.savings).toLocaleString();

    document.getElementById("r3Emergency").textContent =
        "RM" + Math.max(0, game.emergency).toLocaleString();

    document.getElementById("r3Debt").textContent =
        "RM" + game.debt.toLocaleString();

    document.getElementById("r3Points").textContent =
        game.points;

    area.innerHTML = `

        <div class="emergency-box">

            <div style="font-size:48px">${e.icon}</div>

            <h3>EMERGENCY ${game.emergencyIndex + 1} / ${emergencies.length}</h3>

            <p style="font-size:20px; margin-top:10px;">
                ${e.title}
            </p>

            <div class="emergency-amount">
                RM${e.amount}
            </div>

            <p class="mini">
                How will you pay?
            </p>

        </div>

        <div class="choices">

            ${e.options.map((option, index) => `

                <button
                    class="choice"
                    onclick="handleEmergency(${index})"
                >

                    <div class="icon">
                        ${index === 0 ? "๐Ÿ›ก๏ธ" : index === 1 ? "๐Ÿ’ต" : "๐Ÿ’ณ"}
                    </div>

                    <strong>${option.title}</strong>

                    <small>
                        ${index === 0
                            ? "Protect your finances."
                            : index === 1
                            ? "Avoid unnecessary debt."
                            : "Get money now, pay later."
                        }
                    </small>

                </button>

            `).join("")}

        </div>

        <div id="emergencyFeedback"></div>
    `;
}


function handleEmergency(optionIndex) {

    const e = emergencies[game.emergencyIndex];

    const option = e.options[optionIndex];

    let message = "";
    let className = "feedback";

    if (option.type === "emergency") {

        if (game.emergency >= e.amount) {

            game.emergency -= e.amount;

            message = `
                ๐ŸŸข <strong>GOOD DECISION!</strong><br>
                You used your emergency fund to handle the unexpected expense.<br><br>
                Emergency Fund: <strong>-RM${e.amount}</strong><br>
                Debt: <strong>RM${game.debt}</strong><br>
                <strong>+${option.points} POINTS</strong><br><br>
                ๐Ÿ’ก ${option.lesson}
            `;

            className += " good";

        } else {

            const available = game.emergency;

            game.emergency = 0;

            const remaining = e.amount - available;

            game.debt += remaining;

            message = `
                โš ๏ธ <strong>YOUR EMERGENCY FUND WAS TOO SMALL.</strong><br>
                You had RM${available} available, so you still needed RM${remaining}.<br><br>
                Remaining amount became debt.<br>
                Debt: <strong>RM${game.debt}</strong><br>
                <strong>+${Math.max(-5, option.points - 4)} POINTS</strong><br><br>
                ๐Ÿ’ก Try building a larger emergency fund.
            `;

            game.points += Math.max(-5, option.points - 4);

            className += " warning";

            updateTopBar("round3");

            showEmergencyContinue(message, className);

            return;
        }

    } else if (option.type === "savings") {

        if (game.savings >= e.amount) {

            game.savings -= e.amount;

            message = `
                ๐ŸŸก <strong>ACCEPTABLE DECISION</strong><br>
                You used your savings to cover the emergency.<br><br>
                Savings: <strong>-RM${e.amount}</strong><br>
                Debt: <strong>RM${game.debt}</strong><br>
                <strong>+${option.points} POINTS</strong><br><br>
                ๐Ÿ’ก ${option.lesson}
            `;

            className += " warning";

        } else {

            const available = game.savings;

            game.savings = 0;

            const remaining = e.amount - available;

            game.debt += remaining;

            message = `
                โš ๏ธ <strong>NOT ENOUGH SAVINGS.</strong><br>
                You used your remaining RM${available}, then borrowed RM${remaining}.<br><br>
                Debt: <strong>RM${game.debt}</strong><br>
                <strong>+1 POINT</strong>
            `;

            game.points += 1;

            className += " warning";

            updateTopBar("round3");

            showEmergencyContinue(message, className);

            return;
        }

    } else if (option.type === "cash") {

        /*
            Cutting wants means we sacrifice lifestyle money
            instead of touching savings.
        */

        const lifestyleTotal = calculateLifestyleTotal();

        if (lifestyleTotal >= e.amount) {

            game.points += option.points;

            message = `
                ๐ŸŸข <strong>SMART ADJUSTMENT!</strong><br>
                You cut unnecessary spending to handle the emergency.<br><br>
                No new debt.<br>
                Savings protected.<br>
                <strong>+${option.points} POINTS</strong><br><br>
                ๐Ÿ’ก ${option.lesson}
            `;

            className += " good";

        } else {

            const shortfall = e.amount - lifestyleTotal;

            game.debt += shortfall;

            game.points += 2;

            message = `
                ๐ŸŸก <strong>PARTIAL SOLUTION.</strong><br>
                Your lifestyle spending wasn't enough to fully cover the expense.<br><br>
                Remaining debt: <strong>RM${shortfall}</strong><br>
                <strong>+2 POINTS</strong>
            `;

            className += " warning";

            updateTopBar("round3");

            showEmergencyContinue(message, className);

            return;
        }

    } else if (option.type === "borrow") {

        game.debt += e.amount;

        message = `
            ๐Ÿ”ด <strong>RISKY DECISION</strong><br>
            You borrowed RM${e.amount} to pay for the emergency.<br><br>
            Immediate payment: <strong>RM0</strong><br>
            Debt: <strong>RM${game.debt}</strong><br>
            <strong>${option.points} POINTS</strong><br><br>
            ๐Ÿ’ก ${option.lesson}
        `;

        className += " bad";
    }

    game.points += option.points;

    showEmergencyContinue(message, className);
}


function showEmergencyContinue(message, className) {

    const feedback = document.getElementById("emergencyFeedback");

    feedback.className = className;

    feedback.innerHTML = `
        ${message}

        <br><br>

        <button
            class="btn"
            onclick="nextEmergency()"
        >
            ${game.emergencyIndex < emergencies.length - 1
                ? "NEXT EMERGENCY โ†’"
                : "CONTINUE TO ROUND 4 โ†’"
            }
        </button>
    `;

    document.querySelectorAll("#emergencyArea .choice")
        .forEach(button => {
            button.disabled = true;
            button.style.opacity = ".45";
            button.style.pointerEvents = "none";
        });

    updateTopBar("round3");
}


function nextEmergency() {

    game.emergencyIndex++;

    renderEmergency();
}


function finishRound3() {

    /*
        Emergency score is based on:
        - having emergency fund
        - avoiding debt
        - making good decisions
    */

    let score = 0;

    if (game.emergency >= 300) score += 8;
    else if (game.emergency > 0) score += 5;

    if (game.debt === 0) score += 7;
    else if (game.debt <= 300) score += 4;

    if (game.savings > 0) score += 5;

    game.emergencyScore = Math.min(20, score);

    game.points += game.emergencyScore;

    // Prepare Round 4
    setupRound4();

    // FIX: actually move the player to Round 4
    showScreen("round4");
}


/* =========================================================
   ROUND 4 โ€” NEEDS VS WANTS
========================================================= */

const sortingItems = [

    {
        name: "๐Ÿš Groceries",
        price: 200,
        correct: "need"
    },

    {
        name: "๐Ÿ“ฑ New Phone",
        price: 1200,
        correct: "want"
    },

    {
        name: "๐Ÿ  Rent",
        price: 700,
        correct: "need"
    },

    {
        name: "๐ŸŽง New Headphones",
        price: 300,
        correct: "want"
    },

    {
        name: "๐Ÿ’ก Electricity Bill",
        price: 100,
        correct: "need"
    },

    {
        name: "๐Ÿ” Food Delivery",
        price: 80,
        correct: "want"
    },

    {
        name: "๐Ÿ’Š Medicine",
        price: 50,
        correct: "need"
    },

    {
        name: "๐ŸŽฎ New Video Game",
        price: 250,
        correct: "want"
    }

];


function setupRound4() {

    const area = document.getElementById("sortingArea");

    area.innerHTML = `

        <div class="sort-zone">

            <h3>๐Ÿ  NEEDS</h3>

            <div class="sort-items" id="needItems">

                ${sortingItems.map((item, index) => `

                    <button
                        class="sort-btn"
                        id="item${index}"
                        onclick="sortItem(${index}, 'need')"
                    >

                        ${item.name}
                        <span style="float:right;color:#67e8f9">
                            RM${item.price}
                        </span>

                    </button>

                `).join("")}

            </div>

        </div>


        <div class="sort-zone">

            <h3>๐Ÿ›๏ธ WANTS</h3>

            <div class="sort-items" id="wantItems">

                ${sortingItems.map((item, index) => `

                    <button
                        class="sort-btn"
                        id="itemWant${index}"
                        onclick="sortItem(${index}, 'want')"
                    >

                        ${item.name}
                        <span style="float:right;color:#67e8f9">
                            RM${item.price}
                        </span>

                    </button>

                `).join("")}

            </div>

        </div>
    `;

    /*
        We hide duplicate buttons initially.
        A separate selector will appear below.
    */

    const zones = area.querySelectorAll(".sort-zone");

    zones.forEach(zone => {

        const buttons = zone.querySelectorAll(".sort-btn");

        buttons.forEach(button => {
            button.style.display = "none";
        });

    });

    createSortingSelector();
}


function createSortingSelector() {

    const area = document.getElementById("sortingArea");

    const selector = document.createElement("div");

    selector.style.gridColumn = "1 / -1";
    selector.innerHTML = `
        <div class="card">

            <h3>Choose an item to classify:</h3>

            <div
                id="sortingButtons"
                style="
                    display:grid;
                    grid-template-columns:repeat(2,1fr);
                    gap:10px;
                    margin-top:15px;
                "
            >

                ${sortingItems.map((item, index) => `

                    <button
                        class="choice"
                        id="sortChoice${index}"
                        onclick="selectSortItem(${index})"
                        style="padding:15px;"
                    >

                        ${item.name}
                        <br>
                        <span class="mini">
                            RM${item.price}
                        </span>

                    </button>

                `).join("")}

            </div>

            <p
                id="sortInstruction"
                class="mini"
                style="margin-top:15px;"
            >
                Pick an item above, then choose NEED or WANT.
            </p>

        </div>
    `;

    area.appendChild(selector);
}


let selectedSortItem = null;


function selectSortItem(index) {

    selectedSortItem = index;

    document.querySelectorAll("#sortingButtons .choice")
        .forEach(button => {
            button.classList.remove("selected");
        });

    document
        .getElementById("sortChoice" + index)
        .classList.add("selected");

    document.getElementById("sortInstruction").innerHTML = `

        <strong>${sortingItems[index].name}</strong>

        โ€” Is this a NEED or a WANT?

        <br><br>

        <button
            class="btn"
            onclick="sortItem(${index}, 'need')"
        >
            ๐Ÿ  NEED
        </button>

        <button
            class="btn secondary"
            onclick="sortItem(${index}, 'want')"
        >
            ๐Ÿ›๏ธ WANT
        </button>
    `;
}


function sortItem(index, answer) {

    if (selectedSortItem !== index) return;

    const item = sortingItems[index];

    const correct = item.correct === answer;

    if (correct) {

        game.sortCorrect++;

        game.points += 2;

        document.getElementById("sortChoice" + index).style.opacity = ".35";

        document.getElementById("sortChoice" + index).style.pointerEvents = "none";

        document.getElementById("sortInstruction").innerHTML = `
            ๐ŸŸข <strong>CORRECT!</strong>
            ${item.name} is a
            <strong>${item.correct.toUpperCase()}</strong>.
            +2 points!
        `;

    } else {

        game.points -= 1;

        document.getElementById("sortInstruction").innerHTML = `
            ๐Ÿ”ด <strong>Not quite!</strong>
            ${item.name} is better classified as a
            <strong>${item.correct.toUpperCase()}</strong>.
            -1 point.
        `;
    }

    game.sorted++;

    selectedSortItem = null;

    document.querySelectorAll("#sortingButtons .choice")
        .forEach(button => {
            button.classList.remove("selected");
        });

    if (game.sorted >= sortingItems.length) {

        document.getElementById("sortInstruction").innerHTML +=
            "<br><br>๐ŸŽ‰ You've classified all the items!";

        document.getElementById("finishSortBtn").disabled = false;
    }
}


function finishRound4() {

    /*
        Needs/Wants = 20 points maximum.
        8 items x 2.5 points.
    */

    game.needsScore =
        Math.round(
            (game.sortCorrect / sortingItems.length) * 20
        );

    game.points += game.needsScore;

    showFinal();
}


/* =========================================================
   FINAL CALCULATIONS
========================================================= */

function calculateRemainingMoney() {

    const budgetSpent =
        Object.values(game.budget)
            .reduce((sum, value) => sum + value, 0);

    return Math.max(0, 2500 - budgetSpent);
}


function showFinal() {

    const lifestyleTotal =
        calculateLifestyleTotal();

    const totalSpending =
        game.budget.rent +
        game.budget.food +
        game.budget.transport +
        game.budget.bills +
        game.budget.wants +
        game.budget.phone +
        lifestyleTotal;

    /*
        Savings + emergency are technically allocated from
        the original RM2,500. Lifestyle spending represents
        additional pressure on the lifestyle side.
    */

    let finalScore =
        game.budgetScore +
        game.needsScore +
        game.emergencyScore +
        game.decisionScore +
        game.savingsScore;

    /*
        Savings score
    */

    let savingsScore = 0;

    if (game.savings >= 700) savingsScore = 20;
    else if (game.savings >= 500) savingsScore = 17;
    else if (game.savings >= 300) savingsScore = 14;
    else if (game.savings >= 150) savingsScore = 9;
    else if (game.savings > 0) savingsScore = 5;

    /*
        Debt penalty
    */

    if (game.debt >= 1000) {

        savingsScore = Math.max(0, savingsScore - 6);

    } else if (game.debt >= 500) {

        savingsScore = Math.max(0, savingsScore - 4);

    } else if (game.debt > 0) {

        savingsScore = Math.max(0, savingsScore - 2);
    }

    game.savingsScore = Math.min(20, savingsScore);

    finalScore =
        game.budgetScore +
        game.needsScore +
        game.savingsScore +
        game.emergencyScore +
        game.decisionScore;

    finalScore = Math.max(0, Math.min(100, finalScore));

    game.points = finalScore;


    /* Rank */

    let rank = "";
    let title = "";
    let message = "";

    if (finalScore >= 80) {

        rank = "๐Ÿ† FINANCIAL MASTER";
        title = "YOU SURVIVED LIKE A PRO!";
        message = `
            ๐Ÿ”ฅ Amazing work!
            You showed strong budgeting, saving and decision-making skills.
            You were prepared for unexpected expenses and avoided unnecessary debt.
        `;

    } else if (finalScore >= 60) {

        rank = "๐Ÿ’ฐ MONEY SMART";
        title = "YOU SURVIVED!";
        message = `
            ๐Ÿ‘ Good job!
            Your financial decisions were generally strong,
            although there are still some areas you can improve.
        `;

    } else if (finalScore >= 40) {

        rank = "๐Ÿ“š FINANCIAL LEARNER";
        title = "YOU BARELY SURVIVED";
        message = `
            ๐Ÿ˜ You made it through the month,
            but some financial decisions could put you at risk in real life.
            Keep working on your budgeting and emergency savings.
        `;

    } else {

        rank = "๐Ÿšจ FINANCIAL SURVIVOR";
        title = "FINANCIAL TROUBLE!";
        message = `
            ๐Ÿ’€ Your money management needs attention.
            Too much spending or debt can make emergencies much harder to handle.
        `;
    }


    /* Update UI */

    document.getElementById("finalTitle").textContent = title;

    document.getElementById("finalScore").textContent =
        finalScore;

    document.getElementById("finalRank").textContent =
        rank;

    document.getElementById("finalSpending").textContent =
        "RM" + Math.round(totalSpending).toLocaleString();

    document.getElementById("finalSavings").textContent =
        "RM" + Math.max(0, Math.round(game.savings)).toLocaleString();

    document.getElementById("finalEmergency").textContent =
        "RM" + Math.max(0, Math.round(game.emergency)).toLocaleString();

    document.getElementById("finalDebt").textContent =
        "RM" + Math.round(game.debt).toLocaleString();

    document.getElementById("scoreBudget").textContent =
        game.budgetScore;

    document.getElementById("scoreNeeds").textContent =
        game.needsScore;

    document.getElementById("scoreSavings").textContent =
        game.savingsScore;

    document.getElementById("scoreEmergency").textContent =
        game.emergencyScore;

    document.getElementById("scoreDecision").textContent =
        game.decisionScore;

    document.getElementById("finalMessage").innerHTML =
        message;

    document.getElementById("finalMessage").className =
        finalScore >= 60
            ? "feedback good"
            : finalScore >= 40
            ? "feedback warning"
            : "feedback bad";

    showScreen("final");
}


/* =========================================================
   INITIALISE
========================================================= */

updateBudget();

</script>

</body>
</html>

Game Source: Survive Your Finances

Creator: MagicLion67

Libraries: none

Complexity: complex (2538 lines, 61.0 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: survive-your-finances-magiclion67" to link back to the original. Then publish at arcadelab.ai/publish.