UI size slider (50–150 %) in the Appearance mockup #283

Closed
opened 2026-11-01 08:37:33 +00:00 by kayg · 5 comments
Owner

Owner feedback on the mockups (kayg, 2026-11-01, relayed by the orchestrator, job J52):

"on desktop, can we increase the default text size / ui size? i feel like it is too small right now … have a slider in the mockup appearance section for me to test how it feels. it's a slider that goes from 50% to 150%."

Mockup: a "UI size" slider (50–150 %, step 5 %, live, remembered per browser) in Settings → Appearance. It scales the whole UI through rem-based tokens on the root font size (not CSS zoom), so layout and hit targets scale cleanly; default stays 100 % for now. Canvas chrome, sidebar and pills scale. The report says whether the terminal's font size follows or stays separate, and lists the components that do not scale cleanly. Related: TASTE "One type scale everywhere (D174)", "Platform-sized controls".

Owner feedback on the mockups (kayg, 2026-11-01, relayed by the orchestrator, job J52): > "on desktop, can we increase the default text size / ui size? i feel like it is too small right now … have a slider in the mockup appearance section for me to test how it feels. it's a slider that goes from 50% to 150%." Mockup: a "UI size" slider (50–150 %, step 5 %, live, remembered per browser) in Settings → Appearance. It scales the whole UI through rem-based tokens on the root font size (not CSS zoom), so layout and hit targets scale cleanly; default stays 100 % for now. Canvas chrome, sidebar and pills scale. The report says whether the terminal's font size follows or stays separate, and lists the components that do not scale cleanly. Related: TASTE "One type scale everywhere (D174)", "Platform-sized controls".
Author
Owner

J52: UI size slider (50–150 %) (branch mockups-2026-10-31, head 4c389a2f4; commits 86fca7d85, 68c07b527, 4c389a2f4). TASTE row on taste-2026-11-01 (2b3957574). Production build, Chromium 155 headless; 1440×900 DPR 2 and 393×852 DPR 3; videos of both. Not judged as final visuals.

Try it: http://10.69.69.117:47650/mockups.html → "UI size" → open Settings (sidebar footer gear) → Appearance → "UI size". Live while you drag, in 5 % steps, remembered in this browser, default 100 %. Keyboard: arrows, Home, End.

How it scales: the root font size (:root { font-size: calc(16px * var(--ui-scale, 1)) }) and rem lengths, not CSS zoom. A one-off codemod turned 1,842 lengths above 2 px into rem; kept in px: hairlines (≤ 2 px), pill radii, @media/@container conditions, the canvas dot grid. Three JS places that set a width from a constant now multiply by the scale: the sidebar, the widest width of anchored popovers/menus, the details popover. Appearance panes' grid column is now minmax(0, 1fr) so a window never pushes a section's edge out.

100 % is identical, measured: rects, font sizes, paddings, gaps, radii and margins of every chrome element on 21 screens (14 at 1440 px, 7 at 393 px) dumped before and after the rem conversion: 17,481 element pairs compared; the only differences are the machine-card dots meter's transform: scale() transition caught mid-flight.

Does the terminal's font follow? No. It is its own setting, measured in device pixels for the cell grid, and is not read from CSS. The slider's hint line says so.

Scale audit (element sizes at 100 % vs 150 % / 50 %, same 21 screens): 3,936 chrome elements measured at 150 %: 90.0 % scale by 1.5; at 50 %: 3,914 elements, 91.6 % scale by 0.5. No horizontal or vertical page overflow at either end. ui-size.spec.ts 6/6, sidebar-resize.spec.ts 8/8.

Components that do not scale cleanly (to decide):

  1. Windows keep their width (the Window Sizes setting, in JS from the viewport; strips and columns cl-cols, cl-col, cl-content, cl-world: the largest group of the 395 elements that do not scale at 150 %). At 150 % their content grows inside them: window title pills truncate ("Appearan…"), a row that cannot wrap is clipped or scrolls the pane sideways, the details popover (kept inside its window by rule) wraps its rows. Whether windows should grow with the UI size is a design question for you.
  2. The phone sidebar is the screen's width: at 150 % its rows truncate ("r…", "j…").
  3. Mesh graph SVG text (g > text) does not scale.
  4. The dev-only performance HUD (fixed px on purpose).
  5. The first-paint skeleton in index.html (#boot-shell, fixed px) and any length in JS from a constant not listed above (the dot grid, the window-resize minimums 300/160 px, the swipe layers' MIN_REVEAL 72 px).
  6. The dots meter in machine cards shrinks at 150 % because its card is a popover capped by the window.
    Attached: Appearance at 100 %, the sidebar at 50, 100 and 150 % on desktop, 50/100/150 on the phone (150 shown), and the videos (the slider stepped through the range).
**J52: UI size slider (50–150 %)** (branch `mockups-2026-10-31`, head `4c389a2f4`; commits `86fca7d85`, `68c07b527`, `4c389a2f4`). TASTE row on `taste-2026-11-01` (`2b3957574`). Production build, Chromium 155 headless; 1440×900 DPR 2 and 393×852 DPR 3; videos of both. Not judged as final visuals. **Try it:** http://10.69.69.117:47650/mockups.html → "UI size" → open Settings (sidebar footer gear) → Appearance → "UI size". Live while you drag, in 5 % steps, remembered in this browser, default 100 %. Keyboard: arrows, Home, End. **How it scales:** the root font size (`:root { font-size: calc(16px * var(--ui-scale, 1)) }`) and rem lengths, not CSS zoom. A one-off codemod turned 1,842 lengths above 2 px into rem; kept in px: hairlines (≤ 2 px), pill radii, @media/@container conditions, the canvas dot grid. Three JS places that set a width from a constant now multiply by the scale: the sidebar, the widest width of anchored popovers/menus, the details popover. Appearance panes' grid column is now `minmax(0, 1fr)` so a window never pushes a section's edge out. **100 % is identical, measured:** rects, font sizes, paddings, gaps, radii and margins of every chrome element on 21 screens (14 at 1440 px, 7 at 393 px) dumped before and after the rem conversion: 17,481 element pairs compared; the only differences are the machine-card dots meter's `transform: scale()` transition caught mid-flight. **Does the terminal's font follow? No.** It is its own setting, measured in device pixels for the cell grid, and is not read from CSS. The slider's hint line says so. **Scale audit** (element sizes at 100 % vs 150 % / 50 %, same 21 screens): 3,936 chrome elements measured at 150 %: 90.0 % scale by 1.5; at 50 %: 3,914 elements, 91.6 % scale by 0.5. No horizontal or vertical page overflow at either end. `ui-size.spec.ts` 6/6, `sidebar-resize.spec.ts` 8/8. **Components that do not scale cleanly (to decide):** 1. **Windows keep their width** (the Window Sizes setting, in JS from the viewport; strips and columns `cl-cols`, `cl-col`, `cl-content`, `cl-world`: the largest group of the 395 elements that do not scale at 150 %). At 150 % their content grows inside them: window title pills truncate ("Appearan…"), a row that cannot wrap is clipped or scrolls the pane sideways, the details popover (kept inside its window by rule) wraps its rows. Whether windows should grow with the UI size is a design question for you. 2. **The phone sidebar** is the screen's width: at 150 % its rows truncate ("r…", "j…"). 3. **Mesh graph SVG text** (`g > text`) does not scale. 4. **The dev-only performance HUD** (fixed px on purpose). 5. **The first-paint skeleton** in `index.html` (`#boot-shell`, fixed px) and any length in JS from a constant not listed above (the dot grid, the window-resize minimums 300/160 px, the swipe layers' MIN_REVEAL 72 px). 6. The dots meter in machine cards shrinks at 150 % because its card is a popover capped by the window. Attached: Appearance at 100 %, the sidebar at 50, 100 and 150 % on desktop, 50/100/150 on the phone (150 shown), and the videos (the slider stepped through the range).
Author
Owner

Finish: ui-size-283 (product branch, base origin/dev 7bf03044f), head 67dc5441e41156431299eba5a772c2275d246ffb

Commits: 7a4d14277 every length in rem (canvas geometry stays px, container queries in rem), 14299a4ec the slider (50-150 %), 78ee985dc 110 % is the new 100 % and default (desktop; touch keeps base 1), 67dc5441e windows grow with the UI size.

Evidence on production builds (dev-02-std):

  • Commit A (rem lengths only, factor 1) against dev: 9391 elements compared, 0 differ.
  • Default (110 %) against dev at 1440x900 and 1690x1000: 1365 of 1443 chrome elements (94.6 %) are exactly x1.1; the 78 others are the overview strips and the perf HUD. Newly truncated or clipped text: 0 of 9383 (1440) and 0 of 9392 (1690); no page overflow.
  • Phones: identical to dev (0 differ). If phones also took 1.1, 4 elements would newly truncate (sidebar section names, session sub-lines), so I recommend keeping touch at base 1.
  • Transfer budget, critical JS: gzip 306,467 / 327,680 (dev 306,029), brotli 255,415 / 273,408 (dev 255,047).
  • TS half of scripts/verify fast: 377 pass, 0 fail; tsc clean. Rust test row fails with 5 restart::tests::* that fail identically on pure origin/dev.
  • Browser sweep: 36 specs fail on dev and on this branch, same set; 0 new.
  • Not scaled by design: the terminal's own font size (separate setting), canvas geometry constants (gap, column padding, gutter) which JS layout mirrors. Windows do grow by the factor (default widths x factor, hand-resized widths keep proportions, #267 99 % ceiling holds).

New default, 1440x900

283-default-new-1440x900-canvas

Dev, same scene

283-default-dev-1440x900-canvas

Appearance: UI size slider

283-default-new-1440x900-appearance

Sidebar at the new default

283-default-new-1440x900-sidebar

Phone 393x852 (unchanged base)

283-default-new-393x852-canvas

50 %

283-size-50-1440x900-canvas

150 %

283-size-150-1440x900-canvas

150 % Appearance

283-size-150-1440x900-appearance

**Finish: `ui-size-283` (product branch, base origin/dev 7bf03044f), head `67dc5441e41156431299eba5a772c2275d246ffb`** Commits: `7a4d14277` every length in rem (canvas geometry stays px, container queries in rem), `14299a4ec` the slider (50-150 %), `78ee985dc` 110 % is the new 100 % and default (desktop; touch keeps base 1), `67dc5441e` windows grow with the UI size. Evidence on production builds (dev-02-std): - Commit A (rem lengths only, factor 1) against dev: 9391 elements compared, 0 differ. - Default (110 %) against dev at 1440x900 and 1690x1000: 1365 of 1443 chrome elements (94.6 %) are exactly x1.1; the 78 others are the overview strips and the perf HUD. Newly truncated or clipped text: 0 of 9383 (1440) and 0 of 9392 (1690); no page overflow. - Phones: identical to dev (0 differ). If phones also took 1.1, 4 elements would newly truncate (sidebar section names, session sub-lines), so I recommend keeping touch at base 1. - Transfer budget, critical JS: gzip 306,467 / 327,680 (dev 306,029), brotli 255,415 / 273,408 (dev 255,047). - TS half of `scripts/verify fast`: 377 pass, 0 fail; tsc clean. Rust `test` row fails with 5 `restart::tests::*` that fail identically on pure origin/dev. - Browser sweep: 36 specs fail on dev and on this branch, same set; 0 new. - Not scaled by design: the terminal's own font size (separate setting), canvas geometry constants (gap, column padding, gutter) which JS layout mirrors. Windows do grow by the factor (default widths x factor, hand-resized widths keep proportions, #267 99 % ceiling holds). **New default, 1440x900** ![283-default-new-1440x900-canvas](https://git.kayg.org/attachments/927a3b19-8d43-4f27-be99-4190cb0419cb) **Dev, same scene** ![283-default-dev-1440x900-canvas](https://git.kayg.org/attachments/8fd7bd41-6d39-4e73-9147-ba80caa7d0fe) **Appearance: UI size slider** ![283-default-new-1440x900-appearance](https://git.kayg.org/attachments/4ad4ccca-45e7-4759-a787-b05b0da61b61) **Sidebar at the new default** ![283-default-new-1440x900-sidebar](https://git.kayg.org/attachments/c19b6777-30ad-41ff-b373-09fd04f297dc) **Phone 393x852 (unchanged base)** ![283-default-new-393x852-canvas](https://git.kayg.org/attachments/44af4ef4-7163-4c7d-b540-c656fdc67f35) **50 %** ![283-size-50-1440x900-canvas](https://git.kayg.org/attachments/73fbb287-f2c9-4f6c-a339-7de129a5a3d4) **150 %** ![283-size-150-1440x900-canvas](https://git.kayg.org/attachments/e6b9e1f9-1724-4f49-b6ed-85f18b02d20e) **150 % Appearance** ![283-size-150-1440x900-appearance](https://git.kayg.org/attachments/a8c592af-db36-4638-97bb-1c22b56556e9)
Author
Owner

Rebase of ui-size-283 onto dev a26615c50 (orchestrator, 2026-11-01): started. WIP head 7abee68ce (pushed, 4 atomic commits, same order: rem lengths, slider, 1.1 base, windows grow).

Done so far:

  • Conflicts were in packages/ui/styles.css (19 hunks), apps/tracer/auth.css (4), packages/ui/src/tooltip.ts (1) and one slider hunk. Resolved by taking dev's side and converting it with the same px-to-rem rules; every line dev added since 7bf03044f was converted the same way (account.css, version.css, data-toggle.css, toast icons, kv copied feedback, focus-ring room, connection indicator). The connection indicator is kept; .ui-window-dot is gone; --ui-type-button stays normal.
  • Container queries are rem (window 35 / 9.375 / 5.25 / 2.5 rem, version panel 14.875 / 13.6875 rem). The toast stack offset's 12 px gap is now 0.75rem.

Plan (estimate 60 min): tsc + unit tests; my rem/px specs (ui-size, ui-size-windows), alignment (icon-text-centre), and every spec dev changed in this batch, on a production build; compare any failure to dev; then verify fast. The machines are at load 12-25, so runs queue; I will report whatever the numbers say.

Rebase of `ui-size-283` onto dev `a26615c50` (orchestrator, 2026-11-01): started. WIP head `7abee68ce` (pushed, 4 atomic commits, same order: rem lengths, slider, 1.1 base, windows grow). Done so far: - Conflicts were in `packages/ui/styles.css` (19 hunks), `apps/tracer/auth.css` (4), `packages/ui/src/tooltip.ts` (1) and one slider hunk. Resolved by taking dev's side and converting it with the same px-to-rem rules; every line dev added since `7bf03044f` was converted the same way (account.css, version.css, data-toggle.css, toast icons, kv copied feedback, focus-ring room, connection indicator). The connection indicator is kept; `.ui-window-dot` is gone; `--ui-type-button` stays `normal`. - Container queries are rem (window 35 / 9.375 / 5.25 / 2.5 rem, version panel 14.875 / 13.6875 rem). The toast stack offset's 12 px gap is now 0.75rem. Plan (estimate 60 min): tsc + unit tests; my rem/px specs (`ui-size`, `ui-size-windows`), alignment (`icon-text-centre`), and every spec dev changed in this batch, on a production build; compare any failure to dev; then `verify fast`. The machines are at load 12-25, so runs queue; I will report whatever the numbers say.
Author
Owner

Finish: ui-size-283 rebased onto dev 65d986191, head b6fccbaf7c089f9e12bcd07bca32ffcafb244f2d (5 commits: rem lengths, slider, 1.1 base, windows grow, name-column measure).

What changed in the rebase: dev's new CSS is in rem the same way (account card, version panel, toast icons and stack offset, copied feedback, focus-ring room, connection indicator, container queries incl. the sidebar footer's); .ui-window-dot is gone and the connection indicator is kept; --ui-type-button keeps line-height: normal. Two things dev's batch needed beyond conversion: (1) fitHints (#291) measured the name column with a bounding rect, which the canvas camera's zoom shrinks, so every Settings name at 150 % got an ellipsis; it now reads the used width (own commit); (2) four specs asserted px (connection indicator 14, setup gaps 30/26, heading gap 8 and 6): they now multiply by the UI factor.

Browser specs on a production build (real runner), before the last rebase (which changed only crates/): ui-size, ui-size-windows, icon-text-centre, account-card, startup-demo, connection-pill, version-pill, settings-rows, details, focus-ring-clip, palette-navigation, clusters-frame, window-option-new, onboarding pass; the 150 % "no title cut, no row clipped" spec passes; the specs that timed out at 30 s under load (load average 12-25) pass with --timeout=120000 (16 of 16). Failures that are the same on dev plus the fix branch: canvas 301/344/621, machine-pill-flicker 68, sessions-canvas 170/330/439 (+ five other sessions-canvas rows that fail only on the dev baseline). None is new.

scripts/verify fast on compute01 (x86_64), at this head, exit 0. Repository artifact gate: PASS (41 changed paths, merge base 65d9861914).

+---------------------------+--------------+
| Rust gate                 | Result       |
+---------------------------+--------------+
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| SSH runtime test helper   | PASS         |
| real-binary fixture paths | PASS         |
| test                      | PASS         |
| SSH inode reuse fixture   | PASS         |
| shim process-per-user     | PASS         |
| cargo-deny                | PASS         |
| gate architecture         | PASS         |
| static builds             | PASS         |
+---------------------------+--------------+
 472 pass
 106 pass
 17 pass
JavaScript transfer, critical: identity=997815 gzip=310036/327680 brotli=258386/273408 bytes
JavaScript transfer, deferred: identity=175781 gzip=60833/61440 brotli=53731/55296 bytes
 39 pass

Transfer budget, critical JS: gzip 310,036 / 327,680 (dev + fix branch: 309,606; +430 B), brotli 258,386 / 273,408 (+485 B).

**Finish: `ui-size-283` rebased onto dev `65d986191`, head `b6fccbaf7c089f9e12bcd07bca32ffcafb244f2d`** (5 commits: rem lengths, slider, 1.1 base, windows grow, name-column measure). What changed in the rebase: dev's new CSS is in rem the same way (account card, version panel, toast icons and stack offset, copied feedback, focus-ring room, connection indicator, container queries incl. the sidebar footer's); `.ui-window-dot` is gone and the connection indicator is kept; `--ui-type-button` keeps `line-height: normal`. Two things dev's batch needed beyond conversion: (1) `fitHints` (#291) measured the name column with a bounding rect, which the canvas camera's zoom shrinks, so every Settings name at 150 % got an ellipsis; it now reads the used width (own commit); (2) four specs asserted px (connection indicator 14, setup gaps 30/26, heading gap 8 and 6): they now multiply by the UI factor. Browser specs on a production build (real runner), before the last rebase (which changed only `crates/`): `ui-size`, `ui-size-windows`, `icon-text-centre`, `account-card`, `startup-demo`, `connection-pill`, `version-pill`, `settings-rows`, `details`, `focus-ring-clip`, `palette-navigation`, `clusters-frame`, `window-option-new`, `onboarding` pass; the 150 % "no title cut, no row clipped" spec passes; the specs that timed out at 30 s under load (load average 12-25) pass with `--timeout=120000` (16 of 16). Failures that are the same on dev plus the fix branch: `canvas` 301/344/621, `machine-pill-flicker` 68, `sessions-canvas` 170/330/439 (+ five other sessions-canvas rows that fail only on the dev baseline). None is new. `scripts/verify fast` on compute01 (x86_64), at this head, exit 0. Repository artifact gate: PASS (41 changed paths, merge base 65d9861914e8). ``` +---------------------------+--------------+ | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | SSH runtime test helper | PASS | | real-binary fixture paths | PASS | | test | PASS | | SSH inode reuse fixture | PASS | | shim process-per-user | PASS | | cargo-deny | PASS | | gate architecture | PASS | | static builds | PASS | +---------------------------+--------------+ 472 pass 106 pass 17 pass JavaScript transfer, critical: identity=997815 gzip=310036/327680 brotli=258386/273408 bytes JavaScript transfer, deferred: identity=175781 gzip=60833/61440 brotli=53731/55296 bytes 39 pass ``` Transfer budget, critical JS: gzip 310,036 / 327,680 (dev + fix branch: 309,606; +430 B), brotli 258,386 / 273,408 (+485 B).
Author
Owner

Closed by the orchestrator during the 2026-11-09 night housekeeping (owner order: "close stale prs/issues"). The work has landed on dev, and the latest note here is a finish or merge note (J387 inventory on #436). Reopen if anything is still missing.

Closed by the orchestrator during the 2026-11-09 night housekeeping (owner order: "close stale prs/issues"). The work has landed on dev, and the latest note here is a finish or merge note (J387 inventory on #436). Reopen if anything is still missing.
kayg closed this issue 2026-11-08 19:04:26 +00:00
Sign in to join this conversation.
No labels
launch-qa
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/infraternal#283
No description provided.