Badge — visual reference

Variants

variants Default Beta Critical Pending Active Info Archived

In context

heading

Pricing New

interactive

  
/*
 * Badge — element
 *
 * Inline status/category label. CSS-only — no JavaScript, no tweak slots.
 *
 *   <span class="badge">Default</span>
 *   <span class="badge -accent">Beta</span>
 *   <span class="badge -warning">Pending</span>
 */

@layer malevich.components {
  .badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    padding-block: var(--space-inset-element-s);
    padding-inline: var(--space-inset-element-m);

    background-color: var(--color-surface-raised);
    color: var(--color-ink-strong);
    border-radius: var(--radius-tag);

    font-family: var(--font-overline-family);
    font-size: var(--font-overline-size);
    font-weight: var(--font-overline-weight);
    line-height: var(--font-overline-line-height);
    letter-spacing: var(--font-overline-letter-spacing);

    text-transform: uppercase;
    white-space: nowrap;
    user-select: none;
  }

  /* ----- Variants ----- */

  .badge.-accent {
    background-color: var(--color-accent);
    color: var(--color-ink-inverse);
  }

  .badge.-danger {
    background-color: var(--color-danger);
    color: var(--color-ink-inverse);
  }

  /* Warning is bright — ink-strong text per brightness rule. */
  .badge.-warning {
    background-color: var(--color-warning);
    color: var(--color-ink-strong);
  }

  .badge.-success {
    background-color: var(--color-success);
    color: var(--color-ink-inverse);
  }

  .badge.-info {
    background-color: var(--color-info);
    color: var(--color-ink-inverse);
  }

  .badge.-muted {
    background-color: var(--color-border-muted);
    color: var(--color-ink-regular);
  }
}
This component is pure CSS — no JavaScript required.
# Badge — AGENTS.md

> Auto-generated from `badge.docs.md` + the modifier applicability matrix.
> Edit those source files; this file regenerates on build.

## Identity

- **Component:** `badge`
- **Layer:** elements
- **Status:** stable
- **Last updated:** 2026-05-17

## Summary

Use a badge to call out a piece of metadata next to a heading, list

## Variants

| Variant   | Class               | Use for                              |
|-----------|---------------------|--------------------------------------|
| Default   | `.badge`            | Neutral metadata                     |
| Accent    | `.badge.-accent`    | Highlighted state (`Beta`, `New`)    |
| Danger    | `.badge.-danger`    | Critical / error states              |
| Warning   | `.badge.-warning`   | Pending / needs attention            |
| Success   | `.badge.-success`   | Active / completed                   |
| Info      | `.badge.-info`      | Informational tags                   |
| Muted     | `.badge.-muted`     | Archived / disabled                  |

## Modifier applicability

Per ADR-0007. Modifiers attach via `data-{category}="value"` attributes.

| Category | Accepts |
|---|---|
| `background` | — |
| `surface` | `flat` |
| `effect` | — |
| `shader` | — |
| `rhythm` | — |
| `motion` | — |
| `behavior` | — |

## Anatomy

```html
<span class="badge">Default</span>
<span class="badge -accent">Beta</span>
<span class="badge -danger">Critical</span>
<span class="badge -warning">Pending</span>
<span class="badge -success">Active</span>
<span class="badge -info">Info</span>
<span class="badge -muted">Archived</span>
```

`<span>` is the appropriate semantic element — inline text content, not
a button or link.

## Tokens consumed

- `color.accent`, `color.danger`, `color.warning`, `color.success`,
  `color.info`, `color.border-muted`, `color.surface-raised`
- `color.ink-strong`, `color.ink-inverse`, `color.ink-regular`
- `font.overline-s` typography
- `radius.tag`
- `space.inset-element-s`, `space.inset-element-m`

Tier 3 (component-specific): none. Badge consumes semantic tokens
directly — the relationship is canonical, no per-component refinement
needed.

## Accessibility contract

- Use `<span>`, never `<button>` or `<a>` unless the badge IS the
  control.
- Don't rely on color alone to convey meaning — the label text carries
  the meaning, the color reinforces it.
- For interactive contexts, wrap the badge in a real button/link with
  an accessible name.

## Guidance

### Do

- Keep labels short — one or two words ideal.
- Match variant to severity: `-danger` for critical, `-warning` for
  pending, `-muted` for archived.
- Use uppercase per the overline-s token — the component handles
  text-transform automatically.

### Don't

- Don't stack multiple variants on a single badge.
- Don't use `-danger` for decorative red — reserve it for genuine
  errors.
- Don't make a badge clickable by adding `onclick`; wrap it in a
  button instead.