{"id":3258,"date":"2026-02-11T16:00:12","date_gmt":"2026-02-11T15:00:12","guid":{"rendered":"https:\/\/www.papaya.events\/?page_id=3258"},"modified":"2026-02-13T05:11:30","modified_gmt":"2026-02-13T04:11:30","slug":"m-13b","status":"publish","type":"page","link":"https:\/\/www.papaya.events\/hr\/m-13b\/","title":{"rendered":"M-13b"},"content":{"rendered":"<div class=\"wpb-content-wrapper\"><div class=\"vc_row wpb_row vc_row-fluid\"><div class=\"wpb_column vc_column_container vc_col-sm-12 sc_layouts_column_icons_position_left\"><div class=\"vc_column-inner\"><div class=\"wpb_wrapper\">\n\t<div class=\"wpb_raw_code wpb_raw_html wpb_content_element\" >\n\t\t<div class=\"wpb_wrapper\">\n\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\r\n<title>Sonic Lab V25 - Mobile Fixed<\/title>\r\n<style>\r\n    \/* U\u010cITAVANJE FONTOVA *\/\r\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Orbitron:wght@400..900&display=swap');\r\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Rajdhani:wght@500;600;700&display=swap');\r\n\r\n    \/* --- SCOPED THEME & WP RESET --- *\/\r\n    #sonic-lab-v25 {\r\n        \/* Lokalne varijable *\/\r\n        --metal-base: #1e293b;\r\n        --neon-blue: #38bdf8;\r\n        --neon-red: #ef4444;\r\n        --screen-bg: #38bdf8;    \r\n        --screen-ink: #0f172a;\r\n        --glass-bg: rgba(2, 6, 23, 0.6); \r\n\r\n        all: initial; \r\n        display: block;\r\n        \/* GLOBALNO SPRJE\u010cAVANJE POVE\u0106ANJA EKRANA NA DOUBLE TAP *\/\r\n        touch-action: manipulation; \r\n        \r\n        background-color: var(--metal-base) !important;\r\n        background-image: \r\n            repeating-linear-gradient(90deg, transparent 0, transparent 1px, rgba(255,255,255,0.03) 1px, rgba(255,255,255,0.03) 2px),\r\n            linear-gradient(180deg, #334155 0%, #0f172a 100%) !important;\r\n        color: #94a3b8 !important;\r\n        font-family: 'Rajdhani', system-ui, -apple-system, sans-serif !important;\r\n        padding: 35px 10px 45px 10px;\r\n        border-radius: 16px !important;\r\n        max-width: 1050px !important; \r\n        margin: 0px auto !important;\r\n        border: 2px solid #475569 !important;\r\n        box-shadow: 0 0 0 2px #020617, 0 30px 70px rgba(0,0,0,0.8), inset 0 2px 1px rgba(255,255,255,0.15) !important; \r\n        box-sizing: border-box !important;\r\n        position: relative;\r\n        line-height: normal !important;\r\n        transition: border-color 0.5s;\r\n        -webkit-tap-highlight-color: transparent; \r\n    }\r\n\r\n    #sonic-lab-v25 * { \r\n        box-sizing: border-box !important; \r\n        font-family: 'Rajdhani', sans-serif !important; \r\n        margin: 0; padding: 0; \r\n        -webkit-tap-highlight-color: transparent;\r\n    }\r\n\r\n    \/* --- SYSTEM OFF STATE STYLES --- *\/\r\n    #sonic-lab-v25.sys-off { border-color: #334155 !important; }\r\n    \r\n    #sonic-lab-v25.sys-off .pan-side-val,\r\n    #sonic-lab-v25.sys-off .pan-side-label,\r\n    #sonic-lab-v25.sys-off .lab-title span,\r\n    #sonic-lab-v25.sys-off .panel-head,\r\n    #sonic-lab-v25.sys-off .pan-display-row,\r\n    #sonic-lab-v25.sys-off .pan-display-row span,\r\n    #sonic-lab-v25.sys-off .meter-label,\r\n    #sonic-lab-v25.sys-off .meter-scale-half span,\r\n    #sonic-lab-v25.sys-off #sub-status, \r\n    #sonic-lab-v25.sys-off #iso-status,\r\n    #sonic-lab-v25.sys-off .text-glow-white,\r\n    #sonic-lab-v25.sys-off #kick-btn-val,\r\n    #sonic-lab-v25.sys-off .knob-val-display\r\n    {\r\n        color: #475569 !important;\r\n        border-color: #475569 !important;\r\n        text-shadow: none !important;\r\n        transition: color 0.5s, border-color 0.5s;\r\n    }\r\n\r\n    \/* Knob specific OFF styles *\/\r\n    #sonic-lab-v25.sys-off .knob-ring { background: #334155 !important; box-shadow: none !important; }\r\n    #sonic-lab-v25.sys-off .knob-cap { background: #1e293b !important; border-color: #334155 !important; }\r\n    #sonic-lab-v25.sys-off .knob-indicator { background: #475569 !important; box-shadow: none !important; }\r\n\r\n    #sonic-lab-v25.sys-off button.sub-toggle,\r\n    #sonic-lab-v25.sys-off button.sub-toggle.sub-ready {\r\n        color: #475569 !important;\r\n        border-color: #334155 !important;\r\n        text-shadow: none !important;\r\n        cursor: not-allowed !important;\r\n        transition: color 0.5s;\r\n    }\r\n\r\n    #sonic-lab-v25.sys-off .tick,\r\n    #sonic-lab-v25.sys-off .vol-tick { color: #475569 !important; text-shadow: none !important; }\r\n\r\n    #sonic-lab-v25.sys-off .mus-screen,\r\n    #sonic-lab-v25.sys-off .rta-screen,\r\n    #sonic-lab-v25.sys-off .sub-screen,\r\n    #sonic-lab-v25.sys-off .digital-screen-container {\r\n        background: #000 !important;\r\n        box-shadow: inset 0 0 10px #000 !important;\r\n        border-color: #1e293b !important;\r\n    }\r\n\r\n    #sonic-lab-v25.sys-off canvas,\r\n    #sonic-lab-v25.sys-off .mus-grid-display,\r\n    #sonic-lab-v25.sys-off #sub-hz-val,\r\n    #sonic-lab-v25.sys-off #iso-hz-val,\r\n    #sonic-lab-v25.sys-off #freq-mini-disp,\r\n    #sonic-lab-v25.sys-off #warning-overlay {\r\n        opacity: 0 !important;\r\n        transition: opacity 0.3s;\r\n    }\r\n    \r\n    #sonic-lab-v25.sys-off #btn-stop {\r\n        color: #ffffff4a !important; \r\n        text-shadow: none !important;\r\n        border-color: #334155 !important;\r\n    }\r\n\r\n    #sonic-lab-v25.sys-off #btn-sine {\r\n        background: linear-gradient(180deg, #aebcd1 0%, #334155 50%, #1e293b 51%, #334155 100%) !important;\r\n        border: 2px solid #0f172a !important; \r\n        border-top: 2px solid #64748b !important;\r\n        color: #fff !important;\r\n        box-shadow: 0 4px 6px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.1) !important;\r\n        text-shadow: 0 -1px 0 #000 !important;\r\n        transform: none !important;\r\n    }\r\n\r\n    #sonic-lab-v25.sys-off .piano-wrapper::before { background: #475569 !important; box-shadow: none !important; }\r\n\r\n    \/* FONTS & BASE *\/\r\n    #sonic-lab-v25 .modal-header-bar,\r\n    #sonic-lab-v25 h2,\r\n    #sonic-lab-v25 #screen-input,\r\n    #sonic-lab-v25 #warning-overlay,\r\n    #sonic-lab-v25 .meter-label,\r\n    #sonic-lab-v25 .mus-cell,\r\n    #sonic-lab-v25 #sub-hz-val, \r\n    #sonic-lab-v25 #iso-hz-val,\r\n    #sonic-lab-v25 .help-btn,\r\n    #sonic-lab-v25 .knob-label {\r\n        font-family: 'Orbitron', monospace !important;\r\n    }\r\n\r\n    #sonic-lab-v25 button { all: unset; cursor: pointer !important; }\r\n    #sonic-lab-v25 input { all: unset; }\r\n\r\n    \/* --- KNOB STYLES --- *\/\r\n    #sonic-lab-v25 .knob-wrapper {\r\n        display: flex; flex-direction: column; align-items: center; gap: 5px; position: relative; width: 16%;\r\n        touch-action: none !important; \r\n    }\r\n    #sonic-lab-v25 .knob-container {\r\n        width: 55px; height: 55px; position: relative; cursor: ns-resize;\r\n        border-radius: 50%;\r\n        box-shadow: inset 0 2px 5px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.1);\r\n        background: #0f172a;\r\n        touch-action: none !important; \r\n    }\r\n    #sonic-lab-v25 .knob-ring {\r\n        position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%;\r\n        background: conic-gradient(var(--neon-blue) 0%, #334155 0%);\r\n        box-shadow: 0 0 10px rgba(56, 189, 248, 0.2);\r\n        transition: box-shadow 0.3s;\r\n        pointer-events: none; \r\n    }\r\n    #sonic-lab-v25 .knob-cap {\r\n        position: absolute; top: 5px; left: 5px; width: 45px; height: 45px;\r\n        border-radius: 50%;\r\n        background: linear-gradient(135deg, #475569 0%, #1e293b 100%);\r\n        border: 1px solid #64748b; border-bottom: 2px solid #0f172a;\r\n        box-shadow: 0 4px 5px rgba(0,0,0,0.5), inset 0 1px 1px rgba(255,255,255,0.3);\r\n        transform: rotate(0deg); \r\n        z-index: 2;\r\n        pointer-events: none; \r\n    }\r\n    #sonic-lab-v25 .knob-indicator {\r\n        position: absolute; top: 3px; left: 50%; width: 2px; height: 8px;\r\n        background: var(--neon-blue); transform: translateX(-50%);\r\n        box-shadow: 0 0 5px var(--neon-blue); border-radius: 1px;\r\n    }\r\n    #sonic-lab-v25 .knob-label {\r\n        font-size: 8px; color: #94a3b8; font-weight: bold; letter-spacing: 1px; white-space: nowrap;\r\n    }\r\n    #sonic-lab-v25 .knob-val-display {\r\n        font-size: 9px; color: #fff; font-weight: bold; margin-top: -2px; text-shadow: 0 0 5px rgba(255,255,255,0.5); white-space: nowrap;\r\n    }\r\n\r\n    \/* --- MOBILE POPUP SLIDER (POPRAVLJENO CENTRIRANJE) --- *\/\r\n    #sonic-lab-v25 #mobile-knob-editor {\r\n        display: none; \r\n        position: fixed; \/* Fixed je bolje za centriranje preko svega *\/\r\n        top: 50%; \r\n        left: 50%; \r\n        transform: translate(-50%, -50%); \/* Savr\u0161eno centrirano *\/\r\n        width: 80%; \r\n        max-width: 300px;\r\n        background: rgba(15, 23, 42, 0.98);\r\n        border: 2px solid var(--neon-blue); \r\n        border-radius: 12px;\r\n        padding: 20px; \r\n        z-index: 9999; \r\n        backdrop-filter: blur(10px);\r\n        box-shadow: 0 0 50px rgba(0,0,0,0.9);\r\n        flex-direction: column; gap: 15px; text-align: center;\r\n        animation: popUp 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);\r\n    }\r\n    @keyframes popUp { from { transform: translate(-50%, -40%); opacity: 0; } to { transform: translate(-50%, -50%); opacity: 1; } }\r\n    \r\n    #sonic-lab-v25 #mobile-knob-title { color: var(--neon-blue); font-weight: 900; font-size: 14px; letter-spacing: 2px; margin-bottom: 5px; font-family: 'Orbitron'; }\r\n    #sonic-lab-v25 #mobile-knob-val { color: #fff; font-weight: bold; font-size: 24px; margin-bottom: 10px; text-shadow: 0 0 10px rgba(255,255,255,0.5); font-family: 'Orbitron'; }\r\n    #sonic-lab-v25 .close-popup-area { position: fixed; top:0; left:0; width:100%; height:100%; z-index: 9998; display:none; background: rgba(0,0,0,0.5); backdrop-filter: blur(2px); }\r\n\r\n    \/* SCREWS *\/\r\n    #sonic-lab-v25 .screw {\r\n        width: 18px; height: 18px;\r\n        background: linear-gradient(135deg, #94a3b8, #475569);\r\n        border-radius: 50%;\r\n        box-shadow: 0 2px 4px rgba(0,0,0,0.8), inset 0 1px 0 rgba(255,255,255,0.4);\r\n        position: absolute; z-index: 10;\r\n        display: flex; justify-content: center; align-items: center;\r\n        border: 1px solid #334155;\r\n    }\r\n    #sonic-lab-v25 .screw::after {\r\n        content: ''; width: 8px; height: 8px; background: #1e293b;\r\n        clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);\r\n        box-shadow: inset 0 1px 2px #000;\r\n    }\r\n    #sonic-lab-v25 .tl { top: 12px; left: 12px; } #sonic-lab-v25 .tr { top: 12px; right: 12px; }\r\n    #sonic-lab-v25 .bl { bottom: 12px; left: 12px; } #sonic-lab-v25 .br { bottom: 12px; right: 12px; }\r\n\r\n    \/* HELP BUTTON *\/\r\n    #sonic-lab-v25 .help-btn {\r\n        position: absolute; bottom: 5px; left: 50%; transform: translateX(-50%);\r\n        width: 35px; height: 35px; border-radius: 50%;\r\n        background: linear-gradient(145deg, #1e293b, #0f172a) !important; \r\n        color: #64748b;\r\n        font-weight: 900; font-size: 22px; text-align: center; line-height: 24px;\r\n        box-shadow: 0 4px 10px rgba(0,0,0,0.8), inset 0 1px 0 rgba(255,255,255,0.1);\r\n        border: 2px solid #334155; cursor: pointer; z-index: 20;\r\n        transition: all 0.2s;\r\n    }\r\n    #sonic-lab-v25 .help-btn:hover { color: #94a3b8; border-color: #475569; }\r\n    #sonic-lab-v25 .help-btn:active { transform: translateX(-50%) scale(0.95); background: #020617; color: var(--neon-blue); border-color: var(--neon-blue); box-shadow: 0 0 10px rgba(56, 189, 248, 0.3); }\r\n\r\n    \/* MODALS *\/\r\n    #sonic-lab-v25 #safety-modal, #sonic-lab-v25 #help-modal {\r\n        display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;\r\n        background: rgba(2, 6, 23, 0.95); z-index: 9999; \r\n        justify-content: center; align-items: center; backdrop-filter: blur(8px);\r\n    }\r\n    #sonic-lab-v25 .modal-box {\r\n        background: #1e293b; border: 4px solid #334155; border-radius: 12px;\r\n        width: 750px; \r\n        max-width: 95%; height: 600px; max-height: 90vh; text-align: left; \r\n        box-shadow: 0 0 60px rgba(0, 0, 0, 0.8);\r\n        animation: modalPop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);\r\n        overflow: hidden; padding: 0; display: flex; flex-direction: column;\r\n    }\r\n    #sonic-lab-v25 .modal-box.danger { \r\n        border-color: #b91c1c; \r\n        width: 400px !important; \r\n        height: auto !important; \r\n        text-align: center; \r\n        padding-bottom: 20px;\r\n    }\r\n      \r\n    #sonic-lab-v25 .modal-header-bar {\r\n        background: linear-gradient(180deg, #334155, #1e293b);\r\n        color: white; padding: 15px; font-weight: 900; letter-spacing: 2px;\r\n        text-shadow: 0 1px 2px rgba(0,0,0,0.5); border-bottom: 2px solid #0f172a;\r\n        display: flex; align-items: center; justify-content: space-between; font-size: 16px;\r\n    }\r\n    #sonic-lab-v25 .modal-header-bar.danger { background: linear-gradient(180deg, #ef4444, #b91c1c); border-bottom: 2px solid #7f1d1d; justify-content: center; font-size: 20px;}\r\n\r\n    #sonic-lab-v25 .help-layout-grid {\r\n        display: grid; grid-template-columns: 180px 1fr; height: 100%; overflow: hidden;\r\n    }\r\n    #sonic-lab-v25 .help-menu {\r\n        background: #0f172a; border-right: 1px solid #334155; padding: 15px;\r\n        overflow-y: auto; display: flex; flex-direction: column; gap: 5px;\r\n    }\r\n    #sonic-lab-v25 .help-content {\r\n        padding: 25px; overflow-y: auto; background: #1e293b; position: relative;\r\n    }\r\n    \r\n    #sonic-lab-v25 .menu-item {\r\n        color: #94a3b8; font-size: 11px; font-weight: bold; cursor: pointer;\r\n        padding: 8px 10px; border-radius: 4px; transition: all 0.2s;\r\n        text-transform: uppercase; letter-spacing: 1px;\r\n    }\r\n    #sonic-lab-v25 .menu-item:hover { background: #1e293b; color: #cbd5e1; }\r\n    #sonic-lab-v25 .menu-item.active { background: rgba(56, 189, 248, 0.1); color: var(--neon-blue); border-left: 2px solid var(--neon-blue); }\r\n\r\n    @media (max-width: 800px) {\r\n        #sonic-lab-v25 .modal-box { width: 98% !important; height: 85vh !important; }\r\n        #sonic-lab-v25 .help-layout-grid { display: flex !important; flex-direction: column !important; }\r\n        #sonic-lab-v25 .help-menu { width: 100% !important; border-right: none !important; border-bottom: 2px solid #334155; flex-direction: row !important; flex-wrap: wrap !important; gap: 5px !important; padding: 10px !important; min-height: auto; flex-shrink: 0; }\r\n        #sonic-lab-v25 .menu-item { width: calc(50% - 5px) !important; text-align: center !important; border: 1px solid #334155; margin-bottom: 0 !important; background: #020617; padding: 10px 5px !important; }\r\n        #sonic-lab-v25 .menu-item.active { border-left: 1px solid #334155 !important; border-color: var(--neon-blue) !important; background: rgba(56, 189, 248, 0.15) !important; box-shadow: inset 0 0 10px rgba(56, 189, 248, 0.1); }\r\n        #sonic-lab-v25 .help-content { flex: 1; padding: 20px 15px !important; }\r\n        #sonic-lab-v25 .modal-actions .modal-btn { height: 55px !important; font-size: 12px !important; }\r\n    }\r\n\r\n    #sonic-lab-v25 .modal-section { margin-bottom: 40px; border-bottom: 1px solid #334155; padding-bottom: 20px; }\r\n    #sonic-lab-v25 .modal-section:last-child { border: none; }\r\n    \r\n    #sonic-lab-v25 .modal-h3 { \r\n        color: var(--neon-blue); font-family: 'Orbitron'; font-size: 16px; \r\n        margin-bottom: 15px; display: block; font-weight: bold; \r\n        text-transform: uppercase !important; \r\n    }\r\n    \r\n    #sonic-lab-v25 .modal-text { \r\n        font-size: 13px; color: #cbd5e1; line-height: 1.7; margin-bottom: 15px; \r\n        text-transform: none !important; \r\n        text-align: justify !important; \r\n        font-family: 'Rajdhani', sans-serif !important;\r\n    }\r\n    #sonic-lab-v25 .modal-text strong { color: #fff; font-weight: bold; }\r\n    \r\n    #sonic-lab-v25 .help-list { \r\n        padding-left: 20px; color: #94a3b8; font-size: 12px; line-height: 1.6; margin-bottom: 15px; \r\n        text-transform: none !important; \r\n        text-align: justify !important; \r\n        font-family: 'Rajdhani', sans-serif !important;\r\n    }\r\n    #sonic-lab-v25 .help-list li { margin-bottom: 5px; }\r\n\r\n    @keyframes modalPop { from { transform: scale(0.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }\r\n    #sonic-lab-v25 .modal-actions { display: flex; gap: 15px; justify-content: center; margin-top: 20px;}\r\n\r\n    #sonic-lab-v25 .lab-header {\r\n        display: flex; justify-content: space-between; align-items: center;\r\n        margin-bottom: 5px; border-bottom: 0px groove #334155; padding-bottom: 0px; margin-top: -29px;\r\n    }\r\n    #sonic-lab-v25 h2 { \r\n        margin-left: 30px !important; font-size: 14px !important; font-weight: 900 !important; letter-spacing: 1px !important; color: #e2e8f0 !important; \r\n        text-shadow: 0 2px 4px rgba(0,0,0,0.5) !important; \r\n        background: transparent !important; padding: 0 !important; line-height: 1.2 !important;\r\n    }\r\n    #sonic-lab-v25 .lab-title span { color: var(--neon-blue); font-size: 11px; font-weight: bold; letter-spacing: 3px; text-transform: uppercase; text-shadow: 0 0 5px rgba(56,189,248,0.5); margin-left: 0px; margin-left: 30px; transition: color 0.5s; }\r\n        \r\n    #sonic-lab-v25 .status-panel {\r\n        font-size: 09px!important; font-weight: bold; color: #94a3b8; display: flex; align-items: center; gap: 10px;\r\n        background: #0f172a; padding: 5px 5px; border-radius: 4px; border: 1px solid #334155;\r\n        box-shadow: inset 0 2px 5px rgba(0,0,0,0.8); margin-right: 28px;\r\n    }\r\n    #sonic-lab-v25 .led-ind { width: 8px; height: 8px; background: #334155; border-radius: 50%; transition: 0.3s; box-shadow: inset 0 1px 1px rgba(0,0,0,1); }\r\n    #sonic-lab-v25 .led-ind.active { background: var(--neon-blue); box-shadow: 0 0 10px var(--neon-blue); animation: pulseBlue 2s infinite; }\r\n    @keyframes pulseBlue { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } }\r\n\r\n    #sonic-lab-v25 .digital-screen-container {\r\n        background: #020617; padding: 6px; border-radius: 8px; margin-bottom: 10px; height: 296px; \r\n        box-shadow: inset 0 0 0 2px #0f172a, inset 0 0 0 5px #334155, inset 0 1px 0 5px rgba(255,255,255,0.1), 0 10px 30px rgba(0,0,0,0.7); \r\n        border: 1px solid #1e293b; position: relative;\r\n        transition: background 0.5s;\r\n    }\r\n    #sonic-lab-v25 .screen-inner {\r\n        width: 100%; height: 100%; background: #000; transform-origin: center;\r\n        position: relative; border-radius: 2px; overflow: hidden; border: 1px solid #0f172a;\r\n    }\r\n    #sonic-lab-v25 .screen-inner::after {\r\n        content: ''; position: absolute; top:0; left:0; width:100%; height:100%;\r\n        background: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, transparent 40%, rgba(0,0,0,0.1) 100%);\r\n        pointer-events: none; z-index: 10;\r\n    }\r\n    #sonic-lab-v25 .screen-inner.crt-on {\r\n        background: radial-gradient(circle at center, var(--screen-bg) 40%, #0ea5e9 150%);\r\n        box-shadow: inset 0 0 30px rgba(0 0 0 \/ 75%);\r\n        animation: turnOn 0.4s linear forwards;\r\n    }\r\n    @keyframes turnOn {\r\n        0% { transform: scale(1, 0.002); opacity: 0; filter: brightness(0); background: #000;}\r\n        20% { transform: scale(1, 0.002); opacity: 1; filter: brightness(5); background: #fff; }\r\n        50% { transform: scale(1, 1); opacity: 1; filter: brightness(1.5); background: radial-gradient(circle at center, var(--screen-bg) 40%, #0ea5e9 150%); }\r\n        100% { transform: scale(1, 1); opacity: 1; filter: brightness(1); background: radial-gradient(circle at center, var(--screen-bg) 40%, #0ea5e9 150%); }\r\n    }\r\n    #sonic-lab-v25 .screen-inner.crt-off { background: #000 !important; transition: background 0.1s; }\r\n    #sonic-lab-v25 canvas#scope { width: 100%; height: 100%; display: block; opacity: 1; transition: opacity 0.5s; }\r\n\r\n    #sonic-lab-v25 #hz-overlay { position: absolute; top: 10px; right: 5px; display: none; text-align: right; z-index: 9; pointer-events: auto; }\r\n    #sonic-lab-v25 .crt-on #hz-overlay { display: block; animation: fadeIn 1s forwards 0.5s; opacity: 0; }\r\n    @keyframes fadeIn { to { opacity: 1; } }\r\n\r\n    #sonic-lab-v25 #screen-input {\r\n        background: transparent !important; border: none !important; outline: none !important;\r\n        font-size: 30px !important; font-weight: 600 !important;\r\n        color: var(--screen-ink) !important; text-align: right !important; width: 400px !important;\r\n        margin: 0 !important; padding: 0 !important; pointer-events: auto !important; text-transform: none !important;\r\n        text-shadow: 0 0 3px rgba(15, 23, 42, 0.6), 0 0 1px var(--screen-ink) !important;\r\n        box-shadow: none !important;\r\n    }\r\n    #sonic-lab-v25 #screen-input:focus { border-bottom: 2px solid var(--screen-ink) !important; }\r\n\r\n    #sonic-lab-v25 #warning-overlay {\r\n        position: absolute; top: 85%; left: 50%; transform: translate(-50%, -50%);\r\n        font-weight: 900; font-size: 10px;\r\n        color: var(--screen-ink); text-align: center; display: none; z-index: 20;\r\n        text-shadow: 0 0 2px rgba(255,255,255,0.3); width: 90%; letter-spacing: 1px;\r\n    }\r\n    #sonic-lab-v25 .crt-on #warning-overlay.show { display: block; animation: flashWarn 0.5s infinite alternate; color: var(--screen-ink);}\r\n    @keyframes flashWarn { 0% { opacity: 1; } 100% { opacity: 0.3; } }\r\n\r\n    \/* METERS *\/\r\n    #sonic-lab-v25 .meter-bridge {\r\n        background: #0f172a; border: 1px solid #334155; border-radius: 6px; padding: 10px;\r\n        margin-bottom: 10px; box-shadow: inset 0 2px 10px rgba(0,0,0,0.8);\r\n        border-bottom: 1px solid #475569; position: relative; overflow: hidden; \r\n    }\r\n    #sonic-lab-v25 .meter-bridge::after {\r\n        content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%;\r\n        background: linear-gradient(135deg, rgba(255,255,255,0.06) 0%, transparent 40%, rgba(0,0,0,0.3) 100%);\r\n        box-shadow: inset 0 0 25px rgba(2, 6, 23, 0.95), inset 0 0 10px rgba(2, 6, 23, 0.7);\r\n        pointer-events: none; z-index: 10;\r\n    }\r\n    #sonic-lab-v25 .meter-row { display: flex; flex-direction: row; gap: 20px; align-items: center; position: relative; z-index: 2; }\r\n    #sonic-lab-v25 .meter-channel { display: flex; align-items: center; gap: 8px; flex: 1; }\r\n    #sonic-lab-v25 .meter-label { \r\n        font-size: 11px; color: #e0f2fe; \r\n        font-weight: 900; width: 15px; text-shadow: 0 0 6px var(--neon-blue), 0 0 2px var(--neon-blue);\r\n        transition: color 0.5s;\r\n    }\r\n    #sonic-lab-v25 .led-strip { flex: 1; display: flex; gap: 3px; height: 10px; background: #020617; padding: 2px; border-radius: 2px; box-shadow: inset 0 1px 3px #000; }\r\n    #sonic-lab-v25 .led-seg { flex: 1; background: #1e293b; border-radius: 1px; transition: background 0.05s; }\r\n    #sonic-lab-v25 .led-seg.on-green { background: var(--neon-blue); box-shadow: 0 0 8px var(--neon-blue); }\r\n    #sonic-lab-v25 .led-seg.on-yellow { background: #eab308; box-shadow: 0 0 8px #eab308; }\r\n    #sonic-lab-v25 .led-seg.on-red { background: #ef4444; box-shadow: 0 0 10px #ef4444; }\r\n    #sonic-lab-v25 .meter-scale-row { display: flex; flex-direction: row; gap: 20px; margin-top: 4px; position: relative; z-index: 2;}\r\n    #sonic-lab-v25 .meter-scale-half { flex: 1; display: flex; justify-content: space-between; font-family: monospace; font-size: 9px; padding-left: 23px; }\r\n    #sonic-lab-v25 .meter-scale-half span { color: #e0f2fe; text-shadow: 0 0 6px var(--neon-blue), 0 0 2px var(--neon-blue); font-weight: bold; transition: color 0.5s; }\r\n\r\n    #sonic-lab-v25 .controls-grid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 10px; } \r\n    @media (max-width: 900px) { #sonic-lab-v25 .controls-grid { grid-template-columns: 1fr; } }\r\n    #sonic-lab-v25 .right-column-wrap { display: flex; flex-direction: column; gap: 10px; }\r\n\r\n    #sonic-lab-v25 .panel-card { \r\n        background: linear-gradient(135deg, #253045, #1e293b);\r\n        border: 1px solid #475569; border-top: 1px solid #64748b; border-bottom: 1px solid #0f172a;\r\n        border-radius: 8px; padding: 5px; box-shadow: 0 10px 20px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.05);\r\n        position: relative;\r\n    }\r\n    #sonic-lab-v25 .panel-card::before { content:''; position:absolute; top:8px; left:8px; width:8px; height:8px; background:#0f172a; border-radius:50%; box-shadow:inset 0 1px 1px rgba(255,255,255,0.2); opacity:0.0; }\r\n    #sonic-lab-v25 .panel-card::after { content:''; position:absolute; top:8px; right:8px; width:8px; height:8px; background:#0f172a; border-radius:50%; box-shadow:inset 0 1px 1px rgba(255,255,255,0.2); opacity:0.0; }\r\n\r\n    #sonic-lab-v25 .panel-head {\r\n        font-size: 11px; font-weight: 800; text-transform: uppercase; \r\n        letter-spacing: 1px; margin-bottom: 20px; display: block; \r\n        padding-bottom: 10px; color: var(--neon-blue); \r\n        border-bottom: 1px solid var(--neon-blue); text-shadow: 0 0 8px rgba(56,189,248,0.5);\r\n        transition: color 0.5s, border-color 0.5s;\r\n    }\r\n    #sonic-lab-v25 .tech-sub { display: block; font-size: 9px; color: #64748b !important; margin-top: -15px; margin-bottom: 20px; letter-spacing: 1px; font-family: monospace; }\r\n    #sonic-lab-v25 .wave-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-bottom: 20px; }\r\n\r\n    #sonic-lab-v25 button.tech-btn, #sonic-lab-v25 button.modal-btn, #sonic-lab-v25 button.pan-side-btn {\r\n        background: linear-gradient(180deg, #aebcd1 0%, #334155 50%, #1e293b 51%, #334155 100%) !important;\r\n        border: 2px solid #0f172a !important; border-top: 2px solid #64748b !important;\r\n        color: #cbd5e1 !important; text-shadow: 0 -1px 0 #000 !important;\r\n        padding: 0 !important; height: 48px !important; border-radius: 4px !important; \r\n        font-size: 10px !important; font-weight: 700 !important; \r\n        transition: all 0.1s ease-out !important; text-align: center !important; margin: 0 !important;\r\n        width: 100%; display: flex !important; justify-content: center !important; align-items: center !important; gap: 6px !important; \r\n        box-shadow: 0 4px 6px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.1) !important;\r\n        position: relative; z-index: 1;\r\n    }\r\n    #sonic-lab-v25 button.tech-btn:hover { background: linear-gradient(180deg, #576880 0%, #3f4f66 50%, #29354a 51%, #3f4f66 100%) !important; color: #fff !important; }\r\n    #sonic-lab-v25 button.tech-btn:active, #sonic-lab-v25 button.tech-btn.active { \r\n        background: #0f172a !important; color: var(--neon-blue) !important; border: 2px solid var(--neon-blue) !important;\r\n        box-shadow: inset 0 0 10px rgba(56,189,248,0.3), 0 0 8px rgba(56,189,248,0.4) !important;\r\n        text-shadow: 0 0 5px var(--neon-blue) !important; transform: translateY(1px); \r\n    }\r\n    #sonic-lab-v25 button.noise-btn { flex-direction: column !important; justify-content: center !important; gap: 3px !important; }\r\n\r\n    #sonic-lab-v25 button.pan-side-btn { \r\n        width: 62px !important; \r\n        height: 50px !important; \r\n        flex-shrink: 0; \r\n        flex-direction: column !important; \r\n        gap: 2px !important;\r\n        line-height: 1 !important;\r\n    }\r\n    #sonic-lab-v25 .pan-side-label { font-size: 15px; font-weight: 900; color: #e2e8f0; transition: color 0.5s; }\r\n    #sonic-lab-v25 .pan-side-val { font-size: 9px; color: var(--neon-blue); font-weight: bold; transition: color 0.5s; }\r\n    \r\n    #sonic-lab-v25 button.pan-side-btn:active .pan-side-label,\r\n    #sonic-lab-v25 button.pan-side-btn:active .pan-side-val { color: var(--neon-blue) !important; }\r\n\r\n    #sonic-lab-v25 button.modal-btn { width: 120px !important; height: 38px !important; font-size: 11px !important; }\r\n\r\n    #sonic-lab-v25 .btn-icon, #sonic-lab-v25 .noise-icon { \r\n        width: 20px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5px; \r\n        stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.5));\r\n    }\r\n    #sonic-lab-v25 button.noise-white.active { color: #ffffff !important; border-color: #ffffff !important; text-shadow: 0 0 5px #ffffff !important; box-shadow: inset 0 0 10px rgba(255,255,255,0.4), 0 0 8px rgba(255,255,255,0.4) !important; }\r\n    #sonic-lab-v25 button.noise-pink.active { color: #f472b6 !important; border-color: #ec4899 !important; text-shadow: 0 0 5px #ec4899 !important; box-shadow: inset 0 0 10px rgba(236, 72, 153, 0.4), 0 0 8px rgba(236, 72, 153, 0.4) !important; }\r\n    #sonic-lab-v25 button.noise-blue.active { color: #60a5fa !important; border-color: #3b82f6 !important; text-shadow: 0 0 5px #3b82f6 !important; box-shadow: inset 0 0 10px rgba(59, 130, 246, 0.4), 0 0 8px rgba(59, 130, 246, 0.4) !important; }\r\n    #sonic-lab-v25 button.noise-grey.active { color: #cbd5e1 !important; border-color: #94a3b8 !important; text-shadow: 0 0 5px #94a3b8 !important; box-shadow: inset 0 0 10px rgba(148, 163, 184, 0.4), 0 0 8px rgba(148, 163, 184, 0.4) !important; }\r\n    #sonic-lab-v25 button.noise-red.active { color: #f87171 !important; border-color: #ef4444 !important; text-shadow: 0 0 5px #ef4444 !important; box-shadow: inset 0 0 10px rgba(239, 68, 68, 0.4), 0 0 8px rgba(239, 68, 68, 0.4) !important; }\r\n    #sonic-lab-v25 button.btn-confirm { background: linear-gradient(180deg, #ef4444, #991b1b) !important; color: white !important; border: 1px solid #7f1d1d !important; border-bottom: 3px solid #450a0a !important; }\r\n\r\n    \/* MUSICAL DISPLAY *\/\r\n    #sonic-lab-v25 .mus-screen {\r\n        background: radial-gradient(circle at center, var(--screen-bg) 20%, #0369a1 150%); height: 48px; margin-bottom: 8px; \r\n        border: 2px solid #0f172a; border-radius: 4px; position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center;\r\n        box-shadow: inset 0 0 15px rgba(2, 6, 23, 0.8), inset 0 0 5px rgba(2, 6, 23, 0.5);\r\n        transition: background 0.5s;\r\n    }\r\n    #sonic-lab-v25 .mus-grid-display { display: grid; grid-template-columns: 1fr 1fr 1.5fr; gap: 6px; width: 100%; padding: 0 10px; z-index: 2; opacity: 0.85; filter: blur(0.4px); transition: opacity 0.5s;}\r\n    #sonic-lab-v25 .mus-cell {\r\n        border: 1px solid rgba(15, 23, 42, 0.3); border-radius: 2px; text-align: center;\r\n        font-size: 12px; font-weight: 900; color: var(--screen-ink); padding: 4px 0;\r\n        background: rgba(255,255,255,0.05); text-shadow: 0 0 3px rgba(15, 23, 42, 0.6); white-space: nowrap;\r\n    }\r\n\r\n    \/* RTA ANALYZER *\/\r\n    #sonic-lab-v25 .rta-screen {\r\n        background: #020617; height: 100px; margin-bottom: 8px; border: 2px solid #334155; border-radius: 6px;\r\n        position: relative; overflow: hidden; display: flex; align-items: flex-end; justify-content: center; box-shadow: inset 0 0 15px rgba(0,0,0,1); padding: 0 4px 4px 4px;\r\n        transition: background 0.5s;\r\n    }\r\n    #sonic-lab-v25 #iso-status { position: absolute; top: 6px; left: 10px; font-size: 9px; color: #64748b; font-weight: bold; letter-spacing: 1px; z-index: 2; opacity: 0.8; }\r\n\r\n    \/* ADVANCED SUBWOOFER MATRIX *\/\r\n    #sonic-lab-v25 .sub-unit {\r\n        background: linear-gradient(135deg, #1e293b, #0f172a); border: 1px solid #334155; border-radius: 8px; padding: 5px;\r\n        display: flex; flex-direction: column; gap: 12px; box-shadow: inset 0 0 20px rgba(0,0,0,0.5);\r\n    }\r\n    #sonic-lab-v25 .sub-screen {\r\n        background: #020617; border: 2px solid #334155; border-radius: 6px; position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; box-shadow: inset 0 0 15px rgba(0,0,0,1);\r\n        transition: background 0.5s;\r\n    }\r\n    #sonic-lab-v25 canvas#sub-scope-canvas { position: absolute; top:0; left:0; width:100%; height:100%; opacity: 0.8; }\r\n    #sonic-lab-v25 #sub-status { position: absolute; top: 6px; left: 10px; font-size: 9px; color: #64748b; font-weight: bold; letter-spacing: 1px; z-index: 2; opacity: 0.8; }\r\n    #sonic-lab-v25 #sub-invert-status { position: absolute; top: 6px; right: 10px; font-size: 9px; color: #eab308; font-weight: bold; letter-spacing: 1px; z-index: 2; display: none; text-shadow: 0 0 5px rgba(234, 179, 8, 0.5); }\r\n\r\n    #sonic-lab-v25 #sub-hz-val, #sonic-lab-v25 #iso-hz-val {\r\n        font-size: 14px!important; color: var(--screen-ink); font-weight: 900;\r\n        text-shadow: 0 0 4px rgba(15, 23, 42, 0.7), 0 0 1px rgba(15, 23, 42, 0.9); filter: blur(0.4px); z-index: 2; opacity: 0.85; transition: opacity 0.5s;\r\n    }\r\n    #sonic-lab-v25 button.sub-phase.active { color: #fbbf24 !important; border-color: #fbbf24 !important; text-shadow: 0 0 10px #fbbf24; }\r\n    \r\n    #sonic-lab-v25 button.sub-toggle.sub-ready { \r\n        color: var(--neon-blue) !important;\r\n        border-color: #475569 !important;\r\n        text-shadow: 0 0 5px rgba(56, 189, 248, 0.4) !important;\r\n        transition: color 0.5s, text-shadow 0.5s;\r\n    }\r\n    #sonic-lab-v25 button.sub-toggle.sub-active { color: #ef4444 !important; border-color: #ef4444 !important; text-shadow: 0 0 10px #ef4444; }\r\n\r\n    \/* SLIDERS *\/\r\n    #sonic-lab-v25 .slider-track-container { position: relative; margin: 10px 0 30px 0; }\r\n    #sonic-lab-v25 input[type=range].magnet-slider { width: 100%; -webkit-appearance: none; background: transparent; cursor: pointer; margin: 0; position: relative; z-index: 5; }\r\n    #sonic-lab-v25 input[type=range].magnet-slider:focus { outline: none; }\r\n    #sonic-lab-v25 input[type=range].magnet-slider::-webkit-slider-runnable-track {\r\n        height: 10px; background: #0f172a; border-radius: 5px; border: 2px solid #334155; box-shadow: inset 0 2px 5px rgba(0,0,0,0.9);\r\n    }\r\n    #sonic-lab-v25 input[type=range].magnet-slider::-webkit-slider-thumb {\r\n        -webkit-appearance: none; height: 26px; width: 14px; background: linear-gradient(180deg, #e2e8f0 0%, #94a3b8 50%, #64748b 100%); \r\n        border-radius: 3px; margin-top: -10px; border: 1px solid #fff; box-shadow: 0 2px 5px rgba(0,0,0,0.7);\r\n    }\r\n    \r\n    #sonic-lab-v25 .scale-container { position: relative; height: 20px; margin-top: 15px; font-family: monospace; font-size: 9px; color: #64748b; padding: 0 15px; }\r\n    #sonic-lab-v25 .scale-ruler { display: none; width: 100%; justify-content: space-between; position: absolute; top: 0; left: 0; }\r\n    #sonic-lab-v25 .scale-ruler.active { display: block; }\r\n    #sonic-lab-v25 .tick { position: absolute; text-align: center; transform: translateX(-50%); }\r\n    #sonic-lab-v25 .tick::before { content:'|'; display: block; font-size: 10px; margin-bottom: 5px; color: #475569; font-weight:bold; }\r\n    #sonic-lab-v25 .vol-scale-wrapper { position: relative; width: 100%; height: 30px; margin-top: 10px; font-family: monospace; font-size: 9px; color: #64748b; }\r\n    #sonic-lab-v25 .vol-tick { position: absolute; transform: translateX(-50%); }\r\n    #sonic-lab-v25 .pan-display-row { display: flex; justify-content: space-between; font-size: 11px; color: #38bdf8; font-weight: bold; margin-bottom: 8px; font-family: monospace; transition: color 0.5s; }\r\n    #sonic-lab-v25 .big-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 0px; padding: 0px 8px; }\r\n    \r\n    #sonic-lab-v25 #freq-mini-disp {\r\n        filter: blur(0.5px);\r\n        text-shadow: 0 0 2px rgba(15, 23, 42, 0.6);\r\n        cursor: pointer;\r\n        display: flex; align-items: center; justify-content: center; height: 100%; width: 100%;\r\n        transition: opacity 0.5s;\r\n    }\r\n\r\n    \/* SMOKED GLASS STYLE FOR SLIDERS *\/\r\n    #sonic-lab-v25 .smoked-glass {\r\n        background: var(--glass-bg);\r\n        border: 1px solid #334155;\r\n        border-radius: 6px;\r\n        padding: 15px 15px 10px 15px; \r\n        box-shadow: inset 0 2px 10px rgba(0,0,0,0.8);\r\n        margin-top: 5px;\r\n        display: flex; flex-direction: column; justify-content: center;\r\n        min-height: 87px; \r\n    }\r\n    #sonic-lab-v25 .text-glow-white {\r\n        color: #ffffff !important;\r\n        text-shadow: 0 0 5px rgba(255, 255, 255, 0.6), 0 0 10px rgba(255, 255, 255, 0.3);\r\n        font-weight: 700 !important;\r\n        opacity: 0.95;\r\n    }\r\n    #sonic-lab-v25 .smoked-glass .tick { color: #fff; text-shadow: 0 0 6px rgba(255,255,255,0.7); }\r\n    #sonic-lab-v25 .smoked-glass .tick::before { color: #64748b; }\r\n\r\n    #sonic-lab-v25 .pan-wrapper {\r\n        display: flex; align-items: center; gap: 8px; width: 100%; justify-content: space-between;\r\n    }\r\n    #sonic-lab-v25 .pan-slider-container {\r\n        position: relative; flex: 1; margin: 0 10px; display: flex; align-items: center; justify-content: center;\r\n    }\r\n    #sonic-lab-v25 .pan-center-marker {\r\n        position: absolute; left: 50%; height: 12px; width: 2px; background: #64748b; \r\n        transform: translateX(-50%); pointer-events: none; z-index: 1; top: 50%; margin-top: -6px;\r\n        box-shadow: 0 0 2px #000;\r\n    }\r\n\r\n    #sonic-lab-v25 button.pwr-btn {\r\n        padding: 0 !important; height: 40px !important; font-size: 14px !important; letter-spacing: 2px !important; border-radius: 6px; font-weight: 900 !important;\r\n        background: linear-gradient(180deg, #aebcd1 0%, #1e293b 100%) !important; border: 2px solid #0f172a !important; border-top: 2px solid #94a3b8 !important;\r\n        box-shadow: 0 8px 15px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.2) !important; transition: background 0.1s, color 0.1s, box-shadow 0.1s; text-align: center; margin-top: 5px;\r\n    }\r\n    #sonic-lab-v25 button.pwr-btn:active { transform: none !important; }\r\n    \r\n    @keyframes pulseBlueGray { \r\n        0% { box-shadow: 0 0 5px var(--neon-blue); border-color: var(--neon-blue); color: var(--neon-blue); text-shadow: 0 0 5px var(--neon-blue); } \r\n        50% { box-shadow: none; border-color: #ffffff; color: #ffffff; text-shadow: none; } \r\n        100% { box-shadow: 0 0 5px var(--neon-blue); border-color: var(--neon-blue); color: var(--neon-blue); text-shadow: 0 0 5px var(--neon-blue); } \r\n    }\r\n    \r\n    #sonic-lab-v25 button.btn-ready { \r\n        animation: pulseBlueGray 2s infinite ease-in-out;\r\n    }\r\n\r\n    #sonic-lab-v25 button.btn-on { \r\n        color: #38bdf8 !important; \r\n        text-shadow: 0 0 8px rgba(56, 189, 248, 0.6) !important; \r\n        border-color: #334155; \r\n        animation: none !important; \r\n    }\r\n    \r\n    #sonic-lab-v25 button.btn-mute { \r\n        background: #0f172a !important; color: #ef4444 !important; border: 2px solid #ef4444 !important;\r\n        box-shadow: inset 0 0 10px rgba(239, 68, 68, 0.2), 0 0 8px rgba(239, 68, 68, 0.4) !important;\r\n        text-shadow: 0 0 5px #ef4444 !important;\r\n        animation: none !important;\r\n    }\r\n    #sonic-lab-v25 button.btn-off { color: #38bdf8 !important; text-shadow: 0 0px 8px #38bdf899 !important; }\r\n    #sonic-lab-v25 button.btn-off:active, #sonic-lab-v25 button.btn-off.active { \r\n        background: linear-gradient(180deg, #991b1b 0%, #7f1d1d 100%) !important; color: white !important; border-color: #ef4444 !important; \r\n        box-shadow: inset 0 0 20px rgba(0,0,0,0.8) !important; transform: none !important; \r\n    }\r\n\r\n    #sonic-lab-v25 .piano-wrapper {\r\n        position: relative; height: 180px; background: #0d1117; border-radius: 8px; overflow: hidden; margin-bottom: 20px; \r\n        border: 4px solid #1e293b; border-top: 15px solid #1e293b; display: flex; justify-content: center; box-shadow: 0 20px 40px rgba(0,0,0,0.7), inset 0 0 20px rgba(0,0,0,0.8);\r\n    }\r\n    #sonic-lab-v25 .piano-wrapper::before { content: ''; position: absolute; top:0; left:0; width:100%; height:4px; background: #38bdf8; z-index: 20; box-shadow: 0 1px 15px rgb(56 189 248); }\r\n    \r\n    #sonic-lab-v25 .key {\r\n        position: relative; float: left; width: 14.28%; height: 100%; \r\n        background: linear-gradient(to bottom, #f1f5f9 0%, #cbd5e1 85%, #94a3b8 100%);\r\n        border: 1px solid #1e293b; border-top: none; border-radius: 0 0 4px 4px; z-index: 1; cursor: pointer; transition: transform 0.05s, background 0.1s; \r\n        display: flex; align-items: flex-end; justify-content: center; padding-bottom: 10px; font-family: 'Segoe UI', sans-serif; font-size: 10px; font-weight: bold; color: #475569;\r\n        box-shadow: inset 2px 0 3px rgba(255,255,255,0.7), inset -2px 0 3px rgba(0,0,0,0.2), 0 4px 6px rgba(0,0,0,0.6);\r\n        border-bottom: 5px solid #475569; \r\n    }\r\n    #sonic-lab-v25 .key:active, #sonic-lab-v25 .key.active { \r\n        background: linear-gradient(180deg, #94a3b8 0%, #cbd5e1 100%); \r\n        box-shadow: inset 0 0 15px rgba(0,0,0,0.3); transform: translateY(2px); border-bottom: 2px solid #475569; color: #1e293b;\r\n    }\r\n    \r\n    #sonic-lab-v25 .key.black {\r\n        position: absolute; top: 0; height: 65%; width: 10%; \r\n        background: linear-gradient(180deg, #1e293b 0%, #020617 90%, #000 100%);\r\n        z-index: 10; border-radius: 0 0 3px 3px; border: 1px solid #334155; border-top: none; color: #64748b; padding-bottom: 8px; font-size: 8px;\r\n        box-shadow: 2px 2px 5px rgba(0,0,0,0.8), inset 1px 1px 2px rgba(255,255,255,0.2);\r\n    }\r\n    #sonic-lab-v25 .key.black:active, #sonic-lab-v25 .key.black.active { \r\n        background: linear-gradient(180deg, #334155 0%, #1e293b 100%); color: #fff; transform: translateY(1px); box-shadow: 1px 1px 3px rgba(0,0,0,0.8), inset 0 0 5px rgba(0,0,0,0.5);\r\n    }\r\n    #sonic-lab-v25 button.oct-btn { width: 35px !important; font-size: 11px !important; }\r\n<\/style>\r\n\r\n<div id=\"sonic-lab-v25\" class=\"sys-off\">\r\n    <div class=\"screw tl\"><\/div><div class=\"screw tr\"><\/div><div class=\"screw bl\"><\/div><div class=\"screw br\"><\/div>\r\n    \r\n    <button class=\"help-btn\" onclick=\"openHelp()\">?<\/button>\r\n\r\n    <div class=\"close-popup-area\" id=\"popup-closer\" onclick=\"closePopup()\"><\/div>\r\n    <div id=\"mobile-knob-editor\">\r\n        <div id=\"mobile-knob-title\">PARAMETER<\/div>\r\n        <div id=\"mobile-knob-val\">50%<\/div>\r\n        <input type=\"range\" class=\"magnet-slider\" id=\"mobile-slider\" style=\"width:100%; height:40px;\">\r\n        <button class=\"tech-btn\" onclick=\"closePopup()\" style=\"height:30px !important; margin-top:10px;\">DONE<\/button>\r\n    <\/div>\r\n\r\n    <div id=\"safety-modal\">\r\n        <div class=\"modal-box danger\">\r\n            <div class=\"modal-header-bar danger\">\u26a0\ufe0f HIGH GAIN WARNING<\/div>\r\n            <div class=\"modal-content-body\" style=\"padding: 20px;\">\r\n                <p class=\"modal-text\" style=\"text-align:center !important; margin-bottom: 20px;\">\r\n                    Pushing volume above <b>-6dB (50%)<\/b> can damage equipment.<br>Are you sure?\r\n                <\/p>\r\n                <div class=\"modal-actions\">\r\n                    <button class=\"modal-btn\" onclick=\"cancelSafe()\">CANCEL<\/button>\r\n                    <button class=\"modal-btn btn-confirm\" onclick=\"confirmSafe()\">PROCEED<\/button>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"help-modal\">\r\n        <div class=\"modal-box\">\r\n            <div class=\"modal-header-bar\">\r\n                <span>SYSTEM MANUAL V25<\/span>\r\n                <span onclick=\"closeHelp()\" style=\"cursor:pointer; color:#ef4444;\">\u2715<\/span>\r\n            <\/div>\r\n            \r\n            <div class=\"help-layout-grid\">\r\n                <div class=\"help-menu\">\r\n                    <div class=\"menu-item active\" onclick=\"scrollToSection('sec-intro', this)\">01. Intro<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-master', this)\">02. Master I\/O<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-wave', this)\">03. Oscillators<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-noise', this)\">04. Noise Gen<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-sweep', this)\">05. Freq Sweep<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-piano', this)\">06. Musical<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-rta', this)\">07. ISO & RTA<\/div>\r\n                    <div class=\"menu-item\" onclick=\"scrollToSection('sec-sub', this)\">08. LFE Matrix<\/div>\r\n                <\/div>\r\n\r\n                <div class=\"help-content\" id=\"help-content-area\">\r\n                    <div id=\"sec-intro\" class=\"modal-section\">\r\n                        <span class=\"modal-h3\">01. INTRODUCTION<\/span>\r\n                        <p class=\"modal-text\">Sonic Lab V25 is a professional-grade signal generation and analysis tool designed for audio engineers, acoustic testing, and system calibration.<\/p>\r\n                    <\/div>\r\n                    <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"hidden-inputs\" style=\"display:none;\">\r\n        <input type=\"number\" id=\"manual-input\" value=\"0\">\r\n    <\/div>\r\n\r\n    <div class=\"lab-header\">\r\n        <div class=\"lab-title\">\r\n            <span>Liquid Audio Engine<\/span>\r\n            <h2>SONIC LAB <span style=\"color:#94a3b8; font-weight:300;\">V25.1<\/span><\/h2>\r\n        <\/div>\r\n        <div class=\"status-panel\">\r\n            <div class=\"led-ind\" id=\"led-indicator\"><\/div> <span id=\"status-text\">SYSTEM READY<\/span>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"digital-screen-container\" id=\"screen-container\">\r\n        <div class=\"screen-inner crt-off\" id=\"screen-inner\">\r\n            <canvas id=\"scope\"><\/canvas>\r\n            <div id=\"warning-overlay\">SELECT NOISE, SWEEP, FREQUENCY OR ENTER MANUALLY VALUE<\/div>\r\n            <div id=\"hz-overlay\">\r\n                <input type=\"text\" inputmode=\"decimal\" id=\"screen-input\" value=\"0 Hz\" \r\n                       onfocus=\"onHzFocus(this)\" \r\n                       onblur=\"onHzBlur(this)\" \r\n                       onchange=\"manualEntry(this.value)\">\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"meter-bridge\">\r\n        <div class=\"meter-row\">\r\n            <div class=\"meter-channel\">\r\n                <div class=\"meter-label\">L<\/div>\r\n                <div class=\"led-strip\" id=\"meter-l-strip\"><\/div>\r\n            <\/div>\r\n            <div class=\"meter-channel\">\r\n                <div class=\"meter-label\">R<\/div>\r\n                <div class=\"led-strip\" id=\"meter-r-strip\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <div class=\"meter-scale-row\">\r\n            <div class=\"meter-scale-half\"><span>-\u221e<\/span><span>-12<\/span><span>-6<\/span><span>-3<\/span><span>0<\/span><\/div>\r\n            <div class=\"meter-scale-half\"><span>-\u221e<\/span><span>-12<\/span><span>-6<\/span><span>-3<\/span><span>0<\/span><\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"controls-grid\">\r\n        <div class=\"panel-card\">\r\n            <div class=\"big-actions\">\r\n                <button id=\"btn-main\" class=\"pwr-btn btn-ready\" onclick=\"handleMainButton()\">ACTIVATE<\/button>\r\n                <button id=\"btn-stop\" class=\"pwr-btn btn-off\" onclick=\"handleSystemOff()\">SYSTEM OFF<\/button>\r\n            <\/div>\r\n\r\n            <span class=\"panel-head\" style=\"margin-top:20px;\">STEREO & VOLUME<\/span>\r\n            \r\n            <div style=\"display: flex; flex-direction: column; gap: 15px;\">\r\n                <div class=\"smoked-glass\">\r\n                    <div class=\"pan-display-row\" style=\"color:#38bdf8; font-weight:bold; margin-bottom: 2px;\"><span>MASTER GAIN dB<\/span><\/div>\r\n                    <input type=\"range\" class=\"magnet-slider\" id=\"vol-slider\" min=\"0\" max=\"1\" step=\"0.001\" value=\"0.25\" oninput=\"updVol(this.value)\">\r\n                    <div class=\"vol-scale-wrapper\" style=\"margin-top: 15px;\">\r\n                         <span class=\"tick text-glow-white\" style=\"left:0%\">-\u221e<\/span>\r\n                         <span class=\"tick text-glow-white\" style=\"left:25.1%\">-12<\/span>\r\n                         <span class=\"tick text-glow-white\" style=\"left:50.1%\">-6<\/span>\r\n                         <span class=\"tick text-glow-white\" style=\"left:75.1%\">-3<\/span>\r\n                         <span class=\"tick text-glow-white\" style=\"left:98%\">0<\/span>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"smoked-glass\" style=\"min-height: auto; padding-bottom: 15px;\">\r\n                    <div class=\"pan-display-row\"><span>PANNING<\/span><\/div>\r\n                    <div class=\"pan-wrapper\">\r\n                        <button class=\"pan-side-btn\" id=\"btn-pan-l\" onclick=\"panJump('L')\">\r\n                            <span class=\"pan-side-label\">L<\/span>\r\n                            <span class=\"pan-side-val\" id=\"pan-l-val\">50%<\/span>\r\n                        <\/button>\r\n                        <div class=\"pan-slider-container\">\r\n                             <div class=\"pan-center-marker\"><\/div>\r\n                             <input type=\"range\" class=\"magnet-slider\" id=\"pan-slider\" min=\"-1\" max=\"1\" step=\"0.1\" value=\"0\" oninput=\"updPan(this.value)\" style=\"width: 100%;\">\r\n                        <\/div>\r\n                        <button class=\"pan-side-btn\" id=\"btn-pan-r\" onclick=\"panJump('R')\">\r\n                            <span class=\"pan-side-label\">R<\/span>\r\n                            <span class=\"pan-side-val\" id=\"pan-r-val\">50%<\/span>\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"right-column-wrap\">\r\n            <div class=\"panel-card\">\r\n                 <span class=\"panel-head\" style=\"margin-bottom:10px; display:block; border-bottom: 1px solid var(--neon-blue); padding-bottom:5px;\">FREQUENCY TUNING<\/span>\r\n                 <span class=\"tech-sub\" style=\"margin-bottom:15px; margin-top:5px;\">\/\/ TAP FREQUENCY ON MAIN DISPLAY TO EDIT<\/span>\r\n\r\n                 <div style=\"display: flex; gap: 15px; align-items: flex-start; margin-bottom: 25px;\">\r\n                    <div class=\"smoked-glass\" style=\"flex-grow: 1; position: relative;\">\r\n                        <input type=\"range\" id=\"mag-slider\" class=\"magnet-slider\" min=\"0\" max=\"10000\" step=\"1\" value=\"0\" oninput=\"magnetSlide(this.value)\" style=\"width: 100%;\">\r\n                        <div class=\"scale-container\">\r\n                            <div id=\"ruler-lin\" class=\"scale-ruler active\">\r\n                                <span class=\"tick\" style=\"left: 0%\">0<\/span>\r\n                                <span class=\"tick\" style=\"left: 25%\">5k<\/span>\r\n                                <span class=\"tick\" style=\"left: 50%\">10k<\/span>\r\n                                <span class=\"tick\" style=\"left: 75%\">15k<\/span>\r\n                                <span class=\"tick\" style=\"left: 100%\">20k<\/span>\r\n                            <\/div>\r\n                            <div id=\"ruler-log\" class=\"scale-ruler\">\r\n                                 <span class=\"tick\" style=\"left: 0%; color:#ef4444\">LOG<\/span>\r\n                                 <span class=\"tick\" style=\"left: 23.2%\">100<\/span>\r\n                                 <span class=\"tick\" style=\"left: 56.6%\">1k<\/span>\r\n                                 <span class=\"tick\" style=\"left: 89.9%\">10k<\/span>\r\n                                 <span class=\"tick\" style=\"left: 100%\">20k<\/span>\r\n                            <\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                    \r\n                    <div style=\"display: flex; flex-direction: column; gap: 6px; width: 90px; flex-shrink: 0; margin-top: 5px;\">\r\n                        <div class=\"mus-screen\" style=\"width: 100%; height: 32px; margin: 0; font-size: 13px; font-weight: 900; color: var(--screen-ink);\" onclick=\"focusMainInput()\">\r\n                            <div id=\"freq-mini-disp\">0 Hz<\/div>\r\n                        <\/div>\r\n                        <button id=\"btn-scale-toggle\" class=\"tech-btn\" style=\"height: 24px; font-size: 10px;\" onclick=\"toggleScaleMode()\">LIN SCALE<\/button>\r\n                    <\/div>\r\n                 <\/div>\r\n\r\n                 <span class=\"panel-head\">WAVEFORM ENGINE<\/span>\r\n                 <span class=\"tech-sub\">\/\/ SOURCE TONE APPLIES TO ALL MODULES<\/span>\r\n                 \r\n                 <div class=\"wave-row\">\r\n                    <button class=\"tech-btn active w-btn\" id=\"btn-sine\" onclick=\"setWave('sine', this)\">\r\n                        <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 12 Q 8 2 12 12 T 22 12\" stroke-width=\"1.5\"\/><\/svg> SINE\r\n                    <\/button>\r\n                    <button class=\"tech-btn w-btn\" onclick=\"setWave('square', this)\">\r\n                        <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 20V4h9v16h9V4\" stroke-width=\"1.5\"\/><\/svg> SQR\r\n                    <\/button>\r\n                    <button class=\"tech-btn w-btn\" onclick=\"setWave('sawtooth', this)\">\r\n                        <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 20L22 4v16\" stroke-width=\"1.5\"\/><\/svg> SAW\r\n                    <\/button>\r\n                    <button class=\"tech-btn w-btn\" onclick=\"setWave('triangle', this)\">\r\n                        <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 20L12 4l10 16\" stroke-width=\"1.5\"\/><\/svg> TRI\r\n                    <\/button>\r\n                    <button id=\"btn-tone-toggle\" class=\"tech-btn sub-toggle sub-ready\" onclick=\"toggleTone()\" style=\"font-size: 10px !important; font-weight: 900 !important; letter-spacing: 1px;\">SIGNAL<\/button>\r\n                <\/div>\r\n\r\n                 <div class=\"panel-header-row\" style=\"margin-top: 25px;\">\r\n                     <span class=\"panel-head\">NOISE GENERATOR<\/span>\r\n                 <\/div>\r\n                 \r\n                 <div style=\"display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 0;\">\r\n                    <button class=\"tech-btn noise-btn noise-white\" onclick=\"setWave('white', this)\">\r\n                        <div>WHITE<\/div>\r\n                        <svg class=\"noise-icon\" viewBox=\"0 0 24 12\"><path d=\"M0,6 L2,9 L4,3 L6,8 L8,4 L10,7 L12,5 L14,9 L16,3 L18,8 L20,4 L22,7 L24,6\"\/><\/svg>\r\n                    <\/button>\r\n                    <button class=\"tech-btn noise-btn noise-pink\" onclick=\"setWave('pink', this)\">\r\n                        <div>PINK<\/div>\r\n                        <svg class=\"noise-icon\" viewBox=\"0 0 24 12\"><path d=\"M0,6 L2,9 L4,3 L6,8 L8,4 L10,7 L12,5 L14,9 L16,3 L18,8 L20,4 L22,7 L24,6\"\/><\/svg>\r\n                    <\/button>\r\n                    <button class=\"tech-btn noise-btn noise-blue\" onclick=\"setWave('blue', this)\">\r\n                        <div>BLUE<\/div>\r\n                        <svg class=\"noise-icon\" viewBox=\"0 0 24 12\"><path d=\"M0,6 L2,9 L4,3 L6,8 L8,4 L10,7 L12,5 L14,9 L16,3 L18,8 L20,4 L22,7 L24,6\"\/><\/svg>\r\n                    <\/button>\r\n                    \r\n                    <button class=\"tech-btn noise-btn noise-grey\" onclick=\"setWave('grey', this)\">\r\n                        <div>GREY<\/div>\r\n                        <svg class=\"noise-icon\" viewBox=\"0 0 24 12\"><path d=\"M0,6 L2,9 L4,3 L6,8 L8,4 L10,7 L12,5 L14,9 L16,3 L18,8 L20,4 L22,7 L24,6\"\/><\/svg>\r\n                    <\/button>\r\n                    <button class=\"tech-btn noise-btn noise-red\" onclick=\"setWave('red', this)\">\r\n                        <div>RED<\/div>\r\n                        <svg class=\"noise-icon\" viewBox=\"0 0 24 12\"><path d=\"M0,6 L2,9 L4,3 L6,8 L8,4 L10,7 L12,5 L14,9 L16,3 L18,8 L20,4 L22,7 L24,6\"\/><\/svg>\r\n                    <\/button>\r\n                    <button id=\"btn-noise-toggle\" class=\"tech-btn sub-toggle sub-ready\" onclick=\"toggleNoise()\" style=\"font-size: 10px !important; font-weight: 900 !important; letter-spacing: 1px;\">SIGNAL<\/button>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <div class=\"panel-card\">\r\n                <div class=\"panel-header-row\">\r\n                    <span class=\"panel-head\">SWEEP SIGNAL 20-20k Hz<\/span>\r\n                <\/div>\r\n                \r\n                <div style=\"display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 25px;\">\r\n                    <button id=\"btn-sweep-lin\" class=\"tech-btn w-btn-sweep\" onclick=\"armSweep('lin', this)\">\r\n                         <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 20 L22 4\" stroke-width=\"1.5\"\/><\/svg> LIN SWEEP\r\n                    <\/button>\r\n                    <button id=\"btn-sweep-log\" class=\"tech-btn w-btn-sweep\" onclick=\"armSweep('log', this)\">\r\n                         <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M4,20 Q12,20 20,4\" stroke-width=\"1.5\"\/><\/svg> LOG SWEEP\r\n                    <\/button>\r\n                    <button id=\"btn-sweep-toggle\" class=\"tech-btn sub-toggle sub-ready\" onclick=\"toggleSweep()\" style=\"font-size: 10px !important; font-weight: 900 !important; letter-spacing: 1px;\">SIGNAL<\/button>\r\n                <\/div>\r\n\r\n                <span class=\"panel-head\" style=\"margin-top: 25px;\">MUSICAL GENERATOR<\/span>\r\n                <div class=\"sub-unit\" style=\"border:1px solid #334155; margin-bottom:15px; padding:10px; background:linear-gradient(135deg, #1e293b, #0f172a);\">\r\n                    <div class=\"mus-screen\">\r\n                         <div class=\"mus-grid-display\">\r\n                             <div class=\"mus-cell\" id=\"mus-disp-oct\">OCT 4<\/div>\r\n                             <div class=\"mus-cell\" id=\"mus-disp-note\">READY<\/div>\r\n                             <div class=\"mus-cell\" id=\"mus-disp-freq\">0 Hz<\/div>\r\n                         <\/div>\r\n                    <\/div>\r\n                    <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap:5px;\">\r\n                         <button class=\"tech-btn sub-nav\" onclick=\"stepOctave(-1)\">- OCT<\/button>\r\n                         <button class=\"tech-btn sub-nav\" onclick=\"stepOctave(1)\">+ OCT<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"piano-wrapper\">\r\n                    <div class=\"key\" onclick=\"playNote(0)\">C<\/div><div class=\"key\" onclick=\"playNote(2)\">D<\/div><div class=\"key\" onclick=\"playNote(4)\">E<\/div>\r\n                    <div class=\"key\" onclick=\"playNote(5)\">F<\/div><div class=\"key\" onclick=\"playNote(7)\">G<\/div><div class=\"key\" onclick=\"playNote(9)\">A<\/div><div class=\"key\" onclick=\"playNote(11)\">B<\/div>\r\n                    <div class=\"key black\" style=\"left: 10%;\" onclick=\"playNote(1)\"><\/div><div class=\"key black\" style=\"left: 24%;\" onclick=\"playNote(3)\"><\/div>\r\n                    <div class=\"key black\" style=\"left: 53%;\" onclick=\"playNote(6)\"><\/div><div class=\"key black\" style=\"left: 67%;\" onclick=\"playNote(8)\"><\/div><div class=\"key black\" style=\"left: 81%;\" onclick=\"playNote(10)\"><\/div>\r\n                <\/div>\r\n\r\n                <div class=\"panel-card\" style=\"margin-bottom: 25px; background: rgba(0,0,0,0.2);\">\r\n                    <div style=\"display:flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #334155; padding-bottom: 5px; margin-bottom: 10px;\">\r\n                        <span class=\"panel-head\" style=\"margin:0; border:none; font-size: 10px;\">ENVELOPE & TUNING<\/span>\r\n                        <span class=\"tech-sub\" style=\"margin:0; font-size: 9px; color: var(--neon-blue);\">ADSR - GATE - TUNE<\/span>\r\n                    <\/div>\r\n\r\n                    <div style=\"display: flex; justify-content: space-around; gap: 2px; flex-wrap: wrap; margin-bottom: 10px;\">\r\n                        \r\n                        <div class=\"knob-wrapper\">\r\n                            <span class=\"knob-label\">ATTACK<\/span>\r\n                            <div class=\"knob-container\" id=\"knob-att\">\r\n                                <div class=\"knob-ring\" id=\"ring-att\"><\/div>\r\n                                <div class=\"knob-cap\" id=\"cap-att\"><div class=\"knob-indicator\"><\/div><\/div>\r\n                            <\/div>\r\n                            <span class=\"knob-val-display\" id=\"val-att\">0.05s<\/span>\r\n                        <\/div>\r\n\r\n                        <div class=\"knob-wrapper\">\r\n                            <span class=\"knob-label\">DECAY<\/span>\r\n                            <div class=\"knob-container\" id=\"knob-dec\">\r\n                                <div class=\"knob-ring\" id=\"ring-dec\"><\/div>\r\n                                <div class=\"knob-cap\" id=\"cap-dec\"><div class=\"knob-indicator\"><\/div><\/div>\r\n                            <\/div>\r\n                            <span class=\"knob-val-display\" id=\"val-dec\">0.1s<\/span>\r\n                        <\/div>\r\n\r\n                        <div class=\"knob-wrapper\">\r\n                            <span class=\"knob-label\">SUSTAIN<\/span>\r\n                            <div class=\"knob-container\" id=\"knob-sus\">\r\n                                <div class=\"knob-ring\" id=\"ring-sus\"><\/div>\r\n                                <div class=\"knob-cap\" id=\"cap-sus\"><div class=\"knob-indicator\"><\/div><\/div>\r\n                            <\/div>\r\n                            <span class=\"knob-val-display\" id=\"val-sus\">50%<\/span>\r\n                        <\/div>\r\n\r\n                        <div class=\"knob-wrapper\">\r\n                            <span class=\"knob-label\">RELEASE<\/span>\r\n                            <div class=\"knob-container\" id=\"knob-rel\">\r\n                                <div class=\"knob-ring\" id=\"ring-rel\"><\/div>\r\n                                <div class=\"knob-cap\" id=\"cap-rel\"><div class=\"knob-indicator\"><\/div><\/div>\r\n                            <\/div>\r\n                            <span class=\"knob-val-display\" id=\"val-rel\">0.5s<\/span>\r\n                        <\/div>\r\n\r\n                        <div class=\"knob-wrapper\">\r\n                            <span class=\"knob-label\">GATE<\/span>\r\n                            <div class=\"knob-container\" id=\"knob-gate\">\r\n                                <div class=\"knob-ring\" id=\"ring-gate\"><\/div>\r\n                                <div class=\"knob-cap\" id=\"cap-gate\"><div class=\"knob-indicator\"><\/div><\/div>\r\n                            <\/div>\r\n                            <span class=\"knob-val-display\" id=\"val-gate\">0.5s<\/span>\r\n                        <\/div>\r\n\r\n                        <div class=\"knob-wrapper\">\r\n                            <span class=\"knob-label\">TUNE<\/span>\r\n                            <div class=\"knob-container\" id=\"knob-tune\">\r\n                                <div class=\"knob-ring\" id=\"ring-tune\"><\/div>\r\n                                <div class=\"knob-cap\" id=\"cap-tune\"><div class=\"knob-indicator\"><\/div><\/div>\r\n                            <\/div>\r\n                            <span class=\"knob-val-display\" id=\"val-tune\">440Hz<\/span>\r\n                        <\/div>\r\n\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <span class=\"panel-head\">ISO STANDARDS & RTA ANALYZER<\/span>\r\n                <div class=\"sub-unit\" style=\"margin-bottom: 25px; padding: 10px;\">\r\n                    <div class=\"rta-screen\">\r\n                        <canvas id=\"iso-analyzer-canvas\" style=\"width: 100%; height: 100%;\"><\/canvas>\r\n                        <div id=\"iso-status\">RTA ANALYZER<\/div>\r\n                    <\/div>\r\n                    \r\n                    <div class=\"rta-controls-row\" style=\"display: grid; grid-template-columns: 1fr 2fr 1fr 2fr; gap: 8px;\">\r\n                        <button class=\"tech-btn sub-nav\" onclick=\"stepIso(-1)\" style=\"font-size: 26px !important; font-weight: 900 !important;\">-<\/button>\r\n                        <div class=\"mus-screen\" style=\"margin: 0; flex-direction: column; justify-content: center;\">\r\n                            <div id=\"iso-hz-val\" class=\"mus-text-ink\" style=\"font-size: 18px;\">1.000 kHz<\/div>\r\n                        <\/div>\r\n                        <button class=\"tech-btn sub-nav\" onclick=\"stepIso(1)\" style=\"font-size: 26px !important; font-weight: 900 !important;\">+<\/button>\r\n                        <button class=\"tech-btn sub-toggle sub-ready\" id=\"btn-iso-toggle\" onclick=\"toggleIso()\">SIGNAL<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <span class=\"panel-head\">SUBWOOFER MATRIX<\/span>\r\n                <div class=\"sub-unit\">\r\n                    <div style=\"display: grid; grid-template-columns: 1fr 2fr 1fr; gap: 8px; margin-bottom: 8px;\">\r\n                        <div class=\"sub-screen\" style=\"grid-column: 1 \/ 3; height: 70px; margin-bottom: 0;\">\r\n                            <canvas id=\"sub-scope-canvas\"><\/canvas>\r\n                            <div id=\"sub-status\">LFE READY<\/div>\r\n                            <div id=\"sub-invert-status\">INVERT PHASE<\/div>\r\n                        <\/div>\r\n                        <div class=\"mus-screen\" style=\"grid-column: 3 \/ 4; height: 70px; margin-bottom: 0; flex-direction: column; justify-content: center;\">\r\n                            <div id=\"sub-hz-val\">50 Hz<\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n\r\n                    <div class=\"sub-controls-row\" style=\"display: grid; grid-template-columns: 1fr 1fr 2fr; gap: 8px;\">\r\n                        <button class=\"tech-btn sub-nav\" onclick=\"stepSub(-1)\" style=\"font-size: 26px !important; font-weight: 900 !important;\">-<\/button>\r\n                        <button class=\"tech-btn sub-nav\" onclick=\"stepSub(1)\" style=\"font-size: 26px !important; font-weight: 900 !important;\">+<\/button>\r\n                        <button class=\"tech-btn sub-toggle sub-ready\" id=\"btn-sub-toggle\" onclick=\"toggleSub()\">SIGNAL<\/button>\r\n                    <\/div>\r\n\r\n                    <div style=\"flex: 1; margin-bottom:8px; margin-top:5px;\" class=\"smoked-glass\">\r\n                        <div class=\"pan-display-row\" style=\"color:#64748b; margin-bottom: 4px;\"><span>SUB TRIM<\/span> <span id=\"sub-trim-val\" class=\"text-glow-white\">0.0 dB<\/span><\/div>\r\n                        \r\n                        <input type=\"range\" class=\"magnet-slider\" id=\"sub-trim-slider\" min=\"-12\" max=\"6\" step=\"1\" value=\"0\" oninput=\"updSubTrim(this.value)\">\r\n                        \r\n                        <div class=\"vol-scale-wrapper\" style=\"margin-top: 4px; height: 20px;\">\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:2%; font-size:9px;\">-12<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:11%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:22%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:33%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:44%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:55%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:66%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:77%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:88%; font-size:6px; top:12px;\">.<\/span>\r\n                             <span class=\"vol-tick text-glow-white\" style=\"left:98%; font-size:9px;\">+6<\/span>\r\n                        <\/div>\r\n                    <\/div>\r\n\r\n                    <div style=\"display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;\">\r\n                        <button class=\"tech-btn\" onclick=\"setSubHz(40)\" style=\"height: 30px !important;\">40 Hz<\/button>\r\n                        <button class=\"tech-btn\" onclick=\"setSubHz(60)\" style=\"height: 30px !important;\">60 Hz<\/button>\r\n                        <button class=\"tech-btn\" onclick=\"setSubHz(80)\" style=\"height: 30px !important;\">80 Hz<\/button>\r\n                        <button class=\"tech-btn\" onclick=\"setSubHz(120)\" style=\"height: 30px !important;\">120 Hz<\/button>\r\n                    <\/div>\r\n                    \r\n                    <div style=\"display: grid; grid-template-columns: 1.2fr 1.2fr 0.8fr 0.8fr; gap: 6px; margin-top:8px;\">\r\n                        <button class=\"tech-btn w-btn-sweep\" id=\"btn-sub-sweep\" onclick=\"armSubSweep()\">\r\n                            <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 20 L22 4\" stroke-width=\"1.5\"\/><\/svg>\r\n                            LFE SWEEP\r\n                        <\/button>\r\n                        <button class=\"tech-btn\" onclick=\"playSubKick()\">\r\n                            <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M2 12 L 5 12 L 8 4 L 12 20 L 15 12 L 22 12\" stroke-width=\"1.5\" stroke-linejoin=\"round\"\/><\/svg>\r\n                            KICK <span id=\"kick-btn-val\" style=\"margin-left:2px; font-size:9px; color:var(--neon-blue);\">50<\/span>\r\n                        <\/button>\r\n                        <button class=\"tech-btn sub-phase\" id=\"btn-sub-phase\" onclick=\"togglePhase()\">\r\n                            <span style=\"font-size: 14px; margin-right: 2px;\">\u00d8<\/span> INV\r\n                        <\/button>\r\n                        <button class=\"tech-btn\" id=\"btn-sub-drive\" onclick=\"toggleSubDrive()\">DRIVE<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<script>\r\n    const LED_COUNT = 20;\r\n    const SMOOTHING = 0.05; \r\n    \r\n    let actx, osc, gain, pan, anal, noise;\r\n    let isSystemOn = false; \r\n    let isSignalOn = false; \r\n    let activeModule = 'none'; \r\n    \r\n    let curWave = 'sine';\r\n    let safeVol = 0.25;\r\n    let highGainConfirmed = false;\r\n    let pendingVol = 0.25;\r\n    let sweepTimer = null;\r\n    let sweepMode = null;\r\n    let selectedSweepMode = null;\r\n    let moduleStopTimer = null; \r\n    \r\n    let scaleMode = 'lin'; \r\n    let currentOctave = 4;\r\n    let currentFreq = 0;\r\n    let concertPitch = 440; \r\n    let stopTimer;\r\n    \r\n    let isTurningOff = false; \r\n    let offStartTime = 0;\r\n    \r\n    let subFreq = 50;\r\n    let phasePolarity = 1;\r\n    let subTrim = 1.0;\r\n    let isSubDriveActive = false;\r\n    let subDriveNode = null;\r\n    \r\n    const isoFreqs = [20, 32, 64, 125, 250, 500, 1000, 2000, 4000, 8000, 16000, 20000];\r\n    let isoIndex = 6; \r\n    \r\n    let displayToast = null;\r\n    let toastTimer = null;\r\n    \r\n    let rtaData; \r\n    let startupVuLevel = 0;\r\n\r\n    let adsr = {\r\n        a: 0.05, \r\n        d: 0.1,  \r\n        s: 0.5,  \r\n        r: 0.5   \r\n    };\r\n    let activeVoices = []; \r\n\r\n    \/\/ --- KNOB SETUP ---\r\n    let knobs = {\r\n        att: { val: 0.05, min: 0.01, max: 2, step: 0.01, unit: 's', param: 'a' },\r\n        dec: { val: 0.1, min: 0.01, max: 2, step: 0.01, unit: 's', param: 'd' },\r\n        sus: { val: 0.5, min: 0, max: 1, step: 0.05, unit: '%', param: 's' },\r\n        rel: { val: 0.5, min: 0.05, max: 5, step: 0.05, unit: 's', param: 'r' },\r\n        gate: { val: 0.5, min: 0.1, max: 5, step: 0.1, unit: 's', param: 'gate' },\r\n        tune: { val: 440, min: 430, max: 450, step: 1, unit: 'Hz', param: 'tune' }\r\n    };\r\n    \r\n    let activeKnobId = null;\r\n\r\n    function initKnobs() {\r\n        ['att', 'dec', 'sus', 'rel', 'gate', 'tune'].forEach(id => {\r\n            let el = document.getElementById('knob-' + id);\r\n            \r\n            \/\/ Mouse events for desktop (Drag up\/down)\r\n            el.addEventListener('mousedown', (e) => startKnobDrag(e, id));\r\n            \r\n            \/\/ Touch events for mobile (Popup trigger)\r\n            el.addEventListener('touchstart', (e) => {\r\n                e.preventDefault(); \r\n                openKnobPopup(id);  \r\n            }, {passive: false});\r\n            \r\n            updateKnobVisual(id);\r\n        });\r\n    }\r\n\r\n    let knobStartY = 0;\r\n    let knobStartVal = 0;\r\n    let currentDragKnob = null;\r\n\r\n    function startKnobDrag(e, id) {\r\n        if(!isSystemOn) return;\r\n        \/\/ On desktop, we use drag. Prevent click event triggering popup if dragged\r\n        e.preventDefault(); \r\n        currentDragKnob = id;\r\n        knobStartY = e.clientY;\r\n        knobStartVal = knobs[id].val;\r\n        \r\n        document.addEventListener('mousemove', handleKnobMove);\r\n        document.addEventListener('mouseup', endKnobDrag);\r\n    }\r\n\r\n    function handleKnobMove(e) {\r\n        if (!currentDragKnob) return;\r\n        let id = currentDragKnob;\r\n        let conf = knobs[id];\r\n        let delta = (knobStartY - e.clientY); \/\/ Up is positive\r\n        let range = conf.max - conf.min;\r\n        let change = (delta \/ 150) * range; \/\/ Sensitivity\r\n        \r\n        let newVal = knobStartVal + change;\r\n        if(newVal < conf.min) newVal = conf.min;\r\n        if(newVal > conf.max) newVal = conf.max;\r\n        \r\n        \/\/ Snap to step\r\n        newVal = Math.round(newVal \/ conf.step) * conf.step;\r\n        \r\n        knobs[id].val = newVal;\r\n        \r\n        \/\/ Specific logic per parameter\r\n        if (['a','d','s','r'].includes(conf.param)) {\r\n            adsr[conf.param] = newVal;\r\n        } else if (conf.param === 'tune') {\r\n            concertPitch = parseInt(newVal);\r\n        }\r\n        \r\n        updateKnobVisual(id);\r\n    }\r\n\r\n    function endKnobDrag() {\r\n        currentDragKnob = null;\r\n        document.removeEventListener('mousemove', handleKnobMove);\r\n        document.removeEventListener('mouseup', endKnobDrag);\r\n    }\r\n\r\n    function updateKnobVisual(id) {\r\n        let conf = knobs[id];\r\n        let pct = (conf.val - conf.min) \/ (conf.max - conf.min);\r\n        \/\/ Angle: -135deg to +135deg (270deg total)\r\n        let angle = -135 + (pct * 270);\r\n        \r\n        document.getElementById('cap-' + id).style.transform = `rotate(${angle}deg)`;\r\n        \r\n        let disp = conf.unit === '%' ? Math.round(conf.val * 100) : (conf.unit === 'Hz' ? Math.round(conf.val) : conf.val.toFixed(2));\r\n        document.getElementById('val-' + id).innerText = disp + conf.unit;\r\n    }\r\n\r\n    \/\/ --- MOBILE POPUP LOGIC ---\r\n    function openKnobPopup(id) {\r\n        if(!isSystemOn || currentDragKnob) return; \r\n        if(window.innerWidth > 900) return; \r\n\r\n        activeKnobId = id;\r\n        let conf = knobs[id];\r\n        let popup = document.getElementById('mobile-knob-editor');\r\n        let slider = document.getElementById('mobile-slider');\r\n        \r\n        document.getElementById('mobile-knob-title').innerText = id.toUpperCase();\r\n        \r\n        slider.min = conf.min;\r\n        slider.max = conf.max;\r\n        slider.step = conf.step;\r\n        slider.value = conf.val;\r\n        \r\n        slider.oninput = function() {\r\n            let v = parseFloat(this.value);\r\n            knobs[activeKnobId].val = v;\r\n            \r\n            let p = conf.param;\r\n            if (['a','d','s','r'].includes(p)) {\r\n                adsr[p] = v;\r\n            } else if (p === 'tune') {\r\n                concertPitch = parseInt(v);\r\n            }\r\n            \r\n            updateKnobVisual(activeKnobId);\r\n            \r\n            let disp = conf.unit === '%' ? Math.round(v * 100) : (conf.unit === 'Hz' ? Math.round(v) : v.toFixed(2));\r\n            document.getElementById('mobile-knob-val').innerText = disp + conf.unit;\r\n        };\r\n        \r\n        let disp = conf.unit === '%' ? Math.round(conf.val * 100) : (conf.unit === 'Hz' ? Math.round(conf.val) : conf.val.toFixed(2));\r\n        document.getElementById('mobile-knob-val').innerText = disp + conf.unit;\r\n\r\n        document.getElementById('popup-closer').style.display = 'block';\r\n        popup.style.display = 'flex';\r\n    }\r\n\r\n    function closePopup() {\r\n        document.getElementById('mobile-knob-editor').style.display = 'none';\r\n        document.getElementById('popup-closer').style.display = 'none';\r\n        activeKnobId = null;\r\n    }\r\n\r\n    \/\/ --- MAIN AUDIO LOGIC ---\r\n\r\n    function buildMeters() {\r\n        const lStrip = document.getElementById('meter-l-strip');\r\n        const rStrip = document.getElementById('meter-r-strip');\r\n        lStrip.innerHTML = ''; rStrip.innerHTML = '';\r\n        for(let i=0; i<LED_COUNT; i++) {\r\n            let led = document.createElement('div');\r\n            led.className = 'led-seg';\r\n            lStrip.appendChild(led.cloneNode(true));\r\n            rStrip.appendChild(led.cloneNode(true));\r\n        }\r\n    }\r\n    buildMeters();\r\n    \r\n    function makeDistortionCurve() {\r\n        let k = 100;\r\n        let n_samples = 44100;\r\n        let curve = new Float32Array(n_samples);\r\n        let deg = Math.PI \/ 180;\r\n        for (let i = 0; i < n_samples; ++i ) {\r\n            let x = i * 2 \/ n_samples - 1;\r\n            curve[i] = ( 3 + k ) * x * 20 * deg \/ ( Math.PI + k * Math.abs(x) );\r\n        }\r\n        return curve;\r\n    }\r\n\r\n    function init() {\r\n        if (!actx) {\r\n            actx = new (window.AudioContext || window.webkitAudioContext)();\r\n            gain = actx.createGain();\r\n            pan = actx.createStereoPanner();\r\n            anal = actx.createAnalyser();\r\n            anal.fftSize = 4096; \r\n            anal.smoothingTimeConstant = 0.8; \r\n            anal.minDecibels = -100; \r\n            anal.maxDecibels = 0;       \r\n            rtaData = new Uint8Array(anal.frequencyBinCount);\r\n            subDriveNode = actx.createWaveShaper();\r\n            subDriveNode.curve = makeDistortionCurve(); \r\n            gain.connect(pan);\r\n            pan.connect(anal);\r\n            anal.connect(actx.destination);\r\n            loopVis();\r\n            \r\n            initKnobs(); \/\/ Initialize Knobs\r\n        }\r\n        if (actx.state === 'suspended') actx.resume();\r\n    }\r\n    \r\n    function isSubPlaying() { return activeModule === 'sub' || activeModule === 'sub-sweep-running' || activeModule === 'sub-kick'; }\r\n    function isIsoPlaying() { return activeModule === 'iso'; }\r\n\r\n    function getActualVol() {\r\n        return safeVol * phasePolarity * (isSubPlaying() ? subTrim : 1.0);\r\n    }\r\n\r\n    function showToast(msg) {\r\n        displayToast = msg;\r\n        document.getElementById('screen-input').value = msg;\r\n        if(toastTimer) clearTimeout(toastTimer);\r\n        toastTimer = setTimeout(() => {\r\n            displayToast = null;\r\n            updateDisplay(); \r\n        }, 1500); \r\n    }\r\n\r\n    function killCurrentAudio() {\r\n        clearTimeout(moduleStopTimer);\r\n        if(osc) { try{osc.stop();osc.disconnect();}catch(e){} osc=null; }\r\n        if(noise) { try{noise.stop();noise.disconnect();}catch(e){} noise=null; }\r\n    }\r\n\r\n    function resetSignalButtons() {\r\n        let toggles = ['btn-tone-toggle', 'btn-noise-toggle', 'btn-sweep-toggle', 'btn-iso-toggle', 'btn-sub-toggle'];\r\n        toggles.forEach(id => {\r\n            let btn = document.getElementById(id);\r\n            if(btn) {\r\n                btn.classList.remove('sub-active');\r\n                btn.classList.add('sub-ready');\r\n                btn.innerText = \"SIGNAL\";\r\n            }\r\n        });\r\n    }\r\n\r\n    function updateMasterButton() {\r\n        let mainBtn = document.getElementById('btn-main');\r\n        \r\n        if (!isSystemOn) {\r\n            mainBtn.innerText = \"ACTIVATE\"; \r\n            mainBtn.classList.remove('btn-mute', 'btn-on');\r\n            mainBtn.classList.add('btn-ready'); \r\n        } \r\n        else {\r\n            mainBtn.classList.remove('btn-ready');\r\n            if (isSignalOn) {\r\n                if (activeModule === 'iso') mainBtn.innerText = \"ISO & RTS\";\r\n                else if (isSubPlaying()) mainBtn.innerText = \"SUB\";\r\n                else mainBtn.innerText = \"MUTE\"; \r\n                mainBtn.classList.remove('btn-on');\r\n                mainBtn.classList.add('btn-mute'); \r\n            } \r\n            else {\r\n                mainBtn.innerText = \"SIGNAL\"; \r\n                mainBtn.classList.remove('btn-mute');\r\n                mainBtn.classList.add('btn-on'); \r\n            }\r\n        }\r\n    }\r\n\r\n    function switchModuleTo(modName) {\r\n        killCurrentAudio();\r\n        clearInterval(sweepTimer);\r\n        clearTimeout(stopTimer);\r\n        activeModule = modName;\r\n        isSignalOn = true;\r\n        resetSignalButtons();\r\n    }\r\n\r\n    function silencePiano() {\r\n        if(osc) { try{osc.stop(); osc.disconnect();}catch(e){} osc=null; }\r\n        if(noise) { try{noise.stop(); noise.disconnect();}catch(e){} noise=null; }\r\n        isSignalOn = false;\r\n        changeFreq(0); \r\n        updateDisplay();\r\n        updateMasterButton();\r\n    }\r\n\r\n    function stopAllModules() {\r\n        if (!actx) return;\r\n        const now = actx.currentTime;\r\n\r\n        activeVoices.forEach(voice => {\r\n            try {\r\n                voice.gain.gain.cancelScheduledValues(now);\r\n                voice.gain.gain.setValueAtTime(voice.gain.gain.value, now);\r\n                voice.gain.gain.linearRampToValueAtTime(0, now + 0.1); \r\n                voice.osc.stop(now + 0.15);\r\n            } catch(e) {}\r\n        });\r\n        activeVoices = []; \r\n\r\n        clearInterval(sweepTimer);\r\n        clearTimeout(stopTimer);\r\n        clearTimeout(moduleStopTimer);\r\n        \r\n        selectedSweepMode = null; \r\n\r\n        if (gain) {\r\n            gain.gain.cancelScheduledValues(now);\r\n            gain.gain.setValueAtTime(gain.gain.value, now);\r\n            gain.gain.linearRampToValueAtTime(0, now + 0.15); \r\n        }\r\n\r\n        isSignalOn = false;\r\n        activeModule = 'none';\r\n        resetSignalButtons();\r\n        updateMasterButton(); \r\n\r\n        document.getElementById('status-text').innerText = \"SYSTEM ACTIVE\";\r\n        document.getElementById('status-text').style.color = \"#38bdf8\";\r\n        \r\n        document.getElementById('sub-status').innerText = \"LFE READY\";\r\n        document.getElementById('sub-status').style.color = \"#64748b\";\r\n        \r\n        document.getElementById('iso-status').innerText = \"RTA ANALYZER\";\r\n        document.getElementById('iso-status').style.color = \"#64748b\";\r\n        \r\n        document.getElementById('btn-sub-sweep').classList.remove('active');\r\n\r\n        document.querySelectorAll('.w-btn-sweep:not(#btn-sub-sweep)').forEach(b => b.classList.remove('active'));\r\n        \r\n        if (scaleMode !== 'lin') toggleScaleMode();\r\n        changeFreq(0);\r\n        updateDisplay(); \r\n\r\n        moduleStopTimer = setTimeout(() => {\r\n            if(osc) { try{osc.stop(); osc.disconnect();}catch(e){} osc=null; }\r\n            if(noise) { try{noise.stop(); noise.disconnect();}catch(e){} noise=null; }\r\n        }, 200);\r\n    }\r\n\r\n    function handleMainButton() {\r\n        init();\r\n        if (!isSystemOn) {\r\n            isSystemOn = true;\r\n            isTurningOff = false; \r\n            document.getElementById('sonic-lab-v25').classList.remove('sys-off');\r\n            document.getElementById('screen-inner').classList.remove('crt-off'); \r\n            document.getElementById('screen-inner').classList.add('crt-on'); \r\n            document.getElementById('led-indicator').classList.add('active');\r\n            document.getElementById('status-text').innerText = \"SYSTEM ACTIVE\";\r\n            document.getElementById('status-text').style.color = \"#38bdf8\"; \r\n            document.getElementById('btn-stop').classList.remove('active');\r\n            document.getElementById('hz-overlay').style.display = ''; \r\n            updateMasterButton(); \r\n            updateDisplay();\r\n            startupVuLevel = 1.0;\r\n        } \r\n        else if (!isSignalOn) {\r\n            if (selectedSweepMode) runSweepLogic(selectedSweepMode);\r\n            else if (activeModule === 'iso') toggleIso();\r\n            else if (activeModule === 'sub' || activeModule === 'sub-sweep-running' || activeModule === 'sub-sweep-armed' || activeModule === 'sub-kick') toggleSub();\r\n            else if (activeModule === 'noise' || isNoise(curWave)) toggleNoise();\r\n            else toggleTone();\r\n        }\r\n        else {\r\n            stopAllModules(); \r\n        }\r\n    }\r\n\r\n    function showWarning() {\r\n        const warn = document.getElementById('warning-overlay');\r\n        warn.classList.add('show');\r\n        setTimeout(() => warn.classList.remove('show'), 4000);\r\n    }\r\n\r\n    function handleSystemOff() {\r\n        if (!isSystemOn) return; \r\n        stopAllModules();\r\n        isTurningOff = true; \r\n        offStartTime = Date.now();\r\n        document.getElementById('screen-inner').classList.remove('crt-on'); \r\n        document.getElementById('hz-overlay').style.display = 'none'; \r\n        document.getElementById('sonic-lab-v25').classList.add('sys-off');\r\n\r\n        setTimeout(() => {\r\n            isSystemOn = false;\r\n            isTurningOff = false;\r\n            resetSystemState(); \r\n            document.getElementById('led-indicator').classList.remove('active');\r\n            document.getElementById('status-text').innerText = \"SYSTEM READY\";\r\n            document.getElementById('status-text').style.color = \"#64748b\";\r\n            document.getElementById('btn-stop').classList.remove('active');\r\n            document.getElementById('hz-overlay').style.display = ''; \r\n            updateMasterButton(); \r\n        }, 3000); \r\n    }\r\n\r\n    function resetSystemState() {\r\n        curWave = 'sine';\r\n        currentFreq = 0;\r\n        selectedSweepMode = null;\r\n        sweepMode = null;\r\n        activeModule = 'none';\r\n        \r\n        subFreq = 50;\r\n        document.getElementById('sub-hz-val').innerText = \"50 Hz\";\r\n        document.getElementById('kick-btn-val').innerText = \"50\";\r\n        document.getElementById('btn-sub-drive').classList.remove('active');\r\n        document.getElementById('sub-status').innerText = \"LFE READY\";\r\n        document.getElementById('sub-status').style.color = \"#64748b\";\r\n        \r\n        isoIndex = 6;\r\n        document.getElementById('iso-hz-val').innerText = \"1.000 kHz\";\r\n        \r\n        phasePolarity = 1;\r\n        document.getElementById('btn-sub-phase').classList.remove('active');\r\n        document.getElementById('sub-invert-status').style.display = 'none';\r\n        \r\n        document.querySelectorAll('.w-btn').forEach(b => b.classList.remove('active'));\r\n        document.getElementById('btn-sine').classList.add('active'); \r\n        document.querySelectorAll('.w-btn-sweep').forEach(b => b.classList.remove('active'));\r\n        document.querySelectorAll('.noise-btn').forEach(b => b.classList.remove('active')); \r\n        \r\n        if(scaleMode !== 'lin') toggleScaleMode(); \r\n        document.getElementById('mag-slider').value = 0;\r\n        document.getElementById('screen-input').value = \"0 Hz\";\r\n        \r\n        updateMusicalDisplay(-1);\r\n        updateLEDs(0);\r\n        displayToast = null;\r\n        updateDisplay(); \r\n        document.querySelector('#btn-pan-l .pan-side-label').innerText = \"L\";\r\n        document.querySelector('#btn-pan-r .pan-side-label').innerText = \"R\";\r\n        \r\n        \/\/ Reset Knobs\r\n        knobs.att.val = 0.05; updateKnobVisual('att');\r\n        knobs.dec.val = 0.1; updateKnobVisual('dec');\r\n        knobs.sus.val = 0.5; updateKnobVisual('sus');\r\n        knobs.rel.val = 0.5; updateKnobVisual('rel');\r\n        knobs.gate.val = 0.5; updateKnobVisual('gate');\r\n        knobs.tune.val = 440; updateKnobVisual('tune');\r\n        \r\n        adsr = { a:0.05, d:0.1, s:0.5, r:0.5 };\r\n        concertPitch = 440;\r\n    }\r\n\r\n    function isNoise(w) { return ['white','pink','blue','grey','brown','red'].includes(w); }\r\n\r\n    function createOsc() {\r\n        osc = actx.createOscillator();\r\n        osc.type = curWave;\r\n        osc.frequency.value = isSubPlaying() ? subFreq : (isIsoPlaying() ? isoFreqs[isoIndex] : currentFreq);\r\n        if (isSubPlaying() && isSubDriveActive) {\r\n            osc.connect(subDriveNode);\r\n            subDriveNode.connect(gain);\r\n        } else {\r\n            osc.connect(gain);\r\n        }\r\n    }\r\n\r\n    function createNoise() {\r\n        let bufSize = 2 * actx.sampleRate;\r\n        let buf = actx.createBuffer(1, bufSize, actx.sampleRate);\r\n        let data = buf.getChannelData(0);\r\n        if (curWave === 'white') { for(let i=0; i<bufSize; i++) data[i] = Math.random() * 2 - 1; } \r\n        else if (curWave === 'pink') { \r\n            let b0=0,b1=0,b2=0,b3=0,b4=0,b5=0,b6=0;\r\n            for(let i=0; i<bufSize; i++) {\r\n                let w = Math.random()*2-1;\r\n                b0 = 0.99886*b0+w*0.0555179; b1 = 0.99332*b1+w*0.0750759; b2 = 0.96900*b2+w*0.1538520;\r\n                b3 = 0.86650*b3+w*0.3104856; b4 = 0.55000*b4+w*0.5329522; b5 = -0.7616*b5-w*0.0168980;\r\n                data[i] = b0+b1+b2+b3+b4+b5+b6+w*0.5362; data[i] *= 0.11; b6 = w*0.115926;\r\n            }\r\n        }\r\n        else if (curWave === 'red') { \r\n            let lastOut = 0;\r\n            for(let i=0; i<bufSize; i++) {\r\n                let white = Math.random() * 2 - 1;\r\n                lastOut = (lastOut + (0.02 * white)) \/ 1.02; \r\n                let out = lastOut * 3.0; \r\n                if(out > 1) out = 1; if(out < -1) out = -1;\r\n                data[i] = out * 0.5; \r\n            }\r\n        }\r\n        else if (curWave === 'blue') {\r\n             let lastIn = 0;\r\n             for(let i=0; i<bufSize; i++) {\r\n                 let white = Math.random() * 2 - 1;\r\n                 data[i] = (white - lastIn) * 0.5;\r\n                 lastIn = white;\r\n             }\r\n        }\r\n        else if (curWave === 'grey') {\r\n            let lastOut = 0;\r\n            for(let i=0; i<bufSize; i++) {\r\n                let white = Math.random() * 2 - 1;\r\n                lastOut = (lastOut + (0.02 * white)) \/ 1.02;\r\n                data[i] = (white * 0.3) + (lastOut * 3.0);\r\n                data[i] *= 0.5; \r\n            }\r\n        }\r\n        noise = actx.createBufferSource();\r\n        noise.buffer = buf;\r\n        noise.loop = true;\r\n        noise.connect(gain);\r\n    }\r\n\r\n    function startSound() {\r\n        killCurrentAudio(); \r\n        const now = actx.currentTime;\r\n        gain.gain.cancelScheduledValues(now);\r\n        gain.gain.setValueAtTime(0, now);\r\n        \r\n        if (isNoise(curWave)) {\r\n            createNoise();\r\n            noise.start(now);\r\n        } else {\r\n            createOsc();\r\n            osc.start(now);\r\n        }\r\n        \r\n        gain.gain.linearRampToValueAtTime(getActualVol(), now + 0.05);\r\n        updateDisplay(); \r\n        updateMasterButton(); \r\n    }\r\n\r\n    function toggleTone() {\r\n        if (!isSystemOn) return;\r\n        if (activeModule === 'tone') stopAllModules();\r\n        else {\r\n            if (currentFreq === 0 && !isNoise(curWave)) { showWarning(); return; }\r\n            switchModuleTo('tone');\r\n            let btn = document.getElementById('btn-tone-toggle');\r\n            btn.classList.remove('sub-ready');\r\n            btn.classList.add('sub-active');\r\n            btn.innerText = \"STOP\";\r\n            document.getElementById('status-text').innerText = \"TONE LIVE\";\r\n            document.getElementById('status-text').style.color = \"#ef4444\";\r\n            if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n            startSound();\r\n        }\r\n    }\r\n\r\n    function toggleNoise() {\r\n        if (!isSystemOn) return;\r\n        if (activeModule === 'noise') stopAllModules();\r\n        else {\r\n            switchModuleTo('noise');\r\n            let btn = document.getElementById('btn-noise-toggle');\r\n            btn.classList.remove('sub-ready');\r\n            btn.classList.add('sub-active');\r\n            btn.innerText = \"STOP\";\r\n            document.getElementById('status-text').innerText = \"NOISE LIVE\";\r\n            document.getElementById('status-text').style.color = \"#ef4444\";\r\n            if (!isNoise(curWave)) setWave('white', document.querySelector('.noise-white'));\r\n            startSound();\r\n        }\r\n    }\r\n\r\n    function toggleSweep() {\r\n        if (!isSystemOn) return;\r\n        if (activeModule === 'sweep') stopAllModules();\r\n        else {\r\n            switchModuleTo('sweep');\r\n            let btn = document.getElementById('btn-sweep-toggle');\r\n            btn.classList.remove('sub-ready');\r\n            btn.classList.add('sub-active');\r\n            btn.innerText = \"STOP\";\r\n            document.getElementById('status-text').innerText = \"SWEEP LIVE\";\r\n            document.getElementById('status-text').style.color = \"#ef4444\";\r\n            if (!selectedSweepMode) {\r\n                selectedSweepMode = 'lin';\r\n                if(scaleMode !== 'lin') toggleScaleMode(); \r\n                document.getElementById('btn-sweep-lin').classList.add('active'); \r\n            }\r\n            if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n            runSweepLogic(selectedSweepMode);\r\n        }\r\n    }\r\n\r\n    function toggleIso() {\r\n        if(!isSystemOn) return; \r\n        if (activeModule === 'iso') stopAllModules();\r\n        else {\r\n            switchModuleTo('iso');\r\n            let btn = document.getElementById('btn-iso-toggle');\r\n            btn.classList.remove('sub-ready');\r\n            btn.classList.add('sub-active');\r\n            btn.innerText = \"STOP\";\r\n            \r\n            let status = document.getElementById('iso-status');\r\n            status.innerText = \"ISO ACTIVE\";\r\n            status.style.color = \"var(--neon-blue)\";\r\n            \r\n            document.getElementById('status-text').innerText = \"ISO ACTIVE\";\r\n            document.getElementById('status-text').style.color = \"#ef4444\";\r\n            \r\n            showToast(\"ISO & RTA\"); \r\n\r\n            if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n            changeFreq(isoFreqs[isoIndex]); \r\n            startSound();\r\n        }\r\n        updateMasterButton();\r\n    }\r\n\r\n    function toggleSub() {\r\n        if(!isSystemOn) return;\r\n        if (activeModule === 'sub-sweep-running') { stopAllModules(); return; }\r\n        \r\n        if (activeModule === 'sub' && isSignalOn) stopAllModules();\r\n        else {\r\n            if (activeModule === 'sub-sweep-armed') {\r\n                runSubSweepLogic();\r\n            } else {\r\n                switchModuleTo('sub');\r\n                let btn = document.getElementById('btn-sub-toggle');\r\n                btn.classList.remove('sub-ready');\r\n                btn.classList.add('sub-active');\r\n                btn.innerText = \"STOP\";\r\n                \r\n                document.getElementById('status-text').innerText = \"SUBWOOFER ON\";\r\n                document.getElementById('status-text').style.color = \"#ef4444\";\r\n                \r\n                let subStatus = document.getElementById('sub-status');\r\n                if (isSubDriveActive) {\r\n                    subStatus.innerText = \"LFE DRIVE ACTIVE\";\r\n                    subStatus.style.color = \"#ef4444\";\r\n                } else {\r\n                    subStatus.innerText = \"LFE ACTIVE\";\r\n                    subStatus.style.color = \"var(--neon-blue)\";\r\n                }\r\n\r\n                showToast(\"SUB\"); \r\n                \r\n                if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n                changeFreq(subFreq); \r\n                startSound();\r\n            }\r\n        }\r\n        updateMasterButton();\r\n    }\r\n\r\n    function formatHz(val) {\r\n        if (val === 0) return \"0 Hz\";\r\n        let v = parseFloat(val);\r\n        if(v >= 1000) return (v \/ 1000).toFixed(3) + \" kHz\";\r\n        return (v % 1 === 0 ? v : v.toFixed(2)) + \" Hz\";\r\n    }\r\n    \r\n    function updateDisplay() {\r\n        document.getElementById('freq-mini-disp').innerText = formatHz(currentFreq);\r\n\r\n        if (displayToast) {\r\n            document.getElementById('screen-input').value = displayToast;\r\n            return;\r\n        }\r\n        if (isNoise(curWave)) {\r\n             document.getElementById('screen-input').value = curWave.toUpperCase() + \" N.\";\r\n             return;\r\n        }\r\n        document.getElementById('screen-input').value = formatHz(currentFreq);\r\n    }\r\n\r\n    function onHzFocus(el) { if(!isSystemOn) return; el.value = currentFreq; }\r\n    function onHzBlur(el) { if(!isSystemOn) { el.value = \"0 Hz\"; return; } updateDisplay(); }\r\n    \r\n    function focusMainInput() {\r\n        if(!isSystemOn) return;\r\n        document.getElementById('screen-input').focus();\r\n    }\r\n\r\n    function manualEntry(val) {\r\n        if(!isSystemOn) return; \r\n        let clean = val.toLowerCase().replace(\/[^0-9.k]\/g, '');\r\n        let num = 0;\r\n        if(clean.includes('k')) num = parseFloat(clean.replace('k','')) * 1000; \r\n        else num = parseFloat(clean); \r\n        num = parseInt(num); \r\n        if(isNaN(num)) num = 0;\r\n        if(num > 20000) num = 20000;\r\n        if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n        changeFreq(num);\r\n        document.getElementById('screen-input').blur(); \r\n    }\r\n    \r\n    function toggleScaleMode() {\r\n        if(!isSystemOn) return;\r\n        scaleMode = scaleMode === 'lin' ? 'log' : 'lin';\r\n        let btn = document.getElementById('btn-scale-toggle');\r\n        btn.innerText = scaleMode.toUpperCase() + \" SCALE\";\r\n        \r\n        if (scaleMode === 'log') {\r\n            document.getElementById('ruler-lin').classList.remove('active');\r\n            document.getElementById('ruler-log').classList.add('active');\r\n            btn.style.color = '#ef4444';\r\n            btn.style.borderColor = '#ef4444';\r\n        } else {\r\n            document.getElementById('ruler-log').classList.remove('active');\r\n            document.getElementById('ruler-lin').classList.add('active');\r\n            btn.style.color = '#cbd5e1';\r\n            btn.style.borderColor = '#0f172a';\r\n        }\r\n        updateSliderPos(currentFreq);\r\n    }\r\n\r\n    function magnetSlide(rawVal) {\r\n        if(!isSystemOn) return; \r\n        document.querySelectorAll('.w-btn-sweep:not(#btn-sub-sweep)').forEach(b => b.classList.remove('active'));\r\n        \r\n        let sliderMax = 10000;\r\n        let v = 0;\r\n        let minF = 20; \r\n        let maxF = 20000;\r\n        \r\n        if (scaleMode === 'lin') {\r\n            v = minF + (rawVal \/ sliderMax) * (maxF - minF);\r\n        } else {\r\n            if (rawVal == 0) v = 0;\r\n            else v = minF * Math.pow((maxF\/minF), (rawVal \/ sliderMax));\r\n        }\r\n        \r\n        if (v < 100) v = Math.round(v * 10) \/ 10;\r\n        else v = Math.round(v);\r\n        \r\n        if (v > 20000) v = 20000;\r\n        \r\n        changeFreq(v, false); \r\n    }\r\n    \r\n    function updateSliderPos(hz) {\r\n        let slider = document.getElementById('mag-slider');\r\n        let sliderMax = 10000;\r\n        let pos = 0;\r\n        let minF = 20; \r\n        let maxF = 20000;\r\n        \r\n        if (scaleMode === 'lin') {\r\n            if (hz < 20) pos = 0;\r\n            else pos = ((hz - minF) \/ (maxF - minF)) * sliderMax;\r\n        } else {\r\n            if (hz < 20) pos = 0;\r\n            else {\r\n                pos = (Math.log(hz \/ minF) \/ Math.log(maxF \/ minF)) * sliderMax;\r\n            }\r\n        }\r\n        \r\n        if(pos < 0) pos = 0;\r\n        if(pos > sliderMax) pos = sliderMax;\r\n        \r\n        slider.value = pos;\r\n    }\r\n\r\n    function changeFreq(val, updateSlider = true) {\r\n        let v = parseFloat(val);\r\n        currentFreq = v;\r\n        \r\n        if (updateSlider) updateSliderPos(v);\r\n        \r\n        updateDisplay();\r\n        if (osc && !noise && activeModule === 'tone') {\r\n            osc.frequency.setTargetAtTime(v, actx.currentTime, SMOOTHING);\r\n        }\r\n    }\r\n\r\n    function stepIso(step) {\r\n        if(!isSystemOn) return;\r\n        isoIndex += step;\r\n        if(isoIndex < 0) isoIndex = 0;\r\n        if(isoIndex >= isoFreqs.length) isoIndex = isoFreqs.length - 1;\r\n        let f = isoFreqs[isoIndex];\r\n        document.getElementById('iso-hz-val').innerText = formatHz(f);\r\n        if(isIsoPlaying()) {\r\n            changeFreq(f); \r\n            if (osc && !noise) osc.frequency.setTargetAtTime(f, actx.currentTime, SMOOTHING);\r\n        }\r\n    }\r\n\r\n    function updSubTrim(val) {\r\n        let db = parseFloat(val);\r\n        let dispDB = db === -12 ? \"-12.0\" : (db > 0 ? \"+\" + db.toFixed(1) : db.toFixed(1));\r\n        document.getElementById('sub-trim-val').innerText = dispDB + \" dB\";\r\n        subTrim = Math.pow(10, db \/ 20);\r\n        if (isSubPlaying() && isSignalOn && gain) gain.gain.setTargetAtTime(getActualVol(), actx.currentTime, 0.1);\r\n    }\r\n\r\n    function toggleSubDrive() {\r\n        if(!isSystemOn) return;\r\n        isSubDriveActive = !isSubDriveActive;\r\n        const btn = document.getElementById('btn-sub-drive');\r\n        const status = document.getElementById('sub-status');\r\n        if (isSubDriveActive) {\r\n            btn.classList.add('active');\r\n            if (isSubPlaying()) {\r\n                status.innerText = \"LFE DRIVE ACTIVE\";\r\n                status.style.color = \"#ef4444\";\r\n            }\r\n        } else {\r\n            btn.classList.remove('active');\r\n            if (isSubPlaying()) {\r\n                status.innerText = \"LFE ACTIVE\";\r\n                status.style.color = \"var(--neon-blue)\";\r\n            } else {\r\n                status.innerText = \"LFE READY\";\r\n                status.style.color = \"#64748b\";\r\n            }\r\n        }\r\n        if (isSubPlaying() && isSignalOn) startSound(); \r\n    }\r\n\r\n    function togglePhase() {\r\n        if(!isSystemOn) return;\r\n        phasePolarity *= -1;\r\n        const btn = document.getElementById('btn-sub-phase');\r\n        const invStatus = document.getElementById('sub-invert-status');\r\n        if(phasePolarity === -1) {\r\n            btn.classList.add('active');\r\n            invStatus.style.display = 'block';\r\n        } else {\r\n            btn.classList.remove('active');\r\n            invStatus.style.display = 'none';\r\n        }\r\n        if(isSignalOn && gain) gain.gain.setTargetAtTime(getActualVol(), actx.currentTime, 0.05);\r\n    }\r\n\r\n    function stepSub(step) {\r\n        if(!isSystemOn) return; \r\n        subFreq += step;\r\n        if(subFreq < 10) subFreq = 10;\r\n        if(subFreq > 120) subFreq = 120;\r\n        document.getElementById('sub-hz-val').innerText = subFreq + \" Hz\"; \r\n        document.getElementById('kick-btn-val').innerText = subFreq;\r\n        if(isSubPlaying() && osc) {\r\n            osc.frequency.setTargetAtTime(subFreq, actx.currentTime, 0.05);\r\n            currentFreq = subFreq; \r\n            updateDisplay();\r\n        }\r\n    }\r\n\r\n    function setSubHz(val) {\r\n        if(!isSystemOn) return;\r\n        subFreq = val;\r\n        document.getElementById('sub-hz-val').innerText = subFreq + \" Hz\";\r\n        document.getElementById('kick-btn-val').innerText = subFreq;\r\n        if(isSubPlaying() && osc) {\r\n            osc.frequency.setTargetAtTime(subFreq, actx.currentTime, 0.05);\r\n            currentFreq = subFreq;\r\n            updateDisplay();\r\n        }\r\n    }\r\n\r\n    function armSubSweep() {\r\n        if(!isSystemOn) return;\r\n        activeModule = 'sub-sweep-armed';\r\n        resetSignalButtons();\r\n        \r\n        document.getElementById('status-text').innerText = \"LFE SWEEP\";\r\n        document.getElementById('status-text').style.color = \"#ef4444\";\r\n        document.getElementById('sub-status').innerText = \"LFE ARMED\";\r\n        document.getElementById('sub-status').style.color = \"var(--neon-blue)\";\r\n        document.getElementById('btn-sub-sweep').classList.add('active');\r\n        if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n        \r\n        showToast(\"LFE ARMED\");\r\n        updateMasterButton(); \r\n    }\r\n    \r\n    function runSubSweepLogic() {\r\n        switchModuleTo('sub-sweep-running');\r\n        let btn = document.getElementById('btn-sub-toggle');\r\n        btn.classList.remove('sub-ready');\r\n        btn.classList.add('sub-active');\r\n        btn.innerText = \"STOP\";\r\n        document.getElementById('sub-status').innerText = \"SWEEP RUNNING\";\r\n        \r\n        createOsc();\r\n        const now = actx.currentTime;\r\n        osc.start(now);\r\n        gain.gain.cancelScheduledValues(now);\r\n        gain.gain.setValueAtTime(0, now);\r\n        gain.gain.linearRampToValueAtTime(getActualVol(), now + 0.1);\r\n        \r\n        let dur = 10; \r\n        osc.frequency.cancelScheduledValues(now);\r\n        osc.frequency.setValueAtTime(20, now);\r\n        osc.frequency.exponentialRampToValueAtTime(120, now + dur);\r\n        \r\n        let start = Date.now();\r\n        clearInterval(sweepTimer);\r\n        sweepTimer = setInterval(() => {\r\n            let el = (Date.now() - start) \/ 1000;\r\n            if (el >= dur) {\r\n                subFreq = 120;\r\n                document.getElementById('sub-hz-val').innerText = subFreq + \" Hz\";\r\n                document.getElementById('kick-btn-val').innerText = subFreq;\r\n                currentFreq = subFreq;\r\n                updateDisplay(); \r\n                clearInterval(sweepTimer);\r\n                stopAllModules();\r\n                return;\r\n            }\r\n            let p = el\/dur;\r\n            let hz = 20 * Math.pow((120\/20), p);\r\n            subFreq = Math.round(hz);\r\n            document.getElementById('sub-hz-val').innerText = subFreq + \" Hz\";\r\n            document.getElementById('kick-btn-val').innerText = subFreq;\r\n            currentFreq = subFreq;\r\n            updateDisplay(); \r\n        }, 50);\r\n    }\r\n\r\n    function playSubKick() {\r\n        if(!isSystemOn || isTurningOff) return;\r\n        switchModuleTo('sub-kick');\r\n        curWave = 'sine';\r\n        createOsc();\r\n        const now = actx.currentTime;\r\n        \r\n        osc.frequency.setValueAtTime(150, now);\r\n        osc.frequency.exponentialRampToValueAtTime(subFreq, now + 0.25);\r\n        \r\n        gain.gain.cancelScheduledValues(now);\r\n        gain.gain.setValueAtTime(0, now);\r\n        \r\n        let aVol = getActualVol();\r\n        gain.gain.linearRampToValueAtTime(aVol, now + 0.01);\r\n        gain.gain.setValueAtTime(aVol, now + 0.02);\r\n        gain.gain.linearRampToValueAtTime(0, now + 0.25);\r\n        \r\n        osc.start(now);\r\n        osc.stop(now + 0.5); \r\n        \r\n        document.getElementById('status-text').innerText = \"KICK TEST\";\r\n        document.getElementById('status-text').style.color = \"#ef4444\";\r\n        document.getElementById('sub-status').innerText = \"LFE KICK\";\r\n        document.getElementById('sub-status').style.color = \"var(--neon-blue)\";\r\n        \r\n        showToast(\"KICK \" + subFreq + \"Hz\");\r\n        updateMasterButton(); \r\n        \r\n        clearTimeout(stopTimer);\r\n        stopTimer = setTimeout(() => {\r\n            stopAllModules();\r\n        }, 600);\r\n    }\r\n\r\n    function setWave(w, btn) {\r\n        if(!isSystemOn) return; \r\n        curWave = w;\r\n        \r\n        \/\/ A\u017euriraj aktivne glasove ako ih ima\r\n        activeVoices.forEach(v => {\r\n            if(v.osc && !isNoise(w)) v.osc.type = w;\r\n        });\r\n\r\n        if (isNoise(w)) {\r\n            document.querySelectorAll('.w-btn-sweep:not(#btn-sub-sweep)').forEach(b => b.classList.remove('active'));\r\n            if(scaleMode !== 'lin') toggleScaleMode();\r\n        }\r\n        document.querySelectorAll('.w-btn').forEach(b => b.classList.remove('active'));\r\n        document.querySelectorAll('.noise-btn').forEach(b => b.classList.remove('active'));\r\n        btn.classList.add('active');\r\n        let label = w.toUpperCase();\r\n        if (isNoise(w)) label = label + \" N.\"; \r\n        else if (w === 'sine') label = \"SIN\"; \r\n        else if (w === 'square') label = \"SQR\"; \r\n        else if (w === 'sawtooth') label = \"SAW\"; \r\n        else if (w === 'triangle') label = \"TRI\";\r\n        showToast(label);\r\n        if (isSignalOn) {\r\n            if (activeModule === 'noise' && !isNoise(w)) toggleTone(); \r\n            else if (activeModule === 'tone' && isNoise(w)) toggleNoise();\r\n            else {\r\n                if (osc && !isNoise(w)) osc.type = w;\r\n                if (isNoise(w) && activeModule === 'noise') startSound();\r\n            }\r\n        }\r\n    }\r\n\r\n    function updPan(val) {\r\n        if (!pan) return;\r\n        pan.pan.setTargetAtTime(val, actx.currentTime, 0.1);\r\n        let p = parseFloat(val);\r\n        document.getElementById('pan-slider').value = p; \r\n\r\n        let lPct = Math.round(50 + (p * -50));\r\n        let rPct = Math.round(50 + (p * 50));\r\n        \r\n        document.getElementById('pan-l-val').innerText = lPct + \"%\";\r\n        document.getElementById('pan-r-val').innerText = rPct + \"%\";\r\n\r\n        let lLabel = document.querySelector('#btn-pan-l .pan-side-label');\r\n        let rLabel = document.querySelector('#btn-pan-r .pan-side-label');\r\n\r\n        if (p === -1) {\r\n            lLabel.innerText = \"C\";\r\n            rLabel.innerText = \"R\";\r\n        } else if (p === 1) {\r\n            lLabel.innerText = \"L\";\r\n            rLabel.innerText = \"C\";\r\n        } else {\r\n            lLabel.innerText = \"L\";\r\n            rLabel.innerText = \"R\";\r\n        }\r\n    }\r\n\r\n    function panJump(side) {\r\n        const current = parseFloat(document.getElementById('pan-slider').value);\r\n        if (side === 'L') {\r\n            if (current === -1) updPan(0); \r\n            else updPan(-1); \r\n        } else if (side === 'R') {\r\n            if (current === 1) updPan(0); \r\n            else updPan(1); \r\n        }\r\n    }\r\n\r\n    function updVol(val, force=false) {\r\n        let v = parseFloat(val);\r\n        const targets = [0.25, 0.50, 0.75, 1.0];\r\n        const threshold = 0.025; \r\n        for(let t of targets) {\r\n            if(Math.abs(v - t) < threshold) { v = t; document.getElementById('vol-slider').value = v; break; }\r\n        }\r\n        if (v > 0.5 && !highGainConfirmed && !force) {\r\n            pendingVol = v; document.getElementById('vol-slider').value = 0.5;\r\n            document.getElementById('safety-modal').style.display = 'flex';\r\n            return;\r\n        }\r\n        safeVol = v;\r\n        if (gain) gain.gain.setTargetAtTime(getActualVol(), actx.currentTime, 0.1);\r\n    }\r\n\r\n    function toggleRuler(mode) {\r\n        document.querySelectorAll('.scale-ruler').forEach(r => r.classList.remove('active'));\r\n        if (mode === 'log') document.getElementById('ruler-log').classList.add('active');\r\n        else document.getElementById('ruler-lin').classList.add('active');\r\n    }\r\n\r\n    function armSweep(mode, btn) {\r\n        if(!isSystemOn) return; \r\n        selectedSweepMode = mode; \r\n        \r\n        if (mode === 'lin' && scaleMode !== 'lin') toggleScaleMode();\r\n        if (mode === 'log' && scaleMode !== 'log') toggleScaleMode();\r\n\r\n        document.querySelectorAll('.w-btn-sweep:not(#btn-sub-sweep)').forEach(b => b.classList.remove('active'));\r\n        btn.classList.add('active');\r\n        if (isNoise(curWave)) setWave('sine', document.getElementById('btn-sine'));\r\n        showToast(mode === 'lin' ? \"LIN S.\" : \"LOG S.\");\r\n        if(activeModule === 'sweep') runSweepLogic(mode);\r\n    }\r\n\r\n    function runSweepLogic(mode) {\r\n        switchModuleTo('sweep'); \r\n        \r\n        let btn = document.getElementById('btn-sweep-toggle');\r\n        btn.classList.remove('sub-ready');\r\n        btn.classList.add('sub-active');\r\n        btn.innerText = \"STOP\";\r\n        document.getElementById('status-text').innerText = \"SWEEP LIVE\";\r\n        document.getElementById('status-text').style.color = \"#ef4444\";\r\n\r\n        killCurrentAudio();\r\n        createOsc();\r\n        const now = actx.currentTime;\r\n        osc.start(now);\r\n        gain.gain.cancelScheduledValues(now);\r\n        gain.gain.setValueAtTime(0, now);\r\n        gain.gain.linearRampToValueAtTime(getActualVol(), now + 0.1); \r\n        sweepMode = mode === 'lin' ? 'LIN' : 'LOG';\r\n        let dur = mode === 'lin' ? 10 : 20;\r\n        osc.frequency.cancelScheduledValues(now);\r\n        osc.frequency.setValueAtTime(20, now);\r\n        if (mode === 'log') osc.frequency.exponentialRampToValueAtTime(20000, now + dur);\r\n        else osc.frequency.linearRampToValueAtTime(20000, now + dur);\r\n        \r\n        updateMasterButton(); \r\n\r\n        let start = Date.now();\r\n        clearInterval(sweepTimer);\r\n        sweepTimer = setInterval(() => {\r\n            let el = (Date.now() - start) \/ 1000;\r\n            if (el >= dur) {\r\n                clearInterval(sweepTimer);\r\n                stopAllModules(); \r\n                return;\r\n            }\r\n            let p = el\/dur;\r\n            let hz = mode === 'log' ? 20 * Math.pow(1000, p) : 20 + (19980*p);\r\n            if(hz > 20000) hz = 20000;\r\n            changeFreq(Math.round(hz));\r\n        }, 50);\r\n    }\r\n\r\n    function stepOctave(step) {\r\n         if(!isSystemOn) return;\r\n         currentOctave += step;\r\n         if(currentOctave < 0) currentOctave = 0;\r\n         if(currentOctave > 9) currentOctave = 9;\r\n         updateMusicalDisplay();\r\n    }\r\n\r\n    const noteNames = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\r\n    \r\n    function updateMusicalDisplay(noteIndex = -1) {\r\n        document.getElementById('mus-disp-oct').innerText = \"OCT \" + currentOctave;\r\n        if(noteIndex === -1) {\r\n            document.getElementById('mus-disp-note').innerText = \"READY\";\r\n            document.getElementById('mus-disp-freq').innerText = \"0 Hz\";\r\n        } else {\r\n            let nName = noteNames[noteIndex];\r\n            document.getElementById('mus-disp-note').innerText = nName + currentOctave;\r\n            let baseNote = (currentOctave * 12) + 12; \r\n            let midiNote = baseNote + noteIndex;\r\n            let freq = concertPitch * Math.pow(2, (midiNote - 69) \/ 12);\r\n            document.getElementById('mus-disp-freq').innerText = formatHz(freq);\r\n        }\r\n    }\r\n\r\n    function updateTuning(val) {\r\n        concertPitch = parseInt(val);\r\n        document.getElementById('tuning-disp').innerText = concertPitch;\r\n    }\r\n\r\n    function updADSR(param, val) {\r\n        let v = parseFloat(val);\r\n        adsr[param] = v;\r\n        \r\n        if(param === 'a') document.getElementById('val-att').innerText = v + \"s\";\r\n        if(param === 'd') document.getElementById('val-dec').innerText = v + \"s\";\r\n        if(param === 's') document.getElementById('val-sus').innerText = Math.round(v * 100) + \"%\";\r\n        if(param === 'r') document.getElementById('val-rel').innerText = v + \"s\";\r\n    }\r\n\r\n    \/\/ --- POPRAVLJENA POLIFONA FUNKCIJA (Audio + Visual) ---\r\n    function playPolyNote(freq) {\r\n        if(!isSystemOn || isTurningOff) return;\r\n\r\n        isSignalOn = true;\r\n        activeModule = 'piano';\r\n        \r\n        document.getElementById('status-text').innerText = \"POLY SYNTH\";\r\n        document.getElementById('status-text').style.color = \"#ef4444\"; \r\n\r\n        const now = actx.currentTime;\r\n        let gateTime = knobs.gate.val; \r\n        \r\n        let vOsc = actx.createOscillator();\r\n        let vGain = actx.createGain();\r\n        \r\n        if (isNoise(curWave)) vOsc.type = 'sawtooth';\r\n        else vOsc.type = curWave;\r\n\r\n        vOsc.frequency.value = freq;\r\n\r\n        \/\/ Spajanje\r\n        vOsc.connect(vGain);\r\n        vGain.connect(gain); \r\n\r\n        \/\/ === KLJU\u010cNI POPRAVAK ZA ZVUK ===\r\n        gain.gain.cancelScheduledValues(now);\r\n        gain.gain.setValueAtTime(getActualVol(), now);\r\n        \/\/ =================================\r\n\r\n        vGain.gain.setValueAtTime(0, now);\r\n        \r\n        let peakGain = 0.5; \r\n        let susLevel = peakGain * adsr.s;\r\n\r\n        \/\/ ADSR ENVELOPE\r\n        vGain.gain.linearRampToValueAtTime(peakGain, now + adsr.a);\r\n        vGain.gain.linearRampToValueAtTime(susLevel, now + adsr.a + adsr.d);\r\n        vGain.gain.setValueAtTime(susLevel, now + gateTime);\r\n        vGain.gain.exponentialRampToValueAtTime(0.001, now + gateTime + adsr.r);\r\n        vGain.gain.linearRampToValueAtTime(0, now + gateTime + adsr.r + 0.05);\r\n\r\n        vOsc.start(now);\r\n        vOsc.stop(now + gateTime + adsr.r + 0.1); \r\n\r\n        let voice = { osc: vOsc, gain: vGain };\r\n        activeVoices.push(voice);\r\n\r\n        \/\/ CLEANUP\r\n        setTimeout(() => {\r\n            let index = activeVoices.indexOf(voice);\r\n            if (index > -1) {\r\n                activeVoices.splice(index, 1);\r\n            }\r\n            if (activeVoices.length === 0) {\r\n                changeFreq(0);\r\n            }\r\n        }, (gateTime + adsr.r + 0.2) * 1000);\r\n        \r\n        updateMasterButton();\r\n    }\r\n\r\n    function playNote(noteIndex) {\r\n        if(!isSystemOn || isTurningOff) return; \r\n        updateMusicalDisplay(noteIndex);\r\n        let baseNote = (currentOctave * 12) + 12; \r\n        let midiNote = baseNote + noteIndex;\r\n        let freq = concertPitch * Math.pow(2, (midiNote - 69) \/ 12);\r\n        \r\n        currentFreq = freq;\r\n        updateSliderPos(currentFreq);\r\n        updateDisplay();\r\n\r\n        playPolyNote(freq);\r\n    }\r\n    \r\n    function confirmSafe() { highGainConfirmed = true; document.getElementById('safety-modal').style.display = 'none'; updVol(pendingVol, true); }\r\n    function cancelSafe() { highGainConfirmed = false; document.getElementById('safety-modal').style.display = 'none'; updVol(0.5, true); }\r\n\r\n    function openHelp() { document.getElementById('help-modal').style.display = 'flex'; }\r\n    function closeHelp() { document.getElementById('help-modal').style.display = 'none'; }\r\n    \r\n    function scrollToSection(id, btn) {\r\n        const el = document.getElementById(id);\r\n        const container = document.getElementById('help-content-area');\r\n        if(el && container) container.scrollTo({ top: el.offsetTop, behavior: 'smooth' });\r\n        const allBtns = document.querySelectorAll('.menu-item');\r\n        allBtns.forEach(b => b.classList.remove('active'));\r\n        if(btn) btn.classList.add('active');\r\n    }\r\n\r\n    function drawSnow(ctx, w, h, progress) {\r\n         ctx.fillStyle = \"#050a0f\"; \r\n         ctx.fillRect(0,0,w,h);\r\n         ctx.shadowBlur = 5; ctx.shadowColor = \"rgba(200, 220, 255, 0.8)\";\r\n         for(let i=0; i<4000; i++) {\r\n             let x = Math.floor(Math.random() * w); \r\n             let y = Math.floor(Math.random() * h); \r\n             let r = Math.random();\r\n             let rC = r > 0.8 ? 255 : (r > 0.4 ? 160 : 80);\r\n             let gC = r > 0.8 ? 255 : (r > 0.4 ? 170 : 90);\r\n             let bC = r > 0.8 ? 255 : (r > 0.4 ? 180 : 100);\r\n             ctx.fillStyle = `rgb(${rC},${gC},${bC})`; ctx.fillRect(x, y, 1.5, 1.5);\r\n         }\r\n         ctx.shadowBlur = 0;\r\n         let easeOut = progress * progress; \r\n         ctx.fillStyle = `rgba(0, 0, 0, ${easeOut})`; ctx.fillRect(0,0,w,h);\r\n    }\r\n\r\n    function drawSubScope(data) {\r\n        let cvs = document.getElementById('sub-scope-canvas');\r\n        let ctx = cvs.getContext('2d');\r\n        let w = cvs.width = cvs.clientWidth; let h = cvs.height = cvs.clientHeight;\r\n        ctx.clearRect(0,0,w,h);\r\n        \r\n        if(!isSubPlaying()) {\r\n            ctx.lineWidth = 2; ctx.strokeStyle = '#38bdf8'; ctx.beginPath(); ctx.moveTo(0, h\/2); ctx.lineTo(w, h\/2); ctx.stroke(); return;\r\n        }\r\n        \r\n        ctx.lineWidth = 2; ctx.strokeStyle = '#38bdf8'; ctx.beginPath();\r\n        let slice = w * 1.0 \/ data.length; let x = 0;\r\n        for(let i=0; i<data.length; i++) {\r\n            let v = data[i]\/128.0; let y = v * (h\/2); \r\n            if(i===0) ctx.moveTo(x,y); else ctx.lineTo(x,y); x += slice;\r\n        }\r\n        ctx.stroke();\r\n    }\r\n    \r\n    function drawIsoAnalyzer() {\r\n        let cvs = document.getElementById('iso-analyzer-canvas');\r\n        if (!cvs || !actx) return;\r\n        let ctx = cvs.getContext('2d');\r\n        let w = cvs.width = cvs.clientWidth; let h = cvs.height = cvs.clientHeight;\r\n        ctx.clearRect(0, 0, w, h);\r\n        if (!isSystemOn) return;\r\n        \r\n        let textH = 15; let graphH = h - textH;\r\n        ctx.strokeStyle = \"rgba(56, 189, 248, 0.1)\"; ctx.lineWidth = 1; ctx.beginPath();\r\n        ctx.moveTo(0, graphH * 0.25); ctx.lineTo(w, graphH * 0.25);\r\n        ctx.moveTo(0, graphH * 0.50); ctx.lineTo(w, graphH * 0.50);\r\n        ctx.moveTo(0, graphH * 0.75); ctx.lineTo(w, graphH * 0.75);\r\n        ctx.stroke();\r\n\r\n        let numBands = 72; let barW = (w \/ numBands) - 1; \r\n        if (!rtaData || !anal) return;\r\n        \r\n        if (isSignalOn && (currentFreq > 0 || isSubPlaying() || isIsoPlaying() || isNoise(curWave) || activeVoices.length > 0)) {\r\n            anal.getByteFrequencyData(rtaData);\r\n        } else {\r\n            for(let i=0; i<rtaData.length; i++) rtaData[i] = 0;\r\n        }\r\n        \r\n        let minLog = Math.log10(20); let maxLog = Math.log10(20000); let nyquist = actx.sampleRate \/ 2;\r\n        ctx.shadowBlur = 6; ctx.shadowColor = \"rgba(56, 189, 248, 0.8)\"; ctx.fillStyle = \"#38bdf8\"; \r\n        \r\n        for(let i = 0; i < numBands; i++) {\r\n            let fStart = Math.pow(10, minLog + (i \/ numBands) * (maxLog - minLog));\r\n            let fEnd = Math.pow(10, minLog + ((i + 1) \/ numBands) * (maxLog - minLog));\r\n            let binStart = Math.floor((fStart \/ nyquist) * rtaData.length);\r\n            let binEnd = Math.floor((fEnd \/ nyquist) * rtaData.length);\r\n            if (binEnd <= binStart) binEnd = binStart + 1;\r\n            let maxVal = 0;\r\n            for(let b = binStart; b < binEnd && b < rtaData.length; b++) if(rtaData[b] > maxVal) maxVal = rtaData[b];\r\n            let valNorm = maxVal \/ 255.0; \r\n            let barH = Math.pow(valNorm, 1.2) * (graphH - 2); \r\n            if (barH < 2 && isSystemOn) barH = 2; \r\n            ctx.fillRect(i * (w \/ numBands), graphH - barH, barW, barH);\r\n        }\r\n        ctx.shadowBlur = 0;\r\n        ctx.fillStyle = \"#64748b\"; ctx.font = \"bold 8px monospace\"; ctx.textAlign = \"center\"; ctx.textBaseline = \"top\";\r\n        const labels = [20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000];\r\n        labels.forEach(freq => {\r\n            let p = (Math.log10(freq) - minLog) \/ (maxLog - minLog); let x = p * w;\r\n            let txt = freq >= 1000 ? (freq\/1000) + 'k' : freq;\r\n            if(x < 10) x = 10; if(x > w - 10) x = w - 10;\r\n            ctx.fillText(txt, x, graphH + 4);\r\n        });\r\n    }\r\n\r\n    function loopVis() {\r\n        requestAnimationFrame(loopVis);\r\n        let cvs = document.getElementById('scope'); let ctx = cvs.getContext('2d');\r\n        let w = cvs.width = cvs.clientWidth; let h = cvs.height = cvs.clientHeight;\r\n        \r\n        if (isTurningOff) { \r\n            let p = (Date.now() - offStartTime) \/ 3000; if (p > 1) p = 1;\r\n            drawSnow(ctx, w, h, p); drawIsoAnalyzer(); return; \r\n        }\r\n        ctx.clearRect(0,0,w,h); \r\n        if (!isSystemOn) { ctx.fillStyle = '#000'; ctx.fillRect(0,0,w,h); drawIsoAnalyzer(); return; }\r\n        \r\n        drawGrid(ctx, w, h);\r\n        let data = new Uint8Array(anal.fftSize);\r\n        \r\n        if (isSignalOn && (currentFreq > 0 || isNoise(curWave) || isSubPlaying() || activeVoices.length > 0)) {\r\n            anal.getByteTimeDomainData(data);\r\n        } else { \r\n            for(let i=0; i<data.length; i++) data[i] = 128; \r\n        }\r\n        \r\n        drawSubScope(data); drawIsoAnalyzer();\r\n        \r\n        ctx.lineWidth = 3; ctx.strokeStyle = '#0f172a'; ctx.beginPath();\r\n        let slice = w * 1.0 \/ data.length; let x = 0;\r\n        for(let i=0; i<data.length; i++) {\r\n            let v = data[i]\/128.0; let y = v * (h\/2); y = (y * 0.8) + (h * 0.1); \r\n            if(i===0) ctx.moveTo(x,y); else ctx.lineTo(x,y); x += slice;\r\n        }\r\n        ctx.stroke();\r\n        drawKnob(ctx, 30, 35, 15); \r\n        ctx.font = \"bold 16px Orbitron\"; ctx.textAlign = \"left\"; ctx.fillStyle = \"#0f172a\";\r\n        ctx.shadowBlur = 1.5; ctx.shadowColor = \"rgba(15, 23, 42, 0.4)\"; \r\n        let volVal = parseFloat(document.getElementById('vol-slider').value);\r\n        let dispDB = \"-\u221e\";\r\n        if(Math.abs(volVal - 0.25) < 0.01) dispDB = \"-12.0\";\r\n        else if(Math.abs(volVal - 0.50) < 0.01) dispDB = \"-6.0\";\r\n        else if(Math.abs(volVal - 0.75) < 0.01) dispDB = \"-3.0\";\r\n        else if(Math.abs(volVal - 1.0) < 0.01) dispDB = \"0.0\";\r\n        else if(volVal > 0.01) { let db = 20 * Math.log10(volVal); dispDB = db.toFixed(1); }\r\n        ctx.fillText(dispDB + \" dB\", 60, 40); \r\n        drawStatusBar(ctx, w, h);\r\n        ctx.shadowBlur = 0; \r\n        \r\n        if(startupVuLevel > 0) {\r\n            updateLEDs(startupVuLevel * LED_COUNT);\r\n            startupVuLevel -= 0.02;\r\n            if(startupVuLevel < 0) startupVuLevel = 0;\r\n        } else if(isSignalOn && (currentFreq > 0 || isNoise(curWave) || isSubPlaying() || isIsoPlaying() || activeVoices.length > 0)) {\r\n            let sum=0; for(let i=0; i<data.length; i++) { let z=(data[i]-128)\/128; sum+=z*z; }\r\n            let jitter = (Math.random() - 0.5) * 0.05;\r\n            let gainVol = parseFloat(document.getElementById('vol-slider').value);\r\n            let signalStrength = gainVol + jitter;\r\n            if(signalStrength < 0) signalStrength = 0; if(signalStrength > 1) signalStrength = 1;\r\n            let baseLevel = Math.floor(signalStrength * LED_COUNT);\r\n            let pVal = parseFloat(document.getElementById('pan-slider').value);\r\n            let lMod = pVal < 0 ? 1 : 1 - pVal; let rMod = pVal > 0 ? 1 : 1 + pVal;\r\n            updateLEDs(baseLevel, lMod, rMod);\r\n        } else { updateLEDs(0); }\r\n    }\r\n\r\n    function drawGrid(ctx, w, h) {\r\n        ctx.lineWidth = 1; ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)'; ctx.setLineDash([]); ctx.beginPath();\r\n        for (let x = 0; x <= w; x += 40) { ctx.moveTo(x, 0); ctx.lineTo(x, h); }\r\n        for (let y = 0; y <= h; y += 40) { ctx.moveTo(0, y); ctx.lineTo(w, y); }\r\n        ctx.stroke();\r\n        let centerY = (h * 0.15) + (h\/2 * 0.7); let scaleH = (h\/2 * 0.7);\r\n        ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(0, centerY); ctx.lineTo(w, centerY); ctx.stroke();\r\n        ctx.lineWidth = 1; ctx.strokeStyle = 'rgba(255, 255, 255, 0.6)'; ctx.setLineDash([4, 4]); \r\n        let y3_top = centerY - (scaleH * 0.75); let y3_bot = centerY + (scaleH * 0.75);\r\n        ctx.moveTo(0, y3_top); ctx.lineTo(w, y3_top); ctx.moveTo(0, y3_bot); ctx.lineTo(w, y3_bot); ctx.stroke();\r\n        let y6_top = centerY - (scaleH * 0.50); let y6_bot = centerY + (scaleH * 0.50);\r\n        ctx.moveTo(0, y6_top); ctx.lineTo(w, y6_top); ctx.moveTo(0, y6_bot); ctx.lineTo(w, y6_bot); ctx.stroke();\r\n        let y12_top = centerY - (scaleH * 0.25); let y12_bot = centerY + (scaleH * 0.25);\r\n        ctx.moveTo(0, y12_top); ctx.lineTo(w, y12_top); ctx.moveTo(0, y12_bot); ctx.lineTo(w, y12_bot); ctx.stroke();\r\n        ctx.setLineDash([]);\r\n    }\r\n\r\n    function drawKnob(ctx, x, y, r) {\r\n        let pVal = parseFloat(document.getElementById('pan-slider').value);\r\n        let angle = pVal * (Math.PI * 0.75) - (Math.PI \/ 2); \r\n        ctx.font = \"8px Orbitron\"; ctx.textAlign = \"center\"; ctx.fillStyle = \"#0f172a\";\r\n        ctx.fillText(\"C\", x, y - r - 5);\r\n        ctx.beginPath(); ctx.arc(x, y, r, 0, 2 * Math.PI); ctx.lineWidth = 2; ctx.strokeStyle = '#0f172a'; ctx.stroke();\r\n        ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + Math.cos(angle) * r, y + Math.sin(angle) * r); ctx.stroke();\r\n    }\r\n\r\n    function drawStatusBar(ctx, w, h) {\r\n        let labels = ['SINE', 'SQR', 'SAW', 'TRI', 'WHITE', 'PINK', 'BLUE', 'GREY', 'RED', 'LIN', 'LOG'];\r\n        let boxW = 26; let boxH = 12; let gap = 2; let startX = 20; let startY = h - 20; \r\n        let totalW = (labels.length * boxW) + ((labels.length - 1) * gap); startX = (w - totalW) \/ 2;\r\n        ctx.font = \"bold 7px 'Segoe UI'\"; ctx.textAlign = \"center\"; ctx.textBaseline = \"middle\";\r\n        labels.forEach((lbl, i) => {\r\n            let bx = startX + (i * (boxW + gap));\r\n            let isActive = false;\r\n            \r\n            if (curWave.toUpperCase() === lbl) isActive = true;\r\n            if (curWave === 'sawtooth' && lbl === 'SAW') isActive = true;\r\n            if (curWave === 'square' && lbl === 'SQR') isActive = true;\r\n            if (curWave === 'triangle' && lbl === 'TRI') isActive = true;\r\n            if (isNoise(curWave) && curWave.toUpperCase() === lbl) isActive = true;\r\n            \r\n            if(lbl === 'LIN' && selectedSweepMode === 'lin') isActive = true;\r\n            if(lbl === 'LOG' && selectedSweepMode === 'log') isActive = true;\r\n            \r\n            ctx.fillStyle = isActive ? 'rgba(15, 23, 42, 0.1)' : 'rgba(255, 255, 255, 0.1)';\r\n            ctx.fillRect(bx, startY, boxW, boxH);\r\n            ctx.strokeStyle = '#0f172a'; ctx.lineWidth = 1; ctx.strokeRect(bx, startY, boxW, boxH);\r\n            ctx.fillStyle = isActive ? '#0f172a' : 'rgba(15, 23, 42, 0.4)'; ctx.fillText(lbl, bx + (boxW\/2), startY + (boxH\/2));\r\n        });\r\n    }\r\n\r\n    function updateLEDs(level, lMod = 1, rMod = 1) {\r\n        const lLeds = document.getElementById('meter-l-strip').children;\r\n        const rLeds = document.getElementById('meter-r-strip').children;\r\n        let lLevel = Math.floor(level * lMod); let rLevel = Math.floor(level * rMod);\r\n        for (let i = 0; i < LED_COUNT; i++) {\r\n            let color = 'green';\r\n            if(i >= 14) color = 'yellow'; \r\n            if(i >= 17) color = 'red';    \r\n            let l = lLeds[i]; l.className = 'led-seg'; \r\n            if (i < lLevel) l.classList.add('on-' + color);\r\n            else l.classList.remove('on-green', 'on-yellow', 'on-red');\r\n            let r = rLeds[i]; r.className = 'led-seg'; \r\n            if (i < rLevel) r.classList.add('on-' + color);\r\n            else r.classList.remove('on-green', 'on-yellow', 'on-red');\r\n        }\r\n    }\r\n<\/script>\r\n<\/body>\r\n<\/html>\n\t\t<\/div>\n\t<\/div>\n<div class=\"vc_empty_space  height_large\"   style=\"height: 32px\"><span class=\"vc_empty_space_inner\"><\/span><\/div><div class=\"vc_btn3-container vc_btn3-center vc_do_btn\" ><a class=\"vc_general vc_btn3 vc_btn3-size-md vc_btn3-shape-square vc_btn3-style-outline vc_btn3-color-inverse\" href=\"\/master\" title=\"\">MENU<\/a><\/div><\/div><\/div><\/div><\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"Sonic Lab V25 - Mobile Fixed ? PARAMETER 50% DONE \u26a0\ufe0f HIGH GAIN WARNING Pushing volume above -6dB (50%) can damage equipment.Are you sure? CANCEL PROCEED SYSTEM MANUAL V25 \u2715 01. Intro 02. Master I\/O 03. Oscillators 04. Noise Gen 05. Freq Sweep 06. Musical 07. ISO & RTA 08. LFE Matrix 01. INTRODUCTION Sonic Lab V25 is a professional-grade&hellip;","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"TEC\\Tickets\\Commerce\\Module","_tribe_ticket_capacity":"0","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":"","_tec_slr_enabled":"","_tec_slr_layout":""},"class_list":["post-3258","page","type-page","status-publish","hentry"],"a3_pvc":{"activated":false,"total_views":0,"today_views":0},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v27.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>M-13b | papaya.events<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.papaya.events\/hr\/m-13b\/\" \/>\n<meta property=\"og:locale\" content=\"hr_HR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"M-13b\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.papaya.events\/hr\/m-13b\/\" \/>\n<meta property=\"og:site_name\" content=\"papaya.events\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/papaya.events.ls\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-13T04:11:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.papaya.events\/wp-content\/uploads\/2025\/02\/176-1-scaled.jpg?strip=all&quality=70&webp=65&sharp=1\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1695\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Procijenjeno vrijeme \u010ditanja\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minuta\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/\",\"url\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/\",\"name\":\"M-13b | papaya.events\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.papaya.events\\\/#website\"},\"datePublished\":\"2026-02-11T15:00:12+00:00\",\"dateModified\":\"2026-02-13T04:11:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#breadcrumb\"},\"inLanguage\":\"hr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.papaya.events\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"M-13b\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.papaya.events\\\/#website\",\"url\":\"https:\\\/\\\/www.papaya.events\\\/\",\"name\":\"papaya.events\",\"description\":\"Book the ultimate party event\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.papaya.events\\\/#organization\"},\"alternateName\":\"Unrivaled sounds, unforgettable light and FX for your events!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.papaya.events\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"hr\"},{\"@type\":[\"Organization\",\"Place\",\"LocalBusiness\"],\"@id\":\"https:\\\/\\\/www.papaya.events\\\/#organization\",\"name\":\"papaya.events\",\"alternateName\":\"Unrivaled sounds, unforgettable light and FX for your events!\",\"url\":\"https:\\\/\\\/www.papaya.events\\\/\",\"logo\":{\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#local-main-organization-logo\"},\"image\":{\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#local-main-organization-logo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/papaya.events.ls\",\"https:\\\/\\\/soundcloud.com\\\/papaya_events\",\"https:\\\/\\\/www.beatport.com\\\/artist\\\/drama\\\/170702\",\"https:\\\/\\\/www.youtube.com\\\/@papaya.events\",\"https:\\\/\\\/open.spotify.com\\\/user\\\/31m3wahhbsmph36a35fmzv45y344\",\"https:\\\/\\\/www.instagram.com\\\/papaya.events.ls\"],\"description\":\"Papaya Events is an event organization based in Umag, Croatia, run by three artists, specializing in open-air and club events that bring together music lovers through electronic sounds and an engaging atmosphere. The organization provides a complete experience, including its own production, sound, lighting, scene effects, and all essential elements for creating unforgettable moments. Their events range from intimate, small private parties to larger open-air gatherings, offering a diverse range of electronic music to suit every taste and setting. The focus is on crafting unforgettable experiences that leave lasting memories for all music enthusiasts and partygoers.\",\"legalName\":\"V.I.S.T.A. Ltd.\",\"foundingDate\":\"2006-04-07\",\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"minValue\":\"1\",\"maxValue\":\"10\"},\"publishingPrinciples\":\"https:\\\/\\\/www.papaya.events\\\/our-services\\\/\",\"ownershipFundingInfo\":\"https:\\\/\\\/www.papaya.events\\\/our-services\\\/\",\"address\":{\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#local-main-place-address\"},\"geo\":{\"@type\":\"GeoCoordinates\",\"latitude\":\"45.430166630509255\",\"longitude\":\"13.529640133684602\"},\"telephone\":[\"+385915127282\"],\"contactPoint\":{\"@type\":\"ContactPoint\",\"telephone\":\"+385915127282\",\"email\":\"info@papaya.events\"},\"openingHoursSpecification\":{\"@type\":\"OpeningHoursSpecification\",\"dayOfWeek\":[\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"],\"opens\":\"00:00\",\"closes\":\"23:59\"},\"email\":\"info@papaya.events\",\"vatID\":\"HR93447560687\",\"priceRange\":\"$$$\"},{\"@type\":\"PostalAddress\",\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#local-main-place-address\",\"streetAddress\":\"Vladimir Nazor 5\",\"addressLocality\":\"Umag\",\"postalCode\":\"52470\",\"addressRegion\":\"Croatia\",\"addressCountry\":\"HR\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"hr\",\"@id\":\"https:\\\/\\\/www.papaya.events\\\/m-13b\\\/#local-main-organization-logo\",\"url\":\"https:\\\/\\\/cdn.papaya.events\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/favicon-copy.png?strip=all&quality=70&webp=65&sharp=1\",\"contentUrl\":\"https:\\\/\\\/cdn.papaya.events\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/favicon-copy.png?strip=all&quality=70&webp=65&sharp=1\",\"width\":1024,\"height\":1024,\"caption\":\"papaya.events\"}]}<\/script>\n<meta name=\"geo.placename\" content=\"Umag\" \/>\n<meta name=\"geo.position\" content=\"45.430166630509255;13.529640133684602\" \/>\n<meta name=\"geo.region\" content=\"Croatia\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"M-13b | papaya.events","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.papaya.events\/hr\/m-13b\/","og_locale":"hr_HR","og_type":"article","og_title":"M-13b","og_url":"https:\/\/www.papaya.events\/hr\/m-13b\/","og_site_name":"papaya.events","article_publisher":"https:\/\/www.facebook.com\/papaya.events.ls","article_modified_time":"2026-02-13T04:11:30+00:00","og_image":[{"width":2560,"height":1695,"url":"https:\/\/cdn.papaya.events\/wp-content\/uploads\/2025\/02\/176-1-scaled.jpg?strip=all&quality=70&webp=65&sharp=1","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Procijenjeno vrijeme \u010ditanja":"1 minuta"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.papaya.events\/m-13b\/","url":"https:\/\/www.papaya.events\/m-13b\/","name":"M-13b | papaya.events","isPartOf":{"@id":"https:\/\/www.papaya.events\/#website"},"datePublished":"2026-02-11T15:00:12+00:00","dateModified":"2026-02-13T04:11:30+00:00","breadcrumb":{"@id":"https:\/\/www.papaya.events\/m-13b\/#breadcrumb"},"inLanguage":"hr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.papaya.events\/m-13b\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.papaya.events\/m-13b\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.papaya.events\/"},{"@type":"ListItem","position":2,"name":"M-13b"}]},{"@type":"WebSite","@id":"https:\/\/www.papaya.events\/#website","url":"https:\/\/www.papaya.events\/","name":"papaya.events","description":"Rezervirajte vrhunski party doga\u0111aj","publisher":{"@id":"https:\/\/www.papaya.events\/#organization"},"alternateName":"Unrivaled sounds, unforgettable light and FX for your events!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.papaya.events\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"hr"},{"@type":["Organization","Place","LocalBusiness"],"@id":"https:\/\/www.papaya.events\/#organization","name":"papaya.events","alternateName":"Unrivaled sounds, unforgettable light and FX for your events!","url":"https:\/\/www.papaya.events\/","logo":{"@id":"https:\/\/www.papaya.events\/m-13b\/#local-main-organization-logo"},"image":{"@id":"https:\/\/www.papaya.events\/m-13b\/#local-main-organization-logo"},"sameAs":["https:\/\/www.facebook.com\/papaya.events.ls","https:\/\/soundcloud.com\/papaya_events","https:\/\/www.beatport.com\/artist\/drama\/170702","https:\/\/www.youtube.com\/@papaya.events","https:\/\/open.spotify.com\/user\/31m3wahhbsmph36a35fmzv45y344","https:\/\/www.instagram.com\/papaya.events.ls"],"description":"Papaya Events je organizacija za doga\u0111aje sa sjedi\u0161tem u Umagu u Hrvatskoj, koju vode tri umjetnika, specijalizirana za doga\u0111aje na otvorenom i u klubovima koji okupljaju ljubitelje glazbe kroz elektroni\u010dke zvukove i zanimljivu atmosferu. Organizacija pru\u017ea cjelovito iskustvo, uklju\u010duju\u0107i vlastitu produkciju, zvuk, rasvjetu, scenske efekte i sve bitne elemente za stvaranje nezaboravnih trenutaka. Njihovi doga\u0111aji kre\u0107u se od intimnih, malih privatnih zabava do ve\u0107ih okupljanja na otvorenom, nude\u0107i raznolik raspon elektroni\u010dke glazbe za sva\u010diji ukus i okru\u017eenje. Fokus je na stvaranju nezaboravnih iskustava koja ostavljaju trajne uspomene za sve ljubitelje glazbe i ljubitelje zabave.","legalName":"V.I.S.T.A. Ltd.","foundingDate":"2006-04-07","numberOfEmployees":{"@type":"QuantitativeValue","minValue":"1","maxValue":"10"},"publishingPrinciples":"https:\/\/www.papaya.events\/our-services\/","ownershipFundingInfo":"https:\/\/www.papaya.events\/our-services\/","address":{"@id":"https:\/\/www.papaya.events\/m-13b\/#local-main-place-address"},"geo":{"@type":"GeoCoordinates","latitude":"45.430166630509255","longitude":"13.529640133684602"},"telephone":["+385915127282"],"contactPoint":{"@type":"ContactPoint","telephone":"+385915127282","email":"info@papaya.events"},"openingHoursSpecification":{"@type":"OpeningHoursSpecification","dayOfWeek":["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],"opens":"00:00","closes":"23:59"},"email":"info@papaya.events","vatID":"HR93447560687","priceRange":"$$$"},{"@type":"PostalAddress","@id":"https:\/\/www.papaya.events\/m-13b\/#local-main-place-address","streetAddress":"Vladimir Nazor 5","addressLocality":"Umag","postalCode":"52470","addressRegion":"Croatia","addressCountry":"HR"},{"@type":"ImageObject","inLanguage":"hr","@id":"https:\/\/www.papaya.events\/m-13b\/#local-main-organization-logo","url":"https:\/\/cdn.papaya.events\/wp-content\/uploads\/2025\/02\/favicon-copy.png?strip=all&quality=70&webp=65&sharp=1","contentUrl":"https:\/\/cdn.papaya.events\/wp-content\/uploads\/2025\/02\/favicon-copy.png?strip=all&quality=70&webp=65&sharp=1","width":1024,"height":1024,"caption":"papaya.events"}]},"geo.placename":"Umag","geo.position":{"lat":"45.430166630509255","long":"13.529640133684602"},"geo.region":"Croatia"},"ticketed":false,"_links":{"self":[{"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/pages\/3258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/comments?post=3258"}],"version-history":[{"count":23,"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/pages\/3258\/revisions"}],"predecessor-version":[{"id":3311,"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/pages\/3258\/revisions\/3311"}],"wp:attachment":[{"href":"https:\/\/www.papaya.events\/hr\/wp-json\/wp\/v2\/media?parent=3258"}],"curies":[{"name":"radni list","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}