Files
familienarchiv/docs/specs/briefwechsel-fill/index.html
Marcel f5438c4c36 docs(specs): add briefwechsel-fill — 5 concepts exploring empty-row problem
Brainstorming artifact: 5 HTML mockups comparing approaches to fill the
sparse right-hand space on /briefwechsel rows (reported by users as
"feels empty"):

  1. Rich Rows — dense metadata, no images
  2. Thumbnail Rows — PDF preview on the left
  3. Master-Detail Split — list + persistent preview panel
  4. Gallery Cards — grid of letter cards, album style
  5. Person Dashboard — insights live on /persons/[id], not here

Picked: #2 (Thumbnail Rows) + #5 (Person Dashboard), followed up by
final specs in separate commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 20:16:20 +02:00

291 lines
20 KiB
HTML
Raw 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="de">
<head>
<meta charset="UTF-8">
<title>Briefwechsel — Fill the Empty Rows · Overview</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&family=Montserrat:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="_shared.css">
<style>
.ov{max-width:1440px;margin:0 auto;padding:36px 32px 80px}
.lead{display:grid;grid-template-columns:1fr 320px;gap:40px;margin-bottom:36px;align-items:start}
@media (max-width: 900px){ .lead{grid-template-columns:1fr} }
.lead h2{font-family:'Merriweather',serif;font-size:24px;font-weight:700;color:var(--brand-navy);margin-bottom:10px;line-height:1.3}
.lead p{color:#444;font-size:14px;line-height:1.65}
.lead .kit{background:#fff;border:1px solid var(--line);border-radius:2px;padding:16px 18px}
.lead .kit h3{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:1.2px;color:#888;margin-bottom:10px}
.lead .kit li{font-size:12px;padding:5px 0;border-top:1px dashed var(--line);display:flex;justify-content:space-between}
.lead .kit li:first-child{border-top:0}
.lead .kit li b{color:var(--brand-navy);font-weight:700}
.section-h{font-family:'Merriweather',serif;font-size:16px;font-weight:700;color:var(--brand-navy);margin:28px 0 12px;padding-top:20px;border-top:1px dashed var(--line)}
.section-h .sub{font-family:'Montserrat',sans-serif;font-size:12px;color:#888;font-weight:400;margin-left:10px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
@media (max-width: 1200px){ .grid4{grid-template-columns:repeat(2,1fr)} }
.grid1{display:grid;grid-template-columns:1fr;gap:16px}
.spec-card{background:#fff;border:1px solid var(--line);border-radius:2px;overflow:hidden;text-decoration:none;color:inherit;display:flex;flex-direction:column;transition:transform .12s,box-shadow .12s}
.spec-card:hover{transform:translateY(-3px);box-shadow:0 8px 26px rgba(0,0,0,.1)}
.spec-card.wide{flex-direction:row}
.spec-card.wide .mini{width:45%;aspect-ratio:auto;min-height:280px;border-right:1px solid var(--line);border-bottom:0}
.spec-card.wide .sc-body{flex:1}
.spec-card .sc-num{background:var(--brand-navy);color:#fff;padding:3px 8px;font-size:10px;font-weight:800;letter-spacing:.8px;display:inline-block;border-radius:0 0 3px 0;width:max-content}
.spec-card .sc-body{padding:14px 16px;flex:1;display:flex;flex-direction:column;gap:8px}
.spec-card h3{font-family:'Merriweather',serif;font-size:16px;font-weight:700;color:var(--brand-navy);line-height:1.35}
.spec-card p{font-size:12px;color:#555;line-height:1.55}
.spec-card .tags{display:flex;gap:4px;flex-wrap:wrap;margin-top:auto;padding-top:8px}
.spec-card .tag{font-size:9.5px;letter-spacing:.3px}
/* Mini previews */
.mini{aspect-ratio:16/10;border-bottom:1px solid var(--line);background:#fafaf5;display:flex;padding:8px;gap:4px}
.mini.col{flex-direction:column}
.mini .minirow{background:#fff;border:1px solid var(--line-2);border-left:2px solid var(--primary);padding:4px 6px;display:flex;flex-direction:column;gap:2px;flex:1;font-size:7px;color:#888}
.mini .minirow b{color:var(--brand-navy);font-size:8px;font-weight:700}
.mini .minirow.in{border-left-color:var(--accent)}
.mini-1{display:flex;flex-direction:column;gap:3px;padding:8px}
.mini-1 .r{background:#fff;border:1px solid var(--line-2);border-left:2px solid var(--primary);padding:4px 6px;display:grid;grid-template-columns:1fr 48px;gap:4px;flex:1;font-size:7px;color:#888;align-items:center}
.mini-1 .r b{color:var(--brand-navy);font-size:8px;font-weight:700;font-family:'Merriweather',serif}
.mini-1 .r .ar{font-size:6.5px;color:#888;background:#F4F1EA;padding:2px 4px;text-align:center}
.mini-1 .r .tg{display:flex;gap:2px;margin-top:1px}
.mini-1 .r .tg span{background:var(--brand-mint);padding:0 3px;font-size:6px;border-radius:3px;color:var(--brand-navy)}
.mini-2{display:flex;flex-direction:column;gap:3px;padding:8px}
.mini-2 .r2{background:#fff;border:1px solid var(--line-2);border-left:2px solid var(--primary);padding:4px;display:flex;gap:4px;align-items:center;flex:1}
.mini-2 .th2{width:22px;height:28px;background:linear-gradient(#fdfcf7,#f1eadb);border:1px solid #d9d4c6;flex-shrink:0;position:relative}
.mini-2 .th2::before{content:'';position:absolute;inset:2px 3px;border-top:1px solid rgba(0,40,80,.25);border-bottom:1px solid rgba(0,40,80,.25);opacity:.6}
.mini-2 .content{flex:1;display:flex;flex-direction:column;gap:2px;font-size:7px;color:#888}
.mini-2 .content b{color:var(--brand-navy);font-size:8px;font-family:'Merriweather',serif}
.mini-2 .content i{color:#555;font-style:italic}
.mini-2 .content .dt{font-size:7px;color:#888;align-self:flex-end;font-family:'Merriweather',serif}
.mini-3{display:grid;grid-template-columns:1fr 1.1fr;gap:4px;padding:8px}
.mini-3 .left-list{display:flex;flex-direction:column;gap:2px}
.mini-3 .left-list .r{background:#fff;border:1px solid var(--line-2);border-left:2px solid var(--primary);padding:2px 4px;font-size:6.5px;color:#888}
.mini-3 .left-list .r.sel{background:#e7f4f3;border-left-color:var(--accent)}
.mini-3 .left-list .r b{color:var(--brand-navy);font-size:7px}
.mini-3 .preview-mini{background:#fff;border:1px solid var(--line-2);padding:5px;display:flex;gap:4px}
.mini-3 .pv-th{width:28px;height:38px;background:linear-gradient(#fdfcf7,#f1eadb);border:1px solid #d9d4c6;flex-shrink:0}
.mini-3 .pv-meta{font-size:6px;color:#888;line-height:1.4}
.mini-3 .pv-meta b{color:var(--brand-navy);font-size:7px;display:block;font-family:'Merriweather',serif}
.mini-4{display:grid;grid-template-columns:repeat(3,1fr);gap:3px;padding:8px}
.mini-4 .card-s{background:#fff;border:1px solid var(--line-2);overflow:hidden;display:flex;flex-direction:column}
.mini-4 .card-s .th{aspect-ratio:3/4;background:linear-gradient(#fdfcf7,#f1eadb);border-bottom:1px solid var(--line-2)}
.mini-4 .card-s .t{font-size:5.5px;color:var(--brand-navy);font-weight:700;padding:3px 4px;font-family:'Merriweather',serif}
.mini-5{display:grid;grid-template-columns:32% 1fr;gap:6px;padding:10px;align-items:start;min-height:260px}
.mini-5 .person-left{background:#fff;border:1px solid var(--line-2);padding:8px;display:flex;flex-direction:column;align-items:center;gap:4px}
.mini-5 .person-left .av{width:28px;height:28px;border-radius:50%;background:var(--brand-mint);color:var(--brand-navy);display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:800;font-family:'Merriweather',serif}
.mini-5 .person-left .nm{font-family:'Merriweather',serif;font-size:7.5px;font-weight:700;color:var(--brand-navy);text-align:center}
.mini-5 .person-left .dt{font-size:6px;color:#888}
.mini-5 .dash-mini{background:#fff;border:1px solid var(--line-2);display:flex;flex-direction:column}
.mini-5 .dh{background:var(--brand-navy);color:#fff;font-family:'Merriweather',serif;font-size:6.5px;padding:4px 6px;display:flex;justify-content:space-between;align-items:center}
.mini-5 .dh span{background:var(--brand-mint);color:var(--brand-navy);font-size:5.5px;padding:1px 4px;border-radius:2px;font-weight:800}
.mini-5 .stats-m{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-2);border-bottom:1px solid var(--line-2)}
.mini-5 .stats-m div{background:#fafaf5;padding:3px;text-align:center}
.mini-5 .stats-m .v{font-family:'Merriweather',serif;font-size:8px;font-weight:900;color:var(--brand-navy)}
.mini-5 .stats-m .k{font-size:5px;color:#888;font-weight:700}
.mini-5 .hist-m{display:flex;align-items:flex-end;gap:1px;height:22px;padding:4px 5px 0}
.mini-5 .hist-m i{flex:1;background:var(--brand-mint);opacity:.6}
.mini-5 .hist-m i.p{background:var(--brand-navy);opacity:.9}
.mini-5 .bars-m{display:flex;flex-direction:column;gap:1.5px;padding:4px 5px}
.mini-5 .bars-m span{display:flex;align-items:center;gap:2px;font-size:5.5px;color:#555}
.mini-5 .bars-m span .bar{flex:1;height:2px;background:var(--brand-navy);border-radius:1px}
.mini-5 .cloud-m{padding:4px 5px;display:flex;flex-wrap:wrap;gap:2px}
.mini-5 .cloud-m span{background:var(--brand-mint);padding:0 3px;border-radius:3px;font-size:5.5px;color:var(--brand-navy);font-weight:700}
/* Comparison table */
.cmp{background:#fff;border:1px solid var(--line);border-radius:2px;overflow:hidden;margin-top:36px}
.cmp table{width:100%;border-collapse:collapse}
.cmp th,.cmp td{padding:10px 14px;text-align:left;font-size:12px;border-bottom:1px solid var(--line-2);vertical-align:top}
.cmp th{background:#fafaf5;font-size:10px;text-transform:uppercase;letter-spacing:.8px;color:#888;font-weight:800}
.cmp td:first-child{font-weight:700;color:var(--brand-navy);font-family:'Merriweather',serif}
.cmp .yes{color:#166534}
.cmp .no{color:#B91C1C}
.cmp .mid{color:#92400E}
</style>
</head>
<body>
<div class="spec-meta">
<div class="spec-meta-inner">
<div>
<h1>Briefwechsel — <span>Fill the Empty Rows</span></h1>
<p>Five approaches. The first four change the <b>/briefwechsel</b> row itself; the fifth puts insights where they belong — on the person detail page.</p>
</div>
<div class="spec-meta-right">
<div><strong>Page</strong>/briefwechsel &nbsp;·&nbsp; /persons/[id]</div>
<div><strong>Brief</strong>Rows feel sparse — ~60% of row width is empty</div>
</div>
</div>
</div>
<nav class="spec-nav">
<div class="spec-nav-inner">
<span class="lbl">Specs</span>
<a class="on" href="index.html">Overview</a>
<a href="01-rich-rows.html">1 · Rich Rows</a>
<a href="02-thumbnail-rows.html">2 · Thumbnail Rows</a>
<a href="03-master-detail.html">3 · Master-Detail Split</a>
<a href="04-gallery-cards.html">4 · Gallery Cards</a>
<a href="05-person-dashboard.html">5 · Person Dashboard</a>
</div>
</nav>
<div class="ov">
<div class="lead">
<div>
<h2>The situation</h2>
<p>On <code>/briefwechsel?senderId=…</code> (e.g. 851 letters for Walter de Gruyter), each row shows only title, date, location and counterpart — leaving the right half empty. The question is: what belongs there?</p>
<p style="margin-top:10px">The five specs answer differently. Specs 14 rework the row itself. <b>Spec 5</b> argues the archive-level view (top correspondents, activity, tag cloud) belongs on <code>/persons/[id]</code>, not here — and mocks the dashboard that lives there instead.</p>
</div>
<div class="kit">
<h3>Data we can use today</h3>
<ul style="list-style:none">
<li>Title / Filename <b></b></li>
<li>Document date <b></b></li>
<li>Location <b></b></li>
<li>Sender / receivers <b></b></li>
<li>Summary text <b></b></li>
<li>Tags <b></b></li>
<li>Archive box &amp; folder <b></b></li>
<li>PDF thumbnail <b>open issue</b></li>
</ul>
<p style="font-size:11px;color:#888;margin-top:10px;font-style:italic">Removed from earlier drafts: status lifecycle (will be dropped from the product) and script type (only set after OCR, unreliable).</p>
</div>
</div>
<div class="section-h">Concepts that rework /briefwechsel <span class="sub">Specs 14</span></div>
<div class="grid4">
<a class="spec-card" href="01-rich-rows.html">
<span class="sc-num">01</span>
<div class="mini mini-1">
<div class="r"><span><b>Demo leserlicher Brief</b><br>31. Mai 1940 · Belgard<br>„letzte Lebenstage…"<div class="tg"><span>Dörpfeld</span></div></span><div class="ar">VII · 5</div></div>
<div class="r"><span><b>W-0397 2. Sep 1923</b><br>B.Lichterfelde · H. Cram<br>„von Elsbeth…"<div class="tg"><span>Verlag</span></div></span><div class="ar">VI · 7</div></div>
<div class="r"><span><b>W-0521 24. Dez 1922</b><br>Berlin · W. Dieckmann<br>„Weihnachtsbrief…"<div class="tg"><span>Weihn.</span></div></span><div class="ar">V · 3</div></div>
</div>
<div class="sc-body">
<h3>Rich Rows</h3>
<p>Pack summary, tags and archive box into each row. No images, no structural change. Fastest to ship.</p>
<div class="tags"><span class="tag">Scanning</span><span class="tag muted">Small effort</span></div>
</div>
</a>
<a class="spec-card" href="02-thumbnail-rows.html">
<span class="sc-num">02</span>
<div class="mini mini-2">
<div class="r2"><div class="th2"></div><div class="content"><b>Demo leserlicher Brief</b><i>„letzte Lebenstage von W. Dörpfeld…"</i><span>← Gertrud · Belgard</span><span class="dt">31. Mai 1940</span></div></div>
<div class="r2"><div class="th2"></div><div class="content"><b>W-0397 2. Sep 1923</b><i>„von Elsbeth geschriebener Kommentar…"</i><span>→ H. Cram · B.Lichterfelde</span><span class="dt">2. Sep 1923</span></div></div>
<div class="r2"><div class="th2"></div><div class="content"><b>W-0521 24. Dez 1922</b><i>„Weihnachtsbrief, Bitte um Bild…"</i><span>→ W. Dieckmann · Berlin</span><span class="dt">24. Dez 1922</span></div></div>
</div>
<div class="sc-body">
<h3>Thumbnail Rows</h3>
<p>PDF preview on the left anchors each row. Summary (when filled) becomes the readable context line.</p>
<div class="tags"><span class="tag">Recognition</span><span class="tag muted">Needs thumbnails</span></div>
</div>
</a>
<a class="spec-card" href="03-master-detail.html">
<span class="sc-num">03</span>
<div class="mini mini-3">
<div class="left-list">
<div class="r"><b>Demo Brief</b></div>
<div class="r sel"><b>W-0397</b></div>
<div class="r"><b>W-0396</b></div>
<div class="r"><b>W-0524</b></div>
<div class="r"><b>W-0523</b></div>
</div>
<div class="preview-mini">
<div class="pv-th"></div>
<div class="pv-meta"><b>W-0397</b>2. Sep 1923<br>B.Lichterfelde<br>→ H. Cram<br><br>„von Elsbeth…"</div>
</div>
</div>
<div class="sc-body">
<h3>Master-Detail Split</h3>
<p>Compact list left, sticky preview right. Click a row → thumbnail, metadata, summary, excerpt. Browse without losing context.</p>
<div class="tags"><span class="tag">Reading flow</span><span class="tag muted">Mobile pattern needed</span></div>
</div>
</a>
<a class="spec-card" href="04-gallery-cards.html">
<span class="sc-num">04</span>
<div class="mini mini-4">
<div class="card-s"><div class="th"></div><div class="t">Demo Brief</div></div>
<div class="card-s"><div class="th"></div><div class="t">W-0397 · 2 Sep</div></div>
<div class="card-s"><div class="th"></div><div class="t">W-0396 · 2 Sep</div></div>
<div class="card-s"><div class="th"></div><div class="t">W-0524 · 31 Jul</div></div>
<div class="card-s"><div class="th"></div><div class="t">W-0523 · 12 Mai</div></div>
<div class="card-s"><div class="th"></div><div class="t">W-0522 · 7 Mär</div></div>
</div>
<div class="sc-body">
<h3>Gallery Cards</h3>
<p>Abandon the list for a 4-column grid. Thumbnail-first, family-album feel. Biggest visual change.</p>
<div class="tags"><span class="tag">Browsing</span><span class="tag muted">Poor date-scanning</span></div>
</div>
</a>
</div>
<div class="section-h">The archive-level view moves to /persons/[id] <span class="sub">Spec 5 · separate page</span></div>
<div class="grid1">
<a class="spec-card wide" href="05-person-dashboard.html">
<span class="sc-num" style="position:absolute">05</span>
<div class="mini mini-5">
<div class="person-left">
<div class="av">WG</div>
<div class="nm">Walter de Gruyter</div>
<div class="dt">18621923</div>
</div>
<div class="dash-mini">
<div class="dh">Korrespondenz-Überblick <span>↗ Briefwechsel</span></div>
<div class="stats-m">
<div><div class="v">851</div><div class="k">gesamt</div></div>
<div><div class="v" style="color:var(--primary)">612</div><div class="k"></div></div>
<div><div class="v" style="color:var(--accent)">239</div><div class="k"></div></div>
<div><div class="v">42J</div><div class="k">Jahre</div></div>
</div>
<div class="hist-m"><i style="height:15%"></i><i style="height:30%"></i><i style="height:45%"></i><i style="height:60%"></i><i style="height:80%"></i><i class="p" style="height:100%"></i><i style="height:75%"></i><i style="height:55%"></i><i style="height:40%"></i><i style="height:25%"></i><i style="height:15%"></i><i style="height:8%"></i></div>
<div class="bars-m"><span>W. Dieckmann<span class="bar" style="flex:1"></span>184</span><span>H. Cram<span class="bar" style="flex:.78"></span>143</span><span>E. Dieckmann<span class="bar" style="flex:.48"></span>88</span></div>
<div class="cloud-m"><span>Verlag</span><span>Familie</span><span>Weihn.</span><span>Kur</span><span>Reise</span></div>
</div>
</div>
<div class="sc-body">
<h3>Person Dashboard (/persons/[id])</h3>
<p>The /briefwechsel list stays calm and reading-focused; the archive-level view — activity over years, top correspondents, top locations, tag cloud — lives on the person detail page, where it's useful <i>every time</i> you open a person, not only during letter review.</p>
<p>Every correspondent, location, tag and year on the dashboard links into <code>/briefwechsel</code> with pre-filled filters, so the dashboard is the discovery surface and /briefwechsel is the reading surface.</p>
<div class="tags"><span class="tag">Discovery</span><span class="tag">Works for bilateral too (always scoped to the person)</span><span class="tag muted">Needs aggregation endpoints</span></div>
</div>
</a>
</div>
<div class="cmp">
<table>
<thead><tr>
<th>Concept</th><th>Best for user who wants to…</th><th>Visual change</th><th>New backend</th><th>Effort</th><th>Mobile</th>
</tr></thead>
<tbody>
<tr><td>1 · Rich Rows</td><td>Scan quickly, see summary + tags on every letter</td><td>Row height 2× current</td><td>None</td><td class="yes">Small</td><td class="yes">Right column collapses</td></tr>
<tr><td>2 · Thumbnail Rows</td><td>Recognise letters visually, pick up where they left off</td><td>Thumbnail on the left</td><td>PDF thumbnail service (open issue)</td><td class="mid">Medium</td><td class="yes">Fine</td></tr>
<tr><td>3 · Master-Detail</td><td>Flip through letters in a reading session</td><td>Two-column split</td><td>None mandatory</td><td class="mid">Medium</td><td class="no">Drawer / sheet needed</td></tr>
<tr><td>4 · Gallery Cards</td><td>Browse the collection as an album</td><td>Full structural change (list → grid)</td><td>PDF thumbnail service</td><td class="no">Large</td><td class="yes">Grid reflows 4 → 2</td></tr>
<tr><td>5 · Person Dashboard</td><td>Understand a person's correspondence at a glance</td><td>New section on /persons/[id]</td><td>Aggregation endpoints (per-year, per-correspondent, per-location, per-tag)</td><td class="mid">Medium</td><td class="yes">Stacks naturally</td></tr>
</tbody>
</table>
</div>
<div style="margin-top:28px;padding:16px 20px;background:#fff;border-left:4px solid var(--brand-navy);font-size:13px;color:#333;line-height:1.65">
<b style="color:var(--brand-navy)">Proposed path forward:</b>
<ol style="margin:8px 0 0 20px;padding:0">
<li><b>Ship Spec 1 (Rich Rows)</b> now — it uses data we already have and tests whether "empty rows" is really the problem, or whether it's "not enough context to decide which letter to open".</li>
<li><b>Build Spec 5 (Person Dashboard)</b> next — it's independent of /briefwechsel and turns the person page into a real archive overview.</li>
<li><b>Upgrade to Spec 2 (Thumbnail Rows)</b> once the thumbnail service lands — it layers cleanly on top of Spec 1 without throwing work away.</li>
</ol>
<div style="margin-top:10px">Specs 3 and 4 remain on the table but are bigger re-architectures — revisit after watching how users behave with 1 + 5 + 2.</div>
</div>
</div>
</body>
</html>