Skip to content

Instantly share code, notes, and snippets.

@shricodev
Created November 28, 2025 05:55
Show Gist options
  • Select an option

  • Save shricodev/41fdf0596f312573e0efd44a30b5b36b to your computer and use it in GitHub Desktop.

Select an option

Save shricodev/41fdf0596f312573e0efd44a30b5b36b to your computer and use it in GitHub Desktop.
Kombai Cloning Figma Portfolio from Template - Blog Demo
import type { ReactNode } from 'react';
interface ButtonProps {
children: ReactNode;
variant?: 'primary' | 'secondary';
href?: string;
onClick?: () => void;
}
export default function Button({ children, variant = 'primary', href, onClick }: ButtonProps) {
const baseClasses = "text-button px-6 py-3 rounded-sm transition-all hover:opacity-90";
const variantClasses = variant === 'primary'
? "bg-(--primary-yellow) text-(--foreground)"
: "bg-transparent border-2 border-(--foreground) text-(--foreground) hover:bg-(--foreground) hover:text-white";
const className = `${baseClasses} ${variantClasses}`;
if (href) {
return (
<a href={href} className={className}>
{children}
</a>
);
}
return (
<button onClick={onClick} className={className}>
{children}
</button>
);
}
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700&family=Comfortaa:wght@700&family=Playfair+Display:wght@700&family=Roboto:wght@500&display=swap');
@import "tailwindcss";
:root {
--background: #f9faff;
--foreground: #25282b;
--primary-yellow: #fdc435;
--text-gray: #828282;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary-yellow: var(--primary-yellow);
--color-text-gray: var(--text-gray);
--font-nunito: 'Nunito', sans-serif;
--font-comfortaa: 'Comfortaa', cursive;
--font-playfair: 'Playfair Display', serif;
--font-roboto: 'Roboto', sans-serif;
}
body {
background: var(--background);
color: var(--foreground);
font-family: var(--font-nunito);
}
@utility text-heading-large {
font-family: var(--font-playfair);
font-size: 64px;
font-weight: 700;
line-height: 76.8px;
}
@utility text-heading-medium {
font-family: var(--font-playfair);
font-size: 48px;
font-weight: 700;
}
@utility text-heading-small {
font-family: var(--font-playfair);
font-size: 40px;
font-weight: 700;
}
@utility text-subtitle {
font-family: var(--font-nunito);
font-size: 20px;
font-weight: 700;
text-transform: uppercase;
}
@utility text-body-large {
font-family: var(--font-nunito);
font-size: 24px;
font-weight: 400;
line-height: 36px;
}
@utility text-body {
font-family: var(--font-nunito);
font-size: 18px;
font-weight: 400;
line-height: 27px;
}
@utility text-button {
font-family: var(--font-roboto);
font-size: 18px;
font-weight: 500;
}
@utility text-logo {
font-family: var(--font-comfortaa);
font-size: 18px;
font-weight: 700;
}
@utility text-footer {
font-family: var(--font-nunito);
font-size: 16px;
font-weight: 400;
}
import Link from 'next/link';
export default function Header() {
return (
<header className="w-full px-6 py-3 md:px-20">
<div className="flex items-center justify-between max-w-[1440px] mx-auto">
<Link href="/" className="text-logo text-(--foreground)">
Madelyn Torff
</Link>
<nav className="flex gap-12">
<Link
href="#about"
className="text-button text-(--foreground) hover:text-(--primary-yellow) transition-colors"
>
About
</Link>
<Link
href="#projects"
className="text-button text-(--foreground) hover:text-(--primary-yellow) transition-colors"
>
Projects
</Link>
<Link
href="#contacts"
className="text-button text-(--foreground) hover:text-(--primary-yellow) transition-colors"
>
Contacts
</Link>
</nav>
</div>
</header>
);
}
import Image from 'next/image';
import Button from './Button';
export default function Hero() {
return (
<section className="w-full px-6 py-16 md:px-20 md:py-20">
<div className="max-w-[1440px] mx-auto grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
{/* Left Content */}
<div className="flex flex-col gap-3">
<p className="text-subtitle text-(--primary-yellow)">
UI/UX DESIGNER
</p>
<div className="flex flex-col gap-8">
<h1 className="text-heading-large text-(--foreground)">
Hello, my name is Madelyn Torff
</h1>
<p className="text-body-large text-(--text-gray)">
Short text with details about you, what you do or your professional career. You can add more information on the about page.
</p>
<div className="flex gap-3">
<Button variant="primary" href="#projects">
Projects
</Button>
<Button variant="secondary" href="https://linkedin.com">
LinkedIn
</Button>
</div>
</div>
</div>
{/* Right Image */}
<div className="relative w-full aspect-square max-w-[600px] mx-auto lg:ml-auto lg:mr-0">
<div className="absolute inset-0 bg-(--primary-yellow) rounded-full" />
<div className="relative w-full h-full">
<Image
src="/hero-image.svg"
alt="Madelyn Torff - UI/UX Designer"
fill
className="object-contain"
priority
/>
</div>
</div>
</div>
</section>
);
}
import * as React from "react";
import type { SVGProps } from "react";
const Component = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 37.5 37.5" {...props}><path xmlns="http://www.w3.org/2000/svg" fill="currentColor" d="M24.75 18.75c0 1.19-.352 2.35-1.011 3.33a5.95 5.95 0 0 1-2.693 2.21 5.9 5.9 0 0 1-3.467.34 6 6 0 0 1-3.072-1.64 6 6 0 0 1-1.642-3.07 6.02 6.02 0 0 1 .342-3.47 6.03 6.03 0 0 1 2.21-2.69 6 6 0 0 1 3.333-1.01c1.591 0 3.116.63 4.241 1.76a6 6 0 0 1 1.759 4.24M37.5 10.5V27A10.516 10.516 0 0 1 27 37.5H10.5A10.516 10.516 0 0 1 0 27V10.5A10.516 10.516 0 0 1 10.5 0H27a10.516 10.516 0 0 1 10.5 10.5m-9.75 8.25a9 9 0 0 0-1.517-5 9 9 0 0 0-4.039-3.31 9 9 0 0 0-5.2-.52 9 9 0 0 0-4.608 2.47 8.96 8.96 0 0 0-2.463 4.6 9 9 0 0 0 3.827 9.24 8.988 8.988 0 0 0 11.361-1.12 9 9 0 0 0 2.639-6.36m3-9.75a2.251 2.251 0 0 0-2.689-2.21c-.436.09-.837.3-1.152.62a2.247 2.247 0 0 0 .341 3.46c.37.25.805.38 1.25.38.597 0 1.169-.24 1.591-.66s.659-.99.659-1.59" /></svg>;
export default Component;
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "Madelyn Torff - UI/UX Designer Portfolio",
description: "Portfolio of Madelyn Torff, a UI/UX Designer showcasing creative projects and professional work.",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className="antialiased">
{children}
</body>
</html>
);
}
import * as React from "react";
import type { SVGProps } from "react";
const Component = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 38 38" {...props}><path xmlns="http://www.w3.org/2000/svg" fill="currentColor" d="M0 2.72C0 1.22 1.249 0 2.791 0h32.418C36.751 0 38 1.22 38 2.72v32.56c0 1.5-1.249 2.72-2.791 2.72H2.791C1.249 38 0 36.78 0 35.28zm11.74 29.09V14.65H6.037v17.16zm-2.85-19.5c1.988 0 3.225-1.32 3.225-2.97-.036-1.68-1.235-2.96-3.187-2.96C6.975 6.38 5.7 7.66 5.7 9.34c0 1.65 1.237 2.97 3.152 2.97zm11.656 19.5v-9.58c0-.52.038-1.03.19-1.39.411-1.03 1.349-2.09 2.926-2.09 2.064 0 2.888 1.57 2.888 3.88v9.18h5.702v-9.84c0-5.27-2.811-7.72-6.564-7.72-3.026 0-4.382 1.66-5.142 2.83v.06h-.038l.038-.06v-2.43h-5.7c.071 1.61 0 17.16 0 17.16z" /></svg>;
export default Component;
import * as React from "react";
import type { SVGProps } from "react";
const Component = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 42 32" {...props}><path xmlns="http://www.w3.org/2000/svg" fill="currentColor" fillRule="evenodd" d="M.131 4.15a5.38 5.38 0 0 1 1.845-2.99A5.22 5.22 0 0 1 5.25 0h31.5c1.189 0 2.344.41 3.274 1.16a5.38 5.38 0 0 1 1.845 2.99L21 17.1zM0 7.19v18.95l15.233-9.49zm17.748 11.02L.501 28.95a5.34 5.34 0 0 0 1.94 2.23c.84.54 1.815.82 2.809.82h31.5c.994 0 1.968-.29 2.808-.83a5.3 5.3 0 0 0 1.938-2.22L24.25 18.21 21 20.23zm9.019-1.56L42 26.14V7.19z" clipRule="evenodd" /></svg>;
export default Component;
import Header from './components/Header';
import Hero from './components/Hero';
import Projects from './components/Projects';
import Footer from './components/Footer';
export default function Home() {
return (
<div className="min-h-screen bg-(--background)">
<Header />
<main>
<Hero />
<Projects />
</main>
<Footer />
</div>
);
}
import Image from 'next/image';
import Button from './Button';
interface ProjectCardProps {
title: string;
description: string;
imageSrc: string;
imageAlt: string;
imagePosition: 'left' | 'right';
}
export default function ProjectCard({
title,
description,
imageSrc,
imageAlt,
imagePosition
}: ProjectCardProps) {
return (
<div className="bg-white rounded-3xl shadow-[0px_6px_64px_rgba(112,144,176,0.1)] overflow-hidden">
<div className={`grid grid-cols-1 lg:grid-cols-2 ${imagePosition === 'left' ? 'lg:flex-row-reverse' : ''}`}>
{/* Content */}
<div className={`flex flex-col gap-6 p-12 lg:p-16 ${imagePosition === 'right' ? 'order-1' : 'order-2 lg:order-1'}`}>
<h3 className="text-heading-small text-(--foreground)">
{title}
</h3>
<p className="text-body text-(--text-gray)">
{description}
</p>
<div>
<Button variant="secondary" href="#project">
View Project
</Button>
</div>
</div>
{/* Image */}
<div className={`relative w-full aspect-[4/3] lg:aspect-auto lg:min-h-[524px] ${imagePosition === 'right' ? 'order-2' : 'order-1 lg:order-2'}`}>
<Image
src={imageSrc}
alt={imageAlt}
fill
className="object-cover"
/>
</div>
</div>
</div>
);
}
import ProjectCard from './ProjectCard';
export default function Projects() {
const projects = [
{
title: "Project Name",
description: "I created this personal project in order to show how to create an interface in Figma using a portfolio as an example.",
imageSrc: "/project-1.jpg",
imageAlt: "Woman doing yoga pose",
imagePosition: "right" as const
},
{
title: "Project Name",
description: "What was your role, your deliverables, if the project was personal, freelancing.",
imageSrc: "/project-2.jpg",
imageAlt: "Calendar and planning workspace",
imagePosition: "left" as const
},
{
title: "Project Name",
description: "You can also add in this description the type of the project, if it was for web, mobile, electron.",
imageSrc: "/project-3.jpg",
imageAlt: "Phone mockup on desk",
imagePosition: "right" as const
}
];
return (
<section id="projects" className="w-full px-6 py-16 md:px-20 md:py-20">
<div className="max-w-[1440px] mx-auto">
{/* Section Header */}
<div className="flex flex-col items-center gap-1 mb-20">
<h2 className="text-heading-medium text-(--foreground)">
Projects
</h2>
<div className="w-[100px] h-1 bg-(--primary-yellow)" />
</div>
{/* Project Cards */}
<div className="flex flex-col gap-20">
{projects.map((project, index) => (
<ProjectCard
key={index}
title={project.title}
description={project.description}
imageSrc={project.imageSrc}
imageAlt={project.imageAlt}
imagePosition={project.imagePosition}
/>
))}
</div>
</div>
</section>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment