diff --git a/.gitignore b/.gitignore
index 5ef6a52..1788aa4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+.agents
+
diff --git a/package-lock.json b/package-lock.json
index b59d9ca..1da4bfc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,9 +8,13 @@
"name": "project-innovation",
"version": "0.1.0",
"dependencies": {
+ "@types/three": "^0.185.4",
+ "framer-motion": "^13.2.0",
+ "lucide-react": "^1.41.0",
"next": "16.3.4",
"react": "19.2.8",
- "react-dom": "19.2.8"
+ "react-dom": "19.2.8",
+ "three": "^0.185.1"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
@@ -35,7 +39,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/@babel/code-frame": {
@@ -278,6 +282,12 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@dimforge/rapier3d-compat": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
+ "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==",
+ "license": "Apache-2.0"
+ },
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
@@ -504,7 +514,7 @@
},
"funding": {
"type": "github",
- "url": "https://github.com/sponsors/nzakas"
+ "url": "https://github.com/Merch/nzakas"
}
},
"node_modules/@humanwhocodes/retry": {
@@ -518,7 +528,7 @@
},
"funding": {
"type": "github",
- "url": "https://github.com/sponsors/nzakas"
+ "url": "https://github.com/Merch/nzakas"
}
},
"node_modules/@img/colour": {
@@ -1087,7 +1097,7 @@
},
"funding": {
"type": "github",
- "url": "https://github.com/sponsors/Brooooooklyn"
+ "url": "https://github.com/Merch/Brooooooklyn"
},
"peerDependencies": {
"@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
@@ -1606,6 +1616,12 @@
"tailwindcss": "4.3.3"
}
},
+ "node_modules/@tweenjs/tween.js": {
+ "version": "23.1.3",
+ "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
+ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
+ "license": "MIT"
+ },
"node_modules/@tybys/wasm-util": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
@@ -1668,6 +1684,32 @@
"@types/react": "^19.2.0"
}
},
+ "node_modules/@types/stats.js": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
+ "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/three": {
+ "version": "0.185.4",
+ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.185.4.tgz",
+ "integrity": "sha512-gAsBIC07NIFrxjbf7tH2t71c38uulFfk/RFoC7FNBSjMRAQ8J1x/RBvusX0N5PJouaYFJawXQqfCQ0RKUx/1nA==",
+ "license": "MIT",
+ "dependencies": {
+ "@dimforge/rapier3d-compat": "~0.12.0",
+ "@tweenjs/tween.js": "~23.1.3",
+ "@types/stats.js": "*",
+ "@types/webxr": ">=0.5.17",
+ "fflate": "~0.8.2",
+ "meshoptimizer": "~1.1.1"
+ }
+ },
+ "node_modules/@types/webxr": {
+ "version": "0.5.24",
+ "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
+ "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.69.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.69.0.tgz",
@@ -1892,7 +1934,7 @@
"node": "18 || 20 || >=22"
},
"funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "url": "https://github.com/Merch/isaacs"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
@@ -2324,7 +2366,7 @@
},
"funding": {
"type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "url": "https://github.com/Merch/epoberezkin"
}
},
"node_modules/ansi-escapes": {
@@ -2340,7 +2382,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/ansi-regex": {
@@ -2403,7 +2445,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/array-includes": {
@@ -2426,7 +2468,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/array.prototype.findlast": {
@@ -2447,7 +2489,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/array.prototype.findlastindex": {
@@ -2469,7 +2511,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/array.prototype.flat": {
@@ -2488,7 +2530,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/array.prototype.flatmap": {
@@ -2507,7 +2549,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/array.prototype.tosorted": {
@@ -2546,7 +2588,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/ast-types-flow": {
@@ -2579,7 +2621,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/axe-core": {
@@ -2661,7 +2703,7 @@
},
{
"type": "github",
- "url": "https://github.com/sponsors/ai"
+ "url": "https://github.com/Merch/ai"
}
],
"license": "MIT",
@@ -2695,7 +2737,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
@@ -2726,7 +2768,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/callsites": {
@@ -2754,7 +2796,7 @@
},
{
"type": "github",
- "url": "https://github.com/sponsors/ai"
+ "url": "https://github.com/Merch/ai"
}
],
"license": "CC-BY-4.0"
@@ -2789,7 +2831,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/cli-truncate": {
@@ -2806,7 +2848,7 @@
"node": ">=20"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/client-only": {
@@ -2910,7 +2952,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/data-view-byte-length": {
@@ -2928,7 +2970,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/inspect-js"
+ "url": "https://github.com/Merch/inspect-js"
}
},
"node_modules/data-view-byte-offset": {
@@ -2946,7 +2988,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/debug": {
@@ -2989,7 +3031,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/define-properties": {
@@ -3007,7 +3049,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/detect-libc": {
@@ -3086,7 +3128,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/es-abstract": {
@@ -3155,7 +3197,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/es-abstract-get": {
@@ -3174,7 +3216,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/es-define-property": {
@@ -3285,7 +3327,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/escalade": {
@@ -3308,7 +3350,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/eslint": {
@@ -3409,7 +3451,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/eslint-import-resolver-node": {
@@ -3786,6 +3828,12 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fflate": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz",
+ "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==",
+ "license": "MIT"
+ },
"node_modules/file-entry-cache": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
@@ -3826,7 +3874,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/flat-cache": {
@@ -3863,7 +3911,30 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-13.2.0.tgz",
+ "integrity": "sha512-9E33ebgMaO33w1nN/jEdW8z3/GO483fMi4rqbMG9rt83XgW9QLKRe4NcmJ8s+fQ3O34++UHrIQwlIWGIWTITjA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^13.2.0",
+ "motion-utils": "^13.0.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
}
},
"node_modules/function-bind": {
@@ -3873,7 +3944,7 @@
"dev": true,
"license": "MIT",
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/function.prototype.name": {
@@ -3897,7 +3968,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/functions-have-names": {
@@ -3907,7 +3978,7 @@
"dev": true,
"license": "MIT",
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/generator-function": {
@@ -3940,7 +4011,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/get-intrinsic": {
@@ -3965,7 +4036,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/get-proto": {
@@ -3997,7 +4068,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/get-tsconfig": {
@@ -4036,7 +4107,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/globalthis": {
@@ -4053,7 +4124,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/gopd": {
@@ -4066,7 +4137,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/graceful-fs": {
@@ -4086,7 +4157,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/has-flag": {
@@ -4109,7 +4180,7 @@
"es-define-property": "^1.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/has-proto": {
@@ -4125,7 +4196,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/has-symbols": {
@@ -4138,7 +4209,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/has-tostringtag": {
@@ -4154,7 +4225,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/hasown": {
@@ -4200,7 +4271,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/typicode"
+ "url": "https://github.com/Merch/typicode"
}
},
"node_modules/ignore": {
@@ -4227,7 +4298,7 @@
"node": ">=6"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/imurmurhash": {
@@ -4270,7 +4341,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-async-function": {
@@ -4290,7 +4361,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-bigint": {
@@ -4306,7 +4377,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-boolean-object": {
@@ -4323,7 +4394,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-bun-module": {
@@ -4359,7 +4430,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-core-module": {
@@ -4375,7 +4446,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-data-view": {
@@ -4393,7 +4464,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-date-object": {
@@ -4410,7 +4481,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-document.all": {
@@ -4426,7 +4497,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-extglob": {
@@ -4452,7 +4523,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-fullwidth-code-point": {
@@ -4468,7 +4539,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/is-generator-function": {
@@ -4488,7 +4559,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-glob": {
@@ -4514,7 +4585,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-negative-zero": {
@@ -4527,7 +4598,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-number": {
@@ -4554,7 +4625,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-regex": {
@@ -4573,7 +4644,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-set": {
@@ -4586,7 +4657,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-shared-array-buffer": {
@@ -4602,7 +4673,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-string": {
@@ -4619,7 +4690,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-symbol": {
@@ -4637,7 +4708,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-typed-array": {
@@ -4653,7 +4724,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-weakmap": {
@@ -4666,7 +4737,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-weakref": {
@@ -4682,7 +4753,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/is-weakset": {
@@ -4699,7 +4770,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/isarray": {
@@ -4759,11 +4830,11 @@
"funding": [
{
"type": "github",
- "url": "https://github.com/sponsors/puzrin"
+ "url": "https://github.com/Merch/puzrin"
},
{
"type": "github",
- "url": "https://github.com/sponsors/nodeca"
+ "url": "https://github.com/Merch/nodeca"
}
],
"license": "MIT",
@@ -5176,7 +5247,7 @@
"node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "url": "https://github.com/Merch/jonschlinkert"
}
},
"node_modules/listr2": {
@@ -5210,7 +5281,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/lodash.merge": {
@@ -5237,7 +5308,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/log-update/node_modules/ansi-styles": {
@@ -5293,6 +5364,15 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/lucide-react": {
+ "version": "1.41.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.41.0.tgz",
+ "integrity": "sha512-6lksP35l6KszDKUeRTi4LV7i6DEe0Yzl2ALJm9j4c5xEYN91GdW1xGsawGMOg2mgjF5GHBVX8pKX9kP+cWsP3Q==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -5323,6 +5403,12 @@
"node": ">= 8"
}
},
+ "node_modules/meshoptimizer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz",
+ "integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==",
+ "license": "MIT"
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -5347,7 +5433,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/minimatch": {
@@ -5370,9 +5456,24 @@
"dev": true,
"license": "MIT",
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-13.2.0.tgz",
+ "integrity": "sha512-N6gdSoWRDk0Rh/fVtlqUtLs+fEN3ELFZI3cn3IQE9Mnf3E+Mh8wjO6MstzCOPFh4Yf0L1as5m2eUyYWj8ylVSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^13.0.0"
}
},
+ "node_modules/motion-utils": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-13.0.0.tgz",
+ "integrity": "sha512-7DnN7TmbLcYXcG4RVadXIihWlyuM9afoUww8Y5Agg431kGKiuL2/OMyP4mJ5wLz+pvN3t5ySClLOaVXJ+wekRQ==",
+ "license": "MIT"
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -5387,7 +5488,7 @@
"funding": [
{
"type": "github",
- "url": "https://github.com/sponsors/ai"
+ "url": "https://github.com/Merch/ai"
}
],
"license": "MIT",
@@ -5489,7 +5590,7 @@
},
{
"type": "github",
- "url": "https://github.com/sponsors/ai"
+ "url": "https://github.com/Merch/ai"
}
],
"license": "MIT",
@@ -5518,7 +5619,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/node-releases": {
@@ -5551,7 +5652,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/object-keys": {
@@ -5582,7 +5683,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/object.entries": {
@@ -5617,7 +5718,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/object.groupby": {
@@ -5651,7 +5752,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/onetime": {
@@ -5667,7 +5768,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/optionator": {
@@ -5704,7 +5805,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/p-limit": {
@@ -5720,7 +5821,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/p-locate": {
@@ -5736,7 +5837,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/parent-module": {
@@ -5795,7 +5896,7 @@
"node": ">=8.6"
},
"funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "url": "https://github.com/Merch/jonschlinkert"
}
},
"node_modules/possible-typed-array-names": {
@@ -5824,7 +5925,7 @@
},
{
"type": "github",
- "url": "https://github.com/sponsors/ai"
+ "url": "https://github.com/Merch/ai"
}
],
"license": "MIT",
@@ -5877,7 +5978,7 @@
"funding": [
{
"type": "github",
- "url": "https://github.com/sponsors/feross"
+ "url": "https://github.com/Merch/feross"
},
{
"type": "patreon",
@@ -5938,7 +6039,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/regexp.prototype.flags": {
@@ -5959,7 +6060,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/resolve": {
@@ -5983,7 +6084,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/resolve-from": {
@@ -6020,7 +6121,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/reusify": {
@@ -6049,7 +6150,7 @@
"funding": [
{
"type": "github",
- "url": "https://github.com/sponsors/feross"
+ "url": "https://github.com/Merch/feross"
},
{
"type": "patreon",
@@ -6082,7 +6183,7 @@
"node": ">=0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/safe-push-apply": {
@@ -6099,7 +6200,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/safe-regex-test": {
@@ -6117,7 +6218,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/scheduler": {
@@ -6288,7 +6389,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/side-channel-list": {
@@ -6305,7 +6406,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/side-channel-map": {
@@ -6324,7 +6425,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/side-channel-weakmap": {
@@ -6344,7 +6445,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/signal-exit": {
@@ -6357,7 +6458,7 @@
"node": ">=14"
},
"funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "url": "https://github.com/Merch/isaacs"
}
},
"node_modules/slice-ansi": {
@@ -6444,7 +6545,7 @@
"node": ">=20"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/string.prototype.includes": {
@@ -6487,7 +6588,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/string.prototype.repeat": {
@@ -6521,7 +6622,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/string.prototype.trimend": {
@@ -6540,7 +6641,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
@@ -6558,7 +6659,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/strip-ansi": {
@@ -6597,7 +6698,7 @@
"node": ">=8"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/styled-jsx": {
@@ -6646,7 +6747,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/tailwindcss": {
@@ -6670,6 +6771,12 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/three": {
+ "version": "0.185.1",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.185.1.tgz",
+ "integrity": "sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==",
+ "license": "MIT"
+ },
"node_modules/tinyexec": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz",
@@ -6694,7 +6801,7 @@
"node": ">=12.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
+ "url": "https://github.com/Merch/SuperchupuDev"
}
},
"node_modules/tinyglobby/node_modules/fdir": {
@@ -6725,7 +6832,7 @@
"node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "url": "https://github.com/Merch/jonschlinkert"
}
},
"node_modules/to-regex-range": {
@@ -6831,7 +6938,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/typed-array-byte-offset": {
@@ -6853,7 +6960,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/typed-array-length": {
@@ -6874,7 +6981,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/typescript": {
@@ -6931,7 +7038,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/undici-types": {
@@ -6995,7 +7102,7 @@
},
{
"type": "github",
- "url": "https://github.com/sponsors/ai"
+ "url": "https://github.com/Merch/ai"
}
],
"license": "MIT",
@@ -7053,7 +7160,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/which-builtin-type": {
@@ -7081,7 +7188,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/which-collection": {
@@ -7100,7 +7207,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/which-typed-array": {
@@ -7122,7 +7229,7 @@
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/Merch/ljharb"
}
},
"node_modules/word-wrap": {
@@ -7188,7 +7295,7 @@
"node": ">=18"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/yallist": {
@@ -7211,7 +7318,7 @@
"node": ">= 14.6"
},
"funding": {
- "url": "https://github.com/sponsors/eemeli"
+ "url": "https://github.com/Merch/eemeli"
}
},
"node_modules/yocto-queue": {
@@ -7224,7 +7331,7 @@
"node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/Merch/sindresorhus"
}
},
"node_modules/zod": {
@@ -7234,7 +7341,7 @@
"dev": true,
"license": "MIT",
"funding": {
- "url": "https://github.com/sponsors/colinhacks"
+ "url": "https://github.com/Merch/colinhacks"
}
},
"node_modules/zod-validation-error": {
diff --git a/package.json b/package.json
index 0886e4a..ed5fbef 100644
--- a/package.json
+++ b/package.json
@@ -10,9 +10,13 @@
"prepare": "husky"
},
"dependencies": {
+ "@types/three": "^0.185.4",
+ "framer-motion": "^13.2.0",
+ "lucide-react": "^1.41.0",
"next": "16.3.4",
"react": "19.2.8",
- "react-dom": "19.2.8"
+ "react-dom": "19.2.8",
+ "three": "^0.185.1"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
diff --git a/public/bg.png b/public/bg.png
new file mode 100644
index 0000000..389363d
Binary files /dev/null and b/public/bg.png differ
diff --git a/public/celestial-text-bg-inverted.png b/public/celestial-text-bg-inverted.png
new file mode 100644
index 0000000..3e82830
Binary files /dev/null and b/public/celestial-text-bg-inverted.png differ
diff --git a/public/celestial-text-bg.png b/public/celestial-text-bg.png
new file mode 100644
index 0000000..3e152dd
Binary files /dev/null and b/public/celestial-text-bg.png differ
diff --git a/public/cloud-transparent.png b/public/cloud-transparent.png
new file mode 100644
index 0000000..68c99cf
Binary files /dev/null and b/public/cloud-transparent.png differ
diff --git a/public/cloud.png b/public/cloud.png
new file mode 100644
index 0000000..ac342d3
Binary files /dev/null and b/public/cloud.png differ
diff --git a/public/fat-cloud-transparent.png b/public/fat-cloud-transparent.png
new file mode 100644
index 0000000..c5a4614
Binary files /dev/null and b/public/fat-cloud-transparent.png differ
diff --git a/public/fat-cloud.png b/public/fat-cloud.png
new file mode 100644
index 0000000..f4442a2
Binary files /dev/null and b/public/fat-cloud.png differ
diff --git a/public/fonts/Chopsic.woff b/public/fonts/Chopsic.woff
new file mode 100644
index 0000000..f9ebda9
Binary files /dev/null and b/public/fonts/Chopsic.woff differ
diff --git a/public/ink-splash.png b/public/ink-splash.png
new file mode 100644
index 0000000..a693a90
Binary files /dev/null and b/public/ink-splash.png differ
diff --git a/public/ink-splash.svg b/public/ink-splash.svg
new file mode 100644
index 0000000..61008bf
--- /dev/null
+++ b/public/ink-splash.svg
@@ -0,0 +1,81 @@
+
diff --git a/public/ink-spread.gif b/public/ink-spread.gif
new file mode 100644
index 0000000..03fd1db
Binary files /dev/null and b/public/ink-spread.gif differ
diff --git a/public/ink-spread.png b/public/ink-spread.png
new file mode 100644
index 0000000..a693a90
Binary files /dev/null and b/public/ink-spread.png differ
diff --git a/public/innovision_transparent (1).png b/public/innovision_transparent (1).png
new file mode 100644
index 0000000..1a6f611
Binary files /dev/null and b/public/innovision_transparent (1).png differ
diff --git a/public/innovision_transparent.png b/public/innovision_transparent.png
new file mode 100644
index 0000000..1a6f611
Binary files /dev/null and b/public/innovision_transparent.png differ
diff --git a/public/kawaii-kitsune-kevin-macleod-main-version-7984-04-02.mp3 b/public/kawaii-kitsune-kevin-macleod-main-version-7984-04-02.mp3
new file mode 100644
index 0000000..cfde6b5
Binary files /dev/null and b/public/kawaii-kitsune-kevin-macleod-main-version-7984-04-02.mp3 differ
diff --git a/public/textures/gold-planet.png b/public/textures/gold-planet.png
new file mode 100644
index 0000000..a918687
Binary files /dev/null and b/public/textures/gold-planet.png differ
diff --git a/public/textures/starfield-text.png b/public/textures/starfield-text.png
new file mode 100644
index 0000000..59151b8
Binary files /dev/null and b/public/textures/starfield-text.png differ
diff --git a/public/textures/teal-planet.png b/public/textures/teal-planet.png
new file mode 100644
index 0000000..abb7deb
Binary files /dev/null and b/public/textures/teal-planet.png differ
diff --git a/src/app/globals.css b/src/app/globals.css
index a2dc41e..71e4021 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,26 +1,84 @@
@import "tailwindcss";
+@font-face {
+ font-family: 'Chopsic';
+ src: url('/fonts/Chopsic.woff') format('woff');
+ font-weight: normal;
+ font-style: normal;
+ font-display: swap;
+}
+
:root {
- --background: #ffffff;
- --foreground: #171717;
+ --background: #020712;
+ --foreground: #fef3c7;
+ --font-cinzel: var(--font-cinzel), serif;
+ --font-outfit: var(--font-outfit), sans-serif;
+ --font-chopsic: 'Chopsic', sans-serif;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
+ --font-cinzel: var(--font-cinzel);
+ --font-outfit: var(--font-outfit);
+ --font-chopsic: var(--font-chopsic);
}
body {
background: var(--background);
color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+ font-family: var(--font-outfit);
+}
+
+.ink-mask {
+ mask-image: url("/ink-spread.gif");
+ mask-repeat: no-repeat;
+ mask-size: 350vmax;
+ mask-position: center;
+ -webkit-mask-image: url("/ink-spread.gif");
+ -webkit-mask-repeat: no-repeat;
+ -webkit-mask-size: 350vmax;
+ -webkit-mask-position: center;
+ animation: inkReveal 2.8s cubic-bezier(0.77, 0, 0.175, 1) forwards;
+ height: 100svh;
+ width: 100svw;
+ overflow: hidden;
+}
+
+@keyframes inkReveal {
+ 0% {
+ mask-size: 0vmax;
+ -webkit-mask-size: 0vmax;
+ }
+ 15% {
+ mask-size: 25vmax;
+ -webkit-mask-size: 25vmax;
+ }
+ 50% {
+ mask-size: 100vmax;
+ -webkit-mask-size: 100vmax;
+ }
+ 100% {
+ mask-size: 380vmax;
+ -webkit-mask-size: 380vmax;
+ }
+}
+
+@keyframes starTwinkle {
+ 0%, 100% {
+ opacity: 0.25;
+ transform: scale(0.75);
+ }
+ 50% {
+ opacity: 1;
+ transform: scale(1.4);
+ box-shadow: 0 0 10px currentColor;
+ }
}
+
+.animate-star-twinkle {
+ animation: starTwinkle var(--twinkle-duration, 3s) infinite ease-in-out var(--twinkle-delay, 0s);
+}
+
+
+
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 9852c15..8d91d9e 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,29 +1,38 @@
import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
+import { Cinzel, Outfit } from "next/font/google";
import "./globals.css";
-const geistSans = Geist({
- variable: "--font-geist-sans",
+const cinzel = Cinzel({
+ variable: "--font-cinzel",
subsets: ["latin"],
+ weight: ["400", "500", "600", "700", "800"],
});
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
+const outfit = Outfit({
+ variable: "--font-outfit",
subsets: ["latin"],
+ weight: ["300", "400", "500", "600", "700"],
});
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: "INNOVATION",
+ description: "Celestial 3D Web Experience",
};
-export default function RootLayout({ children }: LayoutProps<"/">) {
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
return (
-
{children}
+
+ {children}
+
);
}
+
diff --git a/src/app/page.tsx b/src/app/page.tsx
index c887311..e837e85 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,69 +1,275 @@
+"use client";
+
+import { useEffect, useRef, useState } from "react";
import Image from "next/image";
+import PlanetsCanvas from "@/components/PlanetsCanvas";
+import Navbar from "@/components/Navbar";
+import PaintSplatterIntro from "@/components/PaintSplatterIntro";
export default function Home() {
+ const mouseRef = useRef({ targetX: 0, targetY: 0, currentX: 0, currentY: 0 });
+ const [offset, setOffset] = useState({ x: 0, y: 0 });
+
+ // Ink-Mask reveal states
+ const [showPreloader, setShowPreloader] = useState(true);
+ const [isActive, setIsActive] = useState(false);
+ const [removeGif, setRemoveGif] = useState(false);
+ const wrapperRef = useRef(null);
+
+ // Audio state & controller (Kawai Kitsune)
+ const audioRef = useRef(null);
+ const [isPlaying, setIsPlaying] = useState(false);
+
+ useEffect(() => {
+ const audio = new Audio("/kawaii-kitsune-kevin-macleod-main-version-7984-04-02.mp3");
+ audio.loop = true;
+ audio.volume = 0.5;
+ audioRef.current = audio;
+
+ return () => {
+ audio.pause();
+ audioRef.current = null;
+ };
+ }, []);
+
+ const handleStart = () => {
+ setIsActive(true);
+ setShowPreloader(false);
+ };
+
+ // Play audio on loop after intro reveal completes
+ useEffect(() => {
+ if (removeGif && audioRef.current) {
+ audioRef.current
+ .play()
+ .then(() => setIsPlaying(true))
+ .catch((err) => console.log("Autoplay audio waiting for user gesture:", err));
+ }
+ }, [removeGif]);
+
+ const toggleAudio = () => {
+ if (!audioRef.current) return;
+ if (isPlaying) {
+ audioRef.current.pause();
+ setIsPlaying(false);
+ } else {
+ audioRef.current
+ .play()
+ .then(() => setIsPlaying(true))
+ .catch(console.error);
+ }
+ };
+
+ // 1. Timing the mask removal: wait 3s after isActive becomes true
+ useEffect(() => {
+ if (isActive && !removeGif) {
+ const timer = setTimeout(() => setRemoveGif(true), 3000);
+ return () => clearTimeout(timer);
+ }
+ }, [isActive, removeGif]);
+
+ // 2. Applying/clearing the mask on the DOM node & scroll lock
+ useEffect(() => {
+ if (removeGif && wrapperRef.current) {
+ wrapperRef.current.style.maskImage = "none";
+ wrapperRef.current.style.webkitMaskImage = "none";
+ document.body.style.position = "static";
+ document.body.style.overflow = "auto";
+ }
+ if (isActive && !removeGif && wrapperRef.current) {
+ wrapperRef.current.style.maskImage = "";
+ wrapperRef.current.style.webkitMaskImage = "";
+ document.body.style.position = "fixed";
+ document.body.style.overflow = "hidden";
+ }
+ }, [removeGif, isActive]);
+
+ useEffect(() => {
+ const handleMouseMove = (e: MouseEvent) => {
+ const { innerWidth, innerHeight } = window;
+ // Normalized from -1 to 1 relative to screen center
+ const x = (e.clientX / innerWidth - 0.5) * 2;
+ const y = (e.clientY / innerHeight - 0.5) * 2;
+ mouseRef.current.targetX = x;
+ mouseRef.current.targetY = y;
+ };
+
+ window.addEventListener("mousemove", handleMouseMove, { passive: true });
+
+ let animationFrameId: number;
+ const updateParallax = () => {
+ const m = mouseRef.current;
+ // Lerp for ultra-smooth movement
+ m.currentX += (m.targetX - m.currentX) * 0.08;
+ m.currentY += (m.targetY - m.currentY) * 0.08;
+
+ setOffset({
+ x: m.currentX,
+ y: m.currentY,
+ });
+
+ animationFrameId = requestAnimationFrame(updateParallax);
+ };
+
+ animationFrameId = requestAnimationFrame(updateParallax);
+
+ return () => {
+ window.removeEventListener("mousemove", handleMouseMove);
+ cancelAnimationFrame(animationFrameId);
+ };
+ }, []);
+
return (
-
-
-
-
-
- To get started, edit the{" "}
-
- page.tsx
- {" "}
- file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
+ <>
+
+
+
+ {/* Navigation Header */}
+
+
+ {/* 1. Deep Space Background - Subtle reverse parallax */}
+
+
+
+
+ {/* 2. Midground Integrated Cloud Layer (Hidden on Mobile, Visible on Desktop) */}
+
+ {/* Top-Left Cloud Bank */}
+
+
+
+
+ {/* Mid-Left Cloud Layer */}
+
+
+
+
+ {/* Bottom-Right Main Cloud Bank */}
+
+
+
+
+ {/* Bottom-Left Base Cloud */}
+
+
+
+
+
+ {/* 3. Three.js 3D Textured Planets Canvas */}
+
+
+ {/* 4. Foreground Floating Transparent Cloud Layer (ABSOLUTELY AT FRONT ABOVE NAVBAR AND TEXT) */}
+
+ {/* Bottom-Right Foreground Cloud Overlay */}
+
+
+
+
+ {/* Top-Left Foreground Cloud Overlay */}
+
+
+
+
+ {/* Prominent Fat Cloud Puff */}
+
+
+
+
+ {/* Bottom-Left Foreground Wispy Accent */}
+
+
+
-
+ >
);
}
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
new file mode 100644
index 0000000..12b8994
--- /dev/null
+++ b/src/components/Navbar.tsx
@@ -0,0 +1,95 @@
+"use client";
+
+import { useState } from "react";
+import { Menu, X, Volume2, VolumeX } from "lucide-react";
+
+interface NavbarProps {
+ isPlaying?: boolean;
+ onToggleAudio?: () => void;
+}
+
+export default function Navbar({ isPlaying = false, onToggleAudio }: NavbarProps) {
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+
+ const navLinks = [
+ { name: "Home", href: "#" },
+ { name: "About", href: "#about" },
+ { name: "Events", href: "#events" },
+ { name: "Gallery", href: "#gallery" },
+ { name: "Merch", href: "#Merch" },
+ ];
+
+ return (
+
+ );
+}
diff --git a/src/components/PaintSplatterIntro.tsx b/src/components/PaintSplatterIntro.tsx
new file mode 100644
index 0000000..aef5176
--- /dev/null
+++ b/src/components/PaintSplatterIntro.tsx
@@ -0,0 +1,135 @@
+"use client";
+
+import { useCallback, useEffect, useState } from "react";
+import Image from "next/image";
+
+interface PaintSplatterIntroProps {
+ onStart: () => void;
+ showPreloader: boolean;
+}
+
+interface Star {
+ id: number;
+ top: number;
+ left: number;
+ size: number;
+ color: string;
+ duration: number;
+ delay: number;
+ isCrossStar?: boolean;
+}
+
+export default function PaintSplatterIntro({
+ onStart,
+ showPreloader,
+}: PaintSplatterIntroProps) {
+ const [isFadingOut, setIsFadingOut] = useState(false);
+ const [stars, setStars] = useState([]);
+
+ // Generate galaxy stars asynchronously on mount to avoid React hydration & cascading render lint
+ useEffect(() => {
+ const starColors = [
+ "#ffffff",
+ "#fef08a",
+ "#fbbf24",
+ "#2dd4bf",
+ "#93c5fd",
+ "#f472b6",
+ ];
+ const timer = setTimeout(() => {
+ const generatedStars = Array.from({ length: 80 }, (_, i) => ({
+ id: i,
+ top: Math.floor(Math.random() * 100),
+ left: Math.floor(Math.random() * 100),
+ size: Number((Math.random() * 2.8 + 1.2).toFixed(2)),
+ color: starColors[Math.floor(Math.random() * starColors.length)],
+ duration: Number((2 + Math.random() * 3.5).toFixed(2)),
+ delay: Number((Math.random() * 3).toFixed(2)),
+ isCrossStar: i % 12 === 0,
+ }));
+ setStars(generatedStars);
+ }, 0);
+ return () => clearTimeout(timer);
+ }, []);
+
+ const handleStart = useCallback(() => {
+ if (isFadingOut) return;
+ setIsFadingOut(true);
+ setTimeout(() => {
+ onStart();
+ }, 400);
+ }, [isFadingOut, onStart]);
+
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === "Enter" && showPreloader) {
+ handleStart();
+ }
+ };
+ window.addEventListener("keydown", handleKeyDown);
+ return () => window.removeEventListener("keydown", handleKeyDown);
+ }, [showPreloader, handleStart]);
+
+ if (!showPreloader) return null;
+
+ return (
+
+ {/* Background Deep Space Galaxy Radial Gradient */}
+
+
+ {/* Scattered Galaxy Stars */}
+
+ {stars.map((star) => (
+
+ {star.isCrossStar && (
+
+ )}
+
+ ))}
+
+
+
+ {/* Enter Button */}
+
+
+ {/* Keyboard hint */}
+
+ Press Enter to launch
+
+
+ );
+}
diff --git a/src/components/PlanetsCanvas.tsx b/src/components/PlanetsCanvas.tsx
new file mode 100644
index 0000000..32c3295
--- /dev/null
+++ b/src/components/PlanetsCanvas.tsx
@@ -0,0 +1,204 @@
+"use client";
+
+import { useEffect, useRef } from "react";
+import * as THREE from "three";
+
+interface PlanetsCanvasProps {
+ mouseX?: number;
+ mouseY?: number;
+}
+
+export default function PlanetsCanvas({ mouseX = 0, mouseY = 0 }: PlanetsCanvasProps) {
+ const containerRef = useRef(null);
+ const mouseRef = useRef({ x: mouseX, y: mouseY });
+
+ useEffect(() => {
+ mouseRef.current.x = mouseX;
+ mouseRef.current.y = mouseY;
+ }, [mouseX, mouseY]);
+
+ useEffect(() => {
+ const container = containerRef.current;
+ if (!container) return;
+
+ // 1. Setup Scene, Camera, Renderer
+ const scene = new THREE.Scene();
+ const camera = new THREE.PerspectiveCamera(
+ 45,
+ container.clientWidth / container.clientHeight,
+ 0.1,
+ 1000
+ );
+ camera.position.z = 10;
+
+ const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
+ renderer.setSize(container.clientWidth, container.clientHeight);
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
+ renderer.toneMapping = THREE.ACESFilmicToneMapping;
+ renderer.toneMappingExposure = 1.35;
+ container.appendChild(renderer.domElement);
+
+ // 2. Rich Lighting Setup
+ const ambientLight = new THREE.AmbientLight(0x0f3b4a, 2.0);
+ scene.add(ambientLight);
+
+ const mainSunLight = new THREE.DirectionalLight(0xfbbf24, 4.2);
+ mainSunLight.position.set(12, 12, 10);
+ scene.add(mainSunLight);
+
+ const cyanRimLight = new THREE.PointLight(0x2dd4bf, 5, 40);
+ cyanRimLight.position.set(-10, 6, 6);
+ scene.add(cyanRimLight);
+
+ const warmFillLight = new THREE.PointLight(0xf59e0b, 3, 30);
+ warmFillLight.position.set(6, -8, 5);
+ scene.add(warmFillLight);
+
+ // 3. Texture Loading
+ const textureLoader = new THREE.TextureLoader();
+
+ const tealTexture = textureLoader.load("/textures/teal-planet.png");
+ tealTexture.colorSpace = THREE.SRGBColorSpace;
+ tealTexture.wrapS = THREE.RepeatWrapping;
+ tealTexture.wrapT = THREE.ClampToEdgeWrapping;
+
+ const goldTexture = textureLoader.load("/textures/gold-planet.png");
+ goldTexture.colorSpace = THREE.SRGBColorSpace;
+
+ // 4. Create Planet 1: Top-Right Artistic Teal Celestial Sphere
+ const tealGeo = new THREE.SphereGeometry(1.75, 64, 64);
+ const tealMat = new THREE.MeshStandardMaterial({
+ map: tealTexture,
+ bumpMap: tealTexture,
+ bumpScale: 0.04,
+ roughness: 0.32,
+ metalness: 0.35,
+ emissive: 0x064e3b,
+ emissiveIntensity: 0.25,
+ });
+ const tealPlanet = new THREE.Mesh(tealGeo, tealMat);
+
+ const planet1Group = new THREE.Group();
+ planet1Group.position.set(4.2, 2.5, -0.5);
+ planet1Group.add(tealPlanet);
+
+ // Atmosphere Glow Halo for Teal Planet
+ const glowGeo = new THREE.SphereGeometry(1.88, 32, 32);
+ const glowMat = new THREE.MeshBasicMaterial({
+ color: 0x2dd4bf,
+ transparent: true,
+ opacity: 0.22,
+ side: THREE.BackSide,
+ });
+ const tealGlow = new THREE.Mesh(glowGeo, glowMat);
+ planet1Group.add(tealGlow);
+ scene.add(planet1Group);
+
+ // 5. Create Planet 2: Bottom-Left Golden Astrolabe Sphere & Rings
+ const goldGeo = new THREE.SphereGeometry(1.4, 64, 64);
+ const goldMat = new THREE.MeshStandardMaterial({
+ map: goldTexture,
+ bumpMap: goldTexture,
+ bumpScale: 0.05,
+ roughness: 0.28,
+ metalness: 0.55,
+ emissive: 0x78350f,
+ emissiveIntensity: 0.2,
+ });
+ const goldPlanet = new THREE.Mesh(goldGeo, goldMat);
+
+ // Golden Concentric Rings
+ const ringGeo = new THREE.RingGeometry(1.7, 3.0, 64);
+ const pos = ringGeo.attributes.position;
+ const uv = ringGeo.attributes.uv;
+ for (let i = 0; i < pos.count; i++) {
+ const vx = pos.getX(i);
+ const vy = pos.getY(i);
+ const dist = Math.sqrt(vx * vx + vy * vy);
+ const u = (dist - 1.7) / (3.0 - 1.7);
+ uv.setXY(i, u, 0.5);
+ }
+
+ const ringMat = new THREE.MeshStandardMaterial({
+ map: goldTexture,
+ side: THREE.DoubleSide,
+ transparent: true,
+ opacity: 0.88,
+ roughness: 0.3,
+ metalness: 0.6,
+ });
+ const rings = new THREE.Mesh(ringGeo, ringMat);
+ rings.rotation.x = Math.PI / 2.3;
+ rings.rotation.y = -Math.PI / 7;
+
+ const planet2Group = new THREE.Group();
+ planet2Group.position.set(-4.0, -2.4, -1.0);
+ planet2Group.add(goldPlanet);
+ planet2Group.add(rings);
+ scene.add(planet2Group);
+
+ // Responsive aspect ratio positioning (Keep planets same scale)
+ const updatePositionsForScreen = () => {
+ const aspect = container.clientWidth / container.clientHeight;
+ planet1Group.position.set(aspect * 2.8, 2.3, -0.5);
+ planet1Group.scale.set(1.0, 1.0, 1.0);
+ planet2Group.position.set(-aspect * 2.6, -2.2, -1.0);
+ planet2Group.scale.set(1.0, 1.0, 1.0);
+ };
+ updatePositionsForScreen();
+
+
+
+ // 6. Animation Loop with Mouse Parallax
+ let animationFrameId: number;
+ const animate = () => {
+ // Rotation
+ tealPlanet.rotation.y += 0.002;
+ tealPlanet.rotation.x += 0.0006;
+
+ goldPlanet.rotation.y += 0.003;
+ rings.rotation.z += 0.0004;
+
+ // Parallax camera response
+ const targetCamX = mouseRef.current.x * 0.9;
+ const targetCamY = mouseRef.current.y * 0.9;
+
+ camera.position.x += (targetCamX - camera.position.x) * 0.05;
+ camera.position.y += (targetCamY - camera.position.y) * 0.05;
+ camera.lookAt(0, 0, 0);
+
+ renderer.render(scene, camera);
+ animationFrameId = requestAnimationFrame(animate);
+ };
+
+ animate();
+
+ // 7. Resize Handler
+ const handleResize = () => {
+ if (!container) return;
+ camera.aspect = container.clientWidth / container.clientHeight;
+ camera.updateProjectionMatrix();
+ renderer.setSize(container.clientWidth, container.clientHeight);
+ updatePositionsForScreen();
+ };
+
+ window.addEventListener("resize", handleResize);
+
+ return () => {
+ window.removeEventListener("resize", handleResize);
+ cancelAnimationFrame(animationFrameId);
+ if (container.contains(renderer.domElement)) {
+ container.removeChild(renderer.domElement);
+ }
+ renderer.dispose();
+ };
+ }, []);
+
+ return (
+
+ );
+}
+
diff --git a/src/config/hero.ts b/src/config/hero.ts
new file mode 100644
index 0000000..363e0fe
--- /dev/null
+++ b/src/config/hero.ts
@@ -0,0 +1,3 @@
+export const LOADER_IMAGES = {
+ inkSplash: "/ink-spread.gif",
+};