` mit radialem CSS-Gradient als "Glow"
- Größe: 20-28px Kern
- Glow-Farbe durch Emotion ODER Custom-Farbe
- Glow-Farblogik:
- **Positiv** (> 0): `#FF6B35` (Orange) → `#FFD700` (Gold) → `#4CAF50` (Grün)
- **Negativ** (< 0): `#2196F3` (Blau) → `#9C27B0` (Violett) → `#E91E63` (Pink)
- **Custom:** User-Farbe überschreibt den Glow, Y-Position bleibt
- Klick auf Punkt → öffnet Event-Detail (Phase 5)
### 3.4 — Timeline-Zoom
**Ziel:** Der User kann in die Timeline rein- und rauszoomen. Events und Abstände skalieren, Monats-/Jahres-Schriftgrößen bleiben konstant.
**Umsetzung:**
- `zoomLevel` (0.4–3.0, Default 1.0) multipliziert das `EVENT_SPACING`
- GlowDots skalieren via CSS `transform: scale(var(--dot-scale))` über das `zoom`-Prop
- **Desktop:** Ctrl+Mausrad oder Trackpad-Pinch (beides feuert `wheel` mit `ctrlKey`)
- **Touch:** Zwei-Finger-Pinch-Geste
- Scroll-Position bleibt stabil: Der Punkt unter dem Cursor/Pinch-Zentrum bleibt fixiert
- Monats- und Jahres-Labels behalten ihre feste Schriftgröße
### 3.3 — Verbindungslinien zwischen Dots
**Ziel:** Eine farbverlaufende Linie verbindet die Glow-Punkte und bildet die "LifeWave". Visuell inspiriert durch die FloatingLines-Ästhetik.
**Umsetzung:**
- SVG-Overlay innerhalb des scrollbaren Timeline-Containers
- Cubic Bezier Pfade (`
`) zwischen den Dots
- Gradient entlang des Pfades: Start-Farbe = Glow des linken Dots, End-Farbe = Glow des rechten Dots
- Strichbreite: 2-3px, mit `filter: blur(2px)` für weichen Glow
- Organisches Feeling: Bezier-Kontrollpunkte leicht versetzt
---
## Phase 4: Neues Event anlegen (Slide-Up Panel)
### 4.1 — Event-Panel Komponente
**Ziel:** Glassmorphes Panel fährt von unten hoch. LifeWave bleibt sichtbar und wird durch das "Glas" diffus.
**Umsetzung:**
- Neue Komponente `src/components/EventPanel.vue`
- Positionierung: `position: fixed; bottom: 0; left: 0; right: 0; z-index: 20`
- Höhe: ~65% des Viewports (variabel, Drag-Handle zum Resizen optional)
- `.glass--panel` Styling (starker Backdrop-Blur ~40px)
- Abgerundete obere Ecken (`border-radius: 24px 24px 0 0`)
- Slide-Up Animation: `transform: translateY(100%)` → `translateY(0)` mit `transition` oder Vue ``
- Kleiner Drag-Handle-Balken oben (visueller Indikator, 40px breit, 4px hoch, zentriert)
- **Wichtig:** Hintergrund-LifeWave wird NICHT ausgeblendet — der Glaseffekt erzeugt die Unschärfe
### 4.2 — Event-Formular (Felder im Panel)
**Ziel:** Minimalistisches Formular mit Live-Feedback.
**Felder:**
1. **Titel** — Textfeld, Placeholder "Was ist passiert?"
2. **Datum** — Date-Picker, Default = heute
3. **Emotions-Regler** — Custom Slider von -1.0 (negativ) bis +1.0 (positiv)
- Visuelles Feedback: Slider-Track ändert Farbe (Blau/Kühl ← → Warm/Grün)
- Thumb-Farbe passt sich an
4. **Farbe anpassen** (optional) — Toggle + Color-Picker
- Default: aus (Emotion bestimmt Farbe)
- Es gibt vorgefertigte Farbverläufe für den emotions Leiter hier zum Beispiel Farbkombinationen
Verläufe
Nagativ -> neutral -> Positiv
#FD1D1D -> #FCB045 -> #833AB4
#ED8153 -> #ED8153 -> #217B9E
#00D4FF -> #164173 -> #440559
#FDBB2D -> #96BE74 -> #22C1C3
#FC466B -> #9A52B6 -> #3F5EFB
#EEAECA -> #C2B4D9 -> #94BBE9
5. **Notiz** — Textarea, optional, 3 Zeilen
6. **Speichern-Button** — Glass-Style, auffällig
### 4.3 — Live-Feedback (Der Wow-Moment)
**Ziel:** Während der User das Formular ausfüllt, erscheint in Echtzeit ein neuer Glow-Punkt im Hintergrund.
**Umsetzung:**
- Sobald das Panel geöffnet wird: ein "Ghost-Dot" (halbtransparent, pulsierend) erscheint auf der Wave
- **Emotions-Regler bewegen:** Ghost-Dot wandert auf der Y-Achse nach oben/unten, Glow-Farbe ändert sich live
- **Custom-Farbe wählen:** Glow-Farbe ändert sich sofort
- **Speichern:** Ghost-Dot wird zum festen Dot (Opacity 1.0, Puls-Animation → statisch), Verbindungslinie animiert sich zum neuen Punkt
- Ghost-Dot hat stärkere Puls-Animation als reguläre Dots
---
## Phase 5: Event bearbeiten & Detail-Ansicht
### 5.1 — Event-Detail (Tap auf Glow-Dot)
**Ziel:** Tap auf einen Glow-Dot öffnet eine kompakte Detail-Ansicht.
**Umsetzung:**
- Wiederverwendung des `EventPanel.vue` im "Edit-Modus"
- Panel fährt hoch, vorbelegt mit den Event-Daten
- Gleiche Felder wie beim Anlegen
- Zusätzlich: "Löschen"-Button (dezent, unten im Panel)
- Live-Feedback: Änderungen am Emotions-Regler / Farbe ändern den existierenden Dot in Echtzeit
### 5.2 — Dot-Selection-State
**Ziel:** Visuelles Feedback welcher Dot ausgewählt ist.
**Umsetzung:**
- Ausgewählter Dot bekommt:
- Vergrößerter Glow (Scale 1.3 mit Transition)
- Pulsierender Ring-Effekt (CSS Animation)
- Alle anderen Dots werden leicht gedimmt (Opacity 0.5)
---
## Phase 6: Smart-Panel & Einstellungen
### 6.1 — LifeWave-Einstellungen (User-Personalisierung)
**Ziel:** Der User kann seine Wave anpassen — das macht die App persönlich.
**Umsetzung:**
- Im User-Menü (Off-Canvas rechts) unter "Life Wave":
- **Wellen-Farben:** Gradient-Picker (2-4 Farben auswählen)
- **Wellen-Intensität:** Slider (lineCount: 4-20)
- **Wellen-Geschwindigkeit:** Slider (animationSpeed: 0.2-2.0)
- **Wellen-Stil:** Auswahl welche Waves aktiv sind (top/middle/bottom)
- Änderungen werden live auf die FloatingLines-Props angewendet
- Einstellungen im Pinia Store + localStorage persistiert
### 6.2 — Dark/Light Mode Toggle
**Ziel:** Nahtloser Wechsel zwischen Hell- und Dunkel-Modus.
**Umsetzung:**
- Toggle im User-Menü oder als kleines Icon neben dem User-Button
- Quasar Dark-Mode Plugin aktivieren (`$q.dark.toggle()`)
- CSS Custom Properties wechseln alle Farben
- FloatingLines `mixBlendMode` wechselt automatisch
- Hintergrundfarbe animiert den Übergang (300ms Transition)
---
## Datenmodell (Pinia Store)
### `src/stores/events.js`
```js
{
events: [
{
id: 'uuid',
title: 'Hochzeit von Lisa',
date: '2024-06-15',
emotion: 0.8, // -1.0 bis +1.0
customColor: null, // null = auto, '#FF00FF' = custom
note: 'Wunderschöner Tag im Garten...',
createdAt: timestamp,
updatedAt: timestamp,
},
]
}
```
### `src/stores/settings.js`
```js
{
theme: 'light', // 'light' | 'dark'
wave: {
gradient: ['#E94FF5', '#2F4BA2'],
lineCount: 12,
speed: 0.6,
enabledWaves: ['middle']
}
}
```
---
## Umsetzungsreihenfolge (Arbeitspakete)
| # | Paket | Abhängigkeit | Geschätzt |
| --- | --------------------------------------- | ------------ | ---------- |
| 1 | Phase 1.1 — LifeWaveLayout + Routing | — | Grundlage |
| 2 | Phase 1.2 — Glassmorphism CSS | — | Grundlage |
| 3 | Phase 3.1 — FloatingLines Fullscreen | #1 | Wow-Basis |
| 4 | Phase 2.1 — UserMenuButton | #1, #2 | Navigation |
| 5 | Phase 2.2 — AddEventButton | #1, #2 | Navigation |
| 6 | Phase 4.1 — EventPanel (Slide-Up, leer) | #2 | Panel |
| 7 | Datenmodell — Pinia Stores | — | Daten |
| 8 | Phase 3.2 — GlowDots | #3, #7 | Events |
| 9 | Phase 3.3 — LifeWavePath (Verbindungen) | #8 | Wave |
| 10 | Phase 4.2 — Event-Formular | #6, #7 | Eingabe |
| 11 | Phase 4.3 — Live-Feedback (Ghost-Dot) | #8, #10 | Wow! |
| 12 | Phase 5 — Event bearbeiten & Detail | #10, #8 | Edit |
| 13 | Phase 6.1 — LifeWave-Einstellungen | #3, #7 | Settings |
| 14 | Phase 6.2 — Dark/Light Mode | #1 | Theme |
---
## Demo-Daten für den Prototyp
8 Events vorbelegt — 4 mit Bildern, 4 ohne. Bilder liegen in `public/demo/`.
```js
;[
{ title: 'Erster Schultag', date: '1995-09-01', emotion: 0.6, image: null },
{
title: 'Abiball',
date: '2004-06-25',
emotion: 0.85,
image: 'demo/photo-1530103862676-de8c9debad1d.jpeg',
},
{ title: 'Trennung', date: '2010-03-15', emotion: -0.7, image: null },
{
title: 'Bergwanderung',
date: '2014-08-12',
emotion: 0.75,
image: 'demo/photo-1534067783941-51c9c23ecefd.jpeg',
},
{ title: 'Jobverlust', date: '2016-11-03', emotion: -0.6, image: null },
{
title: 'Hochzeit',
date: '2018-07-20',
emotion: 0.95,
customColor: '#E94FF5',
image: 'demo/photo-1506905925346-21bda4d32df4.jpeg',
},
{ title: 'Umzug', date: '2021-04-01', emotion: -0.3, image: null },
{
title: 'Neuer Job',
date: '2023-01-10',
emotion: 0.5,
image: 'demo/photo-1530103862676-de8c9debad1d.jpeg',
},
]
```
---
## Technische Hinweise
- **Three.js** ist bereits als Dependency vorhanden (über FloatingLines.vue)
- **Keine neuen Dependencies** nötig für Phase 1-5 (alles mit Quasar + CSS + SVG + Three.js machbar)
- **Performance:** GlowDots und LifeWavePath als separate Schicht ÜBER dem WebGL-Canvas (DOM, nicht WebGL) — einfacher zu implementieren, gute Performance bei <50 Events
- **Mobile-First:** Alle Maße in `dvh`/`dvw`, Touch-Events für Slider, Panel-Swipe