Skip to content

ContainersCallout

Callout

A small in-prose note. Used in the design system docs to add context, ask a question, or flag a warning.

4 tonesInline placementCompact

Tones

Info is the default. Accent uses the editorial accent for "designer-to-designer" notes. Warning and success are reserved for cases where the reader needs to take an action.

Tones

Reading order matters

Read color first, then typography, then spacing.

A small note

This site is a portfolio, not a product. That changes which patterns apply.

Be careful

Two primary buttons in the same region means the design hasn't decided.

Looks good

All foreground/background pairings clear WCAG AA at 4.5:1.

Anatomy

  • 1 px border on three sides, 3 px on the left in the tone color
  • --surface-elevated background, 4 px radius
  • 20 px padding (1.25 rem vertical, 1.5 rem horizontal)
  • Icon left, title + body right, all top-aligned
  • Title at 0.875 rem weight 500; body at 0.9375 rem weight normal

Implementation

callout.tsx
import { type ReactNode } from "react"
import { Info, AlertTriangle, CheckCircle2, Sparkles } from "lucide-react"
import SiteIcon, type SiteIconProps } from "@/components/site-icon"

type Tone = "info" | "accent" | "warning" | "success"

interface CalloutProps {
  title: string
  tone?: Tone
  children: ReactNode
}

const iconMap: Record<Tone, SiteIconProps["icon"]> = {
  info: Info,
  accent: Sparkles,
  warning: AlertTriangle,
  success: CheckCircle2,
}

export function Callout({ title, tone = "info", children }: CalloutProps) {
  return (
    <aside className={`ds-callout ${tone === "accent" ? "ds-callout--accent" : ""}`}>
      <span className="ds-callout__icon">
        <SiteIcon icon={iconMap[tone]} size="md" tone="muted" />
      </span>
      <div className="ds-callout__body">
        <p className="ds-callout__title">{title}</p>
        <p className="ds-callout__content">{children}</p>
      </div>
    </aside>
  )
}

Props

PropTypeDefaultDescription
titlestringNoneThe bolded title
tone"info" | "warning" | "success" | "accent""info"Visual style
childrenReactNodeNoneThe body