Elements

Components / Website

Card

Base card shells plus Mode-inspired variants for product features and blog indexes. Feature cards follow the Datasets layout. Blog cards mirror the Mode blog index: featured hero, editor's picks, and detailed grid tiles.

Installation

bash
npx shadcn add https://raw.githubusercontent.com/levi-putna/elements/main/registry/card/registry.json

Also installs the avatar dependency for blog author rows.

Base shells

Three tones from the design system. Use bordered on white backgrounds, accent for highlights, and dark inside forest sections.

bordered · accent · dark

Bordered

White surface

Subtle border and shadow on white backgrounds.

Accent

Lime-soft fill

For featured or highlighted content on light sections.

Dark

Forest mid

Secondary card inside a dark section.

tsx
import { Card, CardEyebrow, CardTitle } from "@/components/ui/card"

<Card tone="bordered">
  <CardEyebrow>For strata managers</CardEyebrow>
  <CardTitle>Everything in one place</CardTitle>
  <p className="text-sm text-ink-muted mt-3">Levies, maintenance, and owner comms connected.</p>
</Card>

Feature card

Tinted visual slot on top, Young Serif title, body copy, and an optional Learn more link. Inspired by the Datasets cards on Mode's self-serve reporting page.

tsx
import { CardGrid, FeatureCard } from "@/components/ui/card"

<CardGrid columns={2}>
  <FeatureCard
    href="/features/datasets"
    title="Datasets"
    description="Built by analysts in tight partnership with domain experts…"
  />
  <FeatureCard
    href="/features/metrics"
    title="Levy metrics"
    description="Governed KPIs for levy collection, arrears, and budget variance."
  />
</CardGrid>

Blog: featured

Hero post layout with image left and copy right. Category eyebrow, title, excerpt, and Read more link.

tsx
import { BlogCardFeatured } from "@/components/ui/card"

<BlogCardFeatured
  href="/blog/levy-forecasting"
  category="Product updates"
  title="Beyond spreadsheets: introducing levy forecasting"
  excerpt="Levy forecasting helps you map out a budget structure before diving into the details."
  imageSrc="/img/building/2.webp"
  imageAlt="Strata manager reviewing levy forecast dashboard"
/>

Blog: simple

Compact tiles for editor's picks rows. Category at the top, title in the middle, date and read time anchored to the bottom.

tsx
import { CardGrid, BlogCardSimple } from "@/components/ui/card"

<CardGrid columns={3}>
  <BlogCardSimple
    href="/blog/paperless"
    category="Product updates"
    title="How Harbourview went paperless in 36 hours"
    date="15 June 2026"
    readTime="5 min read"
  />
</CardGrid>

Blog: detailed

Grid cards with a hero image, metadata, excerpt, and optional author row with avatar.

tsx
import { CardGrid, BlogCard } from "@/components/ui/card"

<CardGrid columns={3}>
  <BlogCard
    href="/blog/levy-forecasting"
    category="Product updates"
    title="Beyond spreadsheets: introducing levy forecasting"
    excerpt="Levy forecasting helps you map out a budget structure…"
    date="31 January 2024"
    readTime="8 min read"
    imageSrc="/img/building/1.webp"
    imageAlt="Levy forecasting dashboard"
    author={{ name: "Samantha Novak", role: "Product Design Lead", avatarSrc: "/img/people/1.webp" }}
  />
</CardGrid>

Tone reference

VariantBackgroundUse case
borderedwhite + borderDefault on white or off-white sections
accentlime-softFeatured content, callouts on light sections
darkforest-midCards inside primary (forest) sections
FeatureCardoff-white visual + open copyProduct feature rows with illustration
BlogCardSimplewhite + shadowEditor's picks, sidebar lists
BlogCardFeaturedwhite + shadowCategory hero post
BlogCardwhite + shadowBlog index grid with image and author

Card props

PropTypeDefaultDescription
tone"bordered" | "accent" | "dark""bordered"Surface colour. bordered = white + border + shadow. accent = lime-soft. dark = forest-mid for use inside dark sections.

FeatureCard props

PropTypeDefaultDescription
titlestring-Young Serif heading below the visual slot.
descriptionstring-Supporting body copy.
visualReactNode-Illustration or screenshot in the off-white visual area. Defaults to an abstract placeholder.
hrefstring-When set, renders as a link and shows a trailing Learn more label.
linkLabelstring"Learn more"Trailing link label with chevron.

BlogCardFeatured props

PropTypeDefaultDescription
categorystring-Uppercase eyebrow above the title.
titlestring-Post headline in Young Serif.
excerptstring-Short summary paragraph.
imageSrcstring-Hero image for the left column.
imageAltstring-Accessible alt text for the image.
linkLabelstring"Read more"Trailing link label with chevron.
hrefstring-Link destination: the entire card is clickable.

BlogCardSimple props

PropTypeDefaultDescription
categorystring-Uppercase eyebrow label at the top.
titlestring-Post headline in Young Serif.
datestring-Publication date.
readTimestring-Optional reading time, appended after the date.
hrefstring-Link destination: the entire card is clickable.

BlogCard props

PropTypeDefaultDescription
categorystring-Uppercase eyebrow above metadata.
titlestring-Post headline in Young Serif.
excerptstring-Summary paragraph, clamped to three lines.
datestring-Publication date.
readTimestring-Optional reading time.
imageSrcstring-Hero image at the top of the card.
imageAltstring-Accessible alt text for the image.
author{ name: string; role?: string; avatarSrc?: string }-Optional author row with Avatar at the bottom.
hrefstring-Link destination: the entire card is clickable.