All components
NucleusCard
LayoutNewA content card with header/content/footer slots, an optional flush image slot and a hoverLift interaction variant that floats the card on a violet glow.
Preview
Installation
- 1shadcn/ui initialized (`npx shadcn@latest init`)
- 2Tailwind CSS v4 configured with the nucleusUI theme tokens
- 3shadcn Card (`npx shadcn@latest add card`)
npm install lucide-react clsx tailwind-mergeAdd to your globals.css
The nucleusUI accent lives in these CSS variables — without them the component falls back to the default shadcn zinc theme.
app/globals.css
:root {
--primary: oklch(0.54 0.24 291);
--primary-foreground: oklch(0.985 0 0);
--ring: oklch(0.54 0.24 291);
--accent: oklch(0.96 0.03 291);
--accent-foreground: oklch(0.4 0.19 291);
}
.dark {
--primary: oklch(0.68 0.21 291);
--primary-foreground: oklch(0.145 0 0);
--ring: oklch(0.68 0.21 291);
--accent: oklch(0.26 0.06 291);
--accent-foreground: oklch(0.87 0.09 291);
}Usage
tsx
import { NucleusCard } from "@/components/nucleus/nucleus-card";
export function Example() {
return (
<NucleusCard
title="Atomic structure"
description="Everything orbits neatly."
image={<img src="/cover.png" alt="" className="aspect-[3/1] w-full object-cover" />}
hoverLift
footer={<span className="text-xs text-muted-foreground">Updated 2h ago</span>}
>
<p>Card body goes here.</p>
</NucleusCard>
);
}Source
Copy this file into components/nucleus/nucleus-card.tsx in your project — it's yours to own and modify.
components/nucleus/nucleus-card.tsx
import * as React from "react";
import { cn } from "@/lib/utils";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
export interface NucleusCardProps
extends Omit<React.ComponentProps<"div">, "title"> {
/** Card title (rendered in the header). */
title?: React.ReactNode;
/** Muted subtitle rendered under the title. */
description?: React.ReactNode;
/** Optional image slot — rendered flush at the top of the card. */
image?: React.ReactNode;
/** Adds a subtle lift + accent shadow on hover. */
hoverLift?: boolean;
/** Content rendered between header and footer. */
children?: React.ReactNode;
/** Footer slot — ideal for actions or meta info. */
footer?: React.ReactNode;
}
export function NucleusCard({
className,
title,
description,
image,
hoverLift = false,
children,
footer,
...props
}: NucleusCardProps) {
return (
<Card
data-slot="nucleus-card"
className={cn(
hoverLift &&
"transition-[translate,box-shadow,border-color] duration-200 hover:-translate-y-1 hover:border-primary/40 hover:shadow-[0_12px_32px_-16px_color-mix(in_oklch,var(--primary)_45%,transparent)]",
className
)}
{...props}
>
{image}
{(title || description) && (
<CardHeader>
{title && <CardTitle>{title}</CardTitle>}
{description && <CardDescription>{description}</CardDescription>}
</CardHeader>
)}
{children && <CardContent>{children}</CardContent>}
{footer && <CardFooter>{footer}</CardFooter>}
</Card>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Card title rendered in the header. |
description | ReactNode | — | Muted subtitle under the title. |
image | ReactNode | — | Optional image slot, rendered flush at the top. |
hoverLift | boolean | false | Lifts the card with an accent shadow on hover. |
footer | ReactNode | — | Footer slot for actions or meta info. |
className | string | — | Extra classes for the root card element. |