# Badge
> Generated from badge.contract.json — do not edit by hand.

A small count or status marker — notification counts, unread dots, a standalone status label.

Tier: **leaf-lit**. Frameworks: HTML (paste-and-run, no build step) · React · Vue 3.

Surfaces: editor, dashboard, settings, audience.

## Props
| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `count` | number | `0` | The number shown in the bubble; 0 hides it unless showZero |
| `overflowCount` | number | `99` | Cap; above it renders as N+ (alias: max) |
| `showZero` | boolean | `false` | Keep the bubble visible when count is 0 |
| `dot` | boolean | `false` | Render a bare marker, no number |
| `status` | success | processing | error | warning | default | primary | `error` | Semantic colour; with `text` (no count/dot) renders a standalone dot + label |
| `text` | string | `—` | Label for a standalone status badge |
| `color` | CSS colour | `—` | Custom colour overriding the semantic default |
| `ribbon` | boolean | `false` | Wrap the slotted child (a card) with a corner ribbon banner; `text` is the label, colour from color/status (default primary) |
| `placement` | start | end | `end` | Ribbon corner: end = top-right (default), start = top-left |
| `tone` | danger | success | positive | essential | pro | branding | primary-alt | `—` | Filled/tinted LABEL chip; each tone binds bg + fg to an --aha-* token |
| `plan` | free | edu | essential | pro | enterprise | `—` | Plan preset chip (solid brand fill); pro/enterprise lead with a crown glyph |
| `cycle` | monthly | yearly | `—` | Appended to a plan chip's default label (e.g. "Pro · Yearly") |
| `rank` | 1 | 2 | 3 | 4 | `—` | Leaderboard rank chip; medal-tinted (gold/silver/bronze) with a leading system-Medal glyph |
| `session` | string | `—` | Renders a "Session N" chip; the value is N (slotted content / `text` overrides the label) |
| `href` | URL | `—` | Makes a tone/plan/rank/session chip a clickable LINK — renders <a class="chip" href> (native focusable, animates on hover), never a <button>. Omit for a static <span> chip |

## Visual standard (measured)
- Count bubble: height 18 · min-width 18 · radius pill · padding 0 6 · scales in
- On a child: floats to the child's top-right, 1px container-colour ring
- Dot: 8×8, no label
- Status: standalone 6px dot + 14px label; processing pulses
- Text: Plus Jakarta SemiBold 600, 11/18, #FFFFFF
- Default colour: count/dot → error #F5222D; status → its semantic token; ribbon → primary #6A1EBB
- Overflow / zero: count > overflowCount → N+; 0 hides unless showZero
- Ribbon: corner banner over a wrapped card; 22px tall, radius 4, triangular fold; placement start/end
- Tone chip: filled/tinted pill (radius pill, 22px); danger·success·positive·essential·pro·branding·primary-alt, each bound to an --aha token
- Plan chip: preset (free·edu·essential·pro·enterprise); solid brand fill, cycle monthly/yearly; pro/enterprise lead with a crown
- Rank chip: leaderboard 1st–4th, medal-tinted (gold/silver/bronze), leading system-Medal glyph
- Session chip: "Session N" brand-accent pill; label from `session` / slotted text
- Clickable = link: with `href` renders <a class="chip"> (native focusable link, animates on hover) — never a <button>; no href = plain <span>

## When to use
- **Badge count/dot** — a count or presence marker attached to another element (a bell, a tab, an avatar)
- **Badge status** — a standalone semantic state label (Published, Generating, Failed) in a list or header
- **Tag** — a standalone label/keyword chip with text but no status semantics

A count/dot marks another element — wrap the element it belongs to so the pill anchors to its top-right. Keep counts meaningful; cap large numbers with overflowCount so the bubble stays small. Reserve the standalone status form for a semantic lifecycle state, and let processing pulse rather than spin a separate loader.
