Skip to content

Stat Card

KPI card: mono label, icon square, giant value, green/red delta chip with arrow, and an outlined mini bar chart whose last bar is filled. Four solid tones.

brutalist/ui/stat-card
Open ↗

Source

import type { ReactNode } from "react";
import { ArrowDownRight, ArrowUpRight } from "lucide-react";
import { cn } from "@/lib/utils";

export interface StatCardProps {
  label: string;
  value: string;
  /** Change vs previous period, e.g. "+12%". Positive/negative inferred from the sign. */
  delta?: string;
  deltaLabel?: string;
  /** Values for the mini bar chart (any scale). */
  series?: number[];
  icon?: ReactNode;
  tone?: "surface" | "primary" | "accent" | "secondary";
  className?: string;
}

const TONES = {
  surface: "bg-da-surface text-da-surface-fg",
  primary: "bg-da-primary text-da-primary-fg",
  accent: "bg-da-accent text-da-accent-fg",
  secondary: "bg-da-secondary text-da-secondary-fg",
} as const;

export function StatCard({ label, value, delta, deltaLabel = "vs last month", series, icon, tone = "surface", className }: StatCardProps) {
  const negative = delta?.trim().startsWith("-") || delta?.trim().startsWith("−");
  const max = series && series.length ? Math.max(...series) : 1;

  return (
    <div className={cn("da-stroke flex flex-col gap-4 p-5 shadow-da-md", TONES[tone], className)}>
      <div className="flex items-center justify-between gap-3">
        <p className="font-da-mono text-[11px] font-bold tracking-da-label uppercase">{label}</p>
        {icon && (
          <span aria-hidden className="da-stroke grid size-8 place-items-center bg-da-bg text-da-fg [&_svg]:size-4">
            {icon}
          </span>
        )}
      </div>
      <p className="font-da-display text-5xl leading-none tracking-da-display">{value}</p>
      {delta && (
        <p className="flex items-center gap-2 text-sm font-bold">
          <span className={cn("da-stroke inline-flex items-center gap-0.5 px-1.5 py-0.5 font-da-mono text-xs", negative ? "bg-da-danger text-da-danger-fg" : "bg-da-success text-da-success-fg")}>
            {negative ? <ArrowDownRight aria-hidden className="size-3.5" strokeWidth={3} /> : <ArrowUpRight aria-hidden className="size-3.5" strokeWidth={3} />}
            {delta}
          </span>
          <span className="opacity-75">{deltaLabel}</span>
        </p>
      )}
      {series && series.length > 0 && (
        <div aria-hidden className="flex h-14 items-end gap-1">
          {series.map((v, i) => (
            <span key={i} className={cn("flex-1 border-[length:var(--da-border-width)] border-current", i === series.length - 1 ? "bg-current" : "bg-transparent")} style={{ height: `${Math.max(8, (v / max) * 100)}%` }} />
          ))}
        </div>
      )}
    </div>
  );
}

export default StatCard;

modules/brutalist/ui/stat-card/index.tsx

Props

PropTypeDefaultDescription
label*string—Metric name.
value*string—Formatted value.
deltastring—Change, e.g. "+12%" or "−9%" (sign drives color).
deltaLabelstring"vs last month"Comparison period.
seriesnumber[]—Mini bar chart values.
iconReactNode—Icon in the corner square.
tone"surface" | "primary" | "accent" | "secondary""surface"Card color.
classNamestring—Classes on the card.

Other card variants in Brutalist

Card in other art directions

Card

Composable frosted card (Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter) with frosted / tinted-gradient / solid variants, specular top edge and interactive lift.

GlassCard

Meeting Card

Meeting recap glass card: title, time / duration / platform meta, gradient participant stack with +N, AI summary panel, action items with checkboxes and owners, and a transcript link.

GlassCard

Profile Card

Teammate glass card: gradient cover, large initials avatar with presence dot, role and timezone, status pill, three stats, expertise tags and Message / Schedule actions.

GlassCard

Stat Ring Card

KPI glass card with a primary→accent gradient progress ring (SVG) showing the percentage, the value over its max and a caption; the ring draws in on mount.

GlassCard

Card

Composable hairline card (Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter) with default / raised / ghost variants and an interactive hover lift.

MinimalCard

Incident Card

Incident summary card: severity chip, id and duration, linked title, service chips, a 4-step status progress bar, commander avatar, stacked responder avatars and update count.

MinimalCard

Integration Card

Integration tile: logo/monogram, name, category, description, a Radix Switch to enable it, live status meta and a Configure link. Controlled or uncontrolled.

MinimalCard

Metric Card

KPI card: muted label, big mono value, inline SVG sparkline with area fill and end dot, and a colored delta chip vs. the previous period (lowerIsBetter flips the colors).

MinimalCard

Profile Card

Studio/person profile card in the Read.cv spirit: square gray portrait with initials, name, role and city in mono, availability dot in signal color, short bio and a list of links with ↗.

Mono CleanCard

Project Card

Portfolio project card: neutral image frame that darkens slightly on hover with a “View case ↗” overlay, then a mono meta row (index, client, year) and the title with discipline tags.

Mono CleanCard

Stat Card

Analytics stat: mono label, large display value, change in mono, and a row of thin vertical bars (last bar in ink, others gray) — no chart chrome.

Mono CleanCard

Template Card

Template tile: a wireframe preview drawn with hairlines (nav, giant title, image grid) in a bordered frame, then name, author, category and usage count, with a “Use template” button revealed on hover/focus.

Mono CleanCard

Account Card

Bank account card: institution + masked number header, big balance with available amount, sync timestamp, and three recent inflow/outflow rows.

Neo CorporateCard

Invoice Card

Invoice summary card: number + status, bill-to and dates grid, line items table with mono amounts, subtotal/tax/total, and download/send actions.

Neo CorporateCard

Kpi Card

Metric card: label, big mono value, colored delta vs. period and an area sparkline in the primary color along the bottom.

Neo CorporateCard

Plan Card

Billing/subscription card: current plan + price + renewal date, usage meters (progressbar semantics, turning amber at 80% and red at 95%), manage and upgrade actions.

Neo CorporateCard

Action Card

Reduction action card: serif title, description, saving and cost figures, leaf-rated impact/effort, and an “Add to plan” pill that toggles to a sage “In your plan” state.

Organic SoftCard

Article Card

Journal article card: an organic shaped “cover” (arch, blob or circle) with a hand-drawn leaf, category and read time, serif title that underlines on hover, excerpt; whole card is one link.

Organic SoftCard

Metric Card

Emissions metric card: label, big serif value with mono unit, a change chip (down = good, sage; up = clay) and a human equivalence line with a small leaf.

Organic SoftCard

Supplier Card

Supplier card: arch-shaped initials avatar, name, category and country, status pill, share of your footprint and a rounded data-completeness bar with a reminder action.

Organic SoftCard

Profile Card

Rounded teammate card: pastel header band, big emoji avatar in a white circle, name, role, status pill, three stats in soft wells, skill pills and a “Say hi” button.

Soft FlatCard

Project Card

Pastel project card: white emoji tile, name link covering the card, description, chunky rounded progress bar with percentage, tasks-left and due chips, member dots.

Soft FlatCard

Stat Card

Friendly KPI tile: emoji in a white circle, change pill, label, big rounded number and a row of rounded mini bars (last one highlighted); five tones.

Soft FlatCard

Task Card

Kanban task card: round done checkbox with bouncy tick, pastel label, title (struck when done), subtask progress, due chip that turns red when overdue, comment/attachment counts and avatar dots.

Soft FlatCard