Files
d4rkbot/frontend/src/style.css
T
D4rkst3randClaude Fable 5 55e9ef57e2
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
Oeffentliche Statusseite nach Statuspage-Vorbild
Neue Seite /status auf dem Hub: Gesamtlage als Banner, darunter die
freigegebenen Dienste mit 90-Tage-Balken, die Game-Server, und die
Stoerungs-Historie der letzten 90 Tage.

Die Adressliste ist von einer kommagetrennten Einstellung in eine Tabelle
gewandert. Jeder Dienst hat jetzt Namen, Gruppe und einen Schalter
"oeffentlich" — sonst stuende auf einer oeffentlichen Seite die nackte URL,
auch von internen Diensten. Die alte Liste wird beim ersten Start uebernommen,
bewusst als nicht oeffentlich: was dort auftaucht, soll eine Entscheidung sein
und nicht durch eine Migration passieren.

/api/status liefert nur freigegebene Dienste und dabei keine Adressen, nur
Namen. Auch die Stoerungs-Historie ist gefiltert — sonst verriete sie, was es
sonst noch gibt. Im Browser gegengeprueft: auf der ganzen Seite steht kein
einziges https://.

Stoerungen werden jetzt aufgezeichnet, nicht nur gemeldet: pro Adresse ein
offener Eintrag, bis es wieder laeuft. Beim Wiederkommen wird er geschlossen,
bevor die DM rausgeht — sonst bliebe er bei einem Sendefehler ewig offen.

Aufbewahrung von 7 auf 90 Tage. Der Balken kann jetzt zwei Aufloesungen:
168 Stunden fuers Panel ("was war letzte Nacht?") und 90 Tage fuer die
Statusseite ("wie zuverlaessig?"). Stuendlich ueber 90 Tage waeren ueber 2000
Striche und unlesbar.

Im Panel sind aus der reinen Anzeige Verwaltung geworden: anlegen, bearbeiten,
entfernen, freigeben — dazu die Stoerungsliste.

Beim Bauen gefunden: die Uebernahme der alten Liste stand mitten in db.js und
rief getSetting(), dessen prepared statement erst 300 Zeilen weiter unten
entsteht. Der Bot starb beim Start mit "Cannot access getSettingStmt before
initialization" — nachgewiesen, dann ans Dateiende verschoben.

Geprueft: 182 SQL-Abfragen gegen das Schema, alle schreibenden Routen bewacht,
Stoerungs-Logik durchgespielt (doppeltes Eroeffnen wird abgelehnt, Schliessen
ohne offene gibt null), und beide Seiten im Browser mit drei Diensten in allen
drei Zustaenden.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 05:45:50 +02:00

2557 lines
97 KiB
CSS

/* ═══════════════════════════════════════════════════
D4RKST3R // DEVLOG — Styles (Design-System der Platform-Seite)
═══════════════════════════════════════════════════ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--neon: #f5c518;
--neon2: #ff4d00;
--bg: #0a0a0a;
--bg2: #111;
--bg3: #161616;
--text: #e8e0d0;
--muted: #8a8378;
--muted2: #666;
--border: rgba(245, 197, 24, 0.15);
--success: #00ff88;
--display: 'Bebas Neue', sans-serif;
--body: 'Barlow Condensed', sans-serif;
--mono: 'Share Tech Mono', monospace;
}
html { scroll-behavior: smooth; color-scheme: dark; }
body {
background: var(--bg);
color: var(--text);
font-family: var(--body);
font-size: 17px;
line-height: 1.6;
overflow-x: hidden;
min-height: 100vh;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
/* Text-Auswahl & Fokus im Brand-Look */
::selection { background: rgba(245, 197, 24, .25); color: var(--text); }
:focus-visible { outline: 1px solid var(--neon); outline-offset: 2px; }
/* Dunkle Scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: #262626; border: 2px solid var(--bg); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--neon); }
/* Einblend-Animation für Inhalte */
@keyframes riseIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
}
/* ── NOISE + SCANLINES ─────────────────────────────── */
body::before {
content: ''; position: fixed; inset: 0;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
opacity: .03; pointer-events: none; z-index: 900;
}
body::after {
content: ''; position: fixed; inset: 0;
background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0, 0, 0, .07) 2px, rgba(0, 0, 0, .07) 4px);
pointer-events: none; z-index: 899;
}
/* ── PARTICLES ─────────────────────────────────────── */
.particles-wrap {
position: fixed; inset: 0; pointer-events: none; z-index: 1; overflow: hidden;
}
.particle {
position: absolute; width: 2px; height: 2px;
background: var(--neon); border-radius: 50%; opacity: 0;
animation: floatUp var(--dur, 8s) var(--delay, 0s) infinite ease-in;
}
@keyframes floatUp {
0% { opacity: 0; transform: translateY(0) scale(1); }
10% { opacity: .6; }
80% { opacity: .2; }
100% { opacity: 0; transform: translateY(-100vh) scale(0); }
}
.app { min-height: 100vh; display: flex; flex-direction: column; position: relative; z-index: 2; }
/* ── NAV ───────────────────────────────────────────── */
.nav {
position: sticky; top: 0; z-index: 200;
display: flex; align-items: center; gap: 2.5rem;
padding: 1.25rem 2.5rem;
background: linear-gradient(to bottom, rgba(10, 10, 10, .98), rgba(10, 10, 10, .75));
border-bottom: 1px solid transparent;
transition: padding .3s, border-color .3s, background .3s, backdrop-filter .3s;
}
.nav.scrolled {
padding: .8rem 2.5rem;
background: rgba(10, 10, 10, .82);
backdrop-filter: blur(14px) saturate(1.2);
-webkit-backdrop-filter: blur(14px) saturate(1.2);
border-bottom-color: var(--border);
}
/* Neon-Glanzlinie unter der Navbar, wird beim Scrollen sichtbar */
.nav::after {
content: '';
position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
background: linear-gradient(90deg, transparent, rgba(245, 197, 24, .5) 30%, rgba(255, 77, 0, .5) 70%, transparent);
opacity: 0; transition: opacity .3s;
pointer-events: none;
}
.nav.scrolled::after { opacity: 1; }
.nav-logo {
font-family: var(--display);
font-size: 1.6rem; letter-spacing: .15em; color: var(--neon);
line-height: 1;
transition: text-shadow .25s;
}
.nav-logo:hover { text-shadow: 0 0 18px rgba(245, 197, 24, .55); }
.nav-logo span { color: var(--neon2); }
.nav-links { display: flex; gap: 1.6rem; flex: 1; align-items: center; }
.nav-links a {
position: relative;
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;
}
/* Animierter Gradient-Unterstrich: wächst von links */
.nav-links a::after {
content: '';
position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
background: linear-gradient(90deg, var(--neon), var(--neon2));
border-radius: 2px;
transform: scaleX(0); transform-origin: left;
transition: transform .25s ease;
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::after { transform: scaleX(.55); }
.nav-links a.active {
color: var(--neon);
text-shadow: 0 0 12px rgba(245, 197, 24, .35);
}
.nav-links a.active::after { transform: scaleX(1); }
/* ── AUTH ──────────────────────────────────────────── */
.auth { display: flex; align-items: center; }
.btn-login {
display: inline-flex; align-items: center; gap: .55rem;
font-family: var(--mono); font-size: .7rem;
letter-spacing: .25em; text-transform: uppercase;
color: var(--neon);
border: 1px solid var(--border);
border-radius: 999px;
padding: .5rem 1.2rem;
transition: background .2s, border-color .2s, color .2s, box-shadow .2s;
}
.btn-login:hover {
border-color: var(--neon);
background: rgba(245, 197, 24, .08);
box-shadow: 0 0 16px rgba(245, 197, 24, .15);
}
.discord-mark { width: 15px; height: 15px; }
.user-chip {
display: flex; align-items: center; gap: .6rem;
border: 1px solid rgba(255, 255, 255, .1);
border-radius: 999px;
padding: .3rem .9rem .3rem .35rem;
background: rgba(255, 255, 255, .03);
transition: border-color .2s;
}
.user-chip:hover { border-color: var(--border); }
.avatar { width: 24px; height: 24px; border-radius: 50%; border: 1px solid rgba(245, 197, 24, .4); }
.username { font-family: var(--mono); font-size: .7rem; letter-spacing: .1em; color: var(--muted); }
.logout { color: var(--muted2); font-size: .75rem; padding: 0 .1rem; transition: color .2s; }
.logout:hover { color: var(--neon2); }
/* ── PAGE HEADER ───────────────────────────────────── */
.page-header {
position: relative; overflow: hidden;
padding: 5.5rem 2.5rem 3.5rem;
border-bottom: 1px solid var(--border);
display: flex; align-items: flex-end;
min-height: 280px;
}
.page-bg-text {
position: absolute;
right: -1rem; top: 50%; transform: translateY(-50%);
font-family: var(--display);
font-size: 14rem; color: rgba(245, 197, 24, .04);
pointer-events: none; user-select: none; white-space: nowrap;
line-height: 1;
}
.page-header-grid {
position: absolute; inset: 0;
background-image:
linear-gradient(var(--border) 1px, transparent 1px),
linear-gradient(90deg, var(--border) 1px, transparent 1px);
background-size: 60px 60px;
mask-image: radial-gradient(ellipse 80% 80% at 30% 50%, black 20%, transparent 70%);
-webkit-mask-image: radial-gradient(ellipse 80% 80% at 30% 50%, black 20%, transparent 70%);
opacity: .5;
}
.page-header-content {
position: relative; z-index: 2;
max-width: 860px; width: 100%;
margin: 0 auto;
animation: riseIn .45s ease both;
}
.page-tag {
font-family: var(--mono);
font-size: .7rem; letter-spacing: .3em;
color: var(--neon2); text-transform: uppercase;
margin-bottom: .9rem;
}
.page-title {
font-family: var(--display);
font-size: clamp(3rem, 7vw, 5.5rem);
line-height: .95; letter-spacing: .02em;
color: var(--text);
margin-bottom: .75rem;
}
.page-subtitle {
font-size: 1.1rem; font-weight: 300;
color: var(--muted); max-width: 600px; line-height: 1.6;
}
/* ── CONTENT ───────────────────────────────────────── */
.main { flex: 1; }
.content {
max-width: 860px; width: 100%;
margin: 0 auto;
padding: 2.75rem 2.5rem 5rem;
animation: riseIn .45s ease .08s both;
}
.notice { color: var(--muted); padding: 1.5rem 0; font-size: 1.05rem; }
.notice.center { text-align: center; padding: 3.5rem 0; }
.notice.center p { margin-bottom: 1.25rem; }
/* ── SUCHE ─────────────────────────────────────────── */
.search {
display: flex; align-items: center; gap: .6rem;
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .1);
padding: .45rem .9rem;
margin-bottom: 1.75rem;
transition: border-color .2s;
}
.search:focus-within { border-color: var(--neon); }
.search-icon { color: var(--muted2); font-size: 1.1rem; }
.search input {
flex: 1;
background: none; border: none; outline: none;
color: var(--text);
font-family: var(--body); font-size: 1rem;
}
.search input::placeholder { color: var(--muted2); }
.search-count {
font-family: var(--mono);
font-size: .65rem; letter-spacing: .15em;
color: var(--neon); white-space: nowrap;
}
/* ── DEVLOG-TIMELINE ───────────────────────────────── */
.timeline {
display: flex; flex-direction: column; gap: 1.5rem;
position: relative; padding-left: 1.6rem;
}
.month-sep {
font-family: var(--mono);
font-size: .68rem; letter-spacing: .3em; text-transform: uppercase;
color: var(--neon2);
margin: .5rem 0 1.25rem;
display: flex; align-items: center; gap: 1rem;
}
.month-sep::after {
content: ''; flex: 1; height: 1px;
background: linear-gradient(to right, rgba(255, 77, 0, .35), transparent);
}
.timeline > div:first-child .month-sep { margin-top: 0; }
.timeline::before {
content: '';
position: absolute; left: 3px; top: 10px; bottom: 10px;
width: 1px;
background: linear-gradient(to bottom, var(--neon), rgba(245, 197, 24, .05));
}
.card {
position: relative;
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .06);
border-radius: 12px;
padding: 1.3rem 1.6rem 1.2rem;
transition: border-color .25s, background .25s, transform .25s, box-shadow .25s;
}
.card:hover {
border-color: var(--border);
background: var(--bg3);
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 0, 0, .45), 0 0 0 1px rgba(245, 197, 24, .06);
}
.timeline .card::before {
/* Marker auf der Timeline */
content: '';
position: absolute; left: -1.72rem; top: 1.55rem;
width: 7px; height: 7px;
background: var(--neon);
box-shadow: 0 0 10px rgba(245, 197, 24, .6);
transition: box-shadow .25s, transform .25s;
}
.timeline .card:hover::before {
box-shadow: 0 0 16px rgba(245, 197, 24, .9);
transform: scale(1.25);
}
.card-meta {
display: flex; align-items: baseline; justify-content: space-between;
gap: 1rem; margin-bottom: .55rem;
}
.card-date {
font-family: var(--mono);
font-size: .75rem; letter-spacing: .2em;
color: var(--neon); text-transform: uppercase;
}
.card-rel {
font-family: var(--mono);
font-size: .65rem; letter-spacing: .1em;
color: var(--muted2); white-space: nowrap;
margin-left: auto;
}
.card-project {
font-family: var(--mono);
font-size: .6rem; letter-spacing: .18em; text-transform: uppercase;
color: var(--neon2);
border: 1px solid rgba(255, 77, 0, .3);
padding: .1rem .5rem;
white-space: nowrap;
}
.card-delete {
font-family: var(--mono);
font-size: .7rem;
color: var(--muted2);
background: none; border: 1px solid transparent;
padding: .05rem .4rem;
transition: color .2s, border-color .2s;
}
.card-delete:hover { color: var(--neon2); border-color: rgba(255, 77, 0, .4); }
.card-body { color: var(--text); font-weight: 300; font-size: 1.08rem; }
.card-body p { margin: .55rem 0; }
.card-body p:first-child { margin-top: 0; }
.card-body p:last-child { margin-bottom: 0; }
.card-body strong { color: var(--neon); font-weight: 600; }
.card-body em { color: var(--muted); }
.card-body a {
color: var(--neon);
border-bottom: 1px solid var(--border);
transition: border-color .2s;
}
.card-body a:hover { border-bottom-color: var(--neon); }
.card-body code {
font-family: var(--mono);
font-size: .82em;
background: #000;
border: 1px solid rgba(255, 255, 255, .08);
padding: .06rem .4rem;
color: var(--success);
}
.card-body .md-list {
margin: .55rem 0;
padding-left: 1.2rem;
list-style: none;
}
.card-body .md-list li {
position: relative;
padding-left: .2rem;
margin: .25rem 0;
}
.card-body .md-list li::before {
content: '▪';
position: absolute;
left: -1.1rem;
color: var(--neon);
font-size: .8em;
top: .15em;
}
.card-body .md-hr {
border: none;
height: 1px;
background: linear-gradient(to right, var(--border), transparent);
margin: 1.1rem 0;
}
.card-body .md-h {
font-family: var(--mono);
font-size: .78rem;
letter-spacing: .2em;
text-transform: uppercase;
color: var(--neon);
margin: 1rem 0 .4rem;
}
.card-body .md-h2, .card-body .md-h3 { color: var(--muted); }
/* Bildergalerie (heruntergeladene Devlog-Screenshots) */
.card-images {
display: grid; gap: .5rem;
margin-top: .9rem;
}
.card-images.n1 { grid-template-columns: 1fr; }
.card-images.n2 { grid-template-columns: 1fr 1fr; }
.card-images.n3 { grid-template-columns: 1fr 1fr 1fr; }
.card-images.n4 { grid-template-columns: 1fr 1fr; }
.card-images a {
display: block; overflow: hidden;
border: 1px solid rgba(255, 255, 255, .08);
aspect-ratio: 16 / 9;
transition: border-color .2s;
}
.card-images a:hover { border-color: var(--neon); }
.card-images img {
width: 100%; height: 100%; object-fit: cover; display: block;
transition: transform .3s;
}
.card-images a:hover img { transform: scale(1.03); }
.card-images.n1 a { aspect-ratio: auto; max-height: 420px; }
.card-images.n1 img { object-fit: contain; background: #000; }
/* Abgesetzte Fußzeile („X Commits heute — Details im Repo") */
.card-footer {
margin-top: .9rem; padding-top: .7rem;
border-top: 1px solid rgba(255, 255, 255, .06);
font-family: var(--mono);
font-size: .68rem; letter-spacing: .08em;
color: var(--muted2);
}
.card-footer p { margin: 0; }
.card-footer a { color: var(--muted); border-bottom: 1px solid transparent; }
.card-footer a:hover { color: var(--neon); }
/* ── HEATMAP + WÜNSCHE (Roadmap) ───────────────────── */
.hm-wrap {
display: flex; gap: 3px;
overflow-x: auto;
padding: .5rem 0;
}
.hm-week { display: flex; flex-direction: column; gap: 3px; }
.hm-cell { width: 11px; height: 11px; border-radius: 2px; flex-shrink: 0; }
.hm-0 { background: rgba(255, 255, 255, .05); }
.hm-1 { background: rgba(245, 197, 24, .25); }
.hm-2 { background: rgba(245, 197, 24, .5); }
.hm-3 { background: rgba(245, 197, 24, .75); }
.hm-4 { background: var(--neon); box-shadow: 0 0 4px rgba(245, 197, 24, .4); }
.wish-row {
display: flex; align-items: baseline; gap: 1rem;
padding: .6rem 1rem;
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .06);
border-radius: 10px;
margin-bottom: .5rem;
transition: border-color .2s, background .2s;
}
.wish-row:hover { border-color: var(--border); background: var(--bg3); }
.wish-score {
font-family: var(--mono); font-size: .78rem;
color: var(--neon); white-space: nowrap; min-width: 3.5rem;
}
.wish-idea { flex: 1; font-weight: 300; }
.wish-author { font-family: var(--mono); font-size: .62rem; color: var(--muted2); white-space: nowrap; }
/* ── GALERIE ───────────────────────────────────────── */
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
gap: 1rem;
}
.shot {
position: relative; display: block; overflow: hidden;
border: 1px solid rgba(255, 255, 255, .08);
border-radius: 10px;
aspect-ratio: 16 / 9;
background: #000;
transition: border-color .25s, transform .25s, box-shadow .25s;
animation: riseIn .5s ease both;
}
/* Gestaffeltes Einblenden der ersten Reihen */
.shot:nth-child(2) { animation-delay: .05s; }
.shot:nth-child(3) { animation-delay: .1s; }
.shot:nth-child(4) { animation-delay: .15s; }
.shot:nth-child(5) { animation-delay: .2s; }
.shot:nth-child(6) { animation-delay: .25s; }
.shot:hover {
border-color: var(--neon);
transform: translateY(-3px);
box-shadow: 0 12px 28px rgba(0, 0, 0, .5), 0 0 18px rgba(245, 197, 24, .12);
}
.shot img {
width: 100%; height: 100%; object-fit: cover; display: block;
transition: transform .35s ease, filter .35s;
filter: brightness(.92);
}
.shot:hover img { transform: scale(1.06); filter: brightness(1.05); }
/* Wer das Bild gemacht hat, steht dauerhaft dran — beim Überfahren nur
deutlicher. Vorher war es nur im Hover sichtbar und damit am Handy nie. */
.shot-meta {
position: absolute; inset: auto 0 0 0;
display: flex; justify-content: space-between; align-items: baseline;
padding: 1.4rem .7rem .5rem;
background: linear-gradient(to top, rgba(0, 0, 0, .92), transparent);
font-family: var(--mono); font-size: .64rem; letter-spacing: .1em;
opacity: .8;
transition: opacity .25s;
}
.shot:hover .shot-meta { opacity: 1; }
.shot-author { color: var(--neon); }
.shot-date { color: var(--muted); }
/* ── ROADMAP ───────────────────────────────────────── */
.roadmap-group { margin-bottom: 2.75rem; }
.roadmap-group .settings-title { margin-bottom: 1rem; }
.milestone {
margin-bottom: 1.1rem;
border-left: 3px solid rgba(245, 197, 24, .25);
}
.milestone:hover { border-left-color: var(--neon); }
.milestone-title {
font-family: var(--display);
font-size: 1.35rem; letter-spacing: .04em;
color: var(--text);
}
.progress {
position: relative;
height: 8px; border-radius: 999px;
background: rgba(255, 255, 255, .06);
margin-top: .9rem;
overflow: hidden;
}
.progress-bar {
position: relative;
height: 100%; border-radius: 999px;
background: linear-gradient(90deg, var(--neon2), var(--neon));
box-shadow: 0 0 12px rgba(245, 197, 24, .45);
transition: width .6s ease;
overflow: hidden;
}
/* Wandernder Glanz auf dem Fortschrittsbalken */
.progress-bar::after {
content: '';
position: absolute; inset: 0;
background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .35) 50%, transparent 70%);
transform: translateX(-100%);
animation: barShine 3.2s ease-in-out infinite;
}
@keyframes barShine {
0%, 55% { transform: translateX(-100%); }
85%, 100% { transform: translateX(100%); }
}
.progress-info {
display: flex; justify-content: space-between;
font-family: var(--mono);
font-size: .65rem; letter-spacing: .1em;
color: var(--muted2);
margin-top: .45rem;
}
.progress-info span:first-child { color: var(--neon); }
/* ── CHANGELOG ─────────────────────────────────────── */
.release-card { margin-bottom: 1.5rem; }
.release-tag {
font-family: var(--mono);
font-size: .85rem; letter-spacing: .1em;
color: var(--neon);
border: 1px solid var(--border);
background: rgba(245, 197, 24, .06);
padding: .12rem .6rem;
}
.release-name {
font-family: var(--display);
font-size: 1.35rem; letter-spacing: .03em;
margin: .3rem 0 .2rem;
color: var(--text);
}
/* ── COMMIT-LISTE ──────────────────────────────────── */
.commit-list { border: 1px solid rgba(255, 255, 255, .06); background: var(--bg2); }
.commit-row {
display: flex; align-items: center; gap: .9rem;
padding: .7rem 1.15rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
transition: background .15s;
}
.commit-row:last-child { border-bottom: none; }
.commit-row:hover { background: var(--bg3); }
.sha {
font-family: var(--mono);
font-size: .72rem; letter-spacing: .05em;
color: var(--neon);
border: 1px solid var(--border);
padding: .12rem .5rem;
white-space: nowrap;
transition: border-color .2s, background .2s;
}
a.sha:hover { border-color: var(--neon); background: rgba(245, 197, 24, .07); }
.commit-msg {
flex: 1;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-weight: 300; font-size: 1.02rem;
}
.chip {
font-family: var(--mono);
font-size: .6rem; letter-spacing: .15em; text-transform: uppercase;
padding: .14rem .55rem; white-space: nowrap;
}
.chip-repo { color: var(--muted); border: 1px solid rgba(255, 255, 255, .1); }
.chip-branch { color: var(--neon2); border: 1px solid rgba(255, 77, 0, .3); }
.commit-time {
font-family: var(--mono);
font-size: .68rem; color: var(--muted2); white-space: nowrap;
}
/* ── SETTINGS-LAYOUT (Sidebar + Content) ───────────── */
/* Config-Seite: deutlich breiter als Lesetexte — hier stehen Formulare und
Karten nebeneinander, schmal erzwingt sonst unnötiges Scrollen. */
.content-wide { max-width: 1440px; padding-left: 2rem; padding-right: 2rem; }
.settings-layout {
display: flex;
gap: 2rem;
align-items: flex-start;
}
.settings-nav {
display: flex;
flex-direction: column;
gap: .25rem;
position: sticky;
top: 5rem;
width: 12.5rem;
flex-shrink: 0;
/* Bei 15 Bereichen wird die Leiste höher als der Bildschirm — dann scrollt sie selbst */
max-height: calc(100vh - 6.5rem);
overflow-y: auto;
padding-right: .3rem;
}
.settings-nav::-webkit-scrollbar { width: 5px; }
.settings-nav::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }
/* Suche über den Bereichen */
.settings-search {
display: flex; align-items: center; gap: .5rem;
background: var(--bg2); border: 1px solid var(--border);
border-radius: 9px; padding: .45rem .6rem;
margin-bottom: .5rem; color: var(--muted2);
transition: border-color .15s;
}
.settings-search:focus-within { border-color: var(--neon); }
.settings-search input {
flex: 1; min-width: 0;
background: none; border: 0; outline: none; padding: 0;
font-family: var(--mono); font-size: .72rem; letter-spacing: .08em;
color: var(--text);
}
.settings-search input::placeholder { color: var(--muted2); letter-spacing: .12em; }
.settings-search-clear {
background: none; border: 0; padding: 0; display: inline-flex;
color: var(--muted2); cursor: pointer;
}
.settings-search-clear:hover { color: var(--neon); }
/* Bereichs-Gruppen */
.settings-nav-group { display: flex; flex-direction: column; gap: .2rem; margin-bottom: .7rem; }
.settings-nav-label {
font-family: var(--mono);
font-size: .55rem; letter-spacing: .22em; text-transform: uppercase;
color: var(--muted2);
padding: .3rem .9rem .25rem;
}
/* Treffer der Einstellungs-Suche */
.settings-hit {
display: flex; flex-direction: column; gap: .1rem;
width: 100%; text-align: left;
background: none; border: 0; border-left: 2px solid transparent;
border-radius: 9px;
padding: .4rem .9rem;
cursor: pointer;
transition: background .15s, border-color .15s;
}
.settings-hit:hover { background: rgba(255, 255, 255, .04); border-left-color: var(--neon); }
.settings-hit-label { color: var(--text); font-size: .88rem; line-height: 1.3; }
.settings-hit-tab {
font-family: var(--mono); font-size: .55rem;
letter-spacing: .14em; text-transform: uppercase; color: var(--muted2);
}
.settings-hit:hover .settings-hit-tab { color: var(--neon); }
/* Angesprungenes Feld kurz hervorheben, damit man es im Formular findet */
.field-found {
animation: fieldFound 2.2s ease both;
border-radius: 8px;
}
@keyframes fieldFound {
0%, 55% { box-shadow: 0 0 0 2px var(--neon), 0 0 18px rgba(245, 197, 24, .25); }
100% { box-shadow: 0 0 0 2px transparent, 0 0 0 transparent; }
}
.settings-nav-empty {
font-family: var(--mono); font-size: .66rem; letter-spacing: .1em;
color: var(--muted2); padding: .6rem .9rem;
}
/* Status-Seite: „Noch einzurichten" */
.stat-of { color: var(--muted2); font-size: .6em; }
.todo-missing {
font-family: var(--mono); font-size: .62rem;
letter-spacing: .1em; text-transform: uppercase;
color: var(--neon2); flex: 1;
}
.todo-done { color: var(--success); }
/* Hebt sich vom „Einrichten"-Knopf daneben ab: der eine tut etwas, der andere
führt nur hin */
.btn-create { color: var(--neon); border-color: rgba(245, 197, 24, .45); }
.btn-create:hover:not(:disabled) { background: rgba(245, 197, 24, .1); }
.btn-create:disabled { opacity: .4; cursor: default; }
/* Stern: heftet eine Funktion in die Seitenleiste. Ungeheftet nur angedeutet,
damit die Karten nicht wie ein Sternenhimmel aussehen. */
.mod-fav {
flex: none; display: inline-flex; align-items: center; justify-content: center;
background: none; border: 0; padding: .15rem;
color: var(--muted2); opacity: .35; cursor: pointer;
transition: color .15s, opacity .15s;
}
.mod-card:hover .mod-fav, .modpage-head .mod-fav { opacity: .75; }
.mod-fav:hover { color: var(--neon); opacity: 1; }
.mod-fav.on { color: var(--neon); opacity: 1; }
.mod-fav.on svg { fill: currentColor; }
/* ── MODUL-SEITE ───────────────────────────────────── */
/* Name und Symbol auf der Karte öffnen die Seite der Funktion */
.mod-open {
display: flex; align-items: flex-start; gap: .8rem;
flex: 1; min-width: 0; text-align: left;
background: none; border: 0; padding: 0; cursor: pointer;
}
.mod-open:hover .mod-name { color: var(--neon); }
.modpage-back {
background: none; border: 0; padding: 0; margin-bottom: 1.2rem;
font-family: var(--mono); font-size: .62rem;
letter-spacing: .15em; text-transform: uppercase;
color: var(--muted2); cursor: pointer;
transition: color .15s;
}
.modpage-back:hover { color: var(--neon); }
.modpage-head {
display: flex; align-items: flex-start; gap: 1rem;
padding-bottom: 1.2rem; margin-bottom: 1.2rem;
border-bottom: 1px solid var(--border);
}
.modpage-icon {
flex: none; display: inline-flex; align-items: center; justify-content: center;
width: 3rem; height: 3rem; border-radius: 11px;
background: var(--bg3); border: 1px solid rgba(245, 197, 24, .3);
color: var(--neon);
}
.modpage-titles { flex: 1; min-width: 0; }
.modpage-name {
font-family: var(--display); font-size: 1.7rem;
letter-spacing: .04em; color: var(--text); margin: 0 0 .2rem;
}
.modpage-desc { color: var(--muted); font-weight: 300; line-height: 1.5; margin: 0; }
/* Abschnitte innerhalb der Seite — flacher als die großen Bereichs-Karten */
.modpage-block { margin-bottom: 1.8rem; }
.modpage-block:last-child { margin-bottom: 0; }
.modpage-block > .settings-title {
font-size: .66rem; color: var(--muted);
margin-bottom: .9rem;
}
.modpage-block > .settings-title::after {
background: linear-gradient(90deg, rgba(255, 255, 255, .12), transparent);
}
/* Die Seite ist schmaler als das zweispaltige Raster — Formulare lesen sich so besser */
.modpage { max-width: 60rem; }
/* Grundgerüst-Assistent: Vorschau und Ergebnis */
.setup-plan {
border: 1px solid var(--border); border-radius: 12px;
background: rgba(255, 255, 255, .015);
padding: 1.1rem 1.2rem; margin-bottom: 1.2rem;
animation: riseIn .25s ease both;
}
.setup-plan-intro { color: var(--muted); font-weight: 300; line-height: 1.6; margin: 0 0 .9rem; }
.setup-plan-intro strong { color: var(--neon); font-weight: 600; }
.setup-plan-list {
display: flex; flex-direction: column;
border: 1px solid rgba(255, 255, 255, .06); border-radius: 8px;
margin-bottom: 1rem; max-height: 22rem; overflow-y: auto;
}
.setup-step {
display: flex; align-items: baseline; gap: 1rem;
padding: .45rem .8rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.setup-step:last-child { border-bottom: 0; }
.setup-step-name {
font-family: var(--mono); font-size: .82rem; color: var(--neon);
min-width: 11rem;
}
/* Was es schon gibt, tritt zurück — es passiert ja nichts Neues */
.setup-step.da .setup-step-name { color: var(--muted); }
.setup-step.fehler .setup-step-name { color: #f23f43; }
.setup-step-note {
font-family: var(--mono); font-size: .62rem;
letter-spacing: .1em; text-transform: uppercase; color: var(--muted2);
flex: 1;
}
.setup-step.fehler .setup-step-note { color: #f23f43; text-transform: none; letter-spacing: .02em; }
.setup-step-for { color: var(--muted2); font-size: .82rem; font-weight: 300; }
.settings-nav-item {
display: flex; align-items: center; gap: .7rem;
font-family: var(--mono);
font-size: .72rem; letter-spacing: .18em; text-transform: uppercase;
color: var(--muted);
background: none;
border: 1px solid transparent;
border-left: 2px solid transparent;
padding: .55rem .9rem;
text-align: left;
transition: color .15s, background .15s, border-color .15s;
}
.settings-nav-item:hover { color: var(--text); background: rgba(255, 255, 255, .03); }
.settings-nav-item.active {
color: var(--neon);
background: rgba(245, 197, 24, .06);
border-left-color: var(--neon);
}
.settings-nav-icon { font-size: .95rem; }
.settings-content { flex: 1; min-width: 0; animation: riseIn .3s ease both; }
/* Tabs, die nur aus Formular-Blöcken bestehen, stellen ihre Blöcke ab genug
Breite nebeneinander — halbiert das Scrollen, ohne das Innenleben eines
Blocks anzufassen. Tabs mit Editoren und Vorschauen bleiben einspaltig. */
@media (min-width: 1180px) {
.settings-content.dense { columns: 2; column-gap: 1.25rem; }
.settings-content.dense > .settings-section {
break-inside: avoid;
margin-top: 0;
}
}
.section-intro {
color: var(--muted);
font-weight: 300;
margin-bottom: 1.2rem;
max-width: 38rem;
}
/* Reaction-Roles-Editor */
.rr-row {
display: flex; gap: .5rem; align-items: center;
margin-bottom: .45rem;
}
.rr-row select { flex: 1; }
.rr-row input[type="text"]:not(.rr-emoji) { flex: 1; }
.rr-emoji { width: 5.5rem !important; flex: none !important; text-align: center; }
/* Kleine Buttons in Listen-Zeilen + Ghost-Variante */
.btn-mini {
font-family: var(--mono);
font-size: .6rem; letter-spacing: .15em; text-transform: uppercase;
color: var(--muted);
background: none;
border: 1px solid rgba(255, 255, 255, .12);
border-radius: 5px;
padding: .25rem .6rem;
white-space: nowrap;
transition: color .15s, border-color .15s;
}
.btn-mini:hover { color: var(--neon); border-color: var(--neon); }
.btn-ghost {
background: none;
color: var(--muted);
border-color: rgba(255, 255, 255, .12);
}
.btn-ghost:hover:not(:disabled) { color: var(--text); background: rgba(255, 255, 255, .04); box-shadow: none; }
/* Feedback-Toast unten rechts */
.feedback-float {
position: fixed;
right: 1.5rem; bottom: 1.5rem;
z-index: 500;
font-family: var(--mono);
font-size: .78rem; letter-spacing: .1em;
color: var(--success);
background: #0d0d0d;
border: 1px solid rgba(0, 255, 136, .3);
padding: .6rem 1.1rem;
animation: riseIn .25s ease both;
}
@media (max-width: 760px) {
.settings-layout { flex-direction: column; }
/* Schmal wird aus der Leiste eine Zeile: Suche oben, Bereiche daneben scrollend.
Die Gruppen-Überschriften fallen weg — waagerecht bringen sie nichts. */
.settings-nav {
position: static;
flex-direction: row;
flex-wrap: wrap;
overflow: visible;
max-height: none;
width: 100%;
gap: .35rem;
padding: 0 0 .35rem;
}
.settings-search { width: 100%; margin-bottom: .2rem; }
.settings-nav-group { flex-direction: row; flex-wrap: wrap; margin-bottom: 0; gap: .35rem; }
.settings-nav-label { display: none; }
.settings-nav-item {
border-left: none;
border-bottom: 2px solid transparent;
white-space: nowrap;
padding: .45rem .7rem;
}
.settings-nav-item.active { border-left: none; border-bottom-color: var(--neon); }
}
/* ── SETTINGS ──────────────────────────────────────── */
.settings-section {
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .06);
padding: 1.4rem 1.6rem;
margin-bottom: 1.5rem;
}
.settings-title {
display: flex; align-items: center; gap: 1rem;
font-family: var(--mono);
font-size: .72rem; letter-spacing: .3em; text-transform: uppercase;
color: var(--neon2);
margin-bottom: 1.2rem;
}
/* Auslaufende Linie hinter Gruppen-Titeln */
.settings-title::after {
content: '';
flex: 1; height: 1px;
background: linear-gradient(90deg, rgba(255, 77, 0, .35), transparent);
}
.stats { display: flex; flex-wrap: wrap; gap: 2.5rem; }
.stat { display: flex; flex-direction: column; gap: .1rem; }
.stat-value {
font-family: var(--display);
font-size: 1.5rem; letter-spacing: .05em; color: var(--text);
}
.stat-label {
font-family: var(--mono);
font-size: .6rem; letter-spacing: .25em; text-transform: uppercase;
color: var(--muted2);
}
.field { margin-bottom: 1.1rem; }
.field:last-child { margin-bottom: 0; }
.field > label {
display: block;
font-family: var(--mono);
font-size: .68rem; letter-spacing: .15em; text-transform: uppercase;
color: var(--muted);
margin-bottom: .4rem;
}
.field-hint {
text-transform: none; letter-spacing: .03em;
color: var(--muted2); margin-left: .5rem;
}
.field-row { display: flex; gap: .6rem; }
.field-row select { flex: 1; }
.field textarea {
width: 100%;
background: #0d0d0d;
border: 1px solid rgba(255, 255, 255, .12);
color: var(--text);
font-family: var(--body);
font-size: .95rem;
padding: .5rem .7rem;
outline: none;
resize: vertical;
transition: border-color .2s;
}
.field textarea:focus { border-color: var(--neon); }
.field select, .field input[type="text"] {
width: 100%;
background: #0d0d0d;
border: 1px solid rgba(255, 255, 255, .12);
color: var(--text);
font-family: var(--body);
font-size: .95rem;
padding: .5rem .7rem;
outline: none;
transition: border-color .2s;
}
.field select:focus, .field input[type="text"]:focus { border-color: var(--neon); }
/* Auf breiten Schirmen sollen Eingabefelder nicht über die halbe Seite laufen */
.field select, .field input[type="text"], .field input[type="number"] { max-width: 44rem; }
.field select option { background: #0d0d0d; }
/* Schalter links, Beschriftung und Hinweis rechts gestapelt — vorher klebten
alle drei in einer Zeile aneinander. Fehlt der Hinweis, bleibt Zeile 2 leer
und kostet keine Höhe.
Der Typ-Selektor muss sein: `.field > label` weiter oben ist spezifischer
als eine einzelne Klasse und hat die Schalter sonst wieder zu Blöcken in
Versalien gemacht. */
label.toggle {
display: grid;
grid-template-columns: auto 1fr;
column-gap: 1rem; row-gap: .2rem;
align-items: center;
cursor: pointer;
padding: .15rem 0;
margin-bottom: 0;
/* Beschriftung des Schalters ist Fließtext, nicht die Versalien-Feldzeile */
font-family: inherit; font-size: inherit;
letter-spacing: normal; text-transform: none;
color: inherit;
}
.toggle input {
appearance: none;
grid-column: 1; grid-row: 1;
width: 42px; height: 24px; flex-shrink: 0;
background: var(--bg3); border: 1px solid var(--border);
position: relative; cursor: pointer;
transition: background .2s, border-color .2s;
}
.toggle input::after {
content: '';
position: absolute; top: 2px; left: 2px;
width: 18px; height: 18px;
background: var(--muted2);
transition: transform .2s, background .2s;
}
.toggle:hover input { border-color: var(--neon); }
.toggle input:checked { background: var(--neon); border-color: var(--neon); }
.toggle input:checked::after { transform: translateX(18px); background: #0a0a0a; }
.toggle > span:first-of-type {
grid-column: 2; grid-row: 1;
color: var(--text); font-size: .95rem;
}
.toggle .field-hint {
grid-column: 2; grid-row: 2;
margin-left: 0; font-size: .82rem; line-height: 1.4;
}
/* API-Keys */
.key-list { margin-bottom: 1.2rem; border: 1px solid rgba(255, 255, 255, .06); }
.key-row {
display: flex; align-items: center; gap: 1rem;
padding: .5rem .8rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
font-size: .9rem;
}
.key-row:last-child { border-bottom: none; }
.key-name { font-weight: 600; min-width: 8rem; }
.key-scopes {
font-family: var(--mono); font-size: .65rem; letter-spacing: .1em;
color: var(--neon); flex: 1;
}
.key-used { font-family: var(--mono); font-size: .62rem; color: var(--muted2); white-space: nowrap; }
.key-created {
border: 1px solid rgba(0, 255, 136, .3);
background: rgba(0, 255, 136, .04);
padding: .8rem 1rem;
margin-bottom: 1.2rem;
font-size: .9rem;
}
.key-created p { margin: 0 0 .5rem; }
.key-created code {
display: block;
font-family: var(--mono); font-size: .8rem;
color: var(--success);
background: #000; padding: .5rem .7rem;
user-select: all; word-break: break-all;
}
.scope-row { display: flex; gap: 1.2rem; margin-top: .5rem; flex-wrap: wrap; }
.scope-pick {
display: flex; align-items: center; gap: .4rem;
font-family: var(--mono); font-size: .7rem; letter-spacing: .1em;
color: var(--muted); cursor: pointer;
}
.scope-pick input { accent-color: var(--neon); }
.settings-actions { display: flex; align-items: center; gap: 1rem; }
.btn-save { background: var(--neon); color: #0a0a0a; border-color: var(--neon); font-weight: 600; }
.btn-save:hover:not(:disabled) { background: var(--text); border-color: var(--text); }
.feedback { font-family: var(--mono); font-size: .75rem; letter-spacing: .1em; color: var(--success); }
/* ── PAGINATION ────────────────────────────────────── */
.pager {
display: flex; align-items: center; justify-content: center;
gap: 1.5rem; margin-top: 2.25rem;
}
.pager-info {
font-family: var(--mono);
font-size: .75rem; letter-spacing: .2em; color: var(--muted2);
}
.btn {
font-family: var(--mono);
font-size: .68rem; letter-spacing: .2em; text-transform: uppercase;
color: var(--neon);
background: none;
border: 1px solid var(--border);
padding: .5rem 1.1rem;
transition: background .2s, border-color .2s, opacity .2s;
}
.btn:hover:not(:disabled) {
border-color: var(--neon);
background: rgba(245, 197, 24, .08);
box-shadow: 0 0 14px rgba(245, 197, 24, .18);
}
.btn:disabled { opacity: .25; cursor: default; }
/* ── FOOTER ────────────────────────────────────────── */
.footer {
position: relative;
border-top: 1px solid var(--border);
padding: 1.5rem 2.5rem;
display: flex; align-items: center; justify-content: center; gap: .9rem;
font-family: var(--mono); font-size: .68rem; letter-spacing: .2em;
color: var(--muted2);
}
.footer::before {
content: '';
position: absolute; left: 0; right: 0; top: -1px; height: 1px;
background: linear-gradient(90deg, transparent, rgba(245, 197, 24, .4), transparent);
}
.footer-logo { font-family: var(--display); font-size: .95rem; letter-spacing: .15em; color: var(--neon); }
.footer-logo span { color: var(--neon2); }
.footer-sep { color: var(--muted2); }
.footer a { color: var(--muted); text-transform: uppercase; transition: color .2s; }
.footer a:hover { color: var(--neon); }
/* ── MOBILE ────────────────────────────────────────── */
@media (max-width: 640px) {
.nav { padding: 1rem 1.25rem; gap: 1.25rem; }
.nav.scrolled { padding: .8rem 1.25rem; }
.username { display: none; }
.page-header { padding: 4rem 1.25rem 2.5rem; min-height: 200px; }
.page-bg-text { font-size: 8rem; }
.content { padding: 2rem 1.25rem 4rem; }
.timeline { padding-left: 1.2rem; }
.commit-row { flex-wrap: wrap; row-gap: .35rem; }
.commit-msg { flex-basis: 100%; order: -1; white-space: normal; }
}
/* ── MODERN POLISH ─────────────────────────────────────
Weiche Radien + feinere Flächen, überschreibt gezielt
die eckigen Basis-Styles weiter oben. */
.card, .settings-section, .commit-list, .key-list, .key-created,
.wish-row, .release-card, .milestone {
border-radius: 12px;
}
.settings-section {
background: linear-gradient(180deg, rgba(255, 255, 255, .015), transparent 40%), var(--bg2);
border-color: rgba(255, 255, 255, .08);
transition: border-color .2s;
}
.settings-section:hover { border-color: rgba(245, 197, 24, .18); }
.settings-section + .settings-section,
.settings-content > .settings-section { margin-bottom: 1.25rem; }
.btn, .btn-login, .field select, .field input[type="text"], .field textarea,
.search, .user-chip, .feedback-float, .sha, .card-project, .card-delete,
.commits th:first-child, .commits th:last-child {
border-radius: 8px;
}
.chip, .key-scopes { border-radius: 99px; }
.settings-nav-item { border-radius: 9px; border-left-width: 2px; }
.key-list .key-row:first-child { border-radius: 12px 12px 0 0; }
.key-list .key-row:last-child { border-radius: 0 0 12px 12px; }
.commit-list .commit-row:first-child { border-radius: 12px 12px 0 0; }
.commit-list .commit-row:last-child { border-radius: 0 0 12px 12px; }
.card-images a, .shot, .progress, .hm-cell { border-radius: 6px; }
.card-images.n1 a { border-radius: 10px; }
/* Inputs: ruhigerer Grundzustand, klarer Fokus */
.field select, .field input[type="text"], .field textarea {
background: rgba(0, 0, 0, .35);
border-color: rgba(255, 255, 255, .09);
}
.field select:hover, .field input[type="text"]:hover, .field textarea:hover {
border-color: rgba(255, 255, 255, .2);
}
.field select:focus, .field input[type="text"]:focus, .field textarea:focus {
border-color: var(--neon);
box-shadow: 0 0 0 3px rgba(245, 197, 24, .12);
}
.toggle input { border-radius: 99px; }
.toggle input::after { border-radius: 50%; }
/* ── LEVEL-BESTENLISTE ─────────────────────────────── */
.lvl-list { border: 1px solid rgba(255, 255, 255, .06); background: var(--bg2); border-radius: 12px; }
.lvl-row {
display: flex; align-items: center; gap: 1rem;
padding: .65rem 1.1rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.lvl-row:last-child { border-bottom: none; }
.lvl-row:first-child { border-radius: 12px 12px 0 0; }
.lvl-rank {
display: inline-flex; align-items: center; gap: .35rem;
font-family: var(--mono); font-size: .85rem; color: var(--muted);
min-width: 3.4rem;
}
.lvl-rank-n { min-width: 1.2rem; text-align: right; }
/* Die ersten drei Plätze dürfen sich abheben — sonst sieht die Liste flach aus */
.lvl-row.top .lvl-rank-n { color: var(--text); font-size: .95rem; }
.lvl-row.top-1 { background: linear-gradient(90deg, rgba(245, 197, 24, .07), transparent 55%); }
.lvl-row.top-2 { background: linear-gradient(90deg, rgba(192, 196, 204, .05), transparent 55%); }
.lvl-row.top-3 { background: linear-gradient(90deg, rgba(192, 122, 62, .05), transparent 55%); }
.lvl-avatar {
flex: none; width: 2.1rem; height: 2.1rem; border-radius: 50%;
object-fit: cover;
background: var(--bg3); border: 1px solid var(--border);
}
.lvl-row.top-1 .lvl-avatar { border-color: rgba(245, 197, 24, .55); }
.lvl-avatar-empty {
display: inline-flex; align-items: center; justify-content: center;
font-family: var(--display); font-size: 1rem; color: var(--muted);
}
.lvl-name { font-weight: 600; min-width: 9rem; }
.lvl-progress { flex: 1; }
.lvl-level {
font-family: var(--mono); font-size: .72rem; letter-spacing: .1em;
color: var(--neon); white-space: nowrap;
}
.lvl-xp { font-family: var(--mono); font-size: .68rem; color: var(--muted2); white-space: nowrap; min-width: 6rem; text-align: right; }
@media (max-width: 640px) {
.lvl-name { min-width: 0; flex: 1; }
.lvl-progress { display: none; }
}
/* Datums-/Zeit-Inputs wie Text-Inputs stylen */
.field input[type="date"], .field input[type="time"] {
background: rgba(0, 0, 0, .35);
border: 1px solid rgba(255, 255, 255, .09);
border-radius: 8px;
color: var(--text);
font-family: var(--body);
font-size: .95rem;
padding: .5rem .7rem;
outline: none;
color-scheme: dark;
}
.field input[type="date"]:focus, .field input[type="time"]:focus {
border-color: var(--neon);
box-shadow: 0 0 0 3px rgba(245, 197, 24, .12);
}
/* Willkommens-Karte: Vorschau + Farbwähler */
.welcome-preview {
display: block; width: 100%; max-width: 900px;
aspect-ratio: 3 / 1;
border: 1px solid var(--border); border-radius: 10px;
background: var(--bg3);
margin-bottom: 1.1rem;
}
.wc-colors { display: flex; flex-wrap: wrap; gap: 1.2rem; margin-bottom: 1.2rem; }
.wc-color { display: flex; align-items: center; gap: .55rem; cursor: pointer; }
.wc-color > span {
font-family: var(--mono); font-size: .64rem;
letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.wc-color:hover > span { color: var(--text); }
/* Branding-Tab: Farb- und Datei-Inputs */
.color-pick {
width: 3.2rem; height: 2.4rem; flex: none;
padding: .2rem;
background: rgba(0, 0, 0, .35);
border: 1px solid rgba(255, 255, 255, .12);
border-radius: 8px;
cursor: pointer;
}
.field input[type="file"] {
width: 100%;
color: var(--muted);
font-family: var(--body);
font-size: .9rem;
}
.field input[type="file"]::file-selector-button {
font-family: var(--mono);
font-size: .68rem; letter-spacing: .15em; text-transform: uppercase;
color: var(--neon);
background: none;
border: 1px solid var(--border);
border-radius: 8px;
padding: .45rem 1rem;
margin-right: .8rem;
cursor: pointer;
transition: border-color .2s, background .2s;
}
.field input[type="file"]::file-selector-button:hover {
border-color: var(--neon);
background: rgba(245, 197, 24, .08);
}
/* Button-Farb-Auswahl im Rollen-Menü-Builder */
.btn-style-pick { width: 7.5rem !important; flex: none !important; }
/* ── BOT-IDENTITY-KARTE (MEE6-Style) ───────────────── */
.bot-card { display: flex; gap: 2rem; align-items: flex-start; }
.bot-card-left {
display: flex; flex-direction: column; gap: .6rem;
align-items: center; flex-shrink: 0;
}
.bot-avatar-wrap { position: relative; }
.bot-avatar {
width: 108px; height: 108px; border-radius: 50%;
border: 3px solid rgba(255, 255, 255, .1);
object-fit: cover; display: block;
background: #000;
}
.bot-avatar-empty {
display: flex; align-items: center; justify-content: center;
font-size: 2.5rem;
}
.bot-dot {
position: absolute; right: 4px; bottom: 4px;
width: 24px; height: 24px; border-radius: 50%;
border: 4px solid var(--bg2);
}
.btn-upload { justify-content: center; width: 100%; cursor: pointer; }
.bot-card-right { flex: 1; min-width: 0; }
@media (max-width: 640px) {
.bot-card { flex-direction: column; align-items: stretch; }
.bot-card-left { flex-direction: row; justify-content: flex-start; }
}
/* ── EVENTS ────────────────────────────────────────── */
.event-card { margin-bottom: 1.5rem; }
.event-cover {
width: 100%; max-height: 220px; object-fit: cover;
border-radius: 8px; margin-bottom: .9rem; display: block;
}
/* ── AKTIVITÄTS-CHART ──────────────────────────────── */
.act-chart {
display: flex; align-items: flex-end; gap: 3px;
height: 120px;
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .06);
border-radius: 12px;
padding: .8rem;
}
.act-bar {
flex: 1;
background: linear-gradient(180deg, var(--neon), rgba(245, 197, 24, .35));
border-radius: 3px 3px 0 0;
min-height: 4px;
transition: opacity .15s;
}
.act-bar:hover { opacity: .7; }
/* ── COMPOSER v2: Builder + Discord-Preview ────────── */
.composer-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
align-items: start;
}
@media (max-width: 900px) { .composer-grid { grid-template-columns: 1fr; } }
.composer-preview > label {
display: block;
font-family: var(--mono);
font-size: .68rem; letter-spacing: .15em; text-transform: uppercase;
color: var(--muted);
margin-bottom: .4rem;
}
/* Discord-Look (bewusst Discord-Farben, nicht Brand) */
.dpv {
background: #313338;
border-radius: 10px;
padding: 1rem;
font-family: 'gg sans', 'Noto Sans', sans-serif;
font-size: .95rem;
line-height: 1.35;
color: #dbdee1;
position: sticky;
top: 5rem;
}
.dpv-msg { display: flex; gap: .8rem; }
.dpv-avatar {
width: 40px; height: 40px; flex-shrink: 0;
border-radius: 50%;
background: #f5c518;
display: flex; align-items: center; justify-content: center;
font-size: 1.3rem;
}
.dpv-body { min-width: 0; flex: 1; }
.dpv-name { font-weight: 600; color: #f2f3f5; margin-bottom: .15rem; }
.dpv-tag {
background: #5865f2; color: #fff;
font-size: .6rem; font-weight: 700;
border-radius: 4px; padding: .05rem .3rem;
vertical-align: middle;
}
.dpv-time { font-size: .7rem; color: #949ba4; font-weight: 400; }
.dpv-content { white-space: pre-wrap; word-break: break-word; }
.dpv-content p, .dpv-desc p { margin: .15rem 0; }
.dpv-content .md-h, .dpv-desc .md-h {
font-family: inherit; text-transform: none; letter-spacing: 0;
font-size: 1.15rem; font-weight: 700; color: #f2f3f5; margin: .4rem 0 .1rem;
}
.dpv .md-list li::before { color: #dbdee1; }
.dpv .md-hr { background: #3f4147; }
.dpv code { background: #1e1f22; border: none; color: #dbdee1; }
.dpv-embed {
display: flex; gap: 1rem;
background: #2b2d31;
border-left: 4px solid #f5c518;
border-radius: 4px;
padding: .7rem .9rem .8rem;
margin-top: .35rem;
max-width: 520px;
}
.dpv-embed-main { min-width: 0; flex: 1; }
.dpv-author {
display: flex; align-items: center; gap: .5rem;
font-size: .82rem; font-weight: 600; color: #f2f3f5;
margin-bottom: .3rem;
}
.dpv-author img { width: 22px; height: 22px; border-radius: 50%; }
.dpv-title { font-weight: 700; color: #f2f3f5; margin-bottom: .3rem; }
.dpv-desc { font-size: .9rem; word-break: break-word; }
.dpv-fields { display: flex; flex-wrap: wrap; gap: .5rem 1rem; margin-top: .5rem; }
.dpv-field { flex: 0 0 100%; }
.dpv-field.inline { flex: 1 0 30%; min-width: 8rem; }
.dpv-field-name { font-size: .8rem; font-weight: 700; color: #f2f3f5; margin-bottom: .1rem; }
.dpv-field-value { font-size: .85rem; }
.dpv-image { max-width: 100%; border-radius: 6px; margin-top: .6rem; display: block; }
.dpv-thumb { width: 76px; height: 76px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
.dpv-footer { font-size: .72rem; color: #949ba4; margin-top: .55rem; }
/* ── GameSelect: stylebare Combobox für die Spiel-Auswahl ── */
.gamesel { position: relative; }
.gamesel input { width: 100%; padding-right: 1.8rem; }
.gamesel-caret {
position: absolute; right: .6rem; top: 50%; transform: translateY(-50%);
color: var(--muted); cursor: pointer; user-select: none; font-size: .8rem;
}
.gamesel-list {
position: absolute; z-index: 40; top: calc(100% + 4px); left: 0; min-width: 100%;
max-height: 16rem; overflow-y: auto;
background: var(--bg2); border: 1px solid var(--border); border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}
.gamesel-item {
display: flex; align-items: center; justify-content: space-between; gap: 1rem;
width: 100%; padding: .45rem .7rem; border: 0; background: none; cursor: pointer;
color: var(--text); font-family: var(--body); font-size: .95rem; text-align: left;
}
.gamesel-item:hover, .gamesel-item.active { background: var(--bg3); color: var(--neon); }
.gamesel-id { color: var(--muted2); font-family: var(--mono); font-size: .75rem; }
.gamesel-item:hover .gamesel-id { color: var(--muted); }
/* Durchsuchbare Kanal-/Rollen-Auswahl (ersetzt die nativen Dropdowns) */
.picksel { position: relative; max-width: 44rem; }
.picksel input {
width: 100%; padding-right: 2rem;
background: #0d0d0d; border: 1px solid var(--border); border-radius: 8px;
color: var(--text); font-family: var(--body); font-size: .95rem;
padding: .55rem .8rem; outline: none;
transition: border-color .2s;
}
.picksel input:focus { border-color: var(--neon); }
.picksel-caret {
position: absolute; right: .6rem; top: 50%; transform: translateY(-50%);
display: inline-flex; color: var(--muted2); cursor: pointer;
}
.picksel-caret:hover { color: var(--neon); }
.picksel-list {
position: absolute; z-index: 60; top: calc(100% + 4px); left: 0; right: 0;
max-height: 17rem; overflow-y: auto;
background: var(--bg2); border: 1px solid var(--border); border-radius: 8px;
box-shadow: 0 10px 28px rgba(0, 0, 0, .65);
}
.picksel-item {
display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
width: 100%; padding: .45rem .75rem; border: 0; background: none; cursor: pointer;
color: var(--text); font-family: var(--body); font-size: .93rem; text-align: left;
}
.picksel-item:hover, .picksel-item.active { background: var(--bg3); color: var(--neon); }
.picksel-label.muted { color: var(--muted2); font-style: italic; }
.picksel-hint { color: var(--muted2); font-family: var(--mono); font-size: .68rem; white-space: nowrap; }
.picksel-item:hover .picksel-hint { color: var(--muted); }
.picksel-none {
display: block; padding: .6rem .75rem;
color: var(--muted2); font-family: var(--mono); font-size: .7rem;
}
/* ── Member-Bereich: Gate-Banner, Profil, Web-Voting ── */
.gate-banner {
display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
margin: 1.2rem auto 0; max-width: 900px; padding: .8rem 1.1rem;
background: rgba(255, 77, 0, 0.08); border: 1px solid rgba(255, 77, 0, 0.4);
border-radius: 10px; font-family: var(--body);
}
.gate-banner span { flex: 1; min-width: 240px; }
.profile-card {
display: flex; gap: 1.4rem; align-items: flex-start;
background: var(--bg2); border: 1px solid var(--border); border-radius: 12px;
padding: 1.4rem; margin-bottom: 2rem;
}
.profile-avatar { width: 84px; height: 84px; border-radius: 50%; border: 2px solid var(--neon); }
.profile-name { font-family: var(--display); font-size: 2rem; letter-spacing: .05em; margin: 0; }
.profile-meta { color: var(--muted); margin: .2rem 0 0; font-family: var(--body); }
.profile-badge {
margin-left: .8rem; padding: .1rem .55rem; border-radius: 999px;
border: 1px solid var(--success); color: var(--success); font-size: .85rem;
}
.profile-roles { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .8rem; }
.role-chip {
padding: .15rem .6rem; border-radius: 999px; font-size: .85rem;
border: 1px solid var(--border); color: var(--text); font-family: var(--body);
}
.xp-bar { height: 12px; border-radius: 999px; background: var(--bg3); border: 1px solid var(--border); overflow: hidden; }
.xp-fill { height: 100%; background: linear-gradient(90deg, var(--neon), var(--neon2)); }
.alpha-key {
font-family: var(--mono); background: var(--bg3); border: 1px solid var(--border);
border-radius: 8px; padding: .5rem .8rem; letter-spacing: .08em;
}
.rolemenu-box { margin-bottom: 1.4rem; }
.rolemenu-title { font-family: var(--body); font-weight: 600; font-size: 1.1rem; margin: 0 0 .2rem; }
.rolemenu-buttons { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.rolemenu-btn.active { border-color: var(--neon); color: var(--neon); }
.wish-vote {
background: var(--bg3); border: 1px solid var(--border); border-radius: 999px;
color: var(--muted); font-family: var(--mono); padding: .25rem .7rem; cursor: pointer;
white-space: nowrap; transition: border-color .15s, color .15s;
}
.wish-vote:hover { border-color: var(--neon); color: var(--text); }
.wish-vote.voted { border-color: var(--neon); color: var(--neon); }
.wish-form { display: flex; gap: .6rem; margin-top: 1rem; }
.wish-form input { flex: 1; }
@media (max-width: 640px) {
.profile-card { flex-direction: column; align-items: center; text-align: center; }
.profile-roles { justify-content: center; }
.wish-form { flex-direction: column; }
}
/* ── NAV-DROPDOWNS + BURGER ────────────────────────── */
.nav-drop { position: relative; display: flex; align-items: center; }
.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;
line-height: 1.6; /* wie die Nav-Links, sonst hängt der Button tiefer */
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 ──────────────────────────────────────── */
/* z-index über Noise/Scanlines (900); rendert per Portal direkt in <body> */
.lightbox {
position: fixed; inset: 0; z-index: 1200;
display: flex; align-items: center; justify-content: center;
background: rgba(0, 0, 0, .95);
animation: lbIn .18s ease both;
}
@keyframes lbIn { from { opacity: 0; } to { opacity: 1; } }
.lb-row {
display: flex; align-items: center; gap: 1.2rem;
max-width: 96vw;
}
.lb-figure { display: flex; flex-direction: column; align-items: center; margin: 0; min-width: 0; }
.lb-img {
max-width: 100%; max-height: 78vh; object-fit: contain;
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 {
flex: none;
background: rgba(255, 255, 255, .04); 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, background .15s;
}
.lb-nav:hover { color: var(--neon); border-color: var(--neon); background: rgba(245, 197, 24, .08); }
.lb-meta {
display: flex; gap: 1.2rem; align-items: baseline;
font-family: var(--mono); font-size: .72rem; letter-spacing: .12em;
color: var(--muted); margin-top: .8rem; white-space: nowrap;
}
.lb-count { color: var(--neon); }
@media (max-width: 640px) {
.lb-row { gap: .5rem; }
.lb-nav { width: 2.4rem; height: 2.4rem; font-size: 1.4rem; }
}
/* ── 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-summary {
display: flex; gap: 2.5rem; flex-wrap: wrap;
background: var(--bg2); border: 1px solid var(--border); border-radius: 12px;
padding: 1.1rem 1.6rem; margin-bottom: 1.5rem;
}
.srv-sum-item { display: flex; flex-direction: column; }
.srv-sum-n {
font-family: var(--display); font-size: 2.2rem; line-height: 1;
color: var(--neon); text-shadow: 0 0 16px rgba(245, 197, 24, .3);
}
.srv-sum-of { font-size: 1.2rem; color: var(--muted2); text-shadow: none; }
.srv-sum-label {
font-family: var(--mono); font-size: .62rem; letter-spacing: .18em;
text-transform: uppercase; color: var(--muted); margin-top: .35rem;
}
.srv-grid { display: grid; grid-template-columns: 1fr; gap: 1.2rem; }
@media (min-width: 980px) { .srv-grid { grid-template-columns: 1fr 1fr; } }
.srv-card { margin-bottom: 0; }
.srv-card.srv-down { border-left: 3px solid rgba(242, 63, 67, .6); }
.srv-head { display: flex; align-items: center; gap: 1rem; }
.srv-logo {
width: 52px; height: 52px; flex: none;
border-radius: 12px; object-fit: cover;
border: 1px solid var(--border); background: var(--bg3);
}
.srv-logo-emoji { display: flex; align-items: center; justify-content: center; font-size: 1.7rem; }
.srv-title { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.srv-name { font-family: var(--display); font-size: 1.5rem; letter-spacing: .04em; line-height: 1.1; }
.srv-status { font-family: var(--mono); font-size: .72rem; letter-spacing: .08em; color: var(--muted); }
.srv-status.on { color: var(--success); }
.srv-status.off { color: #f23f43; }
.srv-ping, .srv-map { color: var(--muted2); }
.srv-count { font-family: var(--display); font-size: 1.9rem; line-height: 1; color: var(--neon); white-space: nowrap; }
.srv-count-max { font-size: 1.1rem; color: var(--muted2); }
.srv-bar { margin-top: .9rem; }
.srv-chart { width: 100%; height: 90px; margin-top: 1rem; display: block; }
.srv-stats {
display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
font-family: var(--mono); font-size: .62rem; letter-spacing: .15em;
text-transform: uppercase; color: var(--muted2); margin-top: .25rem;
}
.srv-stats b { color: var(--text); font-weight: 400; }
.srv-stats .up-good { color: var(--success); }
.srv-stats .up-bad { color: #f23f43; }
.srv-connect { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; margin-top: 1rem; }
.srv-addr { font-size: .8rem; cursor: pointer; transition: border-color .15s, color .15s; }
.srv-addr:hover { border-color: var(--neon); color: var(--neon); }
.srv-checked { font-family: var(--mono); font-size: .62rem; color: var(--muted2); margin-top: .8rem; }
/* ── AUDIT-LOG ─────────────────────────────────────── */
/* ── STATUS-DASHBOARD ──────────────────────────────── */
.dash-head {
display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
margin-bottom: 1.2rem;
}
.dash-avatar {
width: 42px; height: 42px; border-radius: 50%; flex: 0 0 auto;
border: 1px solid color-mix(in srgb, var(--neon) 35%, transparent);
}
.dash-avatar.leer {
display: grid; place-items: center;
background: rgba(255, 255, 255, .05); color: var(--muted);
}
.dash-ident { display: flex; flex-direction: column; gap: .35rem; }
.dash-name { font-weight: 700; font-size: 1rem; display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.dash-tag { font-family: var(--mono); font-size: .62rem; color: var(--muted2); letter-spacing: .06em; }
.dash-pill {
display: inline-flex; align-items: center; gap: .4rem; width: fit-content;
font-family: var(--mono); font-size: .58rem; letter-spacing: .14em; text-transform: uppercase;
padding: .16rem .5rem; border-radius: 999px;
border: 1px solid rgba(59, 165, 93, .45); color: #3ba55d;
}
.dash-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.dash-uptime {
margin-left: auto; font-family: var(--mono);
font-size: .64rem; letter-spacing: .08em; color: var(--muted2);
}
.dash-kpis { display: grid; gap: .7rem; grid-template-columns: repeat(4, 1fr); }
.dash-kpi { display: flex; flex-direction: column; gap: .15rem; padding: .9rem 1rem; min-width: 0; }
.dash-v { font-size: 1.55rem; font-weight: 700; line-height: 1.1; }
.dash-of { font-size: .85rem; color: var(--muted2); font-weight: 400; }
.dash-l {
font-family: var(--mono); font-size: .58rem; letter-spacing: .12em;
text-transform: uppercase; color: var(--muted);
}
/* Nebenzeile: min-height, damit Karten ohne Wert nicht kürzer werden */
.dash-t {
font-family: var(--mono); font-size: .6rem; letter-spacing: .04em;
color: var(--muted2); margin-top: .35rem; min-height: 1em;
}
.dash-t.gut { color: #3ba55d; }
.dash-t.warn { color: var(--neon2); }
.dash-spark {
display: flex; align-items: flex-end; gap: 2px;
height: 70px; margin-top: 1rem;
}
.dash-bar {
flex: 1; min-width: 2px; border-radius: 2px 2px 0 0;
background: linear-gradient(180deg, var(--neon), color-mix(in srgb, var(--neon) 15%, transparent));
}
.dash-bar:hover { background: var(--neon2); }
.dash-groups { display: flex; flex-direction: column; gap: .55rem; margin-top: 1rem; }
.dash-group {
display: flex; align-items: center; gap: .8rem;
background: none; border: none; padding: .25rem 0; cursor: pointer;
font-size: .82rem; color: var(--muted); text-align: left;
}
.dash-group:hover { color: var(--text); }
.dash-group-name { flex: 0 0 12rem; }
.dash-group-bar {
flex: 1; height: 5px; border-radius: 3px;
background: rgba(255, 255, 255, .07); overflow: hidden;
}
.dash-group-bar i { display: block; height: 100%; background: var(--neon); }
.dash-group-bar.warn i { background: var(--neon2); }
.dash-group-n {
font-family: var(--mono); font-size: .64rem; color: var(--muted2);
flex: 0 0 3rem; text-align: right;
}
@media (max-width: 820px) {
.dash-kpis { grid-template-columns: repeat(2, 1fr); }
.dash-uptime { margin-left: 0; width: 100%; }
.dash-group-name { flex-basis: 7rem; }
}
/* ── ÖFFENTLICHE STATUSSEITE ───────────────────────── */
.st-banner {
display: flex; align-items: center; gap: .8rem;
padding: 1rem 1.2rem; border-radius: 12px; margin-bottom: 2rem;
font-family: var(--mono); font-size: .8rem; letter-spacing: .1em;
text-transform: uppercase; border: 1px solid;
}
.st-banner.gut { border-color: rgba(59, 165, 93, .4); background: rgba(59, 165, 93, .07); color: #3ba55d; }
.st-banner.teil { border-color: color-mix(in srgb, var(--neon) 40%, transparent); background: color-mix(in srgb, var(--neon) 7%, transparent); color: var(--neon); }
.st-banner.aus { border-color: rgba(242, 63, 67, .45); background: rgba(242, 63, 67, .08); color: #f23f43; }
.st-banner.wartet, .st-banner.leer { border-color: var(--border); color: var(--muted); }
.st-row { padding: .9rem 1.1rem; margin-bottom: .7rem; min-width: 0; }
.st-head { display: flex; align-items: center; gap: .6rem; }
.st-name { font-weight: 600; font-size: .92rem; }
.st-state {
margin-left: auto; font-family: var(--mono);
font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted2);
}
.st-servers { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); }
.st-server { display: flex; align-items: center; gap: .6rem; padding: .75rem .9rem; min-width: 0; }
.st-server-icon { font-size: 1.1rem; }
.st-incidents { display: flex; flex-direction: column; }
.st-incident {
display: flex; align-items: center; gap: 1rem;
padding: .6rem .2rem; font-size: .84rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.st-incident:last-child { border-bottom: none; }
.st-incident.offen .st-inc-dur { color: #f23f43; }
.st-inc-name { font-weight: 600; min-width: 9rem; }
.st-inc-time { font-family: var(--mono); font-size: .66rem; color: var(--muted2); }
.st-inc-dur { margin-left: auto; font-family: var(--mono); font-size: .68rem; color: var(--muted); }
@media (max-width: 620px) {
.st-inc-name { min-width: 0; }
}
/* ── WATCHDOG-ÜBERSICHT ────────────────────────────── */
.wd-card { padding: .9rem 1.1rem; margin-bottom: .7rem; min-width: 0; }
.wd-head { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.wd-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.wd-dot.an { background: var(--success, #3ba55d); }
.wd-dot.aus { background: #f23f43; }
.wd-dot.wartet { background: var(--muted2); }
.wd-url {
font-family: var(--mono); font-size: .74rem;
color: var(--text); text-decoration: none;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.wd-url:hover { color: var(--neon); }
.wd-meta {
margin-left: auto; font-family: var(--mono);
font-size: .62rem; letter-spacing: .06em; color: var(--muted2); white-space: nowrap;
}
/* ── ERREICHBARKEITS-BALKEN ────────────────────────── */
/* Ein Strich pro Stunde, 168 Stück. Auf schmalen Schirmen werden die Striche
dünner als ein Pixel — deshalb scrollt der Balken dort lieber, statt zu
Matsch zu verschmelzen. */
/* Ohne das sprengt der Balken auf schmalen Schirmen die ganze Karte: Grid-Items
haben min-width:auto und schrumpfen nicht unter ihren Inhalt — 168 Striche à
3 px sind rund 840 px, und die Karte wuchs auf 724 statt 335 px. */
.srv-card { min-width: 0; }
.up-track-wrap { margin-top: .9rem; min-width: 0; }
.up-track {
display: flex; gap: 1px; align-items: stretch;
height: 30px; overflow-x: auto; overflow-y: hidden;
scrollbar-width: none;
}
.up-track::-webkit-scrollbar { display: none; }
.up-tick {
flex: 1 0 3px; min-width: 3px; border-radius: 1px;
background: var(--success, #3ba55d);
transition: transform .1s ease;
}
.up-tick:hover { transform: scaleY(1.15); }
.up-tick.teil { background: var(--neon); }
.up-tick.aus { background: #f23f43; }
/* Keine Messung ist kein „läuft" — deshalb sichtbar leer statt grün */
.up-tick.leer { background: rgba(255, 255, 255, .07); }
.up-track-foot {
display: flex; justify-content: space-between; align-items: baseline;
font-family: var(--mono); font-size: .62rem; letter-spacing: .08em;
color: var(--muted2); margin-top: .45rem;
}
.up-track-foot .up-good { color: var(--success, #3ba55d); }
.up-track-foot .up-bad { color: #f23f43; }
/* ── SPRACHUMSCHALTER ──────────────────────────────── */
.lang-switch {
display: inline-flex;
border: 1px solid rgba(255, 255, 255, .1);
border-radius: 999px;
overflow: hidden;
margin-right: .6rem;
}
.lang-btn {
font-family: var(--mono);
font-size: .62rem; letter-spacing: .12em;
padding: .3rem .55rem;
background: transparent; border: none;
color: var(--muted2); cursor: pointer;
transition: color .15s ease, background .15s ease;
}
.lang-btn:hover { color: var(--text); }
.lang-btn.on {
background: color-mix(in srgb, var(--neon) 14%, transparent);
color: var(--neon);
}
/* Im Schubladen-Menü steht er allein in einer Zeile */
.drawer-lang { padding: .6rem 0 0; }
.drawer-lang .lang-switch { margin-right: 0; }
.drawer-lang .lang-btn { padding: .4rem .8rem; font-size: .7rem; }
/* ── TEAM & PROTOKOLL ──────────────────────────────── */
.tm-list {
display: flex; flex-direction: column;
border: 1px solid rgba(255, 255, 255, .07);
border-radius: 12px; overflow: hidden;
margin-bottom: 1.6rem;
}
.tm-row {
display: flex; align-items: center; gap: .9rem;
padding: .7rem .9rem;
border-bottom: 1px solid rgba(255, 255, 255, .05);
font-size: .9rem;
transition: background .15s ease;
}
.tm-row:last-child { border-bottom: none; }
.tm-row:hover { background: rgba(255, 255, 255, .02); }
/* Tönungen aus der Leitfarbe mischen — die ist auf der Bot-Seite orange,
im Hub gold, und beides soll stimmen. */
.tm-row.owner { background: color-mix(in srgb, var(--neon) 5%, transparent); }
.tm-row.aktiv {
background: color-mix(in srgb, var(--neon) 9%, transparent);
box-shadow: inset 3px 0 0 var(--neon);
}
.tm-row.leer {
justify-content: center; color: var(--muted2);
font-family: var(--mono); font-size: .72rem; letter-spacing: .1em;
padding: 1.4rem;
}
.tm-avatar {
width: 34px; height: 34px; border-radius: 50%;
flex: 0 0 auto; object-fit: cover;
border: 1px solid rgba(255, 255, 255, .12);
}
.tm-avatar.klein { width: 24px; height: 24px; }
.tm-avatar.ohne {
display: grid; place-items: center;
background: rgba(255, 255, 255, .05);
color: var(--muted); font-weight: 700; font-size: .85rem;
}
.tm-avatar.klein.ohne { font-size: .65rem; }
.tm-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.tm-name { font-weight: 600; }
.tm-scopes { display: flex; flex-wrap: wrap; gap: .3rem; }
.tm-chip {
font-family: var(--mono); font-size: .6rem; letter-spacing: .08em;
padding: .18rem .45rem; border-radius: 999px;
border: 1px solid rgba(255, 255, 255, .12);
color: var(--muted); white-space: nowrap;
}
.tm-chip.alle {
border-color: color-mix(in srgb, var(--neon) 40%, transparent);
color: var(--neon);
}
.tm-role {
font-family: var(--mono); font-size: .62rem; letter-spacing: .14em;
color: var(--neon); text-transform: uppercase;
}
.tm-form-title {
font-family: var(--mono); font-size: .75rem; letter-spacing: .16em;
text-transform: uppercase; color: var(--muted);
margin: 0 0 1rem;
}
.tm-scopes-pick {
display: grid; gap: .5rem;
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.tm-scope {
display: flex; align-items: center; gap: .6rem; text-align: left;
padding: .6rem .7rem;
background: rgba(0, 0, 0, .25);
border: 1px solid rgba(255, 255, 255, .09);
border-radius: 10px; color: var(--muted);
cursor: pointer; transition: all .15s ease;
}
.tm-scope:hover { border-color: rgba(255, 255, 255, .22); color: var(--text); }
.tm-scope.on {
border-color: var(--neon);
background: color-mix(in srgb, var(--neon) 8%, transparent);
color: var(--text);
}
.tm-scope-mark {
width: 18px; height: 18px; flex: 0 0 auto;
display: grid; place-items: center;
border: 1px solid rgba(255, 255, 255, .2); border-radius: 5px;
font-size: .7rem; color: #0a0a0a;
}
.tm-scope.on .tm-scope-mark { background: var(--neon); border-color: var(--neon); }
.tm-scope-text { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.tm-scope-id {
font-family: var(--mono); font-size: .68rem; letter-spacing: .1em;
color: inherit;
}
.tm-scope-desc { font-size: .72rem; color: var(--muted2); }
.tm-row.audit { font-size: .82rem; padding: .5rem .9rem; }
.tm-audit-name { font-weight: 600; min-width: 7rem; }
.tm-audit-action {
font-family: var(--mono); font-size: .68rem; letter-spacing: .06em;
color: var(--neon); white-space: nowrap; min-width: 9rem;
}
.tm-audit-detail {
flex: 1; min-width: 0; color: var(--muted);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tm-audit-time {
font-family: var(--mono); font-size: .62rem;
color: var(--muted2); white-space: nowrap;
}
@media (max-width: 700px) {
.tm-audit-action { min-width: 0; }
.tm-audit-detail { display: none; }
}
/* ── STARTSEITE ────────────────────────────────────── */
.home-hero { min-height: 420px; }
.home-accent { color: var(--neon2); }
.home-cta { display: flex; gap: .9rem; flex-wrap: wrap; margin-top: 1.6rem; }
.home-cta-alt { border: 1px solid var(--border); }
.home-stats { margin-bottom: 1.5rem; }
.home-tiles {
display: grid; gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.home-tile {
display: flex; flex-direction: column; gap: .3rem;
padding: 1.3rem 1.4rem;
}
.home-tile-icon { font-size: 1.6rem; line-height: 1; margin-bottom: .3rem; }
.home-tile-title {
font-family: var(--display); font-size: 1.4rem; letter-spacing: .05em;
color: var(--text); transition: color .2s;
}
.home-tile:hover .home-tile-title { color: var(--neon); }
.home-tile-desc { font-weight: 300; color: var(--muted); font-size: .95rem; line-height: 1.4; }
.home-devlog { display: block; }
.home-devlog-more {
display: inline-block; margin-top: .8rem;
font-family: var(--mono); font-size: .7rem; letter-spacing: .2em;
text-transform: uppercase; color: var(--neon);
}
/* Permalink-Icon an der Devlog-Karte */
.card-permalink {
font-size: .8rem; opacity: .35; transition: opacity .15s;
text-decoration: none;
}
.card-permalink:hover { opacity: 1; }
/* ── RECHTSTEXTE (Impressum / Datenschutz) ─────────── */
.legal-text { max-width: 780px; }
.legal-text .settings-title { margin-top: 2.2rem; }
.legal-text .settings-title:first-of-type { margin-top: 0; }
.legal-text p {
color: var(--muted); font-weight: 300; line-height: 1.75;
margin-bottom: 1rem;
}
.legal-text strong { color: var(--text); font-weight: 600; }
.legal-text a { color: var(--neon); border-bottom: 1px solid rgba(245, 197, 24, .3); }
.legal-text a:hover { border-bottom-color: var(--neon); }
.legal-text code {
font-family: var(--mono); font-size: .85em;
background: var(--bg3); border: 1px solid var(--border);
border-radius: 4px; padding: .05rem .35rem; color: var(--text);
}
.legal-list { list-style: none; margin: 0 0 1rem; padding: 0; }
.legal-list li {
position: relative; padding-left: 1.4rem; margin-bottom: .7rem;
color: var(--muted); font-weight: 300; line-height: 1.7;
}
.legal-list li::before {
content: '▸'; position: absolute; left: 0; color: var(--neon2);
}
/* Lösch-Bereich im Profil */
.danger-zone {
border: 1px solid rgba(242, 63, 67, .25);
border-radius: 12px; padding: 1.2rem 1.4rem;
background: rgba(242, 63, 67, .03);
}
.danger-zone .settings-title { color: #f23f43; }
.danger-zone .settings-title::after {
background: linear-gradient(90deg, rgba(242, 63, 67, .35), transparent);
}
.btn-danger { border-color: rgba(242, 63, 67, .5); color: #f23f43; }
.btn-danger:hover { border-color: #f23f43; background: rgba(242, 63, 67, .1); }
.home-tile-ext { font-size: .8rem; color: var(--muted2); }
/* ── ICONS (Lucide) ────────────────────────────────── */
/* Einheitliche Ausrichtung: Icons sitzen auf der Textlinie, erben die Farbe */
.ic {
display: inline-block;
vertical-align: -0.18em;
flex-shrink: 0;
}
/* Text + Icon nebeneinander, ohne Zeilenumbruch dazwischen */
.with-icon {
display: inline-flex;
align-items: center;
gap: .45rem;
}
button.with-icon, a.with-icon { justify-content: center; }
/* Nav-Pfeil des Dropdowns */
.nav-caret { transition: transform .2s; }
.nav-drop.open .nav-caret { transform: rotate(180deg); }
/* Setup-Sidebar: Icons in Markenfarbe, aktiver Tab hebt sich ab */
.settings-nav-icon { display: inline-flex; color: var(--muted); transition: color .2s; }
.settings-nav-item:hover .settings-nav-icon { color: var(--text); }
.settings-nav-item.active .settings-nav-icon { color: var(--neon); }
/* Kachel-Icons auf der Startseite */
.home-tile-icon { color: var(--neon); display: inline-flex; }
.home-tile:hover .home-tile-icon { color: var(--neon2); }
.home-tile-emoji { font-size: 1.6rem; line-height: 1; }
.home-tile-ext { color: var(--muted2); }
/* Server-Status: Punkt statt Emoji */
.srv-status { flex-wrap: wrap; row-gap: .1rem; }
.srv-status > span { white-space: nowrap; }
.srv-dot {
width: 8px; height: 8px; border-radius: 50%;
background: var(--muted2); display: inline-block; flex-shrink: 0;
}
.srv-status.on .srv-dot { background: var(--success); box-shadow: 0 0 8px #00ff8866; }
.srv-status.off .srv-dot { background: #f23f43; box-shadow: 0 0 8px #f23f4366; }
.srv-status { display: inline-flex; align-items: center; gap: .4rem; }
.srv-map, .srv-ping { display: inline-flex; align-items: center; gap: .3rem; }
/* Bestenliste: Pokal statt Medaillen-Emoji */
/* Bot-Avatar-Platzhalter */
.bot-avatar-empty { display: flex; align-items: center; justify-content: center; color: var(--muted); }
/* Discord-Vorschau im Composer */
.dpv-avatar { display: flex; align-items: center; justify-content: center; color: var(--muted); }
/* Vorschau im Seiten-Editor */
.page-preview {
max-height: 26rem; overflow-y: auto;
background: var(--bg2);
}
/* ── BOT-PRODUKTSEITE ──────────────────────────────── */
/* Gleiche Marke, aber Orange als Leitfarbe — beim Domainwechsel sofort erkennbar */
.site-bot {
--neon: #ff4d00;
--neon2: #f5c518;
--border: rgba(255, 77, 0, 0.15);
}
.site-bot .page-bg-text { color: rgba(255, 77, 0, .045); }
.site-bot .page-header-grid {
background-image:
linear-gradient(rgba(255, 77, 0, .12) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 77, 0, .12) 1px, transparent 1px);
}
.site-bot .particle { background: #ff4d00; }
.bot-hero { min-height: 460px; }
/* Funktionsliste der Produktseite */
.feature-group { margin-bottom: 2.6rem; }
.feature-grid {
display: grid; gap: .8rem;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
margin-top: 1.1rem;
}
.feature-card {
display: flex; gap: .9rem; align-items: flex-start;
padding: 1.1rem 1.2rem;
transition: border-color .2s, transform .2s;
}
.feature-card:hover { border-color: var(--neon); transform: translateY(-2px); }
.feature-icon {
flex: none; display: inline-flex;
color: var(--neon); margin-top: .15rem;
}
.feature-name {
display: block;
font-family: var(--display); font-size: 1.1rem;
letter-spacing: .04em; color: var(--text);
margin-bottom: .3rem;
}
.feature-desc {
color: var(--muted); font-weight: 300;
font-size: .92rem; line-height: 1.5; margin: 0;
}
.feature-outro {
border-top: 1px solid var(--border);
padding-top: 1.8rem; margin-top: .5rem;
}
.feature-outro p {
color: var(--muted); font-weight: 300;
line-height: 1.7; max-width: 46rem; margin: 0 0 1.4rem;
}
/* Befehlsliste */
.cmd-list { display: flex; flex-direction: column; gap: .5rem; }
.cmd-row {
display: flex; gap: 1.2rem; align-items: baseline; flex-wrap: wrap;
background: var(--bg2); border: 1px solid rgba(255, 255, 255, .06);
border-radius: 10px; padding: .7rem 1rem;
transition: border-color .2s, background .2s;
}
.cmd-row:hover { border-color: var(--border); background: var(--bg3); }
.cmd-name {
font-family: var(--mono); font-size: .82rem; color: var(--neon);
white-space: nowrap; flex: none; min-width: 15rem;
}
.cmd-desc { color: var(--muted); font-weight: 300; flex: 1; min-width: 15rem; }
@media (max-width: 640px) {
.cmd-name { min-width: 0; }
}
/* ── MODUL-KARTEN ──────────────────────────────────── */
.mod-grid {
display: grid; gap: .9rem;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
/* Filter über dem Raster */
.mod-filters { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1.2rem; }
.mod-filter {
display: inline-flex; align-items: center; gap: .45rem;
font-family: var(--mono); font-size: .62rem;
letter-spacing: .12em; text-transform: uppercase;
color: var(--muted); background: var(--bg2);
border: 1px solid var(--border); border-radius: 99px;
padding: .35rem .8rem; cursor: pointer;
transition: color .15s, border-color .15s, background .15s;
}
.mod-filter:hover:not(:disabled) { color: var(--text); border-color: var(--neon); }
.mod-filter.active { color: #0a0a0a; background: var(--neon); border-color: var(--neon); }
.mod-filter:disabled { opacity: .3; cursor: default; }
.mod-filter-n {
font-size: .58rem; opacity: .7;
padding-left: .35rem; border-left: 1px solid currentColor;
}
.mod-card {
display: flex; flex-direction: column; gap: .6rem;
padding: 1.1rem 1.2rem; opacity: .55;
transition: opacity .2s, border-color .2s, transform .2s;
}
.mod-card.on { opacity: 1; }
.mod-card:hover { border-color: var(--neon); transform: translateY(-2px); }
.mod-head { display: flex; align-items: flex-start; gap: .8rem; }
/* Symbol-Kachel wie auf der Funktionsseite — macht die Karten unterscheidbar */
.mod-icon {
flex: none; display: inline-flex; align-items: center; justify-content: center;
width: 2.4rem; height: 2.4rem; border-radius: 9px;
background: var(--bg3); border: 1px solid var(--border);
color: var(--muted2);
transition: color .2s, border-color .2s;
}
.mod-card.on .mod-icon { color: var(--neon); border-color: rgba(245, 197, 24, .3); }
.mod-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.mod-name {
font-family: var(--display); font-size: 1.15rem;
letter-spacing: .04em; color: var(--text);
}
.mod-group {
font-family: var(--mono); font-size: .55rem;
letter-spacing: .16em; text-transform: uppercase; color: var(--muted2);
}
.mod-desc { color: var(--muted); font-weight: 300; font-size: .93rem; line-height: 1.45; flex: 1; }
.mod-foot {
display: flex; align-items: center; justify-content: space-between;
gap: .8rem; flex-wrap: wrap;
padding-top: .2rem;
}
.mod-missing, .mod-ready, .mod-off {
font-family: var(--mono); font-size: .62rem;
letter-spacing: .1em; text-transform: uppercase;
}
.mod-missing { color: var(--neon2); }
.mod-ready { color: var(--success); }
.mod-off { color: var(--muted2); }
.mod-link {
background: none; border: 0; padding: 0; margin-left: auto;
font-family: var(--mono); font-size: .62rem; letter-spacing: .15em;
text-transform: uppercase; color: var(--muted2); cursor: pointer;
white-space: nowrap;
transition: color .15s;
}
.mod-link:hover { color: var(--neon); }
/* Schiebeschalter */
.mod-switch {
flex: none; width: 42px; height: 24px; border-radius: 999px;
background: var(--bg3); border: 1px solid var(--border);
position: relative; cursor: pointer; padding: 0;
transition: background .2s, border-color .2s;
}
.mod-switch.on { background: var(--neon); border-color: var(--neon); }
.mod-knob {
position: absolute; top: 2px; left: 2px;
width: 18px; height: 18px; border-radius: 50%;
background: var(--muted2); transition: transform .2s, background .2s;
}
.mod-switch.on .mod-knob { transform: translateX(18px); background: #0a0a0a; }
.mod-switch:hover { border-color: var(--neon); }
/* ── TEXT-VORLAGEN ─────────────────────────────────── */
/* Vorlagen als Liste zum Aufklappen — 27 offene Felder auf einmal erschlagen.
Zugeklappt sieht man Namen und erste Zeile, das reicht zum Wiederfinden. */
.tpl-list {
display: flex; flex-direction: column;
border: 1px solid rgba(255, 255, 255, .06);
border-radius: 10px; overflow: hidden;
}
.tpl-row { border-bottom: 1px solid rgba(255, 255, 255, .06); }
.tpl-row:last-child { border-bottom: 0; }
.tpl-row.open { background: rgba(255, 255, 255, .015); }
.tpl-row.dirty { box-shadow: inset 2px 0 0 var(--neon); }
.tpl-head {
display: flex; align-items: center; gap: .7rem;
width: 100%; text-align: left;
background: none; border: 0;
padding: .7rem 1rem;
cursor: pointer;
transition: background .15s;
}
.tpl-head:hover { background: rgba(255, 255, 255, .03); }
.tpl-head-main {
flex: 1; min-width: 0;
display: flex; align-items: baseline; gap: .8rem;
}
.tpl-name {
font-family: var(--display); font-size: 1.02rem;
letter-spacing: .04em; color: var(--text);
white-space: nowrap;
}
/* Erste Zeile des aktuellen Texts als Vorschau */
.tpl-peek {
flex: 1; min-width: 0;
font-family: var(--mono); font-size: .74rem;
color: var(--muted2);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tpl-row.open .tpl-peek { opacity: 0; }
.tpl-caret { color: var(--muted2); flex: none; transition: transform .2s; }
.tpl-caret.up { transform: rotate(180deg); color: var(--neon); }
.tpl-body {
display: flex; flex-direction: column; gap: .7rem;
padding: 0 1rem 1rem;
animation: riseIn .2s ease both;
}
.tpl-vars-label {
font-family: var(--mono); font-size: .6rem;
letter-spacing: .15em; text-transform: uppercase;
color: var(--muted2); align-self: center; margin-right: .2rem;
}
.tpl-badge {
font-family: var(--mono); font-size: .55rem;
letter-spacing: .12em; text-transform: uppercase;
color: var(--neon); border: 1px solid var(--neon);
border-radius: 4px; padding: .1rem .4rem;
}
.tpl-badge.muted { color: var(--muted2); border-color: var(--border); }
.tpl-input {
width: 100%; max-width: 62rem; resize: vertical;
font-family: var(--mono); font-size: .84rem; line-height: 1.6;
color: var(--text); background: #0d0d0d;
border: 1px solid var(--border); border-radius: 5px;
padding: .7rem .8rem;
}
.tpl-input:focus { outline: none; border-color: var(--neon); }
.tpl-vars { display: flex; flex-wrap: wrap; gap: .35rem; }
.tpl-var {
font-family: var(--mono); font-size: .6rem; letter-spacing: .05em;
color: var(--muted); background: var(--bg3);
border: 1px solid var(--border); border-radius: 4px;
padding: .18rem .45rem; cursor: pointer;
transition: color .15s, border-color .15s;
}
.tpl-var:hover { color: var(--neon); border-color: var(--neon); }
.tpl-actions { display: flex; gap: .5rem; align-items: center; }
.tpl-actions .btn { font-size: .6rem; padding: .4rem .9rem; }
@media (max-width: 720px) {
/* Schmal ist für die Vorschau kein Platz mehr — Name und Marken reichen */
.tpl-peek { display: none; }
}
/* ── DEVLOG-FILTER ─────────────────────────────────── */
/* Gleiche Form wie die Modul-Filter — beides sind Chips zum Einschränken */
.dl-filters { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .9rem; }
.dl-filter {
display: inline-flex; align-items: center; gap: .45rem;
font-family: var(--mono); font-size: .62rem;
letter-spacing: .12em; text-transform: uppercase;
color: var(--muted); background: var(--bg2);
border: 1px solid var(--border); border-radius: 99px;
padding: .35rem .8rem; cursor: pointer;
transition: color .15s, border-color .15s, background .15s;
}
.dl-filter:hover { color: var(--text); border-color: var(--neon); }
.dl-filter.active { color: #0a0a0a; background: var(--neon); border-color: var(--neon); }
.dl-filter-n {
font-size: .58rem; opacity: .7;
padding-left: .35rem; border-left: 1px solid currentColor;
}
/* ── LEERE BEREICHE ────────────────────────────────── */
/* Vorher stand hier ein einzelner Satz in einer sonst leeren Seite —
das sah nach Fehler aus statt nach „noch nichts da". */
.empty-state {
display: flex; flex-direction: column; align-items: center; text-align: center;
gap: .6rem;
padding: 3.5rem 1.5rem;
border: 1px dashed var(--border); border-radius: 14px;
background: rgba(255, 255, 255, .012);
}
.empty-icon {
display: inline-flex; align-items: center; justify-content: center;
width: 3.6rem; height: 3.6rem; border-radius: 50%;
background: var(--bg3); border: 1px solid var(--border);
color: var(--muted2);
margin-bottom: .3rem;
}
.empty-title {
font-family: var(--display); font-size: 1.5rem;
letter-spacing: .04em; color: var(--text); margin: 0;
}
.empty-text {
color: var(--muted); font-weight: 300;
line-height: 1.6; max-width: 34rem; margin: 0;
}
.empty-actions { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin-top: .8rem; }
/* ── SPEICHERN-LEISTE ──────────────────────────────── */
/* Klebt am unteren Rand, sobald etwas offen ist. Vorher stand der Knopf am
Seitenende — bei den zweispaltigen Bereichen sah man ihn oft gar nicht. */
.save-bar {
position: sticky; bottom: 1.2rem; z-index: 300;
display: flex; align-items: center; gap: 1rem;
width: fit-content; max-width: 100%;
margin: -3.5rem auto 0;
padding: .7rem .9rem .7rem 1.3rem;
background: rgba(18, 18, 18, .96);
border: 1px solid var(--neon);
border-radius: 99px;
box-shadow: 0 10px 30px rgba(0, 0, 0, .55), 0 0 20px rgba(245, 197, 24, .12);
animation: riseIn .25s ease both;
}
.save-bar-text {
font-family: var(--mono); font-size: .68rem;
letter-spacing: .12em; text-transform: uppercase;
color: var(--neon); white-space: nowrap;
}
.save-bar .btn { padding: .45rem 1.1rem; font-size: .62rem; }
@media (max-width: 640px) {
.save-bar { gap: .5rem; padding: .6rem .6rem .6rem .9rem; }
.save-bar-text { font-size: .6rem; letter-spacing: .08em; }
}
/* ── NACH OBEN ─────────────────────────────────────── */
.to-top {
position: fixed; right: 1.5rem; bottom: 1.5rem; z-index: 400;
display: inline-flex; align-items: center; justify-content: center;
width: 2.8rem; height: 2.8rem; border-radius: 50%;
background: var(--bg2); border: 1px solid var(--border);
color: var(--muted); cursor: pointer;
transition: color .2s, border-color .2s, opacity .25s, transform .25s;
}
.to-top:hover { color: var(--neon); border-color: var(--neon); }
@media (max-width: 640px) {
.to-top { right: 1rem; bottom: 1rem; }
}
/* ── STELLWERTE ────────────────────────────────────── */
.tune-list {
display: flex; flex-direction: column;
border: 1px solid rgba(255, 255, 255, .06);
border-radius: 10px; overflow: hidden;
}
.tune-row {
display: flex; align-items: center; gap: 1.5rem;
justify-content: space-between; flex-wrap: wrap;
padding: .75rem 1rem;
border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.tune-row:last-child { border-bottom: 0; }
.tune-row.dirty { box-shadow: inset 2px 0 0 var(--neon); }
.tune-label { display: flex; flex-direction: column; gap: .15rem; min-width: 14rem; flex: 1; }
.tune-name {
display: flex; align-items: center; gap: .5rem;
color: var(--text); font-size: .95rem;
}
.tune-hint { color: var(--muted2); font-weight: 300; font-size: .82rem; line-height: 1.4; }
.tune-input { display: flex; align-items: center; gap: .6rem; flex: none; }
.tune-input input, .tune-input select {
width: 6rem; text-align: right;
font-family: var(--mono); font-size: .85rem;
color: var(--text); background: #0d0d0d;
border: 1px solid var(--border); border-radius: 5px;
padding: .4rem .55rem;
}
.tune-input select { text-align: left; }
.tune-input input:focus, .tune-input select:focus { outline: none; border-color: var(--neon); }
.tune-unit {
font-family: var(--mono); font-size: .64rem;
letter-spacing: .12em; text-transform: uppercase;
color: var(--muted); min-width: 6.5rem;
}
.tune-range {
font-family: var(--mono); font-size: .6rem;
letter-spacing: .06em; color: var(--muted2); min-width: 9rem;
}
@media (max-width: 720px) {
.tune-row { gap: .6rem; }
.tune-range { display: none; }
}