<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="theme-color" content="#090b12">
    <title>ELYWARE Video Mixer 4.1</title>
    <link rel="icon" type="image/svg+xml" href="/static/brand/video-mixer-mark.svg">
    <link rel="icon" type="image/png" sizes="32x32" href="/static/brand/video-mixer-icon-32.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/static/brand/video-mixer-icon-180.png">
    <link rel="stylesheet" href="/static/css/style.css?v=4.1">
</head>
<body class="fullscreen-decks">
    <!-- Compact Toolbar -->
    <div id="toolbar">
        <div class="brand-lockup" aria-label="ELYWARE Video Mixer 4.1">
            <img class="brand-mark" src="/static/brand/video-mixer-mark.svg" alt="" width="30" height="30">
            <span class="brand-copy">
                <span class="brand-wordmark">ELYWARE</span>
                <span class="brand-product">VIDEO MIXER <span class="version-tag">4.1</span></span>
            </span>
        </div>
        <div id="toolbar-controls">
            <span id="output-status" class="output-disconnected"><i></i> OUTPUT OFFLINE</span>
            <button id="popout-btn" title="Open Output Window (drag to second monitor)">&#x2750; Open Output</button>
            <label class="resolution-control">RES
                <select id="output-resolution">
                    <option value="1280x720">720p</option>
                    <option value="1920x1080" selected>1080p</option>
                </select>
            </label>
            <button id="theme-toggle-btn" title="Theme: Dark / Light / Auto">&#x263E;</button>
            <button id="fullscreen-btn" title="Fullscreen Mixer (F)">&#x26F6;</button>
            <button id="save-session-btn" title="Save Session">&#x1F4BE; Save</button>
            <button id="load-session-btn" title="Load Session">&#x1F4C2; Load</button>
            <button id="reset-layout-btn" title="Reset panel sizes">&#x2922;</button>
            <button id="shortcuts-btn" title="Keyboard Shortcuts">?</button>
        </div>
    </div>

    <!-- Hidden master canvas (renders mix for BroadcastChannel sync) -->
    <canvas id="master-output" style="display:none;"></canvas>

    <!-- Decks Row — fills remaining screen, panels resizable via splitters -->
    <div id="decks-row">
        <!-- Deck A -->
        <div class="deck" id="deck-a">
            <div class="drop-overlay hidden" data-deck="a">Drop files or folders here</div>
            <div class="deck-header">
                <span class="deck-label">DECK A</span>
                <span class="deck-now-playing" id="deck-a-now-playing">No media loaded</span>
                <span class="deck-error hidden" id="deck-a-error" title="Media load error">&#x26A0;</span>
            </div>
            <div class="deck-preview-wrap" data-deck="a">
                <canvas class="deck-preview" id="deck-a-preview"></canvas>
                <video id="deck-a-video" muted playsinline preload="auto"></video>
                <!-- VU Meter -->
                <div class="vu-meter" id="vu-meter-a">
                    <div class="vu-bar"><div class="vu-fill" id="vu-fill-a"></div></div>
                </div>
            </div>
            <div class="preview-resize-handle" title="Drag to resize previews (double-click to reset)"></div>
            <div class="deck-transport">
                <button class="transport-btn" data-deck="a" data-action="prev" title="Previous">&#x23EE;</button>
                <button class="transport-btn play-btn" data-deck="a" data-action="play" title="Play/Pause">&#x25B6;</button>
                <button class="transport-btn" data-deck="a" data-action="next" title="Next">&#x23ED;</button>
                <button class="transport-btn" data-deck="a" data-action="loop" title="Loop">&#x1F501;</button>
                <button class="transport-btn" data-deck="a" data-action="shuffle" title="Shuffle">&#x1F500;</button>
            </div>
            <div class="deck-sliders">
                <label>Vol <input type="range" min="0" max="100" value="100" class="vol-slider" data-deck="a"> <span class="vol-val" data-deck="a">100</span></label>
                <label>Speed <input type="range" min="25" max="200" value="100" class="speed-slider" data-deck="a"> <span class="speed-val" data-deck="a">1.0x</span></label>
                <label title="Image/visual auto-advance (slideshow). 0 = OFF, stays on screen.">Slide <input type="range" min="0" max="30" value="0" class="slide-dur-slider" data-deck="a"> <span class="slide-dur-val" data-deck="a">OFF</span></label>
            </div>
            <div class="deck-progress-wrap">
                <input type="range" min="0" max="1000" value="0" class="progress-slider" data-deck="a">
                <span class="time-display" data-deck="a">0:00 / 0:00</span>
            </div>
            <!-- Per-Deck FX -->
            <div class="deck-fx collapsed" id="deck-a-fx">
                <button class="deck-fx-toggle" data-deck="a">FX &#x25BC;</button>
                <div class="deck-fx-controls hidden" data-deck="a">
                    <label>Bright <input type="range" min="50" max="200" value="100" class="dfx-slider" data-deck="a" data-fx="brightness"></label>
                    <label>Contrast <input type="range" min="50" max="200" value="100" class="dfx-slider" data-deck="a" data-fx="contrast"></label>
                    <label>Saturate <input type="range" min="0" max="200" value="100" class="dfx-slider" data-deck="a" data-fx="saturate"></label>
                    <label>Hue <input type="range" min="0" max="360" value="0" class="dfx-slider" data-deck="a" data-fx="hue"></label>
                    <button class="deck-fx-reset" data-deck="a">Reset</button>
                </div>
            </div>

            <!-- Tabbed Panel: Browse | Playlist | Stock -->
            <div class="deck-tabs" data-deck="a">
                <button class="deck-tab active" data-deck="a" data-tab="browse">Browse</button>
                <button class="deck-tab" data-deck="a" data-tab="playlist">Playlist <span class="tab-badge" data-deck="a">0</span></button>
                <button class="deck-tab" data-deck="a" data-tab="visuals">Stock</button>
            </div>
            <div class="deck-panels" data-deck="a">
                <div class="file-browser deck-panel active" data-panel="browse" id="browser-a">
                    <div class="browser-nav">
                        <button class="nav-btn" data-deck="a" data-nav="up" title="Parent folder">&#x2191;</button>
                        <button class="nav-btn" data-deck="a" data-nav="home" title="Home folder">&#x2302;</button>
                        <button class="nav-btn recent-btn" data-deck="a" data-nav="recent" title="Recent folders">&#x23F1; &#x25BE;</button>
                        <input type="text" class="path-input" data-deck="a" placeholder="Folder path... (Enter to go)">
                        <div class="recent-menu hidden" data-deck="a"></div>
                    </div>
                    <div class="browser-search">
                        <span class="search-icon">&#x2315;</span>
                        <input type="text" class="search-input" data-deck="a" placeholder="Search media... Enter = include subfolders">
                        <button class="search-clear hidden" data-deck="a" title="Clear search (Esc)">&#x2715;</button>
                    </div>
                    <div class="search-status hidden" data-deck="a"></div>
                    <div class="browser-path breadcrumb" data-deck="a"></div>
                    <ul class="file-list" data-deck="a"></ul>
                    <div class="browser-actions">
                        <button class="load-folder-btn" data-deck="a">Load All to Deck A</button>
                    </div>
                </div>
                <div class="playlist-panel deck-panel" data-panel="playlist" data-deck="a">
                    <div class="playlist-head">
                        <div class="playlist-summary">
                            <span class="playlist-count" data-deck="a">0 items</span>
                            <span class="playlist-position" data-deck="a">Ready</span>
                        </div>
                        <div class="playlist-actions">
                            <button class="playlist-copy" data-deck="a" title="Copy this set to Deck B">A&#x2192;B</button>
                            <button class="playlist-export" data-deck="a" title="Save this set as JSON">Save Set</button>
                            <button class="playlist-import" data-deck="a" title="Load or append a saved set">Load Set</button>
                            <button class="playlist-clear" data-deck="a" title="Clear playlist">Clear</button>
                        </div>
                    </div>
                    <div class="playlist-filter">
                        <span class="search-icon">&#x2315;</span>
                        <input type="text" class="playlist-search" data-deck="a" placeholder="Filter this set...">
                        <button class="playlist-search-clear hidden" data-deck="a" title="Clear filter">&#x2715;</button>
                    </div>
                    <ul class="playlist-list" data-deck="a"></ul>
                    <div class="playlist-empty" data-deck="a">Playlist is empty.<br>Load media from Browse or Stock.</div>
                    <div class="playlist-foot">Double-click to play &middot; Drag to reorder &middot; Use row tools to cue</div>
                </div>
                <div class="stock-panel deck-panel" data-panel="visuals" data-deck="a">
                    <div class="stock-toolbar">
                        <form class="stock-search-form" data-deck="a" role="search">
                            <input type="search" class="stock-search-input" data-deck="a" placeholder="Search Pixabay video..." autocomplete="off" aria-label="Search Pixabay stock video">
                            <button class="stock-search-btn" type="submit">Search</button>
                        </form>
                        <div class="stock-subnav">
                            <div class="stock-modes" role="tablist" aria-label="Stock video view">
                                <button class="stock-mode active" type="button" role="tab" aria-selected="true" data-deck="a" data-mode="discover">Discover</button>
                                <button class="stock-mode" type="button" role="tab" aria-selected="false" data-deck="a" data-mode="cached">Cached</button>
                            </div>
                            <span class="stock-cache-summary" data-deck="a">Checking cache...</span>
                            <button class="stock-config-btn hidden" type="button" data-deck="a" title="Change Pixabay API key">Key</button>
                        </div>
                    </div>
                    <div class="stock-status" data-deck="a" role="status" aria-live="polite"></div>
                    <div class="stock-content" data-deck="a"></div>
                    <div class="stock-preview hidden" data-deck="a" role="dialog" aria-modal="true" aria-label="Stock video details"></div>
                    <div class="stock-hint">Pixabay thumbnails &middot; clips cache locally before play or queue</div>
                </div>
            </div>
        </div>

        <div class="splitter" id="split-a" title="Drag to resize (double-click to reset)"></div>

        <!-- Center / Crossfader -->
        <div id="center-panel">
            <div id="crossfader-section">
                <span class="cf-label">A</span>
                <input type="range" id="crossfader" min="0" max="1000" value="500">
                <span class="cf-label">B</span>
            </div>

            <!-- Mini output preview -->
            <div id="mini-preview-wrap">
                <canvas id="mini-preview"></canvas>
                <span class="mini-label">MIX PREVIEW</span>
            </div>

            <!-- Transition Picker -->
            <div id="transition-section">
                <span class="section-title">TRANSITION</span>
                <div class="trans-search">
                    <input type="text" id="transition-search" placeholder="Filter transitions...">
                </div>
                <div id="transition-picker">
                    <!-- Populated by JS -->
                </div>
                <div id="transition-current">
                    <span id="transition-current-name">Crossfade</span>
                </div>
            </div>

            <div id="auto-mix-section">
                <button id="auto-mix-btn">Auto Mix</button>
                <label>Duration:
                    <input type="range" id="auto-mix-duration" min="500" max="10000" value="2000" step="100">
                    <span id="auto-mix-dur-val">2.0s</span>
                </label>
            </div>

            <div id="autopilot-section">
                <span class="section-title">AUTOPILOT</span>
                <button id="autopilot-btn">Autopilot</button>
                <label>Hold: <input type="range" id="autopilot-hold" min="3" max="30" value="8"> <span id="autopilot-hold-val">8s</span></label>
                <label>Fade: <input type="range" id="autopilot-trans" min="1" max="8" value="3" step="0.5"> <span id="autopilot-trans-val">3s</span></label>
            </div>

            <!-- BPM / Beat Sync -->
            <div id="bpm-section">
                <span class="section-title">BEAT SYNC</span>
                <div id="bpm-display">-- BPM</div>
                <button id="tap-tempo-btn">TAP</button>
                <button id="beat-sync-btn">Sync to Beat</button>
            </div>

            <div id="fx-section">
                <span class="section-title">MASTER FX</span>
                <label>Bright <input type="range" id="fx-brightness" min="50" max="200" value="100"></label>
                <label>Contrast <input type="range" id="fx-contrast" min="50" max="200" value="100"></label>
                <label>Saturate <input type="range" id="fx-saturate" min="0" max="200" value="100"></label>
                <label>Hue <input type="range" id="fx-hue" min="0" max="360" value="0"></label>
                <button id="fx-reset">Reset FX</button>
            </div>

            <div id="custom-transitions-section">
                <span class="section-title">CUSTOM FX</span>
                <button id="load-custom-btn">Reload Custom</button>
                <div id="custom-list"></div>
            </div>
        </div>

        <div class="splitter" id="split-b" title="Drag to resize (double-click to reset)"></div>

        <!-- Deck B -->
        <div class="deck" id="deck-b">
            <div class="drop-overlay hidden" data-deck="b">Drop files or folders here</div>
            <div class="deck-header">
                <span class="deck-label">DECK B</span>
                <span class="deck-now-playing" id="deck-b-now-playing">No media loaded</span>
                <span class="deck-error hidden" id="deck-b-error" title="Media load error">&#x26A0;</span>
            </div>
            <div class="deck-preview-wrap" data-deck="b">
                <canvas class="deck-preview" id="deck-b-preview"></canvas>
                <video id="deck-b-video" muted playsinline preload="auto"></video>
                <!-- VU Meter -->
                <div class="vu-meter" id="vu-meter-b">
                    <div class="vu-bar"><div class="vu-fill" id="vu-fill-b"></div></div>
                </div>
            </div>
            <div class="preview-resize-handle" title="Drag to resize previews (double-click to reset)"></div>
            <div class="deck-transport">
                <button class="transport-btn" data-deck="b" data-action="prev" title="Previous">&#x23EE;</button>
                <button class="transport-btn play-btn" data-deck="b" data-action="play" title="Play/Pause">&#x25B6;</button>
                <button class="transport-btn" data-deck="b" data-action="next" title="Next">&#x23ED;</button>
                <button class="transport-btn" data-deck="b" data-action="loop" title="Loop">&#x1F501;</button>
                <button class="transport-btn" data-deck="b" data-action="shuffle" title="Shuffle">&#x1F500;</button>
            </div>
            <div class="deck-sliders">
                <label>Vol <input type="range" min="0" max="100" value="100" class="vol-slider" data-deck="b"> <span class="vol-val" data-deck="b">100</span></label>
                <label>Speed <input type="range" min="25" max="200" value="100" class="speed-slider" data-deck="b"> <span class="speed-val" data-deck="b">1.0x</span></label>
                <label title="Image/visual auto-advance (slideshow). 0 = OFF, stays on screen.">Slide <input type="range" min="0" max="30" value="0" class="slide-dur-slider" data-deck="b"> <span class="slide-dur-val" data-deck="b">OFF</span></label>
            </div>
            <div class="deck-progress-wrap">
                <input type="range" min="0" max="1000" value="0" class="progress-slider" data-deck="b">
                <span class="time-display" data-deck="b">0:00 / 0:00</span>
            </div>
            <!-- Per-Deck FX -->
            <div class="deck-fx collapsed" id="deck-b-fx">
                <button class="deck-fx-toggle" data-deck="b">FX &#x25BC;</button>
                <div class="deck-fx-controls hidden" data-deck="b">
                    <label>Bright <input type="range" min="50" max="200" value="100" class="dfx-slider" data-deck="b" data-fx="brightness"></label>
                    <label>Contrast <input type="range" min="50" max="200" value="100" class="dfx-slider" data-deck="b" data-fx="contrast"></label>
                    <label>Saturate <input type="range" min="0" max="200" value="100" class="dfx-slider" data-deck="b" data-fx="saturate"></label>
                    <label>Hue <input type="range" min="0" max="360" value="0" class="dfx-slider" data-deck="b" data-fx="hue"></label>
                    <button class="deck-fx-reset" data-deck="b">Reset</button>
                </div>
            </div>

            <!-- Tabbed Panel: Browse | Playlist | Stock -->
            <div class="deck-tabs" data-deck="b">
                <button class="deck-tab active" data-deck="b" data-tab="browse">Browse</button>
                <button class="deck-tab" data-deck="b" data-tab="playlist">Playlist <span class="tab-badge" data-deck="b">0</span></button>
                <button class="deck-tab" data-deck="b" data-tab="visuals">Stock</button>
            </div>
            <div class="deck-panels" data-deck="b">
                <div class="file-browser deck-panel active" data-panel="browse" id="browser-b">
                    <div class="browser-nav">
                        <button class="nav-btn" data-deck="b" data-nav="up" title="Parent folder">&#x2191;</button>
                        <button class="nav-btn" data-deck="b" data-nav="home" title="Home folder">&#x2302;</button>
                        <button class="nav-btn recent-btn" data-deck="b" data-nav="recent" title="Recent folders">&#x23F1; &#x25BE;</button>
                        <input type="text" class="path-input" data-deck="b" placeholder="Folder path... (Enter to go)">
                        <div class="recent-menu hidden" data-deck="b"></div>
                    </div>
                    <div class="browser-search">
                        <span class="search-icon">&#x2315;</span>
                        <input type="text" class="search-input" data-deck="b" placeholder="Search media... Enter = include subfolders">
                        <button class="search-clear hidden" data-deck="b" title="Clear search (Esc)">&#x2715;</button>
                    </div>
                    <div class="search-status hidden" data-deck="b"></div>
                    <div class="browser-path breadcrumb" data-deck="b"></div>
                    <ul class="file-list" data-deck="b"></ul>
                    <div class="browser-actions">
                        <button class="load-folder-btn" data-deck="b">Load All to Deck B</button>
                    </div>
                </div>
                <div class="playlist-panel deck-panel" data-panel="playlist" data-deck="b">
                    <div class="playlist-head">
                        <div class="playlist-summary">
                            <span class="playlist-count" data-deck="b">0 items</span>
                            <span class="playlist-position" data-deck="b">Ready</span>
                        </div>
                        <div class="playlist-actions">
                            <button class="playlist-copy" data-deck="b" title="Copy this set to Deck A">B&#x2192;A</button>
                            <button class="playlist-export" data-deck="b" title="Save this set as JSON">Save Set</button>
                            <button class="playlist-import" data-deck="b" title="Load or append a saved set">Load Set</button>
                            <button class="playlist-clear" data-deck="b" title="Clear playlist">Clear</button>
                        </div>
                    </div>
                    <div class="playlist-filter">
                        <span class="search-icon">&#x2315;</span>
                        <input type="text" class="playlist-search" data-deck="b" placeholder="Filter this set...">
                        <button class="playlist-search-clear hidden" data-deck="b" title="Clear filter">&#x2715;</button>
                    </div>
                    <ul class="playlist-list" data-deck="b"></ul>
                    <div class="playlist-empty" data-deck="b">Playlist is empty.<br>Load media from Browse or Stock.</div>
                    <div class="playlist-foot">Double-click to play &middot; Drag to reorder &middot; Use row tools to cue</div>
                </div>
                <div class="stock-panel deck-panel" data-panel="visuals" data-deck="b">
                    <div class="stock-toolbar">
                        <form class="stock-search-form" data-deck="b" role="search">
                            <input type="search" class="stock-search-input" data-deck="b" placeholder="Search Pixabay video..." autocomplete="off" aria-label="Search Pixabay stock video">
                            <button class="stock-search-btn" type="submit">Search</button>
                        </form>
                        <div class="stock-subnav">
                            <div class="stock-modes" role="tablist" aria-label="Stock video view">
                                <button class="stock-mode active" type="button" role="tab" aria-selected="true" data-deck="b" data-mode="discover">Discover</button>
                                <button class="stock-mode" type="button" role="tab" aria-selected="false" data-deck="b" data-mode="cached">Cached</button>
                            </div>
                            <span class="stock-cache-summary" data-deck="b">Checking cache...</span>
                            <button class="stock-config-btn hidden" type="button" data-deck="b" title="Change Pixabay API key">Key</button>
                        </div>
                    </div>
                    <div class="stock-status" data-deck="b" role="status" aria-live="polite"></div>
                    <div class="stock-content" data-deck="b"></div>
                    <div class="stock-preview hidden" data-deck="b" role="dialog" aria-modal="true" aria-label="Stock video details"></div>
                    <div class="stock-hint">Pixabay thumbnails &middot; clips cache locally before play or queue</div>
                </div>
            </div>
        </div>
    </div>

    <!-- Keyboard Shortcuts Overlay -->
    <div id="shortcuts-overlay" class="hidden">
        <div id="shortcuts-box">
            <h3>Keyboard Shortcuts</h3>
            <table>
                <tr><td><kbd>Q</kbd></td><td>Play/Pause Deck A</td></tr>
                <tr><td><kbd>W</kbd></td><td>Play/Pause Deck B</td></tr>
                <tr><td><kbd>A</kbd> / <kbd>S</kbd></td><td>Prev / Next on Deck A</td></tr>
                <tr><td><kbd>K</kbd> / <kbd>L</kbd></td><td>Prev / Next on Deck B</td></tr>
                <tr><td><kbd>[</kbd> / <kbd>]</kbd></td><td>Search Deck A / Deck B</td></tr>
                <tr><td><kbd>&larr;</kbd> / <kbd>&rarr;</kbd></td><td>Move Crossfader</td></tr>
                <tr><td><kbd>Space</kbd></td><td>Auto Mix</td></tr>
                <tr><td><kbd>P</kbd></td><td>Toggle Autopilot</td></tr>
                <tr><td><kbd>O</kbd></td><td>Open Output Window</td></tr>
                <tr><td><kbd>F</kbd></td><td>Toggle Fullscreen</td></tr>
                <tr><td><kbd>T</kbd></td><td>Tap Tempo</td></tr>
                <tr><td><kbd>D</kbd></td><td>Cycle Theme (Dark/Light/Auto)</td></tr>
                <tr><td><kbd>1</kbd> / <kbd>2</kbd></td><td>Vol Down Deck A / B</td></tr>
                <tr><td><kbd>3</kbd> / <kbd>4</kbd></td><td>Vol Up Deck A / B</td></tr>
                <tr><td><kbd>Ctrl+S</kbd></td><td>Save Session</td></tr>
                <tr><td><kbd>?</kbd></td><td>Toggle Shortcuts</td></tr>
            </table>
            <p class="shortcuts-tip">Tip: drag the bars between panels to resize them. Double-click a bar to reset.</p>
            <button id="close-shortcuts">Close</button>
        </div>
    </div>

    <div id="app-toast" role="status" aria-live="polite"></div>

    <script src="/static/js/transitions.js?v=4.1"></script>
    <script src="/static/js/visuals.js?v=4.1"></script>
    <script src="/static/js/mixer.js?v=4.1"></script>
</body>
</html>
