Files
familienarchiv/docs/specs/dokumente-dashboard-spec.html
Marcel 40db46945f
Some checks failed
CI / OCR Service Tests (push) Successful in 28s
CI / Backend Unit Tests (push) Failing after 2m42s
CI / Unit & Component Tests (push) Failing after 2m38s
docs(spec): add Dokumente dashboard design spec (Variant A)
Pixel-accurate spec for the dashboard redesign: Resume + Family Pulse
layout with hero resume card, mission control 3-up, and activity feed.
Relates to #271

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:07:01 +02:00

1079 lines
79 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="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dokumente Dashboard · Final Design Spec · Familienarchiv #271</title>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Helvetica Neue',Arial,sans-serif;background:#ECEAE4;color:#1A1A1A;line-height:1.5}
.doc{max-width:1400px;margin:0 auto;padding:48px 32px}
/* ── Masthead ─── */
.mast{background:#0D2240;border-radius:10px;padding:32px 40px;margin-bottom:48px}
.mast-top{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin-bottom:16px}
.mast h1{font-size:22px;font-weight:900;color:#fff;letter-spacing:-.4px;margin-bottom:6px}
.mast p{font-size:12px;color:rgba(255,255,255,.5);max-width:640px;line-height:1.7}
.mast-badge{font-size:9px;font-weight:800;padding:3px 9px;border-radius:20px;text-transform:uppercase;letter-spacing:.8px;white-space:nowrap;flex-shrink:0;margin-top:4px}
.mb-final{background:#A6DAD8;color:#002850}
.decisions{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:20px;border-top:1px solid rgba(255,255,255,.1);padding-top:16px}
.dec{background:rgba(255,255,255,.06);border-radius:6px;padding:10px 12px}
.dec-label{font-size:7px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;color:rgba(255,255,255,.35);margin-bottom:5px}
.dec-value{font-size:9.5px;font-weight:700;color:#fff;line-height:1.5}
/* ── Section headings ─── */
.sec{margin-bottom:64px}
.sec+.sec{border-top:2px dashed #C8C4BE;padding-top:56px}
.sec-h{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:1.2px;color:#888;margin-bottom:20px;display:flex;align-items:center;gap:10px}
.sec-h::after{content:'';flex:1;height:1px;background:#D8D4CE}
.sec-num{background:#0D2240;color:#fff;font-size:9px;font-weight:900;padding:2px 7px;border-radius:10px}
/* ── Grid ─── */
.sg{display:grid;gap:20px;align-items:start}
.sg-2{grid-template-columns:1fr 1fr}
.sg-3{grid-template-columns:1fr 1fr 1fr}
.sg-4{grid-template-columns:1fr 1fr 1fr 1fr}
.sb{display:flex;flex-direction:column}
.sl{font-size:9px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:1.5px;margin-bottom:6px;display:flex;align-items:center;gap:6px}
.sc{font-size:10px;color:#888;margin-top:8px;font-style:italic;line-height:1.5}
/* ── Browser chrome ─── */
.wf{background:#fff;border:2px solid #B8B4AE;border-radius:10px;overflow:hidden;box-shadow:0 4px 18px rgba(0,0,0,.08)}
.wf-bar{height:24px;background:#E8E4DF;border-bottom:1px solid #C8C4BE;display:flex;align-items:center;padding:0 9px;gap:4px}
.dot{width:7px;height:7px;border-radius:50%;background:#C8C4BE}
.dot.r{background:#F87171}.dot.y{background:#FCD34D}.dot.g{background:#4ADE80}
.urlbar{flex:1;height:11px;background:#D8D4CE;border-radius:3px;margin-left:6px;display:flex;align-items:center;padding:0 5px}
.urlbar span{font-size:7.5px;color:#888;font-family:monospace}
/* ── Mobile chrome ─── */
.WF-M{background:#fff;border:2px solid #B8B4AE;border-radius:16px;overflow:hidden;box-shadow:0 4px 18px rgba(0,0,0,.08);width:220px}
.WF-M-STATUS{height:14px;background:#012851;display:flex;align-items:center;justify-content:space-between;padding:0 10px}
.WF-M-TIME{font-size:6px;color:#fff;font-weight:700}
.WF-M-ICONS{display:flex;gap:3px}
.WF-M-ICON{width:5px;height:5px;background:rgba(255,255,255,.5);border-radius:1px}
/* ── State pill labels ─── */
.state-label{display:inline-block;font-size:7px;font-weight:800;text-transform:uppercase;letter-spacing:.5px;border-radius:3px;padding:1px 5px;margin-bottom:5px}
.st-default{background:#E8E4DF;color:#555}
.st-hover{background:#DBEAFE;color:#1D4ED8}
.st-focus{background:#EDE9FE;color:#6D28D9}
.st-active{background:#DCFCE7;color:#166534}
.st-loading{background:#FEF9C3;color:#854D0E}
.st-error{background:#FEE2E2;color:#991B1B}
.st-for-you{background:#CFFAFE;color:#0e7490}
/* ── Annotation callouts ─── */
.ann-block{background:#FFF7ED;border:1px solid #FDBA74;border-radius:5px;padding:10px 14px;font-size:10.5px;color:#7C2D12;line-height:1.6;margin-top:14px}
.ann-block strong{font-weight:800}
.ann-block ul{padding-left:16px;display:flex;flex-direction:column;gap:3px;margin-top:6px}
.ann-info{background:#EFF6FF;border:1px solid #BFDBFE;border-radius:5px;padding:10px 14px;font-size:10.5px;color:#1E3A5F;line-height:1.6;margin-top:14px}
.ann-info strong{font-weight:800}
.ann-info ul{padding-left:16px;display:flex;flex-direction:column;gap:3px;margin-top:6px}
/* ── Spec disclaimer ─── */
.spec-disclaimer{background:#FFF8E1;border:1.5px solid #FFC107;border-radius:6px;padding:11px 16px;font-size:11px;color:#6D4C00;margin-bottom:32px;line-height:1.6}
.spec-disclaimer strong{font-weight:800}
/* ── impl-ref ─── */
.impl-ref{background:#0d1117;border-radius:8px;margin-top:20px;overflow:hidden;border:1px solid #30363d}
.impl-ref-hdr{background:#161b22;padding:9px 16px;font-size:9.5px;font-weight:800;color:#f0883e;border-bottom:1px solid #30363d;display:flex;align-items:center;gap:8px;letter-spacing:.4px;text-transform:uppercase}
.impl-ref-hdr::before{content:'⚙';font-size:12px}
.impl-ref-hdr span{color:rgba(240,136,62,.55);font-weight:400;margin-left:auto;font-size:9px;text-transform:none;letter-spacing:0}
.impl-ref table{width:100%;border-collapse:collapse;font-size:10px}
.impl-ref th{text-align:left;font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.8px;color:#8b949e;padding:8px 14px;border-bottom:1px solid #21262d}
.impl-ref td{padding:6px 14px;border-bottom:1px solid #161b22;vertical-align:top;line-height:1.6;color:#c9d1d9}
.impl-ref tr:last-child td{border-bottom:none}
.impl-ref td:first-child{color:#79c0ff;font-weight:700;white-space:nowrap;width:210px}
.impl-ref td code{font-family:'SFMono-Regular',Consolas,monospace;font-size:9.5px;background:#161b22;color:#a5d6ff;padding:1px 5px;border-radius:3px;white-space:nowrap}
.impl-ref .ir-px{color:#7ee787;font-family:monospace;font-size:9.5px}
/* ════════════════════════════════════════
DASHBOARD MOCKUP COMPONENTS
All sizes ~55% of real implementation values.
DO NOT copy sizes from mockup CSS.
════════════════════════════════════════ */
/* Page shell */
.DB{background:#f0efe9;font-family:'Helvetica Neue',Arial,sans-serif}
/* ── Header ─── */
.DB-HDR{background:#012851;flex-shrink:0}
.DB-STRIPE{height:2px;background:#a1dcd8}
.DB-NAV{height:35px;display:flex;align-items:center;padding:0 18px;gap:0}
.DB-WORDMARK{font-size:11px;font-weight:900;color:#fff;letter-spacing:.15em;text-transform:uppercase;margin-right:22px}
.DB-NAVLINK{font-size:6.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.7);padding:0 8px;height:35px;display:inline-flex;align-items:center;border-bottom:1.5px solid transparent;text-decoration:none}
.DB-NAVLINK.on{color:#fff;border-bottom-color:#a1dcd8}
.DB-HDR-ACTIONS{margin-left:auto;display:flex;align-items:center;gap:8px}
.DB-UPLOAD-BTN{display:inline-flex;align-items:center;gap:4px;border:1px solid rgba(255,255,255,.25);color:#fff;padding:3px 8px;border-radius:2px;font-size:6px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;background:transparent}
.DB-AVATAR{width:18px;height:18px;border-radius:999px;background:#fff;color:#012851;display:flex;align-items:center;justify-content:center;font-size:6px;font-weight:800}
/* ── Search bar ─── */
.DB-SEARCH{background:#fff;border:1px solid #e4e2d7;box-shadow:0 1px 2px 0 rgb(0 0 0/.05);border-radius:2px;padding:11px 13px;margin-bottom:11px;display:flex;align-items:center;gap:7px}
.DB-SEARCH-INPUT{flex:1;border:1px solid #e4e2d7;background:#fff;padding:7px 27px 7px 8px;font-size:9px;color:#9ca3af;border-radius:2px;font-style:italic;position:relative}
.DB-SEARCH-FILTER{border:1px solid #e4e2d7;padding:7px 9px;border-radius:2px;font-size:6.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:#4b5563;background:#fff;display:flex;align-items:center;gap:4px}
/* ── Layout grid ─── */
.DB-LAYOUT{display:grid;grid-template-columns:1fr 176px;gap:11px;align-items:start}
.DB-MAIN{display:flex;flex-direction:column;gap:11px}
.DB-ASIDE{display:flex;flex-direction:column;gap:11px}
/* ── Card shell ─── */
.DB-CARD{background:#fff;border:1px solid #e4e2d7;box-shadow:0 1px 2px 0 rgb(0 0 0/.05);border-radius:2px}
/* ── Greeting ─── */
.DB-GREET{margin-bottom:11px}
.DB-GREET-H{font-size:18px;font-weight:400;color:#012851;font-family:Georgia,serif;line-height:1.1;margin-bottom:4px}
.DB-GREET-SUB{font-size:9px;color:#4b5563;font-family:Georgia,serif;line-height:1.45}
.DB-GREET-SUB a{color:#012851;text-decoration:underline;text-decoration-color:#a1dcd8;text-underline-offset:2px}
/* ── Section caption ─── */
.DB-SCAP{display:flex;align-items:center;gap:7px;margin-bottom:9px}
.DB-SCAP-TEXT{font-size:6px;font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:#012851;white-space:nowrap}
.DB-SCAP-RULE{flex:1;height:1px;background:#e4e2d7}
.DB-SCAP-ACT{font-size:6px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:#4b5563;text-decoration:none}
/* ── Hero resume card ─── */
.DB-HERO{padding:15px;display:grid;grid-template-columns:99px 1fr;gap:18px;align-items:center}
.DB-HERO-THUMB{width:99px;height:135px;border-radius:1px;background:linear-gradient(180deg,#f1e6cc,#e7d8b3);position:relative;overflow:hidden;flex-shrink:0}
.DB-HERO-CONTENT{}
.DB-HERO-EYEBROW{display:flex;align-items:center;gap:5px;margin-bottom:6px;flex-wrap:wrap}
.DB-HERO-LABEL{display:inline-flex;align-items:center;gap:4px;font-size:6px;font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:#00c7b1}
.DB-HERO-DOT{width:4px;height:4px;border-radius:999px;background:#00c7b1}
.DB-HERO-PAGE{font-size:6px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:#9ca3af}
.DB-HERO-TITLE{font-size:16.5px;font-weight:400;color:#012851;font-family:Georgia,serif;line-height:1.2;margin-bottom:3px}
.DB-HERO-CAPTION{font-size:7.5px;font-style:italic;color:#6b7280;margin-bottom:9px;font-family:Georgia,serif}
.DB-HERO-QUOTE{font-size:9.5px;font-style:italic;color:#4b5563;font-family:Georgia,serif;line-height:1.55;border-left:2px solid #a1dcd8;padding-left:9px;margin-bottom:10px}
.DB-HERO-PROG-ROW{display:flex;justify-content:space-between;align-items:center;font-size:6.5px;color:#6b7280;margin-bottom:4px}
.DB-PROG{height:3.5px;background:#eeede8;border-radius:999px;overflow:hidden;margin-bottom:10px}
.DB-PROG-FILL{height:100%;background:#00c7b1;border-radius:999px}
.DB-HERO-BTNS{display:flex;align-items:center;gap:11px}
.DB-BTN-NAVY{background:#012851;color:#fff;border:none;border-radius:2px;padding:7px 11px;font-size:6px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;display:inline-flex;align-items:center;gap:4px}
.DB-BTN-GHOST{border:1px solid #e4e2d7;color:#4b5563;background:transparent;border-radius:2px;padding:6px 9px;font-size:6px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
.DB-LINK-GHOST{font-size:6px;font-weight:600;color:#4b5563;text-decoration:underline;text-decoration-color:#cdcbbf;text-underline-offset:2px}
/* ── Avatar ─── */
.AV{border-radius:999px;display:inline-flex;align-items:center;justify-content:center;font-weight:800;font-size:6px;color:#fff;flex-shrink:0}
/* ── Avatar stack ─── */
.AV-STACK{display:inline-flex;align-items:center}
.AV-STACK .AV+.AV{margin-left:-5px}
/* ── Mission control ─── */
.DB-MISSION{display:grid;grid-template-columns:1fr 1fr 1fr;gap:9px}
.MC-COL{background:#fff;border:1px solid #e4e2d7;border-radius:2px;overflow:hidden;display:flex;flex-direction:column}
.MC-HDR{padding:9px 10px;border-bottom:1px solid #eeede8}
.MC-HDR-ROW{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:3px}
.MC-LABEL{font-size:6px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:#012851}
.MC-COUNT{font-size:6px;color:#6b7280}
.MC-BLURB{font-size:7.5px;color:#4b5563;font-family:Georgia,serif;line-height:1.4}
.MC-ROWS{padding:3px}
.MC-ROW{display:flex;align-items:center;gap:7px;padding:6px 8px;border-radius:2px}
.MC-ROW:hover{background:#f7f6f1}
.MC-ROW-BODY{flex:1;min-width:0}
.MC-TITLE{font-size:8.5px;color:#012851;font-family:Georgia,serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}
.MC-META{font-size:6px;color:#6b7280;margin-top:1px;display:flex;align-items:center;gap:4px}
.MC-SEP{color:#cdcbbf}
.MC-PCT-OK{color:#5a8a6a;font-weight:700}
.MC-FOOT{text-align:center;padding:6px;border-top:1px solid #eeede8;font-size:6px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:#012851;text-decoration:none;display:block;margin-top:auto}
.MC-AV-EMPTY{width:12px;height:12px;border-radius:999px;border:1px dashed #cdcbbf;flex-shrink:0}
/* ── Family Pulse sidebar ─── */
.DB-PULSE{padding:13px 15px;background:#fff;border:1px solid #e4e2d7;border-radius:2px;box-shadow:0 1px 2px 0 rgb(0 0 0/.05)}
.DB-PULSE-EYE{font-size:5.5px;font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:#6b7280;margin-bottom:5px}
.DB-PULSE-HEADLINE{font-size:12px;font-family:Georgia,serif;font-weight:400;color:#012851;line-height:1.3;margin-bottom:4px}
.DB-PULSE-HEADLINE strong{font-weight:600}
.DB-PULSE-SUB{font-size:7px;color:#6b7280;font-family:Georgia,serif;margin-bottom:10px}
.DB-PULSE-CONTRIB{display:flex;align-items:center;gap:6px;margin-bottom:10px}
.DB-PULSE-CONTRIB-LABEL{font-size:6px;color:#6b7280}
.DB-PULSE-STATS{display:grid;grid-template-columns:1fr 1fr 1fr;gap:5px}
.DB-PULSE-STAT{background:#faf9f4;border:1px solid #eeede8;border-radius:2px;padding:8px 9px}
.DB-PULSE-STAT-N{font-size:16px;font-family:Georgia,serif;font-weight:400;color:#012851;line-height:1;display:flex;align-items:baseline;gap:4px}
.DB-PULSE-STAT-DOT{width:3.5px;height:3.5px;border-radius:999px;flex-shrink:0}
.DB-PULSE-STAT-LABEL{font-size:5.5px;color:#6b7280;margin-top:3px}
/* ── Activity feed ─── */
.DB-FEED{padding:13px 15px}
.DB-FEED-ITEM{display:flex;gap:7px;align-items:flex-start;padding:7px 0;border-bottom:1px solid #eeede8}
.DB-FEED-ITEM:last-child{border-bottom:none}
.DB-FEED-BODY{flex:1;min-width:0}
.DB-FEED-TEXT{font-size:8px;color:#012851;font-family:Georgia,serif;line-height:1.45}
.DB-FEED-TEXT strong{font-family:'Helvetica Neue',Arial,sans-serif;font-size:7px;font-weight:800}
.DB-FEED-TEXT a{color:#012851;text-decoration:underline;text-underline-offset:2px}
.DB-FOR-YOU{display:inline-block;padding:1px 5px;border:1px solid #a1dcd8;border-radius:999px;font-size:5.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:#012851;background:rgba(161,220,216,.2);margin-left:4px;vertical-align:middle}
.DB-FEED-WHEN{display:inline-flex;align-items:center;gap:4px;font-size:5.5px;color:#6b7280;margin-top:2px}
.DB-FEED-DOT{width:3.5px;height:3.5px;border-radius:999px;flex-shrink:0}
/* ── Dropzone ─── */
.DB-DROP{display:flex;flex-direction:column;align-items:center;gap:5px;padding:13px 9px;border:1px dashed rgba(1,40,81,.3);border-radius:2px;text-align:center}
.DB-DROP-TITLE{font-size:7px;font-weight:700;color:#012851}
.DB-DROP-SUB{font-size:6.5px;color:#6b7280}
.DB-DROP-HINT{font-size:5.5px;color:#9ca3af;margin-top:2px}
/* ── Letter thumb (simulated scan) ─── */
.LT{display:block;border-radius:1px;box-shadow:0 1px 2px rgba(0,0,0,.08)}
/* ── Progress bars ─── */
.PB{height:3px;background:#eeede8;border-radius:999px;overflow:hidden}
.PB-FILL{height:100%;border-radius:999px}
</style>
</head>
<body>
<div class="doc">
<!-- ══════════════════════════════════════
MASTHEAD
══════════════════════════════════════ -->
<div class="mast">
<div class="mast-top">
<div>
<h1>Dokumente Dashboard · Final Design Spec</h1>
<p>Redesign of the homepage (<code style="font-size:10px;color:#A6DAD8">/</code>) as an action-led document hub. Replaces the wall-of-lists approach with a warm, collaborative dashboard: personal greeting, hero "resume" card, Mission Control 3-up, Family Pulse (this week only), activity feed, and sidebar dropzone. Variant A selected from a three-concept exploration. Addresses Issue #271.</p>
</div>
<span class="mast-badge mb-final">Final · Ready for implementation</span>
</div>
<div class="decisions">
<div class="dec">
<div class="dec-label">Issue</div>
<div class="dec-value">#271 — Dashboard redesign</div>
</div>
<div class="dec">
<div class="dec-label">Variant</div>
<div class="dec-value">A — Resume + Family Pulse · hero-led, warm greeting, mission-control 3-up</div>
</div>
<div class="dec">
<div class="dec-label">Thumbnails</div>
<div class="dec-value">Hero only (large = legible). No thumbnails in task rows — kurrent is unreadable noise at small sizes.</div>
</div>
<div class="dec">
<div class="dec-label">Progress framing</div>
<div class="dec-value">"Diese Woche" only. Never show 1,500 total — demotivating at early state. Per-letter bars stay (clear denominator).</div>
</div>
</div>
</div>
<!-- ── spec disclaimer ── -->
<div class="spec-disclaimer">
<strong>📐 Mockup scale notice —</strong> all font-size, height, and padding values
in the mockup CSS are scaled to ~55% of actual implementation values.
<strong>Do not copy sizes from mockup CSS.</strong> Use the ⚙ Implementation
Reference tables after each section.
</div>
<!-- ══════════════════════════════════════
SECTION 1 — FULL PAGE OVERVIEW (DESKTOP)
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">1</span> Full page — desktop (1280px)</div>
<div class="sb">
<span class="state-label st-default">Default — logged in as Marie</span>
<div class="wf" style="max-width:960px">
<div class="wf-bar">
<div class="dot r"></div><div class="dot y"></div><div class="dot g"></div>
<div class="urlbar"><span>localhost:3000/</span></div>
</div>
<div class="DB">
<!-- Header -->
<div class="DB-HDR">
<div class="DB-STRIPE"></div>
<div class="DB-NAV">
<span class="DB-WORDMARK">Familienarchiv</span>
<a class="DB-NAVLINK on" href="#">Dokumente</a>
<a class="DB-NAVLINK" href="#">Personen</a>
<a class="DB-NAVLINK" href="#">Briefwechsel</a>
<div class="DB-HDR-ACTIONS">
<div class="DB-UPLOAD-BTN">↑ Hochladen</div>
<div class="DB-AVATAR">MR</div>
</div>
</div>
</div>
<!-- Main -->
<div style="padding:18px;background:#f0efe9">
<!-- Greeting -->
<div class="DB-GREET">
<div class="DB-GREET-H">Hallo, Marie.</div>
<div class="DB-GREET-SUB">Klaus hat dich gestern in einem Brief erwähnt, und Anna wartet auf deine Meinung zur <a href="#">„Postkarte aus Wien"</a>.</div>
</div>
<!-- Search -->
<div class="DB-SEARCH">
<div class="DB-SEARCH-INPUT" style="flex:1;height:20px;display:flex;align-items:center;color:#9ca3af;font-size:8.5px;font-style:italic">Titel, Personen, Tags durchsuchen…</div>
<div class="DB-SEARCH-FILTER">Filter</div>
</div>
<!-- Content grid -->
<div class="DB-LAYOUT">
<div class="DB-MAIN">
<!-- Hero -->
<div class="DB-CARD DB-HERO">
<!-- Letter thumb -->
<div class="DB-HERO-THUMB">
<svg viewBox="0 0 99 135" width="99" height="135" class="LT">
<defs><linearGradient id="pa" x1="0" x2="0" y1="0" y2="1"><stop offset="0" stop-color="#f1e6cc"/><stop offset="1" stop-color="#e7d8b3"/></linearGradient></defs>
<rect x="0" y="0" width="99" height="135" fill="url(#pa)"/>
<circle cx="12" cy="24" r="2" fill="#a07a3a" opacity=".18"/>
<circle cx="77" cy="84" r="1.5" fill="#a07a3a" opacity=".22"/>
<circle cx="32" cy="118" r="2" fill="#a07a3a" opacity=".18"/>
<line x1="49.5" y1="0" x2="49.5" y2="135" stroke="#9a7b50" stroke-width=".4" opacity=".3"/>
<rect x="10" y="20" width="36" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="28" width="55" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="36" width="42" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="51" y="36" width="28" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="44" width="60" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="52" width="30" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="43" y="52" width="36" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="60" width="50" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="68" width="38" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="51" y="68" width="22" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="76" width="60" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="84" width="44" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="92" width="55" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<rect x="10" y="100" width="36" height="2.2" rx="1" fill="#3a2a18" opacity=".62"/>
<path d="M14 126 q10-10 22-2 t18-3" fill="none" stroke="#3a2a18" stroke-width="1.4" opacity=".7" stroke-linecap="round"/>
</svg>
</div>
<!-- Content -->
<div class="DB-HERO-CONTENT">
<div class="DB-HERO-EYEBROW">
<span class="DB-HERO-LABEL"><span class="DB-HERO-DOT"></span>Weiter, wo du aufgehört hast</span>
<span class="DB-HERO-PAGE">Seite 2 von 4</span>
</div>
<div class="DB-HERO-TITLE">Brief an Frieda aus dem Harz</div>
<div class="DB-HERO-CAPTION">Frieda Lehmann an Wilhelm Lehmann · Bad Sachsa, 14. März 1923</div>
<div class="DB-HERO-QUOTE">„Liebe Frieda, der Schnee ist endlich gewichen und die Wege wieder begehbar. Vater hat heute Morgen vom Markt geschrieben, daß die Preise abermals…"</div>
<div class="DB-HERO-PROG-ROW">
<span>Transkription 38%</span>
<span style="display:inline-flex;align-items:center;gap:5px">
<span class="AV-STACK">
<span class="AV" style="width:11px;height:11px;background:#7a4f9a">MR</span>
<span class="AV" style="width:11px;height:11px;background:#5a8a6a">AN</span>
</span>
<span style="font-size:6px;color:#6b7280">du und Anna</span>
</span>
</div>
<div class="DB-PROG"><div class="DB-PROG-FILL" style="width:38%;background:#00c7b1"></div></div>
<div class="DB-HERO-BTNS">
<button class="DB-BTN-NAVY">✏ Weitertranskribieren</button>
<span class="DB-LINK-GHOST">oder anderen Brief wählen</span>
</div>
</div>
</div>
<!-- Mission Control -->
<div>
<div class="DB-SCAP"><span class="DB-SCAP-TEXT">Mitmachen</span><span class="DB-SCAP-RULE"></span></div>
<div class="DB-MISSION">
<!-- Segmentieren -->
<div class="MC-COL">
<div class="MC-HDR" style="background:rgba(160,82,45,.06)">
<div class="MC-HDR-ROW"><span class="MC-LABEL">Segmentieren</span><span class="MC-COUNT">5 offen</span></div>
<div class="MC-BLURB">Seiten zu Briefen zuordnen.</div>
</div>
<div class="MC-ROWS">
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Konvolut Rose, Heft III</div><div class="MC-META"><span>Mappe A</span><span class="MC-SEP">·</span><span>14 Seiten</span></div></div><span class="AV" style="width:12px;height:12px;background:#5a8a6a">AN</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Umschlag Mariahilf</div><div class="MC-META"><span>19. Nov 1925</span><span class="MC-SEP">·</span><span>3 Seiten</span></div></div><span class="MC-AV-EMPTY"></span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Mappe B — unsortiert</div><div class="MC-META"><span>neu, 18. Apr</span><span class="MC-SEP">·</span><span>27 Seiten</span></div></div><span class="MC-AV-EMPTY"></span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Briefbündel Lehrzeit</div><div class="MC-META"><span>19281930</span><span class="MC-SEP">·</span><span>11 Seiten</span></div></div><span class="MC-AV-EMPTY"></span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Einzelseiten Dachboden</div><div class="MC-META"><span>ohne Datum</span><span class="MC-SEP">·</span><span>8 Seiten</span></div></div><span class="MC-AV-EMPTY"></span></div>
</div>
<a class="MC-FOOT" href="#">Alle anzeigen →</a>
</div>
<!-- Transkribieren -->
<div class="MC-COL">
<div class="MC-HDR" style="background:rgba(0,199,177,.08)">
<div class="MC-HDR-ROW"><span class="MC-LABEL">Transkribieren</span><span class="MC-COUNT">5 offen</span></div>
<div class="MC-BLURB">Alte Handschriften lesen und abtippen.</div>
</div>
<div class="MC-ROWS">
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Brief an Frieda aus dem Harz</div><div class="MC-META"><span>14. März 1923</span><span class="MC-SEP">·</span><span>38%</span></div></div><span class="AV" style="width:12px;height:12px;background:#7a4f9a">MR</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Postkarte aus Wien</div><div class="MC-META"><span>2. Aug 1924</span><span class="MC-SEP">·</span><span>60%</span></div></div><span class="AV" style="width:12px;height:12px;background:#a0522d">OS</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Geburtstagsbrief</div><div class="MC-META"><span>22. Mai 1928</span><span class="MC-SEP">·</span><span>5%</span></div></div><span class="AV" style="width:12px;height:12px;background:#c0446e">LO</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Weihnachtsgruß an die Familie</div><div class="MC-META"><span>21. Dez 1931</span><span class="MC-SEP">·</span><span>12%</span></div></div><span class="AV" style="width:12px;height:12px;background:#7a4f9a">MR</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Brief aus Hamburg</div><div class="MC-META"><span>3. Juni 1929</span></div></div><span class="MC-AV-EMPTY"></span></div>
</div>
<a class="MC-FOOT" href="#">Alle anzeigen →</a>
</div>
<!-- Prüfen -->
<div class="MC-COL">
<div class="MC-HDR" style="background:rgba(90,138,106,.08)">
<div class="MC-HDR-ROW"><span class="MC-LABEL">Prüfen</span><span class="MC-COUNT">4 offen</span></div>
<div class="MC-BLURB">Letzte Korrektur und freigeben.</div>
</div>
<div class="MC-ROWS">
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Brief aus der Lehrzeit</div><div class="MC-META"><span>8. Okt 1930</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig</span></div></div><span class="AV" style="width:12px;height:12px;background:#c17a00">TH</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Weihnachtsgruß</div><div class="MC-META"><span>21. Dez 1931</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig</span></div></div><span class="AV" style="width:12px;height:12px;background:#7a4f9a">MR</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Geschäftsbrief Mariahilf</div><div class="MC-META"><span>19. Nov 1925</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig</span></div></div><span class="AV" style="width:12px;height:12px;background:#3060b0">KL</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Kartengruß aus Dresden</div><div class="MC-META"><span>7. Apr 1927</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig</span></div></div><span class="AV" style="width:12px;height:12px;background:#5a8a6a">AN</span></div>
</div>
<a class="MC-FOOT" href="#">Alle anzeigen →</a>
</div>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="DB-ASIDE">
<!-- Family Pulse -->
<div class="DB-PULSE">
<div class="DB-PULSE-EYE">Diese Woche · gemeinsam</div>
<div class="DB-PULSE-HEADLINE">Ihr habt zusammen <strong>86 Seiten</strong> bearbeitet.</div>
<div class="DB-PULSE-SUB">Du selbst hast 4 davon transkribiert.</div>
<div class="DB-PULSE-CONTRIB">
<span class="AV-STACK">
<span class="AV" style="width:15px;height:15px;background:#5a8a6a;border:1.5px solid #fff">AN</span>
<span class="AV" style="width:15px;height:15px;background:#3060b0;border:1.5px solid #fff">KL</span>
<span class="AV" style="width:15px;height:15px;background:#a0522d;border:1.5px solid #fff">OS</span>
<span class="AV" style="width:15px;height:15px;background:#7a4f9a;border:1.5px solid #fff">MR</span>
<span class="AV" style="width:15px;height:15px;background:#c0446e;border:1.5px solid #fff">LO</span>
</span>
<span class="DB-PULSE-CONTRIB-LABEL">6 Mitwirkende</span>
</div>
<div class="DB-PULSE-STATS">
<div class="DB-PULSE-STAT">
<div class="DB-PULSE-STAT-N">23<span class="DB-PULSE-STAT-DOT" style="background:#00c7b1"></span></div>
<div class="DB-PULSE-STAT-LABEL">Briefe transkribiert</div>
</div>
<div class="DB-PULSE-STAT">
<div class="DB-PULSE-STAT-N">9<span class="DB-PULSE-STAT-DOT" style="background:#5a8a6a"></span></div>
<div class="DB-PULSE-STAT-LABEL">Briefe geprüft</div>
</div>
<div class="DB-PULSE-STAT">
<div class="DB-PULSE-STAT-N">47<span class="DB-PULSE-STAT-DOT" style="background:#3060b0"></span></div>
<div class="DB-PULSE-STAT-LABEL">Seiten hochgeladen</div>
</div>
</div>
</div>
<!-- Activity feed -->
<div class="DB-CARD">
<div class="DB-FEED">
<div class="DB-SCAP"><span class="DB-SCAP-TEXT">Kommentare &amp; Aktivität</span><span class="DB-SCAP-RULE"></span><a class="DB-SCAP-ACT" href="#">Alle</a></div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#5a8a6a;flex-shrink:0">AN</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Anna</strong> <span style="color:#4b5563">hat transkribiert</span> <a href="#">Postkarte aus Wien</a></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#00c7b1"></span>vor 12 Min.</div>
</div>
</div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#3060b0;flex-shrink:0">KL</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Klaus</strong> <span style="color:#4b5563">hat dich erwähnt in</span> <a href="#">Brief an Frieda</a><span class="DB-FOR-YOU">für dich</span></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#c0446e"></span>vor 1 Std.</div>
</div>
</div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#a0522d;flex-shrink:0">OS</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Oskar</strong> <span style="color:#4b5563">hat zugeordnet</span> <a href="#">Konvolut Rose, Heft III</a></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#a0522d"></span>vor 3 Std.</div>
</div>
</div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#c0446e;flex-shrink:0">LO</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Lotte</strong> <span style="color:#4b5563">hat geantwortet auf</span> <a href="#">deinem Kommentar</a><span class="DB-FOR-YOU">für dich</span></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#7a4f9a"></span>gestern</div>
</div>
</div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#c17a00;flex-shrink:0">TH</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Theo</strong> <span style="color:#4b5563">hat 4 Scans hochgeladen</span> <a href="#">Mappe B</a></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#3060b0"></span>gestern</div>
</div>
</div>
</div>
</div>
<!-- Dropzone -->
<div class="DB-CARD" style="padding:13px 15px">
<div class="DB-SCAP"><span class="DB-SCAP-TEXT">Hochladen</span><span class="DB-SCAP-RULE"></span></div>
<div class="DB-DROP">
<div style="font-size:16px;opacity:.4"></div>
<div class="DB-DROP-TITLE">Neue Scans hochladen</div>
<div class="DB-DROP-SUB">Hierher ziehen oder klicken</div>
<div class="DB-DROP-HINT">PDF, JPG, PNG bis 50 MB</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Page structure<span>routes/+page.svelte + +page.server.ts</span></div>
<table>
<tr><th>Element</th><th>Tailwind classes</th><th>Real px</th><th>Notes</th></tr>
<tr><td>Page background</td><td><code>min-h-screen bg-canvas</code></td><td></td><td>Canvas = <code>#f0efe9</code></td></tr>
<tr><td>Main content wrapper</td><td><code>max-w-screen-xl mx-auto px-8 py-8</code></td><td>32px padding, 1280px max</td><td></td></tr>
<tr><td>2-column layout grid</td><td><code>grid grid-cols-[1fr_320px] gap-5 items-start</code></td><td>20px gap, 320px sidebar</td><td>Collapses to 1-col on mobile</td></tr>
<tr><td>Main column</td><td><code>flex flex-col gap-5</code></td><td>20px gap between sections</td><td></td></tr>
<tr><td>Sidebar</td><td><code>flex flex-col gap-5</code></td><td>20px gap</td><td>Sticky on tall viewports: <code>sticky top-[80px]</code> (below header)</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 2 — HEADER + NAV
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">2</span> Header — authenticated nav bar</div>
<div class="sg sg-2" style="gap:20px">
<div class="sb">
<span class="state-label st-default">Dokumente active</span>
<div class="wf">
<div class="DB-HDR">
<div class="DB-STRIPE"></div>
<div class="DB-NAV">
<span class="DB-WORDMARK">Familienarchiv</span>
<a class="DB-NAVLINK on" href="#">Dokumente</a>
<a class="DB-NAVLINK" href="#">Personen</a>
<a class="DB-NAVLINK" href="#">Briefwechsel</a>
<div class="DB-HDR-ACTIONS">
<div class="DB-UPLOAD-BTN">↑ Hochladen</div>
<div class="DB-AVATAR">MR</div>
</div>
</div>
</div>
</div>
<div class="sc">Active nav item: white text + 2px mint border-bottom. Upload button: ghost (transparent bg, 25% white border).</div>
</div>
<div class="sb">
<span class="state-label st-hover">Upload button — hover</span>
<div class="wf">
<div class="DB-HDR">
<div class="DB-STRIPE"></div>
<div class="DB-NAV">
<span class="DB-WORDMARK">Familienarchiv</span>
<a class="DB-NAVLINK on" href="#">Dokumente</a>
<a class="DB-NAVLINK" href="#">Personen</a>
<a class="DB-NAVLINK" href="#">Briefwechsel</a>
<div class="DB-HDR-ACTIONS">
<div class="DB-UPLOAD-BTN" style="background:rgba(255,255,255,.12)">↑ Hochladen</div>
<div class="DB-AVATAR">MR</div>
</div>
</div>
</div>
</div>
<div class="sc">Hover: rgba(255,255,255,.12) bg tint on upload button.</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Header (authenticated)<span>routes/+layout.svelte (existing — minimal changes needed)</span></div>
<table>
<tr><th>Element</th><th>Tailwind classes</th><th>Real px</th><th>Notes</th></tr>
<tr><td>Header</td><td><code>sticky top-0 z-50 bg-[#012851]</code></td><td></td><td>Already implemented — no change needed</td></tr>
<tr><td>Mint stripe</td><td><code>h-1 bg-accent</code></td><td>4px</td><td>Already implemented</td></tr>
<tr><td>Nav bar height</td><td><code>h-16 flex items-center px-8</code></td><td>64px</td><td>Already implemented</td></tr>
<tr><td>Upload button (new)</td><td><code>inline-flex items-center gap-2 border border-white/25 text-white font-sans text-[11px] font-bold tracking-[.12em] uppercase px-3.5 py-1.5 rounded-sm hover:bg-white/10 transition-colors</code></td><td>11px font</td><td>New addition to existing header. Routes to <code>/documents/new</code> or triggers upload modal.</td></tr>
<tr><td>User avatar</td><td><code>w-8 h-8 rounded-full bg-white text-ink font-sans text-[11px] font-bold flex items-center justify-center</code></td><td>32px</td><td>Shows user initials. Click → user menu (out of scope for this issue).</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 3 — GREETING + SEARCH BAR
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">3</span> Greeting + search bar</div>
<div class="sg sg-2" style="gap:20px">
<div class="sb">
<span class="state-label st-default">Morning greeting (activity-aware)</span>
<div class="wf">
<div style="padding:18px;background:#f0efe9">
<div class="DB-GREET">
<div class="DB-GREET-H">Guten Morgen, Marie.</div>
<div class="DB-GREET-SUB">Klaus hat dich gestern in einem Brief erwähnt, und Anna wartet auf deine Meinung zur <a href="#">„Postkarte aus Wien"</a>.</div>
</div>
<div class="DB-SEARCH">
<div style="flex:1;height:20px;border:1px solid #e4e2d7;background:#fff;display:flex;align-items:center;padding:0 8px;font-size:8.5px;color:#9ca3af;font-style:italic;border-radius:2px">Titel, Personen, Tags durchsuchen…</div>
<div class="DB-SEARCH-FILTER">Filter</div>
</div>
</div>
</div>
<div class="sc">Greeting text changes by time of day: "Guten Morgen" (&lt;11h), "Hallo" (1118h), "Guten Abend" (&gt;18h).</div>
</div>
<div class="sb">
<span class="state-label st-focus">Search — focused state</span>
<div class="wf">
<div style="padding:18px;background:#f0efe9">
<div class="DB-GREET">
<div class="DB-GREET-H">Hallo, Marie.</div>
<div class="DB-GREET-SUB">Klaus hat dich gestern in einem Brief erwähnt.</div>
</div>
<div class="DB-SEARCH">
<div style="flex:1;height:20px;border:1px solid #012851;background:#fff;display:flex;align-items:center;padding:0 8px;font-size:8.5px;color:#012851;border-radius:2px;box-shadow:0 0 0 1.5px rgba(1,40,81,.15)">Frieda Lehmann</div>
<div class="DB-SEARCH-FILTER">Filter</div>
</div>
</div>
</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Greeting + Search<span>routes/+page.svelte</span></div>
<table>
<tr><th>Element</th><th>Tailwind / implementation</th><th>Real px</th><th>Notes</th></tr>
<tr><td>Greeting wrapper</td><td><code>mb-5</code></td><td>20px bottom margin</td><td></td></tr>
<tr><td>Greeting headline</td><td><code>font-serif font-normal text-[32px] leading-tight text-ink</code></td><td>32px</td><td>Time-of-day: <code>getHours() &lt; 11 → m.greeting_morning()</code>. Uses logged-in user's first name from <code>data.currentUser.firstName</code>.</td></tr>
<tr><td>Greeting subtitle</td><td><code>font-serif text-[17px] text-ink-2 mt-2 leading-[1.45]</code></td><td>17px</td><td>Driven by actual notification data. Priority: @mention &gt; reply &gt; new scan. Links to document. Falls back to a neutral welcome if no recent activity.</td></tr>
<tr><td>Search bar card</td><td><code>bg-surface border border-line shadow-sm rounded-sm p-5 mb-6 flex items-center gap-3</code></td><td>20px padding, 24px bottom margin</td><td>Same component as existing <code>SearchFilterBar.svelte</code> — no change needed.</td></tr>
<tr><td>Search input</td><td><code>flex-1 border border-line px-3.5 py-3 font-serif text-base text-ink placeholder:text-ink-3 rounded-none focus-visible:ring-2 focus-visible:ring-focus-ring/15 focus-visible:border-ink</code></td><td>16px font / 48px tall</td><td>Already implemented in SearchFilterBar.</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 4 — HERO RESUME CARD
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">4</span> Hero — "Weiter, wo du aufgehört hast"</div>
<div class="sg sg-2" style="gap:20px">
<div class="sb">
<span class="state-label st-default">Default — in-progress letter</span>
<div class="wf">
<div class="DB-CARD DB-HERO" style="margin:0">
<div class="DB-HERO-THUMB">
<svg viewBox="0 0 99 135" width="99" height="135" class="LT">
<defs><linearGradient id="pb" x1="0" x2="0" y1="0" y2="1"><stop offset="0" stop-color="#f1e6cc"/><stop offset="1" stop-color="#e7d8b3"/></linearGradient></defs>
<rect x="0" y="0" width="99" height="135" fill="url(#pb)"/>
<line x1="49.5" y1="0" x2="49.5" y2="135" stroke="#9a7b50" stroke-width=".4" opacity=".3"/>
<rect x="10" y="16" width="50" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="24" width="65" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="32" width="38" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="51" y="32" width="28" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="40" width="72" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="48" width="44" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="56" width="60" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="64" width="32" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="72" width="55" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="80" width="48" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="88" width="68" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="96" width="40" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="104" width="56" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<rect x="10" y="112" width="30" height="2" rx="1" fill="#3a2a18" opacity=".65"/>
<path d="M14 126 q10-10 22-2 t18-3" fill="none" stroke="#3a2a18" stroke-width="1.4" opacity=".7" stroke-linecap="round"/>
</svg>
</div>
<div class="DB-HERO-CONTENT">
<div class="DB-HERO-EYEBROW">
<span class="DB-HERO-LABEL"><span class="DB-HERO-DOT"></span>Weiter, wo du aufgehört hast</span>
<span class="DB-HERO-PAGE">Seite 2 von 4</span>
</div>
<div class="DB-HERO-TITLE">Brief an Frieda aus dem Harz</div>
<div class="DB-HERO-CAPTION">Frieda Lehmann an Wilhelm Lehmann · Bad Sachsa, 14. März 1923</div>
<div class="DB-HERO-QUOTE">„Liebe Frieda, der Schnee ist endlich gewichen und die Wege wieder begehbar. Vater hat heute Morgen geschrieben…"</div>
<div class="DB-HERO-PROG-ROW">
<span>Transkription 38%</span>
<span style="display:inline-flex;align-items:center;gap:5px">
<span class="AV-STACK">
<span class="AV" style="width:11px;height:11px;background:#7a4f9a;border:1.5px solid #fff">MR</span>
<span class="AV" style="width:11px;height:11px;background:#5a8a6a;border:1.5px solid #fff">AN</span>
</span>
<span style="font-size:6px;color:#6b7280">du und Anna</span>
</span>
</div>
<div class="DB-PROG"><div class="DB-PROG-FILL" style="width:38%;background:#00c7b1"></div></div>
<div class="DB-HERO-BTNS">
<button class="DB-BTN-NAVY">✏ Weitertranskribieren</button>
<span class="DB-LINK-GHOST">oder anderen Brief wählen</span>
</div>
</div>
</div>
</div>
<div class="sc">Thumbnail only here — 180×246px on real page. This is the only location large enough to make kurrent legible.</div>
</div>
<div class="sb">
<span class="state-label st-default">No in-progress letter (empty state)</span>
<div class="wf">
<div class="DB-CARD" style="padding:22px;text-align:center">
<div style="font-size:22px;margin-bottom:9px;opacity:.35"></div>
<div style="font-size:13px;font-weight:400;color:#012851;font-family:Georgia,serif;margin-bottom:5px">Wo möchtest du anfangen?</div>
<div style="font-size:8px;color:#6b7280;font-family:Georgia,serif;margin-bottom:11px;line-height:1.5">Wähle einen Brief aus einer der Warteschlangen unten oder durchsuche das Archiv.</div>
<button class="DB-BTN-NAVY" style="font-size:6px;padding:7px 10px">Zum Archiv →</button>
</div>
</div>
<div class="sc">Shown when the user has no in-progress transcription task.</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Hero resume card<span>lib/components/DashboardResumeStrip.svelte (refactor from existing)</span></div>
<table>
<tr><th>Element</th><th>Tailwind classes</th><th>Real px</th><th>Notes</th></tr>
<tr><td>Hero card</td><td><code>bg-surface border border-line shadow-sm rounded-sm p-7 grid grid-cols-[180px_1fr] gap-8 items-center</code></td><td>28px padding, 32px gap</td><td>Collapses to single-column on mobile: <code>sm:grid-cols-[180px_1fr]</code></td></tr>
<tr><td>Letter thumbnail</td><td><code>w-[180px] h-[246px] rounded-sm shadow-sm flex-shrink-0</code></td><td>180×246px</td><td>Real scan image when available; SVG placeholder when not. <code>&lt;img&gt;</code> with <code>object-cover</code>.</td></tr>
<tr><td>Eyebrow label</td><td><code>inline-flex items-center gap-2 font-sans text-[11px] font-bold tracking-[.18em] uppercase text-turquoise</code></td><td>11px</td><td>Dot: <code>w-2 h-2 rounded-full bg-turquoise</code>. i18n: <code>m.dashboard_resume_label()</code></td></tr>
<tr><td>Page counter</td><td><code>font-sans text-[11px] tracking-[.12em] uppercase text-ink-3</code></td><td>11px</td><td><code>m.dashboard_page_of({ page, pages })</code></td></tr>
<tr><td>Letter title</td><td><code>font-serif font-normal text-[30px] leading-tight text-ink mb-1.5</code></td><td>30px</td><td>From <code>document.title</code></td></tr>
<tr><td>Archival caption</td><td><code>font-serif text-sm italic text-ink-3 mb-4</code></td><td>14px</td><td>"{from} an {to} · {place}, {date}"</td></tr>
<tr><td>Excerpt pull-quote</td><td><code>font-serif text-[17px] italic leading-[1.55] text-ink-2 border-l-[3px] border-accent pl-4 mb-5</code></td><td>17px, 3px left border (mint)</td><td>First 200 chars of transcription draft or OCR excerpt.</td></tr>
<tr><td>Progress row</td><td><code>flex justify-between items-center font-sans text-xs text-ink-3 mb-2</code></td><td>12px</td><td>Left: "{pct}% transkribiert". Right: avatar stack + collaborator names.</td></tr>
<tr><td>Progress bar</td><td><code>w-full h-1.5 bg-[#eeede8] rounded-full overflow-hidden mb-5</code></td><td>6px</td><td>Fill: <code>bg-turquoise</code> (<code>#00c7b1</code>). This is per-letter (clear denominator) — motivating, not crushing.</td></tr>
<tr><td>Primary CTA</td><td><code>bg-primary text-primary-fg font-sans text-xs font-bold tracking-[.12em] uppercase px-5 py-3 rounded-sm inline-flex items-center gap-2.5</code></td><td>12px</td><td>href="/documents/{id}/edit". i18n: <code>m.dashboard_resume_cta()</code></td></tr>
<tr><td>"oder anderen Brief" link</td><td><code>font-sans text-xs font-semibold text-ink-2 underline decoration-[#cdcbbf] underline-offset-[4px]</code></td><td>12px</td><td>href="/" (to search). Not a button — no prominent treatment.</td></tr>
<tr><td>Empty state</td><td>Centered card with envelope icon, serif heading, body, CTA button</td><td></td><td>Shown when backend returns no active transcription for current user.</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 5 — MISSION CONTROL
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">5</span> Mission Control — 3-column task queues</div>
<div class="sg sg-3" style="gap:14px">
<!-- Segmentieren -->
<div class="sb">
<span class="state-label st-default">Segmentieren — row states</span>
<div class="wf">
<div class="MC-COL">
<div class="MC-HDR" style="background:rgba(160,82,45,.06)">
<div class="MC-HDR-ROW"><span class="MC-LABEL">Segmentieren</span><span class="MC-COUNT">5 offen</span></div>
<div class="MC-BLURB">Seiten zu Briefen zuordnen.</div>
</div>
<div class="MC-ROWS">
<div class="MC-ROW" style="background:#f7f6f1"><div class="MC-ROW-BODY"><div class="MC-TITLE">Konvolut Rose, Heft III</div><div class="MC-META"><span>Mappe A</span><span class="MC-SEP">·</span><span>14 Seiten</span></div></div><span class="AV" style="width:12px;height:12px;background:#5a8a6a">AN</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Umschlag Mariahilf</div><div class="MC-META"><span>19. Nov 1925</span><span class="MC-SEP">·</span><span>3 Seiten</span></div></div><span class="MC-AV-EMPTY"></span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Mappe B — unsortiert</div><div class="MC-META"><span>neu, 18. Apr</span><span class="MC-SEP">·</span><span>27 Seiten</span></div></div><span class="MC-AV-EMPTY"></span></div>
</div>
<a class="MC-FOOT" href="#">Alle anzeigen →</a>
</div>
</div>
<div class="sc">Row with sienna tint = hover state. Filled avatar = someone has started it. Dashed circle = nobody started yet.</div>
</div>
<!-- Transkribieren -->
<div class="sb">
<span class="state-label st-default">Transkribieren — with % progress</span>
<div class="wf">
<div class="MC-COL">
<div class="MC-HDR" style="background:rgba(0,199,177,.08)">
<div class="MC-HDR-ROW"><span class="MC-LABEL">Transkribieren</span><span class="MC-COUNT">5 offen</span></div>
<div class="MC-BLURB">Alte Handschriften lesen und abtippen.</div>
</div>
<div class="MC-ROWS">
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Brief an Frieda aus dem Harz</div><div class="MC-META"><span>14. März 1923</span><span class="MC-SEP">·</span><span>38%</span></div></div><span class="AV" style="width:12px;height:12px;background:#7a4f9a">MR</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Postkarte aus Wien</div><div class="MC-META"><span>2. Aug 1924</span><span class="MC-SEP">·</span><span>60%</span></div></div><span class="AV" style="width:12px;height:12px;background:#a0522d">OS</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Geburtstagsbrief</div><div class="MC-META"><span>22. Mai 1928</span><span class="MC-SEP">·</span><span>5%</span></div></div><span class="AV" style="width:12px;height:12px;background:#c0446e">LO</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Brief aus Hamburg</div><div class="MC-META"><span>3. Juni 1929</span></div></div><span class="MC-AV-EMPTY"></span></div>
</div>
<a class="MC-FOOT" href="#">Alle anzeigen →</a>
</div>
</div>
<div class="sc">Percentage shown inline in metadata for in-progress items. No progress bar in rows — that would be too heavy.</div>
</div>
<!-- Prüfen -->
<div class="sb">
<span class="state-label st-active">Prüfen — all complete</span>
<div class="wf">
<div class="MC-COL">
<div class="MC-HDR" style="background:rgba(90,138,106,.08)">
<div class="MC-HDR-ROW"><span class="MC-LABEL">Prüfen</span><span class="MC-COUNT">4 offen</span></div>
<div class="MC-BLURB">Letzte Korrektur und freigeben.</div>
</div>
<div class="MC-ROWS">
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Brief aus der Lehrzeit</div><div class="MC-META"><span>8. Okt 1930</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig ✓</span></div></div><span class="AV" style="width:12px;height:12px;background:#c17a00">TH</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Weihnachtsgruß</div><div class="MC-META"><span>21. Dez 1931</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig ✓</span></div></div><span class="AV" style="width:12px;height:12px;background:#7a4f9a">MR</span></div>
<div class="MC-ROW"><div class="MC-ROW-BODY"><div class="MC-TITLE">Geschäftsbrief Mariahilf</div><div class="MC-META"><span>19. Nov 1925</span><span class="MC-SEP">·</span><span class="MC-PCT-OK">fertig ✓</span></div></div><span class="AV" style="width:12px;height:12px;background:#3060b0">KL</span></div>
</div>
<a class="MC-FOOT" href="#">Alle anzeigen →</a>
</div>
</div>
<div class="sc">Green "fertig" label when pct === 100. Still shows in queue until someone actively reviews and archives.</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Mission Control<span>lib/components/MissionControlStrip.svelte (refactor from existing)</span></div>
<table>
<tr><th>Element</th><th>Tailwind classes</th><th>Real px</th><th>Notes</th></tr>
<tr><td>3-column grid</td><td><code>grid grid-cols-3 gap-4</code></td><td>16px gap</td><td>Collapses to 1-col on mobile</td></tr>
<tr><td>Column card</td><td><code>bg-surface border border-line rounded-sm overflow-hidden flex flex-col</code></td><td></td><td></td></tr>
<tr><td>Column header — Segmentieren</td><td><code>p-4 border-b border-[#eeede8] bg-[rgba(160,82,45,.06)]</code></td><td>16px padding</td><td>Sienna tint</td></tr>
<tr><td>Column header — Transkribieren</td><td><code>bg-[rgba(0,199,177,.08)]</code></td><td></td><td>Turquoise tint</td></tr>
<tr><td>Column header — Prüfen</td><td><code>bg-[rgba(90,138,106,.08)]</code></td><td></td><td>Sage tint</td></tr>
<tr><td>Column label</td><td><code>font-sans text-[12px] font-bold tracking-[.16em] uppercase text-ink</code></td><td>12px</td><td>i18n: <code>m.queue_segment()</code>, <code>m.queue_transcribe()</code>, <code>m.queue_review()</code></td></tr>
<tr><td>Open count</td><td><code>font-sans text-[11px] text-ink-3</code></td><td>11px</td><td>"{n} offen"</td></tr>
<tr><td>Column blurb</td><td><code>font-serif text-[13px] text-ink-2 leading-snug mt-1.5</code></td><td>13px</td><td>i18n keys: <code>m.queue_segment_blurb()</code> etc.</td></tr>
<tr><td>Task row wrapper</td><td><code>p-1.5</code></td><td>6px</td><td>Padding around all rows within the column body.</td></tr>
<tr><td>Task row</td><td><code>&lt;a&gt; flex items-center gap-3 px-3.5 py-2.5 rounded-sm hover:bg-[#f7f6f1] transition-colors no-underline</code></td><td>14px/10px padding</td><td>Entire row is a link to the document edit page.</td></tr>
<tr><td>Task title</td><td><code>font-serif text-base text-ink truncate leading-snug</code></td><td>16px</td><td>Single line, truncated with ellipsis.</td></tr>
<tr><td>Task metadata</td><td><code>font-sans text-[12px] text-ink-3 mt-0.5 flex items-center gap-2</code></td><td>12px</td><td>Hint · separator · pages or % or "fertig". "fertig" = <code>text-[#5a8a6a] font-semibold</code>.</td></tr>
<tr><td>Starter avatar (filled)</td><td><code>w-[22px] h-[22px] rounded-full flex-shrink-0</code></td><td>22px</td><td>Uses person's <code>color</code> from the persons list.</td></tr>
<tr><td>Starter avatar (empty)</td><td><code>w-[22px] h-[22px] rounded-full border-[1.5px] border-dashed border-[#cdcbbf] flex-shrink-0</code></td><td>22px</td><td>Title attribute: "noch niemand angefangen" (tooltip).</td></tr>
<tr><td>"Alle anzeigen" footer</td><td><code>text-center py-2.5 font-sans text-[11px] font-bold tracking-[.12em] uppercase text-ink border-t border-[#eeede8] mt-auto block</code></td><td>11px</td><td>Links to filtered document list for that queue.</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 6 — FAMILY PULSE SIDEBAR
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">6</span> Family Pulse — sidebar "Diese Woche"</div>
<div class="sg sg-2" style="gap:20px;max-width:800px">
<div class="sb">
<span class="state-label st-default">Normal week</span>
<div class="wf" style="max-width:360px">
<div class="DB-PULSE" style="border-radius:0;box-shadow:none;border:none;border-bottom:1px solid #e4e2d7">
<div class="DB-PULSE-EYE">Diese Woche · gemeinsam</div>
<div class="DB-PULSE-HEADLINE">Ihr habt zusammen <strong>86 Seiten</strong> bearbeitet.</div>
<div class="DB-PULSE-SUB">Du selbst hast 4 davon transkribiert.</div>
<div class="DB-PULSE-CONTRIB">
<span class="AV-STACK">
<span class="AV" style="width:15px;height:15px;background:#5a8a6a;border:1.5px solid #fff">AN</span>
<span class="AV" style="width:15px;height:15px;background:#3060b0;border:1.5px solid #fff">KL</span>
<span class="AV" style="width:15px;height:15px;background:#a0522d;border:1.5px solid #fff">OS</span>
<span class="AV" style="width:15px;height:15px;background:#7a4f9a;border:1.5px solid #fff">MR</span>
<span class="AV" style="width:15px;height:15px;background:#c0446e;border:1.5px solid #fff">LO</span>
<span class="AV" style="width:15px;height:15px;background:#c17a00;border:1.5px solid #fff">TH</span>
</span>
<span class="DB-PULSE-CONTRIB-LABEL">6 Mitwirkende</span>
</div>
<div class="DB-PULSE-STATS">
<div class="DB-PULSE-STAT"><div class="DB-PULSE-STAT-N">23<span class="DB-PULSE-STAT-DOT" style="background:#00c7b1"></span></div><div class="DB-PULSE-STAT-LABEL">Briefe transkribiert</div></div>
<div class="DB-PULSE-STAT"><div class="DB-PULSE-STAT-N">9<span class="DB-PULSE-STAT-DOT" style="background:#5a8a6a"></span></div><div class="DB-PULSE-STAT-LABEL">Briefe geprüft</div></div>
<div class="DB-PULSE-STAT"><div class="DB-PULSE-STAT-N">47<span class="DB-PULSE-STAT-DOT" style="background:#3060b0"></span></div><div class="DB-PULSE-STAT-LABEL">Seiten hochgeladen</div></div>
</div>
</div>
</div>
</div>
<div class="sb">
<span class="state-label st-default">Quiet week (low numbers)</span>
<div class="wf" style="max-width:360px">
<div class="DB-PULSE" style="border-radius:0;box-shadow:none;border:none;border-bottom:1px solid #e4e2d7">
<div class="DB-PULSE-EYE">Diese Woche · gemeinsam</div>
<div class="DB-PULSE-HEADLINE">Ihr habt zusammen <strong>4 Seiten</strong> bearbeitet.</div>
<div class="DB-PULSE-SUB">Du selbst hast 1 davon transkribiert.</div>
<div class="DB-PULSE-CONTRIB">
<span class="AV-STACK">
<span class="AV" style="width:15px;height:15px;background:#5a8a6a;border:1.5px solid #fff">AN</span>
<span class="AV" style="width:15px;height:15px;background:#7a4f9a;border:1.5px solid #fff">MR</span>
</span>
<span class="DB-PULSE-CONTRIB-LABEL">2 Mitwirkende diese Woche</span>
</div>
<div class="DB-PULSE-STATS">
<div class="DB-PULSE-STAT"><div class="DB-PULSE-STAT-N">2<span class="DB-PULSE-STAT-DOT" style="background:#00c7b1"></span></div><div class="DB-PULSE-STAT-LABEL">Briefe transkribiert</div></div>
<div class="DB-PULSE-STAT"><div class="DB-PULSE-STAT-N">0<span class="DB-PULSE-STAT-DOT" style="background:#5a8a6a"></span></div><div class="DB-PULSE-STAT-LABEL">Briefe geprüft</div></div>
<div class="DB-PULSE-STAT"><div class="DB-PULSE-STAT-N">2<span class="DB-PULSE-STAT-DOT" style="background:#3060b0"></span></div><div class="DB-PULSE-STAT-LABEL">Seiten hochgeladen</div></div>
</div>
</div>
</div>
<div class="sc">Low numbers are fine — no framing around "goal". The number grows; no ceiling. Never shows 1,500 total.</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Family Pulse<span>lib/components/ (new component) — DashboardFamilyPulse.svelte</span></div>
<table>
<tr><th>Element</th><th>Tailwind classes</th><th>Real px</th><th>Notes</th></tr>
<tr><td>Card</td><td><code>bg-surface border border-line shadow-sm rounded-sm p-6</code></td><td>24px padding</td><td>White card — intentionally same as other sidebar cards (no warm cream — confirmed decision).</td></tr>
<tr><td>Eyebrow</td><td><code>font-sans text-[11px] font-bold tracking-[.18em] uppercase text-ink-3 mb-2</code></td><td>11px</td><td>i18n: <code>m.pulse_eyebrow()</code> = "Diese Woche · gemeinsam"</td></tr>
<tr><td>Headline</td><td><code>font-serif text-[22px] font-normal leading-snug text-ink mb-1</code></td><td>22px</td><td>i18n: <code>m.pulse_headline({ pages })</code>. Strong tag on the number: <code>font-semibold</code>.</td></tr>
<tr><td>Personal contribution</td><td><code>font-serif text-[14px] text-ink-3 mb-4</code></td><td>14px</td><td>i18n: <code>m.pulse_you({ pages })</code>. Hidden when current user's contribution = 0.</td></tr>
<tr><td>Avatar stack</td><td><code>inline-flex items-center</code> with <code>-ml-2</code> on all except first</td><td>28px avatars, -8px overlap</td><td>Shows contributors who participated this week. <code>ring-2 ring-white</code> on each.</td></tr>
<tr><td>Contributor count</td><td><code>font-sans text-xs text-ink-3 ml-3</code></td><td>12px</td><td>"{n} Mitwirkende"</td></tr>
<tr><td>3-stat grid</td><td><code>grid grid-cols-3 gap-2.5 mt-4</code></td><td>10px gap, 16px top margin</td><td></td></tr>
<tr><td>Stat card</td><td><code>bg-[#faf9f4] border border-[#eeede8] rounded-sm p-3.5</code></td><td>14px padding</td><td></td></tr>
<tr><td>Big number</td><td><code>font-serif text-[30px] font-normal text-ink leading-none flex items-baseline gap-2</code></td><td>30px</td><td>Dot: <code>w-1.5 h-1.5 rounded-full flex-shrink-0</code> in kind color.</td></tr>
<tr><td>Stat label</td><td><code>font-sans text-[12px] text-ink-3 mt-1.5</code></td><td>12px</td><td>i18n: <code>m.pulse_transcribed()</code>, <code>m.pulse_reviewed()</code>, <code>m.pulse_uploaded()</code></td></tr>
<tr><td>Data source</td><td></td><td></td><td>New backend endpoint: <code>GET /api/dashboard/pulse?period=week</code>. Returns <code>{ transcribed, reviewed, uploaded, pages, you: { pages }, contributors: Person[] }</code>.</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 7 — ACTIVITY FEED + DROPZONE
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">7</span> Activity feed &amp; sidebar dropzone</div>
<div class="sg sg-3" style="gap:16px;align-items:start">
<!-- Feed — default -->
<div class="sb">
<span class="state-label st-default">Activity feed</span>
<div class="wf">
<div class="DB-FEED">
<div class="DB-SCAP"><span class="DB-SCAP-TEXT">Kommentare &amp; Aktivität</span><span class="DB-SCAP-RULE"></span><a class="DB-SCAP-ACT" href="#">Alle</a></div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#5a8a6a;flex-shrink:0">AN</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Anna</strong> <span style="color:#4b5563">hat transkribiert</span> <a href="#">Postkarte aus Wien</a></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#00c7b1"></span>vor 12 Min.</div>
</div>
</div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#3060b0;flex-shrink:0">KL</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Klaus</strong> <span style="color:#4b5563">hat dich erwähnt in</span> <a href="#">Brief an Frieda</a><span class="DB-FOR-YOU">für dich</span></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#c0446e"></span>vor 1 Std.</div>
</div>
</div>
<div class="DB-FEED-ITEM">
<span class="AV" style="width:20px;height:20px;background:#c0446e;flex-shrink:0">LO</span>
<div class="DB-FEED-BODY">
<div class="DB-FEED-TEXT"><strong>Lotte</strong> <span style="color:#4b5563">hat geantwortet auf</span> <a href="#">deinem Kommentar</a><span class="DB-FOR-YOU">für dich</span></div>
<div class="DB-FEED-WHEN"><span class="DB-FEED-DOT" style="background:#7a4f9a"></span>gestern</div>
</div>
</div>
</div>
</div>
<div class="sc">Tinted dot = activity kind (turquoise = transcribe, pink = mention, purple = reply, sienna = segment, blue = upload). "für dich" badge on @mentions and replies.</div>
</div>
<!-- Dropzone — default -->
<div class="sb">
<span class="state-label st-default">Dropzone — idle</span>
<div class="wf">
<div style="padding:13px 15px">
<div class="DB-SCAP"><span class="DB-SCAP-TEXT">Hochladen</span><span class="DB-SCAP-RULE"></span></div>
<div class="DB-DROP">
<div style="font-size:24px;opacity:.4"></div>
<div class="DB-DROP-TITLE">Neue Scans hochladen</div>
<div class="DB-DROP-SUB">Hierher ziehen oder klicken</div>
<div class="DB-DROP-HINT">PDF, JPG, PNG bis 50 MB</div>
</div>
</div>
</div>
</div>
<!-- Dropzone — drag over -->
<div class="sb">
<span class="state-label st-hover">Dropzone — drag active</span>
<div class="wf">
<div style="padding:13px 15px">
<div class="DB-SCAP"><span class="DB-SCAP-TEXT">Hochladen</span><span class="DB-SCAP-RULE"></span></div>
<div class="DB-DROP" style="border-color:#012851;background:rgba(161,220,216,.18)">
<div style="font-size:24px;opacity:.7"></div>
<div class="DB-DROP-TITLE" style="color:#012851">Loslassen zum Hochladen</div>
<div class="DB-DROP-SUB">PDF, JPG, PNG bis 50 MB</div>
</div>
</div>
</div>
<div class="sc">Drag-over: navy border, mint tint bg, title changes to "Loslassen zum Hochladen".</div>
</div>
</div>
<div class="impl-ref">
<div class="impl-ref-hdr">Implementation Reference — Activity feed &amp; dropzone<span>routes/+page.svelte (new feed) + routes/DropZone.svelte (existing, minor tweaks)</span></div>
<table>
<tr><th>Element</th><th>Tailwind classes</th><th>Real px</th><th>Notes</th></tr>
<tr><td>Feed card wrapper</td><td><code>bg-surface border border-line shadow-sm rounded-sm p-5</code></td><td>20px padding</td><td></td></tr>
<tr><td>Feed item</td><td><code>flex gap-3.5 items-start py-3.5 border-b border-[#eeede8] last:border-b-0</code></td><td>14px padding, 14px gap</td><td></td></tr>
<tr><td>Feed avatar</td><td><code>w-9 h-9 rounded-full flex-shrink-0</code></td><td>36px</td><td>Color from person's <code>color</code> field.</td></tr>
<tr><td>Feed text</td><td><code>font-serif text-[15px] leading-snug text-ink</code></td><td>15px</td><td>Name: <code>font-sans text-[13px] font-bold</code>. Verb: <code>text-ink-2</code>. Target: link <code>text-ink underline underline-offset-[2px]</code>.</td></tr>
<tr><td>"für dich" badge</td><td><code>ml-2 inline-block px-2 py-px border border-accent rounded-full font-sans text-[10px] font-bold tracking-[.12em] uppercase text-ink bg-accent/20 align-middle</code></td><td>10px</td><td>Only shown when <code>activity.you === true</code> (mention or reply to current user).</td></tr>
<tr><td>Timestamp row</td><td><code>mt-1 inline-flex items-center gap-2 font-sans text-[11px] text-ink-3</code></td><td>11px</td><td>Kind dot: <code>w-1.5 h-1.5 rounded-full</code> in kind color (see dot-color map below).</td></tr>
<tr><td>Kind → dot color</td><td>transcribe: <code>#00c7b1</code> · segment: <code>#a0522d</code> · review: <code>#5a8a6a</code> · upload: <code>#3060b0</code> · mention: <code>#c0446e</code> · reply: <code>#7a4f9a</code> · tag: <code>#c17a00</code></td><td></td><td>Purely decorative — color-blind safe because avatar + name already identify the person and action.</td></tr>
<tr><td>Dropzone — idle</td><td><code>flex flex-col items-center gap-2.5 py-6 px-4 border border-dashed border-ink/30 rounded-sm text-center transition-all</code></td><td></td><td>Already implemented in <code>DropZone.svelte</code>. Already existing; verify styles match.</td></tr>
<tr><td>Dropzone — drag active</td><td>+ <code>border-ink bg-accent/18</code></td><td></td><td>Title changes to <code>m.dropzone_release()</code>.</td></tr>
<tr><td>Data source — feed</td><td></td><td></td><td>New endpoint: <code>GET /api/dashboard/activity?limit=7</code>. Returns recent actions across all document activity for the archive.</td></tr>
</table>
</div>
</div>
<!-- ══════════════════════════════════════
SECTION 8 — IMPLEMENTATION NOTES
══════════════════════════════════════ -->
<div class="sec">
<div class="sec-h"><span class="sec-num">8</span> Implementation notes — backend, i18n, data model</div>
<div class="sg sg-2" style="gap:20px;align-items:start">
<!-- Backend -->
<div class="sb">
<div class="sl">New backend endpoints</div>
<div class="impl-ref" style="margin-top:0">
<div class="impl-ref-hdr">GET /api/dashboard/*</div>
<table>
<tr><th>Endpoint</th><th>Response</th><th>Notes</th></tr>
<tr><td><code>GET /api/dashboard/resume</code></td><td><code>{ document, page, pages, pct, collaborators: Person[] }</code></td><td>The current user's last-touched in-progress transcription. Returns <code>null</code> when none.</td></tr>
<tr><td><code>GET /api/dashboard/pulse?period=week</code></td><td><code>{ transcribed, reviewed, uploaded, pages, you: { pages, comments }, contributors: Person[] }</code></td><td>Aggregate stats for the current ISO week. Never exposes cumulative total.</td></tr>
<tr><td><code>GET /api/dashboard/activity?limit=7</code></td><td><code>Activity[]</code><code>{ who: Person, verb, target, targetId, when, kind, youMentioned }</code></td><td>Recent archive-wide activity, newest first. <code>youMentioned=true</code> when activity targets the current user.</td></tr>
</table>
</div>
<div class="impl-ref" style="margin-top:12px">
<div class="impl-ref-hdr">Existing endpoints used</div>
<table>
<tr><th>Endpoint</th><th>Used for</th></tr>
<tr><td><code>GET /api/documents?status=UPLOADED&transcriptionPct=0..99&sort=DATE&limit=5</code></td><td>Transkribieren queue</td></tr>
<tr><td><code>GET /api/documents?status=PLACEHOLDER&limit=5</code></td><td>Segmentieren queue</td></tr>
<tr><td><code>GET /api/documents?status=TRANSCRIBED&limit=5</code></td><td>Prüfen queue</td></tr>
<tr><td><code>GET /api/documents?q=&sort=DATE&dir=desc</code></td><td>Search bar (unchanged)</td></tr>
</table>
</div>
</div>
<!-- i18n + components -->
<div class="sb">
<div class="sl">New i18n keys</div>
<div class="impl-ref" style="margin-top:0">
<div class="impl-ref-hdr">messages/de.json additions</div>
<table>
<tr><th>Key</th><th>DE</th></tr>
<tr><td><code>greeting_morning</code></td><td>Guten Morgen, {name}.</td></tr>
<tr><td><code>greeting_day</code></td><td>Hallo, {name}.</td></tr>
<tr><td><code>greeting_evening</code></td><td>Guten Abend, {name}.</td></tr>
<tr><td><code>dashboard_resume_label</code></td><td>Weiter, wo du aufgehört hast</td></tr>
<tr><td><code>dashboard_page_of</code></td><td>Seite {page} von {pages}</td></tr>
<tr><td><code>dashboard_resume_cta</code></td><td>Weitertranskribieren</td></tr>
<tr><td><code>dashboard_resume_other</code></td><td>oder anderen Brief wählen</td></tr>
<tr><td><code>dashboard_empty_title</code></td><td>Wo möchtest du anfangen?</td></tr>
<tr><td><code>dashboard_empty_body</code></td><td>Wähle einen Brief aus einer Warteschlange unten oder durchsuche das Archiv.</td></tr>
<tr><td><code>dashboard_mission_caption</code></td><td>Mitmachen</td></tr>
<tr><td><code>queue_segment</code></td><td>Segmentieren</td></tr>
<tr><td><code>queue_segment_blurb</code></td><td>Seiten zu Briefen zuordnen.</td></tr>
<tr><td><code>queue_transcribe</code></td><td>Transkribieren</td></tr>
<tr><td><code>queue_transcribe_blurb</code></td><td>Alte Handschriften lesen und abtippen.</td></tr>
<tr><td><code>queue_review</code></td><td>Prüfen</td></tr>
<tr><td><code>queue_review_blurb</code></td><td>Letzte Korrektur und freigeben.</td></tr>
<tr><td><code>queue_n_open</code></td><td>{n} offen</td></tr>
<tr><td><code>queue_show_all</code></td><td>Alle anzeigen →</td></tr>
<tr><td><code>pulse_eyebrow</code></td><td>Diese Woche · gemeinsam</td></tr>
<tr><td><code>pulse_headline</code></td><td>Ihr habt zusammen {pages} Seiten bearbeitet.</td></tr>
<tr><td><code>pulse_you</code></td><td>Du selbst hast {pages} davon transkribiert.</td></tr>
<tr><td><code>pulse_contributors</code></td><td>{n} Mitwirkende</td></tr>
<tr><td><code>pulse_transcribed</code></td><td>Briefe transkribiert</td></tr>
<tr><td><code>pulse_reviewed</code></td><td>Briefe geprüft</td></tr>
<tr><td><code>pulse_uploaded</code></td><td>Seiten hochgeladen</td></tr>
<tr><td><code>feed_caption</code></td><td>Kommentare &amp; Aktivität</td></tr>
<tr><td><code>feed_for_you</code></td><td>für dich</td></tr>
<tr><td><code>dropzone_release</code></td><td>Loslassen zum Hochladen</td></tr>
</table>
</div>
<div class="ann-info" style="margin-top:16px">
<strong>Implementation sequence:</strong>
<ul>
<li>1. Add <code>GET /api/dashboard/resume</code>, <code>/pulse</code>, <code>/activity</code> endpoints to Spring Boot</li>
<li>2. Regenerate TypeScript types (<code>npm run generate:api</code>)</li>
<li>3. Update <code>routes/+page.server.ts</code> to load all dashboard data in parallel</li>
<li>4. Refactor <code>DashboardResumeStrip.svelte</code> — add thumb, caption, pull-quote, progress bar, new CTAs</li>
<li>5. Refactor <code>MissionControlStrip.svelte</code> — 3-col grid, TaskRow with avatar-of-starter, accent headers</li>
<li>6. Create <code>DashboardFamilyPulse.svelte</code> (new)</li>
<li>7. Create <code>DashboardActivityFeed.svelte</code> (new) — replaces DashboardRecentDocuments</li>
<li>8. Add greeting headline + subtitle to <code>+page.svelte</code></li>
<li>9. Add Upload button to <code>+layout.svelte</code> header</li>
<li>10. Add all i18n keys to de/en/es message files</li>
</ul>
</div>
</div>
</div>
</div>
</div><!-- /.doc -->
</body>
</html>