LAB // NEXTUI
Card
Feature card with an experiment code label, SVG icon (atom, grid, diamond, network, monitor, warning), description, and a colored pill tag.
$
Or install the base component for free:
Live Preview
Open full demoUsage
TSX
<Card card={{
expCode: "EXP-07",
icon: "atom",
tag: "Core",
tagVariant: "green",
title: "Quantum renderer",
description: "Parallel render pipeline with zero layout shift.",
}} />Variants
<Card card={{ expCode: "EXP-01", icon: "atom", tag: "Core", tagVariant: "green", title: "Quantum renderer", description: "Parallel render pipeline." }} /><Card card={{ expCode: "EXP-02", icon: "network", tag: "Network", tagVariant: "blue", title: "Edge routing", description: "Sub-10ms global routing." }} /><Card card={{ expCode: "EXP-03", icon: "grid", tag: "Layout", tagVariant: "green", title: "Grid engine", description: "Adaptive multi-column layout." }} />Source
TSX
import { cn } from '@/lib/utils'
import type { CardItem, LabIcon } from '@/types'
interface CardProps {
card: CardItem
className?: string
}
function LabIconSvg({ name }: { name: LabIcon }): React.JSX.Element {
const icons: Record<LabIcon, React.JSX.Element> = {
atom: (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<circle cx="20" cy="20" r="7" stroke="currentColor" strokeWidth="1.5"/>
<circle cx="20" cy="20" r="15" stroke="currentColor" strokeWidth="1" strokeDasharray="3 3" opacity="0.35"/>
<circle cx="20" cy="5" r="2.5" fill="currentColor"/>
<circle cx="33" cy="27" r="2.5" fill="currentColor" opacity="0.7"/>
<circle cx="7" cy="27" r="2.5" fill="currentColor" opacity="0.5"/>
</svg>
),
grid: (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<rect x="4" y="4" width="14" height="14" rx="2" stroke="currentColor" strokeWidth="1.5"/>
<rect x="22" y="4" width="14" height="14" rx="2" stroke="currentColor" strokeWidth="1.5" opacity="0.65"/>
<rect x="4" y="22" width="14" height="14" rx="2" stroke="currentColor" strokeWidth="1.5" opacity="0.45"/>
<rect x="22" y="22" width="14" height="14" rx="2" stroke="currentColor" strokeWidth="1.5" opacity="0.8"/>
<line x1="18" y1="11" x2="22" y2="11" stroke="currentColor" strokeWidth="1.5"/>
<line x1="18" y1="29" x2="22" y2="29" stroke="currentColor" strokeWidth="1.5"/>
</svg>
),
diamond: (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<path d="M6 20 L20 6 L34 20 L20 34 Z" stroke="currentColor" strokeWidth="1.5"/>
<path d="M12 20 L20 12 L28 20 L20 28 Z" stroke="currentColor" strokeWidth="1" opacity="0.45"/>
<circle cx="20" cy="20" r="3.5" fill="currentColor"/>
</svg>
),
network: (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<circle cx="8" cy="20" r="4" stroke="currentColor" strokeWidth="1.5"/>
<circle cx="32" cy="8" r="4" stroke="currentColor" strokeWidth="1.5" opacity="0.7"/>
<circle cx="32" cy="32" r="4" stroke="currentColor" strokeWidth="1.5" opacity="0.5"/>
<line x1="12" y1="20" x2="28" y2="10" stroke="currentColor" strokeWidth="1" opacity="0.55"/>
<line x1="12" y1="20" x2="28" y2="30" stroke="currentColor" strokeWidth="1" opacity="0.55"/>
<line x1="32" y1="12" x2="32" y2="28" stroke="currentColor" strokeWidth="1" opacity="0.35"/>
</svg>
),
monitor: (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<rect x="6" y="10" width="28" height="20" rx="3" stroke="currentColor" strokeWidth="1.5"/>
<line x1="6" y1="17" x2="34" y2="17" stroke="currentColor" strokeWidth="1" opacity="0.45"/>
<circle cx="20" cy="24" r="3" stroke="currentColor" strokeWidth="1.5"/>
<line x1="20" y1="30" x2="20" y2="34" stroke="currentColor" strokeWidth="1.5"/>
<line x1="14" y1="34" x2="26" y2="34" stroke="currentColor" strokeWidth="1.5"/>
</svg>
),
warning: (
<svg viewBox="0 0 40 40" fill="none" aria-hidden="true">
<polygon points="20,5 36,31 4,31" stroke="currentColor" strokeWidth="1.5" fill="none"/>
<line x1="20" y1="14" x2="20" y2="24" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
<circle cx="20" cy="28" r="2" fill="currentColor"/>
</svg>
),
}
return icons[name]
}
const PILL_CLASSES: Record<CardItem['tagVariant'] | 'default', string> = {
green: 'feat-pill feat-pill--green',
blue: 'feat-pill feat-pill--blue',
default: 'feat-pill feat-pill--blue',
}
export function Card({ card, className }: CardProps): React.JSX.Element {
const pillClass = PILL_CLASSES[card.tagVariant] ?? PILL_CLASSES.default
return (
<div className={cn('lab-feat-card', className)}>
<div className="feat-exp">{card.expCode}</div>
<div className="feat-icon-el">
<LabIconSvg name={card.icon} />
</div>
<div className="feat-title">{card.title}</div>
<p className="feat-desc">{card.description}</p>
<span className={pillClass}>{card.tag}</span>
</div>
)
}
Works withNext.js 15React 19Tailwind v4TypeScript 5
More from LAB // NEXT
Button
Scientific dark-theme button with primary, secondary, and ghost variants in three sizes. Renders as a Next.js Link when an href is provided.
Badge
Lab-aesthetic badge with green and blue pill variants for experiment tags and status markers.
Text
Polymorphic text primitive with body, caption, label, and code variants styled for the LAB dark scientific palette.