docs(specs): add final specs for transcription feature
Some checks failed
CI / Unit & Component Tests (push) Failing after 1m52s
CI / Backend Unit Tests (push) Failing after 2m54s
CI / E2E Tests (push) Failing after 1h13m6s

Three final UI/UX specs for the collaborative transcription system:
- expandable-metadata-header-spec: labeled "Details" toggle with drawer
- annotation-transcription-final-spec: annotation-backed transcription with block-level comment threads
- transcription-read-mode-final-spec: clean split read mode with flowing prose and scroll sync

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-05 09:27:22 +02:00
parent 1a57ec2036
commit 46d64f50a5
3 changed files with 2467 additions and 0 deletions

View File

@@ -0,0 +1,700 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Expandable Metadata Header — Final Spec</title>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,500&family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet"/>
<style>
:root{--color-page:#FAFAF7;--color-surface:#F5F4EE;--color-subtle:#EDECEA;--color-border:#D8D7D0;--color-text-muted:#6B6A63;--color-text:#1C1C18;--navy:#012851;--mint:#A1DCD8;--sand:#F0EFE9;--turquoise:#00C7B1;--accent-bg:rgba(161,220,216,.12);--blue-tint:#E6F1FB;--blue:#2D7DD2;--blue-dark:#185FA5;--green-tint:#E8F5EA;--green:#3D8C4A;--green-dark:#2E6E39;--orange-tint:#FEF0E6;--orange:#E8862A;--orange-dark:#B46820;--color-error:#DC4C3E;--font-display:'Fraunces',Georgia,serif;--font-sans:'DM Sans',system-ui,sans-serif;--font-mono:'DM Mono',monospace;--radius-sm:4px;--radius-md:6px;--radius-lg:10px;--radius-xl:16px;--shadow-card:0 1px 3px rgba(28,28,24,.06),0 1px 2px rgba(28,28,24,.04);--shadow-raised:0 4px 12px rgba(28,28,24,.08),0 2px 4px rgba(28,28,24,.04);--shadow-overlay:0 8px 32px rgba(28,28,24,.12),0 2px 8px rgba(28,28,24,.06);}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
body{font-family:var(--font-sans);background:#E8E7E2;color:var(--color-text);font-size:14px;line-height:1.6;}
.doc{max-width:1200px;margin:0 auto;padding:48px 40px 120px;}
.doc-header{display:flex;justify-content:space-between;align-items:flex-end;padding-bottom:28px;border-bottom:1px solid var(--color-border);margin-bottom:48px;background:var(--color-page);margin:-48px -40px 48px;padding:48px 40px 28px;border-radius:var(--radius-xl) var(--radius-xl) 0 0;}
.doc-header h1{font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-.02em;margin-bottom:4px;}
.doc-header p{font-size:13px;color:var(--color-text-muted);max-width:680px;}
.doc-meta{font-family:var(--font-mono);font-size:11px;color:var(--color-text-muted);text-align:right;line-height:1.9;}
.pill{display:inline-block;padding:2px 8px;border-radius:var(--radius-sm);font-size:10px;font-weight:500;letter-spacing:.05em;}
.pill-g{background:var(--green-tint);color:var(--green-dark);}
.section{margin-bottom:64px;}
.section-title{font-size:10px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--color-text-muted);padding-bottom:10px;border-bottom:1px solid var(--color-border);margin-bottom:24px;}
.prose{font-size:13px;color:var(--color-text-muted);line-height:1.65;max-width:720px;margin-bottom:20px;}
.scr{margin-bottom:56px;}
.scr-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;}
.scr-head h3{font-family:var(--font-display);font-size:20px;font-weight:500;letter-spacing:-.02em;}
.scr-id{font-family:var(--font-mono);font-size:11px;color:var(--color-text-muted);padding:2px 8px;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-page);}
.scr-desc{font-size:12px;color:var(--color-text-muted);line-height:1.6;max-width:720px;margin-bottom:6px;}
.scr-var{font-size:11px;color:var(--color-text-muted);margin-bottom:20px;}.scr-var strong{color:var(--color-text);}
.previews{display:flex;gap:32px;flex-wrap:wrap;justify-content:center;align-items:flex-start;margin-bottom:20px;}
.prev-col{display:flex;flex-direction:column;align-items:center;gap:10px;}
.bp-lbl{font-family:var(--font-mono);font-size:10px;color:var(--color-text-muted);}
.desk{width:100%;max-width:1040px;background:var(--color-page);border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-overlay),0 0 0 1px rgba(0,0,0,.06);display:flex;flex-direction:column;min-height:520px;}
.phone{width:320px;flex-shrink:0;background:var(--color-page);border-radius:36px;overflow:hidden;box-shadow:var(--shadow-overlay),0 0 0 1px rgba(0,0,0,.07);display:flex;flex-direction:column;border:6px solid #1C1C18;}
.pst{padding:10px 20px 0;display:flex;justify-content:space-between;align-items:center;font-size:12px;background:var(--color-page);}.pst b{font-weight:600;}.pst span{font-size:10px;}
.pb{flex:1;overflow-y:auto;display:flex;flex-direction:column;}
/* ── FA chrome ── */
.fa-nav{height:32px;background:var(--navy);display:flex;align-items:center;padding:0 12px;gap:8px;flex-shrink:0;}
.fa-logo{font-size:7px;font-weight:900;color:#fff;letter-spacing:.8px;border-bottom:2px solid var(--mint);padding-bottom:1px;}
.fa-link{font-size:5.5px;color:rgba(255,255,255,.4);font-weight:700;text-transform:uppercase;}
.fa-nav-r{margin-left:auto;display:flex;gap:5px;align-items:center;}
.fa-av{width:16px;height:16px;background:rgba(255,255,255,.1);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:800;color:rgba(255,255,255,.5);}
/* ── Topbar ── */
.topbar{background:#fff;border-bottom:1px solid #e4e2d7;flex-shrink:0;position:relative;}
.topbar-main{display:flex;align-items:center;padding:0 12px;gap:6px;height:42px;}
.topbar .back{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:9px;color:var(--color-text-muted);}
.topbar .title{font-family:Georgia,serif;font-size:11px;color:var(--navy);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.topbar .date{font-size:8px;color:var(--color-text-muted);}
.fa-chip{display:inline-flex;align-items:center;gap:2px;padding:1px 5px 1px 2px;background:var(--sand);border:1px solid #e4e2d7;border-radius:8px;white-space:nowrap;font-size:7px;color:var(--color-text);}
.fa-chip .av{width:12px;height:12px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:800;flex-shrink:0;}
.fa-chip .av.navy{background:var(--navy);color:var(--mint);}
.fa-chip .av.purple{background:#5A3080;color:#fff;}
.fa-chip a{color:inherit;text-decoration:none;}
.fa-chip a:hover{text-decoration:underline;}
.fa-topbar-btn{font-size:7px;font-weight:600;padding:3px 8px;border-radius:4px;border:1px solid var(--navy);color:var(--navy);background:transparent;display:flex;align-items:center;gap:3px;cursor:pointer;}
.fa-topbar-btn.active{background:var(--navy);color:#fff;border-color:var(--navy);}
.fa-topbar-btn.transcribe{background:var(--turquoise);color:var(--navy);border-color:var(--turquoise);font-weight:700;}
.fa-topbar-btn.ghost{border-color:var(--color-border);color:var(--color-text-muted);font-weight:500;}
/* ── Details toggle ── */
.details-toggle{display:inline-flex;align-items:center;gap:3px;padding:2px 8px 2px 6px;border-radius:4px;font-size:7px;font-weight:600;color:var(--color-text-muted);cursor:pointer;border:1px solid var(--color-border);background:transparent;transition:all .15s ease;white-space:nowrap;}
.details-toggle:hover{background:var(--sand);color:var(--color-text);}
.details-toggle.open{background:var(--navy);color:#fff;border-color:var(--navy);}
.details-toggle .chevron-icon{display:inline-block;font-size:7px;transition:transform .2s ease;}
.details-toggle.open .chevron-icon{transform:rotate(180deg);}
/* ── PDF area ── */
.pdf-area{background:#D4D0C8;flex:1;display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden;}
.paper{background:#FFFEF8;box-shadow:0 2px 8px rgba(0,0,0,.14);border-radius:1px;padding:9px 11px;display:flex;flex-direction:column;gap:2px;position:relative;}
.pl{height:3px;background:#C4BDB0;border-radius:1px;opacity:.5;margin-bottom:2px;}
.ps{height:2px;background:#C4BDB0;border-radius:1px;opacity:.28;margin-bottom:1.5px;}
/* ── Annotation rects ── */
.ann-rect{position:absolute;border:1.5px solid var(--turquoise);background:rgba(0,199,177,.1);border-radius:2px;}
.ann-num{position:absolute;top:-8px;left:-8px;width:14px;height:14px;border-radius:50%;background:var(--navy);display:flex;align-items:center;justify-content:center;font-size:6px;font-weight:700;color:#fff;box-shadow:0 1px 2px rgba(0,0,0,.3);}
/* ── Transcript blocks ── */
.tblock{margin-bottom:5px;border:1px solid var(--color-border);border-radius:5px;overflow:hidden;}
.tblock.active{border-color:var(--turquoise);box-shadow:0 0 0 1px var(--turquoise);}
.tblock-head{display:flex;align-items:center;gap:4px;padding:3px 8px;font-size:6px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--color-text-muted);}
.tblock-head .num{width:14px;height:14px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:6px;font-weight:700;flex-shrink:0;}
.tblock-body{padding:5px 8px;font-family:Georgia,serif;font-size:9px;line-height:1.65;color:var(--color-text);min-height:16px;}
.trans-cursor{display:inline-block;width:1px;height:10px;background:var(--blue);animation:blink 1s infinite;margin-left:1px;}
@keyframes blink{0%,50%{opacity:1}51%,100%{opacity:0}}
.split{display:flex;flex:1;overflow:hidden;}
.split-handle{width:4px;background:var(--color-border);cursor:col-resize;flex-shrink:0;display:flex;align-items:center;justify-content:center;}
.split-handle::after{content:'';width:2px;height:20px;background:var(--color-text-muted);border-radius:1px;opacity:.3;}
.status-bar{background:var(--sand);border-top:1px solid #e4e2d7;height:18px;display:flex;align-items:center;padding:0 8px;font-size:7px;color:var(--color-text-muted);gap:8px;flex-shrink:0;}
/* ── Metadata display elements ── */
.meta-icon{width:14px;height:14px;display:flex;align-items:center;justify-content:center;font-size:9px;opacity:.5;flex-shrink:0;}
.meta-label{font-size:5px;font-weight:600;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;}
.meta-value{font-family:Georgia,serif;font-size:8px;color:var(--color-text);}
.meta-value a{color:var(--navy);text-decoration:none;}.meta-value a:hover{text-decoration:underline;}
.tag-chip{display:inline-block;font-size:6px;font-weight:600;padding:1px 5px;border-radius:3px;background:var(--sand);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.04em;cursor:pointer;}
.tag-chip:hover{background:var(--navy);color:#fff;}
/* ── Person card (for expanded metadata) ── */
.person-card{display:flex;align-items:center;gap:5px;padding:4px 6px;border:1px solid var(--color-border);border-radius:5px;background:var(--color-page);cursor:pointer;transition:all .1s;}
.person-card:hover{border-color:var(--mint);background:var(--accent-bg);}
.person-card .pc-av{width:18px;height:18px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:6px;font-weight:800;flex-shrink:0;}
.person-card .pc-name{font-family:Georgia,serif;font-size:8px;color:var(--color-text);}
.person-card .pc-alias{font-size:6px;color:var(--color-text-muted);}
.person-card .pc-action{font-size:7px;color:var(--color-text-muted);margin-left:auto;opacity:0;transition:opacity .1s;}
.person-card:hover .pc-action{opacity:1;}
/* ── Agent table ── */
.agent{background:var(--color-text);color:#E8E8E2;padding:24px;border-radius:var(--radius-lg);margin-top:20px;}
.agent h4{font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:#5A5A55;margin-bottom:12px;}
.agent pre{font-family:var(--font-mono);font-size:10px;color:#444440;margin-bottom:16px;line-height:1.8;white-space:pre-wrap;}
.at{width:100%;border-collapse:collapse;font-family:var(--font-mono);font-size:10px;}
.at thead tr{border-bottom:1px solid #2A2A26;}.at th{text-align:left;padding:6px 10px;font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:#5A5A55;font-family:var(--font-sans);}.at td{padding:5px 10px;border-bottom:1px solid #1E1E1A;vertical-align:top;line-height:1.5;}.at tr:last-child td{border-bottom:none;}.at td:first-child{color:#7A7A72;}.at td:nth-child(2){color:#E8E8E2;font-weight:500;}.at td:nth-child(3){color:#5A5A55;}.at .grp td{padding-top:14px;font-family:var(--font-sans);font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:#3A3A36;}
.llm{background:var(--color-page);border:2px solid var(--navy);border-radius:var(--radius-xl);padding:32px 40px;margin-top:64px;}
.llm h2{font-family:var(--font-display);font-size:22px;font-weight:500;letter-spacing:-.02em;margin-bottom:8px;color:var(--navy);}
.llm h3{font-size:14px;font-weight:600;margin:20px 0 8px;color:var(--color-text);}
.llm p,.llm li{font-size:13px;color:var(--color-text-muted);line-height:1.65;}
.llm ul,.llm ol{padding-left:20px;margin-bottom:12px;}
.llm li{margin-bottom:4px;}
.llm code{font-family:var(--font-mono);font-size:11px;background:var(--color-surface);padding:1px 5px;border-radius:3px;}
.llm table{width:100%;border-collapse:collapse;margin:12px 0;font-size:12px;}
.llm th,.llm td{text-align:left;padding:6px 10px;border-bottom:1px solid var(--color-border);}
.llm th{font-weight:500;color:var(--color-text);font-size:11px;text-transform:uppercase;letter-spacing:.05em;}
.llm td{color:var(--color-text-muted);}
@media(max-width:900px){.doc{padding:24px 16px 80px;}}
</style>
</head>
<body>
<div class="doc">
<div class="doc-header">
<div>
<h1>Expandable Metadata Header</h1>
<p>The document topbar gains a labeled toggle button (<strong>&ldquo;Details &#9660;&rdquo;</strong>) that opens a full-width metadata drawer below the main row. This replaces the bottom panel&rsquo;s Metadata tab in transcribe mode, keeping all interactive elements (person links, conversation links, tag filters) accessible without consuming permanent viewport space.</p>
</div>
<div class="doc-meta">
Familienarchiv<br/>
<span class="pill pill-g">Final spec</span><br/>
2026-04-04 &middot; @leonievoss
</div>
</div>
<!-- ═══ DESIGN DECISION ═══ -->
<div class="section">
<div class="section-title">Why a labeled toggle, not just a chevron</div>
<p class="prose">User interviews include family members aged 60+. A bare 12&ndash;16px chevron icon is easy to miss or misinterpret as decorative. A labeled button &mdash; <strong>&ldquo;Details &#9660;&rdquo;</strong> &mdash; is self-explanatory, provides a larger click target (min 44&times;28px), and follows the progressive disclosure pattern: key facts (title, date, person chips) are always visible in the topbar; the toggle reveals the full metadata only when needed.</p>
</div>
<div class="section">
<div class="section-title">What lives where</div>
<div style="display:flex;gap:12px;flex-wrap:wrap;font-size:12px;">
<div style="background:#fff;border:1px solid var(--color-border);border-radius:var(--radius-md);padding:10px 14px;flex:1;min-width:200px;">
<div style="font-weight:600;color:var(--navy);margin-bottom:4px;">Always visible in topbar</div>
<ul style="padding-left:16px;color:var(--color-text-muted);line-height:1.8;">
<li>Document title (truncated)</li>
<li>Date (compact format)</li>
<li>Sender &amp; receiver chips (abbreviated)</li>
<li>Action buttons (Edit, Annotate, Download)</li>
<li><strong>&ldquo;Details&rdquo;</strong> toggle button</li>
</ul>
</div>
<div style="background:#fff;border:1px solid var(--color-border);border-radius:var(--radius-md);padding:10px 14px;flex:1;min-width:200px;">
<div style="font-weight:600;color:var(--orange);margin-bottom:4px;">Revealed in drawer</div>
<ul style="padding-left:16px;color:var(--color-text-muted);line-height:1.8;">
<li>Full date (long format)</li>
<li>Creation location (e.g. &ldquo;Breslau&rdquo;)</li>
<li>Archive location (e.g. &ldquo;Ordner A3, Schublade 2&rdquo;)</li>
<li>Tags (clickable &rarr; filter documents)</li>
<li>Full person cards with avatar, name, alias</li>
<li>Person detail links (/persons/{id})</li>
<li>Conversation links (/korrespondenz?...)</li>
</ul>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════════
DESKTOP — COLLAPSED
═══════════════════════════════════════════════════════════════════════════ -->
<div class="scr" id="collapsed">
<div class="scr-head"><h3>Desktop &mdash; collapsed (default)</h3><span class="scr-id">S1</span></div>
<div class="scr-desc">The topbar looks identical to today except for the &ldquo;Details&rdquo; button between the person chips and the action buttons. The split view gets the full remaining viewport.</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Desktop &middot; 1040px &middot; collapsed</div>
<div class="desk" style="min-height:480px;">
<div class="fa-nav">
<div class="fa-logo">FAMILIENARCHIV</div>
<div class="fa-link">Dokumente</div>
<div class="fa-link">Personen</div>
<div class="fa-nav-r"><div class="fa-av">MR</div></div>
</div>
<div class="topbar">
<div class="topbar-main">
<div class="back">&larr;</div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 2px;"></div>
<div class="title">Brief von Heinrich an Martha, 14. Mai 1943</div>
<div style="flex:1"></div>
<div class="fa-chip"><div class="av navy">HR</div> <a href="#">Heinrich R.</a></div>
<span style="font-size:7px;color:var(--color-text-muted);">&rarr;</span>
<div class="fa-chip"><div class="av purple">MR</div> <a href="#">Martha R.</a></div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 4px;"></div>
<!-- Labeled toggle button -->
<div class="details-toggle">Details <span class="chevron-icon">&#9660;</span></div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 4px;"></div>
<div class="fa-topbar-btn transcribe">&#9998; Transkribieren</div>
<div class="fa-topbar-btn ghost">Annotieren</div>
</div>
</div>
<!-- Split view fills remaining space -->
<div class="split" style="flex:1;">
<div style="flex:1;">
<div class="pdf-area" style="height:100%;">
<div class="paper" style="width:50%;min-height:180px;position:relative;">
<div style="font-size:7px;color:#8A8070;font-style:italic;margin-bottom:4px;opacity:.7;">Liebe Martha,</div>
<div class="pl" style="width:90%;"></div><div class="ps" style="width:85%;"></div><div class="ps" style="width:92%;"></div>
<div class="pl" style="width:78%;"></div><div class="ps" style="width:88%;"></div><div class="ps" style="width:70%;"></div>
<div class="pl" style="width:84%;"></div><div class="ps" style="width:90%;"></div>
<div class="ann-rect" style="left:2%;top:0%;width:50%;height:12%;"><div class="ann-num">1</div></div>
<div class="ann-rect" style="left:2%;top:16%;width:96%;height:35%;"><div class="ann-num">2</div></div>
<div class="ann-rect" style="left:2%;top:55%;width:96%;height:25%;"><div class="ann-num">3</div></div>
</div>
</div>
</div>
<div class="split-handle"></div>
<div style="width:360px;display:flex;flex-direction:column;border-left:1px solid #e4e2d7;">
<div style="background:#fff;border-bottom:1px solid #e4e2d7;display:flex;align-items:center;padding:4px 8px;gap:4px;flex-shrink:0;">
<span style="font-size:7px;font-weight:600;color:var(--navy);">3 Bl&ouml;cke</span>
<div style="flex:1;"></div>
<span style="font-size:7px;color:var(--green-dark);">&#10003; Gespeichert</span>
</div>
<div style="flex:1;overflow-y:auto;padding:6px 8px;background:#fff;display:flex;flex-direction:column;gap:4px;">
<div class="tblock"><div class="tblock-head"><div class="num">1</div> Anrede <span style="margin-left:auto;color:var(--green-dark);">&#10003;</span></div><div class="tblock-body">Liebe Martha,</div></div>
<div class="tblock active"><div class="tblock-head" style="background:rgba(0,199,177,.08);"><div class="num">2</div> Hauptteil</div><div class="tblock-body">ich schreibe Dir heute aus dem Lazarett in Breslau...<span class="trans-cursor"></span></div></div>
<div class="tblock"><div class="tblock-head"><div class="num">3</div> Familie</div><div class="tblock-body" style="color:var(--color-text-muted);font-style:italic;">noch leer</div></div>
</div>
<div class="status-bar"><span>Block 2 aktiv</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════════
DESKTOP — EXPANDED
═══════════════════════════════════════════════════════════════════════════ -->
<div class="scr" id="expanded">
<div class="scr-head"><h3>Desktop &mdash; expanded</h3><span class="scr-id">S2</span></div>
<div class="scr-desc">Clicking &ldquo;Details&rdquo; slides open a full-width drawer below the topbar. Three-column grid: details (date, location, archive), persons (sender &amp; receiver cards with conversation links), and tags. The drawer <strong>pushes content down</strong> &mdash; it is part of the document flow, not an overlay. No clipping, no z-index issues.</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Desktop &middot; 1040px &middot; expanded</div>
<div class="desk" style="min-height:540px;">
<div class="fa-nav">
<div class="fa-logo">FAMILIENARCHIV</div>
<div class="fa-link">Dokumente</div>
<div class="fa-link">Personen</div>
<div class="fa-nav-r"><div class="fa-av">MR</div></div>
</div>
<div class="topbar" style="border-bottom:none;">
<div class="topbar-main">
<div class="back">&larr;</div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 2px;"></div>
<div class="title">Brief von Heinrich an Martha, 14. Mai 1943</div>
<div style="flex:1"></div>
<div class="fa-chip"><div class="av navy">HR</div> <a href="#">Heinrich R.</a></div>
<span style="font-size:7px;color:var(--color-text-muted);">&rarr;</span>
<div class="fa-chip"><div class="av purple">MR</div> <a href="#">Martha R.</a></div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 4px;"></div>
<!-- Toggle: active state -->
<div class="details-toggle open">Details <span class="chevron-icon">&#9660;</span></div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 4px;"></div>
<div class="fa-topbar-btn transcribe">&#9998; Transkribieren</div>
<div class="fa-topbar-btn ghost">Annotieren</div>
</div>
<!-- Expanded metadata drawer -->
<div style="border-top:1px solid #e4e2d7;padding:10px 16px;display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;background:var(--color-page);">
<!-- Column 1: Details -->
<div>
<div class="meta-label" style="margin-bottom:5px;">Details</div>
<div style="display:flex;flex-direction:column;gap:6px;">
<div style="display:flex;align-items:center;gap:5px;">
<div class="meta-icon">&#128197;</div>
<div><div class="meta-value">14. Mai 1943</div><div class="meta-label">Datum</div></div>
</div>
<div style="display:flex;align-items:center;gap:5px;">
<div class="meta-icon">&#128205;</div>
<div><div class="meta-value">Breslau</div><div class="meta-label">Entstehungsort</div></div>
</div>
<div style="display:flex;align-items:center;gap:5px;">
<div class="meta-icon">&#128193;</div>
<div><div class="meta-value">Ordner A3, Schublade 2</div><div class="meta-label">Archivstandort</div></div>
</div>
</div>
</div>
<!-- Column 2: Persons -->
<div>
<div class="meta-label" style="margin-bottom:5px;">Personen</div>
<div style="display:flex;flex-direction:column;gap:4px;">
<div class="meta-label" style="margin-top:2px;">Absender</div>
<div class="person-card">
<div class="pc-av" style="background:var(--navy);color:var(--mint);">HR</div>
<div><div class="pc-name">Heinrich Raddatz</div><div class="pc-alias">Opa Heinrich</div></div>
<div class="pc-action">&#128172;</div>
</div>
<div class="meta-label" style="margin-top:4px;">Empf&auml;nger</div>
<div class="person-card">
<div class="pc-av" style="background:#5A3080;color:#fff;">MR</div>
<div><div class="pc-name">Martha Raddatz</div><div class="pc-alias">Oma Martha</div></div>
<div class="pc-action">&#128172;</div>
</div>
</div>
</div>
<!-- Column 3: Tags -->
<div>
<div class="meta-label" style="margin-bottom:5px;">Schlagw&ouml;rter</div>
<div style="display:flex;flex-wrap:wrap;gap:3px;">
<div class="tag-chip">Feldpost</div>
<div class="tag-chip">2. Weltkrieg</div>
<div class="tag-chip">Lazarett</div>
<div class="tag-chip">Breslau</div>
</div>
</div>
</div>
</div>
<div style="border-top:1px solid #e4e2d7;"></div>
<!-- Split view (pushed down) -->
<div class="split" style="flex:1;">
<div style="flex:1;">
<div class="pdf-area" style="height:100%;">
<div class="paper" style="width:50%;min-height:140px;position:relative;">
<div style="font-size:7px;color:#8A8070;font-style:italic;opacity:.7;">Liebe Martha,</div>
<div class="pl" style="width:90%;"></div><div class="ps" style="width:85%;"></div><div class="ps" style="width:92%;"></div>
<div class="pl" style="width:78%;"></div><div class="ps" style="width:88%;"></div>
</div>
</div>
</div>
<div class="split-handle"></div>
<div style="width:360px;display:flex;flex-direction:column;border-left:1px solid #e4e2d7;">
<div style="flex:1;overflow-y:auto;padding:6px 8px;background:#fff;display:flex;flex-direction:column;gap:4px;">
<div class="tblock"><div class="tblock-head"><div class="num">1</div> Anrede</div><div class="tblock-body">Liebe Martha,</div></div>
<div class="tblock active"><div class="tblock-head" style="background:rgba(0,199,177,.08);"><div class="num">2</div> Hauptteil</div><div class="tblock-body">ich schreibe Dir heute...<span class="trans-cursor"></span></div></div>
</div>
<div class="status-bar"><span>Block 2 aktiv</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════════
MOBILE — COLLAPSED
═══════════════════════════════════════════════════════════════════════════ -->
<div class="scr" id="mobile-collapsed">
<div class="scr-head"><h3>Mobile &mdash; collapsed</h3><span class="scr-id">S3</span></div>
<div class="scr-desc">On mobile, the topbar shows the title, a compact &ldquo;Details&rdquo; toggle, and the transcribe mode pill. Person chips are hidden (shown in drawer instead). The toggle provides a 44px tap target.</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Mobile &middot; 320px &middot; collapsed</div>
<div class="phone" style="height:560px;">
<div class="pst"><b>14:23</b><span>&bull;&bull;&bull; WiFi &#128267;</span></div>
<div class="pb">
<div style="background:#fff;border-bottom:1px solid #e4e2d7;padding:6px 12px;">
<div style="display:flex;align-items:center;gap:6px;">
<span style="font-size:11px;color:var(--color-text-muted);">&larr;</span>
<span style="font-family:Georgia,serif;font-size:11px;color:var(--navy);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">Brief von Heinrich, 14.05.1943</span>
<div class="details-toggle" style="font-size:8px;padding:4px 10px 4px 8px;min-height:28px;">Details <span class="chevron-icon" style="font-size:8px;">&#9660;</span></div>
<span style="font-size:7px;font-weight:700;padding:2px 6px;border-radius:3px;background:var(--turquoise);color:var(--navy);">Transkr.</span>
</div>
</div>
<!-- PDF strip -->
<div style="background:#D4D0C8;height:110px;display:flex;align-items:center;justify-content:center;border-bottom:2px solid var(--turquoise);">
<div style="background:#FFFEF8;width:40%;padding:6px 8px;box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:1px;position:relative;">
<div style="font-size:5px;color:#8A8070;font-style:italic;opacity:.7;">Liebe Martha,</div>
<div style="height:2px;background:#C4BDB0;opacity:.4;margin:2px 0;width:80%;"></div>
<div style="height:1.5px;background:#C4BDB0;opacity:.2;margin:1px 0;width:90%;"></div>
<div style="height:1.5px;background:#C4BDB0;opacity:.2;margin:1px 0;width:70%;"></div>
</div>
</div>
<!-- Transcript blocks -->
<div style="flex:1;overflow-y:auto;padding:8px 12px;background:#fff;">
<div style="border:1px solid var(--color-border);border-radius:5px;overflow:hidden;margin-bottom:6px;">
<div style="padding:3px 8px;font-size:6px;font-weight:600;color:var(--color-text-muted);display:flex;align-items:center;gap:3px;background:var(--sand);"><div style="width:12px;height:12px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:700;">1</div> Anrede <span style="margin-left:auto;color:var(--green-dark);">&#10003;</span></div>
<div style="padding:4px 8px;font-family:Georgia,serif;font-size:10px;line-height:1.6;">Liebe Martha,</div>
</div>
<div style="border:1px solid var(--turquoise);border-radius:5px;overflow:hidden;margin-bottom:6px;box-shadow:0 0 0 1px var(--turquoise);">
<div style="padding:3px 8px;font-size:6px;font-weight:600;color:var(--color-text-muted);display:flex;align-items:center;gap:3px;background:rgba(0,199,177,.08);"><div style="width:12px;height:12px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:700;">2</div> Hauptteil</div>
<div style="padding:4px 8px;font-family:Georgia,serif;font-size:10px;line-height:1.6;">ich schreibe Dir heute aus dem Lazarett in Breslau...<span class="trans-cursor"></span></div>
</div>
<div style="border:1px solid var(--color-border);border-radius:5px;overflow:hidden;margin-bottom:6px;">
<div style="padding:3px 8px;font-size:6px;font-weight:600;color:var(--color-text-muted);display:flex;align-items:center;gap:3px;background:var(--sand);"><div style="width:12px;height:12px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:700;">3</div> Familie</div>
<div style="padding:4px 8px;font-family:Georgia,serif;font-size:10px;line-height:1.6;color:var(--color-text-muted);font-style:italic;">noch leer</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════════
MOBILE — EXPANDED
═══════════════════════════════════════════════════════════════════════════ -->
<div class="scr" id="mobile-expanded">
<div class="scr-head"><h3>Mobile &mdash; expanded</h3><span class="scr-id">S4</span></div>
<div class="scr-desc">The drawer opens as a single-column stack below the topbar. Person cards are full-width with 44px minimum touch targets. Conversation links are always visible (no hover-reveal on touch). Tags wrap naturally. The PDF strip and transcript blocks are pushed down.</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Mobile &middot; 320px &middot; expanded</div>
<div class="phone" style="height:620px;">
<div class="pst"><b>14:23</b><span>&bull;&bull;&bull; WiFi &#128267;</span></div>
<div class="pb">
<div style="background:#fff;border-bottom:none;padding:6px 12px;">
<div style="display:flex;align-items:center;gap:6px;">
<span style="font-size:11px;color:var(--color-text-muted);">&larr;</span>
<span style="font-family:Georgia,serif;font-size:11px;color:var(--navy);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">Brief von Heinrich, 14.05.1943</span>
<div class="details-toggle open" style="font-size:8px;padding:4px 10px 4px 8px;min-height:28px;">Details <span class="chevron-icon" style="font-size:8px;">&#9660;</span></div>
<span style="font-size:7px;font-weight:700;padding:2px 6px;border-radius:3px;background:var(--turquoise);color:var(--navy);">Transkr.</span>
</div>
</div>
<!-- Expanded drawer: single-column -->
<div style="background:var(--color-page);border-bottom:1px solid #e4e2d7;padding:10px 12px;">
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px;">
<div style="flex:1;min-width:100px;">
<div class="meta-label">Datum</div>
<div class="meta-value">14. Mai 1943</div>
</div>
<div style="flex:1;min-width:100px;">
<div class="meta-label">Ort</div>
<div class="meta-value">Breslau</div>
</div>
</div>
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px;">
<div style="flex:1;min-width:100px;">
<div class="meta-label">Archivstandort</div>
<div class="meta-value">Ordner A3, Schublade 2</div>
</div>
</div>
<div class="meta-label" style="margin-bottom:3px;">Absender</div>
<div class="person-card" style="margin-bottom:4px;min-height:36px;">
<div class="pc-av" style="background:var(--navy);color:var(--mint);">HR</div>
<div><div class="pc-name">Heinrich Raddatz</div><div class="pc-alias">Opa Heinrich</div></div>
<div class="pc-action" style="opacity:1;">&#128172;</div>
</div>
<div class="meta-label" style="margin-bottom:3px;">Empf&auml;nger</div>
<div class="person-card" style="margin-bottom:6px;min-height:36px;">
<div class="pc-av" style="background:#5A3080;color:#fff;">MR</div>
<div><div class="pc-name">Martha Raddatz</div><div class="pc-alias">Oma Martha</div></div>
<div class="pc-action" style="opacity:1;">&#128172;</div>
</div>
<div class="meta-label" style="margin-bottom:3px;">Schlagw&ouml;rter</div>
<div style="display:flex;flex-wrap:wrap;gap:3px;">
<div class="tag-chip">Feldpost</div>
<div class="tag-chip">2. Weltkrieg</div>
<div class="tag-chip">Lazarett</div>
<div class="tag-chip">Breslau</div>
</div>
</div>
<!-- PDF strip (pushed down) -->
<div style="background:#D4D0C8;height:70px;display:flex;align-items:center;justify-content:center;border-bottom:2px solid var(--turquoise);">
<div style="background:#FFFEF8;width:40%;padding:4px 6px;box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:1px;">
<div style="height:2px;background:#C4BDB0;opacity:.4;margin:2px 0;width:80%;"></div>
<div style="height:1.5px;background:#C4BDB0;opacity:.2;margin:1px 0;width:90%;"></div>
</div>
</div>
<!-- Blocks -->
<div style="flex:1;overflow-y:auto;padding:8px 12px;background:#fff;">
<div style="border:1px solid var(--color-border);border-radius:5px;overflow:hidden;margin-bottom:6px;">
<div style="padding:3px 8px;font-size:6px;font-weight:600;color:var(--color-text-muted);display:flex;align-items:center;gap:3px;background:var(--sand);"><div style="width:12px;height:12px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:700;">1</div> Anrede</div>
<div style="padding:4px 8px;font-family:Georgia,serif;font-size:10px;line-height:1.6;">Liebe Martha,</div>
</div>
<div style="border:1px solid var(--turquoise);border-radius:5px;overflow:hidden;margin-bottom:6px;box-shadow:0 0 0 1px var(--turquoise);">
<div style="padding:3px 8px;font-size:6px;font-weight:600;color:var(--color-text-muted);display:flex;align-items:center;gap:3px;background:rgba(0,199,177,.08);"><div style="width:12px;height:12px;border-radius:50%;background:var(--navy);color:#fff;display:flex;align-items:center;justify-content:center;font-size:5px;font-weight:700;">2</div> Hauptteil</div>
<div style="padding:4px 8px;font-family:Georgia,serif;font-size:10px;line-height:1.6;">ich schreibe Dir heute...<span class="trans-cursor"></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════════════
NON-TRANSCRIBE MODE (standard document view)
═══════════════════════════════════════════════════════════════════════════ -->
<div class="scr" id="non-transcribe">
<div class="scr-head"><h3>Non-transcribe mode &mdash; standard document view</h3><span class="scr-id">S5</span></div>
<div class="scr-desc">Outside of transcribe mode, the document detail page uses the <strong>same &ldquo;Details&rdquo; drawer pattern</strong>. No bottom panel. The PDF gets the full remaining viewport. Discussion and transcription are accessible via dedicated buttons (Transkribieren enters split mode, Annotieren enters annotation mode). One consistent pattern everywhere &mdash; no mode-dependent UI structure.</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Desktop &middot; non-transcribe &middot; collapsed</div>
<div class="desk" style="min-height:400px;">
<div class="fa-nav">
<div class="fa-logo">FAMILIENARCHIV</div>
<div class="fa-link">Dokumente</div>
<div class="fa-link">Personen</div>
<div class="fa-nav-r"><div class="fa-av">MR</div></div>
</div>
<div class="topbar">
<div class="topbar-main">
<div class="back">&larr;</div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 2px;"></div>
<div class="title">Brief von Heinrich an Martha, 14. Mai 1943</div>
<div style="flex:1"></div>
<div class="fa-chip"><div class="av navy">HR</div> <a href="#">Heinrich R.</a></div>
<span style="font-size:7px;color:var(--color-text-muted);">&rarr;</span>
<div class="fa-chip"><div class="av purple">MR</div> <a href="#">Martha R.</a></div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 4px;"></div>
<div class="details-toggle">Details <span class="chevron-icon">&#9660;</span></div>
<div style="width:1px;height:16px;background:#e4e2d7;margin:0 4px;"></div>
<div class="fa-topbar-btn ghost">&#9998; Transkribieren</div>
<div class="fa-topbar-btn ghost">Annotieren</div>
<div class="fa-topbar-btn ghost" style="padding:3px 5px;">
<span style="font-size:8px;">&#9998;</span>
</div>
<div style="width:14px;height:14px;border-radius:3px;background:var(--sand);display:flex;align-items:center;justify-content:center;font-size:6px;">&#8681;</div>
</div>
</div>
<!-- Full PDF — no bottom panel -->
<div class="pdf-area" style="flex:1;">
<div class="paper" style="width:45%;min-height:240px;">
<div style="font-size:7px;color:#8A8070;font-style:italic;margin-bottom:4px;opacity:.7;">Liebe Martha,</div>
<div class="pl" style="width:90%;"></div><div class="ps" style="width:85%;"></div><div class="ps" style="width:92%;"></div>
<div class="pl" style="width:78%;"></div><div class="ps" style="width:88%;"></div><div class="ps" style="width:70%;"></div>
<div class="pl" style="width:84%;"></div><div class="ps" style="width:90%;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ═══ AGENT TABLE ═══ -->
<div class="agent">
<h4>Expandable metadata header &middot; Implementation spec</h4>
<pre>/* The topbar gains a labeled "Details ▼" toggle button that opens a full-width metadata
* drawer below the main topbar row.
*
* Collapsed (default): topbar looks like today + a "Details ▼" button between
* the person chips and the action buttons.
* Expanded: a new row slides down with a 3-column grid (desktop):
* Col 1: date (long format), location, archive location — icon + value + label
* Col 2: sender card + receiver cards — clickable, links to /persons/{id}
* conversation icon links to /korrespondenz?senderId=X&receiverId=Y
* Col 3: tag chips — clickable, link to /?tag=X
*
* The drawer PUSHES content down (document flow, not overlay).
* Background: color-page (sand) to visually separate from white topbar.
* Animation: Svelte slide transition or max-height + overflow:hidden, 200ms ease.
*
* KEY DECISION: "Details ▼" labeled toggle instead of bare chevron icon.
* Reason: 60+ year old users in user interviews — bare icons are easy to miss.
* The label makes the interaction self-explanatory and provides a 44×28px min tap target.
*
* Mobile: single-column stack, person cards full-width with 44px min-height,
* conversation links always visible (no hover-reveal on touch). */</pre>
<table class="at"><thead><tr><th>Element</th><th>Value</th><th>Notes</th></tr></thead><tbody>
<tr class="grp"><td colspan="3">Toggle button</td></tr>
<tr><td>Label</td><td>"Details" + ▼ chevron</td><td>i18n key: topbar_details_toggle</td></tr>
<tr><td>Size</td><td>min 44×28px tap target, text-xs font-semibold</td><td>WCAG 2.5.5 compliant target size</td></tr>
<tr><td>Inactive style</td><td>border border-line, text-ink-2, bg-transparent</td><td>Subtle, doesn't compete with action buttons</td></tr>
<tr><td>Active style</td><td>bg-primary, text-primary-fg, border-primary</td><td>Clear open state — matches annotate button pattern</td></tr>
<tr><td>Chevron</td><td>▼ (U+25BC), rotates 180deg when open</td><td>CSS transition transform 200ms</td></tr>
<tr><td>Aria</td><td>aria-expanded, aria-controls="metadata-drawer"</td><td>Button role implicit</td></tr>
<tr><td>Keyboard</td><td>Ctrl+M toggles, Escape closes</td><td>Ctrl+M matches "M for metadata"</td></tr>
<tr class="grp"><td colspan="3">Drawer (expanded)</td></tr>
<tr><td>Layout</td><td>grid 3-col desktop (1fr 1fr 1fr), 1-col mobile</td><td>bg:color-page, border-top:line, p:12px 16px</td></tr>
<tr><td>Animation</td><td>Svelte slide transition, 200ms</td><td>Or CSS max-height 0↔auto with overflow:hidden</td></tr>
<tr><td>Push behavior</td><td>In document flow, pushes split view down</td><td>Not absolute/overlay — no clipping</td></tr>
<tr><td>ID</td><td>id="metadata-drawer"</td><td>role="region", aria-label="Dokumentmetadaten"</td></tr>
<tr class="grp"><td colspan="3">Drawer content — Details column</td></tr>
<tr><td>Date</td><td>Long format (14. Mai 1943), icon 📅</td><td>Uses existing formatDate utility</td></tr>
<tr><td>Location</td><td>Text, icon 📍</td><td>Only shown if doc.creationLocation exists</td></tr>
<tr><td>Archive</td><td>Text, icon 📁</td><td>Only shown if doc.archiveLocation exists</td></tr>
<tr class="grp"><td colspan="3">Drawer content — Persons column</td></tr>
<tr><td>Person card</td><td>border:line, radius:5px, bg:page, hover:accent-bg</td><td>Entire card is a link to /persons/{id}</td></tr>
<tr><td>Card content</td><td>18px avatar + full name + alias</td><td>Alias from person.alias field</td></tr>
<tr><td>Conversation icon</td><td>💬 appears on hover (desktop), always visible (mobile)</td><td>Links to /korrespondenz?senderId=X&amp;receiverId=Y</td></tr>
<tr><td>Mobile card height</td><td>min-height 44px</td><td>WCAG touch target compliance</td></tr>
<tr class="grp"><td colspan="3">Drawer content — Tags column</td></tr>
<tr><td>Chip</td><td>text-[10px]/600, sand bg, uppercase, radius:3px</td><td>Click → navigate to /?tag=X</td></tr>
<tr><td>Hover</td><td>bg-primary, text-primary-fg</td><td>Visual feedback that chips are interactive</td></tr>
<tr class="grp"><td colspan="3">Non-transcribe mode</td></tr>
<tr><td>Toggle shown?</td><td>Yes — always present in topbar</td><td>Consistent UX across all modes</td></tr>
<tr><td>Bottom panel</td><td>Removed entirely — all modes</td><td>Drawer is the single metadata pattern everywhere</td></tr>
</tbody></table>
</div>
<!-- ═══ LLM IMPLEMENTATION GUIDE ═══ -->
<div class="llm">
<h2>Implementation Guide &mdash; Expandable Metadata Header</h2>
<h3>1. Scope</h3>
<p>Add a labeled &ldquo;Details&rdquo; toggle button and a collapsible metadata drawer to <code>DocumentTopBar.svelte</code>. This spec covers <strong>only the header expansion</strong> &mdash; the transcription split view, inline comments, and history toolbar are covered in the companion spec (<code>annotation-transcription-final-spec.html</code>).</p>
<h3>2. State</h3>
<ul>
<li><code>let metadataOpen = $state(false)</code> in <code>DocumentTopBar.svelte</code>.</li>
<li>Toggle on button click. Close on Escape key. Toggle on Ctrl+M.</li>
<li>State is local &mdash; not persisted. Defaults to closed on every page load.</li>
</ul>
<h3>3. Component Changes</h3>
<table>
<thead><tr><th>Component</th><th>Change</th></tr></thead>
<tbody>
<tr><td><code>DocumentTopBar.svelte</code></td><td>Add <code>metadataOpen</code> state, toggle button, and conditional drawer div. New props needed: <code>doc.creationLocation</code>, <code>doc.archiveLocation</code>, <code>doc.tags</code>, full sender/receiver objects with aliases.</td></tr>
<tr><td><code>MetadataDrawer.svelte</code> (new)</td><td>Extracted child component. Receives the doc object. Renders the 3-column grid (desktop) or 1-column stack (mobile). Contains person cards, tag chips, and metadata fields.</td></tr>
<tr><td><code>PersonChipRow.svelte</code></td><td>No change. Still renders the abbreviated chips in the main topbar row.</td></tr>
<tr><td><code>DocumentBottomPanel.svelte</code></td><td>Remove entirely. The metadata drawer replaces the Metadata tab. Transcription, Discussion, and History move to inline UI (see companion transcription spec). No bottom panel in any mode.</td></tr>
</tbody>
</table>
<h3>4. Toggle Button Placement</h3>
<p>In the topbar&rsquo;s flex row, the button goes <strong>after the person chips divider and before the action buttons divider</strong>:</p>
<p><code>← | Title | chips → | <strong>Details ▼</strong> | Transkribieren | Annotieren | Edit | Download</code></p>
<p>On mobile (&lt;375px), person chips are hidden. The toggle sits after the title, before the transcribe pill.</p>
<h3>5. Drawer Markup</h3>
<ul>
<li>Use Svelte <code>slide</code> transition: <code>{#if metadataOpen}&lt;div transition:slide={{ duration: 200 }}&gt;</code></li>
<li>The drawer is a direct child of the topbar wrapper, below the main flex row.</li>
<li>Desktop: <code>grid grid-cols-3 gap-4 p-3 sm:p-4 bg-canvas border-t border-line</code></li>
<li>Mobile: <code>grid grid-cols-1 gap-3 p-3 bg-canvas border-t border-line</code></li>
<li>Breakpoint for 3-col: <code>md:grid-cols-3</code> (768px+).</li>
</ul>
<h3>6. Person Cards in Drawer</h3>
<ul>
<li>Each card: avatar (using <code>personAvatarColor</code>), full name (font-serif), alias (text-xs text-ink-2).</li>
<li>Card wraps an <code>&lt;a href="/persons/{id}"&gt;</code>.</li>
<li>Conversation icon: separate <code>&lt;a&gt;</code> inside the card, absolute-positioned or flex-end. Links to <code>/korrespondenz?senderId={sender.id}&amp;receiverId={receiver.id}</code>.</li>
<li>On mobile: <code>min-h-[44px]</code> for touch targets. Conversation icon always visible (<code>opacity-100</code> instead of <code>opacity-0 group-hover:opacity-100</code>).</li>
</ul>
<h3>7. Tag Chips in Drawer</h3>
<ul>
<li>Each tag: <code>&lt;a href="/?tag={tag.name}"&gt;</code> with <code>text-[10px] font-semibold uppercase bg-muted rounded px-2 py-0.5 hover:bg-primary hover:text-primary-fg transition-colors</code>.</li>
<li><code>aria-label="Dokumente mit Schlagwort {tag.name} filtern"</code>.</li>
</ul>
<h3>8. Accessibility</h3>
<ul>
<li>Toggle button: <code>aria-expanded={metadataOpen}</code>, <code>aria-controls="metadata-drawer"</code>.</li>
<li>Drawer: <code>id="metadata-drawer"</code>, <code>role="region"</code>, <code>aria-label="Dokumentmetadaten"</code>.</li>
<li>Person cards: accessible name includes full name + &ldquo;Zur Personenseite&rdquo;.</li>
<li>Conversation link: <code>aria-label="Korrespondenz zwischen {sender} und {receiver} anzeigen"</code>.</li>
<li>Tab order: toggle button &rarr; drawer contents (when open) &rarr; action buttons.</li>
<li>Escape closes drawer and returns focus to the toggle button.</li>
</ul>
<h3>9. i18n Keys</h3>
<table>
<thead><tr><th>Key</th><th>de</th><th>en</th></tr></thead>
<tbody>
<tr><td><code>topbar_details_toggle</code></td><td>Details</td><td>Details</td></tr>
<tr><td><code>topbar_details_date</code></td><td>Datum</td><td>Date</td></tr>
<tr><td><code>topbar_details_location</code></td><td>Entstehungsort</td><td>Location</td></tr>
<tr><td><code>topbar_details_archive</code></td><td>Archivstandort</td><td>Archive location</td></tr>
<tr><td><code>topbar_details_sender</code></td><td>Absender</td><td>Sender</td></tr>
<tr><td><code>topbar_details_receivers</code></td><td>Empf&auml;nger</td><td>Receivers</td></tr>
<tr><td><code>topbar_details_tags</code></td><td>Schlagw&ouml;rter</td><td>Tags</td></tr>
<tr><td><code>topbar_details_conversation</code></td><td>Korrespondenz anzeigen</td><td>View correspondence</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>