Layout
Card
The raised surface for grouped content: card fill, border, radius-xl (14px), shadow-sm, 24px padding and gap.
Guidelines#
Parts: Card › CardHeader (CardTitle, CardDescription, optional CardAction top-right) › CardContent › CardFooter. className="border-b" on the header or "border-t" on the footer rules them off.
Use it for a self-contained unit: a feature's settings, a report, a record summary. Many Max pages frame whole sections in the glass shell instead — glass-panel border border-glass rounded-3xl px-6 py-6 — which KpiCard's KpiSection uses.
What you provide: a short noun-phrase title ("Inbox Autopilot"), a one-sentence description, at most one CardAction (an outline or ghost small Button), and footer buttons with the main action first.
Don't nest cards, tint a card with an agent colour, or make a whole card clickable without making it one link or button.
Facts#
| Group | Layout |
|---|---|
| Product | Max |
| Global | window.DigitalCrew.Card |
| Source | max-agent: src/components/ui/card.tsx |
| Import in the app | import { Card } from "@/components/ui/card"; |
API#
TypeScript declarations emitted from src/components/ui/card.tsx (the module also exports its other parts).
declare function Card({ className, ...props }: React.ComponentProps<"div">): any;
declare function CardHeader({ className, ...props }: React.ComponentProps<"div">): any;
declare function CardTitle({ className, ...props }: React.ComponentProps<"div">): any;
declare function CardDescription({ className, ...props }: React.ComponentProps<"div">): any;
declare function CardAction({ className, ...props }: React.ComponentProps<"div">): any;
declare function CardContent({ className, ...props }: React.ComponentProps<"div">): any;
declare function CardFooter({ className, ...props }: React.ComponentProps<"div">): any;
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, };Example#
The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.
<div id="root" class="p-6"></div>
<script>
(function () {
var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
function Stat(label, value) {
return h("div", { className: "flex flex-col gap-1" },
h("span", { className: "text-xs text-muted-foreground" }, label),
h("span", { className: "text-2xl font-semibold tabular-nums tracking-tight" }, value));
}
function App() {
return h("div", { className: "grid grid-cols-2 gap-6" },
h(DC.Card, null,
h(DC.CardHeader, null,
h(DC.CardTitle, null, "Inbox Autopilot"),
h(DC.CardDescription, null, "Max drafts replies to warm conversations for your review."),
h(DC.CardAction, null, h(DC.Button, { variant: "outline", size: "sm" }, "Settings"))),
h(DC.CardContent, { className: "grid grid-cols-3 gap-4" }, Stat("Drafted", "42"), Stat("Sent", "37"), Stat("Replies", "11")),
h(DC.CardFooter, { className: "gap-2" }, h(DC.Button, { size: "sm" }, "Review drafts"), h(DC.Button, { size: "sm", variant: "ghost" }, "Pause"))),
h(DC.Card, null,
h(DC.CardHeader, { className: "border-b" },
h(DC.CardTitle, null, "Sender rotation"),
h(DC.CardDescription, null, "3 mailboxes share the daily volume.")),
h(DC.CardContent, null, h("p", { className: "text-sm text-muted-foreground" }, "Each mailbox sends at most 40 a day while warming. Max spreads the rest across the week.")),
h(DC.CardFooter, null, h(DC.Button, { className: "w-full" }, "Add mailbox"))));
}
ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>