├── .eslintrc.json ├── public ├── favicon.ico ├── assets │ ├── CV.pdf │ ├── atzinescandia.png │ ├── devfolio-banner.png │ ├── send.svg │ ├── linkedin.svg │ ├── insta.svg │ ├── download.svg │ ├── link.svg │ ├── web.svg │ └── git.svg └── logo.svg ├── next.config.js ├── postcss.config.js ├── lib └── utils.ts ├── components.json ├── .gitignore ├── components ├── ui │ ├── Socials.tsx │ ├── Reveal.tsx │ ├── DownloadCV.tsx │ ├── FloatingBar.tsx │ ├── Button.tsx │ ├── Spotlight.tsx │ ├── NavBar.tsx │ ├── Sparkle.tsx │ └── BentoGrid.tsx ├── Projects.tsx ├── Contact.tsx ├── Footer.tsx ├── Hero.tsx ├── Experience.tsx └── About.tsx ├── tsconfig.json ├── app ├── page.tsx ├── globals.css └── layout.tsx ├── package.json ├── tailwind.config.ts ├── README.md └── data └── index.ts /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atzin-escandia/devfolio/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/assets/CV.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atzin-escandia/devfolio/HEAD/public/assets/CV.pdf -------------------------------------------------------------------------------- /public/assets/atzinescandia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atzin-escandia/devfolio/HEAD/public/assets/atzinescandia.png -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | module.exports = nextConfig; 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/assets/devfolio-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atzin-escandia/devfolio/HEAD/public/assets/devfolio-banner.png -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /public/assets/send.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/linkedin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/insta.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /components/ui/Socials.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import { socialMedia } from "@/data"; 5 | 6 | export const Socials = (): JSX.Element => ( 7 |
8 | {socialMedia.map(({ id, link, img }) => ( 9 | 16 | social-icon 17 | 18 | ))} 19 |
20 | ); 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /public/assets/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/ui/Reveal.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { ReactNode, useRef } from 'react'; 4 | import { motion } from 'framer-motion'; 5 | 6 | interface RevealProps { 7 | children: ReactNode; 8 | className?: string; 9 | } 10 | 11 | const Reveal = ({ children, className = '' }: RevealProps) => { 12 | const ref = useRef(null); 13 | 14 | return ( 15 |
16 | 22 | {children} 23 | 24 |
25 | ); 26 | }; 27 | 28 | export default Reveal; 29 | -------------------------------------------------------------------------------- /components/ui/DownloadCV.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import Button from "./Button"; 5 | 6 | interface DownloadCVProps { 7 | fileUrl: string; 8 | fileName: string; 9 | } 10 | 11 | const DownloadCV: React.FC = ({ fileUrl, fileName }) => { 12 | return ( 13 | 32 | ); 33 | }; 34 | 35 | export default Button; 36 | -------------------------------------------------------------------------------- /components/Contact.tsx: -------------------------------------------------------------------------------- 1 | import Button from "./ui/Button"; 2 | import Reveal from "./ui/Reveal"; 3 | 4 | const Contact = () => { 5 | return ( 6 |
7 |
8 | 9 |

10 | Contact 11 | me. 12 |

13 |
14 |

15 | {"Want more purple neon?"} 16 |

17 |

18 | Download my 23 | VSCode theme 24 | for free! 25 |

26 | 27 | 28 |
35 |
36 | ); 37 | }; 38 | 39 | export default Contact; 40 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Poppins } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const poppins = Poppins({ subsets: ["latin"], weight: ["100", "200", "400", "700", '900'] }); 6 | 7 | export default function RootLayout({ 8 | children, 9 | }: Readonly<{ 10 | children: React.ReactNode; 11 | }>) { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | {children} 19 | 20 | 21 | ); 22 | } 23 | 24 | 25 | // Change this data with your own 🤭 26 | export const metadata: Metadata = { 27 | title: { 28 | default: 'Atzin Escandia ✷ Portfolio', 29 | template: '%s - Atzin Escandia', 30 | }, 31 | description: 32 | 'A customizable portfolio template for frontend developers, created by Atzin Escandia. Showcase your skills, projects, and experience with a clean and modern design.', 33 | icons: { 34 | icon: './favicon.ico', 35 | }, 36 | applicationName: 'Frontend Portfolio Template by Atzin Escandia', 37 | authors: [ 38 | { 39 | name: 'Atzin Escandia', 40 | url: 'https://www.linkedin.com/in/atzin-escandia/', 41 | }, 42 | ], 43 | generator: 'Next.js', 44 | referrer: 'origin', 45 | themeColor: '#120012', 46 | colorScheme: 'dark', 47 | viewport: 'width=device-width, initial-scale=1', 48 | creator: 'Atzin Escandia', 49 | publisher: 'Atzin Escandia', 50 | }; 51 | -------------------------------------------------------------------------------- /components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import { Socials } from "./ui/Socials"; 2 | 3 | const Footer = () => { 4 | return ( 5 | 38 | ); 39 | }; 40 | 41 | export default Footer; 42 | -------------------------------------------------------------------------------- /components/ui/Spotlight.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import React from "react"; 3 | 4 | type SpotlightProps = { 5 | className?: string; 6 | fill?: string; 7 | }; 8 | 9 | export const Spotlight = ({ className, fill }: SpotlightProps) => { 10 | return ( 11 | 20 | 21 | 30 | 31 | 32 | 41 | 42 | 48 | 52 | 53 | 54 | 55 | ); 56 | }; 57 | -------------------------------------------------------------------------------- /components/Hero.tsx: -------------------------------------------------------------------------------- 1 | import Button from "./ui/Button"; 2 | import Reveal from "./ui/Reveal"; 3 | import { Spotlight } from "./ui/Spotlight"; 4 | 5 | const Hero = () => { 6 | return ( 7 |
8 |
9 | 13 | 17 | 18 |
19 |
20 | 21 |

22 | Hey, I'm {''} 23 | 24 | Atzin Escandia! 25 | 26 |

27 |
28 |

29 | I'm a Software Developer 30 |

31 |

32 | A designer, developer and fitness enthusiast who spends way too much time creating websites that look cool. If you're into tech, fitness, or just want to chat DM me - let's make your brand everyone's crush! 🍓 33 |

34 | 35 |
42 |
43 | ); 44 | }; 45 | 46 | export default Hero; 47 | -------------------------------------------------------------------------------- /components/Experience.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { workExperience } from "@/data"; 3 | import { Sparkle } from "./ui/Sparkle"; 4 | 5 | const Experience = (): JSX.Element => ( 6 |
7 |

8 | My{' '} 9 | 10 | experience. 11 | 12 |

13 | 14 |
15 | {workExperience.map(({ id, company, title, period, location, desc, skills }) => ( 16 | 17 |
18 |
19 | 20 |
21 |

{company}

22 |

23 | 24 | {title} 25 | 26 |

27 |
28 | 29 |
30 |

{period}

31 |

{location}

32 |
33 | 34 |

{desc}

35 | 36 |
37 | {skills.map((skill) => ( 38 |
42 | {skill} 43 |
44 | ))} 45 |
46 |
47 |
48 |
49 | ))} 50 |
51 |
52 | ); 53 | 54 | export default Experience; 55 | -------------------------------------------------------------------------------- /components/ui/NavBar.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useEffect, useState } from "react"; 4 | import Link from "next/link"; 5 | import { cn } from "@/lib/utils"; 6 | import { navItems } from "@/data"; 7 | 8 | const NavBar = (): JSX.Element => { 9 | const [activeSection, setActiveSection] = useState(""); 10 | 11 | useEffect(() => { 12 | const observer = new IntersectionObserver((entries) => { 13 | entries.forEach((entry) => { 14 | if (entry.isIntersecting) { 15 | const id = entry.target.getAttribute("id"); 16 | if (id) setActiveSection(id); 17 | } 18 | }); 19 | }); 20 | 21 | document.querySelectorAll("section").forEach((section) => observer.observe(section)); 22 | 23 | return () => observer.disconnect(); 24 | }, []); 25 | 26 | return ( 27 |
34 | {navItems.map(({ name, link }, index) => { 35 | const isActive = `#${activeSection}` === link; 36 | 37 | return ( 38 | 46 | 54 | {name} 55 | 56 | 57 | ); 58 | })} 59 |
60 | ); 61 | }; 62 | 63 | export default NavBar; 64 | -------------------------------------------------------------------------------- /components/About.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Sparkle } from "./ui/Sparkle"; 3 | import { myTechStack } from "@/data"; 4 | import Reveal from "./ui/Reveal"; 5 | 6 | const About = () => ( 7 |
8 | 9 |

10 | About{' '} 11 | 12 | me. 13 | 14 |

15 |
16 |
17 | 21 |

22 | Hey! I'm Atzin, web designer, developer, fitness lover (& accidental content creator) 23 |

24 |

25 | My background in design and development gives me the tools to bring ideas to life, but my heart is in 26 | connecting with people, I love sharing my journey and what I've learned along the way. 27 |

28 |

29 | Got something in mind or just want to chat? Whether it's a new project or a fitness tip, I'd love to 30 | connect, don't be shy! 31 |

32 |
33 | 34 |
37 |

38 | 39 | My tech Stack! 40 | 41 |

42 | 43 |
44 | {myTechStack.map((skill) => ( 45 |
49 | {skill} 50 |
51 | ))} 52 |
53 |
54 |
55 |
56 | ); 57 | 58 | export default About; 59 | -------------------------------------------------------------------------------- /components/ui/Sparkle.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useRef } from "react"; 4 | import { 5 | motion, 6 | useAnimationFrame, 7 | useMotionTemplate, 8 | useMotionValue, 9 | useTransform, 10 | } from "framer-motion"; 11 | import { cn } from "@/lib/utils"; 12 | 13 | type SparkleProps = { 14 | children: React.ReactNode; 15 | as?: React.ElementType; 16 | duration?: number; 17 | className?: string; 18 | [key: string]: any; 19 | }; 20 | 21 | export function Sparkle({ 22 | children, 23 | as: Component = "button", 24 | duration = 2000, 25 | className = "", 26 | ...otherProps 27 | }: SparkleProps) { 28 | 29 | return ( 30 | 34 |
37 | 38 |
41 | 42 |
43 |
49 | {children} 50 |
51 | 52 | ); 53 | } 54 | 55 | type SparkleBoxProps = { 56 | children: React.ReactNode; 57 | duration?: number; 58 | rx?: string; 59 | ry?: string; 60 | [key: string]: any; 61 | }; 62 | 63 | export const SparkleBox = ({ 64 | children, 65 | duration = 2000, 66 | rx = "0%", 67 | ry = "0%", 68 | ...otherProps 69 | }: SparkleBoxProps) => { 70 | const pathRef = useRef(null); 71 | const progress = useMotionValue(0); 72 | 73 | useAnimationFrame((time) => { 74 | const length = pathRef.current?.getTotalLength(); 75 | if (length) { 76 | const pxPerMs = length / duration; 77 | progress.set((time * pxPerMs) % length); 78 | } 79 | }); 80 | 81 | const x = useTransform(progress, (val) => 82 | pathRef.current?.getPointAtLength(val).x 83 | ); 84 | const y = useTransform(progress, (val) => 85 | pathRef.current?.getPointAtLength(val).y 86 | ); 87 | 88 | const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`; 89 | 90 | return ( 91 | <> 92 | 98 | 99 | 100 | 108 | {children} 109 | 110 | 111 | ); 112 | }; 113 | -------------------------------------------------------------------------------- /components/ui/BentoGrid.tsx: -------------------------------------------------------------------------------- 1 | import { skills } from "@/data"; 2 | import { cn } from "@/lib/utils"; 3 | 4 | interface BentoGridProps { 5 | className?: string; 6 | children?: React.ReactNode; 7 | } 8 | 9 | export const BentoGrid: React.FC = ({ className, children }) => ( 10 |
16 | {children} 17 |
18 | ); 19 | 20 | interface BentoGridItemProps { 21 | className?: string; 22 | id: number; 23 | title?: string | React.ReactNode; 24 | description?: string | React.ReactNode; 25 | link?: string; 26 | github?: string; 27 | img?: string; 28 | titleClassName?: string; 29 | } 30 | 31 | 32 | export const BentoGridItem: React.FC = ({ 33 | className, 34 | id, 35 | title, 36 | description, 37 | link, 38 | github, 39 | img, 40 | titleClassName, 41 | }) => ( 42 |
48 |
49 | {img && ( 50 |
51 | {`Image 56 |
57 | )} 58 | 59 |
60 | 61 |
67 |
68 |
69 | {github && ( 70 | 76 | GitHub 81 | 82 | )} 83 | 84 | {link && ( 85 | 91 | External link 96 | 97 | )} 98 |
99 | 100 |
101 |

{title}

102 |

103 | {description} 104 |

105 | 106 |
107 | {skills.map((skill) => ( 108 |
112 | {skill} 113 |
114 | ))} 115 |
116 |
117 |
118 |
119 |
120 |
121 | ); 122 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | const svgToDataUri = require("mini-svg-data-uri"); 4 | 5 | const { 6 | default: flattenColorPalette, 7 | } = require("tailwindcss/lib/util/flattenColorPalette"); 8 | 9 | const config = { 10 | content: [ 11 | "./pages/**/*.{ts,tsx}", 12 | "./components/**/*.{ts,tsx}", 13 | "./app/**/*.{ts,tsx}", 14 | "./src/**/*.{ts,tsx}", 15 | "./data/**/*.{ts,tsx}", 16 | ], 17 | prefix: "", 18 | theme: { 19 | container: { 20 | center: true, 21 | padding: "2rem", 22 | screens: { 23 | "2xl": "1400px", 24 | }, 25 | }, 26 | extend: { 27 | colors: { 28 | black: { 29 | DEFAULT: "#000", 30 | 100: "#000319", 31 | 200: "rgba(17, 25, 40, 0.75)", 32 | 300: "rgba(255, 255, 255, 0.125)", 33 | }, 34 | white: { 35 | DEFAULT: "#FFF", 36 | 100: "#BEC1DD", 37 | 200: "#C1C2D3", 38 | }, 39 | blue: { 40 | "100": "#E4ECFF", 41 | }, 42 | purple: "#9B4D96", 43 | ring: "hsl(var(--ring))", 44 | background: "hsl(var(--background))", 45 | foreground: "hsl(var(--foreground))", 46 | primary: { 47 | DEFAULT: "hsl(var(--primary))", 48 | foreground: "hsl(var(--primary-foreground))", 49 | }, 50 | secondary: { 51 | DEFAULT: "hsl(var(--secondary))", 52 | foreground: "hsl(var(--secondary-foreground))", 53 | }, 54 | }, 55 | keyframes: { 56 | spotlight: { 57 | "0%": { 58 | opacity: "0", 59 | transform: "translate(-72%, -62%) scale(0.5)", 60 | }, 61 | "100%": { 62 | opacity: "1", 63 | transform: "translate(-50%,-40%) scale(1)", 64 | }, 65 | }, 66 | scroll: { 67 | to: { 68 | transform: "translate(calc(-50% - 0.5rem))", 69 | }, 70 | }, 71 | }, 72 | animation: { 73 | "accordion-down": "accordion-down 0.2s ease-out", 74 | "accordion-up": "accordion-up 0.2s ease-out", 75 | spotlight: "spotlight 2s ease .75s 1 forwards", 76 | scroll: 77 | "scroll var(--animation-duration, 40s) var(--animation-direction, forwards) linear infinite", 78 | }, 79 | }, 80 | }, 81 | plugins: [ 82 | require("tailwindcss-animate"), 83 | addVariablesForColors, 84 | function ({ matchUtilities, theme }: any) { 85 | matchUtilities( 86 | { 87 | "bg-grid": (value: any) => ({ 88 | backgroundImage: `url("${svgToDataUri( 89 | `` 90 | )}")`, 91 | }), 92 | "bg-grid-small": (value: any) => ({ 93 | backgroundImage: `url("${svgToDataUri( 94 | `` 95 | )}")`, 96 | }), 97 | "bg-dot": (value: any) => ({ 98 | backgroundImage: `url("${svgToDataUri( 99 | `` 100 | )}")`, 101 | }), 102 | }, 103 | { values: flattenColorPalette(theme("backgroundColor")), type: "color" } 104 | ); 105 | }, 106 | ], 107 | } satisfies Config; 108 | 109 | function addVariablesForColors({ addBase, theme }: any) { 110 | let allColors = flattenColorPalette(theme("colors")); 111 | let newVars = Object.fromEntries( 112 | Object.entries(allColors).map(([key, val]) => [`--${key}`, val]) 113 | ); 114 | 115 | addBase({ 116 | ":root": newVars, 117 | }); 118 | } 119 | 120 | export default config; 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | Devfolio Banner 5 | 6 |
7 | 8 | 19 | 20 |

Atzin Escandia's Devfolio

21 |

A super easy, simple, and neon purple (pretty me) ready to create your developer portfolio. Because who has time for complicated setups?

22 |
23 | 24 | ## 📋 Table of Contents 25 | 26 | 1. 💡 [Why This Project?](#why-this-project) 27 | 2. ⚙️ [Tech Stack](#tech-stack) 28 | 3. 🛠️ [Features](#features) 29 | 4. 🚀 [Getting Started](#getting-started) 30 | 5. 🌟 [Portfolio Inspiration](#portfolio-inspiration) 31 | 6. 📝 [More Resources](#more-resources) 32 | 33 | ## 💡 Why This Project? 34 | 35 | Hey there, dev! 👋 36 | 37 | You know that feeling when you're ready to show off your skills but get overwhelmed trying to build the _perfect_ portfolio? I’ve been there. You start searching for the right design, the best tools, the _ideal_ way to present your awesomeness... only to get stuck in a rabbit hole. 38 | 39 | So, I thought: **why not create something that makes this super simple, fast, and, dare I say, fun?** This portfolio template is for developers who want to get their work online without spending days tweaking code and layouts. 40 | 41 | ## ⚙️ Tech Stack 42 | 43 | - **Next.js**: Because who doesn’t love fast, production-ready sites that _just work_? 44 | - **Framer Motion**: Transform your portfolio into an interactive experience with smooth animations. 45 | - **TailwindCSS**: The magic wand for styling without the headache. 46 | - **TypeScript**: Because you deserve to code with confidence and zero guesswork. 47 | 48 | ## 🛠️ Features 49 | 50 | ✨ **Responsive Design**: Your portfolio will look great on any device—bye-bye, broken layouts! 51 | 52 | 🎨 **Clean & Stylish UI**: Simple yet stunning—designed to let your work take center stage. No frills, just results. 53 | 54 | 💡 **Customization Made Easy**: Want to change colors, fonts, or content? Do it without pulling your hair out. Seriously. 55 | 56 | 🎬 **Smooth Animations**: Thanks to Framer Motion, your portfolio will glide and flip like a pro. 57 | 58 | 🔧 **Developer Friendly**: Built with devs in mind, using the best tools and practices. You'll feel right at home. 59 | 60 | 💌 **Easy Contact Section**: Let potential employers, collaborators, or even fans reach out. No need to complicate things! 61 | 62 | ## 🚀 Getting Started 63 | 64 | Ready to launch your portfolio? Follow these simple steps, and you’ll be live in a flash! 65 | 66 | ### Prerequisites 67 | 68 | Before you get started, make sure you have: 69 | 70 | - [Git](https://git-scm.com/) installed on your machine. 71 | - [Node.js](https://nodejs.org/) (and Yarn) to manage dependencies. 72 | 73 | ### Clone the Repository 74 | 75 | ```bash 76 | git clone https://github.com/atzinescandia/atzin-escandia-devfolio.git 77 | cd atzin-escandia-devfolio 78 | ``` 79 | 80 | ### Install Dependencies 81 | 82 | Run this command to install all the necessary dependencies: 83 | 84 | ```bash 85 | yarn install 86 | ``` 87 | 88 | ### Run the Development Server 89 | 90 | Once you’re all set, fire up the server with: 91 | 92 | ```bash 93 | yarn dev 94 | ``` 95 | 96 | Now, head to [http://localhost:3000](http://localhost:3000) in your browser and _boom_, your portfolio is ready to shine! 97 | 98 | ## 🌟 Portfolio Inspiration 99 | 100 | Looking for some inspo? Check out these amazing portfolios made using this template! 101 | 102 | - [Atzin Escandia Portfolio](https://atzinescandia.dev) - My personal site, where I show off my journey as a web dev and showcase my projects. 103 | - [The Plum Up Purple Neon](https://vscodethemes.com/e/atzinescandia.theplumup/theplumup) - A collection of portfolios by talented devs around the globe. 104 | 105 | ## 📝 More Resources 106 | 107 | - [Next.js Docs](https://nextjs.org/docs) - For when you need to level up your Next.js skills. 108 | - [Framer Motion](https://www.framer.com/motion/) - Bring your animations to life! 109 | - [TailwindCSS Docs](https://tailwindcss.com/docs) - The most efficient way to style your projects without the fuss. 110 | 111 | --- 112 | 113 | Feel free to fork this repo, tweak it to your heart's content, and start showing off your work! If you’ve got any questions or want to contribute, don’t hesitate to open an issue or submit a pull request. I’m always up for some collaboration! 🎉 114 | -------------------------------------------------------------------------------- /data/index.ts: -------------------------------------------------------------------------------- 1 | export const navItems = [ 2 | { name: "About", link: "#about" }, 3 | { name: "Projects", link: "#projects" }, 4 | { name: "Experience", link: "#experience" }, 5 | { name: "Contact", link: "#contact" }, 6 | ]; 7 | 8 | export const myTechStack = [ 9 | "JavaScript (ES6+)", 10 | "React", 11 | "Next.js", 12 | "TypeScript", 13 | "Jest", 14 | "Cypress", 15 | "Storybook", 16 | "Performance Testing", 17 | "HTML", 18 | "CSS", 19 | "SCSS", 20 | "Tailwind", 21 | "ShadCn/UI", 22 | "Figma", 23 | "Framer", 24 | "Git", 25 | "TanStack Query", 26 | "CI/CD", 27 | "Jira", 28 | "Agile", 29 | ]; 30 | 31 | export const projects = [ 32 | { 33 | id: 1, 34 | title: "FitLife: Your Gym Buddy in Code", 35 | description: 36 | "What if your fitness app could help you design websites while tracking your push-ups? This is it. Built with love, sweat, and a bit of JavaScript magic!", 37 | className: "lg:col-span-3 md:col-span-6 md:row-span-4 lg:min-h-[60vh]", 38 | titleClassName: "justify-end", 39 | img: "https://i.pinimg.com/originals/be/f4/1a/bef41a7d5a877841bbf7d8f9f0d42f14.gif", 40 | github: "https://github.com/atzin-escandia", 41 | link: "https://www.instagram.com/atzinescandia", 42 | techs: [ 43 | "JavaScript", 44 | "React", 45 | "NodeJS", 46 | "Express", 47 | "MongoDB", 48 | "Tailwind", 49 | ], 50 | }, 51 | { 52 | id: 2, 53 | title: "Timezone Buddy: Never Miss a Workout", 54 | description: 55 | "You can’t train for a marathon if you're confused about timezones! Sync with your squad no matter where they are and never miss a coding session or a yoga flow.", 56 | className: "lg:col-span-2 md:col-span-3 md:row-span-2", 57 | titleClassName: "justify-start", 58 | img: "https://i.pinimg.com/originals/84/f6/d1/84f6d14f1f88d34d3956150d19060d3a.gif", 59 | github: "https://github.com/atzin-escandia", 60 | link: "https://www.threads.net/@atzinescandia", 61 | techs: ["JavaScript", "React", "NodeJS", "AWS", "GitHub", "Jira"], 62 | }, 63 | { 64 | id: 3, 65 | title: "Code & Paint: A Creative Playground", 66 | description: 67 | "What if coding met art? This interactive web builder lets you design while you create. Whether you’re coding a landing page or painting a masterpiece, this is where your creativity comes to life.", 68 | className: "lg:col-span-2 md:col-span-3 md:row-span-2", 69 | titleClassName: "justify-center", 70 | img: "https://i.pinimg.com/originals/54/b5/24/54b52468335fd6eb935e330eb3197b25.gif", 71 | github: "https://github.com/atzin-escandia", 72 | link: "https://atzinescandia.dev", 73 | techs: ["TypeScript", "React", "NextJS", "CSS", "AWS", "GitHub"], 74 | }, 75 | { 76 | id: 4, 77 | title: "JavaScript Quest: Level Up Your Code", 78 | description: 79 | "Time to put your JavaScript skills to the test in an RPG-style adventure. Solve puzzles, defeat bugs, and unlock pro tips as you level up to coding mastery.", 80 | className: "lg:col-span-2 md:col-span-3 md:row-span-1", 81 | titleClassName: "justify-start", 82 | img: "https://i.pinimg.com/736x/c7/de/01/c7de016c811fa5fae9d7120402f27645.jpg", 83 | github: "https://github.com/atzin-escandia", 84 | link: "https://atzinescandia.dev", 85 | techs: ["JavaScript", "NodeJS", "Express", "React", "Heroku", "GitHub"], 86 | }, 87 | { 88 | id: 5, 89 | title: "JS Animation Magic: Making Transitions Dance", 90 | description: 91 | "No more boring fades or slides. Animate your website with smooth, interactive animations that will have users tapping their feet. It's magic, but with code!", 92 | className: "md:col-span-3 md:row-span-2", 93 | titleClassName: "justify-center md:justify-start lg:justify-center", 94 | img: "https://i.pinimg.com/736x/09/2e/25/092e252b5562c7e5eb576215c6d9db8d.jpg", 95 | github: "https://github.com/atzin-escandia", 96 | link: "https://atzinescandia.dev/about", 97 | techs: ["JavaScript", "CSS", "React", "Tailwind", "GitHub", "AWS"], 98 | }, 99 | { 100 | id: 6, 101 | title: "Space Explorer App: Code Your Way Through the Cosmos", 102 | description: 103 | "Ever wanted to explore space? Now you can—without leaving your desk. Navigate through galaxies, discover planets, and learn about the universe, all while building your dream website.", 104 | className: "lg:col-span-2 md:col-span-3 md:row-span-1", 105 | img: "https://i.pinimg.com/originals/bf/c3/fb/bfc3fb764ff5f4d8d9ecb6da8544709c.gif", 106 | github: "https://github.com/atzin-escandia", 107 | link: "https://atzinescandia.com/contact", 108 | techs: ["JavaScript", "React", "NodeJS", "CSS", "NextJS", "GitHub"], 109 | }, 110 | ]; 111 | 112 | export const workExperience = [ 113 | { 114 | id: 1, 115 | company: "LumoTech", 116 | title: "UX/UI Sorcerer", 117 | desc: "Transformed the user dashboard with a sleek design that boosted engagement by 35%. Optimized the onboarding flow to make new users feel like wizards on their first try.", 118 | className: "md:col-span-2", 119 | location: "Los Angeles", 120 | period: "2022 - Present", 121 | skills: [ 122 | "Figma", 123 | "Sketch", 124 | "Prototyping", 125 | "User Testing", 126 | "Illustrator", 127 | "Adobe XD", 128 | ], 129 | }, 130 | { 131 | id: 2, 132 | company: "PixelMinds", 133 | title: "Product Design Genius", 134 | desc: "Revamped the interface with intuitive controls, increasing user retention by 28%. Pioneered AR features for interactive learning experiences—because education should be fun and engaging.", 135 | className: "md:col-span-2", 136 | location: "San Francisco", 137 | period: "2020 - 2022", 138 | skills: [ 139 | "Figma", 140 | "User Research", 141 | "Wireframing", 142 | "Prototyping", 143 | "Usability Testing", 144 | "CSS", 145 | ], 146 | }, 147 | { 148 | id: 3, 149 | company: "DesignHub", 150 | title: "Design Systems Guru", 151 | desc: "Crafted design systems that were so organized they could be put in a museum. Pushed for consistent, user-friendly components that made developers’ lives easier.", 152 | className: "md:col-span-2", 153 | location: "Remote", 154 | period: "2016 - 2020", 155 | skills: [ 156 | "Figma", 157 | "React", 158 | "Design Tokens", 159 | "Accessibility", 160 | "Storybook", 161 | "Collaboration", 162 | ], 163 | }, 164 | ]; 165 | 166 | export const socialMedia = [ 167 | { 168 | id: 1, 169 | img: "assets/git.svg", 170 | link: "https://github.com/atzin-escandia", 171 | }, 172 | { 173 | id: 2, 174 | img: "assets/linkedin.svg", 175 | link: "https://www.linkedin.com/in/atzin-escandia/", 176 | }, 177 | { 178 | id: 3, 179 | img: "assets/web.svg", 180 | link: "https://atzinescandia.dev/", 181 | }, 182 | { 183 | id: 3, 184 | img: "assets/insta.svg", 185 | link: "https://www.instagram.com/atzinescandia.dev/", 186 | }, 187 | { 188 | id: 3, 189 | img: "assets/link.svg", 190 | link: "https://github.com/atzin-escandia/devfolio", 191 | }, 192 | ]; 193 | 194 | export const skills = [ 195 | "TypeScript", 196 | "React", 197 | "Redux", 198 | "NodeJS", 199 | "NextJS", 200 | "Tailwind", 201 | ]; 202 | -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------