Skip to content

feat(webui): a real type scale, because more than half the UI was under 12px - #61

Merged
404SecNotFound merged 2 commits into
mainfrom
feat/type-scale
Aug 4, 2026
Merged

feat(webui): a real type scale, because more than half the UI was under 12px#61
404SecNotFound merged 2 commits into
mainfrom
feat/type-scale

Conversation

@404SecNotFound

Copy link
Copy Markdown
Owner

Reported as "the text is quite small, you have to really focus your eyes".
Measured on the rendered page rather than argued about:

most common size in the whole UI 10.5px (30 of 104 elements)
below 12px 58 of 104
at or above the 16px default 3 of 104
smallest 8.5px (a rule id in the signal diagram)
contrast failures 1

So contrast was fine. Somebody audited that properly during the reskin. Nobody
ever audited size, and that was the actual gap.

It was not a design decision either. docs/webui-reskin-design.md defines a
palette, spacing and a motif and contains no type scale at all, one incidental
mention of "11px mono labels" aside, while the code carried ELEVEN hardcoded
sizes across 84 call sites. Eleven sizes is not a scale, it is eleven separate
decisions made one component at a time and never compared.

The scale distinguishes READ from SCAN, which is what was missing. Prose is read
in sentences and needs size; monospace and tabular data is scanned, where density
genuinely helps. So data stays tight at 12.5 while body goes 13 -> 14 and the
technique objective gets its own lede at 15. Nothing renders below 11px.

Two regressions I caused and caught by measuring again afterwards:

  • "SIGNAL FIELDS" grew wide enough to sit underneath its own values in the
    diagram. The values moved right rather than the label shrinking back.
  • "Check Point" wrapped to two lines in the vendor picker, doubling the control
    height. It needs 84.1px in an 83.7px segment, so half a pixel of growth tipped
    it over; it had always been marginal. Restored to 12px and given nowrap, so
    the next long vendor name overflows visibly instead of silently reflowing,
    which is how it shipped that way the first time.

Also fixes scripts/capture-webui-screenshots.py, which clicked a button
labelled "Start run". PR #31 renamed that to name its destination, so the script
had been broken since and nobody knew, because it only runs when someone
regenerates screenshots. It now matches on the stable prefix. All five images
regenerated.

952 py + 137 fe. tsc, black, ruff clean. No horizontal overflow at 1280 or 1440.

…er 12px

Reported as "the text is quite small, you have to really focus your eyes".
Measured on the rendered page rather than argued about:

  most common size in the whole UI   10.5px  (30 of 104 elements)
  below 12px                         58 of 104
  at or above the 16px default        3 of 104
  smallest                            8.5px  (a rule id in the signal diagram)
  contrast failures                   1

So contrast was fine. Somebody audited that properly during the reskin. Nobody
ever audited size, and that was the actual gap.

It was not a design decision either. `docs/webui-reskin-design.md` defines a
palette, spacing and a motif and contains no type scale at all, one incidental
mention of "11px mono labels" aside, while the code carried ELEVEN hardcoded
sizes across 84 call sites. Eleven sizes is not a scale, it is eleven separate
decisions made one component at a time and never compared.

The scale distinguishes READ from SCAN, which is what was missing. Prose is read
in sentences and needs size; monospace and tabular data is scanned, where density
genuinely helps. So `data` stays tight at 12.5 while `body` goes 13 -> 14 and the
technique objective gets its own `lede` at 15. Nothing renders below 11px.

Two regressions I caused and caught by measuring again afterwards:

- "SIGNAL FIELDS" grew wide enough to sit underneath its own values in the
  diagram. The values moved right rather than the label shrinking back.
- "Check Point" wrapped to two lines in the vendor picker, doubling the control
  height. It needs 84.1px in an 83.7px segment, so half a pixel of growth tipped
  it over; it had always been marginal. Restored to 12px and given `nowrap`, so
  the next long vendor name overflows visibly instead of silently reflowing,
  which is how it shipped that way the first time.

Also fixes `scripts/capture-webui-screenshots.py`, which clicked a button
labelled "Start run". PR #31 renamed that to name its destination, so the script
had been broken since and nobody knew, because it only runs when someone
regenerates screenshots. It now matches on the stable prefix. All five images
regenerated.

952 py + 137 fe. tsc, black, ruff clean. No horizontal overflow at 1280 or 1440.
The type-scale guard imported tailwind.config.js directly. It is plain JS with
no declaration file, so `tsc` rejected it under noImplicitAny and took down four
CI jobs: both frontend builds, the installer (which builds the web UI) and the
wheel job (same).

My error was one of sequence rather than of judgement. I ran `tsc --noEmit`
before adding that last test and did not run it again afterwards, so the local
gate passed on a tree that no longer existed.

`?raw` is typed as string by vite/client, so the guard now reads the config as
text and stays type-clean. Verified with the exact command CI runs, after the
edit this time.
@404SecNotFound
404SecNotFound merged commit 401d4a3 into main Aug 4, 2026
10 checks passed
@404SecNotFound
404SecNotFound deleted the feat/type-scale branch August 4, 2026 05:52
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