{"product_id":"sgp-watch","title":"SGP watch","description":"\u003cbody\u003e\n\n\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eSGP WATCH - Diagnostic Hub\u003c\/title\u003e\n    \n    \u003clink rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\"\u003e\n    \u003clink rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin\u003e\n    \u003clink href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600\u0026amp;family=Space+Grotesk:wght@700;800\u0026amp;family=Share+Tech+Mono\u0026amp;display=swap\" rel=\"stylesheet\"\u003e\n    \n    \u003cscript src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/tone\/14.8.49\/Tone.js\"\u003e\u003c\/script\u003e\n\n    \u003cstyle\u003e\n        :root {\n            --bg-color: #e0e5ec;\n            --text-main: #2d3748;\n            --text-muted: #718096;\n            --accent: #eab308;\n            --success: #38a169;\n            --danger: #e53e3e;\n            \n            --shadow-light: rgba(255, 255, 255, 0.8);\n            --shadow-dark: rgba(163, 177, 198, 0.6);\n            --neu-out: 9px 9px 16px var(--shadow-dark), -9px -9px 16px var(--shadow-light);\n            --neu-out-sm: 5px 5px 10px var(--shadow-dark), -5px -5px 10px var(--shadow-light);\n            --neu-in: inset 6px 6px 10px var(--shadow-dark), inset -6px -6px 10px var(--shadow-light);\n            \n            --radius-xl: 40px;\n            --radius-lg: 30px;\n            --radius-pill: 100px;\n            \n            \/* SGP OS Colors *\/\n            --os-bg: #000000;\n            --os-green: #00ff00;\n            --os-dim: #005500;\n            --os-text: #88ff88;\n            --os-red: #ff2222;\n        }\n\n        * { box-sizing: border-box; margin: 0; padding: 0; }\n        body { background-color: var(--bg-color); color: var(--text-main); font-family: 'Inter', sans-serif; line-height: 1.6; padding: 20px; overflow-x: hidden; }\n        h1, h2, h3 { font-family: 'Space Grotesk', sans-serif; font-weight: 800; color: var(--text-main); margin-bottom: 15px; letter-spacing: -0.5px; }\n\n        .product-container { max-width: 1000px; margin: 0 auto; padding-bottom: 60px; }\n        .neu-card { background: var(--bg-color); border-radius: var(--radius-xl); box-shadow: var(--neu-out); padding: 40px; margin-bottom: 40px; }\n        .neu-card-sm { background: var(--bg-color); border-radius: var(--radius-lg); box-shadow: var(--neu-out); padding: 25px; display: flex; flex-direction: column; gap: 15px; }\n        .neu-sunken { background: var(--bg-color); border-radius: var(--radius-lg); box-shadow: var(--neu-in); padding: 25px; }\n        \n        .neu-icon { width: 60px; height: 60px; border-radius: 50%; background: var(--bg-color); box-shadow: var(--neu-out); display: flex; align-items: center; justify-content: center; color: var(--accent); font-size: 24px; margin-bottom: 10px; }\n        .svg-icon { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }\n\n        .header-section { text-align: center; margin-bottom: 50px; padding-top: 20px; }\n        .badge { display: inline-block; background: var(--bg-color); box-shadow: var(--neu-in); padding: 8px 20px; border-radius: var(--radius-pill); font-size: 13px; font-weight: 600; color: var(--accent); text-transform: uppercase; letter-spacing: 2px; margin-bottom: 20px; }\n        .main-title { font-size: clamp(36px, 6vw, 64px); background: linear-gradient(135deg, #2d3748 0%, #718096 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 10px; }\n        \n        .hero-image-wrapper { margin: 30px auto; max-width: 350px; border-radius: var(--radius-xl); padding: 15px; background: var(--bg-color); box-shadow: var(--neu-out); }\n        .hero-image-wrapper img { width: 100%; height: auto; border-radius: var(--radius-lg); display: block; }\n\n        .section-title { text-align: center; font-size: 28px; margin-bottom: 40px; margin-top: 60px; }\n        .features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 30px; margin-bottom: 50px; }\n        .feature-title { font-size: 18px; margin-bottom: 5px; }\n        .feature-desc { color: var(--text-muted); font-size: 15px; }\n        \n        .neu-list { list-style: none; padding: 0; }\n        .neu-list li { display: flex; align-items: center; gap: 15px; padding: 12px 0; border-bottom: 1px solid rgba(163, 177, 198, 0.3); color: var(--text-muted); font-size: 15px; }\n        .neu-list li:last-child { border-bottom: none; }\n        .neu-list .check { color: var(--success); font-weight: bold; font-size: 18px; }\n\n        .disclaimer { margin-top: 60px; text-align: center; }\n        .disclaimer p { font-size: 12px; color: var(--text-muted); margin-top: 10px; }\n        \n        .watch-container { display: flex; justify-content: center; align-items: center; padding: 40px 0; }\n        .watch-case { width: 280px; height: 340px; background: #1a1a1a; border-radius: 40px; position: relative; box-shadow: 20px 20px 60px var(--shadow-dark), -20px -20px 60px var(--shadow-light), inset 5px 5px 15px #333, inset -5px -5px 15px #000; border: 4px solid #2a2a2a; display: flex; justify-content: center; align-items: center; }\n        \n        \/* Physical Buttons *\/\n        .watch-button { position: absolute; right: -12px; width: 12px; background: #222; border-radius: 0 6px 6px 0; box-shadow: 3px 3px 5px var(--shadow-dark); border: 2px solid #111; border-left: none; cursor: pointer; transition: transform 0.1s; }\n        .watch-button:active { transform: translateX(-4px); }\n        .btn-top { top: 60px; height: 35px; }\n        .btn-mid { top: 120px; height: 35px; }\n        .btn-bot { top: 180px; height: 35px; }\n        \n        .watch-button-label { position: absolute; font-size: 11px; color: var(--text-muted); font-weight: bold; pointer-events: none; right: -40px; transform: rotate(90deg); letter-spacing: 2px; white-space: nowrap; }\n        \n        .watch-screen-bezel { width: 240px; height: 280px; background: #000; border-radius: 25px; overflow: hidden; position: relative; box-shadow: inset 0 0 20px rgba(0,0,0,1); }\n        .os-screen { width: 100%; height: 100%; font-family: 'Share Tech Mono', monospace; color: var(--os-green); background: var(--os-bg); position: relative; user-select: none; }\n        \n        .os-header { background: var(--os-green); color: var(--os-bg); padding: 5px 10px; font-weight: bold; font-size: 14px; display: flex; justify-content: space-between; position: sticky; top: 0; z-index: 10; }\n        .os-content { padding: 10px; height: calc(100% - 28px); overflow-y: auto; overflow-x: hidden; scroll-behavior: smooth; }\n        \n        .os-content::-webkit-scrollbar { width: 6px; }\n        .os-content::-webkit-scrollbar-track { background: var(--os-bg); }\n        .os-content::-webkit-scrollbar-thumb { background: var(--os-dim); border-radius: 3px; }\n        .os-content::-webkit-scrollbar-thumb:hover { background: var(--os-green); }\n\n        .os-menu-item { border: 1px solid var(--os-dim); padding: 12px 10px; margin-bottom: 8px; border-radius: 4px; display: flex; justify-content: space-between; align-items: center; cursor: pointer; font-size: 14px; transition: all 0.1s; }\n        .os-menu-item:hover { background: var(--os-dim); color: var(--os-text); }\n        .os-menu-item:active { background: var(--os-green); color: var(--os-bg); }\n        \n        .os-text { color: var(--os-text); }\n        .os-green { color: var(--os-green); }\n        .os-red { color: var(--os-red); }\n        .os-dim { color: var(--os-dim); }\n        \n        .scan-item { border: 1px solid var(--os-dim); margin-bottom: 5px; padding: 5px; font-size: 12px; }\n        \n        @keyframes reveal { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }\n        .reveal { animation: reveal 0.6s ease-out forwards; }\n        \n        @keyframes blink { 0%, 100% { opacity:1; } 50% { opacity:0.3; } }\n        @keyframes colorCycle { 0% {background:#f00;} 33% {background:#0f0;} 66% {background:#00f;} 100% {background:#f00;} }\n        @keyframes scanSweep { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n        \n        \/* Estilos específicos para DOOM *\/\n        #dosbox-container { width: 100%; height: 100%; background: #000; position: relative; z-index: 20; display: flex; flex-direction: column; justify-content: center; align-items: center;}\n    \u003c\/style\u003e\n\n\n\n\u003cdiv class=\"product-container reveal\"\u003e\n\n    \u003cheader class=\"header-section\"\u003e\n        \u003cdiv class=\"badge\"\u003eAdvanced Wearable Hub\u003c\/div\u003e\n        \u003ch1 class=\"main-title\"\u003eSGP WATCH\u003c\/h1\u003e\n        \u003cp class=\"subtitle\" style=\"font-size: 18px; color: var(--text-muted); font-weight: 500; max-width: 600px; margin: 0 auto;\"\u003eIntegrate. Program. Deploy. Professional hardware disguised as an everyday timepiece.\u003c\/p\u003e\n    \u003c\/header\u003e\n\n    \u003ch2 class=\"section-title\"\u003e💻 Interactive SGP OS Emulator\u003c\/h2\u003e\n\n    \u003cdiv class=\"watch-container\"\u003e\n        \u003cdiv class=\"watch-case\"\u003e\n            \u003c!-- 3 Hardware Buttons --\u003e\n            \u003cdiv class=\"watch-button btn-top\" onclick=\"appMenu()\" title=\"Back \/ Home\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"watch-button-label\" style=\"top: 70px;\"\u003eBACK\u003c\/div\u003e\n            \n            \u003cdiv class=\"watch-button btn-mid\" onclick=\"scrollMenu(-1)\" title=\"Scroll Up\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"watch-button-label\" style=\"top: 130px;\"\u003eUP\u003c\/div\u003e\n            \n            \u003cdiv class=\"watch-button btn-bot\" onclick=\"scrollMenu(1)\" title=\"Scroll Down\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"watch-button-label\" style=\"top: 190px;\"\u003eDOWN\u003c\/div\u003e\n\n            \u003c!-- Screen --\u003e\n            \u003cdiv class=\"watch-screen-bezel\"\u003e\n                \u003cdiv class=\"os-screen\" id=\"os-screen\"\u003e\n                    \u003c!-- OS Content injected here --\u003e\n                \u003c\/div\u003e\n            \u003c\/div\u003e\n        \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003ch2 class=\"section-title\"\u003e🔧 Core Capabilities\u003c\/h2\u003e\n    \n    \u003cdiv class=\"features-grid\"\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eOpen-Source Core\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eEquipped with a dual-core Xtensa LX7 processor @ 240MHz, 8MB PSRAM, and 16MB Flash memory. 100% open-source.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003crect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"\u003e\u003c\/rect\u003e\u003cline x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"\u003e\u003c\/line\u003e\u003cline x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"\u003e\u003c\/line\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003e1.69\" LCD Interface\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eCrisp 240x280 pixel display with 262K colors, driven by the ST7789V2 chip. Fluid GUI under any condition.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M22 12h-4l-3 9L9 3l-3 9H2\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eKinetic Tracking\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eIntegrated QMI8658 sensor (6-axis IMU). Ideal for telemetry, gesture commands, and environmental motion tracking.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M5 12.55a11 11 0 0 1 14.08 0\"\u003e\u003c\/path\u003e\u003cpath d=\"M1.42 9a16 16 0 0 1 21.16 0\"\u003e\u003c\/path\u003e\u003ccircle cx=\"12\" cy=\"20\" r=\"1\"\u003e\u003c\/circle\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eSignal Analysis\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eDeploy diagnostic capabilities with native support for 2.4 GHz Wi-Fi and Bluetooth 5 (LE) directly from your wrist.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003crect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\"\u003e\u003c\/rect\u003e\u003cline x1=\"23\" y1=\"13\" x2=\"23\" y2=\"11\"\u003e\u003c\/line\u003e\u003cline x1=\"15\" y1=\"6\" x2=\"15\" y2=\"18\"\u003e\u003c\/line\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eExtended Power\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eMassive 500+ mAh battery for days of continuous testing, backed by ultra-low power RTC management.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\"\u003e\u003c\/path\u003e\u003cpolyline points=\"13 2 13 9 20 9\"\u003e\u003c\/polyline\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eRapid Modding\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eUSB Type-C connector and a reserved 12PIN port (GPIO, I2C, UART) to instantly dock external peripherals.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003c!-- Nuevas capacidades añadidas --\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"10\"\u003e\u003c\/circle\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"6\"\u003e\u003c\/circle\u003e\u003ccircle cx=\"12\" cy=\"12\" r=\"2\"\u003e\u003c\/circle\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eProximity Radar\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eDetects and tracks nearby wireless devices in real-time. Ideal for spatial awareness and locating active Wi-Fi\/BLE emitters.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M8 3l4 8 5-5 5 15H2L8 3z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eOutdoor \u0026amp; Sports\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eFully programmable for mountain excursions and sports telemetry. Log kinetic data, altitude variations, and track your routes.\u003c\/p\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003cdiv class=\"neu-icon\"\u003e\u003csvg class=\"svg-icon\" viewbox=\"0 0 24 24\"\u003e\u003cpath d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 11a2 2 0 1 0 0-4 2 2 0 0 0 0 4z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/div\u003e\n            \u003ch3 class=\"feature-title\"\u003eTactical Security\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eThe ultimate discreet instrument for surveillance and security teams. Perform silent network audits and monitor environments seamlessly.\u003c\/p\u003e\n        \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003ch2 class=\"section-title\"\u003e⚡ Authorized Operations: Use Cases\u003c\/h2\u003e\n    \n    \u003cdiv class=\"features-grid\"\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003ch3 class=\"feature-title\" style=\"color: var(--accent);\"\u003e01. Network Auditing\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eAuthorized mapping, analysis, and security testing of personal or corporate Wi-Fi\/BLE networks to identify vulnerabilities.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003ch3 class=\"feature-title\" style=\"color: var(--accent);\"\u003e02. IoT Command Node\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eSeamless integration with smart home environments (e.g., Home Assistant, MQTT) for wrist-based device control.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003ch3 class=\"feature-title\" style=\"color: var(--accent);\"\u003e03. Kinetic Development\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eCreating custom algorithms for sports telemetry, gesture-based remote controls, or fall detection via the built-in IMU.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003ch3 class=\"feature-title\" style=\"color: var(--accent);\"\u003e04. Academic Sandbox\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eA highly portable laboratory for learning embedded systems, C\/C++, MicroPython, and secure wireless communications.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003ch3 class=\"feature-title\" style=\"color: var(--accent);\"\u003e05. Ecosystem Synergy\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eFully compatible with our entire range of devices. Connect the SGP Watch to expand your diagnostic capabilities exponentially.\u003c\/p\u003e\n        \u003c\/div\u003e\n        \u003cdiv class=\"neu-card-sm\"\u003e\n            \u003ch3 class=\"feature-title\" style=\"color: var(--accent);\"\u003e06. Maximum Portability\u003c\/h3\u003e\n            \u003cp class=\"feature-desc\"\u003eThe smallest and most discrete tool in our arsenal. Carry immense analytical power wherever you go without drawing attention.\u003c\/p\u003e\n        \u003c\/div\u003e\n    \u003c\/div\u003e\n\n    \u003cdiv class=\"disclaimer neu-sunken\"\u003e\n        \u003ch4 style=\"color: var(--danger); font-size: 14px; margin-bottom: 5px; text-transform: uppercase;\"\u003e🔒 Responsibility Protocol\u003c\/h4\u003e\n        \u003cp\u003eEngineered exclusively for education, authorized security research, and personal IoT development. Operators must ensure compliance with all applicable local, state, and federal laws. Obtain explicit consent before auditing any network infrastructure.\u003c\/p\u003e\n    \u003c\/div\u003e\n\n\u003c\/div\u003e\n\n\u003cscript\u003e\n    let synth;\n    async function playBeep() {\n        if (!synth) {\n            \/\/ Configurar un pitido estilo \"reloj digital clásico\" (onda cuadrada, muy corto)\n            synth = new Tone.Synth({\n                oscillator: { type: \"square\" },\n                envelope: { attack: 0.005, decay: 0.05, sustain: 0.0, release: 0.01 }\n            }).toDestination();\n            synth.volume.value = -15; \/\/ Bajar un poco el volumen para que sea agradable\n        }\n        \/\/ Iniciar el contexto de audio (requerido por los navegadores)\n        await Tone.start();\n        synth.triggerAttackRelease(\"C6\", \"0.05\");\n    }\n\n    const screen = document.getElementById('os-screen');\n    let currentState = 'BOOT';\n    let renderInterval;\n    let mouseListener;\n    let doomAnim; \/\/ Variable para el motor 3D\n    let doomEventHandlers = {}; \/\/ Guardar referencias a eventos para limpiarlos\n\n    \/\/ Purified App List matching the C++ Menu WITHOUT RFID\n    const appsList = [\n        { name: \"DOOM\", id: \"DOOM\" },\n        { name: \"WATCH FACES\", id: \"FACES\" },\n        { name: \"WIFI MOTION\", id: \"WIFI_MOTION\" },\n        { name: \"BIO SAFETY\", id: \"BIO\" },\n        { name: \"GAS MONITOR\", id: \"BIO\" },\n        { name: \"ALTIMETER\", id: \"ALTIMETER\" },\n        { name: \"MOOD LIGHT\", id: \"MOOD\" },\n        { name: \"BLE TESTER\", id: \"STRESSER\" },\n        { name: \"REMOTE CTRL\", id: \"REMOTE\" },\n        { name: \"BLE KEYBOARD\", id: \"REMOTE\" },\n        { name: \"SGP WIRED\", id: \"TERMINAL\" },\n        { name: \"CAPTIVE PORTAL\", id: \"TERMINAL\" },\n        { name: \"USB MOUSE\", id: \"REMOTE\" },\n        { name: \"USB SCRIPTING\", id: \"BADUSB\" },\n        { name: \"PIN AUDITOR\", id: \"BRUTE\" },\n        { name: \"BEACON TESTER\", id: \"STRESSER\" },\n        { name: \"NET DIAGNOSTIC\", id: \"STRESSER\" },\n        { name: \"WIFI RECON\", id: \"SCANNER\" },\n        { name: \"BLE EMULATOR\", id: \"TERMINAL\" },\n        { name: \"BLE DISTANCE\", id: \"RADAR\" },\n        { name: \"SYSTEM\", id: \"SYS_INFO\" },\n        { name: \"DATA STREAM\", id: \"MATRIX\" },\n        { name: \"SPIRIT LEVEL\", id: \"LEVEL\" },\n        { name: \"GRAVITY PHYS\", id: \"SENSOR\" },\n        { name: \"SPECTRE RADAR\", id: \"RADAR\" },\n        { name: \"MAC SCANNER\", id: \"SCANNER\" },\n        { name: \"PROBE ANALYZER\", id: \"TERMINAL\" },\n        { name: \"NET STRESSER\", id: \"STRESSER\" },\n        { name: \"PACKET MONITOR\", id: \"GRAPH\" },\n        { name: \"ARCADE OPS\", id: \"GAMES\" },\n        { name: \"BLE ULTIMATE\", id: \"STRESSER\" },\n        { name: \"BLE OVERLOAD\", id: \"STRESSER\" },\n        { name: \"BLE SCANNER\", id: \"SCANNER\" },\n        { name: \"SIGNAL DEFENSE\", id: \"GRAPH\" },\n        { name: \"Q-LABS SENSORS\", id: \"SENSOR\" },\n        { name: \"AUDIO FX\", id: \"AUDIO\" },\n        { name: \"CHRONOS\", id: \"CHRONOS\" },\n        { name: \"SYSTEM INFO\", id: \"SYS_INFO\" }\n    ];\n\n    function scrollMenu(direction) {\n        const content = document.querySelector('.os-content');\n        if (content) {\n            content.scrollBy({ top: direction * 45, behavior: 'smooth' });\n        }\n    }\n\n    function clearScreen() {\n        clearInterval(renderInterval);\n        \n        \/\/ Limpiar animaciones y eventos del motor 3D de DOOM\n        if(doomAnim) { cancelAnimationFrame(doomAnim); doomAnim = null; }\n        if(doomEventHandlers.keydown) document.removeEventListener('keydown', doomEventHandlers.keydown);\n        if(doomEventHandlers.keyup) document.removeEventListener('keyup', doomEventHandlers.keyup);\n        \n        if(mouseListener) {\n            document.removeEventListener('mousemove', mouseListener);\n            mouseListener = null;\n        }\n        screen.innerHTML = '';\n        screen.onclick = null;\n        screen.style.background = 'var(--os-bg)'; \/\/ reset background\n    }\n\n    function renderHeader(title) {\n        const header = document.createElement('div');\n        header.className = 'os-header';\n        header.innerHTML = `\u003cspan\u003e${title}\u003c\/span\u003e\u003cspan\u003e100%\u003c\/span\u003e`;\n        screen.appendChild(header);\n    }\n\n    function appMenu() {\n        clearScreen();\n        currentState = 'MENU';\n        renderHeader(\"SGP OS\");\n        \n        const content = document.createElement('div');\n        content.className = 'os-content';\n        \n        appsList.forEach(app =\u003e {\n            const item = document.createElement('div');\n            item.className = 'os-menu-item';\n            item.innerHTML = `\u003cspan\u003e${app.name}\u003c\/span\u003e\u003cspan class=\"os-green\"\u003e\u003e\u003c\/span\u003e`;\n            item.onclick = (e) =\u003e {\n                e.stopPropagation();\n                currentState = app.id;\n                launchApp(app.id, app.name);\n            };\n            content.appendChild(item);\n        });\n\n        screen.appendChild(content);\n    }\n\n    function launchApp(id, title) {\n        if(id === 'SCANNER') appScanner(title);\n        else if(id === 'DOOM') appDoom(title);\n        else if(id === 'BRUTE') appBrute(title);\n        else if(id === 'LEVEL') appLevel(title);\n        else if(id === 'BIO') appBio(title);\n        else if(id === 'MATRIX') appMatrix(title);\n        else if(id === 'RADAR') appRadar(title);\n        else if(id === 'BADUSB') appBadUsb(title);\n        else if(id === 'FACES') appFaces(title);\n        else if(id === 'GAMES') appGames(title);\n        else if(id === 'WIFI_MOTION') appWiFiMotion(title);\n        else if(id === 'ALTIMETER') appAltimeter(title);\n        else if(id === 'MOOD') appMood(title);\n        else if(id === 'STRESSER') appStresser(title);\n        else if(id === 'REMOTE') appRemote(title);\n        else if(id === 'TERMINAL') appTerminal(title);\n        else if(id === 'SYS_INFO') appSysInfo(title);\n        else if(id === 'SENSOR') appSensor(title);\n        else if(id === 'GRAPH') appGraph(title);\n        else if(id === 'AUDIO') appAudio(title);\n        else if(id === 'CHRONOS') appChronos(title);\n    }\n\n    function appDoom(title) {\n        clearScreen();\n        \n        \/\/ Usaremos resolución interna 120x120 escalada para rendimiento puro de renderizado por software\n        const w = 120; \n        const h = 120;\n        const canvas = document.createElement('canvas');\n        canvas.width = w;\n        canvas.height = h;\n        canvas.style.width = '100%';\n        canvas.style.height = '100%';\n        canvas.style.imageRendering = 'pixelated'; \/\/ Estilo retro nítido\n        \n        \/\/ Overlay táctil transparente\n        const touchOverlay = document.createElement('div');\n        touchOverlay.style.position = 'absolute';\n        touchOverlay.style.top = '0'; touchOverlay.style.left = '0';\n        touchOverlay.style.width = '100%'; touchOverlay.style.height = '100%';\n        touchOverlay.style.display = 'flex';\n        touchOverlay.style.zIndex = '30';\n        \n        const btnL = document.createElement('div'); btnL.style.flex = '1';\n        const btnM = document.createElement('div'); btnM.style.flex = '1';\n        const btnR = document.createElement('div'); btnR.style.flex = '1';\n        touchOverlay.appendChild(btnL); touchOverlay.appendChild(btnM); touchOverlay.appendChild(btnR);\n\n        const container = document.createElement('div');\n        container.style.position = 'relative';\n        container.style.width = '100%'; container.style.height = '100%';\n        container.appendChild(canvas);\n        container.appendChild(touchOverlay);\n        screen.appendChild(container);\n\n        const ctx = canvas.getContext('2d', { alpha: false });\n        \/\/ Buffer de píxeles para renderizado estilo DOS\n        const imgData = ctx.createImageData(w, h);\n        const data = imgData.data;\n\n        const texWidth = 32;\n        const texHeight = 32;\n        const textures = [];\n        for(let i=0; i\u003c4; i++) {\n            let tex = [];\n            for(let x=0; x\u003ctexWidth; x++) {\n                for(let y=0; y\u003ctexHeight; y++) {\n                    let r=0, g=0, b=0;\n                    if(i===1) { \/\/ 1: Muro de piedra\n                        let noise = Math.random()*30;\n                        r = 90+noise; g = 90+noise; b = 90+noise;\n                        if(x%16===0 || y%16===0) { r-=40; g-=40; b-=40; } \/\/ Juntas\n                    }\n                    else if(i===2) { \/\/ 2: Panel de Advertencia Rojo\n                        if((x+y)%16 \u003c 8) { r=160; g=20; b=20; } else { r=30; g=30; b=30; }\n                    }\n                    else if(i===3) { \/\/ 3: SGP Mainframe\n                        r=10; g=30; b=10;\n                        if(x%8===0 || y%8===0) { g=100; } \/\/ Rejilla\n                        if(Math.random()\u003c0.03) { r=0; g=255; b=0; } \/\/ Luces parpadeantes LED\n                    }\n                    tex[texWidth * y + x] = {r, g, b};\n                }\n            }\n            textures.push(tex);\n        }\n\n        const worldMap = [\n            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\n            [1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1],\n            [1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1],\n            [1,0,0,3,3,0,1,0,0,2,2,2,2,0,0,1],\n            [1,0,0,3,0,0,0,0,0,2,0,0,2,0,0,1],\n            [1,0,0,0,0,0,0,0,0,2,0,0,2,0,0,1],\n            [1,0,0,0,0,0,0,0,0,2,2,0,2,0,0,1],\n            [1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,1],\n            [1,0,0,0,0,0,1,0,0,3,3,3,3,0,0,1],\n            [1,0,0,0,0,0,1,0,0,3,0,0,3,0,0,1],\n            [1,0,0,2,0,0,1,0,0,3,0,0,0,0,0,1],\n            [1,0,0,2,0,0,1,0,0,3,0,0,0,0,0,1],\n            [1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1],\n            [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]\n        ];\n\n        let posX = 2.5, posY = 2.5; \n        let dirX = 1.0, dirY = 0.0; \n        let planeX = 0.0, planeY = 0.66;\n        let time = 0, oldTime = 0;\n        \n        let isFiring = false;\n        let weaponRecoil = 0;\n        let headBob = 0; \/\/ Animación al caminar\n        let isMoving = false;\n        let faceLooking = 0; \/\/ -1 izq, 0 centro, 1 der\n\n        const keys = { w: false, s: false, left: false, right: false, space: false };\n\n        doomEventHandlers.keydown = (e) =\u003e {\n            if(e.key === 'w' || e.key === 'ArrowUp') keys.w = true;\n            if(e.key === 's' || e.key === 'ArrowDown') keys.s = true;\n            if(e.key === 'a' || e.key === 'ArrowLeft') { keys.left = true; faceLooking = -1; }\n            if(e.key === 'd' || e.key === 'ArrowRight') { keys.right = true; faceLooking = 1; }\n            if(e.key === ' ') { keys.space = true; fireWeapon(); }\n        };\n        doomEventHandlers.keyup = (e) =\u003e {\n            if(e.key === 'w' || e.key === 'ArrowUp') keys.w = false;\n            if(e.key === 's' || e.key === 'ArrowDown') keys.s = false;\n            if(e.key === 'a' || e.key === 'ArrowLeft') { keys.left = false; faceLooking = 0; }\n            if(e.key === 'd' || e.key === 'ArrowRight') { keys.right = false; faceLooking = 0; }\n            if(e.key === ' ') keys.space = false;\n        };\n        document.addEventListener('keydown', doomEventHandlers.keydown);\n        document.addEventListener('keyup', doomEventHandlers.keyup);\n\n        btnL.ontouchstart = btnL.onmousedown = (e) =\u003e { e.preventDefault(); keys.left = true; faceLooking = -1; };\n        btnL.ontouchend = btnL.onmouseup = btnL.onmouseleave = () =\u003e { keys.left = false; faceLooking = 0; };\n        btnR.ontouchstart = btnR.onmousedown = (e) =\u003e { e.preventDefault(); keys.right = true; faceLooking = 1; };\n        btnR.ontouchend = btnR.onmouseup = btnR.onmouseleave = () =\u003e { keys.right = false; faceLooking = 0; };\n        btnM.ontouchstart = btnM.onmousedown = (e) =\u003e { e.preventDefault(); keys.w = true; };\n        btnM.ontouchend = btnM.onmouseup = btnM.onmouseleave = () =\u003e { keys.w = false; };\n        btnM.ondblclick = (e) =\u003e { e.preventDefault(); fireWeapon(); };\n\n        function fireWeapon() {\n            if(!isFiring) {\n                isFiring = true;\n                weaponRecoil = 12;\n                playBeep();\n                setTimeout(() =\u003e isFiring = false, 150);\n            }\n        }\n\n        function gameLoop(timestamp) {\n            oldTime = time;\n            time = timestamp;\n            let frameTime = (time - oldTime) \/ 1000.0; \n            if(frameTime \u003e 0.1) frameTime = 0.1;\n            \n            let moveSpeed = frameTime * 3.0; \n            let rotSpeed = frameTime * 2.0;\n\n            isMoving = false;\n            \/\/ Movimiento\n            if (keys.w) {\n                if(worldMap[Math.floor(posX + dirX * moveSpeed)][Math.floor(posY)] === 0) posX += dirX * moveSpeed;\n                if(worldMap[Math.floor(posX)][Math.floor(posY + dirY * moveSpeed)] === 0) posY += dirY * moveSpeed;\n                isMoving = true;\n            }\n            if (keys.s) {\n                if(worldMap[Math.floor(posX - dirX * moveSpeed)][Math.floor(posY)] === 0) posX -= dirX * moveSpeed;\n                if(worldMap[Math.floor(posX)][Math.floor(posY - dirY * moveSpeed)] === 0) posY -= dirY * moveSpeed;\n                isMoving = true;\n            }\n            if (keys.right) {\n                let oldDirX = dirX; dirX = dirX * Math.cos(-rotSpeed) - dirY * Math.sin(-rotSpeed); dirY = oldDirX * Math.sin(-rotSpeed) + dirY * Math.cos(-rotSpeed);\n                let oldPlaneX = planeX; planeX = planeX * Math.cos(-rotSpeed) - planeY * Math.sin(-rotSpeed); planeY = oldPlaneX * Math.sin(-rotSpeed) + planeY * Math.cos(-rotSpeed);\n            }\n            if (keys.left) {\n                let oldDirX = dirX; dirX = dirX * Math.cos(rotSpeed) - dirY * Math.sin(rotSpeed); dirY = oldDirX * Math.sin(rotSpeed) + dirY * Math.cos(rotSpeed);\n                let oldPlaneX = planeX; planeX = planeX * Math.cos(rotSpeed) - planeY * Math.sin(rotSpeed); planeY = oldPlaneX * Math.sin(rotSpeed) + planeY * Math.cos(rotSpeed);\n            }\n\n            \/\/ Actualizar Head Bobbing\n            if (isMoving) headBob += frameTime * 15;\n            else headBob = 0;\n            let pitch = Math.sin(headBob) * 8; \/\/ Sube y baja la cámara\n            let flicker = Math.random() * 0.1; \/\/ Parpadeo de luces\n\n            \/\/ Limpiar Buffer (Cielo y Suelo)\n            for(let i=0; i\u003cw*h; i++) {\n                let y = Math.floor(i \/ w);\n                let r,g,b;\n                if (y \u003c h\/2 + pitch) { r = 40; g = 40; b = 40; } \/\/ Techo gris oscuro\n                else { r = 80 - (y-h\/2); g = 30; b = 30; } \/\/ Suelo degradado rojo oscuro\n                \n                data[i*4] = r; data[i*4+1] = g; data[i*4+2] = b; data[i*4+3] = 255;\n            }\n\n            for (let x = 0; x \u003c w; x++) {\n                let cameraX = 2 * x \/ w - 1; \n                let rayDirX = dirX + planeX * cameraX;\n                let rayDirY = dirY + planeY * cameraX;\n\n                let mapX = Math.floor(posX);\n                let mapY = Math.floor(posY);\n\n                let sideDistX, sideDistY;\n                let deltaDistX = Math.abs(1 \/ rayDirX);\n                let deltaDistY = Math.abs(1 \/ rayDirY);\n                let perpWallDist;\n\n                let stepX, stepY;\n                let hit = 0, side = 0;\n\n                if (rayDirX \u003c 0) { stepX = -1; sideDistX = (posX - mapX) * deltaDistX; } \n                else { stepX = 1; sideDistX = (mapX + 1.0 - posX) * deltaDistX; }\n                if (rayDirY \u003c 0) { stepY = -1; sideDistY = (posY - mapY) * deltaDistY; } \n                else { stepY = 1; sideDistY = (mapY + 1.0 - posY) * deltaDistY; }\n\n                while (hit === 0) {\n                    if (sideDistX \u003c sideDistY) { sideDistX += deltaDistX; mapX += stepX; side = 0; } \n                    else { sideDistY += deltaDistY; mapY += stepY; side = 1; }\n                    if (worldMap[mapX][mapY] \u003e 0) hit = 1;\n                }\n\n                if (side === 0) perpWallDist = (sideDistX - deltaDistX);\n                else perpWallDist = (sideDistY - deltaDistY);\n\n                let lineHeight = Math.floor(h \/ perpWallDist);\n                let drawStart = Math.floor(-lineHeight \/ 2 + h \/ 2 + pitch);\n                if (drawStart \u003c 0) drawStart = 0;\n                let drawEnd = Math.floor(lineHeight \/ 2 + h \/ 2 + pitch);\n                if (drawEnd \u003e= h) drawEnd = h - 1;\n\n                \/\/ Calcular posición exacta de la textura (UV Mapping)\n                let texNum = worldMap[mapX][mapY];\n                let wallX;\n                if (side === 0) wallX = posY + perpWallDist * rayDirY;\n                else wallX = posX + perpWallDist * rayDirX;\n                wallX -= Math.floor(wallX);\n\n                let texX = Math.floor(wallX * texWidth);\n                if(side === 0 \u0026\u0026 rayDirX \u003e 0) texX = texWidth - texX - 1;\n                if(side === 1 \u0026\u0026 rayDirY \u003c 0) texX = texWidth - texX - 1;\n\n                let step = 1.0 * texHeight \/ lineHeight;\n                let texPos = (drawStart - pitch - h \/ 2 + lineHeight \/ 2) * step;\n\n                \/\/ Dinamic Fog\n                let fog = Math.min(1.0, (perpWallDist \/ 9.0) + flicker);\n\n                for (let y = drawStart; y \u003c drawEnd; y++) {\n                    let texY = Math.floor(texPos) \u0026 (texHeight - 1);\n                    texPos += step;\n                    \n                    let color = textures[texNum][texWidth * texY + texX];\n                    let finalR = color.r, finalG = color.g, finalB = color.b;\n\n                    \/\/ Oscurecer paredes E\/O\n                    if(side === 1) { finalR\/=1.5; finalG\/=1.5; finalB\/=1.5; }\n                    \n                    \/\/ Aplicar niebla\n                    finalR = Math.floor(finalR * (1 - fog));\n                    finalG = Math.floor(finalG * (1 - fog));\n                    finalB = Math.floor(finalB * (1 - fog));\n\n                    let pixelIdx = (y * w + x) * 4;\n                    data[pixelIdx] = finalR;\n                    data[pixelIdx+1] = finalG;\n                    data[pixelIdx+2] = finalB;\n                }\n            }\n\n            \/\/ Volcar buffer al canvas\n            ctx.putImageData(imgData, 0, 0);\n\n            \/\/ 1. Interfaz HUD (Caja inferior gris)\n            ctx.fillStyle = \"#444\";\n            ctx.fillRect(0, h - 20, w, 20);\n            ctx.fillStyle = \"#222\";\n            ctx.fillRect(1, h - 19, w - 2, 18);\n            \n            \/\/ Texto HUD\n            ctx.fillStyle = \"#a00\";\n            ctx.font = \"8px 'Share Tech Mono'\";\n            ctx.fillText(\"AMMO\", 5, h - 5);\n            ctx.fillStyle = \"#fff\";\n            ctx.fillText(\"50\", 25, h - 5);\n            \n            ctx.fillStyle = \"#a00\";\n            ctx.fillText(\"HP\", w - 30, h - 5);\n            ctx.fillStyle = \"#fff\";\n            ctx.fillText(\"100%\", w - 18, h - 5);\n\n            \/\/ Carita del Doomguy\n            let faceX = w\/2 - 7;\n            let faceY = h - 17;\n            ctx.fillStyle = \"#e5c298\"; \/\/ Piel\n            ctx.fillRect(faceX, faceY, 14, 14);\n            ctx.fillStyle = \"#000\"; \/\/ Ojos\n            ctx.fillRect(faceX + 3 + (faceLooking*2), faceY + 4, 2, 2);\n            ctx.fillRect(faceX + 9 + (faceLooking*2), faceY + 4, 2, 2);\n            ctx.fillRect(faceX + 4, faceY + 10, 6, 2); \/\/ Boca recta (concentrado)\n\n            \/\/ 2. Arma Escopeta Detallada\n            let weaponX = w \/ 2 - 8;\n            let weaponY = h - 20 - 40 + weaponRecoil + pitch;\n            \n            \/\/ Cañones\n            ctx.fillStyle = \"#333\";\n            ctx.fillRect(weaponX, weaponY, 7, 45); \/\/ Cañón izq\n            ctx.fillRect(weaponX + 9, weaponY, 7, 45); \/\/ Cañón der\n            \/\/ Reflejos metálicos\n            ctx.fillStyle = \"#666\";\n            ctx.fillRect(weaponX + 1, weaponY, 2, 45); \n            ctx.fillRect(weaponX + 10, weaponY, 2, 45);\n            \/\/ Agarre madera oscura\n            ctx.fillStyle = \"#311\";\n            ctx.fillRect(weaponX - 2, weaponY + 30, 20, 15);\n\n            \/\/ Destello de Fuego\n            if(isFiring) {\n                \/\/ Luz de ambiente naranja en paredes\n                ctx.fillStyle = \"rgba(255, 100, 0, 0.2)\";\n                ctx.fillRect(0,0,w,h);\n                \n                \/\/ Sprite de fuego retro\n                ctx.fillStyle = \"yellow\";\n                ctx.beginPath(); ctx.arc(w\/2, weaponY - 5, 12, 0, Math.PI*2); ctx.fill();\n                ctx.fillStyle = \"orange\";\n                ctx.beginPath(); ctx.arc(w\/2 + 5, weaponY - 10, 8, 0, Math.PI*2); ctx.fill();\n                ctx.beginPath(); ctx.arc(w\/2 - 5, weaponY - 10, 8, 0, Math.PI*2); ctx.fill();\n                ctx.fillStyle = \"white\";\n                ctx.beginPath(); ctx.arc(w\/2, weaponY - 5, 5, 0, Math.PI*2); ctx.fill();\n            }\n\n            if(weaponRecoil \u003e 0) weaponRecoil -= 2;\n\n            doomAnim = requestAnimationFrame(gameLoop);\n        }\n\n        doomAnim = requestAnimationFrame(gameLoop);\n    }\n\n    function appScanner(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        \n        const networks = [\n            { ssid: \"CORP_5G\", mac: \"A1:B2:C3:D4:E5\", rssi: -45 },\n            { ssid: \"GUEST_WIFI\", mac: \"F1:E2:D3:C4:B5\", rssi: -65 },\n            { ssid: \"IOT_HUB\", mac: \"11:22:33:44:55\", rssi: -70 },\n            { ssid: \"PRINTER_NET\", mac: \"99:88:77:66:55\", rssi: -85 },\n            { ssid: \"HIDDEN_AP\", mac: \"AA:BB:CC:DD:EE\", rssi: -90 }\n        ];\n\n        let html = '';\n        networks.forEach(n =\u003e {\n            let color = n.rssi \u003e -60 ? 'var(--os-green)' : (n.rssi \u003e -80 ? 'var(--os-text)' : 'var(--os-red)');\n            html += `\n                \u003cdiv class=\"scan-item\"\u003e\n                    \u003cdiv style=\"display:flex; justify-content:space-between;\"\u003e\n                        \u003cspan class=\"os-text\"\u003e${n.ssid}\u003c\/span\u003e\n                        \u003cspan style=\"color:${color}\"\u003e${n.rssi} dBm\u003c\/span\u003e\n                    \u003c\/div\u003e\n                    \u003cdiv class=\"os-green\" style=\"font-size:10px; margin-top:4px;\"\u003eMAC: ${n.mac}\u003c\/div\u003e\n                \u003c\/div\u003e\n            `;\n        });\n        \n        content.innerHTML = html;\n        screen.appendChild(content);\n    }\n\n    function appBrute(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.textAlign = 'center';\n        content.innerHTML = `\n            \u003cdiv class=\"os-red\" style=\"font-size:10px; margin-top:10px; animation: blink 1s infinite;\"\u003eTESTING PIN...\u003c\/div\u003e\n            \u003cdiv id=\"brute-pin\" class=\"os-green\" style=\"font-size:40px; margin:20px 0;\"\u003e0000\u003c\/div\u003e\n            \u003cdiv style=\"width:100%; height:10px; border:1px solid var(--os-dim); margin-bottom:10px;\"\u003e\n                \u003cdiv id=\"brute-bar\" style=\"height:100%; width:0%; background:var(--os-green);\"\u003e\u003c\/div\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:12px;\"\u003ePINS: \u003cspan id=\"brute-count\"\u003e0\u003c\/span\u003e\/9999\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n\n        let pin = 0;\n        const pinEl = document.getElementById('brute-pin');\n        const barEl = document.getElementById('brute-bar');\n        const countEl = document.getElementById('brute-count');\n\n        renderInterval = setInterval(() =\u003e {\n            pin += 17; \/\/ Simulate speed\n            if(pin \u003e 9999) pin = 9999;\n            \n            pinEl.innerText = pin.toString().padStart(4, '0');\n            barEl.style.width = (pin \/ 9999 * 100) + '%';\n            countEl.innerText = pin;\n\n            if(pin === 9999) {\n                clearInterval(renderInterval);\n                document.querySelector('.os-red').innerText = \"AUDIT COMPLETE\";\n                document.querySelector('.os-red').style.color = \"var(--os-green)\";\n                document.querySelector('.os-red').style.animation = \"none\";\n            }\n        }, 50);\n    }\n\n    function appLevel(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.position = 'relative';\n        content.style.height = '240px';\n        content.innerHTML = `\n            \u003cdiv style=\"position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); width:120px; height:120px; border-radius:50%; border:2px solid var(--os-dim);\"\u003e\u003c\/div\u003e\n            \u003cdiv style=\"position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); width:60px; height:60px; border-radius:50%; border:2px solid var(--os-green);\"\u003e\u003c\/div\u003e\n            \u003cdiv style=\"position:absolute; top:50%; left:0; width:100%; height:1px; background:var(--os-dim);\"\u003e\u003c\/div\u003e\n            \u003cdiv style=\"position:absolute; top:0; left:50%; width:1px; height:100%; background:var(--os-dim);\"\u003e\u003c\/div\u003e\n            \u003cdiv id=\"level-bubble\" style=\"position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); width:20px; height:20px; border-radius:50%; background:var(--os-green); transition: all 0.1s;\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"position:absolute; bottom:0; width:100%; text-align:center; font-size:10px;\"\u003eMove cursor over screen\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n\n        const bubble = document.getElementById('level-bubble');\n        \n        mouseListener = (e) =\u003e {\n            const rect = screen.getBoundingClientRect();\n            let x = e.clientX - rect.left;\n            let y = e.clientY - rect.top - 28;\n            \n            x = Math.max(40, Math.min(x, 200));\n            y = Math.max(40, Math.min(y, 200));\n\n            if(Math.abs(x - 120) \u003c 10 \u0026\u0026 Math.abs(y - 120) \u003c 10) {\n                bubble.style.background = 'var(--os-green)';\n            } else {\n                bubble.style.background = 'var(--os-red)';\n            }\n\n            bubble.style.left = x + 'px';\n            bubble.style.top = y + 'px';\n        };\n        \n        document.addEventListener('mousemove', mouseListener);\n    }\n\n    function appBio(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv style=\"border:1px solid var(--os-red); padding:10px; text-align:center; margin-bottom:20px;\"\u003e\n                \u003cdiv class=\"os-red\" style=\"font-size:18px; font-weight:bold; animation: blink 1s infinite;\"\u003eTOXICITY ALERT\u003c\/div\u003e\n            \u003c\/div\u003e\n            \u003cdiv style=\"display:flex; justify-content:space-between; font-size:12px; margin-bottom:10px;\"\u003e\n                \u003cspan class=\"os-text\"\u003eTEMP: 24.5C\u003c\/span\u003e\n                \u003cspan class=\"os-text\"\u003eHUM: 45%\u003c\/span\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:12px; margin-bottom:5px;\"\u003eVOC RESISTANCE:\u003c\/div\u003e\n            \u003cdiv class=\"os-red\" style=\"font-size:24px; font-weight:bold; margin-bottom:20px;\"\u003e18.4 KOhm\u003c\/div\u003e\n            \u003cdiv style=\"display:flex; justify-content:space-between; font-size:12px;\"\u003e\n                \u003cspan class=\"os-dim\"\u003ePARTICLE SCAN:\u003c\/span\u003e\n                \u003cspan class=\"os-red\"\u003eDETECTED\u003c\/span\u003e\n            \u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appMatrix(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.overflow = 'hidden';\n        content.innerHTML = `\u003cdiv id=\"matrix-rain\" style=\"color:var(--os-green); font-size:14px; line-height:12px; word-break:break-all; font-family:monospace;\"\u003e\u003c\/div\u003e`;\n        screen.appendChild(content);\n        \n        const m = document.getElementById('matrix-rain');\n        const chars = \"0101100101ABCF1000101\";\n        renderInterval = setInterval(() =\u003e {\n            let rain = \"\";\n            for(let i=0; i\u003c300; i++) rain += chars.charAt(Math.floor(Math.random() * chars.length));\n            m.innerText = rain;\n        }, 100);\n    }\n\n    function appRadar(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv style=\"width:160px; height:160px; border:2px solid var(--os-dim); border-radius:50%; margin:20px auto; position:relative; overflow:hidden;\"\u003e\n                \u003cdiv style=\"position:absolute; width:100%; height:1px; background:var(--os-dim); top:50%;\"\u003e\u003c\/div\u003e\n                \u003cdiv style=\"position:absolute; width:1px; height:100%; background:var(--os-dim); left:50%;\"\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:80px; height:80px; border-right:2px solid var(--os-green); position:absolute; bottom:50%; left:0; transform-origin:bottom right; animation: scanSweep 2s linear infinite; background: linear-gradient(to right, rgba(0,255,0,0) 0%, rgba(0,255,0,0.4) 100%);\"\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:6px; height:6px; background:var(--os-red); border-radius:50%; position:absolute; top:40px; left:50px; box-shadow: 0 0 5px var(--os-red);\"\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:6px; height:6px; background:var(--os-green); border-radius:50%; position:absolute; bottom:50px; right:40px; box-shadow: 0 0 5px var(--os-green);\"\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:4px; height:4px; background:var(--os-text); border-radius:50%; position:absolute; top:90px; left:120px;\"\u003e\u003c\/div\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-green\" style=\"text-align:center; font-size:12px; margin-top:20px; animation: blink 1.5s infinite;\"\u003eSCANNING FREQUENCIES...\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appBadUsb(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv class=\"os-menu-item\"\u003e\u003e SGP INJECT\u003c\/div\u003e\n            \u003cdiv class=\"os-menu-item\"\u003e\u003e POWERSHELL\u003c\/div\u003e\n            \u003cdiv class=\"os-menu-item\"\u003e\u003e NOTEPAD LOG\u003c\/div\u003e\n            \u003cdiv class=\"os-menu-item\" style=\"border-color:var(--os-red); color:var(--os-red);\"\u003e\u003e SGP PAYLOAD\u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:10px; text-align:center; margin-top:20px;\"\u003e[ PLUG INTO TARGET USB ]\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appFaces(title) {\n        clearScreen();\n        const content = document.createElement('div');\n        content.style.height = '100%';\n        content.style.display = 'flex';\n        content.style.flexDirection = 'column';\n        content.style.justifyContent = 'center';\n        content.style.alignItems = 'center';\n        content.style.background = '#000';\n        \n        const now = new Date();\n        const timeStr = now.getHours().toString().padStart(2, '0') + \":\" + now.getMinutes().toString().padStart(2, '0');\n        \n        content.innerHTML = `\n            \u003cdiv style=\"font-size:50px; font-weight:bold; color:#fff; font-family:'Inter', sans-serif;\"\u003e${timeStr}\u003c\/div\u003e\n            \u003cdiv style=\"font-size:14px; color:#aaa; font-family:'Inter', sans-serif; margin-bottom: 20px;\"\u003e22°C SUNNY\u003c\/div\u003e\n            \n            \u003cdiv style=\"position:relative; width:120px; height:120px;\"\u003e\n                \u003csvg width=\"120\" height=\"120\" viewBox=\"0 0 120 120\"\u003e\n                    \u003ccircle cx=\"60\" cy=\"60\" r=\"50\" fill=\"none\" stroke=\"#310\" stroke-width=\"10\"\/\u003e\n                    \u003ccircle cx=\"60\" cy=\"60\" r=\"50\" fill=\"none\" stroke=\"#f03\" stroke-width=\"10\" stroke-dasharray=\"314\" stroke-dashoffset=\"60\" stroke-linecap=\"round\" transform=\"rotate(-90 60 60)\"\/\u003e\n                    \n                    \u003ccircle cx=\"60\" cy=\"60\" r=\"38\" fill=\"none\" stroke=\"#130\" stroke-width=\"10\"\/\u003e\n                    \u003ccircle cx=\"60\" cy=\"60\" r=\"38\" fill=\"none\" stroke=\"#0f0\" stroke-width=\"10\" stroke-dasharray=\"238\" stroke-dashoffset=\"100\" stroke-linecap=\"round\" transform=\"rotate(-90 60 60)\"\/\u003e\n                    \n                    \u003ccircle cx=\"60\" cy=\"60\" r=\"26\" fill=\"none\" stroke=\"#013\" stroke-width=\"10\"\/\u003e\n                    \u003ccircle cx=\"60\" cy=\"60\" r=\"26\" fill=\"none\" stroke=\"#0df\" stroke-width=\"10\" stroke-dasharray=\"163\" stroke-dashoffset=\"80\" stroke-linecap=\"round\" transform=\"rotate(-90 60 60)\"\/\u003e\n                \u003c\/svg\u003e\n            \u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n    \n    function appGames(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv class=\"os-menu-item\"\u003eFLAPPY DRONE\u003c\/div\u003e\n            \u003cdiv class=\"os-menu-item\"\u003ePONG\u003c\/div\u003e\n            \u003cdiv class=\"os-menu-item\"\u003eSNAKE\u003c\/div\u003e\n            \u003cdiv class=\"os-menu-item\"\u003eSPACE INVADERS\u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:10px; text-align:center; margin-top:20px;\"\u003eHardware buttons to play\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appWiFiMotion(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv class=\"os-green\" style=\"text-align:center; margin-top:10px;\"\u003eTARGET: CORP_5G\u003c\/div\u003e\n            \u003cdiv style=\"height:80px; border:1px solid var(--os-dim); margin:20px 0; position:relative; overflow:hidden;\"\u003e\n                \u003csvg width=\"200%\" height=\"100%\" style=\"position:absolute; left:0; bottom:0;\"\u003e\n                    \u003cpath id=\"wave\" d=\"M0 40 Q 20 20, 40 40 T 80 40 T 120 40 T 160 40 T 200 40\" fill=\"none\" stroke=\"var(--os-green)\" stroke-width=\"2\"\/\u003e\n                \u003c\/svg\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"text-align:center; font-size:16px;\"\u003eSTATUS: \u003cspan class=\"os-green\"\u003eSTABLE\u003c\/span\u003e\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n        \n        let offset = 0;\n        const wave = document.getElementById('wave');\n        renderInterval = setInterval(() =\u003e {\n            offset -= 5;\n            let d = `M${offset} 40 `;\n            for(let i=0; i\u003c10; i++) {\n                let amp = Math.random() \u003e 0.8 ? Math.random() * 30 : 5; \/\/ Occasional spike\n                d += `Q ${offset + i*40 + 20} ${40 - amp}, ${offset + (i+1)*40} 40 `;\n            }\n            wave.setAttribute('d', d);\n            if(offset \u003c -80) offset = 0;\n        }, 100);\n    }\n\n    function appAltimeter(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.textAlign = 'center';\n        content.innerHTML = `\n            \u003cdiv class=\"os-dim\" style=\"font-size:12px; margin-top:30px;\"\u003eCURRENT ALTITUDE\u003c\/div\u003e\n            \u003cdiv class=\"os-green\" style=\"font-size:42px; font-weight:bold; margin:10px 0;\"\u003e642 m\u003c\/div\u003e\n            \u003cdiv class=\"os-text\" style=\"font-size:14px;\"\u003ePRESSURE: 1013.25 hPa\u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:10px; margin-top:30px;\"\u003eCalibrated to QNH\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appMood(title) {\n        clearScreen();\n        screen.style.animation = 'colorCycle 5s infinite';\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.display = 'flex';\n        content.style.justifyContent = 'center';\n        content.style.alignItems = 'center';\n        content.innerHTML = `\u003cdiv style=\"background:rgba(0,0,0,0.5); padding:10px; border-radius:10px; color:#fff; font-size:12px;\"\u003eMOOD ACTIVE\u003c\/div\u003e`;\n        screen.appendChild(content);\n    }\n\n    function appStresser(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv class=\"os-red\" style=\"text-align:center; font-size:18px; margin:20px 0; animation:blink 0.5s infinite;\"\u003eINJECTING PACKETS\u003c\/div\u003e\n            \u003cdiv style=\"border:1px solid var(--os-dim); height:15px; margin-bottom:10px;\"\u003e\n                \u003cdiv id=\"stresser-bar\" style=\"height:100%; width:0%; background:var(--os-red);\"\u003e\u003c\/div\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-text\" style=\"font-size:12px;\"\u003eTX RATE: \u003cspan id=\"tx-rate\" class=\"os-green\"\u003e0\u003c\/span\u003e pkt\/s\u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:10px; margin-top:10px;\"\u003eTarget: 11:22:33:44:55:66\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n        \n        let width = 0;\n        renderInterval = setInterval(() =\u003e {\n            width = (width + 5) % 100;\n            document.getElementById('stresser-bar').style.width = width + '%';\n            document.getElementById('tx-rate').innerText = Math.floor(Math.random() * 500 + 1000);\n        }, 100);\n    }\n\n    function appRemote(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv style=\"display:grid; grid-template-columns: 1fr 1fr 1fr; gap:5px; width:120px; margin:30px auto;\"\u003e\n                \u003cdiv\u003e\u003c\/div\u003e\u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eW\u003c\/div\u003e\u003cdiv\u003e\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eA\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eS\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eD\u003c\/div\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"text-align:center; font-size:10px;\"\u003eLINKED TO HOST PC\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appTerminal(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.fontSize = '10px';\n        content.innerHTML = `\u003cdiv id=\"term-out\"\u003e\u003c\/div\u003e`;\n        screen.appendChild(content);\n        \n        const logs = [\n            \"Initializing interface...\", \"Handshake OK.\", \"Fetching device descriptor...\",\n            \"Tx Pwr: +20dBm\", \"Promiscuous mode enabled.\", \"Listening on CH 6...\",\n            \"Captured 14 probes.\", \"Buffer flush complete.\", \"Awaiting instructions...\"\n        ];\n        let idx = 0;\n        const out = document.getElementById('term-out');\n        renderInterval = setInterval(() =\u003e {\n            if(idx \u003c logs.length) {\n                out.innerHTML += `\u003cdiv\u003e\u003e ${logs[idx]}\u003c\/div\u003e`;\n                idx++;\n            } else {\n                out.innerHTML += `\u003cdiv\u003e\u003cspan class=\"os-green\"\u003e_\u003c\/span\u003e\u003c\/div\u003e`;\n                clearInterval(renderInterval);\n            }\n        }, 400);\n    }\n\n    function appSysInfo(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv class=\"os-text\" style=\"font-size:12px; margin-bottom:5px;\"\u003eFW: SGP OS v2.0-PRO\u003c\/div\u003e\n            \u003cdiv class=\"os-text\" style=\"font-size:12px; margin-bottom:5px;\"\u003eCPU: Xtensa LX7 @ 240MHz\u003c\/div\u003e\n            \u003cdiv class=\"os-text\" style=\"font-size:12px; margin-bottom:5px;\"\u003eRAM: 8MB PSRAM\u003c\/div\u003e\n            \u003cdiv class=\"os-green\" style=\"font-size:12px; margin-bottom:15px;\"\u003eBATTERY: 98% (Discharging)\u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"font-size:10px;\"\u003eMAC: AA:BB:CC:DD:EE:FF\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appSensor(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv style=\"margin-top:20px;\"\u003e\n                \u003cdiv class=\"os-dim\" style=\"font-size:12px;\"\u003eX-AXIS: \u003cspan id=\"s-x\" class=\"os-text\"\u003e0.00\u003c\/span\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:100%; height:4px; background:var(--os-dim); margin-bottom:10px;\"\u003e\u003cdiv id=\"b-x\" style=\"height:100%; background:var(--os-green); width:50%;\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n                \n                \u003cdiv class=\"os-dim\" style=\"font-size:12px;\"\u003eY-AXIS: \u003cspan id=\"s-y\" class=\"os-text\"\u003e0.00\u003c\/span\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:100%; height:4px; background:var(--os-dim); margin-bottom:10px;\"\u003e\u003cdiv id=\"b-y\" style=\"height:100%; background:var(--os-green); width:50%;\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n                \n                \u003cdiv class=\"os-dim\" style=\"font-size:12px;\"\u003eZ-AXIS: \u003cspan id=\"s-z\" class=\"os-text\"\u003e1.00\u003c\/span\u003e\u003c\/div\u003e\n                \u003cdiv style=\"width:100%; height:4px; background:var(--os-dim); margin-bottom:10px;\"\u003e\u003cdiv id=\"b-z\" style=\"height:100%; background:var(--os-green); width:100%;\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n            \u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n        \n        renderInterval = setInterval(() =\u003e {\n            let x = (Math.random() - 0.5) * 0.2;\n            let y = (Math.random() - 0.5) * 0.2;\n            document.getElementById('s-x').innerText = x.toFixed(2);\n            document.getElementById('s-y').innerText = y.toFixed(2);\n            document.getElementById('b-x').style.width = (50 + x*100) + '%';\n            document.getElementById('b-y').style.width = (50 + y*100) + '%';\n        }, 200);\n    }\n\n    function appGraph(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.display = 'flex';\n        content.style.alignItems = 'flex-end';\n        content.style.gap = '5px';\n        content.style.paddingTop = '40px';\n        content.innerHTML = `\n            \u003cdiv class=\"bar\" style=\"width:30px; background:var(--os-dim); transition:height 0.2s;\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"bar\" style=\"width:30px; background:var(--os-green); transition:height 0.2s;\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"bar\" style=\"width:30px; background:var(--os-text); transition:height 0.2s;\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"bar\" style=\"width:30px; background:var(--os-green); transition:height 0.2s;\"\u003e\u003c\/div\u003e\n            \u003cdiv class=\"bar\" style=\"width:30px; background:var(--os-dim); transition:height 0.2s;\"\u003e\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n        \n        const bars = content.querySelectorAll('.bar');\n        renderInterval = setInterval(() =\u003e {\n            bars.forEach(b =\u003e b.style.height = (Math.random() * 100 + 20) + 'px');\n        }, 300);\n    }\n\n    function appAudio(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.innerHTML = `\n            \u003cdiv style=\"display:grid; grid-template-columns: 1fr 1fr; gap:10px; margin-top:20px;\"\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center; color:var(--os-red); border-color:var(--os-red);\"\u003eSIREN\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eR2D2\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eBOMB\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"justify-content:center;\"\u003eUFO\u003c\/div\u003e\n            \u003c\/div\u003e\n            \u003cdiv class=\"os-dim\" style=\"text-align:center; font-size:10px; margin-top:10px;\"\u003eBUZZER READY\u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n    }\n\n    function appChronos(title) {\n        clearScreen();\n        renderHeader(title.substring(0,14));\n        const content = document.createElement('div');\n        content.className = 'os-content';\n        content.style.textAlign = 'center';\n        content.innerHTML = `\n            \u003cdiv class=\"os-dim\" style=\"font-size:12px; margin-top:30px;\"\u003eTACTICAL TIMER\u003c\/div\u003e\n            \u003cdiv id=\"chrono-time\" class=\"os-green\" style=\"font-size:40px; font-weight:bold; margin:10px 0;\"\u003e00:00:00\u003c\/div\u003e\n            \u003cdiv style=\"display:flex; justify-content:center; gap:10px; margin-top:20px;\"\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"padding:5px 15px;\"\u003eSTART\u003c\/div\u003e\n                \u003cdiv class=\"os-menu-item\" style=\"padding:5px 15px; border-color:var(--os-red); color:var(--os-red);\"\u003eSTOP\u003c\/div\u003e\n            \u003c\/div\u003e\n        `;\n        screen.appendChild(content);\n        \n        let secs = 0;\n        renderInterval = setInterval(() =\u003e {\n            secs++;\n            let h = Math.floor(secs \/ 3600).toString().padStart(2, '0');\n            let m = Math.floor((secs % 3600) \/ 60).toString().padStart(2, '0');\n            let s = (secs % 60).toString().padStart(2, '0');\n            document.getElementById('chrono-time').innerText = `${h}:${m}:${s}`;\n        }, 1000);\n    }\n\n    \/\/ Initialize Menu on Load\n    window.onload = function() {\n        appMenu();\n        \n        \/\/ Añadir el sonido a cualquier interacción (clic) dentro de la carcasa del reloj\n        document.querySelector('.watch-case').addEventListener('mousedown', playBeep);\n        document.querySelector('.watch-case').addEventListener('touchstart', playBeep, {passive: true});\n    };\n\n\u003c\/script\u003e\n\n\u003c\/body\u003e","brand":"sgpstore","offers":[{"title":"Orange","offer_id":57534131011916,"sku":null,"price":149.0,"currency_code":"EUR","in_stock":true},{"title":"Black","offer_id":57534131044684,"sku":null,"price":149.0,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1057\/9807\/4700\/files\/rn-image_picker_lib_temp_465450ff-354f-4947-b2ec-9a0e5dc61fbb.png?v=1778713734","url":"https:\/\/sgpstore.net\/products\/sgp-watch","provider":"sgpstore","version":"1.0","type":"link"}