UX-Paket: Navbar aufgeräumt, /server-Seite, Lightbox, Skeletons, Audit-Log, Reroll

- Navbar entschlackt: nur noch Devlog · Roadmap · Server · Community ·
  Setup; Galerie/Level/Events/Changelog im Community-Dropdown,
  Profil/Commits/Logout im Avatar-Menü; Mobile-Burger mit Drawer
- Öffentliche /server-Seite: Live-Status-Karten mit Spieler-Balken,
  Map, Connect-Button und 24h-Spielerzahl-Chart (SVG); Monitor sampelt
  jede Abfrage in player_history (7 Tage Retention), GET /api/servers
  liefert nur öffentliche Felder (keine Query-URLs/Hosts)
- Lightbox: Galerie- und Devlog-Bilder öffnen im Overlay mit
  Pfeiltasten, Buttons, Wisch-Gesten und Zähler statt neuem Tab
- Skeleton-Loader: schimmernde Platzhalter auf Devlogs, Roadmap,
  Galerie, Level, Changelog und Server statt "Lade …"
- Team-Audit-Log: audit_log-Tabelle (max 500 Einträge), Logging bei
  Settings/Composer/Vorlagen/Rollen-Menüs/Gameservern/Team/API-Keys/
  Branding, GET /api/auditlog (Owner) + Liste im Team-Tab
- Giveaway: 🔁 Reroll-Button (Admin-only) + 👥 Teilnehmerliste am
  Gewinner-Post

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 22:15:58 +02:00
co-authored by Claude Fable 5
parent 8d470ba26b
commit be11398f7c
17 changed files with 671 additions and 28 deletions
+148
View File
@@ -1255,3 +1255,151 @@ a.sha:hover { border-color: var(--neon); background: rgba(245, 197, 24, .07); }
.profile-roles { justify-content: center; }
.wish-form { flex-direction: column; }
}
/* ── NAV-DROPDOWNS + BURGER ────────────────────────── */
.nav-drop { position: relative; }
.nav-drop-btn {
display: inline-flex; align-items: center; gap: .35rem;
background: none; border: 0; cursor: pointer;
font-family: var(--mono); font-size: .7rem;
letter-spacing: .25em; text-transform: uppercase;
color: var(--muted); padding: .3rem 0;
transition: color .2s, text-shadow .2s;
}
.nav-drop-btn:hover { color: var(--text); }
.nav-drop-btn.active { color: var(--neon); text-shadow: 0 0 12px rgba(245, 197, 24, .35); }
.nav-caret { font-size: .6rem; transition: transform .2s; }
.nav-drop.open .nav-caret { transform: rotate(180deg); }
.nav-drop-menu {
position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%);
display: flex; flex-direction: column; min-width: 11rem;
background: rgba(14, 14, 14, .97); border: 1px solid var(--border); border-radius: 10px;
padding: .4rem; box-shadow: 0 12px 32px rgba(0, 0, 0, .6);
animation: riseIn .18s ease both;
z-index: 300;
}
.auth .nav-drop-menu { left: auto; right: 0; transform: none; }
.nav-drop-menu a {
font-family: var(--mono); font-size: .7rem;
letter-spacing: .2em; text-transform: uppercase;
color: var(--muted); padding: .55rem .8rem; border-radius: 6px;
transition: color .15s, background .15s;
}
.nav-drop-menu a:hover { color: var(--text); background: rgba(255, 255, 255, .05); }
.nav-drop-menu a.active { color: var(--neon); }
.user-chip-inner { display: inline-flex; align-items: center; gap: .55rem; letter-spacing: 0; }
.auth .nav-drop-btn {
border: 1px solid rgba(255, 255, 255, .1); border-radius: 999px;
padding: .3rem .8rem .3rem .35rem; background: rgba(255, 255, 255, .03);
}
.auth .nav-drop-btn:hover { border-color: var(--border); }
.burger {
display: none; background: none; border: 1px solid var(--border); border-radius: 8px;
color: var(--neon); font-size: 1.1rem; line-height: 1; padding: .4rem .6rem; cursor: pointer;
}
.drawer {
position: fixed; inset: 0; top: 0; z-index: 190;
display: flex; flex-direction: column; gap: .2rem;
padding: 5.5rem 1.5rem 2rem;
background: rgba(8, 8, 8, .97);
animation: riseIn .2s ease both;
overflow-y: auto;
}
.drawer a {
font-family: var(--mono); font-size: .95rem;
letter-spacing: .25em; text-transform: uppercase;
color: var(--muted); padding: .85rem .6rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
transition: color .15s;
}
.drawer a:hover, .drawer a.active { color: var(--neon); }
@media (max-width: 760px) {
.nav-links, .auth { display: none; }
.burger { display: block; margin-left: auto; }
}
/* ── LIGHTBOX ──────────────────────────────────────── */
.lightbox {
position: fixed; inset: 0; z-index: 1000;
display: flex; align-items: center; justify-content: center;
background: rgba(0, 0, 0, .92);
animation: lbIn .18s ease both;
}
@keyframes lbIn { from { opacity: 0; } to { opacity: 1; } }
.lb-img {
max-width: min(92vw, 1400px); max-height: 84vh;
border: 1px solid var(--border); border-radius: 8px;
box-shadow: 0 24px 80px rgba(0, 0, 0, .8);
}
.lb-close {
position: absolute; top: 1.2rem; right: 1.4rem;
background: none; border: 1px solid var(--border); border-radius: 999px;
color: var(--text); font-size: 1rem; padding: .45rem .7rem; cursor: pointer;
transition: color .15s, border-color .15s;
}
.lb-close:hover { color: var(--neon2); border-color: var(--neon2); }
.lb-nav {
position: absolute; top: 50%; transform: translateY(-50%);
background: rgba(0, 0, 0, .5); border: 1px solid var(--border); border-radius: 999px;
color: var(--text); font-size: 1.8rem; line-height: 1;
width: 3rem; height: 3rem; cursor: pointer;
transition: color .15s, border-color .15s;
}
.lb-nav:hover { color: var(--neon); border-color: var(--neon); }
.lb-prev { left: 1.2rem; }
.lb-next { right: 1.2rem; }
.lb-meta {
position: absolute; bottom: 1.4rem; left: 50%; transform: translateX(-50%);
display: flex; gap: 1.2rem; align-items: baseline;
font-family: var(--mono); font-size: .72rem; letter-spacing: .12em;
color: var(--muted); background: rgba(0, 0, 0, .6);
border: 1px solid rgba(255, 255, 255, .08); border-radius: 999px;
padding: .4rem 1rem; white-space: nowrap;
}
.lb-count { color: var(--neon); }
/* ── SKELETON-LOADER ───────────────────────────────── */
.skel {
position: relative; overflow: hidden;
background: rgba(255, 255, 255, .05); border-radius: 8px;
}
.skel::after {
content: '';
position: absolute; inset: 0;
background: linear-gradient(90deg, transparent, rgba(245, 197, 24, .07), transparent);
transform: translateX(-100%);
animation: skelShine 1.4s ease-in-out infinite;
}
@keyframes skelShine { to { transform: translateX(100%); } }
.skel-card { animation: riseIn .3s ease both; margin-bottom: 1.1rem; }
.skel-line { height: .95rem; margin: .55rem 0; }
.skel-shot { aspect-ratio: 16 / 9; border-radius: 10px; animation: riseIn .3s ease both; }
.skel-row { height: 2.6rem; border-radius: 10px; margin-bottom: .5rem; animation: riseIn .3s ease both; }
/* ── SERVER-STATUS-SEITE ───────────────────────────── */
.srv-card { margin-bottom: 1.3rem; }
.srv-card.srv-down { border-left: 3px solid rgba(242, 63, 67, .6); }
.srv-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.srv-name { font-family: var(--display); font-size: 1.5rem; letter-spacing: .04em; }
.srv-status { font-family: var(--mono); font-size: .78rem; letter-spacing: .08em; color: var(--muted); }
.srv-status.on { color: var(--success); }
.srv-status.off { color: #f23f43; }
.srv-ping { color: var(--muted2); }
.srv-bar { margin-top: .9rem; }
.srv-players { font-family: var(--mono); font-size: .75rem; color: var(--muted); margin-top: .4rem; }
.srv-map { color: var(--muted2); }
.srv-chart { width: 100%; height: 90px; margin-top: 1rem; display: block; }
.srv-chart-label {
font-family: var(--mono); font-size: .62rem; letter-spacing: .15em;
text-transform: uppercase; color: var(--muted2); margin-top: .25rem;
}
.srv-connect { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; margin-top: 1rem; }
.srv-addr { font-size: .8rem; }
.srv-checked { font-family: var(--mono); font-size: .62rem; color: var(--muted2); margin-top: .8rem; }
/* ── AUDIT-LOG ─────────────────────────────────────── */
.audit-list { max-height: 24rem; overflow-y: auto; }
.audit-ts { font-family: var(--mono); font-size: .65rem; color: var(--muted2); white-space: nowrap; }
.audit-action { font-family: var(--mono); font-size: .7rem; color: var(--neon); white-space: nowrap; }
.audit-detail { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 18rem; }