
A single card listing four on-call contacts as rows with a greyscale Cloud shape avatar, name, title and an outline Email button. Rows are divided by hairlines under a header and description.
blocks/app/contact-list-card/index.tsx
import { EnvelopeSimpleIcon } from "@phosphor-icons/react/dist/ssr"
import { cn } from "cn"
import {
CloudShape,
type CloudPalette,
} from "@/components/graphics/cloud-shapes"
import { buttonVariants } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"
// The copy: change text here, not in the markup.
const COPY = {
title: "Who to call",
body: "The four people on console this week, in the order the checklist names them.",
action: "Email",
} as const
const PEOPLE = [
{
name: "JoAnn Morgan",
title: "Instrumentation Controller",
email: "joann@orbcore.co",
},
{ name: "Gene Kranz", title: "Flight Director", email: "gene@orbcore.co" },
{
name: "Katherine Johnson",
title: "Trajectory Analyst",
email: "katherine@orbcore.co",
},
{
name: "Margaret Hamilton",
title: "Flight Software Lead",
email: "margaret@orbcore.co",
},
] as const
// Knob: the orb's shading; zero chroma keeps it greyscale.
const ORB: CloudPalette = {
main: "oklch(0.55 0 0)",
accent: "oklch(0.7 0 0)",
}
export default function ContactListCard() {
return (
<Card className="mx-auto w-full max-w-md">
<CardHeader>
<CardTitle>{COPY.title}</CardTitle>
<CardDescription>{COPY.body}</CardDescription>
</CardHeader>
<CardContent>
<ul role="list" className="divide-y divide-border">
{PEOPLE.map((person) => (
<li key={person.email}>
<Item size="sm" className="rounded-none px-0 py-3">
<ItemMedia>
<CloudShape palette={ORB} width={40} height={40} />
</ItemMedia>
<ItemContent className="gap-0.5">
<ItemTitle>{person.name}</ItemTitle>
<ItemDescription className="text-xs">
{person.title}
</ItemDescription>
</ItemContent>
<ItemActions>
<a
href={`mailto:${person.email}`}
className={cn(
buttonVariants({ variant: "outline", size: "sm" })
)}
>
<EnvelopeSimpleIcon
aria-hidden="true"
data-icon="inline-start"
/>
{COPY.action}
</a>
</ItemActions>
</Item>
</li>
))}
</ul>
</CardContent>
</Card>
)
}
