<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>FOMO Trap™ Simulator</title>

    <script src="https://cdn.tailwindcss.com"></script>

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>

    <link rel="preconnect" href="https://fonts.googleapis.com">

    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

    <style>

        body {

            font-family: 'Inter', sans-serif;

            background-color: #f0f4f8;

            padding-top: 4.5rem;

            display: flex;

            flex-direction: column;

            min-height: 100vh;

        }

        .main-content {

            flex-grow: 1;

        }

        [data-tooltip] { position: relative; cursor: pointer; }

        [data-tooltip]::before {

            content: attr(data-tooltip); position: absolute; bottom: 125%; left: 50%;

            transform: translateX(-50%); background-color: #334155; color: white;

            padding: 4px 8px; border-radius: 4px; font-size: 0.8rem; white-space: nowrap;

            opacity: 0; visibility: hidden; transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out; z-index: 50;

        }

        [data-tooltip]:hover::before { opacity: 1; visibility: visible; }

        .chartjs-tooltip { background: rgba(0, 0, 0, 0.7); color: white; padding: 5px; border-radius: 3px; font-size: 0.8rem; }

        .message-enter { opacity: 0; transform: translateY(-10px); transition: opacity 0.3s ease, transform 0.3s ease; }

        .message-enter-active { opacity: 1; transform: translateY(0); }

        #stockChartContainer { position: relative; height: 45vh; width: 100%; }

        #countdownTimer {

            position: absolute; top: 1rem; left: 1rem; z-index: 10;

            background-color: rgba(51, 65, 85, 0.8); color: white;

            padding: 0.25rem 0.75rem; border-radius: 0.375rem;

            font-family: monospace; font-size: 0.875rem; font-weight: 600;

            box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);

        }

        button:disabled, input[type="range"]:disabled { opacity: 0.4; cursor: not-allowed; filter: grayscale(50%); }

        button:disabled:hover { filter: grayscale(50%) brightness(100%); background-color: initial; }

        #pauseResumeButton:disabled:hover { background-color: rgb(37 99 235); }

        #startButton:disabled:hover { background-color: rgb(22 163 74); }

        #muteButton:disabled:hover { background-color: rgb(100 116 139); }


        #simulationControlButtons {

             position: fixed; top: 1rem; left: 1rem; z-index: 20;

             display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;

        }

        #startButton, #pauseResumeButton { width: 8rem; text-align: center; }

        #muteButton { width: 2.5rem; height: 2.5rem; padding: 0.5rem; display: flex; align-items: center; justify-content: center; }


        button:focus-visible, input[type="range"]:focus-visible, input[type="number"]:focus-visible {

            outline: 2px solid transparent; outline-offset: 2px;

            box-shadow: 0 0 0 2px #f0f4f8, 0 0 0 4px rgb(59 130 246);

        }

        .card-hover:hover { transform: translateY(-2px); box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.07), 0 4px 6px -4px rgb(0 0 0 / 0.07); }

        @keyframes flash-green { 0%, 100% { background-color: transparent; } 50% { background-color: rgba(74, 222, 128, 0.2); } }

        @keyframes flash-red { 0%, 100% { background-color: transparent; } 50% { background-color: rgba(248, 113, 113, 0.2); } }

        .flash-bg-green { animation: flash-green 0.6s ease-in-out; }

        .flash-bg-red { animation: flash-red 0.6s ease-in-out; }


        #newsTickerContainer {

            background-color: #1f2937; color: #f3f4f6; overflow: hidden;

            white-space: nowrap; box-shadow: inset 0 1px 3px rgba(0,0,0,0.2);

        }

        #newsTickerContent { display: inline-block; padding-left: 100%; animation: scroll-left 60s linear infinite; }

        #newsTickerContent span { display: inline-block; padding: 0 1.5rem; }

        #newsTickerContainer:hover #newsTickerContent { animation-play-state: paused; }

        @keyframes scroll-left { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } }

        @keyframes blink { 50% { opacity: 0.3; } }

        .animate-blink { animation: blink 1.2s linear infinite; }


        /* Modal Styles */

        .modal-overlay {

            position: fixed; inset: 0; background-color: rgba(0, 0, 0, 0.5);

            display: flex; align-items: center; justify-content: center;

            padding: 1rem; z-index: 30; transition: opacity 0.3s ease-in-out;

        }

         .modal-overlay.hidden { opacity: 0; pointer-events: none; }

         .modal-overlay:not(.hidden) { opacity: 1; pointer-events: auto; }

         .modal-content {

            background-color: white; border-radius: 0.5rem;

            box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);

            position: relative; width: 85%; max-width: 48rem;

            max-height: 85vh; display: flex; flex-direction: column;

            overflow: hidden;

         }

         .modal-header {

             background-image: linear-gradient(to right, #ef4444, #f97316); color: white;

             padding: 1rem 1.5rem; border-bottom: 1px solid rgba(255,255,255,0.2);

             flex-shrink: 0;

         }

         .modal-body {

             padding: 1.5rem; overflow-y: auto; background-color: #f9fafb;

             flex-grow: 1;

         }

         .modal-close-button { position: absolute; top: 0.5rem; right: 0.5rem; padding: 0.25rem; color: rgba(255, 255, 255, 0.7); transition: color 0.15s ease-in-out; }

         .modal-close-button:hover { color: white; }


         #fomoMeterBar { transition-property: width, background-color; transition-duration: 500ms; transition-timing-function: ease-out; }

         #fomoLevelText { text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); }

    </style>

</head>

<body class="p-4 md:p-8">


    <div id="simulationControlButtons">

         <button id="startButton" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 active:bg-green-800 transition duration-150 ease-in-out focus-visible:ring-green-500">Start Sim</button>

         <button id="pauseResumeButton" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 active:bg-blue-800 transition duration-150 ease-in-out focus-visible:ring-blue-500" disabled>Pause</button>

         <button id="muteButton" class="bg-slate-500 text-white rounded-md hover:bg-slate-600 active:bg-slate-700 transition duration-150 ease-in-out focus-visible:ring-slate-500" disabled aria-label="Mute Music">

             <span id="muteIconContainer"></span>

         </button>

    </div>


    <div class="main-content">

        <h1 class="text-3xl font-bold text-center text-slate-800 mb-2">FOMO Trap™</h1>

        <p class="text-center text-slate-600 text-md mb-8">The financial cost of emotional decisions—quantified</p>


        <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">


            <div class="lg:col-span-2 space-y-6">


                 <div class="bg-white p-4 sm:p-6 rounded-lg shadow-md transition duration-200 ease-in-out card-hover">

                    <h2 class="text-xl font-semibold text-slate-700 mb-2" data-tooltip="Rises with market volatility and strong trends, indicating potential FOMO pressure.">

                        FOMO Meter <span class="text-sm text-blue-600 cursor-help">(?)</span>

                    </h2>

                    <div class="relative w-full bg-slate-200 rounded-full h-6 overflow-hidden">

                         <div id="fomoMeterBar" class="h-full rounded-full" style="width: 0%;"></div>

                         <div id="fomoLevelText" class="absolute inset-0 flex items-center justify-center text-xs font-semibold text-white">Low</div>

                    </div>

                    <div class="mt-2 text-center">

                        <span class="text-xs font-semibold text-slate-600 mr-1">Advisor:</span>

                        <span id="advisorText" class="text-sm text-slate-500 h-6 inline-block"></span>

                    </div>

                 </div>


                <div class="bg-white p-4 sm:p-6 rounded-lg shadow-md relative transition duration-200 ease-in-out card-hover">

                    <h2 class="text-xl font-semibold text-slate-700 mb-4">Stock Price (INR)</h2>

                     <div id="stockChartContainer">

                        <canvas id="stockChart"></canvas>

                        <div id="countdownTimer">04:30</div>

                     </div>

                     <div class="text-center text-xs text-slate-500 mt-2 pt-2 border-t border-slate-100">

                         Value Zone: <span id="valueZoneIndicator" class="font-medium text-blue-600">₹??.?? - ₹??.??</span>

                     </div>

                     <div id="newsTickerContainer" class="h-8 flex items-center mt-4 rounded-md">

                         <div id="newsTickerContent" class="text-sm">

                             <span>Welcome to the FOMO Trap™ Simulator...</span>

                         </div>

                     </div>

                     <div class="flex justify-center items-center space-x-2 mt-4 pt-4 border-t border-slate-100">

                         <label for="speedSlider" class="text-sm text-slate-600">Speed:</label>

                         <input type="range" id="speedSlider" min="100" max="2000" step="100" class="w-32 h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-blue-600 focus-visible:ring-blue-500" disabled>

                         <span id="speedValue" class="text-sm text-slate-600 w-10 text-right">0.1s</span>

                     </div>

                </div>


                 <div class="bg-white p-4 sm:p-6 rounded-lg shadow-md transition duration-200 ease-in-out card-hover">

                    <h2 class="text-xl font-semibold text-slate-700 mb-4">Trade History</h2>

                    <div class="max-h-48 overflow-y-auto">

                        <ul id="tradeHistoryList" class="text-sm space-y-1 text-slate-600">

                            <li>No trades yet.</li>

                        </ul>

                    </div>

                </div>

            </div> <div class="space-y-6">

                 <div class="bg-white p-4 sm:p-6 rounded-lg shadow-md transition duration-200 ease-in-out card-hover">

                    <h2 class="text-xl font-semibold text-slate-700 mb-4">Portfolio</h2>

                    <div class="space-y-2 text-slate-600">

                        <div class="flex justify-between"><span>Capital:</span><span id="capitalValue" class="font-medium">₹1,000.00</span></div>

                        <div class="flex justify-between"><span>Shares Held:</span><span id="sharesValue" class="font-medium">0</span></div>

                        <div class="flex justify-between"><span>Current Price:</span><span id="currentPriceValue" class="font-medium">₹---.--</span></div>

                        <hr class="my-2 border-slate-200">

                        <div class="flex justify-between font-semibold text-slate-800">

                            <span>Total Value:</span>

                            <span id="totalValue" class="font-medium px-1 rounded-sm" aria-live="polite">₹1,000.00</span>

                        </div>

                    </div>

                </div>


                 <div class="bg-white p-4 sm:p-6 rounded-lg shadow-md transition duration-200 ease-in-out card-hover">

                    <h2 class="text-xl font-semibold text-slate-700 mb-4">Trade Controls</h2>

                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4 items-end">

                        <div>

                            <label for="tradeQuantity" class="block text-sm font-medium text-slate-600 mb-1">Quantity</label>

                            <input type="number" id="tradeQuantity" value="10" min="1" class="w-full p-2 border border-slate-300 rounded-md focus:ring-blue-500 focus:border-blue-500 focus-visible:ring-blue-500">

                        </div>

                         <div class="flex space-x-3">

                            <button id="buyButton" class="flex-1 bg-green-500 text-white px-6 py-2 rounded-md hover:bg-green-600 active:bg-green-800 transition duration-150 ease-in-out focus-visible:ring-green-500" disabled>Buy</button>

                            <button id="sellButton" class="flex-1 bg-red-500 text-white px-6 py-2 rounded-md hover:bg-red-600 active:bg-red-800 transition duration-150 ease-in-out focus-visible:ring-red-500" disabled>Sell</button>

                        </div>

                    </div>

                     <div id="tradeFeedback" class="mt-4 text-sm text-slate-600 h-10" aria-live="polite"></div>

                </div>


                 <div class="bg-white p-4 sm:p-6 rounded-lg shadow-md transition duration-200 ease-in-out card-hover">

                    <h2 class="text-xl font-semibold text-slate-700 mb-4">Performance Analysis</h2>

                     <div class="space-y-2 text-sm text-slate-600">

                        <div class="flex justify-between"><span>Trades Made:</span><span id="tradesMade" class="font-medium">0</span></div>

                        <div class="flex justify-between">

                            <span>Profit/Loss:</span>

                             <span id="profitLoss" class="font-medium px-1 rounded-sm" aria-live="polite">₹0.00</span>

                        </div>

                        <div class="flex justify-between">

                            <span data-tooltip="Trades potentially influenced by FOMO (buying high, selling low, buying false bottoms/consolidations).">FOMO Trades: <span class="text-sm text-blue-600 cursor-help">(?)</span></span>

                            <span id="fomoTradesCount" class="font-medium">0</span>

                        </div>

                         <div class="flex justify-between">

                            <span data-tooltip="Trades made within defined 'value zones'.">Value Trades: <span class="text-sm text-blue-600 cursor-help">(?)</span></span>

                            <span id="valueTradesCount" class="font-medium">0</span>

                        </div>

                         <div id="finalAnalysis" class="mt-3 pt-3 border-t border-slate-200 text-center font-medium text-blue-700 hidden">

                             Simulation Complete! Review your results.

                         </div>

                         <div id="counterfactualSection" class="mt-4 pt-4 border-t border-dashed border-slate-300 hidden"> <h3 class="text-base font-semibold text-slate-700 mb-2">Key Trade Analysis:</h3>

                              <ul id="counterfactualAnalysisOutputMain" class="text-xs space-y-1 text-slate-600 max-h-32 overflow-y-auto">

                                  </ul>

                         </div>

                    </div>

                </div>


                 </div> </div> </div> <footer class="mt-12 py-4 border-t border-slate-200">

        <p class="text-center text-xs text-slate-500">

            © 2025 NidaaanInvestwise. Educational content only, not financial advice.

            <a href="https://www.nidaaaninvestwise.com" target="_blank" rel="noopener noreferrer" class="text-blue-600 hover:underline">

                www.nidaaaninvestwise.com

            </a>

        </p>

    </footer>


    <div id="simEndOverlay" class="modal-overlay hidden">

        <div class="modal-content text-center w-[85%] max-w-xl">

             <h3 class="text-xl lg:text-2xl font-semibold text-slate-800 mb-4">Simulation Ended</h3>

             <p class="text-slate-600 mb-6">Your 4.5 minute trading session is complete.</p>

             <button id="showResultsButton" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 active:bg-blue-800 transition duration-150 ease-in-out focus-visible:ring-blue-500">

                 See Results & Analysis

             </button>

        </div>

    </div>


    <div id="analysisModalOverlay" class="modal-overlay hidden">

        <div class="modal-content w-[85%] max-w-3xl max-h-[85vh] p-0" role="dialog" aria-modal="true" aria-labelledby="analysisModalTitle">

             <button id="closeAnalysisModalButton" class="modal-close-button z-10" aria-label="Close Analysis"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /></svg>

             </button>

             <div class="modal-header rounded-t-lg">

                 <h3 id="analysisModalTitle" class="text-xl lg:text-2xl font-semibold text-white text-center">Look what FOMO cost you</h3>

             </div>

             <div class="modal-body">

                <ul id="counterfactualAnalysisOutputModal" class="text-sm space-y-2 text-slate-700">

                    </ul>

                <p id="analysisInsight" class="mt-4 pt-4 border-t border-slate-200 text-xs text-slate-500 italic">

                    Remember: Emotional trades (Panic Sells, FOMO Buys) are flagged based on the conditions when you traded. While the outcome might sometimes be lucky due to market randomness, focusing on a disciplined process is key.

                </p>

            </div>

        </div>

    </div>



    <script>

        // --- Configuration ---

        const INITIAL_CAPITAL = 1000; const STARTING_PRICE = 45; const MIN_PRICE_FLOOR = 18;

        const FALSE_BOTTOM_THRESHOLD = 25; const MAX_DATA_POINTS = 100;

        const SIMULATION_DURATION_MINUTES = 4.5; const TICKS_PER_SECOND = 1;

        const SIMULATION_TICKS = SIMULATION_DURATION_MINUTES * 60 * TICKS_PER_SECOND;

        const TOTAL_SECONDS = SIMULATION_DURATION_MINUTES * 60;

        const CAP_TIME_1 = 30 * TICKS_PER_SECOND; const CAP_PRICE_1 = STARTING_PRICE * 1.31;

        const CAP_TIME_2 = 120 * TICKS_PER_SECOND; const CAP_PRICE_2 = STARTING_PRICE * 2.21;

        const CAP_TIME_3 = 240 * TICKS_PER_SECOND; const CAP_PRICE_3 = STARTING_PRICE * 2.90;

        const VALUE_ZONE_LOW_FACTOR = 0.9; const VALUE_ZONE_HIGH_FACTOR = 1.1;

        const VALUE_ZONE_LOW = STARTING_PRICE * VALUE_ZONE_LOW_FACTOR; const VALUE_ZONE_HIGH = STARTING_PRICE * VALUE_ZONE_HIGH_FACTOR;

        const VALUE_ZONE_BOUNCE_PROBABILITY = 0.6; const CONSOLIDATION_CHANCE = 0.03;

        const CONSOLIDATION_MIN_TICKS = 10; const CONSOLIDATION_MAX_TICKS = 30;

        const BUY_TRAP_PROBABILITY = 0.90; const SELL_TRAP_PROBABILITY = 0.90;

        const BUY_TRAP_FACTOR_MIN = 0.02; const BUY_TRAP_FACTOR_MAX = 0.05;

        const SELL_TRAP_FACTOR_MIN = 0.025; const SELL_TRAP_FACTOR_MAX = 0.06;

        const MAX_TICKER_ITEMS = 20;

        const DEFAULT_SIMULATION_SPEED = 100;


        // --- State Variables ---

        let capital = INITIAL_CAPITAL; let shares = 0; let currentPrice = STARTING_PRICE;

        let portfolioValue = INITIAL_CAPITAL; let prevPortfolioValue = INITIAL_CAPITAL;

        let priceHistory = [currentPrice];

        let chartLabels = ['Start']; let simulationInterval; let tickCount = 0;

        let isPaused = false; let simulationRunning = false;

        let simulationSpeed = DEFAULT_SIMULATION_SPEED;

        let trades = []; let fomoLevel = 0;

        let recentPriceChanges = []; let fomoTrades = 0; let valueTrades = 0;

        let isConsolidating = false; let consolidationLevel = null; let consolidationTicksRemaining = 0;

        let isMuted = false;

        let positiveBuzzTicks = 0;

        let currentFomoCategory = 'Low';


        // --- DOM Elements ---

        const capitalValueEl = document.getElementById('capitalValue');

        const sharesValueEl = document.getElementById('sharesValue');

        const currentPriceValueEl = document.getElementById('currentPriceValue');

        const totalValueEl = document.getElementById('totalValue');

        const tradeQuantityInput = document.getElementById('tradeQuantity');

        const buyButton = document.getElementById('buyButton');

        const sellButton = document.getElementById('sellButton');

        const tradeFeedbackEl = document.getElementById('tradeFeedback');

        const tradeHistoryListEl = document.getElementById('tradeHistoryList');

        const fomoMeterBarEl = document.getElementById('fomoMeterBar');

        const fomoLevelTextEl = document.getElementById('fomoLevelText');

        const advisorTextEl = document.getElementById('advisorText');

        const newsTickerContentEl = document.getElementById('newsTickerContent');

        const startButton = document.getElementById('startButton');

        const pauseResumeButton = document.getElementById('pauseResumeButton');

        const muteButton = document.getElementById('muteButton');

        const muteIconContainer = document.getElementById('muteIconContainer');

        const speedSlider = document.getElementById('speedSlider');

        const speedValueEl = document.getElementById('speedValue');

        const tradesMadeEl = document.getElementById('tradesMade');

        const profitLossEl = document.getElementById('profitLoss');

        const fomoTradesCountEl = document.getElementById('fomoTradesCount');

        const valueTradesCountEl = document.getElementById('valueTradesCount');

        const finalAnalysisEl = document.getElementById('finalAnalysis');

        const countdownTimerEl = document.getElementById('countdownTimer');

        const valueZoneIndicatorEl = document.getElementById('valueZoneIndicator');

        const simEndOverlayEl = document.getElementById('simEndOverlay');

        const showResultsButtonEl = document.getElementById('showResultsButton');

        const analysisModalOverlayEl = document.getElementById('analysisModalOverlay');

        const closeAnalysisModalButtonEl = document.getElementById('closeAnalysisModalButton');

        const counterfactualAnalysisOutputModalEl = document.getElementById('counterfactualAnalysisOutputModal');

        const counterfactualSectionEl = document.getElementById('counterfactualSection');

        const counterfactualAnalysisOutputMainEl = document.getElementById('counterfactualAnalysisOutputMain');


         // --- SVG Icons ---

        const speakerWaveIcon = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M19.114 5.636a9 9 0 0 1 0 12.728M16.463 8.288a5.25 5.25 0 0 1 0 7.424M6.75 8.25l4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" /></svg>`;

        const speakerXMarkIcon = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M17.25 9.75 19.5 12m0 0 2.25 2.25M19.5 12l2.25-2.25M19.5 12l-2.25 2.25m-10.5-6 4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" /></svg>`;



        // --- Audio Setup (Tone.js) ---

        let synth = null; let musicLoop = null; let audioReady = false;

        function setupAudio() { /* ... no changes ... */

            if (audioReady) return; try { synth = new Tone.FMSynth({ volume: -12, harmonicity: 1.5, modulationIndex: 5, envelope: { attack: 0.01, decay: 0.2, sustain: 0.1, release: 0.5 }, modulationEnvelope: { attack: 0.05, decay: 0.1, sustain: 0.05, release: 0.2 } }).toDestination(); const pattern = ["C3", null, "E3", null, "G3", null, null, null]; let patternIndex = 0; musicLoop = new Tone.Loop(time => { let note = pattern[patternIndex % pattern.length]; if (note) { synth.triggerAttackRelease(note, "8n", time); } patternIndex++; }, "2n").start(0); Tone.Transport.bpm.value = 90; Tone.Destination.mute = isMuted; audioReady = true; muteButton.disabled = false; updateMuteButtonIcon(); } catch (error) { console.error("Failed to initialize audio:", error); muteButton.disabled = true; }

        }

        function updateMuteButtonIcon() { /* ... no changes ... */

             if (!muteIconContainer) return; if (isMuted) { muteIconContainer.innerHTML = speakerXMarkIcon; muteButton.setAttribute('aria-label', 'Unmute Music'); } else { muteIconContainer.innerHTML = speakerWaveIcon; muteButton.setAttribute('aria-label', 'Mute Music'); }

        }


        // --- Chart.js Setup ---

        const ctx = document.getElementById('stockChart').getContext('2d');

        let stockChart;

        let pointRadius = []; let pointBackgroundColor = []; let pointBorderColor = [];

        function initializeChart() { /* ... no changes ... */

             const initialData = Array(MAX_DATA_POINTS).fill(null); initialData[MAX_DATA_POINTS - 1] = currentPrice; const initialLabels = Array(MAX_DATA_POINTS).fill(''); initialLabels[MAX_DATA_POINTS - 1] = 'Start'; pointRadius = Array(MAX_DATA_POINTS).fill(0); pointBackgroundColor = Array(MAX_DATA_POINTS).fill('transparent'); pointBorderColor = Array(MAX_DATA_POINTS).fill('transparent');

             stockChart = new Chart(ctx, { type: 'line', data: { labels: initialLabels, datasets: [{ label: 'Stock Price', data: initialData, borderColor: 'rgb(59, 130, 246)', backgroundColor: 'rgba(59, 130, 246, 0.1)', borderWidth: 2, pointRadius: pointRadius, pointBackgroundColor: pointBackgroundColor, pointBorderColor: pointBorderColor, pointHoverRadius: 5, tension: 0.1, fill: true }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: false, ticks: { callback: function(value) { return '₹' + value.toFixed(2); } }, grid: { color: '#e5e7eb' } }, x: { ticks: { display: false }, grid: { display: false } } }, plugins: { tooltip: { enabled: true, mode: 'index', intersect: false, callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) label += ': '; if (context.parsed.y !== null) label += '₹' + context.parsed.y.toFixed(2); return label; } }, backgroundColor: 'rgba(51, 65, 85, 0.9)', titleFont: { weight: 'bold', family: 'Inter' }, bodyFont: { family: 'Inter' }, padding: 8, cornerRadius: 4, displayColors: false, }, legend: { display: false } }, animation: { duration: 0 }, hover: { mode: 'nearest', intersect: true } } });

        }


        // --- Simulation Logic ---

        function enterConsolidation() { /* ... no changes ... */

            if (currentPrice < MIN_PRICE_FLOOR * 1.2 || currentPrice > CAP_PRICE_3 * 0.95) return; isConsolidating = true; consolidationLevel = currentPrice; consolidationTicksRemaining = Math.floor(Math.random() * (CONSOLIDATION_MAX_TICKS - CONSOLIDATION_MIN_TICKS + 1)) + CONSOLIDATION_MIN_TICKS;

        }

        function generateNextPrice() { /* ... no changes ... */

            let baseChangePercent = (Math.random() - 0.5) * 0.015; let momentumFactor = 0; let pullToConsolidation = 0; let trapAdjustment = 0;

            if (isConsolidating) { consolidationTicksRemaining--; if (consolidationTicksRemaining <= 0) { isConsolidating = false; consolidationLevel = null; } else { baseChangePercent *= 0.2; momentumFactor *= 0.5; pullToConsolidation = (consolidationLevel - currentPrice) * 0.015; } }

            if (positiveBuzzTicks > 0) { baseChangePercent += 0.003; positiveBuzzTicks--; }

            if (recentPriceChanges.length > 0 && !isConsolidating) { const avgChange = recentPriceChanges.reduce((a, b) => a + b, 0) / recentPriceChanges.length; momentumFactor = avgChange * 0.5; }

            let baseNetChange = currentPrice * (baseChangePercent + momentumFactor) + pullToConsolidation; baseNetChange += (Math.random() - 0.5) * (currentPrice * 0.003);

            const lastTrade = trades.length > 0 ? trades[trades.length - 1] : null;

            if (lastTrade && tickCount === lastTrade.tick + 1) { if (lastTrade.type === 'buy') { if (Math.random() < BUY_TRAP_PROBABILITY) { const dropPercent = BUY_TRAP_FACTOR_MIN + Math.random() * (BUY_TRAP_FACTOR_MAX - BUY_TRAP_FACTOR_MIN); trapAdjustment = -Math.abs(currentPrice * dropPercent); addTradeFeedback("Price dropped immediately after your buy!", "warning"); if (!lastTrade.fomo && !lastTrade.value) { lastTrade.fomo = true; fomoTrades++; fomoTradesCountEl.textContent = fomoTrades; updateTradeHistory(lastTrade); } } } else if (lastTrade.type === 'sell') { if (Math.random() < SELL_TRAP_PROBABILITY) { const risePercent = SELL_TRAP_FACTOR_MIN + Math.random() * (SELL_TRAP_FACTOR_MAX - SELL_TRAP_FACTOR_MIN); trapAdjustment = Math.abs(currentPrice * risePercent); addTradeFeedback("Price surged right after you sold!", "warning"); if (!lastTrade.panic && currentPrice < VALUE_ZONE_LOW * 1.1) { lastTrade.panic = true; fomoTrades++; fomoTradesCountEl.textContent = fomoTrades; updateTradeHistory(lastTrade); } } } }

            let nextPrice = currentPrice + baseNetChange + trapAdjustment;

            let maxAllowedPrice = Infinity; if (tickCount <= CAP_TIME_1) maxAllowedPrice = CAP_PRICE_1; else if (tickCount <= CAP_TIME_2) maxAllowedPrice = CAP_PRICE_2; else if (tickCount <= CAP_TIME_3) maxAllowedPrice = CAP_PRICE_3; else maxAllowedPrice = CAP_PRICE_3; nextPrice = Math.min(nextPrice, maxAllowedPrice); nextPrice = Math.max(MIN_PRICE_FLOOR, nextPrice);

            const change = (nextPrice - currentPrice) / currentPrice; recentPriceChanges.push(change); if (recentPriceChanges.length > 5) recentPriceChanges.shift(); return nextPrice;

         }

        function updateFOMOMeter() { /* ... no changes ... */

             if (recentPriceChanges.length < 3) fomoLevel = 0; else { const mean = recentPriceChanges.reduce((a, b) => a + b, 0) / recentPriceChanges.length; const variance = recentPriceChanges.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / recentPriceChanges.length; const volatility = Math.sqrt(variance); const momentum = mean; let calculatedLevel = (volatility * 3000) + Math.max(0, momentum * 5000); fomoLevel = Math.min(100, Math.max(0, calculatedLevel)); }

            fomoMeterBarEl.style.width = `${fomoLevel}%`; let newCategory = 'Low'; let levelText = 'Low'; let advisorMessage = ''; let barColorClass = 'bg-sky-500';

            if (fomoLevel > 75) { newCategory = 'Extreme'; levelText = 'Extreme'; barColorClass = 'bg-red-500'; advisorMessage = "Extreme FOMO! High risk of emotional trade."; } else if (fomoLevel > 50) { newCategory = 'High'; levelText = 'High'; barColorClass = 'bg-amber-500'; advisorMessage = "Caution: FOMO levels high. Stick to your plan."; } else if (fomoLevel > 25) { newCategory = 'Moderate'; levelText = 'Moderate'; barColorClass = 'bg-emerald-500'; advisorMessage = "Market heating up. Stay objective."; }

            fomoLevelTextEl.textContent = levelText; if (newCategory !== currentFomoCategory) { advisorTextEl.textContent = advisorMessage; currentFomoCategory = newCategory; } const colorClasses = ['bg-sky-500', 'bg-emerald-500', 'bg-amber-500', 'bg-red-500']; fomoMeterBarEl.classList.remove(...colorClasses); fomoMeterBarEl.classList.add(barColorClass); if (fomoLevel > 50) { fomoMeterBarEl.classList.add('animate-pulse'); } else { fomoMeterBarEl.classList.remove('animate-pulse'); }

        }

        function addSocialComment(comment, type = "neutral") { /* ... no changes ... */

            if (!newsTickerContentEl) return; const newItem = document.createElement('span'); const symbolSpan = document.createElement('span'); symbolSpan.className = 'inline-block mr-1 animate-blink'; let symbol = '▪'; switch (type) { case 'positive': symbol = '▲'; symbolSpan.className += ' text-green-400'; break; case 'negative': symbol = '▼'; symbolSpan.className += ' text-red-400'; break; case 'warning': symbol = '!'; symbolSpan.className += ' text-yellow-400 font-bold'; break; case 'news': symbol = '*'; symbolSpan.className += ' text-blue-400'; break; case 'info': symbol = 'i'; symbolSpan.className += ' text-cyan-400 italic'; break; case 'neutral': symbol = '-'; symbolSpan.className += ' text-slate-400'; break; } symbolSpan.textContent = symbol; newItem.appendChild(symbolSpan); newItem.appendChild(document.createTextNode(comment)); newItem.className = 'mx-4'; newsTickerContentEl.appendChild(newItem); while (newsTickerContentEl.children.length > MAX_TICKER_ITEMS) { if(newsTickerContentEl.firstChild) { newsTickerContentEl.removeChild(newsTickerContentEl.firstChild); } } const placeholder = newsTickerContentEl.querySelector('.italic.text-slate-500'); if (placeholder && placeholder.textContent.includes("Welcome")) { placeholder.remove(); }

        }

        function generateSocialChatter() { /* ... no changes ... */

            const lastPrice = priceHistory[priceHistory.length - 2] || currentPrice; const change = (currentPrice - lastPrice) / lastPrice; const commentProbability = 0.15 + (fomoLevel / 300); if (Math.random() < commentProbability) { let buzzType = "info"; let comment = ""; if (fomoLevel > 70 && change > 0.005) { const comments = ["🚀 Analyst Upgrade!", "This is flying!", "#ToTheMoon", "Don't miss out!"]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "news"; positiveBuzzTicks = 3; } else if (fomoLevel > 50 && change < -0.01) { const comments = ["📉 Insider Selling Reported!", "This looks bad...", "Get out now!", "Panic!", "#FallingKnife"]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "negative"; positiveBuzzTicks = 0; } else if (isConsolidating) { const comments = ["Choppy action.", "Market waiting for news?", "Low volume consolidation.", "Deciding direction..."]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "info"; positiveBuzzTicks = 0; } else if (currentPrice < MIN_PRICE_FLOOR * 1.2) { const comments = ["Looks like a bottom forming?", "Good entry point here?", "Testing support again.", "Accumulating?"]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "info"; positiveBuzzTicks = 1; } else if (change > 0.005) { const comments = ["Nice little pop.", "Looking bullish.", "Green day!", "Moving up steadily."]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "positive"; positiveBuzzTicks = 2; } else if (change < -0.005) { const comments = ["Bit of a pullback.", "Red candle forming.", "Profit taking?", "Losing steam."]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "negative"; positiveBuzzTicks = 0; } else if (tickCount % 15 === 0) { const comments = ["Market flat.", "Watching paint dry...", "No major news.", "Sideways movement."]; comment = comments[Math.floor(Math.random() * comments.length)]; buzzType = "neutral"; positiveBuzzTicks = 0; } if (comment) { addSocialComment(comment, buzzType); } }

        }

        function updateTimerDisplay() { /* ... no changes ... */

            const secondsElapsed = tickCount; const secondsRemaining = Math.max(0, TOTAL_SECONDS - secondsElapsed); const minutes = Math.floor(secondsRemaining / 60); const seconds = secondsRemaining % 60; const formattedTime = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`; countdownTimerEl.textContent = formattedTime;

        }

        function flashElementBackground(element, flashClass) { /* ... no changes ... */

            if (!element) return; element.classList.add(flashClass); setTimeout(() => { element.classList.remove(flashClass); }, 600);

        }

        function updateUI() { /* ... no changes ... */

            capitalValueEl.textContent = `₹${capital.toFixed(2)}`; sharesValueEl.textContent = shares; currentPriceValueEl.textContent = `₹${currentPrice.toFixed(2)}`; portfolioValue = capital + (shares * currentPrice); totalValueEl.textContent = `₹${portfolioValue.toFixed(2)}`; if (portfolioValue > prevPortfolioValue) { flashElementBackground(totalValueEl, 'flash-bg-green'); } else if (portfolioValue < prevPortfolioValue) { flashElementBackground(totalValueEl, 'flash-bg-red'); } prevPortfolioValue = portfolioValue;

            stockChart.data.labels.push(tickCount.toString()); stockChart.data.datasets[0].data.push(currentPrice); pointRadius.push(0); pointBackgroundColor.push('transparent'); pointBorderColor.push('transparent'); if (stockChart.data.labels.length > MAX_DATA_POINTS) { stockChart.data.labels.shift(); stockChart.data.datasets[0].data.shift(); pointRadius.shift(); pointBackgroundColor.shift(); pointBorderColor.shift(); } stockChart.data.datasets[0].pointRadius = pointRadius; stockChart.data.datasets[0].pointBackgroundColor = pointBackgroundColor; stockChart.data.datasets[0].pointBorderColor = pointBorderColor; stockChart.update('none');

            tradesMadeEl.textContent = trades.length; const profit = portfolioValue - INITIAL_CAPITAL; profitLossEl.textContent = `₹${profit.toFixed(2)}`; profitLossEl.className = `font-medium px-1 rounded-sm ${profit >= 0 ? 'text-green-600' : 'text-red-600'}`; if (profit > parseFloat(profitLossEl.dataset.prevProfit || 0)) { flashElementBackground(profitLossEl, 'flash-bg-green'); } else if (profit < parseFloat(profitLossEl.dataset.prevProfit || 0)) { flashElementBackground(profitLossEl, 'flash-bg-red'); } profitLossEl.dataset.prevProfit = profit; fomoTradesCountEl.textContent = fomoTrades; valueTradesCountEl.textContent = valueTrades; updateFOMOMeter(); updateTimerDisplay();

        }

        function addTradeFeedback(message, type = "info") { /* ... no changes ... */

             let textColor = 'text-slate-600'; if (type === 'success') textColor = 'text-green-600'; if (type === 'error') textColor = 'text-red-600'; if (type === 'warning') textColor = 'text-yellow-700'; tradeFeedbackEl.textContent = message; tradeFeedbackEl.className = `mt-2 text-sm text-slate-600 h-10 ${textColor} font-medium`; setTimeout(() => { if (tradeFeedbackEl.textContent === message) { tradeFeedbackEl.textContent = ''; tradeFeedbackEl.className = 'mt-2 text-sm text-slate-600 h-10'; } }, 5000);

         }

        function updateTradeHistory(trade) { /* ... no changes ... */

             let li = tradeHistoryListEl.querySelector(`[data-tick="${trade.tick}"]`); if (!li) { li = document.createElement('li'); li.setAttribute('data-tick', trade.tick); tradeHistoryListEl.insertBefore(li, tradeHistoryListEl.firstChild); } const typeClass = trade.type === 'buy' ? 'text-green-700' : 'text-red-700'; let tag = ''; if (trade.fomo && trade.price > VALUE_ZONE_HIGH) tag = '<span class="ml-2 text-xs bg-yellow-200 text-yellow-800 px-1 rounded">FOMO</span>'; else if (trade.fomo && trade.price < FALSE_BOTTOM_THRESHOLD) tag = '<span class="ml-2 text-xs bg-orange-300 text-orange-800 px-1 rounded">Trap</span>'; else if (trade.panic) tag = '<span class="ml-2 text-xs bg-red-200 text-red-800 px-1 rounded">Panic</span>'; else if (trade.value) tag = '<span class="ml-2 text-xs bg-blue-200 text-blue-800 px-1 rounded">Value</span>'; li.innerHTML = `<span class="font-medium ${typeClass}">${trade.type.toUpperCase()}</span> ${trade.quantity} shares @ ₹${trade.price.toFixed(2)} (Tick ${trade.tick}) ${tag}`; const placeholder = tradeHistoryListEl.querySelector('li:only-child'); if (placeholder && placeholder.textContent.includes("No trades yet")) placeholder.remove();

         }

        function executeTrade(type) { /* ... no changes ... */

            const quantity = parseInt(tradeQuantityInput.value); if (isNaN(quantity) || quantity <= 0) { addTradeFeedback("Please enter a valid quantity.", "error"); return; } let isFomoTrade = false, isPanicTrade = false, isValueTrade = false, feedback = "";

            if (type === 'buy') { const cost = quantity * currentPrice; if (cost > capital) { addTradeFeedback("Not enough capital.", "error"); return; } capital -= cost; shares += quantity; if (currentPrice >= VALUE_ZONE_LOW && currentPrice <= VALUE_ZONE_HIGH) { isValueTrade = true; valueTrades++; feedback = "Bought within the value zone."; addTradeFeedback(feedback, "success"); } else { feedback = `Bought ${quantity} shares at ₹${currentPrice.toFixed(2)}.`; addTradeFeedback(feedback, "info"); isFomoTrade = true; } }

            else if (type === 'sell') { if (quantity > shares) { addTradeFeedback("Not enough shares to sell.", "error"); return; } const revenue = quantity * currentPrice; capital += revenue; shares -= quantity; feedback = `Sold ${quantity} shares at ₹${currentPrice.toFixed(2)}.`; addTradeFeedback(feedback, "info"); if (currentPrice < VALUE_ZONE_LOW * 1.1) { isPanicTrade = true; } }

             const trade = { type, quantity, price: currentPrice, tick: tickCount, fomo: isFomoTrade, panic: isPanicTrade, value: isValueTrade }; trades.push(trade); updateTradeHistory(trade); updateUI();

             const currentDataIndex = stockChart.data.labels.length - 1; if (currentDataIndex >= 0) { pointRadius[currentDataIndex] = 5; if (type === 'buy') { pointBackgroundColor[currentDataIndex] = 'rgba(34, 197, 94, 0.8)'; pointBorderColor[currentDataIndex] = 'rgba(22, 163, 74, 1)'; } else { pointBackgroundColor[currentDataIndex] = 'rgba(239, 68, 68, 0.8)'; pointBorderColor[currentDataIndex] = 'rgba(220, 38, 38, 1)'; } }

        }


        // --- Counterfactual Analysis ---

        function runCounterfactualAnalysis() { /* ... no changes ... */

            const modalList = counterfactualAnalysisOutputModalEl; const mainList = counterfactualAnalysisOutputMainEl; if (!modalList || !mainList) return; modalList.innerHTML = ''; mainList.innerHTML = ''; if (trades.length === 0 || priceHistory.length <= 1) { const noTradesMsg = '<li>No trades made for analysis.</li>'; modalList.innerHTML = noTradesMsg; mainList.innerHTML = noTradesMsg; return; } const finalPrice = priceHistory[priceHistory.length - 1]; let analysisResultsHtml = []; trades.forEach(trade => { let resultText = ''; if (trade.panic) { const actualRevenue = trade.quantity * trade.price; const heldValue = trade.quantity * finalPrice; const difference = heldValue - actualRevenue; resultText = `Panic Sell @ Tick ${trade.tick} (₹${trade.price.toFixed(2)}): Holding instead would have resulted in <span class="${difference >= 0 ? 'text-green-600' : 'text-red-600'} font-medium">${difference >= 0 ? '+' : ''}${difference.toFixed(2)}</span>.`; } else if (trade.fomo) { const actualProfitLoss = trade.quantity * (finalPrice - trade.price); const counterfactualProfitLoss = 0; const difference = counterfactualProfitLoss - actualProfitLoss; let tradeType = "FOMO Buy"; if (trade.price < FALSE_BOTTOM_THRESHOLD) tradeType = "Trap Buy"; resultText = `${tradeType} @ Tick ${trade.tick} (₹${trade.price.toFixed(2)}): Not making this trade would have resulted in <span class="${difference >= 0 ? 'text-green-600' : 'text-red-600'} font-medium">${difference >= 0 ? '+' : ''}${difference.toFixed(2)}</span> vs this trade's outcome.`; } if (resultText) { analysisResultsHtml.push(`<li>${resultText}</li>`); } }); if (analysisResultsHtml.length > 0) { const finalHtml = analysisResultsHtml.join(''); modalList.innerHTML = finalHtml; mainList.innerHTML = finalHtml; } else { const noEmotionalTradesMsg = '<li>No significant emotional trades identified for counterfactual analysis.</li>'; modalList.innerHTML = noEmotionalTradesMsg; mainList.innerHTML = noEmotionalTradesMsg; }

        }



        // --- Simulation Control Functions ---

        function simulationStep() { /* ... no changes ... */

            if (!simulationRunning || isPaused) return; if (tickCount >= SIMULATION_TICKS) { endSimulation(); return; }; if (!isConsolidating && Math.random() < CONSOLIDATION_CHANCE && tickCount > 30 && tickCount < SIMULATION_TICKS - 30) { enterConsolidation(); } tickCount++; currentPrice = generateNextPrice(); priceHistory.push(currentPrice); updateFOMOMeter(); generateSocialChatter(); updateUI(); clearTimeout(simulationInterval); if (simulationRunning && !isPaused) { simulationInterval = setTimeout(simulationStep, simulationSpeed); }

        }

        async function startSimulation() { /* ... no changes ... */

            if (simulationRunning) return; if (!audioReady) { try { await Tone.start(); console.log("Audio Context started"); setupAudio(); } catch (e) { console.error("Tone.start failed:", e); muteButton.disabled = true; } } simulationRunning = true; isPaused = false; if (audioReady) { Tone.Transport.start(); } pauseResumeButton.disabled = false; speedSlider.disabled = false; buyButton.disabled = false; sellButton.disabled = false; startButton.disabled = true; addTradeFeedback("Simulation Started!", "info"); simulationInterval = setTimeout(simulationStep, simulationSpeed);

        }

        function togglePause() { /* ... no changes ... */

            if (!simulationRunning) return; isPaused = !isPaused; if (isPaused) { pauseResumeButton.textContent = 'Resume'; pauseResumeButton.classList.replace('bg-blue-600', 'bg-yellow-500'); pauseResumeButton.classList.replace('hover:bg-blue-700', 'hover:bg-yellow-600'); clearTimeout(simulationInterval); if (audioReady) Tone.Transport.pause(); addTradeFeedback("Simulation Paused.", "info"); } else { pauseResumeButton.textContent = 'Pause'; pauseResumeButton.classList.replace('bg-yellow-500', 'bg-blue-600'); pauseResumeButton.classList.replace('hover:bg-yellow-600', 'hover:bg-blue-700'); if (audioReady) Tone.Transport.start(); simulationInterval = setTimeout(simulationStep, simulationSpeed); addTradeFeedback("Simulation Resumed.", "info"); }

        }

         function updateSpeed() { /* ... no changes ... */

            simulationSpeed = parseInt(speedSlider.max) + parseInt(speedSlider.min) - parseInt(speedSlider.value); speedValueEl.textContent = (simulationSpeed / 1000).toFixed(1) + 's'; if (simulationRunning && !isPaused) { clearTimeout(simulationInterval); simulationInterval = setTimeout(simulationStep, simulationSpeed); }

        }

         function endSimulation() { /* ... no changes ... */

            simulationRunning = false; isPaused = true; clearTimeout(simulationInterval); if (audioReady) Tone.Transport.stop(); pauseResumeButton.disabled = true; buyButton.disabled = true; sellButton.disabled = true; speedSlider.disabled = true; muteButton.disabled = true; pauseResumeButton.classList.add('opacity-50', 'cursor-not-allowed'); buyButton.classList.add('opacity-50', 'cursor-not-allowed'); sellButton.classList.add('opacity-50', 'cursor-not-allowed'); finalAnalysisEl.classList.remove('hidden'); addTradeFeedback("Simulation Complete!", "info"); updateTimerDisplay(); runCounterfactualAnalysis(); simEndOverlayEl.classList.remove('hidden');

            const finalValue = portfolioValue.toFixed(2); const profit = (portfolioValue - INITIAL_CAPITAL).toFixed(2); const profitPercent = ((portfolioValue / INITIAL_CAPITAL - 1) * 100).toFixed(1); let summaryMessage = `🏁 Simulation Over! Final Value: ₹${finalValue} (Profit: ₹${profit}, ${profitPercent}%).`; if (fomoTrades > trades.length / 2 && fomoTrades > 0) summaryMessage += " Looks like FOMO/Panic/False Bottoms played a big role!"; else if (valueTrades > trades.length / 2 && valueTrades > 0) summaryMessage += " Good job utilizing value zones!"; addSocialComment(summaryMessage, "info");

        }


        function toggleMute() { /* ... no changes ... */

            if (!audioReady) return; isMuted = !isMuted; Tone.Destination.mute = isMuted; updateMuteButtonIcon();

        }


        // --- Event Listeners ---

        startButton.addEventListener('click', startSimulation);

        buyButton.addEventListener('click', () => executeTrade('buy'));

        sellButton.addEventListener('click', () => executeTrade('sell'));

        pauseResumeButton.addEventListener('click', togglePause);

        muteButton.addEventListener('click', toggleMute);

        speedSlider.addEventListener('input', updateSpeed);


        showResultsButtonEl.addEventListener('click', () => {

            simEndOverlayEl.classList.add('hidden');

            analysisModalOverlayEl.classList.remove('hidden');

        });


        closeAnalysisModalButtonEl.addEventListener('click', () => {

            analysisModalOverlayEl.classList.add('hidden');

            // Show the persistent results section in the card

            counterfactualSectionEl.classList.remove('hidden');

        });


        // --- REMOVED Overlay click listeners ---



        // --- Initialization ---

        window.onload = () => { /* ... no changes ... */

            capitalValueEl.textContent = `₹${INITIAL_CAPITAL.toFixed(2)}`; totalValueEl.textContent = `₹${INITIAL_CAPITAL.toFixed(2)}`; currentPriceValueEl.textContent = `₹${currentPrice.toFixed(2)}`; speedValueEl.textContent = (DEFAULT_SIMULATION_SPEED / 1000).toFixed(1) + 's'; speedSlider.value = parseInt(speedSlider.max) + parseInt(speedSlider.min) - DEFAULT_SIMULATION_SPEED; valueZoneIndicatorEl.textContent = `₹${VALUE_ZONE_LOW.toFixed(2)} - ₹${VALUE_ZONE_HIGH.toFixed(2)}`; initializeChart(); updateTimerDisplay(); updateMuteButtonIcon(); advisorTextEl.textContent = '';

        };


    </script>


</body>

</html>