Agent docs

Kicker

The small uppercase label that opens a section or names a tile; one primitive, two sizes.

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" (default default).
    • default: 11px, weight 600, 0.08em tracking. 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 the Button sense of bricked (inert); the two never meet in code.
  • as?: "p" | "span" | "div" | "h2" | "h3" | "h4" | "label" (default p). A group title inside a form is often a heading for the outline; a label naming a control is label with htmlFor. In a flex row inside a Card body pass as="span" (or shrink-0): daisyUI's card CSS grows every p to fill its row, so the default element stretches and pushes its neighbour to the far edge.
  • htmlFor?: with as="label", the control it names.
  • className: merged last; use it for margin, never to change size, case or tracking.
  • Every other HTMLAttributes prop (id, aria-*, data-*) passes through.

Sanctioned combinations#

  • Kicker above Card title's h2 in a landing section (apps/playground/src/app/landing-sections.tsx, the eyebrow) with gap-2 between them.
  • Kicker variant="bricked" as the first child of a Card with no title, naming a demo tile (apps/playground/src/app/landing-strip.tsx, the strip's tiles).
  • Kicker as="h3" opening each form group inside one Card, 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.

  1. Does the shell, a parent layout, or a global provider already render this? A Card renders its own title; the kicker is the level below it, never a second title.
  2. 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 its SectionLabel component are this idiom hand-typed; adopt Kicker there on the app's next deliberate kit upgrade, never as a ride-along.
  3. Does this app's kit pin reach the version this component or prop landed in? Kicker lands in the bump after 0.2.0; a pin below that has no Kicker export.
  4. 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" plus htmlFor when it names a control.
  5. 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>
@versable-git/ui · reference, canon, and method, read in place