feat(e10): put the 1024x768 size contract inside the primitives
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.
This commit is contained in:
@@ -539,6 +539,26 @@ body {
|
||||
.btn-warn:hover:not(:disabled) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ===== E10 S1c · the minimum-target half of the 1024x768 comfort contract =====
|
||||
A 32px icon button is fine with a mouse (a precise pointer plus hover to confirm the aim) and
|
||||
not fine with a thumb. So the minimum grows ONLY where there is no precise pointer, which on
|
||||
this app's real second device — a tablet — is exactly where it is needed.
|
||||
|
||||
min-* rather than width/height so it can only ever grow a control, never shrink one, and so a
|
||||
`w-8 h-8` utility on the same element still loses to it (min-width beats width in CSS).
|
||||
Growing the BOX rather than painting an invisible ::after hit area is deliberate: an expanded
|
||||
hit area on two icon buttons sitting 4px apart would overlap, and the overlap fires the WRONG
|
||||
button — a worse failure than a small target. Real space cannot overlap.
|
||||
|
||||
2.75rem, not 44px: the whole app is rem-derived off `--font-scale`, so a target defined in px
|
||||
would be the one control that ignores the user's text-size setting. */
|
||||
@media (pointer: coarse) {
|
||||
.touch-target {
|
||||
min-width: 2.75rem;
|
||||
min-height: 2.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.glass-hover:hover {
|
||||
border-color: color-mix(in srgb, var(--accent) 55%, transparent);
|
||||
|
||||
Reference in New Issue
Block a user