Files
my2/docs/DESIGN_SYSTEM.md
Bastian Masanek d9f08bbef2 Enhance user communication and improve UI components
- Update CLAUDE.md to mandate informal "Du" form for user communication in all UI text and emails.
- Modify LoginForm and RegisterForm components to reflect informal language in validation messages and placeholders.
- Add secure connection indicators in LoginForm for user awareness.
- Update alert component styles for better visual feedback.
- Introduce experimenta company information document for user reference.
2025-10-31 17:28:07 +01:00

1296 lines
27 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.
# experimenta Design System
**Version:** 1.0
**Letzte Aktualisierung:** 2025-10-30
**Font:** Roboto (Open Source Alternative zu DIN OT)
Dieses Design System definiert die visuelle Identität und Komponenten-Bibliothek für **my.experimenta.science**. Es basiert auf dem Corporate Design der experimenta Science Center Website und den bereitgestellten Design-Vorlagen.
---
## ⚠️ Wichtiger Hinweis zu Schriftarten
**Wir verwenden Roboto statt der DIN OT Hausschrift.**
**Gründe:**
- **Open Source:** Roboto ist kostenlos und frei verfügbar
- **Web-Performance:** Optimiert für digitale Anwendungen
- **Ähnliche Optik:** Moderne, klare Sans-Serif ähnlich zu DIN OT
- **DSGVO-konform:** Lokales Hosting ohne externe CDN-Abhängigkeit (Google Fonts)
**Font-Hosting:**
- Die Roboto-Schrift wird lokal aus `/public/fonts/roboto/` geladen
- @font-face Deklarationen befinden sich in `assets/css/tailwind.css`
- Benötigte Weights: 300 (Light), 400 (Regular), 500 (Medium), 700 (Bold)
- Format: WOFF2 (beste Kompression, moderne Browser-Unterstützung)
---
## Inhaltsverzeichnis
1. [Farbpalette](#farbpalette)
2. [Typografie](#typografie)
3. [Spacing & Layout](#spacing--layout)
4. [Komponenten](#komponenten)
- [Buttons](#1-buttons)
- [Cards](#2-cards)
- [Status Messages](#3-status-messages)
- [Progress Bar](#4-progress-bar)
- [Forms](#5-forms)
- [Links](#6-links)
- [Logo](#7-logo)
- [Icons](#8-icons)
5. [Animationen & Transitions](#animationen--transitions)
6. [Accessibility](#accessibility)
---
## Farbpalette
### Primärfarben
**Experimenta Magenta** (Hauptfarbe)
```css
--color-primary: #e6007e;
--color-primary-hover: #c2006a;
--color-primary-light: #ff4081;
```
**Verwendung:** Primary Buttons, Links, aktive Zustände, Brand-Elemente
**Experimenta Pink**
```css
--color-secondary: #e91e63;
--color-secondary-dark: #c2185b;
```
**Verwendung:** Secondary Buttons, Footer Headings, Social Media Icons
**Experimenta Orange** (Akzent)
```css
--color-accent: #f59d24;
--color-accent-hover: #ffb347;
```
**Verwendung:** Border-Akzente (links), Hover-Effekte, Highlights, Labels
**Experimenta Rot** (Button-Gradient)
```css
--color-red: #e40521;
```
**Verwendung:** Button-Gradienten, Error-Zustände (zusammen mit Magenta)
### Background-Farben
**Dark Gradient** (Haupt-Background)
```css
--bg-gradient-primary: linear-gradient(135deg, #2e1065 0%, #1a0a3a 50%, #0f051d 100%);
```
**Purple Variants**
```css
--color-purple-dark: #2e1065; /* Start des Gradienten */
--color-purple-deeper: #1a0a3a; /* Mitte des Gradienten */
--color-purple-darkest: #0f051d; /* Ende des Gradienten */
```
**Header Background**
```css
--bg-header: rgba(46, 16, 101, 0.95); /* Mit backdrop-filter: blur(10px) */
```
**Footer Background**
```css
--bg-footer: linear-gradient(135deg, #1a0a3a 0%, #0f051d 100%);
```
### Glassmorphism (Cards & Containers)
```css
--glass-background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
--glass-backdrop: blur(15px);
--glass-border: 1px solid rgba(255, 255, 255, 0.2);
--glass-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
```
**Section Backgrounds (auf Glassmorphism Cards)**
```css
--bg-section: rgba(255, 255, 255, 0.08); /* Leicht heller als Card */
--bg-section-hover: rgba(255, 255, 255, 0.15);
```
### Semantische Farben
**Success**
```css
--color-success: #46c74a;
--color-success-dark: #3ba83e;
--color-success-gradient: linear-gradient(90deg, #46c74a 0%, #66d96a 50%, #46c74a 100%);
```
**Error**
```css
--color-error: #e53e3e;
--color-error-dark: #c53030;
```
**Warning**
```css
--color-warning: #f59d24;
--color-warning-dark: #dd8a1e;
```
**Info**
```css
--color-info: #4299e1;
--color-info-dark: #3182ce;
```
### Text-Farben
```css
--text-primary: #ffffff; /* Haupt-Text auf dunklem BG */
--text-secondary: rgba(255, 255, 255, 0.9); /* Sekundär-Text */
--text-muted: rgba(255, 255, 255, 0.8); /* Footer, Labels */
--text-disabled: rgba(255, 255, 255, 0.5); /* Disabled Elemente */
/* Text auf hellem Background (falls benötigt) */
--text-dark: #333333;
--text-dark-secondary: #666666;
```
### Border-Farben
```css
--border-accent: 4px solid #f59d24; /* Links-Border für Sections */
--border-light: 1px solid rgba(255, 255, 255, 0.2); /* Card Borders */
--border-footer: 1px solid rgba(255, 255, 255, 0.1); /* Footer Divider */
```
---
## Typografie
### Font-Family
**Roboto** (Open Source, ähnlich zu DIN OT, lokal gehostet)
```css
font-family: 'Roboto', sans-serif;
```
**Lokales Hosting:**
Die Roboto-Schrift wird lokal aus `/public/fonts/roboto/` geladen:
```bash
public/fonts/roboto/
├── Roboto-VariableFont-latin.woff2 # Variable Font (Weight 100-900)
└── roboto.css # @font-face Deklarationen
```
**Variable Font:** Wir nutzen eine einzige Variable Font Datei, die alle Weights von 100-900 abdeckt. Das bedeutet bessere Performance (nur eine Datei statt 4 separate Dateien) und nahtlose Übergänge zwischen Font-Weights.
**@font-face Deklarationen:** Siehe `assets/css/tailwind.css` (Zeile 15-40)
**Download:** Die Datei wurde bereits heruntergeladen. Falls neu benötigt: [Google Fonts - Roboto](https://fonts.google.com/specimen/Roboto) → Download → WOFF2 Format → Variable Font auswählen
**Gewichte:**
- `300` - Light (Headlines)
- `400` - Regular (Body Text)
- `500` - Medium (Buttons, Labels)
- `700` - Bold (Footer Links, Strong Text)
### Font-Scale (Desktop)
| Element | Size | Weight | Line Height | Letter Spacing |
| -------------- | ---- | ------ | ----------- | -------------- |
| **H1** | 36px | 300 | 1.2 | -1px |
| **H2** | 30px | 300 | 1.3 | -0.5px |
| **H3** | 24px | 400 | 1.4 | 0 |
| **H4** | 20px | 500 | 1.4 | 0 |
| **H5** | 18px | 500 | 1.5 | 0.5px |
| **H6** | 16px | 600 | 1.5 | 0.5px |
| **Body** | 18px | 400 | 1.7 | 0 |
| **Body Small** | 16px | 400 | 1.6 | 0 |
| **Caption** | 14px | 400 | 1.6 | 0 |
| **Tiny** | 12px | 400 | 1.5 | 0 |
### Responsive Font-Scale
**Tablet (≤768px):**
```css
H1: 28px
H2: 24px
H3: 20px
Body: 16px
```
**Mobile (≤480px):**
```css
H1: 24px
H2: 20px
H3: 18px
Body: 14px
```
### Tailwind Klassen
```html
<!-- Headlines -->
<h1 class="text-4xl md:text-3xl sm:text-2xl font-light tracking-tight">
<h2 class="text-3xl md:text-2xl sm:text-xl font-light">
<h3 class="text-2xl md:text-xl sm:text-lg font-normal">
<!-- Body Text -->
<p class="text-lg md:text-base sm:text-sm leading-relaxed">
<!-- Labels -->
<span class="text-lg md:text-base sm:text-sm font-medium tracking-wide"></span>
</p>
</h3>
</h2>
</h1>
```
---
## Spacing & Layout
### Spacing-System (8px Grid)
```css
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 30px;
--space-10: 40px;
--space-15: 60px;
--space-20: 80px;
```
### Container Max-Widths
```css
--container-main: 800px; /* Main Content (forms, text) */
--container-wide: 1200px; /* Footer, wide sections */
--container-full: 1760px; /* Full-width content (aus Website) */
```
### Border-Radius
```css
--radius-sm: 6px; /* Small elements (badges) */
--radius-md: 12px; /* Sections, Info-Cards */
--radius-lg: 15px; /* Standard Cards (mobile) */
--radius-xl: 20px; /* Standard Cards (desktop) */
--radius-2xl: 25px; /* Buttons */
--radius-full: 100%; /* Icons, Avatar */
```
### Breakpoints
```css
/* Mobile First */
--breakpoint-sm: 480px; /* Small phones */
--breakpoint-md: 768px; /* Tablets */
--breakpoint-lg: 1024px; /* Small desktops */
--breakpoint-xl: 1280px; /* Large desktops */
```
**Verwendung in Tailwind:**
```html
<!-- Mobile First: base = mobile, md = tablet, lg = desktop -->
<div class="p-4 md:p-8 lg:p-15"></div>
```
### Standard Paddings
**Cards:**
```css
/* Desktop */
padding: 60px 40px;
/* Tablet */
@media (max-width: 768px) {
padding: 40px 20px;
}
/* Mobile */
@media (max-width: 480px) {
padding: 30px 15px;
}
```
**Sections:**
```css
padding: 30px;
/* Tablet */
@media (max-width: 768px) {
padding: 25px 20px;
}
/* Mobile */
@media (max-width: 480px) {
padding: 20px 15px;
}
```
---
## Komponenten
### 1. Buttons
#### Primary Button
**Style:**
```css
background: #e6007e;
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
background-size: 300%;
color: #ffffff;
padding: 10px 30px;
border-radius: 25px;
font-size: 18px;
font-weight: 500;
transition:
background-position 1s,
all 0.3s ease;
/* Hover */
background-position: 100%;
```
**Tailwind:**
```html
<button class="btn-primary">Zur experimenta Startseite</button>
```
**CSS Klasse (Tailwind Config):**
```css
.btn-primary {
@apply bg-gradient-to-l from-primary via-red to-primary;
@apply bg-[length:300%] bg-left;
@apply text-white px-8 py-2.5 rounded-full;
@apply text-lg font-medium;
@apply transition-all duration-300;
@apply hover:bg-right;
}
```
#### Secondary Button
**Style:**
```css
background: transparent;
border: 2px solid rgba(255, 255, 255, 0.3);
color: #ffffff;
padding: 10px 30px;
border-radius: 25px;
font-size: 18px;
font-weight: 500;
transition: all 0.3s ease;
/* Hover */
background: #ffffff;
color: #2e1065; /* Dark purple text on white */
border-color: #ffffff;
```
**Tailwind:**
```html
<button class="btn-secondary">Abbrechen</button>
```
**CSS Klasse (Tailwind Config):**
```css
.btn-secondary {
@apply inline-block relative;
@apply px-[30px] py-[10px];
@apply text-lg font-medium text-white;
@apply rounded-[25px];
@apply bg-transparent border-2 border-white/30;
@apply transition-all duration-300;
@apply hover:bg-white hover:text-purple-darkest hover:border-white;
}
```
#### Destructive Button
**Verwendung:** Gefährliche/irreversible Aktionen (z.B. "Konto löschen", "Bestellung stornieren", "Aus Warenkorb entfernen")
**Style:**
```css
background: #ea5b0c;
background-image: linear-gradient(to left, #ea5b0c, #ea5b0c, #c7490a, #ea5b0c);
background-size: 300%;
color: #ffffff;
padding: 10px 30px;
border-radius: 25px;
font-size: 18px;
font-weight: 500;
transition: background-position 1s, all 0.3s ease;
/* Hover */
background-position: 100%;
```
**Tailwind:**
```html
<button class="btn-destructive">Aus Warenkorb entfernen</button>
```
**CSS Klasse (Tailwind Config):**
```css
.btn-destructive {
@apply inline-block relative;
@apply px-[30px] py-[10px];
@apply text-lg font-medium text-white;
@apply rounded-[25px];
@apply cursor-pointer;
@apply border-0 outline-0;
@apply no-underline;
background: #ea5b0c;
background-image: linear-gradient(to left, #ea5b0c, #ea5b0c, #c7490a, #ea5b0c);
background-size: 300%;
background-position: 0%;
line-height: 1.7em;
transition: background-position 1s, all 0.3s ease;
}
.btn-destructive:hover {
background-position: 100%;
}
```
**Design-Rationale:**
- **EXP Signalorange** (#ea5b0c) aus dem offiziellen experimenta Styleguide
- Signalisiert "Vorsicht" und "Gefahr" (stärker als gelbes Orange, weniger aggressiv als reines Rot)
- Konsistentes Animations-Pattern wie Primary Button (1s Gradient-Shift)
- Klar unterscheidbar vom Primary Button (Pink/Rot vs. Signal-Orange)
- Offizielle CI-Farbe für Warnungen und destruktive Aktionen
#### Button Sizes
```html
<!-- Large (default) -->
<button class="btn-primary text-lg px-8 py-2.5">
<!-- Medium -->
<button class="btn-primary text-base px-6 py-2">
<!-- Small (mobile) -->
<button class="btn-primary text-base px-6 py-2 md:px-8 md:py-2.5"></button>
</button>
</button>
```
---
### 2. Cards
#### Glass-morphism Card (Main Pattern)
**Style:**
```css
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
backdrop-filter: blur(15px);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
padding: 60px 40px;
```
**Tailwind:**
```html
<div class="card-glass">
<!-- Content -->
</div>
```
**CSS Klasse:**
```css
.card-glass {
@apply bg-gradient-to-br from-white/10 to-white/5;
@apply backdrop-blur-xl;
@apply rounded-2xl border border-white/20;
@apply shadow-2xl;
@apply p-15 md:p-10 sm:p-8;
}
```
#### Info Section Card
**Style:**
```css
background: rgba(255, 255, 255, 0.08);
border-radius: 12px;
padding: 30px;
border-left: 4px solid #f59d24;
```
**Tailwind:**
```html
<div class="card-info">
<h3 class="text-accent font-medium mb-4">Überschrift</h3>
<p class="text-white/90">Inhalt...</p>
</div>
```
**CSS Klasse:**
```css
.card-info {
@apply bg-white/8 rounded-xl;
@apply p-8 md:p-6 sm:p-5;
@apply border-l-4 border-accent;
}
```
---
### 3. Status Messages
#### Success Message
```html
<div class="status-message status-success">
<div class="status-icon"></div>
<h1>Verlängerung erfolgreich!</h1>
<p>Ihre Jahreskarte wurde verlängert.</p>
</div>
```
**CSS:**
```css
.status-icon {
@apply flex items-center justify-center;
@apply w-25 h-25 rounded-full;
@apply text-6xl text-white;
@apply mb-8;
@apply animate-pulse;
}
.status-success .status-icon {
@apply bg-success;
}
```
#### Error Message
```html
<div class="status-message status-error">
<div class="status-icon"></div>
<h1>Ein Fehler ist aufgetreten</h1>
<p>Bitte versuchen Sie es erneut.</p>
</div>
```
```css
.status-error .status-icon {
@apply bg-error;
}
```
---
### 4. Progress Bar
```html
<div class="progress-container">
<div class="progress-header">
<h3 class="progress-title">Verlängerungsfortschritt</h3>
<div class="progress-stats">5 / 10</div>
</div>
<div class="progress-bar-wrapper">
<div class="progress-bar" style="width: 50%"></div>
<div class="progress-percentage">50%</div>
</div>
</div>
```
**CSS:**
```css
.progress-container {
@apply bg-white/8 rounded-2xl;
@apply p-8 md:p-6;
@apply border-l-4 border-accent;
}
.progress-bar-wrapper {
@apply relative w-full h-8;
@apply bg-white/10 rounded-full;
@apply overflow-hidden;
@apply shadow-inner;
}
.progress-bar {
@apply h-full rounded-full;
@apply bg-gradient-to-r from-success via-[#66d96a] to-success;
@apply bg-[length:200%] animate-shimmer;
@apply transition-all duration-500;
}
.progress-percentage {
@apply absolute inset-0;
@apply flex items-center justify-center;
@apply text-base font-semibold text-white;
@apply drop-shadow-lg;
}
```
---
### 5. Forms
#### Input Field
```html
<div class="form-field">
<label for="email" class="form-label">E-Mail-Adresse</label>
<input type="email" id="email" class="form-input" placeholder="ihre.email@example.com" />
</div>
```
**CSS:**
```css
.form-label {
@apply block text-lg font-medium text-white/90;
@apply mb-3;
}
.form-input {
@apply w-full px-4 py-3;
@apply bg-white/10 border border-white/20;
@apply rounded-xl;
@apply text-white placeholder:text-white/50;
@apply focus:outline-none focus:ring-2 focus:ring-accent;
@apply transition-all duration-300;
}
.form-input:hover {
@apply bg-white/15;
}
```
#### Checkbox
```html
<label class="form-checkbox">
<input type="checkbox" class="checkbox-input" />
<span class="checkbox-label">Adresse für zukünftige Bestellungen speichern</span>
</label>
```
**CSS:**
```css
.form-checkbox {
@apply flex items-start gap-3 cursor-pointer;
}
.checkbox-input {
@apply w-5 h-5 mt-0.5;
@apply rounded border-2 border-white/30;
@apply bg-white/10;
@apply checked:bg-accent checked:border-accent;
@apply focus:ring-2 focus:ring-accent;
@apply cursor-pointer;
}
.checkbox-label {
@apply text-base text-white/90;
}
```
---
### 6. Links
```html
<a href="#" class="link-primary">Mehr erfahren</a> <a href="#" class="link-accent">Hier klicken</a>
```
**CSS:**
```css
.link-primary {
@apply text-primary underline;
@apply font-medium;
@apply transition-colors duration-300;
@apply hover:text-primary-light;
}
.link-accent {
@apply text-accent underline;
@apply font-medium;
@apply transition-colors duration-300;
@apply hover:text-accent-hover;
}
```
---
### 7. Logo
**SVG Logo** (Experimenta X-Logo)
Wird in den Design-Vorlagen verwendet. Sollte als Vue-Komponente gespeichert werden:
```vue
<!-- components/ExperimentaLogo.vue -->
<template>
<svg
class="logo"
viewBox="0 0 382.94 87.17"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<!-- SVG paths from design examples -->
</svg>
</template>
<style scoped>
.logo {
width: 300px;
height: auto;
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
}
/* Tablet */
@media (max-width: 768px) {
.logo {
width: 250px;
}
}
/* Mobile */
@media (max-width: 480px) {
.logo {
width: 200px;
}
}
</style>
```
---
### 8. Icons
**Icon Library:** [Lucide Vue Next](https://lucide.dev) (bereits installiert)
Das Projekt verwendet **lucide-vue-next** für alle Icons. Lucide bietet über 1.500+ hochwertige, konsistente Icons, die perfekt mit shadcn-nuxt und unserem Design System harmonieren.
#### Installation
```bash
# Bereits installiert in package.json
pnpm add lucide-vue-next
```
#### Verwendung
**Import:**
```vue
<script setup lang="ts">
// Named imports für tree-shaking (empfohlen)
import { Mail, Lock, CheckCircle, AlertCircle, Info, X } from 'lucide-vue-next'
</script>
<template>
<!-- Icon mit Standard-Größe -->
<Mail />
<!-- Icon mit Custom-Größe und Farbe -->
<Mail :size="24" class="text-accent" />
<!-- Icon mit Tailwind-Klassen -->
<CheckCircle class="w-6 h-6 text-success" />
</template>
```
#### Häufig verwendete Icons
```vue
<script setup lang="ts">
import {
// Auth & User
Mail,
Lock,
User,
UserCircle,
LogIn,
LogOut,
// Shopping
ShoppingCart,
CreditCard,
Package,
// Navigation
ChevronRight,
ChevronLeft,
ChevronDown,
Menu,
X,
// Status & Feedback
CheckCircle,
AlertCircle,
AlertTriangle,
Info,
XCircle,
// Actions
Trash2,
Edit,
Plus,
Minus,
Search,
} from 'lucide-vue-next'
</script>
```
#### Icons in Komponenten
**Alert mit Icon:**
```vue
<script setup lang="ts">
import { AlertCircle } from 'lucide-vue-next'
</script>
<template>
<Alert variant="error">
<AlertCircle class="h-4 w-4" />
<AlertTitle>Fehler</AlertTitle>
<AlertDescription> Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. </AlertDescription>
</Alert>
</template>
```
**Button mit Icon:**
```vue
<script setup lang="ts">
import { ShoppingCart } from 'lucide-vue-next'
</script>
<template>
<button class="btn-primary flex items-center gap-2">
<ShoppingCart :size="20" />
<span>In den Warenkorb</span>
</button>
</template>
```
**Login Form mit Icons:**
```vue
<script setup lang="ts">
import { Mail, Lock } from 'lucide-vue-next'
</script>
<template>
<form class="space-y-6">
<!-- E-Mail Input -->
<div class="form-field">
<label for="email" class="form-label flex items-center gap-2">
<Mail :size="18" class="text-accent" />
<span>E-Mail-Adresse</span>
</label>
<input type="email" id="email" class="form-input" />
</div>
<!-- Password Input -->
<div class="form-field">
<label for="password" class="form-label flex items-center gap-2">
<Lock :size="18" class="text-accent" />
<span>Passwort</span>
</label>
<input type="password" id="password" class="form-input" />
</div>
</form>
</template>
```
#### Icon-Größen
```vue
<!-- Extra Small (16px) -->
<Mail :size="16" />
<!-- Small (20px) - Standard für Buttons -->
<Mail :size="20" />
<!-- Medium (24px) - Standard für Inputs -->
<Mail :size="24" />
<!-- Large (32px) - Status Icons -->
<CheckCircle :size="32" />
<!-- Custom mit Tailwind -->
<Mail class="w-8 h-8" />
```
#### Icon-Farben
```vue
<!-- Experimenta Colors -->
<Mail class="text-experimenta-primary" />
<CheckCircle class="text-experimenta-accent" />
<AlertTriangle class="text-experimenta-red" />
<!-- Semantic Colors -->
<CheckCircle class="text-success" />
<AlertCircle class="text-error" />
<AlertTriangle class="text-warning" />
<Info class="text-info" />
<!-- White/Muted -->
<Mail class="text-white" />
<Mail class="text-white/90" />
<Mail class="text-white/70" />
```
#### Status Icons Pattern
Für Status-Meldungen verwenden wir konsistente Icons:
```vue
<script setup lang="ts">
import { CheckCircle, XCircle, AlertTriangle, Info } from 'lucide-vue-next'
</script>
<template>
<!-- Success -->
<div class="flex items-center gap-3 text-success">
<CheckCircle :size="24" />
<span>Erfolgreich!</span>
</div>
<!-- Error -->
<div class="flex items-center gap-3 text-error">
<XCircle :size="24" />
<span>Fehler aufgetreten</span>
</div>
<!-- Warning -->
<div class="flex items-center gap-3 text-warning">
<AlertTriangle :size="24" />
<span>Achtung!</span>
</div>
<!-- Info -->
<div class="flex items-center gap-3 text-info">
<Info :size="24" />
<span>Hinweis</span>
</div>
</template>
```
#### Best Practices
1. **Tree-Shaking:** Nutze Named Imports statt `import * as Icons`
```vue
✅ import { Mail, Lock } from 'lucide-vue-next'
❌ import * as Icons from 'lucide-vue-next'
```
2. **Accessibility:** Verwende `aria-label` wenn Icons ohne Text stehen
```vue
<button aria-label="Schließen">
<X :size="20" />
</button>
```
3. **Konsistenz:** Verwende innerhalb einer Komponente einheitliche Icon-Größen
4. **Farben:** Nutze Tailwind-Klassen für Farben statt inline-Styles
5. **Stroke Width:** Lucide Icons haben eine Standardstärke von 2. Für dünnere/dickere Linien:
```vue
<Mail :size="24" :stroke-width="1.5" />
```
#### Icon-Übersicht
Alle verfügbaren Icons: [https://lucide.dev/icons/](https://lucide.dev/icons/)
**Kategorien:**
- **Arrows & Chevrons:** ChevronRight, ArrowRight, ChevronDown
- **Shopping:** ShoppingCart, CreditCard, Package, Truck
- **User & Auth:** User, UserCircle, LogIn, LogOut, Lock, Key
- **Status:** CheckCircle, XCircle, AlertTriangle, Info
- **Actions:** Plus, Minus, Edit, Trash2, Search, Filter
- **Media:** Image, File, FileText, Download, Upload
- **Navigation:** Menu, X, Home, Settings, HelpCircle
---
## Animationen & Transitions
### Pulse (für Status Icons)
```css
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.animate-pulse {
animation: pulse 2s ease-in-out infinite;
}
```
### Shimmer (für Progress Bars)
```css
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
.animate-shimmer {
animation: shimmer 3s ease-in-out infinite;
}
```
### Button Gradient Animation
```css
.btn-primary {
background-size: 300%;
background-position: left;
transition:
background-position 1s ease,
all 0.3s ease;
}
.btn-primary:hover {
background-position: right;
}
```
### Hover Transitions
```css
/* Standard Hover */
.hover-scale {
@apply transition-transform duration-300;
@apply hover:scale-105;
}
/* Logo Hover */
.logo:hover {
transform: scale(1.05);
transition: all 0.3s ease;
}
/* Social Links Hover */
.social-link:hover {
transform: translateY(-3px);
transition: all 0.3s ease;
}
```
---
## Accessibility
### Farb-Kontraste
Alle Text-Farben wurden auf **WCAG AA Standard** getestet:
- **Weiß auf Dark Purple**: ✅ AAA (Kontrast > 7:1)
- **Magenta Buttons**: ✅ AA (Kontrast > 4.5:1)
- **Orange Akzente**: ✅ AA (Kontrast > 4.5:1)
### Focus States
```css
/* Alle interaktiven Elemente */
.focus-visible {
@apply focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2 focus:ring-offset-purple-darkest;
}
```
### Screen Reader Support
```html
<!-- Buttons -->
<button aria-label="Zur experimenta Startseite zurückkehren">Zurück</button>
<!-- Status Messages -->
<div role="alert" aria-live="polite">
<p>Ihre Jahreskarte wurde erfolgreich verlängert.</p>
</div>
```
### Keyboard Navigation
- **Tab-Reihenfolge**: Logisch von oben nach unten
- **Focus Indicators**: Sichtbarer Fokus-Ring auf allen interaktiven Elementen
- **Skip Links**: "Zum Hauptinhalt springen" Link am Anfang
---
## Verwendung in Nuxt 4
### 1. Tailwind Config importieren
Siehe `tailwind.config.ts` für die vollständige Theme-Konfiguration.
### 2. Komponenten verwenden
```vue
<template>
<div class="card-glass">
<div class="status-icon bg-success">✓</div>
<h1 class="text-4xl md:text-3xl sm:text-2xl font-light tracking-tight mb-8">Erfolgreich!</h1>
<p class="text-lg md:text-base leading-relaxed text-white/90">Ihre Aktion war erfolgreich.</p>
<button class="btn-primary mt-8">Weiter</button>
</div>
</template>
```
### 3. shadcn-nuxt Komponenten anpassen
Die shadcn-nuxt Komponenten können mit den experimenta-Farben überschrieben werden:
```vue
<!-- components/ui/button/Button.vue -->
<Button class="btn-primary">Click me</Button>
```
---
## Beispiel: Complete Page Layout
```vue
<template>
<div class="min-h-screen bg-gradient-primary">
<!-- Header -->
<header class="bg-header backdrop-blur-lg sticky top-0 z-50 py-8">
<div class="container-wide mx-auto px-5">
<ExperimentaLogo />
</div>
</header>
<!-- Main Content -->
<main class="container-main mx-auto px-5 py-10">
<div class="card-glass">
<!-- Success Icon -->
<div class="status-icon bg-success">✓</div>
<!-- Headline -->
<h1 class="text-4xl md:text-3xl sm:text-2xl font-light tracking-tight mb-8">
Verlängerung erfolgreich!
</h1>
<!-- Body Text -->
<p class="text-lg md:text-base leading-relaxed text-white/90 mb-6">
Ihre Pädagogische Jahreskarte wurde erfolgreich verlängert.
</p>
<!-- Info Section -->
<div class="card-info mt-8">
<h3 class="text-accent font-medium text-lg mb-4">Ihre Vorteile</h3>
<p class="text-white/90">
Mit der Jahreskarte erhalten Sie ein Jahr lang freien Eintritt...
</p>
</div>
<!-- Button -->
<button class="btn-primary mt-8">Zur experimenta Startseite</button>
</div>
</main>
<!-- Footer -->
<footer class="bg-footer mt-20">
<div class="container-wide mx-auto px-5 py-15">
<div
class="border-t border-white/10 pt-8 flex flex-wrap justify-between items-center gap-5"
>
<p class="text-white/80">
© 2025 experimenta gGmbH Das Science Center. Alle Rechte vorbehalten.
</p>
<div class="flex gap-8">
<a href="#" class="link-primary">Kontakt</a>
<a href="#" class="link-primary">Impressum</a>
<a href="#" class="link-primary">Datenschutz</a>
</div>
</div>
</div>
</footer>
</div>
</template>
```
---
## Weiterführende Ressourcen
- **Roboto Font:** [Google Fonts](https://fonts.google.com/specimen/Roboto)
- **Tailwind CSS v4:** [Tailwind Docs](https://tailwindcss.com/docs)
- **shadcn-nuxt:** [shadcn-nuxt Docs](https://www.shadcn-vue.com/docs/installation/nuxt.html)
- **WCAG Accessibility:** [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
---
**Maintainer:** Experimenta Team
**Fragen?** → `docs@experimenta.science`