# Atoms — Badge

An uppercase **pill** that labels a product on its card: *New*, *Best tested*, *Pre-order*. Built
from Gazelle's **Tailwind v4 utilities**: a single `<span>` with a light Gazelle-blue fill and the
Label type role. The copy field on the Atoms → Badge screen emits this exact markup. A
framework-free `.gz-badge` API in `components/badge.css` mirrors the same design for projects not on
Tailwind.

## Metadata

- **Category:** Atoms
- **Status:** Stable
- **Source:** `docs/atom-classes.js` (`GZ_ATOM_CLASSES.badge` + `GZ_ATOM_MARKUP.badge`, canonical
  markup); `components/badge.css` (`.gz-badge` framework-free compatibility API)
- **Production source:** `gazelle-int-website/app/components/ProductBadge.vue` (staging,
  `e1acfea4`)

## When to use

- One short product label on a product card, in the image's top-left corner (Bike card). The
  text comes from the product data (`badge.text`).
- Labels a product state, not an action. It is not clickable.

## When not to use

- Not for counts or notification dots. That is a different, smaller element.
- Not for more than one label per card. Pick the most important one.
- Not as a button or filter chip: it has no hover, focus or selected state.
- Keep it to one or two words. It never wraps (`inline-flex`, single line).

## Anatomy

```html
<span class="inline-flex items-center rounded-full bg-brand-blue-gazelle-50 px-3 type-label-sm text-fg-primary py-2">
  New
</span>
```

On a card the badge is absolutely positioned by the card, which adds `absolute left-0 top-0 z-10`
in front of the atom's classes (`GZ_ATOM_MARKUP.badge({ className })`).

## Class lists

| Part | Utilities |
| --- | --- |
| **Base** | `inline-flex items-center rounded-full bg-brand-blue-gazelle-50 px-3 type-label-sm text-fg-primary` |
| **Size — Small** (28px) | `py-2` |
| **Size — Large** (32px) | `py-2.5` |
| **Step — `lg-tablet`** (Small → Large from tablet) | `tablet:py-2.5` |

## Tokens

- Fill `bg-brand-blue-gazelle-50` (`#f2f7fd`), text `text-fg-primary`, shape `rounded-full`.
- Type: **Label Small** (`type-label-sm`, 12px, medium, +5% tracking, uppercase, leading 100).

## Production mapping

| Part | Production | Design system | Decision |
| --- | --- | --- | --- |
| Fill | `bg-functional-blue-200` (`#edf5fd`) | `bg-brand-blue-gazelle-50` (`#f2f7fd`) | There is no functional-blue scale in Gazelle. The nearest existing token is a barely visible step lighter |
| Type | `text-xxs tablet:text-[12px] font-regular tracking-[0.8px] leading-[1.25] uppercase` (11 → 12px, 400) | `type-label-sm` (12px, 500, +5%, leading 100) | Label is the system's uppercase UI role. It is 1px larger on mobile and one weight heavier. The Badge type role (bold) was not used: production is regular weight |
| Padding | `px-03 py-[7px] tablet:py-[9px]` (≈28 → 33px tall) | `px-3 py-2` + `tablet:py-2.5` (28 → 32px) | 4px-grid steps; 1px shorter from tablet |
| Text colour | `text-main-black-500` | `text-fg-primary` | Exact |

## Usage

- Pass the product's own label text; don't uppercase it in data. The type role does that.
- Use the `lg-tablet` step on product cards, so the badge grows with the card's other parts.

## Cross-references

- `specs/foundations/typography.md` — the Label role.
- `specs/molecules/bike-card.md` — where the badge sits on a card.
