● Primitives / Tag
Tag.
Tag is a read-only pill for skills, stacks, and topics. It replaces one-off rounded-full spans on the about teaser, work index, posts, and selected-work cards.
How the primitive behaves
Tag renders a span with token-based border and fill. Variants are implemented with tailwind-variants so new surfaces can share tagVariants without copying class strings.
Source of truth
Custom primitive in system/primitives/tag. Exported from $lib/system.
Primitive roles
Skill chip
Neutral outline pills for grouped skills on the homepage about teaser.
Topic label
Muted fill tags on project and post cards for stack or category metadata.
Filter affordance
Read-only labels today; same styles if interactive filters are added later.
Anatomy
outline
muted (default)
Variant
outline uses border only; muted adds bg-muted for slightly stronger contrast on cards.
Shape
Rounded-full pill with text-xs and muted-foreground label color.
Children
Short text only. Keep labels concise so wraps stay even in flex groups.
Guidelines
- Import Tag from $lib/system. Do not recreate rounded-full border spans in route files.
- Use variant="outline" for dense skill lists; default muted for card tag rows.
- Wrap tags in flex flex-wrap gap-2 (or gap-1.5 for tight skill groups).
- Tags are not buttons. If a tag becomes clickable, use a button or link with explicit semantics.
- Do not use Tag for status (Live, Open to work). Use LiveBadge or StatusIndicator instead.
In practice
Homepage skills?
variant="outline" inside gap-1.5 flex wrap.
Project card metadata?
Default muted variant in gap-2 flex wrap.
Green availability?
StatusIndicator, not Tag.
Nav “Live” pill?
LiveBadge.
Related primitives
Other primitives in the system, in the same order as the documentation sidebar.