Component
Stable Display

Badge

Badges are small status indicators used to communicate state, category, or quantity. They are always pill-shaped, always soft-colored, and never use hard/saturated backgrounds.

Overview

Badges appear inline next to text, in table cells, and in card headers. The design language uses soft tinted backgrounds (10–15% opacity of the semantic color) paired with a dark-tinted text color from the same hue family. Never use a full-saturation background like #0E9F6E directly — always use the -bg token pair.

Never use emojis inside badges. Use text labels only. The dot modifier (.badge-dot) adds a colored dot via CSS pseudo-element — no emoji needed.

When to Use

Use Badge when
  • Indicating the status of a record (Active, Pending, Inactive)
  • Categorizing by role, type, or classification
  • Labeling items in tables, lists, and cards
Don't use Badge when
  • An action is needed — use a Button instead
  • Displaying long text (>3 words) — use a callout
  • Navigation or filtering — use tabs or a select

Anatomy

1
Container
Always a <span> element. display:inline-flex, align-items:center. Pill shape via border-radius:999px. Never a div or button.
2
Dot Indicator (optional)
Added via .badge-dot class. CSS ::before pseudo-element. width/height:6px, border-radius:50%, background:currentColor.
3
Label Text
Plain text only. 11px fw-700. Never use emoji, icons, or HTML inside badge text. Keep to 1–3 words maximum.
4
Color Pair
Always paired tokens: soft background + matching dark text. Never full-saturation backgrounds.

Variants

Success
Active
Warning
Pending
Danger
Inactive
Info
Admin
Purple
Director
Neutral
Archived
Hot
Hot
Warm
Warm
Cold
Cold
Deal
Deal
Lost
Lost

Sizes

Small
Active
Default
Active
Large
Active

Token Reference

ClassBackgroundText ColorUse For
.badge-success#DEF7EC#03543FActive, approved, completed
.badge-warning#FEF3C7#92400EPending, review, in progress
.badge-danger#FDE2E2#9B1C1CInactive, rejected, error
.badge-info#E1EFFE#1E429FRole: Admin, informational
.badge-purple#F5F3FF#5521B5Role: Director
.badge-neutral#F1F5F9#64748BArchived, no status
.badge-hot#fef2f2#dc2626Lead: Hot prospect
.badge-warm#fff7ed#ea580cLead: Warm prospect
.badge-cold#f0f9ff#0284c7Lead: Cold prospect
.badge-deal#f0fdf4#16a34aLead: Closed deal
.badge-lost#f9fafb#6b7280Lead: Lost deal

States

Badges are static display elements — they have no interactive states. They do not respond to hover, focus, or click. If interaction is needed, use a Button component instead.

Properties

PropertyTypeRequiredDefaultDescription
variantstringrequiredColor theme.
'success'|'warning'|'danger'|'info'|'purple'|'amber'|'neutral'|'hot'|'warm'|'cold'|'deal'|'lost'
dotbooleanoptionalfalseAdds colored dot via CSS ::before. Use for status badges.
sizestringoptional'default'
'sm' | 'default' | 'lg'
childrenstringrequiredLabel text. Plain text only. Max 3 words.

Accessibility

RequirementImplementation
Screen readerBadge text is read inline as part of its parent context. No additional ARIA needed for static badges.
Color aloneNever rely on color alone. Always include a text label. Dot indicators supplement but never replace the label.
ContrastAll badge color pairs meet WCAG AA minimum 4.5:1 contrast ratio.

Composition

Allowed
Inline with text in table cells
In card headers next to titles
In nav items as count indicators
Forbidden
With onClick or hover styles
Full-saturation background colors
Emoji or icons inside badge text

Best Practices

Do
Active
Soft bg, dot indicator, specific label. Paired token set.
Don't
Active
Full-saturation background — looks like a button.

Content Rules

Active
1 word, clear status
Currently Active User
Too long — max 3 words

AI Implementation Guide

For AI coding assistants: Badges are always <span> elements, always inline-flex. Base class is .badge + one variant class. The dot is added via .badge-dot CSS ::before — never a DOM element. Do NOT use emoji. Never make badges interactive. Always use the soft bg+text paired token system.

Design Decisions

Why soft backgrounds instead of full-saturation?
Badges appear inline with text. Full-saturation backgrounds compete aggressively with primary actions and create visual noise in data-dense views like tables. Soft tinted backgrounds provide clear categorization without interrupting reading flow.
Why is the dot a CSS ::before instead of a DOM element?
A CSS pseudo-element is purely decorative — screen readers ignore it. A real DOM element would be read aloud unnecessarily. The text label alone conveys the status to assistive technologies.

Changelog

v1.0.0July 2026Added
  • 13 variants across status, role, and lead temperature categories
  • Dot indicator via CSS ::before pseudo-element
  • 3 sizes: sm, default, lg

Behavior

Badges are purely presentational — no hover, focus, click, or animation states. Their value updates reactively when the underlying data changes. The UI re-renders with the new variant and label instantly. No entrance or exit animation is applied to badge changes. If a badge needs to be interactive (e.g. a removable tag), that is a separate component with button semantics.