wordeck/apps/web/src/lib/i18n/de.ts
Till JS 03ec7e7b3e feat(decks): Edit-Icon auf Deck-Karten + Deck-Edit-Page
- DeckStack: Pencil-Icon absolut unten-rechts, erscheint beim Hover
  (z-index über Card, ausserhalb des <a>-Links zur Detail-Page)
- Neuer Route /decks/[id]/edit: Form für Name, Beschreibung, Farbe
- i18n deck_edit keys (de + en)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 15:57:37 +02:00

271 lines
11 KiB
TypeScript

// Default-Locale. Schlüssel sind Punkt-getrennt nach Bereich.
// Interpolation: {n}, {name}, {count} → simple replace.
export type TranslationNode = { [key: string]: string | TranslationNode };
export const de: TranslationNode = {
app: {
name: 'Cards',
title_suffix: 'Cards',
},
nav: {
decks: 'Decks',
study: 'Lernen',
explore: 'Library',
import: 'Import',
stats: 'Statistik',
login_dev: 'Login (dev)',
account: 'Account',
},
landing: {
welcome: 'Lernkarten mit Spaced-Repetition.',
intro:
'Cardecky ist die föderierte Karteikarten-App des Vereins mana e.V. — FSRS-Scheduler, Cloze-Karten, Anki-Import.',
cta_login: 'Login (dev)',
dev_user_prompt: 'User-ID (dev):',
},
decks: {
title: 'Decks',
new: 'Neues Deck',
empty: 'Noch keine Decks.',
empty_cta: 'Erstes Deck anlegen',
loading: 'Lade…',
error: 'Fehler: {msg}',
card_count: '{n} Karten',
card_count_one: '1 Karte',
card_count_more: '{n} weitere Karten im Stapel',
card_count_more_one: '1 weitere Karte im Stapel',
due_count: '{n} fällig',
delete_confirm:
'Deck "{name}" wirklich löschen? Alle Karten + Review-Daten gehen verloren.',
deleted: 'Deck "{name}" gelöscht',
delete_failed: 'Löschen fehlgeschlagen: {msg}',
},
deck_detail: {
back: '← Zurück zu Decks',
study_button: 'Lernen',
new_card: 'Neue Karte',
empty: 'Keine Karten in diesem Deck.',
empty_cta: 'Erste Karte anlegen →',
card_summary_due: '{cards} · {due} fällig',
card_delete_aria: 'Karte löschen',
card_delete_label: 'Löschen',
card_delete_confirm: 'Karte wirklich löschen? Reviews werden mit gelöscht.',
fan_aria: 'Aufgefächerte Karten von Stapel "{name}"',
card_open: 'Karte öffnen — {type}',
},
deck_stack: {
aria_label: 'Stapel "{name}" — {cards} Karten, {due} fällig',
},
deck_edit: {
title: 'Deck bearbeiten',
back: '← Zurück zum Deck',
name_label: 'Name',
description_label: 'Beschreibung (optional)',
color_label: 'Farbe',
save: 'Speichern',
saving: 'Speichere…',
cancel: 'Abbrechen',
save_failed: 'Speichern fehlgeschlagen: {msg}',
saved: 'Deck gespeichert',
},
deck_new: {
title: 'Neues Deck',
name_label: 'Name',
description_label: 'Beschreibung (optional)',
color_label: 'Farbe (optional)',
create: 'Deck anlegen',
creating: 'Lege an…',
cancel: 'Abbrechen',
create_failed: 'Anlegen fehlgeschlagen: {msg}',
},
card_new: {
title: 'Neue Karte',
back: '← Zurück',
deck_label: 'Deck',
type_label: 'Typ',
type_basic: 'Basic (front → back)',
type_basic_reverse: 'Basic + Reverse (front ↔ back, 2 Reviews)',
type_cloze: 'Cloze (Lückentext, 1 Review pro Cluster)',
front_label: 'Vorderseite (Markdown)',
back_label: 'Rückseite (Markdown)',
back_placeholder: 'Antwort',
front_placeholder: '# Markdown ist erlaubt\n**fett**, _kursiv_, `code`',
preview_label: 'Vorschau',
cloze_text_label: 'Text mit Lücken (Markdown)',
cloze_text_placeholder: 'Die Hauptstadt von {{c1::Frankreich}} ist {{c2::Paris}}.',
cloze_help: '{{c1::Antwort}} definiert eine Lücke. Pro Cluster-ID (c1, c2, …) entsteht ein eigenes Review. Optionaler Hinweis: {{c1::Antwort::Tipp}} — der Tipp erscheint im Prompt anstelle von „…".',
cloze_no_clusters: 'Mindestens ein {{cN::…}}-Cluster wird gebraucht.',
cloze_clusters_detected: '{n} Cluster erkannt: c{ids} → {n} Reviews.',
cloze_preview_label: 'Vorschau (c{first} maskiert)',
cloze_extra_label: 'Extra (optional)',
cloze_extra_placeholder: 'Zusätzlicher Kontext, wird unter der Antwort gezeigt.',
create: 'Karte anlegen',
creating: 'Speichere…',
cancel: 'Abbrechen',
create_failed: 'Anlegen fehlgeschlagen: {msg}',
toast_basic: 'Karte angelegt',
toast_basic_reverse: '2 Reviews initialisiert (front→back, back→front)',
toast_cloze: '{n} Reviews initialisiert (1 pro Cluster)',
toast_image_occlusion: '{n} Reviews initialisiert (1 pro Maske)',
type_image_occlusion: 'Image-Occlusion (Bild + N Masken)',
type_typing: 'Typing (Texteingabe, Fuzzy-Match)',
type_multiple_choice: 'Multiple-Choice (4 Optionen, KI-Distractors)',
type_audio_front: 'Audio-Front (Hören + Antworten)',
answer_label: 'Antwort (Markdown)',
answer_placeholder: 'Richtige Antwort',
distractor_pool_label: 'Distractor-Pool (optional)',
distractor_pool_placeholder: 'Ein Eintrag pro Zeile — Fallback wenn das Deck zu klein für KI-Distractors ist',
audio_ref_label: 'Audio-Referenz (media_ref)',
audio_ref_placeholder: 'z. B. abc123.mp3',
back_audio_label: 'Antworttext (Markdown)',
toast_typing: 'Typing-Karte angelegt',
toast_multiple_choice: 'Multiple-Choice-Karte angelegt',
toast_audio_front: 'Audio-Front-Karte angelegt',
decks_load_failed: 'Decks konnten nicht geladen werden: {msg}',
},
card_edit: {
title: 'Karte bearbeiten',
back: '← Zurück zum Deck',
type_locked_help: 'Der Card-Type kann nicht geändert werden — die Reviews-Tabelle hängt am Type.',
save: 'Speichern',
saving: 'Speichere…',
cancel: 'Abbrechen',
delete: 'Löschen',
deleting: 'Lösche…',
delete_confirm: 'Karte wirklich löschen? Reviews werden mit gelöscht.',
updated: 'Karte aktualisiert',
save_failed: 'Speichern fehlgeschlagen: {msg}',
delete_failed: 'Löschen fehlgeschlagen: {msg}',
deleted: 'Karte gelöscht',
},
study: {
title: 'Lernen',
empty: 'Keine Decks.',
none_due: 'Aktuell nichts fällig.',
study_now: 'Jetzt lernen',
due_count: '{n} fällig',
},
study_session: {
back: '← Übersicht',
all_done: 'Geschafft! Alle fälligen Karten gemacht.',
stats: 'Reviews: {reviewed} · Wieder: {again}',
reveal: 'Lösung zeigen',
reveal_hint: 'Leertaste / Enter zum Aufdecken',
grade_again: 'Wieder',
grade_hard: 'Schwer',
grade_good: 'Gut',
grade_easy: 'Leicht',
grade_hint: '1=Wieder · 2=Schwer · 3=Gut · 4=Leicht',
loading: 'Lade…',
error: 'Fehler: {msg}',
manage_link: 'Karten verwalten →',
},
import: {
title: 'Importieren',
intro: 'Übernimm Decks und Karten aus einer Anki-Datei (.apkg oder .colpkg). FSRS-Verlauf wird nicht übernommen — alle Karten starten als „neu".',
what_works_title: 'Was wird übernommen',
what_works_decks: 'Decks (Anki-Hierarchie Foo::Bar wird zu Foo / Bar).',
what_works_basic: 'Basic + Basic-Reverse: Front/Back direkt.',
what_works_cloze: 'Cloze: {{c1::…}} wird mit Sub-Index pro Cluster angelegt.',
what_works_media: 'Bilder + Audio (eingebettet als Markdown bzw. <audio>-Tag).',
what_skipped_title: 'Was nicht übernommen wird',
what_skipped_media: '— (Bilder + Audio werden seit Phase 9k mit übernommen, siehe oben)',
what_skipped_history: 'FSRS-Lernverlauf (Anki-Reviews werden bewusst neu aufgesetzt).',
what_skipped_addons: 'Add-on-spezifische Card-Types (image-occlusion etc.).',
anki_label: 'Aus Anki importieren',
dropzone: '📦 .apkg-Datei hier ablegen oder klicken',
dropzone_hint: 'Basic, Basic + Reverse, Cloze · Bilder + Audio werden mit übernommen (Limit 25 MB pro Datei).',
parsing: 'Lese {file}…',
preview_found: 'Gefunden in',
preview_decks_one: '1 Deck',
preview_decks: '{n} Decks',
preview_cards_one: '1 Karte',
preview_cards: '{n} Karten',
preview_breakdown: '({basic} basic, {basic_reverse} basic-reverse, {cloze} cloze)',
preview_media: '{n} Medien werden mitgeladen',
preview_skipped: '{n} übersprungen (unbekannter Typ)',
preview_warnings: 'Hinweise ({n})',
cancel: 'Abbrechen',
import_now: 'Importieren',
stage_media: 'Lade Medien hoch · {current} / {total}',
stage_decks: 'Lege Decks an · {current} / {total}',
stage_cards: 'Importiere Karten · {current} / {total}',
stage_done: 'Fertig.',
done_summary_one: '✓ {cards} Karten in 1 Deck angelegt.',
done_summary: '✓ {cards} Karten in {decks} Decks angelegt.',
done_dupes: '{n} Duplikate übersprungen (gleicher Inhalt schon vorhanden).',
done_media: '{uploaded} Medien geladen, {failed} fehlgeschlagen.',
done_failures: '{n} Fehler',
done_more: 'Weitere Datei',
error_label: 'Fehler: {msg}',
retry: 'Erneut versuchen',
},
inbox_banner: {
label: '📥 Inbox',
count_one: '1 eingegangene Karte aus anderen Apps',
count: '{n} eingegangene Karten aus anderen Apps',
cta: '— sortieren →',
},
account: {
title: 'Account',
user_id_label: 'User-ID',
logout: 'Abmelden',
phase2_hint:
'Phase-2-Hinweis: aktuell ist die Identität ein Dev-Stub (sessionStorage). Mit Auth-Föderation wechselt das auf einen mana-auth-Login gegen auth.mana.how.',
export_title: 'Daten-Export',
export_intro:
'Lade alle deine Cards-Daten als JSON herunter — Decks, Karten, Reviews, Study-Sessions, Tags, Media-Refs, Import-Jobs. DSGVO Art. 15/20.',
export_button: 'Daten exportieren',
export_loading: 'Lade…',
export_done: 'Export geladen: {decks} Decks, {cards} Karten, {reviews} Reviews.',
export_failed: 'Export fehlgeschlagen: {msg}',
delete_title: 'Konto löschen',
delete_intro:
'Löscht unwiderruflich alle deine Cards-Daten. DSGVO Art. 17. Andere mana-Apps (Memoro, Who, …) behalten ihre Daten unabhängig — wenn du dort auch löschen willst, mach das jeweils dort oder nutze die Verein-DSGVO-Sammelanfrage über mana-admin.',
delete_button: 'Alle Cards-Daten löschen',
delete_loading: 'Lösche…',
delete_confirm:
'ALLE deine Cards-Daten werden unwiderruflich gelöscht. Tippe LÖSCHEN zur Bestätigung.',
delete_confirm_word: 'LÖSCHEN',
delete_done: 'Gelöscht: {decks} Decks, {imports} Import-Jobs.',
delete_failed: 'Löschen fehlgeschlagen: {msg}',
},
stats: {
title: 'Statistik',
generated_at: 'Stand {date}',
decks: 'Decks',
cards: 'Karten',
reviews: 'Reviews',
due_now: 'Fällig jetzt',
days_title: 'Lerntage',
streak: 'Streak: {n} Tage · letzte 7 Tage: {total} Reviews',
streak_one: 'Streak: 1 Tag · letzte 7 Tage: {total} Reviews',
fsrs_title: 'FSRS-Status',
fsrs_intro: 'Verteilung deiner Karten-Reviews über die FSRS-Zustände.',
fsrs_new: 'Neu',
fsrs_learning: 'Lernend',
fsrs_review: 'Review',
fsrs_relearning: 'Relearning',
loading: 'Lade…',
error: 'Fehler: {msg}',
},
common: {
empty: '(leer)',
skip_to_content: 'Zum Inhalt springen',
main_nav: 'Hauptnavigation',
notifications: 'Benachrichtigungen',
language_switcher: 'Sprache wechseln',
},
image_occlusion: {
image_label: 'Bild auswählen',
uploading: 'Lade Bild hoch…',
not_an_image: 'Datei ist kein Bild.',
canvas_aria: 'Bild-Canvas — ziehe mit der Maus, um Masken anzulegen',
draw_hint: 'Ziehe ein Rechteck auf dem Bild, um eine Maske anzulegen.',
label_placeholder: 'Beschriftung (optional)',
delete_mask: 'Maske löschen',
no_image_selected: 'Wähle zuerst ein Bild aus.',
no_masks: 'Lege mindestens eine Maske an.',
},
};