Skip to content
Components

Card

Bordered surface for grouping related content. Uses radius-container and a border; no shadow (shadows are for floating layers only).

Preview

Project

Last edited 2 hours ago.

Design tokens and components for vibe coders.

Props

  • header
  • action
  • footer
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"

<Card>
  <CardHeader>
    <CardTitle>Project</CardTitle>
    <CardDescription>Last edited 2 hours ago.</CardDescription>
  </CardHeader>
  <CardContent>Design tokens and components for vibe coders.</CardContent>
  <CardFooter>
    <Button variant="secondary">Cancel</Button>
    <Button>Save</Button>
  </CardFooter>
</Card>

Usage

When to use

  • Group related content about one subject, such as a project with its title, a short description and its actions.
  • Give the group a header, a body and at most one main action, in the footer.

When not to use

  • A single line of text or a lone value. Use a list row.
  • Content that is already inside a card. Use a divider or spacing instead.
  • A surface that acts as one button. Card is not a button; to make the whole card clickable, stretch one link over it and put no other buttons or links inside.

Examples

Default

Project

Last edited 2 hours ago.

Design tokens and components for vibe coders.
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"

<Card>
  <CardHeader>
    <CardTitle>Project</CardTitle>
    <CardDescription>Last edited 2 hours ago.</CardDescription>
  </CardHeader>
  <CardContent>Design tokens and components for vibe coders.</CardContent>
  <CardFooter>
    <Button variant="secondary">Cancel</Button>
    <Button>Save</Button>
  </CardFooter>
</Card>

With action

Project

Last edited 2 hours ago.

Design tokens and components for vibe coders.
import { Button } from "@/components/ui/button"
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"

<Card>
  <CardHeader>
    <CardTitle>Project</CardTitle>
    <CardDescription>Last edited 2 hours ago.</CardDescription>
    <CardAction>
      <Button variant="secondary" size="sm">Share</Button>
    </CardAction>
  </CardHeader>
  <CardContent>Design tokens and components for vibe coders.</CardContent>
</Card>

Do and don't

Do

  • Use Card to group related content. Give it one primary action at most, in the footer.
  • To make the whole card clickable, stretch one link over it, use color-overlay-hover on hover and show the focus ring on the card. Then don't put any other button inside.
  • Use a border, not a shadow. Shadows are for menus, popovers and dialogs.

Don't

  • Don't put a card inside a card. Use a divider (color-border) or spacing instead.
  • Don't use a card for a single line of text or a lone value. Use a list row.
  • Don't restyle the fill through className. If the surface color is wrong, open an issue instead of overriding it.

Props

Slots

NameRequiredDescription
headernoOptional header: title, description, and an optional CardAction.
contentnoMain body content.
footernoOptional footer actions or meta.

Anatomy

PartDescription
rootThe card surface: border, radius-container, background-surface.
headerTop block for title and description. Becomes a two-column grid when it holds an action.
actionOptional slot at the top right of the header (a button or menu), next to the title and description.
titlePrimary label of the card.
descriptionSupporting text under the title.
contentMain body of the card.
footerActions or meta row at the bottom.

Accessibility

Role: generic

  • Root is a plain div with no role. If a card needs to be announced as a group, add role="group" and aria-labelledby pointing at the CardTitle at the call site.
  • Card is not interactive by itself. Put buttons and links inside; do not make the whole card a button.
  • If the whole card is clickable, use one link stretched over the card (an ::after on the link with absolute inset-0; the root is relative) and no other buttons or links inside.
  • Title should be a heading level that fits the page outline (h2 or h3 in most views).

Install

npx shadcn add https://werewolf-ui.vercel.app/r/card.json

This also adds styles/werewolf.css, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after @import "tailwindcss", with a path relative to that CSS file (from app/globals.css it is @import "../styles/werewolf.css").