Login to your account
Enter your email below to login.
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export default function CardDemo() {
return (
<Card className="w-full">
<CardHeader>
<CardTitle>Login to your account</CardTitle>
<CardDescription>Enter your email below to login.</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
<div className="grid gap-2">
<Label htmlFor="card-email">Email</Label>
<Input id="card-email" type="email" placeholder="m@example.com" />
</div>
<div className="grid gap-2">
<Label htmlFor="card-password">Password</Label>
<Input id="card-password" type="password" />
</div>
</CardContent>
<CardFooter>
<Button className="w-full">Login</Button>
</CardFooter>
</Card>
)
}Installation
npx logic2b@latest add cardWorking with an AI assistant? Copy this prompt into Claude Code, Cursor or Copilot — it carries the install steps, a no-CLI fallback and a verification checklist.
Add the "card" item from the logic2b ui registry (https://ui.logic2b.com) to this project. Follow every step and verify at the end. ## Steps 1. If the project has no `components.json` yet, set up logic2b ui first: ```bash npx logic2b@latest init ``` 2. Install the item (the CLI resolves registry dependencies automatically): ```bash npx logic2b@latest add card ``` 3. Install any npm dependencies the command prints. ## If the CLI is not available Do it manually from the registry payload: 1. Fetch https://ui.logic2b.com/r/card.json. 2. Write every entry in `files[]` to its mapped project path (see below). 3. Repeat (recursively) for each name in `registryDependencies`. 4. Install every package listed in `dependencies` across those payloads. ## Registry reference - Index of every item: https://ui.logic2b.com/r/index.json - Item payload (full source): https://ui.logic2b.com/r/<name>.json - Usage examples per item: https://ui.logic2b.com/r/demos/index.json → https://ui.logic2b.com/r/demos/<demo>.json - Docs index for agents: https://ui.logic2b.com/llms.txt (full docs: https://ui.logic2b.com/llms-full.txt) - Every docs page is Markdown when you append `.md` to its URL. Registry file paths map to project paths like this: - `ui/*` → `@/components/ui/*` - `blocks/<name>/*` → `@/components/*` - `charts/*` → `@/components/charts/*` - `hooks/*` → `@/hooks/*` - `lib/utils.ts` → `@/lib/utils.ts` - `theme.css` → next to the project's Tailwind entry stylesheet ## Conventions (do not break these) - Tailwind CSS v4 (CSS-first config; no tailwind.config.js needed) and React 19. - All colors go through semantic tokens (`bg-primary`, `text-muted-foreground`, `border-border`, …). Never hardcode hex/oklch values in components. - Dark mode is class-based: toggle `.dark` on `<html>`. - Icons come from lucide-react. ## Verify before finishing 1. The dev server starts and the app renders without console errors. 2. TypeScript compiles (`tsc --noEmit` or the framework's check). 3. Components use the theme: a `<Button>` shows the primary token color, and toggling `.dark` on `<html>` switches the palette.
Copy into ui/card.tsx:
import * as React from "react"
import { cn } from "@/lib/utils"
function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card"
className={cn(
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6",
className
)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn(
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
className
)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-title"
className={cn("leading-none font-semibold", className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
}
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-action"
className={cn(
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
className
)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-content"
className={cn("px-6", className)}
{...props}
/>
)
}
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
{...props}
/>
)
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
}Usage
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Description</CardDescription>
<CardAction>{/* e.g. a button, top-right */}</CardAction>
</CardHeader>
<CardContent>Content</CardContent>
<CardFooter>Footer</CardFooter>
</Card>
API
Card is composed of layout primitives — Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, and CardFooter. Each is a styled div that accepts className plus the standard div props; there are no variant props. CardAction is positioned in the top-right of the header, and CardHeader switches to a two-column grid when a CardAction is present.
Examples
With action
Place a control such as a badge or button in the header via CardAction.
Total revenue
$45,231.89
+12.5%
Trending up compared to last month.
import { Badge } from "@/components/ui/badge"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
export default function CardStatsDemo() {
return (
<Card className="w-full max-w-sm">
<CardHeader>
<CardDescription>Total revenue</CardDescription>
<CardTitle className="text-2xl">$45,231.89</CardTitle>
<CardAction>
<Badge variant="secondary">+12.5%</Badge>
</CardAction>
</CardHeader>
<CardContent>
<p className="text-muted-foreground text-sm">
Trending up compared to last month.
</p>
</CardContent>
</Card>
)
}Notification
Combine header, content, and footer for a self-contained panel.
Notifications
You have 3 unread messages.
Your build is ready
2 minutes ago
import { Bell } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
export default function CardNotificationDemo() {
return (
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Bell className="size-4" />
Notifications
</CardTitle>
<CardDescription>You have 3 unread messages.</CardDescription>
</CardHeader>
<CardContent className="grid gap-3">
<div className="flex items-start gap-3 rounded-md border p-3">
<span className="bg-primary mt-1 size-2 shrink-0 rounded-full" />
<div className="grid gap-0.5">
<p className="text-sm font-medium">Your build is ready</p>
<p className="text-muted-foreground text-xs">2 minutes ago</p>
</div>
</div>
</CardContent>
<CardFooter>
<Button variant="outline" className="w-full">
Mark all as read
</Button>
</CardFooter>
</Card>
)
}