Badge
A small status indicator used to communicate settlement state, activity, or urgency. Dot-only for compact contexts, dot + label for clarity. Never decorative — every badge communicates something real about the expense or the person's status.
Variants
Dot + label — default. Clear enough to stand alone anywhere. Used in list rows and detail views where vertical space allows a label.
Pill — filled background with colored label. More prominent. Use in card headers, empty states, or anywhere the badge needs to compete with other content.
Dot only — for extreme space constraints, e.g. inline within a ledger row that already has the label elsewhere. Always pair with a tooltip or nearby text so the dot isn't the sole signal.
States
| Variant | Dot color | Token | When to use |
|---|---|---|---|
| Settled | Teal | --teal | Expense is fully settled — all members paid |
| Pending | Butter | --butter | Awaiting payment or confirmation from at least one person |
| Overdue | Coral | --coral | A requested payment is past the expected date |
| New | Ink | --ink | An expense the current user hasn't viewed yet |
On dark surfaces
Dot colors remain the same — teal, butter, and coral are all legible on dark backgrounds. The label color shifts to --dark-text-2. The "New" dot changes from ink to --dark-text so it remains visible. Add .on-dark to the ancestor element.
Anatomy
| Part | Element | Notes |
|---|---|---|
| Container | .badge | Inline-flex, baseline-aligned, gap 6px. Non-interactive by default. |
| Dot | .badge-dot | 6px circle. Color determined by variant modifier. Always present. |
| Label | .badge-label (optional) | 12px body font. Omit for dot-only; still include in aria-label on the container. |
Usage
Accessibility
aria-label to the badge container with the full state: aria-label="Settled" or aria-label="Overdue". For dot-only badges, the aria-label is mandatory since there's no visible text. For badges inside a larger interactive element that already announces the state, use aria-hidden="true".
Code
HTML
<!-- Dot + label --> <span class="badge badge-settled" aria-label="Settled"> <span class="badge-dot"></span> <span class="badge-label">Settled</span> </span> <!-- Pill variant --> <span class="badge badge-overdue badge-pill" aria-label="Overdue"> <span class="badge-dot"></span> <span class="badge-label">Overdue</span> </span> <!-- Dot only (must have aria-label) --> <span class="badge badge-pending" aria-label="Pending"> <span class="badge-dot"></span> </span>
CSS classes
| Class | Purpose |
|---|---|
.badge | Base — flex, gap, font, no-wrap |
.badge-settled | Teal dot — all settled |
.badge-pending | Butter dot — awaiting payment |
.badge-overdue | Coral dot — past due |
.badge-new | Ink dot — unseen by current user |
.badge-pill | Adds filled background and rounded container |
.badge-colored | Makes label inherit dot color (optional emphasis) |
.badge-dot | The 6px indicator circle |
.badge-label | The text label (optional) |
Design tokens used
| Token | Value | Role |
|---|---|---|
--teal | #0E7C66 | Settled dot |
--butter | #F4C94E | Pending dot |
--coral | #E76F51 | Overdue dot |
--ink | #171513 | New dot |
--success-bg | #D6EAE2 | Settled pill background |
--warning-bg | #FAF0D4 | Pending pill background |
--error-bg | #FADED4 | Overdue pill background |