232 lines
11 KiB
HTML
232 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>Spotify Roulette – Lobby</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root{
|
||
--bg:#121212; --card:#181818; --border:#282828; --text:#fff; --muted:#b3b3b3;
|
||
--accent: #1db954; --accent-press:#169e47; --glow:rgba(29,185,84,.25);
|
||
--radius:16px; --shadow:0 10px 30px rgba(0,0,0,.35)
|
||
}
|
||
*{box-sizing:border-box}
|
||
html,body{height:100%}
|
||
body{
|
||
margin:0; font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
|
||
color:var(--text);
|
||
background: radial-gradient(1000px 500px at 20% -10%, rgba(29,185,84,.14), transparent 60%),
|
||
radial-gradient(900px 450px at 110% -20%, rgba(29,185,84,.12), transparent 70%),
|
||
var(--bg);
|
||
padding:24px;
|
||
}
|
||
.container{max-width:1100px; margin:0 auto}
|
||
header{display:flex; align-items:center; gap:12px; padding-bottom:12px; border-bottom:1px solid var(--border)}
|
||
.logo{width:40px; height:40px; border-radius:50%; background:var(--accent); color:#121212;
|
||
display:grid; place-content:center; box-shadow:0 0 0 6px var(--glow)}
|
||
h1{margin:0; font-size:24px}
|
||
.pill{margin-left:auto; display:inline-flex; gap:8px; align-items:center; padding:6px 10px; border-radius:999px;
|
||
border:1px solid var(--border); background:#101010; color:var(--muted); font-size:12px}
|
||
|
||
.grid{display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-top:20px}
|
||
@media (max-width:900px){ .grid{grid-template-columns:1fr} }
|
||
|
||
.card{background:var(--card); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow)}
|
||
.card .hd{padding:18px 18px 8px}
|
||
.card .bd{padding:0 18px 18px}
|
||
.muted{color:var(--muted)}
|
||
|
||
.btn{width:100%; border:0; border-radius:14px; padding:14px 16px; cursor:pointer; font-weight:700; display:flex; align-items:center; justify-content:center; gap:10px; transition:transform .06s ease, filter .15s ease, background .2s ease}
|
||
.btn:active{transform:translateY(1px)}
|
||
.btn-primary{background:var(--accent); color:#0a0a0a}
|
||
.btn-primary:hover{filter:brightness(1.05)}
|
||
.btn-primary:active{background:var(--accent-press)}
|
||
.btn-ghost{background:transparent; color:var(--text); border:1px solid var(--border)}
|
||
.btn-ghost:hover{border-color:var(--muted)}
|
||
|
||
.tile{display:flex; gap:14px; align-items:center; padding:14px; border:1px solid var(--border); border-radius:14px; background:#101010}
|
||
.tile .icon{width:44px; height:44px; border-radius:10px; display:grid; place-content:center; background:#0e0e0e; border:1px solid var(--border)}
|
||
.tile .txt{display:flex; flex-direction:column}
|
||
.tile .txt b{font-size:16px}
|
||
.tile .txt span{font-size:13px; color:var(--muted)}
|
||
|
||
/* Join form – Spotify-like Input */
|
||
.row{display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap}
|
||
.field{display:flex; flex-direction:column; gap:6px}
|
||
label{color:var(--muted); font-size:13px}
|
||
|
||
.inputWrap{position:relative; min-width:220px}
|
||
.inputWrap .leading-icon{
|
||
position:absolute; left:12px; top:50%; transform:translateY(-50%); opacity:.9;
|
||
}
|
||
.inputWrap .chip{
|
||
position:absolute; right:10px; top:50%; transform:translateY(-50%);
|
||
font-size:11px; color:var(--muted);
|
||
border:1px solid var(--border); background:#0d0d0d;
|
||
padding:4px 8px; border-radius:999px;
|
||
}
|
||
input#gameId{
|
||
width:100%;
|
||
background:#0b0b0b; color:var(--text);
|
||
border:1px solid var(--border);
|
||
border-radius:999px;
|
||
padding:14px 78px 14px 42px; /* Platz für Icon + Chip */
|
||
outline:none;
|
||
letter-spacing:.12em; font-weight:600;
|
||
box-shadow: inset 0 1px 0 rgba(255,255,255,.02);
|
||
transition:border-color .2s, box-shadow .2s, background .2s, transform .06s;
|
||
}
|
||
input#gameId::placeholder{color:#777}
|
||
input#gameId:focus{
|
||
border-color:var(--accent);
|
||
box-shadow:0 0 0 4px var(--glow), inset 0 1px 0 rgba(255,255,255,.02);
|
||
background:#0e0e0e;
|
||
}
|
||
input#gameId:active{transform:translateY(1px)}
|
||
|
||
/* Icon-only clipboard button */
|
||
.icon-btn{width:auto; padding:10px; border-radius:999px; display:inline-flex; align-items:center; justify-content:center}
|
||
.icon-btn svg{display:block}
|
||
.icon-btn--accent{
|
||
background:var(--accent); color:#0a0a0a;
|
||
box-shadow:0 0 0 0 var(--glow);
|
||
transition: box-shadow .2s, filter .15s, transform .06s, background .2s;
|
||
}
|
||
.icon-btn--accent:hover{ filter:brightness(1.05); box-shadow:0 0 0 6px var(--glow) }
|
||
.icon-btn--accent:active{ background:var(--accent-press); transform:translateY(1px) }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<header>
|
||
<div class="logo" aria-hidden="true">
|
||
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2 2 7l10 5 10-5-10-5Zm10 7-10 5v9l10-5V9ZM2 9v9l10 5v-9L2 9Z"/></svg>
|
||
</div>
|
||
<h1>Lobby</h1>
|
||
<span class="pill">Angemeldet als <b id="uname" style="color:#fff">—</b></span>
|
||
</header>
|
||
|
||
<section class="grid" aria-label="Aktionen">
|
||
<div class="card">
|
||
<div class="hd"><h2 style="margin:0">Neues Spiel</h2></div>
|
||
<div class="bd">
|
||
<div class="tile" style="margin-bottom:12px">
|
||
<div class="icon" aria-hidden="true">
|
||
<svg width="22" height="22" viewBox="0 0 24 24" fill="#1db954"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2Z"/></svg>
|
||
</div>
|
||
<div class="txt"><b>Spiel erstellen</b><span>Starte eine neue Runde und teile den Code.</span></div>
|
||
</div>
|
||
<button id="createGame" class="btn btn-primary">Spiel erstellen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="hd"><h2 style="margin:0">Spiel beitreten</h2></div>
|
||
<div class="bd">
|
||
<div class="tile" style="margin-bottom:12px">
|
||
<div class="icon" aria-hidden="true">
|
||
<svg width="22" height="22" viewBox="0 0 24 24" fill="#1db954"><path d="M12 2a6 6 0 0 1 6 6v2h2v12H4V10h2V8a6 6 0 0 1 6-6Zm0 2a4 4 0 0 0-4 4v2h8V8a4 4 0 0 0-4-4Z"/></svg>
|
||
</div>
|
||
<div class="txt"><b>Bestehendem Spiel beitreten</b><span>Du hast schon einen Code? Gib ihn unten ein.</span></div>
|
||
</div>
|
||
|
||
<!-- Direktes Join-Formular in der Lobby -->
|
||
<form id="joinForm" class="row">
|
||
<div class="field">
|
||
<label for="gameId">Spiel-Code</label>
|
||
<div class="inputWrap">
|
||
<span class="leading-icon" aria-hidden="true">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="#1db954">
|
||
<path d="M3 11h18v10H3V11Zm9-8a5 5 0 0 1 5 5v3h-2V8a3 3 0 1 0-6 0v3H7V8a5 5 0 0 1 5-5Z"/>
|
||
</svg>
|
||
</span>
|
||
<input id="gameId" name="gameId"
|
||
placeholder="••••"
|
||
inputmode="numeric"
|
||
pattern="\d{4}"
|
||
maxlength="4"
|
||
autocomplete="one-time-code"
|
||
required />
|
||
<span class="chip">4-stellig</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Icon-Button: Zwischenablage (grün) -->
|
||
<button type="button" id="pasteCode"
|
||
class="btn icon-btn icon-btn--accent"
|
||
aria-label="Code aus Zwischenablage einfügen"
|
||
title="Aus Zwischenablage">
|
||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||
<path d="M9 2h6a2 2 0 0 1 2 2h1a2 2 0 0 1 2 2v13a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V6a2 2 0 0 1 2-2h1a2 2 0 0 1 2-2Zm0 2a1 1 0 0 0-1 1h8a1 1 0 0 0-1-1H9Z"/>
|
||
</svg>
|
||
</button>
|
||
|
||
<button type="submit" class="btn btn-primary" style="width:auto">Beitreten</button>
|
||
|
||
<!-- (legacy) -->
|
||
<button id="joinGame" type="button" style="display:none">Join (legacy)</button>
|
||
</form>
|
||
|
||
<p class="muted" style="margin-top:8px">Tipp: Code ist vierstellig (z. B. 6767).</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- Username-Anzeige + Clipboard-Button -->
|
||
<script type="module">
|
||
// Username-Badge
|
||
const p = new URLSearchParams(location.search);
|
||
const u = p.get('username');
|
||
if (u) document.querySelector('#uname').textContent = u;
|
||
|
||
// Clipboard-Paste für Spiel-Code
|
||
const input = document.getElementById('gameId');
|
||
const pasteBtn = document.getElementById('pasteCode');
|
||
|
||
pasteBtn?.addEventListener('click', async () => {
|
||
try {
|
||
// Clipboard ist nur über HTTPS/localhost verfügbar
|
||
const text = await navigator.clipboard.readText();
|
||
const digits = (text.match(/\d/g) || []).join('').slice(0, 4);
|
||
|
||
if (!digits) {
|
||
alert('Keinen 4-stelligen Code in der Zwischenablage gefunden.');
|
||
return;
|
||
}
|
||
input.value = digits;
|
||
input.focus();
|
||
input.select();
|
||
// Optional auto-submit, wenn 4 Ziffern vorhanden
|
||
if (digits.length === 4) {
|
||
if (input.form?.requestSubmit) input.form.requestSubmit();
|
||
else input.form?.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
|
||
}
|
||
} catch (err) {
|
||
alert('Zwischenablage nicht verfügbar. Öffne die Seite über HTTPS oder erlaube Zugriff.');
|
||
console.error(err);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<script type="module" src="/js/lobby.js"></script>
|
||
<!-- Join-Handling wiederverwenden -->
|
||
<script type="module" src="/js/join-game.js"></script>
|
||
|
||
<!-- Optional: alter Join-Button (legacy) fokussiert nur das Feld -->
|
||
<script>
|
||
const btn = document.getElementById('joinGame');
|
||
if (btn) {
|
||
btn.addEventListener('click', (ev) => {
|
||
ev.preventDefault(); ev.stopImmediatePropagation();
|
||
const input = document.getElementById('gameId');
|
||
if (input) { input.focus(); input.select(); }
|
||
}, true);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|