From b18d6a66cc8bed7002ae625fb83a011fabbff31e Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 11 Mar 2026 10:31:35 +0100 Subject: [PATCH] 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 --- web/STYLEGUIDE.md | 641 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 641 insertions(+) create mode 100644 web/STYLEGUIDE.md diff --git a/web/STYLEGUIDE.md b/web/STYLEGUIDE.md new file mode 100644 index 0000000..b33ef2c --- /dev/null +++ b/web/STYLEGUIDE.md @@ -0,0 +1,641 @@ +# 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 2–4 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 +
+
+
+
+
+``` + +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; + } +} +```