[PR #7238] [CLOSED] [WIP] feat: Switch to Geist Variable for UI text and Geist Mono for numeric displays #41460

Closed
opened 2026-04-23 14:15:11 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/actualbudget/actual/pull/7238
Author: @ustunfatih
Created: 3/19/2026
Status: Closed

Base: masterHead: claude/brave-clarke


📝 Commits (2)

  • 0b67faf Switch font from Inter Variable to Geist Variable
  • 760b69a Add Geist Mono as the font for all numeric displays

📊 Changes

5 files changed (+19 additions, -9 deletions)

View changed files

📝 packages/component-library/src/styles.ts (+1 -0)
📝 packages/desktop-client/index.html (+2 -2)
📝 packages/desktop-client/package.json (+2 -1)
📝 packages/desktop-client/src/fonts.scss (+2 -2)
📝 yarn.lock (+12 -4)

📄 Description

Summary

Introduces the Geist font family (by Vercel) into the app:

  • Geist Variable replaces Inter Variable as the primary UI font for all text
  • Geist Mono is added as a dedicated monospace font exclusively for all financial and numeric values

Motivation

Geist Variable (UI font)

Geist is a modern, clean sans-serif designed for interfaces. It ships as a variable font (single file covers all weights 300–900), making it a drop-in replacement for Inter Variable with no additional overhead.

Geist Mono (numeric font)

Using a monospace font for numbers provides two key benefits:

  • Alignment — Fixed-width digits keep decimal points and currency amounts vertically aligned in tables and budget cells
  • Readability — Monospace numerals are easier to scan when comparing figures across rows

Implementation

Geist Variable

The global font-family is declared in index.html and the font files are loaded via fonts.scss. Replacing Inter requires updating both: the npm package, the SCSS import, and the two font-family declarations in index.html.

Geist Mono

All numeric displays share a single style object — styles.tnum in packages/component-library/src/styles.ts. This object is spread into every component that renders financial values. Adding fontFamily to this one object propagates the change to all 34 call sites automatically with no per-component changes needed.

Affected numeric display locations:

  • Transaction amounts (TransactionsTable, mobile TransactionListItem)
  • Budget cells (BudgetCell, BudgetTotal, BalanceCell, SpentCell)
  • Envelope and tracking budget components
  • Amount inputs (AmountInput, FinancialInput)
  • Schedule and import modal amounts

Changes

File Change
packages/desktop-client/package.json Replace @fontsource-variable/inter with @fontsource-variable/geist and add @fontsource/geist-mono
packages/desktop-client/src/fonts.scss Import Geist Variable and Geist Mono (keep Redacted Script for privacy filter)
packages/desktop-client/index.html Update global font-family from 'Inter Variable' to 'Geist Variable'
packages/component-library/src/styles.ts Add fontFamily: 'Geist Mono, monospace' to styles.tnum

The monospace fallback in the Geist Mono font stack ensures number column alignment is preserved even if the web font fails to load.

Test plan

  • All UI text (labels, headings, menus, navigation) renders in Geist Variable
  • Transaction amounts render in Geist Mono
  • Budget cell figures render in Geist Mono
  • Numbers remain correctly aligned in table columns
  • Privacy filter still uses Redacted Script
  • All 382 unit tests pass (yarn workspace @actual-app/web test)
  • TypeScript check passes (yarn workspace @actual-app/web typecheck)

🤖 Generated with Claude Code


Bundle Stats

Bundle Files count Total bundle size % Changed
desktop-client 26 11.99 MB → 11.99 MB (+37 B) +0.00%
loot-core 1 4.83 MB 0%
api 4 4.06 MB 0%
cli 1 7.88 MB 0%
View detailed bundle stats

desktop-client

Total

Files count Total bundle size % Changed
26 11.99 MB → 11.99 MB (+37 B) +0.00%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/component-library/src/styles.ts 📈 +42 B (+1.37%) 2.99 kB → 3.03 kB
package.json 📈 +37 B (+1.12%) 3.22 kB → 3.26 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger

Asset File Size % Changed
static/js/index.js 3.23 MB → 3.23 MB (+37 B) +0.00%

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
static/js/BackgroundImage.js 119.98 kB 0%
static/js/FormulaEditor.js 846.44 kB 0%
static/js/ReportRouter.js 1021.25 kB 0%
static/js/TransactionList.js 81.29 kB 0%
static/js/ca.js 185.62 kB 0%
static/js/da.js 104.66 kB 0%
static/js/de.js 177.63 kB 0%
static/js/en-GB.js 7.16 kB 0%
static/js/en.js 170.68 kB 0%
static/js/es.js 172.13 kB 0%
static/js/fr.js 177.63 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.46 kB 0%
static/js/it.js 168.97 kB 0%
static/js/narrow.js 354.12 kB 0%
static/js/nb-NO.js 154.72 kB 0%
static/js/nl.js 111.58 kB 0%
static/js/pl.js 88.34 kB 0%
static/js/pt-BR.js 180.55 kB 0%
static/js/resize-observer.js 18.03 kB 0%
static/js/th.js 179.94 kB 0%
static/js/theme.js 30.68 kB 0%
static/js/uk.js 213.14 kB 0%
static/js/useTransactionBatchActions.js 4.29 MB 0%
static/js/wide.js 418 B 0%
static/js/workbox-window.prod.es5.js 7.28 kB 0%

loot-core

Total

Files count Total bundle size % Changed
1 4.83 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.Dmj0rSrb.js 4.83 MB 0%

api

Total

Files count Total bundle size % Changed
4 4.06 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
index.js 3.84 MB 0%
from-Bl-Hslp4.js 167.73 kB 0%
multipart-parser-BnDysoMr.js 8.1 kB 0%
src-iMkUmuwR.js 43.64 kB 0%

cli

Total

Files count Total bundle size % Changed
1 7.88 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
cli.js 7.88 MB 0%

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/actualbudget/actual/pull/7238 **Author:** [@ustunfatih](https://github.com/ustunfatih) **Created:** 3/19/2026 **Status:** ❌ Closed **Base:** `master` ← **Head:** `claude/brave-clarke` --- ### 📝 Commits (2) - [`0b67faf`](https://github.com/actualbudget/actual/commit/0b67fafa645aaa7499669ea742c4f0db04902e35) Switch font from Inter Variable to Geist Variable - [`760b69a`](https://github.com/actualbudget/actual/commit/760b69a50155fb5dbbae2ec25b4561bf53cd3e18) Add Geist Mono as the font for all numeric displays ### 📊 Changes **5 files changed** (+19 additions, -9 deletions) <details> <summary>View changed files</summary> 📝 `packages/component-library/src/styles.ts` (+1 -0) 📝 `packages/desktop-client/index.html` (+2 -2) 📝 `packages/desktop-client/package.json` (+2 -1) 📝 `packages/desktop-client/src/fonts.scss` (+2 -2) 📝 `yarn.lock` (+12 -4) </details> ### 📄 Description ## Summary Introduces the [Geist font family](https://vercel.com/font) (by Vercel) into the app: - **Geist Variable** replaces Inter Variable as the primary UI font for all text - **Geist Mono** is added as a dedicated monospace font exclusively for all financial and numeric values ## Motivation ### Geist Variable (UI font) Geist is a modern, clean sans-serif designed for interfaces. It ships as a variable font (single file covers all weights 300–900), making it a drop-in replacement for Inter Variable with no additional overhead. ### Geist Mono (numeric font) Using a monospace font for numbers provides two key benefits: - **Alignment** — Fixed-width digits keep decimal points and currency amounts vertically aligned in tables and budget cells - **Readability** — Monospace numerals are easier to scan when comparing figures across rows ## Implementation ### Geist Variable The global `font-family` is declared in `index.html` and the font files are loaded via `fonts.scss`. Replacing Inter requires updating both: the npm package, the SCSS import, and the two `font-family` declarations in `index.html`. ### Geist Mono All numeric displays share a single style object — `styles.tnum` in `packages/component-library/src/styles.ts`. This object is spread into every component that renders financial values. Adding `fontFamily` to this one object propagates the change to all 34 call sites automatically with no per-component changes needed. Affected numeric display locations: - Transaction amounts (TransactionsTable, mobile TransactionListItem) - Budget cells (BudgetCell, BudgetTotal, BalanceCell, SpentCell) - Envelope and tracking budget components - Amount inputs (AmountInput, FinancialInput) - Schedule and import modal amounts ## Changes | File | Change | |---|---| | `packages/desktop-client/package.json` | Replace `@fontsource-variable/inter` with `@fontsource-variable/geist` and add `@fontsource/geist-mono` | | `packages/desktop-client/src/fonts.scss` | Import Geist Variable and Geist Mono (keep Redacted Script for privacy filter) | | `packages/desktop-client/index.html` | Update global `font-family` from `'Inter Variable'` to `'Geist Variable'` | | `packages/component-library/src/styles.ts` | Add `fontFamily: 'Geist Mono, monospace'` to `styles.tnum` | The `monospace` fallback in the Geist Mono font stack ensures number column alignment is preserved even if the web font fails to load. ## Test plan - [ ] All UI text (labels, headings, menus, navigation) renders in Geist Variable - [ ] Transaction amounts render in Geist Mono - [ ] Budget cell figures render in Geist Mono - [ ] Numbers remain correctly aligned in table columns - [ ] Privacy filter still uses Redacted Script - [ ] All 382 unit tests pass (`yarn workspace @actual-app/web test`) - [ ] TypeScript check passes (`yarn workspace @actual-app/web typecheck`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!--- actual-bot-sections ---> <hr /> <!--- bundlestats-action-comment key:combined start ---> ### Bundle Stats Bundle | Files count | Total bundle size | % Changed ------ | ----------- | ----------------- | --------- desktop-client | 26 | 11.99 MB → 11.99 MB (+37 B) | +0.00% loot-core | 1 | 4.83 MB | 0% api | 4 | 4.06 MB | 0% cli | 1 | 7.88 MB | 0% <details> <summary>View detailed bundle stats</summary> #### desktop-client **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 26 | 11.99 MB → 11.99 MB (+37 B) | +0.00% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `home/runner/work/actual/actual/packages/component-library/src/styles.ts` | 📈 +42 B (+1.37%) | 2.99 kB → 3.03 kB `package.json` | 📈 +37 B (+1.12%) | 3.22 kB → 3.26 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** Asset | File Size | % Changed ----- | --------- | --------- static/js/index.js | 3.23 MB → 3.23 MB (+37 B) | +0.00% **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- static/js/BackgroundImage.js | 119.98 kB | 0% static/js/FormulaEditor.js | 846.44 kB | 0% static/js/ReportRouter.js | 1021.25 kB | 0% static/js/TransactionList.js | 81.29 kB | 0% static/js/ca.js | 185.62 kB | 0% static/js/da.js | 104.66 kB | 0% static/js/de.js | 177.63 kB | 0% static/js/en-GB.js | 7.16 kB | 0% static/js/en.js | 170.68 kB | 0% static/js/es.js | 172.13 kB | 0% static/js/fr.js | 177.63 kB | 0% static/js/indexeddb-main-thread-worker-e59fee74.js | 13.46 kB | 0% static/js/it.js | 168.97 kB | 0% static/js/narrow.js | 354.12 kB | 0% static/js/nb-NO.js | 154.72 kB | 0% static/js/nl.js | 111.58 kB | 0% static/js/pl.js | 88.34 kB | 0% static/js/pt-BR.js | 180.55 kB | 0% static/js/resize-observer.js | 18.03 kB | 0% static/js/th.js | 179.94 kB | 0% static/js/theme.js | 30.68 kB | 0% static/js/uk.js | 213.14 kB | 0% static/js/useTransactionBatchActions.js | 4.29 MB | 0% static/js/wide.js | 418 B | 0% static/js/workbox-window.prod.es5.js | 7.28 kB | 0% </div> </details> --- #### loot-core **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 4.83 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- kcab.worker.Dmj0rSrb.js | 4.83 MB | 0% </div> </details> --- #### api **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 4 | 4.06 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- index.js | 3.84 MB | 0% from-Bl-Hslp4.js | 167.73 kB | 0% multipart-parser-BnDysoMr.js | 8.1 kB | 0% src-iMkUmuwR.js | 43.64 kB | 0% </div> </details> --- #### cli **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 7.88 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- cli.js | 7.88 MB | 0% </div> </details> </details> <!--- bundlestats-action-comment key:combined end ---> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-23 14:15:11 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#41460