mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-26 18:31:34 +01:00
End-to-end validation measured two WCAG AA failures on the recessed recovery UI in real Chromium: the light-mode `in_progress` chip at 4.34:1 (`text-muted-foreground` on solid `bg-muted`) and the escalated card's microcopy at 4.39:1 on `bg-red-50/85`. Both render at --text-nano/--text-micro, so the bar is 4.5:1. The root cause is that `--muted-foreground` is tuned against `--background` and is only just AA there (4.73:1). Every recovery surface is a tint or a wash, and the token drops below AA the moment the surface stops being paper. Rather than retune a token the whole app depends on, this adds `--recessed-foreground`: an AA-safe neutral sibling for subordinate text that sits on muted or tinted surfaces. Dark mode keeps the existing value on purpose — it already passes, so dark renders identically. Measured in Chromium 151 over the real Storybook surfaces: recessed chip @10px 4.34:1 -> 6.04:1 light, 5.86:1 dark card microcopy @11px 4.39:1 -> 6.36:1 light, 7.36:1 dark axe color-contrast 6 violations -> 0 The `needed`/`escalated` chips move amber-700 -> amber-800 and red-700 -> red-800, which axe independently flagged at 4.41:1 at nano size. The quiet-vs- prominent contract is unchanged: recession is carried by the neutral hue, never by low contrast. The active-run panel story kept a hand-copied tone table that had drifted off `RECOVERY_CHIP_DEFAULT_TONE`, so it still rendered the failing pairing after the components were fixed — and it was the only surface axe still flagged. It now reads the shared table, which also retires an arbitrary `text-[10px]`. Guards: `recovery-contrast.test.ts` pins the arithmetic against oklch values read from index.css, calibrated to Chromium-sampled sRGB anchors, and keeps a negative control asserting the retired pairing still measures as a failure. Pre-existing and NOT changed here: `text-muted-foreground/60` on aria-hidden `·` separators (decorative, WCAG 1.4.3 exempt) and `text-muted-foreground/50` on compact chat timestamps at 1.96:1 in IssueChatThread — real content, out of scope, tracked separately. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Paperclip <noreply@paperclip.ing>
@paperclipai/ui
Published static assets for the Paperclip board UI.
What gets published
The npm package contains the production build under dist/. It does not ship the UI source tree or workspace-only dependencies.
Storybook
Storybook config, stories, and fixtures live under ui/storybook/.
pnpm --filter @paperclipai/ui storybook
pnpm --filter @paperclipai/ui build-storybook
Typical use
Install the package, then serve or copy the built files from node_modules/@paperclipai/ui/dist.