since3-website/components/ui/card.tsx
2026-09-25 00:45:33 +02:00

96 lines
2 KiB
TypeScript

import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
/**
* Two strictly separate variants (DESIGN.md §8):
* - `flat`: hairline, no shadow, no blur. For lists.
* - `glass`: tool panels only. Never mix both in one section.
*/
const cardVariants = cva("flex flex-col text-card-foreground", {
variants: {
variant: {
flat: "card-flat rounded-2xl border border-line bg-transparent",
glass: "glass",
},
},
defaultVariants: {
variant: "flat",
},
})
function Card({
className,
variant,
...props
}: React.ComponentProps<"div"> & VariantProps<typeof cardVariants>) {
return (
<div
data-slot="card"
data-variant={variant ?? "flat"}
className={cn(cardVariants({ variant }), className)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn("flex flex-col gap-2 p-6", className)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<"h3">) {
return (
<h3
data-slot="card-title"
className={cn("text-title font-heading", className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<p
data-slot="card-description"
className={cn("type-body text-fg-muted", className)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-content"
className={cn("px-6 pb-6", className)}
{...props}
/>
)
}
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center px-6 pb-6", className)}
{...props}
/>
)
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardDescription,
CardContent,
cardVariants,
}