<!-- https://getkonjo.com/design/components/badge · source: docs/design/components/badge.md -->

# Badge

A status pill: a fill and a short label. It states a fact and never takes a tap.

```kata-specimen
badge-tones
```

> Source: [`Badge.tsx`](../../../src/components/ui/Badge.tsx). When status belongs in a badge
> rather than a banner or a push: [notifications](../patterns/notifications.md).

## When to use it

- To mark the state of one thing in a list: "Overdue", "Paid", "Draft".
- In a [Row](row.md)'s trailing slot, or under a detail screen's title.

Not as a filter or a choice — that is a [chip](tag-chip.md), which has an edge and a press. Not
for a value with a label ("12 classes") — that is `StatPill`. Not for a belt's verification
state — that is `BeltStateBadge`.

## Anatomy

| Part | Token |
|---|---|
| Height floor | 24 (`spacing.s24`); grows with the label |
| Padding | `spacing.s4` × `spacing.s8` |
| Shape | `radius.pill` |
| Label | `typography.label` 13/700, sentence case |

Each tone pairs a fill with its own text colour:

| Tone | Fill | Text |
|---|---|---|
| `neutral` (default) | `surface.tag` | `text.secondary` |
| `error` | `feedback.errorFill` | `feedback.errorText` |
| `warning` | `feedback.warningFill` | `feedback.warningText` |
| `info` | `feedback.infoFill` | `feedback.infoText` |
| `success` | `feedback.successFill` | `feedback.successText` |
| `gold` | `gold.fill` | `gold.text` |

```kata-specimen
badge-in-row
```

## States

A badge has one state: shown. It has no pressed, focus, disabled or loading state because it is
not a control. Change its tone or label when the thing it describes changes.

## Content

- One or two words, sentence case: "Expires soon", not "EXPIRES SOON".
- Say the state, not the instruction: "Overdue", not "Pay now".
- Never colour alone. The word carries the meaning; the tone reinforces it.

## Accessibility

- No role: it is read as part of the row or heading it sits in. Make sure that container's label
  includes it ("Jordan Lee. Membership. Overdue").
- The fills are nearly the page's colour, so the **text** colour carries the severity; every
  text token clears 4.5:1 on its own fill in both themes.
- It never has a `border.control` edge, because an edge says "tap me".

## Do and don't

```kata-specimen
badge-case
```

## Code

```tsx
import { Badge, Row } from '../../components/ui';

<Row title="Jordan Lee" subtitle="Membership" trailing={<Badge label="Overdue" tone="error" />} onPress={open} />
```
