Adds the design decision record for how to expand the dashboard without pushing content below the fold: a full-width 3-column strip (Segmentierung / Transkription / Lesefertig) below the existing grid. - dashboard-expansion-patterns.html — four pattern alternatives evaluated (Tabs, Accordion, Mission Control, Priority Queue) with annotated mockups, engagement feature proposal, and final recommendation. - mission-control-strip-final.html — clean implementation blueprint with pipeline diagram, column definitions, seeded-weekly-shuffle sorting, expert-flag escape hatch, all Tailwind impl-ref values, and backend contracts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1123 lines
75 KiB
HTML
1123 lines
75 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8"/>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||
<title>Dashboard Expansion — 4 Layout-Muster (Issue #240)</title>
|
||
<style>
|
||
:root{
|
||
--navy:#002850;--mint:#A6DAD8;--sand:#E4E2D7;
|
||
--surface:#FAFAF7;--bg:#E8E7E2;--border:#D8D7D0;
|
||
--text:#1C1C18;--muted:#6B6A63;--subtle:#9B9A93;
|
||
--orange:#C26A00;--orange-bg:#FEF4E2;
|
||
--green:#2E6E39;--green-bg:#EAF5EA;
|
||
--font:system-ui,sans-serif;--mono:'Courier New',monospace;
|
||
}
|
||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
|
||
body{font-family:var(--font);background:var(--bg);color:var(--text);font-size:14px;line-height:1.6;}
|
||
.doc{max-width:1100px;margin:0 auto;padding:48px 32px 96px;}
|
||
|
||
/* Header */
|
||
.doc-header{background:var(--navy);color:#fff;padding:32px 32px 28px;border-radius:8px 8px 0 0;}
|
||
.doc-header h1{font-family:Georgia,serif;font-size:26px;font-weight:400;letter-spacing:-.02em;margin-bottom:8px;}
|
||
.badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:4px;font-size:10px;font-weight:600;letter-spacing:.05em;background:var(--mint);color:var(--navy);}
|
||
.badge-ghost{background:rgba(255,255,255,.15);color:rgba(255,255,255,.9);}
|
||
.badges{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px;}
|
||
.doc-meta{font-family:var(--mono);font-size:11px;color:rgba(255,255,255,.45);}
|
||
.intro-box{background:#fff;border:1px solid var(--border);border-top:none;border-radius:0 0 6px 6px;padding:20px 28px 24px;margin-bottom:40px;}
|
||
.intro-box h2{font-family:Georgia,serif;font-size:16px;font-weight:400;color:var(--navy);margin-bottom:8px;}
|
||
.prose{font-size:13px;color:var(--muted);line-height:1.65;max-width:720px;margin-bottom:12px;}
|
||
.prose:last-child{margin-bottom:0;}
|
||
|
||
/* Sections */
|
||
.section{margin-bottom:56px;}
|
||
.section-label{font-size:10px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding-bottom:8px;border-bottom:1px solid var(--border);margin-bottom:24px;}
|
||
hr{border:none;border-top:1px solid var(--border);margin:48px 0;}
|
||
|
||
/* Pattern header */
|
||
.pattern-title{font-family:Georgia,serif;font-size:22px;font-weight:400;color:var(--navy);margin-bottom:4px;}
|
||
.pattern-sub{font-size:13px;color:var(--muted);margin-bottom:14px;}
|
||
.tag-list{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px;}
|
||
.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:10px;font-weight:600;letter-spacing:.04em;}
|
||
.tag-pro{background:var(--green-bg);color:var(--green);}
|
||
.tag-con{background:var(--orange-bg);color:var(--orange);}
|
||
.tag-rec{background:var(--navy);color:#fff;}
|
||
|
||
/* Frames row */
|
||
.frames-row{display:flex;gap:24px;flex-wrap:wrap;align-items:flex-start;margin-bottom:20px;}
|
||
.caption{font-family:var(--mono);font-size:10px;color:var(--muted);display:block;margin-top:6px;}
|
||
|
||
/* Desktop frame */
|
||
.frame-desktop{background:var(--surface);border-radius:8px;overflow:hidden;border:1px solid var(--border);box-shadow:0 4px 16px rgba(0,0,0,.08);}
|
||
.f-nav{height:26px;background:var(--navy);display:flex;align-items:center;padding:0 8px;gap:5px;}
|
||
.f-logo{font-size:6.5px;font-weight:700;color:#fff;letter-spacing:.7px;border-bottom:1px solid var(--mint);padding-bottom:1px;}
|
||
.f-navlinks{display:flex;gap:5px;margin-left:8px;}
|
||
.f-navlink{font-size:5.5px;color:rgba(255,255,255,.4);font-weight:600;text-transform:uppercase;}
|
||
.f-navlink.on{color:rgba(255,255,255,.9);}
|
||
.f-navr{margin-left:auto;display:flex;gap:4px;align-items:center;}
|
||
.f-av{width:14px;height:14px;border-radius:50%;background:rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center;font-size:4.5px;font-weight:800;color:rgba(255,255,255,.5);}
|
||
.f-body{padding:10px;}
|
||
|
||
/* Search bar mock */
|
||
.f-search{background:#fff;border:1px solid var(--border);border-radius:4px;height:24px;display:flex;align-items:center;padding:0 8px;gap:5px;margin-bottom:5px;}
|
||
.f-search-icon{font-size:9px;color:var(--muted);}
|
||
.f-search-txt{font-size:7.5px;color:var(--subtle);flex:1;}
|
||
.f-chip-sm{font-size:6px;padding:1px 5px;border-radius:3px;border:1px solid var(--border);color:var(--muted);background:#fff;}
|
||
.f-chip-sm.on{background:var(--navy);color:#fff;border-color:var(--navy);}
|
||
|
||
/* Resume strip */
|
||
.f-resume{background:var(--mint);opacity:.2;height:7px;border-radius:3px;margin-bottom:8px;}
|
||
|
||
/* Grid */
|
||
.f-grid-2{display:grid;grid-template-columns:1fr 155px;gap:7px;}
|
||
.f-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px;}
|
||
|
||
/* Cards */
|
||
.f-card{background:#fff;border:1px solid var(--sand);border-radius:3px;padding:7px;}
|
||
.f-htitle{font-size:6px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:5px;}
|
||
.f-htitle.orange{color:var(--orange);}
|
||
.f-htitle.green{color:var(--green);}
|
||
.f-htitle.navy{color:var(--navy);}
|
||
.f-row{display:flex;align-items:flex-start;border-bottom:1px solid var(--sand);padding:3px 0;gap:3px;}
|
||
.f-row:last-of-type{border-bottom:none;}
|
||
.f-doc-name{font-family:Georgia,serif;font-size:7.5px;color:var(--navy);line-height:1.3;}
|
||
.f-doc-sub{font-size:6px;color:var(--muted);margin-top:1px;}
|
||
.f-doc-date{font-size:5.5px;color:var(--subtle);margin-left:auto;white-space:nowrap;flex-shrink:0;padding-top:1px;}
|
||
.f-dot{width:4px;height:4px;border-radius:50%;flex-shrink:0;margin-top:3px;}
|
||
.f-dot.orange{background:var(--orange);}
|
||
.f-dot.navy{background:var(--navy);}
|
||
.f-dot.green{background:var(--green);}
|
||
.f-link{font-size:6px;color:var(--navy);display:block;margin-top:5px;}
|
||
.f-link.green{color:var(--green);}
|
||
.f-stats{font-size:5.5px;color:var(--muted);margin-top:5px;}
|
||
|
||
/* DropZone */
|
||
.f-dz{border:1.5px dashed var(--mint);background:rgba(166,218,216,.07);border-radius:3px;padding:7px;text-align:center;}
|
||
.f-dz-icon{font-size:12px;color:var(--navy);opacity:.35;margin-bottom:2px;}
|
||
.f-dz-txt{font-size:6px;font-weight:700;color:var(--navy);}
|
||
.f-dz-sub{font-size:5px;color:var(--muted);}
|
||
|
||
/* Tabs */
|
||
.f-tabs{display:flex;border-bottom:1px solid var(--border);margin-bottom:5px;}
|
||
.f-tab{font-size:6.5px;padding:3px 5px;color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap;}
|
||
.f-tab.on{color:var(--navy);border-bottom-color:var(--navy);font-weight:600;}
|
||
|
||
/* Accordion */
|
||
.f-acc-item{border-bottom:1px solid var(--sand);}
|
||
.f-acc-item:last-child{border-bottom:none;}
|
||
.f-acc-head{display:flex;align-items:center;justify-content:space-between;padding:4px 0;}
|
||
.f-acc-label{font-size:6.5px;font-weight:600;color:var(--navy);}
|
||
.f-acc-label.orange{color:var(--orange);}
|
||
.f-acc-label.green{color:var(--green);}
|
||
.f-acc-body{padding-bottom:3px;}
|
||
|
||
/* Phone frame */
|
||
.frame-phone{width:200px;flex-shrink:0;background:var(--surface);border-radius:24px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.12),0 0 0 1px rgba(0,0,0,.06);display:flex;flex-direction:column;border:4px solid #1C1C18;}
|
||
.ph-nav{height:20px;background:var(--navy);display:flex;align-items:center;padding:0 6px;}
|
||
.ph-logo{font-size:5.5px;font-weight:700;color:#fff;letter-spacing:.6px;border-bottom:1px solid var(--mint);padding-bottom:1px;}
|
||
.ph-body{flex:1;overflow:hidden;padding:6px;display:flex;flex-direction:column;gap:4px;}
|
||
.ph-search{background:#fff;border:1px solid var(--border);border-radius:3px;height:18px;display:flex;align-items:center;padding:0 6px;gap:3px;}
|
||
.ph-search-txt{font-size:6.5px;color:var(--subtle);flex:1;}
|
||
|
||
/* Problem callout */
|
||
.problem-strip{border:1.5px dashed var(--orange);border-radius:3px;padding:5px 7px;background:var(--orange-bg);opacity:.7;margin-bottom:3px;}
|
||
.problem-txt{font-size:6px;color:var(--orange);font-weight:700;}
|
||
|
||
/* impl-ref */
|
||
.impl-ref{margin-top:20px;}
|
||
.impl-ref table{width:100%;border-collapse:collapse;font-size:12px;}
|
||
.impl-ref th{background:var(--navy);color:#fff;padding:6px 10px;text-align:left;font-size:10px;font-weight:600;letter-spacing:.06em;}
|
||
.impl-ref td{padding:7px 10px;border-bottom:1px solid var(--border);vertical-align:top;}
|
||
.impl-ref tr:nth-child(even) td{background:var(--surface);}
|
||
.impl-ref code{font-family:var(--mono);font-size:11px;background:rgba(0,40,80,.06);padding:1px 4px;border-radius:2px;}
|
||
.impl-ref .note{font-size:11px;color:var(--muted);}
|
||
|
||
/* Comparison table */
|
||
.cmp{width:100%;border-collapse:collapse;font-size:12px;margin-bottom:24px;}
|
||
.cmp th{background:var(--navy);color:#fff;padding:7px 10px;font-size:10px;font-weight:600;letter-spacing:.05em;text-align:left;}
|
||
.cmp td{padding:7px 10px;border-bottom:1px solid var(--border);vertical-align:top;}
|
||
.cmp tr:nth-child(even) td{background:var(--surface);}
|
||
.cmp .pass{color:var(--green);font-weight:600;}
|
||
.cmp .fail{color:var(--orange);font-weight:600;}
|
||
.cmp .warn{color:#8A6800;font-weight:600;}
|
||
.cmp td.best{background:rgba(0,40,80,.05) !important;}
|
||
|
||
/* Recommendation */
|
||
.rec{background:var(--navy);color:#fff;padding:24px 28px;border-radius:6px;margin-top:32px;}
|
||
.rec h3{font-family:Georgia,serif;font-size:20px;font-weight:400;margin-bottom:12px;}
|
||
.rec p{font-size:13px;line-height:1.65;color:rgba(255,255,255,.8);margin-bottom:8px;}
|
||
.rec ul{margin:8px 0 0 18px;}
|
||
.rec li{font-size:13px;color:rgba(255,255,255,.75);margin-bottom:6px;line-height:1.5;}
|
||
.rec strong{color:var(--mint);}
|
||
|
||
/* Right-column stack helper */
|
||
.rhs{display:flex;flex-direction:column;gap:6px;}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="doc">
|
||
|
||
<!-- ── HEADER ───────────────────────────────────────────────────────── -->
|
||
<div class="doc-header">
|
||
<h1>Dashboard Expansion — 4 Layout-Muster</h1>
|
||
<div class="badges">
|
||
<span class="badge">Issue #240</span>
|
||
<span class="badge badge-ghost">Leonie Voss — UX & Accessibility</span>
|
||
<span class="badge badge-ghost">15. April 2026</span>
|
||
</div>
|
||
<div class="doc-meta">src/routes/+page.svelte · src/lib/components/Dashboard*.svelte · Muster A Tabs · B Accordion · C Mission Control · D Priority Queue</div>
|
||
</div>
|
||
|
||
<div class="intro-box">
|
||
<h2>Das Problem</h2>
|
||
<p class="prose">
|
||
Die rechte Spalte der Startseite ist mit <strong>DropZone + „Metadaten fehlen"</strong> bereits ausgelastet.
|
||
Issue #240 möchte zwei weitere Karten ergänzen: <em>Transkription ausstehend</em> und <em>Lesefertig</em>.
|
||
Direkt gestapelt scrollt die Spalte sofort aus dem sichtbaren Bereich — ein 67-jähriger Nutzer auf einem kleinen
|
||
Display sieht die unteren Karten nie.
|
||
</p>
|
||
<p class="prose">
|
||
Der Nutzer schlug <strong>Tabs</strong> vor (Neueste Aktivität / Transkription fehlt / Metadaten fehlen / Lesefertig).
|
||
Diese Spec bewertet diesen Vorschlag und zeigt drei weitere Muster im Vergleich.
|
||
Alle Muster werden bei <strong>320 px (Mobiltelefon)</strong> und <strong>Desktop (~55 % Skalierung)</strong> gezeigt.
|
||
</p>
|
||
</div>
|
||
|
||
<!-- ── CURRENT STATE ─────────────────────────────────────────────────── -->
|
||
<div class="section">
|
||
<div class="section-label">Ist-Zustand — rechte Spalte überfüllt</div>
|
||
<div class="frames-row">
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="frame-desktop">
|
||
<div class="f-nav">
|
||
<div class="f-logo">FAMILIENARCHIV</div>
|
||
<div class="f-navlinks"><div class="f-navlink on">Archiv</div><div class="f-navlink">Personen</div><div class="f-navlink">Gespräche</div></div>
|
||
<div class="f-navr"><div class="f-av">MR</div></div>
|
||
</div>
|
||
<div class="f-body">
|
||
<div class="f-search"><div class="f-search-icon">⌕</div><div class="f-search-txt">Dokumente durchsuchen…</div><div class="f-chip-sm">↑↓ Datum</div><div class="f-chip-sm">+ Filter</div></div>
|
||
<div class="f-resume"></div>
|
||
<div class="f-grid-2">
|
||
<div class="f-card">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief von Oma Martha, 1943</div><div class="f-doc-sub">Karl Raddatz</div></div><div class="f-doc-date">12. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl Raddatz</div><div class="f-doc-sub">Standesamt</div></div><div class="f-doc-date">9. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div><div class="f-doc-sub">Martha Raddatz</div></div><div class="f-doc-date">7. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto Sommer 1952</div><div class="f-doc-sub">Unbekannt</div></div><div class="f-doc-date">3. Apr</div></div>
|
||
<div class="f-stats">47 Dokumente · 12 Personen</div>
|
||
</div>
|
||
<div class="rhs">
|
||
<div class="f-dz"><div class="f-dz-icon">↑</div><div class="f-dz-txt">Datei hochladen</div><div class="f-dz-sub">Drag & Drop oder klicken</div></div>
|
||
<div class="f-card">
|
||
<div class="f-htitle orange">Metadaten fehlen</div>
|
||
<div class="f-row"><div class="f-doc-name">Familienfoto 1952</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Standesamtsurkunde</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Reisepass Opa Heinrich</div></div>
|
||
<a class="f-link">Alle anzeigen →</a>
|
||
</div>
|
||
<div class="problem-strip"><div class="problem-txt">▼ TRANSKRIPTION FEHLT (neu) — scrollt aus dem Sichtfeld</div></div>
|
||
<div class="problem-strip"><div class="problem-txt">▼ LESEFERTIG (neu) — nie sichtbar ohne Scrollen</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Desktop (55 % Skalierung) — zwei neue Karten würden die rechte Spalte sprengen</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<!-- PATTERN A: TABS -->
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="section-label">Muster A — Tabs in der rechten Spalte (Vorschlag des Nutzers)</div>
|
||
|
||
<div class="pattern-title">Aufgaben-Karte mit Tab-Strip</div>
|
||
<div class="pattern-sub">DropZone bleibt oben. Darunter: eine Karte mit drei Tabs (Metadaten / Transkription / Lesefertig).</div>
|
||
|
||
<div class="tag-list">
|
||
<span class="tag tag-pro">+ Kein zusätzlicher Scroll in der rechten Spalte</span>
|
||
<span class="tag tag-pro">+ Bekanntes Muster für jüngere Nutzer</span>
|
||
<span class="tag tag-pro">+ Platzsparend in 300 px</span>
|
||
<span class="tag tag-con">− Inaktive Kategorien unsichtbar — Senioren übersehen sie</span>
|
||
<span class="tag tag-con">− Drei kurze Labels kaum lesbar bei 300 px / 320 px</span>
|
||
<span class="tag tag-con">− JS-Zustand nötig (aktiver Tab)</span>
|
||
</div>
|
||
|
||
<p class="prose">
|
||
Der ursprüngliche Vorschlag nannte vier Tabs für die <em>gesamte Seite</em> (Neueste Aktivität / Transkription / Metadaten / Lesefertig).
|
||
Das ist ein UX-Antipattern: „Neueste Aktivität" ist der häufigste Anwendungsfall — ihn hinter einem Klick zu verstecken erhöht den Aufwand für jeden Dashboard-Besuch.
|
||
<strong>Tabs sollten ausschließlich auf die drei To-do-Widget-Kategorien in der rechten Spalte angewendet werden</strong>, nicht auf die gesamte Seite.
|
||
</p>
|
||
<p class="prose">
|
||
Accessibility: Tab-Elemente müssen <code>role="tablist"</code>, <code>role="tab"</code>, <code>aria-selected</code> und
|
||
<code>role="tabpanel"</code> tragen. Jeder Tab braucht <code>min-h-[44px]</code> (WCAG 2.2 Touchziel).
|
||
Drei Tabs in einer 300-px-Spalte = ~100 px pro Tab — grenzwertig auf Deutsch mit langen Wörtern.
|
||
</p>
|
||
|
||
<div class="frames-row">
|
||
<!-- Phone A -->
|
||
<div>
|
||
<div class="frame-phone">
|
||
<div class="ph-nav"><div class="ph-logo">FAMILIENARCHIV</div></div>
|
||
<div class="ph-body">
|
||
<div class="ph-search"><div class="ph-search-txt">⌕ Dokumente…</div></div>
|
||
<div class="f-dz" style="padding:5px;"><div class="f-dz-icon" style="font-size:10px;">↑</div><div class="f-dz-txt">Hochladen</div></div>
|
||
<!-- Tabbed card -->
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-tabs">
|
||
<div class="f-tab on">Metadaten</div>
|
||
<div class="f-tab">Transkr.</div>
|
||
<div class="f-tab">Lesefertig</div>
|
||
</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub">Titel fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub">Datum fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Reisepass Opa</div><div class="f-doc-sub">Absender fehlt</div></div></div>
|
||
<a class="f-link">Alle anzeigen →</a>
|
||
</div>
|
||
<!-- Recent below -->
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div class="f-doc-name">Brief von Oma Martha</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Taufurkunde Karl R.</div></div>
|
||
<div class="f-stats">47 Dok. · 12 Pers.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Mobil 320 px</span>
|
||
</div>
|
||
|
||
<!-- Desktop A -->
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="frame-desktop">
|
||
<div class="f-nav">
|
||
<div class="f-logo">FAMILIENARCHIV</div>
|
||
<div class="f-navlinks"><div class="f-navlink on">Archiv</div><div class="f-navlink">Personen</div></div>
|
||
<div class="f-navr"><div class="f-av">MR</div></div>
|
||
</div>
|
||
<div class="f-body">
|
||
<div class="f-search"><div class="f-search-icon">⌕</div><div class="f-search-txt">Dokumente durchsuchen…</div></div>
|
||
<div class="f-resume"></div>
|
||
<div class="f-grid-2">
|
||
<div class="f-card">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief von Oma Martha, 1943</div></div><div class="f-doc-date">12. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl Raddatz</div></div><div class="f-doc-date">9. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div></div><div class="f-doc-date">7. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto Sommer 1952</div></div><div class="f-doc-date">3. Apr</div></div>
|
||
<div class="f-stats">47 Dokumente · 12 Personen</div>
|
||
</div>
|
||
<div class="rhs">
|
||
<div class="f-dz"><div class="f-dz-icon">↑</div><div class="f-dz-txt">Datei hochladen</div><div class="f-dz-sub">Drag & Drop</div></div>
|
||
<div class="f-card" style="flex:1;">
|
||
<div class="f-tabs">
|
||
<div class="f-tab on">Metadaten</div>
|
||
<div class="f-tab">Transkr.</div>
|
||
<div class="f-tab">Lesefertig</div>
|
||
</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub">Titel fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub">Datum fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Reisepass Opa Heinrich</div><div class="f-doc-sub">Absender fehlt</div></div></div>
|
||
<a class="f-link">Alle anzeigen →</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Desktop (55 %) — DropZone + Tabbed-Karte; zwei Kategorien versteckt hinter Klick</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="impl-ref">
|
||
<table>
|
||
<thead><tr><th>Element</th><th>Tailwind-Klassen</th><th>Wert</th><th>Hinweis</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Tab-Strip</td><td><code>flex border-b border-line</code></td><td>—</td><td>ARIA: <code>role="tablist"</code></td></tr>
|
||
<tr><td>Tab inaktiv</td><td><code>px-3 py-3 text-xs font-medium text-gray-500 border-b-2 border-transparent whitespace-nowrap -mb-px</code></td><td>min-h 44 px ✓</td><td><code>role="tab" aria-selected="false"</code></td></tr>
|
||
<tr><td>Tab aktiv</td><td><code>px-3 py-3 text-xs font-semibold text-ink border-b-2 border-ink -mb-px</code></td><td>2 px navy Unterlinie</td><td><code>aria-selected="true"</code></td></tr>
|
||
<tr><td>Tab-Panel</td><td><code>pt-3 focus:outline-none</code></td><td>—</td><td><code>role="tabpanel" tabindex="0"</code></td></tr>
|
||
<tr><td>Aufgaben-Karte</td><td><code>rounded-sm border border-line bg-white p-4 flex-1</code></td><td>padding 16 px</td><td>Ersetzt 3 separate Karten</td></tr>
|
||
<tr><td>Zeile mit Kontext</td><td><code>flex flex-col py-2 border-b border-line last:border-0</code></td><td>min-h ~44 px</td><td>z. B. „3 von 8 Blöcken geprüft"</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<!-- PATTERN B: ACCORDION -->
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="section-label">Muster B — Accordion-Stapel in der rechten Spalte</div>
|
||
|
||
<div class="pattern-title">Aufklappbare Kategorien</div>
|
||
<div class="pattern-sub">DropZone oben. Darunter: drei Accordion-Sektionen, standardmäßig nur die dringlichste offen.</div>
|
||
|
||
<div class="tag-list">
|
||
<span class="tag tag-pro">+ Alle drei Kategorien-Überschriften immer sichtbar</span>
|
||
<span class="tag tag-pro">+ Kein JS — implementierbar mit nativem <code><details></code></span>
|
||
<span class="tag tag-pro">+ Vertraut für 60+ (wie FAQ)</span>
|
||
<span class="tag tag-con">− Inhalt zu 2/3 verborgen (nur Überschriften sichtbar)</span>
|
||
<span class="tag tag-con">− „Lesefertig" wird meist zugeklappt bleiben und übersehen</span>
|
||
</div>
|
||
|
||
<p class="prose">
|
||
Jede Sektion zeigt eine klickbare Kopfzeile (Pfeil + Label + Anzahl). Server-seitig wird die Sektion mit der
|
||
höchsten Anzahl als <code><details open></code> gerendert. Kein Client-JS nötig — native
|
||
<code><details></code>/<code><summary></code>-Elemente liefern ARIA-Accessibility gratis.
|
||
Sortierung der offenen Sektion nach Dringlichkeit: Metadaten → Transkription → Lesefertig.
|
||
</p>
|
||
|
||
<div class="frames-row">
|
||
<!-- Phone B -->
|
||
<div>
|
||
<div class="frame-phone">
|
||
<div class="ph-nav"><div class="ph-logo">FAMILIENARCHIV</div></div>
|
||
<div class="ph-body">
|
||
<div class="ph-search"><div class="ph-search-txt">⌕ Dokumente…</div></div>
|
||
<div class="f-dz" style="padding:5px;"><div class="f-dz-icon" style="font-size:10px;">↑</div><div class="f-dz-txt">Hochladen</div></div>
|
||
<div class="f-card" style="padding:4px 6px;">
|
||
<div class="f-acc-item">
|
||
<div class="f-acc-head"><span class="f-acc-label orange">▼ Metadaten fehlen (5)</span></div>
|
||
<div class="f-acc-body">
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub">Titel fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub">Datum fehlt</div></div></div>
|
||
<a class="f-link">Alle 5 anzeigen →</a>
|
||
</div>
|
||
</div>
|
||
<div class="f-acc-item"><div class="f-acc-head"><span class="f-acc-label">▶ Transkription fehlt (8)</span></div></div>
|
||
<div class="f-acc-item"><div class="f-acc-head"><span class="f-acc-label green">▶ Lesefertig ✓ (3)</span></div></div>
|
||
</div>
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div class="f-doc-name">Brief von Oma Martha</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Taufurkunde Karl R.</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Mobil 320 px</span>
|
||
</div>
|
||
|
||
<!-- Desktop B -->
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="frame-desktop">
|
||
<div class="f-nav">
|
||
<div class="f-logo">FAMILIENARCHIV</div>
|
||
<div class="f-navlinks"><div class="f-navlink on">Archiv</div><div class="f-navlink">Personen</div></div>
|
||
<div class="f-navr"><div class="f-av">MR</div></div>
|
||
</div>
|
||
<div class="f-body">
|
||
<div class="f-search"><div class="f-search-icon">⌕</div><div class="f-search-txt">Dokumente durchsuchen…</div></div>
|
||
<div class="f-resume"></div>
|
||
<div class="f-grid-2">
|
||
<div class="f-card">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief von Oma Martha, 1943</div></div><div class="f-doc-date">12. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl Raddatz</div></div><div class="f-doc-date">9. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div></div><div class="f-doc-date">7. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto Sommer 1952</div></div><div class="f-doc-date">3. Apr</div></div>
|
||
<div class="f-stats">47 Dokumente · 12 Personen</div>
|
||
</div>
|
||
<div class="rhs">
|
||
<div class="f-dz"><div class="f-dz-icon">↑</div><div class="f-dz-txt">Datei hochladen</div><div class="f-dz-sub">Drag & Drop</div></div>
|
||
<div class="f-card" style="flex:1;padding:4px 8px;">
|
||
<div class="f-acc-item">
|
||
<div class="f-acc-head"><span class="f-acc-label orange">▼ Metadaten fehlen (5)</span></div>
|
||
<div class="f-acc-body">
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub">Titel fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub">Datum fehlt</div></div></div>
|
||
<a class="f-link">Alle 5 anzeigen →</a>
|
||
</div>
|
||
</div>
|
||
<div class="f-acc-item"><div class="f-acc-head"><span class="f-acc-label">▶ Transkription fehlt (8)</span></div></div>
|
||
<div class="f-acc-item"><div class="f-acc-head"><span class="f-acc-label green">▶ Lesefertig ✓ (3)</span></div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Desktop (55 %) — Metadaten-Sektion offen, Transkription und Lesefertig zugeklappt</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="impl-ref">
|
||
<table>
|
||
<thead><tr><th>Element</th><th>HTML / Tailwind-Klassen</th><th>Wert</th><th>Hinweis</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Accordion-Wrapper</td><td><code><details></code> nativ</td><td>—</td><td>Accessibility gratis, kein JS</td></tr>
|
||
<tr><td>Accordion-Header</td><td><code><summary class="flex items-center justify-between min-h-[44px] cursor-pointer list-none"></code></td><td>min-h 44 px ✓</td><td>WCAG 2.2 Touchziel</td></tr>
|
||
<tr><td>Pfeil-Icon</td><td><code>transition-transform group-open:rotate-90</code></td><td>w-4 h-4</td><td>CSS-only; kein JS</td></tr>
|
||
<tr><td>Zähler-Badge</td><td><code>ml-auto font-mono text-xs text-gray-400</code></td><td>—</td><td>z. B. „(5)"</td></tr>
|
||
<tr><td>Dringlichste Sektion</td><td><code><details open></code></td><td>—</td><td>Server-seitig rendern: <code>if incompleteDocs.length >= needsTrans.length</code></td></tr>
|
||
<tr><td>Accordion-Inhalt</td><td><code>pt-1 pb-2</code> direkt nach <code><summary></code></td><td>—</td><td>Keine <code>overflow:hidden</code>-Animation nötig</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<!-- PATTERN C: MISSION CONTROL — RECOMMENDATION -->
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="section-label">Muster C — Mission-Control-Streifen <span class="tag tag-rec">★ Empfohlen</span></div>
|
||
|
||
<div class="pattern-title">Volle Breite unterhalb des Hauptgitters</div>
|
||
<div class="pattern-sub">Rechte Spalte bleibt unverändert. Unterhalb des Gitters: drei gleichwertige Spalten als neuer horizontaler Aktionsbereich.</div>
|
||
|
||
<div class="tag-list">
|
||
<span class="tag tag-pro">+ Alle drei Kategorien gleichzeitig sichtbar — kein Klick nötig</span>
|
||
<span class="tag tag-pro">+ „Neueste Aktivität" bleibt primärer Inhalt, nichts rückt dahinter</span>
|
||
<span class="tag tag-pro">+ Kein JS-Zustand</span>
|
||
<span class="tag tag-pro">+ „Lesefertig" bekommt eigene mint-Karte als visuellen Applaus</span>
|
||
<span class="tag tag-pro">+ Mobil stapeln die drei Spalten natürlich</span>
|
||
<span class="tag tag-con">− Leichtes Scrollen auf Desktop erforderlich</span>
|
||
<span class="tag tag-con">− Sechster API-Aufruf beim Dashboard-Load (via <code>Promise.allSettled</code> isoliert)</span>
|
||
</div>
|
||
|
||
<p class="prose">
|
||
Der Ist-Zustand der rechten Spalte bleibt vollständig erhalten. Die zwei neuen Karten des Issue #240 werden
|
||
<em>nicht</em> in die rechte Spalte gepackt, sondern in einen neuen vollbreiten Abschnitt direkt unterhalb des
|
||
bestehenden Zwei-Spalten-Gitters. Der Abschnitt ist nur sichtbar, wenn mindestens eine der beiden Kategorien
|
||
Einträge hat (<code>{#if needsTranscription.length > 0 || readyToRead.length > 0}</code>).
|
||
</p>
|
||
<p class="prose">
|
||
Die „Lesefertig"-Spalte erhält einen mint-gefärbten Hintergrund (<code>bg-mint/10 border-mint</code>) als positives Signal — kein
|
||
neutrales To-do, sondern eine Einladung zum Lesen. Leere Zustände zeigen eine kurze Erfolgsmeldung in
|
||
<code>bg-mint/5</code>, nicht eine tote weiße Box.
|
||
</p>
|
||
|
||
<div class="frames-row">
|
||
<!-- Phone C -->
|
||
<div>
|
||
<div class="frame-phone" style="height:580px;">
|
||
<div class="ph-nav"><div class="ph-logo">FAMILIENARCHIV</div></div>
|
||
<div class="ph-body" style="overflow-y:auto;">
|
||
<div class="ph-search"><div class="ph-search-txt">⌕ Dokumente…</div></div>
|
||
<!-- Right col first on mobile (lg:order-last) -->
|
||
<div class="f-dz" style="padding:5px;"><div class="f-dz-icon" style="font-size:10px;">↑</div><div class="f-dz-txt">Hochladen</div></div>
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-htitle orange">Metadaten fehlen</div>
|
||
<div class="f-row"><div class="f-doc-name">Familienfoto 1952</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Standesamtsurkunde</div></div>
|
||
<a class="f-link">Alle anzeigen →</a>
|
||
</div>
|
||
<!-- Left col (recent docs) -->
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div class="f-doc-name">Brief von Oma Martha</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Taufurkunde Karl R.</div></div>
|
||
<div class="f-stats">47 Dok. · 12 Pers.</div>
|
||
</div>
|
||
<!-- Mission control strip — stacks on mobile -->
|
||
<div style="background:#fff;border:1px solid var(--sand);border-radius:3px;padding:6px;">
|
||
<div class="f-htitle" style="margin-bottom:6px;">Was braucht Aufmerksamkeit?</div>
|
||
<div class="f-card" style="margin-bottom:4px;padding:4px;border-color:#DDD;">
|
||
<div class="f-htitle navy">Transkription fehlt</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl R.</div><div class="f-doc-sub">Noch nicht begonnen</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Reisepass Opa Heinrich</div><div class="f-doc-sub">3 von 8 Blöcken geprüft</div></div></div>
|
||
<a class="f-link">Alle 8 anzeigen →</a>
|
||
</div>
|
||
<div class="f-card" style="padding:4px;background:rgba(166,218,216,.10);border-color:var(--mint);">
|
||
<div class="f-htitle green">Lesefertig ✓</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div><div class="f-doc-sub">100 % geprüft</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief Oma Martha 1938</div><div class="f-doc-sub">95 % geprüft</div></div></div>
|
||
<a class="f-link green">Alle 3 anzeigen →</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Mobil 320 px — Streifen stapelt vertikal</span>
|
||
</div>
|
||
|
||
<!-- Desktop C -->
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="frame-desktop">
|
||
<div class="f-nav">
|
||
<div class="f-logo">FAMILIENARCHIV</div>
|
||
<div class="f-navlinks"><div class="f-navlink on">Archiv</div><div class="f-navlink">Personen</div></div>
|
||
<div class="f-navr"><div class="f-av">MR</div></div>
|
||
</div>
|
||
<div class="f-body">
|
||
<div class="f-search"><div class="f-search-icon">⌕</div><div class="f-search-txt">Dokumente durchsuchen…</div></div>
|
||
<div class="f-resume"></div>
|
||
<!-- Existing grid — unchanged -->
|
||
<div class="f-grid-2" style="margin-bottom:7px;">
|
||
<div class="f-card">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief von Oma Martha, 1943</div></div><div class="f-doc-date">12. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl Raddatz</div></div><div class="f-doc-date">9. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div></div><div class="f-doc-date">7. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto Sommer 1952</div></div><div class="f-doc-date">3. Apr</div></div>
|
||
<div class="f-stats">47 Dokumente · 12 Personen</div>
|
||
</div>
|
||
<div class="rhs">
|
||
<div class="f-dz"><div class="f-dz-icon">↑</div><div class="f-dz-txt">Datei hochladen</div><div class="f-dz-sub">Drag & Drop</div></div>
|
||
<div class="f-card" style="flex:1;">
|
||
<div class="f-htitle orange">Metadaten fehlen</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub">Titel fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub">Datum fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Reisepass Opa Heinrich</div><div class="f-doc-sub">Absender fehlt</div></div></div>
|
||
<a class="f-link">Alle anzeigen →</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ★ Mission control strip — new, full width -->
|
||
<div style="background:#fff;border:1px solid var(--sand);border-radius:3px;padding:8px;">
|
||
<div class="f-htitle" style="margin-bottom:7px;">Was braucht Aufmerksamkeit?</div>
|
||
<div class="f-grid-3">
|
||
<!-- Col 1: needs transcription -->
|
||
<div style="background:rgba(0,40,80,.03);border:1px solid var(--sand);border-radius:3px;padding:6px;">
|
||
<div class="f-htitle navy">Transkription fehlt</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl R.</div><div class="f-doc-sub">Noch nicht begonnen</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Reisepass Opa Heinrich</div><div class="f-doc-sub">3 von 8 Blöcken geprüft</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamt 1889</div><div class="f-doc-sub">Noch nicht begonnen</div></div></div>
|
||
<a class="f-link">Alle 8 anzeigen →</a>
|
||
</div>
|
||
<!-- Col 2: ready to read -->
|
||
<div style="background:rgba(166,218,216,.10);border:1px solid var(--mint);border-radius:3px;padding:6px;">
|
||
<div class="f-htitle green">Lesefertig ✓</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div><div class="f-doc-sub">100 % geprüft</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief Oma Martha 1938</div><div class="f-doc-sub">95 % geprüft</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Heiratsurkunde 1921</div><div class="f-doc-sub">91 % geprüft</div></div></div>
|
||
<a class="f-link green">Alle 3 lesen →</a>
|
||
</div>
|
||
<!-- Col 3: empty state example -->
|
||
<div style="background:rgba(166,218,216,.06);border:1.5px dashed var(--mint);border-radius:3px;padding:6px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:72px;">
|
||
<div style="font-size:12px;margin-bottom:3px;color:var(--green);">✓</div>
|
||
<div style="font-size:6px;color:var(--green);font-weight:700;">Alle Dokumente transkribiert</div>
|
||
<div style="font-size:5.5px;color:var(--muted);margin-top:2px;">Keine offenen Aufgaben</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Desktop (55 %) — Hauptgitter unberührt; Streifen darunter zeigt leeren Zustand in Spalte 3</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="impl-ref">
|
||
<table>
|
||
<thead><tr><th>Element</th><th>Tailwind-Klassen</th><th>Wert</th><th>Hinweis</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Streifen-Wrapper</td><td><code>mt-4 bg-white border border-line rounded-sm p-6</code></td><td>padding 24 px</td><td>Direkt nach bestehendem <code>div.mt-4.grid</code></td></tr>
|
||
<tr><td>Streifen-Titel</td><td><code>text-xs font-bold uppercase tracking-widest text-gray-400 mb-4</code></td><td>12 px / 700</td><td>Standard-Section-Title-Muster</td></tr>
|
||
<tr><td>3-Spalten-Grid</td><td><code>grid grid-cols-1 gap-4 sm:grid-cols-3</code></td><td>gap 16 px</td><td>Mobil: 1 Spalte, sm+: 3</td></tr>
|
||
<tr><td>Transkription-Spalte</td><td><code>bg-surface rounded-sm border border-line p-4</code></td><td>—</td><td>Neutral — es ist eine Aufgabe</td></tr>
|
||
<tr><td>Lesefertig-Spalte</td><td><code>bg-mint/10 rounded-sm border border-mint p-4</code></td><td>—</td><td>Mint-Ton = positives Signal</td></tr>
|
||
<tr><td>Leerer Zustand</td><td><code>flex flex-col items-center justify-center text-center bg-mint/5 border border-dashed border-mint rounded-sm p-6 min-h-[80px]</code></td><td>min-h 80 px</td><td>Niemals leere graue Box</td></tr>
|
||
<tr><td>Untertext-Zeile</td><td><code>text-xs text-gray-400 mt-0.5</code></td><td>12 px</td><td>z. B. „3 von 8 Blöcken geprüft"</td></tr>
|
||
<tr><td>Sichtbarkeit</td><td><code>{#if needsTranscription.length > 0 || readyToRead.length > 0}</code></td><td>—</td><td>Streifen komplett ausgeblendet wenn leer</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<!-- PATTERN D: PRIORITY QUEUE -->
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="section-label">Muster D — Priorisierte Aufgabenliste (Priority Queue)</div>
|
||
|
||
<div class="pattern-title">„Was als nächstes?" — zusammengeführte Liste</div>
|
||
<div class="pattern-sub">Alle drei Kategorien in einer sortierten Liste mit Typ-Badge. Ersetzt die separaten drei Karten in der rechten Spalte.</div>
|
||
|
||
<div class="tag-list">
|
||
<span class="tag tag-pro">+ Keine mentale Auswahl zwischen Kategorien</span>
|
||
<span class="tag tag-pro">+ Eine einzelne Entscheidungsfläche</span>
|
||
<span class="tag tag-con">− „Lesefertig" verliert seinen Belohnungscharakter (gemischt mit Aufgaben)</span>
|
||
<span class="tag tag-con">− Merge-Logik auf dem Server ist komplexer als zwei separate Queries</span>
|
||
<span class="tag tag-con">− Farb-Badge allein reicht nicht — Icon + Label immer nötig (WCAG 1.4.1)</span>
|
||
</div>
|
||
|
||
<p class="prose">
|
||
Alle drei Kategorien werden in einer einzigen sortierten Liste zusammengeführt. Sortierung:
|
||
Metadaten fehlen (blockiert Suche) → Transkription fehlt → Lesefertig. Jede Zeile trägt ein farbkodiertes Label;
|
||
Farbe darf niemals der einzige Indikator sein — Icon und Text sind Pflicht (WCAG 1.4.1).
|
||
</p>
|
||
<p class="prose">
|
||
Kontrast-Check: Orange-700 auf Weiß = 5,4:1 ✓ AA. Navy auf Weiß = 14,5:1 ✓ AAA. Green-800 auf Weiß = 9,7:1 ✓ AAA.
|
||
</p>
|
||
|
||
<div class="frames-row">
|
||
<!-- Phone D -->
|
||
<div>
|
||
<div class="frame-phone">
|
||
<div class="ph-nav"><div class="ph-logo">FAMILIENARCHIV</div></div>
|
||
<div class="ph-body">
|
||
<div class="ph-search"><div class="ph-search-txt">⌕ Dokumente…</div></div>
|
||
<div class="f-dz" style="padding:5px;"><div class="f-dz-icon" style="font-size:10px;">↑</div><div class="f-dz-txt">Hochladen</div></div>
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-htitle">Was als nächstes?</div>
|
||
<div class="f-row"><div class="f-dot orange" style="margin-top:2px;"></div><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub" style="color:var(--orange);">⚠ Metadaten fehlen</div></div></div>
|
||
<div class="f-row"><div class="f-dot navy" style="margin-top:2px;"></div><div><div class="f-doc-name">Taufurkunde Karl R.</div><div class="f-doc-sub">✏ Noch nicht begonnen</div></div></div>
|
||
<div class="f-row"><div class="f-dot navy" style="margin-top:2px;"></div><div><div class="f-doc-name">Reisepass Opa</div><div class="f-doc-sub">✏ 3 von 8 Blöcken</div></div></div>
|
||
<div class="f-row" style="border-bottom:none;"><div class="f-dot green" style="margin-top:2px;"></div><div><div class="f-doc-name">Postkarte 1943</div><div class="f-doc-sub" style="color:var(--green);">✓ Lesefertig</div></div></div>
|
||
</div>
|
||
<div class="f-card" style="padding:5px;">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div class="f-doc-name">Brief von Oma Martha</div></div>
|
||
<div class="f-row"><div class="f-doc-name">Taufurkunde Karl R.</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Mobil 320 px</span>
|
||
</div>
|
||
|
||
<!-- Desktop D -->
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="frame-desktop">
|
||
<div class="f-nav">
|
||
<div class="f-logo">FAMILIENARCHIV</div>
|
||
<div class="f-navlinks"><div class="f-navlink on">Archiv</div><div class="f-navlink">Personen</div></div>
|
||
<div class="f-navr"><div class="f-av">MR</div></div>
|
||
</div>
|
||
<div class="f-body">
|
||
<div class="f-search"><div class="f-search-icon">⌕</div><div class="f-search-txt">Dokumente durchsuchen…</div></div>
|
||
<div class="f-resume"></div>
|
||
<div class="f-grid-2">
|
||
<div class="f-card">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief von Oma Martha, 1943</div></div><div class="f-doc-date">12. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl Raddatz</div></div><div class="f-doc-date">9. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div></div><div class="f-doc-date">7. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto Sommer 1952</div></div><div class="f-doc-date">3. Apr</div></div>
|
||
<div class="f-stats">47 Dokumente · 12 Personen</div>
|
||
</div>
|
||
<div class="rhs">
|
||
<div class="f-dz"><div class="f-dz-icon">↑</div><div class="f-dz-txt">Datei hochladen</div><div class="f-dz-sub">Drag & Drop</div></div>
|
||
<div class="f-card" style="flex:1;">
|
||
<div class="f-htitle">Was als nächstes?</div>
|
||
<div class="f-row"><div class="f-dot orange"></div><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub" style="color:var(--orange);">⚠ Metadaten fehlen</div></div></div>
|
||
<div class="f-row"><div class="f-dot orange"></div><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub" style="color:var(--orange);">⚠ Datum fehlt</div></div></div>
|
||
<div class="f-row"><div class="f-dot navy"></div><div><div class="f-doc-name">Taufurkunde Karl R.</div><div class="f-doc-sub">✏ Noch nicht begonnen</div></div></div>
|
||
<div class="f-row"><div class="f-dot navy"></div><div><div class="f-doc-name">Reisepass Opa Heinrich</div><div class="f-doc-sub">✏ 3 von 8 Blöcken</div></div></div>
|
||
<div class="f-row" style="border-bottom:none;"><div class="f-dot green"></div><div><div class="f-doc-name">Postkarte aus Breslau</div><div class="f-doc-sub" style="color:var(--green);">✓ Lesefertig</div></div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Desktop (55 %) — eine Liste, drei Typen durch Farbe + Icon + Label unterschieden</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="impl-ref">
|
||
<table>
|
||
<thead><tr><th>Element</th><th>Tailwind-Klassen</th><th>Wert</th><th>Hinweis</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Listen-Wrapper</td><td><code>rounded-sm border border-line bg-white p-4 flex-1</code></td><td>—</td><td>Ersetzt separate 3 Karten</td></tr>
|
||
<tr><td>Prioritäts-Zeile</td><td><code>flex items-start gap-3 py-2 border-b border-line last:border-0 min-h-[44px]</code></td><td>min-h 44 px ✓</td><td>WCAG touch target</td></tr>
|
||
<tr><td>Typ-Punkt</td><td><code>w-2 h-2 rounded-full mt-1.5 shrink-0</code></td><td>8 × 8 px</td><td>Nie allein — Label ist Pflicht</td></tr>
|
||
<tr><td>Label orange</td><td><code>text-xs text-orange-700</code></td><td>12 px</td><td>Kontrast 5,4:1 ✓ AA</td></tr>
|
||
<tr><td>Label navy</td><td><code>text-xs text-ink</code></td><td>12 px</td><td>Kontrast 14,5:1 ✓ AAA</td></tr>
|
||
<tr><td>Label grün</td><td><code>text-xs text-green-800</code></td><td>12 px</td><td>Kontrast 9,7:1 ✓ AAA</td></tr>
|
||
<tr><td>Merge-Service</td><td><code>findWhatsNext(int size)</code> auf <code>DashboardController</code></td><td>—</td><td>Sortierung: Metadaten → Trans → Lesefertig; per Markus: Threshold als <code>@Param</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<!-- ── COMPARISON TABLE ──────────────────────────────────────────────── -->
|
||
<div class="section">
|
||
<div class="section-label">Vergleich aller vier Muster</div>
|
||
<table class="cmp">
|
||
<thead>
|
||
<tr>
|
||
<th>Kriterium</th>
|
||
<th>A — Tabs</th>
|
||
<th>B — Accordion</th>
|
||
<th>C — Mission Control ★</th>
|
||
<th>D — Priority Queue</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Alle 3 Kategorien sofort sichtbar</strong></td>
|
||
<td class="fail">Nein</td>
|
||
<td class="warn">Nur Überschriften</td>
|
||
<td class="pass best">Ja</td>
|
||
<td class="fail">Nein (gemischt)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Neueste Aktivität bleibt Primärinhalt</strong></td>
|
||
<td class="pass">Ja</td>
|
||
<td class="pass">Ja</td>
|
||
<td class="pass best">Ja</td>
|
||
<td class="pass">Ja</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>60+ Usability (Discovery ohne Klick)</strong></td>
|
||
<td class="warn">Mittel</td>
|
||
<td class="warn">Überschriften sichtbar</td>
|
||
<td class="pass best">Sehr gut</td>
|
||
<td class="warn">Mittel — gemischte Liste</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>JS-Zustand nötig</strong></td>
|
||
<td class="fail">Ja (aktiver Tab)</td>
|
||
<td class="pass">Nein</td>
|
||
<td class="pass best">Nein</td>
|
||
<td class="pass">Nein</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>WCAG 2.2 compliance (out of the box)</strong></td>
|
||
<td class="warn">tablist + aria-selected nötig</td>
|
||
<td class="pass">details/summary nativ</td>
|
||
<td class="pass best">Keine neuen Anforderungen</td>
|
||
<td class="warn">Farbe + Icon + Label alle Pflicht</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Mobile 320 px</strong></td>
|
||
<td class="warn">3 Tabs zu schmal</td>
|
||
<td class="pass">Gut</td>
|
||
<td class="pass best">Sehr gut — stapelt natürlich</td>
|
||
<td class="pass">Gut</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>„Lesefertig" als visueller Applaus</strong></td>
|
||
<td class="warn">Nur wenn Tab aktiv</td>
|
||
<td class="warn">Nur wenn offen</td>
|
||
<td class="pass best">Ja — eigene mint-Karte</td>
|
||
<td class="fail">Nein — gleichwertig mit Aufgaben</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Backend-Merge-Komplexität</strong></td>
|
||
<td class="pass">Gering</td>
|
||
<td class="pass">Gering</td>
|
||
<td class="pass best">Gering (2 separate Queries)</td>
|
||
<td class="warn">Mittel (Merge + Sortierung)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Implementierungsaufwand Frontend</strong></td>
|
||
<td class="warn">Mittel</td>
|
||
<td class="pass">Gering</td>
|
||
<td class="pass best">Gering</td>
|
||
<td class="pass">Gering</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- ── RECOMMENDATION ────────────────────────────────────────────────── -->
|
||
<div class="rec">
|
||
<h3>Empfehlung: Muster C — Mission-Control-Streifen</h3>
|
||
<p>
|
||
Der Mission-Control-Streifen ist das einzige Muster, das alle drei Kategorien gleichzeitig sichtbar macht,
|
||
ohne den Primärinhalt zu verstecken oder JS-Zustand zu erzeugen. Scrollen nach unten ist kein Fehler —
|
||
versteckter Inhalt schon.
|
||
</p>
|
||
<ul>
|
||
<li><strong>Tabs (A)</strong> — Gut für kompakten Platz, aber inaktive Kategorien werden von 60+-Nutzern übersehen. Tabs für die <em>gesamte Seite</em> (wie ursprünglich vorgeschlagen) wäre ein Antipattern — Neueste Aktivität wäre hinter einem Klick.</li>
|
||
<li><strong>Accordion (B)</strong> — Solide Fallback-Option ohne JS, wenn der Streifen aus Platzgründen abgelehnt wird. Alle Kategorien-Überschriften bleiben sichtbar.</li>
|
||
<li><strong>Priority Queue (D)</strong> — Elegant, aber „Lesefertig" verliert seinen Belohnungscharakter. Die Merge-Logik ist auch komplexer als zwei separate Queries.</li>
|
||
<li><strong>Mission Control (C)</strong> — Keine versteckten Inhalte. Kein JS. „Lesefertig" bekommt eine eigene mint-getönte Spalte als visuellen Applaus. Mobil stapeln die Spalten ohne weiteren Code. Der einzige Trade-off ist ein leichtes Scrollen auf Desktop.</li>
|
||
</ul>
|
||
<p style="margin-top:12px;">
|
||
<strong>Quick win:</strong> Wenn C abgelehnt wird — <strong>Muster B (Accordion)</strong> als Zweitstimme. Kein Refactoring der rechten Spalte, kein JS, alle Kategorien-Überschriften immer sichtbar.
|
||
</p>
|
||
</div>
|
||
|
||
|
||
<hr/>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<!-- MISSION CONTROL v2: SEGMENTATION SPLIT + ENGAGEMENT -->
|
||
<!-- ══════════════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="section-label">Mission-Control-Streifen v2 — Segmentierung / Transkription / Lesefertig</div>
|
||
|
||
<div class="pattern-title">Beitragspyramide: Skill-basierte Aufgabentrennung</div>
|
||
<div class="pattern-sub">
|
||
Die ursprüngliche „Transkription fehlt"-Spalte wird in zwei klar getrennte Aufgaben aufgeteilt, die
|
||
unterschiedliche Fähigkeiten erfordern. Das löst gleichzeitig das Problem der leeren dritten Spalte.
|
||
</div>
|
||
|
||
<!-- Lifecycle diagram -->
|
||
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:20px;padding:16px 20px;background:#fff;border:1px solid var(--border);border-radius:6px;font-size:12px;">
|
||
<div style="text-align:center;">
|
||
<div style="background:var(--navy);color:#fff;border-radius:4px;padding:4px 10px;font-weight:600;font-size:11px;margin-bottom:4px;">Kein Segment</div>
|
||
<div style="font-size:10px;color:var(--muted);">0 Annotationen</div>
|
||
</div>
|
||
<div style="color:var(--muted);font-size:18px;">→</div>
|
||
<div style="text-align:center;">
|
||
<div style="background:var(--navy);color:#fff;border-radius:4px;padding:4px 10px;font-weight:600;font-size:11px;margin-bottom:4px;">Segmentiert</div>
|
||
<div style="font-size:10px;color:var(--muted);">Rahmen vorhanden, kein Text</div>
|
||
</div>
|
||
<div style="color:var(--muted);font-size:18px;">→</div>
|
||
<div style="text-align:center;">
|
||
<div style="background:var(--navy);color:#fff;border-radius:4px;padding:4px 10px;font-weight:600;font-size:11px;margin-bottom:4px;">Transkribiert</div>
|
||
<div style="font-size:10px;color:var(--muted);">Text vorhanden, review < 90 %</div>
|
||
</div>
|
||
<div style="color:var(--muted);font-size:18px;">→</div>
|
||
<div style="text-align:center;">
|
||
<div style="background:var(--green);color:#fff;border-radius:4px;padding:4px 10px;font-weight:600;font-size:11px;margin-bottom:4px;">Lesefertig ✓</div>
|
||
<div style="font-size:10px;color:var(--muted);">review ≥ 90 %</div>
|
||
</div>
|
||
<div style="margin-left:auto;font-size:11px;color:var(--muted);max-width:220px;line-height:1.4;">
|
||
Jede Stufe landet in einer eigenen Spalte. Die dritte Spalte ist strukturell nie leer —
|
||
Lesefertig-Dokumente erscheinen sobald auch nur eines fertig ist.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Column content definitions -->
|
||
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-bottom:24px;">
|
||
<div style="background:#fff;border:1px solid var(--border);border-radius:6px;padding:14px;">
|
||
<div style="font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--navy);margin-bottom:6px;">Spalte 1 — Segmentierung</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;margin-bottom:8px;">
|
||
Dokumente ohne Annotationsrahmen. <strong>Keine Vorkenntnisse nötig</strong> — Rahmen um Textblöcke einzeichnen. Niedrigste Einstiegshürde, breiteste Zielgruppe.
|
||
</div>
|
||
<div style="font-size:11px;color:var(--navy);font-weight:600;">Query: <code>SELECT … WHERE annotation_count = 0</code></div>
|
||
</div>
|
||
<div style="background:#fff;border:1px solid var(--border);border-radius:6px;padding:14px;">
|
||
<div style="font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--navy);margin-bottom:6px;">Spalte 2 — Transkription</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;margin-bottom:8px;">
|
||
Dokumente mit Rahmen, aber wenig/kein Text (<code>text IS NULL OR LENGTH(text) < threshold</code>). <strong>Kurrent-Kenntnisse empfohlen.</strong>
|
||
</div>
|
||
<div style="font-size:11px;color:var(--navy);font-weight:600;">Query: <code>annotation_count > 0 AND reviewed < 75 %</code></div>
|
||
</div>
|
||
<div style="background:rgba(166,218,216,.10);border:1px solid var(--mint);border-radius:6px;padding:14px;">
|
||
<div style="font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--green);margin-bottom:6px;">Spalte 3 — Lesefertig ✓</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;margin-bottom:8px;">
|
||
Dokumente mit reviewed ≥ 90 %. Belohnungsbereich — kein Auftrag, sondern eine Einladung zum Lesen.
|
||
</div>
|
||
<div style="font-size:11px;color:var(--green);font-weight:600;">Query: <code>reviewed_pct >= 0.90</code> (bestehend)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── ENGAGEMENT FEATURES ── -->
|
||
<div style="margin-bottom:20px;">
|
||
<div style="font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:14px;padding-bottom:6px;border-bottom:1px solid var(--border);">Engagement-Elemente — 5 Ideen</div>
|
||
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px;">
|
||
|
||
<div style="background:#fff;border-left:3px solid var(--navy);padding:12px 16px;border-radius:0 4px 4px 0;">
|
||
<div style="font-size:12px;font-weight:700;color:var(--navy);margin-bottom:4px;">① Fortschritt — drei verschiedene Granularitäten</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;">
|
||
<strong style="color:var(--orange);">Kein globaler Balken</strong> bei 1 500 Dokumenten.
|
||
Ein Balken bei 0,8 % Füllstand ist psychologisch demotivierender als gar kein Balken
|
||
(endowed-progress-Effekt: Menschen brechen auf, wenn das Ziel unerreichbar wirkt).
|
||
<br/><br/>
|
||
Stattdessen drei zielgruppengerechte Ansätze:
|
||
<ul style="margin:6px 0 0 14px;line-height:1.7;">
|
||
<li><strong>Segmentierung-Spalte:</strong> Wochenpuls — „Diese Woche: +5 Dokumente". Zeigt Schwung, nicht den Berg. Query: <code style="font-size:10px;">COUNT(*) WHERE created_at > NOW() - INTERVAL '7 days'</code></li>
|
||
<li><strong>Transkription-Zeilen:</strong> Balkensegment pro Dokument — „3 von 8 Blöcken". Hier ist der Maßstab korrekt: 8 Blöcke sind in einer Sitzung erreichbar. Nur sichtbar wenn annotation_count > 0.</li>
|
||
<li><strong>Lesefertig-Zeilen:</strong> Prozentzahl als Text — „94 % geprüft". Kein Balken nötig — der Erfolg ist bereits kommuniziert durch die mint-Spalte selbst.</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="background:#fff;border-left:3px solid var(--navy);padding:12px 16px;border-radius:0 4px 4px 0;">
|
||
<div style="font-size:12px;font-weight:700;color:var(--navy);margin-bottom:4px;">② Skill-Label als Zugangsfilter</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;">
|
||
Unter dem Spaltentitel: ein kleines Pill-Label mit der Anforderung. „Ohne Vorkenntnisse" (grün) vs.
|
||
„Kurrent-Kenntnisse" (neutral). Senkt die Hemmschwelle für Neueinsteiger drastisch — sie sehen sofort,
|
||
was sie tun können.
|
||
</div>
|
||
</div>
|
||
|
||
<div style="background:#fff;border-left:3px solid var(--mint);padding:12px 16px;border-radius:0 4px 4px 0;">
|
||
<div style="font-size:12px;font-weight:700;color:var(--navy);margin-bottom:4px;">③ Contributor-Avatare (Social Proof)</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;">
|
||
Unter dem Titel: kleine Initialen-Bubbles der letzten 3 Beitragenden. Kein Leaderboard (erzeugt
|
||
Wettbewerb), aber soziale Sichtbarkeit (erzeugt Zugehörigkeit). „MR, TG und 2 weitere haben hier
|
||
mitgemacht."
|
||
</div>
|
||
</div>
|
||
|
||
<div style="background:#fff;border-left:3px solid var(--mint);padding:12px 16px;border-radius:0 4px 4px 0;">
|
||
<div style="font-size:12px;font-weight:700;color:var(--navy);margin-bottom:4px;">④ „Starte hier →" CTA-Button</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;">
|
||
Jede Aufgaben-Spalte endet mit einem einzelnen, klaren CTA, der direkt zum nächsten zu bearbeitenden
|
||
Dokument springt. Kein Auswahlprozess, kein Überlegen — ein Klick, sofort im Dokument. Entscheidungslähmung
|
||
ist der Hauptgrund für Non-Participation.
|
||
</div>
|
||
</div>
|
||
|
||
<div style="background:#fff;border-left:3px solid var(--orange);padding:12px 16px;border-radius:0 4px 4px 0;grid-column:span 2;">
|
||
<div style="font-size:12px;font-weight:700;color:var(--navy);margin-bottom:4px;">⑤ Lesefertig-Leerstand → Cross-Column-Redirect</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.5;">
|
||
Wenn Lesefertig leer ist (frühe Projektphase), zeigt die Spalte <em>nicht</em> „Noch nichts fertig" als
|
||
stille Sackgasse. Stattdessen: „Dokumente erscheinen hier, wenn die Transkription abgeschlossen ist —
|
||
<a style="color:var(--navy);">jetzt mithelfen →</a>". Der Link springt direkt zur Segmentierungs-Spalte. Leerer Zustand = aktive
|
||
Einladung, kein toter Endpunkt.
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Desktop mockup v2 -->
|
||
<div class="frames-row">
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="frame-desktop">
|
||
<div class="f-nav">
|
||
<div class="f-logo">FAMILIENARCHIV</div>
|
||
<div class="f-navlinks"><div class="f-navlink on">Archiv</div><div class="f-navlink">Personen</div></div>
|
||
<div class="f-navr"><div class="f-av">MR</div></div>
|
||
</div>
|
||
<div class="f-body">
|
||
<div class="f-search"><div class="f-search-icon">⌕</div><div class="f-search-txt">Dokumente durchsuchen…</div></div>
|
||
<div class="f-resume"></div>
|
||
<div class="f-grid-2" style="margin-bottom:7px;">
|
||
<div class="f-card">
|
||
<div class="f-htitle">Neueste Aktivität</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Brief von Oma Martha, 1943</div></div><div class="f-doc-date">12. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl Raddatz</div></div><div class="f-doc-date">9. Apr</div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Postkarte aus Breslau</div></div><div class="f-doc-date">7. Apr</div></div>
|
||
<div class="f-stats">47 Dokumente · 12 Personen</div>
|
||
</div>
|
||
<div class="rhs">
|
||
<div class="f-dz"><div class="f-dz-icon">↑</div><div class="f-dz-txt">Datei hochladen</div><div class="f-dz-sub">Drag & Drop</div></div>
|
||
<div class="f-card" style="flex:1;">
|
||
<div class="f-htitle orange">Metadaten fehlen</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Familienfoto 1952</div><div class="f-doc-sub">Titel fehlt</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamtsurkunde</div><div class="f-doc-sub">Datum fehlt</div></div></div>
|
||
<a class="f-link">Alle 5 anzeigen →</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ★★ Enhanced strip v2 -->
|
||
<div style="background:#fff;border:1px solid var(--sand);border-radius:3px;padding:8px;">
|
||
<div class="f-htitle" style="margin-bottom:7px;">Was braucht Aufmerksamkeit?</div>
|
||
<div class="f-grid-3">
|
||
|
||
<!-- Col 1: SEGMENTIERUNG — weekly pulse replaces global bar -->
|
||
<div style="background:rgba(0,40,80,.03);border:1px solid var(--sand);border-radius:3px;padding:6px;display:flex;flex-direction:column;gap:4px;">
|
||
<div>
|
||
<div class="f-htitle navy" style="margin-bottom:2px;">Rahmen einzeichnen</div>
|
||
<div style="display:inline-flex;align-items:center;gap:2px;padding:1px 5px;border-radius:8px;background:var(--green-bg);border:1px solid rgba(46,110,57,.2);font-size:5px;font-weight:700;color:var(--green);margin-bottom:3px;">✓ Ohne Vorkenntnisse</div>
|
||
<!-- Weekly pulse: shows momentum, not the mountain -->
|
||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:3px;">
|
||
<div style="font-size:5.5px;color:var(--green);font-weight:700;">↑ +5 diese Woche</div>
|
||
<div style="font-size:5px;color:var(--muted);">· 1 480 offen</div>
|
||
</div>
|
||
<div style="display:flex;gap:2px;margin-bottom:4px;">
|
||
<div style="width:10px;height:10px;border-radius:50%;background:var(--navy);display:flex;align-items:center;justify-content:center;font-size:4px;font-weight:700;color:#fff;">MR</div>
|
||
<div style="width:10px;height:10px;border-radius:50%;background:#5B5EA6;display:flex;align-items:center;justify-content:center;font-size:4px;font-weight:700;color:#fff;">TG</div>
|
||
<div style="width:10px;height:10px;border-radius:50%;background:#8C6E3F;display:flex;align-items:center;justify-content:center;font-size:4px;font-weight:700;color:#fff;">AS</div>
|
||
<div style="font-size:5px;color:var(--muted);line-height:10px;margin-left:2px;">+ 2</div>
|
||
</div>
|
||
</div>
|
||
<div class="f-row"><div><div class="f-doc-name">Taufurkunde Karl R.</div><div class="f-doc-sub">Noch keine Rahmen</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Standesamt 1889</div><div class="f-doc-sub">Noch keine Rahmen</div></div></div>
|
||
<div class="f-row"><div><div class="f-doc-name">Heiratsurkunde 1921</div><div class="f-doc-sub">Noch keine Rahmen</div></div></div>
|
||
<a style="display:block;font-size:6px;font-weight:700;color:#fff;background:var(--navy);border-radius:2px;padding:3px 6px;text-align:center;margin-top:3px;">Jetzt einzeichnen →</a>
|
||
</div>
|
||
|
||
<!-- Col 2: TRANSKRIPTION — per-document mini bar, no global bar -->
|
||
<div style="background:rgba(0,40,80,.03);border:1px solid var(--sand);border-radius:3px;padding:6px;display:flex;flex-direction:column;gap:4px;">
|
||
<div>
|
||
<div class="f-htitle navy" style="margin-bottom:2px;">Text eintippen</div>
|
||
<div style="display:inline-flex;align-items:center;gap:2px;padding:1px 5px;border-radius:8px;background:rgba(0,40,80,.08);border:1px solid rgba(0,40,80,.15);font-size:5px;font-weight:700;color:var(--navy);margin-bottom:3px;">Kurrent hilfreich</div>
|
||
<div style="display:flex;align-items:center;gap:4px;margin-bottom:3px;">
|
||
<div style="font-size:5.5px;color:var(--navy);font-weight:700;">↑ +2 diese Woche</div>
|
||
<div style="font-size:5px;color:var(--muted);">· 8 offen</div>
|
||
</div>
|
||
<div style="display:flex;gap:2px;margin-bottom:4px;">
|
||
<div style="width:10px;height:10px;border-radius:50%;background:var(--navy);display:flex;align-items:center;justify-content:center;font-size:4px;font-weight:700;color:#fff;">MR</div>
|
||
<div style="font-size:5px;color:var(--muted);line-height:10px;margin-left:2px;">1 Person</div>
|
||
</div>
|
||
</div>
|
||
<!-- Per-document mini bar — right granularity, achievable in one session -->
|
||
<div style="display:flex;flex-direction:column;gap:2px;border-bottom:1px solid var(--sand);padding-bottom:4px;">
|
||
<div class="f-doc-name">Brief v. Oma Martha 1943</div>
|
||
<div style="display:flex;align-items:center;gap:3px;">
|
||
<div style="flex:1;height:3px;background:rgba(0,40,80,.12);border-radius:2px;overflow:hidden;"><div style="width:0%;height:100%;background:var(--navy);border-radius:2px;"></div></div>
|
||
<div style="font-size:5px;color:var(--muted);white-space:nowrap;">0 / 6 Blöcke</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:2px;border-bottom:1px solid var(--sand);padding-bottom:4px;">
|
||
<div class="f-doc-name">Reisepass Opa Heinrich</div>
|
||
<div style="display:flex;align-items:center;gap:3px;">
|
||
<div style="flex:1;height:3px;background:rgba(0,40,80,.12);border-radius:2px;overflow:hidden;"><div style="width:37%;height:100%;background:var(--navy);border-radius:2px;"></div></div>
|
||
<div style="font-size:5px;color:var(--muted);white-space:nowrap;">3 / 8 Blöcke</div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:2px;">
|
||
<div class="f-doc-name">Postkarte aus Breslau</div>
|
||
<div style="display:flex;align-items:center;gap:3px;">
|
||
<div style="flex:1;height:3px;background:rgba(0,40,80,.12);border-radius:2px;overflow:hidden;"><div style="width:0%;height:100%;background:var(--navy);border-radius:2px;"></div></div>
|
||
<div style="font-size:5px;color:var(--muted);white-space:nowrap;">0 / 4 Blöcke</div>
|
||
</div>
|
||
</div>
|
||
<a style="display:block;font-size:6px;font-weight:700;color:#fff;background:var(--navy);border-radius:2px;padding:3px 6px;text-align:center;margin-top:3px;">Jetzt tippen →</a>
|
||
</div>
|
||
|
||
<!-- Col 3: LESEFERTIG — filled: % as text; empty: cross-column redirect -->
|
||
<div style="background:rgba(166,218,216,.10);border:1px solid var(--mint);border-radius:3px;padding:6px;display:flex;flex-direction:column;gap:4px;">
|
||
<div>
|
||
<div class="f-htitle green" style="margin-bottom:2px;">Lesefertig ✓</div>
|
||
<div style="font-size:5.5px;color:var(--green);font-weight:600;margin-bottom:4px;">3 Dokumente bereit</div>
|
||
<div style="display:flex;gap:2px;margin-bottom:4px;">
|
||
<div style="width:10px;height:10px;border-radius:50%;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:4px;font-weight:700;color:#fff;">MR</div>
|
||
<div style="width:10px;height:10px;border-radius:50%;background:#5B5EA6;display:flex;align-items:center;justify-content:center;font-size:4px;font-weight:700;color:#fff;">TG</div>
|
||
</div>
|
||
</div>
|
||
<!-- % as text — no bar, the mint column itself signals success -->
|
||
<div style="display:flex;flex-direction:column;gap:1px;border-bottom:1px solid rgba(166,218,216,.4);padding-bottom:3px;">
|
||
<div class="f-doc-name">Postkarte aus Breslau 1943</div>
|
||
<div style="font-size:5.5px;color:var(--green);font-weight:600;">100 % geprüft</div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:1px;border-bottom:1px solid rgba(166,218,216,.4);padding-bottom:3px;">
|
||
<div class="f-doc-name">Brief Oma Martha 1938</div>
|
||
<div style="font-size:5.5px;color:var(--green);font-weight:600;">95 % geprüft</div>
|
||
</div>
|
||
<div style="display:flex;flex-direction:column;gap:1px;">
|
||
<div class="f-doc-name">Heiratsurkunde 1921</div>
|
||
<div style="font-size:5.5px;color:var(--green);font-weight:600;">91 % geprüft</div>
|
||
</div>
|
||
<a class="f-link green" style="margin-top:3px;">Alle 3 lesen →</a>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="caption">Desktop (55 %) — v2: Spalten 1+2 aufgeteilt, Lesefertig-Leerstand mit aktivem Cross-Column-CTA</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- impl-ref v2 -->
|
||
<div class="impl-ref">
|
||
<table>
|
||
<thead><tr><th>Element</th><th>Tailwind-Klassen / Logik</th><th>Wert</th><th>Hinweis</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Skill-Pill „Ohne Vorkenntnisse"</td><td><code>inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold bg-green-50 border border-green-200 text-green-800</code></td><td>Kontrast 9,7:1 ✓</td><td>Klärung für 60+ und Neueinsteiger</td></tr>
|
||
<tr><td>Skill-Pill „Kurrent hilfreich"</td><td><code>inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold bg-surface border border-line text-ink</code></td><td>neutral — kein Schreckpunkt</td><td>Nicht „Experten nötig" sondern „hilfreich"</td></tr>
|
||
<tr><td>Wochenpuls (Segmentierung + Transkription)</td><td><code>text-xs font-semibold text-green-700</code> (Seg.) / <code>text-ink</code> (Trans.)</td><td>12 px</td><td>Query: <code>COUNT WHERE created_at > NOW() - INTERVAL '7 days'</code>; kein globaler Balken</td></tr>
|
||
<tr><td>Per-Dokument-Balken Track</td><td><code>flex-1 h-1 bg-navy/20 rounded-full overflow-hidden</code></td><td>h: 4 px</td><td>Nur in Transkription-Spalte, nur wenn <code>annotation_count > 0</code></td></tr>
|
||
<tr><td>Per-Dokument-Balken Füllstand</td><td><code>h-full bg-navy rounded-full</code> + <code>style="width:{pct}%"</code></td><td>—</td><td>pct = textedBlocks / totalBlocks * 100; Guard: totalBlocks = 0 → width 0</td></tr>
|
||
<tr><td>Lesefertig-Prozentzahl</td><td><code>text-xs font-semibold text-green-800</code></td><td>12 px</td><td>Kein Balken — die mint-Spalte selbst ist das Erfolgssignal</td></tr>
|
||
<tr><td>Contributor-Avatar</td><td><code>w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-bold text-white</code></td><td>24 × 24 px</td><td>Farbe per User-ID deterministisch (kein API-Feld nötig)</td></tr>
|
||
<tr><td>„Starte hier"-CTA</td><td><code>block w-full text-center text-xs font-semibold text-white bg-ink rounded-sm py-1.5 mt-2 hover:bg-ink-2 transition-colors focus-visible:ring-2 focus-visible:ring-ink</code></td><td>min-h 36 px</td><td>Link: <code>/enrich?filter=NEEDS_SEGMENTATION&next=1</code></td></tr>
|
||
<tr><td>Lesefertig-Leerstand CTA</td><td><code>inline-flex items-center text-xs font-semibold text-ink border border-ink rounded-sm px-3 py-1 hover:bg-ink hover:text-white transition-colors</code></td><td>—</td><td>Link springt zur Segmentierungs-Ansicht</td></tr>
|
||
<tr><td>Contributor-API-Feld</td><td><code>GET /api/documents/needs-segmentation</code> → DTO enthält <code>lastContributors: [{initials, colorSeed}]</code></td><td>max 3 Avatare</td><td>Neues DTO-Feld — beachte Nora: nur Initialen, keine Namen</td></tr>
|
||
<tr><td>Segmentierung-Query</td><td><code>WHERE NOT EXISTS (SELECT 1 FROM document_annotations WHERE document_id = d.id)</code></td><td>—</td><td>Index auf <code>document_annotations.document_id</code> prüfen (Tobias)</td></tr>
|
||
<tr><td>Transkription-Query</td><td><code>EXISTS annotation AND (no blocks OR reviewed_pct < 0.75)</code></td><td>—</td><td>Guard gegen Division durch 0 (Sara)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Security note -->
|
||
<div style="margin-top:16px;background:var(--orange-bg);border-left:3px solid var(--orange);padding:12px 16px;border-radius:0 4px 4px 0;font-size:12px;">
|
||
<strong style="color:var(--orange);">Datenschutz-Hinweis (Nora):</strong> Contributor-Avatare zeigen nur Initialen, niemals volle Namen im DOM.
|
||
Das DTO liefert <code>initials</code> + einen deterministischen <code>colorSeed</code> (z. B. Hash der User-ID mod 6 Farben),
|
||
keine E-Mail-Adressen oder echten Namen. Das <code>@RequirePermission(READ_ALL)</code> auf den neuen Endpoints gilt auch hier.
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /doc -->
|
||
</body>
|
||
</html>
|