Badge
A muted pill. 12px label. Status uses the word plus color.
Spec
- Fill
-muted, textfg-. Pill radius. - Label 12px (
--text-caption-size). - Variants: subtle, outline, solid-count.
- Sizes: sm, md (compact / standard).
- Dismissible: close with a 44px hit.
- Empty dot: 8px, top-end, on a 40 avatar.
- Counts: 9, 99, 99+. Never 132. Never New!!
Live demo
Runnable controls. Not a screenshot. Paper / Ink in the header recolors tokens.
Subtle, outline, counts
LiveStaleEmptyErrorOutline99999+sm
Dismissible filter
region:eu-westEmpty 8px dot on a 40 avatar
OCDo / Don't
| Do | Don't |
|---|---|
| Live, Stale, Empty, Error as words. | Color alone as status. |
| Cap counts at 99+. | New!!, HOT, or a shout. |
| Subtle by default. | Solid fill behind a sentence. |
Motion
| Property | Duration | Easing | Trigger | Reduced motion |
|---|---|---|---|---|
transform: scale(0.97) | 120ms --dur-fast | --ease-out | :active | instant |
| color / border | 120ms --dur-fast | --ease-out | :hover | instant |
| outline | 80ms --dur-micro | --ease-out | :focus-visible | instant |
Dismiss uses the same press as a ghost button.
Accessibility
- Contrast:
fg-*on muted, not fill-on-paper for small type. - Dismiss name: “Remove filter” (the object), not “×”.
- Dot badges that are status must have a text alternative on the parent.
- These notes describe construction. They are not a guarantee of WCAG conformance. Validate with axe, keyboard, and operators. See Accessibility.