# Badge Component Design Notes (WCAG)

Design rationale for the central `<.badge>` core component
(`MvWeb.CoreComponents`) and the WCAG-driven theme overrides in
`assets/css/app.css`. Before it, badges were raw `<span class="badge ...">`
markup with no central component.

## `<.badge>` API contract

- `attr :variant` — `:neutral | :primary | :info | :success | :warning | :error`
- `attr :style` — `:soft | :solid | :outline` (default: `:soft`)
- `attr :size` — `:sm | :md` (default: `:md`)
- `attr :sr_label` — optional screen-reader label for icon-only badges
- `slot :icon` — optional
- `slot :inner_block` — badge text

## Design rules

- `:soft` and `:solid` use a visible background; `:soft` is the default. No
  transparent ghost as a default.
- `:outline` **always** sets a background (e.g. `bg-base-100`) so the border
  stays visible on grey (`base-200`/`base-300`) surfaces.
- Ghost only as an explicit opt-in, and then with `bg-base-100` for visibility
  (plain DaisyUI `badge-ghost` is `base-200` on `base-200` — nearly invisible).
- Clickable chips keep `<.badge>` as a plain container with a button in the
  `inner_block`.

## WCAG contrast overrides (`app.css`)

DaisyUI defaults do not reach the WCAG 2.2 AA **4.5:1** text-contrast ratio for
badges, so `app.css` adds per-theme overrides on top of the custom `light` /
`dark` themes:

- **Light theme:** darker `--badge-fg` for all solid variants; darker text on
  `badge-soft`'s tinted background; uniform dark text for `badge-outline` on
  `base-100`.
- **Dark theme:** slightly darkened solid-badge backgrounds so the light
  `*-content` colors reach 4.5:1; lighter, readable variant tints for
  `badge-soft`; light `--badge-fg` for `badge-outline` on `base-100`.

Related: contrast overrides for the member-filter join buttons
(`.member-filter-dropdown .join .btn`) under the same 4.5:1 rule.

## Variant helpers

- `MembershipFeeHelpers.status_variant/1` → `:success | :error | :warning`.
  `status_variant(:suspended) -> :warning` (yellow) deliberately matches the
  Edit button (`btn-warning`), keeping the "suspended" badge the same color as
  its action.
- `RoleLive.Helpers.permission_set_badge_variant/1` →
  `:neutral | :info | :success | :error`.
- `MembershipFeeStatus.format_cycle_status_badge/1` additionally returns a
  `:variant` for `<.badge>`.
