Init
This commit is contained in:
2241
docs/ARCHITECTURE.md
Normal file
2241
docs/ARCHITECTURE.md
Normal file
File diff suppressed because it is too large
Load Diff
2392
docs/CIDAAS_INTEGRATION.md
Normal file
2392
docs/CIDAAS_INTEGRATION.md
Normal file
File diff suppressed because it is too large
Load Diff
923
docs/DESIGN_SYSTEM.md
Normal file
923
docs/DESIGN_SYSTEM.md
Normal file
@@ -0,0 +1,923 @@
|
||||
# experimenta Design System
|
||||
|
||||
**Version:** 1.0
|
||||
**Letzte Aktualisierung:** 2025-10-29
|
||||
**Font:** Roboto (Open Source Alternative zu DIN OT)
|
||||
|
||||
Dieses Design System definiert die visuelle Identität und Komponenten-Bibliothek für **my.experimenta.science**. Es basiert auf dem Corporate Design der experimenta Science Center Website und den bereitgestellten Design-Vorlagen.
|
||||
|
||||
---
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
|
||||
1. [Farbpalette](#farbpalette)
|
||||
2. [Typografie](#typografie)
|
||||
3. [Spacing & Layout](#spacing--layout)
|
||||
4. [Komponenten](#komponenten)
|
||||
5. [Animationen & Transitions](#animationen--transitions)
|
||||
6. [Accessibility](#accessibility)
|
||||
|
||||
---
|
||||
|
||||
## Farbpalette
|
||||
|
||||
### Primärfarben
|
||||
|
||||
**Experimenta Magenta** (Hauptfarbe)
|
||||
|
||||
```css
|
||||
--color-primary: #e6007e;
|
||||
--color-primary-hover: #c2006a;
|
||||
--color-primary-light: #ff4081;
|
||||
```
|
||||
|
||||
**Verwendung:** Primary Buttons, Links, aktive Zustände, Brand-Elemente
|
||||
|
||||
**Experimenta Pink**
|
||||
|
||||
```css
|
||||
--color-secondary: #e91e63;
|
||||
--color-secondary-dark: #c2185b;
|
||||
```
|
||||
|
||||
**Verwendung:** Secondary Buttons, Footer Headings, Social Media Icons
|
||||
|
||||
**Experimenta Orange** (Akzent)
|
||||
|
||||
```css
|
||||
--color-accent: #f59d24;
|
||||
--color-accent-hover: #ffb347;
|
||||
```
|
||||
|
||||
**Verwendung:** Border-Akzente (links), Hover-Effekte, Highlights, Labels
|
||||
|
||||
**Experimenta Rot** (Button-Gradient)
|
||||
|
||||
```css
|
||||
--color-red: #e40521;
|
||||
```
|
||||
|
||||
**Verwendung:** Button-Gradienten, Error-Zustände (zusammen mit Magenta)
|
||||
|
||||
### Background-Farben
|
||||
|
||||
**Dark Gradient** (Haupt-Background)
|
||||
|
||||
```css
|
||||
--bg-gradient-primary: linear-gradient(135deg, #2e1065 0%, #1a0a3a 50%, #0f051d 100%);
|
||||
```
|
||||
|
||||
**Purple Variants**
|
||||
|
||||
```css
|
||||
--color-purple-dark: #2e1065; /* Start des Gradienten */
|
||||
--color-purple-deeper: #1a0a3a; /* Mitte des Gradienten */
|
||||
--color-purple-darkest: #0f051d; /* Ende des Gradienten */
|
||||
```
|
||||
|
||||
**Header Background**
|
||||
|
||||
```css
|
||||
--bg-header: rgba(46, 16, 101, 0.95); /* Mit backdrop-filter: blur(10px) */
|
||||
```
|
||||
|
||||
**Footer Background**
|
||||
|
||||
```css
|
||||
--bg-footer: linear-gradient(135deg, #1a0a3a 0%, #0f051d 100%);
|
||||
```
|
||||
|
||||
### Glassmorphism (Cards & Containers)
|
||||
|
||||
```css
|
||||
--glass-background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
--glass-backdrop: blur(15px);
|
||||
--glass-border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
--glass-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
```
|
||||
|
||||
**Section Backgrounds (auf Glassmorphism Cards)**
|
||||
|
||||
```css
|
||||
--bg-section: rgba(255, 255, 255, 0.08); /* Leicht heller als Card */
|
||||
--bg-section-hover: rgba(255, 255, 255, 0.15);
|
||||
```
|
||||
|
||||
### Semantische Farben
|
||||
|
||||
**Success**
|
||||
|
||||
```css
|
||||
--color-success: #46c74a;
|
||||
--color-success-dark: #3ba83e;
|
||||
--color-success-gradient: linear-gradient(90deg, #46c74a 0%, #66d96a 50%, #46c74a 100%);
|
||||
```
|
||||
|
||||
**Error**
|
||||
|
||||
```css
|
||||
--color-error: #e53e3e;
|
||||
--color-error-dark: #c53030;
|
||||
```
|
||||
|
||||
**Warning**
|
||||
|
||||
```css
|
||||
--color-warning: #f59d24;
|
||||
--color-warning-dark: #dd8a1e;
|
||||
```
|
||||
|
||||
**Info**
|
||||
|
||||
```css
|
||||
--color-info: #4299e1;
|
||||
--color-info-dark: #3182ce;
|
||||
```
|
||||
|
||||
### Text-Farben
|
||||
|
||||
```css
|
||||
--text-primary: #ffffff; /* Haupt-Text auf dunklem BG */
|
||||
--text-secondary: rgba(255, 255, 255, 0.9); /* Sekundär-Text */
|
||||
--text-muted: rgba(255, 255, 255, 0.8); /* Footer, Labels */
|
||||
--text-disabled: rgba(255, 255, 255, 0.5); /* Disabled Elemente */
|
||||
|
||||
/* Text auf hellem Background (falls benötigt) */
|
||||
--text-dark: #333333;
|
||||
--text-dark-secondary: #666666;
|
||||
```
|
||||
|
||||
### Border-Farben
|
||||
|
||||
```css
|
||||
--border-accent: 4px solid #f59d24; /* Links-Border für Sections */
|
||||
--border-light: 1px solid rgba(255, 255, 255, 0.2); /* Card Borders */
|
||||
--border-footer: 1px solid rgba(255, 255, 255, 0.1); /* Footer Divider */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Typografie
|
||||
|
||||
### Font-Family
|
||||
|
||||
**Roboto** (Open Source, ähnlich zu DIN OT)
|
||||
|
||||
```css
|
||||
font-family: 'Roboto', sans-serif;
|
||||
```
|
||||
|
||||
**Import:**
|
||||
|
||||
```html
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
```
|
||||
|
||||
**Gewichte:**
|
||||
|
||||
- `300` - Light (Headlines)
|
||||
- `400` - Regular (Body Text)
|
||||
- `500` - Medium (Buttons, Labels)
|
||||
- `700` - Bold (Footer Links, Strong Text)
|
||||
|
||||
### Font-Scale (Desktop)
|
||||
|
||||
| Element | Size | Weight | Line Height | Letter Spacing |
|
||||
| -------------- | ---- | ------ | ----------- | -------------- |
|
||||
| **H1** | 36px | 300 | 1.2 | -1px |
|
||||
| **H2** | 30px | 300 | 1.3 | -0.5px |
|
||||
| **H3** | 24px | 400 | 1.4 | 0 |
|
||||
| **H4** | 20px | 500 | 1.4 | 0 |
|
||||
| **H5** | 18px | 500 | 1.5 | 0.5px |
|
||||
| **H6** | 16px | 600 | 1.5 | 0.5px |
|
||||
| **Body** | 18px | 400 | 1.7 | 0 |
|
||||
| **Body Small** | 16px | 400 | 1.6 | 0 |
|
||||
| **Caption** | 14px | 400 | 1.6 | 0 |
|
||||
| **Tiny** | 12px | 400 | 1.5 | 0 |
|
||||
|
||||
### Responsive Font-Scale
|
||||
|
||||
**Tablet (≤768px):**
|
||||
|
||||
```css
|
||||
H1: 28px
|
||||
H2: 24px
|
||||
H3: 20px
|
||||
Body: 16px
|
||||
```
|
||||
|
||||
**Mobile (≤480px):**
|
||||
|
||||
```css
|
||||
H1: 24px
|
||||
H2: 20px
|
||||
H3: 18px
|
||||
Body: 14px
|
||||
```
|
||||
|
||||
### Tailwind Klassen
|
||||
|
||||
```html
|
||||
<!-- Headlines -->
|
||||
<h1 class="text-4xl md:text-3xl sm:text-2xl font-light tracking-tight">
|
||||
<h2 class="text-3xl md:text-2xl sm:text-xl font-light">
|
||||
<h3 class="text-2xl md:text-xl sm:text-lg font-normal">
|
||||
<!-- Body Text -->
|
||||
<p class="text-lg md:text-base sm:text-sm leading-relaxed">
|
||||
<!-- Labels -->
|
||||
<span class="text-lg md:text-base sm:text-sm font-medium tracking-wide"></span>
|
||||
</p>
|
||||
</h3>
|
||||
</h2>
|
||||
</h1>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Spacing & Layout
|
||||
|
||||
### Spacing-System (8px Grid)
|
||||
|
||||
```css
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 30px;
|
||||
--space-10: 40px;
|
||||
--space-15: 60px;
|
||||
--space-20: 80px;
|
||||
```
|
||||
|
||||
### Container Max-Widths
|
||||
|
||||
```css
|
||||
--container-main: 800px; /* Main Content (forms, text) */
|
||||
--container-wide: 1200px; /* Footer, wide sections */
|
||||
--container-full: 1760px; /* Full-width content (aus Website) */
|
||||
```
|
||||
|
||||
### Border-Radius
|
||||
|
||||
```css
|
||||
--radius-sm: 6px; /* Small elements (badges) */
|
||||
--radius-md: 12px; /* Sections, Info-Cards */
|
||||
--radius-lg: 15px; /* Standard Cards (mobile) */
|
||||
--radius-xl: 20px; /* Standard Cards (desktop) */
|
||||
--radius-2xl: 25px; /* Buttons */
|
||||
--radius-full: 100%; /* Icons, Avatar */
|
||||
```
|
||||
|
||||
### Breakpoints
|
||||
|
||||
```css
|
||||
/* Mobile First */
|
||||
--breakpoint-sm: 480px; /* Small phones */
|
||||
--breakpoint-md: 768px; /* Tablets */
|
||||
--breakpoint-lg: 1024px; /* Small desktops */
|
||||
--breakpoint-xl: 1280px; /* Large desktops */
|
||||
```
|
||||
|
||||
**Verwendung in Tailwind:**
|
||||
|
||||
```html
|
||||
<!-- Mobile First: base = mobile, md = tablet, lg = desktop -->
|
||||
<div class="p-4 md:p-8 lg:p-15"></div>
|
||||
```
|
||||
|
||||
### Standard Paddings
|
||||
|
||||
**Cards:**
|
||||
|
||||
```css
|
||||
/* Desktop */
|
||||
padding: 60px 40px;
|
||||
|
||||
/* Tablet */
|
||||
@media (max-width: 768px) {
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 480px) {
|
||||
padding: 30px 15px;
|
||||
}
|
||||
```
|
||||
|
||||
**Sections:**
|
||||
|
||||
```css
|
||||
padding: 30px;
|
||||
|
||||
/* Tablet */
|
||||
@media (max-width: 768px) {
|
||||
padding: 25px 20px;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 480px) {
|
||||
padding: 20px 15px;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Komponenten
|
||||
|
||||
### 1. Buttons
|
||||
|
||||
#### Primary Button
|
||||
|
||||
**Style:**
|
||||
|
||||
```css
|
||||
background: #e6007e;
|
||||
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
|
||||
background-size: 300%;
|
||||
color: #ffffff;
|
||||
padding: 10px 30px;
|
||||
border-radius: 25px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
transition:
|
||||
background-position 1s,
|
||||
all 0.3s ease;
|
||||
|
||||
/* Hover */
|
||||
background-position: 100%;
|
||||
```
|
||||
|
||||
**Tailwind:**
|
||||
|
||||
```html
|
||||
<button class="btn-primary">Zur experimenta Startseite</button>
|
||||
```
|
||||
|
||||
**CSS Klasse (Tailwind Config):**
|
||||
|
||||
```css
|
||||
.btn-primary {
|
||||
@apply bg-gradient-to-l from-primary via-red to-primary;
|
||||
@apply bg-[length:300%] bg-left;
|
||||
@apply text-white px-8 py-2.5 rounded-full;
|
||||
@apply text-lg font-medium;
|
||||
@apply transition-all duration-300;
|
||||
@apply hover:bg-right;
|
||||
}
|
||||
```
|
||||
|
||||
#### Secondary Button
|
||||
|
||||
```html
|
||||
<button class="btn-secondary">Abbrechen</button>
|
||||
```
|
||||
|
||||
```css
|
||||
.btn-secondary {
|
||||
@apply bg-transparent border-2 border-accent text-accent;
|
||||
@apply px-8 py-2.5 rounded-full;
|
||||
@apply text-lg font-medium;
|
||||
@apply transition-all duration-300;
|
||||
@apply hover:bg-accent hover:text-white;
|
||||
}
|
||||
```
|
||||
|
||||
#### Button Sizes
|
||||
|
||||
```html
|
||||
<!-- Large (default) -->
|
||||
<button class="btn-primary text-lg px-8 py-2.5">
|
||||
<!-- Medium -->
|
||||
<button class="btn-primary text-base px-6 py-2">
|
||||
<!-- Small (mobile) -->
|
||||
<button class="btn-primary text-base px-6 py-2 md:px-8 md:py-2.5"></button>
|
||||
</button>
|
||||
</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Cards
|
||||
|
||||
#### Glass-morphism Card (Main Pattern)
|
||||
|
||||
**Style:**
|
||||
|
||||
```css
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
backdrop-filter: blur(15px);
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
padding: 60px 40px;
|
||||
```
|
||||
|
||||
**Tailwind:**
|
||||
|
||||
```html
|
||||
<div class="card-glass">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
```
|
||||
|
||||
**CSS Klasse:**
|
||||
|
||||
```css
|
||||
.card-glass {
|
||||
@apply bg-gradient-to-br from-white/10 to-white/5;
|
||||
@apply backdrop-blur-xl;
|
||||
@apply rounded-2xl border border-white/20;
|
||||
@apply shadow-2xl;
|
||||
@apply p-15 md:p-10 sm:p-8;
|
||||
}
|
||||
```
|
||||
|
||||
#### Info Section Card
|
||||
|
||||
**Style:**
|
||||
|
||||
```css
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
border-left: 4px solid #f59d24;
|
||||
```
|
||||
|
||||
**Tailwind:**
|
||||
|
||||
```html
|
||||
<div class="card-info">
|
||||
<h3 class="text-accent font-medium mb-4">Überschrift</h3>
|
||||
<p class="text-white/90">Inhalt...</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
**CSS Klasse:**
|
||||
|
||||
```css
|
||||
.card-info {
|
||||
@apply bg-white/8 rounded-xl;
|
||||
@apply p-8 md:p-6 sm:p-5;
|
||||
@apply border-l-4 border-accent;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Status Messages
|
||||
|
||||
#### Success Message
|
||||
|
||||
```html
|
||||
<div class="status-message status-success">
|
||||
<div class="status-icon">✓</div>
|
||||
<h1>Verlängerung erfolgreich!</h1>
|
||||
<p>Ihre Jahreskarte wurde verlängert.</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
**CSS:**
|
||||
|
||||
```css
|
||||
.status-icon {
|
||||
@apply flex items-center justify-center;
|
||||
@apply w-25 h-25 rounded-full;
|
||||
@apply text-6xl text-white;
|
||||
@apply mb-8;
|
||||
@apply animate-pulse;
|
||||
}
|
||||
|
||||
.status-success .status-icon {
|
||||
@apply bg-success;
|
||||
}
|
||||
```
|
||||
|
||||
#### Error Message
|
||||
|
||||
```html
|
||||
<div class="status-message status-error">
|
||||
<div class="status-icon">✖</div>
|
||||
<h1>Ein Fehler ist aufgetreten</h1>
|
||||
<p>Bitte versuchen Sie es erneut.</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
```css
|
||||
.status-error .status-icon {
|
||||
@apply bg-error;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Progress Bar
|
||||
|
||||
```html
|
||||
<div class="progress-container">
|
||||
<div class="progress-header">
|
||||
<h3 class="progress-title">Verlängerungsfortschritt</h3>
|
||||
<div class="progress-stats">5 / 10</div>
|
||||
</div>
|
||||
|
||||
<div class="progress-bar-wrapper">
|
||||
<div class="progress-bar" style="width: 50%"></div>
|
||||
<div class="progress-percentage">50%</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**CSS:**
|
||||
|
||||
```css
|
||||
.progress-container {
|
||||
@apply bg-white/8 rounded-2xl;
|
||||
@apply p-8 md:p-6;
|
||||
@apply border-l-4 border-accent;
|
||||
}
|
||||
|
||||
.progress-bar-wrapper {
|
||||
@apply relative w-full h-8;
|
||||
@apply bg-white/10 rounded-full;
|
||||
@apply overflow-hidden;
|
||||
@apply shadow-inner;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
@apply h-full rounded-full;
|
||||
@apply bg-gradient-to-r from-success via-[#66d96a] to-success;
|
||||
@apply bg-[length:200%] animate-shimmer;
|
||||
@apply transition-all duration-500;
|
||||
}
|
||||
|
||||
.progress-percentage {
|
||||
@apply absolute inset-0;
|
||||
@apply flex items-center justify-center;
|
||||
@apply text-base font-semibold text-white;
|
||||
@apply drop-shadow-lg;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Forms
|
||||
|
||||
#### Input Field
|
||||
|
||||
```html
|
||||
<div class="form-field">
|
||||
<label for="email" class="form-label">E-Mail-Adresse</label>
|
||||
<input type="email" id="email" class="form-input" placeholder="ihre.email@example.com" />
|
||||
</div>
|
||||
```
|
||||
|
||||
**CSS:**
|
||||
|
||||
```css
|
||||
.form-label {
|
||||
@apply block text-lg font-medium text-white/90;
|
||||
@apply mb-3;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
@apply w-full px-4 py-3;
|
||||
@apply bg-white/10 border border-white/20;
|
||||
@apply rounded-xl;
|
||||
@apply text-white placeholder:text-white/50;
|
||||
@apply focus:outline-none focus:ring-2 focus:ring-accent;
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
.form-input:hover {
|
||||
@apply bg-white/15;
|
||||
}
|
||||
```
|
||||
|
||||
#### Checkbox
|
||||
|
||||
```html
|
||||
<label class="form-checkbox">
|
||||
<input type="checkbox" class="checkbox-input" />
|
||||
<span class="checkbox-label">Adresse für zukünftige Bestellungen speichern</span>
|
||||
</label>
|
||||
```
|
||||
|
||||
**CSS:**
|
||||
|
||||
```css
|
||||
.form-checkbox {
|
||||
@apply flex items-start gap-3 cursor-pointer;
|
||||
}
|
||||
|
||||
.checkbox-input {
|
||||
@apply w-5 h-5 mt-0.5;
|
||||
@apply rounded border-2 border-white/30;
|
||||
@apply bg-white/10;
|
||||
@apply checked:bg-accent checked:border-accent;
|
||||
@apply focus:ring-2 focus:ring-accent;
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
@apply text-base text-white/90;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. Links
|
||||
|
||||
```html
|
||||
<a href="#" class="link-primary">Mehr erfahren</a> <a href="#" class="link-accent">Hier klicken</a>
|
||||
```
|
||||
|
||||
**CSS:**
|
||||
|
||||
```css
|
||||
.link-primary {
|
||||
@apply text-primary underline;
|
||||
@apply font-medium;
|
||||
@apply transition-colors duration-300;
|
||||
@apply hover:text-primary-light;
|
||||
}
|
||||
|
||||
.link-accent {
|
||||
@apply text-accent underline;
|
||||
@apply font-medium;
|
||||
@apply transition-colors duration-300;
|
||||
@apply hover:text-accent-hover;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. Logo
|
||||
|
||||
**SVG Logo** (Experimenta X-Logo)
|
||||
|
||||
Wird in den Design-Vorlagen verwendet. Sollte als Vue-Komponente gespeichert werden:
|
||||
|
||||
```vue
|
||||
<!-- components/ExperimentaLogo.vue -->
|
||||
<template>
|
||||
<svg
|
||||
class="logo"
|
||||
viewBox="0 0 382.94 87.17"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<!-- SVG paths from design examples -->
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* Tablet */
|
||||
@media (max-width: 768px) {
|
||||
.logo {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 480px) {
|
||||
.logo {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Animationen & Transitions
|
||||
|
||||
### Pulse (für Status Icons)
|
||||
|
||||
```css
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-pulse {
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
```
|
||||
|
||||
### Shimmer (für Progress Bars)
|
||||
|
||||
```css
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-shimmer {
|
||||
animation: shimmer 3s ease-in-out infinite;
|
||||
}
|
||||
```
|
||||
|
||||
### Button Gradient Animation
|
||||
|
||||
```css
|
||||
.btn-primary {
|
||||
background-size: 300%;
|
||||
background-position: left;
|
||||
transition:
|
||||
background-position 1s ease,
|
||||
all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-position: right;
|
||||
}
|
||||
```
|
||||
|
||||
### Hover Transitions
|
||||
|
||||
```css
|
||||
/* Standard Hover */
|
||||
.hover-scale {
|
||||
@apply transition-transform duration-300;
|
||||
@apply hover:scale-105;
|
||||
}
|
||||
|
||||
/* Logo Hover */
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Social Links Hover */
|
||||
.social-link:hover {
|
||||
transform: translateY(-3px);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessibility
|
||||
|
||||
### Farb-Kontraste
|
||||
|
||||
Alle Text-Farben wurden auf **WCAG AA Standard** getestet:
|
||||
|
||||
- **Weiß auf Dark Purple**: ✅ AAA (Kontrast > 7:1)
|
||||
- **Magenta Buttons**: ✅ AA (Kontrast > 4.5:1)
|
||||
- **Orange Akzente**: ✅ AA (Kontrast > 4.5:1)
|
||||
|
||||
### Focus States
|
||||
|
||||
```css
|
||||
/* Alle interaktiven Elemente */
|
||||
.focus-visible {
|
||||
@apply focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2 focus:ring-offset-purple-darkest;
|
||||
}
|
||||
```
|
||||
|
||||
### Screen Reader Support
|
||||
|
||||
```html
|
||||
<!-- Buttons -->
|
||||
<button aria-label="Zur experimenta Startseite zurückkehren">Zurück</button>
|
||||
|
||||
<!-- Status Messages -->
|
||||
<div role="alert" aria-live="polite">
|
||||
<p>Ihre Jahreskarte wurde erfolgreich verlängert.</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Keyboard Navigation
|
||||
|
||||
- **Tab-Reihenfolge**: Logisch von oben nach unten
|
||||
- **Focus Indicators**: Sichtbarer Fokus-Ring auf allen interaktiven Elementen
|
||||
- **Skip Links**: "Zum Hauptinhalt springen" Link am Anfang
|
||||
|
||||
---
|
||||
|
||||
## Verwendung in Nuxt 4
|
||||
|
||||
### 1. Tailwind Config importieren
|
||||
|
||||
Siehe `tailwind.config.ts` für die vollständige Theme-Konfiguration.
|
||||
|
||||
### 2. Komponenten verwenden
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="card-glass">
|
||||
<div class="status-icon bg-success">✓</div>
|
||||
<h1 class="text-4xl md:text-3xl sm:text-2xl font-light tracking-tight mb-8">Erfolgreich!</h1>
|
||||
<p class="text-lg md:text-base leading-relaxed text-white/90">Ihre Aktion war erfolgreich.</p>
|
||||
|
||||
<button class="btn-primary mt-8">Weiter</button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 3. shadcn-nuxt Komponenten anpassen
|
||||
|
||||
Die shadcn-nuxt Komponenten können mit den experimenta-Farben überschrieben werden:
|
||||
|
||||
```vue
|
||||
<!-- components/ui/button/Button.vue -->
|
||||
<Button class="btn-primary">Click me</Button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Beispiel: Complete Page Layout
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="min-h-screen bg-gradient-primary">
|
||||
<!-- Header -->
|
||||
<header class="bg-header backdrop-blur-lg sticky top-0 z-50 py-8">
|
||||
<div class="container-wide mx-auto px-5">
|
||||
<ExperimentaLogo />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="container-main mx-auto px-5 py-10">
|
||||
<div class="card-glass">
|
||||
<!-- Success Icon -->
|
||||
<div class="status-icon bg-success">✓</div>
|
||||
|
||||
<!-- Headline -->
|
||||
<h1 class="text-4xl md:text-3xl sm:text-2xl font-light tracking-tight mb-8">
|
||||
Verlängerung erfolgreich!
|
||||
</h1>
|
||||
|
||||
<!-- Body Text -->
|
||||
<p class="text-lg md:text-base leading-relaxed text-white/90 mb-6">
|
||||
Ihre Pädagogische Jahreskarte wurde erfolgreich verlängert.
|
||||
</p>
|
||||
|
||||
<!-- Info Section -->
|
||||
<div class="card-info mt-8">
|
||||
<h3 class="text-accent font-medium text-lg mb-4">Ihre Vorteile</h3>
|
||||
<p class="text-white/90">
|
||||
Mit der Jahreskarte erhalten Sie ein Jahr lang freien Eintritt...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Button -->
|
||||
<button class="btn-primary mt-8">Zur experimenta Startseite</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="bg-footer mt-20">
|
||||
<div class="container-wide mx-auto px-5 py-15">
|
||||
<div
|
||||
class="border-t border-white/10 pt-8 flex flex-wrap justify-between items-center gap-5"
|
||||
>
|
||||
<p class="text-white/80">
|
||||
© 2025 experimenta gGmbH – Das Science Center. Alle Rechte vorbehalten.
|
||||
</p>
|
||||
<div class="flex gap-8">
|
||||
<a href="#" class="link-primary">Kontakt</a>
|
||||
<a href="#" class="link-primary">Impressum</a>
|
||||
<a href="#" class="link-primary">Datenschutz</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Weiterführende Ressourcen
|
||||
|
||||
- **Roboto Font:** [Google Fonts](https://fonts.google.com/specimen/Roboto)
|
||||
- **Tailwind CSS v4:** [Tailwind Docs](https://tailwindcss.com/docs)
|
||||
- **shadcn-nuxt:** [shadcn-nuxt Docs](https://www.shadcn-vue.com/docs/installation/nuxt.html)
|
||||
- **WCAG Accessibility:** [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
|
||||
|
||||
---
|
||||
|
||||
**Maintainer:** Experimenta Team
|
||||
**Fragen?** → `docs@experimenta.science`
|
||||
103
docs/EXPERIMENTA_BUTTON.md
Normal file
103
docs/EXPERIMENTA_BUTTON.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# experimenta Button Component
|
||||
|
||||
## Beschreibung
|
||||
|
||||
Der experimenta-Button ist eine spezielle Button-Variante, die das offizielle experimenta-Design umsetzt. Der Button verfügt über einen animierten Gradient-Effekt beim Hovern, der von Pink (#e6007e) zu Rot (#e40521) wechselt.
|
||||
|
||||
## Design-Eigenschaften
|
||||
|
||||
- **Farben**: Pink (#e6007e) zu Rot (#e40521) Gradient
|
||||
- **Border-Radius**: 25px (abgerundete Ecken)
|
||||
- **Padding**: 10px 30px (Desktop), 8px 24px (Mobile)
|
||||
- **Font-Size**: 18px (Desktop), 16px (Mobile)
|
||||
- **Hover-Effekt**: Animierter Gradient, der sich über 1 Sekunde von links nach rechts bewegt
|
||||
- **Transition**: Smooth transition für alle Eigenschaften (0.3s ease)
|
||||
|
||||
## Verwendung
|
||||
|
||||
### Als Button
|
||||
|
||||
```vue
|
||||
<UiButtonButton variant="experimenta" size="experimenta" @click="handleClick">
|
||||
Button Text
|
||||
</UiButtonButton>
|
||||
```
|
||||
|
||||
### Als Link
|
||||
|
||||
```vue
|
||||
<UiButtonButton variant="experimenta" size="experimenta" as="a" href="https://www.experimenta.science/">
|
||||
Zur experimenta Startseite
|
||||
</UiButtonButton>
|
||||
```
|
||||
|
||||
### Mit NuxtLink
|
||||
|
||||
```vue
|
||||
<UiButtonButton variant="experimenta" size="experimenta" as="NuxtLink" to="/some-page">
|
||||
Interne Seite
|
||||
</UiButtonButton>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
- **variant**: `"experimenta"` (erforderlich für das experimenta-Design)
|
||||
- **size**: `"experimenta"` (empfohlen für das richtige Padding und die Schriftgröße)
|
||||
- **as**: `"button"` (Standard) | `"a"` | `"NuxtLink"` - Element-Typ
|
||||
- **href** / **to**: URL/Route (wenn `as="a"` oder `as="NuxtLink"`)
|
||||
- **@click**: Event-Handler (wenn `as="button"`)
|
||||
|
||||
## Responsive Verhalten
|
||||
|
||||
Der Button passt sich automatisch an mobile Geräte an:
|
||||
- **Desktop**: 18px Schriftgröße, 10px 30px Padding
|
||||
- **Mobile (≤480px)**: 16px Schriftgröße, 8px 24px Padding
|
||||
|
||||
## Beispiel
|
||||
|
||||
Live-Beispiel auf der Startseite: `app/pages/index.vue`
|
||||
|
||||
## Technische Details
|
||||
|
||||
### Implementierung
|
||||
|
||||
Die Button-Komponente verwendet:
|
||||
- `class-variance-authority` (CVA) für Varianten-Management
|
||||
- `reka-ui` Primitive für Flexibilität
|
||||
- Custom CSS für den Gradient-Effekt (`assets/css/main.css`)
|
||||
- CSS Custom Properties für Farben (`--color-pink`, `--color-pink-dark`)
|
||||
|
||||
### Dateien
|
||||
|
||||
- **Komponente**: `app/components/ui/button/Button.vue`
|
||||
- **Varianten**: `app/components/ui/button/index.ts`
|
||||
- **Styles**: `assets/css/main.css` (`.btn-experimenta`)
|
||||
|
||||
## CSS-Implementierung
|
||||
|
||||
Der Gradient-Effekt wird mit Custom CSS implementiert:
|
||||
|
||||
```css
|
||||
.btn-experimenta {
|
||||
background: var(--color-pink);
|
||||
background-image: linear-gradient(to left, var(--color-pink), var(--color-pink), var(--color-pink-dark), var(--color-pink));
|
||||
background-size: 300%;
|
||||
background-position: 0%;
|
||||
transition: background-position 1s ease, all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-experimenta:hover {
|
||||
background-position: 100%;
|
||||
}
|
||||
```
|
||||
|
||||
## Barrierefreiheit
|
||||
|
||||
Der Button unterstützt:
|
||||
- ✅ Keyboard-Navigation (Tab, Enter, Space)
|
||||
- ✅ Focus-Styles
|
||||
- ✅ Screen-Reader (via Primitive-Komponente)
|
||||
- ✅ Disabled-State
|
||||
|
||||
|
||||
996
docs/PRD.md
Normal file
996
docs/PRD.md
Normal file
@@ -0,0 +1,996 @@
|
||||
# Product Requirements Document (PRD)
|
||||
|
||||
## my.experimenta.science E-Commerce App
|
||||
|
||||
**Version:** 1.0
|
||||
**Datum:** 28. Oktober 2025
|
||||
**Status:** Draft
|
||||
**Autor:** experimenta Development Team
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
### 1.1 Projektvision
|
||||
|
||||
Die **my.experimenta.science** App ist eine moderne, komponentenbasierte E-Commerce-Plattform für das experimenta Science Center. Sie soll den bestehenden Webshop zunächst ergänzen.
|
||||
|
||||
### 1.2 Ziele
|
||||
|
||||
**Primäre Ziele:**
|
||||
|
||||
- Vereinfachter Online-Verkauf von Makerspace-Jahreskarten
|
||||
- Mobile-first Nutzererlebnis mit exzellenter Desktop-Kompatibilität
|
||||
- Nahtlose Integration mit bestehenden Systemen (NAV ERP, Cidaas)
|
||||
- Skalierbare Architektur für zukünftige Produkterweiterungen
|
||||
|
||||
**Geschäftsziele:**
|
||||
|
||||
- Steigerung der Online-Verkäufe durch verbesserte UX
|
||||
- Reduzierung manueller Prozesse durch Automatisierung
|
||||
- Erhöhung der Kundenzufriedenheit
|
||||
- Grundlage für digitale Transformation des Ticketing-Systems
|
||||
|
||||
### 1.3 Erfolgsmetriken
|
||||
|
||||
- Erfolgreiche Verkäufe von Makerspace-Jahreskarten
|
||||
- Conversion Rate > 3%
|
||||
- Page Load Time < 2 Sekunden (mobile)
|
||||
- Fehlerfreie Synchronisation mit NAV ERP
|
||||
- Positive Nutzerfeedbacks
|
||||
|
||||
---
|
||||
|
||||
## 2. Produktübersicht
|
||||
|
||||
### 2.1 Was ist my.experimenta.science?
|
||||
|
||||
Eine spezialisierte E-Commerce-App, die es Besuchern des experimenta Science Centers ermöglicht, Produkte und Services online zu erwerben:
|
||||
|
||||
- Jahreskarten für den Makerspace
|
||||
- Pädagogische Jahreskarten (Post-MVP)
|
||||
- Experimenta-Tickets mit Platzreservierung (Post-MVP)
|
||||
- Laborkurse für Schulen (Post-MVP)
|
||||
|
||||
### 2.2 Abgrenzung
|
||||
|
||||
**Im Scope (MVP):**
|
||||
|
||||
- Registrierung und Login
|
||||
- Anzeige von Makerspace-Jahreskarten
|
||||
- Warenkorb-Funktionalität
|
||||
- Checkout-Prozess
|
||||
- PayPal-Bezahlung
|
||||
- NAV ERP Push-Integration
|
||||
|
||||
**Out of Scope (MVP):**
|
||||
|
||||
- Rollen-System (Pädagogen, Unternehmen)
|
||||
- Pädagogische Jahreskarten
|
||||
- Genehmigungsworkflows
|
||||
- Platzreservierung
|
||||
- Multi-Payment-Provider
|
||||
- Laborkurse
|
||||
|
||||
---
|
||||
|
||||
## 3. Zielgruppen
|
||||
|
||||
### 3.1 Primäre Zielgruppe (MVP)
|
||||
|
||||
**Privatpersonen:**
|
||||
|
||||
- Besucher des experimenta Science Centers
|
||||
- Interessenten am Makerspace
|
||||
- Alter: 18-65 Jahre
|
||||
- Technikaffinität: mittel bis hoch
|
||||
- Gerät: überwiegend Smartphone, teilweise Desktop
|
||||
|
||||
### 3.2 Zukünftige Zielgruppen (Post-MVP)
|
||||
|
||||
**Pädagogen/Erzieher:**
|
||||
|
||||
- Lehrkräfte an Schulen
|
||||
- Erzieher in Kindergärten
|
||||
- Benötigen Genehmigungsprozess für vergünstigte Tickets
|
||||
|
||||
**Unternehmen:**
|
||||
|
||||
- Firmen mit Interesse an Gruppenbesuchen
|
||||
- Corporate Events
|
||||
- Teambuilding-Maßnahmen
|
||||
|
||||
---
|
||||
|
||||
## 4. User Stories & Use Cases
|
||||
|
||||
### 4.1 MVP User Stories
|
||||
|
||||
#### US-001: Benutzerregistrierung
|
||||
|
||||
**Als** Besucher
|
||||
**möchte ich** mich mit meiner E-Mail-Adresse registrieren
|
||||
**damit** ich Produkte kaufen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Registrierungsformular mit Feldern: E-Mail, Passwort, Vorname, Nachname
|
||||
- Passwort-Anforderungen: mind. 8 Zeichen, Groß-/Kleinbuchstaben, Zahl
|
||||
- Registrierung erfolgt über Cidaas Registration API
|
||||
- Custom Registrierungs-Maske im experimenta Design (nicht Cidaas hosted)
|
||||
- Bestätigungs-E-Mail wird von Cidaas versendet
|
||||
- E-Mail muss bestätigt werden bevor Login möglich ist
|
||||
- Nach erster Anmeldung wird User-Profil in lokaler DB angelegt (über OAuth2 Callback)
|
||||
- User erhält Fehlermeldung wenn E-Mail bereits registriert
|
||||
- Validierung: Client-seitig (UX) + Server-seitig (Sicherheit)
|
||||
- Übersetzung in Deutsch und Englisch
|
||||
|
||||
**Technische Details:**
|
||||
|
||||
- Custom Registrierungsseite: `/auth?tab=register`
|
||||
- POST `/api/auth/register` → Cidaas Registration API
|
||||
- Response: "Bitte bestätigen Sie Ihre E-Mail"
|
||||
- User-Profil wird bei erstem Login erstellt (nicht bei Registrierung)
|
||||
|
||||
---
|
||||
|
||||
#### US-002: Benutzer-Login
|
||||
|
||||
**Als** registrierter Nutzer
|
||||
**möchte ich** mich mit meinen Zugangsdaten anmelden
|
||||
**damit** ich auf mein Profil und meine Bestellungen zugreifen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Custom Login-Maske im experimenta Design (nicht Cidaas hosted)
|
||||
- Login erfolgt über OAuth2 Authorization Code Flow mit PKCE
|
||||
- E-Mail-Adresse als Identifier (kein Benutzername)
|
||||
- Weiterleitung zur Cidaas Login-Seite für Credential-Eingabe
|
||||
- Nach erfolgreicher Authentifizierung: OAuth2 Callback
|
||||
- User-Profil wird in lokaler DB erstellt (erste Anmeldung) oder aktualisiert
|
||||
- Session wird erstellt (30 Tage Gültigkeit)
|
||||
- Automatische Weiterleitung zur ursprünglich angeforderten Seite (oder Homepage)
|
||||
- Bei fehlgeschlagenem Login: Klare Fehlermeldung
|
||||
- Rate Limiting: Max. 5 Login-Versuche pro 15 Minuten
|
||||
- "Passwort vergessen"-Link zu Cidaas Password Reset
|
||||
|
||||
**Technische Details:**
|
||||
|
||||
- Custom Login-Seite: `/auth?tab=login`
|
||||
- OAuth2 Flow:
|
||||
1. POST `/api/auth/login` → Redirect zu Cidaas
|
||||
2. User authentifiziert sich bei Cidaas
|
||||
3. Cidaas redirected zu `/api/auth/callback?code=xxx`
|
||||
4. Server exchanged code für tokens
|
||||
5. User-Profil wird aus Cidaas UserInfo geholt
|
||||
6. User-Profil in DB erstellt/aktualisiert (via `experimenta_id`)
|
||||
7. Encrypted session cookie gesetzt
|
||||
8. Redirect zu Homepage
|
||||
- Session: HTTP-only, Secure, SameSite=Lax, 30 Tage
|
||||
|
||||
---
|
||||
|
||||
#### US-002a: Benutzer-Logout
|
||||
|
||||
**Als** angemeldeter Nutzer
|
||||
**möchte ich** mich sicher abmelden
|
||||
**damit** meine Daten geschützt bleiben (besonders auf gemeinsam genutzten Geräten)
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Logout-Button ist im Benutzerm enü prominent platziert
|
||||
- Klick auf Logout löscht die Session sofort
|
||||
- User wird zur Homepage weitergeleitet
|
||||
- Session-Cookie wird vollständig entfernt
|
||||
- Nach Logout ist kein Zugriff auf geschützte Bereiche mehr möglich
|
||||
- Optional: Single Sign-Out bei Cidaas (Logout aus allen Apps)
|
||||
|
||||
**Technische Details:**
|
||||
|
||||
- POST `/api/auth/logout`
|
||||
- `clearUserSession(event)` löscht Session-Cookie
|
||||
- Redirect zu `/`
|
||||
|
||||
---
|
||||
|
||||
#### US-002b: Session-Management
|
||||
|
||||
**Als** angemeldeter Nutzer
|
||||
**möchte ich** dass meine Session sicher verwaltet wird
|
||||
**damit** ich nicht nach jeder Interaktion neu anmelden muss, aber dennoch geschützt bin
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Session bleibt 30 Tage gültig (configurable)
|
||||
- Session wird bei jeder Interaktion automatisch verlängert (sliding expiration)
|
||||
- Session-Cookie ist verschlüsselt (AES-256-GCM)
|
||||
- Session-Cookie ist HTTP-only (nicht via JavaScript auslesbar)
|
||||
- Session-Cookie nur über HTTPS übertragen (Secure flag)
|
||||
- CSRF-Schutz durch SameSite=Lax Cookie-Attribut
|
||||
- Nach Ablauf der Session: Automatisches Logout + Weiterleitung zu `/auth`
|
||||
- User sieht Meldung: "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an."
|
||||
|
||||
**Technische Details:**
|
||||
|
||||
- Session Implementierung: `nuxt-auth-utils` Module
|
||||
- Cookie Name: `experimenta-session`
|
||||
- Verschlüsselung: AES-256-GCM via `nuxt-auth-utils`
|
||||
- Max-Age: 2592000 Sekunden (30 Tage)
|
||||
|
||||
---
|
||||
|
||||
#### US-002c: Geschützte Bereiche
|
||||
|
||||
**Als** System
|
||||
**möchte ich** dass bestimmte Bereiche nur für angemeldete Nutzer zugänglich sind
|
||||
**damit** nicht-autorisierte Zugriffe verhindert werden
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Geschützte Bereiche: Profil, Bestellhistorie, Checkout (teilweise)
|
||||
- Unangemeldete User werden zu `/auth` weitergeleitet
|
||||
- Nach erfolgreichem Login: Automatische Weiterleitung zur ursprünglich angeforderten Seite
|
||||
- Ursprüngliche URL wird temporär gespeichert (max. 10 Minuten)
|
||||
- API-Endpoints prüfen Session und geben 401 bei fehlender Authentifizierung
|
||||
- Klare visuelle Kennzeichnung geschützter Bereiche (z.B. Schloss-Icon)
|
||||
|
||||
**Technische Details:**
|
||||
|
||||
- Middleware: `middleware/auth.ts`
|
||||
- Usage: `definePageMeta({ middleware: 'auth' })`
|
||||
- Redirect-Cookie: `redirect_after_login` (10min TTL)
|
||||
- Protected API: `requireUserSession(event)` wirft 401
|
||||
|
||||
---
|
||||
|
||||
#### US-002d: Sicherheit & Rate Limiting
|
||||
|
||||
**Als** System
|
||||
**möchte ich** dass Authentifizierungs-Endpoints vor Missbrauch geschützt sind
|
||||
**damit** Brute-Force-Angriffe und Spam verhindert werden
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Login: Max. 5 Versuche pro 15 Minuten pro IP-Adresse
|
||||
- Registrierung: Max. 3 Versuche pro Stunde pro IP-Adresse
|
||||
- Bei Überschreitung: HTTP 429 (Too Many Requests) mit Retry-After Header
|
||||
- Klare Fehlermeldung: "Zu viele Versuche. Bitte versuchen Sie es in X Sekunden erneut."
|
||||
- Rate Limit-Zähler wird bei erfolgreichem Login zurückgesetzt
|
||||
- PKCE (Proof Key for Code Exchange) wird für OAuth2 verwendet
|
||||
- State-Parameter schützt vor CSRF-Angriffen
|
||||
- JWT-Tokens von Cidaas werden validiert (Signatur, Expiration, Issuer, Audience)
|
||||
|
||||
**Technische Details:**
|
||||
|
||||
- Rate Limiting Middleware: `server/middleware/rate-limit.ts`
|
||||
- In-Memory Store für Rate Limits (Production: Redis empfohlen)
|
||||
- PKCE: Code verifier (64 chars random) → SHA-256 Challenge
|
||||
- State: 32 bytes random string, validiert im Callback
|
||||
- JWT Validation: `jose` Library mit JWKS Caching
|
||||
|
||||
---
|
||||
|
||||
#### US-003: Makerspace-Jahreskarte ansehen
|
||||
|
||||
**Als** Nutzer
|
||||
**möchte ich** Details zur Makerspace-Jahreskarte sehen
|
||||
**damit** ich informiert eine Kaufentscheidung treffen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Produktseite zeigt: Name, Beschreibung, Preis, Bild
|
||||
- Informationen kommen aus der lokalen DB (synchronisiert von NAV)
|
||||
- Call-to-Action: "In den Warenkorb"
|
||||
- Mobile-optimierte Darstellung
|
||||
|
||||
---
|
||||
|
||||
#### US-004: Produkt in den Warenkorb legen
|
||||
|
||||
**Als** Nutzer
|
||||
**möchte ich** die Jahreskarte in den Warenkorb legen
|
||||
**damit** ich sie später kaufen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Button "In den Warenkorb" ist prominent platziert
|
||||
- Warenkorb-Icon zeigt Anzahl der Artikel
|
||||
- Feedback nach Hinzufügen (z.B. Toast-Notification)
|
||||
- Warenkorb ist persistent (auch nach Logout)
|
||||
|
||||
---
|
||||
|
||||
#### US-005: Warenkorb ansehen
|
||||
|
||||
**Als** Nutzer
|
||||
**möchte ich** meinen Warenkorb einsehen und bearbeiten
|
||||
**damit** ich meine Bestellung überprüfen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Warenkorb zeigt alle hinzugefügten Artikel
|
||||
- Menge kann angepasst werden
|
||||
- Artikel können entfernt werden
|
||||
- Gesamtpreis wird angezeigt
|
||||
- Button "Zur Kasse" führt zum Checkout
|
||||
|
||||
---
|
||||
|
||||
#### US-006: Checkout durchführen
|
||||
|
||||
**Als** Nutzer
|
||||
**möchte ich** meine Bestellung abschließen
|
||||
**damit** ich die Jahreskarte erhalte
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Übersicht der Bestellung (Artikel, Preis)
|
||||
- Eingabe/Bestätigung von Rechnungsdaten
|
||||
- Auswahl der Zahlungsmethode (MVP: nur PayPal)
|
||||
- Weiterleitung zu PayPal
|
||||
- Nach erfolgreicher Zahlung: Bestätigungsseite
|
||||
|
||||
---
|
||||
|
||||
#### US-007: Bestellbestätigung erhalten
|
||||
|
||||
**Als** Nutzer
|
||||
**möchte ich** eine Bestätigung meiner Bestellung sehen
|
||||
**damit** ich weiß, dass der Kauf erfolgreich war
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Bestätigungsseite mit Bestellnummer
|
||||
- E-Mail mit Bestelldetails und Jahreskarte (PDF/Link)
|
||||
- Bestellung wird in der Bestellhistorie angezeigt
|
||||
- Daten werden an NAV ERP übermittelt
|
||||
|
||||
---
|
||||
|
||||
#### US-008: Gespeicherte Rechnungsadresse verwenden
|
||||
|
||||
**Als** wiederkehrender Nutzer
|
||||
**möchte ich** meine Rechnungsadresse gespeichert haben
|
||||
**damit** ich sie beim nächsten Kauf nicht erneut eingeben muss
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Beim Checkout wird gespeicherte Adresse automatisch vorausgefüllt
|
||||
- Option "Adresse für zukünftige Käufe speichern" ist beim ersten Kauf vorausgewählt
|
||||
- Gespeicherte Adresse kann im Profil bearbeitet werden
|
||||
- Adresse kann beim Checkout vor Abschluss editiert werden
|
||||
- Im Profil unter `/profil/adresse` einsehbar und änderbar
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Post-MVP User Stories
|
||||
|
||||
#### US-101: Rollenauswahl nach Registrierung
|
||||
|
||||
**Als** neuer Nutzer
|
||||
**möchte ich** nach dem ersten Login meine Rolle auswählen
|
||||
**damit** ich auf für mich relevante Produkte zugreifen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Modal/Seite zur Rollenauswahl nach erstem Login
|
||||
- Optionen: Privatperson, Pädagoge/Erzieher, Unternehmen
|
||||
- Auswahl wird im User-Profil gespeichert
|
||||
- Pädagogen-Rolle löst Genehmigungsprozess aus
|
||||
|
||||
---
|
||||
|
||||
#### US-102: Pädagogische Jahreskarte beantragen
|
||||
|
||||
**Als** Pädagoge
|
||||
**möchte ich** eine pädagogische Jahreskarte beantragen
|
||||
**damit** ich die experimenta kostenlos besuchen kann
|
||||
|
||||
**Akzeptanzkriterien:**
|
||||
|
||||
- Antragsformular mit Nachweis (Schulnachweis, etc.)
|
||||
- Status: "In Prüfung"
|
||||
- Kann reservieren, aber nicht kaufen
|
||||
- Benachrichtigung bei Genehmigung/Ablehnung
|
||||
|
||||
---
|
||||
|
||||
## 5. Funktionale Anforderungen
|
||||
|
||||
### 5.1 Authentifizierung & Benutzerverwaltung
|
||||
|
||||
#### F-001: Cidaas Integration
|
||||
|
||||
- Integration mit Cidaas über OIDC/OAuth2
|
||||
- Custom Registrierungs- und Login-Masken im experimenta Design
|
||||
- E-Mail-basierte Registrierung (minimal)
|
||||
- Session Management
|
||||
|
||||
#### F-002: User-Profil Verwaltung
|
||||
|
||||
- User-Profile werden in lokaler PostgreSQL-DB gespeichert
|
||||
- Cidaas dient nur zur Authentifizierung
|
||||
- Verknüpfung über Cidaas User-ID
|
||||
- Profildaten: E-Mail, Name, Adresse (für Rechnungen)
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Produktverwaltung
|
||||
|
||||
#### F-003: Produkt-Synchronisation
|
||||
|
||||
- NAV ERP sendet Produktdaten per Push an Server-Endpunkt
|
||||
- Endpunkt: `POST /api/erp/products`
|
||||
- Produktdaten werden in lokaler DB gespeichert
|
||||
- Felder: ID, Name, Beschreibung, Preis, Lagerbestand, Status
|
||||
|
||||
#### F-004: Produktanzeige
|
||||
|
||||
- Produktseite für Makerspace-Jahreskarten
|
||||
- Responsives Layout (mobile-first)
|
||||
- Bilder und Texte aus lokaler DB (synchronisiert via X-API)
|
||||
- Preisanzeige in Euro
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Warenkorb & Checkout
|
||||
|
||||
#### F-005: Warenkorb-Funktionalität
|
||||
|
||||
- Session-basierter Warenkorb für nicht-angemeldete User
|
||||
- DB-persistenter Warenkorb für angemeldete User
|
||||
- CRUD-Operationen: Hinzufügen, Entfernen, Mengenänderung
|
||||
- Warenkorb-Icon mit Badge (Artikelanzahl)
|
||||
|
||||
#### F-006: Checkout-Prozess
|
||||
|
||||
- Schritt 1: Warenkorb-Übersicht
|
||||
- Schritt 2: Rechnungsdaten
|
||||
- Schritt 3: Zahlungsmethode (MVP: nur PayPal)
|
||||
- Schritt 4: Bestellübersicht & Bestätigung
|
||||
|
||||
#### F-007: PayPal Integration
|
||||
|
||||
- PayPal Checkout Integration
|
||||
- Redirect zu PayPal für Zahlung
|
||||
- Webhook für Payment-Bestätigung
|
||||
- Fehlerbehandlung bei fehlgeschlagener Zahlung
|
||||
|
||||
---
|
||||
|
||||
### 5.4 Bestellverwaltung
|
||||
|
||||
#### F-008: Bestellung speichern
|
||||
|
||||
- Bestellung wird nach erfolgreicher Zahlung in DB gespeichert
|
||||
- Status: "Bezahlt", "In Bearbeitung", "Abgeschlossen"
|
||||
- Bestellnummer generieren
|
||||
- Timestamp & User-ID verknüpfen
|
||||
|
||||
#### F-009: Bestellbestätigung
|
||||
|
||||
- Bestätigungsseite nach erfolgreichem Kauf
|
||||
- E-Mail mit Bestelldetails
|
||||
- PDF-Ticket/Jahreskarte als Anhang oder Download-Link
|
||||
|
||||
#### F-010: Bestellhistorie
|
||||
|
||||
- User kann eigene Bestellungen einsehen
|
||||
- Filtermöglichkeiten: Status, Datum
|
||||
- Details-Ansicht pro Bestellung
|
||||
|
||||
---
|
||||
|
||||
### 5.5 ERP & API Integrationen
|
||||
|
||||
#### F-011: NAV ERP Push-Endpunkt
|
||||
|
||||
- REST-API Endpunkt: `POST /api/erp/products`
|
||||
- Authentifizierung via API-Key oder OAuth
|
||||
- Payload: Produktdaten (JSON)
|
||||
- Validierung & Speicherung in DB
|
||||
- Logging & Error Handling
|
||||
|
||||
#### F-012: X-API Integration
|
||||
|
||||
- Abruf von Veranstaltungstexten und Bildern
|
||||
- Caching in lokaler DB
|
||||
- Regelmäßige Synchronisation (Cronjob)
|
||||
|
||||
#### F-013: Bestellung an NAV senden (via X-API)
|
||||
|
||||
- Nach erfolgreichem Kauf: Bestellung an NAV übermitteln
|
||||
- REST-API Call zu X-API Endpoint `/shopware/order`
|
||||
- **Authentifizierung:** HTTP Basic Auth (Username + Password)
|
||||
- X-API konvertiert JSON zu SOAP für NAV ERP
|
||||
- Retry-Mechanismus bei Fehlern (exponentieller Backoff)
|
||||
- Status-Tracking
|
||||
- **Environments:**
|
||||
- Development: `https://x-api-dev.experimenta.science`
|
||||
- Staging: `https://x-api-stage.experimenta.science`
|
||||
- Production: `https://x-api.experimenta.science`
|
||||
|
||||
---
|
||||
|
||||
## 6. Nicht-funktionale Anforderungen
|
||||
|
||||
### 6.1 Performance
|
||||
|
||||
- **Page Load Time:** < 2 Sekunden (mobile, 4G)
|
||||
- **Time to Interactive:** < 3 Sekunden
|
||||
- **API Response Time:** < 500ms (95th percentile)
|
||||
- **Checkout Response:** < 1 Sekunde (nach PayPal Erfolg)
|
||||
- **Concurrent Users:** 500+ gleichzeitige Nutzer
|
||||
- **Queue Processing:** Order submission innerhalb 5 Minuten nach Payment
|
||||
|
||||
### 6.2 Skalierbarkeit
|
||||
|
||||
- Horizontal skalierbar (Docker Container)
|
||||
- Stateless Server-Design
|
||||
- DB Connection Pooling
|
||||
- Redis für Caching-Strategie (Redis optional)
|
||||
|
||||
### 6.3 Sicherheit
|
||||
|
||||
- **HTTPS only** (TLS 1.3)
|
||||
- **DSGVO-konform:** Datensparsamkeit, Einwilligungen, Löschkonzept
|
||||
- **PCI-DSS-konform:** Keine Speicherung von Kreditkartendaten
|
||||
- **Input Validation:** Alle User-Inputs validieren
|
||||
- **Rate Limiting:** API-Endpunkte gegen Missbrauch schützen
|
||||
- **Secrets Management:** Keine Secrets im Code (Environment Variables)
|
||||
|
||||
### 6.4 Verfügbarkeit
|
||||
|
||||
- **Uptime:** 99.5% (außer geplante Wartung)
|
||||
- **Backup:** Tägliche DB-Backups
|
||||
- **Disaster Recovery:** Wiederherstellung innerhalb 24h
|
||||
|
||||
### 6.5 Usability
|
||||
|
||||
- **Mobile-first Design:** Optimiert für Smartphones
|
||||
- **Responsive:** Funktioniert auf allen Geräten (320px - 4K)
|
||||
- **Accessibility:** WCAG 2.1 Level AA konform
|
||||
- **Intuitive Navigation:** Maximal 3 Klicks zum Ziel
|
||||
- **Corporate Design:** experimenta Styleguide (Farben, Fonts)
|
||||
|
||||
### 6.6 Wartbarkeit
|
||||
|
||||
- **Clean Code:** ESLint, Prettier
|
||||
- **Dokumentation:** Inline-Kommentare, README
|
||||
- **Testing:** Unit Tests (>80% Coverage), E2E Tests
|
||||
- **CI/CD:** Automatisierte Builds & Deployments
|
||||
- **Monitoring:** Logging, Error Tracking (Sentry optional)
|
||||
|
||||
---
|
||||
|
||||
## 7. User Experience & Design
|
||||
|
||||
### 7.1 Design-Prinzipien
|
||||
|
||||
- **Mobile-first:** Primär für Smartphones optimiert
|
||||
- **Minimal:** Fokus auf Kernfunktionen, keine Ablenkungen
|
||||
- **Schnell:** Kurze Ladezeiten, optimierte Assets
|
||||
- **Konsistent:** Einheitliches Design im gesamten System
|
||||
|
||||
### 7.2 Corporate Design Integration
|
||||
|
||||
- Farben aus experimenta Styleguide
|
||||
- Schriftarten aus experimenta Styleguide
|
||||
- Logo-Nutzung gemäß Brand Guidelines
|
||||
- Icons: Material Design Icons oder Heroicons
|
||||
|
||||
### 7.3 Key Screens (MVP)
|
||||
|
||||
#### Homepage
|
||||
|
||||
- Hero-Bereich mit Call-to-Action
|
||||
- Makerspace-Jahreskarte prominent anzeigen
|
||||
- Login/Registrierung Button (Header)
|
||||
- Warenkorb-Icon (Header)
|
||||
|
||||
#### Produktseite
|
||||
|
||||
- Großes Produktbild
|
||||
- Name, Beschreibung, Preis
|
||||
- "In den Warenkorb" Button (sticky)
|
||||
- Zusätzliche Informationen (Accordion)
|
||||
|
||||
#### Warenkorb
|
||||
|
||||
- Liste der Artikel
|
||||
- Menge anpassen, entfernen
|
||||
- Gesamtpreis
|
||||
- "Zur Kasse" Button
|
||||
|
||||
#### Checkout
|
||||
|
||||
- Multi-Step Form (Progress Indicator)
|
||||
- Rechnungsdaten (Formular)
|
||||
- Zahlungsmethode (PayPal Button)
|
||||
- Bestellübersicht
|
||||
|
||||
#### Bestätigung
|
||||
|
||||
- Erfolgs-Icon
|
||||
- Bestellnummer
|
||||
- Zusammenfassung
|
||||
- Link zur Bestellhistorie
|
||||
|
||||
---
|
||||
|
||||
## 8. Technische Anforderungen
|
||||
|
||||
### 8.1 Tech Stack
|
||||
|
||||
Siehe [TECH_STACK.md](./TECH_STACK.md) für Details.
|
||||
|
||||
**Übersicht:**
|
||||
|
||||
- Frontend: Nuxt 4
|
||||
- UI-Framework: Nuxt UI oder shadcn-vue
|
||||
- Backend: Nuxt Server APIs
|
||||
- Datenbank: PostgreSQL
|
||||
- ORM: Drizzle
|
||||
- Auth: Cidaas (OIDC/OAuth2)
|
||||
- Payment: PayPal SDK
|
||||
- Deployment: Docker, Hetzner Proxmox
|
||||
- CI/CD: GitLab
|
||||
|
||||
### 8.2 Hosting & Infrastructure
|
||||
|
||||
- **Hosting:** Hetzner Dedicated Server / VPS
|
||||
- **Virtualisierung:** Proxmox Container
|
||||
- **Container Runtime:** Docker
|
||||
- **Reverse Proxy:** Nginx oder Traefik
|
||||
- **SSL:** Let's Encrypt (automatisch)
|
||||
- **Domain:** my.experimenta.science
|
||||
|
||||
### 8.3 CI/CD Pipeline
|
||||
|
||||
- **Repository:** GitLab (intern gehostet)
|
||||
- **Pipeline:** GitLab CI/CD
|
||||
- **Deploy-Strategie:** Blue-Green oder Rolling Deployment
|
||||
- **SSH-Zugang:** GitLab Runner mit SSH-Key oder Runner auf Server
|
||||
- **Stages:** Build → Test → Deploy (Staging) → Deploy (Production)
|
||||
|
||||
---
|
||||
|
||||
## 9. Datenmodell (MVP)
|
||||
|
||||
### 9.1 Hauptentitäten
|
||||
|
||||
#### User
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: string(UUID)
|
||||
cidaas_user_id: string(unique)
|
||||
email: string
|
||||
first_name: string ? last_name : string ? phone : string ? created_at : timestamp
|
||||
updated_at: timestamp
|
||||
}
|
||||
```
|
||||
|
||||
#### Product
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: string (UUID)
|
||||
nav_product_id: string (unique)
|
||||
name: string
|
||||
description: text
|
||||
price: decimal
|
||||
image_url: string?
|
||||
stock: integer
|
||||
status: enum (active, inactive)
|
||||
created_at: timestamp
|
||||
updated_at: timestamp
|
||||
}
|
||||
```
|
||||
|
||||
#### Cart
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: string (UUID)
|
||||
user_id: string? (FK to User, null for anonymous)
|
||||
session_id: string? (for anonymous users)
|
||||
created_at: timestamp
|
||||
updated_at: timestamp
|
||||
}
|
||||
```
|
||||
|
||||
#### CartItem
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: string (UUID)
|
||||
cart_id: string (FK to Cart)
|
||||
product_id: string (FK to Product)
|
||||
quantity: integer
|
||||
price_snapshot: decimal (Preis zum Zeitpunkt des Hinzufügens)
|
||||
created_at: timestamp
|
||||
}
|
||||
```
|
||||
|
||||
#### Order
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: string (UUID)
|
||||
order_number: string (unique, z.B. "EXP-2025-00001")
|
||||
user_id: string (FK to User)
|
||||
status: enum (pending, paid, processing, completed, cancelled)
|
||||
total_amount: decimal
|
||||
payment_method: enum (paypal)
|
||||
payment_id: string? (PayPal Transaction ID)
|
||||
billing_address: jsonb
|
||||
created_at: timestamp
|
||||
updated_at: timestamp
|
||||
}
|
||||
```
|
||||
|
||||
#### OrderItem
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: string (UUID)
|
||||
order_id: string (FK to Order)
|
||||
product_id: string (FK to Product)
|
||||
quantity: integer
|
||||
price: decimal
|
||||
created_at: timestamp
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. API-Spezifikation
|
||||
|
||||
### 10.1 Public API Endpoints
|
||||
|
||||
#### Authentication
|
||||
|
||||
- `POST /api/auth/login` - Initiiert Cidaas Login
|
||||
- `POST /api/auth/callback` - OAuth Callback von Cidaas
|
||||
- `POST /api/auth/logout` - Beendet Session
|
||||
|
||||
#### Products
|
||||
|
||||
- `GET /api/products` - Liste aller aktiven Produkte
|
||||
- `GET /api/products/:id` - Details zu einem Produkt
|
||||
|
||||
#### Cart
|
||||
|
||||
- `GET /api/cart` - Warenkorb abrufen
|
||||
- `POST /api/cart/items` - Artikel hinzufügen
|
||||
- `PATCH /api/cart/items/:id` - Menge ändern
|
||||
- `DELETE /api/cart/items/:id` - Artikel entfernen
|
||||
|
||||
#### Orders
|
||||
|
||||
- `POST /api/orders` - Bestellung erstellen
|
||||
- `GET /api/orders` - Bestellhistorie
|
||||
- `GET /api/orders/:id` - Bestelldetails
|
||||
|
||||
#### Payment
|
||||
|
||||
- `POST /api/payment/paypal/create` - PayPal Order erstellen
|
||||
- `POST /api/payment/paypal/capture` - PayPal Zahlung erfassen
|
||||
- `POST /api/payment/paypal/webhook` - PayPal Webhook
|
||||
|
||||
---
|
||||
|
||||
### 10.2 Internal API Endpoints (ERP Integration)
|
||||
|
||||
#### NAV ERP Push
|
||||
|
||||
- `POST /api/erp/products` - Produkte von NAV empfangen
|
||||
- `POST /api/erp/stock` - Lagerbestände aktualisieren
|
||||
|
||||
**Authentication:** API-Key oder OAuth Client Credentials
|
||||
|
||||
**Payload Example (Produkt):**
|
||||
|
||||
```json
|
||||
{
|
||||
"nav_product_id": "MS-JK-2025",
|
||||
"name": "Makerspace Jahreskarte 2025",
|
||||
"description": "Jahresticket für unbegrenzten Zugang zum Makerspace",
|
||||
"price": 99.0,
|
||||
"stock": 500,
|
||||
"status": "active",
|
||||
"image_url": "https://api.experimenta.science/images/ms-jk.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Abhängigkeiten & Risiken
|
||||
|
||||
### 11.1 Externe Abhängigkeiten
|
||||
|
||||
- **Cidaas:** Verfügbarkeit und Stabilität der Auth-Platform
|
||||
- **NAV ERP:** Zuverlässigkeit der Push-Integration
|
||||
- **X-API:** Verfügbarkeit der Veranstaltungsdaten
|
||||
- **PayPal:** Uptime des Payment-Gateways
|
||||
- **Hetzner:** Infrastruktur-Verfügbarkeit
|
||||
|
||||
### 11.2 Technische Risiken
|
||||
|
||||
- **Cidaas Integration:** Komplexität der Custom-UI Integration
|
||||
- **ERP Synchronisation:** Dateninkonsistenzen, Timing-Probleme
|
||||
- **Payment Failures:** Umgang mit fehlgeschlagenen Transaktionen
|
||||
- **Skalierung:** Performance bei hohem Nutzeraufkommen
|
||||
|
||||
### 11.3 Mitigationsstrategien
|
||||
|
||||
- **Cidaas:** Ausführliches Testing, Fallback-Mechanismen
|
||||
- **ERP:** Retry-Logik, Monitoring, manuelle Sync-Option
|
||||
- **Payment:** Klare Error-Messages, Support-Kontakt prominent
|
||||
- **Skalierung:** Load Testing, horizontale Skalierung vorbereiten
|
||||
|
||||
---
|
||||
|
||||
## 12. Zeitplan & Meilensteine
|
||||
|
||||
### 12.1 MVP (Phase 1) - 8-12 Wochen
|
||||
|
||||
**Sprint 1-2 (Woche 1-4): Foundation**
|
||||
|
||||
- Projekt-Setup (Nuxt 4, Drizzle, PostgreSQL)
|
||||
- Datenbank-Schema erstellen
|
||||
- Basic Layout & Routing
|
||||
- Cidaas Integration (Auth)
|
||||
|
||||
**Sprint 3-4 (Woche 5-8): Core Features**
|
||||
|
||||
- Produktseite implementieren
|
||||
- Warenkorb-Funktionalität
|
||||
- NAV ERP Push-Endpunkt
|
||||
- User-Profil
|
||||
|
||||
**Sprint 5-6 (Woche 9-12): Checkout & Payment**
|
||||
|
||||
- Checkout-Flow implementieren
|
||||
- PayPal Integration
|
||||
- Bestellbestätigung & E-Mail
|
||||
- Testing & Bug Fixes
|
||||
|
||||
**Sprint 7 (Optional): Launch Preparation**
|
||||
|
||||
- UAT (User Acceptance Testing)
|
||||
- Performance-Optimierung
|
||||
- Dokumentation
|
||||
- Production Deployment
|
||||
|
||||
---
|
||||
|
||||
### 12.2 Post-MVP Roadmap
|
||||
|
||||
**Phase 2 (Q2 2025): Pädagogen & Rollen**
|
||||
|
||||
- Rollen-System implementieren
|
||||
- Pädagogische Jahreskarten
|
||||
- Genehmigungsworkflow
|
||||
- Admin-Panel (Basic)
|
||||
|
||||
**Phase 3 (Q3 2025): Experimenta-Tickets**
|
||||
|
||||
- Ticket-Varianten
|
||||
- Science Dome Platzreservierung
|
||||
- Kalender-Integration
|
||||
- Multi-Payment-Provider
|
||||
|
||||
**Phase 4 (Q4 2025): Laborkurse**
|
||||
|
||||
- Kurs-Verwaltung
|
||||
- Schulen-Accounts
|
||||
- Gruppenbuchungen
|
||||
- Erweiterte Reporting-Funktionen
|
||||
|
||||
---
|
||||
|
||||
## 13. Testing-Strategie
|
||||
|
||||
### 13.1 Test-Arten
|
||||
|
||||
**Unit Tests:**
|
||||
|
||||
- Nuxt Composables
|
||||
- Utility Functions
|
||||
- Drizzle Queries (Mocked)
|
||||
- Ziel: >80% Coverage
|
||||
|
||||
**Integration Tests:**
|
||||
|
||||
- API Endpoints
|
||||
- Database Operations
|
||||
- Auth Flow
|
||||
|
||||
**E2E Tests:**
|
||||
|
||||
- User Flows (Registrierung bis Kauf)
|
||||
- Payment Flow (mit Sandbox)
|
||||
- Responsive Design
|
||||
|
||||
### 13.2 Test-Tools
|
||||
|
||||
- **Vitest:** Unit & Integration Tests
|
||||
- **Playwright:** E2E Tests
|
||||
- **MSW (Mock Service Worker):** API Mocking
|
||||
- **Testing Library:** Component Tests
|
||||
|
||||
---
|
||||
|
||||
## 14. Monitoring & Support
|
||||
|
||||
### 14.1 Monitoring
|
||||
|
||||
- **Application Monitoring:** Error Tracking (Sentry optional)
|
||||
- **Performance Monitoring:** Core Web Vitals
|
||||
- **Uptime Monitoring:** Ping-Service
|
||||
- **Logging:** Strukturiertes Logging (JSON)
|
||||
|
||||
### 14.2 Support
|
||||
|
||||
- **E-Mail-Support:** support@experimenta.science
|
||||
- **FAQ-Seite:** Häufige Fragen & Antworten
|
||||
- **Status-Page:** System-Status & geplante Wartungen
|
||||
|
||||
---
|
||||
|
||||
## 15. Open Questions
|
||||
|
||||
### 15.1 Zu klären
|
||||
|
||||
- [ ] Welches UI-Framework: Nuxt UI vs. shadcn-vue?
|
||||
- [ ] Detailliertes Design der Custom Cidaas Login/Registrierungs-UI
|
||||
- [ ] Exakte Struktur der NAV ERP Push-Payload
|
||||
- [ ] X-API Dokumentation & Zugang
|
||||
- [ ] E-Mail-Versand: Eigener SMTP oder Service (SendGrid, etc.)?
|
||||
- [ ] Ticket-Format: PDF, QR-Code, oder anderes?
|
||||
- [ ] Admin-Panel: Ab wann benötigt?
|
||||
|
||||
### 15.2 Entscheidungen treffen
|
||||
|
||||
- [ ] GitLab Runner: Auf Server oder SSH-Zugang?
|
||||
- [ ] Caching-Strategie: Redis verwenden?
|
||||
- [ ] Staging-Environment: Separate Instanz?
|
||||
|
||||
---
|
||||
|
||||
## 16. Glossar
|
||||
|
||||
| Begriff | Bedeutung |
|
||||
| ---------------- | ---------------------------------------------------------- |
|
||||
| **MVP** | Minimum Viable Product - Erste funktionsfähige Version |
|
||||
| **NAV ERP** | Microsoft Dynamics NAV - ERP-System der experimenta |
|
||||
| **X-API** | Externe API für Veranstaltungsdaten |
|
||||
| **Cidaas** | Customer Identity and Access Management Platform von Widas |
|
||||
| **OIDC** | OpenID Connect - Authentifizierungsprotokoll |
|
||||
| **JK** | Jahreskarte |
|
||||
| **MS** | Makerspace |
|
||||
| **Päd. JK** | Pädagogische Jahreskarte |
|
||||
| **Science Dome** | 150-Sitzer Kino/Planetarium der experimenta |
|
||||
|
||||
---
|
||||
|
||||
## 17. Anhang
|
||||
|
||||
### 17.1 Referenzen
|
||||
|
||||
- [Nuxt 4 Dokumentation](https://nuxt.com)
|
||||
- [Drizzle ORM](https://orm.drizzle.team)
|
||||
- [Cidaas Dokumentation](https://docs.cidaas.com)
|
||||
- [PayPal Developer Docs](https://developer.paypal.com)
|
||||
|
||||
### 17.2 Änderungshistorie
|
||||
|
||||
| Version | Datum | Autor | Änderungen |
|
||||
| ------- | ---------- | -------- | ---------------------- |
|
||||
| 1.0 | 2025-10-28 | Dev Team | Initiales PRD erstellt |
|
||||
|
||||
---
|
||||
|
||||
**Ende des Dokuments**
|
||||
1698
docs/TECH_STACK.md
Normal file
1698
docs/TECH_STACK.md
Normal file
File diff suppressed because it is too large
Load Diff
132
docs/design-examples/components/ExperimentaButton.vue
Normal file
132
docs/design-examples/components/ExperimentaButton.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* ExperimentaButton Component
|
||||
*
|
||||
* Experimenta-branded button with animated gradient background.
|
||||
* Based on the experimenta Design System.
|
||||
*
|
||||
* @example
|
||||
* <ExperimentaButton>Click me</ExperimentaButton>
|
||||
* <ExperimentaButton variant="secondary">Cancel</ExperimentaButton>
|
||||
* <ExperimentaButton size="small">Small</ExperimentaButton>
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
/** Button variant */
|
||||
variant?: 'primary' | 'secondary'
|
||||
/** Button size */
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
/** Disabled state */
|
||||
disabled?: boolean
|
||||
/** Button type */
|
||||
type?: 'button' | 'submit' | 'reset'
|
||||
/** Link behavior (renders as <a> tag) */
|
||||
href?: string
|
||||
/** Target for links */
|
||||
target?: '_blank' | '_self' | '_parent' | '_top'
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
variant: 'primary',
|
||||
size: 'large',
|
||||
disabled: false,
|
||||
type: 'button',
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
click: [event: MouseEvent]
|
||||
}>()
|
||||
|
||||
function handleClick(event: MouseEvent) {
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="href ? 'a' : 'button'"
|
||||
:href="href"
|
||||
:target="href ? target : undefined"
|
||||
:type="!href ? type : undefined"
|
||||
:disabled="!href ? disabled : undefined"
|
||||
:class="[
|
||||
'btn-experimenta',
|
||||
`btn-${variant}`,
|
||||
`btn-${size}`,
|
||||
{
|
||||
'btn-disabled': disabled,
|
||||
},
|
||||
]"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Base Button Styles */
|
||||
.btn-experimenta {
|
||||
@apply inline-block cursor-pointer;
|
||||
@apply font-medium text-white;
|
||||
@apply transition-all;
|
||||
@apply outline-0 border-0;
|
||||
@apply rounded-2xl;
|
||||
text-decoration: none;
|
||||
line-height: 1.7em;
|
||||
}
|
||||
|
||||
/* Primary Variant */
|
||||
.btn-primary {
|
||||
background: #e6007e;
|
||||
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
|
||||
background-size: 300%;
|
||||
background-position: left;
|
||||
transition:
|
||||
background-position 1s ease,
|
||||
all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover:not(.btn-disabled) {
|
||||
background-position: right;
|
||||
}
|
||||
|
||||
/* Secondary Variant */
|
||||
.btn-secondary {
|
||||
@apply bg-transparent border-2 border-accent text-accent;
|
||||
}
|
||||
|
||||
.btn-secondary:hover:not(.btn-disabled) {
|
||||
@apply bg-accent text-white;
|
||||
}
|
||||
|
||||
/* Sizes */
|
||||
.btn-large {
|
||||
@apply text-lg px-8 py-2.5;
|
||||
}
|
||||
|
||||
.btn-medium {
|
||||
@apply text-base px-6 py-2;
|
||||
}
|
||||
|
||||
.btn-small {
|
||||
@apply text-base px-6 py-2;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 480px) {
|
||||
.btn-large {
|
||||
@apply text-base px-6 py-2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disabled State */
|
||||
.btn-disabled {
|
||||
@apply opacity-50 cursor-not-allowed;
|
||||
}
|
||||
|
||||
/* Focus State (Accessibility) */
|
||||
.btn-experimenta:focus-visible {
|
||||
@apply outline-none ring-2 ring-accent ring-offset-2;
|
||||
ring-offset-color: var(--color-purple-darkest, #0f051d);
|
||||
}
|
||||
</style>
|
||||
115
docs/design-examples/components/ExperimentaCard.vue
Normal file
115
docs/design-examples/components/ExperimentaCard.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* ExperimentaCard Component
|
||||
*
|
||||
* Glass-morphism card component based on the experimenta Design System.
|
||||
*
|
||||
* @example
|
||||
* <ExperimentaCard>Content here</ExperimentaCard>
|
||||
* <ExperimentaCard variant="info">Info section</ExperimentaCard>
|
||||
* <ExperimentaCard title="Card Title">Content</ExperimentaCard>
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
/** Card variant */
|
||||
variant?: 'glass' | 'info' | 'contact' | 'progress'
|
||||
/** Card title (optional) */
|
||||
title?: string
|
||||
/** Title color (only for info/contact variants) */
|
||||
titleColor?: 'accent' | 'primary'
|
||||
/** Show left accent border */
|
||||
accentBorder?: boolean
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
variant: 'glass',
|
||||
titleColor: 'accent',
|
||||
accentBorder: false,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="[
|
||||
'card-experimenta',
|
||||
`card-${variant}`,
|
||||
{
|
||||
'card-accent-border': accentBorder || variant !== 'glass',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<!-- Title Slot or Prop -->
|
||||
<h3 v-if="title || $slots.title" :class="['card-title', `title-${titleColor}`]">
|
||||
<slot name="title">{{ title }}</slot>
|
||||
</h3>
|
||||
|
||||
<!-- Main Content -->
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Base Card Styles */
|
||||
.card-experimenta {
|
||||
@apply rounded-xl;
|
||||
@apply p-8 md:p-6 sm:p-5;
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
/* Glass-morphism Variant (Main Card) */
|
||||
.card-glass {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
backdrop-filter: blur(15px);
|
||||
@apply border border-white/20;
|
||||
@apply shadow-glass;
|
||||
@apply rounded-2xl;
|
||||
@apply p-15 md:p-10 sm:p-8;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.card-glass {
|
||||
@apply rounded-lg;
|
||||
}
|
||||
}
|
||||
|
||||
/* Info Variant */
|
||||
.card-info {
|
||||
@apply bg-white/8;
|
||||
}
|
||||
|
||||
/* Contact Variant */
|
||||
.card-contact {
|
||||
@apply bg-white/8;
|
||||
@apply text-center;
|
||||
}
|
||||
|
||||
/* Progress Variant */
|
||||
.card-progress {
|
||||
@apply bg-white/8;
|
||||
@apply rounded-2xl md:rounded-lg;
|
||||
}
|
||||
|
||||
/* Accent Border (Left) */
|
||||
.card-accent-border {
|
||||
@apply border-l-4 border-accent;
|
||||
}
|
||||
|
||||
/* Card Title */
|
||||
.card-title {
|
||||
@apply font-medium mb-4;
|
||||
@apply text-lg md:text-base;
|
||||
}
|
||||
|
||||
.title-accent {
|
||||
@apply text-accent;
|
||||
}
|
||||
|
||||
.title-primary {
|
||||
@apply text-primary;
|
||||
}
|
||||
|
||||
/* Hover Effect (Optional) */
|
||||
.card-experimenta:hover {
|
||||
@apply shadow-2xl;
|
||||
}
|
||||
</style>
|
||||
216
docs/design-examples/components/ExperimentaLogo.vue
Normal file
216
docs/design-examples/components/ExperimentaLogo.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* ExperimentaLogo Component
|
||||
*
|
||||
* Official experimenta Science Center logo (X-Logo with gradients).
|
||||
* SVG is taken from the design templates.
|
||||
*
|
||||
* @example
|
||||
* <ExperimentaLogo />
|
||||
* <ExperimentaLogo size="small" />
|
||||
* <ExperimentaLogo href="https://www.experimenta.science" />
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
/** Logo size */
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
/** Link URL (if logo should be clickable) */
|
||||
href?: string
|
||||
/** Link target */
|
||||
target?: '_blank' | '_self'
|
||||
/** Accessible label */
|
||||
ariaLabel?: string
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
size: 'large',
|
||||
href: undefined,
|
||||
target: '_self',
|
||||
ariaLabel: 'experimenta Science Center Logo',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="href ? 'a' : 'div'"
|
||||
:href="href"
|
||||
:target="href ? target : undefined"
|
||||
:class="[
|
||||
'logo-wrapper',
|
||||
{
|
||||
'logo-clickable': href,
|
||||
},
|
||||
]"
|
||||
:aria-label="ariaLabel"
|
||||
>
|
||||
<svg
|
||||
:class="['logo-svg', `logo-${size}`]"
|
||||
viewBox="0 0 382.94 87.17"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
role="img"
|
||||
:aria-label="ariaLabel"
|
||||
>
|
||||
<defs>
|
||||
<!-- Gradients for logo -->
|
||||
<linearGradient
|
||||
id="logo-gradient-a"
|
||||
x1="102.63"
|
||||
y1="152.32"
|
||||
x2="135.19"
|
||||
y2="191.11"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ce0f60" />
|
||||
<stop offset="0.47" stop-color="#de0b75" />
|
||||
<stop offset="0.59" stop-color="#e4097d" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="logo-gradient-b"
|
||||
x1="104.87"
|
||||
y1="170.45"
|
||||
x2="104.87"
|
||||
y2="170.45"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ab1a4e" />
|
||||
<stop offset="0.43" stop-color="#9f1d4f" />
|
||||
<stop offset="0.57" stop-color="#9b1e4f" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="logo-gradient-c"
|
||||
x1="68.79"
|
||||
y1="182.84"
|
||||
x2="154.66"
|
||||
y2="182.84"
|
||||
xlink:href="#logo-gradient-b"
|
||||
/>
|
||||
<linearGradient
|
||||
id="logo-gradient-d"
|
||||
x1="94.04"
|
||||
y1="182.21"
|
||||
x2="114.5"
|
||||
y2="126"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.22" stop-color="#e4097d" />
|
||||
<stop offset="0.32" stop-color="#e4115e" />
|
||||
<stop offset="0.45" stop-color="#e5193d" />
|
||||
<stop offset="0.55" stop-color="#e51e28" />
|
||||
<stop offset="0.62" stop-color="#e52021" />
|
||||
<stop offset="0.9" stop-color="#f7a822" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- X Logo -->
|
||||
<polygon
|
||||
points="143.78 50 151.18 39.6 144.43 39.6 139.68 46.33 135.13 39.6 127.79 39.6 135.32 50.08 127.29 61.23 134.09 61.23 139.3 53.78 144.43 61.23 151.59 61.23 143.78 50"
|
||||
fill="#fff"
|
||||
/>
|
||||
|
||||
<!-- "experimenta" Text -->
|
||||
<path
|
||||
d="M245.79,175.33a9.2,9.2,0,0,0-1.85-3.39,7.28,7.28,0,0,0-2.9-2,10.29,10.29,0,0,0-3.65-.63c-3.12,0-5.47.95-7,2.82l-.56-2.23h-7.72v5.29h3.13v24.7h6.13v-8.4a8.29,8.29,0,0,0,1.7.42,17.3,17.3,0,0,0,2.6.19,11.8,11.8,0,0,0,4.53-.82,9.29,9.29,0,0,0,3.39-2.39,10.78,10.78,0,0,0,2.11-3.78,15.69,15.69,0,0,0,.74-5A16,16,0,0,0,245.79,175.33Zm-12.76,0a5.26,5.26,0,0,1,2.73-.75,4,4,0,0,1,3.12,1.4,5.85,5.85,0,0,1,1.25,4,10.56,10.56,0,0,1-.4,3.12,5.84,5.84,0,0,1-1.1,2.09,4.11,4.11,0,0,1-1.62,1.18,7.15,7.15,0,0,1-4.21.12,4.71,4.71,0,0,1-1.43-.58v-8.48A3.79,3.79,0,0,1,233,175.35Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<!-- Additional text paths omitted for brevity - see design-example1.html for full SVG -->
|
||||
|
||||
<!-- Gradient Logo Mark (X with colors) -->
|
||||
<path
|
||||
d="M93.1,181.53l20.42-19.22c.87-.76,1.61-1.66,2.61-1.8,1.19-.17,3,1.09,3.3,1.28s10.7,6.64,12.57,7.77l15.75,9.71c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53h0s-17.5-10.32-22.43-13.18a22.83,22.83,0,0,0-11-3c-4.71.09-8.62,2.32-12.24,5h0l-24,18.2,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83A17.88,17.88,0,0,0,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#logo-gradient-a)"
|
||||
/>
|
||||
<path
|
||||
d="M104.87,170.45h0"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#logo-gradient-b)"
|
||||
/>
|
||||
<path
|
||||
d="M93.1,181.53h0l11.77-11.08a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11-7.26,5.5s-4.11,2.67-4,6.32c.15,4.65,5.34,6.69,5.34,6.69l30.63,13.13a35.93,35.93,0,0,0,11.38,2.53c3.39.08,6.83-1.14,10.49-2.24l24.76-8.46c1.26-.41,3.26-1.65,3.26-3.17,0-1.2-1.57-2.73-3.33-3.51a16.28,16.28,0,0,0-8.57-1.19c-4.7.44-25.95,7.65-25.95,7.65L93.16,184.23a1.28,1.28,0,0,1-.91-1.58A2.68,2.68,0,0,1,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#logo-gradient-c)"
|
||||
/>
|
||||
<path
|
||||
d="M147.75,179.27c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53L132,169.56l-27.13.89h0a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73h0a66.73,66.73,0,0,0,7.06.19C107.65,182,144.08,180.38,147.75,179.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#e4097d"
|
||||
/>
|
||||
<path
|
||||
d="M104.87,170.45a3.26,3.26,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.67-9-3-3.55a1.94,1.94,0,0,1-.41-1.27,2.18,2.18,0,0,1,1-1.83L110,141.9a6.43,6.43,0,0,1,1.81-.87,5.82,5.82,0,0,1,1.86.09l16.49,2.64a24.38,24.38,0,0,0,9.39-.52c1.94-.49,4.31-1.25,5.39-2.91s-.6-2.9-1.11-3.27c-2.08-1.5-4.67-1.92-7.18-2.32l-25.48-4.08a23.84,23.84,0,0,0-10.88.57A19.61,19.61,0,0,0,95,133.6L71.44,149.36a6.34,6.34,0,0,0-1.08,9.38l.21.27,13.12,17a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#logo-gradient-d)"
|
||||
/>
|
||||
</svg>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Logo Wrapper */
|
||||
.logo-wrapper {
|
||||
@apply flex items-center;
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
.logo-clickable {
|
||||
@apply cursor-pointer no-underline;
|
||||
}
|
||||
|
||||
.logo-clickable:hover .logo-svg {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* Logo SVG */
|
||||
.logo-svg {
|
||||
@apply h-auto;
|
||||
@apply transition-transform duration-300;
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* Logo Sizes */
|
||||
.logo-large {
|
||||
@apply w-[300px];
|
||||
}
|
||||
|
||||
.logo-medium {
|
||||
@apply w-[250px];
|
||||
}
|
||||
|
||||
.logo-small {
|
||||
@apply w-[200px];
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.logo-large {
|
||||
@apply w-[250px] max-w-[90%];
|
||||
}
|
||||
|
||||
.logo-medium {
|
||||
@apply w-[200px] max-w-[85%];
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.logo-large {
|
||||
@apply w-[200px] max-w-[85%];
|
||||
}
|
||||
|
||||
.logo-medium {
|
||||
@apply w-[180px] max-w-[80%];
|
||||
}
|
||||
|
||||
.logo-small {
|
||||
@apply w-[150px] max-w-[75%];
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus State */
|
||||
.logo-clickable:focus-visible {
|
||||
@apply outline-none ring-2 ring-accent ring-offset-2;
|
||||
ring-offset-color: var(--color-purple-darkest, #0f051d);
|
||||
}
|
||||
</style>
|
||||
125
docs/design-examples/components/ExperimentaStatusMessage.vue
Normal file
125
docs/design-examples/components/ExperimentaStatusMessage.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* ExperimentaStatusMessage Component
|
||||
*
|
||||
* Status message component with animated icon.
|
||||
* Used for success, error, warning, and info states.
|
||||
*
|
||||
* @example
|
||||
* <ExperimentaStatusMessage type="success" title="Erfolg!">
|
||||
* Ihre Aktion war erfolgreich.
|
||||
* </ExperimentaStatusMessage>
|
||||
*
|
||||
* <ExperimentaStatusMessage type="error" title="Fehler">
|
||||
* Ein Fehler ist aufgetreten.
|
||||
* </ExperimentaStatusMessage>
|
||||
*/
|
||||
|
||||
interface Props {
|
||||
/** Status type */
|
||||
type: 'success' | 'error' | 'warning' | 'info'
|
||||
/** Status title */
|
||||
title?: string
|
||||
/** Custom icon (overrides default) */
|
||||
icon?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
icon: undefined,
|
||||
})
|
||||
|
||||
// Default icons for each type
|
||||
const defaultIcons = {
|
||||
success: '✓',
|
||||
error: '✖',
|
||||
warning: '!',
|
||||
info: 'i',
|
||||
}
|
||||
|
||||
const displayIcon = computed(() => props.icon || defaultIcons[props.type])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="status-message">
|
||||
<!-- Animated Status Icon -->
|
||||
<div :class="['status-icon', `status-icon-${type}`]" role="img" :aria-label="`${type} icon`">
|
||||
{{ displayIcon }}
|
||||
</div>
|
||||
|
||||
<!-- Title -->
|
||||
<h1 v-if="title || $slots.title" class="status-title">
|
||||
<slot name="title">{{ title }}</slot>
|
||||
</h1>
|
||||
|
||||
<!-- Message Content -->
|
||||
<div class="status-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Status Message Container */
|
||||
.status-message {
|
||||
@apply text-center;
|
||||
}
|
||||
|
||||
/* Status Icon */
|
||||
.status-icon {
|
||||
@apply flex items-center justify-center;
|
||||
@apply w-25 h-25 rounded-full;
|
||||
@apply text-6xl text-white;
|
||||
@apply mb-8 mx-auto;
|
||||
@apply animate-pulse;
|
||||
}
|
||||
|
||||
/* Icon Colors by Type */
|
||||
.status-icon-success {
|
||||
@apply bg-success;
|
||||
}
|
||||
|
||||
.status-icon-error {
|
||||
@apply bg-error;
|
||||
}
|
||||
|
||||
.status-icon-warning {
|
||||
@apply bg-warning;
|
||||
}
|
||||
|
||||
.status-icon-info {
|
||||
@apply bg-info;
|
||||
}
|
||||
|
||||
/* Responsive Icon Size */
|
||||
@media (max-width: 480px) {
|
||||
.status-icon {
|
||||
@apply text-5xl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Status Title */
|
||||
.status-title {
|
||||
@apply text-4xl md:text-3xl sm:text-2xl;
|
||||
@apply font-light tracking-tight;
|
||||
@apply mb-8;
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
/* Status Content */
|
||||
.status-content {
|
||||
@apply text-lg md:text-base sm:text-sm;
|
||||
@apply text-white/90;
|
||||
@apply leading-relaxed;
|
||||
}
|
||||
|
||||
/* Pulse Animation Override (Custom) */
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
400
docs/design-examples/components/README.md
Normal file
400
docs/design-examples/components/README.md
Normal file
@@ -0,0 +1,400 @@
|
||||
# experimenta Vue Komponenten-Beispiele
|
||||
|
||||
Dieser Ordner enthält **Referenz-Implementierungen** der experimenta Design System Komponenten als Vue 3 Single File Components (SFC).
|
||||
|
||||
Diese Komponenten dienen als **Vorlagen und Beispiele** für die Entwicklung eigener Komponenten oder können direkt in das Projekt kopiert werden.
|
||||
|
||||
---
|
||||
|
||||
## Verfügbare Komponenten
|
||||
|
||||
### 1. ExperimentaButton.vue
|
||||
|
||||
Animierter Button mit Gradient-Hintergrund nach experimenta Design System.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Primary & Secondary Variants
|
||||
- Responsive Größen (Small, Medium, Large)
|
||||
- Link-Verhalten (kann als `<a>` oder `<button>` gerendert werden)
|
||||
- Hover-Animation mit Gradient-Shift
|
||||
- Accessibility-Ready (Focus States, ARIA Labels)
|
||||
|
||||
**Verwendung:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import ExperimentaButton from './ExperimentaButton.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Primary Button (default) -->
|
||||
<ExperimentaButton @click="handleClick"> Zur Startseite </ExperimentaButton>
|
||||
|
||||
<!-- Secondary Button -->
|
||||
<ExperimentaButton variant="secondary"> Abbrechen </ExperimentaButton>
|
||||
|
||||
<!-- As Link -->
|
||||
<ExperimentaButton href="https://www.experimenta.science" target="_blank">
|
||||
Zur experimenta Website
|
||||
</ExperimentaButton>
|
||||
|
||||
<!-- Small Size -->
|
||||
<ExperimentaButton size="small"> Small Button </ExperimentaButton>
|
||||
|
||||
<!-- Disabled -->
|
||||
<ExperimentaButton disabled> Disabled Button </ExperimentaButton>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. ExperimentaCard.vue
|
||||
|
||||
Glass-morphism Card-Komponente mit verschiedenen Variants.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Glass-morphism Styling (Backdrop Blur)
|
||||
- Info, Contact, Progress Variants
|
||||
- Optional: Akzent-Border (links)
|
||||
- Slot-basiertes Design (flexibel)
|
||||
|
||||
**Verwendung:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import ExperimentaCard from './ExperimentaCard.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Glass Card (Main) -->
|
||||
<ExperimentaCard>
|
||||
<h1>Willkommen!</h1>
|
||||
<p>Dies ist eine Glass-morphism Card.</p>
|
||||
</ExperimentaCard>
|
||||
|
||||
<!-- Info Card mit Titel -->
|
||||
<ExperimentaCard variant="info" title="Ihre Vorteile">
|
||||
<p>Mit der Jahreskarte erhalten Sie...</p>
|
||||
</ExperimentaCard>
|
||||
|
||||
<!-- Card mit Custom Title Slot -->
|
||||
<ExperimentaCard variant="contact">
|
||||
<template #title>
|
||||
<span>Kontakt</span>
|
||||
</template>
|
||||
<p>E-Mail: info@experimenta.science</p>
|
||||
</ExperimentaCard>
|
||||
|
||||
<!-- Progress Card -->
|
||||
<ExperimentaCard variant="progress">
|
||||
<!-- Progress Bar Content -->
|
||||
</ExperimentaCard>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. ExperimentaStatusMessage.vue
|
||||
|
||||
Status-Nachrichten mit animierten Icons (Success, Error, Warning, Info).
|
||||
|
||||
**Features:**
|
||||
|
||||
- 4 Status-Typen mit passenden Farben
|
||||
- Animiertes Icon (Pulse Animation)
|
||||
- Responsive Icon-Größe
|
||||
- Slot-basierte Inhalte
|
||||
|
||||
**Verwendung:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import ExperimentaStatusMessage from './ExperimentaStatusMessage.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Success Message -->
|
||||
<ExperimentaStatusMessage type="success" title="Verlängerung erfolgreich!">
|
||||
<p>Ihre Jahreskarte wurde erfolgreich verlängert.</p>
|
||||
</ExperimentaStatusMessage>
|
||||
|
||||
<!-- Error Message -->
|
||||
<ExperimentaStatusMessage type="error" title="Ein Fehler ist aufgetreten">
|
||||
<p>Bitte versuchen Sie es erneut.</p>
|
||||
</ExperimentaStatusMessage>
|
||||
|
||||
<!-- Custom Icon -->
|
||||
<ExperimentaStatusMessage type="warning" title="Achtung" icon="⚠">
|
||||
<p>Dies ist eine Warnung.</p>
|
||||
</ExperimentaStatusMessage>
|
||||
|
||||
<!-- Custom Title Slot -->
|
||||
<ExperimentaStatusMessage type="info">
|
||||
<template #title>
|
||||
<span>Information</span>
|
||||
</template>
|
||||
<p>Hier ist eine Info.</p>
|
||||
</ExperimentaStatusMessage>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. ExperimentaLogo.vue
|
||||
|
||||
Offizielles experimenta X-Logo mit Farbverläufen.
|
||||
|
||||
**Features:**
|
||||
|
||||
- SVG-basiert (skalierbar, scharf)
|
||||
- 3 Größen (Small, Medium, Large)
|
||||
- Responsive (passt sich automatisch an)
|
||||
- Optional als Link verwendbar
|
||||
- Hover-Animation
|
||||
|
||||
**Verwendung:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import ExperimentaLogo from './ExperimentaLogo.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Logo (default: large) -->
|
||||
<ExperimentaLogo />
|
||||
|
||||
<!-- Logo als Link -->
|
||||
<ExperimentaLogo href="https://www.experimenta.science" target="_blank" />
|
||||
|
||||
<!-- Small Logo -->
|
||||
<ExperimentaLogo size="small" />
|
||||
|
||||
<!-- Medium Logo -->
|
||||
<ExperimentaLogo size="medium" />
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration in Nuxt 4
|
||||
|
||||
### Option 1: Komponenten in `components/` verschieben
|
||||
|
||||
Kopiere die gewünschten Komponenten nach `components/`:
|
||||
|
||||
```bash
|
||||
cp docs/design-examples/components/ExperimentaButton.vue components/
|
||||
```
|
||||
|
||||
Nuxt erkennt sie automatisch (Auto-Imports):
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<ExperimentaButton>Click me</ExperimentaButton>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Als Composable verwenden
|
||||
|
||||
Erstelle eine Composable-Funktion in `composables/useExperimenta.ts`:
|
||||
|
||||
```typescript
|
||||
export function useExperimenta() {
|
||||
return {
|
||||
// Export component references
|
||||
ExperimentaButton: () => import('@/docs/design-examples/components/ExperimentaButton.vue'),
|
||||
ExperimentaCard: () => import('@/docs/design-examples/components/ExperimentaCard.vue'),
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anpassungen & Erweiterungen
|
||||
|
||||
### shadcn-nuxt Integration
|
||||
|
||||
Diese Komponenten können **shadcn-nuxt Komponenten ersetzen** oder ergänzen:
|
||||
|
||||
```vue
|
||||
<!-- Statt shadcn Button: -->
|
||||
<Button>Click me</Button>
|
||||
|
||||
<!-- Verwende experimenta Button: -->
|
||||
<ExperimentaButton>Click me</ExperimentaButton>
|
||||
```
|
||||
|
||||
### Tailwind Klassen verwenden
|
||||
|
||||
Alle Komponenten verwenden Tailwind CSS Utilities. Du kannst sie anpassen:
|
||||
|
||||
```vue
|
||||
<ExperimentaButton class="mt-8">
|
||||
Custom Margin
|
||||
</ExperimentaButton>
|
||||
```
|
||||
|
||||
### Custom Variants hinzufügen
|
||||
|
||||
Beispiel: Eine neue Button-Variant hinzufügen:
|
||||
|
||||
```vue
|
||||
<!-- In ExperimentaButton.vue -->
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
variant?: 'primary' | 'secondary' | 'tertiary' // Neu: tertiary
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Neue Variant definieren */
|
||||
.btn-tertiary {
|
||||
@apply bg-info text-white;
|
||||
}
|
||||
|
||||
.btn-tertiary:hover {
|
||||
@apply bg-info-dark;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## TypeScript Support
|
||||
|
||||
Alle Komponenten sind **TypeScript-ready** mit vollständigen Prop-Definitionen.
|
||||
|
||||
Beispiel für Type-Safe Usage:
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import ExperimentaButton from './ExperimentaButton.vue'
|
||||
|
||||
function handleClick(event: MouseEvent) {
|
||||
console.log('Button clicked', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ExperimentaButton variant="primary" size="large" :disabled="false" @click="handleClick">
|
||||
Click me
|
||||
</ExperimentaButton>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessibility (A11y)
|
||||
|
||||
Alle Komponenten folgen **WCAG 2.1 AA Standards**:
|
||||
|
||||
- ✅ **Keyboard Navigation** (Tab, Enter, Space)
|
||||
- ✅ **Focus Indicators** (sichtbarer Focus-Ring)
|
||||
- ✅ **ARIA Labels** (Screen Reader Support)
|
||||
- ✅ **Color Contrast** (mindestens 4.5:1 Ratio)
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Beispiel für Vitest Unit Tests:
|
||||
|
||||
```typescript
|
||||
// ExperimentaButton.spec.ts
|
||||
import { mount } from '@vue/test-utils'
|
||||
import ExperimentaButton from './ExperimentaButton.vue'
|
||||
|
||||
describe('ExperimentaButton', () => {
|
||||
it('renders primary button by default', () => {
|
||||
const wrapper = mount(ExperimentaButton, {
|
||||
slots: { default: 'Click me' },
|
||||
})
|
||||
|
||||
expect(wrapper.find('.btn-primary').exists()).toBe(true)
|
||||
expect(wrapper.text()).toBe('Click me')
|
||||
})
|
||||
|
||||
it('emits click event', async () => {
|
||||
const wrapper = mount(ExperimentaButton)
|
||||
await wrapper.trigger('click')
|
||||
|
||||
expect(wrapper.emitted('click')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('renders as link when href is provided', () => {
|
||||
const wrapper = mount(ExperimentaButton, {
|
||||
props: { href: 'https://example.com' },
|
||||
})
|
||||
|
||||
expect(wrapper.element.tagName).toBe('A')
|
||||
expect(wrapper.attributes('href')).toBe('https://example.com')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Storybook Integration (Optional)
|
||||
|
||||
Erstelle Stories für visuelle Dokumentation:
|
||||
|
||||
```typescript
|
||||
// ExperimentaButton.stories.ts
|
||||
import type { Meta, StoryObj } from '@storybook/vue3'
|
||||
import ExperimentaButton from './ExperimentaButton.vue'
|
||||
|
||||
const meta: Meta<typeof ExperimentaButton> = {
|
||||
title: 'Components/ExperimentaButton',
|
||||
component: ExperimentaButton,
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof ExperimentaButton>
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
variant: 'primary',
|
||||
},
|
||||
render: (args) => ({
|
||||
components: { ExperimentaButton },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<ExperimentaButton v-bind="args">Click me</ExperimentaButton>',
|
||||
}),
|
||||
}
|
||||
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
variant: 'secondary',
|
||||
},
|
||||
render: (args) => ({
|
||||
components: { ExperimentaButton },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<ExperimentaButton v-bind="args">Cancel</ExperimentaButton>',
|
||||
}),
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Weitere Ressourcen
|
||||
|
||||
- **Design System Dokumentation**: `docs/DESIGN_SYSTEM.md`
|
||||
- **Tailwind Config**: `tailwind.config.ts`
|
||||
- **CSS Custom Properties**: `assets/css/tailwind.css`
|
||||
- **Design-Vorlagen**: `design-examples/*.html`
|
||||
|
||||
---
|
||||
|
||||
**Fragen oder Feedback?** → docs@experimenta.science
|
||||
981
docs/design-examples/design-example1.html
Normal file
981
docs/design-examples/design-example1.html
Normal file
@@ -0,0 +1,981 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Jahreskarte verlängert | experimenta</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background: linear-gradient(135deg, #2e1065 0%, #1a0a3a 50%, #0f051d 100%);
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
color: white;
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Simplified Header */
|
||||
.header-wrapper {
|
||||
background: rgba(46, 16, 101, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.main-content {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
backdrop-filter: blur(15px);
|
||||
border-radius: 20px;
|
||||
padding: 60px 40px;
|
||||
margin: 40px 0;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #46c74a;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 100%;
|
||||
font-size: 4rem;
|
||||
color: #fff;
|
||||
margin-bottom: 30px;
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
margin-bottom: 30px;
|
||||
color: white;
|
||||
font-weight: 300;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 18px;
|
||||
margin-bottom: 25px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Progress Bar Styles */
|
||||
.progress-container {
|
||||
margin: 40px 0;
|
||||
padding: 30px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 15px;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.progress-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.progress-title {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #f59d24;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.progress-stats {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.progress-bar-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 15px;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #46c74a 0%, #66d96a 50%, #46c74a 100%);
|
||||
border-radius: 15px;
|
||||
transition: width 0s ease-out;
|
||||
position: relative;
|
||||
width: 0%;
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-percentage {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-info {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin: 30px 0;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
color: #f59d24;
|
||||
margin-bottom: 15px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.card-info p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 40px 30px;
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.contact-info p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: 30px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.contact-item strong {
|
||||
color: #f59d24;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.contact-item a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
transition: color 0.3s ease;
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.contact-item a:hover {
|
||||
color: #ffb347;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.info-section p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-section a {
|
||||
color: #f59d24;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.info-section a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
background: #e6007e;
|
||||
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
|
||||
background-size: 300%;
|
||||
color: #ffffff;
|
||||
padding: 10px 30px;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-position 1s,
|
||||
all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
margin-top: 30px;
|
||||
text-transform: none;
|
||||
line-height: 1.7em;
|
||||
position: relative;
|
||||
outline: 0;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.back-button:hover {
|
||||
background-position: 100%;
|
||||
}
|
||||
|
||||
/* Simplified Footer */
|
||||
.footer {
|
||||
background: linear-gradient(135deg, #1a0a3a 0%, #0f051d 100%);
|
||||
margin-top: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 60px 20px 30px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
display: grid;
|
||||
grid-template-columns: 2.5fr 1fr 1fr 1.5fr;
|
||||
gap: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.footer-section h3 {
|
||||
color: #e91e63;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.footer-section p {
|
||||
margin-bottom: 15px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.footer-links li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 200px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.partner-section {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.partner-logos {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.partner-logo {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 15px 20px;
|
||||
border-radius: 6px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
min-width: 120px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.partner-logo:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.social-links {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.social-links a {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: rgba(233, 30, 99, 0.2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.social-links a:hover {
|
||||
background: #e91e63;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.footer-bottom p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.footer-bottom-links a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-bottom-links a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.recognition-section {
|
||||
text-align: center;
|
||||
margin: 40px 0;
|
||||
padding: 30px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.recognition-section h4 {
|
||||
color: #e91e63;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
padding: 0 15px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 250px;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 40px 15px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
padding: 40px 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
padding: 25px 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.progress-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.progress-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.progress-stats {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.progress-bar-wrapper {
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.progress-percentage {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card-info,
|
||||
.contact-info,
|
||||
.info-section {
|
||||
margin: 20px 0;
|
||||
padding: 25px 20px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.card-info p,
|
||||
.contact-info p,
|
||||
.info-section p,
|
||||
.contact-item a,
|
||||
.contact-item strong,
|
||||
.info-section a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
grid-template-columns: 1fr;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.footer-bottom p,
|
||||
.footer-bottom-links a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 200px;
|
||||
max-width: 85%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
padding: 30px 15px;
|
||||
margin: 15px 0;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
padding: 20px 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.progress-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.progress-stats {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.progress-bar-wrapper {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.progress-percentage {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.card-info,
|
||||
.contact-info,
|
||||
.info-section {
|
||||
padding: 20px 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card-info p,
|
||||
.contact-info p,
|
||||
.info-section p,
|
||||
.contact-item a,
|
||||
.contact-item strong,
|
||||
.info-section a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
padding: 8px 24px;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.footer-bottom p,
|
||||
.footer-bottom-links a {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
gap: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Simplified Header -->
|
||||
<header class="header-wrapper">
|
||||
<div class="header-content">
|
||||
<a href="https://www.experimenta.science/" class="logo">
|
||||
<svg
|
||||
class="logo-svg"
|
||||
viewBox="0 0 382.94 87.17"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="a"
|
||||
x1="102.63"
|
||||
y1="152.32"
|
||||
x2="135.19"
|
||||
y2="191.11"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ce0f60" />
|
||||
<stop offset="0.47" stop-color="#de0b75" />
|
||||
<stop offset="0.59" stop-color="#e4097d" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="b"
|
||||
x1="104.87"
|
||||
y1="170.45"
|
||||
x2="104.87"
|
||||
y2="170.45"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ab1a4e" />
|
||||
<stop offset="0.43" stop-color="#9f1d4f" />
|
||||
<stop offset="0.57" stop-color="#9b1e4f" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="c"
|
||||
x1="68.79"
|
||||
y1="182.84"
|
||||
x2="154.66"
|
||||
y2="182.84"
|
||||
xlink:href="#b"
|
||||
/>
|
||||
<linearGradient
|
||||
id="d"
|
||||
x1="94.04"
|
||||
y1="182.21"
|
||||
x2="114.5"
|
||||
y2="126"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.22" stop-color="#e4097d" />
|
||||
<stop offset="0.32" stop-color="#e4115e" />
|
||||
<stop offset="0.45" stop-color="#e5193d" />
|
||||
<stop offset="0.55" stop-color="#e51e28" />
|
||||
<stop offset="0.62" stop-color="#e52021" />
|
||||
<stop offset="0.9" stop-color="#f7a822" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<polygon
|
||||
points="143.78 50 151.18 39.6 144.43 39.6 139.68 46.33 135.13 39.6 127.79 39.6 135.32 50.08 127.29 61.23 134.09 61.23 139.3 53.78 144.43 61.23 151.59 61.23 143.78 50"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M245.79,175.33a9.2,9.2,0,0,0-1.85-3.39,7.28,7.28,0,0,0-2.9-2,10.29,10.29,0,0,0-3.65-.63c-3.12,0-5.47.95-7,2.82l-.56-2.23h-7.72v5.29h3.13v24.7h6.13v-8.4a8.29,8.29,0,0,0,1.7.42,17.3,17.3,0,0,0,2.6.19,11.8,11.8,0,0,0,4.53-.82,9.29,9.29,0,0,0,3.39-2.39,10.78,10.78,0,0,0,2.11-3.78,15.69,15.69,0,0,0,.74-5A16,16,0,0,0,245.79,175.33Zm-12.76,0a5.26,5.26,0,0,1,2.73-.75,4,4,0,0,1,3.12,1.4,5.85,5.85,0,0,1,1.25,4,10.56,10.56,0,0,1-.4,3.12,5.84,5.84,0,0,1-1.1,2.09,4.11,4.11,0,0,1-1.62,1.18,7.15,7.15,0,0,1-4.21.12,4.71,4.71,0,0,1-1.43-.58v-8.48A3.79,3.79,0,0,1,233,175.35Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M270.8,174.1a8.1,8.1,0,0,0-2.42-2.86,9.3,9.3,0,0,0-3.24-1.5,14.1,14.1,0,0,0-7.91.28,10.48,10.48,0,0,0-3.7,2.14,10,10,0,0,0-2.49,3.58,12.71,12.71,0,0,0-.9,5,13.24,13.24,0,0,0,.79,4.74,9.75,9.75,0,0,0,6,5.88,14.71,14.71,0,0,0,4.91.77,15.93,15.93,0,0,0,3-.26,14.61,14.61,0,0,0,2.59-.68,13.18,13.18,0,0,0,2.05-.92,8,8,0,0,0,1.47-1l.19-.18L269,184.85l-.33.28a8.34,8.34,0,0,1-2.51,1.36,11.84,11.84,0,0,1-4,.57,9.83,9.83,0,0,1-2.28-.26,6,6,0,0,1-1.85-.81,4.16,4.16,0,0,1-1.28-1.39,4.33,4.33,0,0,1-.5-1.75h15l.05-.28a19.77,19.77,0,0,0,.43-4A9.75,9.75,0,0,0,270.8,174.1Zm-11.06.54a6.52,6.52,0,0,1,1.95-.29,4.29,4.29,0,0,1,3.24,1.11,4.13,4.13,0,0,1,1.05,2.72h-9.55a4.05,4.05,0,0,1,.5-1.39,4.45,4.45,0,0,1,1.18-1.33A5.21,5.21,0,0,1,259.74,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M194.59,174.1a8,8,0,0,0-2.43-2.86,9.26,9.26,0,0,0-3.23-1.5A14.09,14.09,0,0,0,181,170a10.48,10.48,0,0,0-3.7,2.14,10,10,0,0,0-2.49,3.58,12.7,12.7,0,0,0-.91,5,13.23,13.23,0,0,0,.8,4.74,9.75,9.75,0,0,0,6,5.88,14.71,14.71,0,0,0,4.91.77,15.82,15.82,0,0,0,3-.26,14.38,14.38,0,0,0,2.59-.68,12.91,12.91,0,0,0,2.06-.92,8,8,0,0,0,1.47-1l.19-.18-2.11-4.18-.34.28a8.22,8.22,0,0,1-2.51,1.36,11.78,11.78,0,0,1-4,.57,9.7,9.7,0,0,1-2.28-.26,6,6,0,0,1-1.86-.81,4.23,4.23,0,0,1-1.27-1.39,4.33,4.33,0,0,1-.5-1.75h15l.06-.28a20.47,20.47,0,0,0,.42-4A9.75,9.75,0,0,0,194.59,174.1Zm-11.06.54a6.52,6.52,0,0,1,1.95-.29,4.31,4.31,0,0,1,3.24,1.11,4.07,4.07,0,0,1,1,2.72h-9.54a4,4,0,0,1,.49-1.39,4.35,4.35,0,0,1,1.19-1.33A5.21,5.21,0,0,1,183.53,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M298.09,178.12v-.34c0-3-.49-5.07-1.52-6.37a5.07,5.07,0,0,0-4.22-2,6.89,6.89,0,0,0-3.69,1,11.46,11.46,0,0,0-2.44,2l-.58-2.52h-10v5.29h5.18v11h-5.18v5.3H296v-5.3h-9.08v-8.47a8.94,8.94,0,0,1,1.61-1.76,3.84,3.84,0,0,1,2.48-.76,1.2,1.2,0,0,1,1.11.54,3.85,3.85,0,0,1,.39,2v.34Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M350.79,173.27a5.61,5.61,0,0,0-1.16-2.29,4.05,4.05,0,0,0-1.79-1.21,7.17,7.17,0,0,0-2.24-.33,6.19,6.19,0,0,0-3.12.82,5,5,0,0,0-1.79,1.7,3.66,3.66,0,0,0-1.7-1.81,6.39,6.39,0,0,0-2.92-.71,6,6,0,0,0-3.17.82,5.75,5.75,0,0,0-1.71,1.57l-.53-1.93h-4.78v21.62h6V176.07a1.89,1.89,0,0,1,.72-.94,2,2,0,0,1,1.92-.27,1.05,1.05,0,0,1,.53.44,3.5,3.5,0,0,1,.41,1.11,9.26,9.26,0,0,1,.17,2v13.16h6V175.94a1.5,1.5,0,0,1,.63-.9,2.12,2.12,0,0,1,1.18-.31,1.62,1.62,0,0,1,1.29.63,3.88,3.88,0,0,1,.56,2.42v13.74h6V176.86A14.23,14.23,0,0,0,350.79,173.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M375.88,174.1a8,8,0,0,0-2.43-2.86,9.3,9.3,0,0,0-3.24-1.5,14.1,14.1,0,0,0-7.91.28,10.44,10.44,0,0,0-3.69,2.14,10.11,10.11,0,0,0-2.5,3.58,12.71,12.71,0,0,0-.9,5,13.46,13.46,0,0,0,.79,4.74,9.89,9.89,0,0,0,2.32,3.6,10,10,0,0,0,3.71,2.28,14.65,14.65,0,0,0,4.9.77,15.93,15.93,0,0,0,3-.26,14.61,14.61,0,0,0,2.59-.68,13.77,13.77,0,0,0,2.06-.92,8.18,8.18,0,0,0,1.47-1l.19-.18-2.12-4.18-.33.28a8.34,8.34,0,0,1-2.51,1.36,11.82,11.82,0,0,1-4,.57,9.7,9.7,0,0,1-2.28-.26,5.93,5.93,0,0,1-1.86-.81,4.23,4.23,0,0,1-1.27-1.39,4.18,4.18,0,0,1-.5-1.75h15l.06-.28a20.52,20.52,0,0,0,.43-4A9.75,9.75,0,0,0,375.88,174.1Zm-11.06.54a6.5,6.5,0,0,1,1.94-.29,4.33,4.33,0,0,1,3.25,1.11,4.18,4.18,0,0,1,1.05,2.72h-9.55a3.84,3.84,0,0,1,.49-1.39,4.35,4.35,0,0,1,1.19-1.33A5.21,5.21,0,0,1,364.82,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M401.33,174a7,7,0,0,0-1.61-2.75,5.79,5.79,0,0,0-2.46-1.46,10.19,10.19,0,0,0-3-.44,9,9,0,0,0-7,3.07l-.57-2.48h-7.94v5.29h3v16.33h6.13V177.67a4.13,4.13,0,0,1,1.59-2,4.48,4.48,0,0,1,2.62-.83,3.6,3.6,0,0,1,2.67,1,4.72,4.72,0,0,1,1,3.43v12.24h6.14V178.15A13.05,13.05,0,0,0,401.33,174Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M425.62,183.62l-1.41,1.17a9.47,9.47,0,0,1-1.29.89,7,7,0,0,1-3.53.92,3.83,3.83,0,0,1-3.12-1.32,7,7,0,0,1-1.14-4.45v-5.64h11V169.9h-11v-6.43L409,165.21v4.69h-4.14v5.29H409v5.64c0,3.87.83,6.74,2.46,8.54s4.09,2.73,7.31,2.73a12.69,12.69,0,0,0,2.7-.3,14.51,14.51,0,0,0,2.64-.84,15.43,15.43,0,0,0,2.35-1.24,8.09,8.09,0,0,0,1.85-1.59l.17-.2Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M449,186.22c0-.27-.06-.54-.1-.81-.05-.71-.08-1.36-.08-1.94,0-.78.05-1.66.14-2.65s.16-2.25.16-3.67a10.5,10.5,0,0,0-.44-3.12,6,6,0,0,0-1.45-2.44,6.56,6.56,0,0,0-2.6-1.57,11.86,11.86,0,0,0-3.81-.54,22.68,22.68,0,0,0-5.29.55,23.45,23.45,0,0,0-3.93,1.32l-.28.12,1.49,4.95.36-.17a22.8,22.8,0,0,1,2.83-1.07,12,12,0,0,1,3.71-.53,4.18,4.18,0,0,1,2.5.62,2.33,2.33,0,0,1,.77,2v.8a2.53,2.53,0,0,1,0,.47l-1.71-.15c-.56,0-1.1-.08-1.61-.08a17.54,17.54,0,0,0-3.92.41,9.29,9.29,0,0,0-3.07,1.26,5.82,5.82,0,0,0-2,2.22,7.07,7.07,0,0,0-.68,3.19,6.12,6.12,0,0,0,1.94,4.7,7.43,7.43,0,0,0,5.19,1.76,8.26,8.26,0,0,0,4.33-1,7.94,7.94,0,0,0,2.17-1.9l.49,2.56h7.66v-5.3Zm-12.43-2.67a2.4,2.4,0,0,1,.88-.71,4.48,4.48,0,0,1,1.31-.43,7.73,7.73,0,0,1,1.51-.15,13.48,13.48,0,0,1,1.73.11c.38,0,.69.09.94.13v2.13a4.16,4.16,0,0,1-4.08,2.05,2.92,2.92,0,0,1-2-.55,2.07,2.07,0,0,1-.57-1.57A1.68,1.68,0,0,1,436.52,183.55Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<polygon
|
||||
points="249.76 48.18 241.03 39.45 230.96 49.53 230.96 52.96 233.6 50.29 240.61 57.31 238.01 59.91 239.67 61.58 253.68 47.56 253.68 44.27 249.76 48.18"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M314.12,162.94a5.56,5.56,0,1,1-5.55-5.55A5.55,5.55,0,0,1,314.12,162.94Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M275.61,204.76l.56,0,.9-.06,1.06-.05,1,0a6.75,6.75,0,0,1,2.74.49,4.2,4.2,0,0,1,1.72,1.32,5.15,5.15,0,0,1,.88,2,11.58,11.58,0,0,1,.25,2.5,11.24,11.24,0,0,1-.25,2.4,5.62,5.62,0,0,1-.9,2.09,4.62,4.62,0,0,1-1.79,1.48,6.81,6.81,0,0,1-2.95.56l-.73,0-.91,0-.89-.06a4.37,4.37,0,0,1-.65-.06Zm3.57,2c-.22,0-.44,0-.66,0l-.48.05v8.34l.22,0h.29l.29,0h.24a3.13,3.13,0,0,0,1.64-.38,2.41,2.41,0,0,0,.92-1,4.31,4.31,0,0,0,.39-1.4,13.77,13.77,0,0,0,.09-1.57,13.6,13.6,0,0,0-.08-1.4,4.16,4.16,0,0,0-.38-1.34,2.46,2.46,0,0,0-.88-1A2.85,2.85,0,0,0,279.18,206.76Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M286.81,208.92a11,11,0,0,1,1.65-.55,9.5,9.5,0,0,1,2.21-.23,5.19,5.19,0,0,1,1.58.22,2.63,2.63,0,0,1,1.05.64,2.38,2.38,0,0,1,.57,1,4.26,4.26,0,0,1,.18,1.28c0,.61,0,1.13-.06,1.55s-.06.81-.06,1.14,0,.53,0,.84a3.93,3.93,0,0,1,.06.48h1.15v2h-3L292,216h-.08a3.31,3.31,0,0,1-1,1,3.46,3.46,0,0,1-1.77.4,3,3,0,0,1-2.1-.71,2.45,2.45,0,0,1-.78-1.89,2.86,2.86,0,0,1,.27-1.29,2.28,2.28,0,0,1,.8-.89,4,4,0,0,1,1.25-.52,7.54,7.54,0,0,1,1.64-.16l.67,0c.24,0,.52,0,.87.07a2.07,2.07,0,0,0,0-.35v-.34a1.13,1.13,0,0,0-.39-1,1.86,1.86,0,0,0-1.15-.29,5.11,5.11,0,0,0-1.62.23,9.05,9.05,0,0,0-1.22.46Zm3,6.53a2.12,2.12,0,0,0,1.27-.31,2.1,2.1,0,0,0,.61-.67v-1.06a4.92,4.92,0,0,0-.52-.08,6.06,6.06,0,0,0-.76-.05,3.05,3.05,0,0,0-.67.07,2.22,2.22,0,0,0-.6.19,1.31,1.31,0,0,0-.42.35.86.86,0,0,0-.16.51,1,1,0,0,0,.29.78A1.39,1.39,0,0,0,289.84,215.45Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M302.86,214.76a.64.64,0,0,0-.44-.57,6.8,6.8,0,0,0-1.07-.39q-.64-.18-1.41-.36a6.44,6.44,0,0,1-1.4-.52,3.49,3.49,0,0,1-1.08-.84,1.93,1.93,0,0,1-.44-1.3,2.2,2.2,0,0,1,.3-1.16,2.59,2.59,0,0,1,.8-.85,3.82,3.82,0,0,1,1.21-.52,6.09,6.09,0,0,1,1.52-.18,7.73,7.73,0,0,1,1.53.13,7.07,7.07,0,0,1,1.15.3,4.28,4.28,0,0,1,.83.4l.6.4-1,1.58-.61-.33-.73-.31a6.89,6.89,0,0,0-.81-.23,3.81,3.81,0,0,0-.82-.09,3.15,3.15,0,0,0-1.21.2.63.63,0,0,0-.46.6c0,.21.14.39.43.52a6.8,6.8,0,0,0,1.08.36l1.4.37a8.06,8.06,0,0,1,1.41.5,3.52,3.52,0,0,1,1.08.81,1.89,1.89,0,0,1,.43,1.28,2.57,2.57,0,0,1-1,2.13,4.69,4.69,0,0,1-2.92.77,7,7,0,0,1-2.64-.45,6,6,0,0,1-1.79-1.06l1.07-1.67a4.73,4.73,0,0,0,.61.43,5.31,5.31,0,0,0,.86.44,7.61,7.61,0,0,0,1,.33,4.55,4.55,0,0,0,1.08.13,2.26,2.26,0,0,0,1-.19A.68.68,0,0,0,302.86,214.76Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M311.81,213.14h1.95v1.76l.11,0a5.28,5.28,0,0,0,.9.29,4.3,4.3,0,0,0,1,.12,2.61,2.61,0,0,0,1.54-.4,1.27,1.27,0,0,0,.55-1.08,1.22,1.22,0,0,0-.45-1,4.42,4.42,0,0,0-1.12-.66c-.44-.19-.93-.37-1.46-.57a7.09,7.09,0,0,1-1.46-.72,4.15,4.15,0,0,1-1.12-1.09,3,3,0,0,1-.45-1.71,3.35,3.35,0,0,1,.31-1.46,3.4,3.4,0,0,1,.87-1.15,4.1,4.1,0,0,1,1.35-.75,5.29,5.29,0,0,1,1.74-.27,11.64,11.64,0,0,1,2.13.2,6.05,6.05,0,0,1,1.68.53v3.62h-2v-2l-.11,0c-.26-.07-.54-.12-.84-.17a6.8,6.8,0,0,0-.9-.06,2.27,2.27,0,0,0-1.34.34,1,1,0,0,0-.49.91,1.19,1.19,0,0,0,.45,1,5.35,5.35,0,0,0,1.12.67c.45.2.93.4,1.46.61a7.15,7.15,0,0,1,1.46.74,4,4,0,0,1,1.12,1.09,2.86,2.86,0,0,1,.45,1.65,3.92,3.92,0,0,1-.35,1.69,3.41,3.41,0,0,1-1,1.2,4.33,4.33,0,0,1-1.51.73,7.68,7.68,0,0,1-3.14.14,7.59,7.59,0,0,1-1.07-.27,8.12,8.12,0,0,1-.86-.34l-.6-.3Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M330.86,216.36a5.24,5.24,0,0,1-1.71.83,7.74,7.74,0,0,1-2,.27,5.92,5.92,0,0,1-2.05-.33,4.16,4.16,0,0,1-1.51-1,4.12,4.12,0,0,1-.94-1.48,5.6,5.6,0,0,1-.32-1.92,5,5,0,0,1,.38-2,3.93,3.93,0,0,1,1-1.48,4.55,4.55,0,0,1,1.57-.92,6.21,6.21,0,0,1,2-.31,7.43,7.43,0,0,1,1.87.23,9.76,9.76,0,0,1,1.34.45v3.13h-2v-1.64a5.22,5.22,0,0,0-1.1-.12,3.35,3.35,0,0,0-1,.15,2.32,2.32,0,0,0-.87.48,2.6,2.6,0,0,0-.63.82,3.12,3.12,0,0,0,0,2.25,2.51,2.51,0,0,0,.55.83,2.42,2.42,0,0,0,.88.56,3.13,3.13,0,0,0,1.17.21,4.15,4.15,0,0,0,1.66-.29,7.06,7.06,0,0,0,1-.49Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M332.69,215.26h3.13v-5h-3.13v-2h5.44v6.94h3.29v2h-8.73Zm2.7-9.36a1.26,1.26,0,0,1,.41-.94,1.58,1.58,0,0,1,1.14-.39,1.74,1.74,0,0,1,1.19.39,1.19,1.19,0,0,1,.44.94,1.16,1.16,0,0,1-.44.94,1.84,1.84,0,0,1-1.19.36,1.66,1.66,0,0,1-1.14-.36A1.23,1.23,0,0,1,335.39,205.9Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M351.63,216.27a3.11,3.11,0,0,1-.6.42,5.25,5.25,0,0,1-.85.38,6.28,6.28,0,0,1-1.08.29,7,7,0,0,1-1.24.1,5.9,5.9,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4.14,4.14,0,0,1-.95-1.48,6,6,0,0,1,0-4,4.07,4.07,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.88-.29,5.78,5.78,0,0,1,1.4.18,3.92,3.92,0,0,1,1.33.61,3.23,3.23,0,0,1,1,1.17,3.87,3.87,0,0,1,.39,1.85,8.31,8.31,0,0,1-.18,1.65h-6.41a2,2,0,0,0,.24,1,1.91,1.91,0,0,0,.59.64,2.56,2.56,0,0,0,.84.37,4.57,4.57,0,0,0,1,.11,5.35,5.35,0,0,0,1.75-.24,3.81,3.81,0,0,0,1.12-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.34,2.34,0,0,0-.74.37,2,2,0,0,0-.54.61,1.71,1.71,0,0,0-.25.81h4.37a1.76,1.76,0,0,0-2-1.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M352.84,208.32H356l.27,1.17h.07a3.42,3.42,0,0,1,1.17-1,3.68,3.68,0,0,1,1.84-.43,4.11,4.11,0,0,1,1.23.18,2.26,2.26,0,0,1,1,.59,2.84,2.84,0,0,1,.65,1.11,5.39,5.39,0,0,1,.24,1.73v5.53H360.1v-5.05a2.14,2.14,0,0,0-.49-1.56,1.7,1.7,0,0,0-1.24-.48,2,2,0,0,0-1.2.38,1.9,1.9,0,0,0-.74.95v5.76h-2.31v-6.93h-1.28Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M372.83,216.36a5.09,5.09,0,0,1-1.7.83,7.74,7.74,0,0,1-2.05.27,5.88,5.88,0,0,1-2.05-.33,4.29,4.29,0,0,1-1.52-1,4,4,0,0,1-.93-1.48,5.6,5.6,0,0,1-.32-1.92,5,5,0,0,1,.37-2,4.17,4.17,0,0,1,1-1.48,4.6,4.6,0,0,1,1.58-.92,6.21,6.21,0,0,1,2-.31,7.43,7.43,0,0,1,1.87.23,9.1,9.1,0,0,1,1.33.45v3.13h-1.95v-1.64a5.24,5.24,0,0,0-1.11-.12,3.28,3.28,0,0,0-1,.15,2.32,2.32,0,0,0-.87.48,2.46,2.46,0,0,0-.63.82,3,3,0,0,0,0,2.25,2.36,2.36,0,0,0,.55.83,2.42,2.42,0,0,0,.88.56,3.13,3.13,0,0,0,1.17.21,4.19,4.19,0,0,0,1.66-.29,7.71,7.71,0,0,0,1-.49Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M383.11,216.27a3.34,3.34,0,0,1-.59.42,5.81,5.81,0,0,1-.86.38,6.16,6.16,0,0,1-1.07.29,7.11,7.11,0,0,1-1.25.1,5.85,5.85,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4,4,0,0,1-1-1.48,5.67,5.67,0,0,1-.33-2,5.26,5.26,0,0,1,.38-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.89-.29,5.7,5.7,0,0,1,1.39.18,3.75,3.75,0,0,1,1.33.61,3.36,3.36,0,0,1,1,1.17,4,4,0,0,1,.38,1.85,8.31,8.31,0,0,1-.18,1.65h-6.4a2,2,0,0,0,.24,1,1.79,1.79,0,0,0,.58.64,2.66,2.66,0,0,0,.84.37,4.6,4.6,0,0,0,1,.11,5.39,5.39,0,0,0,1.75-.24,3.87,3.87,0,0,0,1.11-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.45,2.45,0,0,0-.74.37,2,2,0,0,0-.54.61,1.83,1.83,0,0,0-.25.81h4.38a2,2,0,0,0-.49-1.4A1.94,1.94,0,0,0,379.27,209.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M397.17,213h1.95v3.56a4.32,4.32,0,0,1-1.45.64,7.37,7.37,0,0,1-4-.11,5,5,0,0,1-1.85-1.12,5.51,5.51,0,0,1-1.28-2,8.35,8.35,0,0,1-.48-3,7.5,7.5,0,0,1,.54-3.07,5.58,5.58,0,0,1,1.39-2,5.16,5.16,0,0,1,1.91-1.09,6.82,6.82,0,0,1,2.06-.33,7.84,7.84,0,0,1,1.81.18,6.52,6.52,0,0,1,1.21.41v3.7H397v-2a7.11,7.11,0,0,0-1.14-.09,3.27,3.27,0,0,0-1.29.26,2.83,2.83,0,0,0-1,.79,3.77,3.77,0,0,0-.69,1.34,6.48,6.48,0,0,0-.25,1.92,6,6,0,0,0,.23,1.75,4,4,0,0,0,.67,1.36,3,3,0,0,0,1.09.88,3.26,3.26,0,0,0,1.46.31,6.12,6.12,0,0,0,1.14-.1Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M409.26,216.27a3.11,3.11,0,0,1-.6.42,5.25,5.25,0,0,1-.85.38,6.41,6.41,0,0,1-1.07.29,7.19,7.19,0,0,1-1.25.1,5.9,5.9,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4.14,4.14,0,0,1-.95-1.48,5.44,5.44,0,0,1-.33-2,5.26,5.26,0,0,1,.38-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.88-.29,5.78,5.78,0,0,1,1.4.18,3.92,3.92,0,0,1,1.33.61,3.23,3.23,0,0,1,1,1.17,3.87,3.87,0,0,1,.39,1.85,9.12,9.12,0,0,1-.18,1.65H403a2,2,0,0,0,.24,1,1.79,1.79,0,0,0,.58.64,2.47,2.47,0,0,0,.84.37,4.57,4.57,0,0,0,1,.11,5.35,5.35,0,0,0,1.75-.24,3.81,3.81,0,0,0,1.12-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.34,2.34,0,0,0-.74.37,2,2,0,0,0-.54.61,1.83,1.83,0,0,0-.25.81h4.37a1.75,1.75,0,0,0-2-1.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M410.47,208.32h3.11l.27,1.17h.07a3.46,3.46,0,0,1,1.18-1,3.64,3.64,0,0,1,1.83-.43a4.06,4.06,0,0,1,1.23.18,2.26,2.26,0,0,1,1,.59,2.84,2.84,0,0,1,.65,1.11,5.39,5.39,0,0,1,.24,1.73v5.53h-2.31v-5.05a2.1,2.1,0,0,0-.49-1.56,1.7,1.7,0,0,0-1.24-.48,2,2,0,0,0-1.2.38,1.9,1.9,0,0,0-.74.95v5.76h-2.31v-6.93h-1.28Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M422.81,210.28h-1.75v-2h1.75v-2l2.32-.66v2.69h4.66v2h-4.66v2.54a3.07,3.07,0,0,0,.51,2,1.8,1.8,0,0,0,1.44.62,3,3,0,0,0,.87-.12,2.85,2.85,0,0,0,.71-.29,4.07,4.07,0,0,0,.57-.39l.47-.39,1.07,1.6a4.11,4.11,0,0,1-.76.65,7,7,0,0,1-1,.51,5.78,5.78,0,0,1-1.09.35,5.4,5.4,0,0,1-1.12.12,3.84,3.84,0,0,1-3-1.11,5.17,5.17,0,0,1-1-3.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M440.74,216.27a3.34,3.34,0,0,1-.59.42,5.81,5.81,0,0,1-.86.38,6.16,6.16,0,0,1-1.07.29,7.11,7.11,0,0,1-1.25.1,5.85,5.85,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4,4,0,0,1-1-1.48,5.67,5.67,0,0,1-.32-2,5.26,5.26,0,0,1,.37-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.89-.29,5.7,5.7,0,0,1,1.39.18,3.83,3.83,0,0,1,1.33.61,3.36,3.36,0,0,1,1,1.17,4,4,0,0,1,.38,1.85,8.31,8.31,0,0,1-.18,1.65h-6.4a2,2,0,0,0,.24,1,1.81,1.81,0,0,0,.59.64,2.51,2.51,0,0,0,.83.37,4.67,4.67,0,0,0,1,.11,5.39,5.39,0,0,0,1.75-.24,3.87,3.87,0,0,0,1.11-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.45,2.45,0,0,0-.74.37,2,2,0,0,0-.79,1.42h4.38a2,2,0,0,0-.49-1.4A1.94,1.94,0,0,0,436.9,209.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M442.43,215.26h2.21v-5h-2.21v-2h4l.26,1.17h.07a5,5,0,0,1,1.14-1,2.84,2.84,0,0,1,1.5-.39,2,2,0,0,1,1.68.78,4.28,4.28,0,0,1,.61,2.61h-2.08a1.72,1.72,0,0,0-.19-.93.64.64,0,0,0-.59-.3,1.74,1.74,0,0,0-1.15.36,3.6,3.6,0,0,0-.74.82v3.79h3.86v2h-8.38Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M93.1,181.53l20.42-19.22c.87-.76,1.61-1.66,2.61-1.8,1.19-.17,3,1.09,3.3,1.28s10.7,6.64,12.57,7.77l15.75,9.71c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53h0s-17.5-10.32-22.43-13.18a22.83,22.83,0,0,0-11-3c-4.71.09-8.62,2.32-12.24,5h0l-24,18.2,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83A17.88,17.88,0,0,0,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#a)"
|
||||
/>
|
||||
<path d="M104.87,170.45h0" transform="translate(-68.76 -130.29)" fill="url(#b)" />
|
||||
<path
|
||||
d="M93.1,181.53h0l11.77-11.08a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11-7.26,5.5s-4.11,2.67-4,6.32c.15,4.65,5.34,6.69,5.34,6.69l30.63,13.13a35.93,35.93,0,0,0,11.38,2.53c3.39.08,6.83-1.14,10.49-2.24l24.76-8.46c1.26-.41,3.26-1.65,3.26-3.17,0-1.2-1.57-2.73-3.33-3.51a16.28,16.28,0,0,0-8.57-1.19c-4.7.44-25.95,7.65-25.95,7.65L93.16,184.23a1.28,1.28,0,0,1-.91-1.58A2.68,2.68,0,0,1,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#c)"
|
||||
/>
|
||||
<path
|
||||
d="M147.75,179.27c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53L132,169.56l-27.13.89h0a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73h0a66.73,66.73,0,0,0,7.06.19C107.65,182,144.08,180.38,147.75,179.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#e4097d"
|
||||
/>
|
||||
<path
|
||||
d="M104.87,170.45a3.26,3.26,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.67-9-3-3.55a1.94,1.94,0,0,1-.41-1.27,2.18,2.18,0,0,1,1-1.83L110,141.9a6.43,6.43,0,0,1,1.81-.87,5.82,5.82,0,0,1,1.86.09l16.49,2.64a24.38,24.38,0,0,0,9.39-.52c1.94-.49,4.31-1.25,5.39-2.91s-.6-2.9-1.11-3.27c-2.08-1.5-4.67-1.92-7.18-2.32l-25.48-4.08a23.84,23.84,0,0,0-10.88.57A19.61,19.61,0,0,0,95,133.6L71.44,149.36a6.34,6.34,0,0,0-1.08,9.38l.21.27,13.12,17a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#d)"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content">
|
||||
<div class="success-message">
|
||||
<div class="success-icon">✓</div>
|
||||
<h1>Jahreskarten-Verlängerungen</h1>
|
||||
|
||||
<!-- Progress Bar Section -->
|
||||
<div class="progress-container">
|
||||
<div class="progress-header">
|
||||
<h3 class="progress-title">Verlängerungsfortschritt</h3>
|
||||
<div class="progress-stats">{{payload.count}} / {{payload.total}}</div>
|
||||
</div>
|
||||
<div class="progress-bar-wrapper">
|
||||
<div class="progress-bar" id="progressBar"></div>
|
||||
<div class="progress-percentage" id="progressPercentage">{{payload.perc}}%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="https://www.experimenta.science/" class="back-button"
|
||||
>Zur experimenta Startseite</a
|
||||
>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<div class="footer-bottom">
|
||||
<p>© 2025 experimenta gGmbH – Das Science Center. Alle Rechte vorbehalten.</p>
|
||||
<div class="footer-bottom-links">
|
||||
<a href="https://www.experimenta.science/kontakt/">Kontakt</a>
|
||||
<a href="https://www.experimenta.science/impressum/">Impressum</a>
|
||||
<a href="https://www.experimenta.science/datenschutz/">Datenschutz</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Wait for page to load, then animate progress bar
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Get the percentage value from the template variable
|
||||
const percentage = parseFloat('{{payload.perc}}') || 0
|
||||
const progressBar = document.getElementById('progressBar')
|
||||
|
||||
// Animate the progress bar after a short delay
|
||||
setTimeout(function () {
|
||||
progressBar.style.width = percentage + '%'
|
||||
}, 0)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
867
docs/design-examples/design-example2-success.html
Normal file
867
docs/design-examples/design-example2-success.html
Normal file
@@ -0,0 +1,867 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Jahreskarte verlängert | experimenta</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background: linear-gradient(135deg, #2e1065 0%, #1a0a3a 50%, #0f051d 100%);
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
color: white;
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Simplified Header */
|
||||
.header-wrapper {
|
||||
background: rgba(46, 16, 101, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.main-content {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
backdrop-filter: blur(15px);
|
||||
border-radius: 20px;
|
||||
padding: 60px 40px;
|
||||
margin: 40px 0;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #46c74a;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 100%;
|
||||
font-size: 4rem;
|
||||
color: #fff;
|
||||
margin-bottom: 30px;
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
margin-bottom: 30px;
|
||||
color: white;
|
||||
font-weight: 300;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 18px;
|
||||
margin-bottom: 25px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.card-info {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin: 30px 0;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
color: #f59d24;
|
||||
margin-bottom: 15px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.card-info p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 40px 30px;
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.contact-info p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: 30px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.contact-item strong {
|
||||
color: #f59d24;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.contact-item a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
transition: color 0.3s ease;
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.contact-item a:hover {
|
||||
color: #ffb347;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.info-section p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-section a {
|
||||
color: #f59d24;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.info-section a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
background: #e6007e;
|
||||
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
|
||||
background-size: 300%;
|
||||
color: #ffffff;
|
||||
padding: 10px 30px;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-position 1s,
|
||||
all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
margin-top: 30px;
|
||||
text-transform: none;
|
||||
line-height: 1.7em;
|
||||
position: relative;
|
||||
outline: 0;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.back-button:hover {
|
||||
background-position: 100%;
|
||||
}
|
||||
|
||||
/* Simplified Footer */
|
||||
.footer {
|
||||
background: linear-gradient(135deg, #1a0a3a 0%, #0f051d 100%);
|
||||
margin-top: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 60px 20px 30px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
display: grid;
|
||||
grid-template-columns: 2.5fr 1fr 1fr 1.5fr;
|
||||
gap: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.footer-section h3 {
|
||||
color: #e91e63;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.footer-section p {
|
||||
margin-bottom: 15px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.footer-links li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 200px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.partner-section {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.partner-logos {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.partner-logo {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 15px 20px;
|
||||
border-radius: 6px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
min-width: 120px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.partner-logo:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.social-links {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.social-links a {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: rgba(233, 30, 99, 0.2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.social-links a:hover {
|
||||
background: #e91e63;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.footer-bottom p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.footer-bottom-links a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-bottom-links a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.recognition-section {
|
||||
text-align: center;
|
||||
margin: 40px 0;
|
||||
padding: 30px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.recognition-section h4 {
|
||||
color: #e91e63;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
padding: 0 15px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 250px;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 40px 15px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
padding: 40px 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.card-info,
|
||||
.contact-info,
|
||||
.info-section {
|
||||
margin: 20px 0;
|
||||
padding: 25px 20px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.card-info p,
|
||||
.contact-info p,
|
||||
.info-section p,
|
||||
.contact-item a,
|
||||
.contact-item strong,
|
||||
.info-section a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
grid-template-columns: 1fr;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.footer-bottom p,
|
||||
.footer-bottom-links a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 200px;
|
||||
max-width: 85%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
padding: 30px 15px;
|
||||
margin: 15px 0;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.card-info,
|
||||
.contact-info,
|
||||
.info-section {
|
||||
padding: 20px 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card-info p,
|
||||
.contact-info p,
|
||||
.info-section p,
|
||||
.contact-item a,
|
||||
.contact-item strong,
|
||||
.info-section a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.success-icon {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
padding: 8px 24px;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.footer-bottom p,
|
||||
.footer-bottom-links a {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
gap: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Simplified Header -->
|
||||
<header class="header-wrapper">
|
||||
<div class="header-content">
|
||||
<a href="https://www.experimenta.science/" class="logo">
|
||||
<svg
|
||||
class="logo-svg"
|
||||
viewBox="0 0 382.94 87.17"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="a"
|
||||
x1="102.63"
|
||||
y1="152.32"
|
||||
x2="135.19"
|
||||
y2="191.11"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ce0f60" />
|
||||
<stop offset="0.47" stop-color="#de0b75" />
|
||||
<stop offset="0.59" stop-color="#e4097d" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="b"
|
||||
x1="104.87"
|
||||
y1="170.45"
|
||||
x2="104.87"
|
||||
y2="170.45"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ab1a4e" />
|
||||
<stop offset="0.43" stop-color="#9f1d4f" />
|
||||
<stop offset="0.57" stop-color="#9b1e4f" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="c"
|
||||
x1="68.79"
|
||||
y1="182.84"
|
||||
x2="154.66"
|
||||
y2="182.84"
|
||||
xlink:href="#b"
|
||||
/>
|
||||
<linearGradient
|
||||
id="d"
|
||||
x1="94.04"
|
||||
y1="182.21"
|
||||
x2="114.5"
|
||||
y2="126"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.22" stop-color="#e4097d" />
|
||||
<stop offset="0.32" stop-color="#e4115e" />
|
||||
<stop offset="0.45" stop-color="#e5193d" />
|
||||
<stop offset="0.55" stop-color="#e51e28" />
|
||||
<stop offset="0.62" stop-color="#e52021" />
|
||||
<stop offset="0.9" stop-color="#f7a822" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<polygon
|
||||
points="143.78 50 151.18 39.6 144.43 39.6 139.68 46.33 135.13 39.6 127.79 39.6 135.32 50.08 127.29 61.23 134.09 61.23 139.3 53.78 144.43 61.23 151.59 61.23 143.78 50"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M245.79,175.33a9.2,9.2,0,0,0-1.85-3.39,7.28,7.28,0,0,0-2.9-2,10.29,10.29,0,0,0-3.65-.63c-3.12,0-5.47.95-7,2.82l-.56-2.23h-7.72v5.29h3.13v24.7h6.13v-8.4a8.29,8.29,0,0,0,1.7.42,17.3,17.3,0,0,0,2.6.19,11.8,11.8,0,0,0,4.53-.82,9.29,9.29,0,0,0,3.39-2.39,10.78,10.78,0,0,0,2.11-3.78,15.69,15.69,0,0,0,.74-5A16,16,0,0,0,245.79,175.33Zm-12.76,0a5.26,5.26,0,0,1,2.73-.75,4,4,0,0,1,3.12,1.4,5.85,5.85,0,0,1,1.25,4,10.56,10.56,0,0,1-.4,3.12,5.84,5.84,0,0,1-1.1,2.09,4.11,4.11,0,0,1-1.62,1.18,7.15,7.15,0,0,1-4.21.12,4.71,4.71,0,0,1-1.43-.58v-8.48A3.79,3.79,0,0,1,233,175.35Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M270.8,174.1a8.1,8.1,0,0,0-2.42-2.86,9.3,9.3,0,0,0-3.24-1.5,14.1,14.1,0,0,0-7.91.28,10.48,10.48,0,0,0-3.7,2.14,10,10,0,0,0-2.49,3.58,12.71,12.71,0,0,0-.9,5,13.24,13.24,0,0,0,.79,4.74,9.75,9.75,0,0,0,6,5.88,14.71,14.71,0,0,0,4.91.77,15.93,15.93,0,0,0,3-.26,14.61,14.61,0,0,0,2.59-.68,13.18,13.18,0,0,0,2.05-.92,8,8,0,0,0,1.47-1l.19-.18L269,184.85l-.33.28a8.34,8.34,0,0,1-2.51,1.36,11.84,11.84,0,0,1-4,.57,9.83,9.83,0,0,1-2.28-.26,6,6,0,0,1-1.85-.81,4.16,4.16,0,0,1-1.28-1.39,4.33,4.33,0,0,1-.5-1.75h15l.05-.28a19.77,19.77,0,0,0,.43-4A9.75,9.75,0,0,0,270.8,174.1Zm-11.06.54a6.52,6.52,0,0,1,1.95-.29,4.29,4.29,0,0,1,3.24,1.11,4.13,4.13,0,0,1,1.05,2.72h-9.55a4.05,4.05,0,0,1,.5-1.39,4.45,4.45,0,0,1,1.18-1.33A5.21,5.21,0,0,1,259.74,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M194.59,174.1a8,8,0,0,0-2.43-2.86,9.26,9.26,0,0,0-3.23-1.5A14.09,14.09,0,0,0,181,170a10.48,10.48,0,0,0-3.7,2.14,10,10,0,0,0-2.49,3.58,12.7,12.7,0,0,0-.91,5,13.23,13.23,0,0,0,.8,4.74,9.75,9.75,0,0,0,6,5.88,14.71,14.71,0,0,0,4.91.77,15.82,15.82,0,0,0,3-.26,14.38,14.38,0,0,0,2.59-.68,12.91,12.91,0,0,0,2.06-.92,8,8,0,0,0,1.47-1l.19-.18-2.11-4.18-.34.28a8.22,8.22,0,0,1-2.51,1.36,11.78,11.78,0,0,1-4,.57,9.7,9.7,0,0,1-2.28-.26,6,6,0,0,1-1.86-.81,4.23,4.23,0,0,1-1.27-1.39,4.33,4.33,0,0,1-.5-1.75h15l.06-.28a20.47,20.47,0,0,0,.42-4A9.75,9.75,0,0,0,194.59,174.1Zm-11.06.54a6.52,6.52,0,0,1,1.95-.29,4.31,4.31,0,0,1,3.24,1.11,4.07,4.07,0,0,1,1,2.72h-9.54a4,4,0,0,1,.49-1.39,4.35,4.35,0,0,1,1.19-1.33A5.21,5.21,0,0,1,183.53,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M298.09,178.12v-.34c0-3-.49-5.07-1.52-6.37a5.07,5.07,0,0,0-4.22-2,6.89,6.89,0,0,0-3.69,1,11.46,11.46,0,0,0-2.44,2l-.58-2.52h-10v5.29h5.18v11h-5.18v5.3H296v-5.3h-9.08v-8.47a8.94,8.94,0,0,1,1.61-1.76,3.84,3.84,0,0,1,2.48-.76,1.2,1.2,0,0,1,1.11.54,3.85,3.85,0,0,1,.39,2v.34Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M350.79,173.27a5.61,5.61,0,0,0-1.16-2.29,4.05,4.05,0,0,0-1.79-1.21,7.17,7.17,0,0,0-2.24-.33,6.19,6.19,0,0,0-3.12.82,5,5,0,0,0-1.79,1.7,3.66,3.66,0,0,0-1.7-1.81,6.39,6.39,0,0,0-2.92-.71,6,6,0,0,0-3.17.82,5.75,5.75,0,0,0-1.71,1.57l-.53-1.93h-4.78v21.62h6V176.07a1.89,1.89,0,0,1,.72-.94,2,2,0,0,1,1.92-.27,1.05,1.05,0,0,1,.53.44,3.5,3.5,0,0,1,.41,1.11,9.26,9.26,0,0,1,.17,2v13.16h6V175.94a1.5,1.5,0,0,1,.63-.9,2.12,2.12,0,0,1,1.18-.31,1.62,1.62,0,0,1,1.29.63,3.88,3.88,0,0,1,.56,2.42v13.74h6V176.86A14.23,14.23,0,0,0,350.79,173.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M375.88,174.1a8,8,0,0,0-2.43-2.86,9.3,9.3,0,0,0-3.24-1.5,14.1,14.1,0,0,0-7.91.28,10.44,10.44,0,0,0-3.69,2.14,10.11,10.11,0,0,0-2.5,3.58,12.71,12.71,0,0,0-.9,5,13.46,13.46,0,0,0,.79,4.74,9.89,9.89,0,0,0,2.32,3.6,10,10,0,0,0,3.71,2.28,14.65,14.65,0,0,0,4.9.77,15.93,15.93,0,0,0,3-.26,14.61,14.61,0,0,0,2.59-.68,13.77,13.77,0,0,0,2.06-.92,8.18,8.18,0,0,0,1.47-1l.19-.18-2.12-4.18-.33.28a8.34,8.34,0,0,1-2.51,1.36,11.82,11.82,0,0,1-4,.57,9.7,9.7,0,0,1-2.28-.26,5.93,5.93,0,0,1-1.86-.81,4.23,4.23,0,0,1-1.27-1.39,4.18,4.18,0,0,1-.5-1.75h15l.06-.28a20.52,20.52,0,0,0,.43-4A9.75,9.75,0,0,0,375.88,174.1Zm-11.06.54a6.5,6.5,0,0,1,1.94-.29,4.33,4.33,0,0,1,3.25,1.11,4.18,4.18,0,0,1,1.05,2.72h-9.55a3.84,3.84,0,0,1,.49-1.39,4.35,4.35,0,0,1,1.19-1.33A5.21,5.21,0,0,1,364.82,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M401.33,174a7,7,0,0,0-1.61-2.75,5.79,5.79,0,0,0-2.46-1.46,10.19,10.19,0,0,0-3-.44,9,9,0,0,0-7,3.07l-.57-2.48h-7.94v5.29h3v16.33h6.13V177.67a4.13,4.13,0,0,1,1.59-2,4.48,4.48,0,0,1,2.62-.83,3.6,3.6,0,0,1,2.67,1,4.72,4.72,0,0,1,1,3.43v12.24h6.14V178.15A13.05,13.05,0,0,0,401.33,174Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M425.62,183.62l-1.41,1.17a9.47,9.47,0,0,1-1.29.89,7,7,0,0,1-3.53.92,3.83,3.83,0,0,1-3.12-1.32,7,7,0,0,1-1.14-4.45v-5.64h11V169.9h-11v-6.43L409,165.21v4.69h-4.14v5.29H409v5.64c0,3.87.83,6.74,2.46,8.54s4.09,2.73,7.31,2.73a12.69,12.69,0,0,0,2.7-.3,14.51,14.51,0,0,0,2.64-.84,15.43,15.43,0,0,0,2.35-1.24,8.09,8.09,0,0,0,1.85-1.59l.17-.2Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M449,186.22c0-.27-.06-.54-.1-.81-.05-.71-.08-1.36-.08-1.94,0-.78.05-1.66.14-2.65s.16-2.25.16-3.67a10.5,10.5,0,0,0-.44-3.12,6,6,0,0,0-1.45-2.44,6.56,6.56,0,0,0-2.6-1.57,11.86,11.86,0,0,0-3.81-.54,22.68,22.68,0,0,0-5.29.55,23.45,23.45,0,0,0-3.93,1.32l-.28.12,1.49,4.95.36-.17a22.8,22.8,0,0,1,2.83-1.07,12,12,0,0,1,3.71-.53,4.18,4.18,0,0,1,2.5.62,2.33,2.33,0,0,1,.77,2v.8a2.53,2.53,0,0,1,0,.47l-1.71-.15c-.56,0-1.1-.08-1.61-.08a17.54,17.54,0,0,0-3.92.41,9.29,9.29,0,0,0-3.07,1.26,5.82,5.82,0,0,0-2,2.22,7.07,7.07,0,0,0-.68,3.19,6.12,6.12,0,0,0,1.94,4.7,7.43,7.43,0,0,0,5.19,1.76,8.26,8.26,0,0,0,4.33-1,7.94,7.94,0,0,0,2.17-1.9l.49,2.56h7.66v-5.3Zm-12.43-2.67a2.4,2.4,0,0,1,.88-.71,4.48,4.48,0,0,1,1.31-.43,7.73,7.73,0,0,1,1.51-.15,13.48,13.48,0,0,1,1.73.11c.38,0,.69.09.94.13v2.13a4.16,4.16,0,0,1-4.08,2.05,2.92,2.92,0,0,1-2-.55,2.07,2.07,0,0,1-.57-1.57A1.68,1.68,0,0,1,436.52,183.55Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<polygon
|
||||
points="249.76 48.18 241.03 39.45 230.96 49.53 230.96 52.96 233.6 50.29 240.61 57.31 238.01 59.91 239.67 61.58 253.68 47.56 253.68 44.27 249.76 48.18"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M314.12,162.94a5.56,5.56,0,1,1-5.55-5.55A5.55,5.55,0,0,1,314.12,162.94Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M275.61,204.76l.56,0,.9-.06,1.06-.05,1,0a6.75,6.75,0,0,1,2.74.49,4.2,4.2,0,0,1,1.72,1.32,5.15,5.15,0,0,1,.88,2,11.58,11.58,0,0,1,.25,2.5,11.24,11.24,0,0,1-.25,2.4,5.62,5.62,0,0,1-.9,2.09,4.62,4.62,0,0,1-1.79,1.48,6.81,6.81,0,0,1-2.95.56l-.73,0-.91,0-.89-.06a4.37,4.37,0,0,1-.65-.06Zm3.57,2c-.22,0-.44,0-.66,0l-.48.05v8.34l.22,0h.29l.29,0h.24a3.13,3.13,0,0,0,1.64-.38,2.41,2.41,0,0,0,.92-1,4.31,4.31,0,0,0,.39-1.4,13.77,13.77,0,0,0,.09-1.57,13.6,13.6,0,0,0-.08-1.4,4.16,4.16,0,0,0-.38-1.34,2.46,2.46,0,0,0-.88-1A2.85,2.85,0,0,0,279.18,206.76Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M286.81,208.92a11,11,0,0,1,1.65-.55,9.5,9.5,0,0,1,2.21-.23,5.19,5.19,0,0,1,1.58.22,2.63,2.63,0,0,1,1.05.64,2.38,2.38,0,0,1,.57,1,4.26,4.26,0,0,1,.18,1.28c0,.61,0,1.13-.06,1.55s-.06.81-.06,1.14,0,.53,0,.84a3.93,3.93,0,0,1,.06.48h1.15v2h-3L292,216h-.08a3.31,3.31,0,0,1-1,1,3.46,3.46,0,0,1-1.77.4,3,3,0,0,1-2.1-.71,2.45,2.45,0,0,1-.78-1.89,2.86,2.86,0,0,1,.27-1.29,2.28,2.28,0,0,1,.8-.89,4,4,0,0,1,1.25-.52,7.54,7.54,0,0,1,1.64-.16l.67,0c.24,0,.52,0,.87.07a2.07,2.07,0,0,0,0-.35v-.34a1.13,1.13,0,0,0-.39-1,1.86,1.86,0,0,0-1.15-.29,5.11,5.11,0,0,0-1.62.23,9.05,9.05,0,0,0-1.22.46Zm3,6.53a2.12,2.12,0,0,0,1.27-.31,2.1,2.1,0,0,0,.61-.67v-1.06a4.92,4.92,0,0,0-.52-.08,6.06,6.06,0,0,0-.76-.05,3.05,3.05,0,0,0-.67.07,2.22,2.22,0,0,0-.6.19,1.31,1.31,0,0,0-.42.35.86.86,0,0,0-.16.51,1,1,0,0,0,.29.78A1.39,1.39,0,0,0,289.84,215.45Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M302.86,214.76a.64.64,0,0,0-.44-.57,6.8,6.8,0,0,0-1.07-.39q-.64-.18-1.41-.36a6.44,6.44,0,0,1-1.4-.52,3.49,3.49,0,0,1-1.08-.84,1.93,1.93,0,0,1-.44-1.3,2.2,2.2,0,0,1,.3-1.16,2.59,2.59,0,0,1,.8-.85,3.82,3.82,0,0,1,1.21-.52,6.09,6.09,0,0,1,1.52-.18,7.73,7.73,0,0,1,1.53.13,7.07,7.07,0,0,1,1.15.3,4.28,4.28,0,0,1,.83.4l.6.4-1,1.58-.61-.33-.73-.31a6.89,6.89,0,0,0-.81-.23,3.81,3.81,0,0,0-.82-.09,3.15,3.15,0,0,0-1.21.2.63.63,0,0,0-.46.6c0,.21.14.39.43.52a6.8,6.8,0,0,0,1.08.36l1.4.37a8.06,8.06,0,0,1,1.41.5,3.52,3.52,0,0,1,1.08.81,1.89,1.89,0,0,1,.43,1.28,2.57,2.57,0,0,1-1,2.13,4.69,4.69,0,0,1-2.92.77,7,7,0,0,1-2.64-.45,6,6,0,0,1-1.79-1.06l1.07-1.67a4.73,4.73,0,0,0,.61.43,5.31,5.31,0,0,0,.86.44,7.61,7.61,0,0,0,1,.33,4.55,4.55,0,0,0,1.08.13,2.26,2.26,0,0,0,1-.19A.68.68,0,0,0,302.86,214.76Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M311.81,213.14h1.95v1.76l.11,0a5.28,5.28,0,0,0,.9.29,4.3,4.3,0,0,0,1,.12,2.61,2.61,0,0,0,1.54-.4,1.27,1.27,0,0,0,.55-1.08,1.22,1.22,0,0,0-.45-1,4.42,4.42,0,0,0-1.12-.66c-.44-.19-.93-.37-1.46-.57a7.09,7.09,0,0,1-1.46-.72,4.15,4.15,0,0,1-1.12-1.09,3,3,0,0,1-.45-1.71,3.35,3.35,0,0,1,.31-1.46,3.4,3.4,0,0,1,.87-1.15,4.1,4.1,0,0,1,1.35-.75,5.29,5.29,0,0,1,1.74-.27,11.64,11.64,0,0,1,2.13.2,6.05,6.05,0,0,1,1.68.53v3.62h-2v-2l-.11,0c-.26-.07-.54-.12-.84-.17a6.8,6.8,0,0,0-.9-.06,2.27,2.27,0,0,0-1.34.34,1,1,0,0,0-.49.91,1.19,1.19,0,0,0,.45,1,5.35,5.35,0,0,0,1.12.67c.45.2.93.4,1.46.61a7.15,7.15,0,0,1,1.46.74,4,4,0,0,1,1.12,1.09,2.86,2.86,0,0,1,.45,1.65,3.92,3.92,0,0,1-.35,1.69,3.41,3.41,0,0,1-1,1.2,4.33,4.33,0,0,1-1.51.73,7.68,7.68,0,0,1-3.14.14,7.59,7.59,0,0,1-1.07-.27,8.12,8.12,0,0,1-.86-.34l-.6-.3Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M330.86,216.36a5.24,5.24,0,0,1-1.71.83,7.74,7.74,0,0,1-2,.27,5.92,5.92,0,0,1-2.05-.33,4.16,4.16,0,0,1-1.51-1,4.12,4.12,0,0,1-.94-1.48,5.6,5.6,0,0,1-.32-1.92,5,5,0,0,1,.38-2,3.93,3.93,0,0,1,1-1.48,4.55,4.55,0,0,1,1.57-.92,6.21,6.21,0,0,1,2-.31,7.43,7.43,0,0,1,1.87.23,9.76,9.76,0,0,1,1.34.45v3.13h-2v-1.64a5.22,5.22,0,0,0-1.1-.12,3.35,3.35,0,0,0-1,.15,2.32,2.32,0,0,0-.87.48,2.6,2.6,0,0,0-.63.82,3.12,3.12,0,0,0,0,2.25,2.51,2.51,0,0,0,.55.83,2.42,2.42,0,0,0,.88.56,3.13,3.13,0,0,0,1.17.21,4.15,4.15,0,0,0,1.66-.29,7.06,7.06,0,0,0,1-.49Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M332.69,215.26h3.13v-5h-3.13v-2h5.44v6.94h3.29v2h-8.73Zm2.7-9.36a1.26,1.26,0,0,1,.41-.94,1.58,1.58,0,0,1,1.14-.39,1.74,1.74,0,0,1,1.19.39,1.19,1.19,0,0,1,.44.94,1.16,1.16,0,0,1-.44.94,1.84,1.84,0,0,1-1.19.36,1.66,1.66,0,0,1-1.14-.36A1.23,1.23,0,0,1,335.39,205.9Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M351.63,216.27a3.11,3.11,0,0,1-.6.42,5.25,5.25,0,0,1-.85.38,6.28,6.28,0,0,1-1.08.29,7,7,0,0,1-1.24.1,5.9,5.9,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4.14,4.14,0,0,1-.95-1.48,6,6,0,0,1,0-4,4.07,4.07,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.88-.29,5.78,5.78,0,0,1,1.4.18,3.92,3.92,0,0,1,1.33.61,3.23,3.23,0,0,1,1,1.17,3.87,3.87,0,0,1,.39,1.85,8.31,8.31,0,0,1-.18,1.65h-6.41a2,2,0,0,0,.24,1,1.91,1.91,0,0,0,.59.64,2.56,2.56,0,0,0,.84.37,4.57,4.57,0,0,0,1,.11,5.35,5.35,0,0,0,1.75-.24,3.81,3.81,0,0,0,1.12-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.34,2.34,0,0,0-.74.37,2,2,0,0,0-.54.61,1.71,1.71,0,0,0-.25.81h4.37a1.76,1.76,0,0,0-2-1.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M352.84,208.32H356l.27,1.17h.07a3.42,3.42,0,0,1,1.17-1,3.68,3.68,0,0,1,1.84-.43,4.11,4.11,0,0,1,1.23.18,2.26,2.26,0,0,1,1,.59,2.84,2.84,0,0,1,.65,1.11,5.39,5.39,0,0,1,.24,1.73v5.53H360.1v-5.05a2.14,2.14,0,0,0-.49-1.56,1.7,1.7,0,0,0-1.24-.48,2,2,0,0,0-1.2.38,1.9,1.9,0,0,0-.74.95v5.76h-2.31v-6.93h-1.28Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M372.83,216.36a5.09,5.09,0,0,1-1.7.83,7.74,7.74,0,0,1-2.05.27,5.88,5.88,0,0,1-2.05-.33,4.29,4.29,0,0,1-1.52-1,4,4,0,0,1-.93-1.48,5.6,5.6,0,0,1-.32-1.92,5,5,0,0,1,.37-2,4.17,4.17,0,0,1,1-1.48,4.6,4.6,0,0,1,1.58-.92,6.21,6.21,0,0,1,2-.31,7.43,7.43,0,0,1,1.87.23,9.1,9.1,0,0,1,1.33.45v3.13h-1.95v-1.64a5.24,5.24,0,0,0-1.11-.12,3.28,3.28,0,0,0-1,.15,2.32,2.32,0,0,0-.87.48,2.46,2.46,0,0,0-.63.82,3,3,0,0,0,0,2.25,2.36,2.36,0,0,0,.55.83,2.42,2.42,0,0,0,.88.56,3.13,3.13,0,0,0,1.17.21,4.19,4.19,0,0,0,1.66-.29,7.71,7.71,0,0,0,1-.49Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M383.11,216.27a3.34,3.34,0,0,1-.59.42,5.81,5.81,0,0,1-.86.38,6.16,6.16,0,0,1-1.07.29,7.11,7.11,0,0,1-1.25.1,5.85,5.85,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4,4,0,0,1-1-1.48,5.67,5.67,0,0,1-.33-2,5.26,5.26,0,0,1,.38-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.89-.29,5.7,5.7,0,0,1,1.39.18,3.75,3.75,0,0,1,1.33.61,3.36,3.36,0,0,1,1,1.17,4,4,0,0,1,.38,1.85,8.31,8.31,0,0,1-.18,1.65h-6.4a2,2,0,0,0,.24,1,1.79,1.79,0,0,0,.58.64,2.66,2.66,0,0,0,.84.37,4.6,4.6,0,0,0,1,.11,5.39,5.39,0,0,0,1.75-.24,3.87,3.87,0,0,0,1.11-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.45,2.45,0,0,0-.74.37,2,2,0,0,0-.54.61,1.83,1.83,0,0,0-.25.81h4.38a2,2,0,0,0-.49-1.4A1.94,1.94,0,0,0,379.27,209.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M397.17,213h1.95v3.56a4.32,4.32,0,0,1-1.45.64,7.37,7.37,0,0,1-4-.11,5,5,0,0,1-1.85-1.12,5.51,5.51,0,0,1-1.28-2,8.35,8.35,0,0,1-.48-3,7.5,7.5,0,0,1,.54-3.07,5.58,5.58,0,0,1,1.39-2,5.16,5.16,0,0,1,1.91-1.09,6.82,6.82,0,0,1,2.06-.33,7.84,7.84,0,0,1,1.81.18,6.52,6.52,0,0,1,1.21.41v3.7H397v-2a7.11,7.11,0,0,0-1.14-.09,3.27,3.27,0,0,0-1.29.26,2.83,2.83,0,0,0-1,.79,3.77,3.77,0,0,0-.69,1.34,6.48,6.48,0,0,0-.25,1.92,6,6,0,0,0,.23,1.75,4,4,0,0,0,.67,1.36,3,3,0,0,0,1.09.88,3.26,3.26,0,0,0,1.46.31,6.12,6.12,0,0,0,1.14-.1Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M409.26,216.27a3.11,3.11,0,0,1-.6.42,5.25,5.25,0,0,1-.85.38,6.41,6.41,0,0,1-1.07.29,7.19,7.19,0,0,1-1.25.1,5.9,5.9,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4.14,4.14,0,0,1-.95-1.48,5.44,5.44,0,0,1-.33-2,5.26,5.26,0,0,1,.38-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.88-.29,5.78,5.78,0,0,1,1.4.18,3.92,3.92,0,0,1,1.33.61,3.23,3.23,0,0,1,1,1.17,3.87,3.87,0,0,1,.39,1.85,9.12,9.12,0,0,1-.18,1.65H403a2,2,0,0,0,.24,1,1.79,1.79,0,0,0,.58.64,2.47,2.47,0,0,0,.84.37,4.57,4.57,0,0,0,1,.11,5.35,5.35,0,0,0,1.75-.24,3.81,3.81,0,0,0,1.12-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.34,2.34,0,0,0-.74.37,2,2,0,0,0-.54.61,1.83,1.83,0,0,0-.25.81h4.37a1.75,1.75,0,0,0-2-1.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M410.47,208.32h3.11l.27,1.17h.07a3.46,3.46,0,0,1,1.18-1,3.64,3.64,0,0,1,1.83-.43a4.06,4.06,0,0,1,1.23.18,2.26,2.26,0,0,1,1,.59,2.84,2.84,0,0,1,.65,1.11,5.39,5.39,0,0,1,.24,1.73v5.53h-2.31v-5.05a2.1,2.1,0,0,0-.49-1.56,1.7,1.7,0,0,0-1.24-.48,2,2,0,0,0-1.2.38,1.9,1.9,0,0,0-.74.95v5.76h-2.31v-6.93h-1.28Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M422.81,210.28h-1.75v-2h1.75v-2l2.32-.66v2.69h4.66v2h-4.66v2.54a3.07,3.07,0,0,0,.51,2,1.8,1.8,0,0,0,1.44.62,3,3,0,0,0,.87-.12,2.85,2.85,0,0,0,.71-.29,4.07,4.07,0,0,0,.57-.39l.47-.39,1.07,1.6a4.11,4.11,0,0,1-.76.65,7,7,0,0,1-1,.51,5.78,5.78,0,0,1-1.09.35,5.4,5.4,0,0,1-1.12.12,3.84,3.84,0,0,1-3-1.11,5.17,5.17,0,0,1-1-3.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M440.74,216.27a3.34,3.34,0,0,1-.59.42,5.81,5.81,0,0,1-.86.38,6.16,6.16,0,0,1-1.07.29,7.11,7.11,0,0,1-1.25.1,5.85,5.85,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4,4,0,0,1-1-1.48,5.67,5.67,0,0,1-.32-2,5.26,5.26,0,0,1,.37-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.89-.29,5.7,5.7,0,0,1,1.39.18,3.83,3.83,0,0,1,1.33.61,3.36,3.36,0,0,1,1,1.17,4,4,0,0,1,.38,1.85,8.31,8.31,0,0,1-.18,1.65h-6.4a2,2,0,0,0,.24,1,1.81,1.81,0,0,0,.59.64,2.51,2.51,0,0,0,.83.37,4.67,4.67,0,0,0,1,.11,5.39,5.39,0,0,0,1.75-.24,3.87,3.87,0,0,0,1.11-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.45,2.45,0,0,0-.74.37,2,2,0,0,0-.79,1.42h4.38a2,2,0,0,0-.49-1.4A1.94,1.94,0,0,0,436.9,209.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M442.43,215.26h2.21v-5h-2.21v-2h4l.26,1.17h.07a5,5,0,0,1,1.14-1,2.84,2.84,0,0,1,1.5-.39,2,2,0,0,1,1.68.78,4.28,4.28,0,0,1,.61,2.61h-2.08a1.72,1.72,0,0,0-.19-.93.64.64,0,0,0-.59-.3,1.74,1.74,0,0,0-1.15.36,3.6,3.6,0,0,0-.74.82v3.79h3.86v2h-8.38Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M93.1,181.53l20.42-19.22c.87-.76,1.61-1.66,2.61-1.8,1.19-.17,3,1.09,3.3,1.28s10.7,6.64,12.57,7.77l15.75,9.71c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53h0s-17.5-10.32-22.43-13.18a22.83,22.83,0,0,0-11-3c-4.71.09-8.62,2.32-12.24,5h0l-24,18.2,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83A17.88,17.88,0,0,0,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#a)"
|
||||
/>
|
||||
<path d="M104.87,170.45h0" transform="translate(-68.76 -130.29)" fill="url(#b)" />
|
||||
<path
|
||||
d="M93.1,181.53h0l11.77-11.08a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11-7.26,5.5s-4.11,2.67-4,6.32c.15,4.65,5.34,6.69,5.34,6.69l30.63,13.13a35.93,35.93,0,0,0,11.38,2.53c3.39.08,6.83-1.14,10.49-2.24l24.76-8.46c1.26-.41,3.26-1.65,3.26-3.17,0-1.2-1.57-2.73-3.33-3.51a16.28,16.28,0,0,0-8.57-1.19c-4.7.44-25.95,7.65-25.95,7.65L93.16,184.23a1.28,1.28,0,0,1-.91-1.58A2.68,2.68,0,0,1,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#c)"
|
||||
/>
|
||||
<path
|
||||
d="M147.75,179.27c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53L132,169.56l-27.13.89h0a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73h0a66.73,66.73,0,0,0,7.06.19C107.65,182,144.08,180.38,147.75,179.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#e4097d"
|
||||
/>
|
||||
<path
|
||||
d="M104.87,170.45a3.26,3.26,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.67-9-3-3.55a1.94,1.94,0,0,1-.41-1.27,2.18,2.18,0,0,1,1-1.83L110,141.9a6.43,6.43,0,0,1,1.81-.87,5.82,5.82,0,0,1,1.86.09l16.49,2.64a24.38,24.38,0,0,0,9.39-.52c1.94-.49,4.31-1.25,5.39-2.91s-.6-2.9-1.11-3.27c-2.08-1.5-4.67-1.92-7.18-2.32l-25.48-4.08a23.84,23.84,0,0,0-10.88.57A19.61,19.61,0,0,0,95,133.6L71.44,149.36a6.34,6.34,0,0,0-1.08,9.38l.21.27,13.12,17a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#d)"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content">
|
||||
<div class="success-message">
|
||||
<div class="success-icon">✓</div>
|
||||
<h1>Verlängerung erfolgreich!</h1>
|
||||
<p class="success-text">Ihre Pädagogische Jahreskarte wurde erfolgreich verlängert.</p>
|
||||
|
||||
<div class="card-info">
|
||||
<h3>Ihre Vorteile</h3>
|
||||
<p>
|
||||
Mit der Jahreskarte erhalten Sie ein Jahr lang freien Eintritt in die Ausstellung,
|
||||
Sonderausstellung oder zu den regulären Science Dome Shows.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="contact-info">
|
||||
<p>
|
||||
Bei Fragen zu unseren Angeboten für Bildungseinrichtungen und Pädagogen sind wir gerne
|
||||
für Sie da.
|
||||
</p>
|
||||
<div class="contact-item">
|
||||
<strong>E-Mail-Adresse</strong>
|
||||
<a href="mailto:schulkommunikation@experimenta.science"
|
||||
>schulkommunikation@experimenta.science</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-section">
|
||||
<p>
|
||||
Die neuen Bedingungen der Pädagogischen Jahreskarten finden Sie
|
||||
<a
|
||||
href="https://www.experimenta.science/paedagogische-jahreskarte/"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>hier</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a href="https://www.experimenta.science/" class="back-button"
|
||||
>Zur experimenta Startseite</a
|
||||
>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<div class="footer-bottom">
|
||||
<p>© 2025 experimenta gGmbH – Das Science Center. Alle Rechte vorbehalten.</p>
|
||||
<div class="footer-bottom-links">
|
||||
<a href="https://www.experimenta.science/kontakt/">Kontakt</a>
|
||||
<a href="https://www.experimenta.science/impressum/">Impressum</a>
|
||||
<a href="https://www.experimenta.science/datenschutz/">Datenschutz</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{{#payload.id}}
|
||||
<!-- ID: {{payload.id}}-->{{/payload.id}}
|
||||
</body>
|
||||
</html>
|
||||
796
docs/design-examples/design-example3-error.html
Normal file
796
docs/design-examples/design-example3-error.html
Normal file
@@ -0,0 +1,796 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Fehler bei der Verlängerung | experimenta</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background: linear-gradient(135deg, #2e1065 0%, #1a0a3a 50%, #0f051d 100%);
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
color: white;
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Simplified Header */
|
||||
.header-wrapper {
|
||||
background: rgba(46, 16, 101, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.main-content {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
backdrop-filter: blur(15px);
|
||||
border-radius: 20px;
|
||||
padding: 60px 40px;
|
||||
margin: 40px 0;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #e53e3e;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 100%;
|
||||
font-size: 4rem;
|
||||
color: #fff;
|
||||
margin-bottom: 30px;
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
margin-bottom: 30px;
|
||||
color: white;
|
||||
font-weight: 300;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 18px;
|
||||
margin-bottom: 25px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 40px 30px;
|
||||
margin: 30px 0;
|
||||
text-align: center;
|
||||
border-left: 4px solid #f59d24;
|
||||
}
|
||||
|
||||
.contact-info p {
|
||||
font-size: 18px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: 30px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
margin: 20px 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.contact-item strong {
|
||||
color: #f59d24;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.contact-item a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
transition: color 0.3s ease;
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.contact-item a:hover {
|
||||
color: #ffb347;
|
||||
}
|
||||
|
||||
.contact-item .phone-number {
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
background: #e6007e;
|
||||
background-image: linear-gradient(to left, #e6007e, #e6007e, #e40521, #e6007e);
|
||||
background-size: 300%;
|
||||
color: #ffffff;
|
||||
padding: 10px 30px;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-position 1s,
|
||||
all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
margin-top: 30px;
|
||||
text-transform: none;
|
||||
line-height: 1.7em;
|
||||
position: relative;
|
||||
outline: 0;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.back-button:hover {
|
||||
background-position: 100%;
|
||||
}
|
||||
|
||||
/* Simplified Footer */
|
||||
.footer {
|
||||
background: linear-gradient(135deg, #1a0a3a 0%, #0f051d 100%);
|
||||
margin-top: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 60px 20px 30px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
display: grid;
|
||||
grid-template-columns: 2.5fr 1fr 1fr 1.5fr;
|
||||
gap: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.footer-section h3 {
|
||||
color: #e91e63;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.footer-section p {
|
||||
margin-bottom: 15px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.footer-links li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 200px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.partner-section {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.partner-logos {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.partner-logo {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 15px 20px;
|
||||
border-radius: 6px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
min-width: 120px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.partner-logo:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.social-links {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.social-links a {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: rgba(233, 30, 99, 0.2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.social-links a:hover {
|
||||
background: #e91e63;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.footer-bottom p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.footer-bottom-links a {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-bottom-links a:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.recognition-section {
|
||||
text-align: center;
|
||||
margin: 40px 0;
|
||||
padding: 30px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.recognition-section h4 {
|
||||
color: #e91e63;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
padding: 0 15px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 250px;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 40px 15px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
padding: 40px 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
margin: 20px 0;
|
||||
padding: 25px 20px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.contact-info p,
|
||||
.contact-item a,
|
||||
.contact-item strong,
|
||||
.contact-item .phone-number {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
grid-template-columns: 1fr;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.footer-bottom p,
|
||||
.footer-bottom-links a {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 200px;
|
||||
max-width: 85%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
padding: 30px 15px;
|
||||
margin: 15px 0;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
padding: 20px 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.contact-info p,
|
||||
.contact-item a,
|
||||
.contact-item strong,
|
||||
.contact-item .phone-number {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
padding: 8px 24px;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.footer-bottom p,
|
||||
.footer-bottom-links a {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer-bottom-links {
|
||||
gap: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Simplified Header -->
|
||||
<header class="header-wrapper">
|
||||
<div class="header-content">
|
||||
<a href="https://www.experimenta.science/" class="logo">
|
||||
<svg
|
||||
class="logo-svg"
|
||||
viewBox="0 0 382.94 87.17"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="a"
|
||||
x1="102.63"
|
||||
y1="152.32"
|
||||
x2="135.19"
|
||||
y2="191.11"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ce0f60" />
|
||||
<stop offset="0.47" stop-color="#de0b75" />
|
||||
<stop offset="0.59" stop-color="#e4097d" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="b"
|
||||
x1="104.87"
|
||||
y1="170.45"
|
||||
x2="104.87"
|
||||
y2="170.45"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.16" stop-color="#bf144c" />
|
||||
<stop offset="0.29" stop-color="#ab1a4e" />
|
||||
<stop offset="0.43" stop-color="#9f1d4f" />
|
||||
<stop offset="0.57" stop-color="#9b1e4f" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="c"
|
||||
x1="68.79"
|
||||
y1="182.84"
|
||||
x2="154.66"
|
||||
y2="182.84"
|
||||
xlink:href="#b"
|
||||
/>
|
||||
<linearGradient
|
||||
id="d"
|
||||
x1="94.04"
|
||||
y1="182.21"
|
||||
x2="114.5"
|
||||
y2="126"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.22" stop-color="#e4097d" />
|
||||
<stop offset="0.32" stop-color="#e4115e" />
|
||||
<stop offset="0.45" stop-color="#e5193d" />
|
||||
<stop offset="0.55" stop-color="#e51e28" />
|
||||
<stop offset="0.62" stop-color="#e52021" />
|
||||
<stop offset="0.9" stop-color="#f7a822" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<polygon
|
||||
points="143.78 50 151.18 39.6 144.43 39.6 139.68 46.33 135.13 39.6 127.79 39.6 135.32 50.08 127.29 61.23 134.09 61.23 139.3 53.78 144.43 61.23 151.59 61.23 143.78 50"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M245.79,175.33a9.2,9.2,0,0,0-1.85-3.39,7.28,7.28,0,0,0-2.9-2,10.29,10.29,0,0,0-3.65-.63c-3.12,0-5.47.95-7,2.82l-.56-2.23h-7.72v5.29h3.13v24.7h6.13v-8.4a8.29,8.29,0,0,0,1.7.42,17.3,17.3,0,0,0,2.6.19,11.8,11.8,0,0,0,4.53-.82,9.29,9.29,0,0,0,3.39-2.39,10.78,10.78,0,0,0,2.11-3.78,15.69,15.69,0,0,0,.74-5A16,16,0,0,0,245.79,175.33Zm-12.76,0a5.26,5.26,0,0,1,2.73-.75,4,4,0,0,1,3.12,1.4,5.85,5.85,0,0,1,1.25,4,10.56,10.56,0,0,1-.4,3.12,5.84,5.84,0,0,1-1.1,2.09,4.11,4.11,0,0,1-1.62,1.18,7.15,7.15,0,0,1-4.21.12,4.71,4.71,0,0,1-1.43-.58v-8.48A3.79,3.79,0,0,1,233,175.35Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M270.8,174.1a8.1,8.1,0,0,0-2.42-2.86,9.3,9.3,0,0,0-3.24-1.5,14.1,14.1,0,0,0-7.91.28,10.48,10.48,0,0,0-3.7,2.14,10,10,0,0,0-2.49,3.58,12.71,12.71,0,0,0-.9,5,13.24,13.24,0,0,0,.79,4.74,9.75,9.75,0,0,0,6,5.88,14.71,14.71,0,0,0,4.91.77,15.93,15.93,0,0,0,3-.26,14.61,14.61,0,0,0,2.59-.68,13.18,13.18,0,0,0,2.05-.92,8,8,0,0,0,1.47-1l.19-.18L269,184.85l-.33.28a8.34,8.34,0,0,1-2.51,1.36,11.84,11.84,0,0,1-4,.57,9.83,9.83,0,0,1-2.28-.26,6,6,0,0,1-1.85-.81,4.16,4.16,0,0,1-1.28-1.39,4.33,4.33,0,0,1-.5-1.75h15l.05-.28a19.77,19.77,0,0,0,.43-4A9.75,9.75,0,0,0,270.8,174.1Zm-11.06.54a6.52,6.52,0,0,1,1.95-.29,4.29,4.29,0,0,1,3.24,1.11,4.13,4.13,0,0,1,1.05,2.72h-9.55a4.05,4.05,0,0,1,.5-1.39,4.45,4.45,0,0,1,1.18-1.33A5.21,5.21,0,0,1,259.74,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M194.59,174.1a8,8,0,0,0-2.43-2.86,9.26,9.26,0,0,0-3.23-1.5A14.09,14.09,0,0,0,181,170a10.48,10.48,0,0,0-3.7,2.14,10,10,0,0,0-2.49,3.58,12.7,12.7,0,0,0-.91,5,13.23,13.23,0,0,0,.8,4.74,9.75,9.75,0,0,0,6,5.88,14.71,14.71,0,0,0,4.91.77,15.82,15.82,0,0,0,3-.26,14.38,14.38,0,0,0,2.59-.68,12.91,12.91,0,0,0,2.06-.92,8,8,0,0,0,1.47-1l.19-.18-2.11-4.18-.34.28a8.22,8.22,0,0,1-2.51,1.36,11.78,11.78,0,0,1-4,.57,9.7,9.7,0,0,1-2.28-.26,6,6,0,0,1-1.86-.81,4.23,4.23,0,0,1-1.27-1.39,4.33,4.33,0,0,1-.5-1.75h15l.06-.28a20.47,20.47,0,0,0,.42-4A9.75,9.75,0,0,0,194.59,174.1Zm-11.06.54a6.52,6.52,0,0,1,1.95-.29,4.31,4.31,0,0,1,3.24,1.11,4.07,4.07,0,0,1,1,2.72h-9.54a4,4,0,0,1,.49-1.39,4.35,4.35,0,0,1,1.19-1.33A5.21,5.21,0,0,1,183.53,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M298.09,178.12v-.34c0-3-.49-5.07-1.52-6.37a5.07,5.07,0,0,0-4.22-2,6.89,6.89,0,0,0-3.69,1,11.46,11.46,0,0,0-2.44,2l-.58-2.52h-10v5.29h5.18v11h-5.18v5.3H296v-5.3h-9.08v-8.47a8.94,8.94,0,0,1,1.61-1.76,3.84,3.84,0,0,1,2.48-.76,1.2,1.2,0,0,1,1.11.54,3.85,3.85,0,0,1,.39,2v.34Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M350.79,173.27a5.61,5.61,0,0,0-1.16-2.29,4.05,4.05,0,0,0-1.79-1.21,7.17,7.17,0,0,0-2.24-.33,6.19,6.19,0,0,0-3.12.82,5,5,0,0,0-1.79,1.7,3.66,3.66,0,0,0-1.7-1.81,6.39,6.39,0,0,0-2.92-.71,6,6,0,0,0-3.17.82,5.75,5.75,0,0,0-1.71,1.57l-.53-1.93h-4.78v21.62h6V176.07a1.89,1.89,0,0,1,.72-.94,2,2,0,0,1,1.92-.27,1.05,1.05,0,0,1,.53.44,3.5,3.5,0,0,1,.41,1.11,9.26,9.26,0,0,1,.17,2v13.16h6V175.94a1.5,1.5,0,0,1,.63-.9,2.12,2.12,0,0,1,1.18-.31,1.62,1.62,0,0,1,1.29.63,3.88,3.88,0,0,1,.56,2.42v13.74h6V176.86A14.23,14.23,0,0,0,350.79,173.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M375.88,174.1a8,8,0,0,0-2.43-2.86,9.3,9.3,0,0,0-3.24-1.5,14.1,14.1,0,0,0-7.91.28,10.44,10.44,0,0,0-3.69,2.14,10.11,10.11,0,0,0-2.5,3.58,12.71,12.71,0,0,0-.9,5,13.46,13.46,0,0,0,.79,4.74,9.89,9.89,0,0,0,2.32,3.6,10,10,0,0,0,3.71,2.28,14.65,14.65,0,0,0,4.9.77,15.93,15.93,0,0,0,3-.26,14.61,14.61,0,0,0,2.59-.68,13.77,13.77,0,0,0,2.06-.92,8.18,8.18,0,0,0,1.47-1l.19-.18-2.12-4.18-.33.28a8.34,8.34,0,0,1-2.51,1.36,11.82,11.82,0,0,1-4,.57,9.7,9.7,0,0,1-2.28-.26,5.93,5.93,0,0,1-1.86-.81,4.23,4.23,0,0,1-1.27-1.39,4.18,4.18,0,0,1-.5-1.75h15l.06-.28a20.52,20.52,0,0,0,.43-4A9.75,9.75,0,0,0,375.88,174.1Zm-11.06.54a6.5,6.5,0,0,1,1.94-.29,4.33,4.33,0,0,1,3.25,1.11,4.18,4.18,0,0,1,1.05,2.72h-9.55a3.84,3.84,0,0,1,.49-1.39,4.35,4.35,0,0,1,1.19-1.33A5.21,5.21,0,0,1,364.82,174.64Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M401.33,174a7,7,0,0,0-1.61-2.75,5.79,5.79,0,0,0-2.46-1.46,10.19,10.19,0,0,0-3-.44,9,9,0,0,0-7,3.07l-.57-2.48h-7.94v5.29h3v16.33h6.13V177.67a4.13,4.13,0,0,1,1.59-2,4.48,4.48,0,0,1,2.62-.83,3.6,3.6,0,0,1,2.67,1,4.72,4.72,0,0,1,1,3.43v12.24h6.14V178.15A13.05,13.05,0,0,0,401.33,174Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M425.62,183.62l-1.41,1.17a9.47,9.47,0,0,1-1.29.89,7,7,0,0,1-3.53.92,3.83,3.83,0,0,1-3.12-1.32,7,7,0,0,1-1.14-4.45v-5.64h11V169.9h-11v-6.43L409,165.21v4.69h-4.14v5.29H409v5.64c0,3.87.83,6.74,2.46,8.54s4.09,2.73,7.31,2.73a12.69,12.69,0,0,0,2.7-.3,14.51,14.51,0,0,0,2.64-.84,15.43,15.43,0,0,0,2.35-1.24,8.09,8.09,0,0,0,1.85-1.59l.17-.2Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M449,186.22c0-.27-.06-.54-.1-.81-.05-.71-.08-1.36-.08-1.94,0-.78.05-1.66.14-2.65s.16-2.25.16-3.67a10.5,10.5,0,0,0-.44-3.12,6,6,0,0,0-1.45-2.44,6.56,6.56,0,0,0-2.6-1.57,11.86,11.86,0,0,0-3.81-.54,22.68,22.68,0,0,0-5.29.55,23.45,23.45,0,0,0-3.93,1.32l-.28.12,1.49,4.95.36-.17a22.8,22.8,0,0,1,2.83-1.07,12,12,0,0,1,3.71-.53,4.18,4.18,0,0,1,2.5.62,2.33,2.33,0,0,1,.77,2v.8a2.53,2.53,0,0,1,0,.47l-1.71-.15c-.56,0-1.1-.08-1.61-.08a17.54,17.54,0,0,0-3.92.41,9.29,9.29,0,0,0-3.07,1.26,5.82,5.82,0,0,0-2,2.22,7.07,7.07,0,0,0-.68,3.19,6.12,6.12,0,0,0,1.94,4.7,7.43,7.43,0,0,0,5.19,1.76,8.26,8.26,0,0,0,4.33-1,7.94,7.94,0,0,0,2.17-1.9l.49,2.56h7.66v-5.3Zm-12.43-2.67a2.4,2.4,0,0,1,.88-.71,4.48,4.48,0,0,1,1.31-.43,7.73,7.73,0,0,1,1.51-.15,13.48,13.48,0,0,1,1.73.11c.38,0,.69.09.94.13v2.13a4.16,4.16,0,0,1-4.08,2.05,2.92,2.92,0,0,1-2-.55,2.07,2.07,0,0,1-.57-1.57A1.68,1.68,0,0,1,436.52,183.55Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<polygon
|
||||
points="249.76 48.18 241.03 39.45 230.96 49.53 230.96 52.96 233.6 50.29 240.61 57.31 238.01 59.91 239.67 61.58 253.68 47.56 253.68 44.27 249.76 48.18"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M314.12,162.94a5.56,5.56,0,1,1-5.55-5.55A5.55,5.55,0,0,1,314.12,162.94Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M275.61,204.76l.56,0,.9-.06,1.06-.05,1,0a6.75,6.75,0,0,1,2.74.49,4.2,4.2,0,0,1,1.72,1.32,5.15,5.15,0,0,1,.88,2,11.58,11.58,0,0,1,.25,2.5,11.24,11.24,0,0,1-.25,2.4,5.62,5.62,0,0,1-.9,2.09,4.62,4.62,0,0,1-1.79,1.48,6.81,6.81,0,0,1-2.95.56l-.73,0-.91,0-.89-.06a4.37,4.37,0,0,1-.65-.06Zm3.57,2c-.22,0-.44,0-.66,0l-.48.05v8.34l.22,0h.29l.29,0h.24a3.13,3.13,0,0,0,1.64-.38,2.41,2.41,0,0,0,.92-1,4.31,4.31,0,0,0,.39-1.4,13.77,13.77,0,0,0,.09-1.57,13.6,13.6,0,0,0-.08-1.4,4.16,4.16,0,0,0-.38-1.34,2.46,2.46,0,0,0-.88-1A2.85,2.85,0,0,0,279.18,206.76Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M286.81,208.92a11,11,0,0,1,1.65-.55,9.5,9.5,0,0,1,2.21-.23,5.19,5.19,0,0,1,1.58.22,2.63,2.63,0,0,1,1.05.64,2.38,2.38,0,0,1,.57,1,4.26,4.26,0,0,1,.18,1.28c0,.61,0,1.13-.06,1.55s-.06.81-.06,1.14,0,.53,0,.84a3.93,3.93,0,0,1,.06.48h1.15v2h-3L292,216h-.08a3.31,3.31,0,0,1-1,1,3.46,3.46,0,0,1-1.77.4,3,3,0,0,1-2.1-.71,2.45,2.45,0,0,1-.78-1.89,2.86,2.86,0,0,1,.27-1.29,2.28,2.28,0,0,1,.8-.89,4,4,0,0,1,1.25-.52,7.54,7.54,0,0,1,1.64-.16l.67,0c.24,0,.52,0,.87.07a2.07,2.07,0,0,0,0-.35v-.34a1.13,1.13,0,0,0-.39-1,1.86,1.86,0,0,0-1.15-.29,5.11,5.11,0,0,0-1.62.23,9.05,9.05,0,0,0-1.22.46Zm3,6.53a2.12,2.12,0,0,0,1.27-.31,2.1,2.1,0,0,0,.61-.67v-1.06a4.92,4.92,0,0,0-.52-.08,6.06,6.06,0,0,0-.76-.05,3.05,3.05,0,0,0-.67.07,2.22,2.22,0,0,0-.6.19,1.31,1.31,0,0,0-.42.35.86.86,0,0,0-.16.51,1,1,0,0,0,.29.78A1.39,1.39,0,0,0,289.84,215.45Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M302.86,214.76a.64.64,0,0,0-.44-.57,6.8,6.8,0,0,0-1.07-.39q-.64-.18-1.41-.36a6.44,6.44,0,0,1-1.4-.52,3.49,3.49,0,0,1-1.08-.84,1.93,1.93,0,0,1-.44-1.3,2.2,2.2,0,0,1,.3-1.16,2.59,2.59,0,0,1,.8-.85,3.82,3.82,0,0,1,1.21-.52,6.09,6.09,0,0,1,1.52-.18,7.73,7.73,0,0,1,1.53.13,7.07,7.07,0,0,1,1.15.3,4.28,4.28,0,0,1,.83.4l.6.4-1,1.58-.61-.33-.73-.31a6.89,6.89,0,0,0-.81-.23,3.81,3.81,0,0,0-.82-.09,3.15,3.15,0,0,0-1.21.2.63.63,0,0,0-.46.6c0,.21.14.39.43.52a6.8,6.8,0,0,0,1.08.36l1.4.37a8.06,8.06,0,0,1,1.41.5,3.52,3.52,0,0,1,1.08.81,1.89,1.89,0,0,1,.43,1.28,2.57,2.57,0,0,1-1,2.13,4.69,4.69,0,0,1-2.92.77,7,7,0,0,1-2.64-.45,6,6,0,0,1-1.79-1.06l1.07-1.67a4.73,4.73,0,0,0,.61.43,5.31,5.31,0,0,0,.86.44,7.61,7.61,0,0,0,1,.33,4.55,4.55,0,0,0,1.08.13,2.26,2.26,0,0,0,1-.19A.68.68,0,0,0,302.86,214.76Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M311.81,213.14h1.95v1.76l.11,0a5.28,5.28,0,0,0,.9.29,4.3,4.3,0,0,0,1,.12,2.61,2.61,0,0,0,1.54-.4,1.27,1.27,0,0,0,.55-1.08,1.22,1.22,0,0,0-.45-1,4.42,4.42,0,0,0-1.12-.66c-.44-.19-.93-.37-1.46-.57a7.09,7.09,0,0,1-1.46-.72,4.15,4.15,0,0,1-1.12-1.09,3,3,0,0,1-.45-1.71,3.35,3.35,0,0,1,.31-1.46,3.4,3.4,0,0,1,.87-1.15,4.1,4.1,0,0,1,1.35-.75,5.29,5.29,0,0,1,1.74-.27,11.64,11.64,0,0,1,2.13.2,6.05,6.05,0,0,1,1.68.53v3.62h-2v-2l-.11,0c-.26-.07-.54-.12-.84-.17a6.8,6.8,0,0,0-.9-.06,2.27,2.27,0,0,0-1.34.34,1,1,0,0,0-.49.91,1.19,1.19,0,0,0,.45,1,5.35,5.35,0,0,0,1.12.67c.45.2.93.4,1.46.61a7.15,7.15,0,0,1,1.46.74,4,4,0,0,1,1.12,1.09,2.86,2.86,0,0,1,.45,1.65,3.92,3.92,0,0,1-.35,1.69,3.41,3.41,0,0,1-1,1.2,4.33,4.33,0,0,1-1.51.73,7.68,7.68,0,0,1-3.14.14,7.59,7.59,0,0,1-1.07-.27,8.12,8.12,0,0,1-.86-.34l-.6-.3Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M330.86,216.36a5.24,5.24,0,0,1-1.71.83,7.74,7.74,0,0,1-2,.27,5.92,5.92,0,0,1-2.05-.33,4.16,4.16,0,0,1-1.51-1,4.12,4.12,0,0,1-.94-1.48,5.6,5.6,0,0,1-.32-1.92,5,5,0,0,1,.38-2,3.93,3.93,0,0,1,1-1.48,4.55,4.55,0,0,1,1.57-.92,6.21,6.21,0,0,1,2-.31,7.43,7.43,0,0,1,1.87.23,9.76,9.76,0,0,1,1.34.45v3.13h-2v-1.64a5.22,5.22,0,0,0-1.1-.12,3.35,3.35,0,0,0-1,.15,2.32,2.32,0,0,0-.87.48,2.6,2.6,0,0,0-.63.82,3.12,3.12,0,0,0,0,2.25,2.51,2.51,0,0,0,.55.83,2.42,2.42,0,0,0,.88.56,3.13,3.13,0,0,0,1.17.21,4.15,4.15,0,0,0,1.66-.29,7.06,7.06,0,0,0,1-.49Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M332.69,215.26h3.13v-5h-3.13v-2h5.44v6.94h3.29v2h-8.73Zm2.7-9.36a1.26,1.26,0,0,1,.41-.94,1.58,1.58,0,0,1,1.14-.39,1.74,1.74,0,0,1,1.19.39,1.19,1.19,0,0,1,.44.94,1.16,1.16,0,0,1-.44.94,1.84,1.84,0,0,1-1.19.36,1.66,1.66,0,0,1-1.14-.36A1.23,1.23,0,0,1,335.39,205.9Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M351.63,216.27a3.11,3.11,0,0,1-.6.42,5.25,5.25,0,0,1-.85.38,6.28,6.28,0,0,1-1.08.29,7,7,0,0,1-1.24.1,5.9,5.9,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4.14,4.14,0,0,1-.95-1.48,6,6,0,0,1,0-4,4.07,4.07,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.88-.29,5.78,5.78,0,0,1,1.4.18,3.92,3.92,0,0,1,1.33.61,3.23,3.23,0,0,1,1,1.17,3.87,3.87,0,0,1,.39,1.85,8.31,8.31,0,0,1-.18,1.65h-6.41a2,2,0,0,0,.24,1,1.91,1.91,0,0,0,.59.64,2.56,2.56,0,0,0,.84.37,4.57,4.57,0,0,0,1,.11,5.35,5.35,0,0,0,1.75-.24,3.81,3.81,0,0,0,1.12-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.34,2.34,0,0,0-.74.37,2,2,0,0,0-.54.61,1.71,1.71,0,0,0-.25.81h4.37a1.76,1.76,0,0,0-2-1.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M352.84,208.32H356l.27,1.17h.07a3.42,3.42,0,0,1,1.17-1,3.68,3.68,0,0,1,1.84-.43,4.11,4.11,0,0,1,1.23.18,2.26,2.26,0,0,1,1,.59,2.84,2.84,0,0,1,.65,1.11,5.39,5.39,0,0,1,.24,1.73v5.53H360.1v-5.05a2.14,2.14,0,0,0-.49-1.56,1.7,1.7,0,0,0-1.24-.48,2,2,0,0,0-1.2.38,1.9,1.9,0,0,0-.74.95v5.76h-2.31v-6.93h-1.28Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M372.83,216.36a5.09,5.09,0,0,1-1.7.83,7.74,7.74,0,0,1-2.05.27,5.88,5.88,0,0,1-2.05-.33,4.29,4.29,0,0,1-1.52-1,4,4,0,0,1-.93-1.48,5.6,5.6,0,0,1-.32-1.92,5,5,0,0,1,.37-2,4.17,4.17,0,0,1,1-1.48,4.6,4.6,0,0,1,1.58-.92,6.21,6.21,0,0,1,2-.31,7.43,7.43,0,0,1,1.87.23,9.1,9.1,0,0,1,1.33.45v3.13h-1.95v-1.64a5.24,5.24,0,0,0-1.11-.12,3.28,3.28,0,0,0-1,.15,2.32,2.32,0,0,0-.87.48,2.46,2.46,0,0,0-.63.82,3,3,0,0,0,0,2.25,2.36,2.36,0,0,0,.55.83,2.42,2.42,0,0,0,.88.56,3.13,3.13,0,0,0,1.17.21,4.19,4.19,0,0,0,1.66-.29,7.71,7.71,0,0,0,1-.49Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M383.11,216.27a3.34,3.34,0,0,1-.59.42,5.81,5.81,0,0,1-.86.38,6.16,6.16,0,0,1-1.07.29,7.11,7.11,0,0,1-1.25.1,5.85,5.85,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4,4,0,0,1-1-1.48,5.67,5.67,0,0,1-.33-2,5.26,5.26,0,0,1,.38-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.89-.29,5.7,5.7,0,0,1,1.39.18,3.75,3.75,0,0,1,1.33.61,3.36,3.36,0,0,1,1,1.17,4,4,0,0,1,.38,1.85,8.31,8.31,0,0,1-.18,1.65h-6.4a2,2,0,0,0,.24,1,1.79,1.79,0,0,0,.58.64,2.66,2.66,0,0,0,.84.37,4.6,4.6,0,0,0,1,.11,5.39,5.39,0,0,0,1.75-.24,3.87,3.87,0,0,0,1.11-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.45,2.45,0,0,0-.74.37,2,2,0,0,0-.79,1.42h4.38a2,2,0,0,0-.49-1.4A1.94,1.94,0,0,0,379.27,209.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M397.17,213h1.95v3.56a4.32,4.32,0,0,1-1.45.64,7.37,7.37,0,0,1-4-.11,5,5,0,0,1-1.85-1.12,5.51,5.51,0,0,1-1.28-2,8.35,8.35,0,0,1-.48-3,7.5,7.5,0,0,1,.54-3.07,5.58,5.58,0,0,1,1.39-2,5.16,5.16,0,0,1,1.91-1.09,6.82,6.82,0,0,1,2.06-.33,7.84,7.84,0,0,1,1.81.18,6.52,6.52,0,0,1,1.21.41v3.7H397v-2a7.11,7.11,0,0,0-1.14-.09,3.27,3.27,0,0,0-1.29.26,2.83,2.83,0,0,0-1,.79,3.77,3.77,0,0,0-.69,1.34,6.48,6.48,0,0,0-.25,1.92,6,6,0,0,0,.23,1.75,4,4,0,0,0,.67,1.36,3,3,0,0,0,1.09.88,3.26,3.26,0,0,0,1.46.31,6.12,6.12,0,0,0,1.14-.1Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M409.26,216.27a3.11,3.11,0,0,1-.6.42,5.25,5.25,0,0,1-.85.38,6.41,6.41,0,0,1-1.07.29,7.19,7.19,0,0,1-1.25.1,5.9,5.9,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4.14,4.14,0,0,1-.95-1.48,5.44,5.44,0,0,1-.33-2,5.26,5.26,0,0,1,.38-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.88-.29,5.78,5.78,0,0,1,1.4.18,3.92,3.92,0,0,1,1.33.61,3.23,3.23,0,0,1,1,1.17,3.87,3.87,0,0,1,.39,1.85,9.12,9.12,0,0,1-.18,1.65H403a2,2,0,0,0,.24,1,1.79,1.79,0,0,0,.58.64,2.47,2.47,0,0,0,.84.37,4.57,4.57,0,0,0,1,.11,5.35,5.35,0,0,0,1.75-.24,3.81,3.81,0,0,0,1.12-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.34,2.34,0,0,0-.74.37,2,2,0,0,0-.54.61,1.83,1.83,0,0,0-.25.81h4.37a1.75,1.75,0,0,0-2-1.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M410.47,208.32h3.11l.27,1.17h.07a3.46,3.46,0,0,1,1.18-1,3.64,3.64,0,0,1,1.83-.43,4.06,4.06,0,0,1,1.23.18,2.26,2.26,0,0,1,1,.59,2.84,2.84,0,0,1,.65,1.11,5.39,5.39,0,0,1,.24,1.73v5.53h-2.31v-5.05a2.1,2.1,0,0,0-.49-1.56,1.7,1.7,0,0,0-1.24-.48,2,2,0,0,0-1.2.38,1.9,1.9,0,0,0-.74.95v5.76h-2.31v-6.93h-1.28Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M422.81,210.28h-1.75v-2h1.75v-2l2.32-.66v2.69h4.66v2h-4.66v2.54a3.07,3.07,0,0,0,.51,2,1.8,1.8,0,0,0,1.44.62,3,3,0,0,0,.87-.12,2.85,2.85,0,0,0,.71-.29,4.07,4.07,0,0,0,.57-.39l.47-.39,1.07,1.6a4.11,4.11,0,0,1-.76.65,7,7,0,0,1-1,.51,5.78,5.78,0,0,1-1.09.35,5.4,5.4,0,0,1-1.12.12,3.84,3.84,0,0,1-3-1.11,5.17,5.17,0,0,1-1-3.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M440.74,216.27a3.34,3.34,0,0,1-.59.42,5.81,5.81,0,0,1-.86.38,6.16,6.16,0,0,1-1.07.29,7.11,7.11,0,0,1-1.25.1,5.85,5.85,0,0,1-2-.32,4,4,0,0,1-1.52-.93,4,4,0,0,1-1-1.48,5.67,5.67,0,0,1-.32-2,5.26,5.26,0,0,1,.37-2.06,4.17,4.17,0,0,1,1-1.46,4.36,4.36,0,0,1,1.52-.89,6,6,0,0,1,1.89-.29,5.7,5.7,0,0,1,1.39.18,3.83,3.83,0,0,1,1.33.61,3.36,3.36,0,0,1,1,1.17,4,4,0,0,1,.38,1.85,8.31,8.31,0,0,1-.18,1.65h-6.4a2,2,0,0,0,.24,1,1.81,1.81,0,0,0,.59.64,2.51,2.51,0,0,0,.83.37,4.67,4.67,0,0,0,1,.11,5.39,5.39,0,0,0,1.75-.24,3.87,3.87,0,0,0,1.11-.61Zm-3.84-6.35a2.73,2.73,0,0,0-.87.13,2.45,2.45,0,0,0-.74.37,2,2,0,0,0-.79,1.42h4.38a2,2,0,0,0-.49-1.4A1.94,1.94,0,0,0,436.9,209.92Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M442.43,215.26h2.21v-5h-2.21v-2h4l.26,1.17h.07a5,5,0,0,1,1.14-1,2.84,2.84,0,0,1,1.5-.39,2,2,0,0,1,1.68.78,4.28,4.28,0,0,1,.61,2.61h-2.08a1.72,1.72,0,0,0-.19-.93.64.64,0,0,0-.59-.3,1.74,1.74,0,0,0-1.15.36,3.6,3.6,0,0,0-.74.82v3.79h3.86v2h-8.38Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M93.1,181.53l20.42-19.22c.87-.76,1.61-1.66,2.61-1.8,1.19-.17,3,1.09,3.3,1.28s10.7,6.64,12.57,7.77l15.75,9.71c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53h0s-17.5-10.32-22.43-13.18a22.83,22.83,0,0,0-11-3c-4.71.09-8.62,2.32-12.24,5h0l-24,18.2,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83A17.88,17.88,0,0,0,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#a)"
|
||||
/>
|
||||
<path d="M104.87,170.45h0" transform="translate(-68.76 -130.29)" fill="url(#b)" />
|
||||
<path
|
||||
d="M93.1,181.53h0l11.77-11.08a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11-7.26,5.5s-4.11,2.67-4,6.32c.15,4.65,5.34,6.69,5.34,6.69l30.63,13.13a35.93,35.93,0,0,0,11.38,2.53c3.39.08,6.83-1.14,10.49-2.24l24.76-8.46c1.26-.41,3.26-1.65,3.26-3.17,0-1.2-1.57-2.73-3.33-3.51a16.28,16.28,0,0,0-8.57-1.19c-4.7.44-25.95,7.65-25.95,7.65L93.16,184.23a1.28,1.28,0,0,1-.91-1.58A2.68,2.68,0,0,1,93.1,181.53Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#c)"
|
||||
/>
|
||||
<path
|
||||
d="M147.75,179.27c4.25-1.29,7.2-4.59,7.46-7.92a5.92,5.92,0,0,0-3-5.65l-2.48-1.53L132,169.56l-27.13.89h0a3.11,3.11,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.57-8.93-14.57,11,3.64,4.7a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73h0a66.73,66.73,0,0,0,7.06.19C107.65,182,144.08,180.38,147.75,179.27Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="#e4097d"
|
||||
/>
|
||||
<path
|
||||
d="M104.87,170.45a3.26,3.26,0,0,1-1.35-.18,4.24,4.24,0,0,1-1.33-1.11l-7.67-9-3-3.55a1.94,1.94,0,0,1-.41-1.27,2.18,2.18,0,0,1,1-1.83L110,141.9a6.43,6.43,0,0,1,1.81-.87,5.82,5.82,0,0,1,1.86.09l16.49,2.64a24.38,24.38,0,0,0,9.39-.52c1.94-.49,4.31-1.25,5.39-2.91s-.6-2.9-1.11-3.27c-2.08-1.5-4.67-1.92-7.18-2.32l-25.48-4.08a23.84,23.84,0,0,0-10.88.57A19.61,19.61,0,0,0,95,133.6L71.44,149.36a6.34,6.34,0,0,0-1.08,9.38l.21.27,13.12,17a16.1,16.1,0,0,0,6.48,4.83,17.88,17.88,0,0,0,2.93.73Z"
|
||||
transform="translate(-68.76 -130.29)"
|
||||
fill="url(#d)"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content">
|
||||
<div class="error-message">
|
||||
<div class="error-icon">✖</div>
|
||||
<h1>Ein Fehler ist aufgetreten</h1>
|
||||
<p class="error-text">
|
||||
Bei der Verlängerung Ihrer Pädagogischen Jahreskarte ist leider ein Fehler aufgetreten.
|
||||
</p>
|
||||
|
||||
<div class="contact-info">
|
||||
<p>Bitte setzen Sie sich mit uns in Verbindung, damit wir Ihnen weiterhelfen können.</p>
|
||||
|
||||
<div class="contact-item">
|
||||
<strong>Telefon</strong>
|
||||
<span class="phone-number">+49 (0) 7131 88795 – 0</span>
|
||||
</div>
|
||||
|
||||
<div class="contact-item">
|
||||
<strong>E-Mail-Adresse</strong>
|
||||
<a href="mailto:buchung@experimenta.science">buchung@experimenta.science</a>
|
||||
</div>
|
||||
|
||||
<div class="contact-item">
|
||||
<strong>Öffnungszeiten Besucherservice</strong>
|
||||
<span class="phone-number">Montag bis Freitag von 8 bis 17 Uhr</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="https://www.experimenta.science/" class="back-button"
|
||||
>Zur experimenta Startseite</a
|
||||
>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<div class="footer-bottom">
|
||||
<p>© 2025 experimenta gGmbH – Das Science Center. Alle Rechte vorbehalten.</p>
|
||||
<div class="footer-bottom-links">
|
||||
<a href="https://www.experimenta.science/kontakt/">Kontakt</a>
|
||||
<a href="https://www.experimenta.science/impressum/">Impressum</a>
|
||||
<a href="https://www.experimenta.science/datenschutz/">Datenschutz</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
BIN
docs/styleguides/JM experimenta Styleguide CSS 210413@2x.png
Executable file
BIN
docs/styleguides/JM experimenta Styleguide CSS 210413@2x.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 MiB |
Reference in New Issue
Block a user