Files
PaperClipAI/ui
457a36e0d9 fix(ui): clear the remaining recovery-state AA contrast failures
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>
2026-08-15 19:19:38 +00:00
..

@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.