From 2369e19b8c7dd96b42990e3370278445f8303fe2 Mon Sep 17 00:00:00 2001 From: Luke Stebner Date: Thu, 9 Jul 2026 20:08:24 -0700 Subject: [PATCH] fix: self-host Inter font, document unfixed WebKitGTK bold-text bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bundles Inter (300/400/500/600/700) via @fontsource/inter so typography renders as intended on any Linux install instead of silently falling back to whatever generic sans-serif fontconfig resolves (Noto Sans here, which has no Light face and doesn't match the font stack's original intent). Investigated as a fix for track-list/album-grid text rendering bold once a virtualized list actually overflows and scrolls (a WebKitGTK composited-scroll-layer text rendering bug), but font substitution alone doesn't address the underlying compositing behavior. Several other mitigations (will-change layer promotion, transform-vs-top row positioning, compensating font-weight) were tried and ruled out — see the new CLAUDE.md note under Frontend layout for what was tried and why, so this isn't re-investigated from scratch later. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 2 ++ package-lock.json | 10 ++++++++++ package.json | 1 + src/routes/+layout.svelte | 5 +++++ 4 files changed, 18 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 80923e8..92b4c6e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -100,6 +100,8 @@ Any "fill the parent" layout relationship in this codebase uses `position: absol A Svelte 5 `$effect` that both reactively reads a store (via `$store` auto-subscription) *and* calls a method on that same store that causes it to re-emit will infinite-loop. Where this is needed (e.g. `@tanstack/svelte-virtual`'s `setOptions`), read the store value with `get(store)` from `svelte/store` (a one-time, non-reactive read) instead of `$store`. +**Known, unfixed issue:** once a virtualized list's scroll container (`TrackTable`'s `.track-scroll`, `AlbumGrid`'s `.grid-scroll`) actually overflows and becomes scrollable, WebKitGTK promotes it to a GPU-composited layer, and text inside renders noticeably heavier/bolder there than identical text outside a composited layer — confirmed by setting `WEBKIT_DISABLE_COMPOSITING_MODE=1`, which fixes the weight but costs enough performance elsewhere (opacity transitions, general responsiveness) to not be worth it. Investigated and ruled out: `will-change` layer pre-promotion on rows (helps a *transient* hover-flash version of this bug, used in `AlbumGrid`'s `.hide-toggle`, but not this persistent one), swapping virtualizer row positioning from `transform: translateY()` to `top` (the parent's composited-scroll state turned out to be the trigger, not the children's transforms), and compensating with a lighter `font-weight` while overflowing (technically works but reads as visibly wrong — an abrupt weight jump right at the overflow boundary, not a subtle fix). No finer-grained WebKit setting is exposed at the currently-pinned `tauri` 2.11.3 / `wry` 0.55.1 versions to disable composited scrolling specifically while leaving other GPU compositing on. Not chasing a hand-rolled non-native-scroll replacement for this — the accessibility/robustness cost isn't worth it for a cosmetic bug. Revisit if a future wry/webkit2gtk version exposes more granular control. + ### Icons `@lucide/svelte` (the actively maintained package — not the deprecated `lucide-svelte`). diff --git a/package-lock.json b/package-lock.json index 38ea5e8..0457869 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.5.0", "license": "MIT", "dependencies": { + "@fontsource/inter": "^5.2.8", "@lucide/svelte": "^1.21.0", "@tanstack/svelte-virtual": "^3.13.29", "@tauri-apps/api": "^2", @@ -469,6 +470,15 @@ "node": ">=18" } }, + "node_modules/@fontsource/inter": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz", + "integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", diff --git a/package.json b/package.json index 662b5bc..170d9bf 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "license": "MIT", "dependencies": { + "@fontsource/inter": "^5.2.8", "@lucide/svelte": "^1.21.0", "@tanstack/svelte-virtual": "^3.13.29", "@tauri-apps/api": "^2", diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index c7f44c0..27b08cd 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,4 +1,9 @@