i18n + type: translate the setting descriptions, vendor Libre Franklin locally #332

Merged
Cordy merged 4 commits from feat/vendor-font into main 2026-08-27 19:00:59 +00:00
Owner

Deferred-items cluster B (#311 items 3, 9, 11).

Items 9 and 11 — the setting descriptions are no longer English-only

SET_DESC held raw English prose, so ten descriptions rendered in English regardless of the interface language. It now maps a field id to an i18n key, and the copy lives in the same table as every other string, translated into all four languages.

Two implementation notes:

  • The translations were written as real characters and escaped programmatically. The table stores JS \uXXXX escapes; hand-escaping four languages is how a stray é becomes mojibake in front of a customer.
  • Swiss German throughout — no eszett. lässt, muss, Grösse-style spelling, consistent with the rest of the table and with shipping from a .ch instance. Worth your eye since you'll read these before anyone else does.

Item 11: set-f-audit had no description at all and now has one. set-quotafield still has none — I cannot confirm from the frontend whether it caps the whole instance or sets a per-space default, and a confidently-worded wrong description on a quota control is worse than a blank space. Needs one line from the backend to settle.

There is a real gap worth stating: t(SET_DESC[id]) is a dynamic lookup, so the webcheck guard's undefined-key test cannot see these keys. A typo would render a verbatim key rather than fail CI. The splice therefore validates every SET_DESC key resolves and carries exactly four languages, and the limitation is written into the comment above the map.

Item 3 — Libre Franklin is vendored, not approximated

The stack was "Avenir Next", "Segoe UI Variable", system-ui — an approximation that renders differently on every OS. Now 'Libre Franklin Variable' leads it, served from our own origin.

  • SIL OFL 1.1, which permits bundling and redistribution with software. LibreFranklin-OFL.txt ships beside the font because the licence requires it.
  • One variable file, latin subset, 29 KB — smaller than shipping static 400 and 500 cuts, and latin covers all four interface languages. Text in other scripts falls back per-glyph to the system stack, which is the correct behaviour.
  • font-display: swap so a cold cache shows system text immediately instead of a blank page.
  • Fetched at build time from the npm registry and committed; nothing is fetched at runtime. An admin tool that phones home for a typeface isn't a sovereign product, which is the whole point of the no-CDN constraint.
  • Verified the flat file survives the release build's non-recursive cp web/static/* cmd/cairnd/webdist/, rather than assuming it.

Gate: node --check, go vet ./..., go test ./..., go build ./cmd/cairnd, plus the SET_DESC key/language validation above.

Deferred-items cluster B (#311 items 3, 9, 11). ## Items 9 and 11 — the setting descriptions are no longer English-only `SET_DESC` held raw English prose, so ten descriptions rendered in English regardless of the interface language. It now maps a field id to an **i18n key**, and the copy lives in the same table as every other string, translated into all four languages. Two implementation notes: - **The translations were written as real characters and escaped programmatically.** The table stores JS `\uXXXX` escapes; hand-escaping four languages is how a stray `é` becomes mojibake in front of a customer. - **Swiss German throughout — no eszett.** `lässt`, `muss`, `Grösse`-style spelling, consistent with the rest of the table and with shipping from a `.ch` instance. Worth your eye since you'll read these before anyone else does. Item 11: `set-f-audit` had no description at all and now has one. **`set-quotafield` still has none** — I cannot confirm from the frontend whether it caps the whole instance or sets a per-space default, and a confidently-worded wrong description on a quota control is worse than a blank space. Needs one line from the backend to settle. There is a real gap worth stating: `t(SET_DESC[id])` is a *dynamic* lookup, so the webcheck guard's undefined-key test cannot see these keys. A typo would render a verbatim key rather than fail CI. The splice therefore validates every `SET_DESC` key resolves and carries exactly four languages, and the limitation is written into the comment above the map. ## Item 3 — Libre Franklin is vendored, not approximated The stack was `"Avenir Next", "Segoe UI Variable", system-ui` — an approximation that renders differently on every OS. Now `'Libre Franklin Variable'` leads it, served from our own origin. - **SIL OFL 1.1**, which permits bundling and redistribution with software. `LibreFranklin-OFL.txt` ships beside the font because the licence requires it. - **One variable file, latin subset, 29 KB** — smaller than shipping static 400 and 500 cuts, and latin covers all four interface languages. Text in other scripts falls back per-glyph to the system stack, which is the correct behaviour. - **`font-display: swap`** so a cold cache shows system text immediately instead of a blank page. - Fetched at build time from the npm registry and committed; nothing is fetched at runtime. An admin tool that phones home for a typeface isn't a sovereign product, which is the whole point of the no-CDN constraint. - Verified the flat file survives the release build's **non-recursive** `cp web/static/* cmd/cairnd/webdist/`, rather than assuming it. Gate: `node --check`, `go vet ./...`, `go test ./...`, `go build ./cmd/cairnd`, plus the SET_DESC key/language validation above.
Cordy merged commit 9c0ae5b198 into main 2026-08-27 19:00:59 +00:00
Cordy deleted branch feat/vendor-font 2026-08-27 19:01:00 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#332
No description provided.