LAB // NEXTUI

Card

Feature card with an experiment code label, SVG icon (atom, grid, diamond, network, monitor, warning), description, and a colored pill tag.

$npx @voltenworks/shipui add card --theme lab
Or install the base component for free:
Live Preview
Open full demo
voltenworks.com/shipui/lab/demo/components#04-card
Usage
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>
  )
}
Preview in theme demoGet full theme, $29
Works withNext.js 15React 19Tailwind v4TypeScript 5
More from LAB // NEXT
LAB // NEXTUI

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.

LAB // NEXTUI

Badge

Lab-aesthetic badge with green and blue pill variants for experiment tags and status markers.

LAB // NEXTUI

Text

Polymorphic text primitive with body, caption, label, and code variants styled for the LAB dark scientific palette.