2026-04-14 17:41:39 +02:00

469 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Elevator UI</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@400;500;600;700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
:root {
--panel: rgba(13, 12, 11, 0.97);
--panel-2: rgba(20, 17, 14, 0.95);
--border: rgba(255,255,255,0.06);
--border-bright: rgba(255,255,255,0.10);
--accent: #f07830;
--accent-dim: rgba(240, 120, 48, 0.08);
--accent-mid: rgba(240, 120, 48, 0.16);
--accent-glow: rgba(240, 120, 48, 0.35);
--text: #c8c4c0;
--text-muted: #504840;
--green: #3ddc84;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html {
background: transparent !important;
}
body {
display: none;
background: transparent !important;
font-family: 'Rajdhani', sans-serif;
height: 100vh;
width: 100vw;
align-items: center;
justify-content: center;
}
body.visible {
display: flex;
}
body::before {
content: '';
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 0;
}
#elevator-panel {
width: 420px;
background: var(--panel);
border: 1px solid var(--border-bright);
position: relative;
z-index: 1;
overflow: hidden;
animation: popIn 0.3s cubic-bezier(0.22, 1, 0.36, 1) forwards;
box-shadow: 0 8px 40px rgba(0,0,0,0.6);
}
/* Top orange accent line */
#elevator-panel::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 2px;
background: linear-gradient(90deg, transparent 5%, var(--accent) 40%, var(--accent) 60%, transparent 95%);
z-index: 10;
}
/* Scanlines */
#elevator-panel::after {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 3px,
rgba(0,0,0,0.06) 3px,
rgba(0,0,0,0.06) 4px
);
pointer-events: none;
z-index: 0;
}
@keyframes popIn {
from { opacity: 0; transform: scale(0.94) translateY(10px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
/* HEADER */
.panel-header {
padding: 16px 24px;
border-bottom: 1px solid var(--border);
position: relative;
z-index: 1;
display: flex;
align-items: center;
gap: 14px;
background: linear-gradient(180deg, rgba(240,120,48,0.05) 0%, transparent 100%);
}
.logo-wrap {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
border: 1px solid rgba(240,120,48,0.25);
padding: 4px;
}
.logo-wrap img {
width: 100%;
height: 100%;
object-fit: contain;
/* If image has transparent bg it'll blend nicely */
filter: brightness(1.1);
}
.header-info { flex: 1; min-width: 0; }
.building-name {
font-size: 20px;
font-weight: 700;
color: var(--accent);
letter-spacing: 0.1em;
text-transform: uppercase;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.2;
}
.panel-sub {
font-family: 'Share Tech Mono', monospace;
font-size: 10px;
color: var(--text-muted);
letter-spacing: 0.14em;
margin-top: 3px;
}
/* CURRENT FLOOR */
.current-floor-bar {
padding: 14px 24px;
background: var(--accent-dim);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
position: relative;
z-index: 1;
}
.current-floor-inner { flex: 1; }
.current-floor-label {
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
color: var(--text-muted);
letter-spacing: 0.16em;
text-transform: uppercase;
margin-bottom: 3px;
}
.current-floor-name {
font-size: 18px;
font-weight: 700;
color: var(--accent);
letter-spacing: 0.06em;
}
.floor-indicator {
display: flex;
flex-direction: column;
align-items: center;
gap: 3px;
}
.indicator-bar {
width: 2px;
height: 18px;
background: linear-gradient(180deg, var(--accent) 0%, transparent 100%);
opacity: 0.4;
}
.indicator-dot {
width: 8px;
height: 8px;
border: 1px solid var(--accent);
border-radius: 50%;
position: relative;
}
.indicator-dot::after {
content: '';
position: absolute;
inset: 2px;
background: var(--accent);
border-radius: 50%;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.3; transform: scale(0.6); }
}
/* FLOOR LIST */
.section-label {
padding: 16px 24px 8px;
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
color: var(--text-muted);
letter-spacing: 0.18em;
text-transform: uppercase;
position: relative;
z-index: 1;
display: flex;
align-items: center;
gap: 10px;
}
.section-label::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.floor-list {
padding: 0 16px 16px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
max-height: 280px;
overflow-y: auto;
position: relative;
z-index: 1;
}
.floor-list::-webkit-scrollbar { width: 3px; }
.floor-list::-webkit-scrollbar-track { background: transparent; }
.floor-list::-webkit-scrollbar-thumb { background: rgba(240,120,48,0.3); border-radius: 2px; }
.floor-button {
padding: 14px 16px;
background: var(--panel-2);
border: 1px solid var(--border);
color: var(--text);
font-family: 'Rajdhani', sans-serif;
font-size: 15px;
font-weight: 600;
letter-spacing: 0.05em;
text-align: left;
cursor: pointer;
position: relative;
overflow: hidden;
transition: border-color 0.15s, color 0.15s, background 0.15s, transform 0.1s;
display: flex;
flex-direction: column;
gap: 4px;
}
.floor-button::before {
content: '';
position: absolute;
left: 0; top: 0; bottom: 0;
width: 2px;
background: var(--accent);
transform: scaleY(0);
transform-origin: bottom;
transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}
.floor-button::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(240,120,48,0.06) 0%, transparent 60%);
opacity: 0;
transition: opacity 0.15s;
}
.floor-button:hover {
border-color: rgba(240, 120, 48, 0.3);
background: var(--accent-mid);
color: #fff;
}
.floor-button:hover::before { transform: scaleY(1); }
.floor-button:hover::after { opacity: 1; }
.floor-button:active { transform: scale(0.97); }
.floor-num {
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
color: var(--text-muted);
letter-spacing: 0.1em;
transition: color 0.15s;
}
.floor-button:hover .floor-num {
color: rgba(240,120,48,0.6);
}
/* FOOTER */
.panel-footer {
padding: 12px 24px;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
z-index: 1;
background: rgba(0,0,0,0.2);
}
.esc-hint {
font-family: 'Share Tech Mono', monospace;
font-size: 10px;
color: var(--text-muted);
letter-spacing: 0.1em;
display: flex;
align-items: center;
gap: 7px;
}
.key-badge {
background: rgba(255,255,255,0.05);
border: 1px solid var(--border-bright);
padding: 2px 7px;
font-size: 9px;
letter-spacing: 0.08em;
color: var(--text);
}
.status {
display: flex;
align-items: center;
gap: 6px;
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
color: var(--green);
letter-spacing: 0.1em;
}
.status-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--green);
box-shadow: 0 0 8px rgba(61, 220, 132, 0.6);
}
</style>
</head>
<body>
<div id="elevator-panel">
<div class="panel-header">
<div class="logo-wrap">
<img src="https://images.guns.lol/13ce84134d54a9db53288ce4761e9062fbebdad3/QwKzgg.png" alt="Logo">
</div>
<div class="header-info">
<div class="building-name" id="building-name"></div>
<div class="panel-sub">AUFZUG // STEUERUNG</div>
</div>
</div>
<div class="current-floor-bar">
<div class="current-floor-inner">
<div class="current-floor-label">Aktueller Standort</div>
<div class="current-floor-name" id="current-floor-display"></div>
</div>
<div class="floor-indicator">
<div class="indicator-bar"></div>
<div class="indicator-dot"></div>
<div class="indicator-bar" style="transform:rotate(180deg)"></div>
</div>
</div>
<div class="section-label">Etage wählen</div>
<div class="floor-list" id="floor-list"></div>
<div class="panel-footer">
<div class="esc-hint">
<span class="key-badge">ESC</span>
SCHLIESSEN
</div>
</div>
</div>
<script>
let currentFloors = [];
window.addEventListener('message', (event) => {
if (event.data.action === 'open') {
const { building, currentFloor } = event.data;
document.getElementById('building-name').textContent = building.name;
document.getElementById('current-floor-display').textContent = currentFloor.name;
currentFloors = building.floors
.filter(f => f.name !== currentFloor.name)
.sort((a, b) => parseFloat(b.name) - parseFloat(a.name));
const list = document.getElementById('floor-list');
list.innerHTML = '';
currentFloors.forEach((floor, i) => {
const btn = document.createElement('button');
btn.className = 'floor-button';
btn.innerHTML = `
<span class="floor-num">${String(i + 1).padStart(2, '0')}</span>
${floor.name}
`;
btn.addEventListener('click', () => selectFloor(floor));
list.appendChild(btn);
});
setVisible(true);
}
});
function selectFloor(floor) {
// Sofort schließen, nicht auf Server-Antwort warten
setVisible(false);
$.post('https://rlo_elevator/setNuiFocus', JSON.stringify({ focus: false, cursor: false }));
fetch('https://rlo_elevator/floorSelected', {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
body: JSON.stringify({ coords: floor.coords }),
});
}
document.addEventListener('keyup', handleEsc);
document.addEventListener('keydown', handleEsc);
function handleEsc(e) {
if (e.key === 'Escape' && document.body.classList.contains('visible')) {
e.preventDefault();
fetch('https://rlo_elevator/close', {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
body: JSON.stringify({}),
})
.then(r => r.json())
.then(data => {
if (data === 'OK') {
$.post('https://rlo_elevator/setNuiFocus', JSON.stringify({ focus: false, cursor: false }));
setVisible(false);
}
});
}
}
function setVisible(visible) {
document.body.classList.toggle('visible', visible);
}
</script>
</body>
</html>