fix(i18n): drop dot and dash separators from visible strings

Every bundle value that chained facts with " · " now reads as a phrase,
a comma list or a parenthesis, in all seven locales, and the em-dash
separators in the day, documents, correlation, sharing, environment,
vaccination and Apple Health import strings become sentences or clauses.

The day view's running list names the record first, with the dose in
the name and a life event's category as a chip, and puts a quiet day
count below: "Day 4, since 31 December" instead of a dot chain. Document
meta, location periods, vaccination rows and mood crosstab rows drop
their composed dots too.

A guard walks every bundle and fails on any " · " outside a reasoned
allowlist, and on an allowlist entry that no longer needs its place.
This commit is contained in:
Marc-André Bombeck committed 2026-10-09 13:37:14 +02:00
1 parent d8a3614120
commit 94542e7f2d
39 files changed
+1027 -881

No files matched your search

+3 -3
View File
@@ -33,7 +33,7 @@ import {
* 3. Nothing opens by itself: the row stays closed (`aria-expanded`
* false) in every state, after the answer and after a reload; a row
* opened during the run closes when the answer is done.
* 4. After the answer the row reads "Thought process · 4 steps" and the
* 4. After the answer the row reads "Thought process (4 steps)" and the
* table the answer points at renders as its chart.
* 5. A tap opens the steps; a reasoning round shows its summary under
* its title.
@@ -435,7 +435,7 @@ test.describe("Coach live trail", () => {
await expect(settled).toHaveAttribute("data-state", "done");
await expect(
settled.locator('[data-slot="coach-turn-steps-done"]'),
).toHaveText("Thought process · 4 steps");
).toHaveText("Thought process (4 steps)");
await expect(settled.locator(".text-shimmer")).toHaveCount(0);
const settledToggle = settled.locator(
'[data-slot="coach-turn-steps-toggle"]',
@@ -506,7 +506,7 @@ test.describe("Coach live trail", () => {
await expect(reloaded).toHaveAttribute("data-state", "done");
await expect(
reloaded.locator('[data-slot="coach-turn-steps-done"]'),
).toHaveText("Thought process · 4 steps");
).toHaveText("Thought process (4 steps)");
const reloadedToggle = reloaded.locator(
'[data-slot="coach-turn-steps-toggle"]',
);
+1 -1
View File
@@ -427,7 +427,7 @@ test.describe("document vault — AI assist + content search", () => {
// The PDF is refused locally (tesseract reads images only) — the error
// shows and the server suggest route is never called.
await expect(
sheet.getByText("Local OCR reads images only — not this file."),
sheet.getByText("Local OCR reads images only, not this file."),
).toBeVisible();
await page.waitForTimeout(300);
expect(suggestCalls).toBe(0);
+1 -1
View File
@@ -767,7 +767,7 @@ test.describe("document vault", () => {
await uploadViaPicker(page, `${marker}-copy.pdf`, bytes);
await expect(
page.getByText("Already stored — highlighting the existing document."),
page.getByText("Already stored. The existing document is highlighted."),
).toBeVisible();
// One row, not two — the copy never landed.
await expect(openButton(page, `${marker}-copy.pdf`)).not.toBeVisible();