├── .babelrc
├── .eslintrc.json
├── .gitignore
├── .stylelintrc.json
├── LICENSE
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
└── _redirects
├── src
├── App.jsx
├── ThemeContext.jsx
├── assets
│ ├── carousels
│ │ ├── car rental screenshot 1.png
│ │ ├── car rental screenshot 2.png
│ │ ├── car rental screenshot 3.png
│ │ ├── guess the word screenshot 1.png
│ │ ├── guess the word screenshot 2.png
│ │ ├── guess the word screenshot 3.png
│ │ ├── metrics webapp screenshot 1.png
│ │ ├── metrics webapp screenshot 2.png
│ │ ├── recipe app screenshot 3.png
│ │ ├── recipe app screenshot 4.png
│ │ ├── recipe app screenshot 6.png
│ │ ├── space travelers screenshot 1.png
│ │ ├── space travelers screenshot 2.png
│ │ ├── space travelers screenshot 3.png
│ │ ├── tic tac toe screenshot 1.png
│ │ ├── tic tac toe screenshot 2.png
│ │ ├── tic tac toe screenshot 3.png
│ │ ├── track budget screenshot 1.png
│ │ ├── track budget screenshot 2.png
│ │ ├── track budget screenshot 5.png
│ │ ├── tvshow screenshot 1.png
│ │ ├── tvshow screenshot 2.png
│ │ └── tvshow screenshot 3.png
│ ├── contact.svg
│ ├── dark.png
│ ├── index.js
│ ├── light.png
│ ├── logo.png
│ ├── portfolio1.png
│ ├── portfolio2.png
│ ├── projects
│ │ ├── carrental.png
│ │ ├── guesstheword.png
│ │ ├── mathmagician.png
│ │ ├── metricswebapp.png
│ │ ├── recipeapp.png
│ │ ├── spacetravelers.png
│ │ ├── tictactoe.png
│ │ ├── trackbudget.png
│ │ └── tvshow.png
│ ├── services
│ │ ├── fullstack.gif
│ │ ├── react.gif
│ │ └── responsive.gif
│ └── socials
│ │ ├── facebook (1).png
│ │ ├── facebook.png
│ │ ├── github (1).png
│ │ ├── github.png
│ │ ├── instagram (1).png
│ │ ├── instagram.png
│ │ ├── linkedin (1).png
│ │ ├── linkedin.png
│ │ ├── twitter (1).png
│ │ └── twitter.png
├── components
│ ├── About.jsx
│ ├── Carousel.jsx
│ ├── Contact.jsx
│ ├── Experience.jsx
│ ├── Footer.jsx
│ ├── Home.jsx
│ ├── Loader.jsx
│ ├── Navbar.jsx
│ ├── Popup.jsx
│ ├── Service.jsx
│ ├── Stars.jsx
│ ├── TechStack.jsx
│ ├── Testimonial.jsx
│ ├── Work.jsx
│ └── styles
│ │ ├── about.module.css
│ │ ├── carousel.module.css
│ │ ├── contact.module.css
│ │ ├── footer.module.css
│ │ ├── home.module.css
│ │ ├── navbar.module.css
│ │ ├── popup.module.css
│ │ ├── service.module.css
│ │ ├── techstack.module.css
│ │ ├── testimonial.module.css
│ │ └── work.module.css
├── constants
│ └── index.js
├── hoc
│ ├── SectionWrapper.jsx
│ └── index.js
├── index.css
├── main.jsx
└── utils
│ └── motion.js
├── tailwind.config.js
└── vite.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-react"
4 | ],
5 | "plugins": ["@babel/plugin-syntax-jsx"]
6 | }
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "jest": true
6 | },
7 | "parser": "@babel/eslint-parser",
8 | "parserOptions": {
9 | "ecmaFeatures": {
10 | "jsx": true
11 | },
12 | "ecmaVersion": 2018,
13 | "sourceType": "module"
14 | },
15 | "extends": ["airbnb", "plugin:react/recommended", "plugin:react-hooks/recommended"],
16 | "plugins": ["react"],
17 | "rules": {
18 | "react/jsx-props-no-spreading": "off",
19 | "react/no-unknown-property": "off",
20 | "no-underscore-dangle": ["error", { "allow": ["_getIconUrl"] }],
21 | "react/jsx-filename-extension": ["warn", { "extensions": [".js", ".jsx"] }],
22 | "react/react-in-jsx-scope": "off",
23 | "import/no-unresolved": "off",
24 | "react/no-array-index-key": "off",
25 | "no-shadow": "off",
26 | "linebreak-style": "off",
27 | "max-len": ["error", {
28 | "code": 710,
29 | "ignoreComments": true,
30 | "ignoreUrls": true
31 | }]
32 | },
33 | "ignorePatterns": [
34 | "dist/",
35 | "build/"
36 | ]
37 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/.stylelintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["stylelint-config-standard"],
3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"],
4 | "rules": {
5 | "at-rule-no-unknown": [
6 | true,
7 | {
8 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"]
9 | }
10 | ],
11 | "scss/at-rule-no-unknown": [
12 | true,
13 | {
14 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"]
15 | }
16 | ],
17 | "csstree/validator": null,
18 | "function-linear-gradient-no-nonstandard-direction": null
19 | },
20 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"]
21 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2023] [KaungMyatKyaw]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Portfolio
6 |
7 |
8 |
9 |
10 |
11 | # 📗 Table of Contents
12 |
13 | - [📖 About the Project](#about-project)
14 | - [🛠 Built With](#built-with)
15 | - [Tech Stack](#tech-stack)
16 | - [Key Features](#key-features)
17 | - [🚀 Live Demo](#live-demo)
18 | - [👥 Authors](#authors)
19 | - [🔭 Future Features](#future-features)
20 | - [🤝 Contributing](#contributing)
21 | - [⭐️ Show your support](#support)
22 | - [📝 License](#license)
23 |
24 |
25 |
26 | # 📖 [Portfolio]
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Portfolio
34 |
35 |
36 |
37 | > Welcome to my dynamic portfolio, where the fusion of ReactJS, ThreeJS, and TailwindCSS, embellished with captivating animations from Framer Motion, creates an immersive experience. With a mobile-first approach, this responsive masterpiece ensures seamless viewing across devices. Hosted on the powerful platforms of Vercel and Netlify, my portfolio elegantly presents a showcase of creative ventures and professional accomplishments, inviting you to explore and be inspired.
38 |
39 | ## 🛠 Built With
40 |
41 | ### Tech Stack
42 |
43 |
44 | Client
45 |
50 |
51 |
52 |
53 |
54 |
55 | ### Key Features
56 |
57 | - **[3D_star_canvas]**
58 | - **[Light/Dark_theme]**
59 |
60 | (back to top )
61 |
62 |
63 |
64 | ## 🚀 Live Demo
65 |
66 | - [Live Demo Link](https://rhbarry.me/)
67 |
68 | (back to top )
69 |
70 |
71 |
72 | ## 👥 Authors
73 |
74 | 👤 **Antonio Fernandez**
75 |
76 | - GitHub: [GitHub](https://github.com/smart-dev613)
77 | - Twitter: [Twitter](https://twitter.com/Antonio-Fernandez)
78 | - LinkedIn: [LinkedIn](https://www.linkedin.com/in/antonio-fernandez-364928372)
79 |
80 | (back to top )
81 |
82 |
83 |
84 | ## 🔭 Future Features
85 |
86 | - **[Experience_Section]**
87 | - **[Footer_motion]**
88 |
89 | (back to top )
90 |
91 |
92 |
93 | ## 🤝 Contributing
94 |
95 | Contributions, issues, and feature requests are welcome!
96 |
97 | Feel free to check the [issues page](../../issues/).
98 |
99 | (back to top )
100 |
101 |
102 |
103 | ## ⭐️ Show your support
104 |
105 | Give a ⭐️ if you like this project!
106 |
107 | (back to top )
108 |
109 |
110 |
111 | ## 📝 License
112 |
113 | This project is [MIT](./LICENSE) licensed.
114 |
115 | (back to top )
116 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Antonio Fernandez
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "portfolio",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "homepage": "https://rhaegar121.github.io/Portfolio/",
7 | "scripts": {
8 | "dev": "vite",
9 | "build": "vite build",
10 | "preview": "vite preview",
11 | "predeploy": "npm run build",
12 | "deploy": "gh-pages -d dist"
13 | },
14 | "dependencies": {
15 | "@emailjs/browser": "^3.10.0",
16 | "@react-three/drei": "^9.61.3",
17 | "@react-three/fiber": "^8.12.0",
18 | "framer-motion": "^10.10.0",
19 | "leaflet": "^1.9.4",
20 | "maath": "^0.5.3",
21 | "postcss-custom-properties": "^13.2.1",
22 | "prop-types": "^15.8.1",
23 | "react": "^18.2.0",
24 | "react-dom": "^18.2.0",
25 | "react-icons": "^4.10.1",
26 | "react-leaflet": "^4.2.1",
27 | "react-parallax-tilt": "^1.7.121",
28 | "react-responsive": "^9.0.2",
29 | "react-router-dom": "^6.10.0",
30 | "react-slick": "^0.29.0",
31 | "react-tilt": "^1.0.2",
32 | "react-vertical-timeline-component": "^3.6.0",
33 | "slick-carousel": "^1.8.1"
34 | },
35 | "devDependencies": {
36 | "@babel/core": "^7.22.8",
37 | "@babel/eslint-parser": "^7.22.7",
38 | "@babel/plugin-syntax-jsx": "^7.22.5",
39 | "@babel/preset-react": "^7.22.5",
40 | "@testing-library/jest-dom": "^6.1.2",
41 | "@testing-library/react": "^14.0.0",
42 | "@types/react": "^18.0.28",
43 | "@types/react-dom": "^18.0.11",
44 | "@vitejs/plugin-react": "^3.1.0",
45 | "autoprefixer": "^10.4.14",
46 | "eslint": "^7.32.0",
47 | "eslint-config-airbnb": "^18.2.1",
48 | "eslint-plugin-import": "^2.27.5",
49 | "eslint-plugin-jsx-a11y": "^6.7.1",
50 | "eslint-plugin-react": "^7.32.2",
51 | "eslint-plugin-react-hooks": "^4.6.0",
52 | "gh-pages": "^5.0.0",
53 | "jest": "^29.6.4",
54 | "postcss": "^8.4.21",
55 | "stylelint": "^13.13.1",
56 | "stylelint-config-standard": "^21.0.0",
57 | "stylelint-csstree-validator": "^1.9.0",
58 | "stylelint-scss": "^3.21.0",
59 | "tailwindcss": "^3.3.1",
60 | "vite": "^4.4.2"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { ThemeProvider } from './ThemeContext';
2 | import Navbar from './components/Navbar';
3 | import Home from './components/Home';
4 | import About from './components/About';
5 | import Service from './components/Service';
6 | import TechStack from './components/TechStack';
7 | import Work from './components/Work';
8 | import Testimonial from './components/Testimonial';
9 | import Contact from './components/Contact';
10 | import Footer from './components/Footer';
11 | import StarsCanvas from './components/Stars';
12 |
13 | function App() {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 |
38 | export default App;
39 |
--------------------------------------------------------------------------------
/src/ThemeContext.jsx:
--------------------------------------------------------------------------------
1 | import React, { createContext, useContext, useState } from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | const ThemeContext = createContext();
5 |
6 | export const ThemeProvider = ({ children }) => {
7 | const [theme, setTheme] = useState('dark');
8 |
9 | const toggleTheme = () => {
10 | setTheme((prevTheme) => (prevTheme === 'dark' ? 'light' : 'dark'));
11 | };
12 |
13 | return (
14 |
15 | {children}
16 |
17 | );
18 | };
19 |
20 | export const useTheme = () => useContext(ThemeContext);
21 |
22 | ThemeProvider.propTypes = {
23 | children: PropTypes.node.isRequired,
24 | };
25 |
--------------------------------------------------------------------------------
/src/assets/carousels/car rental screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/car rental screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/car rental screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/car rental screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/car rental screenshot 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/car rental screenshot 3.png
--------------------------------------------------------------------------------
/src/assets/carousels/guess the word screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/guess the word screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/guess the word screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/guess the word screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/guess the word screenshot 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/guess the word screenshot 3.png
--------------------------------------------------------------------------------
/src/assets/carousels/metrics webapp screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/metrics webapp screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/metrics webapp screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/metrics webapp screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/recipe app screenshot 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/recipe app screenshot 3.png
--------------------------------------------------------------------------------
/src/assets/carousels/recipe app screenshot 4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/recipe app screenshot 4.png
--------------------------------------------------------------------------------
/src/assets/carousels/recipe app screenshot 6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/recipe app screenshot 6.png
--------------------------------------------------------------------------------
/src/assets/carousels/space travelers screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/space travelers screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/space travelers screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/space travelers screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/space travelers screenshot 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/space travelers screenshot 3.png
--------------------------------------------------------------------------------
/src/assets/carousels/tic tac toe screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/tic tac toe screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/tic tac toe screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/tic tac toe screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/tic tac toe screenshot 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/tic tac toe screenshot 3.png
--------------------------------------------------------------------------------
/src/assets/carousels/track budget screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/track budget screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/track budget screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/track budget screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/track budget screenshot 5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/track budget screenshot 5.png
--------------------------------------------------------------------------------
/src/assets/carousels/tvshow screenshot 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/tvshow screenshot 1.png
--------------------------------------------------------------------------------
/src/assets/carousels/tvshow screenshot 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/tvshow screenshot 2.png
--------------------------------------------------------------------------------
/src/assets/carousels/tvshow screenshot 3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/carousels/tvshow screenshot 3.png
--------------------------------------------------------------------------------
/src/assets/contact.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/dark.png
--------------------------------------------------------------------------------
/src/assets/index.js:
--------------------------------------------------------------------------------
1 | import logo from './logo.png';
2 | import light from './light.png';
3 | import dark from './dark.png';
4 |
5 | // socials
6 | import facebook from './socials/facebook.png';
7 | import facebook1 from './socials/facebook (1).png';
8 | import github from './socials/github.png';
9 | import github1 from './socials/github (1).png';
10 | import linkedin from './socials/linkedin.png';
11 | import linkedin1 from './socials/linkedin (1).png';
12 | import twitter from './socials/twitter.png';
13 | import twitter1 from './socials/twitter (1).png';
14 | import instagram from './socials/instagram.png';
15 | import instagram1 from './socials/instagram (1).png';
16 |
17 | // projects
18 | import tvshowbox from './projects/tvshow.png';
19 | import guesstheword from './projects/guesstheword.png';
20 | import tictactoe from './projects/tictactoe.png';
21 | import mathmagician from './projects/mathmagician.png';
22 | import metricwebapp from './projects/metricswebapp.png';
23 | import spacetravelers from './projects/spacetravelers.png';
24 | import recipeapp from './projects/recipeapp.png';
25 | import trackbudget from './projects/trackbudget.png';
26 | import carrental from './projects/carrental.png';
27 |
28 | // carousel img
29 | import guesstheword1 from './carousels/guess the word screenshot 1.png';
30 | import guesstheword2 from './carousels/guess the word screenshot 2.png';
31 | import guesstheword3 from './carousels/guess the word screenshot 3.png';
32 | import spacetravelers1 from './carousels/space travelers screenshot 1.png';
33 | import spacetravelers2 from './carousels/space travelers screenshot 2.png';
34 | import spacetravelers3 from './carousels/space travelers screenshot 3.png';
35 | import tictactoe1 from './carousels/tic tac toe screenshot 1.png';
36 | import tictactoe2 from './carousels/tic tac toe screenshot 2.png';
37 | import tictactoe3 from './carousels/tic tac toe screenshot 3.png';
38 | import tvshow1 from './carousels/tvshow screenshot 1.png';
39 | import tvshow2 from './carousels/tvshow screenshot 2.png';
40 | import tvshow3 from './carousels/tvshow screenshot 3.png';
41 | import metricswebapp1 from './carousels/metrics webapp screenshot 1.png';
42 | import metricswebapp2 from './carousels/metrics webapp screenshot 2.png';
43 | import recipeapp3 from './carousels/recipe app screenshot 3.png';
44 | import recipeapp4 from './carousels/recipe app screenshot 4.png';
45 | import recipeapp6 from './carousels/recipe app screenshot 6.png';
46 | import trackbuget1 from './carousels/track budget screenshot 1.png';
47 | import trackbuget2 from './carousels/track budget screenshot 2.png';
48 | import trackbuget5 from './carousels/track budget screenshot 5.png';
49 | import carrental1 from './carousels/car rental screenshot 1.png';
50 | import carrental2 from './carousels/car rental screenshot 2.png';
51 | import carrental3 from './carousels/car rental screenshot 3.png';
52 |
53 | // services
54 | import responsive from './services/responsive.gif';
55 | import react from './services/react.gif';
56 | import fullstack from './services/fullstack.gif';
57 |
58 | export {
59 | logo, light, dark, facebook, instagram, github, linkedin, twitter, facebook1, instagram1, github1, twitter1, linkedin1, tvshowbox, guesstheword, tictactoe, mathmagician, metricwebapp, spacetravelers, recipeapp, trackbudget, carrental, guesstheword1, guesstheword2, guesstheword3, spacetravelers1, spacetravelers2, spacetravelers3, tictactoe1, tictactoe2, tictactoe3, tvshow1, tvshow2, tvshow3, metricswebapp1, metricswebapp2, recipeapp3, recipeapp4, recipeapp6, trackbuget1, trackbuget2, trackbuget5, carrental1, carrental2, carrental3, responsive, react, fullstack,
60 | };
61 |
--------------------------------------------------------------------------------
/src/assets/light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/light.png
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/portfolio1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/portfolio1.png
--------------------------------------------------------------------------------
/src/assets/portfolio2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/portfolio2.png
--------------------------------------------------------------------------------
/src/assets/projects/carrental.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/carrental.png
--------------------------------------------------------------------------------
/src/assets/projects/guesstheword.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/guesstheword.png
--------------------------------------------------------------------------------
/src/assets/projects/mathmagician.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/mathmagician.png
--------------------------------------------------------------------------------
/src/assets/projects/metricswebapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/metricswebapp.png
--------------------------------------------------------------------------------
/src/assets/projects/recipeapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/recipeapp.png
--------------------------------------------------------------------------------
/src/assets/projects/spacetravelers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/spacetravelers.png
--------------------------------------------------------------------------------
/src/assets/projects/tictactoe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/tictactoe.png
--------------------------------------------------------------------------------
/src/assets/projects/trackbudget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/trackbudget.png
--------------------------------------------------------------------------------
/src/assets/projects/tvshow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/projects/tvshow.png
--------------------------------------------------------------------------------
/src/assets/services/fullstack.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/services/fullstack.gif
--------------------------------------------------------------------------------
/src/assets/services/react.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/services/react.gif
--------------------------------------------------------------------------------
/src/assets/services/responsive.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/services/responsive.gif
--------------------------------------------------------------------------------
/src/assets/socials/facebook (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/facebook (1).png
--------------------------------------------------------------------------------
/src/assets/socials/facebook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/facebook.png
--------------------------------------------------------------------------------
/src/assets/socials/github (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/github (1).png
--------------------------------------------------------------------------------
/src/assets/socials/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/github.png
--------------------------------------------------------------------------------
/src/assets/socials/instagram (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/instagram (1).png
--------------------------------------------------------------------------------
/src/assets/socials/instagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/instagram.png
--------------------------------------------------------------------------------
/src/assets/socials/linkedin (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/linkedin (1).png
--------------------------------------------------------------------------------
/src/assets/socials/linkedin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/linkedin.png
--------------------------------------------------------------------------------
/src/assets/socials/twitter (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/twitter (1).png
--------------------------------------------------------------------------------
/src/assets/socials/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/assets/socials/twitter.png
--------------------------------------------------------------------------------
/src/components/About.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { motion } from 'framer-motion';
3 | import SectionWrapper from '../hoc';
4 | import style from './styles/about.module.css';
5 | import { textVariant, fadeIn } from '../utils/motion';
6 |
7 | const About = () => (
8 | <>
9 |
10 |
11 | About Me
12 |
13 |
14 |
15 | Hey there! I'm
16 | {' '}
17 |
23 | Antonio Fernandez,
24 |
25 | {' '}
26 | Senior Full-Stack Engineer with 9+ years of experience building secure, scalable systems across FinTech and E-commerce industries. Skilled in developing end-to-end platforms using React, Node.js, NestJS, PHP, Java, and .NET Core. Proven record delivering high-volume transactional systems, fraud detection engines, credit onboarding flows, and e-commerce CMS tools. Strong background in Agile delivery, platform migration, and regulatory compliance (KYC, GDPR). Comfortable collaborating with cross-border product teams using modern DevOps and CI/CD tools
27 |
28 |
29 | You can explore my work my
30 | {' '}
31 |
37 | {' '}
38 | GitHub
39 |
40 | {' '}
41 | and view my detailed experience in my
42 | {' '}
43 |
49 | {' '}
50 | resume.
51 |
52 |
53 |
54 |
55 |
56 |
57 | Education
58 |
59 |
60 |
61 | Graduated with a Bachelor of Science in computer engineering from
62 | {' '}
63 |
69 | University of Salamanca
70 |
71 | {' '}
72 | (2012-2016), holding a strong GPA of 8.4(/10).
73 |
74 |
75 | Over the past 10 years, I’ve led and delivered enterprise-grade full stack solutions across diverse domains, combining deep technical expertise with proven engineering leadership.
76 | My academic foundation and real-world impact consistently drive teams and products forward — no technical test needed.
77 |
78 |
79 |
80 | >
81 | );
82 |
83 | export default SectionWrapper(About, 'about', '');
84 |
--------------------------------------------------------------------------------
/src/components/Carousel.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Slider from 'react-slick';
4 | import 'slick-carousel/slick/slick.css';
5 | import 'slick-carousel/slick/slick-theme.css';
6 | import '../index.css';
7 |
8 | const Carousel = ({ carousel }) => {
9 | const settings = {
10 | dots: true,
11 | infinite: true,
12 | slidesToShow: 1,
13 | slidesToScroll: 1,
14 | };
15 |
16 | return (
17 |
18 | {carousel.map((img) => (
19 |
20 |
21 |
22 | ))}
23 |
24 | );
25 | };
26 |
27 | Carousel.propTypes = {
28 | carousel: PropTypes.arrayOf(PropTypes.string).isRequired,
29 | };
30 |
31 | export default Carousel;
32 |
--------------------------------------------------------------------------------
/src/components/Contact.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { motion } from 'framer-motion';
3 | import SectionWrapper from '../hoc';
4 | import { fadeIn, textVariant, slideIn } from '../utils/motion';
5 | import contact from '../assets/contact.svg';
6 | import style from './styles/contact.module.css';
7 |
8 | const Contact = () => {
9 | const [form, setForm] = useState({
10 | name: '',
11 | email: '',
12 | message: '',
13 | });
14 |
15 | const handleChange = (e) => {
16 | const { target } = e;
17 | const { name, value } = target;
18 |
19 | setForm({
20 | ...form,
21 | [name]: value,
22 | });
23 | };
24 |
25 | const handleSubmit = (event) => {
26 | event.preventDefault();
27 | const form = event.target;
28 | const isValid = form.checkValidity();
29 | if (isValid) {
30 | // Submit the form
31 | form.submit();
32 | setForm({
33 | name: '',
34 | email: '',
35 | message: '',
36 | });
37 | }
38 | };
39 |
40 | return (
41 | <>
42 |
43 | Get in Touch!
44 |
45 |
46 | I'm always excited to hear about new opportunities and collaborations. Don't hesitate to reach out and let's make something great.
47 |
48 |
98 | >
99 | );
100 | };
101 |
102 | export default SectionWrapper(Contact, 'contact', 'my-0');
103 |
--------------------------------------------------------------------------------
/src/components/Experience.jsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smart-dev613/portfolio-React-Tailwind-/f409821ae83d9ef6f94e1d36a1ee48b58804299d/src/components/Experience.jsx
--------------------------------------------------------------------------------
/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { motion } from 'framer-motion';
3 | import { BsChevronDoubleUp } from 'react-icons/bs';
4 | import { fadeIn } from '../utils/motion';
5 | import { social } from '../constants';
6 | import style from './styles/footer.module.css';
7 |
8 | const Footer = () => (
9 |
50 | );
51 |
52 | export default Footer;
53 |
--------------------------------------------------------------------------------
/src/components/Home.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { MdOutlineArrowForwardIos } from 'react-icons/md';
3 | import { motion } from 'framer-motion';
4 | import style from './styles/home.module.css';
5 | import { fadeIn, staggerContainer } from '../utils/motion';
6 |
7 | const Home = () => (
8 |
14 |
15 |
16 | Hi, I'm
17 | {' '}
18 |
19 | Antonio Fernandez
20 |
21 |
22 |
23 | Also known as
24 | {' '}
25 |
26 | Antonio
27 |
28 |
29 |
30 | I am a senior full-stack Engineer
31 |
32 |
{
36 | window.scrollTo({
37 | top: window.innerHeight,
38 | behavior: 'smooth',
39 | });
40 | }}
41 | >
42 |
43 | Check out my work
44 |
45 |
46 | Check out my work
47 |
48 |
49 |
50 |
51 |
52 | );
53 |
54 | export default Home;
55 |
--------------------------------------------------------------------------------
/src/components/Loader.jsx:
--------------------------------------------------------------------------------
1 | import { Html, useProgress } from '@react-three/drei';
2 |
3 | const Loader = () => {
4 | const { progress } = useProgress();
5 | return (
6 |
16 |
17 |
25 | {progress.toFixed(2)}
26 | %
27 |
28 |
29 | );
30 | };
31 |
32 | export default Loader;
33 |
--------------------------------------------------------------------------------
/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { motion } from 'framer-motion';
3 | import { useTheme } from '../ThemeContext';
4 | import { fadeIn, staggerContainer } from '../utils/motion';
5 | import { logo, light, dark } from '../assets';
6 | import { navLinks } from '../constants';
7 | import style from './styles/navbar.module.css';
8 |
9 | const Navbar = () => {
10 | const { theme, toggleTheme } = useTheme();
11 | const [active, setActive] = useState('');
12 | const [scrolled, setScrolled] = useState(false);
13 | const [isOpen, setOpen] = useState(false);
14 |
15 | const handleMenuClick = () => {
16 | setOpen(!isOpen);
17 | };
18 |
19 | useEffect(() => {
20 | const handleScroll = () => {
21 | const scrollTop = window.pageYOffset;
22 | if (scrollTop > 780) {
23 | setScrolled(true);
24 | } else {
25 | setScrolled(false);
26 | }
27 | };
28 |
29 | window.addEventListener('scroll', handleScroll);
30 |
31 | return () => {
32 | window.removeEventListener('scroll', handleScroll);
33 | };
34 | }, []);
35 |
36 | return (
37 |
38 |
39 | {
42 | window.scrollTo(0, 0);
43 | }}
44 | whileHover={{ scale: 1.12, backgroundColor: 'var(--dark-blue)', transition: { type: 'spring', damping: 20, stiffness: 300 } }}
45 | className={style.logo_btn}
46 | >
47 |
48 |
49 |
50 | {/* desktop navlink */}
51 |
80 |
81 | {/* hamburger menu */}
82 | {
86 | if (e.key === 'Enter') {
87 | handleMenuClick();
88 | }
89 | }}
90 | role="button"
91 | tabIndex={0}
92 | >
93 |
94 |
95 |
96 |
97 |
98 | {/* mobile menu */}
99 |
106 |
107 |
112 | {theme === 'light' ? (
113 |
114 | ) : (
115 |
116 | )}
117 |
118 |
119 | {navLinks.map((link, index) => (
120 |
124 | {
131 | setActive(link.name);
132 | handleMenuClick();
133 | }}
134 | >
135 | {link.name}
136 |
137 |
138 | ))}
139 |
140 |
141 |
142 | );
143 | };
144 |
145 | export default Navbar;
146 |
--------------------------------------------------------------------------------
/src/components/Popup.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { TfiClose } from 'react-icons/tfi';
4 | import { motion } from 'framer-motion';
5 | import { zoomIn } from '../utils/motion';
6 | import style from './styles/popup.module.css';
7 | import Carousel from './Carousel';
8 |
9 | const Popup = ({ handleClose, project }) => (
10 |
17 |
18 |
19 |
20 |
21 |
{project.name}
22 |
23 | {project.tech.map((i) => (
24 | {`#${i}`}
25 | ))}
26 |
27 |
{project.desc}
28 |
40 |
41 |
42 |
43 | );
44 |
45 | Popup.propTypes = {
46 | handleClose: PropTypes.func.isRequired,
47 | project: PropTypes.objectOf(PropTypes.string).isRequired,
48 | };
49 |
50 | export default Popup;
51 |
--------------------------------------------------------------------------------
/src/components/Service.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React from 'react';
3 | import { motion } from 'framer-motion';
4 | import { Tilt } from 'react-tilt';
5 | import { fadeIn, textVariant } from '../utils/motion';
6 | import SectionWrapper from '../hoc';
7 | import style from './styles/service.module.css';
8 | import { services } from '../constants';
9 |
10 | const Service = () => (
11 |
12 |
13 | My Services
14 |
15 |
What I can do for you -
16 |
17 | {/* Services card */}
18 | {services.map((service, index) => (
19 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
{service.title}
32 | {/*
{service.text}
*/}
33 |
34 |
35 |
36 | ))}
37 |
38 |
39 | );
40 |
41 | export default SectionWrapper(Service, 'service', 'my-0');
42 |
--------------------------------------------------------------------------------
/src/components/Stars.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | useState, useRef, useEffect, Suspense,
3 | } from 'react';
4 | import { Canvas, useFrame } from '@react-three/fiber';
5 | import { Points, PointMaterial, Preload } from '@react-three/drei';
6 | import * as random from 'maath/random/dist/maath-random.esm';
7 | import { useTheme } from '../ThemeContext';
8 | import Loader from './Loader';
9 |
10 | const Stars = (props) => {
11 | const ref = useRef();
12 | const [sphere] = useState(() => random.inSphere(new Float32Array(5200), { radius: 1.2 }));
13 | const { theme } = useTheme();
14 | const starColor = theme === 'dark' ? '#ffffff' : '#000000';
15 |
16 | useFrame((state, delta) => {
17 | ref.current.rotation.x -= delta / 10;
18 | ref.current.rotation.y -= delta / 15;
19 | });
20 |
21 | return (
22 |
23 |
24 |
31 |
32 |
33 | );
34 | };
35 |
36 | const StarsCanvas = () => {
37 | const [aspectRatio, setAspectRatio] = useState(1);
38 |
39 | useEffect(() => {
40 | const handleResize = () => {
41 | setAspectRatio(window.innerWidth / window.innerHeight);
42 | };
43 | window.addEventListener('resize', handleResize);
44 | return () => window.removeEventListener('resize', handleResize);
45 | }, []);
46 |
47 | return (
48 |
49 |
59 | }>
60 |
61 |
62 |
63 |
64 |
65 |
66 | );
67 | };
68 |
69 | export default StarsCanvas;
70 |
--------------------------------------------------------------------------------
/src/components/TechStack.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { motion } from 'framer-motion';
3 | import SectionWrapper from '../hoc';
4 | import { technologies } from '../constants';
5 | import { fadeIn, textVariant } from '../utils/motion';
6 | import style from './styles/techstack.module.css';
7 |
8 | const TechStack = () => {
9 | const [stack, setStack] = useState('languages');
10 |
11 | const handlePageChange = (stack) => {
12 | setStack(stack);
13 | };
14 |
15 | const stacks = ['all', 'languages', 'Front-End', 'Back-End', 'WordPress', 'Data & APIs', 'AI & Integrations', 'Testing & Security'];
16 |
17 | return (
18 | <>
19 | Here are a few technologies I`ve been working with recently:
20 |
21 | {stacks.map((currentStack) => (
22 | handlePageChange(currentStack)}
27 | >
28 | {currentStack}
29 |
30 | ))}
31 |
32 |
33 | {technologies.filter((technology) => technology.stack.includes(stack)).map((tech, index) => (
34 |
42 |
43 |
44 | ))}
45 |
46 | >
47 | );
48 | };
49 |
50 | export default SectionWrapper(TechStack, '', '');
51 |
--------------------------------------------------------------------------------
/src/components/Testimonial.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { motion } from 'framer-motion';
3 | import { FaLinkedinIn, FaQuoteLeft } from 'react-icons/fa';
4 | // import { BsArrowLeft, BsArrowRight } from 'react-icons/bs';
5 | import { PiArrowFatLinesLeftBold, PiArrowFatLinesRightBold } from 'react-icons/pi';
6 | import { fadeIn, textVariant, slideIn } from '../utils/motion';
7 | import SectionWrapper from '../hoc';
8 | import { testimonials } from '../constants';
9 | import style from './styles/testimonial.module.css';
10 |
11 | const Testimonial = () => {
12 | const [number, setNumber] = useState(1);
13 | const [showPerPage, setShowPerPage] = useState(1);
14 | const [desktop, setDesktop] = useState(false);
15 | const lastNumber = number * showPerPage;
16 | const firstNumber = lastNumber - showPerPage;
17 | const filterTestimonial = testimonials.slice(firstNumber, lastNumber);
18 |
19 | const prev = () => {
20 | if (desktop) {
21 | setNumber((prevNumber) => (prevNumber === 2 ? prevNumber - 1 : 1));
22 | } else {
23 | setNumber((prevNumber) => (prevNumber === 1 ? testimonials.length : prevNumber - 1));
24 | }
25 | };
26 |
27 | const next = () => {
28 | if (desktop) {
29 | setNumber((prevNumber) => (prevNumber === 1 ? prevNumber + 1 : 2));
30 | } else {
31 | setNumber((prevNumber) => (prevNumber === testimonials.length ? 1 : prevNumber + 1));
32 | }
33 | };
34 |
35 | useEffect(() => {
36 | const mediaQuery = window.matchMedia('(min-width: 1200px)');
37 |
38 | const handleMediaQueryChange = (event) => {
39 | if (event.matches) {
40 | setShowPerPage(3);
41 | setDesktop(true);
42 | } else {
43 | setShowPerPage(1);
44 | setDesktop(false);
45 | }
46 | };
47 |
48 | handleMediaQueryChange(mediaQuery);
49 |
50 | mediaQuery.addEventListener('change', handleMediaQueryChange);
51 |
52 | return () => {
53 | mediaQuery.removeEventListener('change', handleMediaQueryChange);
54 | };
55 | }, []);
56 |
57 | return (
58 |
59 |
60 | Testimonials
61 |
62 |
What my coding partners say about me -
63 |
64 | {/* Testimonials card */}
65 |
66 | {filterTestimonial.map((testimonial) => (
67 |
74 |
75 |
76 |
77 |
78 | {testimonial.text}
79 |
80 |
81 | {testimonial.name}
82 | {' '}
83 |
84 | (
85 | {testimonial.country}
86 | )
87 |
88 |
89 |
90 |
97 |
98 |
99 |
100 |
101 |
102 | ))}
103 |
104 |
105 |
110 |
111 |
112 |
117 |
118 |
119 |
120 |
121 |
122 | );
123 | };
124 |
125 | export default SectionWrapper(Testimonial, 'testimonial', 'my-0');
126 |
--------------------------------------------------------------------------------
/src/components/Work.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { motion, AnimatePresence } from 'framer-motion';
3 | import style from './styles/work.module.css';
4 | import SectionWrapper from '../hoc';
5 | import { projects } from '../constants';
6 | import { fadeIn, textVariant } from '../utils/motion';
7 | import Popup from './Popup';
8 |
9 | const Work = () => {
10 | const [isOpen, setOpen] = useState(false);
11 | const [selectedProject, setSelectedProject] = useState(null);
12 |
13 | const handlePopupClick = (project) => {
14 | setSelectedProject(project);
15 | setOpen(true);
16 | };
17 |
18 | const handlePopupClose = () => {
19 | setSelectedProject(null);
20 | setOpen(false);
21 | };
22 |
23 | return (
24 |
25 |
26 | My Recent Works
27 |
28 |
29 | {/* Projects Card */}
30 | {projects.map((project, index) => (
31 |
37 |
38 |
39 |
40 |
41 |
{project.name}
42 |
43 | {project.tech.map((i) => (
44 | {`#${i}`}
45 | ))}
46 |
47 |
48 |
handlePopupClick(project)}>
49 | Learn more
50 | Learn more
51 |
52 |
53 |
54 |
55 | ))}
56 |
57 | {/* Popup Window */}
58 |
59 | {isOpen && (
60 |
61 | )}
62 |
63 |
64 | );
65 | };
66 |
67 | export default SectionWrapper(Work, 'work', 'my-8');
68 |
--------------------------------------------------------------------------------
/src/components/styles/about.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | color: var(--white);
3 | font-size: 1.8rem;
4 | font-weight: 500;
5 | text-align: center;
6 | position: relative;
7 | padding: 8px 0;
8 | margin-bottom: 40px;
9 | }
10 |
11 | .title::after {
12 | content: "";
13 | background-color: var(--white);
14 | width: 50px;
15 | height: 2.5px;
16 | display: inline-block;
17 | position: absolute;
18 | bottom: 0;
19 | left: 50%;
20 | transform: translateX(-50%);
21 | }
22 |
23 | .para {
24 | width: 89%;
25 | margin: 20px auto;
26 | overflow: hidden;
27 | }
28 |
29 | .text {
30 | font-size: 14.5px;
31 | word-spacing: 0.13rem;
32 | text-align: left;
33 | color: var(--grey);
34 | margin-bottom: 8px;
35 | }
36 |
37 | .link {
38 | color: var(--cyan);
39 | position: relative;
40 | padding-bottom: 1.5px;
41 | }
42 |
43 | .link::after {
44 | content: "";
45 | position: absolute;
46 | width: 0;
47 | height: 1px;
48 | display: inline-block;
49 | left: 0;
50 | bottom: 0;
51 | background-color: var(--cyan);
52 | transition: 0.3s;
53 | }
54 |
55 | .link:hover::after {
56 | width: 100%;
57 | }
58 |
59 | .img_container {
60 | width: 70%;
61 | position: relative;
62 | }
63 |
64 | @keyframes pulse {
65 | 0% { box-shadow: 0 0 0 0 var(--cyan); }
66 | }
67 |
68 | .img {
69 | --s: 14px; /* size of the frame */
70 | --b: 1.4px; /* border thickness */
71 | --w: 260px; /* width of the image */
72 | --c: var(--cyan);
73 |
74 | width: 100%;
75 | aspect-ratio: 1;
76 | object-fit: cover;
77 | padding: calc(2 * var(--s));
78 |
79 | --_g: var(--c) var(--b), #0000 0 calc(100% - var(--b)), var(--c) 0;
80 |
81 | background:
82 | linear-gradient(var(--_g)) 50% / 100% var(--_i, 100%) no-repeat,
83 | linear-gradient(90deg, var(--_g)) 50%/var(--_i, 100%) 100% no-repeat;
84 | outline: calc(var(--w) / 2) solid #0009;
85 | outline-offset: calc(var(--w) / -2 - 2 * var(--s));
86 | transition: 0.4s;
87 | cursor: pointer;
88 | }
89 |
90 | .img:hover {
91 | outline: var(--b) solid var(--c);
92 | outline-offset: calc(var(--s) / -2);
93 |
94 | --_i: calc(100% - 2 * var(--s));
95 | }
96 |
97 | @media screen and (min-width: 480px) {
98 | .title {
99 | font-size: 1.9rem;
100 | }
101 |
102 | .para {
103 | font-size: 15px;
104 | }
105 |
106 | .img_container {
107 | width: 260px;
108 | }
109 | }
110 |
111 | @media screen and (min-width: 768px) {
112 | .title {
113 | font-size: 2rem;
114 | }
115 |
116 | .para {
117 | margin: 0 auto;
118 | }
119 |
120 | .text {
121 | font-size: 1rem;
122 | text-align: justify;
123 | }
124 | }
125 |
126 | @media screen and (min-width: 992px) {
127 | .para {
128 | width: 650px;
129 | }
130 |
131 | .img_container {
132 | width: 280px;
133 | }
134 | }
135 |
136 | @media screen and (min-width: 1200px) {
137 | .title {
138 | font-size: 2.3rem;
139 | }
140 |
141 | .title::after {
142 | width: 80px;
143 | }
144 |
145 | .para {
146 | width: 51%;
147 | }
148 |
149 | .img_container {
150 | width: 320px;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/components/styles/carousel.module.css:
--------------------------------------------------------------------------------
1 | .slider {
2 | position: relative;
3 | width: 100%;
4 | margin-bottom: 30px;
5 | }
6 |
7 | .img {
8 | width: 100%;
9 | height: 190px;
10 | margin: 0 auto;
11 | }
12 |
13 | .img img {
14 | width: 100%;
15 | height: 100%;
16 | object-fit: cover;
17 | }
18 |
19 | @media screen and (min-width: 480px) {
20 | .img {
21 | height: 240px;
22 | }
23 | }
24 |
25 | @media screen and (min-width: 768px) {
26 | .slick_dots li button::before {
27 | font-size: 0.55rem;
28 | }
29 |
30 | .img {
31 | height: 360px;
32 | }
33 | }
34 |
35 | @media screen and (min-width: 1200px) {
36 | .img {
37 | height: 335px;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/styles/contact.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | color: var(--white);
3 | font-size: 1.8rem;
4 | font-weight: 500;
5 | text-align: center;
6 | position: relative;
7 | padding: 8px 0;
8 | margin: 60px auto;
9 | }
10 |
11 | .title::after {
12 | content: "";
13 | background-color: var(--white);
14 | width: 50px;
15 | height: 2.5px;
16 | display: inline-block;
17 | position: absolute;
18 | bottom: 0;
19 | left: 50%;
20 | transform: translateX(-50%);
21 | }
22 |
23 | .subtitle {
24 | text-align: center;
25 | font-size: 0.9rem;
26 | font-family: "Montserrat Alternates", sans-serif;
27 | color: var(--white);
28 | }
29 |
30 | .container {
31 | display: flex;
32 | flex-direction: column;
33 | width: 90%;
34 | margin: 40px auto;
35 | padding: 30px 0 50px 0;
36 | gap: 40px;
37 | overflow: hidden;
38 | }
39 |
40 | .form_container {
41 | width: 100%;
42 | display: flex;
43 | flex-direction: column;
44 | justify-content: center;
45 | border-radius: 10px;
46 | background-color: var(--dark-blue);
47 | }
48 |
49 | .form {
50 | display: flex;
51 | flex-direction: column;
52 | align-content: center;
53 | align-items: flex-end;
54 | gap: 12px;
55 | padding: 30px;
56 | }
57 |
58 | .form_title {
59 | font-size: 1.2rem;
60 | font-weight: 500;
61 | align-self: flex-start;
62 | color: var(--light-blue);
63 | }
64 |
65 | .input {
66 | width: 100%;
67 | height: 40px;
68 | padding: 8px 12px;
69 | outline: none;
70 | font-size: 0.85rem;
71 | font-weight: 300;
72 | color: var(--grey);
73 | background-color: transparent;
74 | border: 1px solid var(--light-blue);
75 | border-radius: 4px;
76 | }
77 |
78 | .input::placeholder {
79 | color: var(--light-blue);
80 | }
81 |
82 | .textarea {
83 | height: 90px;
84 | }
85 |
86 | .btn_container {
87 | color: var(--dark-blue);
88 | background-color: var(--light-blue);
89 | padding: 12px 18px;
90 | border-radius: 4px;
91 | margin-top: 3px;
92 | transition: 0.2s;
93 | font-size: 0.9rem;
94 | font-weight: 600;
95 | text-transform: capitalize;
96 | position: relative;
97 | overflow: hidden;
98 | }
99 |
100 | .btn_hover,
101 | .btn {
102 | transition: all 0.2s ease-out;
103 | }
104 |
105 | .btn_hover {
106 | position: absolute;
107 | top: 12px;
108 | left: 18px;
109 | opacity: 0;
110 | transform: translate(0, -100%);
111 | }
112 |
113 | .btn_container:hover,
114 | .btn_container:focus {
115 | color: var(--cyan);
116 | border-color: var(--cyan);
117 | background-color: var(--dark-blue);
118 | box-shadow: 0 0 8px var(--cyan);
119 | }
120 |
121 | .btn_container:hover .btn,
122 | .btn_container:focus .btn {
123 | opacity: 0;
124 | transform: translate(0, 100%);
125 | }
126 |
127 | .btn_container:hover .btn_hover,
128 | .btn_container:focus .btn_hover {
129 | opacity: 1;
130 | transform: translate(0, 0);
131 | }
132 |
133 | .error {
134 | display: none;
135 | }
136 |
137 | .img_container {
138 | width: 100%;
139 | height: 352.6px;
140 | border-radius: 4px;
141 | margin: 0 auto;
142 | }
143 |
144 | .img {
145 | transform: translateY(40px);
146 | width: 100%;
147 | height: 100%;
148 | object-fit: contain;
149 | }
150 |
151 | @media screen and (min-width: 768px) {
152 | .title {
153 | font-size: 2rem;
154 | }
155 |
156 | .subtitle {
157 | width: 540px;
158 | margin: 0 auto;
159 | }
160 |
161 | .container {
162 | width: 495px;
163 | margin: 50px auto;
164 | }
165 | }
166 |
167 | @media screen and (min-width: 992px) {
168 | .container {
169 | flex-direction: row;
170 | width: 850px;
171 | }
172 | }
173 |
174 | @media screen and (min-width: 1200px) {
175 | .title {
176 | margin: 80px 0 40px 0;
177 | font-size: 2.3rem;
178 | }
179 |
180 | .title::after {
181 | width: 80px;
182 | }
183 |
184 | .container {
185 | width: 950px;
186 | padding: 53px 0 50px 0;
187 | gap: 40px;
188 | }
189 |
190 | .form {
191 | gap: 20px;
192 | padding: 0 45px;
193 | }
194 |
195 | .form_title {
196 | font-size: 1.3rem;
197 | }
198 |
199 | .btn_container {
200 | font-size: 1rem;
201 | }
202 |
203 | .img_container {
204 | height: 400px;
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/src/components/styles/footer.module.css:
--------------------------------------------------------------------------------
1 | #footer {
2 | position: fixed;
3 | bottom: 0;
4 | left: 0;
5 | width: 100%;
6 | height: 320px;
7 | z-index: -2;
8 | background-color: var(--light-blue);
9 | }
10 |
11 | .up_icon_container {
12 | width: fit-content;
13 | margin: 20px auto;
14 | animation-name: floating;
15 | animation-duration: 2.5s;
16 | animation-iteration-count: infinite;
17 | animation-timing-function: ease-in-out;
18 | }
19 |
20 | @keyframes floating {
21 | 0% { transform: translate(0, 0); }
22 | 50% { transform: translate(0, 7px); }
23 | 100% { transform: translate(0, -0); }
24 | }
25 |
26 | .title {
27 | position: relative;
28 | text-align: center;
29 | }
30 |
31 | .text {
32 | position: relative;
33 | text-transform: uppercase;
34 | font-weight: 500;
35 | padding: 0 7px;
36 | color: #fff;
37 | background-color: var(--light-blue) !important;
38 | z-index: -1;
39 | }
40 |
41 | .title::after {
42 | content: "";
43 | position: absolute;
44 | width: 100%;
45 | border-top: 1px solid #fff;
46 | border-bottom: 1px solid #fff;
47 | top: 9px;
48 | left: 0;
49 | z-index: -2;
50 | height: 8px;
51 | }
52 |
53 | .icon_container {
54 | display: flex;
55 | justify-content: center;
56 | gap: 15px;
57 | margin-top: 30px;
58 | }
59 |
60 | .overlay {
61 | position: relative;
62 | overflow: hidden;
63 | }
64 |
65 | .up_overlay {
66 | border: none;
67 | }
68 |
69 | .overlay:hover,
70 | .overlay:active {
71 | cursor: pointer;
72 | }
73 |
74 | .up_overlay:hover,
75 | .up_overlay:active {
76 | background-color: transparent;
77 | }
78 |
79 | .icon,
80 | .icon_hover {
81 | width: 42px;
82 | height: 42px;
83 | border-radius: 10px;
84 | transition: all 0.3s ease-out;
85 | }
86 |
87 | .up_icon,
88 | .up_icon_hover {
89 | padding: 8px;
90 | }
91 |
92 | .icon_hover {
93 | position: absolute;
94 | top: 0;
95 | left: 0;
96 | opacity: 0;
97 | }
98 |
99 | .up_icon_hover {
100 | transform: translate(0, 100%);
101 | }
102 |
103 | .overlay:hover .icon {
104 | opacity: 0;
105 | }
106 |
107 | .overlay:hover .up_icon {
108 | transform: translate(0, -100%);
109 | }
110 |
111 | .overlay:hover .icon_hover,
112 | .overlay:active .icon_hover {
113 | opacity: 1;
114 | transform: translate(0, 0);
115 | }
116 |
117 | .overlay:hover .up_icon_hover,
118 | .overlay:active .up_icon_hover {
119 | color: var(--cyan);
120 | }
121 |
122 | .p {
123 | margin-top: 30px;
124 | display: block;
125 | text-decoration: none;
126 | text-align: center;
127 | }
128 |
129 | .a {
130 | font-size: 0.75rem;
131 | color: #dfe7f3;
132 | font-family: 'Montserrat Alternates', sans-serif;
133 | position: relative;
134 | padding-bottom: 1.8px;
135 | }
136 |
137 | .a::before {
138 | content: "";
139 | position: absolute;
140 | width: 0;
141 | height: 1px;
142 | display: inline-block;
143 | left: 50%;
144 | bottom: 0;
145 | background-color: #b1bcdc;
146 | transition: 0.3s;
147 | }
148 |
149 | .a::after {
150 | content: "";
151 | position: absolute;
152 | width: 0;
153 | height: 1px;
154 | display: inline-block;
155 | right: 50%;
156 | bottom: 0;
157 | background-color: #b1bcdc;
158 | transition: 0.3s;
159 | }
160 |
161 | .a:hover::after {
162 | width: 50%;
163 | }
164 |
165 | .a:hover::before {
166 | width: 50%;
167 | }
168 |
169 | .a:active {
170 | color: var(--cyan);
171 | }
172 |
173 | .span {
174 | font-size: 0.95rem;
175 | }
176 |
177 | @media screen and (min-width: 480px) {
178 | .icon_container {
179 | gap: 20px;
180 | }
181 | }
182 |
183 | @media screen and (min-width: 1200px) {
184 | .title {
185 | width: 950px;
186 | margin: 0 auto;
187 | }
188 |
189 | .text {
190 | font-size: 1.1rem;
191 | }
192 |
193 | .title::after {
194 | height: 9px;
195 | }
196 |
197 | .icon_container {
198 | gap: 25px;
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/src/components/styles/home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100vw;
3 | height: 100vh;
4 | padding-left: 50px;
5 | position: relative;
6 | display: flex;
7 | flex-direction: column;
8 | align-items: flex-start;
9 | justify-content: center;
10 | background: transparent;
11 | z-index: 0;
12 | }
13 |
14 | .intro {
15 | width: 100%;
16 | display: flex;
17 | flex-direction: column;
18 | font-size: 0.75rem;
19 | letter-spacing: 0.1rem;
20 | line-height: 1.7rem;
21 | font-family: 'Montserrat Alternates', sans-serif;
22 | color: var(--white);
23 | }
24 |
25 | .name {
26 | color: var(--cyan);
27 | font-family: 'Bungee', cursive;
28 | font-size: 1.5rem;
29 | }
30 |
31 | .desc {
32 | font-family: 'Montserrat Alternates', sans-serif;
33 | font-size: 0.75rem;
34 | word-spacing: 0.15rem;
35 | margin-top: 5px;
36 | margin-bottom: 15px;
37 | color: var(--white);
38 | }
39 |
40 | .btn_container {
41 | font-size: 0.9rem;
42 | position: relative;
43 | overflow: hidden;
44 | padding: 10px 13px;
45 | transition: 0.2s;
46 | /* border-radius: 4px; */
47 | color: var(--white);
48 | border: 2px solid var(--grey);
49 | }
50 |
51 | .btn_hover,
52 | .btn {
53 | font-family: 'Montserrat Alternates', sans-serif;
54 | transition: all 0.2s ease-out;
55 | }
56 |
57 | .btn_hover {
58 | position: absolute;
59 | top: 10px;
60 | left: 13px;
61 | opacity: 0;
62 | transform: translate(0, -100%);
63 | }
64 |
65 | .arrow {
66 | margin-left: 5px;
67 | font-size: 17px;
68 | display: inline;
69 | transition: transform 0.3s ease-in-out;
70 | }
71 |
72 | .btn_container:hover,
73 | .btn_container:focus {
74 | color: var(--cyan);
75 | background-color: var(--dark-blue);
76 | border-color: var(--cyan);
77 | box-shadow: 0 0 8px var(--cyan);
78 | text-shadow: 0 0 8px var(--cyan);
79 | }
80 |
81 | .btn_container:hover .btn,
82 | .btn_container:focus .btn {
83 | opacity: 0;
84 | transform: translate(0, 100%);
85 | }
86 |
87 | .btn_container:hover .btn_hover,
88 | .btn_container:focus .btn_hover {
89 | opacity: 1;
90 | transform: translate(0, 0);
91 | }
92 |
93 | .btn_container:hover .arrow,
94 | .btn_container:focus .arrow {
95 | transform: rotate(90deg);
96 | }
97 |
98 | @media screen and (min-width: 480px) {
99 | .container {
100 | align-items: center;
101 | padding-left: 0;
102 | }
103 |
104 | .intro {
105 | font-family: 'Bungee', cursive;
106 | flex-direction: row;
107 | justify-content: center;
108 | gap: 10px;
109 | font-size: 1.5rem;
110 | line-height: 2rem;
111 | }
112 |
113 | .desc {
114 | font-size: 0.9rem;
115 | }
116 |
117 | .btn_container {
118 | font-size: 0.9rem;
119 | padding: 8px 13px;
120 | }
121 |
122 | .btn_hover {
123 | top: 8px;
124 | }
125 |
126 | .arrow {
127 | margin-left: 6px;
128 | font-size: 16px;
129 | }
130 | }
131 |
132 | @media screen and (min-width: 768px) {
133 | .intro {
134 | font-size: 1.7rem;
135 | line-height: 2.1rem;
136 | }
137 |
138 | .name {
139 | font-size: 1.7rem;
140 | }
141 |
142 | .desc {
143 | font-size: 1.03rem;
144 | }
145 |
146 | .btn_container {
147 | font-size: 0.95rem;
148 | }
149 |
150 | .arrow {
151 | font-size: 18px;
152 | }
153 | }
154 |
155 | @media screen and (min-width: 1200px) {
156 | .intro {
157 | font-size: 1.9rem;
158 | letter-spacing: 0.2rem;
159 | line-height: 2.4rem;
160 | }
161 |
162 | .name {
163 | font-size: 1.9rem;
164 | }
165 |
166 | .desc {
167 | font-size: 1.1rem;
168 | margin-bottom: 20px;
169 | }
170 |
171 | .btn_container {
172 | font-size: 1.1rem;
173 | padding: 12px 17px;
174 | }
175 |
176 | .btn_hover {
177 | top: 12px;
178 | left: 17px;
179 | }
180 |
181 | .arrow {
182 | margin-left: 8px;
183 | font-size: 1.4rem;
184 | }
185 | }
186 |
187 | @media screen and (min-width: 1400px) {
188 | .intro {
189 | font-size: 2.1rem;
190 | letter-spacing: 0.2rem;
191 | line-height: 2.4rem;
192 | }
193 |
194 | .name {
195 | font-size: 2.1rem;
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/src/components/styles/navbar.module.css:
--------------------------------------------------------------------------------
1 | .navbar_container {
2 | position: relative;
3 | height: 86px;
4 | }
5 |
6 | .progress_bar {
7 | position: fixed;
8 | top: 74.2px;
9 | left: 0;
10 | right: 0;
11 | height: 3px;
12 | background: var(--cyan);
13 | box-shadow: 0 0 10px var(--cyan);
14 | transform-origin: 0%;
15 | z-index: 2;
16 | }
17 |
18 | .navbar {
19 | padding: 14px 30px 14px 15px;
20 | display: flex;
21 | width: 100%;
22 | position: absolute;
23 | top: 0;
24 | justify-content: space-between;
25 | align-items: center;
26 | background-color: var(--navy);
27 | box-shadow: 0 1px 3px var(--dark-blue);
28 | z-index: 3;
29 | }
30 |
31 | .fixed {
32 | position: fixed;
33 | }
34 |
35 | .logo_btn {
36 | width: 40px;
37 | clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
38 | }
39 |
40 | .logo {
41 | width: 100%;
42 | height: auto;
43 | }
44 |
45 | .navlink {
46 | font-size: 13px;
47 | font-weight: 500;
48 | display: none;
49 | align-items: center;
50 | gap: 30px;
51 | color: var(--grey);
52 | }
53 |
54 | .active {
55 | color: var(--cyan);
56 | position: relative;
57 | }
58 |
59 | .font {
60 | font-family: 'Montserrat Alternates', sans-serif;
61 | }
62 |
63 | .font:hover {
64 | color: var(--cyan);
65 | }
66 |
67 | .resume_container {
68 | color: var(--dark-blue);
69 | background-color: var(--cyan);
70 | border-radius: 4px;
71 | padding: 11px 15px;
72 | transition: 0.2s;
73 | position: relative;
74 | overflow: hidden;
75 | }
76 |
77 | .resume,
78 | .resume_hover {
79 | transition: all 0.2s ease-out;
80 | }
81 |
82 | .resume_hover {
83 | position: absolute;
84 | top: 11px;
85 | left: 15px;
86 | opacity: 0;
87 | transform: translate(0, -100%);
88 | }
89 |
90 | .resume_container:hover,
91 | .resume_container:focus {
92 | color: var(--cyan);
93 | background-color: var(--dark-blue);
94 | border-color: var(--cyan);
95 | box-shadow: 0 0 8px var(--cyan);
96 | }
97 |
98 | .resume_container:hover .resume,
99 | .resume_container:focus .resume {
100 | opacity: 0;
101 | transform: translate(0, 100%);
102 | }
103 |
104 | .resume_container:hover .resume_hover,
105 | .resume_container:focus .resume_hover {
106 | opacity: 1;
107 | transform: translate(0, 0);
108 | }
109 |
110 | .theme_btn {
111 | width: 70px;
112 | }
113 |
114 | .theme_img {
115 | width: 100%;
116 | height: 100%;
117 | object-fit: cover;
118 | }
119 |
120 | .mobilemenu {
121 | position: absolute;
122 | top: 65.5px;
123 | left: 0;
124 | opacity: 0;
125 | display: flex;
126 | flex-direction: column;
127 | align-items: flex-end;
128 | gap: 30px;
129 | padding-right: 35px;
130 | overflow: hidden;
131 | transition: height 0.3s ease-out;
132 | width: 100%;
133 | z-index: 1;
134 | color: var(--grey);
135 | background-color: var(--dark-blue);
136 | }
137 |
138 | .mobile_font {
139 | font-family: 'Montserrat Alternates', sans-serif;
140 | text-transform: uppercase;
141 | font-size: 1.3rem;
142 | }
143 |
144 | .mobile_resume_container {
145 | padding: 12px 16px;
146 | text-transform: uppercase;
147 | font-size: 1.2rem;
148 | }
149 |
150 | .mobile_active::before {
151 | content: '';
152 | position: absolute;
153 | width: 2px;
154 | height: 75%;
155 | top: 50%;
156 | left: -8px;
157 | transform: translateY(-50%);
158 | background-color: var(--cyan);
159 | }
160 |
161 | .hamburger {
162 | width: 40px;
163 | height: 22px;
164 | position: relative;
165 | cursor: pointer;
166 | display: inline-block;
167 | }
168 |
169 | .line {
170 | background-color: var(--cyan);
171 | position: absolute;
172 | border-radius: 2px;
173 | transition: 0.3s cubic-bezier(0.8, 0.5, 0.2, 1.4);
174 | height: 3px;
175 | transition-duration: 500ms;
176 | }
177 |
178 | .line:nth-child(1) {
179 | width: 100%;
180 | top: 0;
181 | right: 0;
182 | }
183 |
184 | .line:nth-child(2) {
185 | width: 75%;
186 | top: 9.5px;
187 | right: 0;
188 | opacity: 1;
189 | }
190 |
191 | .line:nth-child(3) {
192 | width: 50%;
193 | bottom: 0;
194 | right: 0;
195 | }
196 |
197 | .open:nth-child(1) {
198 | transform: rotate(45deg);
199 | top: 9px;
200 | }
201 |
202 | .open:nth-child(2) {
203 | opacity: 0;
204 | }
205 |
206 | .open:nth-child(3) {
207 | width: 100%;
208 | transform: rotate(-45deg);
209 | top: 9px;
210 | }
211 |
212 | @media screen and (min-width: 768px) {
213 | .progress_bar {
214 | top: 93.76px;
215 | }
216 |
217 | .navbar {
218 | padding: 18px 45px 18px 30px;
219 | }
220 |
221 | .logo_btn {
222 | width: 50px;
223 | }
224 |
225 | .navlink {
226 | display: flex;
227 | }
228 |
229 | .hamburger {
230 | display: none;
231 | }
232 | }
233 |
234 | @media screen and (min-width: 1200px) {
235 | .navbar {
236 | padding: 18px 60px 18px 40px;
237 | }
238 |
239 | .navlink {
240 | font-size: 15px;
241 | gap: 40px;
242 | }
243 |
244 | .resume_container {
245 | padding: 9px 14px;
246 | }
247 |
248 | .resume_hover {
249 | top: 8px;
250 | left: 14px;
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/src/components/styles/popup.module.css:
--------------------------------------------------------------------------------
1 | .overlay {
2 | position: fixed;
3 | top: 65.5px;
4 | left: 0;
5 | width: 100%;
6 | height: 100vh;
7 | background-color: transparent;
8 | backdrop-filter: blur(10px);
9 | z-index: 999;
10 | }
11 |
12 | .container {
13 | background-color: var(--dark-blue);
14 | width: 90%;
15 | margin: 0 auto;
16 | position: relative;
17 | }
18 |
19 | .close_btn {
20 | position: absolute;
21 | right: 0;
22 | top: 0;
23 | padding: 7px;
24 | z-index: 9;
25 | color: var(--white);
26 | background-color: var(--low-opacity);
27 | font-size: 1.8rem;
28 | }
29 |
30 | .close_btn:hover,
31 | .close_btn:focus {
32 | color: #ec008c;
33 | cursor: pointer;
34 | }
35 |
36 | .img {
37 | width: 90%;
38 | height: 100%;
39 | margin: 0 auto 20px auto;
40 | }
41 |
42 | .content {
43 | width: 90%;
44 | margin: 20px auto 0 auto;
45 | color: var(--white);
46 | }
47 |
48 | .name {
49 | font-family: "Bungee", cursive;
50 | font-size: 1.2rem;
51 | }
52 |
53 | .tech {
54 | display: flex;
55 | gap: 10px;
56 | }
57 |
58 | .tech_list {
59 | color: var(--cyan);
60 | font-size: 0.7rem;
61 | font-family: "Montserrat Alternates", sans-serif;
62 | }
63 |
64 | .tech_list:nth-child(2) {
65 | background: #11998e; /* fallback for old browsers */
66 | background:
67 | -webkit-linear-gradient(
68 | to top,
69 | #11998e,
70 | #38ef7d
71 | ); /* Chrome 10-25, Safari 5.1-6 */
72 |
73 | background:
74 | linear-gradient(
75 | to top,
76 | #11998e,
77 | #38ef7d
78 | ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
79 |
80 | -webkit-background-clip: text;
81 | -webkit-text-fill-color: transparent;
82 | }
83 |
84 | .tech_list:nth-child(3) {
85 | background: #ec008c; /* fallback for old browsers */
86 | background:
87 | -webkit-linear-gradient(
88 | to top,
89 | #ec008c,
90 | #fc6767
91 | ); /* Chrome 10-25, Safari 5.1-6 */
92 |
93 | background:
94 | linear-gradient(
95 | to top,
96 | #ec008c,
97 | #fc6767
98 | ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
99 |
100 | -webkit-background-clip: text;
101 | -webkit-text-fill-color: transparent;
102 | }
103 |
104 | .description {
105 | font-size: 0.8rem;
106 | margin: 10px auto;
107 | }
108 |
109 | .link {
110 | display: flex;
111 | justify-content: space-between;
112 | padding: 15px 0 25px 0;
113 | }
114 |
115 | .btn_container {
116 | padding: 8px 14px;
117 | color: var(--dark-blue);
118 | background-color: var(--cyan);
119 | border-radius: 4px;
120 | font-size: 0.9rem;
121 | font-weight: 600;
122 | transition: 0.2s;
123 | position: relative;
124 | overflow: hidden;
125 | }
126 |
127 | .btn_hover,
128 | .btn {
129 | transition: all 0.2s ease-out;
130 | }
131 |
132 | .btn_hover {
133 | position: absolute;
134 | top: 8px;
135 | left: 14px;
136 | opacity: 0;
137 | transform: translate(0, -100%);
138 | }
139 |
140 | .btn_container:hover,
141 | .btn_container:focus {
142 | color: var(--cyan);
143 | background-color: var(--dark-blue);
144 | box-shadow: 0 0 6px var(--cyan);
145 | }
146 |
147 | .btn_container:hover .btn,
148 | .btn_container:focus .btn {
149 | opacity: 0;
150 | transform: translate(0, 100%);
151 | }
152 |
153 | .btn_container:hover .btn_hover,
154 | .btn_container:focus .btn_hover {
155 | opacity: 1;
156 | transform: translate(0, 0);
157 | }
158 |
159 | @media screen and (min-width: 768px) {
160 | .overlay {
161 | top: 73.5px;
162 | }
163 |
164 | .container {
165 | width: 652px;
166 | }
167 |
168 | .close_btn {
169 | font-size: 2rem;
170 | }
171 |
172 | .img {
173 | margin-bottom: 30px;
174 | }
175 |
176 | .name {
177 | font-size: 1.5rem;
178 | }
179 |
180 | .tech {
181 | gap: 15px;
182 | }
183 |
184 | .tech_list {
185 | font-size: 0.8rem;
186 | }
187 |
188 | .description {
189 | font-size: 1rem;
190 | margin: 20px auto;
191 | }
192 |
193 | .btn_container {
194 | font-size: 1.1rem;
195 | padding: 10px 16px;
196 | }
197 |
198 | .btn_hover {
199 | top: 10px;
200 | left: 16px;
201 | }
202 | }
203 |
204 | @media screen and (min-width: 1200px) {
205 | .overlay {
206 | top: 0;
207 | z-index: 3;
208 | }
209 |
210 | .container {
211 | width: 600px;
212 | }
213 |
214 | .close_btn {
215 | font-size: 2.1rem;
216 | padding: 7px;
217 | }
218 |
219 | .img {
220 | margin-bottom: 20px;
221 | }
222 |
223 | .name {
224 | font-size: 1.3rem;
225 | }
226 |
227 | .tech {
228 | gap: 15px;
229 | }
230 |
231 | .tech_list {
232 | font-size: 0.8rem;
233 | }
234 |
235 | .description {
236 | font-size: 0.9rem;
237 | margin: 10px auto;
238 | }
239 |
240 | .btn_container {
241 | font-size: 1rem;
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/src/components/styles/service.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | color: var(--white);
3 | font-size: 1.8rem;
4 | font-weight: 500;
5 | text-align: center;
6 | position: relative;
7 | padding: 8px 0;
8 | margin-top: 100px;
9 | margin-bottom: 25px;
10 | }
11 |
12 | .title::after {
13 | content: "";
14 | background-color: var(--white);
15 | width: 60px;
16 | height: 2.5px;
17 | display: inline-block;
18 | position: absolute;
19 | bottom: 0;
20 | left: 50%;
21 | transform: translateX(-50%);
22 | }
23 |
24 | .subtitle {
25 | text-align: center;
26 | font-size: 0.9rem;
27 | font-family: 'Montserrat Alternates', sans-serif;
28 | color: var(--white);
29 | }
30 |
31 | .card_container {
32 | width: 89%;
33 | margin: 0 auto;
34 | display: flex;
35 | flex-direction: column;
36 | justify-content: center;
37 | align-items: center;
38 | gap: 40px;
39 | padding: 50px 0;
40 | }
41 |
42 | .tilt {
43 | width: 100%;
44 | }
45 |
46 | .card_shadow {
47 | position: relative;
48 | }
49 |
50 | .card_overlay {
51 | width: 100%;
52 | height: 100%;
53 | position: absolute;
54 | opacity: 0;
55 | display: flex;
56 | flex-direction: column;
57 | justify-content: center;
58 | padding: 20px;
59 | background-color: var(--dark-blue);
60 | transition: 0.45s ease-in-out;
61 | }
62 |
63 | .card {
64 | background-color: var(--dark-blue);
65 | height: 320px;
66 | display: flex;
67 | flex-direction: column;
68 | justify-content: center;
69 | align-items: center;
70 | opacity: 1;
71 | }
72 |
73 | .card_shadow:hover .card {
74 | opacity: 0;
75 | }
76 |
77 | .card_shadow:hover .card_overlay {
78 | opacity: 1;
79 | }
80 |
81 | .img_container {
82 | width: 130px;
83 | height: 130px;
84 | display: flex;
85 | justify-content: center;
86 | align-items: center;
87 | }
88 |
89 | .img {
90 | width: 100%;
91 | height: 100%;
92 | object-fit: cover;
93 | }
94 |
95 | .name {
96 | font-size: 0.9rem;
97 | font-weight: 600;
98 | text-transform: uppercase;
99 | color: var(--white);
100 | }
101 |
102 | .text {
103 | font-size: 0.9rem;
104 | text-align: center;
105 | color: var(--white);
106 | }
107 |
108 | @media screen and (min-width: 480px) {
109 | .title {
110 | font-size: 1.9rem;
111 | }
112 |
113 | .card {
114 | height: 360px;
115 | gap: 5px;
116 | }
117 |
118 | .img_container {
119 | width: 150px;
120 | height: 150px;
121 | }
122 |
123 | .name {
124 | font-size: 1rem;
125 | }
126 | }
127 |
128 | @media screen and (min-width: 768px) {
129 | .title {
130 | font-size: 2rem;
131 | }
132 |
133 | .card_container {
134 | width: 100%;
135 | padding: 50px 20px;
136 | flex-direction: row;
137 | flex-wrap: wrap;
138 | gap: 30px;
139 | }
140 |
141 | .tilt {
142 | width: 47%;
143 | }
144 |
145 | .card {
146 | height: 320px;
147 | }
148 |
149 | .img_container {
150 | width: 120px;
151 | height: 120px;
152 | }
153 |
154 | .name {
155 | font-size: 1rem;
156 | }
157 | }
158 |
159 | @media screen and (min-width: 1024px) {
160 | .card_container {
161 | width: 830px;
162 | padding: 50px 0;
163 | flex-wrap: nowrap;
164 | gap: 20px;
165 | }
166 |
167 | .tilt {
168 | width: 32%;
169 | }
170 |
171 | .card {
172 | height: 300px;
173 | }
174 |
175 | .img_container {
176 | width: 110px;
177 | height: 110px;
178 | }
179 |
180 | .name {
181 | font-size: 0.8rem;
182 | }
183 | }
184 |
185 | @media screen and (min-width: 1200px) {
186 | .title {
187 | font-size: 2.3rem;
188 | }
189 |
190 | .title::after {
191 | width: 80px;
192 | }
193 |
194 | .card_container {
195 | width: 970px;
196 | gap: 40px;
197 | }
198 |
199 | .card {
200 | height: 320px;
201 | }
202 |
203 | .name {
204 | font-size: 0.85rem;
205 | }
206 | }
207 |
208 | @media screen and (min-width: 1400px) {
209 | .container {
210 | max-width: 1200px;
211 | margin: 0 auto;
212 | }
213 |
214 | .card_container {
215 | width: 1062px;
216 | }
217 |
218 | .card {
219 | height: 330px;
220 | gap: 10px;
221 | }
222 |
223 | .name {
224 | font-size: 0.9rem;
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/src/components/styles/techstack.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | width: 89%;
3 | font-size: 14.5px;
4 | word-spacing: 0.13rem;
5 | text-align: left;
6 | color: var(--grey);
7 | margin: 50px auto;
8 | }
9 |
10 | .btn_container {
11 | width: 89%;
12 | display: grid;
13 | grid-template-columns: auto auto auto auto;
14 | margin: 0 auto 25px auto;
15 | color: var(--white);
16 | }
17 |
18 | .btn_container button {
19 | text-transform: capitalize;
20 | font-size: 0.8rem;
21 | font-weight: 500;
22 | font-family: "Montserrat Alternates", sans-serif;
23 | padding: 5px 0;
24 | }
25 |
26 | .btn_active {
27 | color: #fff;
28 | text-transform: capitalize;
29 | background-color: var(--cyan) !important;
30 | }
31 |
32 | .tech_container {
33 | display: flex;
34 | flex-wrap: wrap;
35 | gap: 10px;
36 | justify-content: center;
37 | padding: 0;
38 | margin: 30px auto;
39 | }
40 |
41 | .tech {
42 | width: 85px;
43 | height: 90px;
44 | clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
45 | background-color: #fff;
46 | position: relative;
47 | transition: background-color 0.3s ease-out;
48 | }
49 |
50 | .tech_img {
51 | position: absolute;
52 | width: 60%;
53 | height: 60%;
54 | top: 50%;
55 | left: 50%;
56 | transform: translate(-50%, -50%);
57 | object-fit: cover;
58 | object-position: center;
59 | }
60 |
61 | @media screen and (min-width: 480px) {
62 | .title {
63 | font-size: 15px;
64 | }
65 | }
66 |
67 | @media screen and (min-width: 545px) {
68 | .tech_container {
69 | width: 80%;
70 | }
71 | }
72 |
73 | @media screen and (min-width: 768px) {
74 | .title {
75 | font-size: 16px;
76 | text-align: center;
77 | }
78 |
79 | .btn_container button {
80 | font-size: 0.9rem;
81 | padding: 7px 0;
82 | }
83 |
84 | .tech_container {
85 | width: 89%;
86 | height: 305px;
87 | gap: 13px;
88 | }
89 |
90 | .tech {
91 | width: 90px;
92 | height: 93px;
93 | }
94 | }
95 |
96 | @media screen and (min-width: 1024px) {
97 | .btn_container {
98 | width: 820px;
99 | }
100 |
101 | .tech_container {
102 | width: 830px;
103 | height: 166px;
104 | gap: 0 13px;
105 | }
106 |
107 | .tech {
108 | width: 80px;
109 | height: 83px;
110 | background-color: var(--cyan);
111 | }
112 |
113 | .tech:hover {
114 | cursor: pointer;
115 | background-color: var(--navy);
116 | }
117 |
118 | .tech_img {
119 | mix-blend-mode: multiply;
120 | filter: grayscale(100%) contrast(1);
121 | }
122 |
123 | .tech:hover .tech_img {
124 | mix-blend-mode: normal;
125 | filter: none;
126 | }
127 | }
128 |
129 | @media screen and (min-width: 1200px) {
130 | .title {
131 | font-size: 17px;
132 | }
133 |
134 | .btn_container {
135 | width: 70%;
136 | }
137 |
138 | .btn_container button {
139 | font-size: 1rem;
140 | }
141 |
142 | .tech_container {
143 | width: 970px;
144 | height: 470px;
145 | gap: 0 20px;
146 | }
147 |
148 | .tech {
149 | width: 90px;
150 | height: 93px;
151 | }
152 |
153 | .tech_img {
154 | width: 60%;
155 | height: 60%;
156 | }
157 | }
158 |
159 | @media screen and (min-width: 1400px) {
160 | .tech_container {
161 | width: 1062px;
162 | height: 208px;
163 | }
164 |
165 | .tech {
166 | width: 100px;
167 | height: 103px;
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/components/styles/testimonial.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | color: var(--white);
3 | font-size: 1.8rem;
4 | font-weight: 500;
5 | text-align: center;
6 | position: relative;
7 | padding: 8px 0;
8 | margin-top: 60px;
9 | margin-bottom: 25px;
10 | }
11 |
12 | .title::after {
13 | content: "";
14 | background-color: var(--white);
15 | width: 60px;
16 | height: 2.5px;
17 | display: inline-block;
18 | position: absolute;
19 | bottom: 0;
20 | left: 50%;
21 | transform: translateX(-50%);
22 | }
23 |
24 | .subtitle {
25 | text-align: center;
26 | font-size: 0.9rem;
27 | font-family: 'Montserrat Alternates', sans-serif;
28 | color: var(--white);
29 | }
30 |
31 | .carousel_container {
32 | position: relative;
33 | }
34 |
35 | .btn_container {
36 | display: flex;
37 | justify-content: center;
38 | gap: 50px;
39 | }
40 |
41 | .button {
42 | display: block;
43 | font-size: 1.5rem;
44 | color: var(--cyan);
45 | }
46 |
47 | .prev {
48 | animation-name: prev;
49 | animation-duration: 2.5s;
50 | animation-iteration-count: infinite;
51 | animation-timing-function: ease-in-out;
52 | }
53 |
54 | @keyframes prev {
55 | 0% { transform: translate(0, 0); }
56 | 50% { transform: translate(5px, 0); }
57 | 100% { transform: translate(0, 0); }
58 | }
59 |
60 | .next {
61 | animation-name: next;
62 | animation-duration: 2.5s;
63 | animation-iteration-count: infinite;
64 | animation-timing-function: ease-in-out;
65 | }
66 |
67 | @keyframes next {
68 | 0% { transform: translate(0, 0); }
69 | 50% { transform: translate(-5px, 0); }
70 | 100% { transform: translate(0, 0); }
71 | }
72 |
73 | .card_container {
74 | display: flex;
75 | flex-direction: column;
76 | justify-content: center;
77 | align-items: center;
78 | gap: 30px;
79 | padding: 50px 0 20px 0;
80 | }
81 |
82 | .card {
83 | width: 92%;
84 | background-color: var(--dark-blue);
85 | padding: 50px 40px;
86 | overflow: hidden;
87 | }
88 |
89 | .header {
90 | display: flex;
91 | justify-content: space-between;
92 | align-items: flex-start;
93 | margin-bottom: 10px;
94 | }
95 |
96 | .img {
97 | width: 45px;
98 | height: 45px;
99 | object-fit: cover;
100 | border-radius: 50%;
101 | transform: translateY(6px);
102 | }
103 |
104 | .openquote {
105 | margin: 15px 0 25px 0;
106 | font-size: 2.2rem;
107 | color: var(--cyan);
108 | }
109 |
110 | .para {
111 | font-size: 0.9rem;
112 | font-weight: 500;
113 | color: var(--white);
114 | padding-bottom: 15px;
115 | }
116 |
117 | .label {
118 | display: flex;
119 | justify-content: space-between;
120 | align-items: center;
121 | margin-top: 15px;
122 | }
123 |
124 | .name {
125 | font-size: 0.8rem;
126 | font-weight: 500;
127 | color: var(--white);
128 | }
129 |
130 | .country {
131 | font-family: 'Montserrat Alternates', sans-serif;
132 | font-size: 0.75rem;
133 | color: var(--cyan);
134 | }
135 |
136 | .icon {
137 | font-size: 1.3rem;
138 | padding-bottom: 2px;
139 | position: relative;
140 | color: var(--cyan);
141 | }
142 |
143 | .icon::after {
144 | content: "";
145 | position: absolute;
146 | width: 0;
147 | height: 1px;
148 | display: inline-block;
149 | left: 0;
150 | bottom: 0;
151 | background-color: var(--cyan);
152 | transition: 0.3s;
153 | }
154 |
155 | .icon:hover {
156 | cursor: pointer;
157 | }
158 |
159 | .icon:hover::after {
160 | width: 100%;
161 | }
162 |
163 | @media screen and (min-width: 480px) {
164 | .title {
165 | font-size: 1.9rem;
166 | }
167 |
168 | .button {
169 | font-size: 1.8rem;
170 | }
171 |
172 | .card {
173 | width: 370px;
174 | }
175 | }
176 |
177 | @media screen and (min-width: 768px) {
178 | .title {
179 | font-size: 2rem;
180 | }
181 |
182 | .button {
183 | position: absolute;
184 | top: 50%;
185 | transform: translate(0, -50%);
186 | }
187 |
188 | .prev {
189 | left: 10%;
190 | }
191 |
192 | .next {
193 | right: 10%;
194 | }
195 | }
196 |
197 | @media screen and (min-width: 1200px) {
198 | .title {
199 | font-size: 2.3rem;
200 | }
201 |
202 | .title::after {
203 | width: 80px;
204 | }
205 |
206 | .button {
207 | top: 46%;
208 | }
209 |
210 | .prev {
211 | left: -2%;
212 | }
213 |
214 | .next {
215 | right: -2%;
216 | }
217 |
218 | .card_container {
219 | flex-direction: row;
220 | gap: 25px;
221 | padding: 50px 35px;
222 | }
223 |
224 | .card {
225 | padding: 45px 35px;
226 | }
227 |
228 | .para {
229 | font-size: 0.83rem;
230 | line-height: 1.15rem;
231 | height: 100px;
232 | }
233 |
234 | .label {
235 | margin-top: 10px;
236 | align-items: flex-end;
237 | }
238 |
239 | .icon {
240 | font-size: 1.3rem;
241 | }
242 | }
243 |
244 | @media screen and (min-width: 1400px) {
245 | .button {
246 | font-size: 2rem;
247 | }
248 |
249 | .prev {
250 | left: -1%;
251 | }
252 |
253 | .next {
254 | right: -1%;
255 | }
256 |
257 | .card_container {
258 | gap: 40px;
259 | }
260 |
261 | .para {
262 | font-size: 0.88rem;
263 | height: 110px;
264 | }
265 |
266 | .name {
267 | font-size: 0.85rem;
268 | }
269 |
270 | .country {
271 | font-size: 0.8rem;
272 | }
273 |
274 | .icon {
275 | font-size: 1.4rem;
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/src/components/styles/work.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | color: var(--white);
3 | font-size: 1.8rem;
4 | font-weight: 500;
5 | text-align: center;
6 | position: relative;
7 | padding: 8px 0;
8 | margin: 60px auto;
9 | }
10 |
11 | .title::after {
12 | content: "";
13 | background-color: var(--white);
14 | width: 60px;
15 | height: 2.5px;
16 | display: inline-block;
17 | position: absolute;
18 | bottom: 0;
19 | left: 50%;
20 | transform: translateX(-50%);
21 | }
22 |
23 | .project_container {
24 | display: grid;
25 | grid-template-columns: auto;
26 | grid-gap: 1px;
27 | padding: 0 10px;
28 | }
29 |
30 | .card {
31 | aspect-ratio: 4 / 3;
32 | position: relative;
33 | overflow: hidden;
34 | }
35 |
36 | .img {
37 | width: 100%;
38 | height: 100%;
39 | object-fit: cover;
40 | position: absolute;
41 | opacity: 1;
42 | transform: scale(1);
43 | transition: transform 0.25s ease-in-out;
44 | }
45 |
46 | .card_overlay {
47 | width: 100%;
48 | height: 100%;
49 | position: absolute;
50 | opacity: 0;
51 | transition: 0.45s ease-in-out;
52 | }
53 |
54 | .card:hover .img {
55 | transform: scale(1.1);
56 | opacity: 0.5;
57 | }
58 |
59 | .card:hover .card_overlay {
60 | opacity: 1;
61 | }
62 |
63 | .card_text {
64 | background-color: var(--navy);
65 | width: 100%;
66 | height: 100%;
67 | display: flex;
68 | flex-direction: column;
69 | justify-content: center;
70 | align-items: center;
71 | gap: 40px;
72 | }
73 |
74 | .text {
75 | display: flex;
76 | flex-direction: column;
77 | align-items: center;
78 | }
79 |
80 | .card:hover .text {
81 | animation: slide-down 0.3s ease-out;
82 | }
83 |
84 | @keyframes slide-down {
85 | from {
86 | transform: translateY(-150%);
87 | opacity: 0.5;
88 | }
89 |
90 | to {
91 | transform: translate(0);
92 | opacity: 1;
93 | }
94 | }
95 |
96 | .name {
97 | color: var(--white);
98 | font-family: "Bungee", cursive;
99 | font-size: 1.2rem;
100 | margin-bottom: 5px;
101 | }
102 |
103 | .tech {
104 | display: flex;
105 | gap: 10px;
106 | }
107 |
108 | .tech_list {
109 | font-size: 0.7rem;
110 | font-family: "Montserrat Alternates", sans-serif;
111 | color: var(--cyan);
112 | }
113 |
114 | .tech_list:nth-child(2) {
115 | background: #11998e; /* fallback for old browsers */
116 | background:
117 | -webkit-linear-gradient(
118 | to top,
119 | #11998e,
120 | #38ef7d
121 | ); /* Chrome 10-25, Safari 5.1-6 */
122 |
123 | background:
124 | linear-gradient(
125 | to top,
126 | #11998e,
127 | #38ef7d
128 | ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
129 |
130 | -webkit-background-clip: text;
131 | -webkit-text-fill-color: transparent;
132 | }
133 |
134 | .tech_list:nth-child(3) {
135 | background: #ec008c; /* fallback for old browsers */
136 | background:
137 | -webkit-linear-gradient(
138 | to top,
139 | #ec008c,
140 | #fc6767
141 | ); /* Chrome 10-25, Safari 5.1-6 */
142 |
143 | background:
144 | linear-gradient(
145 | to top,
146 | #ec008c,
147 | #fc6767
148 | ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
149 |
150 | -webkit-background-clip: text;
151 | -webkit-text-fill-color: transparent;
152 | }
153 |
154 | .btn_container {
155 | font-size: 0.9rem;
156 | font-weight: 600;
157 | color: var(--dark-blue);
158 | background-color: var(--cyan) !important;
159 | border-radius: 4px;
160 | padding: 12px 18px;
161 | text-transform: capitalize;
162 | transition: 0.2s;
163 | position: relative;
164 | overflow: hidden;
165 | }
166 |
167 | .btn_hover,
168 | .btn {
169 | transition: all 0.2s ease-out;
170 | }
171 |
172 | .btn_hover {
173 | position: absolute;
174 | top: 12px;
175 | left: 18px;
176 | opacity: 0;
177 | transform: translate(0, -100%);
178 | }
179 |
180 | .btn_container:hover,
181 | .btn_container:focus {
182 | color: var(--cyan);
183 | background-color: var(--dark-blue) !important;
184 | box-shadow: 0 0 8px var(--cyan);
185 | }
186 |
187 | .btn_container:hover .btn,
188 | .btn_container:focus .btn {
189 | opacity: 0;
190 | transform: translate(0, 100%);
191 | }
192 |
193 | .btn_container:hover .btn_hover,
194 | .btn_container:focus .btn_hover {
195 | opacity: 1;
196 | transform: translate(0, 0);
197 | }
198 |
199 | .card:hover .btn_container {
200 | animation: slide-up 0.3s ease-out;
201 | }
202 |
203 | @keyframes slide-up {
204 | from {
205 | transform: translateY(150%);
206 | opacity: 0.5;
207 | }
208 |
209 | to {
210 | transform: translate(0);
211 | opacity: 1;
212 | }
213 | }
214 |
215 | @media screen and (min-width: 480px) {
216 | .title {
217 | font-size: 1.9rem;
218 | }
219 |
220 | .title::after {
221 | width: 70px;
222 | }
223 |
224 | .project_container {
225 | padding: 0 30px;
226 | }
227 |
228 | .card_text {
229 | gap: 50px;
230 | }
231 |
232 | .name {
233 | font-size: 1.35rem;
234 | margin-bottom: 5px;
235 | }
236 |
237 | .tech_list {
238 | font-size: 0.7rem;
239 | }
240 |
241 | .btn_container {
242 | font-size: 1rem;
243 | padding: 12px 20px;
244 | }
245 |
246 | .btn_hover {
247 | left: 20px;
248 | }
249 | }
250 |
251 | @media screen and (min-width: 768px) {
252 | .title {
253 | font-size: 2rem;
254 | }
255 |
256 | .project_container {
257 | grid-template-columns: auto auto;
258 | padding: 0 20px;
259 | }
260 |
261 | .name {
262 | font-size: 1.25rem;
263 | }
264 |
265 | .btn_container {
266 | padding: 12px 18px;
267 | }
268 |
269 | .btn_hover {
270 | left: 18px;
271 | }
272 | }
273 |
274 | @media screen and (min-width: 1024px) {
275 | .project_container {
276 | padding: 0;
277 | width: 830px;
278 | margin: 0 auto;
279 | }
280 | }
281 |
282 | @media screen and (min-width: 1200px) {
283 | .title {
284 | font-size: 2.3rem;
285 | margin-top: 110px;
286 | }
287 |
288 | .title::after {
289 | width: 80px;
290 | }
291 |
292 | .project_container {
293 | width: 970px;
294 | grid-template-columns: auto auto auto;
295 | }
296 |
297 | .name {
298 | font-size: 1.3rem;
299 | }
300 | }
301 |
302 | @media screen and (min-width: 1400px) {
303 | .project_container {
304 | width: 1062px;
305 | }
306 |
307 | .card_text {
308 | gap: 60px;
309 | }
310 |
311 | .name {
312 | font-size: 1.35rem;
313 | }
314 |
315 | .tech_list {
316 | font-size: 0.8rem;
317 | }
318 |
319 | .btn_container {
320 | padding: 12px 20px;
321 | }
322 |
323 | .btn_hover {
324 | left: 20px;
325 | }
326 | }
327 |
--------------------------------------------------------------------------------
/src/constants/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | linkedin, instagram, twitter, github, linkedin1, instagram1, twitter1, github1, tvshowbox, guesstheword, tictactoe, mathmagician, metricwebapp, spacetravelers, recipeapp, trackbudget, carrental, guesstheword1, guesstheword2, guesstheword3, spacetravelers1, spacetravelers2, spacetravelers3, tictactoe1, tictactoe2, tictactoe3, tvshow1, tvshow2, tvshow3, metricswebapp1, metricswebapp2, recipeapp3, recipeapp4, recipeapp6, trackbuget1, trackbuget2, trackbuget5, carrental1, carrental2, carrental3, responsive, react, fullstack,
3 | } from '../assets';
4 |
5 | const social = [
6 | {
7 | id: 1,
8 | name: 'LinkedIn',
9 | url: 'https://www.linkedin.com/in/antonio-fernandez-364928372',
10 | icon: linkedin,
11 | icon1: linkedin1,
12 | },
13 | {
14 | id: 2,
15 | name: 'Instagram',
16 | url: 'https://www.instagram.com/Antonio-Fernandez',
17 | icon: instagram,
18 | icon1: instagram1,
19 | },
20 | {
21 | id: 3,
22 | name: 'Twitter',
23 | url: 'https://twitter.com/Antonio-Fernandez',
24 | icon: twitter,
25 | icon1: twitter1,
26 | },
27 | {
28 | id: 4,
29 | name: 'Github',
30 | url: 'https://github.com/mybuddy4305',
31 | icon: github,
32 | icon1: github1,
33 | },
34 | ];
35 |
36 | const technologies = [
37 | {
38 | stack: ['languages', 'all'],
39 | name: 'HTML 5',
40 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/html5/html5-plain.svg',
41 | },
42 | {
43 | stack: ['languages', 'all'],
44 | name: 'CSS 3',
45 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/css3/css3-plain.svg',
46 | },
47 | {
48 | stack: ['languages', 'all'],
49 | name: 'JavaScript',
50 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-plain.svg',
51 | },
52 | {
53 | stack: ['languages', 'all'],
54 | name: 'Typescript',
55 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg',
56 | },
57 | {
58 | stack: ['languages', 'all'],
59 | name: 'C#',
60 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/csharp/csharp-original.svg',
61 | },
62 | {
63 | stack: ['languages', 'all'],
64 | name: 'Java',
65 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/php/php-original.svg',
66 | },
67 | {
68 | stack: ['languages', 'all'],
69 | name: 'PHP',
70 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/java/java-original.svg',
71 | },
72 | {
73 | stack: ['languages', 'all'],
74 | name: 'SQL',
75 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/mysql/mysql-original.svg',
76 | },
77 | {
78 | stack: ['languages', 'all'],
79 | name: 'Ruby',
80 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/ruby/ruby-plain.svg',
81 | },
82 | {
83 | stack: ['languages', 'all'],
84 | name: 'Python',
85 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg',
86 | },
87 | {
88 | stack: ['Front-End', 'all'],
89 | name: 'React JS',
90 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/react/react-original.svg',
91 | },
92 | {
93 | stack: ['Front-End', 'all'],
94 | name: 'Vue 3',
95 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/vuejs/vuejs-original.svg',
96 | },
97 | {
98 | stack: ['Front-End', 'all'],
99 | name: 'Nuxt 3',
100 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nuxtjs/nuxtjs-original.svg',
101 | },
102 | {
103 | stack: ['Front-End', 'all'],
104 | name: 'Redux Toolkit',
105 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/redux/redux-original.svg',
106 | },
107 | {
108 | stack: ['Front-End', 'all'],
109 | name: 'Bootstrap',
110 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/bootstrap/bootstrap-plain.svg',
111 | },
112 | {
113 | stack: ['Front-End', 'all'],
114 | name: 'Tailwind CSS',
115 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/tailwindcss/tailwindcss-original-wordmark.svg',
116 | },
117 | {
118 | stack: ['Front-End', 'all'],
119 | name: 'Next.js',
120 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nextjs/nextjs-original.svg',
121 | },
122 | {
123 | stack: ['Front-End', 'all'],
124 | name: 'Angular',
125 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/angularjs/angularjs-original.svg',
126 | },
127 | {
128 | stack: ['Back-End', 'all'],
129 | name: 'NestJS',
130 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/nestjs/nestjs-original.svg',
131 | },
132 | {
133 | stack: ['Back-End', 'all'],
134 | name: 'Nuxt 3',
135 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nuxtjs/nuxtjs-original.svg',
136 | },
137 | {
138 | stack: ['Back-End', 'all'],
139 | name: 'Spring Boot',
140 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/spring/spring-original.svg',
141 | },
142 | {
143 | stack: ['Back-End', 'all'],
144 | name: 'Symfony',
145 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/symfony/symfony-original.svg',
146 | },
147 | {
148 | stack: ['Back-End', 'all'],
149 | name: 'Laravel',
150 | icon: ' https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/laravel/laravel-original.svg',
151 | },
152 | {
153 | stack: ['Back-End', 'all'],
154 | name: 'Ruby on Rails',
155 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/rails/rails-plain.svg',
156 | },
157 | {
158 | stack: ['Back-End', 'all'],
159 | name: 'RSpec',
160 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/rspec/rspec-original.svg',
161 | },
162 | {
163 | stack: ['Back-End', 'all'],
164 | name: 'Django',
165 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/django/django-plain.svg',
166 | },
167 | {
168 | stack: ['Back-End', 'all'],
169 | name: '.NET Core',
170 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/dot-net/dot-net-original.svg',
171 | },
172 | {
173 | stack: ['Back-End', 'all'],
174 | name: 'GraphQL',
175 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/graphql/graphql-plain.svg',
176 | },
177 | {
178 | stack: ['Cloud & DevOps', 'all'],
179 | name: 'AWS',
180 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/amazonwebservices/amazonwebservices-original-wordmark.svg',
181 | },
182 | {
183 | stack: ['Cloud & DevOps', 'all'],
184 | name: 'Terraform',
185 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/dot-net/dot-net-original.svg',
186 | },
187 | {
188 | stack: ['Data & APIs', 'all'],
189 | name: 'MongoDB',
190 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/mongodb/mongodb-original.svg',
191 | },
192 | {
193 | stack: ['Data & APIs', 'all'],
194 | name: 'MySQL',
195 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/mysql/mysql-original.svg',
196 | },
197 | {
198 | stack: ['Data & APIs', 'all'],
199 | name: 'Redis',
200 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/redis/redis-original.svg',
201 | },
202 | {
203 | stack: ['Data & APIs', 'all'],
204 | name: 'Kafka',
205 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/apachekafka/apachekafka-original.svg',
206 | },
207 | {
208 | stack: ['Data & APIs', 'all'],
209 | name: 'RabbitMQ',
210 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/rabbitmq/rabbitmq-original.svg',
211 | },
212 | {
213 | stack: ['Data & APIs', 'all'],
214 | name: 'OAuth2',
215 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/oauth/oauth-original.svg',
216 | },
217 | {
218 | stack: ['Data & APIs', 'all'],
219 | name: 'PostgreSQL',
220 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/postgresql/postgresql-plain.svg',
221 | },
222 | {
223 | stack: ['AI & integrations', 'all'],
224 | name: 'OpenAI API',
225 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/openapi/openapi-original.svg',
226 | },
227 | {
228 | stack: ['AI & integrations', 'all'],
229 | name: 'Supabase',
230 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/supabase/supabase-original.svg',
231 | },
232 | {
233 | stack: ['Testing & Security', 'all'],
234 | name: 'Jest',
235 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/jest/jest-plain.svg',
236 | },
237 | {
238 | stack: ['Testing & Security', 'all'],
239 | name: 'Cypressio',
240 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cypressio/cypressio-original.svg',
241 | },
242 | {
243 | stack: ['Cloud & DevOps', 'all'],
244 | name: 'Git',
245 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/git/git-plain.svg',
246 | },
247 | {
248 | stack: ['Cloud & DevOps', 'all'],
249 | name: 'GitHub',
250 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/github/github-original.svg',
251 | },
252 | {
253 | stack: ['Cloud & DevOps', 'all'],
254 | name: 'Docker',
255 | icon: 'https://img.icons8.com/?size=100&id=cdYUlRaag9G9&format=png&color=000000',
256 | },
257 | {
258 | stack: ['WordPress', 'all'],
259 | name: 'WordPress',
260 | icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/wordpress/wordpress-original.svg',
261 | },
262 | // {
263 | // stack: ['tools', 'all'],
264 | // name: 'Postman',
265 | // icon: 'https://www.vectorlogo.zone/logos/getpostman/getpostman-icon.svg',
266 | // },
267 | ];
268 |
269 | const projects = [
270 | {
271 | id: 1,
272 | name: 'Car Rental App',
273 | desc: 'The Car Rental App is a comprehensive full-stack application where you can seamlessly explore an array of cars, search by name, delve into comprehensive car details, make reservations when logged in, manage reservations, add or delete cars in the database, and personalize your profile with ease.',
274 | tech: ['React', 'Redux', 'Ruby on Rails', 'PostgreSQL'],
275 | img: carrental,
276 | carousel: [carrental1, carrental2, carrental3],
277 | source_link: 'https://github.com/Rhaegar121/Car-Rental-front-end',
278 | live_link: 'https://car-rental121.netlify.app/',
279 | },
280 | {
281 | id: 2,
282 | name: 'Recipe App',
283 | desc: 'The Recipe app keeps track of all your foods, recipes, and ingredients. It allows you to save ingredients, keep track of what you have, create recipes, and generate a shopping list based on what you have and what you are missing from a recipe. Since sharing recipes is an important part, it allows you to make them public so anyone can access them.',
284 | tech: ['Ruby', 'Ruby on Rails', 'PostgreSQL'],
285 | img: recipeapp,
286 | carousel: [recipeapp3, recipeapp4, recipeapp6],
287 | source_link: 'https://github.com/Rhaegar121/Recipe-App',
288 | live_link: 'https://recipe-app121-b8888e20687b.herokuapp.com/',
289 | },
290 | {
291 | id: 3,
292 | name: 'TV Shows Box',
293 | desc: 'TVshows Box is a web application showing multiple TV shows with the help of TVmaze API which contains both mobile and desktop versions. The webapp have 3 interfaces: - A home page, a popup window, and a contact page.',
294 | tech: ['HTML5', 'CSS3', 'JavaScript', 'TVmaze API'],
295 | img: tvshowbox,
296 | carousel: [tvshow1, tvshow2, tvshow3],
297 | source_link: 'https://github.com/Rhaegar121/TVshows_Box',
298 | live_link: 'https://tvshowbox.netlify.app/',
299 | },
300 | {
301 | id: 4,
302 | name: 'Metrics Webapp',
303 | desc: 'Metrics Webapp is a mobile web application showing the current weather data of the cities using the Openweather API. It has two interfaces - city page and detail page based on the design of Nelson Sakwa on Behance. Built during the Microverse Module 3 React Captone Project.',
304 | tech: ['React', 'Redux', 'Openweather API'],
305 | img: metricwebapp,
306 | carousel: [metricswebapp1, metricswebapp2],
307 | source_link: 'https://github.com/Rhaegar121/Metrics-Webapp',
308 | live_link: 'https://metrics-webapp121.netlify.app/',
309 | },
310 | {
311 | id: 5,
312 | name: 'Track Budget App',
313 | desc: 'Track Budget is a mobile web application where you can manage your budget: you have a list of purchases associated with a category, so that you can see how much money you spent and on what category.',
314 | tech: ['Ruby', 'Ruby on Rails', 'PostgreSQL'],
315 | img: trackbudget,
316 | carousel: [trackbuget1, trackbuget2, trackbuget5],
317 | source_link: 'https://github.com/Rhaegar121/Track-Budget',
318 | live_link: 'https://track-budget121-70a570d4e3e1.herokuapp.com/',
319 | },
320 | {
321 | id: 6,
322 | name: 'Math Magicians',
323 | desc: 'Math magicians is a website for all fans of mathematics. It is a Single Page App (SPA) that allows users to make simple calculations and read a random math-related quote.',
324 | tech: ['React'],
325 | img: mathmagician,
326 | carousel: [mathmagician],
327 | source_link: 'https://github.com/Rhaegar121/Math-Magicians',
328 | live_link: 'https://math-magicians121.netlify.app/',
329 | },
330 | {
331 | id: 7,
332 | name: 'Tic Tac Toe',
333 | desc: 'Tic Tac Toe is a simple and classic game that is played on a 3x3 grid. The game is typically played with two players, one using “X” and the other using “O”. Mainly built with JavaScript.',
334 | tech: ['HTML5', 'CSS3', 'JavaScript'],
335 | img: tictactoe,
336 | carousel: [tictactoe1, tictactoe2, tictactoe3],
337 | source_link: 'https://github.com/Rhaegar121/Tic-Tac-Toe',
338 | live_link: 'https://tic-tac-toe121.netlify.app/',
339 | },
340 | {
341 | id: 8,
342 | name: "Space Travelers' Hub",
343 | desc: "Space Travelers' Hub is a web application that provides commercial and scientific space travel services using the real live data from the SpaceX API. The application will allow users to book rockets and join selected space missions.",
344 | tech: ['React', 'Redux', 'SpaceX API'],
345 | img: spacetravelers,
346 | carousel: [spacetravelers1, spacetravelers2, spacetravelers3],
347 | source_link: 'https://github.com/Rhaegar121/React-Group-Project',
348 | live_link: 'https://space-travelers-hub121.netlify.app/',
349 | },
350 | {
351 | id: 9,
352 | name: 'Guess the word',
353 | desc: 'Guess The Word is a fun letter puzzle game where the player have to guess the hidden word using the clues that the game gives. The game ends if the player guesses the correct word or if he chooses the wrong letter 8 times. Mainly built with Javascript.',
354 | tech: ['HTML5', 'CSS3', 'JavaScript'],
355 | img: guesstheword,
356 | carousel: [guesstheword1, guesstheword2, guesstheword3],
357 | source_link: 'https://github.com/Rhaegar121/Guess-the-word',
358 | live_link: 'https://guess-the-word121.netlify.app/',
359 | },
360 | ];
361 |
362 | const testimonials = [
363 | {
364 | id: 1,
365 | name: 'Ahmed Hasan Rony',
366 | image: 'https://avatars.githubusercontent.com/u/77187003?v=4',
367 | text: 'I really am comfortable with collaborating and coding with Antonio. His ingenious ideas give me a lot of ideas solving a problem multiple ways.',
368 | country: 'Netherland',
369 | linkedIn: 'https://www.linkedin.com/in/hozyfa-b-nasir-7bOb2bb8/',
370 | },
371 | {
372 | id: 2,
373 | name: 'Ryker Nguyen',
374 | image: 'https://media.licdn.com/dms/image/D4D35AQHOKsZ2nSaTjg/profile-framedphoto-shrink_400_400/0/1665541124692?e=1721469600&v=beta&t=Evk76YZRsti88Lyr1khjrlxcZKF8v2hrbA3G7YLhIz4',
375 | text: "Throughout our collaboration, I was consistently impressed by Barry's professionalism, attention to detail, and ability to adapt to changing requirements.",
376 | country: 'Canada',
377 | linkedIn: 'https://www.linkedin.com/ryker-nguyen7111142368/',
378 | },
379 | {
380 | id: 3,
381 | name: 'Muhammad Talha Hanif',
382 | image: 'https://media.licdn.com/dms/image/D4D03AQF6A-cET7akGQ/profile-displayphoto-shrink_400_400/0/1687861230806?e=1726099200&v=beta&t=C1jrASsQ8AXgmkVrndSBMyBfh7eTBQ_pe2VG79FSNN0',
383 | text: 'He possesses a deep understanding of the latest technologies and trends in his field, allowing him to tackle complex challenges with ease.',
384 | country: 'Pakistan',
385 | linkedIn: 'https://www.linkedin.com/in/muhammad-talha-hanif/',
386 | },
387 | {
388 | id: 4,
389 | name: 'Jerome Osman',
390 | image: 'https://media.licdn.com/dms/image/D4D03AQE1F2tqE5cttw/profile-displayphoto-shrink_400_400/0/1694205105262?e=1726099200&v=beta&t=TYftRu2dWsY-5eUgZSsorbbURiQMGtGVOcmcJeDrsGQ',
391 | text: 'His kindness and patience with his peers makes him easy to work with no matter the difficulty, and that reflects as well when it comes to helping others in his team or explaining something when need be',
392 | country: 'South Africa',
393 | linkedIn: 'https://www.linkedin.com/in/jerome-osman/',
394 | },
395 | {
396 | id: 5,
397 | name: 'Innocent N.',
398 | image: 'https://media.licdn.com/dms/image/D5603AQE1qYMUswBOAw/profile-displayphoto-shrink_400_400/0/1688151359384?e=1726099200&v=beta&t=rkHvuiSC9ww8BOxUhz2cqpIdzAoW6ZUEWbJDQW5W5OU',
399 | text: 'Communication was another strength that Barry brought to the table. He actively listened, communicated ideas clearly, and collaborated effectively with team members.',
400 | country: 'Rwanda',
401 | linkedIn: 'https://www.linkedin.com/in/innocent-n/',
402 | },
403 | {
404 | id: 6,
405 | name: 'Marko Kermichiev',
406 | image: 'https://avatars.githubusercontent.com/u/112749658?v=4',
407 | text: 'I learned too much from you and I can say that you are fantastic developer. Working with you is always a pleasure, hope that we can work on some project asap.',
408 | country: 'Macedonia',
409 | linkedIn: 'https://www.linkedin.com/in/marko-kermichiev/',
410 | },
411 | ];
412 |
413 | const services = [
414 | {
415 | id: 1,
416 | icon: responsive,
417 | title: 'WordPress Development',
418 | text: 'WordPress development empowers businesses with scalable, user-friendly websites tailored for performance, SEO, and seamless content management.',
419 | },
420 | {
421 | id: 2,
422 | icon: react,
423 | title: 'Full-Stack Development',
424 | text: 'I breathe life into your creative ideas by translating them into captivating web interfaces. Using the latest frontend technologies and best practices, I build engaging, user-friendly websites that leave a lasting impression.',
425 | },
426 | {
427 | id: 3,
428 | icon: fullstack,
429 | title: 'Software Development',
430 | text: 'Software development drives innovation by delivering custom, efficient, and reliable digital solutions that solve real-world problems and accelerate growth.',
431 | },
432 | ];
433 |
434 | const navLinks = [
435 | {
436 | id: 1,
437 | name: 'About',
438 | url: '/#about',
439 | },
440 | {
441 | id: 2,
442 | name: 'Service',
443 | url: '/#service',
444 | },
445 | {
446 | id: 3,
447 | name: 'Work',
448 | url: '/#work',
449 | },
450 | {
451 | id: 4,
452 | name: 'Testimonial',
453 | url: '/#testimonial',
454 | },
455 | {
456 | id: 5,
457 | name: 'Contact',
458 | url: '/#contact',
459 | },
460 | ];
461 |
462 | export {
463 | technologies, projects, testimonials, social, services, navLinks,
464 | };
465 |
--------------------------------------------------------------------------------
/src/hoc/SectionWrapper.jsx:
--------------------------------------------------------------------------------
1 | import { motion } from 'framer-motion';
2 | import { useMediaQuery } from 'react-responsive';
3 | import { staggerContainer } from '../utils/motion';
4 |
5 | const SectionWrapper = (Component, idName, margin) => function HOC() {
6 | const isLargeScreen = useMediaQuery({ minWidth: 768 });
7 |
8 | return (
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default SectionWrapper;
26 |
--------------------------------------------------------------------------------
/src/hoc/index.js:
--------------------------------------------------------------------------------
1 | import SectionWrapper from './SectionWrapper';
2 |
3 | export default SectionWrapper;
4 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Bungee&family=Bungee+Inline&family=Bungee+Outline&family=Merriweather+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&family=Montserrat+Alternates:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
2 |
3 | @tailwind base;
4 | @tailwind components;
5 | @tailwind utilities;
6 |
7 | * {
8 | margin: 0;
9 | padding: 0;
10 | box-sizing: border-box;
11 | font-family: 'Calibre', 'Inter', 'San Francisco', 'SF Pro Text', -apple-system, system-ui, sans-serif;
12 | scroll-behavior: smooth;
13 | color-scheme: dark;
14 | }
15 |
16 | ::-webkit-scrollbar {
17 | width: 8.5px;
18 | height: 0;
19 | background-color: var(--dark-blue);
20 | }
21 |
22 | ::-webkit-scrollbar-thumb {
23 | background-color: var(--light-grey);
24 | border-radius: 8px;
25 | }
26 |
27 | .App {
28 | --navy: #030b25;
29 | --cyan: #22abfa;
30 | --white: #dfe7f3;
31 | --grey: #b1bcdc;
32 | --light-grey: #1b243f;
33 | --light-blue: #26517d;
34 | --dark-blue: #020716;
35 | --low-opacity: #000000cd;
36 | }
37 |
38 | .App.light {
39 | --navy: #dfe7f3;
40 | --cyan: #22abfa;
41 | --white: #020716;
42 | --grey: #030b25;
43 | --dark-blue: #fff;
44 | --light-grey: #dfe7f3;
45 | --light-blue: #26517d;
46 | --low-opacity: #ffffffcd;
47 | }
48 |
49 | .body {
50 | background-color: var(--navy);
51 | }
52 |
53 | .star-canvas {
54 | background-color: var(--dark-blue);
55 | }
56 |
57 | .green-pink-gradient {
58 | background: "#00cea8";
59 | background: -webkit-linear-gradient(-90.13deg, #00cea8 1.9%, #bf61ff 97.5%);
60 | background: linear-gradient(90.13deg, #00cea8 1.9%, #bf61ff 97.5%);
61 | }
62 |
63 | .grey-gradient {
64 | background: #3f4e85;
65 | background:
66 | -webkit-linear-gradient(
67 | -90deg,
68 | #3f4e85 0%,
69 | rgba(51, 53, 80, 0) 100%
70 | );
71 | background: linear-gradient(-90deg, #3f4e85 0%, rgba(51, 53, 80, 0) 100%);
72 | }
73 |
74 | .slick-slider {
75 | position: relative;
76 | width: 100%;
77 | margin-bottom: 30px;
78 | }
79 |
80 | .carousel-img {
81 | width: 100%;
82 | height: auto;
83 | margin: 0 auto;
84 | }
85 |
86 | .carousel-img img {
87 | width: 100%;
88 | height: 100%;
89 | object-fit: contain;
90 | }
91 |
92 | .slick-dots li button::before {
93 | font-size: 0.4rem !important;
94 | opacity: 1 !important;
95 | color: var(--white);
96 | }
97 |
98 | .slick-dots li.slick-active button::before {
99 | color: var(--cyan) !important;
100 | }
101 |
102 | .slick-arrow {
103 | top: 100% !important;
104 | z-index: 9;
105 | }
106 |
107 | .slick-prev {
108 | left: 0 !important;
109 | }
110 |
111 | .slick-next {
112 | right: 0 !important;
113 | }
114 |
115 | .slick-prev::before,
116 | .slick-next::before {
117 | font-family: "Montserrat Alternates", sans-serif !important;
118 | position: absolute;
119 | opacity: 1 !important;
120 | padding: 8px 10px 12px 10px;
121 | top: -36px !important;
122 | color: var(--white);
123 | background-color: var(--low-opacity);
124 | }
125 |
126 | .slick-prev::before {
127 | left: 0;
128 | }
129 |
130 | .slick-next::before {
131 | right: 0;
132 | }
133 |
134 | .contact {
135 | width: 100%;
136 | padding-bottom: 40px;
137 | background-color: var(--light-grey);
138 | background-image:
139 | linear-gradient(335deg, var(--dark-blue) 23px, transparent 23px),
140 | linear-gradient(155deg, var(--dark-blue) 23px, transparent 23px),
141 | linear-gradient(335deg, var(--dark-blue) 23px, transparent 23px),
142 | linear-gradient(155deg, var(--dark-blue) 23px, transparent 23px);
143 | background-size: 58px 58px;
144 | background-position: 0 2px, 4px 35px, 29px 31px, 34px 6px;
145 | }
146 |
147 | @media screen and (min-width: 768px) {
148 | .slick-prev::before,
149 | .slick-next::before {
150 | font-size: 1.8rem !important;
151 | top: -45px !important;
152 | }
153 | }
154 |
155 | @media screen and (min-width: 1200px) {
156 | .slick-prev::before,
157 | .slick-next::before {
158 | font-size: 2rem !important;
159 | padding: 10px 12px 14px 12px;
160 | top: -52px !important;
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './App';
4 | import './index.css';
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | );
11 |
--------------------------------------------------------------------------------
/src/utils/motion.js:
--------------------------------------------------------------------------------
1 | export const textVariant = (delay) => ({
2 | hidden: {
3 | y: -50,
4 | opacity: 0,
5 | },
6 | show: {
7 | y: 0,
8 | opacity: 1,
9 | transition: {
10 | type: 'spring',
11 | duration: 1.25,
12 | delay,
13 | },
14 | },
15 | });
16 |
17 | export const fadeIn = (direction, type, delay, duration) => {
18 | let hiddenX;
19 | let hiddenY;
20 |
21 | if (direction === 'left') {
22 | hiddenX = 100;
23 | } else if (direction === 'right') {
24 | hiddenX = -100;
25 | } else {
26 | hiddenX = 0;
27 | }
28 |
29 | if (direction === 'up') {
30 | hiddenY = 100;
31 | } else if (direction === 'down') {
32 | hiddenY = -100;
33 | } else {
34 | hiddenY = 0;
35 | }
36 |
37 | return {
38 | hidden: {
39 | x: hiddenX,
40 | y: hiddenY,
41 | opacity: 0,
42 | },
43 | show: {
44 | x: 0,
45 | y: 0,
46 | opacity: 1,
47 | transition: {
48 | type,
49 | delay,
50 | duration,
51 | ease: 'easeOut',
52 | },
53 | },
54 | exit: {
55 | x: 0,
56 | y: 10,
57 | opacity: 0,
58 | },
59 | };
60 | };
61 |
62 | export const zoomIn = (delay, duration) => ({
63 | hidden: {
64 | scale: 0,
65 | opacity: 0,
66 | },
67 | show: {
68 | scale: 1,
69 | opacity: 1,
70 | transition: {
71 | type: 'tween',
72 | delay,
73 | duration,
74 | ease: 'easeOut',
75 | },
76 | },
77 | });
78 |
79 | export const slideIn = (direction, type, delay, duration) => {
80 | let hiddenX;
81 | let hiddenY;
82 |
83 | if (direction === 'left') {
84 | hiddenX = '-100%';
85 | } else if (direction === 'right') {
86 | hiddenX = '100%';
87 | } else {
88 | hiddenX = 0;
89 | }
90 |
91 | if (direction === 'up') {
92 | hiddenY = '100%';
93 | } else if (direction === 'down') {
94 | hiddenY = '-100%';
95 | } else {
96 | hiddenY = 0;
97 | }
98 |
99 | return {
100 | hidden: {
101 | x: hiddenX,
102 | y: hiddenY,
103 | },
104 | show: {
105 | x: 0,
106 | y: 0,
107 | transition: {
108 | type,
109 | delay,
110 | duration,
111 | ease: 'easeOut',
112 | },
113 | },
114 | };
115 | };
116 |
117 | export const staggerContainer = (staggerChildren, delayChildren) => ({
118 | hidden: {},
119 | show: {
120 | transition: {
121 | staggerChildren,
122 | delayChildren: delayChildren || 0,
123 | },
124 | },
125 | });
126 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | './index.html',
5 | './src/**/*.{js,ts,jsx,tsx}',
6 | ],
7 | theme: {
8 | extend: {
9 | colors: {
10 | navy: '#030b25',
11 | // navy: '#26517d',
12 | cyan: '#22abfa',
13 | white: '#e6f1ff',
14 | grey: '#b1bcdc',
15 | light_grey: '#1b243f',
16 | dark_blue: '#02091d',
17 | },
18 | },
19 | },
20 | plugins: [],
21 | };
22 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'; // eslint-disable-line
2 | import react from '@vitejs/plugin-react'; // eslint-disable-line
3 |
4 | export default defineConfig({
5 | base: '/',
6 | plugins: [react()],
7 | build: {
8 | rollupOptions: {
9 | output: {
10 | manualChunks(id) {
11 | if (id.includes('node_modules')) {
12 | return id.toString().split('node_modules/')[1].split('/')[0].toString();
13 | }
14 | return null;
15 | },
16 | },
17 | },
18 | },
19 | });
20 |
--------------------------------------------------------------------------------