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

17 KiB
Raw Blame History

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: deepprimarysecondary/cardtertiary/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):

@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

.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:

.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):

.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:

.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

.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

.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

/* 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

.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

.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

/* 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

.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

.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

.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:

<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-:

/* ── 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;
  }
}