GitHub

Card

Surface container with an optional header (icon, title, subtitle, actions), body, and footer. Variants, header tints, and padding scales.

Stable .astro import EsaCard from '@esa/ecology/esa-card.astro';

Preview

Report

Q3 summary

Body content for the card.

<Card title="Report" subtitle="Q3 summary">
  <p>Body content for the card.</p>
</Card>

Variants

Default

Bordered surface

Default card.

Elevated

Shadow, no border

Elevated card.

Filled

Sunken background

Filled card.

<Card title="Default" subtitle="Bordered surface"></Card>
<Card variant="elevated" title="Elevated" subtitle="Shadow, no border"></Card>
<Card variant="filled" title="Filled" subtitle="Sunken background"></Card>

Header variants

Primary header

Inverted text

Tinted header band.

Muted header

Subtle sunken header.

<Card headerVariant="primary" title="Primary header" subtitle="Inverted text"></Card>
<Card headerVariant="muted" title="Muted header"></Card>

Padding

Compact

Tighter body.

Default

Standard body.

Spacious

Roomy body.

<Card padding="compact" title="Compact"></Card>
<Card padding="default" title="Default"></Card>
<Card padding="spacious" title="Spacious"></Card>

Actions & footer

The actions slot sits at the right of the header; the footer slot renders a bottom band.

Report

Q3 summary

The actions slot sits at the right of the header; the footer slot renders a bottom band.

<Card title="Report" subtitle="Q3 summary" icon="info">
  <button slot="actions" type="button">Edit</button>
  <p>Body content.</p>
  <span slot="footer">Last updated 2 hours ago</span>
</Card>

API

PropTypeDefaultDescription
title string Header title. Presence (or a header/actions slot) renders the header band.
subtitle string Secondary line under the title.
icon string Lucide icon name shown left of the title.
variant 'default' | 'outlined' | 'elevated' | 'filled' 'default' Surface treatment: bordered, shadowed, or sunken.
headerVariant 'default' | 'primary' | 'muted' 'default' Header band tint.
padding 'none' | 'compact' | 'default' | 'spacious' 'default' Body and header padding scale.

Slots

PropTypeDefaultDescription
default slot Card body content.
header slot Replaces the title block entirely with custom markup.
actions slot Right-aligned controls in the header band.
footer slot Bottom band below the body.

Accessibility

  • Renders a plain <div> — add role/landmarks at the call site if the card is interactive or a region.
  • The title is an <h3>; keep heading order sensible within the surrounding page.
  • The header icon is aria-hidden — it decorates the title, not replaces it.

Theming surface

Every public token this component reads, extracted from its source at build time. The Resolves to column walks each token's real lineage — component → semantic → primitive → raw value — so you can see exactly where re-pointing it lands. A spoke re-skins by overriding these in its theme-<slug>.css; component internals are never edited. No hook for what you need? File it with /request-lego.

TokenTierResolves to
--card-bg component #fcfcfc via --color-surface--color-gray-1
--card-border-color component #cecece via --color-border--color-gray-7
--card-footer-bg component #f0f0f0 via --color-surface-sunken--color-gray-3
--card-header-bg component transparent
--card-header-border-color component #d9d9d9 via --color-border-light--color-gray-6
--card-header-color component #202020 via --color-text-primary--color-gray-12
--card-padding component 1.5rem via --spacing-500
--card-radius component 0.5rem via --radius-300
--color-border semantic #cecece via --color-gray-7
--color-primary semantic #46a758 via --color-grass-9
--color-surface-sunken semantic #f0f0f0 via --color-gray-3
--color-text-inverse semantic #fcfcfc via --color-gray-1
--color-text-secondary semantic #646464 via --color-gray-11
--font-sans semantic 'DM Sans', sans-serif
--type-size-150 semantic clamp(0.6875rem, 0.61rem + 0.38vw, 0.875rem)
--type-size-250 semantic clamp(0.8125rem, 0.71rem + 0.5vw, 1.0625rem)
--shadow-100 primitive 0 2px 12px 0 rgba(0, 0, 0, 0.04)
--spacing-050 primitive 0.125rem
--spacing-200 primitive 0.5rem
--spacing-300 primitive 0.75rem
--spacing-400 primitive 1rem
--spacing-700 primitive 3rem