Components
Badge
StableBadges are compact labels that communicate status, category, or promotional context — from booking states to card overlay callouts.
Purpose
A badge attaches a short, scannable piece of metadata to a piece of content. It is always read-only — never interactive — and should never be the sole carrier of critical information, because colour alone does not convey meaning to everyone.
Badge has two distinct colour systems that map to two use cases:
General tones (neutral, brand, info, success, warning, danger) are for status indicators and metadata labels — a booking confirmation state, a filter chip count, an "on hold" tag. These follow a semantic colour convention and support a status dot.
Kuoni product variants (promotion, exclusive, featured, sold-out, new, offer) are for promotional overlays and product callouts — card image stamps, "Save up to 30%" banners, "Kuoni Exclusive" corner stamps. They use brand-specific colours and are not dot-eligible.
Usage
Reach for Badge when you need a compact, read-only piece of metadata attached to content — a status, category, or promotional stamp. If the label needs to be tappable or toggled (a filter the user selects), use Chip instead; Badge never carries interaction.
Badges appear inline next to text (a status label beside a booking reference) or as an absolutely-positioned overlay on a card image (a promotional stamp in the corner).
Anatomy
- 1Container — Coloured surface. Shape varies: pill (rounded), card overlay (square), or corner stamp (stamp). Background and text colour are determined by the variant.
- 2Dot (optional) — A 6 px filled circle in the current text colour. Available only for general tones — signals live or streaming status at a glance.
- 3Label — One to three words in sentence case. The label carries all meaning — colour is an enhancement, not a substitute.
Variants
General tones
Use these for status, state, and metadata. Each tone has a defined semantic meaning — do not repurpose a tone for a different meaning (e.g. do not use danger for a promotional label).
| Tone | Colour | Use for |
|---|---|---|
neutral | Grey | Default state, draft, inactive |
brand | Teal tint | Kuoni brand attributes, included features |
info | Blue tint | Informational, "on hold" |
success | Green tint | Confirmed, complete, available |
warning | Amber tint | Pending, awaiting action |
danger | Red tint | Cancelled, error, unavailable |
Kuoni product variants
Use these for promotional content on offer cards, holiday tiles, and search results. They carry bolder, higher-contrast colours to stand out against imagery and card surfaces.
| Variant | Background | Text | Typical label |
|---|---|---|---|
promotion | Teal #005B55 | White | "Save up to 30%", "Late Deal" |
exclusive | Dark #1A1A1A | White | "Kuoni Exclusive" |
featured | Wow Yellow #F5C518 | Dark | "Featured" |
sold-out | Grey #999999 | White | "Sold Out" |
new | Green #2E7D32 | White | "New" |
offer | Terracotta #C96742 | White | "Special Offer" |
Shapes
Three shape variants let the badge adapt to its placement context.
| Shape | Border radius | Use for |
|---|---|---|
rounded | 9999px (pill) | Filter chips, status labels, inline metadata |
square | 4px | Overlay badges on card image corners |
stamp | 0 | Kuoni Exclusive corner stamps on card images |
Tip: Use
shape="square"orshape="stamp"with absolute positioning over a card's image — e.g.absolute top-3 left-3.
Sizes
| Size | Font | H-padding | V-padding | Use for |
|---|---|---|---|---|
sm | 10 px | 8 px | 2 px | Dense card grids, compact table cells |
md | 12 px | 10 px | 2 px | Default — most contexts |
lg | 13 px | 12 px | 4 px | Hero sections, large card tiles |
With status dot
Add dot to a general-tone badge to show a 6 px filled circle before the label. Use this for live or streaming states — booking confirmed, payment processing — where the dot signals something is actively in a given state.
The
dotprop has no effect on Kuoni product variants (promotion,exclusive,featured,sold-out,new,offer).
Best practices
Keep badge labels short and specific: 'Confirmed', 'Late Deal', 'Kuoni Exclusive'.
One or two words is enough — the badge is a signal, not a sentence.
Put a full phrase or sentence inside a badge.
A badge that wraps to two lines stops being compact. Use a tag or chip instead.
Use a single Kuoni product variant badge per offer card to highlight the most important message.
One promotional badge per card orients the eye to the key selling point.
Stack multiple promotional variant badges on the same card or tile.
Stacking 'Kuoni Exclusive', 'Save 30%' and 'Featured' on the same card dilutes all three messages.
Use the semantic general-tone system for booking and availability status.
Match the tone to the meaning — success for positive states, danger for unavailable.
Repurpose a semantic tone for a promotional or decorative purpose.
Using 'danger' for a promotional label breaks the user's mental model of what red means.
Always include descriptive text in the label, never rely on colour alone.
The label text must repeat the information colour conveys — screen readers see text only.
Use a badge with no visible text, or use it as an interactive control.
An empty badge or a badge whose only content is an icon gives screen readers nothing to announce.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | ReactNode | — | The badge label. Keep to one to three words in sentence case. |
| variant | 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'danger' | 'promotion' | 'exclusive' | 'featured' | 'sold-out' | 'new' | 'offer' | 'neutral' | Colour and meaning of the badge. First six are general tones; last six are Kuoni product variants. |
| shape | 'rounded' | 'square' | 'stamp' | 'rounded' | Border-radius style. 'rounded' = pill; 'square' = 4 px radius for card overlays; 'stamp' = no radius for corner stamps. |
| size | 'sm' | 'md' | 'lg' | 'md' | Controls font size and padding. sm=10px, md=12px, lg=13px. |
| dot | boolean | false | Renders a 6 px status dot before the label. Only applies to general tones — has no effect on Kuoni product variants. |
| className | string | — | Additional Tailwind classes merged onto the root element. Use for positioning (e.g. absolute top-3 left-3) or minor overrides. |
Accessibility
Static vs dynamic badges
Most badges are static — they render with the page and do not change. For these, no ARIA role is needed; the surrounding content provides context.
For badges that update dynamically in response to user action or data — for example, a count badge on a filter chip that updates when results load — add role="status" and aria-live="polite" so assistive technology announces the change:
{/* Dynamic badge — announces update */}
<Badge variant="info" role="status" aria-live="polite">
3 results
</Badge>
{/* Static badge — no ARIA role needed */}
<Badge variant="success">Confirmed</Badge>
Colour and meaning
Every badge tone conveys meaning through colour. Because colour alone is not perceivable by everyone, the label text must always carry the same meaning independently. Do not use a badge where the label text is empty or generic (e.g. "●") and colour is the only signal.
Contrast
All general-tone combinations meet WCAG 2.1 AA for normal text (4.5:1). All Kuoni product variants use full-saturation backgrounds with white or dark #1A1A1A text and meet or exceed AA at the smallest badge size (10 px semi-bold).
| Variant | Foreground | Background | Ratio | WCAG |
|---|---|---|---|---|
neutral | #666666 | #F5F5F5 | 4.6:1 | ✅ AA |
promotion | #FFFFFF | #005B55 | 8.6:1 | ✅ AAA |
exclusive | #FFFFFF | #1A1A1A | 17.4:1 | ✅ AAA |
featured | #1A1A1A | #F5C518 | 10.7:1 | ✅ AAA |
sold-out | #FFFFFF | #999999 | 2.8:1 | ⚠ use size lg |
offer | #FFFFFF | #C96742 | 3.2:1 | ⚠ use size lg |
Related components
- Chip — use instead of Badge whenever the label needs to be tappable or toggled.
- Pill — a related compact label component; see that page for the distinction from Badge.
- NotificationBadge — the count/dot indicator variant of the small-label family, typically anchored to an icon.