The house section-opener: the eyebrow above a landing section, the group title inside a card that holds several forms, the label on a demo tile. Uppercase, tracked, muted at /65 ink (the lightest small text that clears AA in light), never a tone and never a title substitute. It exists so the idiom is a component choice rather than a class recipe re-typed on every page.
The canon behind it. docs/design-language/01-foundations.md (01-foundations.md:47, the kicker idiom row: 11px, 600 weight, 0.08em tracking, uppercase, muted; :55, "adopt the kicker idiom" on the consumer checklist), docs/design-language/09-page-composition.md §A5 (09-page-composition.md:28, "One kicker idiom, five names", the house section-opener with its 30/26px rhythm), and the title sets in docs/plan/60-typography-structure.md §2 (level 3 group title and the tile label) until canon doc 12 carries them.
When to reach for it#
Four places, and only these. A group title inside a Card body when the card holds more than one form or field cluster (the level below the card title). The eyebrow above a landing section's display title. The label of a specimen or demo tile that has no card title of its own, read at close range inside its frame. The heading of a table group or sub-block, a bricked label naming a row set (doc 60 §2's label level).
Do not reach for it as a page or section title; those are PageTitle and Card title. Do not colour it; a tone on a label is a status, and status has its own components. Do not re-type it as text-xs uppercase tracking-wide anywhere: the survey behind this component counted about 76 hand-typed copies across walmart, speedway and the kit, and 176 uppercase classes in walmart alone.
Contract#
children(required): the label text; short, one line, no punctuation.variant?: "default" | "bricked"(defaultdefault).default: 11px, weight 600,0.08emtracking. The section-opener and the eyebrow.bricked: 12px, weight 600,tracking-wide. The tile label inside its own frame; one step larger and tighter so it reads as the frame's name rather than a page-level opener. Not theButtonsense ofbricked(inert); the two never meet in code.
as?: "p" | "span" | "div" | "h2" | "h3" | "h4" | "label"(defaultp). A group title inside a form is often a heading for the outline; a label naming a control islabelwithhtmlFor. In a flex row inside aCardbody passas="span"(orshrink-0): daisyUI's card CSS grows everypto fill its row, so the default element stretches and pushes its neighbour to the far edge.htmlFor?: withas="label", the control it names.className: merged last; use it for margin, never to change size, case or tracking.- Every other
HTMLAttributesprop (id,aria-*,data-*) passes through.
Sanctioned combinations#
KickeraboveCard title's h2 in a landing section (apps/playground/src/app/landing-sections.tsx, the eyebrow) withgap-2between them.Kicker variant="bricked"as the first child of aCardwith notitle, naming a demo tile (apps/playground/src/app/landing-strip.tsx, the strip's tiles).Kicker as="h3"opening each form group inside oneCard, with the card title as the level above.
Banned combinations#
Do not give a Kicker a colour class; a label is never a status. Do not use it in place of PageTitle or Card title. Do not stack two kickers with nothing between them; a kicker opens content, it is not the content. Do not pass a paragraph as children; the idiom is a two-to-four word label.
Before you adopt this#
Five questions to answer before reaching for Kicker.
- Does the shell, a parent layout, or a global provider already render this? A
Cardrenders its own title; the kicker is the level below it, never a second title. - Does this app already ship a local implementation of the same thing? Speedway's
.section-label,.panel-kicker,.rail-label,.field-label,.orch-k(doc 9 §A5) and itsSectionLabelcomponent are this idiom hand-typed; adoptKickerthere on the app's next deliberate kit upgrade, never as a ride-along. - Does this app's kit pin reach the version this component or prop landed in?
Kickerlands in the bump after 0.2.0; a pin below that has noKickerexport. - Does the component derive its own accessible name and keyboard path, or must the call site supply them? A kicker is text; pass
as="h3"when the group needs an outline entry,as="label"plushtmlForwhen it names a control. - Which canon §A rules bind this surface, and which does the composition break? Doc 9 §A5 (one idiom, never a sixth variant); the title sets in doc 60 §2 (a kicker is level 3 or a tile label, never level 1 or 2).
Travels with#
Card (the kicker sits inside its body or above its section), PageTitle (the level above; a kicker never replaces it), StatTile (whose own label is sentence case and not a kicker).
Snippet#
import { Card, Kicker } from "@versable-git/ui";<Card title="Notifications"> <Kicker as="h3">Email</Kicker> {/* the email fields */} <Kicker as="h3" className="mt-6">Slack</Kicker> {/* the slack fields */}</Card><Card> <Kicker variant="bricked">Buttons</Kicker> {/* the demo tile's content */}</Card>