Files

242 lines
13 KiB
HTML
Raw Permalink Normal View History

2026-03-25 14:14:07 +01:00
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Nexus AzA Remote</title>
<style>
:root {
--bg:#06080c;--surface:#0d1117;--surface2:#151b23;--border:#1e2733;
--text:#e6edf3;--text2:#8b949e;--accent:#00b4d8;--accent2:#0096c7;
--green:#2ea043;--red:#e5534b;--radius:8px;
}
*{margin:0;padding:0;box-sizing:border-box}
body{background:var(--bg);color:var(--text);font-family:'Segoe UI',system-ui,-apple-system,sans-serif;overflow:hidden;height:100vh}
/* ─── Control Bar ─── */
#bar{
position:fixed;top:0;left:0;right:0;z-index:100;
display:flex;align-items:center;gap:10px;
padding:10px 16px;
background:var(--surface);border-bottom:1px solid var(--border);
transition:opacity .4s ease,transform .3s ease;
}
#bar.dim{opacity:.08;transform:translateY(-2px)}
#bar:hover{opacity:1;transform:translateY(0)}
.bar-group{display:flex;align-items:center;gap:8px}
.bar-sep{width:1px;height:28px;background:var(--border);flex-shrink:0}
.bar-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:1.2px;color:var(--text2)}
.status-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--red);box-shadow:0 0 6px var(--red);transition:all .3s}
.status-dot.online{background:var(--green);box-shadow:0 0 8px var(--green)}
.id-display{display:flex;align-items:center;gap:6px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:6px 10px}
.id-value{font-family:'Cascadia Code','Consolas',monospace;font-size:18px;font-weight:700;letter-spacing:4px;color:var(--accent);min-width:80px;text-align:center}
.btn-copy{background:none;border:none;cursor:pointer;color:var(--text2);padding:2px;display:flex;border-radius:4px;transition:all .15s}
.btn-copy:hover{color:var(--accent);background:rgba(0,180,216,.1)}
.btn-copy.copied{color:var(--green)}
.key-box{padding:4px 8px}
.key-value{font-family:'Cascadia Code','Consolas',monospace;font-size:11px;letter-spacing:2px;color:var(--text2)}
.btn-renew{background:transparent;color:var(--text2);border:1px solid var(--border);padding:5px 7px;border-radius:var(--radius);cursor:pointer;display:flex;align-items:center;transition:all .15s}
.btn-renew:hover{color:var(--accent);border-color:var(--accent);background:rgba(0,180,216,.08)}
.input-remote{background:var(--surface2);border:1px solid var(--border);color:var(--text);padding:6px 10px;border-radius:var(--radius);font-family:'Cascadia Code','Consolas',monospace;font-size:18px;letter-spacing:4px;width:96px;text-align:center;transition:border-color .2s}
.input-remote:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px rgba(0,180,216,.15)}
.input-remote::placeholder{color:#333;letter-spacing:4px}
.input-key{width:114px;font-size:14px;letter-spacing:2px}
.key-input-wrap{position:relative;display:inline-flex;align-items:center}
.trust-badge{display:none;position:absolute;right:7px;top:50%;transform:translateY(-50%);color:var(--green);font-size:13px;font-weight:700;pointer-events:none}
.trust-badge.show{display:block}
.input-key.trusted{border-color:var(--green);background:rgba(46,160,67,.06)}
.btn{padding:7px 16px;border:none;border-radius:var(--radius);font-size:13px;font-weight:600;cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:6px}
.btn-connect{background:var(--accent);color:#fff;font-size:14px;padding:8px 24px}
.btn-connect:hover{background:var(--accent2);transform:translateY(-1px)}
.btn-connect:active{transform:translateY(0)}
.btn-share{background:var(--green);color:#fff}
.btn-share:hover{background:#33b24d}
.btn-share.active{background:var(--red)}
.btn-share.active:hover{background:#d44940}
/* ─── Kill Button ─── */
.btn-kill{
background:transparent;color:var(--red);
border:1px solid rgba(229,83,75,.3);
padding:7px 16px;font-size:12px;
}
.btn-kill:hover{background:var(--red);color:#fff;border-color:var(--red)}
.toggle-wrap{display:flex;align-items:center;gap:6px}
.toggle-label{font-size:11px;color:var(--text2);cursor:pointer;white-space:nowrap}
.toggle{position:relative;width:32px;height:18px;cursor:pointer}
.toggle input{opacity:0;width:0;height:0}
.toggle .slider{position:absolute;inset:0;background:#333;border-radius:9px;transition:background .2s}
.toggle .slider::before{content:'';position:absolute;width:14px;height:14px;border-radius:50%;left:2px;top:2px;background:#888;transition:all .2s}
.toggle input:checked+.slider{background:var(--accent)}
.toggle input:checked+.slider::before{transform:translateX(14px);background:#fff}
#status-text{font-size:11px;color:var(--text2);margin-left:auto;white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis}
/* ─── Shortcut Hint ─── */
.shortcut-hint{font-size:9px;color:#444;margin-left:4px;white-space:nowrap}
/* ─── Video ─── */
#remote-video{width:100vw;height:100vh;object-fit:contain;background:#000;cursor:crosshair}
.no-stream #remote-video{cursor:default}
/* ─── Placeholder ─── */
#placeholder{position:fixed;inset:0;z-index:50;display:flex;flex-direction:column;align-items:center;justify-content:center;background:var(--bg);gap:16px}
#placeholder.hidden{display:none}
#placeholder svg{width:64px;height:64px;opacity:.15}
#placeholder h2{font-size:20px;font-weight:300;color:#333;letter-spacing:4px;text-transform:uppercase}
#placeholder p{font-size:13px;color:#222}
.saved-peers{display:none;margin-top:20px;width:100%;max-width:340px}
.saved-peers.show{display:flex;flex-direction:column;gap:6px}
.saved-peers-title{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:1.5px;color:var(--text2);margin-bottom:4px}
.saved-peer-item{display:flex;align-items:center;gap:10px;padding:10px 16px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all .15s}
.saved-peer-item:hover{border-color:var(--accent);background:var(--surface2)}
.saved-peer-id{font-family:'Cascadia Code','Consolas',monospace;font-size:18px;letter-spacing:3px;color:var(--accent)}
.saved-peer-time{font-size:10px;color:var(--text2);margin-left:auto}
.saved-peer-remove{background:none;border:none;color:#444;font-size:18px;cursor:pointer;padding:0 4px;line-height:1;transition:color .15s}
.saved-peer-remove:hover{color:var(--red)}
/* ─── Kill-Switch Overlay ─── */
#kill-overlay{
position:fixed;inset:0;z-index:300;
background:rgba(6,8,12,.95);
display:none;flex-direction:column;
align-items:center;justify-content:center;gap:16px;
}
#kill-overlay.show{display:flex}
#kill-overlay .kill-icon{
width:72px;height:72px;border-radius:50%;
background:rgba(229,83,75,.12);border:2px solid rgba(229,83,75,.3);
display:flex;align-items:center;justify-content:center;
animation:kill-pulse .6s ease-out;
}
@keyframes kill-pulse{0%{transform:scale(.5);opacity:0}50%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
#kill-overlay h2{font-size:22px;font-weight:600;color:var(--red)}
#kill-overlay p{font-size:14px;color:var(--text2)}
#kill-overlay .kill-close{
margin-top:12px;padding:8px 32px;border:1px solid var(--border);
background:var(--surface2);color:var(--text);border-radius:var(--radius);
font-size:14px;cursor:pointer;transition:all .15s;
}
#kill-overlay .kill-close:hover{background:var(--surface);border-color:var(--accent)}
/* ─── Remote-Control Active Indicator ─── */
#rc-indicator{
position:fixed;top:56px;right:16px;z-index:110;
display:none;align-items:center;gap:6px;
background:rgba(46,160,67,.1);border:1px solid rgba(46,160,67,.25);
padding:5px 12px;border-radius:20px;
font-size:11px;color:var(--green);
animation:rc-fadein .3s ease-out;
}
#rc-indicator.show{display:flex}
#rc-indicator .rc-dot{width:6px;height:6px;border-radius:50%;background:var(--green);animation:rc-blink 1.5s infinite}
@keyframes rc-blink{0%,100%{opacity:1}50%{opacity:.3}}
@keyframes rc-fadein{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
/* ─── Toast ─── */
.toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:var(--surface2);border:1px solid var(--border);padding:8px 20px;border-radius:20px;font-size:12px;color:var(--text2);z-index:200;opacity:0;transition:opacity .3s;pointer-events:none}
.toast.show{opacity:1}
.toast.kill{border-color:rgba(229,83,75,.4);color:var(--red)}
</style>
</head>
<body class="no-stream">
<div id="bar">
<div class="bar-group">
<span class="status-dot" id="dot"></span>
<div>
<div class="bar-label">Meine ID</div>
<div class="id-display">
<span class="id-value" id="my-id">------</span>
<button class="btn-copy" id="btn-copy" title="ID kopieren">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
</button>
</div>
</div>
<div>
<div class="bar-label">Key</div>
<div class="id-display key-box">
<span class="key-value" id="my-key">--------</span>
</div>
</div>
<button class="btn-renew" id="btn-renew" title="ID & Key erneuern">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21.5 2v6h-6"/><path d="M2.5 22v-6h6"/><path d="M2 11.5a10 10 0 0118.8-4.3L21.5 8"/><path d="M22 12.5a10 10 0 01-18.8 4.3L2.5 16"/></svg>
</button>
</div>
<div class="bar-sep"></div>
<div class="bar-group">
<div>
<div class="bar-label">Remote ID</div>
<input type="text" class="input-remote" id="remote-id" placeholder="------" maxlength="6">
</div>
<div>
<div class="bar-label">Remote Key</div>
<div class="key-input-wrap">
<input type="text" class="input-remote input-key" id="remote-key" placeholder="--------" maxlength="8">
<span class="trust-badge" id="trust-badge" title="Gespeicherte Verbindung">&#10003;</span>
</div>
</div>
<button class="btn btn-connect" id="btn-connect">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4M10 17l5-5-5-5M13.8 12H3"/></svg>
Verbinden
</button>
</div>
<div class="bar-sep"></div>
<button class="btn btn-share" id="btn-share">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
Screen teilen
</button>
<div class="bar-sep"></div>
<button class="btn btn-kill" id="btn-kill">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
Trennen
</button>
<div class="bar-sep"></div>
<div class="toggle-wrap">
<label class="toggle"><input type="checkbox" id="cb-ctrl" checked><span class="slider"></span></label>
<span class="toggle-label">Steuerung</span>
</div>
<div class="toggle-wrap">
<label class="toggle"><input type="checkbox" id="cb-aot"><span class="slider"></span></label>
<span class="toggle-label">Pin</span>
</div>
<span id="status-text">Starte...</span>
<span class="shortcut-hint">ESC = Trennen &nbsp; Ctrl+Alt+K = Notaus</span>
</div>
<!-- Remote-Control Indicator -->
<div id="rc-indicator">
<span class="rc-dot"></span>
Fernsteuerung aktiv
</div>
<!-- Kill-Switch Overlay -->
<div id="kill-overlay">
<div class="kill-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#e5534b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
</div>
<h2>Verbindung sicher getrennt</h2>
<p>Alle Streams und Fernsteuerung wurden sofort beendet.</p>
<button class="kill-close" id="kill-close">OK</button>
</div>
<!-- Placeholder -->
<div id="placeholder">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
<h2>Nexus AzA Remote</h2>
<p>Remote-ID + Key eingeben oder auf Verbindung warten</p>
<div id="saved-peers" class="saved-peers"></div>
</div>
<video id="remote-video" autoplay></video>
<div class="toast" id="toast">ID kopiert</div>
<script src="renderer.js"></script>
</body>
</html>