fix(design): the S3g conformance sweep — primitives at their rung (E28 S3g)

The probe re-run over the 15 pages at 1920x1080 found every button, icon
button, chip, field, tab, segment and menu row drawn by its primitive
except the S3h Plex picture, a div with the button role. It is a
Pressable now, and the button-primitive lint rule refuses an element
with role="button" outside the control primitives.

- SegmentedToggle defaults to the toolbar rung (28, text-xs): the old
  small default had put the pager's page sizes and the YouTube result
  count on 10px type beside 28px buttons. The Plex match toggle asks
  for the small rung explicitly.
- The language badge on the rail uses text-3xs (was an 8px one-off);
  the Plex playlist's watched mark and the Home hero's length use
  MEDIA_BADGE instead of hand-copied classes.
- A media picture shows the pointer whether it is a link or a button.
- DESIGN.md: a Conformance chapter (the four-step check before a UI
  change is done, with the S3g baseline), the segmented rung, two log
  rows. CLAUDE.md points at the check.
This commit is contained in:
2026-09-27 05:11:34 +02:00
parent ef343dbec0
commit 6c2c01e67b
16 changed files with 90 additions and 33 deletions
@@ -21,7 +21,7 @@ export default function SegmentedToggle<T extends string>({
label,
title,
fullWidth = false,
size = "sm",
size = "md",
className,
}: {
options: readonly SegmentedOption<T>[];
@@ -37,7 +37,9 @@ export default function SegmentedToggle<T extends string>({
title?: string;
// Full-width track with flex-1 buttons (the scope bar); default is intrinsic width.
fullWidth?: boolean;
// sm = text-3xs, compact padding (the captioned match toggles); md = text-xs (the scope bar).
// md (28, text-xs) is the toolbar rung: it lines up with the search pill, the triggers and an `sm`
// Button (DESIGN B1). sm (24, text-3xs) is only a side panel's captioned match toggle. md is the
// default because the old sm default slid a pager and a toolbar count onto 10px type (S3g).
size?: "sm" | "md";
className?: string;
}) {