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
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><Button variant="experimenta" size="experimenta" @click="handleClick">
|
|
experimenta Button
|
|
</Button></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><!-- As Link -->
|
|
<a href="#" class="btn-secondary">
|
|
Secondary Action
|
|
</a>
|
|
|
|
<!-- As NuxtLink -->
|
|
<NuxtLink to="/products" class="btn-secondary">
|
|
Weitere Produkte ansehen
|
|
</NuxtLink></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><Button variant="default">Default</Button>
|
|
<Button variant="destructive">Destructive</Button>
|
|
<Button variant="outline">Outline</Button>
|
|
<Button variant="secondary">Secondary</Button>
|
|
<Button variant="ghost">Ghost</Button>
|
|
<Button variant="link">Link</Button></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><!-- Glass Card -->
|
|
<div class="card-glass">
|
|
<h3>Title</h3>
|
|
<p>Content</p>
|
|
</div>
|
|
|
|
<!-- Info Card with Accent Border -->
|
|
<div class="card-info card-accent-border">
|
|
<h3>Title</h3>
|
|
<p>Content</p>
|
|
</div>
|
|
|
|
<!-- Progress Card -->
|
|
<div class="card-progress card-accent-border">
|
|
<div class="progress-header">
|
|
<h3 class="progress-title">Title</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 Card -->
|
|
<div class="card-white">
|
|
<h3>Card Title</h3>
|
|
<p>
|
|
Card description text goes here. Links automatically get
|
|
pink color with chevron arrow and hover to orange.
|
|
</p>
|
|
<a href="#">Link Text</a>
|
|
</div></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><!-- Import -->
|
|
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@/components/ui/select'
|
|
|
|
<!-- Basic Select -->
|
|
<Select v-model="selectedValue">
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Bitte wählen" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="option1">Option 1</SelectItem>
|
|
<SelectItem value="option2">Option 2</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
|
|
<!-- Error State -->
|
|
<SelectTrigger variant="error">
|
|
<SelectValue placeholder="Bitte wählen" />
|
|
</SelectTrigger>
|
|
|
|
<!-- Disabled -->
|
|
<Select v-model="value" disabled>
|
|
...
|
|
</Select>
|
|
|
|
<!-- Size Variants -->
|
|
<SelectTrigger size="sm">...</SelectTrigger>
|
|
<SelectTrigger size="default">...</SelectTrigger>
|
|
<SelectTrigger size="lg">...</SelectTrigger></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><label class="form-label">Text Input</label>
|
|
<input type="text" class="form-input" placeholder="Enter text..." />
|
|
|
|
<label class="flex items-center gap-3">
|
|
<input type="checkbox" class="form-checkbox" />
|
|
<span>Checkbox Label</span>
|
|
</label></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><a href="#" class="link-primary">Primary Link</a>
|
|
<a href="#" class="link-accent">Accent Link</a></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><div class="status-message status-success">
|
|
<span class="status-icon">✓</span>
|
|
<span>Success message</span>
|
|
</div></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><!-- Error Alert (empfohlen für Fehler) -->
|
|
<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">Erfolg!</AlertTitle>
|
|
<AlertDescription>
|
|
Deine Nachricht...
|
|
</AlertDescription>
|
|
</Alert></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><div class="progress-bar-wrapper">
|
|
<div class="progress-bar" style="width: 60%"></div>
|
|
</div></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><!-- Import component -->
|
|
<script setup>
|
|
import RoleSwitcher from '@/components/navigation/RoleSwitcher.vue'
|
|
</script>
|
|
|
|
<!-- Use in template -->
|
|
<template>
|
|
<RoleSwitcher />
|
|
</template></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 © 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>
|
|
|