fix(a11y): names that carry what they show; the unused-key check stops covering whole files

- The palette launcher's name replaced its visible "Jump to…" (and the key cap's its "Ctrl K"):
  a voice-control "click Jump to" matched nothing (WCAG 2.5.3). Each name contains its text now.
- SegmentedToggle's `title` was only a tooltip on a non-focusable box — the live search's "how
  many per batch" hint reached no keyboard or screen-reader user. It is the group's accessible
  description, standalone and captioned alike.
- The unused-key contract let a template like `card.${status}` cover its whole namespace, which hid
  five dead keys (deleted). Dynamic keys are matched by shape (`editor.*.hint`); a bare namespace
  shape covers nothing, and the audit/quota namespaces are now held both ways by backendIds.
- CLAUDE.md's "FE control" row matches the lint rule it cites; each no-restricted-syntax entry has
  its reason directly above it.
This commit is contained in:
2026-09-19 19:19:43 +02:00
parent fa4f823fc8
commit cf0c55ba80
13 changed files with 128 additions and 39 deletions
@@ -54,8 +54,9 @@ describe("the command palette's visible entry", () => {
it("is a key cap inside the search field, naming the chord the palette row binds", () => {
page = "feed";
const isOpen = mount();
const cap = screen.getByRole("button", { name: "palette.open" });
expect(cap.textContent).toMatch(/^(Ctrl|⌘) K$/);
const cap = screen.getByRole("button", { name: /^palette\.open \((Ctrl|⌘) K\)$/ });
// Label in Name: the name carries what the cap shows, so "click Ctrl K" finds it.
expect(cap.getAttribute("aria-label")).toContain(cap.textContent);
expect(screen.getByRole("textbox")).toBeTruthy();
fireEvent.click(cap);
expect(isOpen()).toBe(true);
@@ -65,8 +66,9 @@ describe("the command palette's visible entry", () => {
page = "home";
const isOpen = mount();
expect(screen.queryByRole("textbox")).toBeNull();
const pill = screen.getByRole("button", { name: "palette.open" });
expect(pill.textContent).toContain("palette.title");
// Named by what it shows ("Jump to…"), not by a label that replaced it.
const pill = screen.getByRole("button", { name: "palette.title" });
expect(pill.getAttribute("title")).toBe("palette.open");
fireEvent.click(pill);
expect(isOpen()).toBe(true);
});