UI: Google Sans default + configurable fonts in Settings → Appearance #234

Closed
opened 2026-09-27 12:36:52 +00:00 by kayg · 12 comments
Owner

Owner request (2026-09-27): make Google Sans the default UI font. Keep a characterful display face for headings and numbers (today Fraunces), but the owner wants a different font that stands out the same way. Fonts must be configurable in Settings → Appearance.

Decided

  • Default UI font: Google Sans (replaces Inter as default). Verify the license (must be OFL or another AGPL-compatible licence) and the exact family on Google Fonts (Google Sans / Google Sans Flex / Google Sans Code) before bundling; record it in apps/web/static/fonts/README.md with the OFL text file, like the existing fonts.
  • Self-host all fonts as woff2 subsets (latin, and latin-ext where cheap), variable where available. Never load from fonts.googleapis.com (privacy + CSP). Keep font-display and the metric-override fallbacks consistent with the existing tokens.css approach (see the Fraunces ascent/descent notes there); no layout shift on load.
  • Settings → Appearance gets a Fonts group with three choices: UI font, display font (headings + big numbers), mono font. Each is a dropdown that previews each option in its own face. Stored in per-user settings (<home>/.calternal/settings.json, same path as the other appearance prefs), applied via the --font-ui / --font-display / --font-mono tokens, deep-linkable settings section per DESIGN §33.
  • Options — UI: Google Sans (default), Inter, System. Display: Fraunces (default until the owner picks), plus 4 candidates that "stand out the same way" (expressive, variable, OFL, good tabular/lining figures for big numbers): e.g. Instrument Serif, Newsreader, Young Serif, Bricolage Grotesque, Gloock — pick the 4 best after checking figures and weights. Mono: Spline Sans Mono (default), JetBrains Mono, System.
  • Fonts not in use are not downloaded (only the selected faces load).
  • Performance: measure the added bytes per default page load and the first-load cost; stay within the current font budget or report the delta.
  • Screenshots (production build, desktop + phone, light + dark): Home, a Note with headings, Calendar month (big numbers), Settings → Appearance Fonts with each display candidate. Attach them; the orchestrator reviews and sends them to the owner to choose the display default.
Owner request (2026-09-27): make **Google Sans** the default UI font. Keep a characterful display face for headings and numbers (today Fraunces), but the owner wants a *different* font that stands out the same way. Fonts must be configurable in **Settings → Appearance**. ## Decided - Default UI font: Google Sans (replaces Inter as default). Verify the license (must be OFL or another AGPL-compatible licence) and the exact family on Google Fonts (Google Sans / Google Sans Flex / Google Sans Code) before bundling; record it in `apps/web/static/fonts/README.md` with the OFL text file, like the existing fonts. - Self-host all fonts as woff2 subsets (latin, and latin-ext where cheap), variable where available. Never load from fonts.googleapis.com (privacy + CSP). Keep `font-display` and the metric-override fallbacks consistent with the existing `tokens.css` approach (see the Fraunces ascent/descent notes there); no layout shift on load. - Settings → Appearance gets a **Fonts** group with three choices: UI font, display font (headings + big numbers), mono font. Each is a dropdown that previews each option in its own face. Stored in per-user settings (`<home>/.calternal/settings.json`, same path as the other appearance prefs), applied via the `--font-ui` / `--font-display` / `--font-mono` tokens, deep-linkable settings section per DESIGN §33. - Options — UI: Google Sans (default), Inter, System. Display: Fraunces (default until the owner picks), plus 4 candidates that "stand out the same way" (expressive, variable, OFL, good tabular/lining figures for big numbers): e.g. Instrument Serif, Newsreader, Young Serif, Bricolage Grotesque, Gloock — pick the 4 best after checking figures and weights. Mono: Spline Sans Mono (default), JetBrains Mono, System. - Fonts not in use are not downloaded (only the selected faces load). - Performance: measure the added bytes per default page load and the first-load cost; stay within the current font budget or report the delta. - Screenshots (production build, desktop + phone, light + dark): Home, a Note with headings, Calendar month (big numbers), Settings → Appearance Fonts with each display candidate. Attach them; the orchestrator reviews and sends them to the owner to choose the display default.
Author
Owner

Started fonts work on branch job/fonts, based on dev at f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0. I am checking the existing font licensing and appearance settings implementation before making the first atomic change.

Started fonts work on branch `job/fonts`, based on `dev` at `f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0`. I am checking the existing font licensing and appearance settings implementation before making the first atomic change.
Author
Owner

Finding: the existing /api/v1/appearance route currently stores only background in the User's .calternal/settings.json; the UI preloads Inter unconditionally. The Google Sans Flex upstream repository provides an OFL 1.1 license, and the Google Fonts CSS API returned variable WOFF2 files for both Latin and Latin Extended. I am using those local assets and extending the existing appearance document with an independently mergeable fonts field.

Finding: the existing `/api/v1/appearance` route currently stores only `background` in the User's `.calternal/settings.json`; the UI preloads Inter unconditionally. The Google Sans Flex upstream repository provides an OFL 1.1 license, and the Google Fonts CSS API returned variable WOFF2 files for both Latin and Latin Extended. I am using those local assets and extending the existing appearance document with an independently mergeable `fonts` field.
Author
Owner

Started work on job/fonts from dev at base SHA f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0. The worktree contains an uncommitted change in crates/calternal-server/src/appearance.rs; I am retaining it and checking it against the owner decisions for #234.

Started work on `job/fonts` from `dev` at base SHA `f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0`. The worktree contains an uncommitted change in `crates/calternal-server/src/appearance.rs`; I am retaining it and checking it against the owner decisions for #234.
Author
Owner

Owner decision (2026-09-27): default display font = Bricolage Grotesque (headings H1–H6 + big numbers). Newsreader is the owner's second favourite. Fraunces stays selectable. Record the choice in docs/DESIGN.md (ASD-STE100).

Owner decision (2026-09-27): default display font = **Bricolage Grotesque** (headings H1–H6 + big numbers). Newsreader is the owner's second favourite. Fraunces stays selectable. Record the choice in docs/DESIGN.md (ASD-STE100).
Author
Owner

Continuing #234 on job/fonts, based on dev at f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0. I reviewed the issue comments and the existing uncommitted appearance API work. I will preserve it, align the stored options with the owner’s current font choices, and finish the UI, licensed font assets, headings, docs and screenshot captures.

Continuing #234 on `job/fonts`, based on `dev` at `f1c0766907d5d1a0a3a7ea0ae807e43dd2caf9f0`. I reviewed the issue comments and the existing uncommitted appearance API work. I will preserve it, align the stored options with the owner’s current font choices, and finish the UI, licensed font assets, headings, docs and screenshot captures.
Author
Owner

Evidence during production review: the shared UI token sheet can load before app font preferences apply, so its initial token value could request Inter even when the User chose Google Sans. I changed the shared tokens to local system stacks until the app preference rules take over. The real production review then captured all 21 requested screenshots and passed the network assertion: only Google Sans, Bricolage Grotesque, Spline Sans Mono, and the selected Newsreader comparison face were requested. The runner also verified that H1–H6 render in the Note. I added this request assertion to apps/web/e2e/fonts-review.mjs.

Evidence during production review: the shared UI token sheet can load before app font preferences apply, so its initial token value could request Inter even when the User chose Google Sans. I changed the shared tokens to local system stacks until the app preference rules take over. The real production review then captured all 21 requested screenshots and passed the network assertion: only Google Sans, Bricolage Grotesque, Spline Sans Mono, and the selected Newsreader comparison face were requested. The runner also verified that H1–H6 render in the Note. I added this request assertion to `apps/web/e2e/fonts-review.mjs`.
Author
Owner

Forgejo #234 final report

Built per-User interface, display, and monospace font preferences; self-hosted variable WOFF2 assets; live font previews in Settings → Appearance → Fonts; and matching display-face typography for all six heading levels and large numeric readouts. The User's selected faces load without external font requests or layout shift. Bricolage Grotesque's lining figures are the default and its tnum feature is available for aligned numbers. The font inventory lists exact family names, internal versions, Google Fonts revisions, and the local SIL OFL 1.1 license files in apps/web/static/fonts/README.md. Google Sans is the exact family from the official Google Sans project; Bricolage Grotesque features are documented by its upstream project.

Files

  • API and persistence: crates/calternal-server/src/appearance.rs, contracts/openapi.json, packages/api-client/src/generated.ts.
  • Preferences, caching and Settings controls: apps/web/src/lib/fonts.ts, apps/web/src/lib/appearance/background.svelte.ts, apps/web/src/routes/settings/appearance/AppearanceSection.svelte, apps/web/src/routes/settings/appearance/FontsGroup.svelte, apps/web/src/app.html.
  • Font roles and typography: apps/web/src/calternal-app.css, packages/ui/src/tokens.css, apps/web/src/lib/notes/NoteEditorSurface.svelte, apps/web/src/lib/notes/NoteView.svelte, analytics and service headings, packages/editor/src/extensions.ts.
  • Licenses and font files: apps/web/static/fonts/.
  • Decision record: docs/DESIGN.md §44.
  • Real-production screenshot runner and 21 captures: apps/web/e2e/fonts-review.mjs, apps/web/e2e/harness.mjs, artifacts/fonts-review/.
  • API adversarial checks: tests/adversarial/attack.py.

Screenshots

All captures use a real production build and API-backed data. They cover Home, a Note with H1–H6 and a table, Calendar month, Analytics, and Fonts settings in light/dark at desktop 1440 and phone 390; the 21st image compares the same Note in Bricolage Grotesque and Newsreader.

Final gates

cargo fmt --check — exit 0; stdout and stderr were empty.

cargo clippy --all-targets -- -D warnings — exit 0. Verbatim final output:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 8m 05s

cargo test — exit 0. The feature tests passed:

test appearance::tests::font_preferences_persist_and_merge_with_background_updates ... ok
test appearance::tests::concurrent_puts_preserve_other_settings ... ok
test result: ok. 43 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 6.46s

Verbatim final workspace test output:

   Doc-tests calternal_tags

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

bun run check — exit 0:

svelte-check found 0 errors and 0 warnings

bun run test — exit 0:

 Test Files  81 passed (81)
      Tests  588 passed (588)
   Start at  17:52:01
   Duration  128.22s (transform 68%, import 13%, environment 11%, tests 7%, setup 2%)

Adversarial round and known gaps

The post-merge real-server round passed the 916-operation authorization matrix, editor stress probes, malformed font-value checks, mixed concurrent font/background writes, hostile-byte checks, CLI and sync probes, and final restart probe. The server remained alive. The runner returned exit 1 because it counts SLOW load findings as failures: appearance PUT p95 was 0.871 s against a 0.500 s target; Calendar Event-from-Log took 6.7 s; Round 2 had 26 SLOW findings, with no non-SLOW finding.

The production build succeeded. Vite still reports existing MODULE_LEVEL_DIRECTIVE warnings for vendored Bklit chart modules; these did not stop the build. Cargo build output was cleaned (Removed 17447 files, 15.5GiB total), and apps/web/build plus apps/web/.svelte-kit were removed.

Decisions

The owner-selected defaults and heading rule are recorded in Design §44: Google Sans for UI, Bricolage Grotesque for every H1–H6 and large number, and Spline Sans Mono for monospace. The seven display alternatives, Inter and System UI options, JetBrains Mono and System mono options, variable axis behavior, tabular figure support, per-User storage, local cache, and adjusted fallback metrics are also recorded there. I made no additional product-design choice beyond that owner direction.

Head: ffcc5d2a117ebafd4d32df9968230b3803f25a32 (job/fonts). dev is merged. git push origin job/fonts completed with Everything up-to-date.

## Forgejo #234 final report Built per-User interface, display, and monospace font preferences; self-hosted variable WOFF2 assets; live font previews in Settings → Appearance → Fonts; and matching display-face typography for all six heading levels and large numeric readouts. The User's selected faces load without external font requests or layout shift. Bricolage Grotesque's lining figures are the default and its `tnum` feature is available for aligned numbers. The font inventory lists exact family names, internal versions, Google Fonts revisions, and the local SIL OFL 1.1 license files in `apps/web/static/fonts/README.md`. Google Sans is the exact family from the [official Google Sans project](https://github.com/googlefonts/googlesans); Bricolage Grotesque features are documented by its [upstream project](https://github.com/ateliertriay/bricolage). ### Files - API and persistence: `crates/calternal-server/src/appearance.rs`, `contracts/openapi.json`, `packages/api-client/src/generated.ts`. - Preferences, caching and Settings controls: `apps/web/src/lib/fonts.ts`, `apps/web/src/lib/appearance/background.svelte.ts`, `apps/web/src/routes/settings/appearance/AppearanceSection.svelte`, `apps/web/src/routes/settings/appearance/FontsGroup.svelte`, `apps/web/src/app.html`. - Font roles and typography: `apps/web/src/calternal-app.css`, `packages/ui/src/tokens.css`, `apps/web/src/lib/notes/NoteEditorSurface.svelte`, `apps/web/src/lib/notes/NoteView.svelte`, analytics and service headings, `packages/editor/src/extensions.ts`. - Licenses and font files: `apps/web/static/fonts/`. - Decision record: `docs/DESIGN.md` §44. - Real-production screenshot runner and 21 captures: `apps/web/e2e/fonts-review.mjs`, `apps/web/e2e/harness.mjs`, `artifacts/fonts-review/`. - API adversarial checks: `tests/adversarial/attack.py`. ### Screenshots All captures use a real production build and API-backed data. They cover Home, a Note with H1–H6 and a table, Calendar month, Analytics, and Fonts settings in light/dark at desktop 1440 and phone 390; the 21st image compares the same Note in Bricolage Grotesque and Newsreader. ### Final gates `cargo fmt --check` — exit 0; stdout and stderr were empty. `cargo clippy --all-targets -- -D warnings` — exit 0. Verbatim final output: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 8m 05s ``` `cargo test` — exit 0. The feature tests passed: ``` test appearance::tests::font_preferences_persist_and_merge_with_background_updates ... ok test appearance::tests::concurrent_puts_preserve_other_settings ... ok test result: ok. 43 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 6.46s ``` Verbatim final workspace test output: ``` Doc-tests calternal_tags running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `bun run check` — exit 0: ``` svelte-check found 0 errors and 0 warnings ``` `bun run test` — exit 0: ``` Test Files 81 passed (81) Tests 588 passed (588) Start at 17:52:01 Duration 128.22s (transform 68%, import 13%, environment 11%, tests 7%, setup 2%) ``` ### Adversarial round and known gaps The post-merge real-server round passed the 916-operation authorization matrix, editor stress probes, malformed font-value checks, mixed concurrent font/background writes, hostile-byte checks, CLI and sync probes, and final restart probe. The server remained alive. The runner returned exit 1 because it counts `SLOW` load findings as failures: appearance PUT p95 was 0.871 s against a 0.500 s target; Calendar Event-from-Log took 6.7 s; Round 2 had 26 `SLOW` findings, with no non-`SLOW` finding. The production build succeeded. Vite still reports existing `MODULE_LEVEL_DIRECTIVE` warnings for vendored Bklit chart modules; these did not stop the build. Cargo build output was cleaned (`Removed 17447 files, 15.5GiB total`), and `apps/web/build` plus `apps/web/.svelte-kit` were removed. ### Decisions The owner-selected defaults and heading rule are recorded in Design §44: Google Sans for UI, Bricolage Grotesque for every H1–H6 and large number, and Spline Sans Mono for monospace. The seven display alternatives, Inter and System UI options, JetBrains Mono and System mono options, variable axis behavior, tabular figure support, per-User storage, local cache, and adjusted fallback metrics are also recorded there. I made no additional product-design choice beyond that owner direction. Head: `ffcc5d2a117ebafd4d32df9968230b3803f25a32` (`job/fonts`). `dev` is merged. `git push origin job/fonts` completed with `Everything up-to-date`.
Author
Owner

Continuing issue #234 on branch job/fonts, starting at head ffcc5d2a117ebafd4d32df9968230b3803f25a32, based on dev at 235073a6318b9a0b96818ab7f0f1b595e9555744. Investigating the font picker and narrow time labels before making focused fixes. The Browser plugin is not available in this session; I will use the repository's Playwright workflow for the production-build screenshots if configured.

Continuing issue #234 on branch `job/fonts`, starting at head `ffcc5d2a117ebafd4d32df9968230b3803f25a32`, based on `dev` at `235073a6318b9a0b96818ab7f0f1b595e9555744`. Investigating the font picker and narrow time labels before making focused fixes. The Browser plugin is not available in this session; I will use the repository's Playwright workflow for the production-build screenshots if configured.
Author
Owner

Finding: FontsGroup.svelte used native <select> controls, while the Light and Dark pickers use the shared Pill + Menu. The new component test reproduced the old control (expected ... <select> ... to be null) and now passes for all three roles. Each option label uses its hosted font stack in the open menu; the separate brown-fox lines are removed because the in-menu labels provide the preview. The old Agenda time track is fixed at 44 px on phones while formatClockTime emits labels such as 10:15 AM; I added the requested 390 px / 12-hour / 24-hour layout check and will run it against the production build before adjusting the track.

Finding: `FontsGroup.svelte` used native `<select>` controls, while the Light and Dark pickers use the shared `Pill` + `Menu`. The new component test reproduced the old control (`expected ... <select> ... to be null`) and now passes for all three roles. Each option label uses its hosted font stack in the open menu; the separate brown-fox lines are removed because the in-menu labels provide the preview. The old Agenda time track is fixed at 44 px on phones while `formatClockTime` emits labels such as `10:15 AM`; I added the requested 390 px / 12-hour / 24-hour layout check and will run it against the production build before adjusting the track.
Author
Owner

Finding: the production build's focused real-server layout sweep reproduced the 12-hour phone regression. bun apps/web/e2e/layout-sweep.mjs --only agenda-times reported: FAIL Agenda 390px 12_hour: wrapped time labels [{"text":"8:30 AM","lines":2},{"text":"9:15 AM","lines":2},{"text":"10:00 AM","lines":2},{"text":"12:00 PM","lines":2}]. The same 24-hour pass did not report wrapping. Agenda's phone CSS fixed the time track at 2.75rem (44 px). I am changing the track to follow its widest formatted label and keeping each label on one line.

Finding: the production build's focused real-server layout sweep reproduced the 12-hour phone regression. `bun apps/web/e2e/layout-sweep.mjs --only agenda-times` reported: `FAIL Agenda 390px 12_hour: wrapped time labels [{"text":"8:30 AM","lines":2},{"text":"9:15 AM","lines":2},{"text":"10:00 AM","lines":2},{"text":"12:00 PM","lines":2}]`. The same 24-hour pass did not report wrapping. Agenda's phone CSS fixed the time track at `2.75rem` (44 px). I am changing the track to follow its widest formatted label and keeping each label on one line.
Author
Owner

Implemented and pushed job/fonts at ac94121594105c1090e4cc3f787064773c0d590b (merge commit includes dev). Push completed with Everything up-to-date.

Changes

  • Replaced the Fonts group's native selects with the shared pill/menu controls. Menu labels preview their own font face; non-selected faces load only while the menu is open. Removed the clipped fox sample because the menu previews make it redundant.
  • Kept Agenda start/end times on one line at phone widths using a content-sized time column and non-wrapping labels. Added a 390 px layout sweep for 12 h and 24 h settings.
  • Kept the dev layout sweep probes during merge conflict resolution. Removed tracked review PNGs from the repository and retained the root artifacts/ ignore rule.

Files: apps/web/src/routes/settings/appearance/FontsGroup.svelte, apps/web/src/lib/fonts.ts, apps/web/src/lib/fontsGroup.svelte.test.ts, packages/ui/src/components/menu/MenuItem.svelte, packages/ui/src/components/menu/types.ts, packages/ui/src/components/calendar/AgendaList.svelte, apps/web/e2e/fonts-review.mjs, apps/web/e2e/layout-sweep.mjs, .gitignore, and removal of inherited tracked PNGs under artifacts/fonts-review/.

Review captures

Gates

All final gates ran after merging dev.

  • cargo fmt --check: exit 0; no stdout.
  • cargo clippy --all-targets -- -D warnings: exit 0. Output: Finished \dev` profile [unoptimized + debuginfo] target(s) in 15m 42s`
  • cargo test: exit 0. Output: Finished \test` profile [unoptimized + debuginfo] target(s) in 6m 50s`. Across 72 result lines: 1280 passed, 0 failed, 12 ignored, 0 measured, 0 filtered.
  • bun run check: exit 0. Output:
    $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
    Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/fonts/apps/web
    Getting Svelte diagnostics...
    
    svelte-check found 0 errors and 0 warnings
    
  • bun run test: exit 0. Output:
     Test Files  83 passed (83)
          Tests  593 passed (593)
       Start at  20:49:59
       Duration  113.59s (transform 63%, environment 14%, import 12%, tests 9%, setup 2%)
    
  • node apps/web/e2e/fonts-review.mjs: PASS Fonts review captures: 22 screenshots in /home/kayg/Developer/calternal-wt/fonts/artifacts/fonts-review
  • node apps/web/e2e/layout-sweep.mjs --only agenda-times: checked 0 screens / LAYOUT SWEEP PASSED (the focused agenda-times check ran; no standard screens were selected).
  • Production bun run build succeeded during the adversarial run. It emitted existing analytics vendor use client warnings.

Adversarial findings

The post-merge adversarial run found non-SLOW issues, which are filed or recorded on their existing issues:

  • #255: Concurrent upload/index mismatch under CPU saturation; disk bytes and index rows diverged.
  • #225: History storm reproduced duplicate block IDs after paste/IME and 500 undo/redo cycles.
  • #256: Planned restart caused 502s on file, notes, backlinks, and search reads; the edit marker persisted once.
  • #205: Analytics reads timed out under concurrent Journal writes; later consistency checks passed and the server stayed alive.
  • #223: Public Edit WebSocket accepted 301 empty binary frames without closing during the 10-second probe.

These findings concern existing backend/API behavior outside this font UI change. SLOW-only latency observations were treated as load per the owner rule. Vitest also printed existing CSS parse and unimplemented scrollTo() notices; all 593 tests passed.

Decisions

  • Used the shared menu's per-option font previews as the sample, so the separate fox preview was removed.
  • Sized the Agenda time column from its rendered label and disabled wrapping, so both date-format settings fit the visible time text.
Implemented and pushed `job/fonts` at `ac94121594105c1090e4cc3f787064773c0d590b` (merge commit includes `dev`). Push completed with `Everything up-to-date`. ## Changes - Replaced the Fonts group's native selects with the shared pill/menu controls. Menu labels preview their own font face; non-selected faces load only while the menu is open. Removed the clipped fox sample because the menu previews make it redundant. - Kept Agenda start/end times on one line at phone widths using a content-sized time column and non-wrapping labels. Added a 390 px layout sweep for 12 h and 24 h settings. - Kept the `dev` layout sweep probes during merge conflict resolution. Removed tracked review PNGs from the repository and retained the root `artifacts/` ignore rule. Files: `apps/web/src/routes/settings/appearance/FontsGroup.svelte`, `apps/web/src/lib/fonts.ts`, `apps/web/src/lib/fontsGroup.svelte.test.ts`, `packages/ui/src/components/menu/MenuItem.svelte`, `packages/ui/src/components/menu/types.ts`, `packages/ui/src/components/calendar/AgendaList.svelte`, `apps/web/e2e/fonts-review.mjs`, `apps/web/e2e/layout-sweep.mjs`, `.gitignore`, and removal of inherited tracked PNGs under `artifacts/fonts-review/`. ## Review captures - Display font menu: [fonts-options-display-light-1440.png](https://git.kayg.org/attachments/72f0c326-bd9d-4050-81b4-1cbb844aa41e) - Fonts settings: [fonts-settings-light-1440.png](https://git.kayg.org/attachments/78cc8ba2-5b43-497e-974a-35844971dc9e) - Phone Home: [home-light-390.png](https://git.kayg.org/attachments/ac9e8e82-88a3-46c0-8734-f788df85399d) ## Gates All final gates ran after merging `dev`. - `cargo fmt --check`: exit 0; no stdout. - `cargo clippy --all-targets -- -D warnings`: exit 0. Output: `Finished \`dev\` profile [unoptimized + debuginfo] target(s) in 15m 42s` - `cargo test`: exit 0. Output: `Finished \`test\` profile [unoptimized + debuginfo] target(s) in 6m 50s`. Across 72 result lines: 1280 passed, 0 failed, 12 ignored, 0 measured, 0 filtered. - `bun run check`: exit 0. Output: ``` $ svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/fonts/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` - `bun run test`: exit 0. Output: ``` Test Files 83 passed (83) Tests 593 passed (593) Start at 20:49:59 Duration 113.59s (transform 63%, environment 14%, import 12%, tests 9%, setup 2%) ``` - `node apps/web/e2e/fonts-review.mjs`: `PASS Fonts review captures: 22 screenshots in /home/kayg/Developer/calternal-wt/fonts/artifacts/fonts-review` - `node apps/web/e2e/layout-sweep.mjs --only agenda-times`: `checked 0 screens` / `LAYOUT SWEEP PASSED` (the focused `agenda-times` check ran; no standard screens were selected). - Production `bun run build` succeeded during the adversarial run. It emitted existing analytics vendor `use client` warnings. ## Adversarial findings The post-merge adversarial run found non-SLOW issues, which are filed or recorded on their existing issues: - #255: Concurrent upload/index mismatch under CPU saturation; disk bytes and index rows diverged. - #225: History storm reproduced duplicate block IDs after paste/IME and 500 undo/redo cycles. - #256: Planned restart caused 502s on file, notes, backlinks, and search reads; the edit marker persisted once. - #205: Analytics reads timed out under concurrent Journal writes; later consistency checks passed and the server stayed alive. - #223: Public Edit WebSocket accepted 301 empty binary frames without closing during the 10-second probe. These findings concern existing backend/API behavior outside this font UI change. SLOW-only latency observations were treated as load per the owner rule. Vitest also printed existing CSS parse and unimplemented `scrollTo()` notices; all 593 tests passed. ## Decisions - Used the shared menu's per-option font previews as the sample, so the separate fox preview was removed. - Sized the Agenda time column from its rendered label and disabled wrapping, so both date-format settings fit the visible time text.
Author
Owner

Merged in 3ad937ec (menu types conflict resolved keeping fontFamily + Lucide icon; svelte-check 0/0, web 604/604, generated client OK). Google Sans UI / Bricolage display defaults live after the next deploy; menu blur comes with #246.

Merged in 3ad937ec (menu types conflict resolved keeping fontFamily + Lucide icon; svelte-check 0/0, web 604/604, generated client OK). Google Sans UI / Bricolage display defaults live after the next deploy; menu blur comes with #246.
kayg referenced this issue from a commit 2026-09-27 19:08:04 +00:00
kayg closed this issue 2026-09-27 19:08:05 +00:00
Sign in to join this conversation.
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
kayg/calternal#234
No description provided.