Skip to content

ContainersFeature card

Feature card

The card used on the design system home, the work index, and the case study teasers. A small link, a one-sentence lede, and a trailing arrow.

Whole card is the linkTrailing arrow on hoverOptional icon

Demo

The whole card is a link. The arrow nudges right on hover to signal interactivity.

Anatomy

  • 1 px --line-strong border, 4 px radius
  • 24 px padding (1.5 rem)
  • Eyebrow at 0.6875 rem / 0.18 em tracking, uppercase
  • Title at display (1.5 rem, serif, -0.015 em tracking)
  • Lede at body (0.9375 rem, 1.55 line-height)
  • CTA at body-sm (0.8125 rem, weight 500); arrow shifts 4 px on hover

Implementation

feature-card.tsx
import Link from "next/link"
import { ArrowRight } from "lucide-react"
import SiteIcon, type SiteIconProps } from "@/components/site-icon"

interface FeatureCardProps {
  eyebrow: string
  title: string
  lede: string
  href: string
  icon?: SiteIconProps["icon"]
}

export function FeatureCard({ eyebrow, title, lede, href, icon }: FeatureCardProps) {
  return (
    <Link href={href} className="ds-feature-card">
      <span className="ds-feature-card__eyebrow">{eyebrow}</span>
      <h2 className="ds-feature-card__title">{title}</h2>
      <p className="ds-feature-card__lede">{lede}</p>
      <span className="ds-feature-card__cta">
        {icon ? <SiteIcon icon={icon} size="sm" /> : null}
        Explore {eyebrow.toLowerCase()}
        <SiteIcon icon={ArrowRight} size="sm" className="ds-feature-card__arrow" />
      </span>
    </Link>
  )
}

Props

PropTypeDefaultDescription
eyebrowstringNoneSmall uppercase label above the title
titlestringNoneRequired: the title
ledestringNoneRequired: a one-sentence description
hrefstringNoneRequired: link destination
iconLucideIconNoneDecorative icon, top-right