Skip to content

fix(frontend): apply Geist to body text - #170

Merged
Valtora merged 1 commit into
mainfrom
fix/apply-geist-sans-body-font
Jul 29, 2026
Merged

fix(frontend): apply Geist to body text#170
Valtora merged 1 commit into
mainfrom
fix/apply-geist-sans-body-font

Conversation

@Valtora

@Valtora Valtora commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Pull Request

Description

Geist and Geist Mono are loaded in layout.tsx via next/font/google, their variables are applied to <body>, and @theme inline maps them to Tailwind's --font-sans and --font-mono. The wiring is complete. But globals.css still carried the create-next-app default:

body { font-family: Arial, Helvetica, sans-serif; }

That override won everywhere, so Geist Sans reached only elements naming font-sans explicitly — exactly one in the entire application. Geist Sans was therefore downloaded on every page load and applied to almost nothing, while the interface rendered in Arial.

Geist Mono was never affected: its twenty call sites all use the font-mono utility, so it has been working as intended throughout.

The fix sets the body font to the variable, making the loaded font the inherited default, which is what the existing wiring already assumed.

On the fallback chain

--font-geist-sans does not resolve to a bare Geist. It resolves to Geist, Geist Fallback, and Next generates that fallback as:

@font-face{font-family:Geist Fallback;src:local(Arial);
  ascent-override:95.94%;descent-override:28.16%;
  line-gap-override:0.0%;size-adjust:104.76%}

That is Arial metrically adjusted to Geist, so it — not the trailing generics — is what covers the window before the webfont resolves, and it is why the swap should not visibly reflow the page.

Worth noting for review, because it is easy to get backwards: var() with no default invalidates the whole declaration when the variable is missing, rather than falling through to the next family in the list. A trailing Arial would not have protected against an absent font class. The default is therefore written inside var(), where it actually takes effect.

No new dependencies.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that changes existing behaviour)
  • Documentation update

Non-breaking in the code sense, but it changes the typeface of every page, so it is a visible change rather than an invisible one.

Checks run

  • Backend tests — not applicable, no backend files touched
  • Python quality — not applicable
  • Frontend lint: cd frontend && npm run lint — clean
  • Frontend unit tests: cd frontend && npm run test — 335 passed in 52 files
  • Frontend build: cd frontend && npm run build — succeeded
  • Docs validation: python3 scripts/validate_docs.py — 20 files, no broken links
  • Alembic validation — not applicable, no migrations touched

Verified in the compiled output

The change was confirmed in the built CSS rather than assumed from the source:

body{...font-family:var(--font-geist-sans,Arial), Helvetica, sans-serif}
--font-geist-sans:"Geist", "Geist Fallback"

Both halves are present, so the variable resolves and the rule applies.

Also checked: nothing draws text to a canvas (ctx.font / fillText / measureText have no hits under frontend/src), and after this change no other Arial or Helvetica reference remains in the frontend, so nothing else depended on the old metrics. PDF and DOCX export render server-side and are untouched.

Migration impact

  • No database migration in this PR.

Documentation impact

  • No documentation change required.
  • Updated the relevant guide(s) in the same PR.

docs/DESIGN.md documented the previous behaviour, having been written from the code last week. Its typography section is corrected here, including the account of which part of the stack covers the font-load window.

Security impact

  • No security-sensitive change.

Manual verification

Visual confirmation is outstanding, which is why this is a draft. No browser or headless tooling is available in this environment, so I verified the mechanism — the compiled rule, the variable's value, and the generated fallback's metric overrides — but I have not looked at a rendered page. Since this changes the typeface of every screen, someone should look before it merges.

Suggested pass, once running:

  • Dashboard, recordings workspace, and a transcript view render in Geist rather than Arial.
  • Monospace areas are unchanged, since font-mono was already resolving to Geist Mono.
  • No obvious reflow or clipping in dense UI: the sidebar, settings tabs, and the compact density mode (data-ui-density="compact") are the places where a metric change would show first.
  • Both light and dark themes, as the change is theme-independent but the check is cheap.

Mark ready for review once that looks right; there is nothing else pending.

Geist and Geist Mono are loaded in layout.tsx and their variables are
mapped to Tailwind's font-sans and font-mono, but globals.css still
carried the create-next-app default of `body { font-family: Arial,
Helvetica, sans-serif; }`. That override won everywhere, so Geist Sans
reached only elements that named `font-sans` explicitly, of which there
is exactly one in the whole application.

The result was that Geist Sans was downloaded on every page load and then
applied to almost nothing, while the interface rendered in Arial. Geist
Mono was unaffected, since its twenty call sites all use `font-mono`.

Setting the body font to the variable makes the loaded font the inherited
default, which is what the existing wiring already assumed. The variable
resolves to `Geist, Geist Fallback`, and that fallback is Arial with
size-adjust and metric overrides generated by Next, so the swap when the
webfont lands does not reflow the page. The `var()` default and the
trailing generics only apply if the font class is ever absent from body.

docs/DESIGN.md is updated in the same commit, since it documented the
previous behaviour.
@Valtora
Valtora marked this pull request as ready for review July 29, 2026 23:40
@Valtora
Valtora merged commit 4c6b188 into main Jul 29, 2026
19 of 20 checks passed
@Valtora
Valtora deleted the fix/apply-geist-sans-body-font branch July 29, 2026 23:40
Valtora added a commit that referenced this pull request Jul 30, 2026
Bump docs/VERSION to 2.2.0 so the tag validates, and fill in the
release-notes template for this range instead of hand-editing the
published body afterwards, which is how v2.1.0 was done.

A minor bump rather than a patch: #168 adds a capture action that did
not exist before, stopping and processing a paused recording.

Refs: #162, #163, #165, #167, #168, #169, #170, #171
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant