Design SystemComponents
Cards
Stats card and content card patterns
Card Components
Cards are fundamental to the HRMS UI. There are two primary card types.
Stats Card (Gradient)
Stats cards display key metrics with colorful gradients and hover effects.
Pattern
<div className="
bg-gradient-to-br from-blue-500 to-blue-600
rounded-2xl p-6 text-white shadow-lg
transition-all hover:shadow-xl hover:-translate-y-1 duration-300
">
<div className="flex items-center justify-between">
<div>
<p className="text-white/80 text-sm font-medium mb-1">{title}</p>
<p className="text-4xl font-semibold tracking-tight">{value}</p>
</div>
<div className="w-12 h-12 bg-white/20 rounded-2xl flex items-center justify-center backdrop-blur-sm">
<Icon className="w-6 h-6 text-white" />
</div>
</div>
</div>Stats Card Gradients
| Metric Type | Gradient |
|---|---|
| Employees/Primary | from-blue-500 to-blue-600 |
| On Leave/Warning | from-amber-400 to-orange-500 |
| Pending/Secondary | from-violet-500 to-purple-600 |
| Open Positions/Success | from-emerald-400 to-green-500 |
| Upcoming Event | from-indigo-900 to-indigo-950 |
Stats Card Rules
| Property | Value |
|---|---|
| Border Radius | rounded-2xl |
| Padding | p-6 |
| Shadow | shadow-lg |
| Hover Shadow | shadow-xl |
| Hover Lift | -translate-y-1 |
| Icon Container | bg-white/20 backdrop-blur-sm rounded-2xl |
| Label Color | text-white/80 |
| Value Size | text-4xl font-semibold tracking-tight |
StatsCard Component
interface StatsCardProps {
title: string;
value: string | number;
icon: LucideIcon;
gradient: string;
}
export function StatsCard({ title, value, icon: Icon, gradient }: StatsCardProps) {
return (
<div className={cn(
"bg-gradient-to-br rounded-2xl p-6 text-white shadow-lg",
"transition-all hover:shadow-xl hover:-translate-y-1 duration-300",
gradient
)}>
<div className="flex items-center justify-between">
<div>
<p className="text-white/80 text-sm font-medium mb-1">{title}</p>
<p className="text-4xl font-semibold tracking-tight">{value}</p>
</div>
<div className="w-12 h-12 bg-white/20 rounded-2xl flex items-center justify-center backdrop-blur-sm">
<Icon className="w-6 h-6 text-white" />
</div>
</div>
</div>
);
}Content Card (White/Dark)
Content cards contain data and UI elements with soft shadows.
Pattern
<div className="
bg-card text-card-foreground
rounded-2xl p-6
shadow-lg shadow-gray-200/50 dark:shadow-black/40
border-none
">
<h3 className="text-lg font-semibold">{title}</h3>
{children}
</div>Content Card Rules
| Property | Light Mode | Dark Mode |
|---|---|---|
| Background | bg-card (#FFFFFF) | bg-card (#1C1C1E) |
| Text | text-card-foreground (#000) | text-card-foreground (#FAFAFA) |
| Border Radius | rounded-2xl | rounded-2xl |
| Padding | p-6 | p-6 |
| Shadow | shadow-lg shadow-gray-200/50 | shadow-lg shadow-black/40 |
| Border | NONE | NONE |
ContentCard Component
interface ContentCardProps extends React.HTMLAttributes<HTMLDivElement> {
title?: string;
children: React.ReactNode;
}
export function ContentCard({ title, children, className, ...props }: ContentCardProps) {
return (
<div
className={cn(
"bg-card text-card-foreground rounded-2xl p-6",
"shadow-lg shadow-gray-200/50 dark:shadow-black/40",
"border-none",
className
)}
{...props}
>
{title && <h3 className="text-lg font-semibold mb-4">{title}</h3>}
{children}
</div>
);
}DO vs DON'T
Stats Cards
// ✅ CORRECT: Gradient with hover lift
<div className="bg-gradient-to-br from-blue-500 to-blue-600 rounded-2xl p-6 text-white shadow-lg hover:shadow-xl hover:-translate-y-1 duration-300">
...
</div>
// ❌ WRONG: Plain white with border
<div className="bg-white border border-gray-200 rounded-lg p-4">
...
</div>Content Cards
// ✅ CORRECT: Shadow with dark mode variant
<div className="bg-card rounded-2xl p-6 shadow-lg shadow-gray-200/50 dark:shadow-black/40">
...
</div>
// ❌ WRONG: Border instead of shadow
<div className="bg-white border border-gray-100 rounded-md p-4">
...
</div>Card with Header
<div className="bg-card rounded-2xl shadow-lg shadow-gray-200/50 dark:shadow-black/40 overflow-hidden">
<div className="px-6 py-4 border-b border-border">
<h3 className="text-lg font-semibold">Card Title</h3>
<p className="text-sm text-muted-foreground">Card description</p>
</div>
<div className="p-6">
{/* Card content */}
</div>
</div>Card with Footer
<div className="bg-card rounded-2xl shadow-lg shadow-gray-200/50 dark:shadow-black/40 overflow-hidden">
<div className="p-6">
{/* Card content */}
</div>
<div className="px-6 py-4 border-t border-border bg-muted/50">
<div className="flex justify-end gap-2">
<Button variant="outline">Cancel</Button>
<Button>Save</Button>
</div>
</div>
</div>Common Mistakes
| Mistake | Correct Pattern |
|---|---|
bg-white | Use bg-card |
border border-gray-200 | Use shadow-lg shadow-gray-200/50 |
rounded-lg | Use rounded-2xl |
p-4 | Use p-6 |
| Missing dark shadow | Add dark:shadow-black/40 |
| Stats card without gradient | Always use gradient |
| Missing hover lift on stats | Add hover:-translate-y-1 |