<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cyber Network Quest: Network Pion Expedition</title>
    <!-- STREAMING_CHUNK: Loading external libraries and styles... -->
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <!-- Tone.js for Web Audio SFX -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Rajdhani:wght@500;600;700&display=swap');
        
        body {
            font-family: 'Rajdhani', sans-serif;
            background-color: #050811;
            color: #e2e8f0;
            user-select: none;
            overflow: hidden;
        }

        .font-pixel { font-family: 'Press Start 2P', monospace; }

        /* Neon Glow Effects */
        .glow-cyan { filter: drop-shadow(0 0 8px rgba(6, 182, 212, 0.6)); }
        .glow-green { filter: drop-shadow(0 0 8px rgba(16, 185, 129, 0.6)); }
        .glow-red { filter: drop-shadow(0 0 8px rgba(239, 68, 68, 0.6)); }
        .glow-amber { filter: drop-shadow(0 0 8px rgba(245, 158, 11, 0.6)); }

        .border-glow {
            box-shadow: 0 0 15px rgba(6, 182, 212, 0.25), inset 0 0 15px rgba(6, 182, 212, 0.1);
        }

        /* Custom Scrollbar for Inventory & Dialogs */
        ::-webkit-scrollbar {
            width: 6px;
        }
        ::-webkit-scrollbar-track {
            background: #0f172a;
        }
        ::-webkit-scrollbar-thumb {
            background: #06b6d4;
            border-radius: 3px;
        }

        /* Animations */
        @keyframes float {
            0%, 100% { transform: translateY(0px); }
            50% { transform: translateY(-6px); }
        }
        .animate-float { animation: float 3s ease-in-out infinite; }

        @keyframes scanline {
            0% { transform: translateY(-100%); }
            100% { transform: translateY(1000%); }
        }
        .scanline {
            position: absolute;
            top: 0; left: 0; right: 0; height: 10px;
            background: linear-gradient(to bottom, rgba(6, 182, 212, 0), rgba(6, 182, 212, 0.25), rgba(6, 182, 212, 0));
            animation: scanline 8s linear infinite;
            pointer-events: none;
        }
    </style>
</head>
<body class="h-screen w-screen flex flex-col justify-between relative bg-slate-950">

    <!-- STREAMING_CHUNK: Canvas & Scanline Layer... -->
    <!-- Canvas Viewport for Isometric Game Map -->
    <canvas id="gameCanvas" class="absolute inset-0 z-0 w-full h-full cursor-pointer"></canvas>

    <!-- Scanline overlay effect -->
    <div class="scanline z-10"></div>

    <!-- STREAMING_CHUNK: HUD Top Navigation Bar... -->
    <!-- Top HUD Bar -->
    <header class="relative z-20 p-3 md:p-4 bg-slate-900/80 backdrop-blur-md border-b border-cyan-500/30 flex justify-between items-center text-sm md:text-base">
        <!-- Agent Identity & HP -->
        <div class="flex items-center space-x-4">
            <div class="flex items-center space-x-2 bg-slate-950/80 px-3 py-1.5 rounded-lg border border-cyan-500/40">
                <i class="fa-solid fa-robot text-cyan-400 text-xl animate-pulse"></i>
                <div>
                    <div class="text-xs text-slate-400 font-mono">PION USER</div>
                    <div class="font-bold text-cyan-300 font-pixel text-xs">AGEN-01</div>
                </div>
            </div>

            <div class="flex items-center space-x-2 bg-slate-950/80 px-3 py-1.5 rounded-lg border border-red-500/40">
                <span class="text-xs text-slate-400 font-mono hidden sm:inline">HP:</span>
                <div id="hp-hearts" class="flex space-x-1 text-red-500 text-lg">
                    <i class="fa-solid fa-heart"></i>
                    <i class="fa-solid fa-heart"></i>
                    <i class="fa-solid fa-heart"></i>
                </div>
            </div>
        </div>

        <!-- Title Banner -->
        <div class="hidden lg:flex flex-col items-center">
            <h1 class="font-pixel text-sm text-cyan-400 tracking-wider glow-cyan">CYBER EXPEDITION</h1>
            <span class="text-xs text-slate-400 tracking-widest">THE NETWORK PION MISSION</span>
        </div>

        <!-- Score & Quest Progress -->
        <div class="flex items-center space-x-4">
            <div class="flex items-center space-x-2 bg-slate-950/80 px-3 py-1.5 rounded-lg border border-amber-500/40">
                <i class="fa-solid fa-star text-amber-400"></i>
                <div>
                    <div class="text-xs text-slate-400 font-mono">SKOR</div>
                    <div id="score-text" class="font-bold text-amber-300 font-mono">0</div>
                </div>
            </div>

            <div class="flex items-center space-x-2 bg-slate-950/80 px-3 py-1.5 rounded-lg border border-emerald-500/40">
                <i class="fa-solid fa-flag text-emerald-400"></i>
                <div>
                    <div class="text-xs text-slate-400 font-mono">MISI</div>
                    <div id="quest-progress" class="font-bold text-emerald-300 font-mono">0 / 20</div>
                </div>
            </div>
        </div>
    </header>

    <!-- STREAMING_CHUNK: Main Game HUD (Minimap, Controls & Inventory)... -->
    <!-- Side HUD Controls & Info overlay -->
    <div class="relative z-20 flex-grow pointer-events-none p-4 flex justify-between items-end">
        
        <!-- Left Side Controls Guide & Mini-map -->
        <div class="pointer-events-auto space-y-3 max-w-xs">
            <div class="bg-slate-900/85 backdrop-blur-md border border-cyan-500/30 p-3 rounded-xl border-glow">
                <div class="text-xs text-cyan-400 font-bold mb-1 flex items-center gap-1">
                    <i class="fa-solid fa-gamepad"></i> KONTROL PION
                </div>
                <div class="text-xs text-slate-300 space-y-1">
                    <p><span class="bg-slate-800 px-1.5 py-0.5 rounded border border-slate-700 font-mono">WASD</span> / <span class="bg-slate-800 px-1.5 py-0.5 rounded border border-slate-700 font-mono">PANAH</span> : Jalan</p>
                    <p><span class="bg-slate-800 px-1.5 py-0.5 rounded border border-slate-700 font-mono">KLIK PETA</span> : Pergi ke lokasi</p>
                    <p><span class="bg-slate-800 px-1.5 py-0.5 rounded border border-slate-700 font-mono">SPASI</span> : Interaksi Node</p>
                </div>
            </div>

            <!-- Mini Map HUD -->
            <div class="bg-slate-900/85 backdrop-blur-md border border-cyan-500/30 p-2 rounded-xl border-glow flex flex-col items-center">
                <div class="text-[10px] text-cyan-400 font-bold mb-1 w-full flex justify-between items-center px-1">
                    <span>TOPOLOGI PETA</span>
                    <span id="current-zone-tag" class="text-emerald-400">ZONE 1</span>
                </div>
                <canvas id="miniMapCanvas" width="120" height="90" class="bg-slate-950 rounded border border-slate-800"></canvas>
            </div>
        </div>

        <!-- Right Side Inventory -->
        <div class="pointer-events-auto bg-slate-900/85 backdrop-blur-md border border-cyan-500/30 p-3 rounded-xl border-glow w-48 sm:w-56">
            <div class="text-xs text-cyan-400 font-bold mb-2 flex justify-between items-center">
                <span>INVENTORY ALAT</span>
                <i class="fa-solid fa-toolbox"></i>
            </div>
            <div id="inventory-grid" class="grid grid-cols-3 gap-2">
                <!-- Inventory slots generated in JS -->
            </div>
        </div>
    </div>

    <!-- STREAMING_CHUNK: Quiz Interactive Modal Dialogue... -->
    <!-- Interactive Quiz Node Dialogue Modal -->
    <div id="quiz-modal" class="fixed inset-0 z-50 bg-slate-950/80 backdrop-blur-sm hidden flex items-center justify-center p-4">
        <div class="bg-slate-900/95 border-2 border-cyan-500/60 rounded-2xl max-w-2xl w-full p-6 shadow-2xl relative border-glow animate-float">
            
            <!-- Modal Header -->
            <div class="flex justify-between items-start border-b border-cyan-500/30 pb-3 mb-4">
                <div class="flex items-center space-x-3">
                    <div id="node-icon-bg" class="p-3 bg-cyan-950/80 border border-cyan-400/40 rounded-xl text-cyan-400 text-2xl">
                        <i id="node-icon" class="fa-solid fa-server"></i>
                    </div>
                    <div>
                        <h3 id="node-title" class="font-bold text-lg text-cyan-300">STASIUN ETHERNET SWITCH</h3>
                        <p id="node-subtitle" class="text-xs text-slate-400 font-mono">Misi 01 • Zona 1: Media & Hardware</p>
                    </div>
                </div>
                <span id="quiz-badge" class="bg-cyan-500/20 text-cyan-300 border border-cyan-400/30 text-xs px-2.5 py-1 rounded-full font-mono">
                    SOAL 1/20
                </span>
            </div>

            <!-- Narrative Context -->
            <div id="quiz-narrative" class="bg-slate-950/70 border-l-4 border-cyan-400 p-3 rounded-r text-xs sm:text-sm text-cyan-200 italic mb-4">
                "Pion menemukan terminal kabel switch yang tidak aktif. Pilih konfigurasi kabel yang tepat!"
            </div>

            <!-- Question Text -->
            <h4 id="quiz-question" class="text-base sm:text-lg font-semibold text-white mb-5 leading-relaxed">
                Pertanyaan akan dimuat di sini...
            </h4>

            <!-- Options Container -->
            <div id="quiz-options" class="space-y-2.5 mb-5">
                <!-- Options injected via JS -->
            </div>

            <!-- Explanation Feedback Box -->
            <div id="quiz-feedback" class="hidden p-3.5 rounded-xl border mb-4 text-xs sm:text-sm">
                <div id="feedback-title" class="font-bold mb-1"></div>
                <div id="feedback-explanation" class="text-slate-300"></div>
            </div>

            <!-- Modal Action Buttons -->
            <div class="flex justify-end">
                <button id="quiz-action-btn" class="hidden px-5 py-2.5 bg-emerald-500 hover:bg-emerald-400 text-slate-950 font-bold text-sm rounded-lg transition transform hover:scale-105 flex items-center gap-2 cursor-pointer">
                    Lanjutkan Petualangan <i class="fa-solid fa-arrow-right"></i>
                </button>
            </div>
        </div>
    </div>

    <!-- STREAMING_CHUNK: Game Over & Win Modal Screens... -->
    <!-- Game Win / Lose Modal Screen -->
    <div id="end-modal" class="fixed inset-0 z-50 bg-slate-950/90 backdrop-blur-md hidden flex items-center justify-center p-4">
        <div class="bg-slate-900 border-2 border-cyan-500/60 rounded-2xl max-w-md w-full p-6 text-center shadow-2xl border-glow">
            <div id="end-icon" class="text-6xl mb-4 text-amber-400">
                <i class="fa-solid fa-trophy"></i>
            </div>
            <h2 id="end-title" class="text-2xl font-bold font-pixel text-cyan-400 mb-2">MISI SELESAI</h2>
            <p id="end-description" class="text-sm text-slate-300 mb-6">
                Selamat Agen-01! Kamu berhasil menjelajahi seluruh papan topologi dan memulihkan jaringan cyber.
            </p>

            <div class="bg-slate-950 p-4 rounded-xl border border-slate-800 mb-6 space-y-2 text-sm font-mono">
                <div class="flex justify-between">
                    <span class="text-slate-400">Total Skor:</span>
                    <span id="final-score" class="text-amber-300 font-bold">2000</span>
                </div>
                <div class="flex justify-between">
                    <span class="text-slate-400">Akurasi Soal:</span>
                    <span id="final-accuracy" class="text-emerald-400 font-bold">20/20</span>
                </div>
                <div class="flex justify-between">
                    <span class="text-slate-400">Gelar Agen:</span>
                    <span id="final-rank" class="text-cyan-300 font-bold">Cyber Arch-Mage</span>
                </div>
            </div>

            <button onclick="restartGame()" class="w-full py-3 bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-400 hover:to-blue-500 text-slate-950 font-bold font-pixel text-xs rounded-xl transition transform hover:scale-105 cursor-pointer glow-cyan">
                <i class="fa-solid fa-rotate-right mr-2"></i> MAIN LAGI
            </button>
        </div>
    </div>

    <!-- STREAMING_CHUNK: Core JavaScript Logic and Game Engine... -->
    <script>
        /* STREAMING_CHUNK: 20 Questions Data Structure... */
        const quizDatabase = [
            // ZONA 1: Media Transmisi & Kabel (1-4)
            {
                nodeName: "STASIUN FIBER CORE",
                zone: "Zona 1: Media Kabel",
                icon: "fa-cable-car",
                itemUnlock: { name: "Fiber Cable", icon: "fa-bolt", desc: "Kabel serat kaca cepat" },
                narrative: "Pion berada di pusat kanal transmisi kaca. Terjadi kegagalan transmisi sinyal data jarak jauh.",
                question: "Kabel jaringan yang menggunakan serat kaca/plastik tipis untuk memancarkan sinyal berupa kilatan cahaya adalah...",
                options: [
                    { text: "Kabel Coaxial", correct: false, reason: "Coaxial menggunakan tembaga dengan pelindung teranyam." },
                    { text: "Kabel Fiber Optic", correct: true, reason: "Fiber optic mentransmisikan paket data dalam bentuk pulsa cahaya berkecepatan tinggi." },
                    { text: "Kabel UTP Unshielded", correct: false, reason: "UTP adalah kawat tembaga terpilin." },
                    { text: "Kabel Console Serial", correct: false, reason: "Console serial digunakan untuk konfigurasi CLI perangkat." }
                ]
            },
            {
                nodeName: "TERMINAL CRIMPING RJ-45",
                zone: "Zona 1: Media Kabel",
                icon: "fa-plug",
                itemUnlock: { name: "RJ-45 Crimper", icon: "fa-wrench", desc: "Tang crimping konektor" },
                narrative: "Pion menemukan UTP tanpa konektor. Pasang kepala konektor standar LAN!",
                question: "Konektor fisik yang digunakan di ujung kabel UTP untuk disambungkan ke port LAN Ethernet adalah...",
                options: [
                    { text: "Konektor RJ-11", correct: false, reason: "RJ-11 memiliki 4 pin dan dipakai untuk kabel telepon rumah." },
                    { text: "Konektor BNC", correct: false, reason: "BNC digunakan untuk jenis kabel Coaxial tua." },
                    { text: "Konektor RJ-45", correct: true, reason: "RJ-45 adalah standar konektor 8-pin untuk kabel LAN UTP/STP." },
                    { text: "Konektor LC/SC", correct: false, reason: "LC/SC digunakan khusus pada kabel Fiber Optic." }
                ]
            },
            {
                nodeName: "PANEL SHIELDED STP",
                zone: "Zona 1: Media Kabel",
                icon: "fa-shield-halved",
                itemUnlock: { name: "STP Cable", icon: "fa-shield-cat", desc: "Kabel terlindung foil" },
                narrative: "Terjadi gangguan interferensi gelombang listrik dari mesin pabrik di sekitar instalasi.",
                question: "Kabel Twisted Pair yang memiliki lapisan alumunium foil pelindung interferensi elektromagnetik dinamakan...",
                options: [
                    { text: "STP (Shielded Twisted Pair)", correct: true, reason: "STP memiliki foil pelindung internal untuk menangkal gangguan elektromagnetik luar." },
                    { text: "UTP (Unshielded Twisted Pair)", correct: false, reason: "UTP tidak dilengkapi pelindung foil tambahan." },
                    { text: "Coaxial Thicknet", correct: false, reason: "Coaxial adalah jenis kabel berinti kawat tunggal tebal." },
                    { text: "Kabel Fiber Single-mode", correct: false, reason: "Fiber single-mode menggunakan inti kaca ultra-tipis." }
                ]
            },
            {
                nodeName: "DIRECT CROSSOVER LINK",
                zone: "Zona 1: Media Kabel",
                icon: "fa-arrows-rotate",
                itemUnlock: { name: "Cross Cable", icon: "fa-arrows-left-right", desc: "Penyambung antar PC" },
                narrative: "Dua komputer klien perlu ditransfer data secara langsung tanpa melewati Switch.",
                question: "Urutan pin kabel UTP yang tepat untuk menghubungkan dua perangkat sejenis (PC ke PC langsung) adalah...",
                options: [
                    { text: "Straight-Through Cable", correct: false, reason: "Straight-Through dipakai untuk perangkat berbeda jenis (PC ke Switch)." },
                    { text: "Crossover Cable", correct: true, reason: "Crossover menukar pasangan kabel TX/RX untuk menghubungkan dua perangkat serupa." },
                    { text: "Rollover Cable", correct: false, reason: "Rollover digunakan untuk port console manajemen perangkat." },
                    { text: "Serial Bus Cable", correct: false, reason: "Serial bus bukan jenis urutan susunan kawat UTP standar." }
                ]
            },

            // ZONA 2: Perangkat Keras / Hardware (5-8)
            {
                nodeName: "PENGUAT SIGNAL REPEATER",
                zone: "Zona 2: Hardware Jaringan",
                icon: "fa-wave-square",
                itemUnlock: { name: "Signal Booster", icon: "fa-tower-cell", desc: "Penguat sinyal lemah" },
                narrative: "Sinyal kabel jaringan melemah di jarak melebihi 100 meter dari pusat server.",
                question: "Perangkat keras yang berfungsi menerima sinyal lemah lalu memancarkan kembali sinyal kuat adalah...",
                options: [
                    { text: "Repeater", correct: true, reason: "Repeater meregenerasi sinyal fisik (Layer 1) yang melemah akibat faktor jarak." },
                    { text: "Modem", correct: false, reason: "Modem memodulasi sinyal analog/digital ISP." },
                    { text: "NIC / Card", correct: false, reason: "NIC adalah kartu adaptor LAN pada komputer." },
                    { text: "Splitter", correct: false, reason: "Splitter hanya membagi cabang sinyal tanpa memperkuatnya." }
                ]
            },
            {
                nodeName: "CENTRALE ETHERNET SWITCH",
                zone: "Zona 2: Hardware Jaringan",
                icon: "fa-network-wired",
                itemUnlock: { name: "MAC Scanner", icon: "fa-barcode", desc: "Pemindai alamat fisik" },
                narrative: "Trafik LAN sangat padat karena semua data disebar ke seluruh port tanpa filter tujuan.",
                question: "Perangkat Layer 2 yang mengirimkan paket data khusus hanya ke port tujuannya berdasarkan MAC Address adalah...",
                options: [
                    { text: "Hub", correct: false, reason: "Hub mengirim paket ke seluruh port (broadcast) sehingga sering tumbukan data." },
                    { text: "Switch", correct: true, reason: "Switch mencatat CAM/MAC table untuk meneruskan data secara presisi." },
                    { text: "Repeater", correct: false, reason: "Repeater tidak memiliki tabel logika pengalamatan MAC." },
                    { text: "Attenuator", correct: false, reason: "Attenuator mengurangi besaran daya sinyal." }
                ]
            },

            {
                nodeName: "ADAPTOR KARTU NIC",
                zone: "Zona 2: Hardware Jaringan",
                icon: "fa-memory",
                itemUnlock: { name: "LAN Card", icon: "fa-microchip", desc: "Kartu adaptor PC" },
                narrative: "Komputer PC desktop baru tidak dapat mendeteksi sambungan kabel LAN.",
                question: "Perangkat keras berupa papan sirkuit terpasang di PC untuk akses jaringan fisik disebut...",
                options: [
                    { text: "Sound Card", correct: false, reason: "Sound card mengolah output suara audio." },
                    { text: "NIC (Network Interface Card)", correct: true, reason: "NIC adalah pemicu antarmuka fisik antara PC dan media jaringan." },
                    { text: "VGA Card", correct: false, reason: "VGA Card mengolah grafis dan tampilan layar." },
                    { text: "RAM Module", correct: false, reason: "RAM adalah memori penyimpanan acak sementara." }
                ]
            },
            {
                nodeName: "MODULATOR DEMODULATOR",
                zone: "Zona 2: Hardware Jaringan",
                icon: "fa-radio",
                itemUnlock: { name: "Modem Unit", icon: "fa-sliders", desc: "Konverter sinyal ISP" },
                narrative: "Sinyal telepon analog dari ISP luar perlu disesuaikan dengan format komputer digital.",
                question: "Perangkat yang mengonversi sinyal analog ke digital dan sebaliknya adalah...",
                options: [
                    { text: "Router", correct: false, reason: "Router menentukan rute pengiriman paket IP." },
                    { text: "Modem", correct: true, reason: "Modem (Modulator Demodulator) mengubah bentuk gelombang sinyal." },
                    { text: "Switch", correct: false, reason: "Switch mengolah frame data dalam LAN." },
                    { text: "Access Point", correct: false, reason: "Access Point memancarkan gelombang nirkabel Wi-Fi." }
                ]
            },

            // ZONA 3: Routing & Gateway (9-12)
            {
                nodeName: "ROUTER GATEWAY TOWER",
                zone: "Zona 3: Routing & IP",
                icon: "fa-route",
                itemUnlock: { name: "IP Probe", icon: "fa-magnifying-glass-chart", desc: "Lacak rute IP" },
                narrative: "Paket data dari LAN Internal (192.168.1.0/24) hendak dikirim ke server Internet luar.",
                question: "Perangkat Layer 3 yang bertugas menghubungkan dua atau lebih jaringan ber-subnet beda adalah...",
                options: [
                    { text: "Hub", correct: false, reason: "Hub hanya menghubungkan komputer dalam 1 subnet lokal sama." },
                    { text: "Router", correct: true, reason: "Router menjembatani dan menyeberangkan data antar IP subnet berbeda." },
                    { text: "Access Point", correct: false, reason: "Access Point fokus memancarkan jaringan nirkabel." },
                    { text: "Ethernet Repeater", correct: false, reason: "Repeater tidak memiliki kecerdasan membaca alamat IP." }
                ]
            },
            {
                nodeName: "ROUTING TABLE VAULT",
                zone: "Zona 3: Routing & IP",
                icon: "fa-map-location-dot",
                itemUnlock: { name: "Route Map", icon: "fa-map", desc: "Tabel peta rute terbaik" },
                narrative: "Router kebingungan menentukan jalur mana yang paling cepat untuk sampai ke tujuan.",
                question: "Tabel internal pada router tempat menyimpan daftar alamat IP tujuan dan jalur antarmuka terbaiknya adalah...",
                options: [
                    { text: "MAC Address Table", correct: false, reason: "MAC Table ada pada Switch." },
                    { text: "Routing Table", correct: true, reason: "Routing table berisi peta rute destinasi IP dan hop berikutnya." },
                    { text: "DNS Cache", correct: false, reason: "DNS Cache menyimpan pemetaan nama domain." },
                    { text: "ARP Table", correct: false, reason: "ARP Table memetakan IP ke MAC Address lokal." }
                ]
            },
            {
                nodeName: "PACKET INSPECTOR",
                zone: "Zona 3: Routing & IP",
                icon: "fa-box-archive",
                itemUnlock: { name: "Packet Analyzer", icon: "fa-box-open", desc: "Pemeriksa paket data" },
                narrative: "Pion sedang membedah struktur data yang mengalir di Layer 3 (Network Layer).",
                question: "Satuan unit data terkapsulasi yang diproses pada Layer 3 (Network Layer) oleh router dinamakan...",
                options: [
                    { text: "Bits", correct: false, reason: "Bits adalah satuan sinyal pada Layer 1 Physical." },
                    { text: "Frames", correct: false, reason: "Frames adalah unit data pada Layer 2 Data Link." },
                    { text: "Packets (Paket)", correct: true, reason: "Data pada Layer 3 dibungkus sebagai Paket dengan header IP." },
                    { text: "Segments", correct: false, reason: "Segments adalah unit data pada Layer 4 Transport." }
                ]
            },
            {
                nodeName: "STASIUN PROTOKOL ARP",
                zone: "Zona 3: Routing & IP",
                icon: "fa-address-card",
                itemUnlock: { name: "ARP Sniffer", icon: "fa-id-card", desc: "Penerjemah IP ke MAC" },
                narrative: "Router tahu IP tujuan, tetapi butuh mengetahui alamat fisik kartu jaringan tujuan tersebut.",
                question: "Protokol yang menerjemahkan IP Address menjadi MAC Address fisik di jaringan lokal dinamakan...",
                options: [
                    { text: "DHCP", correct: false, reason: "DHCP bertugas memberikan IP otomatis." },
                    { text: "ARP (Address Resolution Protocol)", correct: true, reason: "ARP memetakan alamat logika (IP) ke alamat fisik (MAC)." },
                    { text: "DNS", correct: false, reason: "DNS menerjemahkan nama domain web ke IP." },
                    { text: "ICMP", correct: false, reason: "ICMP digunakan untuk pesan kontrol/tes ping." }
                ]
            },

            // ZONA 4: Wireless & Security (13-16)
            {
                nodeName: "ACCESS POINT WIRELESS",
                zone: "Zona 4: Wireless & Security",
                icon: "fa-wifi",
                itemUnlock: { name: "Wi-Fi Antenna", icon: "fa-tower-broadcast", desc: "Pemancar frekuensi radio" },
                narrative: "Perangkat smartphone dan laptop memerlukan akses internet tanpa mencolokkan kabel.",
                question: "Perangkat yang memancarkan sinyal gelombang radio Wi-Fi agar klien nirkabel dapat terhubung adalah...",
                options: [
                    { text: "Wireless Access Point (AP)", correct: true, reason: "Access Point mengonversi data kabel ke gelombang radio nirkabel." },
                    { text: "Server Rack", correct: false, reason: "Server Rack adalah lemari dudukan fisik hardware." },
                    { text: "Fiber Patch Panel", correct: false, reason: "Patch Panel adalah terminal fisik kerapian kabel." },
                    { text: "Attenuator", correct: false, reason: "Attenuator bukan pemancar nirkabel." }
                ]
            },
            {
                nodeName: "FIREWALL SECURITY BARRICADE",
                zone: "Zona 4: Wireless & Security",
                icon: "fa-fire-burner",
                itemUnlock: { name: "Cyber Shield", icon: "fa-shield", desc: "Dinding penapis peretas" },
                narrative: "Terdapat percobaan peretasan port tak dikenal yang datang dari jaringan luar.",
                question: "Sistem keamanan yang menyaring lalu lintas data masuk/keluar berdasarkan aturan keamanan adalah...",
                options: [
                    { text: "Firewall", correct: true, reason: "Firewall memblokir atau mengizinkan lalu lintas data sesuai rule set." },
                    { text: "Proxy Cache", correct: false, reason: "Proxy menyimpan salinan situs lokal." },
                    { text: "Bandwidth Shaper", correct: false, reason: "Bandwidth shaper membatasi kecepatan Mbps." },
                    { text: "Load Balancer", correct: false, reason: "Load balancer membagi beban ke beberapa server." }
                ]
            },
            {
                nodeName: "ENKRIPSI WPA3 VAULT",
                zone: "Zona 4: Wireless & Security",
                icon: "fa-key",
                itemUnlock: { name: "Security Key", icon: "fa-lock", desc: "Kunci enkripsi terkuat" },
                narrative: "Sandi jaringan Wi-Fi lama (WEP) sangat mudah dibobol hacker dalam 5 menit.",
                question: "Standar enkripsi keamanan Wi-Fi nirkabel yang paling modern dan kuat saat ini adalah...",
                options: [
                    { text: "WEP", correct: false, reason: "WEP adalah standar lama yang sangat rapuh." },
                    { text: "WPA3", correct: true, reason: "WPA3 menggunakan enkripsi 128/192-bit mutakhir yang sangat aman." },
                    { text: "WPA1-PSK", correct: false, reason: "WPA1 sudah usang dan memiliki celah keamanan." },
                    { text: "SSID Broadcast", correct: false, reason: "SSID hanyalah nama identitas pancaran Wi-Fi." }
                ]
            },
            {
                nodeName: "HARDWARE MAC ADDRESS",
                zone: "Zona 4: Wireless & Security",
                icon: "fa-fingerprint",
                itemUnlock: { name: "MAC Tag", icon: "fa-passport", desc: "Identitas fisik pabrik" },
                narrative: "Pion mencatat kode unik bawaan pabrik yang menempel permanen pada setiap kartu jaringan.",
                question: "Alamat fisik unik sepanjang 48-bit yang terpatri pada chip NIC buatan pabrik adalah...",
                options: [
                    { text: "IP Address", correct: false, reason: "IP Address bersifat logis dan bisa diubah-ubah." },
                    { text: "MAC Address", correct: true, reason: "MAC Address adalah nomor seri fisik unik global per perangkat." },
                    { text: "Port Number", correct: false, reason: "Port number menentukan nomor aplikasi layanan (misal 80)." },
                    { text: "Subnet Mask", correct: false, reason: "Subnet Mask menentukan pembagian ID jaringan." }
                ]
            },

            // ZONA 5: Layanan & Protocol Cloud (17-20)
            {
                nodeName: "DHCP AUTOMATION SERVER",
                zone: "Zona 5: Cloud & Services",
                icon: "fa-robot",
                itemUnlock: { name: "Auto IP Leaser", icon: "fa-wand-magic-sparkles", desc: "Pembagi IP Otomatis" },
                narrative: "Ratusan komputer baru terhubung sekaligus dan kelelahan jika setting IP manual.",
                question: "Layanan server yang membagikan konfigurasi IP Address secara otomatis ke klien adalah...",
                options: [
                    { text: "DNS Server", correct: false, reason: "DNS menerjemahkan nama domain ke IP." },
                    { text: "DHCP Server", correct: true, reason: "DHCP (Dynamic Host Configuration Protocol) mengalokasikan IP otomatis." },
                    { text: "FTP Server", correct: false, reason: "FTP digunakan untuk pengiriman berkas/file." },
                    { text: "SMTP Server", correct: false, reason: "SMTP digunakan untuk berkirim surat elektronik email." }
                ]
            },
            {
                nodeName: "DNS TRANSLATOR HUB",
                zone: "Zona 5: Cloud & Services",
                icon: "fa-book-atlas",
                itemUnlock: { name: "Domain Book", icon: "fa-book", desc: "Penerjemah Domain ke IP" },
                narrative: "Pengguna tidak mau menghafal nomor IP '142.250.196.110' untuk mengakses google.com.",
                question: "Protokol yang menerjemahkan nama domain website menjadi IP Address angka adalah...",
                options: [
                    { text: "DNS (Domain Name System)", correct: true, reason: "DNS berfungsi seperti buku telepon internet menerjemahkan nama ke IP." },
                    { text: "HTTP", correct: false, reason: "HTTP adalah protokol penyaji dokumen halaman web." },
                    { text: "TCP/IP", correct: false, reason: "TCP/IP adalah sekumpulan protokol dasar internet." },
                    { text: "ICMP", correct: false, reason: "ICMP adalah protokol tes status koneksi." }
                ]
            },
            {
                nodeName: "ICMP DIAGNOSTIC PING",
                zone: "Zona 5: Cloud & Services",
                icon: "fa-terminal",
                itemUnlock: { name: "Ping Terminal", icon: "fa-code", desc: "Alat penguji responsibel" },
                narrative: "Pion ingin menguji apakah server Cloud tujuan di internet sedang aktif merespons.",
                question: "Perintah CLI standar yang memanfaatkan protokol ICMP untuk mengecek konektivitas adalah...",
                options: [
                    { text: "ipconfig", correct: false, reason: "ipconfig untuk melihat alamat IP lokal komputer." },
                    { text: "ping", correct: true, reason: "Perintah 'ping' mengirim ICMP Echo Request untuk tes respon status." },
                    { text: "tracert", correct: false, reason: "tracert melacak rantai lompatan router (hops)." },
                    { text: "netstat", correct: false, reason: "netstat menampilkan statistik koneksi port aktif." }
                ]
            },
            {
                nodeName: "HTTPS CLOUD GATEWAY",
                zone: "Zona 5: Cloud & Services",
                icon: "fa-cloud-arrow-up",
                itemUnlock: { name: "SSL Certificate", icon: "fa-certificate", desc: "Sertifikat keamanan web" },
                narrative: "Misi Terakhir! Mengamankan transaksi data finansial pada portal server cloud.",
                question: "Protokol web terenkripsi SSL/TLS aman yang menggunakan port standar 443 adalah...",
                options: [
                    { text: "HTTP", correct: false, reason: "HTTP port 80 tidak terenkripsi (teks terbuka)." },
                    { text: "HTTPS", correct: true, reason: "HTTPS (Hypertext Transfer Protocol Secure) menyandi data dengan SSL/TLS." },
                    { text: "TELNET", correct: false, reason: "TELNET adalah akses remote lama tanpa enkripsi." },
                    { text: "FTP", correct: false, reason: "FTP digunakan khusus untuk mentransfer file." }
                ]
            }
        ];

        /* STREAMING_CHUNK: Game State Variables & Canvas Engine... */
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const miniCanvas = document.getElementById('miniMapCanvas');
        const miniCtx = miniCanvas.getContext('2d');

        // Game State
        let hp = 3;
        let score = 0;
        let completedNodes = 0;
        let inventory = [];
        let currentActiveNode = null;
        let isQuizOpen = false;
        let soundEnabled = true;

        // Tone.js Sound Synthesizer setup
        let synth, polySynth;
        try {
            synth = new Tone.Synth().toDestination();
            polySynth = new Tone.PolySynth().toDestination();
        } catch(e) {
            console.log("Audio Context initialization deferred");
        }

        function playSound(type) {
            if (!soundEnabled || !Tone || Tone.context.state !== 'running') return;
            try {
                if (type === 'move') {
                    synth.triggerAttackRelease("C5", "32n", undefined, 0.1);
                } else if (type === 'correct') {
                    polySynth.triggerAttackRelease(["C4", "E4", "G4", "C5"], "16n");
                } else if (type === 'wrong') {
                    polySynth.triggerAttackRelease(["C3", "C#3"], "8n");
                } else if (type === 'click') {
                    synth.triggerAttackRelease("G4", "32n", undefined, 0.2);
                }
            } catch(e){}
        }

        // Map Setup (Grid & Nodes)
        const MAP_SIZE = 12; // 12x12 Grid
        let TILE_WIDTH = 80;
        let TILE_HEIGHT = 40;

        // Map Isometric Node Locations
        // Map 20 questions to 20 coordinates on the board
        const nodePositions = [
            { x: 1, y: 1 }, { x: 3, y: 1 }, { x: 5, y: 1 }, { x: 7, y: 1 }, // Zone 1
            { x: 9, y: 2 }, { x: 9, y: 4 }, { x: 9, y: 6 }, { x: 9, y: 8 }, // Zone 2
            { x: 7, y: 10 }, { x: 5, y: 10 }, { x: 3, y: 10 }, { x: 1, y: 10 }, // Zone 3
            { x: 1, y: 8 }, { x: 1, y: 6 }, { x: 1, y: 4 }, { x: 3, y: 4 }, // Zone 4
            { x: 5, y: 4 }, { x: 5, y: 6 }, { x: 5, y: 8 }, { x: 7, y: 6 }  // Zone 5
        ];

        // Combine pos & questions
        const nodes = quizDatabase.map((q, idx) => {
            return {
                ...q,
                id: idx,
                gridX: nodePositions[idx].x,
                gridY: nodePositions[idx].y,
                completed: false
            };
        });

        // Player Pion Object
        const player = {
            gridX: 0,
            gridY: 0,
            targetX: 0,
            targetY: 0,
            pixelX: 0,
            pixelY: 0,
            speed: 0.1,
            isMoving: false,
            facing: 'SE'
        };

        /* STREAMING_CHUNK: Canvas Resize & Coordinate Converters... */
        function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            // Responsive tile sizing
            if (canvas.width < 640) {
                TILE_WIDTH = 50;
                TILE_HEIGHT = 25;
            } else if (canvas.width < 1024) {
                TILE_WIDTH = 66;
                TILE_HEIGHT = 33;
            } else {
                TILE_WIDTH = 80;
                TILE_HEIGHT = 40;
            }
        }
        window.addEventListener('resize', resizeCanvas);
        resizeCanvas();

        // Convert Grid (x,y) to Screen Isometric (px, py)
        function gridToIso(gx, gy) {
            const originX = canvas.width / 2;
            const originY = canvas.height / 5;
            const screenX = originX + (gx - gy) * (TILE_WIDTH / 2);
            const screenY = originY + (gx + gy) * (TILE_HEIGHT / 2);
            return { x: screenX, y: screenY };
        }

        // Convert Screen (px, py) to closest Grid (x, y)
        function isoToGrid(screenX, screenY) {
            const originX = canvas.width / 2;
            const originY = canvas.height / 5;
            const dx = screenX - originX;
            const dy = screenY - originY;

            const gx = Math.round((dx / (TILE_WIDTH / 2) + dy / (TILE_HEIGHT / 2)) / 2);
            const gy = Math.round((dy / (TILE_HEIGHT / 2) - dx / (TILE_WIDTH / 2)) / 2);
            return { x: Math.max(0, Math.min(MAP_SIZE - 1, gx)), y: Math.max(0, Math.min(MAP_SIZE - 1, gy)) };
        }

        /* STREAMING_CHUNK: Game Input Controls (Keyboard & Mouse)... */
        const keys = {};
        window.addEventListener('keydown', (e) => {
            if (isQuizOpen) return;
            try { Tone.start(); } catch(err){}
            keys[e.key.toLowerCase()] = true;
            handleKeyMovement();
        });

        window.addEventListener('keyup', (e) => {
            keys[e.key.toLowerCase()] = false;
        });

        canvas.addEventListener('click', (e) => {
            if (isQuizOpen) return;
            try { Tone.start(); } catch(err){}
            const rect = canvas.getBoundingClientRect();
            const clickX = e.clientX - rect.left;
            const clickY = e.clientY - rect.top;

            const targetGrid = isoToGrid(clickX, clickY);
            player.targetX = targetGrid.x;
            player.targetY = targetGrid.y;
            playSound('move');
        });

        function handleKeyMovement() {
            if (player.isMoving) return;
            let dx = 0, dy = 0;

            if (keys['arrowup'] || keys['w']) { dx = -1; dy = -1; }
            else if (keys['arrowdown'] || keys['s']) { dx = 1; dy = 1; }
            else if (keys['arrowleft'] || keys['a']) { dx = -1; dy = 1; }
            else if (keys['arrowright'] || keys['d']) { dx = 1; dy = -1; }

            if (dx !== 0 || dy !== 0) {
                const newX = Math.max(0, Math.min(MAP_SIZE - 1, player.gridX + dx));
                const newY = Math.max(0, Math.min(MAP_SIZE - 1, player.gridY + dy));
                player.targetX = newX;
                player.targetY = newY;
                playSound('move');
            }

            // Interact Key
            if (keys[' ']) {
                checkNodeProximity(true);
            }
        }

        /* STREAMING_CHUNK: Game Loop and Render Cycle... */
        function gameLoop() {
            updatePlayerPosition();
            renderMap();
            renderMiniMap();
            requestAnimationFrame(gameLoop);
        }

        function updatePlayerPosition() {
            // Smooth movement interpolation
            const startIso = gridToIso(player.gridX, player.gridY);
            const targetIso = gridToIso(player.targetX, player.targetY);

            if (player.gridX !== player.targetX || player.gridY !== player.targetY) {
                player.isMoving = true;
                player.pixelX += (targetIso.x - player.pixelX) * player.speed;
                player.pixelY += (targetIso.y - player.pixelY) * player.speed;

                if (Math.hypot(targetIso.x - player.pixelX, targetIso.y - player.pixelY) < 2) {
                    player.gridX = player.targetX;
                    player.gridY = player.targetY;
                    player.pixelX = targetIso.x;
                    player.pixelY = targetIso.y;
                    player.isMoving = false;
                    checkNodeProximity(false);
                }
            } else {
                player.pixelX = startIso.x;
                player.pixelY = startIso.y;
            }
        }

        function checkNodeProximity(forceOpen) {
            const node = nodes.find(n => n.gridX === player.gridX && n.gridY === player.gridY);
            if (node && (!node.completed || forceOpen)) {
                openQuizModal(node);
            }
        }

        /* STREAMING_CHUNK: Drawing Isometric Canvas Map Elements... */
        function renderMap() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // 1. Draw Grid Tiles
            for (let gx = 0; gx < MAP_SIZE; gx++) {
                for (let gy = 0; gy < MAP_SIZE; gy++) {
                    const pos = gridToIso(gx, gy);
                    
                    // Path connecting lines
                    ctx.beginPath();
                    ctx.moveTo(pos.x, pos.y);
                    ctx.lineTo(pos.x + TILE_WIDTH / 2, pos.y + TILE_HEIGHT / 2);
                    ctx.lineTo(pos.x, pos.y + TILE_HEIGHT);
                    ctx.lineTo(pos.x - TILE_WIDTH / 2, pos.y + TILE_HEIGHT / 2);
                    ctx.closePath();

                    // Tile Styling
                    ctx.fillStyle = ((gx + gy) % 2 === 0) ? '#0f172a' : '#090d16';
                    ctx.fill();
                    ctx.strokeStyle = '#1e293b';
                    ctx.lineWidth = 1;
                    ctx.stroke();
                }
            }

            // 2. Draw Network Topologi Cyber Pathways
            ctx.strokeStyle = 'rgba(6, 182, 212, 0.4)';
            ctx.lineWidth = 3;
            ctx.beginPath();
            for (let i = 0; i < nodes.length - 1; i++) {
                const startIso = gridToIso(nodes[i].gridX, nodes[i].gridY);
                const endIso = gridToIso(nodes[i+1].gridX, nodes[i+1].gridY);
                ctx.moveTo(startIso.x, startIso.y + TILE_HEIGHT / 2);
                ctx.lineTo(endIso.x, endIso.y + TILE_HEIGHT / 2);
            }
            ctx.stroke();

            // 3. Draw Nodes / Hardware Stations
            nodes.forEach((n) => {
                const pos = gridToIso(n.gridX, n.gridY);
                const isCurrent = (n.gridX === player.gridX && n.gridY === player.gridY);

                // Base Pedestal
                ctx.beginPath();
                ctx.ellipse(pos.x, pos.y + TILE_HEIGHT / 2, TILE_WIDTH / 3, TILE_HEIGHT / 3, 0, 0, Math.PI * 2);
                ctx.fillStyle = n.completed ? 'rgba(16, 185, 129, 0.2)' : 'rgba(6, 182, 212, 0.2)';
                ctx.fill();
                ctx.strokeStyle = n.completed ? '#10b981' : (isCurrent ? '#f59e0b' : '#06b6d4');
                ctx.lineWidth = isCurrent ? 3 : 2;
                ctx.stroke();

                // Station Hologram Pillar
                ctx.beginPath();
                ctx.moveTo(pos.x, pos.y + TILE_HEIGHT / 2);
                ctx.lineTo(pos.x, pos.y - 20);
                ctx.strokeStyle = n.completed ? 'rgba(16, 185, 129, 0.6)' : 'rgba(6, 182, 212, 0.6)';
                ctx.stroke();

                // Icon / Node Top Box
                ctx.fillStyle = n.completed ? '#10b981' : '#06b6d4';
                ctx.beginPath();
                ctx.arc(pos.x, pos.y - 25, 12, 0, Math.PI * 2);
                ctx.fill();

                // Node Question Number Text
                ctx.fillStyle = '#050811';
                ctx.font = 'bold 10px monospace';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText(n.id + 1, pos.x, pos.y - 25);
            });

            // 4. Draw Player Cyber Pion Character
            const pIso = { x: player.pixelX, y: player.pixelY };
            
            // Pion Shadow
            ctx.beginPath();
            ctx.ellipse(pIso.x, pIso.y + TILE_HEIGHT / 2, 14, 7, 0, 0, Math.PI * 2);
            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
            ctx.fill();

            // Cyber Pion Body Avatar
            const bounce = Math.sin(Date.now() / 150) * 3;
            const pionY = pIso.y + TILE_HEIGHT / 2 - 20 + bounce;

            // Outer Glow Body
            ctx.fillStyle = '#06b6d4';
            ctx.beginPath();
            ctx.arc(pIso.x, pionY, 14, 0, Math.PI * 2);
            ctx.fill();
            ctx.strokeStyle = '#67e8f9';
            ctx.lineWidth = 2;
            ctx.stroke();

            // Cyber Visor / Headphone Line
            ctx.fillStyle = '#050811';
            ctx.beginPath();
            ctx.arc(pIso.x + 2, pionY - 1, 8, 0, Math.PI * 2);
            ctx.fill();

            ctx.fillStyle = '#38bdf8';
            ctx.fillRect(pIso.x - 2, pionY - 3, 8, 4);

            // Agent Tag Label above Pion
            ctx.fillStyle = '#06b6d4';
            ctx.font = 'bold 10px Rajdhani';
            ctx.textAlign = 'center';
            ctx.fillText("PION AGEN-01", pIso.x, pionY - 20);
        }

        /* STREAMING_CHUNK: Render Mini Map HUD Engine... */
        function renderMiniMap() {
            miniCtx.clearRect(0, 0, miniCanvas.width, miniCanvas.height);
            const scaleX = miniCanvas.width / MAP_SIZE;
            const scaleY = miniCanvas.height / MAP_SIZE;

            // Draw grid outline
            miniCtx.strokeStyle = '#1e293b';
            miniCtx.strokeRect(0, 0, miniCanvas.width, miniCanvas.height);

            // Draw Nodes
            nodes.forEach(n => {
                miniCtx.fillStyle = n.completed ? '#10b981' : '#06b6d4';
                miniCtx.fillRect(n.gridX * scaleX, n.gridY * scaleY, 4, 4);
            });

            // Draw Player Position
            miniCtx.fillStyle = '#f59e0b';
            miniCtx.beginPath();
            miniCtx.arc(player.gridX * scaleX + 2, player.gridY * scaleY + 2, 3, 0, Math.PI * 2);
            miniCtx.fill();
        }

        /* STREAMING_CHUNK: Quiz Modal & Inventory Logic... */
        function openQuizModal(node) {
            currentActiveNode = node;
            isQuizOpen = true;

            const modal = document.getElementById('quiz-modal');
            modal.classList.remove('hidden');

            document.getElementById('node-title').textContent = node.nodeName;
            document.getElementById('node-subtitle').textContent = `Misi ${String(node.id + 1).padStart(2, '0')} • ${node.zone}`;
            document.getElementById('node-icon').className = `fa-solid ${node.icon}`;
            document.getElementById('quiz-badge').textContent = `SOAL ${node.id + 1}/20`;
            document.getElementById('quiz-narrative').textContent = `"${node.narrative}"`;
            document.getElementById('quiz-question').textContent = node.question;

            // Reset Feedback UI
            const feedbackBox = document.getElementById('quiz-feedback');
            const actionBtn = document.getElementById('quiz-action-btn');
            feedbackBox.classList.add('hidden');
            actionBtn.classList.add('hidden');

            // Render Option Buttons
            const optionsContainer = document.getElementById('quiz-options');
            optionsContainer.innerHTML = '';

            node.options.forEach((opt, idx) => {
                const btn = document.createElement('button');
                btn.className = "w-full text-left p-3 rounded-xl bg-slate-950/80 hover:bg-slate-800/80 border border-slate-800 hover:border-cyan-400/50 transition flex items-center justify-between text-xs sm:text-sm text-slate-200 cursor-pointer group";
                btn.onclick = () => handleAnswerSelect(idx);
                btn.innerHTML = `
                    <div class="flex items-center space-x-3">
                        <span class="w-6 h-6 rounded bg-slate-900 border border-slate-700 flex items-center justify-center font-bold text-cyan-400 text-xs group-hover:border-cyan-400">
                            ${String.fromCharCode(65 + idx)}
                        </span>
                        <span>${opt.text}</span>
                    </div>
                    <i class="fa-regular fa-circle text-slate-600 group-hover:text-cyan-400"></i>
                `;
                optionsContainer.appendChild(btn);
            });
        }

        function handleAnswerSelect(selectedIdx) {
            const node = currentActiveNode;
            const selectedOpt = node.options[selectedIdx];
            const optionBtns = document.getElementById('quiz-options').children;

            // Disable re-selection
            for (let btn of optionBtns) {
                btn.onclick = null;
                btn.classList.remove('cursor-pointer', 'hover:border-cyan-400/50');
            }

            const feedbackBox = document.getElementById('quiz-feedback');
            const feedbackTitle = document.getElementById('feedback-title');
            const feedbackExp = document.getElementById('feedback-explanation');
            const actionBtn = document.getElementById('quiz-action-btn');

            if (selectedOpt.correct) {
                playSound('correct');
                score += 100;
                if (!node.completed) {
                    node.completed = true;
                    completedNodes++;
                    addInventoryItem(node.itemUnlock);
                }

                optionBtns[selectedIdx].className = "w-full text-left p-3 rounded-xl bg-emerald-950/70 border-2 border-emerald-500 text-white flex items-center justify-between text-xs sm:text-sm glow-green";
                optionBtns[selectedIdx].querySelector('i').className = "fa-solid fa-circle-check text-emerald-400 text-base";

                feedbackBox.className = "p-3.5 rounded-xl bg-emerald-950/40 border border-emerald-500/50 text-emerald-200 mb-4 text-xs sm:text-sm";
                feedbackTitle.innerHTML = `<i class="fa-solid fa-circle-check text-emerald-400 mr-2"></i> JAWABAN BENAR! (+100 Poin)`;
            } else {
                playSound('wrong');
                hp--;
                updateHPDisplay();

                optionBtns[selectedIdx].className = "w-full text-left p-3 rounded-xl bg-red-950/70 border-2 border-red-500 text-white flex items-center justify-between text-xs sm:text-sm glow-red";
                optionBtns[selectedIdx].querySelector('i').className = "fa-solid fa-circle-xmark text-red-400 text-base";

                // Highlight correct option
                node.options.forEach((opt, idx) => {
                    if (opt.correct) {
                        optionBtns[idx].className = "w-full text-left p-3 rounded-xl bg-emerald-950/40 border border-emerald-500/50 text-white flex items-center justify-between text-xs sm:text-sm";
                        optionBtns[idx].querySelector('i').className = "fa-solid fa-circle-check text-emerald-400";
                    }
                });

                feedbackBox.className = "p-3.5 rounded-xl bg-red-950/40 border border-red-500/50 text-red-200 mb-4 text-xs sm:text-sm";
                feedbackTitle.innerHTML = `<i class="fa-solid fa-triangle-exclamation text-red-400 mr-2"></i> JAWABAN SALAH! (HP Berkurang)`;
            }

            feedbackExp.textContent = selectedOpt.reason;
            feedbackBox.classList.remove('hidden');
            actionBtn.classList.remove('hidden');

            updateHUD();

            actionBtn.onclick = () => {
                document.getElementById('quiz-modal').classList.add('hidden');
                isQuizOpen = false;

                if (hp <= 0) {
                    endGame(false);
                } else if (completedNodes >= nodes.length) {
                    endGame(true);
                }
            };
        }

        /* STREAMING_CHUNK: Inventory UI Handler... */
        function addInventoryItem(item) {
            if (!inventory.some(i => i.name === item.name)) {
                inventory.push(item);
                renderInventory();
            }
        }

        function renderInventory() {
            const grid = document.getElementById('inventory-grid');
            grid.innerHTML = '';

            for (let i = 0; i < 6; i++) {
                const slot = document.createElement('div');
                slot.className = "w-full aspect-square bg-slate-950 rounded-lg border border-slate-800 flex items-center justify-center text-slate-600 text-lg relative group";

                if (inventory[i]) {
                    slot.className = "w-full aspect-square bg-slate-900 rounded-lg border border-cyan-500/40 flex items-center justify-center text-cyan-400 text-lg relative group glow-cyan";
                    slot.innerHTML = `<i class="fa-solid ${inventory[i].icon}"></i>`;
                    
                    // Tooltip
                    const tooltip = document.createElement('div');
                    tooltip.className = "absolute bottom-full mb-1 hidden group-hover:block bg-slate-950 border border-cyan-500 text-[10px] text-cyan-200 p-1.5 rounded whitespace-nowrap z-30 font-mono";
                    tooltip.textContent = inventory[i].name;
                    slot.appendChild(tooltip);
                }
                grid.appendChild(slot);
            }
        }

        /* STREAMING_CHUNK: HUD & Game State Updaters... */
        function updateHUD() {
            document.getElementById('score-text').textContent = score;
            document.getElementById('quest-progress').textContent = `${completedNodes} / ${nodes.length}`;
            
            const currentZone = Math.min(5, Math.floor(completedNodes / 4) + 1);
            document.getElementById('current-zone-tag').textContent = `ZONE ${currentZone}`;
        }

        function updateHPDisplay() {
            const container = document.getElementById('hp-hearts');
            container.innerHTML = '';
            for (let i = 0; i < 3; i++) {
                const heart = document.createElement('i');
                heart.className = i < hp ? "fa-solid fa-heart text-red-500" : "fa-regular fa-heart text-slate-700";
                container.appendChild(heart);
            }
        }

        function endGame(isWin) {
            const modal = document.getElementById('end-modal');
            modal.classList.remove('hidden');

            document.getElementById('final-score').textContent = score;
            document.getElementById('final-accuracy').textContent = `${completedNodes} / 20 Misi`;

            let rank = "Cyber Novice";
            if (completedNodes >= 18) rank = "Network Arch-Mage 🏆";
            else if (completedNodes >= 14) rank = "Senior Cyber Engineer 💻";
            else if (completedNodes >= 10) rank = "Network Administrator 🔧";

            document.getElementById('final-rank').textContent = rank;

            if (isWin) {
                document.getElementById('end-title').textContent = "MISI SUKSES!";
                document.getElementById('end-description').textContent = "Luar biasa! Pion Agen Cyber berhasil menjelajahi semua node dan memulihkan seluruh topologi jaringan.";
            } else {
                document.getElementById('end-title').textContent = "SYSTEM COLLAPSE!";
                document.getElementById('end-description').textContent = "Pion kehabisan daya HP di tengah jalan. Pelajari kembali komponen jaringan dan coba lagi!";
            }
        }

        function restartGame() {
            hp = 3;
            score = 0;
            completedNodes = 0;
            inventory = [];
            player.gridX = 0;
            player.gridY = 0;
            player.targetX = 0;
            player.targetY = 0;

            nodes.forEach(n => n.completed = false);

            document.getElementById('end-modal').classList.add('hidden');
            updateHPDisplay();
            updateHUD();
            renderInventory();
        }

        /* STREAMING_CHUNK: Game Initialization... */
        window.onload = function() {
            renderInventory();
            updateHPDisplay();
            updateHUD();
            gameLoop();
        };
    </script>
</body>
</html>
```eof

### Fitur Gameplay Isometric Pion RPG:
1. **Pergerakan Karakter Pion Real-Time:** 
   - Bergerak bebas menggunakan papan ketik (**WASD / Panah**) atau **klik langsung di atas peta isometric**.
   - Animasi Pion bergerak mulus dengan efek pantulan (*bounce*) dan *shadowing* di atas grid.
2. **Topologi Jaringan Isometric 2D:**
   - 20 Node stasiun komponen jaringan saling terhubung oleh jalur kabel cyber neon.
   - Dilengkapi *Mini-map* topologi di pojok kiri bawah yang memantau lokasi Pion secara *real-time*.
3. **Papan Inventoris Alat Jaringan (Inventory):**
   - Setiap kali menyelesaikan soal node dengan benar, kamu akan mendapatkan alat kerja jaringan baru (seperti *RJ-45 Crimper, Fiber Cable, IP Probe, Cyber Shield*, dll) yang langsung masuk ke slot inventoris.
4. **20 Soal Kuis Komprehensif:**
   - Terbagi dalam 5 Zona (Media Kabel, Hardware, Routing/IP, Wireless/Security, & Cloud/Services).
   - Dialog interaktif langsung terbuka ketika Pion menginjak stasiun node.
   - Dilengkapi efek suara sintetis web audio (Tone.js).