Files
familienarchiv/docs/specs/stammbaum-tree-spec.html
Marcel 33ca2df45b
Some checks failed
CI / Unit & Component Tests (push) Failing after 3m12s
CI / OCR Service Tests (push) Successful in 29s
CI / Backend Unit Tests (push) Failing after 3m1s
docs(specs): add Stammbaum UI specs — tree, document badge, person edit
Three standalone HTML spec files covering the initial Stammbaum release:
- stammbaum-tree-spec.html — desktop/tablet/mobile tree canvas with side panel, light + dark
- stammbaum-doc-badge-spec.html — inline relationship pill on document detail
- stammbaum-person-edit-spec.html — relationship editor card on person edit page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 13:09:47 +02:00

1044 lines
72 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stammbaum — Tree Page · /stammbaum · Familienarchiv</title>
<link href="https://fonts.googleapis.com/css2?family=Tinos:ital,wght@0,400;0,700&family=Montserrat:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Montserrat',system-ui,sans-serif;background:#ECEAE4;color:#1A1A1A;line-height:1.5;font-size:13px}
.doc{max-width:1300px;margin:0 auto;padding:48px 32px 120px}
/* ── Masthead ── */
.mh{padding-bottom:24px;border-bottom:3px solid #012851;margin-bottom:60px}
.mh h1{font-size:23px;font-weight:900;color:#012851;letter-spacing:-.4px}
.mh p{font-size:13px;color:#555;max-width:740px;line-height:1.75;margin-top:8px}
.mh .byline{font-size:9px;color:#999;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;margin-top:10px}
.tag-row{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}
.tag{background:#012851;color:#A1DCD8;padding:2px 8px;border-radius:2px;font-size:8px;font-weight:700;letter-spacing:.8px;text-transform:uppercase}
.tag.amber{background:#7c4a00;color:#fde68a}
/* ── Section headers ── */
.sh{margin:0 0 28px}
.sh h2{font-size:16px;font-weight:900;color:#012851;letter-spacing:-.2px}
.sh p{font-size:12.5px;color:#666;max-width:720px;line-height:1.7;margin-top:5px}
.section{margin-bottom:80px;padding-bottom:80px;border-bottom:2px dashed #C8C4BE}
.section:last-of-type{border-bottom:none;margin-bottom:0;padding-bottom:0}
/* ── Token tables ── */
.token-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}
.token-table{border-radius:6px;overflow:hidden}
.token-table.light{background:#fff;border:1px solid #E0DDD6}
.token-table.dark{background:#0F1923;border:1px solid #1E2D3D}
.token-head{padding:8px 14px;font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;border-bottom:1px solid #E0DDD6}
.token-table.light .token-head{background:#F4F2EC;color:#888;border-bottom-color:#E0DDD6}
.token-table.dark .token-head{background:#0A1218;color:#4E6070;border-bottom-color:#1E2D3D}
.token-table table{width:100%;border-collapse:collapse;font-size:11px}
.token-table.light td{padding:6px 14px;border-bottom:1px solid #F0EEE8;vertical-align:middle}
.token-table.dark td{padding:6px 14px;border-bottom:1px solid #1A2830;vertical-align:middle;color:#8AAABB}
.token-table tr:last-child td{border-bottom:none}
.token-table.light td:first-child{font-size:9px;font-weight:700;color:#888;width:180px}
.token-table.dark td:first-child{font-size:9px;font-weight:700;color:#4E6070;width:180px}
.swatch{display:inline-block;width:12px;height:12px;border-radius:2px;vertical-align:middle;margin-right:6px}
.swatch.bordered{border:1px solid #DDD}
.warn{display:inline-block;background:#FEF3C7;color:#92400E;font-size:8px;font-weight:700;padding:1px 5px;border-radius:2px;margin-left:4px;vertical-align:middle}
.pass{display:inline-block;background:#D1FAE5;color:#065F46;font-size:8px;font-weight:700;padding:1px 5px;border-radius:2px;margin-left:4px;vertical-align:middle}
/* ── Browser chrome ── */
.chrome{border:1.5px solid #C4C0BA;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.1)}
.chrome.dark{background:#010e1e;border-color:#0d3358}
.chrome-bar{height:20px;background:#E8E6E0;border-bottom:1px solid #C4C0BA;display:flex;align-items:center;padding:0 8px;gap:4px;flex-shrink:0}
.chrome.dark .chrome-bar{background:#010a18;border-bottom-color:#0d3358}
.chrome-dot{width:6px;height:6px;border-radius:50%;background:#BDB8B1}
.chrome.dark .chrome-dot{background:#1a2a3a}
.chrome-url{flex:1;height:9px;background:#CCC8C2;border-radius:5px;margin-left:6px}
.chrome.dark .chrome-url{background:#1a2a3a}
/* ── App nav ── */
.app-nav{height:30px;background:#012851;display:flex;align-items:center;padding:0 12px;gap:10px;flex-shrink:0}
.app-logo{font-family:'Tinos',Georgia,serif;font-size:7px;font-weight:700;color:#fff;border-bottom:2px solid #A1DCD8;padding-bottom:1px}
.app-link{font-size:5.5px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:rgba(255,255,255,.4);white-space:nowrap}
.app-link.on{color:rgba(255,255,255,.9)}
.app-nav-r{margin-left:auto;display:flex;gap:6px;align-items:center}
.app-av{width:16px;height:16px;border-radius:50%;background:rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:800;color:rgba(255,255,255,.5)}
/* ── Side-by-side layout ── */
.split-screens{display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-bottom:16px}
.screen-lbl{font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:1.2px;color:#888;margin-bottom:8px;display:flex;align-items:center;gap:5px}
.lbl-dot{width:8px;height:8px;border-radius:50%;display:inline-block}
.cap{font-size:10px;color:#999;font-style:italic;line-height:1.6;margin-top:10px;max-width:460px}
/* ── Rules table ── */
.rules{background:#fff;border:1px solid #E0DDD6;border-radius:6px;overflow:hidden}
.rules table{width:100%;border-collapse:collapse}
.rules th{background:#F4F2EC;font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;color:#888;padding:8px 12px;text-align:left;border-bottom:1px solid #E0DDD6}
.rules td{font-size:11px;color:#444;padding:8px 12px;border-bottom:1px solid #F0EEE8;vertical-align:top;line-height:1.6}
.rules tr:last-child td{border-bottom:none}
.rules td:first-child{font-size:9px;font-weight:700;color:#012851;white-space:nowrap;width:170px}
.rules td code{font-size:9px;background:#F0EFE9;padding:1px 4px;border-radius:2px;color:#555;white-space:nowrap}
/* ── Scale wrapper for desktop chromes ── */
.scale-outer{border:1.5px solid #C4C0BA;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.1);width:832px;height:390px}
.scale-outer.dark{border-color:#0d3358}
.scale-inner{width:1280px;transform:scale(0.65);transform-origin:top left}
/* ── Stammbaum page shell (inside scale-inner) ── */
.stb-page{background:#f0efe9;min-height:560px;display:flex;flex-direction:column}
.stb-page.dark-bg{background:#010e1e}
/* Page-level header row (below app-nav) */
.stb-page-head{display:flex;align-items:center;padding:20px 32px 0;gap:16px}
.stb-page-title{font-family:'Tinos',Georgia,serif;font-size:22px;font-weight:700;color:#012851}
.stb-page.dark-bg .stb-page-title{color:#f0efe9}
.stb-controls{margin-left:auto;display:flex;align-items:center;gap:8px}
.stb-btn{height:28px;padding:0 12px;border-radius:3px;font-size:9px;font-weight:700;display:flex;align-items:center;gap:5px;cursor:default}
.stb-btn.outline{border:1.5px solid #012851;color:#012851;background:transparent}
.stb-btn.outline-dark{border:1.5px solid #1e3a55;color:#8b97a5;background:transparent}
.stb-btn.primary{background:#012851;color:#a1dcd8}
.stb-btn.primary-dark{background:#a1dcd8;color:#012851}
.stb-zoom{display:flex;border:1.5px solid #012851;border-radius:3px;overflow:hidden}
.stb-page.dark-bg .stb-zoom{border-color:#1e3a55}
.stb-zoom-btn{width:26px;height:26px;display:flex;align-items:center;justify-content:center;font-size:13px;color:#012851;background:#fff;cursor:default}
.stb-page.dark-bg .stb-zoom-btn{color:#8b97a5;background:#011526}
.stb-zoom-btn+.stb-zoom-btn{border-left:1.5px solid #012851}
.stb-page.dark-bg .stb-zoom-btn+.stb-zoom-btn{border-left-color:#1e3a55}
/* Tree + panel layout */
.stb-body{display:flex;gap:18px;padding:20px 32px 32px;flex:1}
.stb-tree-area{flex:1;background:#fff;border:1.5px solid #e4e2d7;border-radius:4px;overflow:hidden;position:relative}
.stb-page.dark-bg .stb-tree-area{background:#011526;border-color:#0d3358}
.stb-panel{width:268px;flex-shrink:0;background:#fff;border:1.5px solid #e4e2d7;border-radius:4px;display:flex;flex-direction:column;overflow:hidden}
.stb-page.dark-bg .stb-panel{background:#011526;border-color:#0d3358}
/* Panel header */
.stb-panel-head{padding:14px 14px 0}
.stb-panel-name{font-family:'Tinos',Georgia,serif;font-size:14px;font-weight:700;color:#012851}
.stb-page.dark-bg .stb-panel-name{color:#f0efe9}
.stb-panel-years{font-size:9px;color:#6b7280;margin-top:2px}
.stb-page.dark-bg .stb-panel-years{color:#8b97a5}
.stb-panel-avatar{width:36px;height:36px;border-radius:50%;background:#012851;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;color:#a1dcd8;flex-shrink:0;margin-bottom:10px}
.stb-page.dark-bg .stb-panel-avatar{background:#a1dcd8;color:#012851}
.stb-panel-toprow{display:flex;align-items:center;gap:10px;margin-bottom:2px}
.stb-panel-divider{height:1px;background:#e4e2d7;margin:10px 0}
.stb-page.dark-bg .stb-panel-divider{background:#0d3358}
/* Panel section */
.stb-panel-body{padding:0 14px 14px;flex:1;overflow:auto}
.stb-rel-section{margin-bottom:12px}
.stb-rel-section-label{font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:#6b7280;margin-bottom:7px}
.stb-page.dark-bg .stb-rel-section-label{color:#8b97a5}
.stb-rel-list{display:flex;flex-direction:column;gap:5px}
/* Rel pill */
.stb-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;border-radius:99px;font-size:9px;border:1px solid}
.stb-pill.direct{background:rgba(161,220,216,.2);border-color:#a1dcd8;color:#012851}
.stb-pill.derived{background:#f5f4ef;border-color:#e4e2d7;color:#4b5563}
.stb-pill.direct-dark{background:rgba(0,199,177,.12);border-color:#00c7b1;color:#f0efe9}
.stb-pill.derived-dark{background:#011a30;border-color:#0d3358;color:#9ca3af}
.stb-pill-role{font-weight:700;font-size:8px;opacity:.6}
.stb-pill-name{font-family:'Tinos',Georgia,serif;font-size:9.5px}
/* Add rel button (resting) */
.stb-add-btn{margin-top:6px;font-size:9px;font-weight:700;color:#012851;opacity:.45;cursor:default;padding:4px 0;display:inline-block}
.stb-page.dark-bg .stb-add-btn{color:#a1dcd8;opacity:.5}
/* Add form (expanded) */
.stb-add-form{margin-top:8px;display:flex;flex-direction:column;gap:7px}
.stb-form-select{width:100%;height:26px;border:1.5px solid #e4e2d7;border-radius:3px;font-size:9px;font-family:'Montserrat',sans-serif;color:#012851;padding:0 8px;background:#fff}
.stb-page.dark-bg .stb-form-select{border-color:#1e3a55;background:#011a30;color:#f0efe9}
.stb-form-input{width:100%;height:26px;border:1.5px solid #012851;border-radius:3px;font-size:9px;font-family:'Montserrat',sans-serif;color:#012851;padding:0 8px;background:#fff}
.stb-page.dark-bg .stb-form-input{border-color:#a1dcd8;background:#011a30;color:#f0efe9}
.stb-form-row{display:flex;gap:6px}
.stb-form-row .stb-form-input{flex:1}
.stb-form-actions{display:flex;gap:6px;justify-content:flex-end}
.stb-form-cancel{height:24px;padding:0 10px;border:1.5px solid #e4e2d7;border-radius:3px;font-size:8px;font-weight:700;color:#4b5563;background:#fff;cursor:default}
.stb-page.dark-bg .stb-form-cancel{border-color:#1e3a55;background:#011a30;color:#8b97a5}
.stb-form-save{height:24px;padding:0 10px;border-radius:3px;font-size:8px;font-weight:700;color:#a1dcd8;background:#012851;cursor:default}
.stb-page.dark-bg .stb-form-save{background:#a1dcd8;color:#012851}
/* ── Tablet chrome ── */
.scale-outer-tablet{border:1.5px solid #C4C0BA;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.1)}
.scale-inner-tablet{width:768px;transform:scale(0.75);transform-origin:top left}
/* ── Mobile chrome ── */
.scale-outer-mobile{border:1.5px solid #C4C0BA;border-radius:8px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.1)}
.scale-inner-mobile{width:375px;transform:scale(0.88);transform-origin:top left}
/* ── Annotation overlay ── */
.annotation{display:inline-block;background:#FEF3C7;color:#92400E;font-size:8px;font-weight:700;padding:2px 7px;border-radius:2px;border:1px dashed #F59E0B;margin:6px 4px 4px}
</style>
</head>
<body>
<div class="doc">
<!-- ══ MASTHEAD ══════════════════════════════════════════════════════════════ -->
<div class="mh">
<h1>Stammbaum — Tree Page · /stammbaum</h1>
<p>
Visual specification for the generational family tree view. Covers the SVG canvas with
Gen IIII 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.
</p>
<div class="byline">Familienarchiv · 2026-04-27 · Leonie Voss, UX Lead</div>
<div class="tag-row">
<span class="tag">Stammbaum Feature</span>
<span class="tag">View 1 of 3 — Tree Page</span>
<span class="tag">Desktop / Tablet / Mobile</span>
<span class="tag">Light + Dark</span>
</div>
</div>
<!-- ══ SECTION 1 — DESIGN TOKENS ════════════════════════════════════════════ -->
<div class="section">
<div class="sh">
<h2>1 · Design tokens</h2>
<p>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 <code>layout.css</code>.</p>
</div>
<div class="token-grid">
<!-- Light -->
<div class="token-table light">
<div class="token-head">Light theme</div>
<table>
<tr>
<td>Canvas bg</td>
<td><span class="swatch" style="background:#f0efe9;border:1px solid #ccc"></span>#f0efe9 — sand page background</td>
</tr>
<tr>
<td>Node bg default</td>
<td><span class="swatch" style="background:#ffffff;border:1px solid #ccc"></span>#ffffff — white</td>
</tr>
<tr>
<td>Node bg selected</td>
<td><span class="swatch" style="background:#012851"></span>#012851 — navy<span class="pass">AAA on white acc. bar</span></td>
</tr>
<tr>
<td>Node accent bar</td>
<td><span class="swatch" style="background:#a1dcd8;border:1px solid #ccc"></span>#a1dcd8 — mint, 4 px left strip on selected</td>
</tr>
<tr>
<td>Node border default</td>
<td><span class="swatch" style="background:#012851"></span>#012851 1.5 px</td>
</tr>
<tr>
<td>Connector / dot</td>
<td><span class="swatch" style="background:#012851"></span>#012851 stroke-width 1.5, r=4.5</td>
</tr>
<tr>
<td>Name text default</td>
<td><span class="swatch" style="background:#012851"></span>#012851<span class="pass">14.5:1 AAA ✓</span></td>
</tr>
<tr>
<td>Name text selected</td>
<td><span class="swatch" style="background:#ffffff;border:1px solid #ccc"></span>#ffffff on #012851<span class="pass">14.5:1 AAA ✓</span></td>
</tr>
<tr>
<td>Years text default</td>
<td><span class="swatch" style="background:#6b7280"></span>#6b7280<span class="pass">4.8:1 AA ✓</span></td>
</tr>
<tr>
<td>Years text selected</td>
<td><span class="swatch" style="background:rgba(255,255,255,.6);border:1px solid #ccc"></span>rgba(255,255,255,.6) — decorative, aria-hidden years</td>
</tr>
<tr>
<td>Gen label</td>
<td><span class="swatch" style="background:#6b7280"></span>#6b7280 — 8 px, tracking 2 px, aria-hidden</td>
</tr>
<tr>
<td>Panel surface</td>
<td><span class="swatch" style="background:#ffffff;border:1px solid #ccc"></span>#ffffff</td>
</tr>
<tr>
<td>Direct pill</td>
<td><span class="swatch" style="background:rgba(161,220,216,.2);border:1px solid #a1dcd8"></span>rgba(161,220,216,.2) bg · #a1dcd8 border · #012851 text</td>
</tr>
<tr>
<td>Derived pill</td>
<td><span class="swatch" style="background:#f5f4ef;border:1px solid #e4e2d7"></span>#f5f4ef bg · #e4e2d7 border · #4b5563 text</td>
</tr>
</table>
</div>
<!-- Dark -->
<div class="token-table dark">
<div class="token-head">Dark theme</div>
<table>
<tr>
<td>Canvas bg</td>
<td><span class="swatch" style="background:#010e1e;border:1px solid #1a2a3a"></span>#010e1e</td>
</tr>
<tr>
<td>Node bg default</td>
<td><span class="swatch" style="background:#011526;border:1px solid #1e3a55"></span>#011526</td>
</tr>
<tr>
<td>Node bg selected</td>
<td><span class="swatch" style="background:#a1dcd8;border:1px solid #ccc"></span>#a1dcd8 — mint inverted</td>
</tr>
<tr>
<td>Node accent bar</td>
<td><span class="swatch" style="background:#012851;border:1px solid #1e3a55"></span>#012851 — navy inverted</td>
</tr>
<tr>
<td>Node border default</td>
<td><span class="swatch" style="background:#1e3a55;border:1px solid #333"></span>#1e3a55 1.5 px</td>
</tr>
<tr>
<td>Connector / dot</td>
<td><span class="swatch" style="background:#3a6080;border:1px solid #555"></span>#3a6080 stroke-width 1.5</td>
</tr>
<tr>
<td>Name text default</td>
<td><span class="swatch" style="background:#f0efe9;border:1px solid #555"></span>#f0efe9<span class="pass" style="background:rgba(209,250,229,.15);color:#6EE7B7">14.5:1 AAA ✓</span></td>
</tr>
<tr>
<td>Name text selected</td>
<td><span class="swatch" style="background:#012851;border:1px solid #1e3a55"></span>#012851 on #a1dcd8<span class="pass" style="background:rgba(209,250,229,.15);color:#6EE7B7">9.2:1 AAA ✓</span></td>
</tr>
<tr>
<td>Years text default</td>
<td><span class="swatch" style="background:#8b97a5;border:1px solid #444"></span>#8b97a5<span class="pass" style="background:rgba(209,250,229,.15);color:#6EE7B7">7.1:1 AAA ✓</span></td>
</tr>
<tr>
<td>Gen label</td>
<td><span class="swatch" style="background:#4e6070;border:1px solid #333"></span>#4e6070 — aria-hidden</td>
</tr>
<tr>
<td>Panel surface</td>
<td><span class="swatch" style="background:#011526;border:1px solid #1e3a55"></span>#011526</td>
</tr>
<tr>
<td>Direct pill</td>
<td><span class="swatch" style="background:rgba(0,199,177,.12);border:1px solid #00c7b1"></span>rgba(0,199,177,.12) bg · #00c7b1 border · #f0efe9 text</td>
</tr>
<tr>
<td>Derived pill</td>
<td><span class="swatch" style="background:#011a30;border:1px solid #0d3358"></span>#011a30 bg · #0d3358 border · #9ca3af text</td>
</tr>
</table>
</div>
</div>
</div>
<!-- ══ SECTION 2 — DESKTOP LIGHT & DARK ════════════════════════════════════ -->
<div class="section">
<div class="sh">
<h2>2 · Desktop (1280 px) — light &amp; dark, resting state</h2>
<p>Full tree canvas with Gen IIII nodes and the 268 px side panel showing Maria Raddatz (selected). Rendered at ~65 % scale. Light and dark stacked.</p>
</div>
<div>
<!-- ── Light ── -->
<div>
<div class="screen-lbl"><span class="lbl-dot" style="background:#A1DCD8;border:1px solid #ccc"></span>Light theme</div>
<div class="scale-outer">
<div class="scale-inner" style="height:600px">
<!-- Chrome bar -->
<div style="height:20px;background:#E8E6E0;border-bottom:1px solid #C4C0BA;display:flex;align-items:center;padding:0 8px;gap:4px">
<div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-dot"></div>
<div class="chrome-url"></div>
</div>
<!-- App nav -->
<div class="app-nav">
<div class="app-logo">Familienarchiv</div>
<div class="app-link">Dokumente</div>
<div class="app-link">Personen</div>
<div class="app-link on">Stammbaum</div>
<div class="app-nav-r"><div class="app-av">M</div></div>
</div>
<!-- Page -->
<div class="stb-page" style="padding-bottom:0">
<div class="stb-page-head">
<div class="stb-page-title">Stammbaum</div>
<div class="stb-controls">
<div class="stb-btn outline" style="font-size:8px">Generationen ▾</div>
<div class="stb-zoom">
<div class="stb-zoom-btn"></div>
<div class="stb-zoom-btn">+</div>
</div>
</div>
</div>
<div class="stb-body">
<!-- Tree SVG -->
<div class="stb-tree-area">
<svg width="820" height="490" xmlns="http://www.w3.org/2000/svg" style="display:block">
<!-- Gen labels -->
<text x="30" y="89" font-size="8" letter-spacing="2" text-anchor="start" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" text-transform="uppercase" aria-hidden="true">GEN I</text>
<text x="30" y="269" font-size="8" letter-spacing="2" text-anchor="start" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN II</text>
<text x="30" y="449" font-size="8" letter-spacing="2" text-anchor="start" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN III</text>
<!-- Connectors -->
<line x1="362" y1="85" x2="398" y2="85" stroke="#012851" stroke-width="1.5"/>
<line x1="380" y1="110" x2="380" y2="175" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="175" x2="640" y2="175" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="175" x2="240" y2="240" stroke="#012851" stroke-width="1.5"/>
<line x1="640" y1="175" x2="640" y2="240" stroke="#012851" stroke-width="1.5"/>
<line x1="222" y1="265" x2="258" y2="265" stroke="#012851" stroke-width="1.5"/>
<line x1="622" y1="265" x2="658" y2="265" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="290" x2="240" y2="370" stroke="#012851" stroke-width="1.5"/>
<line x1="130" y1="370" x2="470" y2="370" stroke="#012851" stroke-width="1.5"/>
<line x1="130" y1="370" x2="130" y2="420" stroke="#012851" stroke-width="1.5"/>
<line x1="300" y1="370" x2="300" y2="420" stroke="#012851" stroke-width="1.5"/>
<line x1="470" y1="370" x2="470" y2="420" stroke="#012851" stroke-width="1.5"/>
<!-- Marriage dots -->
<circle cx="380" cy="85" r="4.5" fill="#012851"/>
<circle cx="240" cy="265" r="4.5" fill="#012851"/>
<circle cx="640" cy="265" r="4.5" fill="#012851"/>
<!-- GEN I — Heinrich (default) -->
<rect x="218" y="60" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="290" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Heinrich</text>
<text x="290" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="290" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18501920</text>
<!-- GEN I — Maria (SELECTED) -->
<rect x="398" y="60" width="144" height="50" rx="2" fill="#012851" stroke="#012851" stroke-width="1.5"/>
<rect x="398" y="60" width="4" height="50" rx="2" fill="#a1dcd8"/>
<text x="470" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#ffffff">Maria</text>
<text x="470" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#ffffff">Raddatz</text>
<text x="470" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="rgba(255,255,255,.6)">18551932</text>
<!-- GEN II — Karl (default) -->
<rect x="78" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="150" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Karl</text>
<text x="150" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="150" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18781944</text>
<!-- GEN II — Frieda (default) -->
<rect x="258" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="330" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Frieda</text>
<text x="330" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="330" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18821956</text>
<!-- GEN II — Ernst (default) -->
<rect x="478" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="550" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Ernst</text>
<text x="550" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="550" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18801961</text>
<!-- GEN II — Helga (default) -->
<rect x="658" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="730" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Helga</text>
<text x="730" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Müller</text>
<text x="730" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18851940</text>
<!-- GEN III — Hans (default) -->
<rect x="58" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="130" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Hans</text>
<text x="130" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="130" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19051972</text>
<!-- GEN III — Lotte (default) -->
<rect x="228" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="300" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Lotte</text>
<text x="300" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Berger</text>
<text x="300" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19081987</text>
<!-- GEN III — Werner (default) -->
<rect x="398" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="470" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Werner</text>
<text x="470" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="470" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19121966</text>
</svg>
</div>
<!-- Side panel — resting -->
<div class="stb-panel">
<div class="stb-panel-head">
<div class="stb-panel-toprow">
<div class="stb-panel-avatar">MR</div>
<div>
<div class="stb-panel-name">Maria Raddatz</div>
<div class="stb-panel-years">18551932</div>
</div>
</div>
<div class="stb-panel-divider"></div>
</div>
<div class="stb-panel-body">
<div class="stb-rel-section">
<div class="stb-rel-section-label">Direkte Beziehungen</div>
<div class="stb-rel-list">
<span class="stb-pill direct"><span class="stb-pill-role">Ehegatte</span><span class="stb-pill-name">Heinrich Raddatz</span></span>
<span class="stb-pill direct"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Karl Raddatz</span></span>
<span class="stb-pill direct"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Ernst Raddatz</span></span>
</div>
<span class="stb-add-btn">+ Beziehung hinzufügen</span>
</div>
<div class="stb-panel-divider"></div>
<div class="stb-rel-section">
<div class="stb-rel-section-label">Abgeleitete Beziehungen</div>
<div class="stb-rel-list">
<span class="stb-pill derived"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Hans Raddatz</span></span>
<span class="stb-pill derived"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Lotte Berger</span></span>
<span class="stb-pill derived"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Werner Raddatz</span></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="cap">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.</p>
</div>
<!-- ── Dark ── -->
<div>
<div class="screen-lbl"><span class="lbl-dot" style="background:#1a2a3a"></span>Dark theme</div>
<div class="scale-outer dark">
<div class="scale-inner" style="height:600px">
<div style="height:20px;background:#010a18;border-bottom:1px solid #0d3358;display:flex;align-items:center;padding:0 8px;gap:4px">
<div style="width:6px;height:6px;border-radius:50%;background:#1a2a3a"></div>
<div style="width:6px;height:6px;border-radius:50%;background:#1a2a3a"></div>
<div style="width:6px;height:6px;border-radius:50%;background:#1a2a3a"></div>
<div style="flex:1;height:9px;background:#1a2a3a;border-radius:5px;margin-left:6px"></div>
</div>
<div class="app-nav">
<div class="app-logo">Familienarchiv</div>
<div class="app-link">Dokumente</div>
<div class="app-link">Personen</div>
<div class="app-link on">Stammbaum</div>
<div class="app-nav-r"><div class="app-av">M</div></div>
</div>
<div class="stb-page dark-bg" style="padding-bottom:0">
<div class="stb-page-head">
<div class="stb-page-title">Stammbaum</div>
<div class="stb-controls">
<div class="stb-btn outline-dark" style="font-size:8px">Generationen ▾</div>
<div class="stb-zoom">
<div class="stb-zoom-btn"></div>
<div class="stb-zoom-btn">+</div>
</div>
</div>
</div>
<div class="stb-body">
<div class="stb-tree-area">
<svg width="820" height="490" xmlns="http://www.w3.org/2000/svg" style="display:block">
<text x="30" y="89" font-size="8" letter-spacing="2" fill="#4e6070" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN I</text>
<text x="30" y="269" font-size="8" letter-spacing="2" fill="#4e6070" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN II</text>
<text x="30" y="449" font-size="8" letter-spacing="2" fill="#4e6070" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN III</text>
<!-- Connectors dark -->
<line x1="362" y1="85" x2="398" y2="85" stroke="#3a6080" stroke-width="1.5"/>
<line x1="380" y1="110" x2="380" y2="175" stroke="#3a6080" stroke-width="1.5"/>
<line x1="240" y1="175" x2="640" y2="175" stroke="#3a6080" stroke-width="1.5"/>
<line x1="240" y1="175" x2="240" y2="240" stroke="#3a6080" stroke-width="1.5"/>
<line x1="640" y1="175" x2="640" y2="240" stroke="#3a6080" stroke-width="1.5"/>
<line x1="222" y1="265" x2="258" y2="265" stroke="#3a6080" stroke-width="1.5"/>
<line x1="622" y1="265" x2="658" y2="265" stroke="#3a6080" stroke-width="1.5"/>
<line x1="240" y1="290" x2="240" y2="370" stroke="#3a6080" stroke-width="1.5"/>
<line x1="130" y1="370" x2="470" y2="370" stroke="#3a6080" stroke-width="1.5"/>
<line x1="130" y1="370" x2="130" y2="420" stroke="#3a6080" stroke-width="1.5"/>
<line x1="300" y1="370" x2="300" y2="420" stroke="#3a6080" stroke-width="1.5"/>
<line x1="470" y1="370" x2="470" y2="420" stroke="#3a6080" stroke-width="1.5"/>
<circle cx="380" cy="85" r="4.5" fill="#3a6080"/>
<circle cx="240" cy="265" r="4.5" fill="#3a6080"/>
<circle cx="640" cy="265" r="4.5" fill="#3a6080"/>
<!-- GEN I Heinrich dark default -->
<rect x="218" y="60" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="290" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Heinrich</text>
<text x="290" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Raddatz</text>
<text x="290" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">18501920</text>
<!-- GEN I Maria dark SELECTED -->
<rect x="398" y="60" width="144" height="50" rx="2" fill="#a1dcd8" stroke="#a1dcd8" stroke-width="1.5"/>
<rect x="398" y="60" width="4" height="50" rx="2" fill="#012851"/>
<text x="470" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Maria</text>
<text x="470" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="470" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#012851">18551932</text>
<!-- GEN II dark defaults -->
<rect x="78" y="240" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="150" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Karl</text>
<text x="150" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Raddatz</text>
<text x="150" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">18781944</text>
<rect x="258" y="240" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="330" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Frieda</text>
<text x="330" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Raddatz</text>
<text x="330" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">18821956</text>
<rect x="478" y="240" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="550" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Ernst</text>
<text x="550" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Raddatz</text>
<text x="550" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">18801961</text>
<rect x="658" y="240" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="730" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Helga</text>
<text x="730" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Müller</text>
<text x="730" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">18851940</text>
<!-- GEN III dark defaults -->
<rect x="58" y="420" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="130" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Hans</text>
<text x="130" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Raddatz</text>
<text x="130" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">19051972</text>
<rect x="228" y="420" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="300" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Lotte</text>
<text x="300" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Berger</text>
<text x="300" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">19081987</text>
<rect x="398" y="420" width="144" height="50" rx="2" fill="#011526" stroke="#1e3a55" stroke-width="1.5"/>
<text x="470" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Werner</text>
<text x="470" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#f0efe9">Raddatz</text>
<text x="470" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#8b97a5">19121966</text>
</svg>
</div>
<!-- Side panel dark resting -->
<div class="stb-panel">
<div class="stb-panel-head">
<div class="stb-panel-toprow">
<div class="stb-panel-avatar">MR</div>
<div>
<div class="stb-panel-name">Maria Raddatz</div>
<div class="stb-panel-years">18551932</div>
</div>
</div>
<div class="stb-panel-divider"></div>
</div>
<div class="stb-panel-body">
<div class="stb-rel-section">
<div class="stb-rel-section-label">Direkte Beziehungen</div>
<div class="stb-rel-list">
<span class="stb-pill direct-dark"><span class="stb-pill-role">Ehegatte</span><span class="stb-pill-name">Heinrich Raddatz</span></span>
<span class="stb-pill direct-dark"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Karl Raddatz</span></span>
<span class="stb-pill direct-dark"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Ernst Raddatz</span></span>
</div>
<span class="stb-add-btn">+ Beziehung hinzufügen</span>
</div>
<div class="stb-panel-divider"></div>
<div class="stb-rel-section">
<div class="stb-rel-section-label">Abgeleitete Beziehungen</div>
<div class="stb-rel-list">
<span class="stb-pill derived-dark"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Hans Raddatz</span></span>
<span class="stb-pill derived-dark"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Lotte Berger</span></span>
<span class="stb-pill derived-dark"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Werner Raddatz</span></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="cap">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.</p>
</div>
</div>
</div>
<!-- ══ SECTION 3 — SIDE PANEL STATES ════════════════════════════════════════ -->
<div class="section">
<div class="sh">
<h2>3 · Side panel states — light</h2>
<p>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.</p>
</div>
<div class="split-screens">
<!-- Resting -->
<div>
<div class="screen-lbl"><span class="lbl-dot" style="background:#A1DCD8;border:1px solid #ccc"></span>Resting — quiet add button</div>
<div class="chrome">
<div class="chrome-bar"><div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-url"></div></div>
<div style="background:#f0efe9;padding:16px">
<div style="background:#fff;border:1.5px solid #e4e2d7;border-radius:4px;width:268px;overflow:hidden">
<div style="padding:14px 14px 0">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:6px">
<div style="width:36px;height:36px;border-radius:50%;background:#012851;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;color:#a1dcd8;flex-shrink:0">MR</div>
<div>
<div style="font-family:'Tinos',Georgia,serif;font-size:14px;font-weight:700;color:#012851">Maria Raddatz</div>
<div style="font-size:9px;color:#6b7280;margin-top:2px">18551932</div>
</div>
</div>
<div style="height:1px;background:#e4e2d7;margin:10px 0 12px"></div>
</div>
<div style="padding:0 14px 16px">
<div style="font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:#6b7280;margin-bottom:7px">Direkte Beziehungen</div>
<div style="display:flex;flex-direction:column;gap:5px">
<span class="stb-pill direct"><span class="stb-pill-role">Ehegatte</span><span class="stb-pill-name">Heinrich Raddatz</span></span>
<span class="stb-pill direct"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Karl Raddatz</span></span>
<span class="stb-pill direct"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Ernst Raddatz</span></span>
</div>
<!-- Resting add button -->
<span style="margin-top:8px;font-size:9px;font-weight:700;color:#012851;opacity:.4;cursor:default;display:inline-block">+ Beziehung hinzufügen</span>
<div style="height:1px;background:#e4e2d7;margin:12px 0"></div>
<div style="font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:#6b7280;margin-bottom:7px">Abgeleitete Beziehungen</div>
<div style="display:flex;flex-direction:column;gap:5px">
<span class="stb-pill derived"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Hans Raddatz</span></span>
<span class="stb-pill derived"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Lotte Berger</span></span>
<span class="stb-pill derived"><span class="stb-pill-role">Großelternteil</span><span class="stb-pill-name">Werner Raddatz</span></span>
</div>
</div>
</div>
</div>
</div>
<p class="cap">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).</p>
</div>
<!-- Expanded add form -->
<div>
<div class="screen-lbl"><span class="lbl-dot" style="background:#012851"></span>Add-form expanded</div>
<div class="chrome">
<div class="chrome-bar"><div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-url"></div></div>
<div style="background:#f0efe9;padding:16px">
<div style="background:#fff;border:1.5px solid #e4e2d7;border-radius:4px;width:268px;overflow:hidden">
<div style="padding:14px 14px 0">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:6px">
<div style="width:36px;height:36px;border-radius:50%;background:#012851;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;color:#a1dcd8;flex-shrink:0">MR</div>
<div>
<div style="font-family:'Tinos',Georgia,serif;font-size:14px;font-weight:700;color:#012851">Maria Raddatz</div>
<div style="font-size:9px;color:#6b7280;margin-top:2px">18551932</div>
</div>
</div>
<div style="height:1px;background:#e4e2d7;margin:10px 0 12px"></div>
</div>
<div style="padding:0 14px 16px">
<div style="font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:#6b7280;margin-bottom:7px">Direkte Beziehungen</div>
<div style="display:flex;flex-direction:column;gap:5px">
<span class="stb-pill direct"><span class="stb-pill-role">Ehegatte</span><span class="stb-pill-name">Heinrich Raddatz</span></span>
<span class="stb-pill direct"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Karl Raddatz</span></span>
<span class="stb-pill direct"><span class="stb-pill-role">Elternteil</span><span class="stb-pill-name">Ernst Raddatz</span></span>
</div>
<!-- Add form expanded -->
<div style="margin-top:10px;display:flex;flex-direction:column;gap:7px">
<select style="width:100%;height:26px;border:1.5px solid #e4e2d7;border-radius:3px;font-size:9px;font-family:'Montserrat',sans-serif;color:#012851;padding:0 8px;background:#fff;appearance:none">
<option>Elternteil von</option>
</select>
<input type="text" placeholder="Person suchen…" style="width:100%;height:26px;border:1.5px solid #012851;border-radius:3px;font-size:9px;font-family:'Montserrat',sans-serif;color:#012851;padding:0 8px;background:#fff;outline:none" value="">
<div style="display:flex;gap:6px">
<input type="text" placeholder="Von Jahr" style="flex:1;height:26px;border:1.5px solid #e4e2d7;border-radius:3px;font-size:9px;font-family:'Montserrat',sans-serif;color:#6b7280;padding:0 8px;background:#fff;outline:none">
<input type="text" placeholder="Bis Jahr" style="flex:1;height:26px;border:1.5px solid #e4e2d7;border-radius:3px;font-size:9px;font-family:'Montserrat',sans-serif;color:#6b7280;padding:0 8px;background:#fff;outline:none">
</div>
<div style="display:flex;gap:6px;justify-content:flex-end">
<div style="height:24px;padding:0 10px;border:1.5px solid #e4e2d7;border-radius:3px;font-size:8px;font-weight:700;color:#4b5563;background:#fff;display:flex;align-items:center;cursor:default">Abbrechen</div>
<div style="height:24px;padding:0 10px;border-radius:3px;font-size:8px;font-weight:700;color:#a1dcd8;background:#012851;display:flex;align-items:center;cursor:default">Speichern</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="cap">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.</p>
</div>
</div>
</div>
<!-- ══ SECTION 4 — TABLET 768px ═════════════════════════════════════════════ -->
<div class="section">
<div class="sh">
<h2>4 · Tablet (768 px) — light</h2>
<p>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.</p>
</div>
<div style="margin-bottom:16px">
<div class="screen-lbl"><span class="lbl-dot" style="background:#A1DCD8;border:1px solid #ccc"></span>768 px · no persistent side panel</div>
<div class="scale-outer-tablet" style="width:576px;height:458px"><!-- visible = 768*0.75, 610*0.75 -->
<div class="scale-inner-tablet" style="height:610px">
<!-- Chrome bar -->
<div style="height:20px;background:#E8E6E0;border-bottom:1px solid #C4C0BA;display:flex;align-items:center;padding:0 8px;gap:4px">
<div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-dot"></div>
<div class="chrome-url"></div>
</div>
<!-- App nav -->
<div class="app-nav">
<div class="app-logo">Familienarchiv</div>
<div class="app-link">Dokumente</div>
<div class="app-link">Personen</div>
<div class="app-link on">Stammbaum</div>
<div class="app-nav-r"><div class="app-av">M</div></div>
</div>
<!-- Page -->
<div class="stb-page" style="padding-bottom:0">
<div class="stb-page-head">
<div class="stb-page-title">Stammbaum</div>
<div class="stb-controls">
<div class="stb-btn outline" style="font-size:8px">Generationen ▾</div>
<div class="stb-zoom">
<div class="stb-zoom-btn"></div>
<div class="stb-zoom-btn">+</div>
</div>
</div>
</div>
<!-- Tree only, full width, no side panel -->
<div style="padding:20px 16px 32px">
<div style="background:#fff;border:1.5px solid #e4e2d7;border-radius:4px;overflow:hidden">
<svg width="736" height="490" xmlns="http://www.w3.org/2000/svg" style="display:block">
<text x="30" y="89" font-size="8" letter-spacing="2" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN I</text>
<text x="30" y="269" font-size="8" letter-spacing="2" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN II</text>
<text x="30" y="449" font-size="8" letter-spacing="2" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN III</text>
<line x1="362" y1="85" x2="398" y2="85" stroke="#012851" stroke-width="1.5"/>
<line x1="380" y1="110" x2="380" y2="175" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="175" x2="640" y2="175" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="175" x2="240" y2="240" stroke="#012851" stroke-width="1.5"/>
<line x1="640" y1="175" x2="640" y2="240" stroke="#012851" stroke-width="1.5"/>
<line x1="222" y1="265" x2="258" y2="265" stroke="#012851" stroke-width="1.5"/>
<line x1="622" y1="265" x2="658" y2="265" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="290" x2="240" y2="370" stroke="#012851" stroke-width="1.5"/>
<line x1="130" y1="370" x2="470" y2="370" stroke="#012851" stroke-width="1.5"/>
<line x1="130" y1="370" x2="130" y2="420" stroke="#012851" stroke-width="1.5"/>
<line x1="300" y1="370" x2="300" y2="420" stroke="#012851" stroke-width="1.5"/>
<line x1="470" y1="370" x2="470" y2="420" stroke="#012851" stroke-width="1.5"/>
<circle cx="380" cy="85" r="4.5" fill="#012851"/>
<circle cx="240" cy="265" r="4.5" fill="#012851"/>
<circle cx="640" cy="265" r="4.5" fill="#012851"/>
<rect x="218" y="60" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="290" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Heinrich</text>
<text x="290" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="290" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18501920</text>
<rect x="398" y="60" width="144" height="50" rx="2" fill="#012851" stroke="#012851" stroke-width="1.5"/>
<rect x="398" y="60" width="4" height="50" rx="2" fill="#a1dcd8"/>
<text x="470" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#ffffff">Maria</text>
<text x="470" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#ffffff">Raddatz</text>
<text x="470" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="rgba(255,255,255,.6)">18551932</text>
<rect x="78" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="150" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Karl</text>
<text x="150" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="150" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18781944</text>
<rect x="258" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="330" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Frieda</text>
<text x="330" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="330" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18821956</text>
<rect x="478" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="550" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Ernst</text>
<text x="550" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="550" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18801961</text>
<rect x="658" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="730" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Helga</text>
<text x="730" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Müller</text>
<text x="730" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18851940</text>
<rect x="58" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="130" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Hans</text>
<text x="130" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="130" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19051972</text>
<rect x="228" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="300" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Lotte</text>
<text x="300" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Berger</text>
<text x="300" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19081987</text>
<rect x="398" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="470" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Werner</text>
<text x="470" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="470" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19121966</text>
</svg>
</div>
<div class="annotation">Side panel appears as bottom sheet on node tap</div>
</div>
</div>
</div>
</div>
</div>
<p class="cap">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.</p>
</div>
<!-- ══ SECTION 5 — MOBILE 375px ══════════════════════════════════════════════ -->
<div class="section">
<div class="sh">
<h2>5 · Mobile (375 px) — light</h2>
<p>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.</p>
</div>
<div style="margin-bottom:16px">
<div class="screen-lbl"><span class="lbl-dot" style="background:#A1DCD8;border:1px solid #ccc"></span>375 px · horizontal scroll tree</div>
<div class="scale-outer-mobile" style="width:330px;height:563px"><!-- visible = 375*0.88, 640*0.88 -->
<div class="scale-inner-mobile" style="height:640px">
<!-- Chrome bar -->
<div style="height:20px;background:#E8E6E0;border-bottom:1px solid #C4C0BA;display:flex;align-items:center;padding:0 8px;gap:4px">
<div class="chrome-dot"></div><div class="chrome-dot"></div><div class="chrome-dot"></div>
<div class="chrome-url"></div>
</div>
<!-- Abbreviated app nav -->
<div style="height:30px;background:#012851;display:flex;align-items:center;padding:0 12px">
<div class="app-logo">Familienarchiv</div>
<div style="margin-left:auto"><div class="app-av">M</div></div>
</div>
<!-- Page -->
<div style="background:#f0efe9;padding:12px 12px 0">
<!-- Mobile page title -->
<h1 style="font-family:'Tinos',Georgia,serif;font-size:20px;font-weight:700;color:#012851;margin-bottom:12px">Stammbaum</h1>
<!-- Mode toggle full width -->
<div style="display:flex;border:1.5px solid #012851;border-radius:3px;overflow:hidden;margin-bottom:12px">
<div style="flex:1;height:30px;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:#a1dcd8;background:#012851">Baum</div>
<div style="flex:1;height:30px;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;color:#012851;background:#fff">Liste</div>
</div>
<!-- Tree card with overflow-x:scroll -->
<div style="background:#fff;border:1.5px solid #e4e2d7;border-radius:4px;overflow-x:scroll">
<svg width="820" height="490" xmlns="http://www.w3.org/2000/svg" style="display:block;min-width:820px">
<text x="30" y="89" font-size="8" letter-spacing="2" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN I</text>
<text x="30" y="269" font-size="8" letter-spacing="2" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN II</text>
<text x="30" y="449" font-size="8" letter-spacing="2" fill="#6b7280" font-family="Montserrat,sans-serif" font-weight="800" aria-hidden="true">GEN III</text>
<line x1="362" y1="85" x2="398" y2="85" stroke="#012851" stroke-width="1.5"/>
<line x1="380" y1="110" x2="380" y2="175" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="175" x2="640" y2="175" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="175" x2="240" y2="240" stroke="#012851" stroke-width="1.5"/>
<line x1="640" y1="175" x2="640" y2="240" stroke="#012851" stroke-width="1.5"/>
<line x1="222" y1="265" x2="258" y2="265" stroke="#012851" stroke-width="1.5"/>
<line x1="622" y1="265" x2="658" y2="265" stroke="#012851" stroke-width="1.5"/>
<line x1="240" y1="290" x2="240" y2="370" stroke="#012851" stroke-width="1.5"/>
<line x1="130" y1="370" x2="470" y2="370" stroke="#012851" stroke-width="1.5"/>
<line x1="130" y1="370" x2="130" y2="420" stroke="#012851" stroke-width="1.5"/>
<line x1="300" y1="370" x2="300" y2="420" stroke="#012851" stroke-width="1.5"/>
<line x1="470" y1="370" x2="470" y2="420" stroke="#012851" stroke-width="1.5"/>
<circle cx="380" cy="85" r="4.5" fill="#012851"/>
<circle cx="240" cy="265" r="4.5" fill="#012851"/>
<circle cx="640" cy="265" r="4.5" fill="#012851"/>
<rect x="218" y="60" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="290" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Heinrich</text>
<text x="290" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="290" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18501920</text>
<rect x="398" y="60" width="144" height="50" rx="2" fill="#012851" stroke="#012851" stroke-width="1.5"/>
<rect x="398" y="60" width="4" height="50" rx="2" fill="#a1dcd8"/>
<text x="470" y="80" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#ffffff">Maria</text>
<text x="470" y="92" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#ffffff">Raddatz</text>
<text x="470" y="104" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="rgba(255,255,255,.6)">18551932</text>
<rect x="78" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="150" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Karl</text>
<text x="150" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="150" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18781944</text>
<rect x="258" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="330" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Frieda</text>
<text x="330" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="330" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18821956</text>
<rect x="478" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="550" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Ernst</text>
<text x="550" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="550" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18801961</text>
<rect x="658" y="240" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="730" y="260" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Helga</text>
<text x="730" y="272" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Müller</text>
<text x="730" y="284" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">18851940</text>
<rect x="58" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="130" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Hans</text>
<text x="130" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="130" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19051972</text>
<rect x="228" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="300" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Lotte</text>
<text x="300" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Berger</text>
<text x="300" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19081987</text>
<rect x="398" y="420" width="144" height="50" rx="2" fill="#ffffff" stroke="#012851" stroke-width="1.5"/>
<text x="470" y="440" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Werner</text>
<text x="470" y="452" text-anchor="middle" font-family="Tinos,Georgia,serif" font-size="10" font-weight="700" fill="#012851">Raddatz</text>
<text x="470" y="464" text-anchor="middle" font-family="Montserrat,sans-serif" font-size="8" fill="#6b7280">19121966</text>
</svg>
</div>
</div>
</div>
</div>
</div>
<p class="cap">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 <code>overflow-x: scroll</code>; the SVG renders at full 820 px width and the user pans. Zoom controls removed.</p>
</div>
<!-- ══ SECTION 6 — IMPLEMENTATION REFERENCE ══════════════════════════════════ -->
<div class="section">
<div class="sh">
<h2>6 · Implementation reference</h2>
</div>
<div class="rules">
<table>
<thead>
<tr>
<th>Element</th>
<th>Tailwind / CSS</th>
<th>px value</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tree node</td>
<td><code>w-[144px] h-[50px] rounded-sm</code></td>
<td>144 × 50</td>
<td>SVG <code>rect rx="2"</code>; same size all generations</td>
</tr>
<tr>
<td>Selected accent bar</td>
<td><code>w-1 h-full bg-accent</code></td>
<td>4 × 50</td>
<td>Mint on light; navy on dark; left edge of selected node</td>
</tr>
<tr>
<td>Side panel</td>
<td><code>w-[268px] shrink-0</code></td>
<td>268</td>
<td>Hidden at ≤ 768 px; becomes bottom sheet on node tap</td>
</tr>
<tr>
<td>Tree + panel gap</td>
<td><code>gap-[18px]</code></td>
<td>18</td>
<td>Flex row gap between tree card and side panel</td>
</tr>
<tr>
<td>Page padding</td>
<td><code>px-8 py-6</code></td>
<td>32 / 24</td>
<td>Reduced to <code>px-3 py-3</code> on mobile</td>
</tr>
<tr>
<td>Direct pill</td>
<td><code>rounded-full px-2 py-0.5 text-[9px]</code></td>
<td></td>
<td>Mint border rgba(161,220,216,.2) bg; #a1dcd8 border light</td>
</tr>
<tr>
<td>Derived pill</td>
<td><code>rounded-full px-2 py-0.5 text-[9px]</code></td>
<td></td>
<td>#f5f4ef bg; #e4e2d7 border light; read-only, no add button</td>
</tr>
<tr>
<td>Connector stroke</td>
<td>SVG <code>stroke-width="1.5"</code></td>
<td>1.5 px</td>
<td>#012851 light · #3a6080 dark</td>
</tr>
<tr>
<td>Marriage dot</td>
<td>SVG <code>r="4.5"</code></td>
<td>9 px dia</td>
<td>Filled circle at connector midpoints; same color as connectors</td>
</tr>
<tr>
<td>Gen label</td>
<td><code>text-[8px] tracking-[2px] uppercase</code></td>
<td>8 px</td>
<td><code>aria-hidden="true"</code>; #6b7280 light · #4e6070 dark</td>
</tr>
<tr>
<td>Node name text</td>
<td><code>font-serif text-[10px] font-bold</code></td>
<td>10 px</td>
<td>Two lines: given name y+20, surname y+32; text-anchor middle at cx</td>
</tr>
<tr>
<td>Node years text</td>
<td><code>font-sans text-[8px]</code></td>
<td>8 px</td>
<td>y+44 from node top; subdued color; not aria-hidden (content)</td>
</tr>
<tr>
<td>Zoom controls</td>
<td><code>flex border rounded-sm overflow-hidden</code></td>
<td>26 × 26 each</td>
<td>Hidden on mobile (≤ 640 px)</td>
</tr>
<tr>
<td>Mode toggle (mobile)</td>
<td><code>flex w-full border rounded-sm overflow-hidden</code></td>
<td>full width</td>
<td>Two segments: Baum (active) / Liste; full width on mobile only</td>
</tr>
<tr>
<td>Tree card scroll</td>
<td><code>overflow-x-auto</code></td>
<td></td>
<td>Applied to tree card wrapper on mobile; SVG renders at full 820 px</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><!-- /doc -->
</body>
</html>