Photonix

Card

A flexible container component for grouping related content and actions.

Preview

Basic Card
This is a standard elevated card

Cards contain content and actions about a single subject. They are surface containers that hold content and actions.

Usage
import { Card, CardHeader, CardBody, CardFooter, Button, Text } from '@photonix/ultimate';

<Card w={350} maxW="100%">
  <CardHeader
    title="Basic Card"
    subtitle="This is a standard elevated card"
    action={<Button variant="tertiary" leadingIcon={<MoreHorizontalOutline />} />}
  />
  <CardBody>
    <Text variant="body-md" color="secondary">
      Cards contain content and actions about a single subject. They are surface containers that hold content and actions.
    </Text>
  </CardBody>
  <CardFooter>
    <Button variant="secondary">Cancel</Button>
    <Button>Submit</Button>
  </CardFooter>
</Card>

Component API

Card

Prop
Type
Default
Description
variant
CardVariant
'elevated'
Card variant style
orientation
"horizontal" | "vertical"
'vertical'
Card orientation
isHoverable
boolean
false
Whether the card is interactive (hover states)
isClickable
boolean
false
Whether the card is clickable (cursor pointer)
children
React.ReactNode
-
Children elements
p
ResponsiveValue<SpacingToken>
-
Padding on all sides
px
ResponsiveValue<SpacingToken>
-
Padding inline (left/right)
py
ResponsiveValue<SpacingToken>
-
Padding block (top/bottom)
pt
ResponsiveValue<SpacingToken>
-
Padding block start (top)
pb
ResponsiveValue<SpacingToken>
-
Padding block end (bottom)
pl
ResponsiveValue<SpacingToken>
-
Padding inline start (left)
pr
ResponsiveValue<SpacingToken>
-
Padding inline end (right)
m
ResponsiveValue<SpacingToken | "auto">
-
Margin on all sides
mx
ResponsiveValue<SpacingToken | "auto">
-
Margin inline (left/right)
my
ResponsiveValue<SpacingToken | "auto">
-
Margin block (top/bottom)
mt
ResponsiveValue<SpacingToken | "auto">
-
Margin block start (top)
mb
ResponsiveValue<SpacingToken | "auto">
-
Margin block end (bottom)
ml
ResponsiveValue<SpacingToken | "auto">
-
Margin inline start (left)
mr
ResponsiveValue<SpacingToken | "auto">
-
Margin inline end (right)
display
ResponsiveValue<DisplayValue>
-
CSS display property
aspectRatio
ResponsiveValue<string | number>
-
Aspect Ratio
flexDirection
ResponsiveValue<FlexDirection>
-
Flex direction
flexWrap
ResponsiveValue<boolean | FlexWrap>
-
Flex wrap behavior
flex
ResponsiveValue<string | number>
-
Shorthand for flex-grow, flex-shrink, flex-basis
flexGrow
ResponsiveValue<number>
-
Flex grow factor
flexShrink
ResponsiveValue<number>
-
Flex shrink factor
flexBasis
ResponsiveValue<string | number>
-
Flex basis
order
ResponsiveValue<number>
-
Order
gap
ResponsiveValue<SpacingToken>
-
Gap between items
columnGap
ResponsiveValue<SpacingToken>
-
Column gap
rowGap
ResponsiveValue<SpacingToken>
-
Row gap
alignItems
ResponsiveValue<AlignItems>
-
Align items (cross axis)
alignContent
ResponsiveValue<string>
-
Align content (multiline)
alignSelf
ResponsiveValue<AlignSelf>
-
Align self
justifyContent
ResponsiveValue<JustifyContent>
-
Justify content (main axis)
justifyItems
ResponsiveValue<string>
-
Justify items (grid)
placeItems
ResponsiveValue<string>
-
Place items (align-items + justify-items)
placeContent
ResponsiveValue<string>
-
Place content (align-content + justify-content)
bg
ResponsiveValue<BackgroundToken>
-
Background color using public background tokens mapped to canonical surface vars
pageBg
ResponsiveValue<PageBackgroundToken>
-
Page background using canonical background-* vars for page/root containers
borderRadius
ResponsiveValue<RadiusToken>
-
Border radius using border-radius-* tokens
shadow
ResponsiveValue<ShadowToken>
-
Box shadow using shadow-* tokens
opacity
ResponsiveValue<number>
-
Opacity
border
ResponsiveValue<string>
-
borderWidth
ResponsiveValue<number | BorderWidthToken>
-
borderStyle
ResponsiveValue<string>
-
borderColor
ResponsiveValue<string>
-
textAlign
ResponsiveValue<TextAlign>
-
fontSize
ResponsiveValue<string | number>
-
fontWeight
ResponsiveValue<string | number>
-
lineHeight
ResponsiveValue<string | number>
-
color
ResponsiveValue<string>
-
w
ResponsiveValue<string | number>
-
Width - accepts CSS value
h
ResponsiveValue<string | number>
-
Height - accepts CSS value
minW
ResponsiveValue<string | number>
-
Min width - accepts CSS value
minH
ResponsiveValue<string | number>
-
Min height - accepts CSS value
maxW
ResponsiveValue<string | number>
-
Max width - accepts CSS value
maxH
ResponsiveValue<string | number>
-
Max height - accepts CSS value
position
ResponsiveValue<Position>
-
CSS position property
top
ResponsiveValue<string | number>
-
Top position
right
ResponsiveValue<string | number>
-
Right position
bottom
ResponsiveValue<string | number>
-
Bottom position
left
ResponsiveValue<string | number>
-
Left position
inset
ResponsiveValue<string | number>
-
Inset shortcut
zIndex
ResponsiveValue<number>
-
Z-index
overflow
ResponsiveValue<Overflow>
-
CSS overflow property
overflowX
ResponsiveValue<Overflow>
-
CSS overflow-x property
overflowY
ResponsiveValue<Overflow>
-
CSS overflow-y property
cursor
ResponsiveValue<string>
-
pointerEvents
ResponsiveValue<string>
-
userSelect
ResponsiveValue<string>
-
transform
ResponsiveValue<string>
-
transition
ResponsiveValue<string>
-

CardHeader

Prop
Type
Default
Description
title
React.ReactNode
-
Card title
subtitle
React.ReactNode
-
Card subtitle
isVerified
boolean
-
Whether the entity is verified (shows a checkmark icon)
action
React.ReactNode
-
Action element (e.g., menu button)
avatar
React.ReactNode
-
Avatar or icon to display
children
React.ReactNode
-
Children elements

CardFooter

Prop
Type
Default
Description
justify
"center" | "start" | "end" | "between"
'end'
Justify content alignment
children
React.ReactNode
-
Children elements

CardImage

Prop
Type
Default
Description
position
"top" | "bottom" | "left" | "fill"
'top'
Image position
rounded
boolean
false
Whether to apply border radius to all corners

Variants

Visual Styles

Cards come in three main visual styles: elevated (default), outlined, and filled.

Elevated

Has shadow

Outlined

Has border

Filled

Has background

Visual Styles
import { Card, CardBody, Text, Flex } from '@photonix/ultimate';

<Flex gap="md" wrap="wrap">
  {/* Elevated (Default) */}
  <Card variant="elevated" w={200}>
    <CardBody>
      <Text variant="title-sm">Elevated</Text>
      <Text variant="body-sm" color="secondary">Has shadow</Text>
    </CardBody>
  </Card>

  {/* Outlined */}
  <Card variant="outlined" w={200}>
    <CardBody>
      <Text variant="title-sm">Outlined</Text>
      <Text variant="body-sm" color="secondary">Has border</Text>
    </CardBody>
  </Card>

  {/* Filled */}
  <Card variant="filled" w={200}>
    <CardBody>
      <Text variant="title-sm">Filled</Text>
      <Text variant="body-sm" color="secondary">Has background</Text>
    </CardBody>
  </Card>
</Flex>

Overlay

Use the overlay variant for cards with a background image. The Card automatically analyzes the image brightness and adapts the text color for readability — no manual configuration needed.

Architecture
Urban Architecture
Modern aesthetic for the urban explorer.
Light Demo
Nature Escape
Find peace in the quiet mountains.
Overlay
<Flex gap="md" wrap="wrap">
  {/* Dark Image — text auto-switches to white */}
<Card variant="overlay" w={300} h={400}>
    <CardImage position="fill" src={DARK_IMAGE} alt="Architecture" />
    <Box style={{ position: 'absolute', top: 8, right: 8, zIndex: 2 }}>
      <IconButton variant="tertiary" size="small" icon={<MoreVerticalOutline />} aria-label="More" />
    </Box>
    <div style={{ flex: 1 }} />
    <CardHeader
      title="Urban Architecture"
      subtitle="The intersection of architecture and the city."
    />
    <CardFooter justify="between">
      <HStack gap="sm">
        <HStack gap="4xs" align="center">
          <UserOutline size={24} />
          <Text variant="title-md">1.2k</Text>
        </HStack>
      </HStack>
      <Button size="small" variant="secondary" leadingIcon={<AddOutline size={16} />}>Follow</Button>
    </CardFooter>
  </Card>

  {/* Light Image — text stays dark automatically */}
  <Card variant="overlay" w={300} h={400}>
    <CardImage position="fill" src={LIGHT_IMAGE} alt="Light Demo" />
    {/* ... contents ... */}
  </Card>
</Flex>

Interactive

Cards can be hoverable and clickable.

Hover me

I lift up on hover

Click me

I'm clickable too

Interactive
<Flex gap="md">
  <Card isHoverable w={200}>
    <CardBody>
      <Text variant="title-sm">Hover me</Text>
      <Text variant="body-sm" color="secondary">I lift up on hover</Text>
    </CardBody>
  </Card>
  
  <Card isHoverable isClickable w={200}>
    <CardBody>
      <Text variant="title-sm">Click me</Text>
      <Text variant="body-sm" color="secondary">I'm clickable too</Text>
    </CardBody>
  </Card>
</Flex>

With Image (Padded)

In this variant, the image is inset with a small padding (2xs) and rounded corners, creating a modern, framed look.

Architecture
Modern Architecture
Clean lines and minimalist design.
With Image (Padded)
<Card w={360}>
  <Box p="2xs" pb="none">
    <CardImage 
      rounded 
      src="/card_architecture.png" 
      alt="Architecture" 
      style={{ aspectRatio: '16/9' }} 
    />
  </Box>
  <CardHeader
    title="Modern Architecture"
    isVerified
    subtitle="Clean lines and minimalist design."
  />
  <CardFooter justify="between">
    <HStack gap="sm">
      <HStack gap="4xs" align="center">
        <UserOutline size={24} />
        <Text variant="title-md">1.2k</Text>
      </HStack>
    </HStack>
    <Button size="small">Read More</Button>
  </CardFooter>
</Card>

Full Bleed Image

A card where the image covers the top area completely without any padding, bleeding to the edges.

Nature
Mountain Serenity
Exploring the peaceful peaks.
Full Bleed Image
<Card w={360}>
  <CardImage src="/card_nature.png" alt="Nature" style={{ aspectRatio: '16/9' }} />
  <CardHeader
    title="Mountain Serenity"
    isVerified
    subtitle="Exploring the peaceful peaks."
  />
  <CardFooter justify="between">
    <HStack gap="sm">
      <HStack gap="4xs" align="center">
        <UserOutline size={24} />
        <Text variant="title-md">842</Text>
      </HStack>
    </HStack>
    <Button size="small" variant="primary">Explore</Button>
  </CardFooter>
</Card>

Social Post

Cards tailored for social feeds, featuring an avatar and multiple action buttons.

AW

Alexander Wright
2 hours ago • San Francisco

Just deployed the new Photonix design system update! The automatic brightness detection for overlay cards is a game changer for UX. 🚀

Social Post
<Card w={420}>
  <CardHeader
    avatar={<Box style={{ width: 40, height: 40, borderRadius: '50%', backgroundColor: 'var(--surface-brand-primary)' }} />}
    title="Alexander Wright"
    subtitle="2 hours ago • San Francisco"
    action={<IconButton variant="tertiary" size="small" icon={<MoreHorizontalOutline />} />}
  />
  <CardBody>
    <Text variant="body-lg">
      Just deployed the new Photonix design system update! 🚀
    </Text>
  </CardBody>
  <CardImage src="/card_fashion.png" style={{ aspectRatio: '16/9' }} />
  <CardFooter justify="between">
    {/* ... actions ... */}
  </CardFooter>
</Card>

Product Card

E-commerce style card with badges, ratings, and pricing displays.

Headphones

Electronics

SALE

Studio Headphones Gen 3

$299.00

$350.00

Product Card
<Card isHoverable w={300}>
  <CardImage src="/card_architecture.png" style={{ aspectRatio: '1/1' }} />
  {/* ... contents ... */}
</Card>

Horizontal Layout

Cards can be laid out horizontally, which is ideal for lists and search results.

Demo
Full Bleed Horizontal
Ideal for blog post previews or search results where the image needs to be prominent.
Demo
Inset Rounded Image
Horizontal layout with a padded and rounded image container.
Horizontal Layout
<Card orientation="horizontal" h={160} w="100%">
  <CardImage position="left" src="/path/to/image.jpg" style={{ width: 160 }} />
  <VStack flexGrow={1} flexShrink={1} flexBasis="0%" align="stretch" minW={0}>
    <CardHeader title="Card Title" subtitle="Description content..." />
    <div style={{ flex: 1 }} />
    <CardFooter justify="end">
      <Button variant="secondary">Action</Button>
    </CardFooter>
  </VStack>
</Card>

On this page

Preview
Component API
Variants
Visual Styles
Overlay
Interactive
With Image
Full Bleed Image
Social Post
Product Card
Horizontal Layout
Photonix UI - React Components, Templates & Figma Design System