gaming-hub/web/STYLEGUIDE.md
Daniel b18d6a66cc
All checks were successful
Build & Deploy / build (push) Successful in 18s
Build & Deploy / deploy (push) Has been skipped
Build & Deploy / bump-version (push) Has been skipped
Add: Styleguide fuer einheitliches Plugin-Design
Dokumentiert alle Design-Tokens, Component-Patterns, Naming-Conventions,
Layout-Regeln und Do/Dont-Regeln basierend auf dem CI Redesign v3.
Enthaelt ein Plugin-Template als Starter-CSS fuer neue Plugins.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 10:31:35 +01:00

641 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Gaming Hub — Styleguide
Verbindliche Design-Referenz für alle Plugins. Basiert auf dem CI Redesign v3 (Warm-Brown, DM Sans).
---
## 1. Design Tokens
### Hintergrundfarben (Warm-Brown Palette)
| Variable | Wert | Verwendung |
|-------------------|------------|-------------------------------------|
| `--bg-deep` | `#1a1810` | App-Hintergrund, tiefste Ebene |
| `--bg-primary` | `#211e17` | Header, Hauptflächen |
| `--bg-secondary` | `#2a2620` | Cards, Panels, Sidebar |
| `--bg-tertiary` | `#322d26` | Hover-States, erhöhte Elemente |
| `--bg-card` | `#2a2620` | Alias für Card-Backgrounds |
| `--bg-card-hover` | `#322d26` | Card-Hover |
| `--bg-input` | `#1e1b15` | Input-Felder, Suchleisten |
| `--bg-header` | `#1e1b14` | Header-Bar |
**Helligkeitsreihenfolge:** `deep``primary``secondary/card``tertiary/card-hover`
### Textfarben
| Variable | Wert | Verwendung |
|-----------------|------------|-------------------------------|
| `--text-normal` | `#dbdee1` | Primärtext, Überschriften |
| `--text-muted` | `#949ba4` | Sekundärtext, Labels |
| `--text-faint` | `#6d6f78` | Tertiärtext, Platzhalter, Disabled |
### Accent-System
| Variable | Wert | Verwendung |
|-------------------|--------------------------------|-------------------------------|
| `--accent` | `#e67e22` | Primäre Akzentfarbe (Ember) |
| `--accent-rgb` | `230, 126, 34` | Für `rgba()` Konstrukte |
| `--accent-hover` | `#d35400` | Hover/Active auf Accent |
| `--accent-dim` | `rgba(230, 126, 34, 0.15)` | Subtiler Accent-Hintergrund |
| `--accent-border` | `rgba(230, 126, 34, 0.35)` | Focus-Borders, aktive Ränder |
Weitere Themes via `[data-accent="..."]`:
- `ember` (Standard) — Orange `#e67e22`
- `amethyst` — Lila `#9b59b6`
- `ocean` — Blau `#2e86c1`
- `jade` — Grün `#27ae60`
- `rose` — Pink `#e74c8b`
### Semantische Farben
| Variable | Wert | Verwendung |
|-------------|------------|---------------------|
| `--success` | `#57d28f` | Online, Erfolg, Win |
| `--danger` | `#ed4245` | Fehler, Offline, Loss |
| `--warning` | `#fee75c` | Warnungen |
### Borders
| Variable | Wert | Verwendung |
|------------------|-------------------------------|-------------------------|
| `--border` | `rgba(255, 255, 255, 0.05)` | Standard-Trennlinien |
| `--border-strong`| `rgba(255, 255, 255, 0.08)` | Betonte Ränder, Divider |
---
## 2. Typografie
### Font-Stacks
| Variable | Wert | Verwendung |
|------------|--------------------------------------------------|-----------------|
| `--font` | `'DM Sans', system-ui, -apple-system, sans-serif`| Body, UI-Text |
| `--mono` | `'DM Mono', monospace` | Code, Timer, Zahlen |
Google Fonts Import (bereits in `styles.css`):
```css
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600;9..40,700&family=DM+Mono:wght@400;500&display=swap');
```
### Type Scale
| Größe | Verwendung |
|--------|---------------------------------------------|
| `9px` | Micro-Badges, Tier-Ranks |
| `10px` | Kleine Labels, Plattform-Badges |
| `11px` | Meta-Text, Zähler, Sound-Card-Names |
| `12px` | Small Body, Grid-Text, Chip-Labels |
| `13px` | **Base Body** (globaler Standard) |
| `14px` | Buttons, Inputs, Standard-UI-Text |
| `15px` | Profilnamen, Detail-Labels |
| `16px` | Section-Headings, Titel |
| `18px` | Große Überschriften |
| `20px` | Profil-Titel |
| `24px` | Logo, Hero-Text |
### Font-Weights
| Wert | Name | Verwendung |
|-------|-----------|--------------------------------------|
| `400` | Regular | Body-Text, Inputs |
| `500` | Medium | Labels, Tab-Navigation, Chips |
| `600` | Semibold | Buttons, Card-Titel, aktive Elemente |
| `700` | Bold | Überschriften, Badges, Logo |
---
## 3. Spacing
4px-Basis-Grid. Bevorzugte Werte:
| Wert | Verwendung |
|--------|--------------------------------------|
| `4px` | Micro-Gaps, Icon-Abstände |
| `8px` | Tight Gaps, Badge-Padding |
| `10px` | Button/Input-Padding, Listen-Rows |
| `12px` | Card-Padding, comfortable Gaps |
| `16px` | Grid-Gaps, Section-Padding |
| `20px` | Container-Padding |
| `24px` | Modal-Padding, große Sections |
| `32px` | Section-Abstände |
---
## 4. Border-Radius
| Variable | Wert | Verwendung |
|---------------|----------|-------------------------------------|
| `--radius` | `4px` | **Standard** — Buttons, Inputs, Cards, Chips |
| `--radius-lg` | `6px` | Modals, Admin-Panels, große Cards |
| `50%` | — | Avatare, Status-Dots |
| `9999px` | — | Pill-Shapes (Tags, Badges) |
> **Regel:** Kein `border-radius` über `6px` außer Circles (`50%`) und Pills (`9999px`).
---
## 5. Schatten
| Stufe | Wert | Verwendung |
|--------|-------------------------------------|------------------------|
| xs | `0 1px 3px rgba(0, 0, 0, .24)` | Subtile Erhöhung |
| sm | `0 2px 6px rgba(0, 0, 0, .3)` | Buttons, kleine Panels |
| md | `0 4px 12px rgba(0, 0, 0, .32)` | Cards, Dropdowns |
| lg | `0 4px 20px rgba(0, 0, 0, .4)` | Elevated Cards (Hover) |
| xl | `0 8px 32px rgba(0, 0, 0, .5)` | Modals, Overlays |
> **Regel:** Nur dunkle Elevation-Shadows. Keine farbigen Glow-Effekte (`0 0 Xpx` mit Farbe).
---
## 6. Motion & Transitions
| Variable | Wert | Verwendung |
|----------------|---------|-----------------------------|
| `--transition` | `150ms ease` | Standard-Transition |
### Empfohlene Dauern
| Dauer | Verwendung |
|---------|---------------------------------------|
| `100ms` | Hover-States, Color-Changes |
| `150ms` | Standard-Transitions, Border-Changes |
| `200ms` | Layout-Changes, Transform-Animations |
| `350ms` | Einblende-Animationen, Card-Enter |
### Easing
| Kurve | Verwendung |
|----------------------------------------|-------------------------|
| `ease` | Standard |
| `cubic-bezier(.4, 0, .2, 1)` | Material-Design-Feeling |
| `cubic-bezier(0.16, 1, 0.3, 1)` | Ease-Out (schnell raus) |
---
## 7. Component Patterns
### Cards
```css
.prefix-card {
background: var(--bg-card);
border: 1px solid transparent;
border-radius: var(--radius);
padding: 12px;
cursor: pointer;
transition: all var(--transition);
}
.prefix-card:hover {
background: var(--bg-card-hover);
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}
```
### Buttons
**Primary:**
```css
.prefix-btn-primary {
padding: 8px 16px;
background: var(--accent);
color: #fff;
font-weight: 600;
font-size: 13px;
border-radius: var(--radius);
border: none;
cursor: pointer;
transition: all var(--transition);
}
.prefix-btn-primary:hover {
background: var(--accent-hover);
}
```
**Secondary (Outline):**
```css
.prefix-btn-secondary {
padding: 8px 16px;
background: transparent;
color: var(--text-muted);
font-weight: 500;
border: 1px solid var(--border-strong);
border-radius: var(--radius);
cursor: pointer;
transition: all var(--transition);
}
.prefix-btn-secondary:hover {
color: var(--text-normal);
border-color: rgba(255, 255, 255, 0.15);
}
```
**Icon-Button:**
```css
.prefix-btn-icon {
padding: 6px;
background: none;
color: var(--text-muted);
border: none;
border-radius: var(--radius);
cursor: pointer;
transition: all var(--transition);
}
.prefix-btn-icon:hover {
background: var(--bg-tertiary);
color: var(--text-normal);
}
```
### Inputs
```css
.prefix-input {
padding: 8px 12px;
background: var(--bg-input);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-normal);
font-family: var(--font);
font-size: 13px;
transition: border-color var(--transition);
}
.prefix-input::placeholder {
color: var(--text-faint);
}
.prefix-input:focus {
border-color: var(--accent-border);
outline: none;
}
```
### Chips / Tags
```css
.prefix-chip {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-size: 12px;
font-weight: 500;
color: var(--text-muted);
background: transparent;
border: 1px solid var(--border);
border-radius: var(--radius);
cursor: pointer;
transition: all var(--transition);
}
.prefix-chip:hover {
color: var(--text-normal);
border-color: var(--border-strong);
}
.prefix-chip.active {
background: var(--accent);
border-color: var(--accent);
color: #fff;
font-weight: 600;
}
```
### Modals
```css
/* Overlay — einziger Ort wo backdrop-filter erlaubt ist */
.prefix-overlay {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(4px);
}
/* Modal-Container */
.prefix-modal {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 500px;
width: 90vw;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
```
### Listen-Rows
```css
.prefix-row {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
border-radius: var(--radius);
transition: background var(--transition);
cursor: pointer;
}
.prefix-row:hover {
background: var(--bg-tertiary);
}
.prefix-row.active {
background: var(--accent-dim);
border-left: 3px solid var(--accent);
}
```
### Dropdowns
```css
.prefix-dropdown {
position: absolute;
background: var(--bg-secondary);
border: 1px solid var(--border-strong);
border-radius: var(--radius);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
max-height: 300px;
overflow-y: auto;
z-index: 100;
}
```
### Scrollbars
```css
/* Bereits global in styles.css definiert */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.14); }
```
### Empty States
```css
.prefix-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 48px 24px;
color: var(--text-faint);
text-align: center;
}
.prefix-empty-icon {
font-size: 48px;
margin-bottom: 12px;
opacity: 0.5;
}
.prefix-empty-text {
font-size: 14px;
}
```
### Status-Dots
```css
.prefix-status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--danger);
flex-shrink: 0;
}
.prefix-status-dot.online {
background: var(--success);
animation: pulse-dot 2s ease-in-out infinite;
}
```
---
## 8. Naming Conventions
### Plugin-Prefixe
| Plugin | Prefix | Beispiel |
|---------------|-----------|---------------------|
| Hub/Global | `hub-` | `.hub-header` |
| Soundboard | `sb-` | `.sb-app` |
| Radio | (in `styles.css`) | `.radio-container` |
| Game Library | `gl-` | `.gl-container` |
| LoL Stats | `lol-` | `.lol-container` |
| Streaming | `stream-` | `.stream-container` |
| Watch Together| `wt-` | `.wt-container` |
Neues Plugin: Eigenes 24 Buchstaben Prefix wählen.
### Klassen-Naming
```
.prefix-block → Hauptcontainer
.prefix-block-element → Kindelement
.prefix-block.active → Zustandsmodifier
.prefix-block.disabled → Disabled-State
```
- Hyphen-separated, lowercase
- Keine globalen generischen Klassen (`.card`, `.btn`) — immer mit Prefix
- Modifier als separate Klasse, nicht als BEM-`--modifier`
---
## 9. Layout-Regeln
### App-Shell
```
┌─────────────────────────────────────┐
│ Header (44px, --bg-primary) │ ← .hub-header
│ [Logo] [Tabs...] [Controls] │
├─────────────────────────────────────┤
│ │
│ Content Area (flex: 1, scroll-y) │ ← .hub-content > .tab-panel
│ │
└─────────────────────────────────────┘
```
- Header: `44px` Höhe, `var(--bg-primary)`, `border-bottom: 1px solid var(--border)`
- Tab-Navigation: **Horizontal im Header** (keine Sidebar)
- Content: `flex: 1`, `overflow-y: auto`
### Grids
```css
.prefix-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
padding: 16px;
}
```
- `minmax` Minimum je nach Inhalt: 88px (Sound-Cards), 220px (User-Cards), 280px (Game-Tiles)
- `gap: 16px` Standard, `gap: 3px` nur für dichte Grids (Soundboard)
### Responsive Breakpoints
| Breakpoint | Ziel | Anpassungen |
|------------|-------------|--------------------------------------|
| `768px` | Tablet | Grid-Spalten reduzieren, Modal 90vw |
| `480px` | Mobile | Flex-Direction column, Padding kürzen|
---
## 10. Do / Don't
### DO
- Alle Farben über CSS-Variablen (`var(--bg-card)`, `var(--text-muted)`)
- `var(--transition)` für alle Transitions
- `var(--font)` / `var(--mono)` für Font-Stacks
- `var(--radius)` / `var(--radius-lg)` für Border-Radius
- Solide Hintergründe für Content-Elemente
- `transform: translateY(-2px)` für Card-Hover
- Dunkle `rgba(0,0,0,...)` Shadows für Elevation
### DON'T
- `backdrop-filter: blur()` außer auf Modal-Overlays
- Farbige Glow-Shadows (`box-shadow: 0 0 Xpx var(--accent)`)
- Dekorative `linear-gradient` / `radial-gradient` Hintergründe
- `border-radius` über `6px` (außer `50%` Circles und `9999px` Pills)
- Hardcoded Farben für Hintergründe/Text/Borders (Ausnahme: Brand-Colors wie Steam `#66c0f4`)
- Font-Stacks direkt angeben (`font-family: 'Arial'`)
- Eigene Accent-Farben definieren — `var(--accent)` verwenden
- Globale Klassen ohne Plugin-Prefix
---
## 11. Theme-System
### Accent-Themes (global)
Wechselbar via `data-accent` Attribut auf Root-Element:
```html
<div data-accent="ember"> <!-- Standard: Orange -->
<div data-accent="amethyst"> <!-- Lila -->
<div data-accent="ocean"> <!-- Blau -->
<div data-accent="jade"> <!-- Grün -->
<div data-accent="rose"> <!-- Pink -->
```
Alle Accent-Varianten sind in `styles.css` definiert. Plugins greifen **nur** auf `var(--accent)`, `var(--accent-hover)`, `var(--accent-dim)` etc. zu.
### Plugin-Themes (optional)
Soundboard hat zusätzliche Farbthemes via `[data-theme="..."]`. Andere Plugins sollten das **nicht** nachbauen, sondern den globalen Accent nutzen.
---
## 12. Plugin-Template (Starter CSS)
Minimales Boilerplate für ein neues Plugin `example` mit Prefix `ex-`:
```css
/* ── Example Plugin ──
Prefix: ex-
Inherits all tokens from :root (styles.css)
────────────────────────────────────────── */
/* Container */
.ex-container {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
/* Toolbar */
.ex-toolbar {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
/* Content Grid */
.ex-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
padding: 16px;
overflow-y: auto;
flex: 1;
}
/* Card */
.ex-card {
background: var(--bg-card);
border: 1px solid transparent;
border-radius: var(--radius);
padding: 12px;
cursor: pointer;
transition: all var(--transition);
}
.ex-card:hover {
background: var(--bg-card-hover);
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}
/* Card Title */
.ex-card-title {
font-size: 14px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 4px;
}
/* Card Meta */
.ex-card-meta {
font-size: 12px;
color: var(--text-muted);
}
/* Empty State */
.ex-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 48px 24px;
color: var(--text-faint);
text-align: center;
}
/* Modal */
.ex-overlay {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(4px);
}
.ex-modal {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 24px;
max-width: 500px;
width: 90vw;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
/* Responsive */
@media (max-width: 768px) {
.ex-grid {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 12px;
padding: 12px;
}
}
```