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.
83 lines
3.4 KiB
JSON
83 lines
3.4 KiB
JSON
{
|
|
"heading": "Appearance",
|
|
"intro": "Choose the fonts for this pond's headings, body text, and code. Fonts are served from this instance only.",
|
|
"slots": {
|
|
"heading": "Headings",
|
|
"body": "Body text",
|
|
"mono": "Code"
|
|
},
|
|
"family": "Font",
|
|
"weight": "Weight",
|
|
"preview": "The quick brown fox jumps over the lazy dog. 0123",
|
|
"save": "Save fonts",
|
|
"saved": "Saved",
|
|
"catalogLink": "Font licenses",
|
|
"group": {
|
|
"bundled": "Bundled fonts · {{category}}",
|
|
"custom": "Custom fonts · {{category}}"
|
|
},
|
|
"catalog": {
|
|
"title": "Font catalog",
|
|
"intro": "Every font below is self-hosted — rendering a pond makes no request to any third party (GDPR).",
|
|
"family": "Font",
|
|
"category": "Style",
|
|
"weights": "Weights",
|
|
"license": "License",
|
|
"bundledHeading": "Bundled fonts",
|
|
"bundledIntro": "These fonts are free/libre under the licenses shown.",
|
|
"customHeading": "Custom fonts",
|
|
"customIntro": "These fonts were uploaded by this instance's operator; the licence details are theirs.",
|
|
"customEmpty": "No custom fonts have been uploaded."
|
|
},
|
|
"category": {
|
|
"sans-serif": "Sans-serif",
|
|
"serif": "Serif",
|
|
"monospace": "Monospace"
|
|
},
|
|
"admin": {
|
|
"title": "Custom fonts",
|
|
"intro": "Upload your own licensed font families. They become selectable in every pond alongside the bundled ones and are listed with their licence on the “Font licenses” page. The files are stored, never opened or parsed.",
|
|
"installed": "Uploaded fonts",
|
|
"empty": "No custom fonts have been uploaded yet.",
|
|
"upload": {
|
|
"title": "Add a font",
|
|
"family": "Font name",
|
|
"familyHint": "Exactly the name the font should be selectable under. A name from the bundled catalog is rejected.",
|
|
"category": "Style",
|
|
"licence": "Licence",
|
|
"licenceHint": "Free text, e.g. “Desktop licence, Foundry X, invoice 4711”. Shown on the licence page.",
|
|
"licenceUrl": "Link to the licence (optional)",
|
|
"weights": "Weights",
|
|
"formatHint": "One WOFF2 file per weight (required), optionally a WOFF as well. Other formats are rejected; at most {{max}} MiB per file.",
|
|
"weight": "Weight",
|
|
"woff2": "WOFF2 file for weight {{weight}}",
|
|
"woff": "WOFF file for weight {{weight}} (optional)",
|
|
"removeWeight": "Remove weight {{weight}} again",
|
|
"addWeight": "Add another weight",
|
|
"submit": "Upload font",
|
|
"uploading": "Uploading the font …",
|
|
"done": "The font was uploaded and can now be selected."
|
|
},
|
|
"addWeight": {
|
|
"toggle": "Add a weight",
|
|
"submit": "Upload weight"
|
|
},
|
|
"delete": {
|
|
"start": "Delete font “{{family}}”",
|
|
"usage_one": "One pond currently uses this font.",
|
|
"usage_other": "{{count}} ponds currently use this font.",
|
|
"usageLoading": "Checking how many ponds use this font …",
|
|
"consequence": "After deletion those ponds fall back to the default look. Their setting is kept: uploading the same font again restores their appearance.",
|
|
"confirm": "Delete permanently",
|
|
"cancel": "Cancel"
|
|
}
|
|
},
|
|
"pondTheme": {
|
|
"legend": "Pond accent color",
|
|
"inherit": "Each viewer's own setting (default)",
|
|
"hint": "Colors links, buttons, and highlights of this pond's content for every viewer. The color is automatically adjusted per light/dark mode so text stays readable.",
|
|
"save": "Save accent color",
|
|
"saved": "Saved"
|
|
}
|
|
}
|