Display15
Form1
Playground3
Perspective Card
A component for displaying cards in a perspective view.
Default
Default perspective card
Card Title
Card description
perspective-card.tsx
1"use client";23import { useState, useRef } from "react";4import { cn } from "@/lib/utils";56interface PerspectiveCardProps {7 title: string;8 description: string;9 image: string;10 className?: string;11 cardHeaderClassName?: string;12 cardTitleClassName?: string;13 cardContentClassName?: string;14 imageContainerClassName?: string;15 descriptionClassName?: string;16 overlayClassName?: string;17 rotationIntensity?: number;18 disablePerspective?: boolean;19 cardStyle?: React.CSSProperties;20 titleColor?: string;21 descriptionColor?: string;22 bgColor?: string;23 borderColor?: string;24}2526export function PerspectiveCard({27 title,28 description,29 image,30 className,31 cardHeaderClassName,32 cardTitleClassName,33 cardContentClassName,34 imageContainerClassName,35 descriptionClassName,36 overlayClassName,37 rotationIntensity = 10,38 disablePerspective = false,39 cardStyle,40 titleColor,41 descriptionColor,42 bgColor,43 borderColor,44}: PerspectiveCardProps) {45 const [rotation, setRotation] = useState({ x: 0, y: 0 });46 const [imageError, setImageError] = useState(false);47 const cardRef = useRef<HTMLDivElement>(null);4849 const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {50 if (!cardRef.current || disablePerspective) return;5152 const rect = cardRef.current.getBoundingClientRect();53 const x = e.clientX - rect.left;54 const y = e.clientY - rect.top;5556 const centerX = rect.width / 2;57 const centerY = rect.height / 2;5859 const rotateX = ((y - centerY) / centerY) * -rotationIntensity;60 const rotateY = ((x - centerX) / centerX) * rotationIntensity;6162 setRotation({ x: rotateX, y: rotateY });63 };6465 const handleMouseLeave = () => {66 setRotation({ x: 0, y: 0 });67 };6869 const handleImageError = () => {70 setImageError(true);71 };7273 // Combine inline styles74 const computedCardStyle = {75 ...cardStyle,76 backgroundColor: bgColor,77 borderColor: borderColor,78 transform: disablePerspective79 ? "none"80 : `perspective(1000px) rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,81 };8283 return (84 <div85 ref={cardRef}86 className={cn(87 // Base styles88 "rounded-lg border shadow-sm",89 "group relative overflow-hidden transition-all duration-300 ease-out hover:shadow-xl",90 // Custom classes should come last to override base styles91 className92 )}93 onMouseMove={handleMouseMove}94 onMouseLeave={handleMouseLeave}95 style={computedCardStyle}96 >97 <div className={cn("h-48 overflow-hidden", imageContainerClassName)}>98 {!imageError ? (99 <img100 src={image}101 alt={title}102 className="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"103 onError={handleImageError}104 crossOrigin="anonymous"105 />106 ) : (107 <div className="w-full h-full flex items-center justify-center bg-gray-100 text-gray-400 text-sm">108 Image not available109 </div>110 )}111 </div>112 <div113 className={cn(114 "absolute inset-0 bg-gradient-to-b from-black/50 to-black/0 opacity-0 transition-opacity group-hover:opacity-100",115 overlayClassName116 )}117 />118 <div119 className={cn(120 "flex flex-col space-y-1.5 p-6 relative z-10",121 cardHeaderClassName122 )}123 >124 <h3125 className={cn(126 "font-semibold leading-none tracking-tight transition-colors group-hover:text-white text-lg",127 cardTitleClassName128 )}129 style={{ color: titleColor }}130 >131 {title}132 </h3>133 </div>134 <div className={cn("p-6 pt-0 relative z-10", cardContentClassName)}>135 <p136 className={cn(137 "text-sm transition-colors group-hover:text-white/80",138 descriptionClassName139 )}140 style={{ color: descriptionColor }}141 >142 {description}143 </p>144 </div>145 </div>146 );147}
Custom Styling
Custom styling for the card
Custom Styled Card
This has custom styles for various parts
perspective-card.tsx
1"use client";23import { useState, useRef } from "react";4import { cn } from "@/lib/utils";56interface PerspectiveCardProps {7 title: string;8 description: string;9 image: string;10 className?: string;11 cardHeaderClassName?: string;12 cardTitleClassName?: string;13 cardContentClassName?: string;14 imageContainerClassName?: string;15 descriptionClassName?: string;16 overlayClassName?: string;17 rotationIntensity?: number;18 disablePerspective?: boolean;19 cardStyle?: React.CSSProperties;20 titleColor?: string;21 descriptionColor?: string;22 bgColor?: string;23 borderColor?: string;24}2526export function PerspectiveCard({27 title,28 description,29 image,30 className,31 cardHeaderClassName,32 cardTitleClassName,33 cardContentClassName,34 imageContainerClassName,35 descriptionClassName,36 overlayClassName,37 rotationIntensity = 10,38 disablePerspective = false,39 cardStyle,40 titleColor,41 descriptionColor,42 bgColor,43 borderColor,44}: PerspectiveCardProps) {45 const [rotation, setRotation] = useState({ x: 0, y: 0 });46 const [imageError, setImageError] = useState(false);47 const cardRef = useRef<HTMLDivElement>(null);4849 const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {50 if (!cardRef.current || disablePerspective) return;5152 const rect = cardRef.current.getBoundingClientRect();53 const x = e.clientX - rect.left;54 const y = e.clientY - rect.top;5556 const centerX = rect.width / 2;57 const centerY = rect.height / 2;5859 const rotateX = ((y - centerY) / centerY) * -rotationIntensity;60 const rotateY = ((x - centerX) / centerX) * rotationIntensity;6162 setRotation({ x: rotateX, y: rotateY });63 };6465 const handleMouseLeave = () => {66 setRotation({ x: 0, y: 0 });67 };6869 const handleImageError = () => {70 setImageError(true);71 };7273 // Combine inline styles74 const computedCardStyle = {75 ...cardStyle,76 backgroundColor: bgColor,77 borderColor: borderColor,78 transform: disablePerspective79 ? "none"80 : `perspective(1000px) rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,81 };8283 return (84 <div85 ref={cardRef}86 className={cn(87 // Base styles88 "rounded-lg border shadow-sm",89 "group relative overflow-hidden transition-all duration-300 ease-out hover:shadow-xl",90 // Custom classes should come last to override base styles91 className92 )}93 onMouseMove={handleMouseMove}94 onMouseLeave={handleMouseLeave}95 style={computedCardStyle}96 >97 <div className={cn("h-48 overflow-hidden", imageContainerClassName)}>98 {!imageError ? (99 <img100 src={image}101 alt={title}102 className="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"103 onError={handleImageError}104 crossOrigin="anonymous"105 />106 ) : (107 <div className="w-full h-full flex items-center justify-center bg-gray-100 text-gray-400 text-sm">108 Image not available109 </div>110 )}111 </div>112 <div113 className={cn(114 "absolute inset-0 bg-gradient-to-b from-black/50 to-black/0 opacity-0 transition-opacity group-hover:opacity-100",115 overlayClassName116 )}117 />118 <div119 className={cn(120 "flex flex-col space-y-1.5 p-6 relative z-10",121 cardHeaderClassName122 )}123 >124 <h3125 className={cn(126 "font-semibold leading-none tracking-tight transition-colors group-hover:text-white text-lg",127 cardTitleClassName128 )}129 style={{ color: titleColor }}130 >131 {title}132 </h3>133 </div>134 <div className={cn("p-6 pt-0 relative z-10", cardContentClassName)}>135 <p136 className={cn(137 "text-sm transition-colors group-hover:text-white/80",138 descriptionClassName139 )}140 style={{ color: descriptionColor }}141 >142 {description}143 </p>144 </div>145 </div>146 );147}
Custom Colours
Custom colours for the card using direct color props
Custom Colours
Using direct color props
perspective-card.tsx
1"use client";23import { useState, useRef } from "react";4import { cn } from "@/lib/utils";56interface PerspectiveCardProps {7 title: string;8 description: string;9 image: string;10 className?: string;11 cardHeaderClassName?: string;12 cardTitleClassName?: string;13 cardContentClassName?: string;14 imageContainerClassName?: string;15 descriptionClassName?: string;16 overlayClassName?: string;17 rotationIntensity?: number;18 disablePerspective?: boolean;19 cardStyle?: React.CSSProperties;20 titleColor?: string;21 descriptionColor?: string;22 bgColor?: string;23 borderColor?: string;24}2526export function PerspectiveCard({27 title,28 description,29 image,30 className,31 cardHeaderClassName,32 cardTitleClassName,33 cardContentClassName,34 imageContainerClassName,35 descriptionClassName,36 overlayClassName,37 rotationIntensity = 10,38 disablePerspective = false,39 cardStyle,40 titleColor,41 descriptionColor,42 bgColor,43 borderColor,44}: PerspectiveCardProps) {45 const [rotation, setRotation] = useState({ x: 0, y: 0 });46 const [imageError, setImageError] = useState(false);47 const cardRef = useRef<HTMLDivElement>(null);4849 const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {50 if (!cardRef.current || disablePerspective) return;5152 const rect = cardRef.current.getBoundingClientRect();53 const x = e.clientX - rect.left;54 const y = e.clientY - rect.top;5556 const centerX = rect.width / 2;57 const centerY = rect.height / 2;5859 const rotateX = ((y - centerY) / centerY) * -rotationIntensity;60 const rotateY = ((x - centerX) / centerX) * rotationIntensity;6162 setRotation({ x: rotateX, y: rotateY });63 };6465 const handleMouseLeave = () => {66 setRotation({ x: 0, y: 0 });67 };6869 const handleImageError = () => {70 setImageError(true);71 };7273 // Combine inline styles74 const computedCardStyle = {75 ...cardStyle,76 backgroundColor: bgColor,77 borderColor: borderColor,78 transform: disablePerspective79 ? "none"80 : `perspective(1000px) rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,81 };8283 return (84 <div85 ref={cardRef}86 className={cn(87 // Base styles88 "rounded-lg border shadow-sm",89 "group relative overflow-hidden transition-all duration-300 ease-out hover:shadow-xl",90 // Custom classes should come last to override base styles91 className92 )}93 onMouseMove={handleMouseMove}94 onMouseLeave={handleMouseLeave}95 style={computedCardStyle}96 >97 <div className={cn("h-48 overflow-hidden", imageContainerClassName)}>98 {!imageError ? (99 <img100 src={image}101 alt={title}102 className="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"103 onError={handleImageError}104 crossOrigin="anonymous"105 />106 ) : (107 <div className="w-full h-full flex items-center justify-center bg-gray-100 text-gray-400 text-sm">108 Image not available109 </div>110 )}111 </div>112 <div113 className={cn(114 "absolute inset-0 bg-gradient-to-b from-black/50 to-black/0 opacity-0 transition-opacity group-hover:opacity-100",115 overlayClassName116 )}117 />118 <div119 className={cn(120 "flex flex-col space-y-1.5 p-6 relative z-10",121 cardHeaderClassName122 )}123 >124 <h3125 className={cn(126 "font-semibold leading-none tracking-tight transition-colors group-hover:text-white text-lg",127 cardTitleClassName128 )}129 style={{ color: titleColor }}130 >131 {title}132 </h3>133 </div>134 <div className={cn("p-6 pt-0 relative z-10", cardContentClassName)}>135 <p136 className={cn(137 "text-sm transition-colors group-hover:text-white/80",138 descriptionClassName139 )}140 style={{ color: descriptionColor }}141 >142 {description}143 </p>144 </div>145 </div>146 );147}
Tailwind Color Classes
Using Tailwind color classes with tailwind-merge
Tailwind Colors
Using Tailwind color utilities
perspective-card.tsx
1"use client";23import { useState, useRef } from "react";4import { cn } from "@/lib/utils";56interface PerspectiveCardProps {7 title: string;8 description: string;9 image: string;10 className?: string;11 cardHeaderClassName?: string;12 cardTitleClassName?: string;13 cardContentClassName?: string;14 imageContainerClassName?: string;15 descriptionClassName?: string;16 overlayClassName?: string;17 rotationIntensity?: number;18 disablePerspective?: boolean;19 cardStyle?: React.CSSProperties;20 titleColor?: string;21 descriptionColor?: string;22 bgColor?: string;23 borderColor?: string;24}2526export function PerspectiveCard({27 title,28 description,29 image,30 className,31 cardHeaderClassName,32 cardTitleClassName,33 cardContentClassName,34 imageContainerClassName,35 descriptionClassName,36 overlayClassName,37 rotationIntensity = 10,38 disablePerspective = false,39 cardStyle,40 titleColor,41 descriptionColor,42 bgColor,43 borderColor,44}: PerspectiveCardProps) {45 const [rotation, setRotation] = useState({ x: 0, y: 0 });46 const [imageError, setImageError] = useState(false);47 const cardRef = useRef<HTMLDivElement>(null);4849 const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {50 if (!cardRef.current || disablePerspective) return;5152 const rect = cardRef.current.getBoundingClientRect();53 const x = e.clientX - rect.left;54 const y = e.clientY - rect.top;5556 const centerX = rect.width / 2;57 const centerY = rect.height / 2;5859 const rotateX = ((y - centerY) / centerY) * -rotationIntensity;60 const rotateY = ((x - centerX) / centerX) * rotationIntensity;6162 setRotation({ x: rotateX, y: rotateY });63 };6465 const handleMouseLeave = () => {66 setRotation({ x: 0, y: 0 });67 };6869 const handleImageError = () => {70 setImageError(true);71 };7273 // Combine inline styles74 const computedCardStyle = {75 ...cardStyle,76 backgroundColor: bgColor,77 borderColor: borderColor,78 transform: disablePerspective79 ? "none"80 : `perspective(1000px) rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,81 };8283 return (84 <div85 ref={cardRef}86 className={cn(87 // Base styles88 "rounded-lg border shadow-sm",89 "group relative overflow-hidden transition-all duration-300 ease-out hover:shadow-xl",90 // Custom classes should come last to override base styles91 className92 )}93 onMouseMove={handleMouseMove}94 onMouseLeave={handleMouseLeave}95 style={computedCardStyle}96 >97 <div className={cn("h-48 overflow-hidden", imageContainerClassName)}>98 {!imageError ? (99 <img100 src={image}101 alt={title}102 className="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"103 onError={handleImageError}104 crossOrigin="anonymous"105 />106 ) : (107 <div className="w-full h-full flex items-center justify-center bg-gray-100 text-gray-400 text-sm">108 Image not available109 </div>110 )}111 </div>112 <div113 className={cn(114 "absolute inset-0 bg-gradient-to-b from-black/50 to-black/0 opacity-0 transition-opacity group-hover:opacity-100",115 overlayClassName116 )}117 />118 <div119 className={cn(120 "flex flex-col space-y-1.5 p-6 relative z-10",121 cardHeaderClassName122 )}123 >124 <h3125 className={cn(126 "font-semibold leading-none tracking-tight transition-colors group-hover:text-white text-lg",127 cardTitleClassName128 )}129 style={{ color: titleColor }}130 >131 {title}132 </h3>133 </div>134 <div className={cn("p-6 pt-0 relative z-10", cardContentClassName)}>135 <p136 className={cn(137 "text-sm transition-colors group-hover:text-white/80",138 descriptionClassName139 )}140 style={{ color: descriptionColor }}141 >142 {description}143 </p>144 </div>145 </div>146 );147}
Multiple Styling Options
Different ways to style the PerspectiveCard
Combined Styling
Mix of Tailwind and custom styles
perspective-card.tsx
1"use client";23import { useState, useRef } from "react";4import { cn } from "@/lib/utils";56interface PerspectiveCardProps {7 title: string;8 description: string;9 image: string;10 className?: string;11 cardHeaderClassName?: string;12 cardTitleClassName?: string;13 cardContentClassName?: string;14 imageContainerClassName?: string;15 descriptionClassName?: string;16 overlayClassName?: string;17 rotationIntensity?: number;18 disablePerspective?: boolean;19 cardStyle?: React.CSSProperties;20 titleColor?: string;21 descriptionColor?: string;22 bgColor?: string;23 borderColor?: string;24}2526export function PerspectiveCard({27 title,28 description,29 image,30 className,31 cardHeaderClassName,32 cardTitleClassName,33 cardContentClassName,34 imageContainerClassName,35 descriptionClassName,36 overlayClassName,37 rotationIntensity = 10,38 disablePerspective = false,39 cardStyle,40 titleColor,41 descriptionColor,42 bgColor,43 borderColor,44}: PerspectiveCardProps) {45 const [rotation, setRotation] = useState({ x: 0, y: 0 });46 const [imageError, setImageError] = useState(false);47 const cardRef = useRef<HTMLDivElement>(null);4849 const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {50 if (!cardRef.current || disablePerspective) return;5152 const rect = cardRef.current.getBoundingClientRect();53 const x = e.clientX - rect.left;54 const y = e.clientY - rect.top;5556 const centerX = rect.width / 2;57 const centerY = rect.height / 2;5859 const rotateX = ((y - centerY) / centerY) * -rotationIntensity;60 const rotateY = ((x - centerX) / centerX) * rotationIntensity;6162 setRotation({ x: rotateX, y: rotateY });63 };6465 const handleMouseLeave = () => {66 setRotation({ x: 0, y: 0 });67 };6869 const handleImageError = () => {70 setImageError(true);71 };7273 // Combine inline styles74 const computedCardStyle = {75 ...cardStyle,76 backgroundColor: bgColor,77 borderColor: borderColor,78 transform: disablePerspective79 ? "none"80 : `perspective(1000px) rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,81 };8283 return (84 <div85 ref={cardRef}86 className={cn(87 // Base styles88 "rounded-lg border shadow-sm",89 "group relative overflow-hidden transition-all duration-300 ease-out hover:shadow-xl",90 // Custom classes should come last to override base styles91 className92 )}93 onMouseMove={handleMouseMove}94 onMouseLeave={handleMouseLeave}95 style={computedCardStyle}96 >97 <div className={cn("h-48 overflow-hidden", imageContainerClassName)}>98 {!imageError ? (99 <img100 src={image}101 alt={title}102 className="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"103 onError={handleImageError}104 crossOrigin="anonymous"105 />106 ) : (107 <div className="w-full h-full flex items-center justify-center bg-gray-100 text-gray-400 text-sm">108 Image not available109 </div>110 )}111 </div>112 <div113 className={cn(114 "absolute inset-0 bg-gradient-to-b from-black/50 to-black/0 opacity-0 transition-opacity group-hover:opacity-100",115 overlayClassName116 )}117 />118 <div119 className={cn(120 "flex flex-col space-y-1.5 p-6 relative z-10",121 cardHeaderClassName122 )}123 >124 <h3125 className={cn(126 "font-semibold leading-none tracking-tight transition-colors group-hover:text-white text-lg",127 cardTitleClassName128 )}129 style={{ color: titleColor }}130 >131 {title}132 </h3>133 </div>134 <div className={cn("p-6 pt-0 relative z-10", cardContentClassName)}>135 <p136 className={cn(137 "text-sm transition-colors group-hover:text-white/80",138 descriptionClassName139 )}140 style={{ color: descriptionColor }}141 >142 {description}143 </p>144 </div>145 </div>146 );147}
Disable Perspective
Disable the perspective effect
No Perspective
This has the perspective effect disabled
perspective-card.tsx
1"use client";23import { useState, useRef } from "react";4import { cn } from "@/lib/utils";56interface PerspectiveCardProps {7 title: string;8 description: string;9 image: string;10 className?: string;11 cardHeaderClassName?: string;12 cardTitleClassName?: string;13 cardContentClassName?: string;14 imageContainerClassName?: string;15 descriptionClassName?: string;16 overlayClassName?: string;17 rotationIntensity?: number;18 disablePerspective?: boolean;19 cardStyle?: React.CSSProperties;20 titleColor?: string;21 descriptionColor?: string;22 bgColor?: string;23 borderColor?: string;24}2526export function PerspectiveCard({27 title,28 description,29 image,30 className,31 cardHeaderClassName,32 cardTitleClassName,33 cardContentClassName,34 imageContainerClassName,35 descriptionClassName,36 overlayClassName,37 rotationIntensity = 10,38 disablePerspective = false,39 cardStyle,40 titleColor,41 descriptionColor,42 bgColor,43 borderColor,44}: PerspectiveCardProps) {45 const [rotation, setRotation] = useState({ x: 0, y: 0 });46 const [imageError, setImageError] = useState(false);47 const cardRef = useRef<HTMLDivElement>(null);4849 const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {50 if (!cardRef.current || disablePerspective) return;5152 const rect = cardRef.current.getBoundingClientRect();53 const x = e.clientX - rect.left;54 const y = e.clientY - rect.top;5556 const centerX = rect.width / 2;57 const centerY = rect.height / 2;5859 const rotateX = ((y - centerY) / centerY) * -rotationIntensity;60 const rotateY = ((x - centerX) / centerX) * rotationIntensity;6162 setRotation({ x: rotateX, y: rotateY });63 };6465 const handleMouseLeave = () => {66 setRotation({ x: 0, y: 0 });67 };6869 const handleImageError = () => {70 setImageError(true);71 };7273 // Combine inline styles74 const computedCardStyle = {75 ...cardStyle,76 backgroundColor: bgColor,77 borderColor: borderColor,78 transform: disablePerspective79 ? "none"80 : `perspective(1000px) rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,81 };8283 return (84 <div85 ref={cardRef}86 className={cn(87 // Base styles88 "rounded-lg border shadow-sm",89 "group relative overflow-hidden transition-all duration-300 ease-out hover:shadow-xl",90 // Custom classes should come last to override base styles91 className92 )}93 onMouseMove={handleMouseMove}94 onMouseLeave={handleMouseLeave}95 style={computedCardStyle}96 >97 <div className={cn("h-48 overflow-hidden", imageContainerClassName)}>98 {!imageError ? (99 <img100 src={image}101 alt={title}102 className="w-full h-full object-cover transition-transform duration-300 ease-out group-hover:scale-110"103 onError={handleImageError}104 crossOrigin="anonymous"105 />106 ) : (107 <div className="w-full h-full flex items-center justify-center bg-gray-100 text-gray-400 text-sm">108 Image not available109 </div>110 )}111 </div>112 <div113 className={cn(114 "absolute inset-0 bg-gradient-to-b from-black/50 to-black/0 opacity-0 transition-opacity group-hover:opacity-100",115 overlayClassName116 )}117 />118 <div119 className={cn(120 "flex flex-col space-y-1.5 p-6 relative z-10",121 cardHeaderClassName122 )}123 >124 <h3125 className={cn(126 "font-semibold leading-none tracking-tight transition-colors group-hover:text-white text-lg",127 cardTitleClassName128 )}129 style={{ color: titleColor }}130 >131 {title}132 </h3>133 </div>134 <div className={cn("p-6 pt-0 relative z-10", cardContentClassName)}>135 <p136 className={cn(137 "text-sm transition-colors group-hover:text-white/80",138 descriptionClassName139 )}140 style={{ color: descriptionColor }}141 >142 {description}143 </p>144 </div>145 </div>146 );147}
Props
| Name | Type | Default | Description |
|---|---|---|---|
| title | string | Required | Title of the card |
| description | string | Required | Description of the card |
| image | string | Required | URL of the card image (local or remote) |
| className | string | Tailwind classes for styling the card. These will properly override base styles using tailwind-merge. | |
| cardStyle | React.CSSProperties | {} | Inline styles to apply directly to the card. Useful for custom shadows, animations, or complex styling. |
| bgColor | string | Direct background color value (hex, rgb, etc.) for the card. Alternative to Tailwind bg-* classes. | |
| borderColor | string | Direct border color value (hex, rgb, etc.) for the card. Alternative to Tailwind border-* classes. | |
| titleColor | string | Direct text color value (hex, rgb, etc.) for the title. Alternative to Tailwind text-* classes. | |
| descriptionColor | string | Direct text color value (hex, rgb, etc.) for the description. Alternative to Tailwind text-* classes. | |
| cardHeaderClassName | string | Tailwind classes for styling the card header. These will properly override base styles using tailwind-merge. | |
| cardTitleClassName | string | Tailwind classes for styling the card title. These will properly override base styles using tailwind-merge. | |
| cardContentClassName | string | Tailwind classes for styling the card content. These will properly override base styles using tailwind-merge. | |
| imageContainerClassName | string | Tailwind classes for styling the image container. These will properly override base styles using tailwind-merge. | |
| overlayClassName | string | Tailwind classes for styling the gradient overlay. These will properly override base styles using tailwind-merge. | |
| descriptionClassName | string | Tailwind classes for styling the description. These will properly override base styles using tailwind-merge. | |
| rotationIntensity | number | 10 | How much the card rotates on hover (higher = more rotation) |
| disablePerspective | boolean | false | Disables the 3D perspective effect |