dorfteich/packages/shared/i18n/de/font.json
Claude Opus 5 f8c241b11a
Some checks failed
CI / Lint, typecheck, test (pull_request) Failing after 6m26s
CI / Auth e2e pack (pull_request) Has been skipped
CI / Import/export fidelity gate (pull_request) Has been skipped
CI / Build container images (pull_request) Has been skipped
#304: custom fonts in the pickers, an admin screen, and the licence page
The backend from #303 could store an operator's font but nothing could
choose one: no list endpoint outside the Site-Admin routes, no @font-face
rules for a family that only exists at runtime, and no management UI.

Found while wiring it up — a real defect in #303, invisible to its tests:
`fontStack` cannot tell an uploaded family from a deleted one, so the PDF
exporter embedded the face and then never named it. Every export of a pond
using an operator font rendered in the system font while the job reported
success. Both `fontStack` call sites now take the uploaded families
(`buildPdfHtml`, `pondFontVariables`); `pdf-html.test.ts` pins the
regression from both sides. Verified against a real Gotenberg: with the
families the PDF embeds PlayfairDisplay-Bold, without them NotoSans-Bold —
that was the whole bug, in one diff of two PDFs.

- `GET /fonts/custom` is readable by any signed-in user, not Site Admins
  only: the pickers, the licence page and the injected `@font-face` rules
  all need it, and gating it would have forced a second, admin-only UI.
- Bundled and uploaded families are told apart by their `<optgroup>`, not
  by a badge — the grouping is then part of the control's semantics, so a
  screen reader announces it and the native mobile select keeps it. Within
  each source the catalog's category grouping is preserved.
- The delete confirmation names how many ponds use the family and what
  happens to them; focus moves to it and back on cancel. Deletion stays
  unblocked (the api's decision, #303) — the ponds degrade, they do not
  break.
- The licence page grew a second table. That is what makes an attribution
  obligation satisfiable: a commercial licence that requires naming the
  foundry needs a page to name it on.

Verified in the browser end to end (upload two weights → listed and
rendered in its own font → chosen in a pond → page renders in it → deleted
→ pond falls back): api suite for fonts/export 77 passed, a11y pack 11/11
locally in both schemes, lint/typecheck/i18n:check green.
2026-08-01 18:32:46 +02:00

83 lines
3.8 KiB
JSON

{
"heading": "Darstellung",
"intro": "Wähle die Schriften für Überschriften, Fließtext und Code dieses Teichs. Die Schriften werden ausschließlich von dieser Instanz ausgeliefert.",
"slots": {
"heading": "Überschriften",
"body": "Fließtext",
"mono": "Code"
},
"family": "Schrift",
"weight": "Schnitt",
"preview": "Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. 0123",
"save": "Schriften speichern",
"saved": "Gespeichert",
"catalogLink": "Schrift-Lizenzen",
"group": {
"bundled": "Mitgelieferte Schriften · {{category}}",
"custom": "Eigene Schriften · {{category}}"
},
"catalog": {
"title": "Schriftkatalog",
"intro": "Jede Schrift wird selbst gehostet — beim Anzeigen eines Teichs wird keine Anfrage an Dritte gestellt (DSGVO).",
"family": "Schrift",
"category": "Stil",
"weights": "Schnitte",
"license": "Lizenz",
"bundledHeading": "Mitgelieferte Schriften",
"bundledIntro": "Diese Schriften sind frei unter den angegebenen Lizenzen.",
"customHeading": "Eigene Schriften",
"customIntro": "Diese Schriften hat der Betreiber dieser Instanz hochgeladen; die Lizenzangabe stammt von ihm.",
"customEmpty": "Es wurden keine eigenen Schriften hochgeladen."
},
"category": {
"sans-serif": "Serifenlos",
"serif": "Serif",
"monospace": "Dicktengleich"
},
"admin": {
"title": "Eigene Schriften",
"intro": "Lade eigene, lizenzierte Schriften hoch. Sie stehen zusätzlich zu den mitgelieferten in allen Teichen zur Auswahl und erscheinen mit ihrer Lizenz auf der Seite „Schrift-Lizenzen“. Die Dateien werden gespeichert, aber nicht geöffnet oder ausgewertet.",
"installed": "Hochgeladene Schriften",
"empty": "Es wurden noch keine eigenen Schriften hochgeladen.",
"upload": {
"title": "Schrift hinzufügen",
"family": "Schriftname",
"familyHint": "Genau der Name, unter dem die Schrift ausgewählt werden soll. Ein Name aus dem mitgelieferten Katalog wird abgelehnt.",
"category": "Stil",
"licence": "Lizenz",
"licenceHint": "Freitext, z. B. „Desktop-Lizenz Foundry X, Rechnung 4711“. Erscheint auf der Lizenzseite.",
"licenceUrl": "Link zur Lizenz (optional)",
"weights": "Schnitte",
"formatHint": "Pro Schnitt eine WOFF2-Datei (Pflicht), optional zusätzlich WOFF. Andere Formate werden abgelehnt; höchstens {{max}} MiB je Datei.",
"weight": "Schnitt",
"woff2": "WOFF2-Datei für Schnitt {{weight}}",
"woff": "WOFF-Datei für Schnitt {{weight}} (optional)",
"removeWeight": "Schnitt {{weight}} wieder entfernen",
"addWeight": "Weiteren Schnitt hinzufügen",
"submit": "Schrift hochladen",
"uploading": "Die Schrift wird hochgeladen …",
"done": "Die Schrift wurde hochgeladen und steht jetzt zur Auswahl."
},
"addWeight": {
"toggle": "Schnitt ergänzen",
"submit": "Schnitt hochladen"
},
"delete": {
"start": "Schrift „{{family}}“ löschen",
"usage_one": "Ein Teich benutzt diese Schrift derzeit.",
"usage_other": "{{count}} Teiche benutzen diese Schrift derzeit.",
"usageLoading": "Es wird geprüft, wie viele Teiche diese Schrift benutzen …",
"consequence": "Nach dem Löschen fallen diese Teiche auf die Standard-Schrift zurück. Ihre Einstellung bleibt gespeichert: Wird dieselbe Schrift erneut hochgeladen, sehen sie wieder aus wie vorher.",
"confirm": "Endgültig löschen",
"cancel": "Abbrechen"
}
},
"pondTheme": {
"legend": "Akzentfarbe des Teichs",
"inherit": "Eigene Einstellung der Betrachtenden (Standard)",
"hint": "Färbt Links, Buttons und Hervorhebungen der Teich-Inhalte für alle Betrachtenden. Die Farbe wird je Hell-/Dunkelmodus automatisch angepasst, damit Texte lesbar bleiben.",
"save": "Akzentfarbe speichern",
"saved": "Gespeichert"
}
}