Browse Source

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.
main
Bastian Masanek 2 months ago
parent
commit
d9f08bbef2
  1. 3
      .claude/settings.local.json
  2. 7
      CLAUDE.md
  3. 36
      app/components/Auth/LoginForm.vue
  4. 23
      app/components/Auth/RegisterForm.vue
  5. 4
      app/components/ui/alert/index.ts
  6. 8
      app/pages/auth.vue
  7. 4
      app/pages/internal/styleguide.vue
  8. 265
      docs/DESIGN_SYSTEM.md
  9. 281
      docs/EXPERIMENTA_INFO.md

3
.claude/settings.local.json

@ -50,7 +50,8 @@
"WebFetch(domain:docs.cidaas.com)", "WebFetch(domain:docs.cidaas.com)",
"WebFetch(domain:articles.cidaas.de)", "WebFetch(domain:articles.cidaas.de)",
"WebFetch(domain:pre-release-docs.cidaas.com)", "WebFetch(domain:pre-release-docs.cidaas.com)",
"mcp__playwright__browser_console_messages" "mcp__playwright__browser_console_messages",
"WebFetch(domain:nuxt.com)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

7
CLAUDE.md

@ -63,6 +63,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- **All code comments MUST be written in English** - **All code comments MUST be written in English**
- User-facing content (UI text, emails) should be in German - User-facing content (UI text, emails) should be in German
- **User communication MUST use informal "Du" form** (not formal "Sie" form)
- Examples: "Dein Konto", "Melde dich an", "Bestätige deine E-Mail"
- This applies to all UI text, form labels, buttons, messages, and emails
- Documentation should be in German (PRD, README) - Documentation should be in German (PRD, README)
## Tech Stack ## Tech Stack
@ -222,7 +225,7 @@ Ein Playwright MCP Server ist installiert und verfügbar für:
**Wann nutzen:** **Wann nutzen:**
- Nach Implementierung neuer UI-Komponenten - Nach Implementierung oder Änderung von UI-Komponenten
- Bei Layout-Anpassungen (besonders mobile vs. desktop) - Bei Layout-Anpassungen (besonders mobile vs. desktop)
- Zum Testen von Formularen und Interaktionen - Zum Testen von Formularen und Interaktionen
- Zur Validierung des gesamten Checkout-Flows - Zur Validierung des gesamten Checkout-Flows
@ -880,6 +883,8 @@ For complete implementation with all utilities (PKCE generator, Cidaas API clien
- **PRD:** See `docs/PRD.md` for complete requirements - **PRD:** See `docs/PRD.md` for complete requirements
- **Tech Stack:** See `docs/TECH_STACK.md` for technology decisions - **Tech Stack:** See `docs/TECH_STACK.md` for technology decisions
- **Architecture:** See `docs/ARCHITECTURE.md` for system design and data flows - **Architecture:** See `docs/ARCHITECTURE.md` for system design and data flows
- **experimenta Info:** See `docs/EXPERIMENTA_INFO.md` for company information (address, opening hours, legal links, contact details)
## Deployment ## Deployment

36
app/components/Auth/LoginForm.vue

@ -4,13 +4,14 @@
import { z } from 'zod' import { z } from 'zod'
import { useForm } from 'vee-validate' import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod' import { toTypedSchema } from '@vee-validate/zod'
import { AlertCircle, AlertTriangle, Loader2, ShieldCheck, ShieldAlert } from 'lucide-vue-next'
const { login } = useAuth() const { login } = useAuth()
// Validation schema // Validation schema
const loginSchema = toTypedSchema( const loginSchema = toTypedSchema(
z.object({ z.object({
email: z.string().email('Bitte geben Sie eine gültige E-Mail-Adresse ein'), email: z.string().email('Bitte gib eine gültige E-Mail-Adresse ein'),
password: z.string().min(8, 'Passwort muss mindestens 8 Zeichen lang sein'), password: z.string().min(8, 'Passwort muss mindestens 8 Zeichen lang sein'),
}) })
) )
@ -33,19 +34,30 @@ const onSubmit = handleSubmit(async (values) => {
} catch (error: any) { } catch (error: any) {
console.error('Login error:', error) console.error('Login error:', error)
// Error message is now directly in error.message (thrown by useAuth composable) // Error message is now directly in error.message (thrown by useAuth composable)
submitError.value = error.message || 'Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut.' submitError.value = error.message || 'Anmeldung fehlgeschlagen. Bitte versuche es erneut.'
} }
}) })
// Is the connection secure?
const isSecureConnection = computed(() => {
return window.location.protocol === 'https:'
})
</script> </script>
<template> <template>
<form @submit="onSubmit" class="space-y-6"> <form @submit="onSubmit" class="space-y-6">
<!-- Error Alert -->
<Alert v-if="submitError" variant="error">
<AlertCircle class="h-6 w-6" />
<AlertDescription>{{ submitError }}</AlertDescription>
</Alert>
<!-- Email Field --> <!-- Email Field -->
<FormField v-slot="{ componentField }" name="email"> <FormField v-slot="{ componentField }" name="email">
<FormItem> <FormItem>
<FormLabel class="text-white/90 text-base font-medium">E-Mail-Adresse</FormLabel> <FormLabel class="text-white/90 text-base font-medium">E-Mail-Adresse</FormLabel>
<FormControl> <FormControl>
<Input type="email" placeholder="ihre.email@beispiel.de" v-bind="componentField" /> <Input type="email" placeholder="deine.email@beispiel.de" v-bind="componentField" />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -62,21 +74,21 @@ const onSubmit = handleSubmit(async (values) => {
</FormItem> </FormItem>
</FormField> </FormField>
<!-- Error Alert -->
<Alert v-if="submitError" class="border-destructive bg-destructive/10 text-white">
<AlertCircle class="h-5 w-5 text-destructive" />
<AlertDescription class="text-white/90">{{ submitError }}</AlertDescription>
</Alert>
<!-- Submit Button --> <!-- Submit Button -->
<Button type="submit" variant="experimenta" size="experimenta" class="w-full" :disabled="isSubmitting"> <Button type="submit" variant="experimenta" size="experimenta" class="w-full" :disabled="isSubmitting">
<Loader2 v-if="isSubmitting" class="mr-2 h-5 w-5 animate-spin" /> <Loader2 v-if="isSubmitting" class="mr-2 h-5 w-5 animate-spin" />
{{ isSubmitting ? 'Wird angemeldet...' : 'Anmelden' }} {{ isSubmitting ? 'Wird angemeldet...' : 'Anmelden' }}
</Button> </Button>
<!-- Info Text --> <!-- Secure Connection Text -->
<p class="text-sm text-white/70 text-center"> <p v-if="!isSecureConnection" class="flex items-center justify-center gap-2 text-sm text-white/70">
Anmeldung erfolgt verschlüsselt über unseren Partner Cidaas <ShieldAlert :size="16" class="flex-shrink-0 text-error" />
<span class="text-error">Die Datenübertragung erfolgt NICHT verschlüsselt</span>
</p> </p>
<p v-else class="flex items-center justify-center gap-2 text-sm text-white/70">
<ShieldCheck :size="16" class="flex-shrink-0 text-success" />
<span class="text-success">Die Datenübertragung erfolgt verschlüsselt</span>
</p>
</form> </form>
</template> </template>

23
app/components/Auth/RegisterForm.vue

@ -4,13 +4,14 @@
import { z } from 'zod' import { z } from 'zod'
import { useForm } from 'vee-validate' import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod' import { toTypedSchema } from '@vee-validate/zod'
import { AlertCircle, CheckCircle, Loader2 } from 'lucide-vue-next'
const { register } = useAuth() const { register } = useAuth()
// Validation schema // Validation schema
const registerSchema = toTypedSchema( const registerSchema = toTypedSchema(
z.object({ z.object({
email: z.string().email('Bitte geben Sie eine gültige E-Mail-Adresse ein'), email: z.string().email('Bitte gib eine gültige E-Mail-Adresse ein'),
password: z password: z
.string() .string()
.min(8, 'Das Passwort muss mindestens 8 Zeichen lang sein') .min(8, 'Das Passwort muss mindestens 8 Zeichen lang sein')
@ -51,7 +52,7 @@ const onSubmit = handleSubmit(async (values) => {
if (error.status === 409) { if (error.status === 409) {
submitError.value = 'Diese E-Mail-Adresse ist bereits registriert.' submitError.value = 'Diese E-Mail-Adresse ist bereits registriert.'
} else { } else {
submitError.value = error.data?.message || 'Registrierung fehlgeschlagen. Bitte versuchen Sie es erneut.' submitError.value = error.data?.message || 'Registrierung fehlgeschlagen. Bitte versuche es erneut.'
} }
} }
}) })
@ -60,18 +61,18 @@ const onSubmit = handleSubmit(async (values) => {
<template> <template>
<form @submit="onSubmit" class="space-y-5"> <form @submit="onSubmit" class="space-y-5">
<!-- Success Alert --> <!-- Success Alert -->
<Alert v-if="submitSuccess" class="border-success bg-success/10 text-white"> <Alert v-if="submitSuccess" class="bg-white/15 border-l-4 border-success text-white">
<CheckCircle class="h-5 w-5 text-success" /> <CheckCircle class="h-6 w-6 text-success" />
<AlertTitle class="text-success font-medium">Registrierung erfolgreich!</AlertTitle> <AlertTitle class="text-success font-medium">Registrierung erfolgreich!</AlertTitle>
<AlertDescription class="text-white/90"> <AlertDescription>
Bitte bestätigen Sie Ihre E-Mail-Adresse über den Link, den wir Ihnen gesendet haben. Bitte bestätige deine E-Mail-Adresse über den Link, den wir dir gesendet haben.
</AlertDescription> </AlertDescription>
</Alert> </Alert>
<!-- Error Alert --> <!-- Error Alert -->
<Alert v-if="submitError" class="border-destructive bg-destructive/10 text-white"> <Alert v-if="submitError" variant="error">
<AlertCircle class="h-5 w-5 text-destructive" /> <AlertCircle class="h-6 w-6" />
<AlertDescription class="text-white/90">{{ submitError }}</AlertDescription> <AlertDescription>{{ submitError }}</AlertDescription>
</Alert> </Alert>
<!-- First Name --> <!-- First Name -->
@ -105,7 +106,7 @@ const onSubmit = handleSubmit(async (values) => {
<FormItem> <FormItem>
<FormLabel class="text-white/90 text-base font-medium">E-Mail-Adresse</FormLabel> <FormLabel class="text-white/90 text-base font-medium">E-Mail-Adresse</FormLabel>
<FormControl> <FormControl>
<Input type="email" placeholder="ihre.email@beispiel.de" v-bind="componentField" /> <Input type="email" placeholder="deine.email@beispiel.de" v-bind="componentField" />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>
@ -137,7 +138,7 @@ const onSubmit = handleSubmit(async (values) => {
<!-- Terms & Privacy --> <!-- Terms & Privacy -->
<p class="text-sm text-white/70 text-center"> <p class="text-sm text-white/70 text-center">
Mit der Registrierung stimmen Sie unserer Mit der Registrierung stimmst du unserer
<a href="/datenschutz" class="text-accent font-medium transition-all duration-300 hover:brightness-125"> <a href="/datenschutz" class="text-accent font-medium transition-all duration-300 hover:brightness-125">
Datenschutzerklärung Datenschutzerklärung
</a> </a>

4
app/components/ui/alert/index.ts

@ -6,13 +6,15 @@ export { default as AlertDescription } from './AlertDescription.vue'
export { default as AlertTitle } from './AlertTitle.vue' export { default as AlertTitle } from './AlertTitle.vue'
export const alertVariants = cva( export const alertVariants = cva(
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground', 'relative w-full rounded-lg border p-4 flex items-center gap-3 [&>svg]:shrink-0 [&>svg]:text-foreground',
{ {
variants: { variants: {
variant: { variant: {
default: 'bg-background text-foreground', default: 'bg-background text-foreground',
destructive: destructive:
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive', 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
error:
'bg-white/15 border-l-4 border-warning text-white [&>svg]:text-warning',
}, },
}, },
defaultVariants: { defaultVariants: {

8
app/pages/auth.vue

@ -31,7 +31,7 @@ onMounted(() => {
// Error message from OAuth callback // Error message from OAuth callback
const errorMessage = computed(() => { const errorMessage = computed(() => {
if (route.query.error === 'login_failed') { if (route.query.error === 'login_failed') {
return 'Login fehlgeschlagen. Bitte versuchen Sie es erneut.' return 'Login fehlgeschlagen. Bitte versuche es erneut.'
} }
return null return null
}) })
@ -51,7 +51,7 @@ definePageMeta({
Willkommen Willkommen
</h1> </h1>
<p class="mt-3 text-lg text-white/80"> <p class="mt-3 text-lg text-white/80">
Melden Sie sich an oder erstellen Sie ein Konto Melde dich an oder erstelle ein Konto
</p> </p>
</div> </div>
@ -79,7 +79,7 @@ definePageMeta({
<CardHeader class="px-0 pt-0"> <CardHeader class="px-0 pt-0">
<CardTitle class="text-2xl font-medium">Anmelden</CardTitle> <CardTitle class="text-2xl font-medium">Anmelden</CardTitle>
<CardDescription class="text-white/70 mt-2"> <CardDescription class="text-white/70 mt-2">
Melden Sie sich mit Ihrer E-Mail-Adresse an Melde dich mit deiner E-Mail-Adresse an
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent class="px-0 pb-0"> <CardContent class="px-0 pb-0">
@ -94,7 +94,7 @@ definePageMeta({
<CardHeader class="px-0 pt-0"> <CardHeader class="px-0 pt-0">
<CardTitle class="text-2xl font-medium">Konto erstellen</CardTitle> <CardTitle class="text-2xl font-medium">Konto erstellen</CardTitle>
<CardDescription class="text-white/70 mt-2"> <CardDescription class="text-white/70 mt-2">
Erstellen Sie ein neues experimenta-Konto Erstelle ein neues experimenta-Konto
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent class="px-0 pb-0"> <CardContent class="px-0 pb-0">

4
app/pages/internal/styleguide.vue

@ -435,8 +435,8 @@ const copyCode = async (code: string) => {
<!-- Error Messages --> <!-- Error Messages -->
<div> <div>
<label class="form-label">Form mit Fehlermeldung</label> <label class="form-label">Form mit Fehlermeldung</label>
<input type="email" class="form-input border-red-500/50" placeholder="ihre.email@beispiel.de" /> <input type="email" class="form-input border-red-500/50" placeholder="deine.email@beispiel.de" />
<p class="form-error">Bitte geben Sie eine gültige E-Mail-Adresse ein</p> <p class="form-error">Bitte gib eine gültige E-Mail-Adresse ein</p>
</div> </div>
<!-- Error Message Styles --> <!-- Error Message Styles -->

265
docs/DESIGN_SYSTEM.md

@ -32,6 +32,14 @@ Dieses Design System definiert die visuelle Identität und Komponenten-Bibliothe
2. [Typografie](#typografie) 2. [Typografie](#typografie)
3. [Spacing & Layout](#spacing--layout) 3. [Spacing & Layout](#spacing--layout)
4. [Komponenten](#komponenten) 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) 5. [Animationen & Transitions](#animationen--transitions)
6. [Accessibility](#accessibility) 6. [Accessibility](#accessibility)
@ -806,6 +814,263 @@ Wird in den Design-Vorlagen verwendet. Sollte als Vue-Komponente gespeichert wer
--- ---
### 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 ## Animationen & Transitions
### Pulse (für Status Icons) ### Pulse (für Status Icons)

281
docs/EXPERIMENTA_INFO.md

@ -0,0 +1,281 @@
# experimenta Unternehmensinformationen
Dieses Dokument enthält alle relevanten Informationen zum Unternehmen experimenta, die für die my.experimenta.science App verwendet werden.
**Version:** 1.0
**Letzte Aktualisierung:** 2025
---
## 1. Firmendaten
### 1.1 Firmenname & Rechtsform
- **Offizieller Name:** experimenta gGmbH
- **Rechtsform:** Gemeinnützige GmbH
- **Umsatzsteuer-ID:** DE 264 748 920
-- Sitz Heilbronn, Amtsgericht Stuttgart HRB 722941
### 1.2 Anschrift
```
experimenta gGmbH
Experimenta-Platz
74072 Heilbronn
Deutschland
```
**Zusätzliche Adressdetails:**
- **Straße & Hausnummer:** Experimenta-Platz
- **Postleitzahl:** 74072
- **Stadt:** Heilbronn
- **Bundesland:** Baden-Württemberg
- **Land:** Deutschland
### 1.3 Kontaktinformationen
**E-Mail:**
- **Allgemein:** info@experimenta.science
- **Vorsitzende des Aufssichtsrates:** Prof. Dr. Bärbel G. Renner
- **Geschäftsführung:** Dr. Franziska Lang, Nico Wiest
**Telefon:**
- **Telefon:** 07131 88795-0
- **Telefax:** 07131 88795-900
- **E-Mail:** info@experimenta.science
**Website:**
- **Hauptwebsite:** https://www.experimenta.science
- **Shop:** shop.experimenta.science
---
## 2. Öffnungszeiten
**Hinweis:** Bitte auf der offiziellen Website nach aktuellen Öffnungszeiten informieren, da diese saisonal variieren können.
### 2.1 Ausstellung und Science Dome, e1 KI-Pavillon, e3
**Öffnungszeiten:**
- **Montag bis Freitag:** 09:00 – 17:00 Uhr
- **Samstag, Sonntag und Feiertage:** 10:00 – 18:00 Uhr
### 2.2 Sternwarte, e1
**Öffnungszeiten:**
- **Montag bis Freitag:** 11:00 – 16:30 Uhr
- **Samstag und Sonntag:** 12:00 – 17:30 Uhr
### 2.3 Forum, e2
**Öffnungszeiten:**
- **Montag bis Freitag:** 9:00 – 17:00 Uhr
- **Samstag, Sonntag und Feiertage:** 10:00 – 18:00 Uhr
### 2.4 Maker Space, e2
**Öffnungszeiten:**
- **Dienstag bis Samstag:** 15:00 – 22:00 Uhr (auch in den Ferien und an Feiertagen)
- **Sonntag und Montag:** geschlossen
**Hinweis:** Der Maker Space ist besonders relevant für Makerspace-Jahreskarten.
### 2.5 Gastronomie
**Öffnungszeiten:**
- **Montag bis Freitag:** 11:00 – 17:30 Uhr
- **Samstag, Sonntag und Feiertage:** 11:00 – 18:30 Uhr
### 2.6 Shop / Osiander
**Öffnungszeiten:**
- **Montag bis Freitag:** 12:00 – 17:00 Uhr
- **Samstag und Sonntag:** 12:00 – 18:00 Uhr
### 2.7 Labore, e2
**Öffnungszeiten:**
- **Nur für angemeldete Gruppen**
---
## 3. Rechtliche Dokumente & Links
### 3.1 Allgemeine Geschäftsbedingungen (AGB)
**URL:** https://www.experimenta.science/agb/
**Hinweise:**
- AGB müssen bei Registrierung akzeptiert werden
- AGB müssen bei Checkout erneut bestätigt werden
- AGB für Online-Shop: [separate URL wenn vorhanden]
### 3.2 Datenschutzerklärung
**URL:** https://www.experimenta.science/datenschutz/
**Hinweise:**
- DSGVO-konform
- Datenschutzerklärung muss bei Registrierung akzeptiert werden
- Cookie-Hinweise gemäß DSGVO erforderlich
### 3.3 Impressum
**URL:** [eintragen wenn auf experimenta.science verfügbar]
**Inhalt:**
- Firmendaten (siehe Abschnitt 1.1 & 1.2)
- Geschäftsführer: [eintragen]
- Kontakt: [eintragen]
- Aufsichtsbehörde: [eintragen wenn relevant]
### 3.4 Widerrufsbelehrung
**URL:** [eintragen wenn vorhanden]
**Hinweise:**
- 14-tägiges Widerrufsrecht gemäß Verbraucherrecht
- Besondere Bedingungen für Jahreskarten: [eintragen wenn vorhanden]
### 3.5 Cookie-Richtlinie
**URL:** [eintragen wenn separat vorhanden]
---
## 4. Über experimenta
### 4.1 Beschreibung
experimenta ist Deutschlands größtes Science Center mit über 275 Mitmachstationen, vier Kreativstudios, neun Laboren und einer Sternwarte.
### 4.2 Angebote
**Hauptangebote:**
- Science Center mit interaktiven Ausstellungen
- Makerspace (Kreativwerkstatt)
- Labore für Workshops und Kurse
- Sternwarte
- Science Dome (360°-Fulldome-Theater)
- Jahreskarten für verschiedene Zielgruppen:
- Makerspace-Jahreskarten (Privatpersonen)
- Pädagogische Jahreskarten (für Lehrkräfte)
- [weitere Angebote ergänzen]
### 4.3 Zielgruppen
- **Privatpersonen:** Familien, Einzelbesucher
- **Bildungseinrichtungen:** Schulen, Kindergärten
- **Lehrkräfte:** Pädagogische Jahreskarten
- **Unternehmen:** Firmenveranstaltungen, Teamevents
---
## 5. Zahlungsinformationen
### 5.1 Akzeptierte Zahlungsmethoden
**Online-Shop (MVP):**
- PayPal
**Zukünftig (Post-MVP):**
- Kreditkarte
- Lastschrift
- [weitere Methoden ergänzen]
### 5.2 Preise & Währungen
- **Hauptwährung:** EUR (Euro)
- **Preisformat:** Dezimalstellen (z.B. 99,00 €)
- **Steuersatz:** 7% MwSt. (ermäßigter Satz für Jahreskarten)
---
## 6. Integration & Partner
### 6.1 Technische Partner
- **Authentifizierung:** Cidaas (Widas)
- **ERP-System:** Microsoft Dynamics NAV
- **Payment Provider:** PayPal (MVP)
- **Hosting:** Hetzner
### 6.2 Geschäftspartner
- [Partner ergänzen wenn relevant]
---
## 7. Social Media & Marketing
### 7.1 Social Media Kanäle
- **Facebook:** [eintragen]
- **Instagram:** [eintragen]
- **Twitter/X:** [eintragen]
- **YouTube:** [eintragen]
- **LinkedIn:** [eintragen]
### 7.2 Newsletter
- **Anmeldung:** [eintragen wenn vorhanden]
- **Datenschutz:** Gemäß Datenschutzerklärung
---
## 8. Support & Kundenservice
### 8.1 Support-Kanäle
**E-Mail:**
- info@experimenta.science
**Telefon:**
- 07131 88795-0
---
## 9. Corporate Design & Branding
### 9.1 Logo
- **Hauptlogo:** `/img/experimenta-logo-black.svg` (schwarz)
- **Logo weiß:** `/img/experimenta-logo-white.svg` (weiß)
- **Nutzung:** Siehe `docs/DESIGN_SYSTEM.md`
### 9.2 Brand Colors
Siehe `docs/DESIGN_SYSTEM.md` für vollständige Farbpalette:
- **Primary:** #e6007e (experimenta Pink)
- **Secondary:** [siehe Design System]
- **Destructive:** #ea5b0c (EXP Signalorange)
---
## 10. Verwendung in der App
### 10.1 Footer
Die Firmendaten werden im Footer (`app/components/CommonFooter.vue`) verwendet:
- Firmenname
- Anschrift
- Kontakt-E-Mail
- Links zu AGB, Datenschutz, Impressum
### 10.2 Registrierung & Checkout
- AGB-Link muss akzeptiert werden
- Datenschutzerklärung muss akzeptiert werden
- Widerrufsbelehrung muss angezeigt werden
### 10.3 E-Mails
**E-Mail-Templates sollten enthalten:**
- Firmenanschrift
- Kontaktinformationen
- Links zu AGB/Datenschutz
- Impressum-Hinweis
---
**Stand:** 31.10.2025
**Nächste Überprüfung:** [Datum]
Loading…
Cancel
Save