Files
familienarchiv/design_handoff_familienarchiv_redesign/EPIC.md
marcel fa510f3991
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m1s
CI / OCR Service Tests (push) Successful in 28s
CI / Backend Unit Tests (push) Successful in 6m21s
CI / fail2ban Regex (push) Successful in 44s
CI / Semgrep Security Scan (push) Successful in 27s
CI / Compose Bucket Idempotency (push) Successful in 1m8s
feat(redesign): token foundation close-out + design handoff (#854)
Adds the Mappe design handoff as in-repo ground truth and closes out the design-token foundation: --radius-sm/md/full + --shadow-sm/md tokens (distinct dark values in both dark blocks) and the canonical 10-color $lib/shared/avatarPalette.ts (AA-darkened sage/amber/sand swatches), guarded by avatarPalette.spec.ts. Closes #854.
2026-06-16 17:17:27 +02:00

12 KiB
Raw Blame History

EPIC: Familienarchiv Visual Redesign ("Mappe")

Implement in order. Stories 14 are foundation and shared primitives — every screen depends on them. Do not start a screen story until 14 are merged, or the header, avatar, and tokens get re-implemented per screen and drift. Read DESIGN_RULES.md first; open the matching prototypes/*.dc.html for pixel ground truth while building each story.

Epic goal

Reskin the entire Familienarchiv app to the unified "Mappe" archival direction and ship three new sections (Geschichten, Zeitstrahl, Aktivitäten). All copy German-first via Paraglide; light + dark mode; De Gruyter icon convention preserved.

Epic-level acceptance criteria

  • All eight screens match their prototype in light and dark mode.
  • Header, page-header, avatar, segmented control, and card exist as single shared components — zero duplication of the header markup or the avatar-color function.
  • No raw hex in components; everything references the semantic tokens.
  • Every visible string is a Paraglide message key, German authored first; en/es stubs added.
  • Icons rendered as <img>, invert correctly in dark mode.
  • No gradients, blur, emoji, or transform-based motion introduced.

Reframe (2026-06-16): this is alignment, not greenfield. An audit of the live codebase found the substrate already in place — the full token system (DESIGN_RULES §12), dark mode, the app header, and the three "new" sections (Geschichten, Zeitstrahl, Aktivitäten) all already exist. So Stories 14 below are close-out + extraction, not from-scratch builds, and Stories 511 are "align the existing screen to its prototype," not new pages. The detailed, trackable breakdown lives in the Gitea milestone "Mappe Visual Redesign" (issues split into shared components then pages); Phase B at the bottom of this file lists the screens that previously had no prototype and now do.

Story 1 — Foundation: tokens, fonts, theme

Goal: establish the visual substrate the whole app reads from.

  • Port prototypes/colors_and_type.css into the app's token layer (Tailwind 4 @theme / layout.css). Keep every variable name in DESIGN_RULES.md §1.
  • Wire Montserrat + Tinos (or licensed Gotham/Times) and the --font-sans/--font-serif vars.
  • Implement light/dark via :root[data-theme='dark'] + the pre-paint boot script that reads localStorage['theme']. Add the global img[src*='degruyter-icons']{filter:invert(1)} dark rule.

Done when: a throwaway page using var(--c-*) tokens renders correct in both themes; no flash of wrong theme on reload.

Story 2 — Shared: app header + nav (ArchiveHeader)

Spec: DESIGN_RULES.md §4. Prototype: ArchiveHeader.dc.html.

  • One sticky header component: mint stripe, wordmark, nav with active-key prop, theme toggle, user chip. Nav routes to all sections.
  • Theme toggle drives the Story 1 mechanism.

Done when: header renders identically on every route; active item shows the mint underline; toggle flips theme and persists.

Story 3 — Shared: avatar + deterministic color

Spec: DESIGN_RULES.md §5.

  • avatarFor(name) util (hash → palette index + initials) + an <Avatar name size> component supporting 26/28/40/48px and the overlapping-stack ring variant.

Done when: the same name yields the same color everywhere; stacks overlap with the surface-colored ring.

Story 4 — Shared: page-header, segmented control, card, metadata, empty state

Spec: DESIGN_RULES.md §3, §6, §7.

  • PageHeader (eyebrow + 4px mint left rule + serif h1 + italic lede + right slot).
  • SegmentedControl (active = navy). Card (mint top/left border variants). MetaLine (· separated, optional leading icon). EmptyState (dashed, serif + ellipsis).

Done when: each primitive matches the prototype and is consumed by the screen stories below — not re-styled inline.


Story 5 — Dokumente (dashboard / search results)

Route: /. Prototype: Dokumente.dc.html.

PageHeader (eyebrow "Archiv", title "Dokumente", lede, right count "147 Dokumente · 38 Personen"). Then: a search bar card (input Titel, Personen, Tags durchsuchen… + "Datum ↓" sort + "Filter" buttons); a resume strip (mint left border, "Weiter bei:" + italic underlined doc link); a 1fr 320px grid — left: "Zuletzt hinzugefügt" list (title · avatar stack · right-aligned date width:128px · status dot+label width:118px), right column: upload dropzone (dashed, Upload icon, PDF, JPG, PNG, TIFF bis 50 MB) + "Benötigt Metadaten" card; below full-width Mission Control — 3 tiles (Segmentierung / Transkription / Zur Überprüfung), each with a caption, a pill "skill" hint, a weekly count, and a list of linked items. Right column collapses below lg; main goes full-width.

Done when: matches prototype both themes; status dots use the §7 colors; grid collapses.

Story 6 — Personen (directory)

Route: /persons. Prototype: Personen.dc.html.

PageHeader (eyebrow "Verzeichnis") + right count "38 Personen". Search input (z.B. Oma Frieda, Onkel Karl…) + segmented control (Alle / Personen / Institutionen / Gruppen). 3-column card grid; each card: 48px avatar, serif name, relation sub, optional type badge (Institution/Gruppe/Unbekannt — §1 colors), divider, meta line ✉ N Briefe · N Dokumente. Cards carry the 3px mint top border.

Done when: badge colors correct; avatar colors deterministic; grid responsive.

Story 7 — Briefwechsel — DROPPED

The two-person letter-exchange feature was removed from the product. Its prototype, route, and nav entry no longer exist. Skip.

Story 8 — Geschichten (story collections list) — NEW

Route: /geschichten. Prototype: Geschichten.dc.html.

PageHeader (eyebrow "Sammlungen") + primary button "Neue Geschichte". Segmented control (Alle / Veröffentlicht / In Arbeit / Entwurf) + Filter button. 2-column card grid; each card (link, mint top border): tag chips (dot + UPPERCASE label), serif 24px title, serif dek, meta line 📅 range · N Dokumente · N Personen, footer with overlapping avatar stack + status dot/label. Cards link to the story detail.

Done when: tag dots and status colors correct; cards link to Story 9.

Story 9 — Geschichte (single story detail) — NEW

Route: /geschichten/:id. Prototype: Geschichte.dc.html. Two variants (variant prop): "Lesereise" (a guided reading — intro + narration blocks + letter cards + annotation notes) and "Sammlung" (a collection — intro + "Erwähnte Dokumente" list). Centered max-width:880px article card (mint top border, padding:48px 56px): type badge, 38px serif title, byline row (author avatar + name + "zusammengestellt am …" + Bearbeiten / Löschen actions), intro paragraph, then ordered blocks:

  • narration — 3px mint left rule, serif italic 18px.
  • letter — clickable row: 40px tile w/ Mail icon, serif title, meta date · von X an Y, trailing Arrow-Right icon.
  • note — mint-tinted (--c-accent-bg) left-rule box, "Anmerkung" caption + serif italic.

Done when: both variants render from the prop; block types styled per spec; Löschen uses --c-danger.

Story 10 — Zeitstrahl (timeline) — NEW

Route: /zeitstrahl. Prototype: Zeitstrahl.dc.html.

PageHeader (eyebrow "Chronik") + right count. Segmented control (Alle / Briefe / Personen / Ereignisse) + a small legend. Centered vertical spine (max-width:760px, 2px mint center line). Item types stacked on the spine: year pill (navy), summary card (count + a 12-bar monthly-density mini chart in mint + range labels), letter cards alternating left/right with a spine dot (2px solid --c-primary) and optional tag pill, person node (28px navy circle glyph + name + derived meta), curated node (★, mint left rule), historical band (full-width, Globe icon, serif italic, top/bottom hairline).

Done when: spine centered; letters alternate; bars scale to value %; all five item types render.

Story 11 — Aktivitäten (activity feed) — NEW

Route: /aktivitaeten. Prototype: Aktivitaeten.dc.html.

PageHeader (eyebrow "Verlauf") + "Aktualisieren" button. Segmented control (Alle / Transkription / Uploads / Personen). Feed grouped by day (Heute / Gestern / Diese Woche), each group a UPPERCASE caption + rows. Each row: 40px avatar with a small action-icon badge bottom-right (Check/Upload/Chat/Edit/…), then a sentence — bold actor name + Montserrat verb + italic underlined target link — and a time sub.

Done when: grouping + icon badges match; target links styled with mint underline.

Story 12 (optional) — Regeln (internal style reference)

Prototype: Regeln.dc.html. Internal page documenting the seven blocks (Typografie, Farbe, Seitenkopf, Steuerung, Avatare, Metadaten/Leerzustände). Build only if the team wants a living in-app reference; otherwise DESIGN_RULES.md is the canonical record. Gate behind admin/dev.


Suggested order & dependencies

1 Tokens ─┬─ 2 Header ──┐
          ├─ 3 Avatar ──┼─→ 5 Dokumente, 6 Personen,
          └─ 4 Primitives┘   8 Geschichten → 9 Geschichte,
                              10 Zeitstrahl, 11 Aktivitäten  (parallelizable)
                              12 Regeln (optional, last)
                              → then Phase B (added screens), all depend on 14

Phase B — Added screens (previously un-prototyped pages)

These are the pages the original handoff never covered. Each now has a hifi .dc.html prototype in prototypes/. All depend on the shared primitives from Stories 14 and are parallelizable among themselves. Each maps to one Gitea page-issue in the milestone. Admin + OCR pages are explicitly out of scope here (phase-2 milestone).

# Screen Prototype Route(s) Done when
B1 Dokumente-Liste Dokumente-Liste.dc.html /documents PageHeader; search card; AND/OR segmented; grouped mint-top cards; avatar-stack rows; 7px status dot+label; pagination
B2 Dokument-Detail Dokument-Detail.dc.html /documents/[id] compact top bar w/ mint accent bar; PDF pane + transcription panel w/ Lesen/Bearbeiten segmented + turquoise mode; details card
B3 Dokument-Bearbeiten Dokument-Bearbeiten.dc.html /documents/[id]/edit, /new, /bulk-edit split pane; progress strip; Wer&Wann + Beschreibung cards; dropzone (new); action bar (Löschen danger / Abbrechen / Zur Überprüfung / Speichern)
B4 PersonDetail PersonDetail.dc.html /persons/[id] PageHeader; 2-col mint-top cards; deterministic avatar; correspondents + relationships + letter lists
B5 PersonForm PersonForm.dc.html /persons/new, /[id]/edit PageHeader; Stammdaten card w/ type segmented; caps labels; Namensverlauf; edit-only merge danger zone; save bar
B6 PersonReview PersonReview.dc.html /persons/review PageHeader + count; row card w/ muted avatar; idle/rename/merge states; danger merge+delete; confirm dialog; empty state
B7 Geschichte-Editor Geschichte-Editor.dc.html /geschichten/new, /[id]/edit type-pick segmented; prose editor toolbar; journey editor w/ color-only drag; sidebar status+persons; save bar
B8 Ereignis-Editor Ereignis-Editor.dc.html /zeitstrahl/events/new, /[id]/edit PageHeader; Wann&Was card w/ type segmented + date precision + danger error; persons/docs sidebar; save bar
B9 Stammbaum Stammbaum.dc.html /stammbaum PageHeader + count; node cards w/ §5 avatar in resting/selected/dimmed; line connectors; side panel; zoom controls; empty state
B10 Themen Themen.dc.html /themen PageHeader + count; segmented filter; mint-top cards w/ §1 tag-dot (not stripe); child rows; empty state
B11 Anreicherung Anreicherung.dc.html /enrich, /[id], /done list (status rows) / step (progress bar + split pane + action bar) / done (success card)
B12 Profil Profil.dc.html /profile, /users/[id] PageHeader; 2-col data/password cards; token banners; notifications; public profile card w/ avatar
B13 Anmeldung Anmeldung.dc.html /login, /register, /forgot-password, /reset-password self-contained branded shell (no app header); Tinos sentence-case titles; 17px inputs; token banners
B14 Hilfe-Transkription Hilfe-Transkription.dc.html /hilfe/transkription PageHeader; article column; rule cards w/ De Gruyter icons (no emoji); fixes border-brand-sand/bg-white bugs