Please use Desktop to view and interact with components
Blocks500mseaseOut
Team Section Block
Animated team member cards with avatars, roles, and social links
teammemberscardsavatarssocialaboutshadcn
Useto navigate between components
Preview
Our Dream Team
Meet the people behind
our success
A diverse team of talented individuals working together to build amazing products and deliver exceptional results.
Sarah Johnson
CEO & Founder
San Francisco
Visionary leader with 15+ years in tech
Strategy
Leadership
Innovation
Michael Chen
CTO
New York
Full-stack architect and AI enthusiast
AI/ML
Architecture
Cloud
Emily Rodriguez
Head of Design
London
Creative mind behind beautiful interfaces
UI/UX
Branding
Motion
David Park
Lead Developer
Tokyo
Code wizard and performance optimizer
React
TypeScript
Performance
Join Our Amazing Team
We're always looking for talented people to join our mission
This component requires shadcn/ui
This component uses shadcn/ui components. Make sure you have shadcn/ui set up in your project.
- Install shadcn/ui:
npx shadcn-ui@latest init - Install required components based on the imports in the code (e.g.,
npx shadcn-ui@latest add button) - Ensure your
tailwind.config.tsandglobals.cssare configured as per shadcn/ui documentation
Code
TypeScript + React
'use client'
import { useState } from 'react'
import { motion, useMotionValue, useSpring, useTransform } from 'framer-motion'
import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Github, Linkedin, Twitter, Mail, MapPin, Sparkles } from 'lucide-react'
const teamMembers = [
{
name: 'Sarah Johnson',
role: 'CEO & Founder',
bio: 'Visionary leader with 15+ years in tech',
image: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Sarah',
location: 'San Francisco',
skills: ['Strategy', 'Leadership', 'Innovation'],
gradient: 'from-purple-500/20 to-pink-500/20',
social: {
twitter: '#',
linkedin: '#',
github: '#',
email: 'sarah@example.com',
},
},
{
name: 'Michael Chen',
role: 'CTO',
bio: 'Full-stack architect and AI enthusiast',
image: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Michael',
location: 'New York',
skills: ['AI/ML', 'Architecture', 'Cloud'],
gradient: 'from-blue-500/20 to-cyan-500/20',
social: {
twitter: '#',
linkedin: '#',
github: '#',
email: 'michael@example.com',
},
},
{
name: 'Emily Rodriguez',
role: 'Head of Design',
bio: 'Creative mind behind beautiful interfaces',
image: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Emily',
location: 'London',
skills: ['UI/UX', 'Branding', 'Motion'],
gradient: 'from-orange-500/20 to-red-500/20',
social: {
twitter: '#',
linkedin: '#',
github: '#',
email: 'emily@example.com',
},
},
{
name: 'David Park',
role: 'Lead Developer',
bio: 'Code wizard and performance optimizer',
image: 'https://api.dicebear.com/7.x/avataaars/svg?seed=David',
location: 'Tokyo',
skills: ['React', 'TypeScript', 'Performance'],
gradient: 'from-green-500/20 to-emerald-500/20',
social: {
twitter: '#',
linkedin: '#',
github: '#',
email: 'david@example.com',
},
},
]
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.15,
delayChildren: 0.3,
},
},
}
const itemVariants = {
hidden: { opacity: 0, y: 30, scale: 0.9 },
visible: {
opacity: 1,
y: 0,
scale: 1,
transition: {
duration: 0.6,
ease: [0.6, 0.05, 0.01, 0.9],
},
},
}
function TeamMemberCard({ member, index }: { member: typeof teamMembers[0]; index: number }) {
const [isHovered, setIsHovered] = useState(false)
const mouseX = useMotionValue(0)
const mouseY = useMotionValue(0)
const rotateX = useSpring(useTransform(mouseY, [-0.5, 0.5], [5, -5]), {
stiffness: 300,
damping: 30,
})
const rotateY = useSpring(useTransform(mouseX, [-0.5, 0.5], [-5, 5]), {
stiffness: 300,
damping: 30,
})
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
const rect = e.currentTarget.getBoundingClientRect()
const width = rect.width
const height = rect.height
const x = (e.clientX - rect.left - width / 2) / (width / 2)
const y = (e.clientY - rect.top - height / 2) / (height / 2)
mouseX.set(x)
mouseY.set(y)
}
const handleMouseLeave = () => {
mouseX.set(0)
mouseY.set(0)
setIsHovered(false)
}
return (
<motion.div variants={itemVariants} className="perspective-1000">
<motion.div
style={{
rotateX,
rotateY,
transformStyle: 'preserve-3d',
}}
onMouseMove={handleMouseMove}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={handleMouseLeave}
className="group relative"
>
<Card className="relative overflow-hidden border-border/50 bg-gradient-to-br from-card to-card/50 backdrop-blur-sm transition-all duration-300 hover:border-primary/50 hover:shadow-2xl">
{/* Animated gradient overlay */}
<motion.div
className={`absolute inset-0 bg-gradient-to-br ${member.gradient} opacity-0 transition-opacity duration-500 group-hover:opacity-100`}
/>
{/* Sparkle effect on hover */}
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={isHovered ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0 }}
className="absolute right-4 top-4 z-10"
>
<Sparkles className="h-5 w-5 text-primary" />
</motion.div>
<div className="relative z-10 p-6">
{/* Avatar Section */}
<div className="mb-4 flex justify-center">
<motion.div
className="relative"
whileHover={{ scale: 1.05 }}
transition={{ type: 'spring', stiffness: 300, damping: 20 }}
>
<motion.div
className="absolute -inset-2 rounded-full bg-gradient-to-r from-primary/50 to-primary/0 opacity-0 blur-lg transition-opacity duration-500 group-hover:opacity-100"
animate={
isHovered
? { rotate: 360, scale: [1, 1.1, 1] }
: { rotate: 0 }
}
transition={{ duration: 3, repeat: Infinity, ease: 'linear' }}
/>
<div className="relative h-28 w-28 overflow-hidden rounded-full border-2 border-primary/30 bg-gradient-to-br from-primary/10 to-transparent p-1">
<motion.img
src={member.image}
alt={member.name}
className="h-full w-full rounded-full object-cover"
whileHover={{ scale: 1.1 }}
transition={{ duration: 0.3 }}
/>
</div>
</motion.div>
</div>
{/* Info Section */}
<div className="text-center">
<motion.h3
className="mb-1 text-xl font-bold tracking-tight"
animate={isHovered ? { scale: 1.05 } : { scale: 1 }}
transition={{ duration: 0.2 }}
>
{member.name}
</motion.h3>
<Badge variant="secondary" className="mb-2">
{member.role}
</Badge>
<motion.div
className="mb-3 flex items-center justify-center gap-1 text-xs text-muted-foreground"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.2 }}
>
<MapPin className="h-3 w-3" />
<span>{member.location}</span>
</motion.div>
<p className="mb-4 text-sm text-muted-foreground">{member.bio}</p>
{/* Skills */}
<motion.div
className="mb-4 flex flex-wrap justify-center gap-1.5"
initial={{ opacity: 0, y: 10 }}
animate={isHovered ? { opacity: 1, y: 0 } : { opacity: 0.7, y: 0 }}
transition={{ duration: 0.3 }}
>
{member.skills.map((skill, idx) => (
<motion.div
key={skill}
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ delay: 0.1 * idx, type: 'spring' }}
>
<Badge
variant="outline"
className="text-xs transition-colors hover:bg-primary/10"
>
{skill}
</Badge>
</motion.div>
))}
</motion.div>
{/* Social Links */}
<motion.div
className="flex justify-center gap-2"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.3 }}
>
{[
{ icon: Twitter, label: 'Twitter', color: 'hover:text-blue-400' },
{ icon: Linkedin, label: 'LinkedIn', color: 'hover:text-blue-600' },
{ icon: Github, label: 'GitHub', color: 'hover:text-foreground' },
{ icon: Mail, label: 'Email', color: 'hover:text-red-500' },
].map((social, idx) => (
<motion.div
key={social.label}
initial={{ scale: 0, rotate: -180 }}
animate={isHovered ? { scale: 1, rotate: 0 } : { scale: 0.8, rotate: 0 }}
transition={{
delay: isHovered ? 0.1 * idx : 0,
type: 'spring',
stiffness: 300,
damping: 20,
}}
>
<Button
size="icon"
variant="ghost"
className={`h-8 w-8 transition-colors ${social.color}`}
>
<motion.div
whileHover={{ scale: 1.3, rotate: 360 }}
transition={{ duration: 0.4 }}
>
<social.icon className="h-4 w-4" />
</motion.div>
</Button>
</motion.div>
))}
</motion.div>
</div>
</div>
</Card>
</motion.div>
</motion.div>
)
}
export function TeamSectionBlock() {
return (
<section className="relative w-full overflow-hidden bg-gradient-to-b from-background via-background to-primary/5 px-4 py-20">
{/* Background decorative elements */}
<div className="absolute inset-0 -z-10 overflow-hidden">
<motion.div
animate={{
scale: [1, 1.2, 1],
rotate: [0, 90, 0],
opacity: [0.3, 0.5, 0.3],
}}
transition={{ duration: 20, repeat: Infinity, ease: 'linear' }}
className="absolute -right-20 -top-20 h-80 w-80 rounded-full bg-primary/10 blur-3xl"
/>
<motion.div
animate={{
scale: [1.2, 1, 1.2],
rotate: [0, -90, 0],
opacity: [0.3, 0.5, 0.3],
}}
transition={{ duration: 15, repeat: Infinity, ease: 'linear' }}
className="absolute -bottom-20 -left-20 h-80 w-80 rounded-full bg-primary/10 blur-3xl"
/>
</div>
<div className="mx-auto max-w-7xl">
{/* Header */}
<motion.div
initial={{ opacity: 0, y: -30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, ease: [0.6, 0.05, 0.01, 0.9] }}
className="mb-16 text-center"
>
<motion.div
className="mb-6 inline-block"
>
<Badge className="gap-2" variant="secondary">
<Sparkles className="h-3 w-3" />
Our Dream Team
</Badge>
</motion.div>
<motion.h2
className="mb-6 bg-gradient-to-r from-foreground via-foreground/80 to-foreground bg-clip-text text-5xl font-bold tracking-tight text-transparent md:text-6xl"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2, duration: 0.6 }}
>
Meet the people behind
<br />
<span className="bg-gradient-to-r from-primary to-primary/60 bg-clip-text text-transparent">
our success
</span>
</motion.h2>
<motion.p
className="mx-auto max-w-2xl text-lg text-muted-foreground"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.4, duration: 0.6 }}
>
A diverse team of talented individuals working together to build
amazing products and deliver exceptional results.
</motion.p>
</motion.div>
{/* Team Grid */}
<motion.div
variants={containerVariants}
initial="hidden"
animate="visible"
className="grid gap-8 sm:grid-cols-2 lg:grid-cols-2"
>
{teamMembers.map((member, index) => (
<TeamMemberCard key={index} member={member} index={index} />
))}
</motion.div>
{/* CTA */}
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 1, duration: 0.6 }}
className="mt-16 text-center"
>
<Card className="inline-block border-border/50 bg-gradient-to-r from-primary/5 to-primary/10 p-8">
<h3 className="mb-4 text-2xl font-bold">Join Our Amazing Team</h3>
<p className="mb-6 text-muted-foreground">
We're always looking for talented people to join our mission
</p>
<Button size="lg" className="group relative overflow-hidden">
<motion.span
className="absolute inset-0 bg-gradient-to-r from-primary/0 via-white/20 to-primary/0"
animate={{ x: ['-200%', '200%'] }}
transition={{ repeat: Infinity, duration: 2, ease: 'linear' }}
/>
<span className="relative">View Open Positions</span>
<motion.span
className="relative ml-2"
animate={{ x: [0, 5, 0] }}
transition={{ repeat: Infinity, duration: 1.5 }}
>
→
</motion.span>
</Button>
</Card>
</motion.div>
</div>
</section>
)
}
How to Use
- 1Install Framer Motion:
npm install framer-motion - 2Set up shadcn/ui: Install shadcn/ui components used in this code. Check the imports in the code above and install the required components (e.g.,
npx shadcn-ui@latest add button card) - 3Copy the code from above
- 4Paste it into your project and customize as needed
- 5Colors are customizable via Tailwind CSS classes. The default theme uses dark mode colors defined in your globals.css file