File size: 1,885 Bytes
65d68f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"use client";

import { forwardRef } from "react";
import { cn } from "@/lib/utils";

// =============================================================================
// CleanCard — White card with subtle border, optional hover lift
// =============================================================================

export type CleanCardVariant = "default" | "outlined" | "elevated" | "ghost";

export interface CleanCardProps extends React.HTMLAttributes<HTMLDivElement> {
  variant?: CleanCardVariant;
  padding?: "none" | "sm" | "md" | "lg";
  hoverable?: boolean;
}

const variantClasses: Record<CleanCardVariant, string> = {
  default:
    "bg-white border border-[#E4E6EC] shadow-[0_1px_2px_rgba(15,17,23,0.03),0_8px_24px_rgba(15,17,23,0.04)]",
  outlined: "bg-white border border-[#E4E6EC]",
  elevated:
    "bg-white border border-[#EEF0F4] shadow-[0_4px_12px_rgba(15,17,23,0.05),0_16px_40px_-12px_rgba(15,17,23,0.1)]",
  ghost: "bg-transparent",
};

const paddingClasses: Record<NonNullable<CleanCardProps["padding"]>, string> = {
  none: "",
  sm: "p-3",
  md: "p-5",
  lg: "p-6",
};

export const CleanCard = forwardRef<HTMLDivElement, CleanCardProps>(
  ({ variant = "default", padding = "md", hoverable = false, className, children, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={cn(
          "rounded-xl transition-[transform,box-shadow,border-color] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)]",
          variantClasses[variant],
          paddingClasses[padding],
          hoverable &&
            "cursor-pointer hover:-translate-y-0.5 hover:border-[#D4D7E0] hover:shadow-[0_2px_4px_rgba(15,17,23,0.04),0_14px_36px_rgba(15,17,23,0.08)] active:translate-y-0 active:scale-[0.995]",
          className,
        )}
        {...props}
      >
        {children}
      </div>
    );
  },
);

CleanCard.displayName = "CleanCard";