---
title: "card"
description: "A box around content (text, lists, buttons or other blocks), its title its first heading, in one of the theme's looks."
canonical_url: "http://localhost:3000/components/cards-and-grids/card"
---
# card

> A box around content (text, lists, buttons or other blocks), its title its first heading, in one of the theme's looks.

`::card` puts a box around content: a title, text, lists, buttons, or other blocks such as a form. Cards go in a section (a `page-section`), alone or side by side in a [`grid`](http://localhost:3000/components/cards-and-grids/grid).

## Usage

The content of the card is its default slot: its first heading (`##`, `###` or `####`) is its title, styled by the card's look.

```mdc
::card
### Join the working group

Members take part in the decisions and shape the specifications.
::
```

Options to try:

- `variant`: **bordered**, elevated, filled, tinted, highlight, gradient, promo, plain, minimal, translucent
- `padding`: **default**, small
- `layout`: **flow**, stack
- `width`: **auto**, narrow

### Variant

Use the `variant` option to change the card's look. Its values are the site theme's:

`variant` values in this theme: **bordered**, elevated, filled, tinted, highlight, gradient, promo, plain, minimal, translucent.

```mdc
::card{variant="elevated"}
### A card

A short text in the card.
::
```

### Link

Use the `href` option to make the whole card a link (`new-tab` opens it in a new tab): don't put other links in it. The `icon` option shows an icon above the content.

```mdc
::grid
  :::card{href="/membership/" icon="lucide:users"}
  ### Become a member

  The levels of membership and how to join.
  :::

  :::card{href="https://www.eclipse.org/" new-tab}
  ### Eclipse Foundation

  The foundation the working group is part of.
  :::
::
```

### Layout

Use the `layout` option to stack the blocks of a card with even gaps and push its last one to the bottom (`stack`): in a row of cards, their buttons line up.

```mdc
::grid
  :::card{layout="stack"}
  ### Starter

    ::::styled-list
    - One participant
    - The public meetings
    ::::

    ::::button-link{href="/membership/"}
    Choose
    ::::
  :::

  :::card{layout="stack"}
  ### Full

    ::::styled-list
    - Every employee of the organisation
    - The committees and their votes
    - The task forces
    ::::

    ::::button-link{href="/membership/"}
    Choose
    ::::
  :::
::
```

### Width

Use the `width` option to center a card in a narrower column (`narrow`), e.g. a single card in a section.

## Examples

### Cards in a grid

Side by side in a `grid`, cards on a row share its height.

```mdc
::grid
  :::card
  ### Participate

  Join the discussions and the task forces.
  :::

  :::card
  ### Contribute

  Send feedback on the drafts, review and propose changes.
  :::

  :::card
  ### Follow

  Read the news and come to the events.
  :::
::
```

## Notes

- The title is the first heading: `##` for a large card on its own, `###` in a grid, `####` for small cards. A card without a heading has no title.
- Images in a card are Markdown images, or `media` blocks for a crop, corners or a caption.
- A card has no named slots, so its text and its blocks can come in any order, at any depth (the [nesting rules](http://localhost:3000/writing-pages/rules) are about named slots).
- A card's look never depends on where it is: the same `variant` looks the same in any section. A theme may have looks made for dark sections (see its notes below).
- Related: [`grid`](http://localhost:3000/components/cards-and-grids/grid) (cards side by side), [`content-card`](http://localhost:3000/components/cards-and-grids/content-card) (a card with a large title and a second column), [`link-tile`](http://localhost:3000/components/cards-and-grids/link-tile) (a small linked tile).

## API

### Options

- `variant` (the theme's values): **bordered**, elevated, filled, tinted, highlight, gradient, promo, plain, minimal, translucent — Look of the card
- `icon`: string — Icon above the content, e.g. fa6-solid:palette or lucide:landmark
- `href`: string — Make the whole card a link to this URL
- `new-tab`: boolean, default **false** — Open the link in a new tab
- `padding` (the theme's values): **default**, small — Inner space
- `layout` (the theme's values): **flow**, stack — Its content as text (flow), or its blocks stacked with even gaps, the last one at the bottom (stack: in a row of cards, their buttons line up)
- `width` (the theme's values): **auto**, narrow — Width: auto, or narrow (a narrower column, centered)
- `spacing-top`: **none**, small, medium, large, x-large — Space above the block
- `spacing-bottom`: **none**, small, medium, large, x-large — Space below the block

### Slots

- `default` — The card's content: a leading heading (its title), text, lists and blocks

## Theme

The card's class map in the site's theme: the classes of its parts by option value.

```ts [app/theme/card.ts]
import type { ThemeOf } from '#solstice-ui/utils/ui'

// Rounded boxes with a square icon tile; dark looks are dark surfaces. Only
// linked cards move on hover: they lift, their icon tile turning to the brand
// colour.
const TITLE = 'text-h3 text-highlighted text-balance mb-3 last:mb-0'

export default {
  slots: {
    base: 'group relative block rounded-3xl text-default transition-[translate,box-shadow,border-color,background-color] duration-500 ease-smooth',
    icon: 'mb-6 grid size-15 place-items-center rounded-tile bg-primary-50 text-primary transition-[rotate,scale,background-color,color] duration-500 ease-smooth dark:bg-primary/10',
    iconGlyph: 'size-7',
    title: TITLE,
  },
  variants: {
    variant: {
      'bordered': 'border border-default bg-elevated',
      'elevated': { base: 'bg-elevated shadow-raised', title: `${TITLE} mb-5` },
      'filled': 'surface-dark overflow-hidden bg-band',
      'tinted': 'bg-primary-50 text-default dark:bg-primary/10',
      'highlight': {
        base: 'border border-default bg-elevated text-center text-[clamp(1.5rem,2.6vw,2.25rem)] leading-tight font-extrabold tracking-tight text-primary',
      },
      'gradient': {
        base: 'surface-dark overflow-hidden bg-band text-center',
        title: 'text-h2 text-highlighted text-balance mb-5 last:mb-0',
      },
      'promo': {
        base: 'overflow-hidden border border-default bg-[radial-gradient(60%_80%_at_100%_100%,color-mix(in_oklab,var(--color-secondary-400)_18%,transparent),transparent_70%),linear-gradient(170deg,var(--color-primary-50),var(--color-tertiary-25))] dark:bg-[radial-gradient(60%_80%_at_100%_100%,color-mix(in_oklab,var(--color-secondary-400)_18%,transparent),transparent_70%),linear-gradient(170deg,color-mix(in_oklab,var(--color-primary-500)_14%,var(--surface-bg)),var(--surface-bg-muted))]',
        title: 'text-h2 text-highlighted text-balance mb-5 last:mb-0',
      },
      'plain': {
        base: 'rounded-2xl bg-elevated shadow-[0_8px_30px_color-mix(in_oklab,var(--color-tertiary-900)_8%,transparent)]',
        title: 'mb-2 text-lg font-bold text-primary last:mb-0',
        icon: 'mb-4 size-auto rounded-none bg-transparent dark:bg-transparent',
        iconGlyph: 'size-8',
      },
      'minimal': { base: 'rounded-none' },
      'translucent': 'border border-white/15 bg-[linear-gradient(160deg,rgb(255_255_255/0.08),rgb(255_255_255/0.02))]',
    },
    padding: {
      small: 'p-5 md:p-6',
      default: 'p-7 md:p-9',
    },
    width: {
      narrow: 'md:mx-auto md:w-7/12',
    },
    link: { true: 'cursor-pointer no-underline' },
    // Stack: its blocks one under the other with even gaps, the last one at
    // the bottom (in a row of cards, their buttons line up).
    layout: {
      flow: '',
      stack: { base: 'flex flex-col items-start gap-5 [&>:where(p,ul,ol)]:my-0 [&>:last-child]:mt-auto', title: 'mb-0' },
    },
  },
  compoundVariants: [
    // No box: no inner space either.
    { variant: 'minimal', padding: 'default', class: 'p-0 md:p-0' },
    // Linked boxes lift on hover, the bordered ones taking the brand colour.
    { variant: 'bordered', link: true, class: 'hover:-translate-y-2 hover:border-primary-500 hover:shadow-lifted' },
    { variant: ['elevated', 'tinted', 'plain', 'promo'], link: true, class: 'hover:-translate-y-2 hover:shadow-lifted' },
    { variant: 'translucent', link: true, class: 'hover:-translate-y-2 hover:border-primary-300 hover:shadow-[0_28px_64px_rgb(0_0_0/0.45)]' },
    { variant: ['bordered', 'elevated', 'filled', 'tinted', 'highlight', 'gradient', 'promo', 'translucent'], link: true, class: { icon: 'group-hover:-rotate-8 group-hover:scale-108 group-hover:bg-primary-400 group-hover:text-tertiary-950 dark:group-hover:bg-primary-400' } },
    // Icon tiles on dark and tinted boxes.
    { variant: ['filled', 'gradient', 'translucent'], class: { icon: 'bg-white/10 text-primary-200 dark:bg-white/10' } },
    { variant: 'tinted', class: { icon: 'bg-default dark:bg-default' } },
  ],
  defaultVariants: {
    variant: 'bordered',
    padding: 'default',
    layout: 'flow',
  },
} satisfies ThemeOf<'card'>
```

In ORC's theme, cards have rounded corners (scaled down by the theme's roundness) and a square icon tile; only linked cards move on hover (they lift, their icon tile turning teal):

- `bordered` (the default) and `elevated` (white with a soft navy shadow) are the everyday cards, on white or grey sections; `plain` is lighter (a soft shadow, small bold teal titles, the icon without its tile).
- `filled` (the dark teal brand gradient, white text) and `gradient` (the same, centred, with a larger title) stand out: one per section, e.g. a closing card.
- `tinted` is a light teal box (a teal veil in dark mode) for a short statement; `highlight` a bordered box with a large bold teal text, centred, e.g. a figure or a price.
- `promo` is a soft teal-to-mist card with a coral glow and a larger title, for an offer: pair it with a `styled-list` of check marks and a `secondary` button.
- `minimal` has no box and no inner space: a small image or icon, a title and a text, in a row of features.
- `translucent` is a glass box (a white border and veil) made for the dark `band` background of a `page-section`.
- `padding="small"` for small cards in a dense grid; `width="narrow"` centres a card on 7/12 of the column.


## Sitemap

See the full [sitemap](http://localhost:3000/sitemap.md) for all pages.
