The Profile Card component showcases personal information, including a profile image with an animated gradient border and a personal statement section.
Overview
Location: src/app/components/sections/ProfileCard.tsx
The Profile Card is a prominent component in the portfolio grid layout, occupying 2 columns and 6 rows. It features an animated background gradient effect and displays the developer’s image, name, role, and bio.
Component Structure
export default function ProfileCard() {
return (
<div
className="relative col-span-2 row-span-6 bg-spotify-light-dark rounded-xl p-4 max-md:p-3"
id="#profile"
>
<div className="flex flex-col gap-7 max-md:gap-5">
<BackgroundGradient containerClassName="rounded-[40px] place-self-center">
<Image
src="/luan_real.jpg"
alt="Luan Nguyen"
width={400}
height={400}
className="rounded-[25px] object-cover"
priority
/>
</BackgroundGradient>
<PersonalStatement />
</div>
</div>
);
}
Features
Animated Gradient Border
The profile image is wrapped in a BackgroundGradient component that creates an animated multi-color gradient border effect:
<BackgroundGradient containerClassName="rounded-[40px] place-self-center">
<Image
src="/luan_real.jpg"
alt="Luan Nguyen"
width={400}
height={400}
className="rounded-[25px] object-cover"
priority
/>
</BackgroundGradient>
The priority prop on the Image component ensures the profile photo loads immediately for better perceived performance.
Personal Statement Section
The PersonalStatement subcomponent displays detailed information:
function PersonalStatement() {
return (
<div className="flex flex-col gap-3 px-4">
<div className="space-y-1.5">
<h1 className="text-3xl font-semibold">Luan Nguyen</h1>
<p className="text-spotify-gray text-sm">
Engineer • Researcher • Designer
</p>
</div>
<h4 className="text-sm">
Welcome. I hope your visit is short and beautiful, and that something
here stays with you.
<br /><br />
I'm currently working as a software engineer intern on the
broadcast engineering team at{" "}
<a href="https://www.fox.com/" className="text-spotify-green underline">
FOX.
</a>
{/* Additional content */}
</h4>
</div>
);
}
Content Sections
Developer name displayed as h1 heading
Professional roles: “Engineer • Researcher • Designer”
Personal greeting and introduction
Current employment information with company link
Technical interests and focus areas (systems and AI infrastructure)
Call-to-action linking to blog posts
Background Gradient Component
The BackgroundGradient UI component provides the animated border effect:
Location: src/app/components/ui/background-gradient.tsx
Props Interface
interface BackgroundGradientProps {
children?: React.ReactNode;
className?: string;
containerClassName?: string;
animate?: boolean;
}
Gradient Configuration
The gradient uses a radial gradient combination:
background: radial-gradient(circle farthest-side at 0 100%, #00ccb1, transparent),
radial-gradient(circle farthest-side at 100% 0, #7b61ff, transparent),
radial-gradient(circle farthest-side at 100% 100%, #ffc414, transparent),
radial-gradient(circle farthest-side at 0 0, #1ca0fb, #141316);
Colors in the gradient:
- Teal:
#00ccb1
- Purple:
#7b61ff
- Yellow:
#ffc414
- Blue:
#1ca0fb
Animation
The gradient animates its background position in an infinite loop:
const variants = {
initial: {
backgroundPosition: "0 50%",
},
animate: {
backgroundPosition: ["0, 50%", "100% 50%", "0 50%"],
},
};
<motion.div
variants={animate ? variants : undefined}
initial={animate ? "initial" : undefined}
animate={animate ? "animate" : undefined}
transition={{
duration: 5,
repeat: Infinity,
repeatType: "reverse",
}}
style={{
backgroundSize: animate ? "400% 400%" : undefined,
}}
/>
The animation creates a smooth, flowing effect that draws attention to the profile image without being distracting.
Grid Layout
Desktop Layout
.profile-card {
grid-column: span 2; /* Takes 2 columns */
grid-row: span 6; /* Takes 6 rows */
}
Mobile Responsive
- Tablet/Mobile: Collapses to single column
- Padding: Reduces from
p-4 to p-3 on mobile
- Gap: Reduces from
gap-7 to gap-5 on mobile
Styling Details
Color Usage
/* Background */
bg-spotify-light-dark /* #121212 */
/* Text colors */
text-spotify-gray /* #282828 - for role description */
text-spotify-green /* #1DB954 - for links */
text-white /* Default text */
Border Radius
- Card:
rounded-xl (12px)
- Gradient container:
rounded-[40px]
- Image:
rounded-[25px]
The layered border radius creates depth and visual hierarchy, with the gradient container being the outermost rounded element.
Image Optimization
The component uses Next.js Image optimization:
<Image
src="/luan_real.jpg"
alt="Luan Nguyen"
width={400}
height={400}
className="rounded-[25px] object-cover"
priority
/>
Loads image immediately on page load (no lazy loading)
Ensures image fills the container while maintaining aspect ratio
Dependencies
{
"next/image": "Optimized image component",
"framer-motion": "Animation library for gradient effect",
"../ui/background-gradient": "Custom animated gradient wrapper"
}
Accessibility
- Semantic HTML structure with proper heading hierarchy
- Alt text for profile image
- Descriptive link text for external links
- Proper anchor tags with
rel="noopener noreferrer" for security