Card

A static content surface, styled by the card recipe. The recipe standardizes the surface — background, border radius, and border — so cards look the same everywhere; consumers only choose a padding density and whether the card is flat or elevated.

Card renders a plain div with no interaction semantics. To make a card clickable, put a link or button inside it rather than making the surface itself interactive.

import { Card } from "@pockets-ui/components"

Basic

Rental analysis

Run the numbers on a property before you make an offer — cash flow, cap rate, and cash-on-cash return.

Code
import { Card } from "@pockets-ui/components"
import { css } from "@/styled-system/css"

export default function CardBasic() {
  return (
    <Card css={{ maxWidth: "sm" }}>
      <h3
        className={css({
          textStyle: "body.default.semibold",
          marginBottom: "2",
        })}
      >
        Rental analysis
      </h3>
      <p
        className={css({ color: "fg.subtle", textStyle: "body.small.regular" })}
      >
        Run the numbers on a property before you make an offer — cash flow, cap
        rate, and cash-on-cash return.
      </p>
    </Card>
  )
}

Padding

padding is a density scale, not a size scale — the surface itself doesn't change, only how much air the content gets. compact suits dense dashboards, comfortable (the default) is the general-purpose density, and spacious suits marketing or empty-state surfaces.

Compact
Comfortable
Spacious
Code
import { Card } from "@pockets-ui/components"

export default function CardPadding() {
  return (
    <>
      <Card padding="compact">Compact</Card>
      <Card padding="comfortable">Comfortable</Card>
      <Card padding="spacious">Spacious</Card>
    </>
  )
}

Variants

outline (the default) sits flat with a visible border; elevated softens the border and adds a shadow for surfaces that should read as raised.

Outline
Elevated
Code
import { Card } from "@pockets-ui/components"

export default function CardVariants() {
  return (
    <>
      <Card variant="outline">Outline</Card>
      <Card variant="elevated">Elevated</Card>
    </>
  )
}

Edge-to-edge content

padding="none" removes the inset so media can bleed to the card's edge — the surface clips children to its radius. Pad the inner sections yourself.

Edge-to-edge media

With padding="none" the surface clips content to its radius; pad the inner sections yourself.

Code
import { Card } from "@pockets-ui/components"
import { css } from "@/styled-system/css"

export default function CardEdgeToEdge() {
  return (
    <Card padding="none" css={{ maxWidth: "sm" }}>
      <div
        aria-hidden="true"
        className={css({
          height: "24",
          backgroundColor: "bg.action",
        })}
      />
      <div className={css({ padding: "6" })}>
        <h3
          className={css({
            textStyle: "body.default.semibold",
            marginBottom: "2",
          })}
        >
          Edge-to-edge media
        </h3>
        <p
          className={css({
            color: "fg.subtle",
            textStyle: "body.small.regular",
          })}
        >
          With <code>padding="none"</code> the surface clips content to its
          radius; pad the inner sections yourself.
        </p>
      </div>
    </Card>
  )
}

One-off overrides

Every Pockets component takes a css prop for style overrides that don't deserve a recipe variant. The same properties work as individual style props, and a plain React style object passes through too.

<Card css={{ maxWidth: "md", textAlign: "center" }}>…</Card>
<Card maxW="md" textAlign="center">…</Card>
<Card style={{ height: measuredHeight }}>…</Card>