portfolio-components
Provides reusable, accessible UI components for professional developer portfolios.
Install
mkdir -p .claude/skills/portfolio-components && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14196" && unzip -o skill.zip -d .claude/skills/portfolio-components && rm skill.zipInstalls to .claude/skills/portfolio-components
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Production-ready portfolio components including Hero, About, Projects, Experience, Contact sections with modern design patterns.Key capabilities
- →Provide UI primitives like Button, Card, and Badge components
- →Offer pre-built page sections such as Hero, About, Projects, and Contact
- →Include structural components like Header, Footer, and Navigation
- →Supply shared components like Project Card and Social Links
- →Support composition, accessibility, and animation in component design
How it works
The skill provides a library of modular React components organized into UI primitives, page sections, layout elements, and shared components. Developers import and assemble these components to construct a portfolio site.
Inputs & outputs
When to use portfolio-components
- →Building a developer portfolio site
- →Adding a project showcase section
- →Creating accessible UI primitives
- →Styling portfolio navigation
About this skill
Portfolio Components Library
Core Philosophy
Portfolio components should be memorable, professional, and performant. Each component tells a story about you as a developer. We build with composition, accessibility, and animation in mind.
Project Structure
components/
├── ui/ # Primitives (Button, Card, Badge)
│ ├── button.tsx
│ ├── card.tsx
│ ├── badge.tsx
│ ├── skeleton.tsx
│ └── icons.tsx
├── sections/ # Page sections
│ ├── hero.tsx
│ ├── about.tsx
│ ├── projects.tsx
│ ├── experience.tsx
│ ├── skills.tsx
│ ├── testimonials.tsx
│ └── contact.tsx
├── layout/ # Structure
│ ├── header.tsx
│ ├── footer.tsx
│ ├── navigation.tsx
│ └── mobile-nav.tsx
└── shared/ # Shared components
├── section-header.tsx
├── project-card.tsx
├── tech-stack.tsx
└── social-links.tsx
UI Primitives
Button Component
// components/ui/button.tsx
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { forwardRef } from "react";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-lg font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-95",
{
variants: {
variant: {
primary:
"bg-brand-500 text-white hover:bg-brand-600 focus:ring-brand-400",
secondary:
"bg-zinc-800 text-white hover:bg-zinc-700 focus:ring-zinc-600",
outline:
"border border-zinc-700 bg-transparent hover:bg-zinc-800 focus:ring-zinc-600",
ghost: "bg-transparent hover:bg-zinc-800/50 focus:ring-zinc-600",
link: "text-brand-400 underline-offset-4 hover:underline focus:ring-brand-400",
},
size: {
sm: "h-9 px-4 text-sm",
md: "h-11 px-6 text-base",
lg: "h-14 px-8 text-lg",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "primary",
size: "md",
},
},
);
interface ButtonProps
extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
isLoading?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
(
{ className, variant, size, isLoading, children, disabled, ...props },
ref,
) => {
return (
<button
ref={ref}
className={cn(buttonVariants({ variant, size }), className)}
disabled={disabled || isLoading}
{...props}
>
{isLoading && (
<svg
className="h-4 w-4 animate-spin"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
)}
{children}
</button>
);
},
);
Button.displayName = "Button";
Card Component
// components/ui/card.tsx
import { cn } from "@/lib/utils";
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
hover?: boolean;
}
export function Card({
className,
hover = false,
children,
...props
}: CardProps) {
return (
<div
className={cn(
"rounded-2xl border border-zinc-800 bg-zinc-900/50 p-6",
hover &&
"transition-all duration-300 hover:border-zinc-700 hover:bg-zinc-900",
className,
)}
{...props}
>
{children}
</div>
);
}
export function CardHeader({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn("mb-4", className)} {...props} />;
}
export function CardTitle({
className,
...props
}: React.HTMLAttributes<HTMLHeadingElement>) {
return <h3 className={cn("text-xl font-bold", className)} {...props} />;
}
export function CardDescription({
className,
...props
}: React.HTMLAttributes<HTMLParagraphElement>) {
return <p className={cn("text-sm text-muted", className)} {...props} />;
}
export function CardContent({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn("", className)} {...props} />;
}
export function CardFooter({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div className={cn("mt-4 flex items-center gap-4", className)} {...props} />
);
}
Badge Component
// components/ui/badge.tsx
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-full px-3 py-1 text-xs font-medium transition-colors",
{
variants: {
variant: {
default: "bg-zinc-800 text-zinc-300",
brand: "bg-brand-500/10 text-brand-400 border border-brand-500/20",
success: "bg-green-500/10 text-green-400 border border-green-500/20",
warning: "bg-yellow-500/10 text-yellow-400 border border-yellow-500/20",
outline: "border border-zinc-700 text-zinc-400",
},
},
defaultVariants: {
variant: "default",
},
},
);
interface BadgeProps
extends
React.HTMLAttributes<HTMLSpanElement>,
VariantProps<typeof badgeVariants> {}
export function Badge({ className, variant, ...props }: BadgeProps) {
return (
<span className={cn(badgeVariants({ variant }), className)} {...props} />
);
}
Section Components
Hero Section
// components/sections/hero.tsx
"use client";
import { motion } from "framer-motion";
import { ArrowRight, Download, Github, Linkedin, Twitter } from "lucide-react";
import { Button } from "@/components/ui/button";
import Image from "next/image";
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.1, delayChildren: 0.3 },
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
};
export function HeroSection() {
return (
<section className="relative min-h-screen overflow-hidden">
{/* Background Effects */}
<div className="absolute inset-0 -z-10">
<div className="absolute inset-0 bg-gradient-to-b from-brand-500/10 via-transparent to-transparent" />
<div className="absolute left-1/2 top-1/4 -z-10 h-[500px] w-[500px] -translate-x-1/2 rounded-full bg-brand-500/20 blur-[120px]" />
<div className="absolute bottom-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-zinc-700 to-transparent" />
</div>
<div className="container flex min-h-screen items-center py-20">
<motion.div
variants={containerVariants}
initial="hidden"
animate="visible"
className="grid gap-12 lg:grid-cols-2 lg:items-center"
>
{/* Text Content */}
<div className="order-2 lg:order-1">
{/* Status Badge */}
<motion.div variants={itemVariants} className="mb-6">
<span className="inline-flex items-center gap-2 rounded-full border border-green-500/20 bg-green-500/10 px-4 py-1.5 text-sm text-green-400">
<span className="relative flex h-2 w-2">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75" />
<span className="relative inline-flex h-2 w-2 rounded-full bg-green-500" />
</span>
Available for work
</span>
</motion.div>
{/* Headline */}
<motion.h1
variants={itemVariants}
className="font-heading text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl"
>
Hi, I'm{" "}
<span className="bg-gradient-to-r from-brand-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">
John Doe
</span>
</motion.h1>
{/* Subtitle */}
<motion.p
variants={itemVariants}
className="mt-4 text-xl text-muted sm:text-2xl"
>
Full-Stack Developer
</motion.p>
{/* Description */}
<motion.p
variants={itemVariants}
className="mt-6 max-w-lg text-lg text-zinc-400"
>
I build exceptional digital experiences with modern technologies.
Focused on React, Next.js, and creating interfaces that users
love.
</motion.p>
{/* CTA Buttons */}
<motion.div
variants={itemVariants}
className="mt-8 flex flex-col gap-4 sm:flex-row"
>
<Button size="lg" className="group">
View My Work
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
</Button>
<Button variant="outline" size="lg">
<Download className="h-4 w-4" />
Download CV
</Button>
</motion.div>
{/* Social Links */}
<motion.div
variants={itemVariants}
className="mt-8 flex items-center gap-4"
>
<span className="text-sm text-zinc-500">Find me on</span>
<div className="flex gap-3">
{[
{
icon: Github,
href: "https://github.com/johndoe",
label: "GitHub",
},
{
icon: Linkedin,
href: "https:
---
*Content truncated.*
When not to use it
- →When building applications not focused on portfolio presentation
- →When a custom design system is already in place
- →When only a single, isolated UI element is needed
Limitations
- →The components are tailored for portfolio websites
- →The component library is opinionated in its design patterns
- →The skill focuses on UI components, not backend functionality
How it compares
This skill offers pre-designed, production-ready components specifically for portfolios, unlike manually coding each UI element from scratch.
Compared to similar skills
portfolio-components side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| portfolio-components (this skill) | 0 | 6mo | No flags | Intermediate |
| ui-styling | 12 | 9mo | Review | Beginner |
| figma | 22 | 4mo | No flags | Intermediate |
| interaction-design | 15 | 5mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
ui-styling
mrgoonie
Create beautiful, accessible user interfaces with shadcn/ui components (built on Radix UI + Tailwind), Tailwind CSS utility-first styling, and canvas-based visual designs. Use when building user interfaces, implementing design systems, creating responsive layouts, adding accessible components (dialogs, dropdowns, forms, tables), customizing themes and colors, implementing dark mode, generating visual designs and posters, or establishing consistent styling patterns across applications.
figma
openai
Use the Figma MCP server to fetch design context, screenshots, variables, and assets from Figma, and to translate Figma nodes into production code. Trigger when a task involves Figma URLs, node IDs, design-to-code implementation, or Figma MCP setup and troubleshooting.
interaction-design
wshobson
Design and implement microinteractions, motion design, transitions, and user feedback patterns. Use when adding polish to UI interactions, implementing loading states, or creating delightful user experiences.
web-design-reviewer
github
This skill enables visual inspection of websites running locally or remotely to identify and fix design issues. Triggers on requests like "review website design", "check the UI", "fix the layout", "find design problems". Detects issues with responsive design, accessibility, visual consistency, and layout breakage, then performs fixes at the source code level.
visual-design-foundations
wshobson
Apply typography, color theory, spacing systems, and iconography principles to create cohesive visual designs. Use when establishing design tokens, building style guides, or improving visual hierarchy and consistency.
design-lab
0xdesign
Conduct design interviews, generate five distinct UI variations in a temporary design lab, collect feedback, and produce implementation plans. Use when the user wants to explore UI design options, redesign existing components, or create new UI with multiple approaches to compare.