Files
bordervillegame/game.html
T
2026-08-22 08:40:29 +02:00

1786 lines
68 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Multiplayer Game</title>
<style>
:root {
--bg-panel: rgba(24,26,32,0.94);
--bg-panel-solid: #181a20;
--border-soft: rgba(255,255,255,0.08);
--accent: #5b8def;
--accent-soft: rgba(91,141,239,0.15);
--text-main: #eaeaf0;
--text-dim: #8a8d98;
--radius: 10px;
--shadow: 0 8px 24px rgba(0,0,0,0.45);
--font-main: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}
html, body {
margin: 0;
padding: 0;
background: #0c0d10;
color: var(--text-main);
font-family: var(--font-main);
overflow: hidden;
width: 100%;
height: 100%;
}
/* Gemeinsamer Look für alle Fenster (...Box / ...Window) - ein
zentraler Ort statt 30x derselben rgba(20,20,20,0.9)-Deklaration */
[id$="Box"], [id$="Window"] {
background: var(--bg-panel);
border: 1px solid var(--border-soft);
border-radius: var(--radius);
box-shadow: var(--shadow);
backdrop-filter: blur(6px);
}
[id$="Box"] h3, [id$="Window"] h3 {
margin-top: 0;
color: var(--text-main);
font-weight: 600;
letter-spacing: 0.2px;
}
[id$="Box"] button, [id$="Window"] button {
background: var(--accent);
border: none;
color: white;
border-radius: 6px;
padding: 8px 14px;
font-family: var(--font-main);
cursor: pointer;
transition: filter 0.15s;
}
[id$="Box"] button:hover, [id$="Window"] button:hover { filter: brightness(1.12); }
[id$="Box"] button.secondary, [id$="Window"] button.secondary {
background: #33353e;
}
[id$="Box"] input, [id$="Window"] input,
[id$="Box"] select, [id$="Window"] select,
[id$="Box"] textarea, [id$="Window"] textarea {
background: #14151a;
border: 1px solid var(--border-soft);
color: var(--text-main);
border-radius: 6px;
padding: 8px 10px;
font-family: var(--font-main);
}
#loginBox, #registerBox {
position: absolute;
top: 50%;
left: 50%;
width: 300px;
padding: 20px;
background: #222;
border: 2px solid #444;
transform: translate(-50%, -50%);
display: none;
z-index: 10000;
}
#loginBox input, #registerBox input {
width: 100%;
padding: 8px;
margin: 6px 0;
background: #333;
border: 1px solid #555;
color: #eee;
box-sizing: border-box;
}
#loginBox button, #registerBox button {
width: 100%;
padding: 10px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
margin-top: 10px;
}
#switchToRegister, #switchToLogin {
margin-top: 10px;
text-align: center;
cursor: pointer;
color: #aaa;
}
/* Canvas: linksbündig, ohne Rand, direkt unter dem Top-Menü.
Die tatsächliche Pixel-Größe (canvas.width/height) wird
dynamisch per JS gesetzt (game.js), damit rechts immer
genug Platz für die UI-Fenster bleibt. */
#gameCanvas {
background: #000;
display: none;
position: absolute;
left: 0;
top: 50px; /* Höhe von #topMenu */
}
/* ---------- MOBILE TOUCH-STEUERUNG ---------- */
#touchControls {
display: none; /* wird per JS nur auf Touch-Geräten eingeblendet */
position: fixed;
left: 0; right: 0; bottom: 0;
z-index: 15000;
pointer-events: none; /* nur die Kinder-Elemente sollen Touches fangen */
}
#touchJoystickBase {
position: fixed;
left: 24px;
bottom: 24px;
width: 110px;
height: 110px;
border-radius: 50%;
background: rgba(255,255,255,0.08);
border: 2px solid rgba(255,255,255,0.25);
pointer-events: auto;
touch-action: none;
}
#touchJoystickKnob {
position: absolute;
left: 50%;
top: 50%;
width: 46px;
height: 46px;
margin-left: -23px;
margin-top: -23px;
border-radius: 50%;
background: rgba(255,255,255,0.35);
border: 2px solid rgba(255,255,255,0.5);
}
#touchActionButtons {
position: fixed;
right: 20px;
bottom: 24px;
display: flex;
flex-direction: column-reverse;
align-items: center;
gap: 12px;
pointer-events: auto;
}
.touch-btn {
width: 62px;
height: 62px;
border-radius: 50%;
background: rgba(44,122,61,0.75);
border: 2px solid rgba(255,255,255,0.4);
color: white;
font-size: 22px;
display: flex;
align-items: center;
justify-content: center;
touch-action: manipulation;
user-select: none;
-webkit-user-select: none;
}
.touch-btn:active { background: rgba(44,122,61,1); }
.touch-btn.small { width: 48px; height: 48px; font-size: 18px; background: rgba(60,60,60,0.75); }
#loadingScreen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #0a0a0a;
z-index: 50000;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
font-family: Arial, sans-serif;
transition: opacity 0.4s ease;
}
#loadingScreen.fading { opacity: 0; pointer-events: none; }
#loadingScreen h2 { margin: 0 0 20px 0; font-size: 24px; }
#loadingBarOuter {
width: 280px;
height: 10px;
background: #222;
border: 1px solid #444;
border-radius: 6px;
overflow: hidden;
}
#loadingBarInner {
height: 100%;
width: 0%;
background: #2c7a3d;
transition: width 0.25s ease;
}
#loadingStatusText {
margin-top: 12px;
font-size: 13px;
color: #999;
}
#loadingSpinner {
width: 36px;
height: 36px;
border: 3px solid #333;
border-top-color: #2c7a3d;
border-radius: 50%;
margin-bottom: 20px;
animation: loadingSpin 0.8s linear infinite;
}
@keyframes loadingSpin {
to { transform: rotate(360deg); }
}
#topMenu {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 50px;
background: linear-gradient(180deg, rgba(24,26,32,0.96), rgba(18,19,24,0.96));
color: var(--text-main);
font-size: 18px;
font-family: var(--font-main);
font-weight: 600;
padding-left: 20px;
display: flex;
align-items: center;
border-bottom: 1px solid var(--border-soft);
box-sizing: border-box;
z-index: 9999;
}
/* Rechte Seitenleiste: alle UI-Fenster ordnen sich hier ein,
damit nichts mit dem Canvas überlappt oder Platz "verschwendet" */
#statusWindow {
position: absolute;
right: 10px;
top: 70px;
width: 220px;
padding: 10px;
background: rgba(20,20,20,0.9);
color: white;
font-size: 18px;
border: 2px solid #444;
border-radius: 6px;
z-index: 9999;
box-sizing: border-box;
}
#inventoryWindow {
position: absolute;
right: 10px;
bottom: 10px;
width: 220px;
height: 280px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
box-sizing: border-box;
}
#shopWindow {
position: absolute;
right: 10px;
bottom: 310px;
width: 220px;
height: 280px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
box-sizing: border-box;
}
#atmBox {
position: absolute;
right: 10px;
bottom: 310px;
width: 220px;
height: 280px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
display: none;
box-sizing: border-box;
}
#atmBox input {
width: 100%;
padding: 6px;
margin: 4px 0;
background: #333;
border: 1px solid #555;
color: #eee;
box-sizing: border-box;
}
#atmBox button {
width: 100%;
padding: 6px;
margin-top: 4px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
}
#garageBox {
position: absolute;
right: 10px;
bottom: 310px;
width: 220px;
height: 280px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
display: none;
box-sizing: border-box;
}
#garageBox button {
padding: 4px 8px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
}
#jobBox {
position: absolute;
right: 10px;
bottom: 310px;
width: 220px;
height: 320px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
display: none;
box-sizing: border-box;
font-size: 13px;
}
#jobBox button {
padding: 3px 8px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
font-size: 12px;
}
#trunkBox {
position: absolute;
right: 10px;
bottom: 310px;
width: 260px;
height: 340px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
display: none;
box-sizing: border-box;
font-size: 13px;
}
#trunkBox h4 { margin: 10px 0 4px 0; border-bottom: 1px solid #333; padding-bottom: 4px; }
#trunkBox button {
padding: 3px 8px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
font-size: 11px;
}
#houseBox {
position: absolute;
right: 10px;
bottom: 310px;
width: 260px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #444;
border-radius: 6px;
padding: 10px;
max-height: 400px;
overflow-y: auto;
z-index: 9999;
display: none;
box-sizing: border-box;
font-size: 13px;
}
#houseBox h4 { margin: 10px 0 4px 0; border-bottom: 1px solid #333; padding-bottom: 4px; }
#houseBox button {
padding: 4px 10px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
font-size: 12px;
}
#houseBox .hidden { display: none !important; }
#adminBox {
position: absolute;
left: 50%;
top: 60px;
transform: translateX(-50%);
width: 480px;
max-height: 500px;
background: rgba(15,15,15,0.96);
color: white;
border: 2px solid #a83232;
border-radius: 8px;
padding: 14px;
overflow-y: auto;
z-index: 10000;
display: none;
box-sizing: border-box;
font-size: 13px;
}
#adminBox h3 { margin: 0 0 10px 0; color: #ff7b7b; }
.admin-player-row {
border-bottom: 1px solid #333;
padding: 8px 0;
}
.admin-player-row:last-child { border-bottom: none; }
.admin-player-head { display: flex; justify-content: space-between; margin-bottom: 6px; }
.admin-player-meta { color: #888; font-size: 12px; }
.admin-player-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.admin-player-actions input {
background: #222; border: 1px solid #444; color: #eee;
padding: 4px 6px; border-radius: 4px; font-size: 12px;
}
.admin-player-actions button {
padding: 4px 8px; background: #444; border: none; color: #eee;
cursor: pointer; border-radius: 4px; font-size: 12px;
}
.admin-player-actions button.danger { background: #a83232; }
#adminBoxFooter { margin-top: 10px; display: flex; gap: 8px; }
#taxiBox {
position: absolute;
right: 10px;
bottom: 310px;
width: 260px;
max-height: 340px;
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #f5d90a;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
z-index: 9999;
display: none;
box-sizing: border-box;
font-size: 13px;
}
#taxiBox h3 { margin: 0 0 8px 0; color: #f5d90a; }
#taxiBox button {
padding: 4px 10px;
background: #444;
border: none;
color: #eee;
cursor: pointer;
border-radius: 4px;
font-size: 12px;
}
#houseBuySection button { background: #2c7a3d; }
#jobMenuBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 380px;
max-height: 420px;
background: rgba(15,15,15,0.96);
color: white;
border: 2px solid #2c7a3d;
border-radius: 8px;
padding: 16px;
overflow-y: auto;
z-index: 20000;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#jobMenuTitle { margin: 0 0 12px 0; color: #6fbf73; }
#tuneBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 380px;
max-height: 420px;
background: rgba(15,15,15,0.96);
color: white;
border: 2px solid #2c7a3d;
border-radius: 8px;
padding: 16px;
overflow-y: auto;
z-index: 20000;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#tuneBox h3 { margin: 0 0 12px 0; color: #6fbf73; }
#phoneBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 420px;
max-height: 560px;
background: rgba(15,15,15,0.97);
color: white;
border: 2px solid #2c7a3d;
border-radius: 8px;
padding: 16px;
z-index: 20002;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#phoneBox h3 { margin: 0 0 12px 0; color: #6fbf73; }
#phoneTabs { display: flex; gap: 6px; margin-bottom: 12px; }
.phone-tab-btn {
flex: 1; background: #222; border: 1px solid #444; color: #ccc;
padding: 6px; border-radius: 4px; cursor: pointer; font-size: 12px;
}
.phone-tab-btn.active { background: #2c7a3d; border-color: #2c7a3d; color: white; }
#phoneBody { flex: 1; overflow-y: auto; min-height: 200px; max-height: 380px; }
.phone-panel { display: none; }
.phone-panel.active { display: block; }
.contact-row {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 0; border-bottom: 1px solid #2a2a2a; font-size: 13px;
}
.contact-row .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 6px; }
.contact-row .dot.online { background: #6fbf73; }
.contact-row .dot.offline { background: #555; }
.contact-row button { background: #444; border: none; color: white; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 11px; margin-left: 4px; }
.contact-row button.call { background: #2c7a3d; }
.contact-row button.danger { background: #a83232; }
#phoneAddRow, #phoneSmsRow { display: flex; gap: 6px; margin-top: 10px; }
#phoneAddRow input, #phoneSmsRow input {
flex: 1; background: #222; border: 1px solid #444; color: #eee; padding: 6px 8px; border-radius: 4px; font-size: 12px;
}
#phoneAddRow button, #phoneSmsRow button {
background: #2c7a3d; border: none; color: white; padding: 6px 10px; border-radius: 4px; cursor: pointer; font-size: 12px;
}
#smsThread { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.sms-bubble { max-width: 75%; padding: 6px 10px; border-radius: 10px; font-size: 12px; }
.sms-bubble.mine { background: #2c7a3d; align-self: flex-end; }
.sms-bubble.theirs { background: #333; align-self: flex-start; }
#phoneCloseBtn { margin-top: 14px; background: #a83232; border: none; color: white; padding: 8px; border-radius: 4px; cursor: pointer; }
#clothingBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 360px;
max-height: 520px;
background: rgba(15,15,15,0.97);
color: white;
border: 2px solid #2c7a3d;
border-radius: 8px;
padding: 18px;
z-index: 20002;
display: none;
flex-direction: column;
overflow-y: auto;
box-sizing: border-box;
}
#clothingBox h3 { margin: 0 0 4px 0; color: #6fbf73; }
.clothing-section { margin-top: 14px; }
.clothing-section h4 { margin: 0 0 6px 0; color: #f5d90a; font-size: 13px; }
.clothing-catalog-row {
display: flex; align-items: center; gap: 8px;
padding: 6px 0; border-bottom: 1px solid #2a2a2a; font-size: 13px;
}
.swatch-small { width: 20px; height: 20px; border-radius: 4px; border: 1px solid #555; flex-shrink: 0; }
.clothing-catalog-row button { background: #2c7a3d; border: none; color: white; padding: 5px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; }
#clothingCloseBtn { margin-top: 14px; background: #a83232; border: none; color: white; padding: 8px; border-radius: 4px; cursor: pointer; }
#trailerShopBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 360px;
max-height: 520px;
background: rgba(15,15,15,0.97);
color: white;
border: 2px solid #8e6a3d;
border-radius: 8px;
padding: 18px;
z-index: 20002;
display: none;
flex-direction: column;
overflow-y: auto;
box-sizing: border-box;
}
#trailerShopBox h3 { margin: 0 0 4px 0; color: #d9a45c; }
#trailerShopCloseBtn { margin-top: 14px; background: #a83232; border: none; color: white; padding: 8px; border-radius: 4px; cursor: pointer; }
#tabletBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 460px;
max-height: 580px;
background: rgba(12,16,20,0.97);
color: #d8e6e8;
border: 2px solid #2c7a8a;
border-radius: 8px;
padding: 16px;
z-index: 20002;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#tabletBox h3 { margin: 0 0 12px 0; color: #5fc9dd; }
#tabletTabs { display: flex; gap: 6px; margin-bottom: 12px; }
.tablet-tab-btn {
flex: 1; background: #182228; border: 1px solid #2c4550; color: #9db8bf;
padding: 6px; border-radius: 4px; cursor: pointer; font-size: 12px;
}
.tablet-tab-btn.active { background: #2c7a8a; border-color: #2c7a8a; color: white; }
#tabletBody { flex: 1; overflow-y: auto; min-height: 220px; max-height: 400px; }
.tablet-panel { display: none; }
.tablet-panel.active { display: block; }
#tabletSearchRow, #tabletPlateRow { display: flex; gap: 6px; margin-bottom: 12px; }
#tabletSearchRow input, #tabletPlateRow input {
flex: 1; background: #182228; border: 1px solid #2c4550; color: #d8e6e8; padding: 6px 8px; border-radius: 4px; font-size: 12px;
}
#tabletSearchRow button, #tabletPlateRow button {
background: #2c7a8a; border: none; color: white; padding: 6px 10px; border-radius: 4px; cursor: pointer; font-size: 12px;
}
.tablet-result-card { background: #182228; border: 1px solid #2c4550; border-radius: 6px; padding: 12px; font-size: 13px; line-height: 1.7; }
.tablet-result-card .wanted { color: #e06c6c; font-weight: bold; }
.tablet-result-card .clean { color: #6fbf73; }
.wanted-row {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 0; border-bottom: 1px solid #223038; font-size: 13px;
}
#tabletCloseBtn { margin-top: 14px; background: #a83232; border: none; color: white; padding: 8px; border-radius: 4px; cursor: pointer; }
#fmsStatusButtons { display: flex; flex-direction: column; gap: 6px; }
.fms-btn {
display: flex; justify-content: space-between; align-items: center;
padding: 9px 12px; border-radius: 6px; cursor: pointer;
background: #222; border: 1px solid #444; color: #ddd; font-size: 13px;
}
.fms-btn:hover { border-color: #2c7a8a; }
.fms-btn.active { background: #2c7a8a; border-color: #2c7a8a; color: white; font-weight: bold; }
.fms-btn .fms-code { font-weight: bold; margin-right: 8px; }
#leitstelleBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 520px;
max-height: 600px;
background: rgba(15,15,20,0.97);
color: #ddd;
border: 2px solid #2c7a8a;
border-radius: 8px;
padding: 16px;
z-index: 20002;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#leitstelleBox h3 { margin: 0 0 10px 0; color: #4fb8cc; }
#leitstelleUnitsList { flex: 1; overflow-y: auto; max-height: 280px; margin-bottom: 12px; }
.ls-unit-row {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 10px; margin-bottom: 5px; border-radius: 6px;
background: #1f1f2a; border: 1px solid #333; font-size: 13px;
}
.ls-unit-row .ls-status-badge {
padding: 2px 8px; border-radius: 10px; font-size: 11px; white-space: nowrap;
}
#leitstelleDispatchForm { border-top: 1px solid #333; padding-top: 12px; }
#leitstelleDispatchForm select, #leitstelleDispatchForm textarea {
width: 100%; box-sizing: border-box; background: #14151a; border: 1px solid #444;
color: #ddd; border-radius: 4px; padding: 8px; margin-bottom: 8px; font-size: 13px;
}
#leitstelleDispatchForm button { background: #2c7a8a; border: none; color: white; padding: 8px 14px; border-radius: 4px; cursor: pointer; font-size: 13px; }
#leitstelleBox .footer-row { margin-top: 10px; }
#leitstelleBox .footer-row button.secondary { background: #444; border: none; color: white; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 13px; }
#stockBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 460px;
max-height: 580px;
background: rgba(15,15,20,0.97);
color: #ddd;
border: 2px solid #4fae6a;
border-radius: 8px;
padding: 16px;
z-index: 20002;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#stockBox h3 { margin: 0 0 10px 0; color: #6fd98a; }
#stockTabs { display: flex; gap: 8px; margin-bottom: 10px; }
#stockTabs button { background: #333; border: none; color: #ccc; padding: 6px 14px; border-radius: 4px; cursor: pointer; font-size: 13px; }
#stockTabs button.active { background: #4fae6a; color: white; }
#stockListPanel, #stockPortfolioPanel { display: none; flex: 1; overflow-y: auto; }
#stockListPanel.active, #stockPortfolioPanel.active { display: block; }
.stock-row {
display: flex; justify-content: space-between; align-items: center;
padding: 10px; margin-bottom: 6px; border-radius: 6px;
background: #1f1f2a; border: 1px solid #333;
}
.stock-row .stock-info { display: flex; flex-direction: column; }
.stock-row .stock-symbol { font-weight: bold; color: #6fd98a; }
.stock-row .stock-name { font-size: 11px; color: #888; }
.stock-row .stock-price { font-size: 15px; font-weight: bold; }
.stock-row .stock-trade { display: flex; gap: 6px; align-items: center; }
.stock-row input[type="number"] {
width: 60px; background: #14151a; border: 1px solid #444; color: #ddd;
border-radius: 4px; padding: 5px;
}
.stock-row button {
background: #4fae6a; border: none; color: white; padding: 6px 10px;
border-radius: 4px; cursor: pointer; font-size: 12px;
}
.stock-row button.sell { background: #c15c5c; }
#stockBox .footer-row { margin-top: 10px; }
#stockBox .footer-row button { background: #444; border: none; color: white; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 13px; }
#gamepadSettingsBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 420px;
max-height: 560px;
background: rgba(15,15,20,0.97);
color: #ddd;
border: 2px solid #5c8ac9;
border-radius: 8px;
padding: 16px;
z-index: 20002;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#gamepadSettingsBox h3 { margin: 0 0 10px 0; color: #7fb0ec; }
#gamepadToggleRow { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; font-size: 14px; }
#gamepadActionList { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.gamepad-action-row {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 10px; background: #1f1f2a; border-radius: 6px; font-size: 13px;
}
.gamepad-action-row .gamepad-current-btn { color: #7fb0ec; font-size: 12px; }
.gamepad-action-row button {
background: #5c8ac9; border: none; color: white; padding: 5px 10px;
border-radius: 4px; cursor: pointer; font-size: 12px;
}
.gamepad-action-row button.listening { background: #c98a5c; }
#gamepadSettingsBox .footer-row { display: flex; gap: 8px; }
#gamepadSettingsBox .footer-row button {
background: #444; border: none; color: white; padding: 8px 12px;
border-radius: 4px; cursor: pointer; font-size: 13px;
}
#ticketBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 440px;
max-height: 560px;
background: rgba(15,15,20,0.97);
color: #ddd;
border: 2px solid #6a5acd;
border-radius: 8px;
padding: 16px;
z-index: 20002;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#ticketBox h3 { margin: 0 0 12px 0; color: #9d8fee; }
#ticketListPanel, #ticketDetailPanel, #ticketNewPanel { display: none; }
#ticketListPanel.active, #ticketDetailPanel.active, #ticketNewPanel.active { display: flex; flex-direction: column; }
#ticketListBody { flex: 1; overflow-y: auto; min-height: 200px; max-height: 380px; }
.ticket-row {
display: flex; flex-direction: column; gap: 2px;
padding: 10px; margin-bottom: 6px; border-radius: 6px;
background: #1f1f2a; cursor: pointer; border: 1px solid #333;
}
.ticket-row:hover { border-color: #6a5acd; }
.ticket-row .ticket-row-top { display: flex; justify-content: space-between; font-size: 13px; }
.ticket-row .ticket-row-meta { font-size: 11px; color: #888; }
.ticket-status { padding: 2px 8px; border-radius: 10px; font-size: 11px; }
.ticket-status.open { background: #2c5a3d; color: #9be6b0; }
.ticket-status.in_progress { background: #5a4a2c; color: #e6c89b; }
.ticket-status.closed { background: #444; color: #aaa; }
#ticketMessages { flex: 1; overflow-y: auto; min-height: 220px; max-height: 340px; display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.ticket-msg { padding: 8px 10px; border-radius: 8px; font-size: 13px; max-width: 85%; }
.ticket-msg.mine { background: #3a2f6b; align-self: flex-end; }
.ticket-msg.theirs { background: #262633; align-self: flex-start; }
.ticket-msg .ticket-msg-meta { font-size: 10px; color: #999; margin-bottom: 3px; }
#ticketBox input, #ticketBox textarea, #ticketBox select {
background: #1a1a24; border: 1px solid #444; color: #ddd; padding: 7px 9px; border-radius: 4px; font-size: 13px;
}
#ticketBox textarea { width: 100%; box-sizing: border-box; resize: vertical; min-height: 70px; }
#ticketBox button { background: #6a5acd; border: none; color: white; padding: 8px 12px; border-radius: 4px; cursor: pointer; font-size: 13px; }
#ticketBox button.secondary { background: #444; }
#ticketBox button.danger { background: #a83232; }
/* Anruf-Overlays */
#incomingCallBox, #outgoingCallBox, #activeCallBar {
position: absolute; left: 50%; transform: translateX(-50%);
background: rgba(20,20,20,0.97); color: white; border-radius: 8px;
padding: 14px 20px; z-index: 20003; display: none; text-align: center;
}
#incomingCallBox, #outgoingCallBox { top: 30%; border: 2px solid #f5d90a; }
#activeCallBar { top: 10px; border: 2px solid #6fbf73; display: none; }
#incomingCallBox button, #outgoingCallBox button, #activeCallBar button {
border: none; color: white; padding: 8px 16px; border-radius: 4px; cursor: pointer; margin: 8px 6px 0; font-size: 13px;
}
.call-accept { background: #2c7a3d; }
.call-decline { background: #a83232; }
.job-menu-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid #2a2a2a;
font-size: 13px;
gap: 10px;
}
.job-menu-row:last-child { border-bottom: none; }
.jmBtn {
padding: 6px 12px;
background: #2c7a3d;
border: none;
color: white;
cursor: pointer;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
}
.jmBtn.secondary { background: #555; }
.jmBtn.wide { width: 100%; margin-top: 8px; }
#jobMenuClose {
margin-top: 14px;
background: #a83232;
border: none;
color: white;
padding: 8px;
border-radius: 4px;
cursor: pointer;
}
#commandsBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 520px;
max-width: 92vw;
max-height: 80vh;
background: rgba(15,15,15,0.97);
color: white;
border: 2px solid #2c7a3d;
border-radius: 8px;
padding: 16px;
overflow-y: auto;
z-index: 20001;
display: none;
flex-direction: column;
box-sizing: border-box;
}
#commandsBox h3 { margin: 0 0 10px 0; color: #6fbf73; }
#cmdFreeRow {
display: flex;
gap: 6px;
margin-bottom: 14px;
padding-bottom: 14px;
border-bottom: 1px solid #333;
}
#cmdFreeInput {
flex: 1;
background: #222;
border: 1px solid #444;
color: #eee;
padding: 8px 10px;
border-radius: 4px;
}
#cmdFreeRow button {
background: #2c7a3d;
border: none;
color: white;
padding: 8px 14px;
border-radius: 4px;
cursor: pointer;
}
.cmd-cat { color: #f5d90a; font-size: 13px; margin: 12px 0 6px 0; }
.cmd-row {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 0;
font-size: 13px;
}
.cmd-row .cmd-label { flex: 1; color: #ccc; }
.cmd-row input {
width: 110px;
background: #222;
border: 1px solid #444;
color: #eee;
padding: 5px 7px;
border-radius: 4px;
font-size: 12px;
}
.cmd-row button {
background: #444;
border: none;
color: white;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
white-space: nowrap;
}
.cmd-row button:hover { background: #2c7a3d; }
#commandsCloseBtn {
margin-top: 14px;
background: #a83232;
border: none;
color: white;
padding: 8px;
border-radius: 4px;
cursor: pointer;
}
#worldMapBox {
position: absolute;
left: 0; top: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.85);
z-index: 20500;
display: none;
align-items: center;
justify-content: center;
gap: 20px;
}
#worldMapCanvas {
border: 2px solid #555;
border-radius: 4px;
cursor: crosshair;
image-rendering: pixelated;
max-height: 85vh;
}
#worldMapLegend {
background: rgba(20,20,20,0.9);
border: 1px solid #444;
border-radius: 6px;
padding: 12px;
color: #eee;
font-size: 13px;
max-width: 220px;
max-height: 85vh;
overflow-y: auto;
line-height: 1.8;
}
#worldMapClose {
position: absolute;
top: 20px;
right: 20px;
background: #a83232;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
#naviDisplay {
position: absolute;
left: 50%;
top: 100px;
transform: translateX(-50%);
display: none;
flex-direction: column;
align-items: center;
z-index: 9998;
pointer-events: none;
}
#naviArrow {
font-size: 32px;
filter: drop-shadow(0 0 3px black);
}
#naviLabel {
background: rgba(0,0,0,0.7);
color: #f5d90a;
padding: 3px 10px;
border-radius: 4px;
font-size: 12px;
margin-top: 2px;
}
/* Chat: unter dem Canvas, linksbündig, so breit wie das Spielfeld
(also bis zur rechten Seitenleiste) */
#chatBox {
position: absolute;
left: 0;
bottom: 0;
width: calc(100% - 260px); /* muss zu SIDEBAR_WIDTH in game.js passen */
height: 180px; /* muss zu CHAT_HEIGHT in game.js passen */
background: rgba(12,13,17,0.9);
border-top: 1px solid var(--border-soft);
display: none;
flex-direction: column;
box-sizing: border-box;
z-index: 9999;
}
#chatMessages {
flex: 1;
overflow-y: auto;
padding: 8px 12px;
font-size: 13px;
line-height: 1.5;
}
#chatMessages .chat-line { margin-bottom: 2px; word-break: break-word; }
#chatMessages .system { color: #e8b563; font-style: italic; }
#chatMessages .radio { color: #5bc99f; font-weight: bold; }
#chatMessages .player .name { color: var(--accent); font-weight: bold; }
#chatInputRow {
display: flex;
gap: 8px;
padding: 8px;
border-top: 1px solid var(--border-soft);
}
#chatInputRow input {
flex: 1;
background: #14151a;
border: 1px solid var(--border-soft);
color: var(--text-main);
padding: 8px 10px;
border-radius: 6px;
box-sizing: border-box;
font-family: var(--font-main);
}
#chatInputRow button {
background: var(--accent);
border: none;
color: white;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-family: var(--font-main);
}
/* Debug-Overlay, per Chat-Befehl /debug ein-/ausschaltbar */
#debugBox {
position: absolute;
left: 10px;
top: 210px;
background: rgba(0,0,0,0.75);
color: #6fff6f;
padding: 10px 14px;
border-radius: 6px;
font-family: "Courier New", monospace;
font-size: 13px;
line-height: 1.6;
z-index: 9999;
display: none;
pointer-events: none;
border: 1px solid #2c7a3d;
}
#debugBox .label { color: #8fdc8f; }
/* Auto-HUD: Tacho + Tank, nur sichtbar während der Fahrt */
#carHud {
position: absolute;
left: 10px;
bottom: 200px;
background: rgba(0,0,0,0.75);
color: white;
padding: 10px 14px;
border-radius: 6px;
font-family: Arial, sans-serif;
font-size: 14px;
z-index: 9999;
display: none;
min-width: 160px;
}
#carHud .speed { font-size: 22px; font-weight: bold; margin-bottom: 6px; }
#carHud .speed span { font-size: 13px; font-weight: normal; color: #aaa; }
#carHud .fuel-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
#carHud .fuel-bar-outer {
display: inline-block;
width: 100px;
height: 10px;
background: #333;
border-radius: 4px;
overflow: hidden;
border: 1px solid #555;
}
#carHud .fuel-bar-inner {
display: block;
height: 100%;
background: #4caf50;
width: 100%;
}
#carHud .hint { color: #777; font-size: 11px; margin-top: 6px; }
#carHud .odo-row { color: #999; font-size: 11px; margin-top: 4px; }
#deathScreen {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(80, 0, 0, 0.75);
z-index: 20000;
display: none;
align-items: center;
justify-content: center;
flex-direction: column;
color: white;
text-align: center;
}
#deathScreen h1 { font-size: 48px; margin: 0 0 10px 0; }
#deathScreen p { font-size: 18px; color: #ffbdbd; }
#jailBox {
position: absolute;
left: 50%;
top: 70px;
transform: translateX(-50%);
background: rgba(20,20,20,0.9);
color: white;
border: 2px solid #555;
border-radius: 8px;
padding: 10px 20px;
z-index: 9999;
display: none;
align-items: center;
gap: 10px;
font-size: 15px;
}
#jailCountdown { font-weight: bold; color: #ffcc00; }
.level-up-flash {
animation: levelUpPulse 1.5s ease-out;
}
@keyframes levelUpPulse {
0% { text-shadow: 0 0 2px #f5d90a; transform: scale(1); }
30% { text-shadow: 0 0 16px #f5d90a, 0 0 24px #f5d90a; transform: scale(1.3); }
100% { text-shadow: 0 0 2px #f5d90a; transform: scale(1); }
}
#carHud .health-row { display: flex; align-items: center; gap: 8px; font-size: 12px; margin-top: 4px; }
/* Mini-Map / Radar */
#minimapWrap {
position: absolute;
top: 60px;
left: 10px;
width: 140px;
height: 140px;
z-index: 9999;
border-radius: 50%;
overflow: hidden;
border: 2px solid #444;
background: #0a0a0a;
}
#minimapCanvas { display: block; }
/* ===============================================================
MOBILE-ANPASSUNG: greift auf alle Fenster zu, die dem Namens-
schema "...Box"/"...Window" folgen (praktisch alle UI-Fenster
im Spiel) - statt jedes der ~28 Fenster einzeln umzubauen,
werden hier zentral Breite/Höhe/Schriftgröße für schmale
Bildschirme begrenzt, damit nichts mehr über den Rand hinausragt
oder unbedienbar wird.
=============================================================== */
@media (max-width: 820px) {
[id$="Box"], [id$="Window"] {
max-width: 94vw !important;
max-height: 82vh !important;
overflow-y: auto !important;
font-size: 14px;
box-sizing: border-box !important;
}
/* Fenster, die bisher rechts an der Seitenleiste "andockten",
werden auf dem Handy stattdessen horizontal zentriert -
eine Sidebar ergibt auf einem 380px-Bildschirm keinen Sinn */
#statusWindow, #inventoryWindow, #shopWindow {
left: 50% !important;
right: auto !important;
transform: translateX(-50%);
}
#topMenu {
height: 44px;
font-size: 15px;
padding-left: 12px;
}
/* Chat nimmt auf dem Handy die volle Breite ein und bleibt
kompakter, damit mehr vom Spielfeld sichtbar bleibt */
#chatBox {
width: 100% !important;
height: 130px !important;
}
/* Joystick + Action-Buttons müssen über den Chat angehoben werden,
sonst liegt der Chat (130px hoch, volle Breite) genau darüber
und die Steuerung wäre unbedienbar/verdeckt */
#touchJoystickBase { bottom: 150px !important; }
#touchActionButtons { bottom: 150px !important; }
#chatMessages { font-size: 12px; }
/* Job-Menü- und Befehls-Zeilen: auf dem Handy dürfen sie
umbrechen, statt starr in einer Zeile über den Rand zu laufen
(Label + Button nebeneinander wird bei langen Texten sonst eng) */
.job-menu-row, .cmd-row {
flex-wrap: wrap;
}
/* Größere Tippflächen - wichtig für Finger statt Mauszeiger */
[id$="Box"] button, [id$="Window"] button,
[id$="Box"] input, [id$="Window"] input,
[id$="Box"] select, [id$="Window"] select {
min-height: 40px;
font-size: 16px; /* verhindert, dass iOS beim Fokussieren automatisch reinzoomt */
}
/* Auf sehr schmalen Geräten (Hochformat-Handy) noch etwas enger */
@media (max-width: 480px) {
[id$="Box"], [id$="Window"] {
max-width: 97vw !important;
font-size: 13px;
}
#topMenu { font-size: 13px; padding-left: 8px; }
}
}
</style>
</head>
<body>
<div id="deathScreen">
<h1>💀 Du bist gestorben</h1>
<p id="deathScreenText">Du bist gestorben.</p>
<p style="color:#ccc; font-size:14px;">Du wirst gleich im Krankenhaus wiederbelebt...</p>
</div>
<div id="jailBox">
🔒 Im Gefängnis - noch <span id="jailCountdown">0s</span>
</div>
<div id="worldMapBox">
<button id="worldMapClose" onclick="closeWorldMap()">Schließen (ESC)</button>
<canvas id="worldMapCanvas"></canvas>
<div id="worldMapLegend"></div>
</div>
<div id="naviDisplay">
<div id="naviArrow"></div>
<div id="naviLabel"></div>
</div>
<!-- LOGIN -->
<div id="loginBox" style="display:block;">
<h2>Login</h2>
<input type="text" id="loginUser" placeholder="Benutzername">
<input type="password" id="loginPass" placeholder="Passwort">
<button id="loginBtn">Login</button>
<div id="switchToRegister">Noch keinen Account? Registrieren</div>
</div>
<!-- REGISTER -->
<div id="registerBox">
<h2>Registrieren</h2>
<input type="text" id="regUser" placeholder="Benutzername">
<input type="password" id="regPass" placeholder="Passwort">
<button id="regBtn">Registrieren</button>
<div id="switchToLogin">Schon einen Account? Login</div>
</div>
<!-- SPIEL -->
<div id="eventBanner" style="display:none; position:absolute; top:0; left:0; right:0; background:linear-gradient(90deg,#8e44ad,#e67e22); color:white; text-align:center; padding:6px; font-size:13px; font-weight:bold; z-index:15000; box-shadow:0 2px 6px rgba(0,0,0,0.4);"></div>
<div id="topMenu" style="display:none;">
<span style="margin-right:20px;">Menü</span>
<a href="/index.html" style="color:#eee; text-decoration:none; margin-right:16px;">🏠 Startseite</a>
<a href="/profile.html" style="color:#eee; text-decoration:none;">👤 Profil</a>
<span id="clockDisplay" style="margin-right:16px; color:#ccc; font-size:14px;">🌞 12:00</span>
<span id="levelDisplay" style="margin-right:16px; color:#f5d90a; font-size:13px;">⭐ Lvl 1 (0/500 XP)</span>
<span id="dutyDisplay" style="margin-right:16px; color:#f5d90a; font-size:13px;"></span>
<span id="voiceDisplay" style="margin-right:16px; color:#888; font-size:13px; cursor:pointer;" onclick="toggleMic()" title="Klicken zum Stummschalten/Aktivieren">🎤 Verbinde...</span>
<span id="pvpDisplay" style="margin-right:16px; color:#6fbf73; font-size:13px;">🛡️ PvP aus</span>
<span id="wantedDisplay" style="margin-right:16px; color:#ffcc00; font-size:16px; letter-spacing:2px;"></span>
<span id="onlineCount" style="margin-left:auto; margin-right:16px; color:#6fbf73; font-size:14px;">👥 0 online</span>
<span id="versionDisplay" style="margin-right:20px; color:#666; font-size:12px;"></span>
</div>
<div id="statusWindow" style="display:none;">
Leben: 100<br>
Hunger: 100<br>
Durst: 100
</div>
<div id="atmBox">
<h3 style="margin-top:0;">Bankautomat</h3>
<div>Bargeld: <span id="atmMoney"></span>$</div>
<div>Bank: <span id="atmBank"></span>$</div>
<input id="atmAmount" type="number" placeholder="Betrag">
<button onclick="atmDeposit()">Einzahlen</button>
<button onclick="atmWithdraw()">Auszahlen</button>
<h4>Geld senden</h4>
<input id="atmTarget" type="number" placeholder="Spieler ID">
<button onclick="atmTransfer()">Überweisen</button>
<h4>PIN ändern</h4>
<input id="atmOldPin" type="password" maxlength="4" placeholder="Aktuelle PIN (leer beim ersten Mal)">
<input id="atmNewPin" type="password" maxlength="4" placeholder="Neue PIN (4 Ziffern)">
<button onclick="atmChangePin()">PIN ändern</button>
<div id="atmPinMsg" style="font-size:12px; margin-top:4px; min-height:16px;"></div>
<button onclick="closeATM()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="garageBox">
<h3 style="margin-top:0;">Garage</h3>
<div id="garageList"></div>
<button onclick="closeGarage()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="jobBox">
<h3 style="margin-top:0;">Jobcenter</h3>
<div id="jobList"></div>
<button onclick="closeJobcenter()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="trunkBox">
<h3 style="margin-top:0;">Kofferraum</h3>
<h4>Dein Inventar</h4>
<div id="trunkInventoryList"></div>
<h4>Im Kofferraum</h4>
<div id="trunkContentList"></div>
<button onclick="closeTrunk()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="houseBox">
<h3 id="houseName" style="margin-top:0;">Haus</h3>
<div id="houseBuySection" class="hidden">
<p>Preis: <span id="housePrice"></span></p>
<button onclick="buyCurrentHouse()">Kaufen</button>
</div>
<div id="houseLockedSection" class="hidden">
<p style="color:#e06c6c;">🔒 Dieses Haus ist verschlossen. Du hast keinen Schlüssel.</p>
</div>
<div id="houseForRentSection" class="hidden">
<p>🏠 Dieses Haus wird zur Miete angeboten.</p>
<p>Miete: <span id="houseRentPrice"></span> pro Intervall</p>
<button onclick="rentCurrentHouse()">Mieten</button>
</div>
<div id="houseStorageSection" class="hidden">
<h4>Dein Inventar</h4>
<div id="houseInventoryList"></div>
<h4>Im Haus</h4>
<div id="houseStorageList"></div>
<p style="color:#888; font-size:11px; margin-top:8px;">
Als Besitzer: <code>/housekey Name</code> gibt einen Schlüssel,
<code>/housekey remove Name</code> entzieht ihn.
</p>
</div>
<button onclick="closeHouse()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="wardrobeBox" style="display:none; position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); width:340px; max-height:480px; overflow-y:auto; background:rgba(15,15,15,0.97); color:white; border:2px solid #2c7a3d; border-radius:8px; padding:16px; z-index:20002;">
<h3 style="margin-top:0; color:#6fbf73;">👕 Kleiderschrank</h3>
<h4>Dein Inventar</h4>
<div id="wardrobeInventoryList"></div>
<h4>Im Schrank</h4>
<div id="wardrobeStorageList"></div>
<button onclick="closeWardrobeWindow()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="adminBox">
<h3>🛡️ Admin-Menü</h3>
<div id="adminPlayerList"></div>
<div id="adminBoxFooter">
<button onclick="refreshAdminMenu()">Aktualisieren</button>
<button onclick="toggleAdminDuty()" style="background:#2c6a7a;">🛡️ Dienstmodus an/aus</button>
<button onclick="triggerServerRestart()" style="background:#c77a1f;">🔄 Server neu starten</button>
<button onclick="cancelServerRestart()" style="background:#555;">Neustart abbrechen</button>
<button onclick="closeAdminMenu()" style="background:#a83232;">Schließen</button>
</div>
</div>
<div id="phoneBox">
<h3>📱 Handy</h3>
<div id="phoneTabs">
<button class="phone-tab-btn active" data-phone-tab="contacts">Kontakte</button>
<button class="phone-tab-btn" data-phone-tab="sms">SMS</button>
</div>
<div id="phoneBody">
<div class="phone-panel active" id="phonePanel-contacts">
<div id="pendingRequestsList"></div>
<div id="contactsList"></div>
<div id="phoneAddRow">
<input type="text" id="phoneAddInput" placeholder="Benutzername...">
<button onclick="phoneAddContact()">Hinzufügen</button>
</div>
</div>
<div class="phone-panel" id="phonePanel-sms">
<select id="smsContactSelect" style="width:100%; background:#222; border:1px solid #444; color:#eee; padding:6px; border-radius:4px; margin-bottom:10px;"></select>
<div id="smsThread"></div>
<div id="phoneSmsRow">
<input type="text" id="phoneSmsInput" placeholder="Nachricht...">
<button onclick="phoneSendSms()">Senden</button>
</div>
</div>
</div>
<button id="phoneCloseBtn" onclick="closePhone()">Schließen (ESC)</button>
</div>
<div id="incomingCallBox">
<div id="incomingCallText" style="font-size:15px; margin-bottom:4px;">📞 Anruf...</div>
<button class="call-accept" onclick="acceptIncomingCall()">Annehmen</button>
<button class="call-decline" onclick="declineIncomingCall()">Ablehnen</button>
</div>
<div id="outgoingCallBox">
<div id="outgoingCallText" style="font-size:15px;">📞 Rufe an...</div>
</div>
<div id="activeCallBar">
<span id="activeCallText">📞 Im Gespräch</span>
<button class="call-decline" onclick="endCall()">Auflegen</button>
</div>
<div id="clothingBox">
<h3>👕 Kleidungsladen</h3>
<p style="color:#888; font-size:12px; margin-top:-8px;">Gekaufte Teile landen im Inventar - dort zum Anziehen benutzen.</p>
<div class="clothing-section">
<h4>Aktuell getragen</h4>
<div class="clothing-catalog-row">
<span style="flex:1;">Oberteil</span>
<button onclick="unwearClothing('shirt')">Ausziehen</button>
</div>
<div class="clothing-catalog-row">
<span style="flex:1;">Hose</span>
<button onclick="unwearClothing('pants')">Ausziehen</button>
</div>
<div class="clothing-catalog-row">
<span style="flex:1;">Schuhe</span>
<button onclick="unwearClothing('shoes')">Ausziehen</button>
</div>
<div class="clothing-catalog-row">
<span style="flex:1;">Helm</span>
<button onclick="unwearClothing('helmet')">Ausziehen</button>
</div>
</div>
<div class="clothing-section">
<h4>Oberteile</h4>
<div id="clothingCatalog_shirt"></div>
</div>
<div class="clothing-section">
<h4>Hosen</h4>
<div id="clothingCatalog_pants"></div>
</div>
<div class="clothing-section">
<h4>Schuhe</h4>
<div id="clothingCatalog_shoes"></div>
</div>
<div class="clothing-section">
<h4>Helme</h4>
<div id="clothingCatalog_helmet"></div>
</div>
<button id="clothingCloseBtn" onclick="closeClothingShop()">Schließen (ESC)</button>
</div>
<div id="trailerShopBox">
<h3>🚛 Anhänger-Shop</h3>
<p style="color:#888; font-size:12px; margin-top:-8px;">Der gekaufte Anhänger steht direkt neben dir.</p>
<div id="trailerShopCatalog"></div>
<button id="trailerShopCloseBtn" onclick="closeTrailerShop()">Schließen (ESC)</button>
</div>
<div id="tabletBox">
<h3>🖥️ Einsatz-Tablet</h3>
<div id="tabletTabs">
<button class="tablet-tab-btn active" data-tablet-tab="search">Personensuche</button>
<button class="tablet-tab-btn" data-tablet-tab="wanted">Fahndungsliste</button>
<button class="tablet-tab-btn" data-tablet-tab="plate">Kennzeichen</button>
<button class="tablet-tab-btn" data-tablet-tab="fms">FMS-Status</button>
</div>
<div id="tabletBody">
<div class="tablet-panel active" id="tabletPanel-search">
<div id="tabletSearchRow">
<input type="text" id="tabletSearchInput" placeholder="Benutzername...">
<button onclick="tabletSearchPerson()">Suchen</button>
</div>
<div id="tabletSearchResult"></div>
</div>
<div class="tablet-panel" id="tabletPanel-wanted">
<button onclick="tabletLoadWantedList()" style="margin-bottom:10px; background:#2c7a8a; border:none; color:white; padding:6px 10px; border-radius:4px; cursor:pointer; font-size:12px;">Aktualisieren</button>
<div id="tabletWantedList"></div>
</div>
<div class="tablet-panel" id="tabletPanel-plate">
<div id="tabletPlateRow">
<input type="text" id="tabletPlateInput" placeholder="Kennzeichen...">
<button onclick="tabletLookupPlate()">Abfragen</button>
</div>
<div id="tabletPlateResult"></div>
</div>
<div class="tablet-panel" id="tabletPanel-fms">
<p style="color:#888; font-size:12px; margin-top:0;">Aktueller Status wird über den Job-Funk an alle Kollegen deiner Berufsgruppe gemeldet.</p>
<div id="fmsStatusButtons"></div>
</div>
</div>
<button id="tabletCloseBtn" onclick="closeTablet()">Schließen (ESC)</button>
</div>
<div id="leitstelleBox">
<h3>📻 Leitstelle</h3>
<div id="leitstelleUnitsList"></div>
<div id="leitstelleDispatchForm">
<select id="leitstelleTargetJob">
<option value="police">🚓 Polizei</option>
<option value="medic">⛑️ Rettungsdienst</option>
<option value="fire">🚒 Feuerwehr</option>
</select>
<textarea id="leitstelleDispatchText" placeholder="Einsatzmeldung eingeben..." rows="2"></textarea>
<button onclick="sendLeitstelleDispatch()">Einsatz verteilen</button>
</div>
<div class="footer-row">
<button class="secondary" onclick="closeLeitstelle()">Schließen (ESC)</button>
</div>
</div>
<div id="stockBox">
<h3>📈 Börse</h3>
<div id="stockTabs">
<button class="active" onclick="showStockTab('list')">Markt</button>
<button onclick="showStockTab('portfolio')">Mein Portfolio</button>
</div>
<div id="stockListPanel" class="active"></div>
<div id="stockPortfolioPanel"></div>
<div class="footer-row">
<button onclick="closeStockBox()">Schließen (ESC)</button>
</div>
</div>
<div id="gamepadSettingsBox">
<h3>🎮 Controller-Einstellungen</h3>
<div id="gamepadToggleRow">
<input type="checkbox" id="gamepadEnabledCheckbox" onchange="toggleGamepadEnabled()">
<label for="gamepadEnabledCheckbox">Controller aktiviert</label>
</div>
<div id="gamepadActionList"></div>
<div class="footer-row">
<button onclick="resetGamepadMapping()">Auf Standard zurücksetzen</button>
<button onclick="closeGamepadSettings()">Schließen (ESC)</button>
</div>
</div>
<div id="ticketBox">
<h3>🎫 Support-Tickets</h3>
<div id="ticketListPanel" class="active">
<button onclick="openNewTicketPanel()" style="margin-bottom:10px; align-self:flex-start;">+ Neues Ticket</button>
<div id="ticketListBody"></div>
<button class="secondary" onclick="closeTicketBox()" style="margin-top:10px;">Schließen (ESC)</button>
</div>
<div id="ticketNewPanel">
<label style="font-size:12px; color:#999; margin-bottom:4px;">Kategorie</label>
<select id="ticketNewCategory" style="margin-bottom:8px;">
<option value="bug">Fehler/Bug</option>
<option value="spieler">Spieler-Problem</option>
<option value="frage">Frage</option>
<option value="sonstiges">Sonstiges</option>
</select>
<label style="font-size:12px; color:#999; margin-bottom:4px;">Betreff</label>
<input type="text" id="ticketNewSubject" placeholder="Kurzer Betreff..." style="margin-bottom:8px;">
<label style="font-size:12px; color:#999; margin-bottom:4px;">Nachricht</label>
<textarea id="ticketNewMessage" placeholder="Beschreib dein Anliegen..."></textarea>
<div style="display:flex; gap:8px; margin-top:10px;">
<button onclick="submitNewTicket()">Absenden</button>
<button class="secondary" onclick="backToTicketList()">Zurück</button>
</div>
<div class="msg" id="ticketNewMsg" style="font-size:12px; margin-top:6px; min-height:16px;"></div>
</div>
<div id="ticketDetailPanel">
<div id="ticketDetailHeader" style="margin-bottom:8px; font-size:13px; color:#bbb;"></div>
<div id="ticketMessages"></div>
<div id="ticketReplyRow" style="display:flex; gap:8px;">
<textarea id="ticketReplyText" placeholder="Antworten..." style="min-height:44px;"></textarea>
<button onclick="submitTicketReply()" style="align-self:flex-end;">Senden</button>
</div>
<div style="display:flex; gap:8px; margin-top:10px;">
<button class="secondary" onclick="backToTicketList()">Zurück zur Liste</button>
</div>
</div>
</div>
<div id="commandsBox">
<h3>⌨️ Alle Befehle</h3>
<div id="cmdFreeRow">
<input id="cmdFreeInput" type="text" placeholder="Beliebigen Befehl eingeben, z.B. /gatekey Timo">
<button onclick="runFreeCommand()">Ausführen</button>
</div>
<div id="cmdList"></div>
<button id="commandsCloseBtn" onclick="closeCommandsWindow()">Schließen (ESC)</button>
</div>
<div id="taxiBox">
<h3>🚕 Wartende Fahrgäste</h3>
<div id="taxiRequestList"></div>
<button onclick="closeTaxiWindow()" style="margin-top:10px; background:#a83232;">Schließen</button>
</div>
<div id="jobMenuBox">
<h3 id="jobMenuTitle">📋 Job-Menü</h3>
<div id="jobMenuBody"></div>
<button id="jobMenuClose" onclick="closeJobMenu()">Schließen (ESC)</button>
</div>
<div id="tuneBox">
<h3>🔧 Tuning</h3>
<div id="tuneBody"></div>
<button id="tuneCloseBtn" onclick="closeTuneWindow()">Schließen (ESC)</button>
</div>
<div id="inventoryWindow" style="display:none;">
<h3 style="margin-top:0;">Inventar</h3>
<div id="inventoryList"></div>
</div>
<div id="shopWindow" style="display:none;">
<h3 style="margin-top:0;">Shop</h3>
<div id="shopList"></div>
</div>
<div id="minimapWrap">
<canvas id="minimapCanvas" width="140" height="140"></canvas>
</div>
<div id="carHud">
<div class="speed"><span id="hudSpeed">0</span> <span>km/h</span></div>
<div class="fuel-row">
<span class="fuel-bar-outer"><span id="hudFuelBarInner" class="fuel-bar-inner"></span></span>
<span id="hudFuelText">-- / --L</span>
</div>
<div class="health-row">
🔧
<span class="fuel-bar-outer"><span id="hudHealthBarInner" class="fuel-bar-inner"></span></span>
<span id="hudHealthText">100%</span>
</div>
<div class="odo-row">🛣️ Kilometerstand: <span id="hudOdometer">0.0 km</span></div>
<div class="odo-row" id="hudInsurance">⚠️ Unversichert</div>
<div class="odo-row" id="hudRadioLabel">📻 Aus</div>
<div class="hint">1/2 Blinker · 3 Licht · 4 Warnblinker · 5 Blaulicht · Q Tanken/Reparieren/Tor · T Kofferraum · R Radio</div>
</div>
<audio id="radioAudio" style="display:none;"></audio>
<div id="debugBox">
<div><span class="label">Welt:</span> <span id="dbgWorld"></span></div>
<div><span class="label">Position (px):</span> <span id="dbgPos"></span></div>
<div><span class="label">Tile:</span> <span id="dbgTile"></span></div>
<div><span class="label">Kamera:</span> <span id="dbgCam"></span></div>
<div><span class="label">Modus:</span> <span id="dbgFacing"></span></div>
</div>
<div id="chatBox">
<div id="chatMessages"></div>
<div id="chatInputRow">
<input id="chatInput" placeholder="Nachricht eingeben..." maxlength="300">
<button id="chatSendBtn">Senden</button>
</div>
</div>
<canvas id="gameCanvas"></canvas>
<div id="touchControls">
<div id="touchJoystickBase">
<div id="touchJoystickKnob"></div>
</div>
<div id="touchActionButtons">
<button class="touch-btn" id="touchBtnInteract" title="Interagieren (E)">E</button>
<button class="touch-btn small" id="touchBtnJob" title="Job-Menü (J)">💼</button>
<button class="touch-btn small" id="touchBtnPhone" title="Handy (P)">📱</button>
<button class="touch-btn small" id="touchBtnMenu" title="Alle Befehle"></button>
</div>
</div>
<div id="loadingScreen">
<div id="loadingSpinner"></div>
<h2>🎮 Wird geladen...</h2>
<div id="loadingBarOuter"><div id="loadingBarInner"></div></div>
<div id="loadingStatusText">Verbindung wird hergestellt...</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/livekit-client@2/dist/livekit-client.umd.min.js"></script>
<script src="game.js?v=89"></script>
</body>
</html>