# Globaler Zeitstrahl — Finale Spezifikation

Kanonische Spezifikation für `/zeitstrahl` auf Basis von Konzept A „Der Lebensfaden": eine durchgehende vertikale Achse, die Personen-Lebensereignisse, kuratierte Ereignisse und Briefe zu einer Erzählung in der Zeit verwebt. Dieselbe Komponente betreibt den globalen Zeitstrahl und den per-Person „Lebensweg". Enthält die vollständige Fall-Abdeckung (leere Jahre, wenige Briefe, hunderte Briefe, undatiert) und die drei Gruppierungs-Modi.

Milestone #14 · Zeitstrahl Konzept A — final Phone-first · honest DatePrecision
Familienarchiv · 2026-06-08 · Leonie Voss, UX Lead · ersetzt die A/B/C-Exploration zeitstrahl-global-concepts.html

## 1 · Anatomie von Konzept A

Eine Achse, sieben Bausteine. Die Zeit ist die Achse — Lebensereignisse & Jahre als zentrierte Pillen unterbrechen den Faden (Text wird nie von der Linie gekreuzt), Welt-Ereignisse legen sich als Bänder quer, Briefe verdichten sich adaptiv.

⚭
Lebensereignis-Pille
Geburt * · Tod † · Heirat ⚭. Abgeleitet aus `Person`-Daten. Zentriert, gefüllt — unterbricht die Achse. Glyphen aus `personLifeDates.ts`.
★
Kuratierte Ereignis-Pille
`PERSONAL` — Umzug, Auswanderung. Mint-Rand. Editierbar im Kurator-Editor.
◍
Welt-Band
`HISTORICAL` — Krieg, Inflation. Gedämpftes Band quer über die Achse als Kontext.
Einzel-Brief
Kleiner Punkt + Karte, alternierend links/rechts. Wurzel-Tag-Farbchip. Link zu `/documents/[id]`.
▭
Jahres-Strip
Verdichtung dichter Jahre: Anzahl + 12-Monats-Sparkline. `MonthBucket` / `aggregateToYears`.
⋯
Lücke & Ohne-Datum
Ruhige/leere Jahre als dünne Span-Zeile gefaltet; `UNKNOWN`-Briefe im „Ohne Datum"-Eimer am Ende.
Gruppierungs-Umschalter (oben rechts im Zeitstrahl): DatumEreignisThema steuert nur, wie lose Briefe gebündelt werden. Lebensereignisse, kuratierte Ereignisse und Welt-Bänder bleiben in allen Modi gleich auf der Achse. Standard = Datum.

## 2 · Die drei Gruppierungs-Modi

Gleicher Ausschnitt (1914–1915), dreimal gerendert. Nur die losen Briefe ordnen sich um — die Achse bleibt stabil. Schmale Spaltenbreite = Phone-/Lebensweg-Form derselben Komponente.

Datum Chronologisch
Standard. Briefe nach Datum; dichte Jahre verdichten zum Strip. Reine Zeit-Reihung.
1914
⚭
Heirat: Karl & Elfriede
1914 · abgeleitet
◍ Erster Weltkrieg
1914–1918
✉ Kriegsausbruch — Brief an die Familie
Karl → Elfriede · 4. Aug 1914
1915
*
Geburt: Hans Raddatz
Sommer 1915 · abgeleitet
✉ 24 BriefeMonate ▾
Ereignis Kuratiert
Briefe bündeln unter kuratierte Ereignisse (`TimelineEvent.documents`). Erzählende Cluster statt Listen.
1914
⚭
Heirat: Karl & Elfriede
1914 · abgeleitet
◍ Erster Weltkrieg
1914–1918
1915
*
Geburt: Hans Raddatz
Sommer 1915 · abgeleitet
✉ Briefe von der Front · 24
Karl ⇄ Elfriede & Hans · 1915 ▾
Krieg
✉ Weihnachten 1915 · 3
kuratiertes Ereignis ▾
Weihnachten
Thema Nach Wurzel-Tag
Optional (Post-MVP). Lose Briefe je Jahr in Wurzel-Tag-Eimer; Mehrfach-Tags dedupliziert auf den primären.
1914
⚭
Heirat: Karl & Elfriede
1914 · abgeleitet
◍ Erster Weltkrieg
1914–1918
Krieg6 ▾
1915
*
Geburt: Hans Raddatz
Sommer 1915 · abgeleitet
Krieg › Briefe von der Front24 ▾
Weihnachten3 ▾
Familie2 ▾
Hinweis im UI: „Brief mit mehreren Tags erscheint unter seinem primären Tag."

## 3 · Vollständige Vorschau — alle Dichte-Fälle

Ein durchgehender Zeitstrahl (Desktop, zentrale Achse) von 1899 bis „Ohne Datum". Jeder Dichte-Fall kommt genau einmal vor — von leeren Jahren bis zu hunderten Briefen.

Abgedeckte Fälle: ① leere Jahre (gefaltete Lücke) · ② wenige Briefe ≤ 3 (einzelne Karten) · ③ hunderte Briefe (Jahres-Strip + Sparkline) · ④ kuratiertes Ereignis & Welt-Band · ⑤ ungenaue Präzision (`Sommer`, `ca.`) · ⑥ undatierte Briefe (Ohne-Datum-Eimer).
Zeitstrahl
Die Familie Raddatz · 1899–1950 · 412 Briefe · 38 Ereignisse · Gruppierung: Datum
① Leere Jahre → gefaltet
1899 – 1908 · keine Einträge
1909
② Wenige Briefe → einzeln
✉ Brief aus Stettin
Elfriede → Karl · Mai 1909
Familie
✉ Geburtstagsgruß
Karl → Hans · Sep 1909
✉ Brief zum Jahresende
Karl → Elfriede · Dez 1909
Weihnachten
1914
⚭Heirat: Karl & Elfriede Raddatz1914 · abgeleitet aus Beziehung
④ Welt-Band (RANGE 1914–1918)
◍ Erster Weltkrieg1914–1918 · historisch · 187 Briefe in dieser Zeit
1915
③ Hunderte Briefe → Jahres-Strip ⑤ „Sommer 1915"
*Geburt: Hans RaddatzSommer 1915 · abgeleitet · SEASON
✉ 187 BriefeMonats-Dichte · antippen → Monate → Briefe ▾
Jan 1915Dez 1915
1916 – 1922 · Nachkriegsjahre · 96 Briefe
⑤ „ca. 1923" → APPROX
◍ Hyperinflationca. 1923 · historisch
1924
★Auswanderung nach ArgentinienFrühjahr 1924 · persönlich · kuratiert
1925 – 1950 · keine Einträge
⑥ Undatiert → eigener Eimer am Ende
Ohne Datum · 11 Briefe
Brief ohne JahresangabePräzision UNKNOWN
Fragment, Absender unklar+ 9 weitere ▾
Kein erfundenes Datum: undatierte Briefe wandern nie spekulativ in ein Jahr, sondern bleiben sichtbar im Eimer. `RANGE`-Einträge (Krieg) erscheinen einmal im Start-Jahr mit Spannen-Marker, nicht in jedem überspannten Jahr.

## 4 · Datums-Präzision (geteilt von Ereignissen & Briefen)

Eine Render-Logik für alle datierten Einträge — `dateLabel.ts`, gespeist von `DatePrecision`.

DatePrecision | Darstellung | Beispiel | Wirkung auf der Achse
--- | --- | --- | ---
DAY | vollständiges Datum | 28. Juli 1914 | exakte Sortierung im Jahres-Band
MONTH | Monat + Jahr | Juli 1914 | Monats-Sortierung
SEASON | Jahreszeit + Jahr | Sommer 1914 | grobe Reihung
YEAR | nur Jahr | 1914 | ans Band-Ende
APPROX | „ca." + Jahr | ca. 1914 | mit „ca."-Marker
RANGE | Start–Ende | 1914–1918 | Start-Jahr, Spannen-Marker, nicht dupliziert
UNKNOWN | undatiert | Ohne Datum | eigener Eimer am Ende

## 5 · Responsiv — eine Komponente, drei Breiten

Identisches Markup & identische Daten. Nur die Achs-Position wechselt per Container-Query.

▏
≥ 1024px · Desktop
Zentrale Achse, Briefe alternierend links/rechts, Welt-Bänder über volle Breite. Pillen unterbrechen die Linie.
▎
< 1024px · Phone
Linke Achse, alles einseitig rechts. DOM-Reihenfolge bleibt streng chronologisch (`<ol>`) — Screenreader liest linear.
▎
Lebensweg-Rail · 35%
Gleiche linke Achse in der Personenseite (`<TimelineView personId>`), gefiltert auf eine Person. Rail-Tauglichkeit = Stärke von A.

## 6 · Design-Tokens (echte, ausgelieferte Werte)

Aus `frontend/src/routes/layout.css`. Keine Hardcodes in der Komponente.

Rolle | Token | Wert | Einsatz
--- | --- | --- | ---
Achse / Knoten / Header | `brand-navy` | #012851 | Spine, Lebensereignis-Pillen, Jahres-Badges, Titel
Akzent / Brief-Punkt | `brand-mint` | #a1dcd8 | Brief-Punkte, kuratierte Pillen-Ränder, Sparkline, Dark-Mode-Auswahl
Historisch / Welt | `tag-slate` | #607080 | Welt-Bänder & Glyphe ◍ — gedämpft
Tag-Chip-Farben | `--c-tag-*` (Wurzel) |  | sage · sienna · amber · violet — Farbe vom Wurzel-Tag, Punkt + Label
Seite / Karte / Linie | `canvas · surface · line` |  | #f0efe9 · #ffffff · #e4e2d7
Text sekundär | `text-ink-3` | #6b7280 | Meta-Zeilen (4,8:1 auf weiß — AA ✓)
Schrift | `font-serif · font-sans` | Tinos · Montserrat | Namen/Titel serif · Labels/Chrome sans
Lebensdaten-Glyphen | `personLifeDates.ts` | * † ⚭ | Geburt · Tod · Heirat — konsistent mit Personenkarten

## 7 · Implementierungs-Referenz & Barrierefreiheit

Domain-Ordner `frontend/src/lib/timeline/`; Route `/zeitstrahl`; Backend `GET /api/timeline`.

Baustein | Komponente / Datei | Verantwortung
--- | --- | ---
Orchestrator | `TimelineView.svelte` | Lädt `/api/timeline`; optionaler `personId` für globalen vs. Lebensweg-Modus; hält den Gruppierungs-Modus
Jahres-Band | `YearBand.svelte` | Jahres-Badge + Einträge; Lücken-Faltung ruhiger Spannen
Ereignis-Pille | `EventCard.svelte` | PERSONAL / HISTORICAL / abgeleitet; zentrierte Pille bzw. Welt-Band; präzisions-bewusstes Label
Brief-Karte | `LetterCard.svelte` | Einzel-Brief, alternierende Seite, Wurzel-Tag-Chip, Link `/documents/[id]`
Jahres-Strip | `YearLetterStrip.svelte` | Adaptive Verdichtung ab Schwellwert; 12-Monats-Sparkline aus `MonthBucket` / `aggregateToYears` (`lib/document/timeline.ts`)
Datums-Helfer | `dateLabel.ts` | `DatePrecision` → deutsches Label; geteilt von Ereignissen & Briefen
Kurator-Editor | `/zeitstrahl/events/new · [id]/edit` | Ereignis anlegen/bearbeiten; Personen- + Dokument-Mehrfach-Picker (Bulk-Linking); `WRITE_ALL`
Quick-Add | `DocumentTimelineEventPicker.svelte` | Auf `/documents/[id]`: Ereignis wählen/neu anlegen; verlinkt einen Brief
Daten-API | `GET /api/timeline` | Verschmilzt kuratierte + abgeleitete Ereignisse + Briefe in `TimelineDTO` (Jahres-Eimer + Ohne-Datum); Filter `personId · type · fromYear · toYear`
Barrierefreiheit | — | Achse = `<ol>`, chronologische DOM-Reihenfolge; ◍ ✉ * nie nur Farbe — Glyphe + Label; 44px-Tap-Ziele; `prefers-reduced-motion`; axe in Light & Dark