Kavi Katiyar

Animated Card

Cards 391

About

AnimatedJobCard This component displays job posting information with a subtle, interactive 3D tilt animation on hover. It's designed to be highly reusable, accepting props for content and color variants.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Animated Card to your project and fits it to your theme.

Code

How Animated Card is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import React, { useState } from "react";
import { AnimatedJobCard, JobCardProps } from "@/components/ui/animated-card";
import { cn } from "@/lib/utils";

// --- SVG ICONS FOR DEMO ---
const SlackIcon = () => (
  <svg viewBox="0 0 2447.6 2452.5"><g clip-rule="evenodd" fill-rule="evenodd"><path d="m897.4 0c-135.3.1-244.8 109.9-244.7 245.2-.1 135.3 109.5 245.1 244.8 245.2h244.8v-245.1c.1-135.3-109.5-245.1-244.9-245.3.1 0 .1 0 0 0m0 654h-652.6c-135.3.1-244.9 109.9-244.8 245.2-.2 135.3 109.4 245.1 244.7 245.3h652.7c135.3-.1 244.9-109.9 244.8-245.2.1-135.4-109.5-245.2-244.8-245.3z" fill="#36c5f0"/><path d="m2447.6 899.2c.1-135.3-109.5-245.1-244.8-245.2-135.3.1-244.9 109.9-244.8 245.2v245.3h244.8c135.3-.1 244.9-109.9 244.8-245.3zm-652.7 0v-654c.1-135.2-109.4-245-244.7-245.2-135.3.1-244.9 109.9-244.8 245.2v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.3z" fill="#2eb67d"/><path d="m1550.1 2452.5c135.3-.1 244.9-109.9 244.8-245.2.1-135.3-109.5-245.1-244.8-245.2h-244.8v245.2c-.1 135.2 109.5 245 244.8 245.2zm0-654.1h652.7c135.3-.1 244.9-109.9 244.8-245.2.2-135.3-109.4-245.1-244.7-245.3h-652.7c-135.3.1-244.9 109.9-244.8 245.2-.1 135.4 109.4 245.2 244.7 245.3z" fill="#ecb22e"/><path d="m0 1553.2c-.1 135.3 109.5 245.1 244.8 245.2 135.3-.1 244.9-109.9 244.8-245.2v-245.2h-244.8c-135.3.1-244.9 109.9-244.8 245.2zm652.7 0v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.2v-653.9c.2-135.3-109.4-245.1-244.7-245.3-135.4 0-244.9 109.8-244.8 245.1 0 0 0 .1 0 0" fill="#e01e5a"/></g></svg>
);

const GoogleIcon = () => (
  <svg viewBox="0 0 256 262" preserveAspectRatio="xMidYMid"><path d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027" fill="#4285F4"/><path d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1" fill="#34A853"/><path d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782" fill="#FBBC05"/><path d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251" fill="#EB4335"/></svg>
);

// --- INITIAL DEMO DATA ---
const initialJobs: JobCardProps[] = [
  {
    companyLogo: <SlackIcon />,
    companyName: "Slack",
    jobTitle: "Senior UI Designer",
    salary: "$3,500-5,500 net",
    tags: ["Project Based", "Remote"],
    postedDate: "Posted 2 Day Ago",
    variant: "pink",
  },
  {
    companyLogo: <GoogleIcon />,
    companyName: "Google",
    jobTitle: "Lead UX Designer",
    salary: "$4,000-6,000 net",
    tags: ["Full Time", "B2B"],
    postedDate: "Posted Yesterday",
    variant: "yellow",
  },
  {
    companyLogo: <SlackIcon />,
    companyName: "Slack",
    jobTitle: "Lead Product Designer",
    salary: "$3,500-5,500 net",
    tags: ["Full Time", "Remote"],
    postedDate: "Posted 2 Day Ago",
    variant: "blue",
  },
];

// --- DEMO COMPONENT ---
export default function AnimatedJobCardDemo() {
  const [cards, setCards] = useState(initialJobs);

  const cardTransforms = [
    "rotate-[-8deg] translate-x-[-30%] translate-y-[10%] z-0",
    "rotate-[0deg] translate-y-[-5%] z-20",
    "rotate-[8deg] translate-x-[30%] translate-y-[10%] z-10",
  ];

  const handleCardClick = (index: number) => {
    if (index === 1) return;
    const newCards = [...cards];
    const clickedCard = newCards.splice(index, 1)[0];
    newCards.splice(1, 0, clickedCard);
    setCards(newCards);
  };

  return (
    <div className="relative flex h-[500px] w-full items-center justify-center bg-background">
      <div className="relative h-full w-full" style={{ perspective: "1000px" }}>
        {cards.map((job, index) => (
          <AnimatedJobCard
            key={job.jobTitle + job.companyName}
            {...job}
            onClick={() => handleCardClick(index)}
            className={cn(
              "absolute left-0 right-0 top-1/4 mx-auto",
              "w-96",
              cardTransforms[index]
            )}
          />
        ))}
      </div>
    </div>
  );
}

Dependencies

More by Kavi Katiyar

View all
  • 3D Card

    3D Card

    974
  • Bento Product Features

    Bento Product Features

    828
  • Testimonial Slider

    Testimonial Slider

    713
  • Card

    Card

    604
  • Order Confirmation Card

    Order Confirmation Card

    499
  • Project Detail View

    Project Detail View

    407
  • State

    State

    392
  • Performance Benchmark Card

    Performance Benchmark Card

    386

More in Cards

View all
  • Course Design Cards

    Course Design Cards

    1.1K
  • Stats cards with links

    Stats cards with links

    119
  • Statistics Card 2

    Statistics Card 2

    258
  • Card

    Card

    54
  • Statistics Card 7

    Statistics Card 7

    288
  • The Item one

    The Item one

    3
  • Card Studio

    Card Studio

    9
  • Weather Card

    Weather Card

    52