PO

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.zip

Installs 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.
128 charsno explicit “when” trigger
Intermediate

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

You give it
Configuration for a portfolio section or UI primitive
You get back
A production-ready UI component for a portfolio website

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.

SkillInstallsUpdatedSafetyDifficulty
portfolio-components (this skill)06moNo flagsIntermediate
ui-styling129moReviewBeginner
figma224moNo flagsIntermediate
interaction-design155moNo flagsIntermediate

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.

12132

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.

2266

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.

1550

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.

750

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.

547

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.

735

Search skills

Search the agent skills registry