You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

994 lines
42 KiB

<script setup lang="ts">
/**
* experimenta Design System Styleguide
* Internal page showing all design tokens and components
* Protected by Basic Auth via server/middleware/internal-auth.ts
*/
import { ref } from 'vue'
import { AlertCircle, CheckCircle } from 'lucide-vue-next'
import RoleSwitcher from '@/components/navigation/RoleSwitcher.vue'
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@/components/ui/select'
definePageMeta({
layout: 'styleguide',
})
// Sample button click handler for interactive examples
const handleClick = () => {
console.log('Button clicked!')
}
// Copy code snippet to clipboard
const copyCode = async (code: string) => {
try {
await navigator.clipboard.writeText(code)
alert('Code copied to clipboard!')
} catch (err) {
console.error('Failed to copy:', err)
}
}
// Select component examples state
const selectBasic = ref('')
const selectError = ref('')
const selectDisabled = ref('disabled-option')
const selectCountry = ref('DE')
</script>
<template>
<div class="min-h-screen py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-7xl mx-auto">
<!-- Header -->
<header class="mb-12">
<h1 class="text-5xl font-bold mb-4 text-experimenta-primary">my.experience Design System</h1>
<p class="text-xl text-white/90 mb-6">
Component library and design tokens for my.experimenta.science
</p>
<div class="flex gap-4">
<a href="/" class="link-accent"> Back to Homepage</a>
</div>
</header>
<!-- Table of Contents -->
<nav class="card-glass mb-12">
<h2 class="text-2xl font-semibold mb-4">Contents</h2>
<ul class="grid grid-cols-2 md:grid-cols-4 gap-4 text-white/90">
<li><a href="#overview" class="link-primary">Overview</a></li>
<li><a href="#colors" class="link-primary">Colors</a></li>
<li><a href="#typography" class="link-primary">Typography</a></li>
<li><a href="#buttons" class="link-primary">Buttons</a></li>
<li><a href="#cards" class="link-primary">Cards</a></li>
<li><a href="#forms" class="link-primary">Forms</a></li>
<li><a href="#links" class="link-primary">Links</a></li>
<li><a href="#status" class="link-primary">Status Messages</a></li>
<li><a href="#progress" class="link-primary">Progress Bars</a></li>
<li><a href="#components" class="link-primary">Components</a></li>
<li><a href="/internal/products-demo" class="link-accent"> Product Cards Demo</a></li>
<li><a href="/internal/product-detail-demo" class="link-accent"> Product Detail Demo</a></li>
</ul>
</nav>
<!-- Overview Section -->
<section id="overview" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Overview</h2>
<div class="card-info card-accent-border">
<h3 class="text-xl font-semibold mb-4">Design Principles</h3>
<ul class="list-disc list-inside space-y-2 text-white/90">
<li><strong>Mobile-First:</strong> All components optimized for mobile, then scaled up</li>
<li><strong>Accessibility:</strong> WCAG 2.1 AA compliance, keyboard navigation</li>
<li><strong>Brand Consistency:</strong> experimenta color palette and typography</li>
<li><strong>8px Grid:</strong> Spacing system based on 8px increments</li>
<li><strong>Dark Theme:</strong> Purple gradient background with high contrast text</li>
</ul>
</div>
</section>
<!-- Colors Section -->
<section id="colors" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Colors</h2>
<!-- Primary Colors -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Primary Colors</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div>
<div class="h-24 rounded-lg bg-experimenta-primary mb-2"></div>
<p class="font-mono text-sm text-white/90">#e6007e</p>
<p class="text-sm text-white/70">experimenta-primary</p>
</div>
<div>
<div class="h-24 rounded-lg bg-experimenta-accent mb-2"></div>
<p class="font-mono text-sm text-white/90">#f59d24</p>
<p class="text-sm text-white/70">experimenta-accent</p>
</div>
<div>
<div class="h-24 rounded-lg bg-experimenta-red mb-2"></div>
<p class="font-mono text-sm text-white/90">#e40521</p>
<p class="text-sm text-white/70">experimenta-red</p>
</div>
<div>
<div class="h-24 rounded-lg bg-white mb-2"></div>
<p class="font-mono text-sm text-black">#ffffff</p>
<p class="text-sm text-white/70">white</p>
</div>
</div>
</div>
<!-- Background Colors -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Background Colors (Purple Gradient)</h3>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
<div>
<div class="h-24 rounded-lg bg-purple-950 mb-2 border border-white/20"></div>
<p class="font-mono text-sm text-white/90">#2e1065</p>
<p class="text-sm text-white/70">purple-950</p>
</div>
<div>
<div class="h-24 rounded-lg bg-purple-975 mb-2 border border-white/20"></div>
<p class="font-mono text-sm text-white/90">#1a0a3a</p>
<p class="text-sm text-white/70">purple-975</p>
</div>
<div>
<div class="h-24 rounded-lg bg-purple-990 mb-2 border border-white/20"></div>
<p class="font-mono text-sm text-white/90">#0f051d</p>
<p class="text-sm text-white/70">purple-990</p>
</div>
</div>
</div>
<!-- Semantic Colors -->
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-4 text-white">Semantic Colors</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div>
<div class="h-24 rounded-lg bg-success mb-2"></div>
<p class="font-mono text-sm text-white/90">#10b981</p>
<p class="text-sm text-white/70">success</p>
</div>
<div>
<div class="h-24 rounded-lg bg-warning mb-2"></div>
<p class="font-mono text-sm text-white/90">#f59e0b</p>
<p class="text-sm text-white/70">warning</p>
</div>
<div>
<div class="h-24 rounded-lg bg-error mb-2"></div>
<p class="font-mono text-sm text-white/90">#ef4444</p>
<p class="text-sm text-white/70">error</p>
</div>
<div>
<div class="h-24 rounded-lg bg-info mb-2"></div>
<p class="font-mono text-sm text-white/90">#3b82f6</p>
<p class="text-sm text-white/70">info</p>
</div>
</div>
</div>
</section>
<!-- Typography Section -->
<section id="typography" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Typography</h2>
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Font Family</h3>
<p class="text-lg text-white/90 mb-2">
<strong>Roboto Variable Font</strong> - Locally hosted, weights 100-900
</p>
<p class="text-white/70">
Loaded from <code class="font-mono bg-white/10 px-2 py-1 rounded">/public/fonts/roboto/</code>
</p>
</div>
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Headings</h3>
<div class="space-y-4">
<div>
<h1 class="text-4xl font-bold">Heading 1 - 4xl Bold</h1>
<code class="text-sm text-white/70">text-4xl font-bold</code>
</div>
<div>
<h2 class="text-3xl font-bold">Heading 2 - 3xl Bold</h2>
<code class="text-sm text-white/70">text-3xl font-bold</code>
</div>
<div>
<h3 class="text-2xl font-semibold">Heading 3 - 2xl Semibold</h3>
<code class="text-sm text-white/70">text-2xl font-semibold</code>
</div>
<div>
<h4 class="text-xl font-semibold">Heading 4 - xl Semibold</h4>
<code class="text-sm text-white/70">text-xl font-semibold</code>
</div>
</div>
</div>
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-4 text-white">Body Text</h3>
<div class="space-y-4">
<div>
<p class="text-lg">Body Large - text-lg (1.125rem / 18px)</p>
<code class="text-sm text-white/70">text-lg</code>
</div>
<div>
<p class="text-base">Body Regular - text-base (1rem / 16px)</p>
<code class="text-sm text-white/70">text-base</code>
</div>
<div>
<p class="text-sm">Body Small - text-sm (0.875rem / 14px)</p>
<code class="text-sm text-white/70">text-sm</code>
</div>
<div>
<p class="text-xs">Body Extra Small - text-xs (0.75rem / 12px)</p>
<code class="text-sm text-white/70">text-xs</code>
</div>
</div>
</div>
</section>
<!-- Buttons Section -->
<section id="buttons" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Buttons</h2>
<!-- experimenta Button -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">experimenta Button (Official)</h3>
<p class="mb-6 text-white/90">
The official experimenta button with animated gradient effect (pink to red on hover).
</p>
<div class="flex flex-wrap gap-4 items-center mb-6">
<Button variant="experimenta" size="experimenta" @click="handleClick">
experimenta Button
</Button>
<Button variant="experimenta" size="experimenta" as="a" href="https://www.experimenta.science/">
As Link
</Button>
</div>
<details class="bg-white/5 p-4 rounded-lg">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;Button variant="experimenta" size="experimenta" @click="handleClick"&gt;
experimenta Button
&lt;/Button&gt;</code></pre>
</details>
</div>
<!-- Secondary Button (btn-secondary) -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Secondary Button (.btn-secondary)</h3>
<p class="mb-6 text-white/90">
Transparent button with white border. Perfect for secondary actions alongside primary buttons.
Features a smooth hover effect that fills with white background.
</p>
<div class="flex flex-wrap gap-4 items-center mb-6">
<a href="#" class="btn-secondary" @click.prevent="handleClick">
Secondary Action
</a>
<NuxtLink to="#" class="btn-secondary">
As NuxtLink
</NuxtLink>
</div>
<div class="bg-white/5 p-4 rounded-lg mb-4">
<p class="text-sm text-white/70 mb-2"><strong>Usage Example:</strong> Product detail pages</p>
<p class="text-sm text-white/70">
Use alongside primary "In den Warenkorb" button for actions like "Weitere Produkte ansehen".
The transparent background integrates beautifully with glassmorphism design.
</p>
</div>
<details class="bg-white/5 p-4 rounded-lg">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;!-- As Link --&gt;
&lt;a href="#" class="btn-secondary"&gt;
Secondary Action
&lt;/a&gt;
&lt;!-- As NuxtLink --&gt;
&lt;NuxtLink to="/products" class="btn-secondary"&gt;
Weitere Produkte ansehen
&lt;/NuxtLink&gt;</code></pre>
</details>
</div>
<!-- shadcn-nuxt Button Variants -->
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-4 text-white">shadcn-nuxt Button Variants</h3>
<p class="mb-6 text-white/90">All button variants from shadcn-nuxt component library:</p>
<div class="flex flex-wrap gap-4 mb-6">
<Button variant="default" @click="handleClick">Default</Button>
<Button variant="destructive" @click="handleClick">Destructive</Button>
<Button variant="outline" @click="handleClick">Outline</Button>
<Button variant="secondary" @click="handleClick">Secondary</Button>
<Button variant="ghost" @click="handleClick">Ghost</Button>
<Button variant="link" @click="handleClick">Link</Button>
</div>
<details class="bg-white/5 p-4 rounded-lg">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;Button variant="default"&gt;Default&lt;/Button&gt;
&lt;Button variant="destructive"&gt;Destructive&lt;/Button&gt;
&lt;Button variant="outline"&gt;Outline&lt;/Button&gt;
&lt;Button variant="secondary"&gt;Secondary&lt;/Button&gt;
&lt;Button variant="ghost"&gt;Ghost&lt;/Button&gt;
&lt;Button variant="link"&gt;Link&lt;/Button&gt;</code></pre>
</details>
</div>
</section>
<!-- Cards Section -->
<section id="cards" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Cards</h2>
<!-- Glass Card -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Glass Card (.card-glass)</h3>
<p class="text-white/90">
Semi-transparent card with glassmorphism effect. Perfect for content containers.
</p>
</div>
<!-- Info Card -->
<div class="card-info card-accent-border mb-8">
<h3 class="text-xl font-semibold mb-2 text-experimenta-accent">Info Card (.card-info .card-accent-border)</h3>
<p>Info section with Safrangold left border accent. Used for notices and information blocks.</p>
</div>
<!-- Progress Card -->
<div class="card-progress card-accent-border mb-8">
<div class="progress-header">
<h3 class="progress-title">Progress Card (.card-progress)</h3>
<div class="progress-stats">2963 / 4931</div>
</div>
<div class="progress-bar-wrapper">
<div class="progress-bar" style="width: 60.1%"></div>
<div class="progress-percentage">60.1%</div>
</div>
</div>
<!-- White Info Cards (like experimenta.science) -->
<div class="mb-8">
<h3 class="text-2xl font-semibold mb-6 text-white">White Info Cards (.card-white)</h3>
<p class="text-white/90 mb-6">
White content cards like on experimenta.science homepage. With pink links that have chevron arrows and hover
to orange.
</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="card-white">
<h3>Öffnungszeiten</h3>
<p>
Du möchtest nur in unsere Ausstellung, den Science Dome oder in die Sonderausstellung?
Oder doch lieber alles erleben? Weisst aber nicht wann? Hier findest du eine Übersicht
über unsere Öffnungszeiten.
</p>
<a href="#">Unsere Öffnungszeiten</a>
</div>
<div class="card-white">
<h3>Preise</h3>
<p>
Hier findest du einen Überblick über alle unsere Tickets, Preise und Ermäßigungen.
Wir haben verschiedene Angebote für dich je nach dem, wie oft du zu uns kommen und
was du erleben möchtest.
</p>
<a href="#">Zur Preisübersicht</a>
</div>
<div class="card-white">
<h3>Ticketshop</h3>
<p>
Du hast dich für ein Ticket entschieden? Dann kannst du es hier buchen.
Wir freuen uns auf deinen Besuch!
</p>
<a href="#">Jetzt Ticket kaufen</a>
</div>
<div class="card-white">
<h3>Anfahrt</h3>
<p>
Ob mit dem Auto, dem Zug, dem Reisebus oder der Stadtbahn: Es gibt viele Möglichkeiten
zu uns zu kommen. Hier haben wir für dich alle Informationen zur Anreise zusammengestellt.
</p>
<a href="#">Zur Anreise</a>
</div>
</div>
</div>
<details class="bg-white/5 p-4 rounded-lg card-glass">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;!-- Glass Card --&gt;
&lt;div class="card-glass"&gt;
&lt;h3&gt;Title&lt;/h3&gt;
&lt;p&gt;Content&lt;/p&gt;
&lt;/div&gt;
&lt;!-- Info Card with Accent Border --&gt;
&lt;div class="card-info card-accent-border"&gt;
&lt;h3&gt;Title&lt;/h3&gt;
&lt;p&gt;Content&lt;/p&gt;
&lt;/div&gt;
&lt;!-- Progress Card --&gt;
&lt;div class="card-progress card-accent-border"&gt;
&lt;div class="progress-header"&gt;
&lt;h3 class="progress-title"&gt;Title&lt;/h3&gt;
&lt;div class="progress-stats"&gt;2963 / 4931&lt;/div&gt;
&lt;/div&gt;
&lt;div class="progress-bar-wrapper"&gt;
&lt;div class="progress-bar" style="width: 60.1%"&gt;&lt;/div&gt;
&lt;div class="progress-percentage"&gt;60.1%&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- White Info Card --&gt;
&lt;div class="card-white"&gt;
&lt;h3&gt;Card Title&lt;/h3&gt;
&lt;p&gt;
Card description text goes here. Links automatically get
pink color with chevron arrow and hover to orange.
&lt;/p&gt;
&lt;a href="#"&gt;Link Text&lt;/a&gt;
&lt;/div&gt;</code></pre>
</details>
</section>
<!-- Forms Section -->
<section id="forms" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Forms</h2>
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-6 text-white">Form Elements</h3>
<div class="space-y-6">
<!-- Text Input -->
<div>
<label class="form-label">Text Input (.form-input)</label>
<input type="text" class="form-input" placeholder="Enter text..." />
</div>
<!-- Email Input -->
<div>
<label class="form-label">Email Input</label>
<input type="email" class="form-input" placeholder="email@example.com" />
</div>
<!-- Textarea -->
<div>
<label class="form-label">Textarea</label>
<textarea class="form-input" rows="4" placeholder="Enter message..."></textarea>
</div>
<!-- Checkbox -->
<div>
<label class="flex items-center gap-3">
<input type="checkbox" class="form-checkbox" checked />
<span class="text-white/90">Checkbox (.form-checkbox)</span>
</label>
</div>
<!-- Radio Buttons -->
<div>
<label class="form-label">Radio Buttons</label>
<div class="flex gap-4">
<label class="flex items-center gap-2">
<input type="radio" name="demo" class="form-checkbox" checked />
<span class="text-white/90">Option 1</span>
</label>
<label class="flex items-center gap-2">
<input type="radio" name="demo" class="form-checkbox" />
<span class="text-white/90">Option 2</span>
</label>
</div>
</div>
<!-- Select / Dropdown -->
<div>
<h4 class="text-xl font-semibold text-white mb-4">Select / Dropdown</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Basic Select -->
<div>
<label class="form-label">Basic Select</label>
<Select v-model="selectBasic">
<SelectTrigger>
<SelectValue placeholder="Bitte wählen" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Option 1</SelectItem>
<SelectItem value="option2">Option 2</SelectItem>
<SelectItem value="option3">Option 3</SelectItem>
</SelectContent>
</Select>
</div>
<!-- Select with Error -->
<div>
<label class="form-label">Select mit Fehler *</label>
<Select v-model="selectError">
<SelectTrigger variant="error">
<SelectValue placeholder="Bitte wählen" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Option 1</SelectItem>
<SelectItem value="option2">Option 2</SelectItem>
</SelectContent>
</Select>
<p class="form-error">
<AlertCircle class="w-4 h-4" />
Bitte wähle eine Option
</p>
</div>
<!-- Disabled Select -->
<div>
<label class="form-label">Disabled Select</label>
<Select v-model="selectDisabled" disabled>
<SelectTrigger>
<SelectValue placeholder="Nicht verfügbar" />
</SelectTrigger>
<SelectContent>
<SelectItem value="disabled-option">Option</SelectItem>
</SelectContent>
</Select>
</div>
<!-- Real-World Example (Country) -->
<div>
<label class="form-label">Land *</label>
<Select v-model="selectCountry">
<SelectTrigger>
<SelectValue placeholder="Land auswählen" />
</SelectTrigger>
<SelectContent>
<SelectItem value="DE">Deutschland</SelectItem>
<SelectItem value="AT">Österreich</SelectItem>
<SelectItem value="CH">Schweiz</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<details class="bg-white/5 p-4 rounded-lg mt-6">
<summary class="cursor-pointer text-white/90 font-semibold">Show Select Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;!-- Import --&gt;
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@/components/ui/select'
&lt;!-- Basic Select --&gt;
&lt;Select v-model="selectedValue"&gt;
&lt;SelectTrigger&gt;
&lt;SelectValue placeholder="Bitte wählen" /&gt;
&lt;/SelectTrigger&gt;
&lt;SelectContent&gt;
&lt;SelectItem value="option1"&gt;Option 1&lt;/SelectItem&gt;
&lt;SelectItem value="option2"&gt;Option 2&lt;/SelectItem&gt;
&lt;/SelectContent&gt;
&lt;/Select&gt;
&lt;!-- Error State --&gt;
&lt;SelectTrigger variant="error"&gt;
&lt;SelectValue placeholder="Bitte wählen" /&gt;
&lt;/SelectTrigger&gt;
&lt;!-- Disabled --&gt;
&lt;Select v-model="value" disabled&gt;
...
&lt;/Select&gt;
&lt;!-- Size Variants --&gt;
&lt;SelectTrigger size="sm"&gt;...&lt;/SelectTrigger&gt;
&lt;SelectTrigger size="default"&gt;...&lt;/SelectTrigger&gt;
&lt;SelectTrigger size="lg"&gt;...&lt;/SelectTrigger&gt;</code></pre>
</details>
</div>
<!-- Error Messages -->
<div>
<label class="form-label">Form mit Fehlermeldung</label>
<input type="email" class="form-input border-red-500/50" placeholder="deine.email@beispiel.de" />
<p class="form-error">Bitte gib eine gültige E-Mail-Adresse ein</p>
</div>
<!-- Error Message Styles -->
<div class="space-y-3 mt-6">
<h4 class="text-lg font-semibold text-white">Fehlermeldungen (.form-error)</h4>
<p class="text-sm text-white/70 mb-4">
Orange Border (WCAG AA konform) mit Icon für bessere Barrierefreiheit. Icon optional.
</p>
<p class="form-error">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="text-warning flex-shrink-0">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
Dies ist eine Fehlermeldung mit gutem Kontrast
</p>
<p class="form-error">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="text-warning flex-shrink-0">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
Dieses Feld ist erforderlich
</p>
<p class="form-error">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="text-warning flex-shrink-0">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
Das Passwort muss mindestens 8 Zeichen lang sein
</p>
</div>
</div>
<details class="bg-white/5 p-4 rounded-lg mt-6">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;label class="form-label"&gt;Text Input&lt;/label&gt;
&lt;input type="text" class="form-input" placeholder="Enter text..." /&gt;
&lt;label class="flex items-center gap-3"&gt;
&lt;input type="checkbox" class="form-checkbox" /&gt;
&lt;span&gt;Checkbox Label&lt;/span&gt;
&lt;/label&gt;</code></pre>
</details>
</div>
</section>
<!-- Links Section -->
<section id="links" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Links</h2>
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-6 text-white">Link Styles</h3>
<div class="space-y-4">
<div>
<a href="#" class="link-primary">Primary Link (.link-primary)</a>
<p class="text-sm text-white/70 mt-1">Orange color, used for general navigation (WCAG AA compliant, 4.62:1
contrast)</p>
</div>
<div>
<a href="#" class="link-accent">Accent Link (.link-accent)</a>
<p class="text-sm text-white/70 mt-1">Orange color, used for emphasis</p>
</div>
</div>
<details class="bg-white/5 p-4 rounded-lg mt-6">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;a href="#" class="link-primary"&gt;Primary Link&lt;/a&gt;
&lt;a href="#" class="link-accent"&gt;Accent Link&lt;/a&gt;</code></pre>
</details>
</div>
</section>
<!-- Status Messages Section -->
<section id="status" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Status Messages</h2>
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-6 text-white">Status Indicators</h3>
<p class="text-sm text-white/70 mb-6">
Einheitlicher Stil mit orange/grünem Border für bessere Barrierefreiheit. Alle verwenden den gleichen
Hintergrund mit farbigem Icon.
</p>
<div class="space-y-4">
<div class="status-message status-success">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="status-icon">
<circle cx="12" cy="12" r="10" />
<path d="m9 12 2 2 4-4" />
</svg>
<span>Erfolgsmeldung - Aktion wurde ausgeführt</span>
</div>
<div class="status-message status-warning">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="status-icon">
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
<path d="M12 9v4" />
<path d="M12 17h.01" />
</svg>
<span>Warnung - Bitte beachten</span>
</div>
<div class="status-message status-error">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="status-icon">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
<span>Fehlermeldung - Etwas ist schiefgelaufen</span>
</div>
<div class="status-message status-info">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="status-icon">
<circle cx="12" cy="12" r="10" />
<path d="M12 16v-4" />
<path d="M12 8h.01" />
</svg>
<span>Information - Nützlicher Hinweis</span>
</div>
</div>
<details class="bg-white/5 p-4 rounded-lg mt-6">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;div class="status-message status-success"&gt;
&lt;span class="status-icon"&gt;✓&lt;/span&gt;
&lt;span&gt;Success message&lt;/span&gt;
&lt;/div&gt;</code></pre>
</details>
</div>
</section>
<!-- Alert Components Section -->
<section id="alerts" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Alert Components</h2>
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-6 text-white">shadcn-nuxt Alert Variants</h3>
<p class="text-sm text-white/70 mb-6">
Alert-Komponenten für Benachrichtigungen und Fehlermeldungen. Die "error" Variante verwendet Orange für
bessere Barrierefreiheit (WCAG AA konform).
</p>
<div class="space-y-4">
<!-- Error Alert -->
<Alert variant="error">
<AlertCircle class="h-6 w-6" />
<AlertDescription>
Ungültige E-Mail-Adresse oder Passwort
</AlertDescription>
</Alert>
<!-- Success Alert -->
<Alert class="bg-white/15 border-l-4 border-success text-white">
<CheckCircle class="h-6 w-6 text-success" />
<AlertTitle class="text-success font-medium">Registrierung erfolgreich!</AlertTitle>
<AlertDescription>
Bitte bestätige deine E-Mail-Adresse über den Link, den wir dir gesendet haben.
</AlertDescription>
</Alert>
<!-- Destructive Alert (original red) -->
<Alert variant="destructive">
<AlertCircle class="h-5 w-5" />
<AlertTitle>Warnung</AlertTitle>
<AlertDescription>
Dies ist die ursprüngliche "destructive" Variante mit rotem Border.
</AlertDescription>
</Alert>
</div>
<details class="bg-white/5 p-4 rounded-lg mt-6">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;!-- Error Alert (empfohlen für Fehler) --&gt;
&lt;Alert variant="error"&gt;
&lt;AlertCircle class="h-6 w-6" /&gt;
&lt;AlertDescription&gt;
Ungültige E-Mail-Adresse oder Passwort
&lt;/AlertDescription&gt;
&lt;/Alert&gt;
&lt;!-- Success Alert --&gt;
&lt;Alert class="bg-white/15 border-l-4 border-success text-white"&gt;
&lt;CheckCircle class="h-6 w-6 text-success" /&gt;
&lt;AlertTitle class="text-success font-medium"&gt;Erfolg!&lt;/AlertTitle&gt;
&lt;AlertDescription&gt;
Deine Nachricht...
&lt;/AlertDescription&gt;
&lt;/Alert&gt;</code></pre>
</details>
</div>
</section>
<!-- Progress Bars Section -->
<section id="progress" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Progress Bars</h2>
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-6 text-white">Progress Indicators</h3>
<div class="space-y-6">
<div>
<p class="text-sm text-white/90 mb-2">25% Progress</p>
<div class="progress-bar-wrapper">
<div class="progress-bar" style="width: 25%"></div>
</div>
</div>
<div>
<p class="text-sm text-white/90 mb-2">50% Progress</p>
<div class="progress-bar-wrapper">
<div class="progress-bar" style="width: 50%"></div>
</div>
</div>
<div>
<p class="text-sm text-white/90 mb-2">75% Progress</p>
<div class="progress-bar-wrapper">
<div class="progress-bar" style="width: 75%"></div>
</div>
</div>
<div>
<p class="text-sm text-white/90 mb-2">100% Progress</p>
<div class="progress-bar-wrapper">
<div class="progress-bar" style="width: 100%"></div>
</div>
</div>
</div>
<details class="bg-white/5 p-4 rounded-lg mt-6">
<summary class="cursor-pointer text-white/90 font-semibold">Show Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;div class="progress-bar-wrapper"&gt;
&lt;div class="progress-bar" style="width: 60%"&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
</details>
</div>
</section>
<!-- Components Section -->
<section id="components" class="mb-16">
<h2 class="text-4xl font-bold mb-6 text-experimenta-accent">Components</h2>
<div class="card-info card-accent-border mb-8">
<h3 class="text-xl font-semibold mb-2 text-experimenta-accent">Available Components</h3>
<ul class="list-disc list-inside space-y-2 text-white/90">
<li><strong>CommonHeader</strong> - Main navigation header with experimenta logo</li>
<li><strong>CommonFooter</strong> - Footer with 4-column grid (links, contact, legal, social)</li>
<li><strong>Button</strong> - shadcn-nuxt Button component with 7 variants</li>
<li><strong>ProductCard</strong> - Mobile-optimized product card with image, badges, and CTA</li>
<li><strong>ProductGrid</strong> - Flexible grid layout for product listings (1-4 columns)</li>
</ul>
<p class="mt-4 text-sm text-white/70">
See individual component files in <code
class="font-mono bg-white/10 px-2 py-1 rounded">/app/components/</code>
</p>
</div>
<!-- Product Cards Demo Link -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Product Cards</h3>
<p class="text-white/90 mb-6">
Speziell gestaltete Produktkarten für Jahreskarten und andere Produkte der experimenta.
Mobile-First Design mit Glassmorphism-Effekten, optionalen Badges und animierten Hover-Effekten.
</p>
<div class="flex gap-4">
<NuxtLink to="/internal/products-demo" class="btn-experimenta">
Zur Product Cards Demo →
</NuxtLink>
</div>
</div>
<!-- Product Detail Demo Link -->
<div class="card-glass mb-8">
<h3 class="text-2xl font-semibold mb-4 text-white">Product Detail Page</h3>
<p class="text-white/90 mb-6">
Vollständige Produktdetailseite für Jahreskarten mit Hero-Image, Preis- und Verfügbarkeitsanzeige,
Feature-Liste und Call-to-Action Buttons. Zeigt alle Design-Patterns für Produktseiten.
</p>
<div class="flex gap-4">
<NuxtLink to="/internal/product-detail-demo" class="btn-experimenta">
Zur Product Detail Demo →
</NuxtLink>
</div>
</div>
<!-- Role Switcher Dropdown -->
<div class="card-glass">
<h3 class="text-2xl font-semibold mb-4 text-white">Role Switcher Dropdown</h3>
<p class="text-white/90 mb-6">
Rollen-Auswahl-Dropdown für Benutzer. Ermöglicht das Wechseln zwischen verschiedenen Benutzerrollen
(Privatperson, Pädagoge, Firma). Der Button zeigt die aktuelle Rolle und öffnet ein Dropdown-Menü mit allen
verfügbaren Optionen.
</p>
<!-- Live Example -->
<div class="mb-6 p-6 bg-purple-darker/50 rounded-xl border border-white/10">
<p class="text-sm text-white/70 mb-4">Live-Beispiel (interaktiv):</p>
<div class="flex justify-center">
<RoleSwitcher />
</div>
</div>
<!-- Design Features -->
<div class="bg-white/5 p-6 rounded-lg mb-6">
<h4 class="text-lg font-semibold text-white mb-4">Design Features</h4>
<ul class="space-y-2 text-white/90 text-sm">
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Button-Style:</strong> Transparenter Hintergrund mit weißem Border,
Glassmorphism-Effekt</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Kontext-Label:</strong> "Du kaufst als:" (nur Desktop, versteckt auf Mobile)</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Rolle mit Icon:</strong> Zeigt aktuelle Rolle mit passendem Icon (User, GraduationCap,
Building2)</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Dropdown-Breite:</strong> Fixe Breite von 312px für konsistentes Layout</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Menü-Items:</strong> Große, klickbare Items (py-3) mit Icon, Titel und Beschreibung</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Aktive Rolle:</strong> Markiert mit grünem Check-Icon und lila Hintergrund</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Deaktivierte Rollen:</strong> Opacity 60%, "Demnächst" Badge, cursor-not-allowed</span>
</li>
<li class="flex items-start gap-2">
<span class="mt-1 text-experimenta-accent">✓</span>
<span><strong>Footer-Hinweis:</strong> Informationstext mit Emoji am Ende des Dropdowns</span>
</li>
</ul>
</div>
<!-- Component Usage -->
<details class="bg-white/5 p-4 rounded-lg">
<summary class="cursor-pointer text-white/90 font-semibold">Show Component Code</summary>
<pre class="mt-4 text-sm text-white/80 overflow-x-auto"><code>&lt;!-- Import component --&gt;
&lt;script setup&gt;
import RoleSwitcher from '@/components/navigation/RoleSwitcher.vue'
&lt;/script&gt;
&lt;!-- Use in template --&gt;
&lt;template&gt;
&lt;RoleSwitcher /&gt;
&lt;/template&gt;</code></pre>
</details>
</div>
</section>
<!-- Footer -->
<footer class="mt-16 pt-8 border-t border-white/20 text-center text-white/70">
<p>my.experimenta Design System &copy; 2025</p>
<p class="text-sm mt-2">
For questions or updates, see
<a href="/docs/DESIGN_SYSTEM.md" class="link-primary" target="_blank">DESIGN_SYSTEM.md</a>
</p>
</footer>
</div>
</div>
</template>
<style scoped>
/* Additional scoped styles for styleguide page */
details summary {
transition: opacity 0.2s;
}
details summary:hover {
opacity: 0.8;
}
details[open] summary {
margin-bottom: 1rem;
}
</style>