Files
familienarchiv/docs/specs/briefwechsel-fill/05-person-dashboard.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

304 lines
19 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>Spec 5 — Person Dashboard · Briefwechsel Insights</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>
/* Spec 5 specific */
.person-grid{display:grid;grid-template-columns:35% 1fr;gap:32px;align-items:start}
@media (max-width: 1100px){ .person-grid{grid-template-columns:1fr} }
/* Person card (left) */
.pcard{background:#fff;border:1px solid var(--line);border-radius:2px;padding:24px;display:flex;flex-direction:column;align-items:center;gap:14px}
.pavatar{width:100px;height:100px;border-radius:50%;background:var(--brand-mint);color:var(--brand-navy);display:flex;align-items:center;justify-content:center;font-size:36px;font-weight:900;font-family:'Merriweather',serif}
.pname{font-family:'Merriweather',serif;font-size:22px;font-weight:700;color:var(--brand-navy);text-align:center;line-height:1.3}
.pdates{font-size:12px;color:#888;font-weight:600;letter-spacing:.5px}
.pnotes{font-size:13px;color:#555;line-height:1.6;margin-top:6px;padding-top:14px;border-top:1px dashed var(--line);width:100%;font-family:'Merriweather',serif;font-style:italic}
.pactions{margin-top:14px;display:flex;gap:8px;width:100%}
.pactions .btn{flex:1;justify-content:center;font-size:10px}
.pactions .btn.primary{background:var(--brand-navy);color:#fff;border-color:var(--brand-navy)}
/* Name history card */
.ncard{background:#fff;border:1px solid var(--line);border-radius:2px;padding:18px 20px;margin-top:20px}
.ncard h3{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:1.2px;color:#888;margin-bottom:10px}
.ncard ul{list-style:none}
.ncard li{padding:5px 0;font-size:12.5px;color:#444;border-top:1px dashed var(--line);display:flex;justify-content:space-between}
.ncard li:first-child{border-top:0}
/* Right column */
.dash{background:#fff;border:1px solid var(--line);border-radius:2px;overflow:hidden}
.dash-hdr{background:var(--brand-navy);color:#fff;padding:14px 20px;display:flex;justify-content:space-between;align-items:center}
.dash-hdr h2{font-family:'Merriweather',serif;font-size:16px;font-weight:700}
.dash-hdr .open-conv{background:var(--brand-mint);color:var(--brand-navy);font-size:11px;font-weight:800;padding:6px 14px;border-radius:2px;text-transform:uppercase;letter-spacing:.6px;text-decoration:none}
/* Stat strip */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-2);border-bottom:1px solid var(--line)}
.stats div{background:#fafaf5;padding:14px 18px;text-align:center}
.stats .v{font-family:'Merriweather',serif;font-size:22px;font-weight:900;color:var(--brand-navy);letter-spacing:-.5px}
.stats .k{font-size:10px;color:#888;font-weight:700;text-transform:uppercase;letter-spacing:.6px;margin-top:2px}
.stats .out{color:var(--primary)}
.stats .in{color:var(--accent)}
/* Sections */
.dsec{padding:18px 22px;border-top:1px solid var(--line-2)}
.dsec:first-of-type{border-top:0}
.dsec h3{font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:1.2px;color:#888;margin-bottom:12px;display:flex;justify-content:space-between;align-items:baseline}
.dsec h3 .note{font-size:11px;color:#555;text-transform:none;letter-spacing:0;font-weight:600}
/* Activity histogram */
.hist{display:flex;align-items:flex-end;gap:2px;height:90px;padding:4px 0 0}
.hist .bar{flex:1;background:var(--brand-mint);opacity:.55;border-radius:1px 1px 0 0;position:relative;cursor:pointer;transition:opacity .12s}
.hist .bar:hover{opacity:1}
.hist .bar.peak{background:var(--brand-navy);opacity:.85}
.hist-labels{display:flex;justify-content:space-between;font-size:10px;color:#888;margin-top:6px;font-weight:700}
/* Split bar direction */
.dsplit{display:flex;justify-content:space-between;font-size:12px;font-weight:700;margin-bottom:8px}
.dsplit .out{color:var(--primary)}
.dsplit .in{color:var(--accent)}
.dbar{height:10px;display:flex;border-radius:5px;overflow:hidden;background:#F0EDE5}
.dbar .out{background:var(--brand-navy)}
.dbar .in{background:var(--accent)}
/* Top list */
.toplist{display:flex;flex-direction:column;gap:8px}
.toplist .ti{display:flex;align-items:center;gap:10px;font-size:13px;padding:4px 6px;border-radius:2px;cursor:pointer}
.toplist .ti:hover{background:var(--muted)}
.toplist .ti .name{flex:1;color:var(--ink);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.toplist .ti .bar-wrap{width:120px;height:7px;background:#F0EDE5;border-radius:4px;overflow:hidden;flex-shrink:0}
.toplist .ti .bar{height:100%;background:var(--brand-navy);border-radius:4px}
.toplist .ti .val{width:38px;text-align:right;font-size:12px;color:#888;font-weight:700;font-variant-numeric:tabular-nums}
.toplist .ti .dir{font-size:13px;width:16px;font-weight:800}
.toplist .ti .dir.out{color:var(--primary)}
.toplist .ti .dir.in{color:var(--accent)}
.toplist .ti .dir.both{color:#888}
/* Cloud */
.cloud{display:flex;flex-wrap:wrap;gap:6px}
.cloud .tag{cursor:pointer;padding:3px 10px;border-radius:12px;font-weight:700;transition:transform .1s}
.cloud .tag:hover{transform:translateY(-1px)}
.cloud .tag.s-xl{font-size:15px;padding:4px 12px}
.cloud .tag.s-l{font-size:13px}
.cloud .tag.s-m{font-size:12px}
.cloud .tag.s-s{font-size:11px}
/* Two-col arrangement */
.twocol{display:grid;grid-template-columns:1fr 1fr;gap:32px}
@media (max-width: 900px){ .twocol{grid-template-columns:1fr} }
/* Existing doc lists below (compressed) */
.doclist-card{background:#fff;border:1px solid var(--line);border-radius:2px;margin-top:20px;overflow:hidden}
.doclist-card .dh{padding:14px 20px;border-bottom:1px solid var(--line-2);font-size:13px;font-weight:700;color:var(--brand-navy);display:flex;justify-content:space-between;align-items:center}
.doclist-card .dh .cnt{font-size:11px;color:#888;font-weight:600}
.doclist-card .di{padding:10px 20px;border-bottom:1px solid var(--line-2);display:flex;justify-content:space-between;align-items:center;font-size:12.5px}
.doclist-card .di:last-child{border-bottom:0}
.doclist-card .di .t{font-family:'Merriweather',serif;font-weight:700;color:var(--ink);min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;margin-right:10px}
.doclist-card .di .m{color:#888;font-size:11px;white-space:nowrap}
</style>
</head>
<body>
<div class="spec-meta">
<div class="spec-meta-inner">
<div>
<h1>Briefwechsel — <span>Fill the Empty Rows</span></h1>
<p>Insights belong on the person detail page, not on the letter list. This spec mocks the dashboard that replaces the "empty feeling" problem at its proper home.</p>
</div>
<div class="spec-meta-right">
<div><strong>Concept</strong>Person Dashboard</div>
<div><strong>Spec</strong>5 / 5</div>
<div><strong>Page</strong>/persons/[id] (not /briefwechsel)</div>
</div>
</div>
</div>
<nav class="spec-nav">
<div class="spec-nav-inner">
<span class="lbl">Specs</span>
<a 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 class="on" href="05-person-dashboard.html">5 · Person Dashboard</a>
</div>
</nav>
<div class="page-wrap">
<div class="hdr">
<div class="hdr-logo">FAMILIENARCHIV</div>
<div class="hdr-nav"><a>Documents</a><a class="on">Persons</a><a>Letters</a><a>Admin</a></div>
<div class="hdr-right"><div class="hdr-upload">⬆ UPLOAD</div><span>DE · EN · ES</span><div class="hdr-avatar">MR</div></div>
</div>
<div class="page">
<div class="concept-intro">
<h2>Concept 5 · Person Dashboard — insights live on /persons/[id], not on /briefwechsel</h2>
The /briefwechsel page stays focused on reading letters. The archive-level understanding (how much, with whom, when, about what) is moved to the person detail page, where it's useful in all contexts — not only when a correspondent is selected. A "Briefwechsel öffnen" button ties the two pages together.
<div><span class="gain">✚ /briefwechsel stays calm and focused</span><span class="gain">✚ Dashboard is useful on every visit to a person, not just during letter review</span><span class="gain">✚ Each dashboard element links back into /briefwechsel with filters</span><span class="cost"> Separates the work over two pages — needs a clear handoff button</span></div>
</div>
<div style="font-size:12px;color:#888;margin-bottom:18px"><a href="#" style="color:#888;text-decoration:none">← Zurück</a></div>
<div class="person-grid">
<!-- Left column: person identity -->
<div>
<div class="pcard">
<div class="pavatar">WG</div>
<div class="pname">Walter de Gruyter</div>
<div class="pdates">1862 1923</div>
<div class="pnotes">Verleger und Namensgeber des Verlags Walter de Gruyter. Langjährige Korrespondenz mit Familie Dieckmann und Herbert Cram rund um Verlag, Familie und Kuraufenthalte.</div>
<div class="pactions">
<a class="btn">◎ Bearbeiten</a>
<a class="btn primary">↗ Briefwechsel öffnen</a>
</div>
</div>
<div class="ncard">
<h3>Namens­varianten</h3>
<ul>
<li><span>Walter de Gruyter</span><span style="color:#888">Hauptname</span></li>
<li><span>W. de Gruyter</span><span style="color:#888">Abkürzung</span></li>
<li><span>Dr. Walter de Gruyter</span><span style="color:#888">mit Titel</span></li>
</ul>
</div>
</div>
<!-- Right column: dashboard -->
<div>
<div class="dash">
<div class="dash-hdr">
<h2>Korrespondenz-Überblick</h2>
<a class="open-conv" href="#">↗ Briefwechsel öffnen</a>
</div>
<div class="stats">
<div><div class="v">851</div><div class="k">Briefe gesamt</div></div>
<div><div class="v out">612</div><div class="k out">ausgehend</div></div>
<div><div class="v in">239</div><div class="k in">eingehend</div></div>
<div><div class="v">42</div><div class="k">Jahre</div></div>
</div>
<div class="dsec">
<h3>Aktivität über die Jahre <span class="note">Spitzenjahr <b style="color:var(--brand-navy)">1922 · 78 Briefe</b></span></h3>
<div class="hist">
<div class="bar" style="height:12%" title="1898 · 8"></div>
<div class="bar" style="height:18%" title="1899 · 12"></div>
<div class="bar" style="height:26%" title="1900 · 18"></div>
<div class="bar" style="height:38%" title="1901 · 26"></div>
<div class="bar" style="height:44%" title="1902 · 30"></div>
<div class="bar" style="height:52%" title="1903 · 36"></div>
<div class="bar" style="height:60%" title="1904 · 42"></div>
<div class="bar" style="height:68%" title="1905 · 48"></div>
<div class="bar" style="height:80%" title="1920 · 62"></div>
<div class="bar" style="height:88%" title="1921 · 68"></div>
<div class="bar peak" style="height:100%" title="1922 · 78"></div>
<div class="bar" style="height:72%" title="1923 · 54"></div>
<div class="bar" style="height:58%" title="1924 · 42"></div>
<div class="bar" style="height:48%" title="1925 · 34"></div>
<div class="bar" style="height:38%" title="1926 · 27"></div>
<div class="bar" style="height:28%" title="1927 · 20"></div>
<div class="bar" style="height:22%" title="1928 · 16"></div>
<div class="bar" style="height:18%" title="1929 · 13"></div>
<div class="bar" style="height:14%" title="1930 · 10"></div>
<div class="bar" style="height:10%" title="1932 · 7"></div>
<div class="bar" style="height:6%" title="1935 · 4"></div>
<div class="bar" style="height:4%" title="1938 · 3"></div>
<div class="bar" style="height:2%" title="1940 · 1"></div>
</div>
<div class="hist-labels"><span>1898</span><span>1922 ▲</span><span>1940</span></div>
</div>
<div class="dsec">
<h3>Richtungsverteilung</h3>
<div class="dsplit">
<span class="out">→ 612 ausgehend · 72%</span>
<span class="in">← 239 eingehend · 28%</span>
</div>
<div class="dbar">
<span class="out" style="width:72%"></span>
<span class="in" style="width:28%"></span>
</div>
</div>
<div class="twocol">
<div class="dsec" style="border-top:1px solid var(--line-2)">
<h3>Häufigste Korrespondenten <span class="note">Top 6 von 87</span></h3>
<div class="toplist">
<div class="ti"><span class="dir both"></span><span class="name">Walter Dieckmann</span><span class="bar-wrap"><span class="bar" style="width:100%"></span></span><span class="val">184</span></div>
<div class="ti"><span class="dir both"></span><span class="name">Herbert Cram</span><span class="bar-wrap"><span class="bar" style="width:78%"></span></span><span class="val">143</span></div>
<div class="ti"><span class="dir both"></span><span class="name">Ella Dieckmann</span><span class="bar-wrap"><span class="bar" style="width:48%"></span></span><span class="val">88</span></div>
<div class="ti"><span class="dir both"></span><span class="name">Eugenie de Gruyter</span><span class="bar-wrap"><span class="bar" style="width:42%"></span></span><span class="val">77</span></div>
<div class="ti"><span class="dir both"></span><span class="name">Gertrud von Rofden</span><span class="bar-wrap"><span class="bar" style="width:32%"></span></span><span class="val">58</span></div>
<div class="ti"><span class="dir both"></span><span class="name">Käthe Dieckmann</span><span class="bar-wrap"><span class="bar" style="width:26%"></span></span><span class="val">47</span></div>
</div>
<div style="margin-top:10px"><a style="font-size:11px;color:var(--primary);font-weight:700;text-decoration:none;border-bottom:1px dashed var(--primary)">Alle 87 Korrespondenten →</a></div>
</div>
<div class="dsec" style="border-top:1px solid var(--line-2)">
<h3>Häufigste Orte <span class="note">Top 5 von 42</span></h3>
<div class="toplist">
<div class="ti"><span class="name">📍 Berlin</span><span class="bar-wrap"><span class="bar" style="width:100%"></span></span><span class="val">412</span></div>
<div class="ti"><span class="name">📍 B.Lichterfelde</span><span class="bar-wrap"><span class="bar" style="width:44%"></span></span><span class="val">180</span></div>
<div class="ti"><span class="name">📍 Bad Kissingen</span><span class="bar-wrap"><span class="bar" style="width:14%"></span></span><span class="val">58</span></div>
<div class="ti"><span class="name">📍 Cöln</span><span class="bar-wrap"><span class="bar" style="width:9%"></span></span><span class="val">37</span></div>
<div class="ti"><span class="name">📍 Belgard</span><span class="bar-wrap"><span class="bar" style="width:6%"></span></span><span class="val">26</span></div>
</div>
</div>
</div>
<div class="dsec">
<h3>Beliebte Schlagwörter <span class="note">Klick filtert den Briefwechsel</span></h3>
<div class="cloud">
<span class="tag s-xl">Verlag</span>
<span class="tag s-xl">Familie</span>
<span class="tag s-l">Geburtstag</span>
<span class="tag s-l">Weihnachten</span>
<span class="tag s-m">Kuraufenthalt</span>
<span class="tag s-m">Reise</span>
<span class="tag s-m">Geschäft</span>
<span class="tag s-s">Krieg</span>
<span class="tag s-s muted">Krankheit</span>
<span class="tag s-s muted">Schule</span>
<span class="tag s-s muted">Hochzeit</span>
<span class="tag s-s muted">Tod</span>
<span class="tag s-s muted">Namenstag</span>
<span class="tag s-s muted">Neujahr</span>
</div>
</div>
</div>
<!-- Existing doc lists stay below the dashboard -->
<div class="doclist-card">
<div class="dh">Geschriebene Briefe <span class="cnt">612 Briefe · <a style="color:var(--primary);text-decoration:none;border-bottom:1px dashed">Alle anzeigen →</a></span></div>
<div class="di"><span class="t">W-0397 2. September 1923 B.Lichterfelde</span><span class="m">an Herbert Cram</span></div>
<div class="di"><span class="t">W-0521 24. Dezember 1922 Berlin</span><span class="m">an Walter Dieckmann</span></div>
<div class="di"><span class="t">W-0392 23. November 1921 Bad Kissingen</span><span class="m">an Herbert Cram</span></div>
</div>
<div class="doclist-card">
<div class="dh">Empfangene Briefe <span class="cnt">239 Briefe · <a style="color:var(--primary);text-decoration:none;border-bottom:1px dashed">Alle anzeigen →</a></span></div>
<div class="di"><span class="t">Demo leserlicher Brief</span><span class="m">von Gertrud von Rofden</span></div>
</div>
</div>
</div>
<div style="margin-top:36px;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)">How this ties back to /briefwechsel:</b>
<ul style="margin:8px 0 0 18px;padding:0">
<li>Every correspondent row → <code>/briefwechsel?senderId=&lt;person&gt;&amp;receiverId=&lt;other&gt;</code> (bilateral view)</li>
<li>Every location → <code>/briefwechsel?senderId=&lt;person&gt;&amp;location=&lt;x&gt;</code></li>
<li>Every tag → <code>/briefwechsel?senderId=&lt;person&gt;&amp;tag=&lt;x&gt;</code></li>
<li>Every histogram year → <code>/briefwechsel?…&amp;from=YYYY-01-01&amp;to=YYYY-12-31</code></li>
</ul>
The dashboard is the discovery surface; /briefwechsel is the reading surface.
</div>
</div>
</div>
</body>
</html>