Skip to content
txbrendan/ui

Proof

We only say what a check proves. Each claim below names the check behind it, and what that check does not cover.

Contrast in our theme

Every color pair in our theme contract is checked for contrast, in light and dark.

How we check it

  • The contract lists 81 color pairs: 53 for text at 4.5:1, 26 for borders, fills, focus rings, and chart marks at 3:1, and 2 for bar tracks at 1.25:1.
  • lib/theme/theme.test.ts checks every pair in light and dark, and checks that every color fits in the sRGB gamut.

What it does not cover

  • It checks our theme. A check you can run on your own app's theme is not published yet.
  • The 1.25:1 floor for bar tracks is our own, not a WCAG level. The bar's text carries the number.
  • Contrast is one part of accessibility, not all of it.

Themes from one color

Make a light and dark theme from one brand color. Each one is checked against the same 81 contrast pairs as ours.

How we check it

  • The engine moves lightness until every pair passes. Then it runs the full check, and it throws rather than return a theme that fails.
  • lib/theme/generate.test.ts checks a sample of brand colors in light and dark.

What it does not cover

  • The tests cover a sample of colors. Any other color is checked when the engine makes it.

More than colors

Theme more than colors: density, motion, type, shadows, and radius, per app or per component.

How we check it

  • lib/theme/theme.test.ts checks that each density and motion setting sets every variable in the contract.
  • checks/principles.test.ts fails if a shipped part uses a Tailwind text size, leading, weight, or shadow class, like text-sm, instead of the tokens, apart from a short list of named exceptions.

What it does not cover

  • The checks prove the structure. They do not measure how a page looks.
  • The checks read class names. They do not catch a one-off value, like Kbd's text-[0.6875rem].

Keyboard and screen readers

Popups and form controls handle focus and keys for you.

Keyboard and screen reader behavior is tested.

How we check it

  • Every component's tests run axe.
  • The controls test their keys and Tab order.
  • An icon-only button fails to compile without an aria-label.

What it does not cover

  • axe runs in a test DOM, not a real browser. So contrast is proven by the theme tests instead.
  • No check runs axe on a real page in a browser.

Size budgets

Every component has a size budget, and the build fails over it.

How we check it

  • scripts/size.mts bundles, minifies, and gzips each component and block. npm run check fails when one goes over.
  • The default budget is 8 KB added to an app that already uses shadcn.

What it does not cover

  • 95 of 168 components set a higher budget, for popups, rich controls, and charts. Each of the 8 Recharts charts adds about 100 KB.
  • A block's number leaves out the components it uses, since each has its own budget.

Yours to own

Plain source files in your repo. Change anything.

How we check it

  • Component tests check that a className you pass wins over its own classes.

What it does not cover

  • Action Keys draws nothing, so it takes no className.

Not claimed yet

Some claims are only partly checked so far, so we do not make them yet. Two are one API across every component, and how well agents build pages from these docs. A claim moves to this page once a check proves it.

This page does not show live numbers yet, like each component's size against its budget.