├── src └── app │ ├── projects.js │ ├── favicon.ico │ ├── fonts │ ├── GeistVF.woff │ ├── AfacadFlux.ttf │ ├── GeistMonoVF.woff │ └── AfacadFlux │ │ ├── static │ │ ├── AfacadFlux-Black.ttf │ │ ├── AfacadFlux-Bold.ttf │ │ ├── AfacadFlux-Light.ttf │ │ ├── AfacadFlux-Thin.ttf │ │ ├── AfacadFlux-Medium.ttf │ │ ├── AfacadFlux-Regular.ttf │ │ ├── AfacadFlux-SemiBold.ttf │ │ ├── AfacadFlux-ExtraBold.ttf │ │ └── AfacadFlux-ExtraLight.ttf │ │ ├── README.txt │ │ └── OFL.txt │ ├── constants.js │ ├── components │ ├── misc.css │ ├── education.css │ ├── FollowingCursor.js │ ├── projects.css │ ├── Misc.js │ ├── WorkGrid.js │ ├── ProjectsGrid.js │ ├── resume.css │ ├── HomeGrid.js │ ├── blog.css │ ├── Resume.js │ ├── Contact.js │ ├── contact.css │ ├── Education.js │ ├── work-experience.css │ ├── Blog.js │ ├── Projects.js │ └── WorkExperience.js │ ├── globals.css │ ├── page.js │ └── layout.js ├── .eslintrc.json ├── jsconfig.json ├── next.config.mjs ├── postcss.config.mjs ├── tailwind.config.js ├── .gitignore ├── package.json └── README.md /src/app/projects.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/fonts/GeistVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/GeistVF.woff -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux.ttf -------------------------------------------------------------------------------- /src/app/fonts/GeistMonoVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/GeistMonoVF.woff -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-Black.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-Bold.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-Light.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-Thin.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-Medium.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-Regular.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-SemiBold.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-ExtraBold.ttf -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/static/AfacadFlux-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodedose/bentofolio/HEAD/src/app/fonts/AfacadFlux/static/AfacadFlux-ExtraLight.ttf -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /src/app/constants.js: -------------------------------------------------------------------------------- 1 | import HomeGrid from "./components/HomeGrid" 2 | import ProjectsGrid from "./components/ProjectsGrid" 3 | import WorkGrid from './components/WorkGrid' 4 | 5 | export const GRIDS = [ 6 | { label: "home", Component: HomeGrid }, 7 | { label: "projects", Component: ProjectsGrid }, 8 | 9 | { label: "work", Component: WorkGrid }, 10 | ] 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 5 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 7 | ], 8 | theme: { 9 | extend: { 10 | colors: { 11 | background: "var(--background)", 12 | foreground: "var(--foreground)", 13 | }, 14 | }, 15 | }, 16 | plugins: [], 17 | }; 18 | -------------------------------------------------------------------------------- /src/app/components/misc.css: -------------------------------------------------------------------------------- 1 | #eeLJ3NBQkhu4_tr { 2 | animation: eeLJ3NBQkhu4_tr__tr 3000ms linear infinite normal forwards; 3 | } 4 | 5 | @keyframes eeLJ3NBQkhu4_tr__tr { 6 | 0% { 7 | transform: translate(176.406544px, 173.893578px) rotate(0deg); 8 | } 9 | 53.333333% { 10 | transform: translate(176.406544px, 173.893578px) rotate(20deg); 11 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 12 | } 13 | 100% { 14 | transform: translate(176.406544px, 173.893578px) rotate(0deg); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --background: #ffffff; 7 | --foreground: #171717; 8 | } 9 | 10 | @font-face { 11 | font-family: "AfacadFlux"; 12 | src: url("/fonts/AfacadFlux.ttf") format("ttf"); 13 | font-weight: 400; 14 | font-style: normal; 15 | } 16 | 17 | @media (prefers-color-scheme: dark) { 18 | :root { 19 | --background: #0a0a0a; 20 | --foreground: #ededed; 21 | } 22 | } 23 | 24 | body { 25 | color: var(--foreground); 26 | background: var(--background); 27 | font-weight: 400; 28 | font-style: normal; 29 | font-family: var(--font-afacad-flux), sans-serif; 30 | } 31 | 32 | @layer utilities { 33 | .text-balance { 34 | text-wrap: balance; 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@fortawesome/fontawesome-svg-core": "^6.6.0", 13 | "@fortawesome/free-brands-svg-icons": "^6.6.0", 14 | "@fortawesome/free-solid-svg-icons": "^6.6.0", 15 | "@fortawesome/react-fontawesome": "^0.2.2", 16 | "@react-spring/web": "^9.7.5", 17 | "next": "14.2.14", 18 | "react": "^18", 19 | "react-dom": "^18" 20 | }, 21 | "devDependencies": { 22 | "eslint": "^8", 23 | "eslint-config-next": "14.2.14", 24 | "postcss": "^8", 25 | "svg-react-loader": "^0.4.6", 26 | "tailwindcss": "^3.4.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/page.js: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import React, { useState } from 'react'; 3 | import { GRIDS } from './constants'; 4 | import { useTransition } from '@react-spring/web'; 5 | import FollowingCursor from './components/FollowingCursor'; 6 | 7 | const MemoizedFollowingCursor = React.memo(FollowingCursor); 8 | 9 | export default function Home() { 10 | const [currentGrid, setCurrentGrid] = useState(GRIDS[0]); 11 | 12 | const transitions = useTransition(currentGrid, { 13 | enter: { scale: 1 }, 14 | leave: { scale: 0 }, 15 | config: { duration: 300 }, 16 | }); 17 | 18 | return ( 19 | <> 20 | {transitions((style, item) => { 21 | const Grid = item.Component; 22 | return ; 23 | })} 24 | 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | # or 14 | bun dev 15 | ``` 16 | 17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 18 | 19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. 20 | 21 | ## Customise this Template 22 | 23 | Feel free to add or remove any sections. 24 | 25 | You can populate the `WorkGrid.js` file to add information about your past work experience. 26 | You can populate the `ProjectsGrid.js` file and add your projects there. 27 | Update the links to your social media in `Contact.js`. 28 | 29 | You can update the `Resume.js` and `Blog.js` sections to redirect to the correct locations. 30 | -------------------------------------------------------------------------------- /src/app/layout.js: -------------------------------------------------------------------------------- 1 | import localFont from "next/font/local" 2 | import "./globals.css" 3 | // pages/_app.js 4 | import { library } from "@fortawesome/fontawesome-svg-core" 5 | import { faInstagram } from "@fortawesome/free-brands-svg-icons" 6 | import { config } from "@fortawesome/fontawesome-svg-core" 7 | import "@fortawesome/fontawesome-svg-core/styles.css" // Import the CSS file 8 | 9 | config.autoAddCss = false // Prevent FontAwesome from adding its own CSS 10 | 11 | // Add icons to the library 12 | library.add(faInstagram) 13 | 14 | const geistSans = localFont({ 15 | src: "./fonts/GeistVF.woff", 16 | variable: "--font-geist-sans", 17 | weight: "100 900", 18 | }) 19 | const geistMono = localFont({ 20 | src: "./fonts/GeistMonoVF.woff", 21 | variable: "--font-geist-mono", 22 | weight: "100 900", 23 | }) 24 | const afacadFlux = localFont({ 25 | src: "./fonts/AfacadFlux.ttf", 26 | variable: "--font-afacad-flux", 27 | weight: "100 900", 28 | }) 29 | 30 | export const metadata = { 31 | title: "Create Next App", 32 | description: "Generated by create next app", 33 | } 34 | 35 | export default function RootLayout({ children }) { 36 | return ( 37 | 38 | {children} 39 | 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /src/app/components/education.css: -------------------------------------------------------------------------------- 1 | #eUbxc2KBHAG10_to { 2 | animation: eUbxc2KBHAG10_to__to 4000ms linear infinite normal forwards; 3 | } 4 | @keyframes eUbxc2KBHAG10_to__to { 5 | 0% { 6 | transform: translate(562.451659px, 9.317477px); 7 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 8 | } 9 | 50% { 10 | transform: translate(521.864915px, 9.317414px); 11 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 12 | } 13 | 100% { 14 | transform: translate(562.451659px, 9.317477px); 15 | } 16 | } 17 | #eUbxc2KBHAG11_to { 18 | animation: eUbxc2KBHAG11_to__to 4000ms linear infinite normal forwards; 19 | } 20 | @keyframes eUbxc2KBHAG11_to__to { 21 | 0% { 22 | transform: translate(778.945551px, 21.607485px); 23 | } 24 | 57.5% { 25 | transform: translate(806.864911px, 21.607454px); 26 | } 27 | 100% { 28 | transform: translate(778.945551px, 21.607485px); 29 | } 30 | } 31 | #eUbxc2KBHAG12_to { 32 | animation: eUbxc2KBHAG12_to__to 4000ms linear infinite normal forwards; 33 | } 34 | @keyframes eUbxc2KBHAG12_to__to { 35 | 0% { 36 | transform: translate(589.954996px, -52.830984px); 37 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 38 | } 39 | 60% { 40 | transform: translate(637.781425px, -52.831047px); 41 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 42 | } 43 | 100% { 44 | transform: translate(589.439707px, -52.830984px); 45 | } 46 | } 47 | #eUbxc2KBHAG13_to { 48 | animation: eUbxc2KBHAG13_to__to 4000ms linear infinite normal forwards; 49 | } 50 | @keyframes eUbxc2KBHAG13_to__to { 51 | 0% { 52 | transform: translate(230.26124px, 42.040123px); 53 | animation-timing-function: cubic-bezier(0.382302, 0, 0.894646, 0.823595); 54 | } 55 | 51.5% { 56 | transform: translate(274.356006px, 42.04008px); 57 | animation-timing-function: cubic-bezier(0.65076, 0.641038, 1, 1); 58 | } 59 | 52.5% { 60 | transform: translate(275.636183px, 42.040079px); 61 | animation-timing-function: cubic-bezier(0.42, 0, 1, 1); 62 | } 63 | 100% { 64 | transform: translate(230.776528px, 42.040123px); 65 | } 66 | } 67 | #eUbxc2KBHAG18_ts { 68 | animation: eUbxc2KBHAG18_ts__ts 4000ms linear infinite normal forwards; 69 | } 70 | @keyframes eUbxc2KBHAG18_ts__ts { 71 | 0% { 72 | transform: translate(227.5px, 169.75px) scale(1, 1); 73 | } 74 | 52% { 75 | transform: translate(227.5px, 169.75px) scale(0.5, 0.5); 76 | } 77 | 100% { 78 | transform: translate(227.5px, 169.75px) scale(1, 1); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/README.txt: -------------------------------------------------------------------------------- 1 | Afacad Flux Variable Font 2 | ========================= 3 | 4 | This download contains Afacad Flux as both a variable font and static fonts. 5 | 6 | Afacad Flux is a variable font with these axes: 7 | slnt 8 | wght 9 | 10 | This means all the styles are contained in a single file: 11 | AfacadFlux-VariableFont_slnt,wght.ttf 12 | 13 | If your app fully supports variable fonts, you can now pick intermediate styles 14 | that aren’t available as static fonts. Not all apps support variable fonts, and 15 | in those cases you can use the static font files for Afacad Flux: 16 | static/AfacadFlux-Thin.ttf 17 | static/AfacadFlux-ExtraLight.ttf 18 | static/AfacadFlux-Light.ttf 19 | static/AfacadFlux-Regular.ttf 20 | static/AfacadFlux-Medium.ttf 21 | static/AfacadFlux-SemiBold.ttf 22 | static/AfacadFlux-Bold.ttf 23 | static/AfacadFlux-ExtraBold.ttf 24 | static/AfacadFlux-Black.ttf 25 | 26 | Get started 27 | ----------- 28 | 29 | 1. Install the font files you want to use 30 | 31 | 2. Use your app's font picker to view the font family and all the 32 | available styles 33 | 34 | Learn more about variable fonts 35 | ------------------------------- 36 | 37 | https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts 38 | https://variablefonts.typenetwork.com 39 | https://medium.com/variable-fonts 40 | 41 | In desktop apps 42 | 43 | https://theblog.adobe.com/can-variable-fonts-illustrator-cc 44 | https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts 45 | 46 | Online 47 | 48 | https://developers.google.com/fonts/docs/getting_started 49 | https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide 50 | https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts 51 | 52 | Installing fonts 53 | 54 | MacOS: https://support.apple.com/en-us/HT201749 55 | Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux 56 | Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows 57 | 58 | Android Apps 59 | 60 | https://developers.google.com/fonts/docs/android 61 | https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts 62 | 63 | License 64 | ------- 65 | Please read the full license text (OFL.txt) to understand the permissions, 66 | restrictions and requirements for usage, redistribution, and modification. 67 | 68 | You can use them in your products & projects – print or digital, 69 | commercial or otherwise. 70 | 71 | This isn't legal advice, please consider consulting a lawyer and see the full 72 | license for all details. 73 | -------------------------------------------------------------------------------- /src/app/components/FollowingCursor.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef, useState } from "react" 2 | 3 | const lerp = (start, end, t) => { 4 | return start + (end - start) * t 5 | } 6 | 7 | const FollowingCursor = () => { 8 | const cursorRef = useRef(null) 9 | const innerRef = useRef(null) 10 | const requestRef = useRef() 11 | const cursorPositionRef = useRef({ x: 0, y: 0 }) 12 | const [currentPosition, setCurrentPosition] = useState({ x: 0, y: 0 }) 13 | 14 | const handleMouseMove = (e) => { 15 | cursorPositionRef.current = { x: e.clientX, y: e.clientY } 16 | if (e.target.tagName === "H2" || e.target.id === "home") { 17 | cursorRef.current.style.height = "50px" 18 | cursorRef.current.style.width = "50px" 19 | innerRef.current.style.height = "30px" 20 | innerRef.current.style.width = "30px" 21 | innerRef.current.style.opacity = "100%" 22 | } else { 23 | cursorRef.current.style.height = "40px" 24 | cursorRef.current.style.width = "40px" 25 | innerRef.current.style.height = "0px" 26 | innerRef.current.style.width = "0px" 27 | innerRef.current.style.opacity = "0%" 28 | } 29 | } 30 | 31 | useEffect(() => { 32 | window.addEventListener("mousemove", handleMouseMove) 33 | 34 | return () => { 35 | window.removeEventListener("mousemove", handleMouseMove) 36 | } 37 | }, []) 38 | 39 | const animate = () => { 40 | setCurrentPosition((prev) => ({ 41 | x: lerp(prev.x, cursorPositionRef.current.x, 0.1), 42 | y: lerp(prev.y, cursorPositionRef.current.y, 0.1), 43 | })) 44 | 45 | requestRef.current = requestAnimationFrame(animate) 46 | } 47 | 48 | useEffect(() => { 49 | requestRef.current = requestAnimationFrame(animate) 50 | return () => cancelAnimationFrame(requestRef.current) 51 | }, []) 52 | 53 | return ( 54 |
55 |
74 |
88 |
89 |
90 | ) 91 | } 92 | 93 | export default FollowingCursor 94 | -------------------------------------------------------------------------------- /src/app/components/projects.css: -------------------------------------------------------------------------------- 1 | #ewEtQUf14pr30_to { 2 | animation: ewEtQUf14pr30_to__to 3000ms linear infinite normal forwards; 3 | } 4 | @keyframes ewEtQUf14pr30_to__to { 5 | 0% { 6 | transform: translate(-85.659565px, -89.6748px); 7 | animation-timing-function: cubic-bezier(0.6, -0.28, 0.735, 0.045); 8 | } 9 | 50% { 10 | transform: translate(-85.659565px, -56.944388px); 11 | animation-timing-function: cubic-bezier(0.6, -0.28, 0.735, 0.045); 12 | } 13 | 100% { 14 | transform: translate(-85.659565px, -89.6748px); 15 | } 16 | } 17 | #ewEtQUf14pr31_tr { 18 | animation: ewEtQUf14pr31_tr__tr 3000ms linear infinite normal forwards; 19 | } 20 | @keyframes ewEtQUf14pr31_tr__tr { 21 | 0% { 22 | transform: translate(23.292969px, 20.369141px) rotate(0deg); 23 | } 24 | 50% { 25 | transform: translate(23.292969px, 20.369141px) rotate(360deg); 26 | } 27 | 100% { 28 | transform: translate(23.292969px, 20.369141px) rotate(0deg); 29 | } 30 | } 31 | #ewEtQUf14pr64 { 32 | animation: ewEtQUf14pr64__sz 3000ms linear infinite normal forwards; 33 | } 34 | @keyframes ewEtQUf14pr64__sz { 35 | 0% { 36 | width: 60px; 37 | height: 0px; 38 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 39 | } 40 | 33.333333% { 41 | width: 60px; 42 | height: 60px; 43 | } 44 | 100% { 45 | width: 60px; 46 | height: 60px; 47 | } 48 | } 49 | #ewEtQUf14pr65 { 50 | animation: ewEtQUf14pr65__sz 3000ms linear infinite normal forwards; 51 | } 52 | @keyframes ewEtQUf14pr65__sz { 53 | 0% { 54 | width: 0px; 55 | height: 10px; 56 | animation-timing-function: cubic-bezier(0.42, 0, 1, 1); 57 | } 58 | 33.333333% { 59 | width: 140px; 60 | height: 10px; 61 | } 62 | 100% { 63 | width: 140px; 64 | height: 10px; 65 | } 66 | } 67 | #ewEtQUf14pr66 { 68 | animation: ewEtQUf14pr66__sz 3000ms linear infinite normal forwards; 69 | } 70 | @keyframes ewEtQUf14pr66__sz { 71 | 0% { 72 | width: 0px; 73 | height: 10px; 74 | } 75 | 60% { 76 | width: 190px; 77 | height: 10px; 78 | } 79 | 80% { 80 | width: 180px; 81 | height: 10px; 82 | } 83 | 100% { 84 | width: 180px; 85 | height: 10px; 86 | } 87 | } 88 | #ewEtQUf14pr67 { 89 | animation: ewEtQUf14pr67__sz 3000ms linear infinite normal forwards; 90 | } 91 | @keyframes ewEtQUf14pr67__sz { 92 | 0% { 93 | width: 0px; 94 | height: 10px; 95 | } 96 | 80% { 97 | width: 120px; 98 | height: 10px; 99 | } 100 | 100% { 101 | width: 120px; 102 | height: 10px; 103 | } 104 | } 105 | #ewEtQUf14pr68 { 106 | animation: ewEtQUf14pr68__sz 3000ms linear infinite normal forwards; 107 | } 108 | @keyframes ewEtQUf14pr68__sz { 109 | 0% { 110 | width: 270px; 111 | height: 0px; 112 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 113 | } 114 | 46.666667% { 115 | width: 270px; 116 | height: 60px; 117 | } 118 | 100% { 119 | width: 270px; 120 | height: 60px; 121 | } 122 | } 123 | #ewEtQUf14pr69_to { 124 | animation: ewEtQUf14pr69_to__to 3000ms linear infinite normal forwards; 125 | } 126 | @keyframes ewEtQUf14pr69_to__to { 127 | 0% { 128 | offset-distance: 0%; 129 | } 130 | 43.333333% { 131 | offset-distance: 26.624108%; 132 | } 133 | 63.333333% { 134 | offset-distance: 47.8606%; 135 | } 136 | 83.333333% { 137 | offset-distance: 76.391757%; 138 | } 139 | 100% { 140 | offset-distance: 100%; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/app/components/Misc.js: -------------------------------------------------------------------------------- 1 | import "./misc.css" 2 | 3 | export default function Misc() { 4 | return ( 5 | <> 6 | 14 | 15 | 16 | 20 | 21 | 27 | 33 | 39 | 45 | 51 | 57 | 58 | 59 | 60 | 61 | 67 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 85 | ) 86 | } 87 | -------------------------------------------------------------------------------- /src/app/components/WorkGrid.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | import { useTrail, animated, easings } from "@react-spring/web" 3 | 4 | import WorkExperience from "./WorkExperience" 5 | import Projects from "./Projects" 6 | import Education from "./Education" 7 | import Resume from "./Resume" 8 | import Blog from "./Blog" 9 | import Contact from "./Contact" 10 | import Misc from "./Misc" 11 | import { GRIDS } from "../constants" 12 | 13 | export default function WorkGrid({ setCurrentGrid, animatedStyles }) { 14 | const [nameIdx, setNameIdx] = useState(0) 15 | const name = "Work Experience".split("") 16 | 17 | const [subheadingIdx, setSubheadingIdx] = useState(0) 18 | const subheading = "Here are the places I've worked at over the years".split( 19 | "" 20 | ) 21 | 22 | useEffect(() => { 23 | const id = setInterval(() => { 24 | if (nameIdx < name.length) { 25 | setNameIdx(nameIdx + 1) 26 | } 27 | if (subheadingIdx < subheading.length) { 28 | setSubheadingIdx(subheadingIdx + 1) 29 | } 30 | }, 100) 31 | 32 | return () => { 33 | clearInterval(id) 34 | } 35 | }) 36 | 37 | const trails = useTrail(5, { 38 | from: { scale: 0 }, 39 | to: { scale: 1 }, 40 | leave: { scale: 1 }, 41 | config: { 42 | easing: easings.easeInBack, 43 | delay: 300, 44 | }, 45 | }) 46 | 47 | return ( 48 | 49 | 53 | 57 | 58 | 59 | 63 | 67 | 68 | 69 | 73 | 77 | 78 | 79 | setCurrentGrid(GRIDS[0])} 82 | className='row-start-1 lg:col-span-3 lg:row-span-3' 83 | > 84 | 88 |
89 | 90 | {name.slice(0, nameIdx).join("")} 91 | 92 | 93 |
94 |
95 | 96 | {subheading.slice(0, subheadingIdx).join("")} 97 | 98 | 99 |
100 |
101 |
102 | 103 | 107 | 111 | 112 | 113 | 117 | 121 | 122 |
123 | ) 124 | } 125 | -------------------------------------------------------------------------------- /src/app/components/ProjectsGrid.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | import { useTrail, animated, easings } from "@react-spring/web" 3 | import { GRIDS } from "../constants" 4 | 5 | export default function ProjectsGrid({ setCurrentGrid, animatedStyles }) { 6 | const [nameIdx, setNameIdx] = useState(0) 7 | const name = "Projects".split("") 8 | 9 | const [subheadingIdx, setSubheadingIdx] = useState(0) 10 | const subheading = 11 | "Here are a few personal projects I've worked on over the years".split("") 12 | 13 | useEffect(() => { 14 | const id = setInterval(() => { 15 | if (nameIdx < name.length) { 16 | setNameIdx(nameIdx + 1) 17 | } 18 | if (subheadingIdx < subheading.length) { 19 | setSubheadingIdx(subheadingIdx + 1) 20 | } 21 | }, 100) 22 | 23 | return () => { 24 | clearInterval(id) 25 | } 26 | }) 27 | 28 | const trails = useTrail(7, { 29 | from: { scale: 0 }, 30 | to: { scale: 1 }, 31 | leave: { scale: 1 }, 32 | config: { 33 | easing: easings.easeInBack, 34 | delay: 300, 35 | }, 36 | }) 37 | 38 | return ( 39 | 40 | 44 | 48 | 49 | 50 | 54 | 58 | 59 | 60 | 64 | 68 | 69 | 70 | setCurrentGrid(GRIDS[0])} 73 | className='row-start-1 lg:col-span-3 lg:row-span-3' 74 | > 75 | 79 |
80 | 81 | {name.slice(0, nameIdx).join("")} 82 | 83 | 84 |
85 |
86 | 87 | {subheading.slice(0, subheadingIdx).join("")} 88 | 89 | 90 |
91 |
92 |
93 | 94 | 98 | 102 | 103 | 104 | 108 | 112 | 113 | 114 | 118 | 122 | 123 |
124 | ) 125 | } 126 | -------------------------------------------------------------------------------- /src/app/components/resume.css: -------------------------------------------------------------------------------- 1 | #eGNsHDgmMvZ5 { 2 | animation: eGNsHDgmMvZ5_s_do 3000ms linear infinite normal forwards; 3 | } 4 | @keyframes eGNsHDgmMvZ5_s_do { 5 | 0% { 6 | stroke-dashoffset: 115; 7 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 8 | } 9 | 46.666667% { 10 | stroke-dashoffset: 0; 11 | } 12 | 100% { 13 | stroke-dashoffset: 0; 14 | } 15 | } 16 | #eGNsHDgmMvZ6 { 17 | animation: eGNsHDgmMvZ6_s_do 3000ms linear infinite normal forwards; 18 | } 19 | @keyframes eGNsHDgmMvZ6_s_do { 20 | 0% { 21 | stroke-dashoffset: 115; 22 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 23 | } 24 | 53.333333% { 25 | stroke-dashoffset: 0; 26 | } 27 | 100% { 28 | stroke-dashoffset: 0; 29 | } 30 | } 31 | #eGNsHDgmMvZ7 { 32 | animation: eGNsHDgmMvZ7_s_do 3000ms linear infinite normal forwards; 33 | } 34 | @keyframes eGNsHDgmMvZ7_s_do { 35 | 0% { 36 | stroke-dashoffset: 115; 37 | } 38 | 63.333333% { 39 | stroke-dashoffset: 0; 40 | } 41 | 100% { 42 | stroke-dashoffset: 0; 43 | } 44 | } 45 | #eGNsHDgmMvZ8 { 46 | animation: eGNsHDgmMvZ8_s_do 3000ms linear infinite normal forwards; 47 | } 48 | @keyframes eGNsHDgmMvZ8_s_do { 49 | 0% { 50 | stroke-dashoffset: 115; 51 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 52 | } 53 | 75% { 54 | stroke-dashoffset: 0; 55 | } 56 | 100% { 57 | stroke-dashoffset: 0; 58 | } 59 | } 60 | #eGNsHDgmMvZ9 { 61 | animation: eGNsHDgmMvZ9_s_do 3000ms linear infinite normal forwards; 62 | } 63 | @keyframes eGNsHDgmMvZ9_s_do { 64 | 0% { 65 | stroke-dashoffset: 115; 66 | animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 67 | } 68 | 86.666667% { 69 | stroke-dashoffset: 0; 70 | } 71 | 100% { 72 | stroke-dashoffset: 0; 73 | } 74 | } 75 | #eGNsHDgmMvZ10_ts { 76 | animation: eGNsHDgmMvZ10_ts__ts 3000ms linear infinite normal forwards; 77 | } 78 | @keyframes eGNsHDgmMvZ10_ts__ts { 79 | 0% { 80 | transform: translate(114.521299px, 91.655488px) rotate(-15.268073deg) 81 | scale(0, 0); 82 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 83 | } 84 | 26.666667% { 85 | transform: translate(114.521299px, 91.655488px) rotate(-15.268073deg) 86 | scale(1, 1); 87 | } 88 | 100% { 89 | transform: translate(114.521299px, 91.655488px) rotate(-15.268073deg) 90 | scale(1, 1); 91 | } 92 | } 93 | #eGNsHDgmMvZ14 { 94 | animation: eGNsHDgmMvZ14__m 3000ms linear infinite normal forwards; 95 | } 96 | @keyframes eGNsHDgmMvZ14__m { 97 | 0% { 98 | d: path( 99 | "M46.849999,16.82L36.690447,18.684246L28.077349,17.052517L26.85,16.82L46.85,16.82L46.849999,16.82" 100 | ); 101 | } 102 | 20% { 103 | d: path( 104 | "M46.85,45.49L36.85,39.160653L26.85,45.49L26.85,16.82L46.85,16.82L46.85,45.49" 105 | ); 106 | } 107 | 100% { 108 | d: path( 109 | "M46.85,45.49L36.85,39.160653L26.85,45.49L26.85,16.82L46.85,16.82L46.85,45.49" 110 | ); 111 | } 112 | } 113 | #eGNsHDgmMvZ15 { 114 | animation: eGNsHDgmMvZ15__sz 3000ms linear infinite normal forwards; 115 | } 116 | @keyframes eGNsHDgmMvZ15__sz { 117 | 0% { 118 | width: 0px; 119 | height: 10px; 120 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 121 | } 122 | 43.333333% { 123 | width: 60px; 124 | height: 10px; 125 | } 126 | 100% { 127 | width: 60px; 128 | height: 10px; 129 | } 130 | } 131 | #eGNsHDgmMvZ16 { 132 | animation: eGNsHDgmMvZ16__sz 3000ms linear infinite normal forwards; 133 | } 134 | @keyframes eGNsHDgmMvZ16__sz { 135 | 0% { 136 | width: 0px; 137 | height: 10px; 138 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 139 | } 140 | 56.666667% { 141 | width: 60px; 142 | height: 10px; 143 | } 144 | 100% { 145 | width: 60px; 146 | height: 10px; 147 | } 148 | } 149 | #eGNsHDgmMvZ17 { 150 | animation: eGNsHDgmMvZ17__sz 3000ms linear infinite normal forwards; 151 | } 152 | @keyframes eGNsHDgmMvZ17__sz { 153 | 0% { 154 | width: 40px; 155 | height: 0px; 156 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 157 | } 158 | 30% { 159 | width: 40px; 160 | height: 40px; 161 | } 162 | 100% { 163 | width: 40px; 164 | height: 40px; 165 | } 166 | } 167 | #eGNsHDgmMvZ18 { 168 | animation: eGNsHDgmMvZ18__sz 3000ms linear infinite normal forwards; 169 | } 170 | @keyframes eGNsHDgmMvZ18__sz { 171 | 0% { 172 | width: 60px; 173 | height: 0px; 174 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 175 | } 176 | 20% { 177 | width: 60px; 178 | height: 40px; 179 | } 180 | 100% { 181 | width: 60px; 182 | height: 40px; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/app/fonts/AfacadFlux/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright 2023 The Afacad Project Authors (https://github.com/Dicotype/Afacad) 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | https://openfontlicense.org 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /src/app/components/HomeGrid.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | import { useTrail, animated, easings } from "@react-spring/web" 3 | 4 | import WorkExperience from "./WorkExperience" 5 | import Projects from "./Projects" 6 | import Education from "./Education" 7 | import Resume from "./Resume" 8 | import Blog from "./Blog" 9 | import Contact from "./Contact" 10 | import Misc from "./Misc" 11 | import { GRIDS } from "../constants" 12 | 13 | export default function HomeGrid({ setCurrentGrid, animatedStyles }) { 14 | const [nameIdx, setNameIdx] = useState(0) 15 | const name = "Urvashi".split("") 16 | 17 | const [subheadingIdx, setSubheadingIdx] = useState(0) 18 | const subheading = "Creative Web Developer, Content Creator".split("") 19 | 20 | useEffect(() => { 21 | const id = setInterval(() => { 22 | if (nameIdx < name.length) { 23 | setNameIdx(nameIdx + 1) 24 | } 25 | if (subheadingIdx < subheading.length) { 26 | setSubheadingIdx(subheadingIdx + 1) 27 | } 28 | }, 100) 29 | 30 | return () => { 31 | clearInterval(id) 32 | } 33 | }) 34 | 35 | const trails = useTrail(7, { 36 | from: { scale: 0 }, 37 | to: { scale: 1 }, 38 | leave: { scale: 1 }, 39 | config: { 40 | easing: easings.easeInBack, 41 | delay: 300, 42 | }, 43 | }) 44 | 45 | return ( 46 | 47 | 51 | setCurrentGrid(GRIDS[2])} 55 | > 56 | 57 | 58 | 59 | 63 | setCurrentGrid(GRIDS[1])} 65 | style={trails[3]} 66 | className='relative h-full w-full bg-[#2A9D8F] border border-black' 67 | > 68 | 69 | 70 | 71 | 75 | 79 | 80 | 81 | 82 | 86 | 90 |
91 | 92 | {name.slice(0, nameIdx).join("")} 93 | 94 | 95 |
96 |
97 | 98 | {subheading.slice(0, subheadingIdx).join("")} 99 | 100 | 101 |
102 |
103 |
104 | 108 | 112 | 113 | 114 | 115 | 119 | 123 | 124 | 125 | 126 | 130 | 134 | 135 | 136 | 137 | 141 | 145 | 146 | 147 | 148 |
149 | ) 150 | } 151 | -------------------------------------------------------------------------------- /src/app/components/blog.css: -------------------------------------------------------------------------------- 1 | #ejQcAnIEep746 { 2 | animation: ejQcAnIEep746_c_o 2000ms linear infinite normal forwards; 3 | } 4 | @keyframes ejQcAnIEep746_c_o { 5 | 0% { 6 | opacity: 0; 7 | } 8 | 25% { 9 | opacity: 1; 10 | } 11 | 100% { 12 | opacity: 1; 13 | } 14 | } 15 | #ejQcAnIEep751 { 16 | animation: ejQcAnIEep751_c_o 2000ms linear infinite normal forwards; 17 | } 18 | @keyframes ejQcAnIEep751_c_o { 19 | 0% { 20 | opacity: 0; 21 | } 22 | 30% { 23 | opacity: 1; 24 | } 25 | 100% { 26 | opacity: 1; 27 | } 28 | } 29 | #ejQcAnIEep756 { 30 | animation: ejQcAnIEep756_c_o 2000ms linear infinite normal forwards; 31 | } 32 | @keyframes ejQcAnIEep756_c_o { 33 | 0% { 34 | opacity: 0; 35 | } 36 | 25% { 37 | opacity: 1; 38 | } 39 | 100% { 40 | opacity: 1; 41 | } 42 | } 43 | #ejQcAnIEep761 { 44 | animation: ejQcAnIEep761_c_o 2000ms linear infinite normal forwards; 45 | } 46 | @keyframes ejQcAnIEep761_c_o { 47 | 0% { 48 | opacity: 0; 49 | } 50 | 40% { 51 | opacity: 1; 52 | } 53 | 100% { 54 | opacity: 1; 55 | } 56 | } 57 | #ejQcAnIEep764 { 58 | animation: ejQcAnIEep764_s_do 2000ms linear infinite normal forwards; 59 | } 60 | @keyframes ejQcAnIEep764_s_do { 61 | 0% { 62 | stroke-dashoffset: 110; 63 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 64 | } 65 | 70% { 66 | stroke-dashoffset: 0; 67 | } 68 | 100% { 69 | stroke-dashoffset: 0; 70 | } 71 | } 72 | #ejQcAnIEep765 { 73 | animation: ejQcAnIEep765_s_do 2000ms linear infinite normal forwards; 74 | } 75 | @keyframes ejQcAnIEep765_s_do { 76 | 0% { 77 | stroke-dashoffset: 60; 78 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 79 | } 80 | 60% { 81 | stroke-dashoffset: 0; 82 | } 83 | 100% { 84 | stroke-dashoffset: 0; 85 | } 86 | } 87 | #ejQcAnIEep766 { 88 | animation: ejQcAnIEep766_s_do 2000ms linear infinite normal forwards; 89 | } 90 | @keyframes ejQcAnIEep766_s_do { 91 | 0% { 92 | stroke-dashoffset: 210; 93 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 94 | } 95 | 75% { 96 | stroke-dashoffset: 0; 97 | } 98 | 100% { 99 | stroke-dashoffset: 0; 100 | } 101 | } 102 | #ejQcAnIEep767 { 103 | animation: ejQcAnIEep767_s_do 2000ms linear infinite normal forwards; 104 | } 105 | @keyframes ejQcAnIEep767_s_do { 106 | 0% { 107 | stroke-dashoffset: 60; 108 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 109 | } 110 | 60% { 111 | stroke-dashoffset: 0; 112 | } 113 | 100% { 114 | stroke-dashoffset: 0; 115 | } 116 | } 117 | #ejQcAnIEep768 { 118 | animation: ejQcAnIEep768_s_do 2000ms linear infinite normal forwards; 119 | } 120 | @keyframes ejQcAnIEep768_s_do { 121 | 0% { 122 | stroke-dashoffset: 80; 123 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 124 | } 125 | 70% { 126 | stroke-dashoffset: 0; 127 | } 128 | 100% { 129 | stroke-dashoffset: 0; 130 | } 131 | } 132 | #ejQcAnIEep769 { 133 | animation: ejQcAnIEep769_s_do 2000ms linear infinite normal forwards; 134 | } 135 | @keyframes ejQcAnIEep769_s_do { 136 | 0% { 137 | stroke-dashoffset: 130; 138 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 139 | } 140 | 55% { 141 | stroke-dashoffset: 0; 142 | } 143 | 100% { 144 | stroke-dashoffset: 0; 145 | } 146 | } 147 | #ejQcAnIEep770 { 148 | animation: ejQcAnIEep770_s_do 2000ms linear infinite normal forwards; 149 | } 150 | @keyframes ejQcAnIEep770_s_do { 151 | 0% { 152 | stroke-dashoffset: 90; 153 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 154 | } 155 | 40% { 156 | stroke-dashoffset: 0; 157 | } 158 | 100% { 159 | stroke-dashoffset: 0; 160 | } 161 | } 162 | #ejQcAnIEep771 { 163 | animation: ejQcAnIEep771_s_do 2000ms linear infinite normal forwards; 164 | } 165 | @keyframes ejQcAnIEep771_s_do { 166 | 0% { 167 | stroke-dashoffset: 40; 168 | animation-timing-function: cubic-bezier(0, 0, 0.58, 1); 169 | } 170 | 40% { 171 | stroke-dashoffset: 0; 172 | } 173 | 100% { 174 | stroke-dashoffset: 0; 175 | } 176 | } 177 | #ejQcAnIEep773 { 178 | animation: ejQcAnIEep773_f_o 2000ms linear infinite normal forwards; 179 | } 180 | @keyframes ejQcAnIEep773_f_o { 181 | 0% { 182 | fill-opacity: 0; 183 | } 184 | 35% { 185 | fill-opacity: 1; 186 | } 187 | 100% { 188 | fill-opacity: 1; 189 | } 190 | } 191 | #ejQcAnIEep774 { 192 | animation: ejQcAnIEep774__m 2000ms linear infinite normal forwards; 193 | } 194 | @keyframes ejQcAnIEep774__m { 195 | 0% { 196 | d: path( 197 | "M-18.555501,-24.1L-9.531466,-24.1L-29.531466,-24.1L-18.555501,-24.1" 198 | ); 199 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 200 | } 201 | 30% { 202 | d: path( 203 | "M-19.531466,-34.1L-9.531466,-24.1L-29.531466,-24.1L-19.531466,-34.1" 204 | ); 205 | } 206 | 100% { 207 | d: path( 208 | "M-19.531466,-34.1L-9.531466,-24.1L-29.531466,-24.1L-19.531466,-34.1" 209 | ); 210 | } 211 | } 212 | #ejQcAnIEep775 { 213 | animation: ejQcAnIEep775__m 2000ms linear infinite normal forwards; 214 | } 215 | @keyframes ejQcAnIEep775__m { 216 | 0% { 217 | d: path( 218 | "M-10.609613,-14.1L2.468534,-14.1L-29.531466,-14.1L-10.609613,-14.1" 219 | ); 220 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 221 | } 222 | 25% { 223 | d: path( 224 | "M-13.531466,-34.1L2.468534,-14.1L-29.531466,-14.1L-13.531466,-34.1" 225 | ); 226 | } 227 | 100% { 228 | d: path( 229 | "M-13.531466,-34.1L2.468534,-14.1L-29.531466,-14.1L-13.531466,-34.1" 230 | ); 231 | } 232 | } 233 | #ejQcAnIEep780 { 234 | animation: ejQcAnIEep780__rd 2000ms linear infinite normal forwards; 235 | } 236 | @keyframes ejQcAnIEep780__rd { 237 | 0% { 238 | r: 1px; 239 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 240 | } 241 | 40% { 242 | r: 5px; 243 | } 244 | 100% { 245 | r: 5px; 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/app/components/Resume.js: -------------------------------------------------------------------------------- 1 | import "./resume.css" 2 | 3 | export default function Resume() { 4 | return ( 5 |
6 | 12 | 21 | 30 | 31 | 42 | 53 | 64 | 75 | 86 | 87 | 91 | 92 | 98 | 109 | 117 | 118 | 119 | 126 | 136 | 146 | 156 | 166 | 167 | 168 |
169 |

170 | Resume 171 |

172 |
173 |
174 | ) 175 | } 176 | -------------------------------------------------------------------------------- /src/app/components/Contact.js: -------------------------------------------------------------------------------- 1 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 2 | import { 3 | faGithub, 4 | faInstagram, 5 | faLinkedinIn, 6 | faXTwitter, 7 | faYoutube, 8 | } from "@fortawesome/free-brands-svg-icons" 9 | import { faEnvelope } from "@fortawesome/free-solid-svg-icons" 10 | import "./contact.css" 11 | 12 | function BlackIconWrapper({ icon, ...rest }) { 13 | return ( 14 | 20 | ) 21 | } 22 | 23 | function RedIconWrapper({ icon, ...rest }) { 24 | return ( 25 | 31 | ) 32 | } 33 | 34 | function IconWrapper({ icon, bgColor, textColor, target, isEmail }) { 35 | return ( 36 | 40 | 41 | 42 | ) 43 | } 44 | 45 | export default function Contact() { 46 | return ( 47 | <> 48 |
49 | 50 | 59 | 66 | 67 | 78 | 79 | 85 | 86 | 92 | 93 | 99 | 105 | 106 | 118 | 119 | CONTACT ME 120 | 121 | 122 | 123 | 131 | 139 | 147 | 155 | 163 | 171 | 172 |
173 |
174 | 178 | 179 | 180 | 181 | 182 | 183 |
184 | 185 | ) 186 | } 187 | -------------------------------------------------------------------------------- /src/app/components/contact.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "ecfYqkDzjoQ1:::Oswald"; 3 | font-style: normal; 4 | font-weight: 700; 5 | src: url(data:font/ttf;charset=utf-8;base64,AAEAAAAQAQAABAAAR0RFRgARAAgAAAEwAAAAFkdQT1MsOSS+AAADGAAAAM5HU1VCuPy46gAAAdAAAAAoT1MvMrBXfMYAAAK4AAAAYFNUQVR5lWtJAAAB+AAAACpjbWFwAS0BFwAAAlwAAABcZ2FzcAAAABAAAAEUAAAACGdseWbXOJTkAAAD6AAAAeZoZWFkGnPnDQAAAiQAAAA2aGhlYQk7AsoAAAGIAAAAJGhtdHgSrAGFAAABrAAAACRsb2NhAkIC4wAAARwAAAAUbWF4cAAZAM8AAAFIAAAAIG5hbWUtblCxAAAF0AAAAixwb3N0/58AMgAAAWgAAAAgcHJlcGgGjIUAAAEMAAAAB7gB/4WwBI0AAAEAAf//AA8AAAAUACwAZQB5AJUAqgDiAPMA8wABAAAADAAAAAAAAAACAAEAAQAHAAEAAAABAAAACQBlAAcAaAAFAAEAAAAAAAAAAAAAAAAAAwABAAMAAAAAAAD/nAAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAABKn+3wAABZ//If5CBW4AAQAAAAAAAAAAAAAAAAAAAAkCmwBSAicAFQIzADEBvwA8AsAAOQIxADwCSgAxAb0ACwEAAAAAAQAAAAoAJgAmAAJERkxUABJsYXRuAA4AAAAAAAQAAAAA//8AAAAAAAEAAQAIAAEAAAAUAAEAAAAcAAJ3Z2h0AQAAAAACAAEAAAAAAQYCvAAAAAAAAQAAAAQaXjm7LzdfDzz1AAMD6AAAAADV6qBlAAAAAODe56b/If6bBW4FJgABAAYAAgAAAAAAAAAAAAIAAAADAAAAFAADAAEAAAAUAAQASAAAAA4ACAACAAYAIABBAEMARQBPAFT//wAAACAAQQBDAEUATQBU////6P/A/7//vv+3/7MAAQAAAAAAAAAAAAAAAAAAAAQB0QK8AAUAAAKKAlgAAABLAooCWAAAAV4AMgFbAAAAAAAAAAAAAAAAoAAC/0AAIEsAAAAAAAAAAG5ld3QAoAAgAFQEqf7fAAAFLQF5IAABlwAAAAACQgMqAAAAIAADAAEAAAAKACQAMgACREZMVAAObGF0bgAOAAQAAAAA//8AAQAAAAFrZXJuAAgAAAABAAAAAQAEAAIACAABAAgAAgBYAAQAAAB8AGgABgAGAAAAAAAA//P/+AAAAAAAAP/zAAD/0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4/9MAAP/6AAAAAAAAAAD/+gAAAAEABgABAAIAAwAEAAYABwABAAEABwADAAIAAQAFAAEAAgAEAAEAAQAHAAEAAwACAAUAAAAAAAQAAAACAFIAAAJIAyoAAwAHAAAzESERJSERIVIB9v5xASj+2AMq/NZaAnYAAgAVAAACEQMqAAcACgAAMxMzEyMnIwcTMwMVmcyXpRt3HCxWKwMq/NarqwEWATwAAQAx//QCDQM1ACcAAAUiJiY1ETQ2NjMyFhYVFSM1NCYmIyIGBhURFBYWMzI2NjU1MxUUBgYBJFxrLCxrXFplKq8FGB0cGwcJGxocGAavKWUMQ3lSASRUeUI7akVGURgsHR4tGf6DGy0bHS4YVUZFbT8AAQA8AAABqgMqAAsAADMRIRUjFTMVIxUzFTwBbLmNjbsDKnrJfPJ5AAEAOQAAAocDKgAMAAAzEzMTEzMTIwMDIwMDOQ7AWWC5Dn8PXnFkDAMq/ikB1/zWAhv95QIf/eEAAQA8AAAB9AMqAAkAADMRMxMRMxEjAxE8fqaUeaYDKv56AYb81gGk/lwAAgAx//QCGQM1ABEAIwAABSImJjURNDY2MzIWFhURFAYGJzI2NjURNCYmIyIGBhURFBYWASRbai4ualtcay4ua1wcGggIGhwaGggHGQxAeFMBLVR2Pz92VP7TU3hAfxwsFwGGGCscHCsY/noXLBwAAAEACwAAAbIDKgAHAAAzESM1IRUjEYV6Aad5AqWFhf1bAAAAAAAACgB+AAMAAQQJAAAAqgEEAAMAAQQJAAEADAD4AAMAAQQJAAIACADwAAMAAQQJAAMALADEAAMAAQQJAAQAFgCuAAMAAQQJAAUAVgBYAAMAAQQJAAYAFgBCAAMAAQQJAA4ANgAMAAMAAQQJAQAADAAAAAMAAQQJAQYACADwAFcAZQBpAGcAaAB0AGgAdAB0AHAAcwA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAE8AcwB3AGEAbABkAC0AQgBvAGwAZABWAGUAcgBzAGkAbwBuACAANAAuADEAMAAzADsAZwBmAHQAbwBvAGwAcwBbADAALgA5AC4AMwAzAC4AZABlAHYAOAArAGcAMAAyADkAZQAxADkAZgBdAE8AcwB3AGEAbABkACAAQgBvAGwAZAA0AC4AMQAwADMAOwBuAGUAdwB0ADsATwBzAHcAYQBsAGQALQBCAG8AbABkAEIAbwBsAGQATwBzAHcAYQBsAGQAQwBvAHAAeQByAGkAZwBoAHQAIAAyADAAMQA2ACAAVABoAGUAIABPAHMAdwBhAGwAZAAgAFAAcgBvAGoAZQBjAHQAIABBAHUAdABoAG8AcgBzACAAKABoAHQAdABwAHMAOgAvAC8AZwBpAHQAaAB1AGIALgBjAG8AbQAvAGcAbwBvAGcAbABlAGYAbwBuAHQAcwAvAE8AcwB3AGEAbABkAEYAbwBuAHQAKQ==) 6 | format("truetype"); 7 | } 8 | #ecfYqkDzjoQ3 { 9 | animation: ecfYqkDzjoQ3__m 3000ms linear infinite normal forwards; 10 | } 11 | @keyframes ecfYqkDzjoQ3__m { 12 | 0% { 13 | d: path( 14 | "M60.17149,102.131785L240.17149,102.131785L183.908714,140.391071L117.405176,140.391071L60.17149,102.131785Z" 15 | ); 16 | } 17 | 3.333333% { 18 | d: path( 19 | "M60.17149,102.131785L240.17149,102.131785L183.908714,140.391071L117.405176,140.391071L60.17149,102.131785Z" 20 | ); 21 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 22 | } 23 | 30% { 24 | d: path( 25 | "M60.17149,102.131785L240.17149,102.131785L183.908714,60.159967L117.405176,60.159967L60.17149,102.131785Z" 26 | ); 27 | } 28 | 100% { 29 | d: path( 30 | "M60.17149,102.131785L240.17149,102.131785L183.908714,60.159967L117.405176,60.159967L60.17149,102.131785Z" 31 | ); 32 | } 33 | } 34 | #ecfYqkDzjoQ4_to { 35 | animation: ecfYqkDzjoQ4_to__to 3000ms linear infinite normal forwards; 36 | } 37 | @keyframes ecfYqkDzjoQ4_to__to { 38 | 0% { 39 | transform: translate(112.311339px, 143.37819px); 40 | } 41 | 23.333333% { 42 | transform: translate(112.311339px, 143.37819px); 43 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 44 | } 45 | 60% { 46 | transform: translate(111.546918px, 103px); 47 | } 48 | 100% { 49 | transform: translate(111.546918px, 109.318167px); 50 | } 51 | } 52 | #ecfYqkDzjoQ4 { 53 | animation: ecfYqkDzjoQ4_c_o 3000ms linear infinite normal forwards; 54 | } 55 | @keyframes ecfYqkDzjoQ4_c_o { 56 | 0% { 57 | opacity: 0; 58 | } 59 | 16.666667% { 60 | opacity: 0; 61 | } 62 | 36.666667% { 63 | opacity: 1; 64 | } 65 | 100% { 66 | opacity: 1; 67 | } 68 | } 69 | #ecfYqkDzjoQ6_to { 70 | animation: ecfYqkDzjoQ6_to__to 3000ms linear infinite normal forwards; 71 | } 72 | @keyframes ecfYqkDzjoQ6_to__to { 73 | 0% { 74 | transform: translate(165.331702px, 160.997459px); 75 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 76 | } 77 | 23.333333% { 78 | transform: translate(166.127036px, 251.680044px); 79 | } 80 | 100% { 81 | transform: translate(166.127036px, 257.998211px); 82 | } 83 | } 84 | #ecfYqkDzjoQ9_to { 85 | animation: ecfYqkDzjoQ9_to__to 3000ms linear infinite normal forwards; 86 | } 87 | @keyframes ecfYqkDzjoQ9_to__to { 88 | 0% { 89 | transform: translate(153.264699px, 121.816195px); 90 | } 91 | 23.333333% { 92 | transform: translate(153.264699px, 121.816195px); 93 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 94 | } 95 | 60% { 96 | transform: translate(153.158256px, 97.390451px); 97 | } 98 | 100% { 99 | transform: translate(153.158256px, 103.708618px); 100 | } 101 | } 102 | #ecfYqkDzjoQ9 { 103 | animation: ecfYqkDzjoQ9_c_o 3000ms linear infinite normal forwards; 104 | } 105 | @keyframes ecfYqkDzjoQ9_c_o { 106 | 0% { 107 | opacity: 0; 108 | } 109 | 40% { 110 | opacity: 0; 111 | } 112 | 60% { 113 | opacity: 1; 114 | } 115 | 100% { 116 | opacity: 1; 117 | } 118 | } 119 | #ecfYqkDzjoQ11 { 120 | animation: ecfYqkDzjoQ11_c_o 3000ms linear infinite normal forwards; 121 | } 122 | @keyframes ecfYqkDzjoQ11_c_o { 123 | 0% { 124 | opacity: 0; 125 | } 126 | 76.666667% { 127 | opacity: 0; 128 | } 129 | 100% { 130 | opacity: 1; 131 | } 132 | } 133 | #ecfYqkDzjoQ12 { 134 | animation: ecfYqkDzjoQ12_c_o 3000ms linear infinite normal forwards; 135 | } 136 | @keyframes ecfYqkDzjoQ12_c_o { 137 | 0% { 138 | opacity: 0; 139 | } 140 | 83.333333% { 141 | opacity: 0; 142 | } 143 | 100% { 144 | opacity: 1; 145 | } 146 | } 147 | #ecfYqkDzjoQ13 { 148 | animation: ecfYqkDzjoQ13_c_o 3000ms linear infinite normal forwards; 149 | } 150 | @keyframes ecfYqkDzjoQ13_c_o { 151 | 0% { 152 | opacity: 0; 153 | } 154 | 73.333333% { 155 | opacity: 0; 156 | } 157 | 100% { 158 | opacity: 1; 159 | } 160 | } 161 | #ecfYqkDzjoQ14 { 162 | animation: ecfYqkDzjoQ14_c_o 3000ms linear infinite normal forwards; 163 | } 164 | @keyframes ecfYqkDzjoQ14_c_o { 165 | 0% { 166 | opacity: 0; 167 | } 168 | 80% { 169 | opacity: 0; 170 | } 171 | 100% { 172 | opacity: 1; 173 | } 174 | } 175 | #ecfYqkDzjoQ15 { 176 | animation: ecfYqkDzjoQ15_c_o 3000ms linear infinite normal forwards; 177 | } 178 | @keyframes ecfYqkDzjoQ15_c_o { 179 | 0% { 180 | opacity: 0; 181 | } 182 | 73.333333% { 183 | opacity: 0; 184 | } 185 | 100% { 186 | opacity: 1; 187 | } 188 | } 189 | #ecfYqkDzjoQ16 { 190 | animation: ecfYqkDzjoQ16_c_o 3000ms linear infinite normal forwards; 191 | } 192 | @keyframes ecfYqkDzjoQ16_c_o { 193 | 0% { 194 | opacity: 0; 195 | } 196 | 80% { 197 | opacity: 0; 198 | } 199 | 100% { 200 | opacity: 1; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/app/components/Education.js: -------------------------------------------------------------------------------- 1 | import "./education.css" 2 | 3 | export default function Education() { 4 | return ( 5 |
6 | 12 | 18 | 19 | 28 | 37 | 46 | 55 | 56 | 63 | 64 | 65 | 71 | 72 | 73 | 79 | 80 | 81 | 87 | 88 | 89 | 90 | 91 | 97 | 98 | 99 | 108 | 117 | 123 | 124 | 130 | 131 | 140 | 146 | 147 | 156 | 165 | 174 | 183 | 192 | 201 | 210 | 219 | 220 | 221 | 227 | 228 | 234 | 235 |
236 |

237 | Education 238 |

239 |
240 |
241 | ) 242 | } 243 | -------------------------------------------------------------------------------- /src/app/components/work-experience.css: -------------------------------------------------------------------------------- 1 | #e68ZndEqcxF2_ts { 2 | animation: e68ZndEqcxF2_ts__ts 2000ms linear infinite normal forwards; 3 | } 4 | @keyframes e68ZndEqcxF2_ts__ts { 5 | 0% { 6 | transform: translate(159.889855px, 223.200948px) scale(0, 0); 7 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 8 | } 9 | 40% { 10 | transform: translate(159.889855px, 223.200948px) scale(1, 1); 11 | animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 12 | } 13 | 100% { 14 | transform: translate(159.889855px, 223.200948px) scale(1, 1); 15 | } 16 | } 17 | #e68ZndEqcxF23_ts { 18 | animation: e68ZndEqcxF23_ts__ts 2000ms linear infinite normal forwards; 19 | } 20 | @keyframes e68ZndEqcxF23_ts__ts { 21 | 0% { 22 | transform: translate(310.593054px, 223.200948px) scale(0, 0); 23 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 24 | } 25 | 45% { 26 | transform: translate(310.593054px, 223.200948px) scale(1, 1); 27 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 28 | } 29 | 100% { 30 | transform: translate(310.593054px, 223.200948px) scale(1, 1); 31 | } 32 | } 33 | #e68ZndEqcxF44_ts { 34 | animation: e68ZndEqcxF44_ts__ts 2000ms linear infinite normal forwards; 35 | } 36 | @keyframes e68ZndEqcxF44_ts__ts { 37 | 0% { 38 | transform: translate(311.400408px, 348.20992px) scale(0, 0); 39 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 40 | } 41 | 55% { 42 | transform: translate(311.400408px, 348.20992px) scale(1, 1); 43 | } 44 | 100% { 45 | transform: translate(311.400408px, 348.20992px) scale(1, 1); 46 | } 47 | } 48 | #e68ZndEqcxF65_ts { 49 | animation: e68ZndEqcxF65_ts__ts 2000ms linear infinite normal forwards; 50 | } 51 | @keyframes e68ZndEqcxF65_ts__ts { 52 | 0% { 53 | transform: translate(160.333152px, 347.410049px) scale(0, 0); 54 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 55 | } 56 | 50% { 57 | transform: translate(160.333152px, 347.410049px) scale(1, 1); 58 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 59 | } 60 | 100% { 61 | transform: translate(160.333152px, 347.410049px) scale(1, 1); 62 | } 63 | } 64 | #e68ZndEqcxF86 { 65 | animation: e68ZndEqcxF86_c_o 2000ms linear infinite normal forwards; 66 | } 67 | @keyframes e68ZndEqcxF86_c_o { 68 | 0% { 69 | opacity: 0; 70 | } 71 | 25% { 72 | opacity: 1; 73 | } 74 | 100% { 75 | opacity: 1; 76 | } 77 | } 78 | #e68ZndEqcxF87_tr { 79 | animation: e68ZndEqcxF87_tr__tr 2000ms linear infinite normal forwards; 80 | } 81 | @keyframes e68ZndEqcxF87_tr__tr { 82 | 0% { 83 | transform: translate(341.648742px, 398.036917px) rotate(360deg); 84 | } 85 | 100% { 86 | transform: translate(341.648742px, 398.036917px) rotate(0deg); 87 | } 88 | } 89 | #e68ZndEqcxF88_tr { 90 | animation: e68ZndEqcxF88_tr__tr 2000ms linear infinite normal forwards; 91 | } 92 | @keyframes e68ZndEqcxF88_tr__tr { 93 | 0% { 94 | transform: translate(87.145649px, 222.715121px) rotate(0deg); 95 | } 96 | 60% { 97 | transform: translate(87.145649px, 222.715121px) rotate(360deg); 98 | } 99 | 100% { 100 | transform: translate(87.145649px, 222.715121px) rotate(360deg); 101 | } 102 | } 103 | #e68ZndEqcxF88 { 104 | animation: e68ZndEqcxF88_c_o 2000ms linear infinite normal forwards; 105 | } 106 | @keyframes e68ZndEqcxF88_c_o { 107 | 0% { 108 | opacity: 1; 109 | } 110 | 40% { 111 | opacity: 0.44; 112 | } 113 | 100% { 114 | opacity: 1; 115 | } 116 | } 117 | #e68ZndEqcxF89 { 118 | animation: e68ZndEqcxF89_c_o 2000ms linear infinite normal forwards; 119 | } 120 | @keyframes e68ZndEqcxF89_c_o { 121 | 0% { 122 | opacity: 1; 123 | } 124 | 65% { 125 | opacity: 0.22; 126 | } 127 | 99% { 128 | opacity: 1; 129 | } 130 | 100% { 131 | opacity: 1; 132 | } 133 | } 134 | #e68ZndEqcxF90 { 135 | animation: e68ZndEqcxF90__m 2000ms linear infinite normal forwards; 136 | } 137 | @keyframes e68ZndEqcxF90__m { 138 | 0% { 139 | d: path( 140 | "M35.47,10.52L39.823982,26.158298L56.297299,19.433374L45.248827,32.210729L61.44,39.45997L43.312299,39.750623L47.025048,55.52L35.47,43.107387L23.914952,55.52L27.627701,39.750623L9.5,39.45997L25.691173,32.210729L14.642701,19.433374L31.116018,26.158298L35.47,10.52" 141 | ); 142 | } 143 | 60% { 144 | d: path( 145 | "M39.5,10.52L44.529629,28.583972L63.559259,20.815938L50.796296,35.575202L69.5,43.948881L48.559259,44.284618L52.84815,62.5L39.5,48.162053L26.15185,62.5L30.440741,44.284618L9.5,43.948881L28.203704,35.575202L15.440741,20.815938L34.470371,28.583972L39.5,10.52" 146 | ); 147 | } 148 | 100% { 149 | d: path( 150 | "M35.47,10.52L39.823982,26.158298L56.297299,19.433374L45.248827,32.210729L61.44,39.45997L43.312299,39.750623L47.025048,55.52L35.47,43.107387L23.914952,55.52L27.627701,39.750623L9.5,39.45997L25.691173,32.210729L14.642701,19.433374L31.116018,26.158298L35.47,10.52" 151 | ); 152 | } 153 | } 154 | #e68ZndEqcxF90_tr { 155 | animation: e68ZndEqcxF90_tr__tr 2000ms linear infinite normal forwards; 156 | } 157 | @keyframes e68ZndEqcxF90_tr__tr { 158 | 0% { 159 | transform: translate(45.433396px, 314.439505px) rotate(0deg); 160 | } 161 | 100% { 162 | transform: translate(45.433396px, 314.439505px) rotate(-360deg); 163 | } 164 | } 165 | #e68ZndEqcxF91_tr { 166 | animation: e68ZndEqcxF91_tr__tr 2000ms linear infinite normal forwards; 167 | } 168 | @keyframes e68ZndEqcxF91_tr__tr { 169 | 0% { 170 | transform: translate(402.534766px, 222.715121px) rotate(-8.485073deg); 171 | } 172 | 100% { 173 | transform: translate(402.534766px, 222.715121px) rotate(351.514927deg); 174 | } 175 | } 176 | #e68ZndEqcxF92 { 177 | animation: e68ZndEqcxF92__m 2000ms linear infinite normal forwards; 178 | } 179 | @keyframes e68ZndEqcxF92__m { 180 | 0% { 181 | d: path( 182 | "M38.5,43.5C32.684127,48.122222,30.811111,51.868254,28.5,63.5C26.188889,51.868254,24.315873,48.122222,18.5,43.5C24.315873,38.877778,26.188889,35.131746,28.5,23.5C30.811111,35.131746,32.684127,38.877778,38.5,43.5Z" 183 | ); 184 | } 185 | 23% { 186 | d: path( 187 | "M48.5,53.5C39.776191,60.433333,36.966667,66.052381,33.5,83.5C30.033333,66.052381,27.22381,60.433333,18.5,53.5C27.22381,46.566667,30.033333,40.947619,33.5,23.5C36.966667,40.947619,39.776191,46.566667,48.5,53.5Z" 188 | ); 189 | } 190 | 100% { 191 | d: path( 192 | "M38.5,43.5C32.684127,48.122222,30.811111,51.868254,28.5,63.5C26.188889,51.868254,24.315873,48.122222,18.5,43.5C24.315873,38.877778,26.188889,35.131746,28.5,23.5C30.811111,35.131746,32.684127,38.877778,38.5,43.5Z" 193 | ); 194 | } 195 | } 196 | #e68ZndEqcxF93 { 197 | animation: e68ZndEqcxF93__m 2000ms linear infinite normal forwards; 198 | } 199 | @keyframes e68ZndEqcxF93__m { 200 | 0% { 201 | d: path( 202 | "M38.5,43.5C32.684127,48.122222,30.811111,51.868254,28.5,63.5C26.188889,51.868254,24.315873,48.122222,18.5,43.5C24.315873,38.877778,26.188889,35.131746,28.5,23.5C30.811111,35.131746,32.684127,38.877778,38.5,43.5Z" 203 | ); 204 | } 205 | 75% { 206 | d: path( 207 | "M48.5,53.5C39.776191,60.433333,36.966667,66.052381,33.5,83.5C30.033333,66.052381,27.22381,60.433333,18.5,53.5C27.22381,46.566667,30.033333,40.947619,33.5,23.5C36.966667,40.947619,39.776191,46.566667,48.5,53.5Z" 208 | ); 209 | } 210 | 100% { 211 | d: path( 212 | "M38.5,43.5C32.684127,48.122222,30.811111,51.868254,28.5,63.5C26.188889,51.868254,24.315873,48.122222,18.5,43.5C24.315873,38.877778,26.188889,35.131746,28.5,23.5C30.811111,35.131746,32.684127,38.877778,38.5,43.5Z" 213 | ); 214 | } 215 | } 216 | #e68ZndEqcxF94 { 217 | animation: e68ZndEqcxF94_c_o 2000ms linear infinite normal forwards; 218 | } 219 | @keyframes e68ZndEqcxF94_c_o { 220 | 0% { 221 | opacity: 1; 222 | } 223 | 65% { 224 | opacity: 0.42; 225 | } 226 | 100% { 227 | opacity: 1; 228 | } 229 | } 230 | #e68ZndEqcxF95 { 231 | animation: e68ZndEqcxF95_c_o 2000ms linear infinite normal forwards; 232 | } 233 | @keyframes e68ZndEqcxF95_c_o { 234 | 0% { 235 | opacity: 1; 236 | } 237 | 35% { 238 | opacity: 0.41; 239 | } 240 | 99% { 241 | opacity: 1; 242 | } 243 | 100% { 244 | opacity: 1; 245 | } 246 | } 247 | #e68ZndEqcxF96 { 248 | animation: e68ZndEqcxF96__m 2000ms linear infinite normal forwards; 249 | } 250 | @keyframes e68ZndEqcxF96__m { 251 | 0% { 252 | d: path( 253 | "M26,14L28.869231,22.069231L36.607692,18.392308L32.930769,26.130769L41,29L32.930769,31.869231L36.607692,39.607692L28.869231,35.930769L26,44L23.130769,35.930769L15.392308,39.607692L19.069231,31.869231L11,29L19.069231,26.130769L15.392308,18.392308L23.130769,22.069231L26,14" 254 | ); 255 | } 256 | 35% { 257 | d: path( 258 | "M28.5,14L31.847436,23.414103L40.875641,19.124359L36.585897,28.152564L46,31.5L36.585897,34.847436L40.875641,43.875641L31.847436,39.585897L28.5,49L25.152564,39.585897L16.124359,43.875641L20.414103,34.847436L11,31.5L20.414103,28.152564L16.124359,19.124359L25.152564,23.414103L28.5,14" 259 | ); 260 | } 261 | 100% { 262 | d: path( 263 | "M26,14L28.869231,22.069231L36.607692,18.392308L32.930769,26.130769L41,29L32.930769,31.869231L36.607692,39.607692L28.869231,35.930769L26,44L23.130769,35.930769L15.392308,39.607692L19.069231,31.869231L11,29L19.069231,26.130769L15.392308,18.392308L23.130769,22.069231L26,14" 264 | ); 265 | } 266 | } 267 | #e68ZndEqcxF97 { 268 | animation: e68ZndEqcxF97__m 2000ms linear infinite normal forwards; 269 | } 270 | @keyframes e68ZndEqcxF97__m { 271 | 0% { 272 | d: path( 273 | "M26,14L28.869231,22.069231L36.607692,18.392308L32.930769,26.130769L41,29L32.930769,31.869231L36.607692,39.607692L28.869231,35.930769L26,44L23.130769,35.930769L15.392308,39.607692L19.069231,31.869231L11,29L19.069231,26.130769L15.392308,18.392308L23.130769,22.069231L26,14" 274 | ); 275 | } 276 | 35% { 277 | d: path( 278 | "M28.5,14L31.847436,23.414103L40.875641,19.124359L36.585897,28.152564L46,31.5L36.585897,34.847436L40.875641,43.875641L31.847436,39.585897L28.5,49L25.152564,39.585897L16.124359,43.875641L20.414103,34.847436L11,31.5L20.414103,28.152564L16.124359,19.124359L25.152564,23.414103L28.5,14" 279 | ); 280 | } 281 | 100% { 282 | d: path( 283 | "M26,14L28.869231,22.069231L36.607692,18.392308L32.930769,26.130769L41,29L32.930769,31.869231L36.607692,39.607692L28.869231,35.930769L26,44L23.130769,35.930769L15.392308,39.607692L19.069231,31.869231L11,29L19.069231,26.130769L15.392308,18.392308L23.130769,22.069231L26,14" 284 | ); 285 | } 286 | } 287 | #e68ZndEqcxF98_tr { 288 | animation: e68ZndEqcxF98_tr__tr 2000ms linear infinite normal forwards; 289 | } 290 | @keyframes e68ZndEqcxF98_tr__tr { 291 | 0% { 292 | transform: translate(109.186295px, 93.628666px) rotate(0deg); 293 | } 294 | 100% { 295 | transform: translate(109.186295px, 93.628666px) rotate(360deg); 296 | } 297 | } 298 | #e68ZndEqcxF99 { 299 | animation: e68ZndEqcxF99__rd 2000ms linear infinite normal forwards; 300 | } 301 | @keyframes e68ZndEqcxF99__rd { 302 | 0% { 303 | r: 5px; 304 | } 305 | 40% { 306 | r: 7.5px; 307 | } 308 | 100% { 309 | r: 5px; 310 | } 311 | } 312 | #e68ZndEqcxF104 { 313 | animation: e68ZndEqcxF104__rd 2000ms linear infinite normal forwards; 314 | } 315 | @keyframes e68ZndEqcxF104__rd { 316 | 0% { 317 | r: 5px; 318 | } 319 | 65% { 320 | r: 7.5px; 321 | } 322 | 100% { 323 | r: 5px; 324 | } 325 | } 326 | #e68ZndEqcxF106 { 327 | animation: e68ZndEqcxF106__rd 2000ms linear infinite normal forwards; 328 | } 329 | @keyframes e68ZndEqcxF106__rd { 330 | 0% { 331 | r: 7.5px; 332 | } 333 | 84% { 334 | r: 10px; 335 | } 336 | 100% { 337 | r: 7.5px; 338 | } 339 | } 340 | -------------------------------------------------------------------------------- /src/app/components/Blog.js: -------------------------------------------------------------------------------- 1 | import "./blog.css" 2 | 3 | export default function Blog() { 4 | return ( 5 |
6 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 44 | 45 | 46 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 62 | 66 | 67 | 68 | 69 | 70 | 74 | 75 | 76 | 85 | 94 | 103 | 104 | 105 | 110 | 111 | 112 | 116 | 117 | 118 | 119 | 120 | 130 | 131 | 132 | 136 | 137 | 138 | 143 | 144 | 145 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 172 | 173 | 174 | 175 | 176 | 177 | 186 | 187 | 188 | 192 | 193 | 194 | 195 | 196 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 232 | 233 | 234 | 235 | 236 | 237 | 246 | 255 | 264 | 273 | 282 | 291 | 300 | 309 | 310 | 311 | 322 | 329 | 336 | 337 | 343 | 349 | 358 | 367 | 374 | 375 | 376 |
377 |

378 | Blog 379 |

380 |
381 |
382 | ) 383 | } 384 | -------------------------------------------------------------------------------- /src/app/components/Projects.js: -------------------------------------------------------------------------------- 1 | import "./projects.css" 2 | 3 | export default function Projects() { 4 | return ( 5 |
6 | 12 | 13 | 14 | 15 | 22 | 23 | 24 | 25 | 34 | 40 | 47 | 54 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | 94 | 101 | 108 | 112 | 113 | 118 | 122 | 126 | 127 | 134 | 135 | 139 | 140 | 141 | 142 | 146 | 147 | 148 | 152 | 153 | 154 | 155 | 156 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 171 | 172 | 173 | 177 | 178 | 179 | 180 | 181 | 185 | 186 | 187 | 191 | 192 | 193 | 197 | 198 | 199 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 214 | 215 | 216 | 217 | 218 | 219 | 223 | 224 | 225 | 226 | 236 | 246 | 256 | 266 | 276 | 284 | 292 | 293 | 294 | 295 |
296 |

297 | Projects 298 |

299 |
300 |
301 | ) 302 | } 303 | -------------------------------------------------------------------------------- /src/app/components/WorkExperience.js: -------------------------------------------------------------------------------- 1 | import "./work-experience.css" 2 | 3 | export default function WorkExperience() { 4 | return ( 5 |
6 | 12 | 16 | 17 | 26 | 35 | 44 | 53 | 62 | 71 | 80 | 89 | 98 | 107 | 116 | 125 | 134 | 143 | 152 | 161 | 170 | 179 | 188 | 197 | 198 | 199 | 203 | 204 | 213 | 222 | 231 | 240 | 249 | 258 | 267 | 276 | 285 | 294 | 303 | 312 | 321 | 330 | 339 | 348 | 357 | 366 | 375 | 384 | 385 | 386 | 390 | 391 | 400 | 409 | 418 | 427 | 436 | 445 | 454 | 463 | 472 | 481 | 490 | 499 | 508 | 517 | 526 | 535 | 544 | 553 | 562 | 571 | 572 | 573 | 577 | 578 | 587 | 596 | 605 | 614 | 623 | 632 | 641 | 650 | 659 | 668 | 677 | 686 | 695 | 704 | 713 | 722 | 731 | 740 | 749 | 758 | 759 | 760 | 765 | 769 | 775 | 776 | 780 | 787 | 788 | 795 | 799 | 806 | 807 | 811 | 817 | 818 | 825 | 832 | 839 | 846 | 853 | 860 | 864 | 870 | 871 | 878 | 884 | 890 | 896 | 902 | 909 | 915 | 922 | 928 | 929 | 930 | 931 |
932 |

933 | Work Experience 934 |

935 |
936 |
937 | ) 938 | } 939 | --------------------------------------------------------------------------------