Status badge

A badge has exactly one meaning: the current status of the thing it sits next to (a registration, an invoice, a training). It is not a button, not a filter and not a counter — use a chip for things you press and a count bubble for unread numbers.

The tone maps a status to a colour family and icon (design guide §9.3): success done/paid (check-circle), warning needs attention or is waiting (alert-triangle), danger failed or overdue (alert-circle), info planned, new or neutral information (info), neutral draft/archived/inactive (grey, no icon). It is written to the data-status attribute. The text always carries the meaning; icon and colour only support it. The club accent is never a status colour (§2.4), so there is no accent badge.

Keep the label short (one to three words) and use the same wording for the same status everywhere (glossary, UX guide §9.3).

Examples

Waiting for approval

Wartet auf Freigabe
Data
render({
  "label": "Wartet auf Freigabe",
  "tone": "warning"
})
Markup
<span class="badge" data-status="warning"><svg class="icon" data-size="sm" aria-hidden="true"><use href="../../packages/ui/icons/icons.svg#alert-triangle"/></svg>Wartet auf Freigabe</span>

Done

Bezahlt
Data
render({
  "label": "Bezahlt",
  "tone": "success"
})
Markup
<span class="badge" data-status="success"><svg class="icon" data-size="sm" aria-hidden="true"><use href="../../packages/ui/icons/icons.svg#check-circle"/></svg>Bezahlt</span>

Failed

Fehler in Webling
Data
render({
  "label": "Fehler in Webling",
  "tone": "danger",
  "title": "Die Übertragung schlug am 01.10. fehl."
})
Markup
<span class="badge" data-status="danger" title="Die Übertragung schlug am 01.10. fehl."><svg class="icon" data-size="sm" aria-hidden="true"><use href="../../packages/ui/icons/icons.svg#alert-circle"/></svg>Fehler in Webling</span>

Neutral (draft)

Entwurf
Data
render({
  "label": "Entwurf"
})
Markup
<span class="badge">Entwurf</span>

New / planned

Neu
Data
render({
  "label": "Neu",
  "tone": "info"
})
Markup
<span class="badge" data-status="info"><svg class="icon" data-size="sm" aria-hidden="true"><use href="../../packages/ui/icons/icons.svg#info"/></svg>Neu</span>

Data contract

What render(data) accepts — validated against this JSON Schema in development and tests. Unknown fields are rejected. The same schema is in components.json.

FieldTypeRequiredDefaultDescription
labelstringrequired—Status text, e.g. "Wartet auf Freigabe", "Bezahlt", "Fehler in Webling".
min 1 chars
tone"neutral" | "info" | "success" | "warning" | "danger"optional"neutral"Status, rendered as data-status + leading icon. neutral (draft, inactive; no icon), info (planned, new), success (done, paid), warning (waiting, needs attention), danger (failed, overdue).
titlestringoptional—Optional tooltip with more detail ("seit 3 Tagen offen"). Not announced reliably; never put essential information only here.
JSON Schema
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "label"
  ],
  "properties": {
    "label": {
      "type": "string",
      "minLength": 1,
      "description": "Status text, e.g. \"Wartet auf Freigabe\", \"Bezahlt\", \"Fehler in Webling\"."
    },
    "tone": {
      "type": "string",
      "enum": [
        "neutral",
        "info",
        "success",
        "warning",
        "danger"
      ],
      "default": "neutral",
      "description": "Status, rendered as `data-status` + leading icon. `neutral` (draft, inactive; no icon), `info` (planned, new), `success` (done, paid), `warning` (waiting, needs attention), `danger` (failed, overdue)."
    },
    "title": {
      "type": "string",
      "description": "Optional tooltip with more detail (\"seit 3 Tagen offen\"). Not announced reliably; never put essential information only here."
    }
  }
}

Markup & states

Root: span.badge — usable without render() by writing the markup directly.

Attributes

AttributeValuesDefaultDescription
data-statusinfo | success | warning | danger(none = neutral)Status: subtle background + status text colour.
titletext—Optional tooltip.

Parts

PartDescription
svg.icon[data-size="sm"]Leading status icon (16 px, decorative): info · check-circle · alert-triangle · alert-circle. None for neutral.

Accessibility

  • The status is real text; colour and icon are decorative support (design guide §3.5 "never colour alone"). The icon is aria-hidden.
  • Every tone pairs a *-subtle background with its *-text token, which are verified for 4.5:1 contrast in light and dark themes.
  • If the status changes while the user watches (e.g. after saving), announce it with the save status or a live region — the badge itself is not live.

Guidance

DoUse one fixed vocabulary per status across all apps ("Wartet auf Freigabe", not "Pending" here and "Offen" there).
DoPlace the badge in the row aside, the card header or a table "Status" column.
Don'tDon't make badges clickable — use a chip or a link.
Don'tDon't use badges for counts ("3") — use the count bubble.
Don'tDon't show raw codes ("ERR_422") as badge text.

Related: Count bubble · Chip group · List · Table · Card