Chaithanya18 commited on
Commit
30eeea4
·
verified ·
1 Parent(s): 2dd394f

Upload 74 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .eslintrc.json +3 -0
  2. .gitattributes +12 -35
  3. .gitignore +17 -4
  4. README.md +32 -63
  5. next.config.mjs +6 -0
  6. package-lock.json +0 -0
  7. package.json +45 -31
  8. postcss.config.mjs +8 -0
  9. public/b1.jpg +0 -0
  10. public/b1.png +3 -0
  11. public/b1.svg +0 -0
  12. public/b2.jpg +3 -0
  13. public/b3.jpg +3 -0
  14. public/b4.svg +17 -0
  15. public/b5.jpg +3 -0
  16. public/b5.png +3 -0
  17. public/b5.svg +0 -0
  18. public/grid.svg +0 -0
  19. public/next.svg +1 -0
  20. public/partner01.svg +10 -0
  21. public/partner02.svg +5 -0
  22. public/partner03.svg +15 -0
  23. public/partner04.svg +4 -0
  24. public/sodaimage/bg.png +3 -0
  25. public/sodaimage/bg03.png +3 -0
  26. public/sodaimage/bg2.png +0 -0
  27. public/sodaimage/mockup.png +3 -0
  28. public/vercel.svg +1 -0
  29. public/works/works01.jpg +0 -0
  30. public/works/works02.jpg +3 -0
  31. public/works/works03.jpg +3 -0
  32. public/works/works04.jpg +0 -0
  33. public/works/works05.jpg +0 -0
  34. src/app/favicon.ico +0 -0
  35. src/app/globals.css +160 -0
  36. src/app/layout.tsx +28 -0
  37. src/app/page.tsx +17 -0
  38. src/components/About.tsx +52 -0
  39. src/components/CanvasMenu/Button/index.jsx +36 -0
  40. src/components/CanvasMenu/Button/style.module.scss +68 -0
  41. src/components/CanvasMenu/Nav/anim.js +44 -0
  42. src/components/CanvasMenu/Nav/data.js +37 -0
  43. src/components/CanvasMenu/Nav/index.jsx +54 -0
  44. src/components/CanvasMenu/Nav/style.module.scss +64 -0
  45. src/components/CanvasMenu/index.jsx +44 -0
  46. src/components/CanvasMenu/style.module.scss +17 -0
  47. src/components/Footer.tsx +130 -0
  48. src/components/Header.tsx +22 -0
  49. src/components/Hero.tsx +25 -0
  50. src/components/LostOrb/index.jsx +11 -0
.eslintrc.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "extends": "next/core-web-vitals"
3
+ }
.gitattributes CHANGED
@@ -1,35 +1,12 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+ public/b1.png filter=lfs diff=lfs merge=lfs -text
4
+ public/b2.jpg filter=lfs diff=lfs merge=lfs -text
5
+ public/b3.jpg filter=lfs diff=lfs merge=lfs -text
6
+ public/b5.jpg filter=lfs diff=lfs merge=lfs -text
7
+ public/b5.png filter=lfs diff=lfs merge=lfs -text
8
+ public/sodaimage/bg.png filter=lfs diff=lfs merge=lfs -text
9
+ public/sodaimage/bg03.png filter=lfs diff=lfs merge=lfs -text
10
+ public/sodaimage/mockup.png filter=lfs diff=lfs merge=lfs -text
11
+ public/works/works02.jpg filter=lfs diff=lfs merge=lfs -text
12
+ public/works/works03.jpg filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore CHANGED
@@ -4,20 +4,33 @@
4
  /node_modules
5
  /.pnp
6
  .pnp.js
 
7
 
8
  # testing
9
  /coverage
10
 
 
 
 
 
11
  # production
12
  /build
13
 
14
  # misc
15
  .DS_Store
16
- .env.local
17
- .env.development.local
18
- .env.test.local
19
- .env.production.local
20
 
 
21
  npm-debug.log*
22
  yarn-debug.log*
23
  yarn-error.log*
 
 
 
 
 
 
 
 
 
 
 
4
  /node_modules
5
  /.pnp
6
  .pnp.js
7
+ .yarn/install-state.gz
8
 
9
  # testing
10
  /coverage
11
 
12
+ # next.js
13
+ /.next/
14
+ /out/
15
+
16
  # production
17
  /build
18
 
19
  # misc
20
  .DS_Store
21
+ *.pem
 
 
 
22
 
23
+ # debug
24
  npm-debug.log*
25
  yarn-debug.log*
26
  yarn-error.log*
27
+
28
+ # local env files
29
+ .env*.local
30
+
31
+ # vercel
32
+ .vercel
33
+
34
+ # typescript
35
+ *.tsbuildinfo
36
+ next-env.d.ts
README.md CHANGED
@@ -1,81 +1,50 @@
1
- ---
2
- title: Web Agency
3
- emoji: 🐠
4
- colorFrom: indigo
5
- colorTo: red
6
- sdk: static
7
- pinned: false
8
- app_build_command: npm run build
9
- app_file: build/index.html
10
- ---
11
 
12
- # Getting Started with Create React App
13
 
14
- This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
15
 
16
- ## Available Scripts
17
 
18
- In the project directory, you can run:
 
19
 
20
- ### `npm start`
21
 
22
- Runs the app in the development mode.\
23
- Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
24
 
25
- The page will reload when you make changes.\
26
- You may also see any lint errors in the console.
 
27
 
28
- ### `npm test`
29
 
30
- Launches the test runner in the interactive watch mode.\
31
- See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
32
 
33
- ### `npm run build`
34
 
35
- Builds the app for production to the `build` folder.\
36
- It correctly bundles React in production mode and optimizes the build for the best performance.
 
 
 
 
37
 
38
- The build is minified and the filenames include the hashes.\
39
- Your app is ready to be deployed!
40
 
41
- See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
42
 
43
- ### `npm run eject`
 
 
44
 
45
- **Note: this is a one-way operation. Once you `eject`, you can't go back!**
 
46
 
47
- If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
 
48
 
49
- Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
 
50
 
51
- You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
52
-
53
- ## Learn More
54
-
55
- You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
56
-
57
- To learn React, check out the [React documentation](https://reactjs.org/).
58
-
59
- ### Code Splitting
60
-
61
- This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
62
-
63
- ### Analyzing the Bundle Size
64
-
65
- This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
66
-
67
- ### Making a Progressive Web App
68
-
69
- This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
70
-
71
- ### Advanced Configuration
72
-
73
- This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
74
-
75
- ### Deployment
76
-
77
- This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
78
-
79
- ### `npm run build` fails to minify
80
-
81
- This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
 
1
+ # Agency Website
 
 
 
 
 
 
 
 
 
2
 
3
+ Welcome to the **Agency Website** project! This is a modern, responsive website template built using **Next.js**. It's designed to showcase agency services with a sleek and interactive design, incorporating 3D elements using **Spline**, and animations with **Framer Motion**. The website is styled with **Tailwind CSS** and developed with **TypeScript** for robust type safety.
4
 
 
5
 
6
+ ## 🔗 Live Demo
7
 
8
+ Check out the live version of the Agency Website:
9
+ [**Live Demo**](https://agency01.vercel.app/)
10
 
11
+ ## 🚀 Purpose
12
 
13
+ The goal of this project is to provide a visually stunning and interactive website template for agencies. The website features:
 
14
 
15
+ - A modern, professional design.
16
+ - 3D elements and animations to enhance user experience.
17
+ - Responsive layout to ensure optimal viewing on all devices.
18
 
19
+ Built with **Next.js** for server-side rendering and static site generation, **Tailwind CSS** for utility-first styling, **Framer Motion** for animations, **Spline** for 3D graphics, and **TypeScript** for type safety, this template offers both flexibility and performance.
20
 
21
+ ## 🛠️ Frameworks & Technologies
 
22
 
23
+ This project utilizes the following technologies:
24
 
25
+ - **Next.js** - React framework for server-side rendering (SSR) and static site generation (SSG).
26
+ - **React** - For building the user interface with reusable components.
27
+ - **Tailwind CSS** - For utility-first styling and responsive design.
28
+ - **Framer Motion** - For smooth animations and interactive elements.
29
+ - **Spline** - For integrating 3D graphics into the website.
30
+ - **TypeScript** - For static type checking and improved code quality.
31
 
32
+ ## 📝 Setup & Customization
 
33
 
34
+ To get started with the project:
35
 
36
+ ```bash
37
+ # Clone the repository
38
+ git clone https://github.com/charltonkdev/agency-website.git
39
 
40
+ # Navigate to the project folder
41
+ cd agency-website
42
 
43
+ # Install dependencies
44
+ npm install
45
 
46
+ # Run the development server
47
+ npm run dev
48
 
49
+ # Open http://localhost:3000 in your browser to view the project
50
+ ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
next.config.mjs ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ };
4
+
5
+ export default nextConfig;
6
+
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json CHANGED
@@ -1,39 +1,53 @@
1
  {
2
- "name": "react-template",
3
  "version": "0.1.0",
4
  "private": true,
5
- "dependencies": {
6
- "@testing-library/dom": "^10.4.0",
7
- "@testing-library/jest-dom": "^6.6.3",
8
- "@testing-library/react": "^16.3.0",
9
- "@testing-library/user-event": "^13.5.0",
10
- "react": "^19.1.0",
11
- "react-dom": "^19.1.0",
12
- "react-scripts": "5.0.1",
13
- "web-vitals": "^2.1.4"
14
- },
15
  "scripts": {
16
- "start": "react-scripts start",
17
- "build": "react-scripts build",
18
- "test": "react-scripts test",
19
- "eject": "react-scripts eject"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  },
21
- "eslintConfig": {
22
- "extends": [
23
- "react-app",
24
- "react-app/jest"
25
- ]
 
 
 
 
 
26
  },
27
- "browserslist": {
28
- "production": [
29
- ">0.2%",
30
- "not dead",
31
- "not op_mini all"
32
- ],
33
- "development": [
34
- "last 1 chrome version",
35
- "last 1 firefox version",
36
- "last 1 safari version"
37
- ]
38
  }
39
  }
 
1
  {
2
+ "name": "agency01",
3
  "version": "0.1.0",
4
  "private": true,
 
 
 
 
 
 
 
 
 
 
5
  "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@react-three/drei": "^9.108.3",
13
+ "@react-three/fiber": "^8.16.8",
14
+ "@splinetool/react-spline": "^4.0.0",
15
+ "@splinetool/runtime": "^1.8.9",
16
+ "@studio-freight/lenis": "^1.0.42",
17
+ "@tabler/icons-react": "^3.9.0",
18
+ "@tsparticles/engine": "^3.5.0",
19
+ "@tsparticles/react": "^3.0.0",
20
+ "@tsparticles/slim": "^3.5.0",
21
+ "clsx": "^2.1.1",
22
+ "framer-motion": "^11.2.14",
23
+ "gsap": "^3.12.5",
24
+ "lenis": "^1.1.5",
25
+ "locomotive-scroll": "^4.1.4",
26
+ "mini-svg-data-uri": "^1.4.4",
27
+ "next": "14.2.4",
28
+ "react": "^18.3.1",
29
+ "react-dom": "^18.3.1",
30
+ "react-feather": "^2.0.10",
31
+ "react-icons": "^5.2.1",
32
+ "sass": "^1.77.6",
33
+ "simplex-noise": "^4.0.1",
34
+ "tailwind-merge": "^2.4.0",
35
+ "tailwindcss-animate": "^1.0.7",
36
+ "three": "^0.166.1",
37
+ "three-globe": "^2.31.1"
38
  },
39
+ "devDependencies": {
40
+ "@types/locomotive-scroll": "^4.1.3",
41
+ "@types/node": "^20",
42
+ "@types/react": "^18",
43
+ "@types/react-dom": "^18",
44
+ "eslint": "^8",
45
+ "eslint-config-next": "14.2.4",
46
+ "postcss": "^8",
47
+ "tailwindcss": "^3.4.1",
48
+ "typescript": "^5"
49
  },
50
+ "overrides": {
51
+ "three": "^0.166.1"
 
 
 
 
 
 
 
 
 
52
  }
53
  }
postcss.config.mjs ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ },
6
+ };
7
+
8
+ export default config;
public/b1.jpg ADDED
public/b1.png ADDED

Git LFS Details

  • SHA256: b9366120de5af663060001dcb82a54839d267f5337cec80f9f343fed4acff79c
  • Pointer size: 131 Bytes
  • Size of remote file: 135 kB
public/b1.svg ADDED
public/b2.jpg ADDED

Git LFS Details

  • SHA256: 2f1ca88be428908cf52cf4956225f3c555ae24eea4ccfb6bbd6c1c2ec0433b7e
  • Pointer size: 131 Bytes
  • Size of remote file: 160 kB
public/b3.jpg ADDED

Git LFS Details

  • SHA256: 72b003eefdf1e3194158407f8b5891736b978b57b27dbce5df318faf8c938dfb
  • Pointer size: 131 Bytes
  • Size of remote file: 138 kB
public/b4.svg ADDED
public/b5.jpg ADDED

Git LFS Details

  • SHA256: 31eeb428fc9de8cb1a00239c0a8234955ec592b62fbe15fdadd8e001b20c2195
  • Pointer size: 131 Bytes
  • Size of remote file: 122 kB
public/b5.png ADDED

Git LFS Details

  • SHA256: 0f48710b1b33948d9c49ec28bfd8f7490921165f9978606b9d324dfde9be872b
  • Pointer size: 131 Bytes
  • Size of remote file: 998 kB
public/b5.svg ADDED
public/grid.svg ADDED
public/next.svg ADDED
public/partner01.svg ADDED
public/partner02.svg ADDED
public/partner03.svg ADDED
public/partner04.svg ADDED
public/sodaimage/bg.png ADDED

Git LFS Details

  • SHA256: acf06ade24622bbc3aaa2be7ca1532e06cb3e3f49adfc4ace3fd38f561f7fbcc
  • Pointer size: 131 Bytes
  • Size of remote file: 368 kB
public/sodaimage/bg03.png ADDED

Git LFS Details

  • SHA256: ce0dbc02d06b60ddb77c09055680dcda7bcc8812dd8812ef1c1fbef6e8192eec
  • Pointer size: 132 Bytes
  • Size of remote file: 3.63 MB
public/sodaimage/bg2.png ADDED
public/sodaimage/mockup.png ADDED

Git LFS Details

  • SHA256: 380d93ffa1da9b7b49e8fd11e39e7d9035b89214dc361e059dec844b20549a57
  • Pointer size: 132 Bytes
  • Size of remote file: 7.37 MB
public/vercel.svg ADDED
public/works/works01.jpg ADDED
public/works/works02.jpg ADDED

Git LFS Details

  • SHA256: fd6c0924b5b3604bbdbb3b3e715357a453b9abc49ce59ddf1007c9d7954afb12
  • Pointer size: 131 Bytes
  • Size of remote file: 139 kB
public/works/works03.jpg ADDED

Git LFS Details

  • SHA256: de4531c61d3a90960a1bbc8d613938d08a289aa5c5640ba482af4a61b23b1f39
  • Pointer size: 131 Bytes
  • Size of remote file: 173 kB
public/works/works04.jpg ADDED
public/works/works05.jpg ADDED
src/app/favicon.ico ADDED
src/app/globals.css ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --foreground-rgb: 11, 13, 33;
7
+ --background-start-rgb: 214, 219, 220;
8
+ --background-end-rgb: 0, 0, 0;
9
+ }
10
+
11
+
12
+ body {
13
+ color: rgb(var(--background-start-rgb));
14
+ background: rgb(var(--foreground-rgb));
15
+ }
16
+
17
+ @layer utilities {
18
+ .text-balance {
19
+ text-wrap: balance;
20
+ }
21
+ }
22
+
23
+ html.lenis, html.lenis body {
24
+ height: auto;
25
+ }
26
+
27
+ .lenis.lenis-smooth {
28
+ scroll-behavior: auto !important;
29
+ }
30
+
31
+ .lenis.lenis-smooth [data-lenis-prevent] {
32
+ overscroll-behavior: contain;
33
+ }
34
+
35
+ .lenis.lenis-stopped {
36
+ overflow: hidden;
37
+ }
38
+
39
+ .lenis.lenis-smooth iframe {
40
+ pointer-events: none;
41
+ }
42
+
43
+ .creativeBtn{
44
+ transition: 0.3s ease-in-out;
45
+ position: relative;
46
+ overflow: hidden;
47
+ border: 1px solid #fff;
48
+ }
49
+ .creativeBtn:hover {
50
+ color: #fff;
51
+ }
52
+ .creativeBtn span {
53
+ position: relative;
54
+ z-index: 9;
55
+ }
56
+ .creativeBtn:after {
57
+ content: '';
58
+ width: 100px;
59
+ height: 100px;
60
+ border-radius: 100%;
61
+ background:#000;
62
+ position: absolute;
63
+ display: block;
64
+ left: 0;
65
+ top:calc(-5vh);
66
+ z-index: 0;
67
+ scale: 0;
68
+ transition: 0.3s ease-in-out;
69
+ }
70
+ .creativeBtn:hover:after{
71
+ scale: 1.2;
72
+ }
73
+
74
+
75
+ /* components/Banner.module.css */
76
+
77
+ .product {
78
+ position: absolute;
79
+ right: 0;
80
+ transform: translateX(60%);
81
+ bottom: calc(-10vw);
82
+ z-index: 2;
83
+ width: 500px;
84
+ transition: 0.7s;
85
+ }
86
+
87
+ .product .soda {
88
+ position: absolute;
89
+ bottom: 0;
90
+ right: 50%;
91
+ transform: translateX(-50%);
92
+ }
93
+
94
+ .soda {
95
+ --left: 0px;
96
+ background: var(--url) var(--left), url(/sodaimage/mockup.png) 0 0;
97
+ background-size: auto 100%;
98
+ width: 250px;
99
+ aspect-ratio: 2 / 4;
100
+ background-blend-mode: multiply;
101
+ transition: 0.8s;
102
+ mask-image: url(/sodaimage/mockup.png);
103
+ mask-size: auto 100%;
104
+ }
105
+
106
+ .soda:nth-child(2) {
107
+ opacity: 0;
108
+ }
109
+
110
+ .brandContainer:hover .product {
111
+ bottom: 100px;
112
+ }
113
+
114
+ .brandContainer:hover .product .soda:nth-child(2) {
115
+ opacity: 1;
116
+ --left: 500px;
117
+ }
118
+
119
+ .brandContainer:hover .product .soda:nth-child(1) {
120
+ opacity: 0;
121
+ --left: 500px;
122
+ }
123
+
124
+ @media screen and (max-width: 1023px) {
125
+ .soda {
126
+ width: 250px;
127
+ }
128
+ }
129
+
130
+ @media screen and (max-width: 767px) {
131
+ .soda {
132
+ width: 150px;
133
+ }
134
+ .product {
135
+ bottom: -260px;
136
+ }
137
+
138
+ .brandContainer:hover .product {
139
+ bottom: -150px;
140
+ }
141
+
142
+ .brandContainer:hover .product .soda:nth-child(2) {
143
+ --left: 300px;
144
+ }
145
+ }
146
+
147
+ @keyframes slideFadeInUp {
148
+ from {
149
+ opacity: 0;
150
+ transform: translateY(30px);
151
+ }
152
+ to {
153
+ opacity: 1;
154
+ transform: translateY(0);
155
+ }
156
+ }
157
+
158
+ .orbStyle {
159
+ animation: slideFadeInUp 1s ease forwards;
160
+ }
src/app/layout.tsx ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Metadata } from "next";
2
+ import { Inter } from "next/font/google";
3
+ import "./globals.css";
4
+ import Menu from "@/components/Menu";
5
+ import Footer from "@/components/Footer";
6
+
7
+ const inter = Inter({ subsets: ["latin"] });
8
+
9
+ export const metadata: Metadata = {
10
+ title: "Website Agency",
11
+ description: "We build your ideas",
12
+ };
13
+
14
+ export default function RootLayout({
15
+ children,
16
+ }: Readonly<{
17
+ children: React.ReactNode;
18
+ }>) {
19
+ return (
20
+ <html lang="en">
21
+ <body className={`${inter.className} overflow-x-hidden relative`} >
22
+ <Menu />
23
+ {children}
24
+ <Footer />
25
+ </body>
26
+ </html>
27
+ );
28
+ }
src/app/page.tsx ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import About from "@/components/About";
2
+ import Hero from "@/components/Hero";
3
+ import Services from '@/components/Services';
4
+ import LenisScroll from '@/components/ui/LenisScroll';
5
+ import Works from "@/components/Works";
6
+
7
+ export default function Home() {
8
+ return (
9
+ <main className='flex relative min-h-screen flex-col items-center justify-between overflow-x-hidden'>
10
+ <LenisScroll />
11
+ <Hero />
12
+ <About />
13
+ <Services />
14
+ <Works />
15
+ </main>
16
+ );
17
+ }
src/components/About.tsx ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use client'
2
+ import React, { useRef, useEffect, useState } from 'react';
3
+ import { motion } from "framer-motion";
4
+
5
+ const About = () => {
6
+ const [isVisible, setIsVisible] = useState(false);
7
+ const [hasAnimated, setHasAnimated] = useState(false);
8
+ const ref = useRef<HTMLDivElement>(null);
9
+
10
+ useEffect(() => {
11
+ const observer = new IntersectionObserver(
12
+ ([entry]) => {
13
+ if (entry.isIntersecting && !hasAnimated) {
14
+ setIsVisible(true);
15
+ setHasAnimated(true); // Ensure the animation plays only once
16
+ } else if (!entry.isIntersecting && entry.boundingClientRect.top > 0) {
17
+ setIsVisible(false);
18
+ setHasAnimated(false); // Reset the animation when scrolling up
19
+ }
20
+ },
21
+ {
22
+ threshold: 0.5, // Adjust threshold as needed
23
+ }
24
+ );
25
+
26
+ if (ref.current) {
27
+ observer.observe(ref.current);
28
+ }
29
+
30
+ return () => {
31
+ if (ref.current) {
32
+ observer.unobserve(ref.current);
33
+ }
34
+ };
35
+ }, [hasAnimated]);
36
+
37
+ return (
38
+ <div className='relative flex flex-col w-full h-screen p-12 lg:p-24 justify-center items-center bg-black z-10'>
39
+ <motion.div
40
+ ref={ref}
41
+ initial={{ opacity: 0, y: 50 }}
42
+ animate={isVisible ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
43
+ transition={{ duration: 0.5 }}
44
+ className='flex z-50 flex-col w-full text-xl leading-[2] md:text-3xl max-w-4xl md:leading-[2]'
45
+ >
46
+ Welcome to iDEA agency, where creativity meets technology. We are a team of passionate designers and developers dedicated to crafting stunning websites that not only look great but also deliver exceptional user experiences. With years of industry experience, we specialize in creating custom digital solutions tailored to your business needs. Our mission is to elevate your brand online and help you stand out in the digital landscape.
47
+ </motion.div>
48
+ </div>
49
+ );
50
+ };
51
+
52
+ export default About;
src/components/CanvasMenu/Button/index.jsx ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { motion } from 'framer-motion';
2
+ import styles from './style.module.scss';
3
+
4
+ export default function Button({isActive, toggleMenu}) {
5
+ return (
6
+ <div className={styles.button}>
7
+ <motion.div
8
+ className={styles.slider}
9
+ animate={{top: isActive ? "-100%" : "0%"}}
10
+ transition={{ duration: 0.5, type: "tween", ease: [0.76, 0, 0.24, 1]}}
11
+ >
12
+ <div
13
+ className={styles.el}
14
+ onClick={() => {toggleMenu()}}
15
+ >
16
+ <PerspectiveText label="Menu"/>
17
+ </div>
18
+ <div
19
+ className={styles.el}
20
+ onClick={() => {toggleMenu()}}
21
+ >
22
+ <PerspectiveText label="Close" />
23
+ </div>
24
+ </motion.div>
25
+ </div>
26
+ )
27
+ }
28
+
29
+ function PerspectiveText({label}) {
30
+ return (
31
+ <div className={styles.perspectiveText}>
32
+ <p>{label}</p>
33
+ <p>{label}</p>
34
+ </div>
35
+ )
36
+ }
src/components/CanvasMenu/Button/style.module.scss ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .button{
2
+ position: absolute;
3
+ top: 0;
4
+ right: 0;
5
+ width: 100px;
6
+ height: 40px;
7
+ cursor: pointer;
8
+ border-radius: 25px;
9
+ overflow: hidden;
10
+
11
+ .slider{
12
+ position: relative;
13
+ width: 100%;
14
+ height: 100%;
15
+
16
+ .el{
17
+ width: 100%;
18
+ height: 100%;
19
+ background-color: #D35A0A;
20
+ p{
21
+ margin: 0px;
22
+ }
23
+ &:nth-of-type(2){
24
+ background-color: #000;
25
+ p{
26
+ color: #fff;
27
+ }
28
+ }
29
+ &:hover{
30
+ .perspectiveText{
31
+ transform: rotateX(90deg);
32
+ p{
33
+ &:nth-of-type(1){
34
+ transform: translateY(-100%);
35
+ opacity: 0;
36
+ }
37
+ &:nth-of-type(2){
38
+ opacity: 1;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ }
47
+
48
+ .perspectiveText{
49
+ display: flex;
50
+ flex-direction: column;
51
+ justify-content: center;
52
+ align-items: center;
53
+ height: 100%;
54
+ width: 100%;
55
+ transform-style: preserve-3d;
56
+ transition: transform 0.5s cubic-bezier(0.6, 0, 0.24, 1);
57
+ p{
58
+ transition: all 0.5s cubic-bezier(0.6, 0, 0.24, 1);
59
+ pointer-events: none;
60
+ text-transform: uppercase;
61
+ &:nth-of-type(2){
62
+ position: absolute;
63
+ transform-origin: bottom center;
64
+ transform: rotateX(-90deg) translateY(9px);
65
+ opacity: 0;
66
+ }
67
+ }
68
+ }
src/components/CanvasMenu/Nav/anim.js ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const perspective = {
2
+ initial: {
3
+ opacity: 0,
4
+ rotateX: 90,
5
+ translateY: 80,
6
+ translateX: -20,
7
+ },
8
+ enter: (i) => ({
9
+ opacity: 1,
10
+ rotateX: 0,
11
+ translateY: 0,
12
+ translateX: 0,
13
+ transition: {
14
+ duration: 0.65,
15
+ delay: 0.5 + (i * 0.1),
16
+ ease: [.215,.61,.355,1],
17
+ opacity: { duration: 0.35}
18
+ }
19
+ }),
20
+ exit: {
21
+ opacity: 0,
22
+ transition: { duration: 0.5, type: "linear", ease: [0.76, 0, 0.24, 1]}
23
+ }
24
+ }
25
+
26
+ export const slideIn = {
27
+ initial: {
28
+ opacity: 0,
29
+ y: 20
30
+ },
31
+ enter: (i) => ({
32
+ opacity: 1,
33
+ y: 0,
34
+ transition: {
35
+ duration: 0.5,
36
+ delay: 0.75 + (i * 0.1),
37
+ ease: [.215,.61,.355,1]
38
+ }
39
+ }),
40
+ exit: {
41
+ opacity: 0,
42
+ transition: { duration: 0.5, type: "tween", ease: "easeInOut"}
43
+ }
44
+ }
src/components/CanvasMenu/Nav/data.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const links = [
2
+ {
3
+ title: "About",
4
+ href: "/"
5
+ },
6
+ {
7
+ title: "Works",
8
+ href: "/"
9
+ },
10
+ {
11
+ title: "Services",
12
+ href: "/"
13
+ },
14
+ {
15
+ title: "Contact",
16
+ href: "/"
17
+ }
18
+ ]
19
+
20
+ export const footerLinks = [
21
+ {
22
+ title: "Facebook",
23
+ href: "/"
24
+ },
25
+ {
26
+ title: "LinkedIn",
27
+ href: "/"
28
+ },
29
+ {
30
+ title: "Instagram",
31
+ href: "/"
32
+ },
33
+ {
34
+ title: "Twitter",
35
+ href: "/"
36
+ }
37
+ ]
src/components/CanvasMenu/Nav/index.jsx ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import styles from "./style.module.scss";
2
+ import { motion } from "framer-motion";
3
+ import { links, footerLinks } from "./data";
4
+ import Image from "next/image";
5
+ import { perspective, slideIn } from "./anim";
6
+ import clsx from "clsx";
7
+
8
+ export default function index() {
9
+ return (
10
+ <div className={styles.mainNav}>
11
+ <div className={styles.nav}>
12
+ <div className={clsx(styles.body)}>
13
+ {links.map((link, i) => {
14
+ const { title, href } = link;
15
+ return (
16
+ <div key={`b_${i}`} className={styles.linkContainer}>
17
+ <motion.div
18
+ href={href}
19
+ custom={i}
20
+ variants={slideIn}
21
+ initial="initial"
22
+ animate="enter"
23
+ exit="exit"
24
+ >
25
+ <a>{title}</a>
26
+ </motion.div>
27
+ </div>
28
+ );
29
+ })}
30
+ </div>
31
+ <motion.div className={styles.footer}>
32
+ {footerLinks.map((link, i) => {
33
+ const { title, href } = link;
34
+ return (
35
+ <motion.a
36
+ variants={slideIn}
37
+ custom={i}
38
+ initial="initial"
39
+ animate="enter"
40
+ exit="exit"
41
+ key={`f_${i}`}
42
+ >
43
+ {title}
44
+ </motion.a>
45
+ );
46
+ })}
47
+ </motion.div>
48
+ </div>
49
+ <div className="relative block w-[100vw] h-[50vh] pt-[100px]">
50
+ <Image alt src="/b5.jpg" objectFit="cover" width={1280} height={1080}/>
51
+ </div>
52
+ </div>
53
+ );
54
+ }
src/components/CanvasMenu/Nav/style.module.scss ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .nav{
2
+ display: flex;
3
+ flex-direction: column;
4
+ justify-content: space-between;
5
+ padding: 100px 40px 50px 40px;
6
+ height: 75vh;
7
+ box-sizing: border-box;
8
+ position: relative;
9
+ .body{
10
+ display: flex;
11
+ gap: 10px;
12
+ flex-direction: column;
13
+ .linkContainer{
14
+ perspective: 120px;
15
+ perspective-origin: bottom;
16
+ }
17
+ a{
18
+ text-decoration: none;
19
+ color: #000;
20
+ font-size: 46px;
21
+ width: max-content;
22
+ display: block;
23
+ transition: 0.2s ease-in-out;
24
+ overflow: hidden;
25
+ cursor: pointer;
26
+ }
27
+ a:after {
28
+ content: '';
29
+ display: block;
30
+ position: relative;
31
+ width: 100%;
32
+ height: 3px;
33
+ background: #000;
34
+ transform: translateX(-100%);
35
+ transition: .3s ease-in-out;
36
+ }
37
+ a:hover:after {
38
+ transform: translateX(0);
39
+ transition: .3s ease-in-out;
40
+ }
41
+ }
42
+ .footer{
43
+ display: flex;
44
+ flex-wrap: wrap;
45
+ a{
46
+ width: 50%;
47
+ margin-top: 5px;
48
+ }
49
+ }
50
+ }
51
+
52
+ .mainNav {
53
+ display: grid;
54
+ position: relative;
55
+ grid-template-columns: repeat(2, minmax(0, 1fr));
56
+ }
57
+
58
+ @media (max-width: 1024px){
59
+ .mainNav {
60
+ display: flex !important;
61
+ flex-direction: column !important;
62
+
63
+ }
64
+ }
src/components/CanvasMenu/index.jsx ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use client';
2
+ import { useState } from 'react'
3
+ import { AnimatePresence, motion } from 'framer-motion';
4
+ import Button from './Button';
5
+ import styles from './style.module.scss';
6
+ import Nav from './Nav';
7
+ import clsx from 'clsx';
8
+
9
+ const menu = {
10
+ open: {
11
+ width: "88vw",
12
+ height: "75vh",
13
+ top: "-25px",
14
+ right: "-25px",
15
+ transition: { duration: 0.5, type: "tween", ease: [0.76, 0, 0.24, 1] }
16
+ },
17
+ closed: {
18
+ width: "100px",
19
+ height: "40px",
20
+ top: "0px",
21
+ right: "0px",
22
+ transition: { duration: 0.5, delay: 0.35, type: "tween", ease: [0.76, 0, 0.24, 1] }
23
+ }
24
+ }
25
+
26
+ export default function Index() {
27
+ const [isActive, setIsActive] = useState(false);
28
+
29
+ return (
30
+ <div className={styles.header}>
31
+ <motion.div
32
+ className={clsx(styles.menu)}
33
+ variants={menu}
34
+ animate={isActive ? "open" : "closed"}
35
+ initial="closed"
36
+ >
37
+ <AnimatePresence>
38
+ {isActive && <Nav />}
39
+ </AnimatePresence>
40
+ </motion.div>
41
+ <Button isActive={isActive} toggleMenu={() => { setIsActive(!isActive) }} />
42
+ </div>
43
+ )
44
+ }
src/components/CanvasMenu/style.module.scss ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .header {
2
+ position: fixed;
3
+ right: 50px;
4
+ top: 50px;
5
+ z-index: 99;
6
+ .menu {
7
+ width: 480px;
8
+ height: 650px;
9
+ background-color: #fff;
10
+ border-radius: 25px;
11
+ overflow: hidden;
12
+ position: relative;
13
+ a {
14
+ color: #000;
15
+ }
16
+ }
17
+ }
src/components/Footer.tsx ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use client'
2
+ import { useRef, useEffect } from 'react';
3
+ import { gsap } from 'gsap';
4
+
5
+ export function Footer() {
6
+ const listItemsRef = useRef<(HTMLLIElement | null)[]>([]);
7
+ const spanItemsRef = useRef<(HTMLSpanElement | null)[]>([]);
8
+
9
+ useEffect(() => {
10
+ const handleMouseEnter = (item: HTMLElement) => {
11
+ const textInitial = item.querySelector('.initial');
12
+ const textHover = item.querySelector('.hover');
13
+ gsap.to(textInitial, {
14
+ yPercent: -100,
15
+ perspective: 1000,
16
+ rotationX: 90,
17
+ duration: 1,
18
+ ease: 'power4.out',
19
+ });
20
+ gsap.to(textHover, {
21
+ yPercent: 0,
22
+ perspective: 1000,
23
+ rotationX: 0,
24
+ duration: 1,
25
+ ease: 'power4.out',
26
+ });
27
+ };
28
+
29
+ const handleMouseLeave = (item: HTMLElement) => {
30
+ const textInitial = item.querySelector('.initial');
31
+ const textHover = item.querySelector('.hover');
32
+ gsap.to(textInitial, {
33
+ yPercent: 0,
34
+ perspective: 1000,
35
+ rotationX: 0,
36
+ duration: 1,
37
+ ease: 'power4.out',
38
+ });
39
+ gsap.to(textHover, {
40
+ yPercent: 100,
41
+ perspective: 1000,
42
+ rotationX: -90,
43
+ duration: 1,
44
+ ease: 'power4.out',
45
+ });
46
+ };
47
+
48
+ const addEventListeners = (item: HTMLElement | null) => {
49
+ if (!item) return;
50
+ const textHover = item.querySelector('.hover');
51
+ gsap.set(textHover, { yPercent: 100, perspective: 1000, rotationX: -90 });
52
+
53
+ const enterHandler = () => handleMouseEnter(item);
54
+ const leaveHandler = () => handleMouseLeave(item);
55
+
56
+ item.addEventListener('mouseenter', enterHandler);
57
+ item.addEventListener('mouseleave', leaveHandler);
58
+
59
+ // Store handlers to remove them later
60
+ (item as any).__enterHandler = enterHandler;
61
+ (item as any).__leaveHandler = leaveHandler;
62
+ };
63
+
64
+ const removeEventListeners = (item: HTMLElement | null) => {
65
+ if (!item) return;
66
+ item.removeEventListener('mouseenter', (item as any).__enterHandler);
67
+ item.removeEventListener('mouseleave', (item as any).__leaveHandler);
68
+ };
69
+
70
+ listItemsRef.current.forEach(addEventListeners);
71
+ spanItemsRef.current.forEach(addEventListeners);
72
+
73
+ return () => {
74
+ listItemsRef.current.forEach(removeEventListeners);
75
+ spanItemsRef.current.forEach(removeEventListeners);
76
+ };
77
+ }, []);
78
+
79
+ return (
80
+ <footer className="flex relative flex-col container py-12 h-screen justify-evenly">
81
+ <div className='flex flex-col'>
82
+ <ul className="flex flex-col gap-5 uppercase w-24">
83
+ {['About', 'Services', 'Works', 'Contact'].map((text, index) => (
84
+ <li
85
+ key={index}
86
+ ref={(el) => { listItemsRef.current[index] = el; }}
87
+ className="relative overflow-hidden h-5 cursor-pointer"
88
+ >
89
+ <span className="block initial absolute top-0 left-0 w-full h-full">{text}</span>
90
+ <span className="block hover absolute top-0 left-0 w-full h-full">{text}</span>
91
+ </li>
92
+ ))}
93
+ </ul>
94
+ </div>
95
+ <div className='relative overflow-hidden group/line py-12 mx-auto w-fit cursor-pointer'>
96
+ <h1 className='w-full text-[12vw] uppercase leading-none'>Let&apos;s Talk</h1>
97
+ <span className='block w-full bg-white h-3 -translate-x-full group-hover/line:translate-x-0 duration-500 opacity-0 group-hover/line:opacity-100' />
98
+ </div>
99
+ <div className='w-full flex flex-col md:flex-row gap-10 justify-between'>
100
+ <div className='flex gap-10 uppercase'>
101
+ <div className=' relative overflow-hidden group/line cursor-pointer'>
102
+ <h1 className='leading-none pb-2'>mail</h1>
103
+ <span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
104
+ </div>
105
+ <div className=' relative overflow-hidden group/line cursor-pointer'>
106
+ <h1 className='leading-none pb-2'>github</h1>
107
+ <span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
108
+ </div>
109
+ <div className=' relative overflow-hidden group/line cursor-pointer'>
110
+ <h1 className='leading-none pb-2'>behance</h1>
111
+ <span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
112
+ </div>
113
+ <div className=' relative overflow-hidden group/line cursor-pointer'>
114
+ <h1 className='leading-none pb-2'>dribble</h1>
115
+ <span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
116
+ </div>
117
+ <div className=' relative overflow-hidden group/line cursor-pointer'>
118
+ <h1 className='leading-none pb-2'>linkedin</h1>
119
+ <span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
120
+ </div>
121
+ </div>
122
+ <div className='flex gap-10 uppercase'>
123
+ <span>2024 © CharltonK.dev</span>
124
+ </div>
125
+ </div>
126
+ </footer>
127
+ );
128
+ }
129
+
130
+ export default Footer;
src/components/Header.tsx ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react'
2
+ const Header = () => {
3
+ return (
4
+ <header className='w-full flex items-center relative justify-between'>
5
+ <div className='flex'>
6
+ <span className='text-2xl font-bold'>DNA</span>
7
+ </div>
8
+ <div className='flex items-center gap-10'>
9
+ <ul className='flex gap-10 text-gray-400'>
10
+ <li>Home</li>
11
+ <li>Service</li>
12
+ <li>Project</li>
13
+ <li>Contact</li>
14
+ </ul>
15
+ <span className='text-xl font-semibold'>Let&apos;s Talk</span>
16
+ </div>
17
+
18
+ </header>
19
+ )
20
+ }
21
+
22
+ export default Header
src/components/Hero.tsx ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { Spotlight } from "./ui/Spotlight";
3
+ import HeroContent from "./ui/HeroContent";
4
+ import LostOrb from "./ui/LostOrb";
5
+
6
+ export default function Hero() {
7
+ return (
8
+ <div className="flex flex-col h-screen w-full relative items-center justify-center bg-black bg-grid-white/[0.1]">
9
+ <div className="absolute pointer-events-none inset-0 flex items-center justify-center bg-black [mask-image:radial-gradient(ellipse_at_center,transparent_20%,black)]"></div>
10
+ <Spotlight
11
+ className="-top-40 left-0 md:left-60 md:-top-20"
12
+ fill="orange"
13
+ />
14
+ <Spotlight
15
+ className="-top-40 left-20 md:left-80 md:-top-20"
16
+ fill="blue"
17
+ />
18
+
19
+ <HeroContent />
20
+ <div className="w-full h-full absolute bottom-0">
21
+ <LostOrb />
22
+ </div>
23
+ </div>
24
+ );
25
+ }
src/components/LostOrb/index.jsx ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Spline from '@splinetool/react-spline/next';
2
+
3
+ export default function Home() {
4
+ return (
5
+ <main>
6
+ <Spline
7
+ scene="https://prod.spline.design/kVbOOfwISRC36KJd/scene.splinecode"
8
+ />
9
+ </main>
10
+ );
11
+ }