diff --git a/docs/specs/stammbaum-doc-badge-spec.html b/docs/specs/stammbaum-doc-badge-spec.html new file mode 100644 index 00000000..14a64d08 --- /dev/null +++ b/docs/specs/stammbaum-doc-badge-spec.html @@ -0,0 +1,987 @@ + + + + + +Stammbaum — Document Badge · Inline Pill Variant · Familienarchiv + + + + +
+ + +
+

Stammbaum — Document Badge · Inline Pill Variant

+

+ Design spec for the inline relationship pill on the Document Detail page. Relationship labels appear + as inline pills directly next to each person's name — both in the 48 px sub-header bar + and in the Personen column of the 3-column metadata drawer. Example: Karl Raddatz + ELTERNTEIL + → Hans Raddatz + KIND. + This is View 2 of 3 in the Stammbaum document-badge feature set. +

+ +
+ Stammbaum Feature + View 2 of 3 — Document Badge + Inline Pill Variant + Desktop / Tablet / Mobile + Light + Dark +
+
+ + + +
+
+

1 · Design tokens

+

All colour values used by the inline pill and its surrounding context. Light and dark themes are shown side by side. Contrast ratios are against the respective surface colour.

+
+ + +
+
+ Karl Raddatz + ELTERNTEIL +
+
+ Karl Raddatz + ELTERNTEIL +
+
+ Pill anatomy
+ border-radius: 9999px  ·  padding: 1px 8px
+ font: Montserrat 9px 700 uppercase letter-spacing .07em
+ margin-left: 8px from name span  ·  vertical-align: middle +
+
+ +
+ +
+
Light theme — surface #ffffff
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pill bgrgba(161,220,216,.25) — near-white on white~14:1 AAA ✓ (text on near-white)
Pill border#a1dcd8 — mint accent outline
Pill text#012851 — navy ink14.5:1 AAA ✓
Person name#4b5563 — Montserrat 11px (sub-header)
Meta person name#012851 — Tinos 9.5px (metadata drawer)
Sub-header bg#ffffff
Sub-header border#e4e2d7
Arrow (decorative)#a1dcd8 — aria-hiddennon-text only
Meta label#6b7280 — Montserrat 9px 700 uppercase4.8:1 AA ✓
Meta value#012851 — Tinos 13px14.5:1 AAA ✓
Doc titleTinos serif 18px · #012851
Avatar KR#012851 — navy
Avatar HR#5a2d6f — purple
+
+ +
+
Dark theme — surface #011526
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pill bgrgba(0,199,177,.10) — dark teal washpasses AA ✓
Pill border#00c7b1 — turquoise
Pill text#f0efe9 — warm white14.5:1 AAA ✓
Person name#9ca3af — (sub-header)
Meta person name#f0efe9 — (metadata drawer)
Sub-header bg#011526
Sub-header border#0d3358
Arrow (decorative)#00c7b1 — aria-hiddennon-text only
Meta label#8b97a57.1:1 AAA ✓
Meta value#f0efe914.5:1 AAA ✓
Doc titleTinos serif 18px · #f0efe9
+
+
+ +

+ ⚠ Pill background rgba(161,220,216,.25) is nearly transparent on white — the effective contrast for the text is calculated against the near-white composite, yielding ~14:1. + The arrow between sender and receiver chips in the sub-header is aria-hidden="true" — directional meaning is conveyed by DOM order (sender before receiver) and the visual left-to-right reading order. +

+
+ + + +
+
+

2 · Desktop (1280 px) — light & dark

+

+ Full document detail page at ~65% scale. Sub-header bar (48 px) shows inline pills next to avatar chips. + Metadata drawer is open, showing pills next to person names in the Personen column. + Both light and dark themes shown side by side. +

+
+ +
+ + +
+
Light theme
+
+
+ +
+ +
+ + + + +
MR
+
+ +
+
+ +
+
+
W-0311 · Divacca
+
+ +
+
KR
+ Karl Raddatz + ELTERNTEIL +
+ + + +
+
HR
+ Hans Raddatz + KIND +
+
+
+
Details ▾
+
Transkribieren
+
Bearbeiten
+
+ +
+
+
+ +
+
+ +
+
Details
+
+
Datum
+
+
+
+
Ort
+
Divacca
+
+
+
Status
+
Hochgeladen
+
+
+ +
+
Personen
+
+
Absender
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+
+
+
Empfänger
+
+
HR
+ Hans Raddatz + KIND +
+
+
+ +
+
Schlagwörter
+
+ Familie + 1923 + Berlin +
+
+
+
+ +
+
+
+
+

Light. Pills appear in both the sub-header chip row and the metadata Personen column. Arrow between chips is mint-coloured and aria-hidden.

+
+ + +
+
Dark theme
+
+
+
+ +
+ + + + +
MR
+
+
+
+ +
+
+
W-0311 · Divacca
+
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+ +
+
HR
+ Hans Raddatz + KIND +
+
+
+
Details ▾
+
Transkribieren
+
Bearbeiten
+
+ +
+
+
+
+
+
+
Details
+
+
Datum
+
+
+
+
Ort
+
Divacca
+
+
+
Status
+
Hochgeladen
+
+
+
+
Personen
+
+
Absender
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+
+
+
Empfänger
+
+
HR
+ Hans Raddatz + KIND +
+
+
+
+
Schlagwörter
+
+ Familie + 1923 + Berlin +
+
+
+
+
+
+
+
+

Dark. Pills flip to rgba(0,199,177,.10) bg, #00c7b1 border, #f0efe9 text. Sub-header and metadata surfaces both use #011526.

+
+ +
+
+ + + +
+
+

3 · Tablet (768 px)

+

+ The 3-column metadata grid collapses to a single stacked column. The sub-header truncates the document + title and moves secondary actions behind a "…" overflow button. Pills remain inline next to person names in both locations. +

+
+ +
+ +
+
Tablet · 768 px · Light
+
+
+
+ +
MR
+
+ +
+
+ +
+
+
W-0311 · Divacca
+
+
Bearbeiten
+
···
+
+
+ +
+
Personen
+
+
Absender
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+
+
+
Empfänger
+
+
HR
+ Hans Raddatz + KIND +
+
+
Details
+
Ort
+
Divacca
+
Status
+
Hochgeladen
+
Schlagwörter
+
+ Familie + 1923 +
+
+
+
+
+
+

Tablet light. 3-column metadata collapses to single column. Pills stay inline with names. Sub-header shows only title + primary action + overflow menu.

+
+ + +
+
Tablet · 768 px · Dark
+
+
+
+ +
MR
+
+
+
+ +
+
+
W-0311 · Divacca
+
+
Bearbeiten
+
···
+
+
+
+
Personen
+
+
Absender
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+
+
+
Empfänger
+
+
HR
+ Hans Raddatz + KIND +
+
+
Details
+
Ort
+
Divacca
+
Status
+
Hochgeladen
+
Schlagwörter
+
+ Familie + 1923 +
+
+
+
+
+
+

Tablet dark. Same collapse behaviour. Dark pill tokens apply throughout.

+
+
+
+ + + +
+
+

4 · Mobile (375 px)

+

+ Sub-header is simplified to back arrow and document title only — no person chips in the bar. + Metadata is full-width single column. Each person row is flex; align-items: center; flex-wrap: nowrap + — avatar, name, and pill on one line. If the name is very long the row wraps gracefully before the pill. + Only primary action buttons are shown. +

+
+ +
+ +
+
Mobile · 375 px · Light
+
+
+
+ +
MR
+
+ +
+
+ +
+
+
W-0311 · Divacca
+
Bearbeiten
+
+ +
+
Absender
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+
Empfänger
+
+
HR
+ Hans Raddatz + KIND +
+
Ort
+
Divacca
+
Status
+
Hochgeladen
+
Schlagwörter
+
+ Familie + 1923 + Berlin +
+
+
+
+
+
+

Mobile light. No chips in sub-header — only title + primary action. Person rows: avatar + name + pill, flex-wrap:nowrap. Pill text drops to 6px to fit.

+
+ + +
+
Mobile · 375 px · Dark
+
+
+
+ +
MR
+
+
+
+ +
+
+
W-0311 · Divacca
+
Bearbeiten
+
+
+
Absender
+
+
KR
+ Karl Raddatz + ELTERNTEIL +
+
Empfänger
+
+
HR
+ Hans Raddatz + KIND +
+
Ort
+
Divacca
+
Status
+
Hochgeladen
+
Schlagwörter
+
+ Familie + 1923 +
+
+
+
+
+
+

Mobile dark. Pill tokens #00c7b1/#f0efe9 at reduced 6px font — still passes AA on dark surface.

+
+
+
+ + + +
+
+

5 · Edge cases — when no pill is rendered

+

Three cases where the pill is silently omitted. The person name renders as normal — no gap, no placeholder.

+
+ +
+ + +
+
No family relationship → no pill
+
+
+
Absender
+
+
KR
+ Karl Raddatz + +
+
+
+
Empfänger
+
+
ME
+ Maria Engel + +
+
+
— no pill —
+
inferredRelationship === null because the backend returns 404 (no kinship path). Name renders without trailing pill.
+
+
+ + +
+
Social relationship (Kollegen) → pill shows label
+
+
+
Absender
+
+
KR
+ Karl Raddatz + KOLLEGE +
+
+
+
Empfänger
+
+
FW
+ Fritz Weber + KOLLEGE +
+
+
Non-family relationships (Kollege, Freund, etc.) returned by the inference endpoint still render as pills. The pill component is label-agnostic — it renders whatever inferredRelationship provides.
+
+
+ + +
+
Multiple receivers → no pill
+
+
+
Absender
+
+
KR
+ Karl Raddatz +
+
+
+
Empfänger
+
+
HR
+ Hans Raddatz +
+
+
ER
+ Elfriede Raddatz +
+
+
— no pill —
+
receivers.length > 1 — inference endpoint is never called, inferredRelationship is null. No pill on any person chip.
+
+
+ +
+
+ + + +
+
+

6 · Implementation reference

+

Exact CSS/Tailwind values for every element of the pill and its context. Use these as the ground truth during implementation review.

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementTailwind / CSSNotes
Inline pill (light)rounded-full border border-[#a1dcd8] bg-[rgba(161,220,216,.25)] px-2 py-0.5 text-[9px] font-bold uppercase tracking-[.07em] text-[#012851] ml-2 align-middle inlineMontserrat 9px 700. ml-2 = 8px from name span. vertical-align: middle aligns cap-height to person name.
Inline pill (dark)dark:bg-[rgba(0,199,177,.10)] dark:border-[#00c7b1] dark:text-[#f0efe9]All three dark overrides applied together. Rest of pill class unchanged.
Person name spanfont-sans text-[11px] text-[#4b5563] dark:text-[#9ca3af] (sub-header) or font-serif text-[9.5px] text-ink dark:text-[#f0efe9] (metadata)Name and pill share a flex items-center gap-0 wrapper. Pill is the immediate next sibling of the name <span>.
Sub-header chip areaflex items-center gap-1.5Wraps one sender chip + arrow + one receiver chip. Placed after the doc-title block, before action buttons.
Chip (avatar + name + pill)flex items-center gap-1Avatar, name span, and pill as three siblings inside the chip div.
Arrow between chips (sub-header)h-2.5 w-2.5 shrink-0 text-[#a1dcd8] dark:text-[#00c7b1] with aria-hidden="true"Arrow SVG carries no semantic information. DOM order (sender chip before receiver chip) conveys direction for assistive technology.
Person avatar (sub-header)w-5 h-5 rounded-full flex items-center justify-center text-[6px] font-bold text-white shrink-020×20 px. Initials in 6px bold white. Background colour is person-specific (set inline).
Person avatar (metadata)w-5 h-5 rounded-full flex items-center justify-center text-[6.5px] font-extrabold text-white shrink-0Same 20×20 px. Slightly heavier weight (800) to match existing drawer card style.
Pill condition{#if inferredRelationship} … {/if} wraps both the sender pill and the receiver pillRender only when inferredRelationship !== null && receivers.length === 1. The check lives in +page.server.ts, not in the component.
Pill label valueinferredRelationship.labelFromA next to sender, inferredRelationship.labelFromB next to receiverLabels are pre-translated strings from the backend. No frontend i18n key needed for the label text itself.
Mobile person rowflex items-center gap-1 flex-nowrapflex-wrap: nowrap keeps avatar + name + pill on one line. If name overflows container, truncate name with truncate, never truncate the pill.
Mobile pill font-sizetext-[6px] at ≤375 pxReduced from 9px (desktop) to 6px on mobile to fit without overflow. Contrast still passes AA at 6px bold.
Sub-header at mobileChips removed entirely from sub-header at max-width: 767pxSub-header shows only back arrow + document title + primary action button. Person chips with pills appear only in the metadata section on mobile.
+
+ +

+ Accessibility note: The pill text ("ELTERNTEIL", "KIND") is uppercase visually but the accessible name should be the mixed-case label from the backend (labelFromA). Apply aria-label={labelFromA} on the pill span so screen readers announce "Elternteil" not "E-L-T-E-R-N-T-E-I-L". The visual uppercase is achieved with CSS text-transform: uppercase, not by changing the source string. +

+
+ + +
+ + diff --git a/docs/specs/stammbaum-person-edit-spec.html b/docs/specs/stammbaum-person-edit-spec.html new file mode 100644 index 00000000..df1c19d2 --- /dev/null +++ b/docs/specs/stammbaum-person-edit-spec.html @@ -0,0 +1,1135 @@ + + + + + +Stammbaum — Person Edit · Stammbaum & Beziehungen Card · Familienarchiv + + + + +
+ + +
+

Stammbaum — Person Edit · Stammbaum & Beziehungen Card

+

+ Spec for the new Stammbaum & Beziehungen card appended at the bottom of + /persons/{id}/edit. The card lets editors toggle a person's family-tree membership + and manage their direct relationships (parents-of, spouse, siblings, etc.). Inferred transitive + relationships are shown in a collapsible derived section. +

+ +
+ Stammbaum Feature + View 3 of 3 — Person Edit + Desktop / Tablet / Mobile + Light + Dark +
+
+ + + +
+
+

1 · Design tokens

+

All colour values used by the new card. Components use Tailwind semantic tokens; exact hex values are provided here for reference only.

+
+ +
+ +
+
Light theme — page bg #f0efe9 · card bg #ffffff
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Page bg#f0efe9 — sand
Card bg / border#ffffff / 1px #e4e2d7
Section label#6b7280 — Montserrat 9px 700 uppercase4.8:1 AA ✓
In-tree indicator bgrgba(161,220,216,.1) bg / 1px #a1dcd8 border
In-tree label#01285114.5:1 AAA ✓
Toggle ON track#012851
Toggle OFF track#e4e2d7
Toggle thumb#ffffff
Direct rel pill bg/borderrgba(161,220,216,.2) / 1px #a1dcd8
Direct rel name#012851 — Tinos 10px
Rel years#6b7280 — Montserrat 8px
Delete btn / hover#6b7280 normal / #c0392b hover
Add-form bg / border#f5f4ef / #e4e2d7
Derived pill bg/border#f5f4ef / #e4e2d7
+ Hinzufügen btn#012851 bg / #fff text
+
+ +
+
Dark theme — page bg #010e1e · card bg #011526
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Page bg#010e1e
Card bg / border#011526 / 1px #0d3358
Section label#8b97a57.1:1 AAA ✓
In-tree indicator bgrgba(0,199,177,.08) bg / 1px #00c7b1 border
In-tree label#00c7b1
Toggle ON track#a1dcd8 (mint)
Toggle thumb (ON)#012851
Direct rel pill bg/borderrgba(0,199,177,.12) / 1px #00c7b1
Direct rel name#f0efe9
Rel years#8b97a5
Add-form bg / border#011a30 / #0d3358
Derived pill bg/border#011a30 / #0d3358 / text #9ca3af
+ Hinzufügen btn#a1dcd8 bg / #012851 text
+
+
+
+ + + +
+
+

2 · Desktop (1280 px) — light & dark

+

+ Full person-edit page at desktop width. Light mockup shows the + add-form expanded; dark mockup shows the resting state + (form collapsed, toggle ON, no derived section open). Shown at ~40% scale. +

+
+ +
+ + +
+
Light theme · add form expanded
+
+
+
+ + + + + +
M
+
+ +
+ +
+ + + Zurück + +
+ +
Person bearbeiten
+ + +
+
Angaben zur Person
+
+
+
+
+
+
+
+
Titel + Vorname
+
Nachname
+
+
+
Rufname
+
Geburtsjahr
+
Todesjahr
+
+
+
+ + +
+
Namensverlauf
+
Noch keine Namensänderungen erfasst
+
+
Art
+
Nachname
+
+
+ + +
+ +
+
Stammbaum & Beziehungen
+
+ Als Familienmitglied +
+
+
+ + +
+
+
+ Erscheint im Stammbaum +
+ Ansehen → +
+ + +
Direkte Beziehungen
+
+
+ Elternteil von + Hans Raddatz + ab 1905 + +
+
+ Elternteil von + Lotte Berger + ab 1908 + +
+
+ Elternteil von + Werner Raddatz + ab 1912 + +
+
+ Ehegatte + Frieda Raddatz + 1902–1944 + +
+
+ + +
+ + Beziehung hinzufügen +
+ + +
+
Beziehung hinzufügen
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
+ Abgeleitete Beziehungen + 5 +
+ +
+
+ + +
+ + +
+
+
+

Desktop, light. Toggle is ON → in-tree indicator visible. "Beziehung hinzufügen" form is expanded, showing Typ dropdown, Person typeahead, Von/Bis year inputs, and "+ Hinzufügen" button. Derived section is collapsed with count badge (5).

+
+ + +
+
Dark theme · resting state
+
+
+
+ + + + + +
M
+
+ +
+
+ + + Zurück + +
+ +
Person bearbeiten
+ + +
+
Angaben zur Person
+
+
+
+
+
+
+
+
Vorname
+
Nachname
+
+
+
+ + +
+
Namensverlauf
+
Noch keine Namensänderungen erfasst
+
+
Art
+
Nachname
+
+
+ + +
+
+
Stammbaum & Beziehungen
+
+ Als Familienmitglied +
+
+
+ +
+
+
+ Erscheint im Stammbaum +
+ Ansehen → +
+ +
Direkte Beziehungen
+
+
+ Elternteil von + Hans Raddatz + ab 1905 + +
+
+ Elternteil von + Lotte Berger + ab 1908 + +
+
+ Elternteil von + Werner Raddatz + ab 1912 + +
+
+ Ehegatte + Frieda Raddatz + 1902–1944 + +
+
+ +
+ + Beziehung hinzufügen +
+ +
+
+ Abgeleitete Beziehungen + 5 +
+ +
+
+ +
+ + +
+
+
+

Desktop, dark. Resting state — add form hidden, "+ Beziehung hinzufügen" button visible. Toggle track is mint (#a1dcd8), thumb is navy (#012851). In-tree indicator border shifts to turquoise #00c7b1.

+
+ +
+
+ + + +
+
+

3 · Tablet (768 px)

+

+ Narrower viewport — card fills the single center column, paddings tighten. Same component + structure as desktop. Shown at ~50% scale. +

+
+ +
+
Tablet · light · resting state
+
+
+
+ + +
M
+
+ +
+
Person bearbeiten
+ + +
+
Angaben zur Person
+
+
+
+
+ + +
+
Namensverlauf
+
Noch keine Namensänderungen erfasst
+
+
+ + +
+
+
Stammbaum & Beziehungen
+
+ Als Familienmitglied +
+
+
+ +
+
+
+ Erscheint im Stammbaum +
+ Ansehen → +
+ +
Direkte Beziehungen
+
+
+ Elternteil von + Hans Raddatz + ab 1905 + +
+
+ Ehegatte + Frieda Raddatz + 1902–1944 + +
+
+ +
+ + Beziehung hinzufügen +
+ +
+
+ Abgeleitete Beziehungen + 5 +
+ +
+
+ +
+ + +
+
+
+

Tablet. Card fills single column. Two relationship rows shown (trimmed for space). All controls remain the same size — no stacking yet at 768 px.

+
+
+ + + +
+
+

4 · Mobile (375 px)

+

+ Phone viewport. Card is full-width. Add-form fields stack vertically (single column). + Pill labels truncate to first word on very small screens if needed. Shown at ~65% scale. +

+
+ +
+
Mobile 375px · light · add form expanded
+
+
+
+ +
M
+
+ +
+
Person bearbeiten
+ + +
+
Angaben zur Person
+
+
+
+
+ + +
+ +
+
Stammbaum & Beziehungen
+
+ Als Familienmitglied +
+
+
+ +
+
+
+ Erscheint im Stammbaum +
+ Ansehen → +
+ +
Direkte Beziehungen
+
+
+ Elternteil von + Hans Raddatz + ab 1905 + +
+
+ Ehegatte + Frieda Raddatz + 1902–1944 + +
+
+ + +
+
Beziehung hinzufügen
+ +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ +
+
+ Abgeleitete Beziehungen + 5 +
+ +
+
+ +
+ + +
+
+
+

Mobile. "Typ" and "Person" fields are stacked vertically. Year inputs remain side-by-side. Pill labels shrink to 6 px. Card fills the full width with 7 px side padding.

+
+
+ + + +
+
+

5 · Derived relationships — expanded state

+

+ Clicking the "Abgeleitete Beziehungen" row expands the section. Items are computed + server-side from the direct-relationship graph — the frontend renders them read-only. + Grey pills and muted italic text for entries that cannot be resolved. +

+
+ +
+
Derived relationships — expanded · light
+
+
+
+ + +
M
+
+
+
+
+
Stammbaum & Beziehungen
+
+ Als Familienmitglied +
+
+
+ +
+
+
+ Erscheint im Stammbaum +
+ Ansehen → +
+ +
Direkte Beziehungen
+
+
+ Elternteil von + Hans Raddatz + ab 1905 + +
+
+ Ehegatte + Frieda Raddatz + 1902–1944 + +
+
+
+ + Beziehung hinzufügen +
+ + +
+
+ Abgeleitete Beziehungen + 5 +
+ +
+ +
+
+ Kind von + Heinrich Raddatz +
+
+ Kind von + Maria Raddatz +
+
+ Geschwister von + Ernst Raddatz +
+
+ Schwiegereltern + Eltern von Frieda, nicht im Archiv +
+
+ Onkel/Tante von + — keine Geschwisterkinder erfasst +
+
+
+
+
+

Derived section expanded. Chevron rotates to ▴. Items use grey pills and Tinos italic for unresolvable entries. Section is read-only — no edit or delete controls. Computed by the backend graph traversal.

+
+
+ + + +
+
+

6 · Implementation reference

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementTailwind / CSSNotes
Card wrapperbg-white border border-line rounded-sm p-6Matches existing Angaben and Namensverlauf cards on same page
Section labeltext-xs font-bold uppercase tracking-widest text-gray-400 mb-4Montserrat 9px 700; identical to all other cards on the page
Card header rowflex items-center justify-between mb-3Section label on left; toggle label + toggle on right
Toggle track ONw-[38px] h-5 rounded-full bg-primary transition-colorsdark: bg-accent (#a1dcd8)
Toggle track OFFw-[38px] h-5 rounded-full bg-linebg-line = #e4e2d7
Toggle thumbabsolute top-0.5 w-4 h-4 rounded-full bg-white transition-allON: left-[19px]; OFF: left-0.5; dark ON thumb: bg-primary
In-tree bannerflex items-center justify-between px-2.5 py-1.5 bg-accent/10 border border-accent rounded-sm mb-3Hidden when toggle is OFF. dark: bg-[rgba(0,199,177,.08)] border-[#00c7b1]
In-tree dotw-[7px] h-[7px] rounded-full bg-primary shrink-0dark: bg-[#00c7b1]
In-tree labeltext-[9px] font-bold uppercase tracking-widest text-primarydark: text-[#00c7b1]
In-tree linktext-[9px] font-semibold text-primary/60Navigates to /stammbaum?focus={personId}
Rel row wrapperflex items-center gap-2 py-1.5 border-b border-muted last:border-b-0Padding 7px top/bottom; bottom border except last row
Direct rel pillrounded-full border border-accent bg-accent/20 px-2 py-0.5 text-[9px] font-bold uppercase tracking-wider text-ink shrink-0dark: bg-[rgba(0,199,177,.12)] border-[#00c7b1] text-sand
Rel person namefont-serif text-[13px] text-ink flex-1 min-w-0 truncateTinos; truncate prevents overflow on narrow viewports
Rel year rangefont-sans text-[10px] text-ink-3 whitespace-nowrapFormat: ab {year} or {from}–{to}
Delete buttontext-ink-3 hover:text-danger p-0.5 ml-auto shrink-0✕ icon button; hover color #c0392b; min touch 44px via padding wrapper
Add-rel quiet buttonflex items-center gap-1 text-[8px] font-bold text-primary/60 hover:text-primary/90 mt-1+ icon (heroicons plus-mini); hidden when add form is open
Add-form cardmt-3 bg-muted border border-line rounded-sm p-3.5bg-muted = #f5f4ef; dark: bg-[#011a30] border-[#0d3358]
Type selectw-full border border-line rounded-sm px-2.5 py-2 text-xs font-sans text-ink bg-whiteOptions: Elternteil von / Ehegatte / Geschwister von / Kollege / Freund / Arbeitgeber / Arzt / Nachbar / Sonstiges
Person inputw-full border border-line rounded-sm px-2.5 py-2 font-serif text-sm text-ink bg-whiteDrives PersonTypeahead component; placeholder "z.B. Oma Frieda…"
Year inputsflex-1 border border-line rounded-sm px-2.5 py-2 font-serif text-sm text-ink bg-whiteSide-by-side via flex gap-2; on mobile remain side-by-side (they're short)
+ Hinzufügen buttonbg-primary text-white px-3.5 py-2 text-[10px] font-bold uppercase tracking-wider rounded-sm shrink-0dark: bg-accent text-primary
Cancel buttonbg-white border border-line rounded-sm px-3 py-1.5 text-[10px] font-bold text-ink-2Collapses add form without saving
Derived section headerflex items-center justify-between py-2 border-t border-muted cursor-pointer mt-2.5 select-noneClick toggles derivedExpanded boolean in component state
Derived count badgeml-1.5 rounded-full border border-line bg-muted px-1.5 py-0 text-[7px] font-bold text-ink-3Shows total inferred relationship count from backend
Derived rel pillrounded-full border border-line bg-muted px-2 py-0.5 text-[9px] font-bold uppercase tracking-wider text-ink-2 shrink-0Grey, no accent border; read-only only
Derived rel namefont-serif text-[13px] text-ink-3Muted; unresolvable entries use italic text-ink-4
Mobile form stackingsm:flex-row flex-col on add-form top rowBelow 640 px Typ and Person stack; year inputs stay side-by-side
+
+
+ +
+ + diff --git a/docs/specs/stammbaum-tree-spec.html b/docs/specs/stammbaum-tree-spec.html new file mode 100644 index 00000000..04b86348 --- /dev/null +++ b/docs/specs/stammbaum-tree-spec.html @@ -0,0 +1,1043 @@ + + + + + +Stammbaum — Tree Page · /stammbaum · Familienarchiv + + + + +
+ + +
+

Stammbaum — Tree Page · /stammbaum

+

+ Visual specification for the generational family tree view. Covers the SVG canvas with + Gen I–III nodes, the 268 px side panel (resting and add-form states), and responsive + behavior at 768 px (tablet, slide-over) and 375 px (mobile, horizontal scroll). + Light and dark themes throughout. +

+ +
+ Stammbaum Feature + View 1 of 3 — Tree Page + Desktop / Tablet / Mobile + Light + Dark +
+
+ + + +
+
+

1 · Design tokens

+

All colour values used by the tree canvas, nodes, connectors, and side panel. The component uses only semantic Tailwind tokens — no hardcoded hex. Light and dark themes are handled automatically by layout.css.

+
+ +
+ +
+
Light theme
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Canvas bg#f0efe9 — sand page background
Node bg default#ffffff — white
Node bg selected#012851 — navyAAA on white acc. bar
Node accent bar#a1dcd8 — mint, 4 px left strip on selected
Node border default#012851 1.5 px
Connector / dot#012851 stroke-width 1.5, r=4.5
Name text default#01285114.5:1 AAA ✓
Name text selected#ffffff on #01285114.5:1 AAA ✓
Years text default#6b72804.8:1 AA ✓
Years text selectedrgba(255,255,255,.6) — decorative, aria-hidden years
Gen label#6b7280 — 8 px, tracking 2 px, aria-hidden
Panel surface#ffffff
Direct pillrgba(161,220,216,.2) bg · #a1dcd8 border · #012851 text
Derived pill#f5f4ef bg · #e4e2d7 border · #4b5563 text
+
+ +
+
Dark theme
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Canvas bg#010e1e
Node bg default#011526
Node bg selected#a1dcd8 — mint inverted
Node accent bar#012851 — navy inverted
Node border default#1e3a55 1.5 px
Connector / dot#3a6080 stroke-width 1.5
Name text default#f0efe914.5:1 AAA ✓
Name text selected#012851 on #a1dcd89.2:1 AAA ✓
Years text default#8b97a57.1:1 AAA ✓
Gen label#4e6070 — aria-hidden
Panel surface#011526
Direct pillrgba(0,199,177,.12) bg · #00c7b1 border · #f0efe9 text
Derived pill#011a30 bg · #0d3358 border · #9ca3af text
+
+
+
+ + + +
+
+

2 · Desktop (1280 px) — light & dark, resting state

+

Full tree canvas with Gen I–III nodes and the 268 px side panel showing Maria Raddatz (selected). Rendered at ~65 % scale. Light and dark stacked.

+
+ +
+ + +
+
Light theme
+
+
+ +
+
+
+
+ +
+ + + + +
M
+
+ +
+
+
Stammbaum
+
+
Generationen ▾
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + Heinrich + Raddatz + 1850–1920 + + + + + Maria + Raddatz + 1855–1932 + + + + Karl + Raddatz + 1878–1944 + + + + Frieda + Raddatz + 1882–1956 + + + + Ernst + Raddatz + 1880–1961 + + + + Helga + Müller + 1885–1940 + + + + Hans + Raddatz + 1905–1972 + + + + Lotte + Berger + 1908–1987 + + + + Werner + Raddatz + 1912–1966 + +
+ +
+
+
+
MR
+
+
Maria Raddatz
+
1855–1932
+
+
+
+
+
+
+ +
+ EhegatteHeinrich Raddatz + ElternteilKarl Raddatz + ElternteilErnst Raddatz +
+ + Beziehung hinzufügen +
+
+
+ +
+ GroßelternteilHans Raddatz + GroßelternteilLotte Berger + GroßelternteilWerner Raddatz +
+
+
+
+
+
+
+
+

Light. Maria Raddatz (Gen I, right) is selected — navy fill, mint accent bar, white text. Side panel at right shows direkte Beziehungen as mint pills and abgeleitete Beziehungen as sand pills. "+" add button is quiet / low-opacity.

+
+ + +
+
Dark theme
+
+
+
+
+
+
+
+
+
+ + + + +
M
+
+
+
+
Stammbaum
+
+
Generationen ▾
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + Heinrich + Raddatz + 1850–1920 + + + + Maria + Raddatz + 1855–1932 + + + Karl + Raddatz + 1878–1944 + + Frieda + Raddatz + 1882–1956 + + Ernst + Raddatz + 1880–1961 + + Helga + Müller + 1885–1940 + + + Hans + Raddatz + 1905–1972 + + Lotte + Berger + 1908–1987 + + Werner + Raddatz + 1912–1966 + +
+ +
+
+
+
MR
+
+
Maria Raddatz
+
1855–1932
+
+
+
+
+
+
+ +
+ EhegatteHeinrich Raddatz + ElternteilKarl Raddatz + ElternteilErnst Raddatz +
+ + Beziehung hinzufügen +
+
+
+ +
+ GroßelternteilHans Raddatz + GroßelternteilLotte Berger + GroßelternteilWerner Raddatz +
+
+
+
+
+
+
+
+

Dark mode. Maria's node inverts to mint (#a1dcd8) fill with navy accent bar and navy text — the exact inverse of light. Direct pills use #00c7b1 border on near-black bg; derived pills use #0d3358 border. Canvas bg is #010e1e.

+
+ +
+
+ + + +
+
+

3 · Side panel states — light

+

Left: resting state — "+" text button is quiet (low opacity) below the direct relationships list. Right: add-form expanded — a compact inline form replaces the quiet button. No modal.

+
+ +
+ + +
+
Resting — quiet add button
+
+
+
+
+
+
+
MR
+
+
Maria Raddatz
+
1855–1932
+
+
+
+
+
+
Direkte Beziehungen
+
+ EhegatteHeinrich Raddatz + ElternteilKarl Raddatz + ElternteilErnst Raddatz +
+ + + Beziehung hinzufügen +
+
Abgeleitete Beziehungen
+
+ GroßelternteilHans Raddatz + GroßelternteilLotte Berger + GroßelternteilWerner Raddatz +
+
+
+
+
+

Resting. "+ Beziehung hinzufügen" sits below direct-relationship pills at 40% opacity. It is a button, not a link. Derived relationships are always read-only (no add button).

+
+ + +
+
Add-form expanded
+
+
+
+
+
+
+
MR
+
+
Maria Raddatz
+
1855–1932
+
+
+
+
+
+
Direkte Beziehungen
+
+ EhegatteHeinrich Raddatz + ElternteilKarl Raddatz + ElternteilErnst Raddatz +
+ +
+ + +
+ + +
+
+
Abbrechen
+
Speichern
+
+
+
+
+
+
+

Expanded. Clicking "+" reveals a compact inline form: relationship-type select (full width), focused person-search input (navy border = focus indicator), optional Von/Bis Jahr row, and Abbrechen + Speichern. No modal, no overlay.

+
+ +
+
+ + + +
+
+

4 · Tablet (768 px) — light

+

Tree fills the full viewport width. The 268 px side panel is hidden by default and slides up as a bottom sheet when the user taps a node. Mode toggle and zoom controls remain visible in the page header.

+
+ +
+
768 px · no persistent side panel
+
+
+ +
+
+
+
+ +
+ + + + +
M
+
+ +
+
+
Stammbaum
+
+
Generationen ▾
+
+
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + Heinrich + Raddatz + 1850–1920 + + + Maria + Raddatz + 1855–1932 + + Karl + Raddatz + 1878–1944 + + Frieda + Raddatz + 1882–1956 + + Ernst + Raddatz + 1880–1961 + + Helga + Müller + 1885–1940 + + Hans + Raddatz + 1905–1972 + + Lotte + Berger + 1908–1987 + + Werner + Raddatz + 1912–1966 + +
+
Side panel appears as bottom sheet on node tap
+
+
+
+
+
+

Tablet. The 268 px side panel column is removed; the tree card spans full page width (minus 32 px gutter). Tapping any node slides up a bottom sheet containing the same panel content. Mode toggle and zoom buttons remain in the top bar.

+
+ + + +
+
+

5 · Mobile (375 px) — light

+

App header is abbreviated (logo + avatar only, no nav links). "Stammbaum" appears as a page-level h1 below the header. The tree card overflows horizontally — the user scrolls left/right. Zoom controls are removed on mobile.

+
+ +
+
375 px · horizontal scroll tree
+
+
+ +
+
+
+
+ +
+ +
M
+
+ +
+ +

Stammbaum

+ +
+
Baum
+
Liste
+
+ +
+ + + + + + + + + + + + + + + + + + + + + Heinrich + Raddatz + 1850–1920 + + + Maria + Raddatz + 1855–1932 + + Karl + Raddatz + 1878–1944 + + Frieda + Raddatz + 1882–1956 + + Ernst + Raddatz + 1880–1961 + + Helga + Müller + 1885–1940 + + Hans + Raddatz + 1905–1972 + + Lotte + Berger + 1908–1987 + + Werner + Raddatz + 1912–1966 + +
+
+
+
+
+

Mobile 375 px. Header is abbreviated — logo + avatar, no nav links. "Stammbaum" is a standalone h1. Baum/Liste mode toggle is full width. Tree card has overflow-x: scroll; the SVG renders at full 820 px width and the user pans. Zoom controls removed.

+
+ + + +
+
+

6 · Implementation reference

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementTailwind / CSSpx valueNotes
Tree nodew-[144px] h-[50px] rounded-sm144 × 50SVG rect rx="2"; same size all generations
Selected accent barw-1 h-full bg-accent4 × 50Mint on light; navy on dark; left edge of selected node
Side panelw-[268px] shrink-0268Hidden at ≤ 768 px; becomes bottom sheet on node tap
Tree + panel gapgap-[18px]18Flex row gap between tree card and side panel
Page paddingpx-8 py-632 / 24Reduced to px-3 py-3 on mobile
Direct pillrounded-full px-2 py-0.5 text-[9px]Mint border rgba(161,220,216,.2) bg; #a1dcd8 border light
Derived pillrounded-full px-2 py-0.5 text-[9px]#f5f4ef bg; #e4e2d7 border light; read-only, no add button
Connector strokeSVG stroke-width="1.5"1.5 px#012851 light · #3a6080 dark
Marriage dotSVG r="4.5"9 px diaFilled circle at connector midpoints; same color as connectors
Gen labeltext-[8px] tracking-[2px] uppercase8 pxaria-hidden="true"; #6b7280 light · #4e6070 dark
Node name textfont-serif text-[10px] font-bold10 pxTwo lines: given name y+20, surname y+32; text-anchor middle at cx
Node years textfont-sans text-[8px]8 pxy+44 from node top; subdued color; not aria-hidden (content)
Zoom controlsflex border rounded-sm overflow-hidden26 × 26 eachHidden on mobile (≤ 640 px)
Mode toggle (mobile)flex w-full border rounded-sm overflow-hiddenfull widthTwo segments: Baum (active) / Liste; full width on mobile only
Tree card scrolloverflow-x-autoApplied to tree card wrapper on mobile; SVG renders at full 820 px
+
+
+ +
+ +