Files
michaelschiemer/docs/design-token-system.md
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

9.7 KiB

Design Token System Dokumentation

Übersicht

Das Design Token System ermöglicht die zentrale Verwaltung von Design-Tokens (Farben, Abstände, Typografie, etc.) in PHP mit automatischer CSS-Generierung. Es unterstützt moderne CSS-Features wie OKLCH-Farben, HDR/P3-Support, Dark Mode und State-basierte Token-Variationen.

Architektur

Kernkomponenten

  1. TokenRegistry - Basis-Klasse für Token-Registries
  2. ColorVariation - Verwaltet Farben mit Light/Dark/P3/Fallback-Varianten
  3. ColorManipulator - Service für Farbmanipulation
  4. StateMutation - Definiert Mutationen für Token-States
  5. TokenStateRegistry - Verwaltet Tokens mit States
  6. CssAstBuilder - Generiert CSS aus Tokens

Token-Typen

  • ColorToken - Farb-Token mit Variationen
  • StatefulColorToken - Farb-Token mit States (hover, disabled, etc.)
  • SpacingToken - Abstands-Token
  • TypographyToken - Typografie-Token

Farbmanipulation

ColorManipulator Service

Der ColorManipulator Service bietet Methoden zur Manipulation von Farben:

use App\Framework\Design\Services\ColorManipulator;
use App\Framework\Design\ValueObjects\CssColor;
use App\Framework\Design\ValueObjects\ColorFormat;

$manipulator = new ColorManipulator();
$primary = new CssColor('oklch(70% 0.2 295)', ColorFormat::OKLCH);

// Helligkeit anpassen
$lighter = $manipulator->lighten($primary, 0.1);  // 10% heller
$darker = $manipulator->darken($primary, 0.2);    // 20% dunkler

// Sättigung anpassen
$moreSaturated = $manipulator->saturate($primary, 0.15);
$lessSaturated = $manipulator->desaturate($primary, 0.5);

// Transparenz ändern
$semiTransparent = $manipulator->adjustOpacity($primary, 0.5);

// Farben mixen
$secondary = new CssColor('oklch(60% 0.2 145)', ColorFormat::OKLCH);
$mixed = $manipulator->mix($primary, $secondary, 0.3); // 30% primary, 70% secondary

// Farbton verschieben
$shifted = $manipulator->adjustHue($primary, 30); // 30 Grad verschieben

CssColor Methoden

Farben können auch direkt manipuliert werden:

$primary = new CssColor('oklch(70% 0.2 295)', ColorFormat::OKLCH);

$hover = $primary->lighten(0.1);
$active = $primary->darken(0.15);
$disabled = $primary->desaturate(1.0)->withOpacity(0.5);
$mixed = $primary->mix($secondary, 0.3);

Token States

TokenState Enum

Das TokenState Enum definiert verschiedene States für Tokens:

  • DEFAULT - Standard State
  • DISABLED - Deaktiviert
  • HOVER - Hover State
  • ACTIVE - Aktiv (z.B. gedrückt)
  • SELECTED - Ausgewählt
  • FOCUSED - Fokussiert
  • LOADING - Lade-Zustand
  • ERROR - Fehler-Zustand
  • SUCCESS - Erfolgs-Zustand
  • WARNING - Warnung-Zustand

StateMutation

StateMutation definiert, wie ein Token für einen bestimmten State mutiert werden soll:

use App\Framework\Design\ValueObjects\StateMutation;
use App\Framework\Design\ValueObjects\TokenState;

// Disabled State: 0% Sättigung, 50% Transparenz
$disabledMutation = new StateMutation(
    saturationAdjustment: -1.0,  // 0% Sättigung
    opacityAdjustment: 0.5        // 50% Transparenz
);

// Hover State: 10% heller
$hoverMutation = new StateMutation(
    lightnessAdjustment: 0.1
);

// Komposition mehrerer Mutationen
$desaturateMutation = new StateMutation(saturationAdjustment: -1.0);
$opacityMutation = new StateMutation(opacityAdjustment: 0.5);
$composedMutation = $desaturateMutation->compose($opacityMutation);

StatefulColorToken

Ein StatefulColorToken repräsentiert einen Farb-Token mit einem spezifischen State:

use App\Framework\Design\ValueObjects\Tokens\StatefulColorToken;
use App\Framework\Design\ValueObjects\ColorVariation;
use App\Framework\Design\ValueObjects\TokenState;
use App\Framework\Design\ValueObjects\StateMutation;

$primaryVariation = new ColorVariation(
    name: 'primary',
    light: new CssColor('oklch(70% 0.2 295)', ColorFormat::OKLCH),
    dark: new CssColor('oklch(60% 0.22 295)', ColorFormat::OKLCH)
);

// Default State
$defaultToken = new StatefulColorToken(
    name: 'button-primary',
    variation: $primaryVariation,
    state: TokenState::DEFAULT
);

// Disabled State (abgeleitet)
$disabledToken = new StatefulColorToken(
    name: 'button-primary',
    variation: $primaryVariation,
    state: TokenState::DISABLED,
    baseState: TokenState::DEFAULT,
    mutation: new StateMutation(
        saturationAdjustment: -1.0,
        opacityAdjustment: 0.5
    )
);

TokenStateRegistry

Der TokenStateRegistry verwaltet Tokens mit States:

use App\Framework\Design\ValueObjects\TokenStateRegistry;
use App\Framework\Design\ValueObjects\TokenState;
use App\Framework\Design\ValueObjects\StateMutation;

// Default Mutationen für States definieren
$registry = new TokenStateRegistry(
    tokens: [],
    stateMutations: [
        TokenState::DISABLED => new StateMutation(
            saturationAdjustment: -1.0,
            opacityAdjustment: 0.5
        ),
        TokenState::HOVER => new StateMutation(
            lightnessAdjustment: 0.1
        ),
        TokenState::ACTIVE => new StateMutation(
            lightnessAdjustment: -0.15
        ),
    ]
);

// Token hinzufügen
$registry = $registry->addToken($defaultToken);

// Token für State abrufen
$hoverToken = $registry->getTokenForState('button-primary', TokenState::HOVER);

// Alle States für Token abrufen
$allStates = $registry->getAllStatesForToken('button-primary');

CSS-Generierung

Automatische CSS-Generierung

Das System generiert automatisch CSS aus Tokens:

use App\Framework\Design\ValueObjects\FrameworkTokenRegistry;

$registry = new FrameworkTokenRegistry();
$css = $registry->toCss('framework-settings', includeHdr: true);

CSS Output

Das generierte CSS nutzt moderne Features:

@layer framework-settings {
    :root {
        --color-primary: oklch(70% 0.2 295);
        --color-primary-p3: color(display-p3 0.8 0.3 1);
    }
}

@layer framework-settings {
    @media (prefers-color-scheme: dark) {
        :root {
            --color-primary: oklch(60% 0.22 295);
        }
    }
}

@layer framework-settings {
    @media (dynamic-range: high) {
        :root {
            --color-primary: var(--color-primary-p3);
        }
    }
}

State-basierte CSS mit Pseudo-Klassen

Für StatefulTokens werden Pseudo-Klassen generiert:

.button-primary {
    background: oklch(70% 0.2 295);
}

.button-primary:hover {
    background: oklch(77% 0.2 295); /* Automatisch generiert */
}

.button-primary:active {
    background: oklch(59.5% 0.2 295); /* Automatisch generiert */
}

.button-primary:disabled {
    background: oklch(70% 0 295 / 0.5); /* Komponierte Mutation */
}

Verwendung

FrameworkTokenRegistry

Framework-weite Tokens:

use App\Framework\Design\ValueObjects\FrameworkTokenRegistry;

$registry = new FrameworkTokenRegistry();
$primaryColor = $registry->get('color-primary');

AdminTokenRegistry

Admin-spezifische Tokens:

use App\Application\Admin\ValueObjects\AdminTokenRegistry;

$registry = new AdminTokenRegistry();
$adminBg = $registry->get('admin-bg-primary');

Token generieren

# Framework Tokens generieren
php console.php design:generate-tokens --scope=framework

# Admin Tokens generieren
php console.php design:generate-tokens --scope=admin

# Beide generieren
npm run build  # Generiert automatisch beide vor dem Build

Best Practices

Farben definieren

  1. OKLCH verwenden: Perzeptuell uniforme Farbmanipulation
  2. ColorVariation nutzen: Zentrale Verwaltung von Light/Dark/P3
  3. HDR-Support: Automatische P3-Varianten für HDR-Displays

States definieren

  1. Basis-State: Immer einen DEFAULT State definieren
  2. Mutationen komponieren: Mehrere Mutationen kombinieren
  3. Konsistente Mutationen: Gleiche Mutationen für ähnliche States

Token-Organisation

  1. Scopes trennen: Framework vs. Admin Tokens
  2. Naming Convention: Klare, konsistente Namen
  3. Beschreibungen: Immer Beschreibungen hinzufügen

Erweiterte Features

Custom State Mutationen

// Komplexe Mutation: Desaturate + Opacity + Mix
$complexMutation = new StateMutation(
    saturationAdjustment: -0.5,
    opacityAdjustment: 0.7,
    mixColor: new CssColor('oklch(50% 0 0)', ColorFormat::OKLCH), // Grau
    mixWeight: 0.3
);

State-Hierarchien

// Disabled kann von Hover abgeleitet werden
$disabledFromHover = new StatefulColorToken(
    name: 'button-primary',
    variation: $primaryVariation,
    state: TokenState::DISABLED,
    baseState: TokenState::HOVER, // Basis ist Hover, nicht Default
    mutation: new StateMutation(
        saturationAdjustment: -1.0,
        opacityAdjustment: 0.5
    )
);

Performance

  • Caching: Generierte CSS wird gecacht
  • Lazy Loading: Tokens werden nur bei Bedarf geladen
  • Optimierte Konvertierung: OKLCH-Konvertierung ist optimiert

Browser-Unterstützung

  • OKLCH: Moderne Browser (Chrome 111+, Safari 15.4+, Firefox 113+)
  • Display P3: HDR-Displays mit Wide-Gamut-Support
  • Fallbacks: Automatische RGB/HEX-Fallbacks für ältere Browser

Migration von bestehenden Tokens

Bestehende Tokens können schrittweise migriert werden:

  1. ColorVariation erstellen: Light/Dark Varianten definieren
  2. States hinzufügen: Mutationen für States definieren
  3. CSS aktualisieren: Generierte CSS verwenden

Troubleshooting

Farben sehen falsch aus

  • Prüfe OKLCH-Werte (Lightness 0-1 oder 0-100%, Chroma 0-0.4+, Hue 0-360)
  • Verwende ColorManipulator für konsistente Manipulation

States funktionieren nicht

  • Prüfe ob Token StatefulTokenInterface implementiert
  • Prüfe ob Mutation korrekt definiert ist
  • Prüfe CSS-Output auf Pseudo-Klassen

CSS wird nicht generiert

  • Prüfe ob TokenRegistry korrekt initialisiert ist
  • Prüfe ob Output-Pfad existiert und beschreibbar ist
  • Prüfe Console-Output für Fehlermeldungen