Card

A versatile card component for grouping related content. Card uses the Panel core component as its surface layer, supporting the same theming system — feedback colors, background styles, border, and radius control — while adding a structured layout with optional header (heading, subheading, leading, trailing), a content area, and an optional footer.

Default

Card Title

A brief description of the card content

Card body content goes here. This is the main content area of the card.

Footer info
Action

Elevated Card

With shadow and hover effect

An elevated card with interactive hover state.

---
import Card from "../Card.astro";
import { stack } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
---

<div class={stack({ gap: "md", direction: "column", width: "100%" })}>
  <Card
    header={{
      heading: "Card Title",
      subheading: "A brief description of the card content",
    }}
    footer={{
      leading: "Footer info",
      trailing: "Action",
    }}
  >
    <p class={css({ margin: "0" })}>
      Card body content goes here. This is the main content area of the card.
    </p>
  </Card>

  <Card
    background="elevated"
    header={{
      heading: "Elevated Card",
      subheading: "With shadow and hover effect",
    }}
    interactive
  >
    <p class={css({ margin: "0" })}>
      An elevated card with interactive hover state.
    </p>
  </Card>
</div>

Size

The size prop controls the padding of the header, content, and footer sections, as well as the heading font size.

Small

Small Card

Compact padding and font sizes

Small card body content.

Footer
Action

Medium (default)

Medium Card

Default padding and font sizes

Medium card body content.

Footer
Action

Large

Large Card

Generous padding and font sizes

Large card body content.

Footer
Action
---
import Card from "../Card.astro";
import { stack } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
---

<div class={stack({ gap: "lg", direction: "column", width: "100%" })}>
  <div>
    <h3>Small</h3>
    <Card
      size="sm"
      header={{
        heading: "Small Card",
        subheading: "Compact padding and font sizes",
      }}
      footer={{ leading: "Footer", trailing: "Action" }}
    >
      <p class={css({ margin: "0" })}>Small card body content.</p>
    </Card>
  </div>

  <div>
    <h3>Medium (default)</h3>
    <Card
      size="md"
      header={{
        heading: "Medium Card",
        subheading: "Default padding and font sizes",
      }}
      footer={{ leading: "Footer", trailing: "Action" }}
    >
      <p class={css({ margin: "0" })}>Medium card body content.</p>
    </Card>
  </div>

  <div>
    <h3>Large</h3>
    <Card
      size="lg"
      header={{
        heading: "Large Card",
        subheading: "Generous padding and font sizes",
      }}
      footer={{ leading: "Footer", trailing: "Action" }}
    >
      <p class={css({ margin: "0" })}>Large card body content.</p>
    </Card>
  </div>
</div>

With Buttons and Icons

The card’s header and footer slots accept rich content. Place an icon in the leading position to help users identify the card’s category at a glance, add a ghost button to trailing for contextual actions like settings or a menu, and use the footer trailing for primary and secondary action buttons.

Icon in Header

Document

Last edited 2 hours ago

Draft

An icon in the header leading slot helps users quickly identify the card's category or type at a glance.

Button in Header

Project Settings

Configure your project preferences

Beta

A ghost icon button in the header trailing slot is a common pattern for contextual actions like editing, sharing, or opening a menu.

Buttons in Footer

User Profile

Update your personal information

Active

Action buttons in the footer trailing slot follow a standard confirm/cancel pattern, keeping primary actions clearly separated from the card's content.

---
import Card from "../Card.astro";
import Button from "@pindoba/astro-button";
import Badge from "@pindoba/astro-badge";
import { Icon } from "astro-icon/components";
import { stack, flex } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
---

<div class={stack({ gap: "xl", direction: "column" })}>
  <div>
    <h3>Icon in Header</h3>
    <Card
      header={{
        heading: "Document",
        subheading: "Last edited 2 hours ago",
      }}
    >
      <Icon name="lucide:file-text" size={20} slot="heading-leading" />
      <Icon name="lucide:clock" size={14} slot="subheading-leading" />
      <Badge feedback="warning" slot="header-trailing">
        <Icon name="lucide:pencil" class={css({ w: "1em", h: "1em" })} />
        Draft
      </Badge>
      <p class={css({ margin: "0" })}>
        An icon in the header leading slot helps users quickly identify the
        card's category or type at a glance.
      </p>
    </Card>
  </div>

  <div>
    <h3>Button in Header</h3>
    <Card
      header={{
        heading: "Project Settings",
        subheading: "Configure your project preferences",
      }}
    >
      <Icon name="lucide:settings" size={20} slot="header-leading" />
      <div class={flex({ gap: "sm", align: "center" })} slot="header-trailing">
        <Badge feedback="primary" emphasis="secondary">
          <Icon
            name="lucide:flask-conical"
            class={css({ w: "1em", h: "1em" })}
          />
          Beta
        </Badge>
        <Button emphasis="ghost" shape="circle">
          <Icon name="lucide:ellipsis" />
        </Button>
      </div>
      <p class={css({ margin: "0" })}>
        A ghost icon button in the header trailing slot is a common pattern for
        contextual actions like editing, sharing, or opening a menu.
      </p>
    </Card>
  </div>

  <div>
    <h3>Buttons in Footer</h3>
    <Card
      header={{
        heading: "User Profile",
        subheading: "Update your personal information",
      }}
    >
      <Icon name="lucide:user" size={20} slot="heading-leading" />
      <Badge feedback="success" slot="header-trailing">
        <Icon name="lucide:circle-check" class={css({ w: "1em", h: "1em" })} />
        Active
      </Badge>
      <p class={css({ margin: "0" })}>
        Action buttons in the footer trailing slot follow a standard
        confirm/cancel pattern, keeping primary actions clearly separated from
        the card's content.
      </p>
      <div class={flex({ gap: "sm" })} slot="footer-trailing">
        <Button emphasis="secondary">Cancel</Button>
        <Button>Save</Button>
      </div>
    </Card>
  </div>
</div>

Custom Styling

The passThrough prop provides escape hatches for advanced customization: style accepts any Panda CSS SystemStyleObject applied to any slot, and props forwards arbitrary HTML attributes.

Custom Styled Card

Using passThrough for advanced customization

This card uses passThrough to apply custom styles to specific slots.

---
import Card from "../Card.astro";
import { stack } from "@pindoba/styled-system/patterns";
import { css } from "@pindoba/styled-system/css";
---

<div class={stack({ gap: "md", direction: "column", width: "100%" })}>
  <Card
    feedback="primary"
    border="default"
    header={{
      heading: "Custom Styled Card",
      subheading: "Using passThrough for advanced customization",
    }}
    passThrough={{
      root: {
        style: { borderStyle: "dashed" },
      },
      heading: {
        style: { color: "primary.text" },
      },
    }}
  >
    <p class={css({ margin: "0" })}>
      This card uses passThrough to apply custom styles to specific slots.
    </p>
  </Card>
</div>

Props

Prop
size
size

Controls padding for header, content, and footer sections, and the heading font size. sm: compact. md: default. lg: generous.

Type "sm" | "md" | "lg"
Default "md"
Required No
background
background

Surface background style forwarded to Panel. surface: standard surface color. sunken: recessed background. elevated: raised with shadow. transparent: no background.

Type "surface" | "sunken" | "elevated" | "transparent"
Default "surface"
Required No
feedback
feedback

Semantic color palette forwarded to Panel.

Type "neutral" | "primary" | "success" | "warning" | "danger"
Default "neutral"
Required No
border
border

Box-shadow ring border forwarded to Panel.

Type "none" | "default" | "bold" | "muted"
Default "none"
Required No
radius
radius

Border radius of the card, forwarded to Panel.

Type "none" | "5xs" | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "8xl" | "9xl" | "10xl" | "11xl" | "full"
Default "xl"
Required No
padding
padding

Outer padding of the card, forwarded to Panel. Note: header, content, and footer have their own internal padding controlled by size.

Type "none" | "5xs" | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
Default "none"
Required No
interactive
interactive

Apply pointer cursor and hover/active states.

Type boolean
Default false
Required No
accent
accent

Use the full-color (500) palette color as the background.

Type boolean
Default false
Required No
translucent
translucent

Apply a frosted glass effect with backdrop blur.

Type boolean
Default false
Required No
header
header

Configuration object for the card header section.

Type PrimitiveCardHeaderProps
Default undefined
Required No
footer
footer

Configuration object for the card footer section.

Type PrimitiveCardFooterProps
Default undefined
Required No
passThrough
passThrough

Custom styling and props for card slots. Each slot accepts style (SystemStyleObject) and props (HTML attributes).

Type { root?: { style?: SystemStyleObject; props?: HTMLAttributes<HTMLDivElement> }; header?: { style?: SystemStyleObject }; content?: { style?: SystemStyleObject }; footer?: { style?: SystemStyleObject }; heading?: { style?: SystemStyleObject }; subheading?: { style?: SystemStyleObject }; ... }
Default undefined
Required No
...rest
...rest

Standard HTML div attributes

Type HTMLAttributes<HTMLDivElement>
Default -
Required No

Header Props (PrimitiveCardHeaderProps)

Prop
heading
heading

Main heading content. Can be a string, or an object with content, leading, and trailing.

Type string | TitleWithLeadingTrailing
Default undefined
Required No
subheading
subheading

Subheading content below the main heading.

Type string | TitleWithLeadingTrailing
Default undefined
Required No
leading
leading

Content displayed at the start of the header (e.g., an icon).

Type string | Snippet
Default undefined
Required No
trailing
trailing

Content displayed at the end of the header.

Type string | Snippet
Default undefined
Required No
passThrough
passThrough

Custom styling and props for header slots.

Type object
Default undefined
Required No
Prop
leading
leading

Content displayed at the start of the footer.

Type string | Snippet
Default undefined
Required No
trailing
trailing

Content displayed at the end of the footer.

Type string | Snippet
Default undefined
Required No
children
children

Main footer content.

Type Snippet
Default undefined
Required No
passThrough
passThrough

Custom styling and props for footer slots.

Type object
Default undefined
Required No

TitleWithLeadingTrailing Interface

Prop
content
content

The main content of the title.

Type string | Snippet
Default -
Required Yes
leading
leading

Content before the title.

Type string | Snippet
Default undefined
Required No
trailing
trailing

Content after the title.

Type string | Snippet
Default undefined
Required No