1786 lines
68 KiB
HTML
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> |