Skip to content

Card

Surface component used for grouping content, actions, and metadata in PyColors UI.

The Card component is a foundational surface used to group related content: dashboards, pricing blocks, settings panels, and list items.

It is built on semantic tokens (bg-card, border-border, text-card-foreground) so it stays consistent across themes, and it supports surface variants + an optional interactive state for hover/focus feedback.


Import

import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from from "@pycolors/ui";

Usage

Account

Manage your profile settings.

Update personal details, security preferences, and integrations.

<Card>
  <CardHeader>
    <CardTitle>Account</CardTitle>
    <CardDescription>Manage your profile settings.</CardDescription>
  </CardHeader>

  <CardContent>...</CardContent>

  <CardFooter>...</CardFooter>
</Card>
import {
  Button,
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from "@pycolors/ui";

export default function Demo() {
  return (
    <Card className="max-w-sm">
      <CardHeader>
        <CardTitle>Account</CardTitle>
        <CardDescription>Manage your profile settings.</CardDescription>
      </CardHeader>

      <CardContent>
        <div className="text-sm text-muted-foreground">
          Update personal details, security preferences, and integrations.
        </div>
      </CardContent>

      <CardFooter className="justify-end gap-2">
        <Button variant="secondary">Cancel</Button>
        <Button>Save</Button>
      </CardFooter>
    </Card>
  );
}

Variants

Cards support semantic surface variants. Use them to adjust contrast without changing layout.

Default

Standard surface.

Muted

Subtle background for secondary panels.

Transparent

No background (keeps layout only).

<Card />
<Card variant="muted" />
<Card variant="transparent" />
import { Card, CardHeader, CardTitle, CardDescription } from "@pycolors/ui";

export function CardVariantsExample() {
  return (
    <div className="grid gap-4 sm:grid-cols-3">
      <Card>
        <CardHeader>
          <CardTitle>Default</CardTitle>
          <CardDescription>Standard surface.</CardDescription>
        </CardHeader>
      </Card>

      <Card variant="muted">
        <CardHeader>
          <CardTitle>Muted</CardTitle>
          <CardDescription>Subtle background.</CardDescription>
        </CardHeader>
      </Card>

      <Card variant="transparent">
        <CardHeader>
          <CardTitle>Transparent</CardTitle>
          <CardDescription>No background.</CardDescription>
        </CardHeader>
      </Card>
    </div>
  );
}

Available variants

VariantDescription
defaultMain surface (bg-card)
mutedSecondary surface (bg-muted/40)
transparentNo background (bg-transparent)

Interactive cards

Set interactive to add hover + focus styles. This is useful for selectable list rows, dashboard tiles, and grid cards.

Clickable card

Hover / focus to see feedback.

Interactive + muted

Great for secondary selection items.

<Card interactive>...</Card>
<Card interactive variant="muted">...</Card>
import { Card, CardHeader, CardTitle, CardDescription } from "@pycolors/ui";

export function InteractiveCards() {
  return (
    <div className="grid gap-4 sm:grid-cols-2">
      <Card interactive>
        <CardHeader>
          <CardTitle>Clickable card</CardTitle>
          <CardDescription>Hover / focus to see feedback.</CardDescription>
        </CardHeader>
      </Card>

      <Card interactive variant="muted">
        <CardHeader>
          <CardTitle>Interactive + muted</CardTitle>
          <CardDescription>Great for secondary selection items.</CardDescription>
        </CardHeader>
      </Card>
    </div>
  );
}

Recommendation: if the card is actually a navigation element, prefer asChild with a real <a> (or next/link) so semantics are correct.


As child (Slot)

Use asChild to render the Card as another element while keeping the Card styling. Perfect for cards that are links.

<Card asChild interactive>
  <a href="/docs" className="block">...</a>
</Card>
import { Card, CardHeader, CardTitle, CardDescription } from "@pycolors/ui";

export function CardAsLink() {
  return (
    <Card asChild interactive className="max-w-sm">
      <a href="/docs" className="block">
        <CardHeader>
          <CardTitle>Read the docs</CardTitle>
          <CardDescription>Go to documentation →</CardDescription>
        </CardHeader>
      </a>
    </Card>
  );
}

API

Props

PropTypeDefaultDescription
variantCardVariant"default"Surface style
interactivebooleanfalseAdds hover + focus-visible feedback
asChildbooleanfalseRender via Radix Slot (link cards, sections, etc.)
classNamestringAdditional Tailwind classes

The Card extends standard HTML div props:

React.HTMLAttributes<HTMLDivElement>

TypeScript types

export type CardVariant = "default" | "muted" | "transparent";
export type CardInteractive = boolean;

Accessibility

  • Keep structure consistent: CardHeader → title/description → CardContentCardFooter.
  • If the Card is clickable, prefer asChild with a semantic target (a, button).
  • Avoid multiple nested interactive elements inside an interactive Card.
  • Ensure focus is visible (enabled automatically via interactive).

Design guidelines

  • Use Cards for grouping and layout rhythm, not decoration.
  • Use muted for secondary surfaces and dense layouts.
  • Use transparent for “layout-only” containers (e.g., in a stacked list).
  • Use interactive only for selectable / navigational surfaces.