# Card Component

A flexible, polymorphic container component that provides a consistent visual structure for grouping related content with customizable variants and styling.

## Import path
```tsx
import Card from '@hubspot/cms-component-library/Card';
```

## Purpose

The Card component provides a reusable container for grouping related content in HubSpot CMS projects. It solves the challenge of maintaining visual consistency across content sections while supporting different elevation styles (shadows, borders, or filled backgrounds). Use it when you need to visually separate and organize content into distinct sections with flexible styling.

## Component Structure

```
Card/
├── index.tsx                    # Main component with render logic
├── types.ts                     # TypeScript type definitions
├── StyleFields.tsx              # HubSpot field definitions for styling
├── index.module.scss            # CSS module with design tokens
└── stories/
    ├── Card.stories.tsx         # Storybook examples
    ├── CardDecorator.tsx        # Storybook decorator
    └── CardDecorator.module.css # Decorator styles
```

## Components

### Card (Main Component)

**Purpose:** Polymorphic container component that renders as a `<div>`, `<article>`, or `<section>` element with configurable visual variants.

**Props:**
```tsx
{
  variant?: 'elevated' | 'outlined' | 'filled';   // Visual style variant (default: 'elevated')
  as?: 'div' | 'article' | 'section';             // HTML element to render (default: 'div')
  borderRadius?: number;                          // Border radius in pixels (default: 8)
  children?: React.ReactNode;                     // Card content
  className?: string;                             // Additional CSS classes
  style?: React.CSSProperties;                    // Inline styles with CSS variables
}
```

## Usage Examples

### Basic Card with Content

```tsx
import Card from '@hubspot/cms-component-library/Card';

<Card>
  <h3>Card Title</h3>
  <p>This is the card content.</p>
</Card>
```

### Semantic Article Card

```tsx
<Card as="article" variant="filled">
  <h3>Blog Post Title</h3>
  <p>Article content goes here...</p>
</Card>
```

### Dynamic Cards from Data

```tsx
const features = [
  { title: 'Analytics', description: 'Track performance metrics' },
  { title: 'Integration', description: 'Connect with existing tools' },
  { title: 'Support', description: '24/7 customer assistance' }
];

<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '16px' }}>
  {features.map((feature) => (
    <Card key={feature.title}>
      <h3>{feature.title}</h3>
      <p>{feature.description}</p>
    </Card>
  ))}
</div>
```

### Card with Rich Content

```tsx
<Card variant="outlined">
  <h3>Product Features</h3>
  <ul>
    <li>Real-time collaboration</li>
    <li>Advanced security</li>
    <li>Custom integrations</li>
  </ul>
  <button>Learn More</button>
</Card>
```

## HubSpot CMS Integration

### Field Definitions

The Card component provides field definitions for styling configuration in HubSpot CMS modules.

#### StyleFields.tsx

Configurable props for customizing field labels, names, and defaults:

```tsx
<Card.StyleFields
  variantLabel="Card variant"
  variantName="variant"
  variantDefault="elevated"
/>
```

**Fields:**
- `variant`: ChoiceField for selecting visual style (elevated, outlined, filled)

### Module Usage Example

```tsx
import Card from '@hubspot/cms-component-library/Card';

export default function FeatureCardModule({ fieldValues }) {
  return (
    <Card
      variant={fieldValues.variant}
      as="article"
    >
      <h3>{fieldValues.title}</h3>
      <p>{fieldValues.description}</p>
    </Card>
  );
}

FeatureCardModule.fields = (
  <>
    <Card.StyleFields />
    <TextField label="Title" name="title" default="Feature title" />
    <TextField label="Description" name="description" default="Feature description" />
  </>
);
```

## Styling

### CSS Variables

The Card component uses CSS variables for theming and customization:

**Base Styles:**
- `--hscl-card-padding`: Internal padding (default: 24px)
- `--hscl-card-borderRadius`: Border radius (default: 8px)
- `--hscl-card-backgroundColor`: Background color (default: #ffffff)
- `--hscl-card-boxShadow`: Box shadow (default: none)
- `--hscl-card-border`: Border style (default: none)

**Hover States:**
- `--hscl-card-boxShadow-hover`: Hover box shadow (inherits from base if not set)

## Accessibility

The Card component follows accessibility best practices:

- **Semantic HTML**: Use the `as` prop to render appropriate semantic elements (`article` for blog posts, `section` for page sections, `div` for generic containers)
- **Content Structure**: Ensure proper heading hierarchy within card content (e.g., if cards are in an h2 section, use h3 for card titles)
- **Color Contrast**: Default styles meet WCAG AA contrast requirements; verify custom colors maintain sufficient contrast
- **Focus Management**: Cards themselves are not interactive, but ensure interactive elements within cards (buttons, links) have proper focus styles

## Best Practices

- **Choose semantic elements**: Use `as="article"` for self-contained content, `as="section"` for thematic groupings, and `as="div"` (default) for generic containers
- **Border radius via theme settings**: Border radius is controlled by card shape settings in theme settings/variants, not an element-level field. Use the `borderRadius` prop only for programmatic overrides.
- **Override CSS variables**: Customize appearance using CSS variables rather than overriding class styles
- **Grid layouts**: Use CSS Grid or Flexbox for card layouts rather than relying on card margins
- **Content flexibility**: Cards are content-agnostic containers; structure internal content using appropriate semantic elements

## Related Components

- **Flex**: Use for arranging cards in flexible layouts
- **Grid**: Use for creating responsive card grids
- **Heading**: Commonly used for card titles
