Files
familienarchiv/docs/specs/transkriptions-richtlinien-spec.html
Marcel 1d5219eac4
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m59s
CI / OCR Service Tests (push) Successful in 38s
CI / Backend Unit Tests (push) Failing after 2m58s
docs(specs): add Transkriptions-Richtlinien spec for #320
Final UI/UX spec for the /hilfe/transkription page referenced from
the Transcribe panel coach card. Card-grid layout with per-rule
Beispiel boxes, Wikipedia info-card, "Noch in Klärung" strip, and
closing invitation. Includes impl-ref tables, Paraglide keys for
de/en/es, print styles, and Gherkin acceptance criteria.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 18:47:47 +02:00

1147 lines
82 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Transkriptions-Richtlinien · Spec · Familienarchiv</title>
<link href="https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;1,300&family=Montserrat:wght@400;500;600;700;800;900&display=swap" rel="stylesheet"/>
<style>
/* ── Reset ── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Montserrat',system-ui,sans-serif;background:#ECEAE4;color:#1A1A1A;line-height:1.5;font-size:13px}
.doc{max-width:1320px;margin:0 auto;padding:48px 32px 120px}
/* ── Masthead ── */
.mh{padding-bottom:24px;border-bottom:3px solid #012851;margin-bottom:54px}
.mh .kicker{font-size:9px;font-weight:800;letter-spacing:2px;text-transform:uppercase;color:#A6DAD8}
.mh h1{font-size:30px;font-weight:900;color:#012851;letter-spacing:-.5px;margin-top:6px}
.mh p{font-size:13.5px;color:#555;max-width:820px;line-height:1.8;margin-top:12px}
.mh .byline{font-size:9px;color:#999;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;margin-top:16px}
.tag-row{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}
.tag{background:#012851;color:#A6DAD8;padding:3px 9px;border-radius:2px;font-size:8.5px;font-weight:800;letter-spacing:.8px;text-transform:uppercase}
.tag.green{background:#1e5e34;color:#d1fae5}
.tag.mint{background:#A6DAD8;color:#012851}
.tag.amber{background:#7c4a00;color:#fde68a}
/* ── Section rhythm ── */
.section{margin-bottom:92px}
.section-head{margin-bottom:32px}
.section-kicker{font-size:9px;font-weight:800;letter-spacing:2px;text-transform:uppercase;color:#A6DAD8;display:block;margin-bottom:6px}
.section-head h2{font-family:'Merriweather',Georgia,serif;font-size:26px;font-weight:700;color:#012851;letter-spacing:-.3px}
.section-head p{font-size:13px;color:#555;line-height:1.75;max-width:780px;margin-top:10px}
/* ── State chip row ── */
.state-row{display:flex;align-items:center;gap:10px;margin-bottom:18px;flex-wrap:wrap}
.viewport-chip{background:#F0EEE8;color:#4b5563;padding:4px 10px;border-radius:2px;font-size:9px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;border:1px solid #E4E2D7}
.theme-chip{padding:4px 10px;border-radius:2px;font-size:9px;font-weight:800;letter-spacing:.8px;text-transform:uppercase}
.theme-chip.light{background:#fff;color:#012851;border:1px solid #E4E2D7}
.theme-chip.dark{background:#011526;color:#f0efe9;border:1px solid #0d3358}
.theme-chip.print{background:#fff;color:#333;border:1px solid #333}
.state-note{font-size:11.5px;color:#888;margin-left:6px}
/* ═══════════════════════════════════════════════════════════════════════ */
/* ══ PAGE MOCKUP COMPONENTS ══ */
/* ═══════════════════════════════════════════════════════════════════════ */
.screen{margin:0 auto 28px}
.screen.w-desktop{max-width:1040px}
.screen.w-tablet{max-width:720px}
.screen.w-mobile{max-width:380px}
.chrome{border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,.12);border:1.5px solid rgba(0,0,0,.08)}
/* ── Theme tokens ── */
.chrome.theme-light{
--c-canvas:#E4E2D7; --c-surface:#ffffff; --c-muted:#EFEEE4; --c-paper:#FAF8F1;
--c-line:#E4E2D7; --c-line-2:#D4D1C4;
--c-ink:#012851; --c-ink-2:#3a4a5c; --c-ink-3:#6b7280;
--c-accent:#A6DAD8; --c-accent-bg:rgba(166,218,216,.18);
--c-primary:#012851; --c-primary-fg:#ffffff;
--c-header:#012851;
--c-chrome-bg:#E8E6E0; --c-chrome-border:#C4C0BA;
}
.chrome.theme-dark{
--c-canvas:#010e1e; --c-surface:#011526; --c-muted:#011a30; --c-paper:#0a1d2e;
--c-line:#0d3358; --c-line-2:#133a62;
--c-ink:#f0efe9; --c-ink-2:#9ca3af; --c-ink-3:#8b97a5;
--c-accent:#00c7b1; --c-accent-bg:rgba(0,199,177,.12);
--c-primary:#A6DAD8; --c-primary-fg:#012851;
--c-header:#012851;
--c-chrome-bg:#0b1a2e; --c-chrome-border:#1a2d47;
}
/* ── Browser/app chrome ── */
.bar{height:22px;background:var(--c-chrome-bg);border-bottom:1px solid var(--c-chrome-border);display:flex;align-items:center;padding:0 9px;gap:5px}
.bar .dot{width:7px;height:7px;border-radius:50%;background:var(--c-chrome-border);opacity:.7}
.bar .url{flex:1;height:10px;background:var(--c-chrome-border);border-radius:5px;margin-left:8px;opacity:.6}
.bar .vp{font-size:7.5px;font-weight:800;color:var(--c-accent);letter-spacing:1px;text-transform:uppercase;padding:3px 8px;background:var(--c-header);border-radius:2px;margin-left:8px}
.app-nav{height:32px;background:var(--c-header);display:flex;align-items:center;padding:0 14px;gap:12px;flex-shrink:0}
.app-logo{font-family:'Merriweather',Georgia,serif;font-size:8px;font-weight:700;color:#fff;border-bottom:2px solid var(--c-accent);padding-bottom:1px}
.app-link{font-size:6px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:rgba(255,255,255,.45);white-space:nowrap}
.app-link.on{color:rgba(255,255,255,.9)}
.app-nav-r{margin-left:auto;display:flex;gap:8px;align-items:center}
.app-avatar{width:18px;height:18px;border-radius:50%;background:rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center;font-size:6px;font-weight:800;color:rgba(255,255,255,.6)}
/* ── Page surface ── */
.page{background:var(--c-canvas);padding:20px 28px 32px;display:flex;flex-direction:column;gap:16px;min-height:auto}
.page.narrow{padding:16px 14px 24px}
/* ── Page H1 ── */
.pg-title{font-family:'Merriweather',Georgia,serif;font-size:20px;font-weight:700;color:var(--c-ink);letter-spacing:-.3px}
.pg-intro{font-size:10.5px;line-height:1.6;color:var(--c-ink-2);max-width:460px;font-family:'Merriweather',Georgia,serif}
.page.narrow .pg-title{font-size:17px}
.page.narrow .pg-intro{font-size:10px}
/* ── Wikipedia info-card ── */
.info-card{background:var(--c-surface);border:1px solid var(--c-line);border-left:3px solid var(--c-accent);padding:10px 14px;display:flex;gap:10px;align-items:flex-start;border-radius:2px;max-width:480px}
.info-icon{width:14px;height:14px;border-radius:50%;background:var(--c-accent-bg);color:var(--c-accent);display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:800;flex-shrink:0;margin-top:1px}
.chrome.theme-dark .info-icon{color:var(--c-accent);background:rgba(0,199,177,.15)}
.info-text{font-size:9px;color:var(--c-ink-2);line-height:1.55;font-family:'Montserrat',sans-serif}
.info-text a{color:var(--c-ink);text-decoration:underline;text-decoration-color:var(--c-accent);font-weight:600;text-underline-offset:2px}
.info-text .new-tab{font-size:8px;color:var(--c-ink-3);margin-left:3px}
/* ── Section label ── */
.pg-section-label{font-size:7.5px;font-weight:800;letter-spacing:1.2px;text-transform:uppercase;color:var(--c-ink-3);margin-top:8px}
/* ── Rules grid ── */
.rules-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.rules-grid.tablet{grid-template-columns:repeat(2,1fr)}
.rules-grid.mobile{grid-template-columns:1fr}
/* ── Rule card ── */
.rule-card{background:var(--c-surface);border:1px solid var(--c-line);border-radius:2px;padding:12px;display:flex;flex-direction:column;gap:8px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.rule-head{display:flex;align-items:center;gap:7px}
.rule-icon{width:20px;height:20px;border-radius:50%;background:var(--c-muted);color:var(--c-ink);display:flex;align-items:center;justify-content:center;font-size:10px;flex-shrink:0}
.rule-title{font-family:'Merriweather',Georgia,serif;font-size:10.5px;font-weight:700;color:var(--c-ink);letter-spacing:-.1px}
.rule-body{font-size:8.5px;line-height:1.55;color:var(--c-ink-2);font-family:'Merriweather',Georgia,serif}
.rule-body code{font-family:'SF Mono',Monaco,monospace;font-size:8px;color:var(--c-ink);background:var(--c-muted);padding:0 3px;border-radius:2px}
/* ── Beispiel box ── */
.beispiel{background:var(--c-paper);border:1px dashed var(--c-line-2);border-radius:2px;padding:8px 10px;margin-top:2px}
.chrome.theme-dark .beispiel{background:rgba(166,218,216,.04);border-color:var(--c-line-2)}
.beispiel-label{font-size:6.5px;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:var(--c-ink-3);margin-bottom:5px;font-family:'Montserrat',sans-serif}
.beispiel-row{display:flex;align-items:center;gap:7px}
.beispiel-svg{flex-shrink:0;width:60px;height:22px}
.beispiel-arrow{color:var(--c-accent);font-size:11px;flex-shrink:0}
.beispiel-out{font-family:'SF Mono',Monaco,monospace;font-size:7.5px;color:var(--c-ink);background:var(--c-surface);padding:2px 5px;border-radius:2px;border:1px solid var(--c-line);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}
/* ── Noch in Klärung strip ── */
.klaerung-strip{background:var(--c-muted);border-top:1px solid var(--c-line);border-bottom:1px solid var(--c-line);padding:16px 14px;margin:8px -28px 0;display:flex;flex-direction:column;gap:8px}
.page.narrow .klaerung-strip{margin:8px -14px 0;padding:14px}
.klaerung-intro{font-size:9px;color:var(--c-ink-2);line-height:1.55;font-family:'Merriweather',Georgia,serif;max-width:460px}
.chip-row{display:flex;flex-wrap:wrap;gap:5px}
.klaer-chip{background:var(--c-surface);border:1px dashed var(--c-line-2);border-radius:999px;padding:3px 8px;font-size:7.5px;color:var(--c-ink-2);font-weight:600;display:inline-flex;align-items:center;gap:4px;font-family:'Montserrat',sans-serif}
.klaer-chip .wiggle{color:var(--c-accent);font-weight:800}
/* ── Closing invitation ── */
.closing{background:var(--c-surface);border:1px solid var(--c-line);border-radius:2px;padding:12px 14px;display:flex;gap:10px;align-items:flex-start;max-width:540px;margin-top:8px}
.closing-icon{width:18px;height:18px;color:var(--c-accent);flex-shrink:0}
.closing h4{font-family:'Merriweather',Georgia,serif;font-size:10.5px;font-weight:700;color:var(--c-ink);margin-bottom:3px}
.closing p{font-size:8.5px;line-height:1.55;color:var(--c-ink-2);font-family:'Merriweather',Georgia,serif}
/* ── Callouts ── */
.callouts{margin-top:20px;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px}
.callout{background:#fff;border:1px solid #E4E2D7;border-radius:3px;padding:10px 13px}
.co-num{background:#012851;color:#fff;width:18px;height:18px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;margin-right:6px}
.co-label{font-size:9px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:#012851}
.co-text{font-size:11px;color:#555;line-height:1.55;margin-top:6px}
/* ── Impl sections ── */
.impl{background:#fff;border:1px solid #E4E2D7;border-radius:4px;padding:28px 32px;box-shadow:0 1px 3px rgba(0,0,0,.04);margin-top:48px}
.impl h2{font-size:11px;font-weight:800;letter-spacing:1.5px;text-transform:uppercase;color:#012851;margin-bottom:16px}
.impl h3{font-family:'Merriweather',Georgia,serif;font-size:17px;color:#012851;margin:26px 0 12px}
.impl h3:first-of-type{margin-top:0}
.impl-table{width:100%;border-collapse:collapse;margin-top:6px;font-size:12px}
.impl-table th{text-align:left;font-size:9px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:#012851;padding:8px 10px;background:#F9F8F5;border-bottom:2px solid #E4E2D7}
.impl-table td{padding:10px;border-bottom:1px solid #EFEDE7;vertical-align:top;line-height:1.55}
.impl-table td:first-child{font-weight:700;color:#012851;width:22%}
.impl-table td code{font-family:'SF Mono','Menlo',monospace;font-size:10.5px;background:#F0EEE8;padding:1px 5px;border-radius:2px;color:#012851;display:inline-block;line-height:1.7}
.impl-table td.px{color:#777;font-size:11.5px;width:14%}
.impl-table td.note{color:#888;font-size:11.5px;font-style:italic;width:22%}
.notes{background:#F9F8F5;border-left:3px solid #A6DAD8;padding:16px 22px;border-radius:0 4px 4px 0;margin-top:26px}
.notes.danger{border-left-color:#C0392B}
.notes .nh{font-size:9px;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:#012851;margin-bottom:8px}
.notes.danger .nh{color:#C0392B}
.notes ul{list-style:none;display:flex;flex-direction:column;gap:6px}
.notes li{font-size:12px;color:#333;padding-left:18px;position:relative;line-height:1.7}
.notes li::before{content:"•";position:absolute;left:0;top:0;color:#A6DAD8;font-weight:800}
.notes.danger li::before{color:#C0392B}
.notes li code{font-family:'SF Mono','Menlo',monospace;font-size:11px;background:#F0EEE8;padding:1px 5px;border-radius:2px;color:#012851}
/* ── Layout overview box ── */
.overview{background:#fff;border:1px solid #E4E2D7;border-radius:4px;padding:26px 32px;box-shadow:0 1px 3px rgba(0,0,0,.04);margin-bottom:48px}
.overview h2{font-size:11px;font-weight:800;letter-spacing:1.5px;text-transform:uppercase;color:#012851;margin-bottom:12px}
.overview p{font-size:13px;color:#555;line-height:1.75;max-width:780px;margin-bottom:14px}
.flow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.flow-node{flex:1;min-width:140px;background:#F9F8F5;border:1.5px solid #E4E2D7;border-radius:4px;padding:12px 14px}
.fn-label{font-size:8px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;color:#012851;margin-bottom:4px}
.fn-title{font-family:'Merriweather',Georgia,serif;font-size:12px;color:#012851;font-weight:700;margin-bottom:6px}
.fn-desc{font-size:10.5px;color:#555;line-height:1.55}
.flow-arrow{font-size:20px;color:#A6DAD8;font-weight:800}
.vp-grid{display:grid;grid-template-columns:1fr 1fr;gap:32px;align-items:start}
@media (max-width:980px){.vp-grid{grid-template-columns:1fr}}
/* ── Print preview mock ── */
.print-preview{background:#fff;border:1px solid #ccc;padding:28px 36px;max-width:520px;margin:0 auto 28px;font-family:Georgia,serif;color:#111;box-shadow:0 4px 24px rgba(0,0,0,.08)}
.print-preview h1{font-family:Georgia,serif;font-size:20px;font-weight:700;color:#111;margin-bottom:10px;letter-spacing:-.2px}
.print-preview .p-intro{font-size:11px;color:#333;line-height:1.6;margin-bottom:14px}
.print-preview .p-info{border:1px solid #999;padding:8px 10px;margin-bottom:16px;font-size:10px;color:#333;line-height:1.5}
.print-preview .p-label{font-size:8px;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:#555;margin:10px 0 8px}
.print-rule{border:1px solid #999;border-radius:1px;padding:10px 12px;margin-bottom:8px;page-break-inside:avoid;break-inside:avoid}
.print-rule-title{font-size:11px;font-weight:700;color:#111;margin-bottom:4px}
.print-rule-body{font-size:9.5px;color:#333;line-height:1.55}
.print-rule-beispiel{background:#f5f4ef;padding:6px 8px;margin-top:5px;font-size:9px;color:#333;font-family:monospace}
.print-klaer{border-top:1px solid #999;padding-top:10px;margin-top:12px;font-size:9px;color:#555;line-height:1.55}
</style>
</head>
<body>
<div class="doc">
<!-- ════════════════════════════════════════════ -->
<!-- ═══════════════ MASTHEAD ══════════════ -->
<!-- ════════════════════════════════════════════ -->
<div class="mh">
<div class="kicker">UI/UX Spec · Implementation-ready</div>
<h1>Transkriptions-Richtlinien — editorial conventions page</h1>
<p>
Static help page at <code style="font-family:'SF Mono',monospace;background:#F0EEE8;padding:1px 5px;border-radius:2px;font-size:12px">/hilfe/transkription</code>
that collects the family archive's transcription conventions — the questions Wikipedia's
Kurrent alphabet page cannot answer. Companion to <strong>#320</strong> (guided empty state
for the Transcribe panel). Replaces the original "Kurrent primer" from that issue, which
would have duplicated Wikipedia without adding value.
</p>
<p>
The page is content-heavy but low on content — only five rules in v1. The design problem is
making a thin page feel <em>intentional</em> rather than under-built, and making reference
content <em>fun to read</em> so transcribers actually read it. Solved via a card grid, per-rule
Beispiel boxes with Kurrent SVG fragments, and family-voice prose with named fictional relatives.
</p>
<div class="byline">Leonie Voss · 2026-04-24 · Final spec · Companion to issue #320</div>
<div class="tag-row">
<span class="tag">feature</span>
<span class="tag mint">ui</span>
<span class="tag">a11y 320px+</span>
<span class="tag">light + dark</span>
<span class="tag amber">print styles</span>
<span class="tag green">no backend</span>
</div>
</div>
<!-- ════════════════════════════════════════════ -->
<!-- ═══════════ LAYOUT OVERVIEW ═══════════════ -->
<!-- ════════════════════════════════════════════ -->
<div class="overview">
<h2>Page structure</h2>
<p>
One prerendered SvelteKit route. Five sections stacked vertically. No interactive state,
no forms, no SSR data-loading. Pure content — the kind of page that ships with
<code style="font-family:'SF Mono',monospace;background:#F0EEE8;padding:1px 4px;border-radius:2px;font-size:12px">export const prerender = true;</code>
and lives as static HTML at build time.
</p>
<div class="flow">
<div class="flow-node">
<div class="fn-label">1</div>
<div class="fn-title">Header</div>
<div class="fn-desc">Title + warm 2-sentence intro (family voice). Names fictional relatives to prime mental model.</div>
</div>
<div class="flow-arrow"></div>
<div class="flow-node">
<div class="fn-label">2</div>
<div class="fn-title">Wikipedia info-card</div>
<div class="fn-desc">Light visual weight. Explicitly scopes: "the alphabet is out there; here are <em>our</em> rules."</div>
</div>
<div class="flow-arrow"></div>
<div class="flow-node">
<div class="fn-label">3</div>
<div class="fn-title">Rule cards grid</div>
<div class="fn-desc">5 cards, 3-col / 2-col / 1-col. Each card: icon, title, explanation, Beispiel box with Kurrent SVG ↔ output.</div>
</div>
<div class="flow-arrow"></div>
<div class="flow-node">
<div class="fn-label">4</div>
<div class="fn-title">"Noch in Klärung"</div>
<div class="fn-desc">Full-bleed sand-tinted strip. 4 dashed-pill chips for open questions.</div>
</div>
<div class="flow-arrow"></div>
<div class="flow-node">
<div class="fn-label">5</div>
<div class="fn-title">Closing invitation</div>
<div class="fn-desc">"Fehlt eine Regel?" Turns help page into collaborative document.</div>
</div>
</div>
</div>
<!-- ════════════════════════════════════════════ -->
<!-- ════════ DESKTOP · LIGHT ════════════════ -->
<!-- ════════════════════════════════════════════ -->
<section class="section">
<div class="section-head">
<span class="section-kicker">Primary view</span>
<h2>Desktop, 1280px, light theme</h2>
<p>
The canonical rendering. Three-column card grid fills horizontal space so the page feels
like a deliberate collection, not a thin list. Each Beispiel box is hand-drawn per rule —
a smudge for <em>unleserlich</em>, a strikethrough for <em>durchgestrichen</em>, a stylised
ſ for the long-s, etc. Reader's eye moves rule → example → rule → example, which is the
cadence that keeps reference content readable.
</p>
</div>
<div class="state-row">
<span class="viewport-chip">desktop · 1280</span>
<span class="theme-chip light">Light</span>
</div>
<div class="screen w-desktop">
<div class="chrome theme-light">
<div class="bar">
<span class="dot"></span><span class="dot"></span><span class="dot"></span>
<div class="url"></div><div class="vp">1280 · Desktop · Light</div>
</div>
<div class="app-nav">
<div class="app-logo">Familienarchiv</div>
<div class="app-link">Dokumente</div>
<div class="app-link">Personen</div>
<div class="app-link">Briefwechsel</div>
<div class="app-link">Chronik</div>
<div class="app-link on">Hilfe</div>
<div class="app-nav-r"><div class="app-avatar">MR</div></div>
</div>
<div class="page">
<div class="pg-title">Transkriptions-Richtlinien</div>
<div class="pg-intro">
Damit alle Briefe einheitlich transkribiert werden — egal ob Tante Hedwig oder
Cousin Paul tippt — hier unsere Regeln. Die Seite wächst mit: sobald wir eine
neue Konvention beschließen, landet sie hier.
</div>
<div class="info-card">
<div class="info-icon">i</div>
<div class="info-text">
Das vollständige Kurrent- und Sütterlin-Alphabet brauchen Sie für diese Seite
nicht — das erledigt <a href="#">Wikipedia&nbsp;</a><span class="new-tab">(öffnet in neuem Tab)</span>.
Hier sind unsere <em>eigenen</em> Regeln für das, was Wikipedia nicht beantwortet.
</div>
</div>
<div class="pg-section-label">Regeln für die Transkription</div>
<div class="rules-grid">
<!-- Rule 1 -->
<div class="rule-card">
<div class="rule-head">
<div class="rule-icon">🔍</div>
<div class="rule-title">Nicht lesbare Wörter</div>
</div>
<div class="rule-body">Wenn Sie ein Wort beim besten Willen nicht entziffern können, schreiben Sie <code>[unleserlich]</code>.</div>
<div class="beispiel">
<div class="beispiel-label">Beispiel</div>
<div class="beispiel-row">
<svg class="beispiel-svg" viewBox="0 0 60 22">
<g stroke="#2a2a2a" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 4 14 q 2 -8 5 -2 q 3 7 6 -1 q 2 -5 5 0"/>
<path d="M 24 14 q 2 -8 6 -1 q 3 7 6 -2"/>
</g>
<ellipse cx="34" cy="12" rx="10" ry="5" fill="rgba(100,90,75,.35)"/>
</svg>
<span class="beispiel-arrow"></span>
<span class="beispiel-out">[unleserlich]</span>
</div>
</div>
</div>
<!-- Rule 2 -->
<div class="rule-card">
<div class="rule-head">
<div class="rule-icon"></div>
<div class="rule-title">Durchgestrichene Wörter</div>
</div>
<div class="rule-body">Auch durchgestrichener Text gehört zum Brief. Schreiben Sie ihn in eckigen Klammern mit Präfix <code>durchgestrichen:</code>.</div>
<div class="beispiel">
<div class="beispiel-label">Beispiel</div>
<div class="beispiel-row">
<svg class="beispiel-svg" viewBox="0 0 60 22">
<g stroke="#2a2a2a" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 5 15 q 3 -10 7 0 q 2 -7 6 0 q 3 -8 7 2 q 2 -5 5 -1 q 2 7 5 -3"/>
</g>
<line x1="3" y1="12" x2="40" y2="11" stroke="#222" stroke-width="1.4" stroke-linecap="round"/>
</svg>
<span class="beispiel-arrow"></span>
<span class="beispiel-out">[durchgestrichen: gestern]</span>
</div>
</div>
</div>
<!-- Rule 3 -->
<div class="rule-card">
<div class="rule-head">
<div class="rule-icon">ſ</div>
<div class="rule-title">Das lange s (ſ)</div>
</div>
<div class="rule-body">Das <em>ſ</em> ist nur eine alte Schriftform des Buchstabens <em>s</em> — kein eigener Laut. Schreiben Sie immer ein normales <em>s</em>.</div>
<div class="beispiel">
<div class="beispiel-label">Beispiel</div>
<div class="beispiel-row">
<svg class="beispiel-svg" viewBox="0 0 60 22">
<g stroke="#2a2a2a" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 9 18 C 9 6 12 4 15 5 C 18 6 16 9 15 9"/>
<line x1="7" y1="11" x2="15" y2="11"/>
<path d="M 22 16 q 2 -8 6 -1 q 3 7 6 -3 q 2 -6 6 1 q 2 -7 6 1"/>
</g>
</svg>
<span class="beispiel-arrow"></span>
<span class="beispiel-out">Sommers</span>
</div>
</div>
</div>
<!-- Rule 4 -->
<div class="rule-card">
<div class="rule-head">
<div class="rule-icon">?</div>
<div class="rule-title">Unsichere Namen</div>
</div>
<div class="rule-body">Wenn Sie einen Namen zu erkennen meinen, aber nicht sicher sind, ergänzen Sie ein Fragezeichen in eckigen Klammern.</div>
<div class="beispiel">
<div class="beispiel-label">Beispiel</div>
<div class="beispiel-row">
<svg class="beispiel-svg" viewBox="0 0 60 22">
<g stroke="#2a2a2a" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 3 17 L 7 5 L 12 14 L 17 5 L 21 17"/>
<path d="M 24 16 q 3 -8 7 0 q 2 -5 6 -1 q 2 7 6 -3 q 3 -4 6 3"/>
</g>
<ellipse cx="38" cy="14" rx="7" ry="3" fill="rgba(100,90,75,.2)"/>
</svg>
<span class="beispiel-arrow"></span>
<span class="beispiel-out">[Müller?]</span>
</div>
</div>
</div>
<!-- Rule 5 -->
<div class="rule-card">
<div class="rule-head">
<div class="rule-icon">🌍</div>
<div class="rule-title">Dialekt, Fremdwörter, Zitate</div>
</div>
<div class="rule-body">Plattdeutsch, Französisch, lateinische Phrasen — wörtlich übernehmen, genau wie sie geschrieben stehen.</div>
<div class="beispiel">
<div class="beispiel-label">Beispiel</div>
<div class="beispiel-row">
<svg class="beispiel-svg" viewBox="0 0 60 22">
<g stroke="#2a2a2a" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M 3 15 q 3 -8 6 -1 q 2 -6 5 1 q 2 -5 5 -1 q 2 6 5 -3 q 2 -6 5 1 q 2 -4 5 3 q 2 -8 5 0 q 2 -5 5 -1 q 2 6 5 -2"/>
</g>
</svg>
<span class="beispiel-arrow"></span>
<span class="beispiel-out">pardonnez-moi</span>
</div>
</div>
</div>
</div>
<div class="klaerung-strip">
<div class="pg-section-label">Noch in Klärung</div>
<div class="klaerung-intro">Diese Fragen klären wir noch — stoßen Sie beim Transkribieren darauf, treffen Sie eine plausible Wahl und notieren Sie es in den Kommentaren:</div>
<div class="chip-row">
<span class="klaer-chip"><span class="wiggle"></span> Abkürzungen</span>
<span class="klaer-chip"><span class="wiggle"></span> Datumsformate</span>
<span class="klaer-chip"><span class="wiggle"></span> Zeilenumbrüche</span>
<span class="klaer-chip"><span class="wiggle"></span> Groß-/Kleinschreibung</span>
</div>
</div>
<div class="closing">
<svg class="closing-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M 21 15 a 2 2 0 0 1 -2 2 H 7 l -4 4 V 5 a 2 2 0 0 1 2 -2 h 14 a 2 2 0 0 1 2 2 z"/>
</svg>
<div>
<h4>Fehlt eine Regel?</h4>
<p>Stolpern Sie beim Transkribieren über eine Situation, die hier nicht steht — schreiben Sie einen Kommentar beim betreffenden Block. Wir sammeln sie beim nächsten Familientreffen.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Callouts for the desktop light view -->
<div class="callouts">
<div class="callout">
<span class="co-num">1</span><span class="co-label">Header tone</span>
<div class="co-text">Family-voice intro naming fictional relatives ("Tante Hedwig", "Cousin Paul"). Primes the reader that this is <em>our</em> rulebook, not a corporate style guide.</div>
</div>
<div class="callout">
<span class="co-num">2</span><span class="co-label">Wikipedia scope-card</span>
<div class="co-text">Lighter visual weight than rule cards (3px mint left-border, no full shadow). Signals external reference vs. our-own rule.</div>
</div>
<div class="callout">
<span class="co-num">3</span><span class="co-label">3-col rule grid</span>
<div class="co-text">3+2 layout at desktop fills horizontal space without padding content. Each card is self-contained; the grid reads as a collection.</div>
</div>
<div class="callout">
<span class="co-num">4</span><span class="co-label">Beispiel box</span>
<div class="co-text">Aged-paper bg + dashed border + Kurrent SVG → mint arrow → monospace output. Makes each rule concrete in one glance. Unique drawing per rule.</div>
</div>
<div class="callout">
<span class="co-num">5</span><span class="co-label">Noch in Klärung strip</span>
<div class="co-text">Full-bleed sand-muted band (not another card). Dashed pill chips signal "open, not decided". Collaborative tone with "plausible Wahl treffen…".</div>
</div>
<div class="callout">
<span class="co-num">6</span><span class="co-label">Closing invitation</span>
<div class="co-text">"Fehlt eine Regel?" invites the reader to contribute. Users who contribute rules are users who read them.</div>
</div>
</div>
</section>
<!-- ════════════════════════════════════════════ -->
<!-- ════════ DESKTOP · DARK ═════════════════ -->
<!-- ════════════════════════════════════════════ -->
<section class="section">
<div class="section-head">
<span class="section-kicker">Theme parity</span>
<h2>Desktop, 1280px, dark theme</h2>
<p>
Every semantic token is remapped — no filter-inversion. The Beispiel boxes switch to a
muted mint-tinted background so the Kurrent strokes (#2a2a2a in light → kept dark against
the dark paper) need a contrast check. See the a11y block for exact ratios.
</p>
</div>
<div class="state-row">
<span class="viewport-chip">desktop · 1280</span>
<span class="theme-chip dark">Dark</span>
</div>
<div class="screen w-desktop">
<div class="chrome theme-dark">
<div class="bar">
<span class="dot"></span><span class="dot"></span><span class="dot"></span>
<div class="url"></div><div class="vp">1280 · Desktop · Dark</div>
</div>
<div class="app-nav">
<div class="app-logo">Familienarchiv</div>
<div class="app-link">Dokumente</div>
<div class="app-link">Personen</div>
<div class="app-link">Briefwechsel</div>
<div class="app-link">Chronik</div>
<div class="app-link on">Hilfe</div>
<div class="app-nav-r"><div class="app-avatar">MR</div></div>
</div>
<div class="page">
<div class="pg-title">Transkriptions-Richtlinien</div>
<div class="pg-intro">Damit alle Briefe einheitlich transkribiert werden — egal ob Tante Hedwig oder Cousin Paul tippt — hier unsere Regeln.</div>
<div class="info-card">
<div class="info-icon">i</div>
<div class="info-text">Das vollständige Kurrent-Alphabet brauchen Sie nicht — <a href="#">Wikipedia&nbsp;</a><span class="new-tab">(neuer Tab)</span>. Hier sind unsere <em>eigenen</em> Regeln.</div>
</div>
<div class="pg-section-label">Regeln für die Transkription</div>
<div class="rules-grid">
<div class="rule-card">
<div class="rule-head"><div class="rule-icon">🔍</div><div class="rule-title">Nicht lesbare Wörter</div></div>
<div class="rule-body">Wenn Sie ein Wort nicht entziffern können: <code>[unleserlich]</code>.</div>
<div class="beispiel"><div class="beispiel-label">Beispiel</div><div class="beispiel-row"><svg class="beispiel-svg" viewBox="0 0 60 22"><g stroke="#d9dce0" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M 4 14 q 2 -8 5 -2 q 3 7 6 -1 q 2 -5 5 0"/><path d="M 24 14 q 2 -8 6 -1 q 3 7 6 -2"/></g><ellipse cx="34" cy="12" rx="10" ry="5" fill="rgba(50,60,80,.6)"/></svg><span class="beispiel-arrow"></span><span class="beispiel-out">[unleserlich]</span></div></div>
</div>
<div class="rule-card">
<div class="rule-head"><div class="rule-icon"></div><div class="rule-title">Durchgestrichene Wörter</div></div>
<div class="rule-body">In eckigen Klammern mit <code>durchgestrichen:</code>.</div>
<div class="beispiel"><div class="beispiel-label">Beispiel</div><div class="beispiel-row"><svg class="beispiel-svg" viewBox="0 0 60 22"><g stroke="#d9dce0" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M 5 15 q 3 -10 7 0 q 2 -7 6 0 q 3 -8 7 2 q 2 -5 5 -1 q 2 7 5 -3"/></g><line x1="3" y1="12" x2="40" y2="11" stroke="#e0e3e8" stroke-width="1.4" stroke-linecap="round"/></svg><span class="beispiel-arrow"></span><span class="beispiel-out">[durchgestrichen: gestern]</span></div></div>
</div>
<div class="rule-card">
<div class="rule-head"><div class="rule-icon">ſ</div><div class="rule-title">Das lange s (ſ)</div></div>
<div class="rule-body">Immer als normales <em>s</em> schreiben.</div>
<div class="beispiel"><div class="beispiel-label">Beispiel</div><div class="beispiel-row"><svg class="beispiel-svg" viewBox="0 0 60 22"><g stroke="#d9dce0" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M 9 18 C 9 6 12 4 15 5 C 18 6 16 9 15 9"/><line x1="7" y1="11" x2="15" y2="11"/><path d="M 22 16 q 2 -8 6 -1 q 3 7 6 -3 q 2 -6 6 1 q 2 -7 6 1"/></g></svg><span class="beispiel-arrow"></span><span class="beispiel-out">Sommers</span></div></div>
</div>
<div class="rule-card">
<div class="rule-head"><div class="rule-icon">?</div><div class="rule-title">Unsichere Namen</div></div>
<div class="rule-body">Fragezeichen in eckigen Klammern.</div>
<div class="beispiel"><div class="beispiel-label">Beispiel</div><div class="beispiel-row"><svg class="beispiel-svg" viewBox="0 0 60 22"><g stroke="#d9dce0" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M 3 17 L 7 5 L 12 14 L 17 5 L 21 17"/><path d="M 24 16 q 3 -8 7 0 q 2 -5 6 -1 q 2 7 6 -3 q 3 -4 6 3"/></g><ellipse cx="38" cy="14" rx="7" ry="3" fill="rgba(50,60,80,.5)"/></svg><span class="beispiel-arrow"></span><span class="beispiel-out">[Müller?]</span></div></div>
</div>
<div class="rule-card">
<div class="rule-head"><div class="rule-icon">🌍</div><div class="rule-title">Dialekt &amp; Fremdwörter</div></div>
<div class="rule-body">Wörtlich übernehmen — nicht anpassen.</div>
<div class="beispiel"><div class="beispiel-label">Beispiel</div><div class="beispiel-row"><svg class="beispiel-svg" viewBox="0 0 60 22"><g stroke="#d9dce0" stroke-width="1.1" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M 3 15 q 3 -8 6 -1 q 2 -6 5 1 q 2 -5 5 -1 q 2 6 5 -3 q 2 -6 5 1 q 2 -4 5 3 q 2 -8 5 0 q 2 -5 5 -1 q 2 6 5 -2"/></g></svg><span class="beispiel-arrow"></span><span class="beispiel-out">pardonnez-moi</span></div></div>
</div>
</div>
<div class="klaerung-strip">
<div class="pg-section-label">Noch in Klärung</div>
<div class="klaerung-intro">Diese Fragen klären wir noch — plausible Wahl + Kommentar.</div>
<div class="chip-row">
<span class="klaer-chip"><span class="wiggle"></span> Abkürzungen</span>
<span class="klaer-chip"><span class="wiggle"></span> Datumsformate</span>
<span class="klaer-chip"><span class="wiggle"></span> Zeilenumbrüche</span>
<span class="klaer-chip"><span class="wiggle"></span> Groß-/Kleinschreibung</span>
</div>
</div>
<div class="closing">
<svg class="closing-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M 21 15 a 2 2 0 0 1 -2 2 H 7 l -4 4 V 5 a 2 2 0 0 1 2 -2 h 14 a 2 2 0 0 1 2 2 z"/></svg>
<div><h4>Fehlt eine Regel?</h4><p>Kommentieren Sie beim betreffenden Block — wir besprechen sie beim nächsten Familientreffen.</p></div>
</div>
</div>
</div>
</div>
</section>
<!-- ════════════════════════════════════════════ -->
<!-- ══════════ RESPONSIVE · TABLET ══════════ -->
<!-- ════════════════════════════════════════════ -->
<section class="section">
<div class="section-head">
<span class="section-kicker">Responsive</span>
<h2>Tablet &amp; mobile (the audience that actually reads this page)</h2>
<p>
Per-project memory: transcribers are 60+ on laptop/tablet, readers (younger) are on phones.
The Richtlinien page is shared between both audiences — a family member on a phone may
pull it up mid-conversation to settle a convention. So responsive coverage is a
correctness requirement, not a polish item.
</p>
</div>
<div class="vp-grid">
<div>
<div class="state-row">
<span class="viewport-chip">tablet · 768</span>
<span class="theme-chip light">Light</span>
<span class="state-note">2-col grid · full-bleed strip unchanged</span>
</div>
<div class="screen w-tablet">
<div class="chrome theme-light">
<div class="bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span><div class="url"></div><div class="vp">768 · Tab · Light</div></div>
<div class="app-nav"><div class="app-logo">Familienarchiv</div><div class="app-link on">Hilfe</div><div class="app-nav-r"><div class="app-avatar">MR</div></div></div>
<div class="page">
<div class="pg-title">Transkriptions-Richtlinien</div>
<div class="pg-intro">Damit alle einheitlich transkribieren — Tante Hedwig, Cousin Paul, alle anderen.</div>
<div class="info-card"><div class="info-icon">i</div><div class="info-text">Alphabet: <a href="#">Wikipedia&nbsp;</a><span class="new-tab">(neuer Tab)</span></div></div>
<div class="pg-section-label">Regeln</div>
<div class="rules-grid tablet">
<div class="rule-card"><div class="rule-head"><div class="rule-icon">🔍</div><div class="rule-title">Nicht lesbare Wörter</div></div><div class="rule-body"><code>[unleserlich]</code>.</div></div>
<div class="rule-card"><div class="rule-head"><div class="rule-icon"></div><div class="rule-title">Durchgestrichen</div></div><div class="rule-body"><code>[durchgestrichen: Wort]</code>.</div></div>
<div class="rule-card"><div class="rule-head"><div class="rule-icon">ſ</div><div class="rule-title">Das lange s</div></div><div class="rule-body">Immer als <em>s</em>.</div></div>
<div class="rule-card"><div class="rule-head"><div class="rule-icon">?</div><div class="rule-title">Unsichere Namen</div></div><div class="rule-body"><code>[Müller?]</code>.</div></div>
<div class="rule-card" style="grid-column:span 2"><div class="rule-head"><div class="rule-icon">🌍</div><div class="rule-title">Dialekt &amp; Fremdwörter</div></div><div class="rule-body">Wörtlich übernehmen.</div></div>
</div>
<div class="klaerung-strip"><div class="pg-section-label">Noch in Klärung</div><div class="chip-row"><span class="klaer-chip">〰 Abkürzungen</span><span class="klaer-chip">〰 Datumsformate</span><span class="klaer-chip">〰 Zeilenumbrüche</span><span class="klaer-chip">〰 Groß/Klein</span></div></div>
</div>
</div>
</div>
</div>
<div>
<div class="state-row">
<span class="viewport-chip">mobile · 375</span>
<span class="theme-chip light">Light</span>
<span class="state-note">1-col stack · chips wrap to 2 rows</span>
</div>
<div class="screen w-mobile">
<div class="chrome theme-light">
<div class="bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span><div class="url"></div><div class="vp">375 · Mob</div></div>
<div class="app-nav"><div class="app-logo">Familienarchiv</div><div class="app-nav-r"><div class="app-avatar">MR</div></div></div>
<div class="page narrow">
<div class="pg-title">Transkriptions-Richtlinien</div>
<div class="pg-intro">Unsere Regeln, damit alle einheitlich tippen.</div>
<div class="info-card"><div class="info-icon">i</div><div class="info-text"><a href="#">Wikipedia&nbsp;</a></div></div>
<div class="pg-section-label">Regeln</div>
<div class="rules-grid mobile">
<div class="rule-card"><div class="rule-head"><div class="rule-icon">🔍</div><div class="rule-title">Nicht lesbar</div></div><div class="rule-body"><code>[unleserlich]</code></div></div>
<div class="rule-card"><div class="rule-head"><div class="rule-icon"></div><div class="rule-title">Durchgestrichen</div></div><div class="rule-body"><code>[durchgestrichen: Wort]</code></div></div>
<div class="rule-card"><div class="rule-head"><div class="rule-icon">ſ</div><div class="rule-title">Langes s</div></div><div class="rule-body">Als <em>s</em> schreiben.</div></div>
</div>
<div class="klaerung-strip"><div class="pg-section-label">Noch in Klärung</div><div class="chip-row"><span class="klaer-chip">〰 Abkürz.</span><span class="klaer-chip">〰 Datum</span><span class="klaer-chip">〰 Umbrüche</span></div></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ════════════════════════════════════════════ -->
<!-- ════════════ PRINT VIEW ═════════════════ -->
<!-- ════════════════════════════════════════════ -->
<section class="section">
<div class="section-head">
<span class="section-kicker">@media print</span>
<h2>Print view — Reference für den Schreibtisch</h2>
<p>
Seniors print reference material. The family archivist may also export the page as PDF
and e-mail it before a transcription session. Print styles drop the brand chrome, switch
to black-on-white for ink economy, remove external-link annotations ("neuer Tab" makes no
sense on paper), and enforce <code style="font-family:'SF Mono',monospace;background:#F0EEE8;padding:1px 4px;border-radius:2px;font-size:12px">break-inside: avoid</code>
on each rule card so no rule splits mid-page.
</p>
</div>
<div class="state-row">
<span class="viewport-chip">print · A4</span>
<span class="theme-chip print">Print</span>
</div>
<div class="print-preview">
<h1>Transkriptions-Richtlinien</h1>
<p class="p-intro">
Damit alle Briefe einheitlich transkribiert werden — egal ob Tante Hedwig oder
Cousin Paul tippt — hier unsere Regeln.
</p>
<div class="p-info">
Kurrent-Alphabet nachschlagen: de.wikipedia.org/wiki/Kurrentschrift
</div>
<div class="p-label">Regeln</div>
<div class="print-rule">
<div class="print-rule-title">🔍 Nicht lesbare Wörter</div>
<div class="print-rule-body">Wenn Sie ein Wort nicht entziffern können, schreiben Sie [unleserlich]. Jemand anderes schaut später nochmal drauf.</div>
<div class="print-rule-beispiel">Beispiel: ⟨Kurrent-Fragment⟩ → [unleserlich]</div>
</div>
<div class="print-rule">
<div class="print-rule-title">✂ Durchgestrichene Wörter</div>
<div class="print-rule-body">Auch durchgestrichener Text gehört zum Brief. Schreiben Sie ihn in eckigen Klammern mit Präfix "durchgestrichen:".</div>
<div class="print-rule-beispiel">Beispiel: ⟨gestern⟩ → [durchgestrichen: gestern]</div>
</div>
<div class="print-rule">
<div class="print-rule-title">ſ Das lange s</div>
<div class="print-rule-body">Das ſ ist nur eine alte Schriftform des Buchstabens s — schreiben Sie immer ein normales s.</div>
<div class="print-rule-beispiel">Beispiel: ⟨ſommers⟩ → Sommers</div>
</div>
<div class="print-rule">
<div class="print-rule-title">? Unsichere Namen</div>
<div class="print-rule-body">Fragezeichen in eckigen Klammern.</div>
<div class="print-rule-beispiel">Beispiel: ⟨Müller⟩ → [Müller?]</div>
</div>
<div class="print-rule">
<div class="print-rule-title">🌍 Dialekt, Fremdwörter, Zitate</div>
<div class="print-rule-body">Wörtlich übernehmen, genau wie geschrieben.</div>
<div class="print-rule-beispiel">Beispiel: ⟨pardonnez-moi⟩ → pardonnez-moi</div>
</div>
<div class="p-label">Noch in Klärung</div>
<div class="print-klaer">Abkürzungen · Datumsformate · Originale Zeilenumbrüche · Alte Groß-/Kleinschreibung</div>
</div>
</section>
<!-- ════════════════════════════════════════════ -->
<!-- ═════════ IMPLEMENTATION REFERENCE ══════ -->
<!-- ════════════════════════════════════════════ -->
<div class="impl">
<h2>Implementation reference — Tailwind classes &amp; exact values</h2>
<h3>Page shell</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Route</td>
<td><code>frontend/src/routes/hilfe/transkription/+page.svelte</code> with <code>export const prerender = true;</code></td>
<td class="px">static</td>
<td class="note">no <code>+page.server.ts</code> — pure content; ships as static HTML at build</td>
</tr>
<tr>
<td>Auth boundary</td>
<td>follow decision queue on issue #320</td>
<td class="px"></td>
<td class="note">default <code>authenticated()</code> unless <code>permitAll()</code> is chosen for <code>/hilfe/**</code></td>
</tr>
<tr>
<td>Page container</td>
<td><code>max-w-[1100px] mx-auto px-6 pt-12 pb-16 bg-surface-page</code></td>
<td class="px">max 1100px · py 4864</td>
<td class="note">narrower than the document-edit max (1320) — optimises reading width</td>
</tr>
<tr>
<td>Section gap</td>
<td><code>space-y-12</code> between logical sections</td>
<td class="px">48px</td>
<td class="note">not <code>space-y-10</code> — the 48px gap signals deliberate breathing room</td>
</tr>
</table>
<h3>Header + intro</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>H1 title</td>
<td><code>font-serif text-[32px] font-bold text-ink tracking-[-0.01em] mb-4</code></td>
<td class="px">32px · 700</td>
<td class="note">Merriweather; uses tracking tighten to hold the weight</td>
</tr>
<tr>
<td>Intro paragraph</td>
<td><code>font-serif text-[17px] leading-[1.65] text-ink-2 max-w-[640px]</code></td>
<td class="px">17px · 1.65</td>
<td class="note">max-width 640px is ≈ 66ch — optimum reading measure</td>
</tr>
<tr>
<td>Named-relative copy</td>
<td>literal "Tante Hedwig" / "Cousin Paul" in the intro string</td>
<td class="px"></td>
<td class="note">fictional; sets family-archive voice. Do not localize names for en/es — keep German "Tante"/"Cousin" since the app is archive-of-a-German-family</td>
</tr>
</table>
<h3>Wikipedia info-card</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Card container</td>
<td><code>flex gap-3 items-start bg-white border border-line border-l-[3px] border-l-accent rounded-sm px-5 py-4 mt-6 mb-14 max-w-[640px]</code></td>
<td class="px">640px max · 3px mint accent</td>
<td class="note">mint accent left-border distinguishes from rule cards (which have no accent border)</td>
</tr>
<tr>
<td>Icon bubble</td>
<td><code>w-[22px] h-[22px] flex-shrink-0 text-accent mt-0.5</code> — inline info SVG</td>
<td class="px">22px</td>
<td class="note">lowercase "i" glyph. Use same SVG in both themes; stroke inherits from <code>text-accent</code></td>
</tr>
<tr>
<td>Body text</td>
<td><code>font-sans text-sm text-ink-2 leading-[1.5]</code></td>
<td class="px">14px · 1.5</td>
<td class="note">sans-serif here deliberately (not Merriweather) — signals "meta/helper" vs. primary content</td>
</tr>
<tr>
<td>Wikipedia link</td>
<td><code>text-ink underline decoration-accent underline-offset-[3px] decoration-[1.5px] font-medium hover:decoration-ink</code></td>
<td class="px"></td>
<td class="note">must have <code>target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer"</code> — last per Nora's review</td>
</tr>
<tr>
<td>"neuer Tab" annotation</td>
<td><code>text-xs text-ink-3 ml-1</code> — plain <code>&lt;span&gt;</code>, real text node</td>
<td class="px">12px</td>
<td class="note">NOT CSS <code>::after</code> — must be in the DOM for screen readers to announce it</td>
</tr>
</table>
<h3>Section label (repeated)</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Label</td>
<td><code>font-sans text-[11px] font-bold uppercase tracking-[0.15em] text-ink-3 mb-5</code></td>
<td class="px">11px · 700 · 2.4 tracking</td>
<td class="note">project pattern, see <code>layout.css</code>. Used for "Regeln" and "Noch in Klärung"</td>
</tr>
</table>
<h3>Rule card grid</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Grid container</td>
<td><code>grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5</code></td>
<td class="px">gap 20px</td>
<td class="note">breakpoints: 1-col &lt;640 · 2-col 6401024 · 3-col ≥ 1024</td>
</tr>
<tr>
<td>Card</td>
<td><code>bg-white border border-line rounded-sm shadow-[0_1px_3px_rgba(0,0,0,0.04)] p-6 flex flex-col gap-3.5</code></td>
<td class="px">padding 24px · gap 14px</td>
<td class="note">project card pattern from <code>layout.css</code>, minus the explicit brand-sand border (uses <code>border-line</code> token for theme-adaptive border)</td>
</tr>
<tr>
<td>Card top-line</td>
<td><code>flex items-center gap-2.5</code> — icon + H3 inline</td>
<td class="px">gap 10px</td>
<td class="note">H3 is the clickable landmark if we add anchor navigation later</td>
</tr>
<tr>
<td>Icon chip</td>
<td><code>w-8 h-8 rounded-full bg-brand-sand-muted text-ink flex items-center justify-center flex-shrink-0</code></td>
<td class="px">32px</td>
<td class="note">muted sand circle, navy glyph inside. Glyph: emoji OR inline SVG — see per-rule icons below</td>
</tr>
<tr>
<td>H3 title</td>
<td><code>font-serif text-[19px] font-bold text-ink leading-tight</code></td>
<td class="px">19px · 700</td>
<td class="note">Merriweather serif carries the visual weight of the rule</td>
</tr>
<tr>
<td>Explanation body</td>
<td><code>font-serif text-[15px] leading-[1.55] text-ink-2</code></td>
<td class="px">15px · 1.55</td>
<td class="note">one sentence, max two. Inline <code>&lt;code&gt;</code> for the bracketed-output syntax in-line</td>
</tr>
<tr>
<td>Inline code</td>
<td><code>font-mono text-[14px] text-ink bg-muted px-1 rounded-sm</code></td>
<td class="px">14px</td>
<td class="note">for <code>[unleserlich]</code>, <code>[durchgestrichen: Wort]</code>, <code>[Müller?]</code> etc.</td>
</tr>
</table>
<h3>Beispiel box (per-rule concrete example)</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Box container</td>
<td><code>bg-paper border border-dashed border-[#D4D1C4] dark:border-line-2 rounded-sm px-4 py-3.5 mt-1.5</code></td>
<td class="px">padding 14px 16px</td>
<td class="note">paper-cream bg (<code>#FAF8F1</code> light, muted accent-tint dark) + dashed border creates a visual "this is an example, not a rule" cue</td>
</tr>
<tr>
<td>"Beispiel" label</td>
<td><code>font-sans text-[10px] font-bold uppercase tracking-[0.12em] text-ink-3 mb-2.5</code></td>
<td class="px">10px · 700</td>
<td class="note">tiny top label so the row below can be dense without ambiguity</td>
</tr>
<tr>
<td>Kurrent SVG</td>
<td><code>w-24 h-9 flex-shrink-0</code> — inline SVG, per-rule path data</td>
<td class="px">96×36</td>
<td class="note">five unique SVGs — one per rule. Stroke <code>#2a2a2a</code> light / <code>#d9dce0</code> dark, stroke-width 1.4. See <strong>Per-rule Beispiel visuals</strong> below</td>
</tr>
<tr>
<td>Arrow</td>
<td><code>text-accent text-xl font-normal flex-shrink-0</code></td>
<td class="px">20px · mint</td>
<td class="note">Unicode <code></code>. Kept in the colour of the brand accent so it reads as a design element, not a primary control</td>
</tr>
<tr>
<td>Output token</td>
<td><code>font-mono text-[13px] text-ink bg-white border border-line rounded-sm px-2 py-1 truncate</code></td>
<td class="px">13px</td>
<td class="note">truncate so a long output like <code>[durchgestrichen: gestern]</code> doesn't blow the card width</td>
</tr>
</table>
<h3>Per-rule Beispiel visuals</h3>
<table class="impl-table">
<tr><th>Rule</th><th>Kurrent drawing</th><th>Overlay</th><th>Output</th></tr>
<tr><td>Nicht lesbare Wörter</td><td>Two short cursive waves</td><td>Semi-opaque grey smudge ellipse <code>rgba(100,90,75,.35)</code> over right half</td><td><code>[unleserlich]</code></td></tr>
<tr><td>Durchgestrichene Wörter</td><td>One cursive flourish (5 peaks)</td><td>Solid stroke line at y≈12 crossing the word</td><td><code>[durchgestrichen: gestern]</code></td></tr>
<tr><td>Das lange s (ſ)</td><td>Hand-drawn ſ glyph on the left (Bezier loop + crossbar) + cursive continuation</td><td>none</td><td><code>Sommers</code></td></tr>
<tr><td>Unsichere Namen</td><td>Cursive capital M (zigzag) + cursive word</td><td>Soft grey smudge <code>rgba(100,90,75,.2)</code> over last 3 chars</td><td><code>[Müller?]</code></td></tr>
<tr><td>Dialekt &amp; Fremdwörter</td><td>Longer continuous cursive wave (9 peaks)</td><td>none — signals "just copy it"</td><td><code>pardonnez-moi</code></td></tr>
</table>
<h3>"Noch in Klärung" full-bleed strip</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Strip container</td>
<td><code>bg-brand-sand-muted border-y border-line py-9 -mx-6 mt-14 mb-14</code></td>
<td class="px">py 36px · full-bleed</td>
<td class="note">negative margin breaks out of the 1100px container to hit the page edges at ≤ 1100; visually distinct from white rule-cards</td>
</tr>
<tr>
<td>Inner wrapper</td>
<td><code>max-w-[1052px] mx-auto px-6</code></td>
<td class="px">matches container</td>
<td class="note">restores the reading column inside the full-bleed band</td>
</tr>
<tr>
<td>Intro line</td>
<td><code>font-serif text-[15px] text-ink-2 mb-4.5 max-w-[640px]</code></td>
<td class="px">15px</td>
<td class="note">collaborative voice: "treffen Sie eine plausible Wahl + notieren Sie es in den Kommentaren"</td>
</tr>
<tr>
<td>Chip row</td>
<td><code>flex flex-wrap gap-2.5</code></td>
<td class="px">gap 10px</td>
<td class="note">wraps naturally on narrow viewports</td>
</tr>
<tr>
<td>Chip (pill)</td>
<td><code>inline-flex items-center gap-2 bg-white border border-dashed border-[#C9C4B5] dark:border-line-2 rounded-full px-4 py-2 font-sans text-[13px] text-ink-2 font-medium</code></td>
<td class="px">h≈32 · 13px</td>
<td class="note">dashed border reinforces "provisional / open" semantics. Wiggle prefix <code></code> in accent colour</td>
</tr>
<tr>
<td>Chip suffix examples</td>
<td>italic muted clarifier in parens: <code>(d., u., etc.)</code>, <code>(1.t Januar 1912)</code> etc.</td>
<td class="px"></td>
<td class="note">optional; only for chips whose topic benefits from one example. Keep under 22 chars</td>
</tr>
</table>
<h3>Closing invitation</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Card</td>
<td><code>flex gap-4.5 items-start bg-white border border-line rounded-sm px-8 py-7 max-w-[720px]</code></td>
<td class="px">max 720px · p 28/32</td>
<td class="note">narrower than rule cards — invites a more personal read</td>
</tr>
<tr>
<td>Chat-bubble icon</td>
<td><code>w-7 h-7 text-accent flex-shrink-0</code> — speech-bubble SVG</td>
<td class="px">28px · mint</td>
<td class="note">signals "comment / feedback" non-verbally</td>
</tr>
<tr>
<td>H4</td>
<td><code>font-serif text-lg font-bold text-ink mb-2</code></td>
<td class="px">18px · 700</td>
<td class="note">"Fehlt eine Regel?"</td>
</tr>
<tr>
<td>Body</td>
<td><code>font-serif text-[15px] leading-[1.55] text-ink-2</code></td>
<td class="px">15px</td>
<td class="note">three clauses: stolpern-über → Kommentar → Familientreffen</td>
</tr>
</table>
<h3>@media print</h3>
<table class="impl-table">
<tr><th>Element</th><th>Tailwind / CSS</th><th>Px / value</th><th>Note</th></tr>
<tr>
<td>Page size</td>
<td><code>@page { margin: 1.5cm; }</code></td>
<td class="px">1.5cm</td>
<td class="note">A4 default; leaves margin for hole-punching</td>
</tr>
<tr>
<td>Body override</td>
<td><code>body { background: white; color: #111; }</code></td>
<td class="px"></td>
<td class="note">no brand-sand page bg on paper</td>
</tr>
<tr>
<td>Hidden in print</td>
<td><code>.app-nav, .closing, .new-tab { display: none; }</code></td>
<td class="px"></td>
<td class="note">nav, closing invitation, and "(öffnet in neuem Tab)" annotations — nothing useful on paper</td>
</tr>
<tr>
<td>Rule cards in print</td>
<td><code>.rule-card { break-inside: avoid; border: 1px solid #999; box-shadow: none; margin-bottom: 8pt; }</code></td>
<td class="px">avoid-break</td>
<td class="note">ensures no rule splits across pages</td>
</tr>
<tr>
<td>Kurrent SVG in print</td>
<td>inline SVG renders natively; no change needed</td>
<td class="px"></td>
<td class="note">if the printer is monochrome, strokes still read at <code>#2a2a2a</code></td>
</tr>
<tr>
<td>Wikipedia link</td>
<td>append full URL after the link text via <code>@media print { a[href]::after { content: " (" attr(href) ")"; } }</code></td>
<td class="px"></td>
<td class="note">standard print-a11y pattern — readers on paper need the URL</td>
</tr>
</table>
<h3>Paraglide keys (de/en/es)</h3>
<table class="impl-table">
<tr><th>Key</th><th>de</th><th>en</th><th>es</th></tr>
<tr><td>richtlinien_title</td><td>Transkriptions-Richtlinien</td><td>Transcription Guidelines</td><td>Normas de transcripción</td></tr>
<tr><td>richtlinien_intro</td><td>Damit alle Briefe einheitlich transkribiert werden — egal ob Tante Hedwig oder Cousin Paul tippt — hier unsere Regeln. Die Seite wächst mit: sobald wir eine neue Konvention beschließen, landet sie hier.</td><td>So every letter is transcribed consistently — whether Tante Hedwig or Cousin Paul is typing — here are our rules. The page grows with us: as soon as we agree a new convention, it lands here.</td><td>Para que todas las cartas se transcriban de forma uniforme — ya sea la tía Hedwig o el primo Paul quien escriba — aquí están nuestras reglas. La página crece con nosotros.</td></tr>
<tr><td>richtlinien_wiki_text</td><td>Das vollständige Kurrent- und Sütterlin-Alphabet brauchen Sie für diese Seite nicht — das erledigt Wikipedia. Hier sind unsere <em>eigenen</em> Regeln für das, was Wikipedia nicht beantwortet.</td><td>You don't need the full Kurrent and Sütterlin alphabet on this page — that's what Wikipedia is for. Here are <em>our own</em> rules for everything Wikipedia can't answer.</td><td>No necesitas el alfabeto Kurrent completo aquí — eso lo hace Wikipedia. Aquí están <em>nuestras propias</em> reglas para lo que Wikipedia no responde.</td></tr>
<tr><td>richtlinien_wiki_link</td><td>Wikipedia →</td><td>Wikipedia →</td><td>Wikipedia →</td></tr>
<tr><td>richtlinien_new_tab</td><td>(öffnet in neuem Tab)</td><td>(opens in new tab)</td><td>(abre en pestaña nueva)</td></tr>
<tr><td>richtlinien_rules_label</td><td>Regeln für die Transkription</td><td>Transcription rules</td><td>Reglas de transcripción</td></tr>
<tr><td>richtlinien_rule_unleserlich_title</td><td>Nicht lesbare Wörter</td><td>Illegible words</td><td>Palabras ilegibles</td></tr>
<tr><td>richtlinien_rule_unleserlich_body</td><td>Wenn Sie ein Wort beim besten Willen nicht entziffern können, schreiben Sie <code>[unleserlich]</code>. Jemand anderes schaut später nochmal drauf.</td><td>If you can't decipher a word even after trying, write <code>[unleserlich]</code>. Someone else will take another look later.</td><td>Si no puedes descifrar una palabra, escribe <code>[unleserlich]</code>. Otra persona lo revisará después.</td></tr>
<tr><td>richtlinien_rule_durchgestrichen_title</td><td>Durchgestrichene Wörter</td><td>Struck-through words</td><td>Palabras tachadas</td></tr>
<tr><td>richtlinien_rule_durchgestrichen_body</td><td>Auch durchgestrichener Text gehört zum Brief. Schreiben Sie ihn in eckigen Klammern mit Präfix <code>durchgestrichen:</code>.</td><td>Struck-through text still belongs to the letter. Write it in square brackets with prefix <code>durchgestrichen:</code>.</td><td>El texto tachado también pertenece a la carta. Escríbelo entre corchetes con el prefijo <code>durchgestrichen:</code>.</td></tr>
<tr><td>richtlinien_rule_langes_s_title</td><td>Das lange s (ſ)</td><td>The long s (ſ)</td><td>La s larga (ſ)</td></tr>
<tr><td>richtlinien_rule_langes_s_body</td><td>Das <em>ſ</em> ist nur eine alte Schriftform des Buchstabens <em>s</em> — kein eigener Laut. Schreiben Sie immer ein normales <em>s</em>.</td><td>The <em>ſ</em> is just an old written form of the letter <em>s</em> — not a separate sound. Always write a normal <em>s</em>.</td><td>La <em>ſ</em> es solo una forma antigua de la letra <em>s</em>. Escribe siempre una <em>s</em> normal.</td></tr>
<tr><td>richtlinien_rule_name_title</td><td>Unsichere Namen</td><td>Uncertain names</td><td>Nombres inciertos</td></tr>
<tr><td>richtlinien_rule_name_body</td><td>Wenn Sie einen Namen zu erkennen meinen, aber nicht sicher sind, ergänzen Sie ein Fragezeichen in eckigen Klammern.</td><td>If you think you can read a name but aren't sure, add a question mark in square brackets.</td><td>Si crees reconocer un nombre pero no estás seguro, añade un signo de interrogación entre corchetes.</td></tr>
<tr><td>richtlinien_rule_dialekt_title</td><td>Dialekt, Fremdwörter, fremde Zitate</td><td>Dialect, foreign words, foreign quotes</td><td>Dialecto, palabras extranjeras, citas</td></tr>
<tr><td>richtlinien_rule_dialekt_body</td><td>Plattdeutsch, Französisch, lateinische Phrasen — wörtlich übernehmen, genau wie sie geschrieben stehen.</td><td>Low German, French, Latin phrases — copy them verbatim, exactly as written.</td><td>Bajo alemán, francés, frases latinas — cópialas tal cual están escritas.</td></tr>
<tr><td>richtlinien_beispiel_label</td><td>Beispiel</td><td>Example</td><td>Ejemplo</td></tr>
<tr><td>richtlinien_klaerung_label</td><td>Noch in Klärung</td><td>Still to be decided</td><td>Aún por decidir</td></tr>
<tr><td>richtlinien_klaerung_intro</td><td>Diese Fragen klären wir noch — stoßen Sie beim Transkribieren darauf, treffen Sie eine plausible Wahl und notieren Sie es in den Kommentaren:</td><td>These questions are still open — if you hit one while transcribing, make a plausible choice and note it in the comments:</td><td>Estas preguntas aún están abiertas — si encuentras alguna mientras transcribes, elige algo razonable y nótalo en los comentarios:</td></tr>
<tr><td>richtlinien_klaer_abkuerzungen</td><td>Abkürzungen</td><td>Abbreviations</td><td>Abreviaturas</td></tr>
<tr><td>richtlinien_klaer_datumsformate</td><td>Datumsformate</td><td>Date formats</td><td>Formatos de fecha</td></tr>
<tr><td>richtlinien_klaer_umbrueche</td><td>Originale Zeilenumbrüche</td><td>Original line breaks</td><td>Saltos de línea originales</td></tr>
<tr><td>richtlinien_klaer_caps</td><td>Alte Groß-/Kleinschreibung</td><td>Old capitalisation</td><td>Mayúsculas antiguas</td></tr>
<tr><td>richtlinien_closing_title</td><td>Fehlt eine Regel?</td><td>Missing a rule?</td><td>¿Falta una regla?</td></tr>
<tr><td>richtlinien_closing_body</td><td>Stolpern Sie beim Transkribieren über eine Situation, die hier nicht steht — schreiben Sie einen Kommentar beim betreffenden Block. Wir sammeln sie und besprechen sie beim nächsten Familientreffen.</td><td>If you hit a situation while transcribing that isn't listed here — leave a comment on the relevant block. We collect them and discuss them at the next family gathering.</td><td>Si al transcribir encuentras una situación que no está aquí — deja un comentario en el bloque. Las recogemos y las discutimos en la próxima reunión familiar.</td></tr>
</table>
<div class="notes">
<div class="nh">Interaction + behaviour spec</div>
<ul>
<li><strong>Page is fully static</strong>. No load function, no fetch, no dynamic state. <code>export const prerender = true;</code> builds to HTML at build time. Updates ship as git commits, not runtime data.</li>
<li><strong>Wikipedia link</strong>: opens in a new tab. Never follow internal-nav assumptions (no <code>goto()</code>, no <code>history.back()</code>). Preserves the user's existing tab — important for transcribers who might open this page mid-session.</li>
<li><strong>No anchor navigation in v1</strong>. At 5 rules there's no need for a TOC or deep links. If the rule count grows past ~10, revisit with a sticky sidebar.</li>
<li><strong>Print support</strong>: <code>@media print</code> block in the page's <code>&lt;style&gt;</code> scope. Test via <code>page.emulateMedia({ media: 'print' })</code> in Playwright.</li>
<li><strong>Chips are NOT interactive in v1</strong> — they are visual markers for open questions. If we later add anchors to a discussion thread (e.g. a Gitea issue or forum post per item), the chips become <code>&lt;a&gt;</code> tags. Keep the semantic markup ready.</li>
<li><strong>Page growth model</strong>: when a new convention is agreed, it moves from the "Noch in Klärung" chip row into a new rule card. That commit is the full content update — no CMS, no admin UI, no backend.</li>
</ul>
</div>
<div class="notes danger">
<div class="nh">Edge cases + a11y requirements</div>
<ul>
<li><strong>Heading structure</strong>: <code>&lt;h1&gt;</code> page title → <code>&lt;h2&gt;</code> section labels ("Regeln", "Noch in Klärung") → <code>&lt;h3&gt;</code> per rule card. Do not skip levels. Screen readers navigate by heading.</li>
<li><strong>Decorative SVGs</strong>: Kurrent strokes in Beispiel boxes are <em>decorative</em> — they carry no information that the output token doesn't already carry. Mark each with <code>role="presentation" aria-hidden="true"</code>. The Beispiel row's meaning lives in the output token.</li>
<li><strong>Icon chips</strong>: emoji-icons (🔍 ✂ ſ ? 🌍) are presentational. Wrap each in a <code>&lt;span aria-hidden="true"&gt;</code> next to the H3 title — the H3 carries the rule's name and is what screen readers read.</li>
<li><strong>Colour-alone check (WCAG 1.4.1)</strong>: the "Noch in Klärung" chips differ from rule cards by shape (pill vs. card), border style (dashed vs. solid), and colour (sand-muted vs. white). Three redundant cues.</li>
<li><strong>Contrast — light</strong>: ink (#012851) on white = 14.5:1 AAA · ink-2 (#3a4a5c) on white = 9.1:1 AAA · mint accent (#A6DAD8) is used for backgrounds and borders only — never for body text.</li>
<li><strong>Contrast — dark</strong>: ink (#f0efe9) on surface (#011526) = 14.8:1 AAA · turquoise accent (#00c7b1) on surface = 5.4:1 AA large-text. Kurrent stroke <code>#d9dce0</code> on paper-dark (#0a1d2e) = 11.2:1 AAA.</li>
<li><strong>Beispiel box contrast</strong>: in dark mode, a mint-tinted bg against the card surface must not drop below 3:1. Use <code>rgba(166,218,216,0.04)</code> (not 0.12) for the bg; dashed border carries the delineation.</li>
<li><strong>Reduced motion</strong>: no animations on this page, so <code>prefers-reduced-motion</code> is a no-op. Don't add hover-scale on chips or cards — the page is reference content, not interactive.</li>
<li><strong>Touch targets on chips</strong>: currently non-interactive. If made interactive in v2, each chip must meet ≥ 44×44 (current height is ~32, so add <code>min-h-[44px] py-2.5</code>).</li>
<li><strong>Screen-reader on external link</strong>: the inline "(öffnet in neuem Tab)" annotation is a real DOM text node, so screen readers announce it. Do NOT replace with a CSS <code>::after</code> — that's invisible to AT.</li>
<li><strong>Long words</strong>: rule titles and output tokens must not wrap awkwardly on a 320px viewport. Test with "Transkriptions-Richtlinien" H1 (allow <code>overflow-wrap: break-word</code> or the hyphen between words).</li>
</ul>
</div>
<h3>Component tree (frontend)</h3>
<table class="impl-table">
<tr><th>Component</th><th>Status</th><th>Responsibility</th></tr>
<tr>
<td><code>routes/hilfe/transkription/+page.svelte</code></td>
<td>new</td>
<td>Prerendered static page. Composes header, info-card, rule grid, klaerung strip, closing. Imports message strings via Paraglide.</td>
</tr>
<tr>
<td><code>lib/components/RichtlinienRuleCard.svelte</code></td>
<td>new</td>
<td>One rule: icon chip, title, body, Beispiel box. Props: <code>{ icon, title, body, beispiel }</code> where <code>beispiel</code> is <code>{ svg: Component, output: string }</code>.</td>
</tr>
<tr>
<td><code>lib/components/KurrentSample.svelte</code></td>
<td>new (optional)</td>
<td>Wraps the 5 per-rule Beispiel SVGs. Alternative: inline each SVG in <code>+page.svelte</code> since they're used once each. Pick whichever keeps <code>+page.svelte</code> under 200 lines.</td>
</tr>
<tr>
<td><code>lib/components/InfoCard.svelte</code></td>
<td>new (candidate)</td>
<td>Generic info card with mint left-border accent — reusable for future help pages. If only this one consumer exists in v1, inline it here and extract later.</td>
</tr>
<tr>
<td><code>messages/{de,en,es}.json</code></td>
<td>extend</td>
<td>Add the 23 new keys listed in the Paraglide table above. All three languages in the same commit.</td>
</tr>
</table>
<h3>Acceptance criteria (Gherkin)</h3>
<div class="notes">
<div class="nh">Verifiable from outside the code</div>
<ul>
<li><strong>Given</strong> an authenticated user (or any user, depending on #320 auth decision), <strong>when</strong> they visit <code>/hilfe/transkription</code>, <strong>then</strong> they see the title, family-voice intro, Wikipedia info-card, five rule cards, "Noch in Klärung" strip, and closing invitation — in that order.</li>
<li><strong>Given</strong> the user is on the Richtlinien page, <strong>when</strong> they click the Wikipedia link, <strong>then</strong> the Wikipedia article opens in a new tab AND the current Familienarchiv tab remains on <code>/hilfe/transkription</code>.</li>
<li><strong>Given</strong> the viewport width is 320px, <strong>when</strong> the page renders, <strong>then</strong> the rule grid is one-column, chips wrap to multiple rows, and no horizontal scroll appears.</li>
<li><strong>Given</strong> the viewport width is 768px, <strong>when</strong> the page renders, <strong>then</strong> the rule grid is two-column.</li>
<li><strong>Given</strong> the viewport width is 1024px+, <strong>when</strong> the page renders, <strong>then</strong> the rule grid is three-column.</li>
<li><strong>Given</strong> dark mode is active, <strong>when</strong> axe-core analyzes the page at 320/768/1440, <strong>then</strong> no WCAG 2.1 AA violations are reported.</li>
<li><strong>Given</strong> the user triggers the browser print dialog, <strong>when</strong> the preview renders, <strong>then</strong> the app nav is hidden, rule cards do not break across pages, and each Wikipedia link shows its full URL in parentheses.</li>
<li><strong>Given</strong> the locale is <code>en</code> or <code>es</code>, <strong>when</strong> the page renders, <strong>then</strong> every section has translated text — no raw key tokens visible, no German fallbacks leaking into non-German locales.</li>
</ul>
</div>
<h3>Out of scope for this spec</h3>
<div class="notes">
<div class="nh">Not in v1 — follow-up tickets</div>
<ul>
<li><strong>Anchor navigation / sticky TOC</strong>: needed only when rule count exceeds ~10. Five rules fit on one screen at desktop.</li>
<li><strong>Interactive chips linking to discussion threads</strong>: when "Noch in Klärung" items have their own Gitea discussions, wire the chips to them. Needs a decision on where those discussions live first.</li>
<li><strong>Editing through the UI</strong>: the page is intentionally git-based. Family members propose rules via Gitea issues or transcription-block comments; the archivist commits them. No admin editor.</li>
<li><strong>Per-rule "Warum?" expandables</strong>: some rules (like "warum verbatim belassen?") have more story to tell. If beta users ask, reveal via a <code>HelpPopover</code> (see Markus's review on #320).</li>
<li><strong>Kurrent font embedding</strong>: the Beispiel SVGs approximate handwriting with bezier paths. Embedding a real Kurrent webfont would be more authentic but costs ~40 KB and the brand isn't a Kurrent-typography product.</li>
<li><strong>Search within guidelines</strong>: at 5 rules, Ctrl-F in the browser is the search.</li>
</ul>
</div>
</div>
</div>
</body>
</html>