S1c, the last part of S1. The contract now lives in components/ui/ and
in one CSS recipe instead of in ~160 call sites:
- Minimum target 2.75rem, on coarse pointers only (.touch-target). A
32px icon button is fine with a mouse -- precise pointer, hover to
confirm the aim -- and not fine with a thumb, so it grows exactly where
there is no precise pointer, which on this app's real second device is
the tablet. It grows the real box rather than painting an invisible
::after hit area, because two expanded hit areas on icon buttons 4px
apart would overlap and the overlap fires the WRONG button. `link` is
excluded: it is text inside a sentence.
- 2.75rem rather than 44px so the target obeys the text-size slider like
everything else; verified that the type/geometry ladder was already
rem-derived off --font-scale, so nothing else was needed there.
- The ladder is documented as a closed set in Button.tsx, with the site
counts it was derived from, and ui/README.md states the contract.
Measured in the browser: fine pointer 36x36 and 34px-tall buttons
(unchanged), coarse pointer the same buttons at 44x44 and 44px tall.
1024x768 renders identically. 3x tsc, eslint, knip, prettier and 690
vitest green.