Files
d4rkbot/frontend/src/style.css
T
D4rkst3r dbec4e9775 Panel: die volle Fernbedienung ueber der Senderliste
Was laeuft, wo, aus welcher Quelle, mit Fortschrittsbalken. Sprachkanal
waehlen, Sender abspielen, Ueberspringen, Zum Radio, Stopp,
Lautstaerke-Schieber. Einreihen per Link oder Suchbegriff, Warteschlange
mit Hoch/Runter/Weg und Leeren. Darunter ein aufklappbarer yt-dlp-Block:
Zustand, Fassung, cookies.txt, eigene Argumente, Aktualisieren -- und die
letzte Fehlerzeile im Klartext.

Steht ueber der Senderliste, weil man oefter etwas abspielt als die Liste
pflegt.

Die Abfrage laeuft nur, solange der Community-Reiter offen ist. Sonst
ginge alle fuenf Sekunden eine Anfrage gegen eine Ansicht raus, die
niemand ansieht.

Der Balken erscheint nur bei bekannter Dauer. Bei einem Livestream gaebe
er einen Stand vor, den niemand kennt -- dort steht stattdessen "live".

Die Kanalauswahl graut aus, wo der Bot nicht rein darf. Ein Kanal, den das
Panel anbietet und in den der Bot dann nicht kommt, sieht aus wie ein
kaputter Knopf.

Geprueft: der Vite-Build laeuft durch, und ein Abgleich stellt alle 30
Feldpfade, die die Oberflaeche vom Stand liest, gegen die echte
API-Antwort -- 0 fehlen. Der Abgleich hat eine Gegenprobe mit bekanntem
Ausgang (ein Feld, das es nicht gibt, muss als fehlend erkannt werden) und
prueft vorher, ob die sonst leeren Zweige (Warteschlange, Cookies, letzter
Fehler) ueberhaupt besetzt sind -- sonst meldet er "ungueltig" statt "in
Ordnung". Seine erste Fassung hatte Fehlalarm geschlagen (?. und .map als
fehlende Felder gelesen); das ist behoben.

NICHT geprueft: das tatsaechliche Rendern im Browser -- hier ist weder
Browser noch DOM-Werkzeug vorhanden.
2026-08-28 13:50:06 +02:00

3308 lines
130 KiB
CSS

/* ═══════════════════════════════════════════════════
D4RKST3R — Styles (Graphit + Orange)
Ein Stylesheet für beide Auftritte: Bot-Produktseite und Community-Hub.
═══════════════════════════════════════════════════ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #131316; /* Seiten-Hintergrund */
--bg2: #1b1b20; /* Karten und Panels */
--bg3: #1f1f25; /* Hover-Fläche, erhöht */
--text: #ececee;
--text2: #c9c9cf;
--muted: #9a9aa3;
--muted2: #66666e;
--border: rgba(255, 255, 255, .08);
--accent: #ff9a1f; /* Orange, Einzelakzent (Ränder, Punkte) */
--accent-hi: #ffb340; /* helles Orange — Text, Symbole, Verlaufsanfang */
--accent-lo: #f07800; /* dunkles Orange — Verlaufsende */
--grad: linear-gradient(135deg, #ffb340, #f07800);
--success: #3ba55d;
--danger: #f23f43;
--display: 'Chakra Petch', sans-serif;
--body: 'Chakra Petch', sans-serif;
--mono: 'IBM Plex Mono', ui-monospace, monospace;
}
html { scroll-behavior: smooth; color-scheme: dark; }
body {
background: var(--bg);
color: var(--text);
font-family: var(--body);
font-size: 16px;
line-height: 1.55;
overflow-x: hidden;
min-height: 100vh;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
::selection { background: rgba(255, 154, 31, .35); color: var(--bg); }
:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
/* Dunkle Scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: #2a2a31; border: 2px solid var(--bg); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent); }
@keyframes riseIn {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: none; }
}
@keyframes pulseGlow {
0%, 100% { opacity: .5; }
50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
}
/* ── ABGESCHRÄGTE ECKEN ────────────────────────────────
Kern des Looks: statt Rundungen wird oben links und unten rechts eine
Ecke gekappt. Die Tiefe steuert --bv, damit jede Komponente nur eine
Zahl setzt statt das ganze Polygon zu wiederholen.
Achtung: clip-path schneidet auch Kinder ab. Behälter, aus denen etwas
herausragen darf (offene Auswahllisten in der Config), bekommen deshalb
bewusst keine Abschrägung. */
.bevel,
.card, .home-tile, .feature-card, .cmd-row, .mod-card, .srv-summary,
.hero-panel, .hero-frame, .hero-stat, .page-tag, .btn, .btn-login,
.home-tile-icon, .feature-icon, .mod-icon, .modpage-icon,
.dash-panel, .dash-kpi, .status-pill, .empty-state,
.settings-search, .search, .st-banner, .gate-banner, .profile-card {
clip-path: polygon(
var(--bv, 10px) 0,
100% 0,
100% calc(100% - var(--bv, 10px)),
calc(100% - var(--bv, 10px)) 100%,
0 100%,
0 var(--bv, 10px)
);
}
.app { min-height: 100vh; display: flex; flex-direction: column; position: relative; z-index: 2; }
/* Warmer Schein von oben rechts — ersetzt Raster, Rauschen und Hintergrundtext */
.app::before {
content: '';
position: fixed; inset: 0; z-index: -1;
pointer-events: none;
background:
radial-gradient(900px 500px at 78% -10%, rgba(240, 120, 0, .14), transparent 60%),
radial-gradient(700px 420px at 5% 110%, rgba(255, 179, 64, .06), transparent 60%);
}
/* Verlaufs-Text für betonte Wörter in Überschriften */
.grad-text {
background: var(--grad);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 0 22px rgba(240, 120, 0, .35));
}
/* Gegenstück: nur Kontur, keine Füllung */
.outline-text {
color: transparent;
-webkit-text-stroke: 1.5px var(--muted);
}
/* ── KNÖPFE ────────────────────────────────────────────
Ghost ist die Grundform, .btn-save trägt den Marken-Verlauf.
Die Grundform steht bewusst hier oben, vor allen Abwandlungen: .btn und
.btn-save sind gleich spezifisch, es gewinnt also die spätere Regel. Stand
die Grundform weiter unten, überschrieb ihr `background: none` jeden
Verlauf — der Speichern-Knopf sah dann aus wie ein Ghost-Knopf.
Die Aura (box-shadow) aus dem Entwurf entfällt: clip-path schneidet den
Schatten des eigenen Elements mit weg, sie wäre nicht sichtbar. */
.btn {
--bv: 10px;
display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
font-family: var(--mono);
font-size: .68rem; font-weight: 500;
letter-spacing: .15em; text-transform: uppercase;
color: var(--text2);
background: none;
border: 1px solid rgba(255, 255, 255, .18);
padding: .55rem 1.1rem;
transition: background .2s, border-color .2s, color .2s, filter .2s;
}
.btn:hover:not(:disabled) {
background: rgba(255, 255, 255, .06);
color: var(--accent-hi);
}
.btn:disabled { opacity: .25; cursor: default; }
/* Chakra Petch löst Bebas Neue ab. Die alte Schrift war schmal, versal und
wirkte schon im Grundgewicht fett — die Überschriften, die sie benutzt
haben, brauchen jetzt ein Gewicht, sonst lesen sie sich wie Fließtext. */
.milestone-title, .release-name, .stat-value, .modpage-name, .mod-name,
.tpl-name, .empty-title, .srv-name, .srv-count, .profile-name,
.lvl-avatar-empty, .bot-avatar-empty {
font-weight: 700;
}
/* ── NAV ───────────────────────────────────────────── */
/* Immer kompakt — der frühere „scrolled"-Zustand entfällt, die Leiste
wechselt beim Scrollen also nicht mehr die Höhe. */
.nav {
position: sticky; top: 0; z-index: 200;
display: flex; align-items: center; gap: 2rem;
padding: .85rem 2.5rem;
background: rgba(19, 19, 22, .88);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
}
/* Kein gap: die Wortmarke ist „D4RKST" + <span>3R</span>, und als Flex-Lücke
risse der Abstand mitten durch den Namen. Der Abstand zur Marke hängt
deshalb am Bild. */
.nav-logo {
display: inline-flex; align-items: center;
font-family: var(--display);
font-weight: 700; font-size: 1.12rem; letter-spacing: .06em;
color: var(--text);
line-height: 1;
transition: color .2s;
}
.nav-logo span { color: var(--accent); }
.nav-mark { width: 34px; height: 34px; object-fit: contain; flex: none; margin-right: .65rem; }
.nav-links { display: flex; gap: 1.8rem; flex: 1; align-items: center; }
.nav-links a {
font-family: var(--mono);
font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
color: var(--muted);
border-bottom: 2px solid transparent;
padding-bottom: .2rem;
transition: color .2s, border-color .2s;
}
.nav-links a:hover { color: var(--accent-hi); }
.nav-links a.active { color: var(--accent-hi); border-bottom-color: var(--accent); }
/* ── AUTH ──────────────────────────────────────────── */
.auth { display: flex; align-items: center; }
.btn-login {
--bv: 8px;
display: inline-flex; align-items: center; gap: .5rem;
font-family: var(--mono); font-size: .72rem; font-weight: 500;
letter-spacing: .14em; text-transform: uppercase;
color: var(--bg);
background: var(--grad);
border: 0;
padding: .55rem 1.3rem;
transition: filter .2s;
}
.btn-login:hover { color: var(--bg); filter: brightness(1.1); }
.discord-mark { width: 14px; height: 14px; }
/* Der Nutzer-Chip bleibt rund — er ist ein Personen-Schild, kein Panel */
.user-chip {
display: flex; align-items: center; gap: .6rem;
border: 1px solid rgba(255, 255, 255, .12);
border-radius: 999px;
padding: .3rem .8rem .3rem .35rem;
background: rgba(255, 255, 255, .04);
transition: border-color .2s;
}
.user-chip:hover { border-color: rgba(255, 154, 31, .45); }
.avatar { width: 24px; height: 24px; border-radius: 50%; border: 1px solid rgba(255, 154, 31, .4); }
.username { font-family: var(--mono); font-size: .7rem; letter-spacing: .08em; color: var(--muted); }
.logout { color: var(--muted2); font-size: .75rem; padding: 0 .1rem; transition: color .2s; }
.logout:hover { color: var(--accent-hi); }
/* ── SEITENKOPF ────────────────────────────────────── */
/* Kompakt statt bildschirmfüllend: Schild, Überschrift, ein Satz. */
.page-header {
max-width: 1160px; width: 100%;
margin: 0 auto;
padding: 4.5rem 2.5rem 2.5rem;
animation: riseIn .45s ease both;
}
.page-header-content { position: relative; }
.page-tag {
--bv: 6px;
display: inline-flex; align-items: center; gap: .5rem;
font-family: var(--mono);
font-size: .68rem; letter-spacing: .2em; text-transform: uppercase;
color: var(--accent-hi);
border: 1px solid rgba(255, 154, 31, .4);
padding: .35rem .8rem;
}
/* Punkt für Schilder, die einen Zustand melden („läuft gerade") */
.page-tag.dot::before {
content: '';
width: 6px; height: 6px; border-radius: 50%;
background: var(--accent-hi);
animation: pulseGlow 2s infinite;
}
.page-title {
font-family: var(--display);
font-size: clamp(2.4rem, 6vw, 3.6rem);
font-weight: 700; line-height: 1.02;
text-transform: uppercase;
color: var(--text);
margin: 1.1rem 0 .8rem;
}
.page-subtitle {
font-size: 1.05rem;
color: var(--muted);
max-width: 560px;
line-height: 1.65;
}
/* Der Panel-Kopf läuft auf der Breite der Arbeitsfläche, nicht der Lesespalte */
.page-header.wide { max-width: 1440px; padding: 2.5rem 2rem 1.5rem; }
.dash-title-row { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.dash-title { font-size: 2.1rem; letter-spacing: .02em; margin: 0; }
.dash-meta {
font-family: var(--mono); font-size: .66rem;
letter-spacing: .14em; text-transform: uppercase; color: var(--muted2);
}
.dash-title-row .status-pill { margin-left: auto; }
/* Fußnote unter einem Abschnitt — leiser als .notice */
.footnote {
margin-top: 2.5rem;
font-family: var(--mono); font-size: .74rem;
color: var(--muted2);
}
.footnote a { color: var(--muted); text-decoration: underline; }
.footnote a:hover { color: var(--accent-hi); }
/* ── CONTENT ───────────────────────────────────────── */
.main { flex: 1; }
/* Die Kachel-Raster des neuen Entwurfs brauchen drei Spalten — deshalb 1160
statt der früheren 860 px. Fließtext bekommt seine Lesebreite dort zurück,
wo er steht (.timeline, .legal-text), sonst würden Zeilen zu lang. */
.content {
max-width: 1160px; width: 100%;
margin: 0 auto;
padding: 1rem 2.5rem 5rem;
animation: riseIn .45s ease .08s both;
}
/* Seiten ohne Seitenkopf beginnen nicht direkt unter der Navigation */
.content:first-child { padding-top: 3rem; }
.notice { color: var(--muted); padding: 1.5rem 0; font-size: 1.05rem; }
/* Spalte statt Textfluss: der Hinweis trägt oft einen Knopf, und der klebte
als inline-flex sonst hinter dem Satz statt darunter zu stehen. */
.notice.center {
display: flex; flex-direction: column; align-items: center;
gap: 1.25rem; text-align: center; padding: 3.5rem 0;
}
.notice.center p { margin: 0; }
/* ── 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(--accent-hi); }
.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(--accent-hi); white-space: nowrap;
}
/* ── DEVLOG-TIMELINE ───────────────────────────────── */
/* Lesebreite: die Karten tragen Fließtext, das Raster darum ist breiter */
.timeline {
display: flex; flex-direction: column; gap: 1.5rem;
position: relative; padding-left: 1.6rem;
max-width: 880px;
}
.month-sep {
font-family: var(--mono);
font-size: .68rem; letter-spacing: .3em; text-transform: uppercase;
color: var(--accent-lo);
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(240, 120, 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(--accent-hi), rgba(255, 154, 31, .05));
}
/* Grundform aller Panels: Graphit, feiner Rand, gekappte Ecken.
Der Punkt auf der Timeline ist entfallen — er saß außerhalb der Karte und
würde von der Abschrägung weggeschnitten; die Linie trägt den Verlauf. */
.card {
--bv: 12px;
position: relative;
background: var(--bg2);
border: 1px solid var(--border);
padding: 1.3rem 1.6rem 1.2rem;
transition: border-color .2s, background .2s, transform .2s;
}
.card:hover {
border-color: rgba(255, 154, 31, .5);
background: var(--bg3);
transform: translateY(-3px);
}
.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(--accent-hi); 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(--accent-lo);
border: 1px solid rgba(240, 120, 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(--accent-lo); border-color: rgba(240, 120, 0, .4); }
.card-body { color: var(--text); font-weight: 400; 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(--accent-hi); font-weight: 600; }
.card-body em { color: var(--muted); }
.card-body a {
color: var(--accent-hi);
border-bottom: 1px solid var(--border);
transition: border-color .2s;
}
.card-body a:hover { border-bottom-color: var(--accent-hi); }
.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(--accent-hi);
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(--accent-hi);
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(--accent-hi); }
.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(--accent-hi); }
/* ── 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: 0; flex-shrink: 0; }
.hm-0 { background: rgba(255, 255, 255, .05); }
.hm-1 { background: rgba(255, 154, 31, .25); }
.hm-2 { background: rgba(255, 154, 31, .5); }
.hm-3 { background: rgba(255, 154, 31, .75); }
.hm-4 { background: var(--accent-hi); box-shadow: 0 0 4px rgba(255, 154, 31, .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: 0;
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(--accent-hi); white-space: nowrap; min-width: 3.5rem;
}
.wish-idea { flex: 1; font-weight: 400; min-width: 0; }
.wish-author { font-family: var(--mono); font-size: .62rem; color: var(--muted2); white-space: nowrap; }
/* Begründung des Teams unter der Idee — der Teil, der einen abgelehnten
Wunsch von einem vergessenen unterscheidet */
.wish-grund {
display: block; margin-top: .3rem;
font-size: .82rem; color: var(--muted);
border-left: 2px solid var(--border); padding-left: .6rem;
}
.wish-status {
font-family: var(--mono); font-size: .58rem; letter-spacing: .1em;
text-transform: uppercase; white-space: nowrap;
padding: .18rem .5rem; border-radius: 999px; border: 1px solid;
}
.wish-status.geplant { color: var(--accent-hi); border-color: color-mix(in srgb, var(--accent-hi) 45%, transparent); }
.wish-status.in_arbeit { color: var(--accent-lo, var(--accent-hi)); border-color: color-mix(in srgb, var(--accent-lo, var(--accent-hi)) 45%, transparent); }
.wish-status.umgesetzt { color: #3ba55d; border-color: rgba(59, 165, 93, .45); }
.wish-status.abgelehnt { color: var(--muted2); border-color: var(--border); }
/* Erledigtes tritt zurück, ohne zu verschwinden */
.wish-row.st-umgesetzt, .wish-row.st-abgelehnt { opacity: .72; }
/* Schilder stehen über der Idee, nicht dahinter — sonst rutschen sie bei
langen Texten aus dem Blick */
.wish-schilder { display: flex; gap: .35rem; flex-wrap: wrap; margin-bottom: .25rem; }
.wish-area {
font-family: var(--mono); font-size: .58rem; letter-spacing: .1em;
text-transform: uppercase; white-space: nowrap; color: var(--muted2);
padding: .18rem .5rem; border-radius: 999px; border: 1px solid var(--border);
}
/* Kommentare liegen im Discord-Thread — der Zähler führt direkt hinein */
.wish-komm {
display: inline-flex; align-items: center; gap: .3rem;
font-family: var(--mono); font-size: .68rem; color: var(--muted2);
text-decoration: none; white-space: nowrap;
}
.wish-komm:hover { color: var(--accent-hi); }
.wish-bar { display: flex; flex-direction: column; gap: .3rem; margin-bottom: 1rem; }
.wish-filter-label {
font-family: var(--mono); font-size: .58rem; letter-spacing: .12em;
text-transform: uppercase; color: var(--muted2);
align-self: center; margin-right: .2rem; min-width: 5.2rem;
}
.wish-area-select { flex: 0 0 auto; max-width: 11rem; }
.wish-filter { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.wish-chip {
background: var(--bg2); border: 1px solid var(--border); border-radius: 999px;
color: var(--muted); font-family: var(--mono); font-size: .62rem;
letter-spacing: .06em; padding: .3rem .7rem; cursor: pointer;
transition: border-color .15s, color .15s;
}
.wish-chip:hover { color: var(--text); }
.wish-chip.aktiv { border-color: var(--accent-hi); color: var(--accent-hi); }
.wish-chip-n { opacity: .6; }
/* Treffer beim Tippen: lieber mitstimmen als denselben Wunsch nochmal stellen */
.wish-hits { display: flex; flex-direction: column; gap: .3rem; margin-top: .6rem; }
.wish-hits-label { font-family: var(--mono); font-size: .62rem; color: var(--muted2); }
.wish-hit {
display: flex; align-items: center; gap: .45rem; text-align: left;
background: var(--bg3); border: 1px solid var(--border); border-radius: 0;
color: var(--muted); font: inherit; font-size: .84rem;
padding: .4rem .7rem; cursor: pointer;
}
.wish-hit:hover { border-color: var(--accent-hi); color: var(--accent-hi); }
/* ── 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: 0;
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(--accent-hi);
transform: translateY(-3px);
box-shadow: 0 12px 28px rgba(0, 0, 0, .5), 0 0 18px rgba(255, 154, 31, .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(--accent-hi); }
.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(255, 154, 31, .25);
}
.milestone:hover { border-left-color: var(--accent-hi); }
.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(--accent-lo), var(--accent-hi));
box-shadow: 0 0 12px rgba(255, 154, 31, .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(--accent-hi); }
/* ── CHANGELOG ─────────────────────────────────────── */
.release-card { margin-bottom: 1.5rem; }
.release-tag {
font-family: var(--mono);
font-size: .85rem; letter-spacing: .1em;
color: var(--accent-hi);
border: 1px solid var(--border);
background: rgba(255, 154, 31, .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(--accent-hi);
border: 1px solid var(--border);
padding: .12rem .5rem;
white-space: nowrap;
transition: border-color .2s, background .2s;
}
a.sha:hover { border-color: var(--accent-hi); background: rgba(255, 154, 31, .07); }
.commit-msg {
flex: 1;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
font-weight: 400; 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(--accent-lo); border: 1px solid rgba(240, 120, 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: .2rem;
position: sticky;
top: 5rem;
width: 13rem;
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 {
--bv: 7px;
display: flex; align-items: center; gap: .5rem;
background: var(--bg2); border: 1px solid rgba(255, 255, 255, .1);
padding: .5rem .7rem;
margin-bottom: .6rem; color: var(--muted2);
transition: border-color .15s;
}
.settings-search:focus-within { border-color: var(--accent); }
.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(--accent-hi); }
/* Bereichs-Gruppen */
.settings-nav-group { display: flex; flex-direction: column; gap: .2rem; margin-bottom: .7rem; }
.settings-nav-label {
font-family: var(--mono);
font-size: .56rem; letter-spacing: .22em; text-transform: uppercase;
color: var(--muted2);
padding: .25rem .8rem;
}
/* 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: 0;
padding: .4rem .9rem;
cursor: pointer;
transition: background .15s, border-color .15s;
}
.settings-hit:hover { background: rgba(255, 255, 255, .04); border-left-color: var(--accent-hi); }
.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(--accent-hi); }
/* Angesprungenes Feld kurz hervorheben, damit man es im Formular findet */
.field-found {
animation: fieldFound 2.2s ease both;
border-radius: 0;
}
@keyframes fieldFound {
0%, 55% { box-shadow: 0 0 0 2px var(--accent-hi), 0 0 18px rgba(255, 154, 31, .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(--accent-lo); 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(--accent-hi); border-color: rgba(255, 154, 31, .45); }
.btn-create:hover:not(:disabled) { background: rgba(255, 154, 31, .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(--accent-hi); opacity: 1; }
.mod-fav.on { color: var(--accent-hi); 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(--accent-hi); }
.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(--accent-hi); }
.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 {
--bv: 9px;
flex: none; display: inline-flex; align-items: center; justify-content: center;
width: 3rem; height: 3rem;
background: var(--bg3); border: 1px solid rgba(255, 154, 31, .3);
color: var(--accent-hi);
}
.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: 400; 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: 0;
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: 400; line-height: 1.6; margin: 0 0 .9rem; }
.setup-plan-intro strong { color: var(--accent-hi); font-weight: 600; }
.setup-plan-list {
display: flex; flex-direction: column;
border: 1px solid rgba(255, 255, 255, .06); border-radius: 0;
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(--accent-hi);
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: 400; }
.settings-nav-item {
display: flex; align-items: center; gap: .6rem;
font-family: var(--mono);
font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
color: var(--muted);
background: none;
border: 1px solid transparent;
border-left: 2px solid transparent;
padding: .5rem .8rem;
text-align: left;
transition: color .15s, background .15s, border-color .15s;
}
.settings-nav-item:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.settings-nav-item.active {
color: var(--accent-hi);
background: rgba(255, 154, 31, .08);
border-left-color: var(--accent);
}
.settings-nav-icon { font-size: .95rem; }
/* max-width gehört dazu: min-width allein reicht nicht, wenn ein Kind eine
grosse Mindestbreite mitbringt (die 168 Striche des Erreichbarkeits-Balkens).
Ohne die Grenze wuchs die Spalte auf 724 statt 335 px — und weil der Body
waagerecht abschneidet, war der Überstand nicht scrollbar, sondern weg. */
.settings-content { flex: 1; min-width: 0; max-width: 100%; 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: 400;
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: 0;
padding: .25rem .6rem;
white-space: nowrap;
transition: color .15s, border-color .15s;
}
.btn-mini:hover { color: var(--accent-hi); border-color: var(--accent-hi); }
.btn-ghost {
background: none;
color: var(--text2);
border-color: rgba(255, 255, 255, .18);
}
.btn-ghost:hover:not(:disabled) { color: var(--accent-hi); background: rgba(255, 255, 255, .06); 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: #131316;
border: 1px solid rgba(59, 165, 93, .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(--accent-hi); }
}
/* ── SETTINGS ──────────────────────────────────────── */
.settings-section {
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .06);
padding: 1.4rem 1.6rem;
margin-bottom: 1.5rem;
}
/* Abschnitts-Überschrift: Verlaufs-Strich, Titel, auslaufende Linie und
rechts optional eine Kennzahl (<span class="section-meta">). Die Linie ist
ein ::after und stünde von sich aus hinter allen echten Kindern — order
schiebt die Kennzahl dahinter. */
.settings-title {
display: flex; align-items: center; gap: 1rem;
font-family: var(--display);
font-size: 1.35rem; font-weight: 700;
letter-spacing: .04em; text-transform: uppercase;
color: var(--text);
margin-bottom: 1.2rem;
}
.settings-title::before {
content: '';
flex: none; width: 22px; height: 3px;
background: linear-gradient(90deg, var(--accent-hi), var(--accent-lo));
}
.settings-title::after {
content: '';
flex: 1; height: 1px;
background: linear-gradient(90deg, rgba(255, 255, 255, .15), transparent);
}
.section-meta {
order: 1;
font-family: var(--mono);
font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
color: var(--muted2); white-space: nowrap;
}
/* Was zum Titel gehört und nicht als eigene Spalte danebenstehen soll */
.settings-title-text { display: inline-flex; align-items: center; gap: .6rem; }
.cmd-lock { color: var(--accent-hi); }
.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: #131316;
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(--accent-hi); }
.field select, .field input[type="text"], .field input[type="password"] {
width: 100%;
background: #131316;
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, .field input[type="password"]:focus { border-color: var(--accent-hi); }
/* Auf breiten Schirmen sollen Eingabefelder nicht über die halbe Seite laufen */
.field select, .field input[type="text"], .field input[type="password"], .field input[type="number"] { max-width: 44rem; }
.field select option { background: #131316; }
/* 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(--accent-hi); }
.toggle input:checked { background: var(--accent-hi); border-color: var(--accent-hi); }
.toggle input:checked::after { transform: translateX(18px); background: #131316; }
.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(--accent-hi); flex: 1;
}
.key-used { font-family: var(--mono); font-size: .62rem; color: var(--muted2); white-space: nowrap; }
.key-created {
border: 1px solid rgba(59, 165, 93, .3);
background: rgba(59, 165, 93, .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(--accent-hi); }
.settings-actions { display: flex; align-items: center; gap: 1rem; }
.btn-save {
background: var(--grad);
color: var(--bg);
border-color: transparent;
}
.btn-save:hover:not(:disabled) { background: var(--grad); color: var(--bg); filter: brightness(1.1); }
.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);
}
/* ── FOOTER ────────────────────────────────────────── */
.footer {
border-top: 1px solid var(--border);
padding: 1.4rem 2.5rem;
display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap;
font-family: var(--mono); font-size: .66rem;
letter-spacing: .14em; text-transform: uppercase;
color: var(--muted);
}
/* Wie in der Navigation: kein gap, sonst reißt es den Namen auseinander */
.footer-logo {
display: inline-flex; align-items: center;
font-family: var(--display); font-weight: 700; font-size: .95rem;
letter-spacing: .06em; text-transform: none;
color: var(--text);
}
.footer-logo span { color: var(--accent); }
.footer-mark { width: 20px; height: 20px; object-fit: contain; margin-right: .5rem; }
/* Rechtliches sammelt sich am rechten Rand */
.footer-right { margin-left: auto; display: flex; gap: 1.2rem; flex-wrap: wrap; }
.footer a { color: var(--muted); transition: color .2s; }
.footer a:hover { color: var(--accent-hi); }
/* ── MOBILE ────────────────────────────────────────── */
@media (max-width: 640px) {
.nav { padding: .85rem 1.25rem; gap: 1.25rem; }
.username { display: none; }
.page-header { padding: 2.5rem 1.25rem 1.75rem; }
.content { padding: 1rem 1.25rem 4rem; }
.footer { padding: 1.4rem 1.25rem; }
.footer-right { margin-left: 0; width: 100%; }
.timeline { padding-left: 1.2rem; }
.commit-row { flex-wrap: wrap; row-gap: .35rem; }
.commit-msg { flex-basis: 100%; order: -1; white-space: normal; }
}
/* ── FLÄCHEN & KANTEN ──────────────────────────────────
Der neue Look hat keine Rundungen: Panels sind entweder abgeschrägt
(clip-path, siehe oben) oder scharfkantig. Rund bleibt nur, was einen
Menschen oder einen Zustand darstellt — Avatare, Punkte, Chips.
.settings-section bekommt bewusst keine Abschrägung: in den Bereichen
stehen Auswahllisten, die aus dem Panel herausklappen — clip-path würde
sie abschneiden. */
.card, .settings-section, .commit-list, .key-list, .key-created,
.wish-row, .release-card, .milestone,
.card-images a, .shot, .hm-cell, .lvl-list, .tm-list, .tpl-list, .tune-list {
border-radius: 0;
}
.settings-section {
background: var(--bg2);
border-color: var(--border);
transition: border-color .2s;
}
.settings-section:hover { border-color: rgba(255, 154, 31, .18); }
.settings-section + .settings-section,
.settings-content > .settings-section { margin-bottom: 1.25rem; }
.chip, .key-scopes { border-radius: 99px; }
.settings-nav-item { border-left-width: 2px; }
/* Eingaben: dunkler als das Panel, Fokus in der Leitfarbe */
.field select, .field input[type="text"], .field input[type="password"], .field textarea {
background: var(--bg);
border-color: rgba(255, 255, 255, .12);
border-radius: 0;
}
.field select:hover, .field input[type="text"]:hover, .field input[type="password"]:hover, .field textarea:hover {
border-color: rgba(255, 255, 255, .22);
}
.field select:focus, .field input[type="text"]:focus, .field input[type="password"]:focus, .field textarea:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(255, 154, 31, .12);
}
/* Schalter: an = Marken-Verlauf */
.toggle input { border-radius: 99px; }
.toggle input::after { border-radius: 50%; }
.toggle input:checked { background: var(--grad); border-color: transparent; }
/* ── LEVEL-BESTENLISTE ─────────────────────────────── */
.lvl-list { border: 1px solid rgba(255, 255, 255, .06); background: var(--bg2); border-radius: 0; }
.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: 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(255, 154, 31, .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(255, 154, 31, .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(--accent-hi); 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: 0;
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(--accent-hi);
box-shadow: 0 0 0 3px rgba(255, 154, 31, .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: 0;
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: 0;
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(--accent-hi);
background: none;
border: 1px solid var(--border);
border-radius: 0;
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(--accent-hi);
background: rgba(255, 154, 31, .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: 0; 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: 0;
padding: .8rem;
}
.act-bar {
flex: 1;
background: linear-gradient(180deg, var(--accent-hi), rgba(255, 154, 31, .35));
border-radius: 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: #ff9a1f;
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 #ff9a1f;
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: 0;
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(--accent-hi); }
.gamesel-id { color: var(--muted2); font-family: var(--mono); font-size: .75rem; }
.gamesel-item:hover .gamesel-id { color: var(--muted); }
.gamesel-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Schluessel = das Spiel antwortet nur mit Zugangs-Code */
.gamesel-key { margin-left: .35rem; font-size: .8em; }
/* Die Liste hat ueber 350 Eintraege — wer nichts findet, soll wissen, dass
noch mehr da ist, statt die Auswahl fuer vollstaendig zu halten. */
.gamesel-rest {
padding: .4rem .7rem; border-top: 1px solid var(--border);
font-family: var(--mono); font-size: .68rem; color: var(--muted2);
}
/* Durchsuchbare Kanal-/Rollen-Auswahl (ersetzt die nativen Dropdowns) */
.picksel { position: relative; max-width: 44rem; }
.picksel input {
width: 100%; padding-right: 2rem;
background: #131316; border: 1px solid var(--border); border-radius: 0;
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(--accent-hi); }
.picksel-caret {
position: absolute; right: .6rem; top: 50%; transform: translateY(-50%);
display: inline-flex; color: var(--muted2); cursor: pointer;
}
.picksel-caret:hover { color: var(--accent-hi); }
.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: 0;
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(--accent-hi); }
.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(240, 120, 0, 0.08); border: 1px solid rgba(240, 120, 0, 0.4);
border-radius: 0; 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: 0;
padding: 1.4rem; margin-bottom: 2rem;
}
.profile-avatar { width: 84px; height: 84px; border-radius: 50%; border: 2px solid var(--accent-hi); }
.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(--accent-hi), var(--accent-lo)); }
.alpha-key {
font-family: var(--mono); background: var(--bg3); border: 1px solid var(--border);
border-radius: 0; 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(--accent-hi); color: var(--accent-hi); }
.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(--accent-hi); color: var(--text); }
.wish-vote.voted { border-color: var(--accent-hi); color: var(--accent-hi); }
.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(--accent-hi); text-shadow: 0 0 12px rgba(255, 154, 31, .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(27, 27, 32, .97); border: 1px solid var(--border); border-radius: 0;
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: 0;
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(--accent-hi); }
.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: 0;
color: var(--accent-hi); 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(19, 19, 22, .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(--accent-hi); }
@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: 0;
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(--accent-lo); border-color: var(--accent-lo); }
.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(--accent-hi); border-color: var(--accent-hi); background: rgba(255, 154, 31, .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(--accent-hi); }
@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: 0;
}
.skel::after {
content: '';
position: absolute; inset: 0;
background: linear-gradient(90deg, transparent, rgba(255, 154, 31, .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: 0; animation: riseIn .3s ease both; }
.skel-row { height: 2.6rem; border-radius: 0; margin-bottom: .5rem; animation: riseIn .3s ease both; }
/* ── SERVER-STATUS-SEITE ───────────────────────────── */
.srv-summary {
--bv: 14px;
display: flex; gap: 2.5rem; flex-wrap: wrap;
background: var(--bg2); border: 1px solid var(--border);
padding: 1.2rem 1.6rem; margin-bottom: 1.5rem;
}
.srv-sum-item { display: flex; flex-direction: column; }
.srv-sum-n {
font-size: 2rem; font-weight: 700; line-height: 1.1;
background: var(--grad);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
/* Der Nenner steht neben der Zahl und darf den Verlauf nicht erben */
.srv-sum-of { font-size: 1.1rem; color: var(--muted2); -webkit-text-fill-color: var(--muted2); }
.srv-sum-label {
font-family: var(--mono); font-size: .62rem; letter-spacing: .14em;
text-transform: uppercase; color: var(--muted); margin-top: .3rem;
}
.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: 0; 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); }
/* Das Spiel gehoert zum Server, nicht zum Zustand — deshalb neutral, damit es
die gruene/rote Statusfarbe nicht mitnimmt. Bewusst ohne Trennstrich: die
Zeile bricht auf schmalen Schirmen um, und dann staende der Strich als
einzelnes Zeichen am Zeilenanfang. Abstand und Farbe trennen genug. */
.srv-spiel { color: var(--muted2); margin-left: .5rem; }
.srv-count { font-family: var(--display); font-size: 1.9rem; line-height: 1; color: var(--accent-hi); white-space: nowrap; }
.srv-count-max { font-size: 1.1rem; color: var(--muted2); }
.srv-bar { margin-top: .9rem; }
/* Auslastung: eigener Balken statt des XP-Balkens vom Level-System. Die Farbe
sagt, ob noch jemand reinkommt — gruen frei, gelb eng, rot voll. */
.srv-cap {
position: relative; height: 22px; margin-top: .9rem;
border: 1px solid var(--border); border-radius: 0;
background: var(--bg3); overflow: hidden;
}
.srv-cap-fill { height: 100%; transition: width .5s ease; }
.srv-cap.frei .srv-cap-fill { background: linear-gradient(90deg, #1f7a4d, var(--success)); }
.srv-cap.eng .srv-cap-fill { background: linear-gradient(90deg, #8a6a10, var(--accent-hi)); }
.srv-cap.voll .srv-cap-fill { background: linear-gradient(90deg, #8a2326, #f23f43); }
.srv-cap-pct {
/* Rechtsbuendig, nicht mittig: mittig laege die Zahl bei 50 % genau auf der
Fuellkante und waere halb hell, halb dunkel unterlegt. Rechts steht sie
fast immer auf dem ruhigen Grund. */
position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-end;
padding-right: .55rem;
font-family: var(--mono); font-size: .64rem; letter-spacing: .12em;
color: #fff; font-weight: 600;
text-shadow: 0 1px 3px rgba(0, 0, 0, .95), 0 0 6px rgba(0, 0, 0, .8);
}
/* Map, Version, Ping — was der Server ueber sich verraet */
.srv-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .8rem; }
.srv-chip {
display: inline-flex; align-items: center; gap: .3rem;
font-family: var(--mono); font-size: .64rem; letter-spacing: .06em;
color: var(--muted); background: var(--bg3);
border: 1px solid var(--border); border-radius: 0; padding: .22rem .5rem;
}
/* Steht anstelle des Verlaufs, wenn es nichts zu zeigen gibt */
.srv-leer {
font-family: var(--mono); font-size: .68rem; color: var(--muted2);
margin-top: 1rem; letter-spacing: .04em;
}
.srv-weg {
font-family: var(--mono); font-size: .7rem; color: #f23f43;
margin-top: .9rem; letter-spacing: .04em;
}
/* Spielerliste — dieselben Namen, die auch im Discord-Embed stehen */
.srv-spieler { margin-top: 1rem; }
.srv-spieler-kopf {
display: inline-flex; align-items: center; gap: .4rem;
font-family: var(--mono); font-size: .62rem; letter-spacing: .18em;
text-transform: uppercase; color: var(--muted2);
}
.srv-namen { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; }
.srv-name-chip {
font-family: var(--mono); font-size: .68rem; color: var(--text);
background: var(--bg3); border: 1px solid var(--border);
border-radius: 0; padding: .2rem .5rem;
max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.srv-mehr {
font-family: var(--mono); font-size: .68rem; color: var(--accent-hi);
background: none; border: 1px dashed var(--border); border-radius: 0;
padding: .2rem .5rem; cursor: pointer;
}
.srv-mehr:hover { border-color: var(--accent-hi); }
.srv-chart { width: 100%; height: 100px; margin-top: 1rem; display: block; }
/* Ohne non-scaling-stroke zieht preserveAspectRatio="none" den Strich mit in
die Breite und aus dem Strichmuster wird ein durchgezogener Balken. */
.srv-chart-peak { stroke: var(--muted2); stroke-width: 1; opacity: .5; vector-effect: non-scaling-stroke; }
/* Zeitachse unter dem Verlauf: ohne die weiss man nicht, welche Seite jetzt ist */
.srv-achse {
display: flex; justify-content: space-between;
font-family: var(--mono); font-size: .58rem; letter-spacing: .12em;
text-transform: uppercase; color: var(--muted2); margin-top: .15rem;
}
.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(--accent-hi); color: var(--accent-hi); }
.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: 1rem; flex-wrap: wrap;
margin-bottom: 1.3rem;
}
.dash-avatar {
width: 46px; height: 46px; border-radius: 50%; flex: 0 0 auto;
object-fit: contain;
border: 1px solid rgba(255, 154, 31, .35);
}
/* Die Wolfsmarke ist kein Foto — sie steht ohne Rahmen und ohne Kreis */
.dash-avatar.mark { border: 0; border-radius: 0; }
.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: .3rem; }
.dash-name { font-weight: 700; font-size: 1.05rem; 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: .14rem .5rem;
border: 1px solid rgba(59, 165, 93, .45); color: var(--success);
}
.dash-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.dash-uptime {
margin-left: auto; font-family: var(--mono);
font-size: .66rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted2);
}
/* Zustands-Schild im Seitenkopf des Dashboards */
.status-pill {
--bv: 6px;
display: inline-flex; align-items: center; gap: .45rem;
font-family: var(--mono); font-size: .62rem;
letter-spacing: .14em; text-transform: uppercase;
padding: .25rem .7rem;
border: 1px solid rgba(59, 165, 93, .45); color: var(--success);
}
.status-pill.aus { border-color: rgba(242, 63, 67, .45); color: var(--danger); }
.status-pill::before {
content: ''; width: 6px; height: 6px; border-radius: 50%;
background: currentColor;
}
/* Der Balken sitzt zwischen Kopfzeile und Kennzahlen. min-width: 0, sonst
sprengen ihn die 168 Striche auf schmalen Schirmen (siehe .srv-card). */
.dash-uptrack { margin: 0 0 1.2rem; min-width: 0; }
.dash-hint {
margin: 0 0 1.2rem; font-size: .8rem; color: var(--muted);
}
/* Panels des Dashboards dürfen abgeschrägt sein — anders als die übrigen
Config-Bereiche steht hier nichts drin, das herausklappt. */
.settings-section.dash-panel {
--bv: 16px;
padding: 1.5rem 1.7rem;
border-color: rgba(255, 255, 255, .09);
}
.settings-section.dash-panel:hover { border-color: rgba(255, 255, 255, .09); }
.dash-cols { display: grid; grid-template-columns: 1.2fr .8fr; gap: 1.2rem; }
.dash-cols > .settings-section { margin-bottom: 0; }
@media (max-width: 900px) { .dash-cols { grid-template-columns: 1fr; } }
.dash-kpis { display: grid; gap: .8rem; grid-template-columns: repeat(4, 1fr); }
.dash-kpi {
--bv: 10px;
display: flex; flex-direction: column; gap: .15rem;
padding: 1rem 1.1rem; min-width: 0;
background: var(--bg); border: 1px solid var(--border);
}
.dash-kpi:hover { background: var(--bg); border-color: var(--border); transform: none; }
.dash-v { font-size: 1.6rem; 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: .14em;
text-transform: uppercase; color: var(--muted); margin-top: .2rem;
}
/* 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: .4rem; min-height: 1em;
}
.dash-t.gut { color: var(--success); }
.dash-t.warn { color: var(--accent); }
.dash-spark {
display: flex; align-items: flex-end; gap: 3px;
height: 88px; margin-top: 1rem;
}
.dash-bar {
flex: 1; min-width: 2px;
background: linear-gradient(180deg, var(--accent-hi), rgba(240, 120, 0, .2));
}
.dash-bar:hover { filter: brightness(1.2); }
.dash-groups { display: flex; flex-direction: column; gap: .7rem; margin-top: 1rem; }
.dash-group {
display: flex; align-items: center; gap: .7rem;
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 9.5rem;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-group-bar {
flex: 1; height: 5px;
background: rgba(255, 255, 255, .08); overflow: hidden;
}
.dash-group-bar i { display: block; height: 100%; background: var(--grad); }
.dash-group-bar.warn i { background: var(--danger); }
.dash-group-n {
font-family: var(--mono); font-size: .62rem; color: var(--muted2);
flex: 0 0 2.6rem; 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: 0; 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(--accent-hi) 40%, transparent); background: color-mix(in srgb, var(--accent-hi) 7%, transparent); color: var(--accent-hi); }
.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(--accent-hi); }
.wd-meta {
margin-left: auto; font-family: var(--mono);
font-size: .62rem; letter-spacing: .06em; color: var(--muted2); white-space: nowrap;
}
/* Schlüssel stehen als Code — sonst verwechselt man O und 0 */
.pt-key { font-family: var(--mono); font-size: .74rem; color: var(--accent-hi); }
.pt-wartet { font-family: var(--mono); font-size: .66rem; color: var(--muted2); }
/* Wunsch-Verwaltung im Panel */
.wu-row { padding: .8rem 1rem; margin-bottom: .6rem; min-width: 0; }
.wu-head { display: flex; align-items: baseline; gap: .8rem; }
.wu-idee { flex: 1; min-width: 0; font-size: .92rem; }
.wu-aktionen { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; margin-top: .6rem; }
.wu-grund {
margin: .55rem 0 0; font-size: .82rem; color: var(--muted);
border-left: 2px solid var(--border); padding-left: .6rem;
}
/* ── EMOJI-AUSWAHL ─────────────────────────────────── */
.ep-wrap { position: relative; display: inline-block; min-width: 0; }
.ep-feld { display: flex; align-items: stretch; gap: .3rem; }
.ep-knopf {
flex: 0 0 auto; width: 2.4rem;
background: var(--bg3); border: 1px solid var(--border); color: var(--text);
font-size: 1.05rem; line-height: 1; cursor: pointer;
display: grid; place-items: center;
}
.ep-knopf:hover { border-color: var(--accent-hi); }
.ep-leer { opacity: .35; }
.ep-eingabe { width: 5.5rem; }
.ep-weg {
flex: 0 0 auto; background: none; border: none; color: var(--muted2);
cursor: pointer; padding: 0 .2rem;
}
.ep-weg:hover { color: #f23f43; }
/* Hängt an <body> und wird per JS positioniert — im zweispaltigen Teil der
Config (CSS columns) zerreißt es absolut positionierte Kästen sonst, und die
Tafel landet in der Nachbarspalte. */
.ep-tafel {
position: fixed; z-index: 1100;
background: var(--bg2); border: 1px solid var(--border); border-radius: 0;
box-shadow: 0 12px 30px rgba(0, 0, 0, .55);
animation: riseIn .15s ease both;
}
.ep-suche {
display: flex; align-items: center; gap: .45rem;
padding: .5rem .7rem; border-bottom: 1px solid var(--border); color: var(--muted2);
}
.ep-suche input {
flex: 1; min-width: 0; background: none; border: none; padding: 0;
color: var(--text); font: inherit; font-size: .84rem;
}
.ep-suche input:focus { outline: none; }
.ep-liste { max-height: 17rem; overflow-y: auto; padding: .5rem .7rem .7rem; }
.ep-gruppe {
font-family: var(--mono); font-size: .58rem; letter-spacing: .12em;
text-transform: uppercase; color: var(--muted2); margin: .5rem 0 .3rem;
}
.ep-raster { display: grid; grid-template-columns: repeat(auto-fill, 2rem); gap: .15rem; }
.ep-zelle {
width: 2rem; height: 2rem; display: grid; place-items: center;
background: none; border: 1px solid transparent; border-radius: 0;
font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.ep-zelle:hover { background: var(--bg3); border-color: var(--accent-hi); }
.ep-zelle.aktiv { border-color: var(--accent-hi); background: color-mix(in srgb, var(--accent-hi) 12%, transparent); }
.ep-nix { color: var(--muted); font-size: .84rem; margin: .6rem 0; }
/* ── EINE IDEE FÜR SICH ────────────────────────────── */
.wd-zurueck { margin-bottom: 1.2rem; display: inline-flex; align-items: center; gap: .4rem; }
.wd-kopf { padding: 1.3rem 1.5rem; margin-bottom: 2rem; }
.wd-zeile { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: .9rem; }
.wd-schilder { display: flex; gap: .35rem; flex-wrap: wrap; }
.wd-idee { margin: 0 0 .8rem; font-size: 1.05rem; font-weight: 400; line-height: 1.6; }
.wd-meta {
display: flex; gap: 1rem; flex-wrap: wrap;
font-family: var(--mono); font-size: .64rem; color: var(--muted2);
}
.wd-antwort {
margin-top: 1.1rem; padding: .8rem 1rem;
background: color-mix(in srgb, var(--accent-hi) 6%, transparent);
border-left: 2px solid var(--accent-hi);
font-size: .92rem; color: var(--text);
}
.wd-antwort-kopf {
display: block; margin-bottom: .3rem;
font-family: var(--mono); font-size: .58rem; letter-spacing: .12em;
text-transform: uppercase; color: var(--accent-hi);
}
/* Beiträge aus dem Thread — gespiegelt, nicht geschrieben */
.wd-komm {
display: flex; gap: .8rem; padding: .8rem 0;
border-bottom: 1px solid rgba(255, 255, 255, .05);
}
.wd-komm:last-of-type { border-bottom: none; }
.wd-avatar { width: 34px; height: 34px; border-radius: 50%; flex: 0 0 auto; }
.wd-avatar.leer { background: var(--bg3); }
.wd-komm-text { min-width: 0; flex: 1; }
.wd-komm-kopf { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.wd-komm-name { font-weight: 600; font-size: .88rem; }
.wd-komm-zeit { font-family: var(--mono); font-size: .6rem; color: var(--muted2); }
.wd-komm-inhalt {
margin: .25rem 0 0; font-weight: 400; line-height: 1.55;
white-space: pre-wrap; overflow-wrap: anywhere;
}
.wd-bilder { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }
.wd-bild {
max-height: 180px; max-width: 100%; border-radius: 0; cursor: zoom-in;
border: 1px solid var(--border); object-fit: cover;
}
.wd-bild:hover { border-color: var(--accent-hi); }
.wd-mitreden { margin-top: 1.2rem; display: inline-flex; align-items: center; gap: .45rem; }
/* Die Idee in der Liste führt jetzt zur eigenen Seite */
a.wish-idea { color: inherit; text-decoration: none; }
a.wish-idea:hover { color: var(--accent-hi); }
/* ── DIALOG ────────────────────────────────────────── */
.dlg-backdrop {
position: fixed; inset: 0; z-index: 1200;
display: flex; align-items: center; justify-content: center;
padding: 1.5rem;
background: rgba(0, 0, 0, .82);
animation: lbIn .18s ease both;
}
.dlg {
width: min(34rem, 100%);
/* Hoher Inhalt scrollt im Kasten, nicht die Seite dahinter */
max-height: min(85vh, 46rem);
display: flex; flex-direction: column;
background: var(--bg2); border: 1px solid var(--border);
border-radius: 0; min-width: 0;
animation: riseIn .2s ease both;
}
.dlg.weit { width: min(48rem, 100%); }
.dlg-head {
display: flex; align-items: center; gap: .8rem;
padding: 1rem 1.2rem; border-bottom: 1px solid var(--border);
}
.dlg-title {
margin: 0; flex: 1; min-width: 0;
font-family: var(--mono); font-size: .72rem;
letter-spacing: .12em; text-transform: uppercase; color: var(--accent-hi);
}
.dlg-body { padding: 1.2rem; overflow-y: auto; min-height: 0; }
.dlg-body > .field:last-child { margin-bottom: 0; }
.dlg-foot {
display: flex; gap: .6rem; justify-content: flex-end; flex-wrap: wrap;
padding: .9rem 1.2rem; border-top: 1px solid var(--border);
}
/* Auswahlliste im Dialog — eine Zeile je Person */
.dlg-pick { display: flex; flex-direction: column; gap: .35rem; }
.dlg-pick button {
display: flex; align-items: center; gap: .6rem; width: 100%;
padding: .6rem .8rem; text-align: left;
background: var(--bg3); border: 1px solid var(--border); color: var(--text);
font: inherit; cursor: pointer;
}
.dlg-pick button:hover:not(:disabled) { border-color: var(--accent-hi); color: var(--accent-hi); }
.dlg-pick button:disabled { opacity: .45; cursor: not-allowed; }
.dlg-pick .pick-hint { margin-left: auto; font-family: var(--mono); font-size: .62rem; color: var(--muted2); }
/* Emoji eines Ticket-Anliegens — gleiche Breite wie der Statuspunkt daneben,
damit die Namen untereinander auf einer Linie stehen */
.tk-emoji { font-size: 1rem; line-height: 1; width: 1.2rem; text-align: center; flex: 0 0 auto; }
/* ── AUTOMOD-REGELN ────────────────────────────────── */
.am-row { padding: .9rem 1.1rem; margin-bottom: .7rem; min-width: 0; }
.am-head { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.am-toggle { margin-left: auto; }
.am-meta {
display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
margin-top: .55rem; font-size: .78rem; color: var(--muted);
}
.am-actions { display: flex; gap: .35rem; flex-wrap: wrap; }
.am-exempt { font-family: var(--mono); font-size: .64rem; color: var(--muted2); }
/* ── 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: 32px; overflow-x: auto; overflow-y: hidden;
scrollbar-width: none;
}
.up-track::-webkit-scrollbar { display: none; }
.up-tick {
flex: 1 0 3px; min-width: 3px;
background: var(--success);
transition: transform .1s ease;
}
.up-tick:hover { transform: scaleY(1.15); }
.up-tick.teil { background: var(--accent); }
.up-tick.aus { background: var(--danger); }
/* Keine Messung ist kein „läuft" — deshalb sichtbar leer statt grün */
.up-tick.leer { background: rgba(255, 255, 255, .08); }
.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(--accent-hi) 14%, transparent);
color: var(--accent-hi);
}
/* 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: 0; 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(--accent-hi) 5%, transparent); }
.tm-row.aktiv {
background: color-mix(in srgb, var(--accent-hi) 9%, transparent);
box-shadow: inset 3px 0 0 var(--accent-hi);
}
.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(--accent-hi) 40%, transparent);
color: var(--accent-hi);
}
.tm-role {
font-family: var(--mono); font-size: .62rem; letter-spacing: .14em;
color: var(--accent-hi); 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: 0; 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(--accent-hi);
background: color-mix(in srgb, var(--accent-hi) 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: 0;
font-size: .7rem; color: #131316;
}
.tm-scope.on .tm-scope-mark { background: var(--accent-hi); border-color: var(--accent-hi); }
.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(--accent-hi); 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-accent { color: var(--accent); }
.home-cta { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 1.8rem; }
/* Die Knöpfe im Hero sind größer als die in den Formularen */
.home-cta .btn { font-size: .78rem; letter-spacing: .12em; padding: .8rem 1.6rem; }
.home-tiles {
display: grid; gap: 1rem;
grid-template-columns: repeat(3, 1fr);
}
/* Symbol und Titel in einer Zeile, Beschreibung darunter über die volle
Breite — als Raster, damit die Kacheln ohne zusätzliche Hülle auskommen. */
.home-tile {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: .45rem .7rem;
padding: 1.3rem 1.4rem;
}
.home-tile-icon {
--bv: 7px;
grid-column: 1; grid-row: 1;
display: inline-grid; place-items: center;
width: 36px; height: 36px;
background: rgba(255, 154, 31, .1);
border: 1px solid rgba(255, 154, 31, .3);
color: var(--accent-hi);
transition: none;
}
.home-tile-title {
grid-column: 2; grid-row: 1;
font-weight: 600; font-size: 1.02rem; letter-spacing: 0;
color: var(--text);
}
.home-tile-desc {
grid-column: 1 / -1; grid-row: 2;
color: var(--muted); font-size: .88rem; line-height: 1.55;
}
.home-devlog { display: block; }
.home-devlog-more {
display: inline-flex; align-items: center; gap: .45rem; margin-top: 1rem;
font-family: var(--mono); font-size: .72rem; letter-spacing: .14em;
text-transform: uppercase; color: var(--accent-hi);
}
@media (max-width: 900px) { .home-tiles { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .home-tiles { grid-template-columns: 1fr; } }
/* 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: 400; line-height: 1.75;
margin-bottom: 1rem;
}
.legal-text strong { color: var(--text); font-weight: 600; }
.legal-text a { color: var(--accent-hi); border-bottom: 1px solid rgba(255, 154, 31, .3); }
.legal-text a:hover { border-bottom-color: var(--accent-hi); }
.legal-text code {
font-family: var(--mono); font-size: .85em;
background: var(--bg3); border: 1px solid var(--border);
border-radius: 0; 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: 400; line-height: 1.7;
}
.legal-list li::before {
content: '▸'; position: absolute; left: 0; color: var(--accent-lo);
}
/* Lösch-Bereich im Profil */
.danger-zone {
border: 1px solid rgba(242, 63, 67, .25);
border-radius: 0; 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(--accent-hi); }
/* Dienst-Kacheln tragen ein Emoji statt eines Lucide-Symbols */
.home-tile-emoji { font-size: 1.15rem; 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 #3ba55d66; }
.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 ──────────────────────────────── */
/* Beide Auftritte teilen sich jetzt dieselbe Palette — die frühere
Farbumkehr für .site-bot entfällt. */
/* Funktionsliste der Produktseite */
.feature-group { margin-bottom: 2.8rem; }
.feature-grid {
display: grid; gap: 1rem;
grid-template-columns: repeat(3, 1fr);
margin-top: 1.2rem;
}
.feature-card {
--bv: 12px;
display: flex; flex-direction: column; gap: .4rem;
padding: 1.2rem 1.3rem;
}
.feature-head { display: flex; align-items: center; gap: .65rem; }
.feature-icon {
--bv: 6px;
flex: none; display: inline-grid; place-items: center;
width: 32px; height: 32px;
background: rgba(255, 154, 31, .1);
border: 1px solid rgba(255, 154, 31, .3);
color: var(--accent-hi);
}
.feature-name {
font-weight: 600; font-size: .98rem;
color: var(--text);
}
.feature-desc {
color: var(--muted);
font-size: .85rem; line-height: 1.55; margin: 0;
}
.feature-outro {
border-top: 1px solid var(--border);
padding-top: 1.8rem; margin-top: .5rem;
}
.feature-outro p {
color: var(--muted);
line-height: 1.7; max-width: 46rem; margin: 0 0 1.4rem;
}
@media (max-width: 900px) { .feature-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .feature-grid { grid-template-columns: 1fr; } }
/* Befehlsliste */
.cmd-list { display: flex; flex-direction: column; gap: .55rem; }
.cmd-row {
--bv: 10px;
display: flex; gap: 1.2rem; align-items: baseline; flex-wrap: wrap;
background: var(--bg2); border: 1px solid var(--border);
padding: .75rem 1.1rem;
transition: border-color .2s, background .2s;
}
.cmd-row:hover { border-color: rgba(255, 154, 31, .5); background: var(--bg3); }
.cmd-name {
font-family: var(--mono); font-size: .82rem; color: var(--accent-hi);
white-space: nowrap; flex: none; min-width: 16rem;
}
.cmd-desc { color: var(--muted); font-size: .92rem; flex: 1; min-width: 15rem; }
@media (max-width: 640px) {
.cmd-name { min-width: 0; }
}
/* ── HERO (Landing + Hub-Start) ────────────────────── */
.hero {
max-width: 1160px; width: 100%; margin: 0 auto;
padding: 5rem 2.5rem 4rem;
display: grid; gap: 3rem; align-items: center;
}
.hero-bot { grid-template-columns: 1.15fr .85fr; }
.hero-hub { grid-template-columns: 1fr auto; padding: 4.5rem 2.5rem 3.5rem; }
.hero-text { animation: riseIn .5s ease both; }
.hero-title {
font-family: var(--display);
font-size: clamp(2.6rem, 6.5vw, 4.1rem);
font-weight: 700; line-height: 1.02; letter-spacing: -.01em;
text-transform: uppercase;
margin: 1.2rem 0 1rem;
}
.hero-sub {
font-size: 1.05rem; color: var(--muted);
max-width: 520px; line-height: 1.65;
}
/* Rechte Seite der Produktseite: Karte mit Logo, Zustand und Zahlen.
Der versetzte Rahmen liegt als eigenes Element dahinter — als Pseudo am
Panel würde ihn dessen Abschrägung wegschneiden. */
.hero-card { position: relative; animation: riseIn .5s ease .1s both; }
.hero-frame {
--bv: 24px;
position: absolute; inset: -1.2rem;
border: 1px solid rgba(255, 255, 255, .09);
pointer-events: none;
}
.hero-panel {
--bv: 18px;
position: relative;
background: var(--bg2);
border: 1px solid rgba(255, 255, 255, .1);
padding: 1.4rem;
}
.hero-lockup {
display: flex; justify-content: center;
padding: .4rem 0 1.1rem;
border-bottom: 1px solid rgba(255, 255, 255, .07);
}
.hero-lockup img {
width: 200px; height: auto; object-fit: contain;
filter: drop-shadow(0 8px 24px rgba(0, 0, 0, .5));
}
.hero-state {
display: flex; align-items: center; gap: .7rem;
padding: 1rem 0 .9rem;
font-family: var(--mono); font-size: .66rem;
letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
}
.hero-dot {
width: 8px; height: 8px; border-radius: 50%; flex: none;
background: var(--success);
box-shadow: 0 0 10px rgba(59, 165, 93, .7);
}
.hero-dot.aus { background: var(--danger); box-shadow: 0 0 10px rgba(242, 63, 67, .7); }
.hero-stats { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; }
.hero-stat {
--bv: 8px;
background: rgba(255, 154, 31, .06);
border: 1px solid rgba(255, 154, 31, .22);
padding: .8rem .9rem;
}
.hero-stat-n {
display: block;
font-size: 1.7rem; font-weight: 700; line-height: 1.1;
background: var(--grad);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-stat-label {
display: block; margin-top: .25rem;
font-family: var(--mono); font-size: .6rem;
letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
/* Hub-Start: Zahlenreihe unter den Knöpfen, Logo daneben */
.hero-figures { display: flex; gap: 2.2rem; flex-wrap: wrap; margin-top: 2.4rem; }
.hero-figure-n {
display: block;
font-size: 1.9rem; font-weight: 700; line-height: 1.1;
background: var(--grad);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
/* Der Nenner darf den Verlauf nicht erben, sonst verschwindet er */
.hero-figure-n .hero-figure-of {
font-size: 1.1rem; color: var(--muted2);
-webkit-text-fill-color: var(--muted2);
}
.hero-figure-label {
display: block; margin-top: .25rem;
font-family: var(--mono); font-size: .6rem;
letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.hero-logo { animation: riseIn .5s ease .1s both; }
.hero-logo img {
width: 300px; max-width: 100%; height: auto; object-fit: contain;
filter: drop-shadow(0 16px 44px rgba(0, 0, 0, .6)) drop-shadow(0 0 40px rgba(240, 120, 0, .15));
}
/* Zwei Panels unter den Kacheln: neutral und in der Leitfarbe */
.info-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 3rem; }
.info-panel {
--bv: 16px;
padding: 1.5rem 1.6rem;
background: linear-gradient(135deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, .015));
border: 1px solid rgba(255, 255, 255, .14);
}
.info-panel.warm {
background: linear-gradient(135deg, rgba(240, 120, 0, .16), rgba(240, 120, 0, .04));
border-color: rgba(255, 154, 31, .35);
}
.info-panel-tag {
font-family: var(--mono); font-size: .62rem;
letter-spacing: .2em; text-transform: uppercase; color: var(--text2);
}
.info-panel.warm .info-panel-tag { color: var(--accent-hi); }
.info-panel-title {
font-family: var(--display);
font-size: 1.2rem; font-weight: 700; margin: .4rem 0;
}
.info-panel p { color: var(--muted); font-size: .88rem; line-height: 1.55; margin: 0; }
@media (max-width: 900px) {
.hero-bot, .hero-hub { grid-template-columns: 1fr; }
.hero-hub .hero-logo { justify-self: center; }
.info-panels { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
.hero { padding: 3rem 1.25rem 2.5rem; gap: 2rem; }
.hero-frame { display: none; }
}
/* ── 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(--accent-hi); }
.mod-filter.active { color: #131316; background: var(--accent-hi); border-color: var(--accent-hi); }
.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(--accent-hi); 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 {
--bv: 7px;
flex: none; display: inline-flex; align-items: center; justify-content: center;
width: 2.4rem; height: 2.4rem;
background: var(--bg3); border: 1px solid var(--border);
color: var(--muted2);
transition: color .2s, border-color .2s;
}
.mod-card.on .mod-icon { color: var(--accent-hi); border-color: rgba(255, 154, 31, .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: 400; 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(--accent-lo); }
.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(--accent-hi); }
/* 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(--accent-hi); border-color: var(--accent-hi); }
.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: #131316; }
.mod-switch:hover { border-color: var(--accent-hi); }
/* ── 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: 0; 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(--accent-hi); }
.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(--accent-hi); }
.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(--accent-hi); border: 1px solid var(--accent-hi);
border-radius: 0; 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: #131316;
border: 1px solid var(--border); border-radius: 0;
padding: .7rem .8rem;
}
.tpl-input:focus { outline: none; border-color: var(--accent-hi); }
.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: 0;
padding: .18rem .45rem; cursor: pointer;
transition: color .15s, border-color .15s;
}
.tpl-var:hover { color: var(--accent-hi); border-color: var(--accent-hi); }
.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(--accent-hi); }
.dl-filter.active { color: #131316; background: var(--accent-hi); border-color: var(--accent-hi); }
.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: 0;
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: 400;
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(27, 27, 32, .96);
border: 1px solid var(--accent-hi);
border-radius: 99px;
box-shadow: 0 10px 30px rgba(0, 0, 0, .55), 0 0 20px rgba(255, 154, 31, .12);
animation: riseIn .25s ease both;
}
.save-bar-text {
font-family: var(--mono); font-size: .68rem;
letter-spacing: .12em; text-transform: uppercase;
color: var(--accent-hi); 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(--accent-hi); border-color: var(--accent-hi); }
@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: 0; 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(--accent-hi); }
.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: 400; 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: #131316;
border: 1px solid var(--border); border-radius: 0;
padding: .4rem .55rem;
}
.tune-input select { text-align: left; }
.tune-input input:focus, .tune-input select:focus { outline: none; border-color: var(--accent-hi); }
.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; }
}
/* Schloss am Servernamen + der Grund als Chip */
.srv-schloss { color: var(--accent-hi); margin-left: .45rem; vertical-align: -2px; }
.srv-chip.zu { color: var(--accent-hi); border-color: rgba(255, 154, 31, .35); }
/* Wie der Server sich im Spiel nennt — leiser als der eigene Name */
.srv-spielname {
font-family: var(--mono); font-size: .68rem; color: var(--muted2);
letter-spacing: .04em; margin-top: .1rem;
}
/* ── MOD-LISTE (LS-Server) ─────────────────────────── */
.mod-bar {
display: flex; justify-content: space-between; align-items: center;
gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem;
}
.mod-count {
display: flex; align-items: center; gap: .5rem;
font-family: var(--mono); font-size: .72rem; letter-spacing: .12em;
text-transform: uppercase; color: var(--muted);
}
.mod-count strong { color: var(--accent-hi); font-size: 1rem; font-weight: 400; }
.mod-sum { color: var(--muted2); }
.mod-search {
display: flex; align-items: center; gap: .5rem; flex: 1 1 240px; max-width: 340px;
border: 1px solid var(--border); background: var(--bg2); padding: .45rem .75rem;
color: var(--muted);
}
.mod-search:focus-within { border-color: var(--accent-hi); }
.mod-search input {
flex: 1; min-width: 0; background: none; border: 0; outline: none;
color: var(--text); font-family: var(--body); font-size: 1rem;
}
.mod-list { list-style: none; display: flex; flex-direction: column; gap: 1px; }
.mod-row {
display: grid; align-items: center; gap: .9rem;
grid-template-columns: 1fr auto auto auto;
padding: .7rem .9rem; background: var(--bg2);
border-left: 2px solid transparent;
}
.mod-row:hover { background: var(--bg3); border-left-color: var(--accent-hi); }
.mod-info { min-width: 0; }
.mod-title { display: block; color: var(--text); font-size: 1.05rem; }
.mod-meta {
display: block; font-family: var(--mono); font-size: .62rem;
color: var(--muted2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mod-version, .mod-size {
font-family: var(--mono); font-size: .68rem; color: var(--muted);
white-space: nowrap;
}
/* Feste Spalte, damit die Downloadknöpfe untereinander stehen und nicht
je nach Dateigrösse wandern — auch dann, wenn die Grösse noch fehlt. */
.mod-size { min-width: 4.5rem; text-align: right; }
.mod-dl {
display: inline-flex; align-items: center; gap: .4rem;
border: 1px solid var(--border); padding: .35rem .7rem;
font-family: var(--mono); font-size: .65rem; letter-spacing: .1em;
text-transform: uppercase; color: var(--muted); white-space: nowrap;
transition: border-color .15s, color .15s;
}
.mod-dl:hover { border-color: var(--accent-hi); color: var(--accent-hi); }
.mod-hint { color: var(--muted2); font-size: .9rem; margin-top: 1.2rem; }
@media (max-width: 640px) {
.mod-row { grid-template-columns: 1fr auto; grid-template-areas: 'info dl' 'meta meta'; }
.mod-info { grid-area: info; }
.mod-dl { grid-area: dl; }
.mod-version, .mod-size { grid-area: meta; text-align: left; min-width: 0; }
.mod-version::after { content: ' ·'; }
}
/* ── RADIO-SENDER (Panel) ──────────────────────────── */
/* 44 Sender sind 3300 px — ohne Deckel schiebt die Liste den halben
Community-Bereich aus dem Bild. Gemessen im Panel, nicht geschätzt. */
.radio-list {
display: flex; flex-direction: column; gap: 1px; margin-bottom: 1.5rem;
max-height: 26rem; overflow-y: auto;
border: 1px solid var(--border);
}
.radio-list::-webkit-scrollbar { width: 8px; }
.radio-list::-webkit-scrollbar-thumb { background: var(--border); }
/* Die Config-Seite ist zweispaltig — ein Abschnitt ist rund 480 px breit,
nicht die volle Seite. Mit vier Spalten blieben für Name und Adresse
96 px übrig; gemessen, nicht geschätzt. Deshalb schmale Knöpfe. */
.radio-row {
display: grid; align-items: center; gap: .6rem;
grid-template-columns: auto minmax(0, 1fr) auto;
padding: .6rem .7rem; background: var(--bg2);
border-left: 2px solid transparent;
}
.radio-actions { display: flex; gap: .35rem; }
.radio-actions .btn { padding: .3rem .55rem; font-size: .6rem; }
.radio-row:hover { background: var(--bg3); border-left-color: var(--accent-hi); }
.radio-emoji { font-size: 1.2rem; line-height: 1; }
.radio-info { min-width: 0; }
.radio-name { display: block; color: var(--text); }
.radio-url {
display: block; font-family: var(--mono); font-size: .62rem; color: var(--muted2);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.radio-form { border-top: 1px solid var(--border); padding-top: 1.2rem; }
/* Emoji und Reihenfolge sind beide schmal — nebeneinander statt zwei
halbleere Zeilen, aber auf dem Handy untereinander. */
.radio-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 560px) {
.radio-form-row { grid-template-columns: 1fr; }
}
/* ── Radio-Fernbedienung ──────────────────────────────────────────────── */
.radio-remote {
border: 1px solid var(--border);
background: var(--bg2);
padding: 1rem;
margin-bottom: 1.2rem;
display: flex;
flex-direction: column;
gap: .9rem;
}
.radio-now { border-left: 3px solid var(--accent); padding-left: .8rem; }
.radio-now-head { display: flex; gap: .7rem; align-items: flex-start; }
.radio-badge { font-size: 1.4rem; line-height: 1.2; }
.radio-now-text { min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.radio-now-text strong { color: var(--text); overflow-wrap: anywhere; }
.radio-now-sub { color: var(--text-dim); font-size: .72rem; overflow-wrap: anywhere; }
.radio-progress { display: flex; align-items: center; gap: .6rem; margin-top: .5rem; }
.radio-progress-bar { flex: 1; height: 4px; background: var(--bg3); overflow: hidden; }
.radio-progress-bar span {
display: block; height: 100%; background: var(--accent);
/* Der Balken springt sonst bei jeder Abfrage; fuenf Sekunden Abstand
zwischen zwei Staenden sieht ohne das aus wie ein Ruckeln. */
transition: width .6s linear;
}
.radio-progress-text { color: var(--text-dim); font-size: .68rem; font-variant-numeric: tabular-nums; }
.radio-add { display: flex; gap: .5rem; }
.radio-add input { flex: 1; min-width: 0; }
.radio-station-pick { max-width: 16rem; }
.radio-fehler {
background: var(--bg3);
border: 1px solid var(--border);
padding: .55rem .7rem;
font-size: .68rem;
/* Eine Fehlerzeile von yt-dlp ist lang und darf nicht die Seite
breiter machen -- sie bricht um statt zu schieben. */
white-space: pre-wrap;
overflow-wrap: anywhere;
margin: 0 0 .6rem;
color: var(--text-dim);
}
.radio-yt { border-top: 1px solid var(--border); padding-top: .8rem; }
.radio-yt > summary { cursor: pointer; color: var(--text-dim); font-size: .74rem; }
.radio-yt > summary:hover { color: var(--text); }
.radio-yt textarea { width: 100%; font-family: var(--mono, monospace); font-size: .68rem; }
.radio-yt .field { margin-top: .7rem; }
@media (max-width: 700px) {
.radio-add { flex-direction: column; }
.radio-station-pick { max-width: none; }
}