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 ( -
-
- Next.js logo -
-

- 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 */} +
+ Space Background +
+ + {/* 2. Midground Integrated Cloud Layer (Hidden on Mobile, Visible on Desktop) */} +
+ {/* Top-Left Cloud Bank */} +
+ Top-Left Cloud +
+ + {/* Mid-Left Cloud Layer */} +
+ Mid-Left Cloud +
+ + {/* Bottom-Right Main Cloud Bank */} +
+ Bottom-Right Cloud +
+ + {/* Bottom-Left Base Cloud */} +
+ Bottom-Left 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 */} +
+ Foreground Bottom-Right Cloud +
+ + {/* Top-Left Foreground Cloud Overlay */} +
+ Foreground Top-Left Cloud +
+ + {/* Prominent Fat Cloud Puff */} +
+ Fat Cloud +
+ + {/* Bottom-Left Foreground Wispy Accent */} +
+ Foreground Bottom-Left Cloud +
-
-
+ ); } 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 ( +
+ + + {/* Mobile Menu Dropdown */} + {mobileMenuOpen && ( + + )} +
+ ); +} 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", +};