Skip to book
Tarva BXD · LumosIndex › Components › Card · 2/2
1920 × 1080 · Landscape
Lumos Index › Components › Card 2 of 2 · Density, states & API

Components · Card

One chrome, many densities.

No size prop and no surface accent — density lives in the content and interaction states are opt-in. Everything traces back to the eight exports of a single token-driven surface.

03 · Densityone fixed chrome — density lives in the content, not a size prop
Compact — title only
Avery L.
Senior instructor
Standard — gap-6 / py-6 / px-6
Front desk
Today’s schedule
Six classes, two open slots.

Card ships no size variant. The single token-driven chrome (gap-6 py-6 px-6 rounded-xl) keeps every surface aligned; consumers tune density by overriding className on the slots.

04 · Statesa static surface — interaction states are opt-in via the consumer
Default
border-subtle
Resting
Hairline border, soft shadow.
Hover
border-strong
Lifted
Edge firms, shadow deepens.
Focus
ring · accent
Focused
3px terracotta ring.
Active
accent-subtle
Selected
Accent tint fill.
Disabled
opacity .45
Inactive
Dimmed, no shadow.
Focus/active/hover apply only when a Card is wrapped in an interactive element (button, link, role). The base Card is presentational.
05 · Usagekeep the accent fenced; let slots do the work
Do compose with slots

Reach for CardHeader / Content / Footer rather than nesting raw divs. The grid header keeps CardAction pinned and titles aligned across a list.

Don’t paint the surface accent

Never fill a resting Card with terracotta to draw the eye. Accent belongs to the one CTA inside the footer — the surface stays white on parchment.

Do swap to Card.Skeleton

While data loads, render Card.Skeleton — it mirrors the chrome and announces “Loading” to assistive tech.

Don’t hand-roll dividers

Use the .border-b / .border-t utilities the header and footer detect — they self-apply the matching pad-bottom / pad-top.

06 · API@tarva/ui · ui/card.tsx
Exportdata-slotBase classes / role
Cardcardrounded-xl border py-6 shadow-sm · gap-6
CardHeadercard-headergrid · gap-2 · px-6 · has-action→2col
CardTitlecard-titletext-heading-4 · font-semibold
CardDescriptioncard-descriptiontext-muted-foreground · text-sm
CardActioncard-actioncol-start-2 · row-span-2 · self-start
CardContentcard-contentpx-6
CardFootercard-footerflex · items-center · px-6 · .border-t→pt-6
Card.Skeletoncard-skeletonrole=status · aria-busy · aria-label="Loading"
All exports are ComponentProps<'div'> — every native div prop plus className merged via cn(). No CVA variants, no required props.

Lumos brand book slide: Card · 2 of 2
Rotate your phone for a larger view. Tap the slide to open it full size and zoom.
8.5 × 11 · Portrait