From 74bf1d864cd73ef516b6677b2d576575b7b68f67 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 15 Jun 2026 14:36:35 +0200 Subject: [PATCH] docs(timeline): design doc for the grouped-view contained-card layout Records the visual-brainstorm outcome for #827's grouped view: a cluster becomes one contained card (event/tag as header, first 5 letters + show-more), the leftover bin collapses to a count-only drawer, derived/world fixtures stay plain, and REQ-001/003/014/020 are amended. Mockups under .superpowers/brainstorm/ (gitignored). Refs #827 #847 --- ...5-zeitstrahl-grouped-view-layout-design.md | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-15-zeitstrahl-grouped-view-layout-design.md diff --git a/docs/superpowers/specs/2026-06-15-zeitstrahl-grouped-view-layout-design.md b/docs/superpowers/specs/2026-06-15-zeitstrahl-grouped-view-layout-design.md new file mode 100644 index 00000000..b5420d37 --- /dev/null +++ b/docs/superpowers/specs/2026-06-15-zeitstrahl-grouped-view-layout-design.md @@ -0,0 +1,102 @@ +# Zeitstrahl grouped-view layout redesign + +**Date:** 2026-06-15 +**Feature:** #827 (regroup `/zeitstrahl` by Ereignis/Thema) — layout follow-up on PR #847 +**Status:** Approved (brainstorm), pending implementation plan + +> The REQ contract for #827 lives in the Gitea issue body (and the amendment comment of +> 2026-06-15). This document records the **layout/visual design** agreed in the visual +> brainstorm and the REQ deltas it implies. Mockups: `.superpowers/brainstorm/*/content/`. + +## Problem + +The first grouped-view implementation (PR #847) fixed the flood and the duplicate event title, +but two issues remained on review of the live view: + +1. **Weak belonging.** A clustered event's letters dropped below its centered pill as a + full-width block with only a thin left rail. The connection between an event and its letters + read weakly — the eye couldn't tell the letters belonged to the pill above. +2. **Layout inconsistency.** In Datum mode letters alternate left/right of the centered spine + (events/density centered). In grouped mode the letters became full-width, breaking that + rhythm with no clear reason. + +## Decision: a cluster is one contained card + +A clustered event (Ereignis) or root tag (Thema) renders as **one bordered card** whose header +is the event/tag itself and whose body holds that cluster's letters. Belonging becomes +structural (a single container), not positional guesswork. This replaces the full-width block. + +### Ereignis mode, per year band + +1. **Derived life-events** (Geburt/Tod/Heirat, `abgeleitet`) never cluster — they carry no + document links, so they are always **plain axis fixtures, unchanged from Datum mode**. A + **world-band** (`historisch`) is normally letterless and stays a plain band; on the rare + occasion a historical event has linked letters it follows rule 2 (becomes a card). +2. **A curated event (PERSONAL or HISTORICAL) with letters in this band** → one mint-bordered card: + - **Header** = the event's glyph + title + date + `kuratiert` + edit-✎ + count (the pill's + content, laid out as a header bar). This *replaces* the separate floating pill for that + event in this band — killing the duplicate title. + - **Body** = the cluster's letters, **first 5 shown, then a "+ N weitere Briefe anzeigen" + toggle** that expands/collapses the rest. Letters use the compact `LetterCard` variant. +3. **A curated event with no letters in this band** → stays a plain centered pill (no empty card). +4. **A curated event whose letters fall in a different year than its pill** → those letters form a + labeled card in *their* year (header = event name as text, no ✎/pill since the pill lives + elsewhere); the pill stays in its own band. No adjacent duplication. +5. **Leftover letters** (linked to no surviving curated event) → a collapsed neutral, dashed + **"✉ N Briefe ohne Ereignis · anzeigen ›"** drawer. Clicking expands to the same first-5 + + show-more list. No preview letters until opened. + +### Thema mode + +Identical shape. Each card's header is the **tinted root-tag chip** (`● Krieg · 24`, +`BucketHeaderChip`, fixed-ink label per the contrast fix) instead of an event pill; there is no +axis pill for a tag, so every tag cluster is a standalone card. The per-letter `TagChip` stays +suppressed inside its own card (REQ-017). The leftover drawer reads **"Ohne Thema"**. + +### Layout / spine + +- Cluster cards are **centered on the spine** (like events already are), not full-width-flush — + consistent with how grouped units (events) relate to the axis. Individual chronological + letters keep alternating left/right only in **Datum** mode. +- Each card carries a colour left rail: **mint** for an Ereignis cluster, the **tag colour** for + a Thema cluster, **neutral dashed** for the leftover drawer. + +## Components affected + +- `LetterBucket.svelte` — becomes the contained card: header slot (pill-content / tag chip / + drawer label / cross-year text label) + body with the first-5 cap and the show-more toggle. + Drop the `YearLetterStrip` (sparkline) branch from grouped mode. +- `YearBand.svelte` — in Ereignis mode, a same-year curated event renders *as* the card header + (merge pill into the card) instead of pill-then-nested-bucket; derived/world/letterless events + stay plain; cross-year clusters and the leftover drawer render after the axis entries. +- `LetterCard.svelte` — compact variant already exists (PR #847); reused inside cards. +- `BucketHeaderChip.svelte` — reused as the Thema card header (contrast fix already shipped). +- `timelineGrouping.ts` — the first-visible cap (`CLUSTER_PREVIEW = 5`) replaces + `BUCKET_DENSE_THRESHOLD`; helpers unchanged otherwise. +- Possibly a small `ClusterCard`/header sub-component if `LetterBucket` grows too large. + +## REQ deltas (to fold into issue #827) + +- **REQ-001 (amended):** derived life-events, world-bands, and *letterless* curated event pills + render identically across modes; a curated event **that has letters** renders as its cluster + card's header in grouped mode (no longer byte-identical to its Datum pill). Every event keeps + its spine position (year). +- **REQ-003 / REQ-014 (amended):** event-clustered letters live inside a contained card; the + header is the event (same-year) or a text label (cross-year). First 5 shown + show-more. +- **REQ-020 (amended):** grouped clusters are contained colour-railed cards with a first-5 + preview + show-more toggle; the leftover bin is a collapsed count-only drawer. The + month-density `YearLetterStrip` is **no longer used in grouped mode** (still used in Datum + dense years). + +## Out of scope + +- Datum mode (untouched — keeps the alternating-axis zigzag and the >12 sparkline strip). +- Backend / DTO (`linkedEventId` and root-tag fields already shipped; no change). +- New i18n beyond a show-more / drawer label string set. + +## Testing approach + +TDD per component, mirroring PR #847: `LetterBucket` (card header variants, first-5 cap, +show-more expand/collapse, drawer collapsed-by-default, colour rail), `YearBand` (same-year merge += no duplicate title; cross-year keeps a label; derived/world pills unchanged), and the route +spec for the assembled view. Run targeted `--project=client` / `--project=server` specs only.