---
title: Text Size (separate Desktop and Mobile text size)
---

# Text Size (separate Desktop and Mobile text size)

## What it is

**Text Size** controls how large all text (and the whole UI, which scales with
it) appears. There are **two independent settings**:

- **Desktop text size** — the size used on the desktop app. This is the
  long-standing "Font Size" setting; the keyboard shortcuts **Ctrl+=** (larger)
  and **Ctrl+-** (smaller) step it.
- **Mobile text size** — the size used when you open Omniscio on a **phone or a narrow
  touch screen**, kept completely separate from desktop.

Both offer the same seven steps, from **Extra Small** to **XXX-Large**. Desktop
defaults to **Medium**; mobile defaults to **Extra Large** — phones are easier to read
with bigger text out of the box.

Why two settings: your phone runs the same app as your desktop, and it used to
borrow whatever text size you'd set on the desktop. Now you can have, say, a
comfortable large size on your desktop monitor and a tighter size on your phone —
each remembers its own.

> One-time note: because mobile has its own size (default **Extra Large**), the first
> time you open Omniscio on your phone after this update it shows **Extra Large**, even if
> your desktop was set to a different size. Set "Mobile text size" once and it
> sticks.

## Where to find it

**Settings → Appearance** holds the **Desktop text size** and **Mobile text size** cards, which are the first two in that pane. Away from Settings, the desktop size is reachable from **Ctrl+=** / **Ctrl+-** and from Ctrl+scroll anywhere in the app, and on a phone the fastest route is the **▦ tools menu** in the bottom bar, whose **Text size** row carries **−** / **+** buttons.

## How it behaves

### How to use it

1. Open **Settings → Appearance**.
2. **Desktop text size** and **Mobile text size** are the first two cards.
3. Pick a size on either. The UI resizes instantly — no reload.

You can set the mobile size from your desktop (to pre-configure your phone) or
directly on the phone itself — Settings → Appearance works on both. On the
desktop you can also just press **Ctrl+=** / **Ctrl+-** — the shortcut always steps
whichever size matches the screen you're on.

**Or hold Ctrl and scroll the mouse wheel** — scroll up for larger, down for
smaller. It does the exact same thing as **Ctrl+=** / **Ctrl+-** (one size step per
notch), so if you're used to zooming a web page with Ctrl+scroll, it just works.
(This replaces the browser engine's own blurry page-zoom, which wasn't saved and
didn't match your Text size.) If you're scrolling over something that has its own
Ctrl+scroll zoom — like an image preview or the screen-recorder editor — that keeps
working; Text size only steps on the rest of the app.

**On a phone, the quickest way is the header menu** (no Settings trip needed): tap
the **▦ tools menu** in the bottom bar and use the **Text size** row's **−** / **+**
buttons. It steps the Mobile text size live, the menu stays open so you can keep
tapping, and the buttons grey out at the smallest / largest size.

## For agents

### How it works

Both sizes are settings on `AppSettings` — `fontSize` (desktop) and
`mobileFontSize` (mobile), each one of the seven `FONT_SIZES` tokens (`fontSize`
defaults to `medium`, `mobileFontSize` to `extra-large`), defined in
[/src/shared/font-size.ts](/src/shared/font-size.ts) and added to the Appearance
Zod schema (mirroring the existing `fontSize`).

The app picks which one is "live" through a single helper,
`resolveFontSize(fontSize, mobileFontSize, isMobile)` — on the mobile layout
(narrow + touch) it returns `mobileFontSize`, otherwise `fontSize`. The renderer
reads it through the `useEffectiveFontSize()` hook, which drives the
`data-font-size` attribute on `<html>` (the root `--app-font-size`, so every
rem-based element scales) **and** every place that measures against the font size
(the virtualized session lists, the KMS tags panel, the mind map). Using the one
helper everywhere is what keeps the rendered text and the layout math in step on a
phone — a list that measured the desktop size while rendering the mobile size
would overlap its rows.

Pop-out and other secondary windows (a project or integration opened in its own
window, the KMS window, Quick Launch, Scratchpad, …) each run their own minimal
copy of the app, so they adopt your **desktop** text size through the one shared
window bootstrap (`applyWindowTheme` in
[/src/renderer/src/lib/window-theme-bootstrap.ts](/src/renderer/src/lib/window-theme-bootstrap.ts))
— applied when the window opens and re-applied live when you change the size, the
same way those windows adopt your theme. They keep the **desktop** size (a phone
can't open a second window), and because it rides the shared bootstrap, a new
window can't silently forget it.

The phone receives its size in the initial `WEB_BOOTSTRAP` payload (so it paints
at the right size immediately), and any change you make on desktop reaches an open
phone live over the settings-changed push.

On the desktop main window, **Ctrl+MouseWheel** steps the same Text size. A small
hook (`useFontSizeWheelZoom`) watches for Ctrl+scroll, suppresses the browser
engine's native page zoom, and calls the _same_ stepper the keyboard uses
(`stepLiveFontSize`) — so the two can never drift. A little accumulator makes one
wheel notch equal one size step (and stops a trackpad or Mac pinch-zoom, which the
browser delivers as a burst of Ctrl+scroll events, from blowing through every size
at once), and it stands aside when you're scrolling over a surface that already has
its own Ctrl+scroll zoom (an image preview, the screen-recorder editor).

On mobile the ▦ header menu also carries a **Text size** A−/A+ stepper (the
no-keyboard equivalent of Ctrl+= / Ctrl+-): it writes `mobileFontSize` through the
same `stepFontSize` helper, and because the settings write is optimistic the whole
UI rescales the instant you tap.

The behavior and its invariants are locked by the contracts at
`/.claude/memory/contracts/mobile-font-size-contract.md` and
`/.claude/memory/contracts/mobile-header-menu-contract.md` (the header-menu Text
size stepper, `text-size-stepper-stays-open`), and tests `tests/unit/shared/font-size.test.ts`,
`tests/unit/hooks/useEffectiveFontSize.test.tsx`,
`tests/unit/hooks/useKeyboardShortcuts-mobile-fontSize.test.ts`, and
`tests/unit/components/MobileHeaderMenu.test.tsx`.

## Related

- [per-window-zoom.md](per-window-zoom.md) — Text size is **app-wide** and changes
  text everywhere; per-window zoom is **per pop-out window** and scales everything
  (text, icons, images) on that one window via CSS `zoom`, using the same
  75%–150% ladder.
- [chat-depth.md](chat-depth.md) — another Appearance dial (how three-dimensional
  the chat looks), in the same pane
- [keyboard-shortcuts.md](keyboard-shortcuts.md) — Ctrl+= / Ctrl+- and the full
  shortcut list
