Kalenderansicht · Spec #386

Monatliches Kalenderraster auf /documents als Alternative zur Listenansicht. Jeder Tag mit Dokumenten zeigt kompakte Eintragszeilen; Hover öffnet eine Vorschaukarte; Klick navigiert zu /documents/{id}. Aktive Personen- und Tag-Filter bleiben bei der Monatsnavigation erhalten.

1 · Anatomy

Acht benannte Zonen der Kalenderansicht.

Familienarchiv Dokumente ① Ansichts-Toggle
Dokumente durchsuchen …
② SearchFilterBar (Timeline ausgeblendet)
Oktober 1912
③ Monats-Navigation
Mo
Di
Mi
Do
Fr
Sa
So
30
1
Brief — Herbsternte
⑤ Dokumentzeile
2
3
4
5
Postkarte Hamburg
6
④ Tageszelle · ⑥ Überlauf "+N weitere" · ⑦ Hover-Karte (Overlay) · ⑧ Leere Zelle
① Toggle — Rechts in der SearchFilterBar. List | Kalender. Aktive Ansicht: navy-Hintergrund.
② Timeline — Timeline-Widget (#385) wird in Kalender-Mode ausgeblendet. Eine aktive Auswahl wird im State behalten und bei Rückwechsel wiederhergestellt.
③ Monats-Nav — ‹ / › für Prev/Next. Klick auf Monatstitel öffnet Year/Month-Picker. Feld zeigt „Monat Jahr" (deutsch).
④ Tageszelle — Tagesnummer oben rechts. Unter 4 Dokumente: alle als Zeilen. Ab 4: erste 3 + „+N weitere"-Link.
⑤ Dokumentzeile — Einzeilig: Kurzform des Titels. Linker Mint-Balken als Farb-Akzent. Klick → /documents/{id}.
⑦ Hover-Karte — Erscheint beim Hovern über eine Dokumentzeile. Zeigt Titel, Datum, Absender → Empfänger, optionalen Thumbnail-Stub. Verschwindet on-mouseout.

2 · Design-Tokens

Light theme
cal-surface#FFFFFF — Kalender-Hintergrund
cal-header-bg#F5F4EF — DOW-Kopfzeile, Monat-Nav
cal-line#F0EEE8 — Zellrahmen intern
cal-outer-line#D8D6CF — Widget-Außenrahmen
doc-entry-bg#EFF8F7 — Dokumentzeile Hintergrund
doc-entry-accent#A1DCD8 — Linker Balken der Dokumentzeile (brand-mint)
doc-entry-text#012851 — Titel in Dokumentzeile (navy)
inactive-day-bg#FAFAF8 — Zellen des Vor-/Nachmonats
inactive-day-num#D0CEC8 — Tagesnummer Vor-/Nachmonat
Dark theme
cal-surface#0A1218
cal-header-bg#060C12
cal-line#1A2830
doc-entry-bg#0A2030
doc-entry-accent#1E5060 — gedämpftes Teal
doc-entry-text#A1DCD8 — Mint statt Navy
inactive-day#070E14

3 · Vollständiger Kalender — Oktober 1912 · Light

7 Dokumente verteilt auf den Monat. Zeigt alle Zell-Varianten: leer, 1 Dokument, mehrere Dokumente, und Überlauf.

Desktop · 1440px · ~55% SkalierungLight mode
familienarchiv.local/documents
Dokumente durchsuchen …
Sortierung ▾
▾ Filter
Oktober 1912
7 Dokumente in diesem Monat
Mo
Di
Mi
Do
Fr
Sa
So
14
16
17
18
19
Reisebericht aus Berlin
Reisebericht aus Berlin
19. Oktober 1912
Von Hans Raddatz
An Elfriede Raddatz
Zum Dokument →
20
21
22
24
25
26
27
29
30
31
1
2
3

4 · Tageszellen-Varianten

Alle möglichen Zustände einer Tageszelle im Detail.

Variant ALeere Zelle
14
Nur Tagesnummer. Kein Cursor-Pointer. Kein Hover-Effekt.
Variant B1 Dokument
1
Brief über die Herbsternte
Titel wird auf eine Zeile begrenzt. Klick → /documents/{id}.
Variant C3 Dokumente
8
Nachrichten v. Gut
Grüße aus Posen
Brief a. Elfriede
Bis zu 3 Einträge vollständig sichtbar.
Variant D5 Dokumente — Überlauf
15
Antwort a. Elfriedes Brief
Feldpost Nr. 12
Kurzbrief Sonntag
+2 weitere
Ab 4 Docs: erste 3 anzeigen, Rest als „+N weitere". Klick auf Link → Tages-Ansicht oder Modal (OQ-4, Entscheidung: Modal).
Variant EVor-/Nachmonat
30
Gedimmte Tagesnummer. Kein Dokument-Eintrag (Dokumente des Vormonats erscheinen nicht im aktuellen Raster). Kein klickbarer Inhalt.

5 · Dark Mode — Kalender Oktober 1912

DarkKalender · aktiver Monat
Dokumente durchsuchen …
▾ Filter
Oktober 1912
7 Dokumente in diesem Monat
Dark mode: Dokumentzeilen Mint-Text auf sehr dunklem Hintergrund. Balken-Akzent gedämpftes Teal. Monatstitel Mint.

6 · Filter-Integration

Aktive Personen- und Tag-Filter aus der SearchFilterBar bleiben bei Kalender-Navigation erhalten.

Filter aktivNur Briefe von Karl Raddatz
Dokumente durchsuchen …
KR
Karl Raddatz ×
Oktober 1912
3 von 7 Dokumente sichtbar (Filter aktiv)
Mo
Di
Mi
Do
Fr
Sa
So
30
2
3
4
5
6
7
9
10
11
12
13
14
16
17
18
19
20
Person-Filter „Karl Raddatz" ist aktiv. Monat-Nav zeigt „3 von 7 Dokumente sichtbar (Filter aktiv)". Tage ohne Karl-Dokumente sind leer, auch wenn der Originalmonat dort Briefe anderer Personen hat.

7 · Verhaltensregeln

SzenarioVerhalten
Ansichts-ToggleKlick auf Kalender-Icon → URL wechselt zu ?view=calendar. Listenansicht und Timeline werden per display:none ausgeblendet. State (Filter, Auswahl) bleibt erhalten.
Startmonat (OQ-3)Entscheidung: Monat des aktuellsten Dokuments. Wenn Timeline-Filter aktiv ist, zeigt Kalender den ersten Monat des Filterbereichs. Ohne Filter: Monat des neuesten Dokuments im Archiv.
Monats-Navigation Prev/NextButton ‹ / › lädt Dokumente des Nachbarmonats via GET /api/documents?year=1912&month=11. Vorherige und nachfolgende Monate werden prefetched (SvelteKit prefetch).
Year/Month-PickerKlick auf Monatstitel öffnet ein kompaktes Dropdown mit Jahres-Liste (scrollen) und Monatsgitter (12 Felder). Bestätigung mit Enter oder Klick auf Monat.
Dokumentzeilen-HoverHover-Karte erscheint nach 400 ms Verzögerung neben der Zelle (kein sofortiges Aufpoppen). Karte verschwindet wenn Maus die Zelle verlässt. Kein Hover auf Touch-Geräten.
Klick auf DokumentzeileNavigation zu /documents/{id}.
Überlauf-Link „+N weitere" (OQ-4)Entscheidung: Modal mit vollständiger Liste der Dokumente des Tages. Kein In-Cell-Scroll. Modal zeigt Datum als Titel + alle Dokumente als DocumentRow.
Kein documentDateDokument erscheint nicht im Kalender. Timeline-Widget und Listenansicht zeigen es weiterhin.
Monat ohne DokumenteLeeres Raster (alle Zellen ohne Einträge). Monat-Nav zeigt „0 Dokumente in diesem Monat".
Aktive Filter + KalenderAND-Semantik. Nur Dokumente, die alle aktiven Filter (Person, Tag, Zeitachse) erfüllen, erscheinen im Kalender.
Mobile (<640 px)Kalenderansicht wechselt zu Wochen-View (1 Woche sichtbar, horizontal scrollbar). Toggle zwischen List/Kalender bleibt verfügbar.
Keyboard-NavigationTab auf Monatsnavigation: ‹ / › per Enter/Space. Pfeiltasten bewegen Fokus von Zelle zu Zelle. Enter auf Dokumentzeile: Navigation zu Dokument.
ARIArole="grid" auf Kalender-Container. role="gridcell" auf jede Tageszelle. aria-label="15. Oktober 1912, 3 Dokumente" auf belegte Zellen. aria-label="Vorheriger Monat" auf ‹-Button.

8 · Offene Fragen — Entscheidungen

Backend-Anforderung. Neuer Endpoint GET /api/documents?year=1912&month=10 ohne Paginierung — gibt alle Dokumente des Monats zurück (max. ~100, keine Offset-Pages). Alternativ: bestehender Endpoint mit dateFrom=1912-10-01&dateTo=1912-10-31. Der View-Toggle-State wird als URL-Parameter ?view=calendar gespeichert und von SvelteKit per url.searchParams gelesen.

9 · Implementation Reference

ElementTailwind-KlassenPixelwertAnmerkung
Ansichts-Toggle Containerflex border border-line rounded-sm overflow-hiddenSitzt ganz rechts in der SearchFilterBar-Zeile
Toggle-Button (inaktiv)p-1.5 bg-muted flex items-center justify-center6px paddingIcon: 16px × 16px SVG
Toggle-Button (aktiv)p-1.5 bg-primary flex items-center justify-center6px paddingIcon fill: #A1DCD8
Monat-Nav Containerbg-surface border border-line rounded-t-sm flex items-center justify-between px-4 py-2.5padding 16px / 10pxOberer Radius; Kalender-Grid hat unteren Radius
Prev/Next Buttonw-8 h-8 flex items-center justify-center border border-line rounded-sm bg-muted text-ink-2 hover:bg-line transition-colors32px / 32pxTouch target ≥ 44px durch unsichtbares Padding auf Wrapper
Monatstiteltext-sm font-bold text-primary cursor-pointer hover:underline14px / 700Klick → Year/Month-Picker Dropdown
Monat-Subtexttext-[10px] text-ink-3 text-center mt-0.510pxOrange + fett wenn Filter aktiv: text-orange-600 font-bold
DOW-Kopfzeilegrid grid-cols-7 bg-muted border-b border-line
DOW-Zellepy-1.5 text-center text-[9px] font-bold uppercase tracking-widest text-ink-39px / 700Kein Klick-Handler
Kalender-Gridbg-surface border border-line border-t-0 rounded-b-sm + role="grid"Border-top entfernt wegen Monat-Nav-Header
Wochen-Reihegrid grid-cols-7
Tageszelle (aktiver Monat)border-r border-b border-line min-h-[80px] p-1.5 relativemin 80px hochrole="gridcell" + aria-label
Tageszelle (Vor/Nachmonat)border-r border-b border-line min-h-[80px] p-1.5 bg-muted/40Kein Dokument-Inhalt
Tagesnummer (aktiv)text-right text-[11px] font-bold text-ink mb-1 leading-none11px / 700
Tagesnummer (inaktiv)text-right text-[11px] font-bold text-ink-3/40 mb-1 leading-none11pxStark gedimmt
Dokumentzeileblock text-[10px] text-primary truncate px-1.5 py-0.5 bg-[#EFF8F7] border-l-2 border-mint rounded-[2px] mb-0.5 cursor-pointer hover:bg-mint/20 transition-colors10pxrole="link" + aria-label mit Volltitel
Überlauf-Linktext-[9px] text-ink-3 italic px-1.5 py-0.5 hover:underline cursor-pointer9pxÖffnet Modal via onclick
Hover-Karteabsolute z-50 bg-surface border border-line rounded-sm shadow-lg p-3 min-w-[180px] pointer-events-nonePositioniert per JS (verhindert Viewport-Overflow). pointer-events-none damit sie Hover nicht blockiert.
Hover-Karte Titeltext-[11px] font-bold text-ink mb-1 leading-snug11px / 700Mehrzeilig erlaubt
Hover-Karte Datumtext-[9px] text-ink-3 mb-29pxFormat: „19. Oktober 1912"
Hover-Karte Von/Antext-[9px] text-ink-2 mit font-bold uppercase tracking-wide auf Label9px
Komponenten-NamenCalendarView.svelte, CalendarMonthGrid.svelte, CalendarDayCell.svelte, CalendarDocEntry.svelte, CalendarHoverCard.svelte, MonthPicker.svelteAlle unter src/lib/components/calendar/
Benötigter URL-Parameter?view=calendar&year=1912&month=10SvelteKit url.searchParams in +page.server.ts