Initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# GEMINI_API_KEY: Required for Gemini AI API calls.
|
||||
# AI Studio automatically injects this at runtime from user secrets.
|
||||
# Users configure this via the Secrets panel in the AI Studio UI.
|
||||
GEMINI_API_KEY="MY_GEMINI_API_KEY"
|
||||
|
||||
# APP_URL: The URL where this applet is hosted.
|
||||
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
||||
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
||||
APP_URL="MY_APP_URL"
|
||||
@@ -0,0 +1,8 @@
|
||||
node_modules/
|
||||
build/
|
||||
dist/
|
||||
coverage/
|
||||
.DS_Store
|
||||
*.log
|
||||
.env*
|
||||
!.env.example
|
||||
@@ -0,0 +1,20 @@
|
||||
<div align="center">
|
||||
<img width="1200" height="475" alt="GHBanner" src="https://ai.google.dev/static/site-assets/images/share-ais-513315318.png" />
|
||||
</div>
|
||||
|
||||
# Run and deploy your AI Studio app
|
||||
|
||||
This contains everything you need to run your app locally.
|
||||
|
||||
View your app in AI Studio: https://ai.studio/apps/55306b36-3d34-4fd9-a0e8-4c330db069c4
|
||||
|
||||
## Run Locally
|
||||
|
||||
**Prerequisites:** Node.js
|
||||
|
||||
|
||||
1. Install dependencies:
|
||||
`npm install`
|
||||
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
|
||||
3. Run the app:
|
||||
`npm run dev`
|
||||
@@ -0,0 +1,807 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "react-example",
|
||||
"dependencies": {
|
||||
"@google/genai": "^2.4.0",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@types/canvas-confetti": "^1.9.0",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"dotenv": "^17.2.3",
|
||||
"express": "^4.21.2",
|
||||
"firebase": "^12.17.1",
|
||||
"lucide-react": "^0.546.0",
|
||||
"motion": "^12.23.24",
|
||||
"react": "^19.0.1",
|
||||
"react-dom": "^19.0.1",
|
||||
"vite": "^6.2.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^22.14.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"esbuild": "^0.25.0",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "~5.8.2",
|
||||
"vite": "^6.2.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@babel/code-frame": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="],
|
||||
|
||||
"@babel/compat-data": ["@babel/[email protected]", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="],
|
||||
|
||||
"@babel/core": ["@babel/[email protected]", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-module-transforms": "^7.29.7", "@babel/helpers": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="],
|
||||
|
||||
"@babel/generator": ["@babel/[email protected]", "", { "dependencies": { "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ=="],
|
||||
|
||||
"@babel/helper-compilation-targets": ["@babel/[email protected]", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="],
|
||||
|
||||
"@babel/helper-globals": ["@babel/[email protected]", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="],
|
||||
|
||||
"@babel/helper-module-imports": ["@babel/[email protected]", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="],
|
||||
|
||||
"@babel/helper-module-transforms": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="],
|
||||
|
||||
"@babel/helper-plugin-utils": ["@babel/[email protected]", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="],
|
||||
|
||||
"@babel/helper-string-parser": ["@babel/[email protected]", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="],
|
||||
|
||||
"@babel/helper-validator-identifier": ["@babel/[email protected]", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="],
|
||||
|
||||
"@babel/helper-validator-option": ["@babel/[email protected]", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="],
|
||||
|
||||
"@babel/helpers": ["@babel/[email protected]", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="],
|
||||
|
||||
"@babel/parser": ["@babel/[email protected]", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="],
|
||||
|
||||
"@babel/plugin-transform-react-jsx-self": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw=="],
|
||||
|
||||
"@babel/plugin-transform-react-jsx-source": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q=="],
|
||||
|
||||
"@babel/template": ["@babel/[email protected]", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="],
|
||||
|
||||
"@babel/traverse": ["@babel/[email protected]", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-globals": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/types": "^7.29.7", "debug": "^4.3.1" } }, "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw=="],
|
||||
|
||||
"@babel/types": ["@babel/[email protected]", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
|
||||
|
||||
"@esbuild/android-arm64": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
|
||||
|
||||
"@esbuild/android-x64": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
|
||||
|
||||
"@esbuild/darwin-arm64": ["@esbuild/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
|
||||
|
||||
"@esbuild/darwin-x64": ["@esbuild/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
|
||||
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/[email protected]", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
|
||||
|
||||
"@esbuild/freebsd-x64": ["@esbuild/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
|
||||
|
||||
"@esbuild/linux-arm": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
|
||||
|
||||
"@esbuild/linux-arm64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
|
||||
|
||||
"@esbuild/linux-ia32": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
|
||||
|
||||
"@esbuild/linux-loong64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
|
||||
|
||||
"@esbuild/linux-mips64el": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
|
||||
|
||||
"@esbuild/linux-ppc64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
|
||||
|
||||
"@esbuild/linux-riscv64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
|
||||
|
||||
"@esbuild/linux-s390x": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
|
||||
|
||||
"@esbuild/linux-x64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
|
||||
|
||||
"@esbuild/netbsd-arm64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="],
|
||||
|
||||
"@esbuild/netbsd-x64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
|
||||
|
||||
"@esbuild/openbsd-arm64": ["@esbuild/[email protected]", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="],
|
||||
|
||||
"@esbuild/openbsd-x64": ["@esbuild/[email protected]", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
|
||||
|
||||
"@esbuild/openharmony-arm64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="],
|
||||
|
||||
"@esbuild/sunos-x64": ["@esbuild/[email protected]", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
|
||||
|
||||
"@esbuild/win32-arm64": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
|
||||
|
||||
"@esbuild/win32-ia32": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
|
||||
|
||||
"@firebase/ai": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-types": "0.x" } }, "sha512-TYEQqCQUTyVHuG/HVi9vau6F9kvEaS49o/hmdn/yUuN6ZXQkwIml2nNJTIBfjNl/r9LOxwUNILgcOY16nxObug=="],
|
||||
|
||||
"@firebase/analytics": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-34ALWXzWA6PTRUA5hipZmsm1RKzeecw5J1+qTCXsiMzwLqONC+GuTIQSdmm91MmTAEA+wG1Q5t0IFahcYQOqAA=="],
|
||||
|
||||
"@firebase/analytics-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/analytics": "0.10.23", "@firebase/analytics-types": "0.8.4", "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-allztvCvCUlItZzD97TiRAtGoFJzR1FQFmLxbaLc6PvgscqD9cl5NdKPTtka6keShVYXvCZJpzWcRoH4TME8rw=="],
|
||||
|
||||
"@firebase/analytics-types": ["@firebase/[email protected]", "", {}, "sha512-zQ+XTgkwH6CY/eUSHJRP7e4LxM30RCxlCmob5sy2axs25GE3Ny0XdgpDscMTHHQIGqWkxPXad4w2Mw9sCgT8zQ=="],
|
||||
|
||||
"@firebase/app": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "idb": "7.1.1", "tslib": "^2.1.0" } }, "sha512-G+ZGEyVP8YTb3ay6A+XpcYgFH3sTESHcnHU/EyTktodqhz2BHkLq+QEP7IVwjiMX0cxYwpVKip0/wC0KZcn9vQ=="],
|
||||
|
||||
"@firebase/app-check": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-AbMttBKazQvGVXBZhQdVAdPzRhwHyJAY3Ghu5y2C7IZKIDIppzNYz0shTZ1mP4FBJa+28BuC4t+5h1Q6pT3Asg=="],
|
||||
|
||||
"@firebase/app-check-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/app-check": "0.13.0", "@firebase/app-check-types": "0.5.4", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-2pzNEZEkX84jSqy6TH6FI1HSLA1lc7kakRUybBbKjg9YhIttPlW/XX3N9CDtChji2PTTPWVPZiWhB10exHfA+A=="],
|
||||
|
||||
"@firebase/app-check-interop-types": ["@firebase/[email protected]", "", {}, "sha512-zz3i6e13B8BfWiLy8MABtTh8aGIACgKbf9UVnyHcWs+yQzJXgQcl8A46b0zfaiJHdQ+niF0ouAfcpuf+3LMPQg=="],
|
||||
|
||||
"@firebase/app-check-types": ["@firebase/[email protected]", "", {}, "sha512-xV7JsIyzVr15aA7f3Pi0rB9gdBuVubs89FGA8VkRYA4g0l78poADgdfrScgf7NndSg9mm7cR7PJyY0+t22KaGw=="],
|
||||
|
||||
"@firebase/app-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/app": "0.16.0", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" } }, "sha512-shQq37O8qELDzvsVwYPlDXwD1zlcrZ0m2bpBF5ov2HSbY8x+AHsnL5TtJ2e1JAfkQN05qHao1AfabS69PN6GiA=="],
|
||||
|
||||
"@firebase/app-types": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/logger": "0.5.1" } }, "sha512-YevqTjvo7Iujsa9Dwowmd6dSoElhzmD63ZSrq6bzjvQ6POjYgNjOFHLmNIgJs48eNO093NCERibuFnxbfOvU7A=="],
|
||||
|
||||
"@firebase/auth": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@react-native-async-storage/async-storage": "^2.2.0 || ^3.0.0" }, "optionalPeers": ["@react-native-async-storage/async-storage"] }, "sha512-s+NS1aV0DDyyfoIMeSz53HXnVTv7ufJjJfrP63XyaWHweJ5vOoxKWrTm5tO7S7PDqvyOa/Wi3oP0dgAo6JTMMA=="],
|
||||
|
||||
"@firebase/auth-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/auth": "1.13.4", "@firebase/auth-types": "0.13.1", "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-/hHeTBmQ61+N5J1RECls+WfskZTY78JXr7aO5EMOfUpqJvDqvoS+568k0rp6Ss/4UWwBjadILs+H+SGy1zCS3A=="],
|
||||
|
||||
"@firebase/auth-interop-types": ["@firebase/[email protected]", "", {}, "sha512-1Li/YuBDBAXcKv7BzY4U28gontUmAaw53sYiqbaVOMCFb2lFKK/c3CGMUWqtwe7+TXrl3poWnTCL5umYBg85Eg=="],
|
||||
|
||||
"@firebase/auth-types": ["@firebase/[email protected]", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-0c1Mnid0uMDfGJHeUS4zfvBa4/CedJXotGy/n/NZJnBjwiJawt0ZYU+wH2VAVLiRCEfG2ncCkAX3yd1/2nrB7g=="],
|
||||
|
||||
"@firebase/component": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/util": "1.15.2", "tslib": "^2.1.0" } }, "sha512-tLpOaaCol9ugUIYp2R3CbWPPA8Ajg/papX/XHEy8U52b/QXH3BbX8tTJX9aShDCjp+9sMAxMLD94i7lresdugQ=="],
|
||||
|
||||
"@firebase/data-connect": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/auth-interop-types": "0.2.5", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-nHBFk3Ntl+NZCRIUG2d5j7I69P0otjyQ/duhVKLbw4+5cNke/F6RK1pdE5Jnf831/QOTs2Bd00LlxlZ+jNsb9w=="],
|
||||
|
||||
"@firebase/database": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/auth-interop-types": "0.2.5", "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "sha512-D+j4+8uhGtNd1tVD+X+c8JrC4ppStGJKyujSQt2NPwdN26QcCk0BeIxue+UqspHkHiFHyQOimwlzjLewGq6S+A=="],
|
||||
|
||||
"@firebase/database-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/database": "1.1.4", "@firebase/database-types": "1.0.21", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" }, "optionalPeers": ["@firebase/app", "@firebase/app-compat"] }, "sha512-mu7S/75UIajB1A5M9Vfojk69LttW55uABp9nHEtWrV/mIaSEwvoaIe9GySsEzS2EKFK5/3f5okcAuUbihhYeJg=="],
|
||||
|
||||
"@firebase/database-types": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/app-types": "0.9.5", "@firebase/util": "1.15.2" } }, "sha512-SX1jUqhttKgg/m9dYRTvqU9QvucBooziWfA986r4cpsbi4zlsvewe424j3Vpduwd6DG1MSAMfBVT2VqA61FnkA=="],
|
||||
|
||||
"@firebase/firestore": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "@firebase/webchannel-wrapper": "1.0.6", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", "re2js": "^2.8.3", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-P9tof6pyO1bnLlMWbux+5O7WFJqlb7OTPMKxxOiXKYiQl7mxykAvxr1BFCgWeEXUU7DZxQncyJ040B0IhFVZCg=="],
|
||||
|
||||
"@firebase/firestore-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/firestore": "4.17.0", "@firebase/firestore-types": "3.0.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-k2uX81Ao/S0jnFcWGPOQpKK1cPlJHvD9WIqh/RE1XBDP2yg5zhE4rHhSg1rtB11k39q3nKon9XLNDDrPjGclag=="],
|
||||
|
||||
"@firebase/firestore-types": ["@firebase/[email protected]", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-jGn+JSS4X9zZsrfu7Yw66v5YRdOLD1oyQh4USR0xWl4CUqV/DA6bNIXRPpxH/cUl3iVTNiP6MN7g+EL42A4qfA=="],
|
||||
|
||||
"@firebase/functions": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/auth-interop-types": "0.2.5", "@firebase/component": "0.7.4", "@firebase/messaging-interop-types": "0.2.5", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-9obLnzeQUivK5lmtGFOU2ucQ38BjTp+jpPtbfFp/mDsdVCvEpRqdWNvMMQ6aQwR4vcVc/utsvngm5BRkXbc7ZA=="],
|
||||
|
||||
"@firebase/functions-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/functions": "0.13.6", "@firebase/functions-types": "0.6.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-dj9sOet+FIU91jeU4A3vGJoXHty7NqkSfjRLCwLgJXPDk1m72KFuxD3nlFgw/yXx/Fr7UjqzbxZ0LrIOdpx7+w=="],
|
||||
|
||||
"@firebase/functions-types": ["@firebase/[email protected]", "", {}, "sha512-zV6kgqtduR4rUAdC/ilS7kmb93XD7bEZoJDlVBZqlOw2uGGGCNBQBuleww2rr0Ulr3L9o2TDjumEt68/l1f9DQ=="],
|
||||
|
||||
"@firebase/installations": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "idb": "7.1.1", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-MBkbcQfd+3qHjW+slsH4s7jH5qTdGlYpwqmxEZ7QcIpgDxu1SKyU0f+mCZhCt1BCacLNiOWF5L0R06N0LtlfMg=="],
|
||||
|
||||
"@firebase/installations-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/installations-types": "0.5.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-isaXmjb9roM83eVeXAe+ZRNKYNsSo2s0aNM+cy04AAGEyVL/d8Aa11GwEXovRFeYjl9+1yRAOxRDTOukZRwTxA=="],
|
||||
|
||||
"@firebase/installations-types": ["@firebase/[email protected]", "", { "peerDependencies": { "@firebase/app-types": "0.x" } }, "sha512-U2eFapdHwjb43Vx9o+Pmj4dFfvcHEK1IirEFLqMtWrTHvmdrS3gBpBD1kmJk/9HjsOtoHZxJ2Paoe79e+L1ZPg=="],
|
||||
|
||||
"@firebase/logger": ["@firebase/[email protected]", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-vZKLsqE1ABOy8OjQiE7cUTFn4gvaqlk88yp8N94Pk/sDpq61YqZGqmVFZTvOyflTwuYFcWirBdYGoJgbDaXKYQ=="],
|
||||
|
||||
"@firebase/messaging": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/messaging-interop-types": "0.2.5", "@firebase/util": "1.15.2", "idb": "7.1.1", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-kL8fdjbNBI7hprlXJrUjktDWosrpT4JtfwXtVVevImPF/rBRAsC+LS/jIs+kgQVuotnvMhaBCgAFipBoY9YU9g=="],
|
||||
|
||||
"@firebase/messaging-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/messaging": "0.13.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-/AmMqHRnSQhPsdeED3ocs+s30/tpFvZDiiwIYY2uXFRvLujo1fnbPOeCFoe4Y+dRy1LCSjpvJf+dy5ZTsxi1yg=="],
|
||||
|
||||
"@firebase/messaging-interop-types": ["@firebase/[email protected]", "", {}, "sha512-tUEKnaAP2Y/MNIqgnriPpV6e5l13Vs/+p2yrd6NGlncPJT9O3a8muYZtdnWe+IJ4fgKLHJVC79n/asxk/N5Msw=="],
|
||||
|
||||
"@firebase/performance": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0", "web-vitals": "^4.2.4" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-1u6fuXP9cj0s+lkTFAspr/ttfPebPbEdpx+5Wdr4mPZbp8qH2KCMxOddEAR1ZMRa5GI0E7hDYSnolEmbqOFOAg=="],
|
||||
|
||||
"@firebase/performance-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/performance": "0.7.13", "@firebase/performance-types": "0.2.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-jgoocXLN6ao26xWQ8pzosmzQ33uLzGBJQPNK0NTbVy1XvIHr5pfgBf9hWLOxsWe+R7sJq5bjD+8ybXprmt61mA=="],
|
||||
|
||||
"@firebase/performance-types": ["@firebase/[email protected]", "", {}, "sha512-kJSEk7b0uhpcPRyL4SQ/GPujLqk52XNKcXlnsKDbWGAb9vugcLvOU3u6zfEdwd+d8hWJb5S5ZizV1JFFI0nkKg=="],
|
||||
|
||||
"@firebase/remote-config": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/installations": "0.6.23", "@firebase/logger": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-nzQUSJnk1zAZEl2Q5O3I7Z61cYLK5JI4H6wyyOiHkVZ+bmgy1YXNNMptNbVjixMQ/eCzgA6nZRaC+1eBcJGUFA=="],
|
||||
|
||||
"@firebase/remote-config-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", "@firebase/remote-config": "0.9.1", "@firebase/remote-config-types": "0.5.1", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-kEO9Gn6fbmVj7eNUtZ6d59mLgUDUD0qo7aCicGOWNfuRWTaUv3CF9DMYychO61zaEQ3cfA+CEny4V1E8A1gRGA=="],
|
||||
|
||||
"@firebase/remote-config-types": ["@firebase/[email protected]", "", {}, "sha512-cX/1LT6KQwkXzck2eSzeKnuvXZCyr8qaPpDcikoJs7jmI+oBOXixpDLeDtWj1U6GNMkIoXrEDNoyT2Ypcyp5/A=="],
|
||||
|
||||
"@firebase/storage": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x" } }, "sha512-jfzEWZb3Fpsq3FwAB2ifoc8mcSh935qXdDou3TpyjDWa45hhNcZUv8/w28/10njByhfK7snbakKN30nwnzQ3/w=="],
|
||||
|
||||
"@firebase/storage-compat": ["@firebase/[email protected]", "", { "dependencies": { "@firebase/component": "0.7.4", "@firebase/storage": "0.14.4", "@firebase/storage-types": "0.8.4", "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "peerDependencies": { "@firebase/app": "0.x", "@firebase/app-compat": "0.x" } }, "sha512-qSRgCB9f2R/nCp8t/8OC101cIFBFeUazlRInOMdzbnLzvrQBzEfx19SrR4pvdj/0+M+P/y8AK/a2s+3EB+B1Pw=="],
|
||||
|
||||
"@firebase/storage-types": ["@firebase/[email protected]", "", { "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "sha512-BT7cwxJOx8SWwlQfrlC+bD/Sk3Cw+1odCi8UZNFNWTVZoPsBnA5W+mqtZzVnvsdJpXCFGSGQ7R7vOR6dtM/BRA=="],
|
||||
|
||||
"@firebase/util": ["@firebase/[email protected]", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-974pWIZVLDMc5GW5YAsj8y0XxULxIy/sPUy7tsxmWbF93KRIyh9xpuHlh0zDL+shUcf5nHDjFOg9YLiQ763eiA=="],
|
||||
|
||||
"@firebase/webchannel-wrapper": ["@firebase/[email protected]", "", {}, "sha512-Vr/Mqu79dMwGRAyGbJ4uN4+BtXB3/mRTdzetD1daWNeG8QaWuzhhbG77GltO5c0yYmYls8i250iX73624GJd7Q=="],
|
||||
|
||||
"@google/genai": ["@google/[email protected]", "", { "dependencies": { "google-auth-library": "^10.3.0", "p-retry": "^4.6.2", "protobufjs": "^7.5.4", "ws": "^8.18.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.25.2" }, "optionalPeers": ["@modelcontextprotocol/sdk"] }, "sha512-GM7C8Kaomvjz05x5JEO6+l3d/pciL9LxAG9dUjJLD7nTPZ9X0Cfsf2Z7eET6UjgWyUmxXCHtYnQoQ77F9+ZIOQ=="],
|
||||
|
||||
"@grpc/grpc-js": ["@grpc/[email protected]", "", { "dependencies": { "@grpc/proto-loader": "^0.7.8", "@types/node": ">=12.12.47" } }, "sha512-wE4Ut/olIzfKqp631XrG+wbF0v1vWFN4YL9FyXC2LJiG33DsV7PLzURjrCvY/6je2ntdRkeLpPDluzSRGaVltQ=="],
|
||||
|
||||
"@grpc/proto-loader": ["@grpc/[email protected]", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||
|
||||
"@jridgewell/remapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/[email protected]", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/[email protected]", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/[email protected]", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@protobufjs/aspromise": ["@protobufjs/[email protected]", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
|
||||
|
||||
"@protobufjs/base64": ["@protobufjs/[email protected]", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
|
||||
|
||||
"@protobufjs/codegen": ["@protobufjs/[email protected]", "", {}, "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g=="],
|
||||
|
||||
"@protobufjs/eventemitter": ["@protobufjs/[email protected]", "", {}, "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg=="],
|
||||
|
||||
"@protobufjs/fetch": ["@protobufjs/[email protected]", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1" } }, "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw=="],
|
||||
|
||||
"@protobufjs/float": ["@protobufjs/[email protected]", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="],
|
||||
|
||||
"@protobufjs/path": ["@protobufjs/[email protected]", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="],
|
||||
|
||||
"@protobufjs/pool": ["@protobufjs/[email protected]", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="],
|
||||
|
||||
"@protobufjs/utf8": ["@protobufjs/[email protected]", "", {}, "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug=="],
|
||||
|
||||
"@rolldown/pluginutils": ["@rolldown/[email protected]", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA=="],
|
||||
|
||||
"@rollup/rollup-darwin-arm64": ["@rollup/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ=="],
|
||||
|
||||
"@rollup/rollup-darwin-x64": ["@rollup/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g=="],
|
||||
|
||||
"@rollup/rollup-freebsd-arm64": ["@rollup/[email protected]", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-zvBUvsQUpOWALdDsk6qbS8bXf2VxmPisuudNDrY7x0p0jBdsoZl8HsHczIOgkQiZldmcacMKtBzpoGVNeIe2bQ=="],
|
||||
|
||||
"@rollup/rollup-freebsd-x64": ["@rollup/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-C2KmNrcSem/AMg984H/dev+si0lieQGdXdR/lYGJnuumXnFb9Y7QdiI62obFdLlxRYLBv4P0eUVIDbD4c1vVvw=="],
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA=="],
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA=="],
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q=="],
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ=="],
|
||||
|
||||
"@rollup/rollup-linux-loong64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ=="],
|
||||
|
||||
"@rollup/rollup-linux-loong64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw=="],
|
||||
|
||||
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA=="],
|
||||
|
||||
"@rollup/rollup-linux-ppc64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw=="],
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg=="],
|
||||
|
||||
"@rollup/rollup-linux-riscv64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ=="],
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg=="],
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg=="],
|
||||
|
||||
"@rollup/rollup-linux-x64-musl": ["@rollup/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw=="],
|
||||
|
||||
"@rollup/rollup-openbsd-x64": ["@rollup/[email protected]", "", { "os": "openbsd", "cpu": "x64" }, "sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA=="],
|
||||
|
||||
"@rollup/rollup-openharmony-arm64": ["@rollup/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-+2Cy/ldweGBLlPIKsQLF8U5N44a0KDdbrk1rAjHOM9M2K+kGdIVjHLmmrZIcx+9Ny3ke/1JomCsDI1ocb11+sg=="],
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-dtZvzc8BedpSaFNy75x6uiWwAGTH+aZHDtdrqP6qk+WcLJrfti6sGje1ZJ9UxyzDLF23d/mV+PaMwuC0hL7UVA=="],
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-Rj8Ra4noo+aYy7sKBggCx0407mws34kAb1ySyWuq5DAtFBQdkSwnsjCgPrhPe9cvgBKZIukpE+CVHvORCS93kQ=="],
|
||||
|
||||
"@rollup/rollup-win32-x64-gnu": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-vp7N084ew/odXn2gi/mzm9mUkQu9l6AiN6dt4IeUM2Uvm9o+cVmP+YkqbMOteLbiGgqBBlJZjIMYVCfOOIVbVQ=="],
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-MOG/3gTOn4Fwf574RVOaY61I5o6P90legkFADiTyn1hyjNydT+cerU2rLUwPdZkKKyJ+iT+K9p7WXK4LM1Ka6g=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/[email protected]", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="],
|
||||
|
||||
"@tailwindcss/oxide": ["@tailwindcss/[email protected]", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="],
|
||||
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="],
|
||||
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/[email protected]", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="],
|
||||
|
||||
"@tailwindcss/vite": ["@tailwindcss/[email protected]", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="],
|
||||
|
||||
"@types/babel__core": ["@types/[email protected]", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
|
||||
|
||||
"@types/babel__generator": ["@types/[email protected]", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
|
||||
|
||||
"@types/babel__template": ["@types/[email protected]", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="],
|
||||
|
||||
"@types/babel__traverse": ["@types/[email protected]", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
|
||||
|
||||
"@types/body-parser": ["@types/[email protected]", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="],
|
||||
|
||||
"@types/canvas-confetti": ["@types/[email protected]", "", {}, "sha512-aBGj/dULrimR1XDZLtG9JwxX1b4HPRF6CX9Yfwh3NvstZEm1ZL7RBnel4keCPSqs1ANRu1u2Aoz9R+VmtjYuTg=="],
|
||||
|
||||
"@types/connect": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
|
||||
|
||||
"@types/estree": ["@types/[email protected]", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
|
||||
|
||||
"@types/express": ["@types/[email protected]", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "^1" } }, "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw=="],
|
||||
|
||||
"@types/express-serve-static-core": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg=="],
|
||||
|
||||
"@types/http-errors": ["@types/[email protected]", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="],
|
||||
|
||||
"@types/mime": ["@types/[email protected]", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
|
||||
|
||||
"@types/node": ["@types/[email protected]", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q=="],
|
||||
|
||||
"@types/qs": ["@types/[email protected]", "", {}, "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw=="],
|
||||
|
||||
"@types/range-parser": ["@types/[email protected]", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="],
|
||||
|
||||
"@types/retry": ["@types/[email protected]", "", {}, "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="],
|
||||
|
||||
"@types/send": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="],
|
||||
|
||||
"@types/serve-static": ["@types/[email protected]", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="],
|
||||
|
||||
"@vitejs/plugin-react": ["@vitejs/[email protected]", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw=="],
|
||||
|
||||
"accepts": ["[email protected]", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
|
||||
|
||||
"agent-base": ["[email protected]", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
||||
|
||||
"ansi-regex": ["[email protected]", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"ansi-styles": ["[email protected]", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"array-flatten": ["[email protected]", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="],
|
||||
|
||||
"autoprefixer": ["[email protected]", "", { "dependencies": { "browserslist": "^4.28.6", "caniuse-lite": "^1.0.30001806", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA=="],
|
||||
|
||||
"base64-js": ["[email protected]", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"baseline-browser-mapping": ["[email protected]", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-69D/imtToCsIcAl8WBS2YaRwA4jO/j0HhU+hELqMEu9f54MoUtI6+XH5mrKU8rEFNEk/Ui1I2MK4/JkWacclGw=="],
|
||||
|
||||
"bignumber.js": ["[email protected]", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
|
||||
|
||||
"body-parser": ["[email protected]", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g=="],
|
||||
|
||||
"browserslist": ["[email protected]", "", { "dependencies": { "baseline-browser-mapping": "^2.10.44", "caniuse-lite": "^1.0.30001806", "electron-to-chromium": "^1.5.393", "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw=="],
|
||||
|
||||
"buffer-equal-constant-time": ["[email protected]", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
|
||||
|
||||
"bytes": ["[email protected]", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
||||
|
||||
"call-bind-apply-helpers": ["[email protected]", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||
|
||||
"call-bound": ["[email protected]", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
||||
|
||||
"caniuse-lite": ["[email protected]", "", {}, "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw=="],
|
||||
|
||||
"canvas-confetti": ["[email protected]", "", {}, "sha512-yxQbJkAVrFXWNbTUjPqjF7G+g6pDotOUHGbkZq2NELZUMDpiJ85rIEazVb8GTaAptNW2miJAXbs1BtioA251Pw=="],
|
||||
|
||||
"cliui": ["[email protected]", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
|
||||
|
||||
"color-convert": ["[email protected]", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["[email protected]", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"content-disposition": ["[email protected]", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
|
||||
|
||||
"content-type": ["[email protected]", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
||||
|
||||
"convert-source-map": ["[email protected]", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||
|
||||
"cookie": ["[email protected]", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||
|
||||
"cookie-signature": ["[email protected]", "", {}, "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="],
|
||||
|
||||
"data-uri-to-buffer": ["[email protected]", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
|
||||
|
||||
"debug": ["[email protected]", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||
|
||||
"depd": ["[email protected]", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||
|
||||
"destroy": ["[email protected]", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
||||
|
||||
"detect-libc": ["[email protected]", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||
|
||||
"dotenv": ["[email protected]", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="],
|
||||
|
||||
"dunder-proto": ["[email protected]", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||
|
||||
"ecdsa-sig-formatter": ["[email protected]", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
|
||||
|
||||
"ee-first": ["[email protected]", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
||||
|
||||
"electron-to-chromium": ["[email protected]", "", {}, "sha512-AsvhAxopJGh6museTDMIjn6JpDYOfgu4RLlygomt87MUwBUqTfd/1EiPtx10/LZE8xpTvkP2E9Gafq7lkLtodQ=="],
|
||||
|
||||
"emoji-regex": ["[email protected]", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"encodeurl": ["[email protected]", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
||||
|
||||
"enhanced-resolve": ["[email protected]", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-GVoi+ICHocoOIU7qVVM48wOJziRsqrsyqlI0Ce0LdowRn6v3bcH2zUa9kp85ncx0nwIb9/HOCOLS3fdThDG/XQ=="],
|
||||
|
||||
"es-define-property": ["[email protected]", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||
|
||||
"es-errors": ["[email protected]", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||
|
||||
"es-object-atoms": ["[email protected]", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="],
|
||||
|
||||
"esbuild": ["[email protected]", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
|
||||
|
||||
"escalade": ["[email protected]", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||
|
||||
"escape-html": ["[email protected]", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
|
||||
|
||||
"etag": ["[email protected]", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
|
||||
|
||||
"express": ["[email protected]", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q=="],
|
||||
|
||||
"extend": ["[email protected]", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
||||
|
||||
"faye-websocket": ["[email protected]", "", { "dependencies": { "websocket-driver": ">=0.5.1" } }, "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g=="],
|
||||
|
||||
"fdir": ["[email protected]", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"fetch-blob": ["[email protected]", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
|
||||
|
||||
"finalhandler": ["[email protected]", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "statuses": "~2.0.2", "unpipe": "~1.0.0" } }, "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg=="],
|
||||
|
||||
"firebase": ["[email protected]", "", { "dependencies": { "@firebase/ai": "2.14.0", "@firebase/analytics": "0.10.23", "@firebase/analytics-compat": "0.2.29", "@firebase/app": "0.16.0", "@firebase/app-check": "0.13.0", "@firebase/app-check-compat": "0.4.6", "@firebase/app-compat": "0.5.16", "@firebase/app-types": "0.9.5", "@firebase/auth": "1.13.4", "@firebase/auth-compat": "0.6.9", "@firebase/data-connect": "0.7.3", "@firebase/database": "1.1.4", "@firebase/database-compat": "2.1.6", "@firebase/firestore": "4.17.0", "@firebase/firestore-compat": "0.4.12", "@firebase/functions": "0.13.6", "@firebase/functions-compat": "0.4.6", "@firebase/installations": "0.6.23", "@firebase/installations-compat": "0.2.23", "@firebase/messaging": "0.13.1", "@firebase/messaging-compat": "0.2.28", "@firebase/performance": "0.7.13", "@firebase/performance-compat": "0.2.26", "@firebase/remote-config": "0.9.1", "@firebase/remote-config-compat": "0.2.28", "@firebase/storage": "0.14.4", "@firebase/storage-compat": "0.4.4", "@firebase/util": "1.15.2" } }, "sha512-dhp41ye9jMQvhx5FwjMkf/hjDHJApl7gXmvzOZGvP0M7c/GZGUnQ4qvsvlOBkF0Pa7wAwHMdcpL0ON2pXCQ4Sw=="],
|
||||
|
||||
"formdata-polyfill": ["[email protected]", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="],
|
||||
|
||||
"forwarded": ["[email protected]", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
||||
|
||||
"fraction.js": ["[email protected]", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
|
||||
|
||||
"framer-motion": ["[email protected]", "", { "dependencies": { "motion-dom": "^12.43.0", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g=="],
|
||||
|
||||
"fresh": ["[email protected]", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
|
||||
|
||||
"fsevents": ["[email protected]", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"function-bind": ["[email protected]", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
"gaxios": ["[email protected]", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2" } }, "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA=="],
|
||||
|
||||
"gcp-metadata": ["[email protected]", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
|
||||
|
||||
"gensync": ["[email protected]", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||
|
||||
"get-caller-file": ["[email protected]", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||
|
||||
"get-intrinsic": ["[email protected]", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
|
||||
"get-proto": ["[email protected]", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||
|
||||
"google-auth-library": ["[email protected]", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.1.4", "gcp-metadata": "8.1.2", "google-logging-utils": "1.1.3", "jws": "^4.0.0" } }, "sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw=="],
|
||||
|
||||
"google-logging-utils": ["[email protected]", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="],
|
||||
|
||||
"gopd": ["[email protected]", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||
|
||||
"graceful-fs": ["[email protected]", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"has-symbols": ["[email protected]", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
||||
|
||||
"hasown": ["[email protected]", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
|
||||
|
||||
"http-errors": ["[email protected]", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
|
||||
|
||||
"http-parser-js": ["[email protected]", "", {}, "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA=="],
|
||||
|
||||
"https-proxy-agent": ["[email protected]", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||
|
||||
"iconv-lite": ["[email protected]", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
|
||||
|
||||
"idb": ["[email protected]", "", {}, "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ=="],
|
||||
|
||||
"inherits": ["[email protected]", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"ipaddr.js": ["[email protected]", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
|
||||
|
||||
"is-fullwidth-code-point": ["[email protected]", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
||||
|
||||
"jiti": ["[email protected]", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="],
|
||||
|
||||
"js-tokens": ["[email protected]", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
|
||||
"jsesc": ["[email protected]", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
||||
|
||||
"json-bigint": ["[email protected]", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="],
|
||||
|
||||
"json5": ["[email protected]", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||
|
||||
"jwa": ["[email protected]", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="],
|
||||
|
||||
"jws": ["[email protected]", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
|
||||
|
||||
"lightningcss": ["[email protected]", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||
|
||||
"lightningcss-android-arm64": ["[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||
|
||||
"lightningcss-darwin-arm64": ["[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
||||
|
||||
"lightningcss-darwin-x64": ["[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
|
||||
|
||||
"lightningcss-freebsd-x64": ["[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
|
||||
|
||||
"lightningcss-linux-arm-gnueabihf": ["[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
|
||||
|
||||
"lightningcss-linux-arm64-gnu": ["[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
|
||||
|
||||
"lightningcss-linux-arm64-musl": ["[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
|
||||
|
||||
"lightningcss-linux-x64-gnu": ["[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
|
||||
|
||||
"lightningcss-linux-x64-musl": ["[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
|
||||
|
||||
"lightningcss-win32-arm64-msvc": ["[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
|
||||
|
||||
"lightningcss-win32-x64-msvc": ["[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||
|
||||
"lodash.camelcase": ["[email protected]", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
|
||||
|
||||
"long": ["[email protected]", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||
|
||||
"lru-cache": ["[email protected]", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"lucide-react": ["[email protected]", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Z94u6fKT43lKeYHiVyvyR8fT7pwCzDu7RyMPpTvh054+xahSgj4HFQ+NmflvzdXsoAjYGdCguGaFKYuvq0ThCQ=="],
|
||||
|
||||
"magic-string": ["[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"math-intrinsics": ["[email protected]", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"media-typer": ["[email protected]", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
|
||||
|
||||
"merge-descriptors": ["[email protected]", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="],
|
||||
|
||||
"methods": ["[email protected]", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="],
|
||||
|
||||
"mime": ["[email protected]", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
|
||||
|
||||
"mime-db": ["[email protected]", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||
|
||||
"mime-types": ["[email protected]", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||
|
||||
"motion": ["[email protected]", "", { "dependencies": { "framer-motion": "^12.43.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-BQgQbSa9Hn3/mtbib0MK53y6JSANa+YKUKlaYnWzAVDH424RYQ5LVpV3pNiWH00BA2z4ojsSdMzqT7g2FQwjuQ=="],
|
||||
|
||||
"motion-dom": ["[email protected]", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag=="],
|
||||
|
||||
"motion-utils": ["[email protected]", "", {}, "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ=="],
|
||||
|
||||
"ms": ["[email protected]", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||
|
||||
"nanoid": ["[email protected]", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
|
||||
|
||||
"negotiator": ["[email protected]", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
||||
|
||||
"node-domexception": ["[email protected]", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
|
||||
|
||||
"node-fetch": ["[email protected]", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
|
||||
|
||||
"node-releases": ["[email protected]", "", {}, "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ=="],
|
||||
|
||||
"object-inspect": ["[email protected]", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
|
||||
|
||||
"on-finished": ["[email protected]", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
|
||||
|
||||
"p-retry": ["[email protected]", "", { "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" } }, "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ=="],
|
||||
|
||||
"parseurl": ["[email protected]", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
|
||||
|
||||
"path-to-regexp": ["[email protected]", "", {}, "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA=="],
|
||||
|
||||
"picocolors": ["[email protected]", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["[email protected]", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="],
|
||||
|
||||
"postcss": ["[email protected]", "", { "dependencies": { "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-8RyVklq0owXUTa4xlpzu4l9AaVKIdQvAcOHZWaMh98HgySsUtxRVf/chRe3dsSLqb6i40BzGRzEUddRaI+9TSw=="],
|
||||
|
||||
"postcss-value-parser": ["[email protected]", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
||||
|
||||
"protobufjs": ["[email protected]", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw=="],
|
||||
|
||||
"proxy-addr": ["[email protected]", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
||||
|
||||
"qs": ["[email protected]", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A=="],
|
||||
|
||||
"range-parser": ["[email protected]", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
||||
|
||||
"raw-body": ["[email protected]", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
|
||||
|
||||
"re2js": ["[email protected]", "", {}, "sha512-xLgQil4kIUCrAzVk9fRSkxkFNwmygLFjVxXrLc65aE1F0+Zsb8rxumFBy4XKyvgMCTL6kilDq3EZ0piE2dP/Dg=="],
|
||||
|
||||
"react": ["[email protected]", "", {}, "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw=="],
|
||||
|
||||
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.8" } }, "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ=="],
|
||||
|
||||
"react-refresh": ["[email protected]", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
|
||||
|
||||
"require-directory": ["[email protected]", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
|
||||
|
||||
"retry": ["[email protected]", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
|
||||
|
||||
"rollup": ["[email protected]", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.62.3", "@rollup/rollup-android-arm64": "4.62.3", "@rollup/rollup-darwin-arm64": "4.62.3", "@rollup/rollup-darwin-x64": "4.62.3", "@rollup/rollup-freebsd-arm64": "4.62.3", "@rollup/rollup-freebsd-x64": "4.62.3", "@rollup/rollup-linux-arm-gnueabihf": "4.62.3", "@rollup/rollup-linux-arm-musleabihf": "4.62.3", "@rollup/rollup-linux-arm64-gnu": "4.62.3", "@rollup/rollup-linux-arm64-musl": "4.62.3", "@rollup/rollup-linux-loong64-gnu": "4.62.3", "@rollup/rollup-linux-loong64-musl": "4.62.3", "@rollup/rollup-linux-ppc64-gnu": "4.62.3", "@rollup/rollup-linux-ppc64-musl": "4.62.3", "@rollup/rollup-linux-riscv64-gnu": "4.62.3", "@rollup/rollup-linux-riscv64-musl": "4.62.3", "@rollup/rollup-linux-s390x-gnu": "4.62.3", "@rollup/rollup-linux-x64-gnu": "4.62.3", "@rollup/rollup-linux-x64-musl": "4.62.3", "@rollup/rollup-openbsd-x64": "4.62.3", "@rollup/rollup-openharmony-arm64": "4.62.3", "@rollup/rollup-win32-arm64-msvc": "4.62.3", "@rollup/rollup-win32-ia32-msvc": "4.62.3", "@rollup/rollup-win32-x64-gnu": "4.62.3", "@rollup/rollup-win32-x64-msvc": "4.62.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q=="],
|
||||
|
||||
"safe-buffer": ["[email protected]", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
|
||||
"safer-buffer": ["[email protected]", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"scheduler": ["[email protected]", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||
|
||||
"semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"send": ["[email protected]", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="],
|
||||
|
||||
"serve-static": ["[email protected]", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
|
||||
|
||||
"setprototypeof": ["[email protected]", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
|
||||
|
||||
"side-channel": ["[email protected]", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="],
|
||||
|
||||
"side-channel-list": ["[email protected]", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="],
|
||||
|
||||
"side-channel-map": ["[email protected]", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
|
||||
|
||||
"side-channel-weakmap": ["[email protected]", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
|
||||
|
||||
"source-map-js": ["[email protected]", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"statuses": ["[email protected]", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
|
||||
|
||||
"string-width": ["[email protected]", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"strip-ansi": ["[email protected]", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"tailwindcss": ["[email protected]", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="],
|
||||
|
||||
"tapable": ["[email protected]", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
|
||||
|
||||
"tinyglobby": ["[email protected]", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
|
||||
|
||||
"toidentifier": ["[email protected]", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||
|
||||
"tslib": ["[email protected]", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"tsx": ["[email protected]", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ=="],
|
||||
|
||||
"type-is": ["[email protected]", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
|
||||
|
||||
"typescript": ["[email protected]", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"undici-types": ["[email protected]", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"unpipe": ["[email protected]", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
|
||||
|
||||
"update-browserslist-db": ["[email protected]", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
||||
|
||||
"utils-merge": ["[email protected]", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
|
||||
|
||||
"vary": ["[email protected]", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
|
||||
|
||||
"vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A=="],
|
||||
|
||||
"web-streams-polyfill": ["[email protected]", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
|
||||
|
||||
"web-vitals": ["[email protected]", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="],
|
||||
|
||||
"websocket-driver": ["[email protected]", "", { "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA=="],
|
||||
|
||||
"websocket-extensions": ["[email protected]", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="],
|
||||
|
||||
"wrap-ansi": ["[email protected]", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||
|
||||
"ws": ["[email protected]", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="],
|
||||
|
||||
"y18n": ["[email protected]", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
|
||||
|
||||
"yallist": ["[email protected]", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"yargs": ["[email protected]", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="],
|
||||
|
||||
"yargs-parser": ["[email protected]", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
||||
|
||||
"@babel/core/debug": ["[email protected]", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"@babel/traverse/debug": ["[email protected]", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/[email protected]", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/[email protected]", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^2.0.0-alpha.3", "@emnapi/runtime": "^2.0.0-alpha.3" }, "bundled": true }, "sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["[email protected]", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"@types/serve-static/@types/send": ["@types/[email protected]", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="],
|
||||
|
||||
"https-proxy-agent/debug": ["[email protected]", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"send/ms": ["[email protected]", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"tsx/esbuild": ["[email protected]", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="],
|
||||
|
||||
"@babel/core/debug/ms": ["[email protected]", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"@babel/traverse/debug/ms": ["[email protected]", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"https-proxy-agent/debug/ms": ["[email protected]", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/android-arm": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/android-arm64": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/android-x64": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/[email protected]", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-arm": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/linux-x64": ["@esbuild/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/[email protected]", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/[email protected]", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/[email protected]", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="],
|
||||
|
||||
"tsx/esbuild/@esbuild/win32-x64": ["@esbuild/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="],
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"projectId": "project-db52cc12-fb0e-4a6a-892",
|
||||
"appId": "1:287394811407:web:0d0982e8a1be3e6a38dd7a",
|
||||
"apiKey": "AIzaSyCMYDO243gs6_2ppzGBEUtl6MhzXvzaGNI",
|
||||
"authDomain": "project-db52cc12-fb0e-4a6a-892.firebaseapp.com",
|
||||
"firestoreDatabaseId": "ai-studio-softwarex-55306b36-3d34-4fd9-a0e8-4c330db069c4",
|
||||
"storageBucket": "project-db52cc12-fb0e-4a6a-892.firebasestorage.app",
|
||||
"messagingSenderId": "287394811407",
|
||||
"measurementId": "",
|
||||
"oAuthClientId": "287394811407-stt67h6gobedl0126pvoagk4cukt8u5v.apps.googleusercontent.com",
|
||||
"recaptchaSiteKey": ""
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"entities": {
|
||||
"WaitlistEntry": {
|
||||
"collectionName": "waitlist_entries",
|
||||
"fields": {
|
||||
"id": { "type": "string" },
|
||||
"email": { "type": "string" },
|
||||
"fullName": { "type": "string" },
|
||||
"tier": { "type": "string" },
|
||||
"investmentAmount": { "type": "number" },
|
||||
"createdAt": { "type": "timestamp" },
|
||||
"position": { "type": "number" },
|
||||
"referralCode": { "type": "string" },
|
||||
"referredBy": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"WaitlistStats": {
|
||||
"collectionName": "stats",
|
||||
"fields": {
|
||||
"totalRegistered": { "type": "number" },
|
||||
"totalFundedAmount": { "type": "number" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
rules_version = '2';
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents {
|
||||
match /waitlist_entries/{entryId} {
|
||||
allow read: if true;
|
||||
allow create: if request.resource.data.email is string;
|
||||
allow update, delete: if false;
|
||||
}
|
||||
match /stats/{statId} {
|
||||
allow read: if true;
|
||||
allow write: if true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>My Google AI Studio App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Software X",
|
||||
"description": "Premium launch platform and brand strategy for Software X.",
|
||||
"requestFramePermissions": [],
|
||||
"majorCapabilities": ["MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API"]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "react-example",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist server.js",
|
||||
"lint": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/genai": "^2.4.0",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@types/canvas-confetti": "^1.9.0",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"dotenv": "^17.2.3",
|
||||
"express": "^4.21.2",
|
||||
"firebase": "^12.17.1",
|
||||
"lucide-react": "^0.546.0",
|
||||
"motion": "^12.23.24",
|
||||
"react": "^19.0.1",
|
||||
"react-dom": "^19.0.1",
|
||||
"vite": "^6.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.14.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"esbuild": "^0.25.0",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "~5.8.2",
|
||||
"vite": "^6.2.3",
|
||||
"@types/express": "^4.17.21"
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Navbar } from './components/layout/Navbar';
|
||||
import { Footer } from './components/layout/Footer';
|
||||
import { HeroSection } from './components/sections/HeroSection';
|
||||
import { ProblemSection } from './components/sections/ProblemSection';
|
||||
import { SolutionSection } from './components/sections/SolutionSection';
|
||||
import { EcosystemSection } from './components/sections/EcosystemSection';
|
||||
import { MemeCoinLaunchSection } from './components/sections/MemeCoinLaunchSection';
|
||||
import { CommunityFundingSection } from './components/sections/CommunityFundingSection';
|
||||
import { FeaturesSection } from './components/sections/FeaturesSection';
|
||||
import { RoadmapSection } from './components/sections/RoadmapSection';
|
||||
import { StatsSection } from './components/sections/StatsSection';
|
||||
import { CommunitySection } from './components/sections/CommunitySection';
|
||||
import { FAQSection } from './components/sections/FAQSection';
|
||||
import { WaitlistSection } from './components/sections/WaitlistSection';
|
||||
import { VisionManifestoModal } from './components/sections/VisionManifestoModal';
|
||||
import { TokenomicsModal } from './components/sections/TokenomicsModal';
|
||||
|
||||
export default function App() {
|
||||
const [isTokenomicsOpen, setIsTokenomicsOpen] = useState(false);
|
||||
const [isVisionOpen, setIsVisionOpen] = useState(false);
|
||||
|
||||
const scrollToWaitlist = () => {
|
||||
const element = document.getElementById('waitlist');
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-950 text-slate-100 font-sans selection:bg-orange-500 selection:text-white antialiased">
|
||||
{/* Sticky Header */}
|
||||
<Navbar
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
onOpenTokenomics={() => setIsTokenomicsOpen(true)}
|
||||
onOpenVision={() => setIsVisionOpen(true)}
|
||||
/>
|
||||
|
||||
{/* Main Content Sections */}
|
||||
<main>
|
||||
<HeroSection
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
onOpenTokenomics={() => setIsTokenomicsOpen(true)}
|
||||
onOpenVision={() => setIsVisionOpen(true)}
|
||||
/>
|
||||
|
||||
<ProblemSection />
|
||||
|
||||
<SolutionSection />
|
||||
|
||||
<EcosystemSection onOpenWaitlist={scrollToWaitlist} />
|
||||
|
||||
<MemeCoinLaunchSection
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
onOpenTokenomics={() => setIsTokenomicsOpen(true)}
|
||||
/>
|
||||
|
||||
<CommunityFundingSection
|
||||
onOpenTokenomics={() => setIsTokenomicsOpen(true)}
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
/>
|
||||
|
||||
<FeaturesSection />
|
||||
|
||||
<RoadmapSection onOpenWaitlist={scrollToWaitlist} />
|
||||
|
||||
<StatsSection />
|
||||
|
||||
<CommunitySection />
|
||||
|
||||
<FAQSection />
|
||||
|
||||
<WaitlistSection />
|
||||
</main>
|
||||
|
||||
{/* Footer */}
|
||||
<Footer
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
onOpenTokenomics={() => setIsTokenomicsOpen(true)}
|
||||
onOpenVision={() => setIsVisionOpen(true)}
|
||||
/>
|
||||
|
||||
{/* Modals */}
|
||||
<VisionManifestoModal
|
||||
isOpen={isVisionOpen}
|
||||
onClose={() => setIsVisionOpen(false)}
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
/>
|
||||
|
||||
<TokenomicsModal
|
||||
isOpen={isTokenomicsOpen}
|
||||
onClose={() => setIsTokenomicsOpen(false)}
|
||||
onOpenWaitlist={scrollToWaitlist}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 841 KiB |
@@ -0,0 +1,178 @@
|
||||
import React from 'react';
|
||||
import { Layers, Github, Twitter, MessageSquare, ShieldCheck, ArrowUpRight, Activity } from 'lucide-react';
|
||||
import { Badge } from '../ui/Badge';
|
||||
|
||||
interface FooterProps {
|
||||
onOpenWaitlist: () => void;
|
||||
onOpenTokenomics: () => void;
|
||||
onOpenVision: () => void;
|
||||
}
|
||||
|
||||
export const Footer: React.FC<FooterProps> = ({
|
||||
onOpenWaitlist,
|
||||
onOpenTokenomics,
|
||||
onOpenVision
|
||||
}) => {
|
||||
return (
|
||||
<footer className="relative bg-slate-950 border-t border-slate-900 pt-16 pb-12 overflow-hidden">
|
||||
{/* Subtle background gradient glow */}
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-3/4 h-24 bg-orange-500/5 blur-3xl rounded-full pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-10 pb-12 border-b border-slate-900">
|
||||
|
||||
{/* Brand Info */}
|
||||
<div className="lg:col-span-2 flex flex-col gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-9 h-9 rounded-xl bg-gradient-to-tr from-orange-500 via-amber-500 to-sky-500 flex items-center justify-center p-[1px]">
|
||||
<div className="w-full h-full bg-slate-950 rounded-[11px] flex items-center justify-center">
|
||||
<Layers className="w-4 h-4 text-orange-400" />
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-xl font-bold tracking-tight text-white">
|
||||
Software <span className="text-orange-400">X</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-slate-400 max-w-sm leading-relaxed">
|
||||
Software X is the evolution of BirthdayMessaging.io, anchoring an ecosystem of 30+ digital tools funded directly by a fair community token. Zero VCs. 100% real products.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-2 pt-2">
|
||||
<Badge variant="sky" showDot={true}>
|
||||
<Activity className="w-3 h-3 text-sky-400 inline mr-1" />
|
||||
All 30+ Products Operational
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Ecosystem Column */}
|
||||
<div className="flex flex-col gap-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-widest text-slate-400 font-semibold">
|
||||
Ecosystem Products
|
||||
</h4>
|
||||
<ul className="flex flex-col gap-2.5 text-sm">
|
||||
<li>
|
||||
<a href="#ecosystem" className="text-slate-400 hover:text-white transition-colors flex items-center gap-1 group">
|
||||
<span>BirthdayMessaging.io</span>
|
||||
<ArrowUpRight className="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ecosystem" className="text-slate-400 hover:text-white transition-colors">
|
||||
SignalDrop Protocol
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ecosystem" className="text-slate-400 hover:text-white transition-colors">
|
||||
CraftFlow Engine
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ecosystem" className="text-slate-400 hover:text-white transition-colors">
|
||||
TokenLedger Treasury
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ecosystem" className="text-slate-400 hover:text-white transition-colors">
|
||||
View All 30+ Apps
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Vision & Economics Column */}
|
||||
<div className="flex flex-col gap-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-widest text-slate-400 font-semibold">
|
||||
Architecture & Vision
|
||||
</h4>
|
||||
<ul className="flex flex-col gap-2.5 text-sm">
|
||||
<li>
|
||||
<button onClick={onOpenVision} className="text-slate-400 hover:text-white transition-colors text-left cursor-pointer">
|
||||
Founder Manifesto
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button onClick={onOpenTokenomics} className="text-slate-400 hover:text-white transition-colors text-left cursor-pointer">
|
||||
Tokenomics & Allocation
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#why-community" className="text-slate-400 hover:text-white transition-colors">
|
||||
Why Zero VC Funding?
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#roadmap" className="text-slate-400 hover:text-white transition-colors">
|
||||
Public Development Roadmap
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<button onClick={onOpenWaitlist} className="text-slate-400 hover:text-orange-400 transition-colors text-left font-medium cursor-pointer">
|
||||
Join Early Waitlist →
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Social & Community Column */}
|
||||
<div className="flex flex-col gap-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-widest text-slate-400 font-semibold">
|
||||
Community Channels
|
||||
</h4>
|
||||
<div className="flex items-center gap-2">
|
||||
<a
|
||||
href="https://x.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-9 h-9 rounded-lg bg-slate-900 border border-slate-800 flex items-center justify-center text-slate-400 hover:text-white hover:border-slate-700 transition-all"
|
||||
aria-label="X (Twitter)"
|
||||
>
|
||||
<Twitter className="w-4 h-4" />
|
||||
</a>
|
||||
<a
|
||||
href="https://discord.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-9 h-9 rounded-lg bg-slate-900 border border-slate-800 flex items-center justify-center text-slate-400 hover:text-white hover:border-slate-700 transition-all"
|
||||
aria-label="Discord"
|
||||
>
|
||||
<MessageSquare className="w-4 h-4" />
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="w-9 h-9 rounded-lg bg-slate-900 border border-slate-800 flex items-center justify-center text-slate-400 hover:text-white hover:border-slate-700 transition-all"
|
||||
aria-label="GitHub"
|
||||
>
|
||||
<Github className="w-4 h-4" />
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 leading-relaxed mt-2">
|
||||
Join 18,000+ early supporters across our active community channels.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Bottom Bar */}
|
||||
<div className="pt-8 flex flex-col sm:flex-row items-center justify-between gap-4 text-xs text-slate-400">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>© 2026 Software X Labs. Built for real utility.</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-6">
|
||||
<span className="flex items-center gap-1.5 text-slate-400">
|
||||
<ShieldCheck className="w-3.5 h-3.5 text-sky-400" />
|
||||
100% On-Chain Treasury Verified
|
||||
</span>
|
||||
<a href="#faq" className="hover:text-slate-300 transition-colors">
|
||||
Privacy & Disclaimer
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,213 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import { Layers, Menu, X, ArrowRight, ShieldCheck, PieChart, Sparkles } from 'lucide-react';
|
||||
import { Button } from '../ui/Button';
|
||||
import { Badge } from '../ui/Badge';
|
||||
|
||||
interface NavbarProps {
|
||||
onOpenWaitlist: () => void;
|
||||
onOpenTokenomics: () => void;
|
||||
onOpenVision: () => void;
|
||||
}
|
||||
|
||||
export const Navbar: React.FC<NavbarProps> = ({
|
||||
onOpenWaitlist,
|
||||
onOpenTokenomics,
|
||||
onOpenVision
|
||||
}) => {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setScrolled(window.scrollY > 20);
|
||||
};
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
const navLinks = [
|
||||
{ label: 'Ecosystem', href: '#ecosystem' },
|
||||
{ label: 'Aug 24 Launch', href: '#memecoin-launch' },
|
||||
{ label: 'Why Community', href: '#community-funding' },
|
||||
{ label: 'Features', href: '#features' },
|
||||
{ label: 'Roadmap', href: '#roadmap' },
|
||||
{ label: 'FAQ', href: '#faq' }
|
||||
];
|
||||
|
||||
const handleNavClick = (href: string) => {
|
||||
setMobileMenuOpen(false);
|
||||
const element = document.querySelector(href);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.header
|
||||
initial={{ y: -100 }}
|
||||
animate={{ y: 0 }}
|
||||
transition={{ duration: 0.5, ease: 'easeOut' }}
|
||||
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
||||
scrolled
|
||||
? 'bg-slate-950/80 backdrop-blur-xl border-b border-slate-800/80 shadow-2xl shadow-black/50 py-3.5'
|
||||
: 'bg-transparent py-5'
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
|
||||
{/* Brand Logo */}
|
||||
<a
|
||||
href="#"
|
||||
className="flex items-center gap-3 group focus:outline-none"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}}
|
||||
>
|
||||
<div className="relative flex items-center justify-center w-10 h-10 rounded-xl bg-gradient-to-tr from-orange-500 via-amber-500 to-sky-400 p-[1px] shadow-lg shadow-orange-500/20 group-hover:shadow-orange-500/40 transition-shadow">
|
||||
<div className="w-full h-full bg-slate-950 rounded-[11px] flex items-center justify-center">
|
||||
<Layers className="w-5 h-5 text-orange-400 group-hover:rotate-12 transition-transform duration-300" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xl font-bold tracking-tight text-white font-sans">
|
||||
Software <span className="text-orange-400">X</span>
|
||||
</span>
|
||||
<Badge variant="tangerine" showDot={true} className="hidden sm:inline-flex">
|
||||
30+ Apps
|
||||
</Badge>
|
||||
</div>
|
||||
<span className="text-[10px] text-slate-400 font-mono tracking-wider uppercase">
|
||||
BirthdayMessaging Ecosystem
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{/* Desktop Navigation Links */}
|
||||
<nav className="hidden lg:flex items-center gap-1 bg-slate-900/60 p-1.5 rounded-full border border-slate-800/80 backdrop-blur-md">
|
||||
{navLinks.map((link) => (
|
||||
<button
|
||||
key={link.label}
|
||||
onClick={() => handleNavClick(link.href)}
|
||||
className="px-4 py-1.5 text-xs font-medium text-slate-300 hover:text-white hover:bg-slate-800/60 rounded-full transition-all cursor-pointer"
|
||||
>
|
||||
{link.label}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* Desktop Actions */}
|
||||
<div className="hidden sm:flex items-center gap-3">
|
||||
<button
|
||||
onClick={onOpenTokenomics}
|
||||
className="inline-flex items-center gap-1.5 text-xs font-medium text-slate-300 hover:text-white px-3 py-2 rounded-lg hover:bg-slate-800/50 transition-colors cursor-pointer"
|
||||
>
|
||||
<PieChart className="w-3.5 h-3.5 text-orange-400" />
|
||||
<span>Tokenomics</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={onOpenVision}
|
||||
className="inline-flex items-center gap-1.5 text-xs font-medium text-slate-300 hover:text-white px-3 py-2 rounded-lg hover:bg-slate-800/50 transition-colors cursor-pointer"
|
||||
>
|
||||
<ShieldCheck className="w-3.5 h-3.5 text-sky-400" />
|
||||
<span>Manifesto</span>
|
||||
</button>
|
||||
<Button
|
||||
variant="glow"
|
||||
size="sm"
|
||||
onClick={onOpenWaitlist}
|
||||
icon={<ArrowRight className="w-3.5 h-3.5" />}
|
||||
>
|
||||
Join Waitlist
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
<div className="flex items-center gap-2 sm:hidden">
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={onOpenWaitlist}
|
||||
className="px-3 py-1.5 text-xs"
|
||||
>
|
||||
Waitlist
|
||||
</Button>
|
||||
<button
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
className="p-2 text-slate-400 hover:text-white bg-slate-900 rounded-xl border border-slate-800"
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
{mobileMenuOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.header>
|
||||
|
||||
{/* Mobile Drawer */}
|
||||
<AnimatePresence>
|
||||
{mobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
className="fixed inset-x-0 top-[70px] z-40 bg-slate-950/95 backdrop-blur-2xl border-b border-slate-800 p-6 sm:hidden shadow-2xl"
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex items-center justify-between pb-3 border-b border-slate-800">
|
||||
<span className="text-xs font-mono text-indigo-400 uppercase tracking-widest">Navigation</span>
|
||||
<Badge variant="emerald">Live Ecosystem</Badge>
|
||||
</div>
|
||||
|
||||
{navLinks.map((link) => (
|
||||
<button
|
||||
key={link.label}
|
||||
onClick={() => handleNavClick(link.href)}
|
||||
className="text-left text-base font-medium text-slate-200 hover:text-indigo-400 py-1"
|
||||
>
|
||||
{link.label}
|
||||
</button>
|
||||
))}
|
||||
|
||||
<div className="pt-4 border-t border-slate-800 flex flex-col gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
setMobileMenuOpen(false);
|
||||
onOpenTokenomics();
|
||||
}}
|
||||
className="flex items-center gap-2 text-sm text-slate-300 py-2"
|
||||
>
|
||||
<PieChart className="w-4 h-4 text-indigo-400" />
|
||||
<span>Tokenomics & Treasury</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setMobileMenuOpen(false);
|
||||
onOpenVision();
|
||||
}}
|
||||
className="flex items-center gap-2 text-sm text-slate-300 py-2"
|
||||
>
|
||||
<ShieldCheck className="w-4 h-4 text-emerald-400" />
|
||||
<span>Founder Manifesto</span>
|
||||
</button>
|
||||
<Button
|
||||
variant="glow"
|
||||
size="md"
|
||||
onClick={() => {
|
||||
setMobileMenuOpen(false);
|
||||
onOpenWaitlist();
|
||||
}}
|
||||
icon={<ArrowRight className="w-4 h-4" />}
|
||||
className="w-full mt-2"
|
||||
>
|
||||
Join Waitlist
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,127 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { ShieldOff, Repeat, Eye, Sparkles, PieChart, ArrowRight, Check } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Button } from '../ui/Button';
|
||||
import { tokenomicsPrinciples } from '../../data/tokenomics';
|
||||
|
||||
interface CommunityFundingProps {
|
||||
onOpenTokenomics: () => void;
|
||||
onOpenWaitlist: () => void;
|
||||
}
|
||||
|
||||
export const CommunityFundingSection: React.FC<CommunityFundingProps> = ({
|
||||
onOpenTokenomics,
|
||||
onOpenWaitlist
|
||||
}) => {
|
||||
const getIcon = (iconName: string) => {
|
||||
switch (iconName) {
|
||||
case 'ShieldOff': return ShieldOff;
|
||||
case 'Repeat': return Repeat;
|
||||
case 'Eye': return Eye;
|
||||
default: return Sparkles;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="community-funding" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Fair Tokenomics"
|
||||
badgeVariant="tangerine"
|
||||
title="Why Community Funding?"
|
||||
gradientTitle="Real Software Backing."
|
||||
subtitle="We chose a community token over venture capital to preserve 100% independence, avoid predatory liquidation preferences, and reward our real product users."
|
||||
/>
|
||||
|
||||
{/* 4 Core Pillars Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-16">
|
||||
{tokenomicsPrinciples.map((principle, idx) => {
|
||||
const Icon = getIcon(principle.icon);
|
||||
return (
|
||||
<motion.div
|
||||
key={principle.title}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.4, delay: idx * 0.1 }}
|
||||
>
|
||||
<GlassCard className="h-full flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-gradient-to-tr from-orange-500 to-amber-600 flex items-center justify-center text-white mb-6 shadow-lg shadow-orange-950/40">
|
||||
<Icon className="w-6 h-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">{principle.title}</h3>
|
||||
<p className="text-xs text-slate-400 leading-relaxed">{principle.description}</p>
|
||||
</div>
|
||||
<div className="mt-6 pt-3 border-t border-slate-800/80 flex items-center gap-1.5 text-xs text-sky-400 font-mono">
|
||||
<Check className="w-3.5 h-3.5" />
|
||||
<span>Enforced via Smart Contract</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Tokenomics Highlights Banner */}
|
||||
<div className="p-8 sm:p-10 rounded-3xl bg-gradient-to-r from-slate-900 via-orange-950/60 to-slate-900 border border-orange-500/30 shadow-2xl relative overflow-hidden flex flex-col lg:flex-row items-center justify-between gap-8">
|
||||
<div className="flex-1">
|
||||
<span className="text-xs font-mono text-orange-400 uppercase tracking-widest font-semibold">
|
||||
Transparent Distribution
|
||||
</span>
|
||||
<h3 className="text-2xl sm:text-3xl font-bold text-white mt-2">
|
||||
100% Verifiable On-Chain Token Allocations
|
||||
</h3>
|
||||
<p className="text-sm text-slate-300 mt-3 max-w-xl leading-relaxed">
|
||||
Explore our exact vesting schedule, liquidity locks, and engineering budget allocations before the public token launch. Zero hidden presales.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-4 mt-6">
|
||||
<Button
|
||||
variant="glow"
|
||||
size="md"
|
||||
onClick={onOpenTokenomics}
|
||||
icon={<PieChart className="w-4 h-4" />}
|
||||
>
|
||||
Open Tokenomics Breakdown
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="md"
|
||||
onClick={onOpenWaitlist}
|
||||
icon={<ArrowRight className="w-4 h-4" />}
|
||||
>
|
||||
Reserve Waitlist Spot
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full lg:w-72 p-6 rounded-2xl bg-slate-950/80 border border-slate-800 backdrop-blur-md">
|
||||
<h4 className="text-xs font-mono text-slate-400 uppercase tracking-widest mb-4">Allocation Summary</h4>
|
||||
<ul className="flex flex-col gap-3 text-xs">
|
||||
<li className="flex justify-between items-center">
|
||||
<span className="text-slate-300">Software R&D</span>
|
||||
<span className="font-mono font-bold text-orange-400">45%</span>
|
||||
</li>
|
||||
<li className="flex justify-between items-center">
|
||||
<span className="text-slate-300">Public Liquidity (Locked)</span>
|
||||
<span className="font-mono font-bold text-sky-400">30%</span>
|
||||
</li>
|
||||
<li className="flex justify-between items-center">
|
||||
<span className="text-slate-300">Community Airdrops</span>
|
||||
<span className="font-mono font-bold text-amber-400">15%</span>
|
||||
</li>
|
||||
<li className="flex justify-between items-center">
|
||||
<span className="text-slate-300">Treasury Reserve</span>
|
||||
<span className="font-mono font-bold text-sky-300">10%</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,156 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { Twitter, MessageSquare, Github, Linkedin, Send, ShieldCheck, CheckCircle2, Heart } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Badge } from '../ui/Badge';
|
||||
|
||||
export const CommunitySection: React.FC = () => {
|
||||
const socialChannels = [
|
||||
{
|
||||
name: 'X (Twitter)',
|
||||
icon: Twitter,
|
||||
members: '12,400+ Followers',
|
||||
description: 'Daily product updates, engineering deep dives & founder announcements.',
|
||||
link: 'https://x.com',
|
||||
badge: 'Official Feed'
|
||||
},
|
||||
{
|
||||
name: 'Discord Community',
|
||||
icon: MessageSquare,
|
||||
members: '8,200+ Members',
|
||||
description: 'Engage with core engineers, test private beta builds & join dev workshops.',
|
||||
link: 'https://discord.com',
|
||||
badge: 'Beta Testing'
|
||||
},
|
||||
{
|
||||
name: 'Telegram Hub',
|
||||
icon: Send,
|
||||
members: '5,800+ Members',
|
||||
description: 'Real-time protocol telemetry, treasury announcements & community discussion.',
|
||||
link: 'https://t.me',
|
||||
badge: 'Live Chat'
|
||||
},
|
||||
{
|
||||
name: 'GitHub Protocol',
|
||||
icon: Github,
|
||||
members: 'Open Source',
|
||||
description: 'Inspect our smart contract repositories, SDK code & SDK documentation.',
|
||||
link: 'https://github.com',
|
||||
badge: 'Verified Code'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="community" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Join The Movement"
|
||||
badgeVariant="tangerine"
|
||||
title="Built Out in the Open."
|
||||
gradientTitle="Backed by Community."
|
||||
subtitle="Software X is guided by real users, software engineers, and community members worldwide."
|
||||
/>
|
||||
|
||||
{/* Social Cards Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-16">
|
||||
{socialChannels.map((channel) => {
|
||||
const Icon = channel.icon;
|
||||
return (
|
||||
<GlassCard key={channel.name} className="flex flex-col justify-between group">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="w-10 h-10 rounded-xl bg-slate-800 border border-slate-700 flex items-center justify-center text-orange-400 group-hover:scale-110 transition-transform">
|
||||
<Icon className="w-5 h-5" />
|
||||
</div>
|
||||
<Badge variant="neutral">{channel.badge}</Badge>
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-bold text-white group-hover:text-orange-400 transition-colors">
|
||||
{channel.name}
|
||||
</h3>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
{channel.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 pt-3 border-t border-slate-800/80 flex items-center justify-between text-xs">
|
||||
<span className="font-mono text-slate-400">{channel.members}</span>
|
||||
<a
|
||||
href={channel.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-orange-400 hover:text-orange-300 font-medium transition-colors"
|
||||
>
|
||||
Join Channel →
|
||||
</a>
|
||||
</div>
|
||||
</GlassCard>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Founder's Signed Transparency Pledge Card */}
|
||||
<div className="p-8 sm:p-10 rounded-3xl bg-slate-900/90 border border-sky-500/30 shadow-2xl relative overflow-hidden backdrop-blur-xl">
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 pb-6 border-b border-slate-800">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-sky-950 border border-sky-500/30 flex items-center justify-center text-sky-400">
|
||||
<ShieldCheck className="w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-white">Founders' Public Commitment Pledge</h3>
|
||||
<p className="text-xs text-slate-400 font-mono">Signed by the Software X & BirthdayMessaging.io Core Team</p>
|
||||
</div>
|
||||
</div>
|
||||
<Badge variant="sky" showDot={true}>
|
||||
100% Irrevocable
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6">
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-sky-400 mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white">Product Before Token</h4>
|
||||
<p className="text-xs text-slate-400 mt-1 leading-relaxed">
|
||||
We pledge to prioritize real software updates across BirthdayMessaging.io and the 30+ products above speculative token marketing.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-sky-400 mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white">Zero Insider Deals or Secret Discounts</h4>
|
||||
<p className="text-xs text-slate-400 mt-1 leading-relaxed">
|
||||
No venture capital funds or private insiders hold secret discounted tokens. Public liquidity is 100% permanently locked.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-sky-400 mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white">Multi-Sig Public Treasury Verification</h4>
|
||||
<p className="text-xs text-slate-400 mt-1 leading-relaxed">
|
||||
100% of engineering expenditure and subscription revenue buy-backs are viewable on public smart contracts with real-time telemetry.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-sky-400 mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white">Continuous Revenue Buy-Backs</h4>
|
||||
<p className="text-xs text-slate-400 mt-1 leading-relaxed">
|
||||
A dedicated percentage of subscription revenues generated by ecosystem products is automatically routed into $SX token buy-backs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,328 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import {
|
||||
Search,
|
||||
Gift,
|
||||
Radio,
|
||||
Zap,
|
||||
Cpu,
|
||||
UserCheck,
|
||||
BarChart3,
|
||||
ShieldCheck,
|
||||
Activity,
|
||||
ArrowUpRight,
|
||||
CheckCircle2,
|
||||
Layers,
|
||||
Mail,
|
||||
Users,
|
||||
Target,
|
||||
Database,
|
||||
HeartHandshake,
|
||||
MapPin,
|
||||
Video,
|
||||
Globe,
|
||||
FileText,
|
||||
Image,
|
||||
TrendingUp,
|
||||
Brain,
|
||||
AlertTriangle,
|
||||
CheckSquare,
|
||||
Award,
|
||||
Share2,
|
||||
BarChart,
|
||||
Tv,
|
||||
DollarSign,
|
||||
Sparkles,
|
||||
Flame,
|
||||
Sliders,
|
||||
FolderPlus,
|
||||
FileSpreadsheet,
|
||||
Coins,
|
||||
Briefcase,
|
||||
Store,
|
||||
Compass,
|
||||
Calculator,
|
||||
Building,
|
||||
Star,
|
||||
ExternalLink,
|
||||
Tag
|
||||
} from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Badge } from '../ui/Badge';
|
||||
import { ecosystemApps } from '../../data/ecosystem';
|
||||
|
||||
interface EcosystemSectionProps {
|
||||
onOpenWaitlist: () => void;
|
||||
}
|
||||
|
||||
export const EcosystemSection: React.FC<EcosystemSectionProps> = ({ onOpenWaitlist }) => {
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('All');
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
|
||||
const categories = [
|
||||
'All',
|
||||
'Core Apps',
|
||||
'MicroApps',
|
||||
'MiniApps & Web',
|
||||
'Blockchain & Tokens',
|
||||
'Directories & Services'
|
||||
];
|
||||
|
||||
const filteredApps = ecosystemApps.filter((app) => {
|
||||
const matchesCategory = selectedCategory === 'All' || app.category === selectedCategory;
|
||||
const matchesSearch =
|
||||
app.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
app.description.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
app.badgeText.toLowerCase().includes(searchQuery.toLowerCase());
|
||||
return matchesCategory && matchesSearch;
|
||||
});
|
||||
|
||||
const getIcon = (iconName: string) => {
|
||||
switch (iconName) {
|
||||
case 'Gift': return Gift;
|
||||
case 'Zap': return Zap;
|
||||
case 'Mail': return Mail;
|
||||
case 'UserCheck': return UserCheck;
|
||||
case 'Radio': return Radio;
|
||||
case 'Activity': return Activity;
|
||||
case 'MessageSquare': return Mail;
|
||||
case 'ShieldCheck': return ShieldCheck;
|
||||
case 'Users': return Users;
|
||||
case 'Target': return Target;
|
||||
case 'Layers': return Layers;
|
||||
case 'Database': return Database;
|
||||
case 'HeartHandshake': return HeartHandshake;
|
||||
case 'MapPin': return MapPin;
|
||||
case 'Search': return Search;
|
||||
case 'Video': return Video;
|
||||
case 'Globe': return Globe;
|
||||
case 'Cpu': return Cpu;
|
||||
case 'FileText': return FileText;
|
||||
case 'Image': return Image;
|
||||
case 'TrendingUp': return TrendingUp;
|
||||
case 'Brain': return Brain;
|
||||
case 'AlertTriangle': return AlertTriangle;
|
||||
case 'CheckSquare': return CheckSquare;
|
||||
case 'Award': return Award;
|
||||
case 'Share2': return Share2;
|
||||
case 'BarChart': return BarChart;
|
||||
case 'Tv': return Tv;
|
||||
case 'DollarSign': return DollarSign;
|
||||
case 'Sparkles': return Sparkles;
|
||||
case 'Flame': return Flame;
|
||||
case 'Sliders': return Sliders;
|
||||
case 'FolderPlus': return FolderPlus;
|
||||
case 'FileSpreadsheet': return FileSpreadsheet;
|
||||
case 'Coins': return Coins;
|
||||
case 'Briefcase': return Briefcase;
|
||||
case 'Store': return Store;
|
||||
case 'Compass': return Compass;
|
||||
case 'Calculator': return Calculator;
|
||||
case 'Building': return Building;
|
||||
case 'Star': return Star;
|
||||
default: return Layers;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="ecosystem" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Live Ecosystem Portfolio"
|
||||
badgeVariant="tangerine"
|
||||
title="BirthdayMessaging Products,"
|
||||
gradientTitle="Offers & Services"
|
||||
subtitle="Explore the complete suite of flagship core apps, $17 micro-SaaS marketing programs, mini-apps, blockchain initiatives, and business services."
|
||||
/>
|
||||
|
||||
{/* Filter Controls Bar */}
|
||||
<div className="flex flex-col md:flex-row items-center justify-between gap-4 mb-10">
|
||||
{/* Category Tabs */}
|
||||
<div className="flex flex-wrap items-center gap-2 bg-slate-900/80 p-1.5 rounded-2xl border border-slate-800 backdrop-blur-md w-full md:w-auto">
|
||||
{categories.map((cat) => (
|
||||
<button
|
||||
key={cat}
|
||||
onClick={() => setSelectedCategory(cat)}
|
||||
className={`px-3.5 py-2 rounded-xl text-xs font-semibold transition-all cursor-pointer ${
|
||||
selectedCategory === cat
|
||||
? 'bg-orange-600 text-white shadow-lg shadow-orange-600/30'
|
||||
: 'text-slate-400 hover:text-white hover:bg-slate-800/50'
|
||||
}`}
|
||||
>
|
||||
{cat}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Search Bar */}
|
||||
<div className="relative w-full md:w-72">
|
||||
<Search className="w-4 h-4 text-slate-400 absolute left-3.5 top-1/2 -translate-y-1/2" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search products & tools..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full bg-slate-900/80 border border-slate-800 rounded-xl pl-10 pr-4 py-2 text-xs text-white placeholder-slate-400 focus:outline-none focus:border-orange-500 transition-colors"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* MicroApps Special $17 Program Banner if MicroApps selected */}
|
||||
{selectedCategory === 'MicroApps' && (
|
||||
<div className="mb-8 p-4 rounded-2xl bg-gradient-to-r from-orange-950/80 via-amber-950/60 to-slate-900 border border-orange-500/30 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-orange-600 flex items-center justify-center text-white font-bold text-sm shadow-md">
|
||||
$17
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white flex items-center gap-2">
|
||||
<span>22 Focused Marketing MicroApps</span>
|
||||
<Badge variant="tangerine">One-Time US$17</Badge>
|
||||
</h4>
|
||||
<p className="text-xs text-slate-300 mt-0.5">
|
||||
Pick the tool. Own it for good. No recurring plans, credits, or monthly charges.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="https://program-store-4z7.pages.dev/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="px-4 py-2 rounded-xl bg-orange-600 hover:bg-orange-500 text-white text-xs font-semibold flex items-center gap-2 transition-all flex-shrink-0 cursor-pointer"
|
||||
>
|
||||
<span>Visit MicroApps Store</span>
|
||||
<ExternalLink className="w-3.5 h-3.5" />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Product Cards Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<AnimatePresence mode="popLayout">
|
||||
{filteredApps.map((app) => {
|
||||
const Icon = getIcon(app.iconName);
|
||||
const hasLink = Boolean(app.link);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
key={app.id}
|
||||
layout
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.9 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
>
|
||||
<GlassCard
|
||||
gradientBorder={app.featured}
|
||||
className="h-full flex flex-col justify-between group relative"
|
||||
>
|
||||
<div>
|
||||
{/* Top Header */}
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-tr from-orange-500 to-amber-600 flex items-center justify-center text-white shadow-md group-hover:scale-110 transition-transform">
|
||||
<Icon className="w-5 h-5" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{app.price && (
|
||||
<span className="text-[10px] font-mono font-bold px-2 py-0.5 rounded-md bg-orange-950 text-orange-300 border border-orange-500/30 flex items-center gap-1">
|
||||
<Tag className="w-2.5 h-2.5" />
|
||||
{app.price}
|
||||
</span>
|
||||
)}
|
||||
<Badge
|
||||
variant={
|
||||
app.category === 'Core Apps'
|
||||
? 'tangerine'
|
||||
: app.category === 'MicroApps'
|
||||
? 'sky'
|
||||
: 'neutral'
|
||||
}
|
||||
>
|
||||
{app.badgeText}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title & Description */}
|
||||
<h3 className="text-lg font-bold text-white group-hover:text-orange-400 transition-colors flex items-center justify-between">
|
||||
<span>{app.name}</span>
|
||||
{hasLink ? (
|
||||
<a
|
||||
href={app.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-orange-400 hover:text-amber-300 transition-colors"
|
||||
title="Visit Page"
|
||||
>
|
||||
<ExternalLink className="w-4 h-4" />
|
||||
</a>
|
||||
) : (
|
||||
<ArrowUpRight className="w-4 h-4 opacity-0 group-hover:opacity-100 transition-opacity text-orange-400" />
|
||||
)}
|
||||
</h3>
|
||||
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
{app.description}
|
||||
</p>
|
||||
|
||||
{/* Highlights */}
|
||||
<div className="mt-4 pt-3 border-t border-slate-800/60 flex flex-col gap-1.5">
|
||||
{app.highlights.map((h, i) => (
|
||||
<span key={i} className="text-[11px] text-slate-300 flex items-center gap-1.5">
|
||||
<CheckCircle2 className="w-3 h-3 text-sky-400 flex-shrink-0" />
|
||||
{h}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Meta & Action Link */}
|
||||
<div className="mt-6 pt-3 border-t border-slate-800/80 flex items-center justify-between text-xs text-slate-400 font-mono">
|
||||
<span>{app.usersCount}</span>
|
||||
{hasLink ? (
|
||||
<a
|
||||
href={app.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-orange-400 hover:text-amber-300 font-semibold flex items-center gap-1 transition-colors cursor-pointer"
|
||||
>
|
||||
<span>Sales Page</span>
|
||||
<ExternalLink className="w-3 h-3" />
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
onClick={onOpenWaitlist}
|
||||
className="text-sky-400 hover:text-sky-300 font-semibold transition-colors cursor-pointer"
|
||||
>
|
||||
{app.growthRate || 'Get Access'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
{/* Footer Note */}
|
||||
<div className="mt-12 text-center bg-slate-900/60 p-6 rounded-2xl border border-slate-800 max-w-2xl mx-auto">
|
||||
<p className="text-xs text-slate-300 leading-relaxed font-mono">
|
||||
Explore all 23 US$17 marketing MicroApps on our central program store platform.
|
||||
</p>
|
||||
<a
|
||||
href="https://program-store-4z7.pages.dev/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-3 inline-flex items-center gap-2 text-xs font-bold text-orange-400 hover:text-amber-300 underline underline-offset-4 cursor-pointer"
|
||||
>
|
||||
<span>Open All Programs Store (https://program-store-4z7.pages.dev/)</span>
|
||||
<ExternalLink className="w-3.5 h-3.5" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,118 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import { ChevronDown, Search, HelpCircle } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { faqItems } from '../../data/faq';
|
||||
|
||||
export const FAQSection: React.FC = () => {
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('All');
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
const [openFaqId, setOpenFaqId] = useState<string | null>('faq-1');
|
||||
|
||||
const categories = ['All', 'General', 'Ecosystem', 'Tokenomics', 'Security'];
|
||||
|
||||
const filteredFaqs = faqItems.filter((faq) => {
|
||||
const matchesCategory = selectedCategory === 'All' || faq.category === selectedCategory;
|
||||
const matchesSearch =
|
||||
faq.question.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
faq.answer.toLowerCase().includes(searchQuery.toLowerCase());
|
||||
return matchesCategory && matchesSearch;
|
||||
});
|
||||
|
||||
const toggleAccordion = (id: string) => {
|
||||
setOpenFaqId(openFaqId === id ? null : id);
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="faq" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Clear Answers"
|
||||
badgeVariant="sky"
|
||||
title="Frequently Asked"
|
||||
gradientTitle="Questions"
|
||||
subtitle="Everything you need to know about Software X, BirthdayMessaging.io, tokenomics, and community-driven software development."
|
||||
/>
|
||||
|
||||
{/* Filter Controls Bar */}
|
||||
<div className="flex flex-col sm:flex-row items-center justify-between gap-4 mb-10">
|
||||
<div className="flex flex-wrap items-center gap-2 bg-slate-900/80 p-1.5 rounded-xl border border-slate-800 backdrop-blur-md w-full sm:w-auto">
|
||||
{categories.map((cat) => (
|
||||
<button
|
||||
key={cat}
|
||||
onClick={() => setSelectedCategory(cat)}
|
||||
className={`px-3.5 py-1.5 rounded-lg text-xs font-semibold transition-all cursor-pointer ${
|
||||
selectedCategory === cat
|
||||
? 'bg-orange-600 text-white shadow-md'
|
||||
: 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
{cat}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative w-full sm:w-64">
|
||||
<Search className="w-4 h-4 text-slate-400 absolute left-3 top-1/2 -translate-y-1/2" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search questions..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full bg-slate-900/80 border border-slate-800 rounded-xl pl-9 pr-3 py-1.5 text-xs text-white placeholder-slate-400 focus:outline-none focus:border-orange-500 transition-colors"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* FAQ Accordion List */}
|
||||
<div className="flex flex-col gap-4">
|
||||
{filteredFaqs.map((faq) => {
|
||||
const isOpen = openFaqId === faq.id;
|
||||
return (
|
||||
<GlassCard
|
||||
key={faq.id}
|
||||
hoverEffect={false}
|
||||
className="p-5 cursor-pointer transition-colors"
|
||||
onClick={() => toggleAccordion(faq.id)}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<h3 className="text-base font-bold text-white flex items-center gap-2">
|
||||
<HelpCircle className="w-4 h-4 text-orange-400 flex-shrink-0" />
|
||||
<span>{faq.question}</span>
|
||||
</h3>
|
||||
<div className={`p-1.5 rounded-lg bg-slate-800 text-slate-300 transition-transform duration-200 ${isOpen ? 'rotate-180 text-orange-400' : ''}`}>
|
||||
<ChevronDown className="w-4 h-4" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: 'auto', opacity: 1 }}
|
||||
exit={{ height: 0, opacity: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="overflow-hidden"
|
||||
>
|
||||
<p className="mt-4 pt-3 border-t border-slate-800/80 text-sm text-slate-300 leading-relaxed font-normal">
|
||||
{faq.answer}
|
||||
</p>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</GlassCard>
|
||||
);
|
||||
})}
|
||||
|
||||
{filteredFaqs.length === 0 && (
|
||||
<div className="p-8 text-center text-slate-400 font-mono text-xs">
|
||||
No matching questions found for "{searchQuery}".
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,184 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { KeyRound, TrendingUp, ShieldAlert, Brain, Activity, Code2, Sparkles, Check, Terminal, Copy } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Badge } from '../ui/Badge';
|
||||
|
||||
export const FeaturesSection: React.FC = () => {
|
||||
const [copiedCode, setCopiedCode] = useState(false);
|
||||
const [simulatedSubCount, setSimulatedSubCount] = useState<number>(5000);
|
||||
|
||||
const calculatedBuyback = (simulatedSubCount * 18 * 0.25).toLocaleString('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
});
|
||||
|
||||
const sampleSnippet = `import { SoftwareX } from '@software-x/sdk';
|
||||
|
||||
const sx = new SoftwareX({
|
||||
identityKey: process.env.SX_IDENTITY_KEY,
|
||||
ecosystemApp: 'birthday-messaging'
|
||||
});
|
||||
|
||||
// Authenticate user across 30+ ecosystem apps
|
||||
const session = await sx.auth.verifySession(token);
|
||||
console.log('User active across apps:', session.user.apps);`;
|
||||
|
||||
const copySnippet = () => {
|
||||
navigator.clipboard.writeText(sampleSnippet);
|
||||
setCopiedCode(true);
|
||||
setTimeout(() => setCopiedCode(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="features" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Platform Capabilities"
|
||||
badgeVariant="sky"
|
||||
title="Engineered for Performance."
|
||||
gradientTitle="Built for Scale."
|
||||
subtitle="Software X combines modern TypeScript microservices, zero-trust SSO authentication, and automated treasury buy-backs into a cohesive developer platform."
|
||||
/>
|
||||
|
||||
{/* Bento Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
|
||||
{/* Bento Card 1: Single Sign-On (Spans 2 columns on desktop) */}
|
||||
<GlassCard gradientBorder={true} className="lg:col-span-2 flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="w-10 h-10 rounded-xl bg-orange-600/20 border border-orange-500/30 flex items-center justify-center text-orange-400">
|
||||
<KeyRound className="w-5 h-5" />
|
||||
</div>
|
||||
<Badge variant="tangerine">Sub-Second Auth</Badge>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mb-2">
|
||||
Unified SSO & Zero-Trust Identity Key
|
||||
</h3>
|
||||
<p className="text-sm text-slate-400 leading-relaxed max-w-xl">
|
||||
One single key grants seamless authentication across BirthdayMessaging.io, SignalDrop, CraftFlow, and all 30+ ecosystem products with end-to-end client encryption.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Code Snippet Box inside Bento */}
|
||||
<div className="mt-6 p-4 rounded-xl bg-slate-950 border border-slate-800 font-mono text-xs text-slate-300 relative">
|
||||
<div className="flex items-center justify-between pb-2 mb-2 border-b border-slate-800 text-[11px] text-slate-400">
|
||||
<span className="flex items-center gap-1.5">
|
||||
<Terminal className="w-3.5 h-3.5 text-orange-400" /> software-x-auth.ts
|
||||
</span>
|
||||
<button
|
||||
onClick={copySnippet}
|
||||
className="flex items-center gap-1 hover:text-white transition-colors cursor-pointer"
|
||||
>
|
||||
{copiedCode ? <Check className="w-3 h-3 text-sky-400" /> : <Copy className="w-3 h-3" />}
|
||||
<span>{copiedCode ? 'Copied' : 'Copy'}</span>
|
||||
</button>
|
||||
</div>
|
||||
<pre className="overflow-x-auto text-[11px] leading-relaxed text-orange-200">
|
||||
{sampleSnippet}
|
||||
</pre>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
{/* Bento Card 2: Interactive Buy-Back Calculator */}
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="w-10 h-10 rounded-xl bg-sky-600/20 border border-sky-500/30 flex items-center justify-center text-sky-400">
|
||||
<TrendingUp className="w-5 h-5" />
|
||||
</div>
|
||||
<Badge variant="sky">Live Simulator</Badge>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mb-2">
|
||||
Automated Revenue Buy-Back Engine
|
||||
</h3>
|
||||
<p className="text-xs text-slate-400 leading-relaxed">
|
||||
Adjust simulated monthly paid subscribers across the 30+ apps to calculate quarterly treasury token buy-backs:
|
||||
</p>
|
||||
|
||||
{/* Slider Input */}
|
||||
<div className="mt-6 p-4 rounded-xl bg-slate-950 border border-slate-800">
|
||||
<div className="flex items-center justify-between text-xs text-slate-300 mb-2">
|
||||
<span>Monthly SaaS Subscribers:</span>
|
||||
<span className="font-mono font-bold text-sky-400">{simulatedSubCount.toLocaleString()}</span>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
min="1000"
|
||||
max="50000"
|
||||
step="1000"
|
||||
value={simulatedSubCount}
|
||||
onChange={(e) => setSimulatedSubCount(parseInt(e.target.value, 10))}
|
||||
className="w-full accent-sky-500 cursor-pointer"
|
||||
/>
|
||||
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 flex items-center justify-between text-xs">
|
||||
<span className="text-slate-400">Est. Quarterly Treasury Buy-Back:</span>
|
||||
<span className="font-mono font-bold text-sky-300 text-sm">{calculatedBuyback}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-[11px] text-slate-400 mt-4 font-mono">
|
||||
100% of buy-backs are executed on public DEX liquidity pools.
|
||||
</p>
|
||||
</GlassCard>
|
||||
|
||||
{/* Bento Card 3: AI-Powered Orchestration */}
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-10 h-10 rounded-xl bg-orange-600/20 border border-orange-500/30 flex items-center justify-center text-orange-400 mb-4">
|
||||
<Brain className="w-5 h-5" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">AI-Powered Orchestration</h3>
|
||||
<p className="text-xs text-slate-400 leading-relaxed">
|
||||
Deep LLM integrations generate contextual birthday greetings, optimize message dispatch windows, and summarize team communications in real-time.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800/80 flex items-center justify-between text-xs text-orange-300 font-mono">
|
||||
<span>Latency: <180ms</span>
|
||||
<span>Gemini Powered</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
{/* Bento Card 4: Real-Time Transparency Telemetry */}
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-10 h-10 rounded-xl bg-sky-600/20 border border-sky-500/30 flex items-center justify-center text-sky-400 mb-4">
|
||||
<Activity className="w-5 h-5" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">Real-Time Telemetry</h3>
|
||||
<p className="text-xs text-slate-400 leading-relaxed">
|
||||
Public dashboards display live API request rates, database pings, active subscriptions, and multi-sig wallet balances with 100% mathematical integrity.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800/80 flex items-center justify-between text-xs text-sky-300 font-mono">
|
||||
<span>On-Chain Audited</span>
|
||||
<span>Public Dashboard</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
{/* Bento Card 5: Developer SDK & Open APIs */}
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-10 h-10 rounded-xl bg-amber-600/20 border border-amber-500/30 flex items-center justify-center text-amber-400 mb-4">
|
||||
<Code2 className="w-5 h-5" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-2">Developer SDK & Extensions</h3>
|
||||
<p className="text-xs text-slate-400 leading-relaxed">
|
||||
Build custom micro-SaaS extensions or plug third-party software into the Software X SSO identity matrix using our open-source TypeScript SDK.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800/80 flex items-center justify-between text-xs text-amber-300 font-mono">
|
||||
<span>TypeScript Native</span>
|
||||
<span>npm i @software-x/sdk</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,257 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { ArrowRight, ShieldCheck, Layers, Sparkles, CheckCircle2, Zap, Users, Gift, Radio, Cpu, Activity } from 'lucide-react';
|
||||
import { Button } from '../ui/Button';
|
||||
import { Badge } from '../ui/Badge';
|
||||
import { AnimatedCounter } from '../ui/AnimatedCounter';
|
||||
|
||||
interface HeroSectionProps {
|
||||
onOpenWaitlist: () => void;
|
||||
onOpenTokenomics: () => void;
|
||||
onOpenVision: () => void;
|
||||
}
|
||||
|
||||
export const HeroSection: React.FC<HeroSectionProps> = ({
|
||||
onOpenWaitlist,
|
||||
onOpenTokenomics,
|
||||
onOpenVision
|
||||
}) => {
|
||||
const [activeNode, setActiveNode] = useState<string>('birthday-messaging');
|
||||
const [quickEmail, setQuickEmail] = useState('');
|
||||
|
||||
const handleQuickSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (quickEmail) {
|
||||
onOpenWaitlist();
|
||||
}
|
||||
};
|
||||
|
||||
const ecosystemNodes = [
|
||||
{ id: 'birthday-messaging', name: 'BirthdayMessaging.io', icon: Gift, users: '85k+ Users', status: 'Live Flagship', color: 'from-pink-500 to-rose-600' },
|
||||
{ id: 'software-x-core', name: 'Software X Core', icon: Cpu, users: 'Protocol Hub', status: 'Core Protocol', color: 'from-indigo-500 to-purple-600' },
|
||||
{ id: 'signaldrop', name: 'SignalDrop Protocol', icon: Radio, users: '18k+ Users', status: 'Live App', color: 'from-emerald-500 to-teal-600' },
|
||||
{ id: 'craftflow', name: 'CraftFlow Engine', icon: Zap, users: '12k+ Creators', status: 'Live App', color: 'from-amber-500 to-orange-600' }
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="relative min-h-screen pt-32 pb-20 flex flex-col justify-center overflow-hidden bg-slate-950">
|
||||
{/* Background ambient lighting effects */}
|
||||
<div className="absolute top-1/4 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-orange-600/15 rounded-full blur-[120px] pointer-events-none" />
|
||||
<div className="absolute top-1/3 left-1/4 w-[400px] h-[400px] bg-sky-600/15 rounded-full blur-[100px] pointer-events-none" />
|
||||
<div className="absolute top-1/2 right-1/4 w-[500px] h-[500px] bg-amber-600/10 rounded-full blur-[120px] pointer-events-none" />
|
||||
|
||||
{/* Grid pattern overlay */}
|
||||
<div
|
||||
className="absolute inset-0 bg-[linear-gradient(to_right,#1e293b15_1px,transparent_1px),linear-gradient(to_bottom,#1e293b15_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_0%,#000_70%,transparent_100%)] pointer-events-none"
|
||||
/>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 w-full">
|
||||
<div className="flex flex-col items-center text-center">
|
||||
|
||||
{/* Top Announcement Pill */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="mb-6"
|
||||
>
|
||||
<div
|
||||
onClick={onOpenVision}
|
||||
className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-slate-900/80 border border-orange-500/30 backdrop-blur-md cursor-pointer hover:border-orange-400/60 transition-all group"
|
||||
>
|
||||
<Badge variant="sky" showDot={true}>
|
||||
Next-Gen Launch
|
||||
</Badge>
|
||||
<span className="text-xs font-medium text-slate-300 group-hover:text-white transition-colors">
|
||||
The Evolution of BirthdayMessaging.io & 30+ Products
|
||||
</span>
|
||||
<ArrowRight className="w-3.5 h-3.5 text-orange-400 group-hover:translate-x-1 transition-transform" />
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Main Headline */}
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.1 }}
|
||||
className="text-4xl sm:text-6xl lg:text-7xl font-extrabold text-white tracking-tight max-w-4xl leading-[1.1]"
|
||||
>
|
||||
Building World-Class Software.{' '}
|
||||
<span className="bg-gradient-to-r from-orange-400 via-amber-300 to-sky-400 bg-clip-text text-transparent">
|
||||
Powered by the Community.
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
{/* Subtitle */}
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="mt-6 text-lg sm:text-xl text-slate-300 max-w-2xl leading-relaxed font-normal"
|
||||
>
|
||||
Software X is the core protocol connecting 30+ live digital products. Funded by a fair community token to build real, revenue-generating software — zero VC dilution.
|
||||
</motion.p>
|
||||
|
||||
{/* Fast Email Waitlist Box */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 }}
|
||||
className="mt-8 w-full max-w-md"
|
||||
>
|
||||
<form onSubmit={handleQuickSubmit} className="flex flex-col sm:flex-row gap-2 bg-slate-900/90 p-2 rounded-2xl border border-slate-800 backdrop-blur-xl shadow-2xl shadow-black/60">
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Enter your work email address..."
|
||||
value={quickEmail}
|
||||
onChange={(e) => setQuickEmail(e.target.value)}
|
||||
className="flex-1 bg-transparent px-4 py-3 text-sm text-white placeholder-slate-400 focus:outline-none w-full"
|
||||
required
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="glow"
|
||||
size="md"
|
||||
icon={<ArrowRight className="w-4 h-4" />}
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
Join Waitlist
|
||||
</Button>
|
||||
</form>
|
||||
<div className="flex items-center justify-center gap-4 mt-3 text-xs text-slate-400">
|
||||
<span className="flex items-center gap-1">
|
||||
<CheckCircle2 className="w-3.5 h-3.5 text-sky-400" /> No VC Presale
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<CheckCircle2 className="w-3.5 h-3.5 text-sky-400" /> Instant Queue Position
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<CheckCircle2 className="w-3.5 h-3.5 text-sky-400" /> 100% Free Access
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Quick Metrics Bar */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.4 }}
|
||||
className="mt-12 grid grid-cols-2 sm:grid-cols-4 gap-4 sm:gap-8 w-full max-w-4xl py-6 px-8 rounded-2xl bg-slate-900/50 border border-slate-800/80 backdrop-blur-md"
|
||||
>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="text-2xl sm:text-3xl font-bold text-white font-mono">
|
||||
<AnimatedCounter end={30} suffix="+" />
|
||||
</div>
|
||||
<span className="text-xs text-slate-400 mt-1">Live Ecosystem Apps</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="text-2xl sm:text-3xl font-bold text-sky-400 font-mono">
|
||||
<AnimatedCounter end={140000} suffix="+" />
|
||||
</div>
|
||||
<span className="text-xs text-slate-400 mt-1">Active Monthly Users</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="text-2xl sm:text-3xl font-bold text-orange-400 font-mono">
|
||||
$0.00
|
||||
</div>
|
||||
<span className="text-xs text-slate-400 mt-1">Venture Capital Taken</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="text-2xl sm:text-3xl font-bold text-amber-400 font-mono">
|
||||
100%
|
||||
</div>
|
||||
<span className="text-xs text-slate-400 mt-1">On-Chain Treasury Audit</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Interactive Node Interactive Visualizer */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.8, delay: 0.5 }}
|
||||
className="mt-14 w-full max-w-5xl rounded-3xl bg-slate-900/80 border border-slate-800 p-6 sm:p-8 shadow-2xl relative overflow-hidden backdrop-blur-xl"
|
||||
>
|
||||
{/* Header of Visualizer */}
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between pb-6 border-b border-slate-800 gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-3 h-3 rounded-full bg-orange-500" />
|
||||
<div className="w-3 h-3 rounded-full bg-amber-500" />
|
||||
<div className="w-3 h-3 rounded-full bg-sky-500" />
|
||||
<span className="text-xs font-mono text-slate-400 ml-2">software-x://ecosystem-matrix.v1</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant="sky">Interactive Topology</Badge>
|
||||
<button
|
||||
onClick={onOpenTokenomics}
|
||||
className="text-xs text-orange-400 hover:text-orange-300 font-medium cursor-pointer"
|
||||
>
|
||||
View Treasury →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Visual Grid Nodes */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mt-6">
|
||||
{ecosystemNodes.map((node) => {
|
||||
const Icon = node.icon;
|
||||
const isSelected = activeNode === node.id;
|
||||
return (
|
||||
<div
|
||||
key={node.id}
|
||||
onClick={() => setActiveNode(node.id)}
|
||||
className={`p-5 rounded-2xl border transition-all cursor-pointer flex flex-col justify-between ${
|
||||
isSelected
|
||||
? 'bg-slate-800/90 border-orange-500 shadow-xl shadow-orange-950/40 ring-1 ring-orange-500/50'
|
||||
: 'bg-slate-950/60 border-slate-800/80 hover:border-slate-700'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className={`w-10 h-10 rounded-xl bg-gradient-to-tr ${node.color} flex items-center justify-center text-white shadow-md`}>
|
||||
<Icon className="w-5 h-5" />
|
||||
</div>
|
||||
<span className="text-[11px] font-mono px-2 py-0.5 rounded bg-slate-900 text-slate-300 border border-slate-800">
|
||||
{node.status}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-base font-bold text-white">{node.name}</h4>
|
||||
<p className="text-xs text-slate-400 mt-1 flex items-center gap-1">
|
||||
<Users className="w-3 h-3 text-sky-400" /> {node.users}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-3 border-t border-slate-800/60 flex items-center justify-between text-[11px] text-slate-400 font-mono">
|
||||
<span>Status: Operational</span>
|
||||
<span className="text-sky-400">● 99.9% Uptime</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Active Node Detail Drawer inside Hero */}
|
||||
<div className="mt-6 p-4 rounded-xl bg-slate-950/90 border border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Activity className="w-5 h-5 text-orange-400 animate-pulse" />
|
||||
<div className="text-left">
|
||||
<p className="text-xs font-mono text-slate-400">Selected Node telemetry:</p>
|
||||
<p className="text-sm font-medium text-white">
|
||||
{activeNode === 'birthday-messaging' && 'BirthdayMessaging.io: 85,000+ Active Users • Multi-channel automated engine'}
|
||||
{activeNode === 'software-x-core' && 'Software X Core Protocol: Unified Single Sign-On and automated revenue burn contracts'}
|
||||
{activeNode === 'signaldrop' && 'SignalDrop Protocol: 18,200+ Active encrypted message routes across 24 regions'}
|
||||
{activeNode === 'craftflow' && 'CraftFlow Engine: 12,400+ Active workflows deployed with sub-50ms execution runtime'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button variant="outline" size="sm" onClick={onOpenWaitlist}>
|
||||
Access Protocol
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,960 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import {
|
||||
Sparkles,
|
||||
Clock,
|
||||
Coins,
|
||||
ShieldCheck,
|
||||
Gift,
|
||||
Flame,
|
||||
Award,
|
||||
Crown,
|
||||
CheckCircle2,
|
||||
ExternalLink,
|
||||
ChevronRight,
|
||||
Package,
|
||||
Zap,
|
||||
Lock,
|
||||
Globe,
|
||||
Users,
|
||||
Vote,
|
||||
Star,
|
||||
Check,
|
||||
ArrowRight,
|
||||
Eye,
|
||||
Sliders,
|
||||
DollarSign,
|
||||
TrendingUp,
|
||||
Gift as GiftIcon
|
||||
} from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Badge } from '../ui/Badge';
|
||||
import { Button } from '../ui/Button';
|
||||
|
||||
// Import generated image of the 3 coins
|
||||
import coinShowcaseImg from '../../assets/images/birthday_memecoins_1785932159451.jpg';
|
||||
|
||||
interface MemeCoinLaunchSectionProps {
|
||||
onOpenWaitlist: () => void;
|
||||
onOpenTokenomics: () => void;
|
||||
}
|
||||
|
||||
export const MemeCoinLaunchSection: React.FC<MemeCoinLaunchSectionProps> = ({
|
||||
onOpenWaitlist,
|
||||
onOpenTokenomics
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = useState<'material' | 'non-material'>('material');
|
||||
|
||||
// Custom Investment Calculator State
|
||||
const [customAmount, setCustomAmount] = useState<number>(25); // Default micro investment $25
|
||||
const quickAmounts = [1, 5, 10, 25, 50, 100, 250, 1000, 5000];
|
||||
|
||||
// Countdown timer calculation targeting August 24, 2026 00:00:00 UTC
|
||||
const [timeLeft, setTimeLeft] = useState({
|
||||
days: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const launchDate = new Date('2026-08-24T00:00:00Z').getTime();
|
||||
|
||||
const updateTimer = () => {
|
||||
const now = new Date().getTime();
|
||||
const difference = launchDate - now;
|
||||
|
||||
if (difference > 0) {
|
||||
const days = Math.floor(difference / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
|
||||
const seconds = Math.floor((difference % (1000 * 60)) / 1000);
|
||||
|
||||
setTimeLeft({ days, hours, minutes, seconds });
|
||||
} else {
|
||||
setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });
|
||||
}
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
const interval = setInterval(updateTimer, 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Calculation function for custom token amount and unlocked perks based on custom dollar input
|
||||
const calculateInvestmentDetails = (amount: number) => {
|
||||
const safeAmount = Math.max(1, isNaN(amount) ? 1 : amount);
|
||||
|
||||
// Base rate: 1,000 $SX per $1
|
||||
// Volume bonus tiers:
|
||||
// $1 - $49: standard rate (1,000 $SX / $)
|
||||
// $50 - $249: +10% bonus (1,100 $SX / $)
|
||||
// $250 - $999: +20% bonus (1,200 $SX / $)
|
||||
// $1,000 - $4,999: +50% bonus (1,500 $SX / $)
|
||||
// $5,000+: +80% bonus (1,800 $SX / $)
|
||||
let rate = 1000;
|
||||
let bonusPercentage = 0;
|
||||
|
||||
if (safeAmount >= 5000) {
|
||||
rate = 1800;
|
||||
bonusPercentage = 80;
|
||||
} else if (safeAmount >= 1000) {
|
||||
rate = 1500;
|
||||
bonusPercentage = 50;
|
||||
} else if (safeAmount >= 250) {
|
||||
rate = 1200;
|
||||
bonusPercentage = 20;
|
||||
} else if (safeAmount >= 50) {
|
||||
rate = 1100;
|
||||
bonusPercentage = 10;
|
||||
}
|
||||
|
||||
const totalTokens = safeAmount * rate;
|
||||
|
||||
// Material Perks unlocked
|
||||
const materialPerks: string[] = [
|
||||
`${totalTokens.toLocaleString()} $SX Meme Coin Launch Allocation`,
|
||||
`Official Digital Supporter Badge & Certificate`
|
||||
];
|
||||
|
||||
if (safeAmount >= 50) {
|
||||
const microAppsCount = Math.min(23, Math.floor(safeAmount / 25));
|
||||
materialPerks.push(`${microAppsCount} Free US$17 Marketing MicroApps of choice`);
|
||||
}
|
||||
|
||||
if (safeAmount >= 250) {
|
||||
const coinCount = safeAmount >= 1000 ? 'Full 3-Coin Set (Alpha, Beta, Gamma)' : '1 Minted Physical Collector Coin';
|
||||
materialPerks.push(`${coinCount} with Worldwide Shipping`);
|
||||
}
|
||||
|
||||
if (safeAmount >= 1000) {
|
||||
materialPerks.push('Lifetime Unlimited Pass to ALL 23 US$17 MicroApps');
|
||||
materialPerks.push('Software Revenue Buyback Dividend Pool Access');
|
||||
materialPerks.push('Physical Founders Swag Box (Team Hoodie & Hardware Wallet Case)');
|
||||
}
|
||||
|
||||
if (safeAmount >= 5000) {
|
||||
materialPerks.push('Numbered Serialized Gold-Plated 3-Coin Master Set');
|
||||
materialPerks.push('Permanent Enterprise Pass for all future Software X tools');
|
||||
}
|
||||
|
||||
// Non-Material Perks unlocked
|
||||
const nonMaterialPerks: string[] = [
|
||||
'Supporter Discord Role & Lounge Access',
|
||||
'Whitelisted Presale Launch Access',
|
||||
'Public Wall of Supporters Listing'
|
||||
];
|
||||
|
||||
if (safeAmount >= 50) {
|
||||
nonMaterialPerks.push('Priority Software Update Notifications');
|
||||
}
|
||||
|
||||
if (safeAmount >= 250) {
|
||||
nonMaterialPerks.push('Private Beta Testing Access for All 30+ Core Apps');
|
||||
nonMaterialPerks.push('Insider Alpha Telegram Channel Entry');
|
||||
nonMaterialPerks.push('Quarterly Founders AMA Voice Calls');
|
||||
}
|
||||
|
||||
if (safeAmount >= 1000) {
|
||||
nonMaterialPerks.push('VIP Founder Discord & Direct Developer Chat Access');
|
||||
nonMaterialPerks.push('On-Chain Founder Wall Permanent Name Inscription');
|
||||
nonMaterialPerks.push('Treasury Governance Voting Rights');
|
||||
}
|
||||
|
||||
if (safeAmount >= 5000) {
|
||||
nonMaterialPerks.push('Treasury Advisory Board Seat & Direct Founder Line');
|
||||
nonMaterialPerks.push('Protocol Governance Veto & Acquisition Proposal Voting');
|
||||
nonMaterialPerks.push('Exclusive VIP Annual Retreat & Physical Event Passes');
|
||||
}
|
||||
|
||||
// Calculate next milestone progress
|
||||
let nextMilestoneAmount = 50;
|
||||
let nextMilestoneName = 'Supporter Tier ($50)';
|
||||
let nextMilestonePerk = 'Unlock 2 Free US$17 MicroApps';
|
||||
|
||||
if (safeAmount >= 50 && safeAmount < 250) {
|
||||
nextMilestoneAmount = 250;
|
||||
nextMilestoneName = 'Enthusiast Tier ($250)';
|
||||
nextMilestonePerk = 'Unlock 1 Physical Minted Collector Coin & Beta Access';
|
||||
} else if (safeAmount >= 250 && safeAmount < 1000) {
|
||||
nextMilestoneAmount = 1000;
|
||||
nextMilestoneName = 'VIP Whale Tier ($1,000)';
|
||||
nextMilestonePerk = 'Unlock Full 3-Coin Set, Swag Box & Lifetime Unlimited Pass';
|
||||
} else if (safeAmount >= 1000 && safeAmount < 5000) {
|
||||
nextMilestoneAmount = 5000;
|
||||
nextMilestoneName = 'Treasury Guardian ($5,000)';
|
||||
nextMilestonePerk = 'Unlock Gold-Plated Master Set & Advisory Board Seat';
|
||||
} else if (safeAmount >= 5000) {
|
||||
nextMilestoneAmount = 10000;
|
||||
nextMilestoneName = 'Legendary Backer ($10,000)';
|
||||
nextMilestonePerk = 'Maximum Protocol Allocation & Co-Founder Mentorship';
|
||||
}
|
||||
|
||||
const neededForNext = Math.max(0, nextMilestoneAmount - safeAmount);
|
||||
const progressPercent = Math.min(100, Math.round((safeAmount / nextMilestoneAmount) * 100));
|
||||
|
||||
return {
|
||||
safeAmount,
|
||||
totalTokens,
|
||||
bonusPercentage,
|
||||
materialPerks,
|
||||
nonMaterialPerks,
|
||||
nextMilestoneAmount,
|
||||
nextMilestoneName,
|
||||
nextMilestonePerk,
|
||||
neededForNext,
|
||||
progressPercent
|
||||
};
|
||||
};
|
||||
|
||||
const calcDetails = calculateInvestmentDetails(customAmount);
|
||||
|
||||
const pillars = [
|
||||
{
|
||||
id: 'alpha',
|
||||
code: 'ALPHA',
|
||||
title: 'THE REMINDER',
|
||||
tagline: 'The first one to remember.',
|
||||
motto: 'EVERY BIRTHDAY MATTERS • I REMEMBERED YOU',
|
||||
symbol: 'Candle & Letter A',
|
||||
colors: 'Tangerine Orange & Gold',
|
||||
badge: 'Pillar 01',
|
||||
description: 'The foundation token powering automated relationship reminders, contact syncing, and notification dispatch across all 30+ apps.',
|
||||
role: 'Automated Trigger Utility'
|
||||
},
|
||||
{
|
||||
id: 'beta',
|
||||
code: 'BETA',
|
||||
title: 'THE CELEBRATION',
|
||||
tagline: 'Celebrate every moment.',
|
||||
motto: 'SHARE JOY • SPREAD LOVE • MAKE EVERY DAY SPECIAL',
|
||||
symbol: 'Balloons, Gift Box & Letter B',
|
||||
colors: 'Sky Blue & Antique Bronze',
|
||||
badge: 'Pillar 02',
|
||||
description: 'The utility & access engine granting lifetime MicroApp access, campaign customization, and direct-response offer generation.',
|
||||
role: 'MicroApp & Access Engine'
|
||||
},
|
||||
{
|
||||
id: 'gamma',
|
||||
code: 'GAMMA',
|
||||
title: 'THE MEMORY',
|
||||
tagline: 'Memories that never fade.',
|
||||
motto: 'MEMORIES LAST FOREVER • CONNECTIONS THAT COUNT',
|
||||
symbol: 'Calendar, Bell & Letter G',
|
||||
colors: 'Sky Blue & Deep Gold',
|
||||
badge: 'Pillar 03',
|
||||
description: 'The governance and vault token linking revenue buybacks, on-chain treasury voting rights, and long-term ecosystem equity.',
|
||||
role: 'Treasury & Governance Vault'
|
||||
}
|
||||
];
|
||||
|
||||
const rewardTiers = [
|
||||
{
|
||||
name: 'Micro Backer',
|
||||
price: '$1 – $49',
|
||||
tokens: '1,000 – 49,000 $SX',
|
||||
materialRewards: [
|
||||
'1,000 $SX per $1 USD Invested',
|
||||
'Official Digital Collector Badge',
|
||||
'Whitelisted Presale Token Allocation'
|
||||
],
|
||||
nonMaterialRewards: [
|
||||
'Supporter Discord Role & Lounge Access',
|
||||
'Public Wall of Supporters Listing',
|
||||
'Early Software Launch Notifications'
|
||||
],
|
||||
highlight: false,
|
||||
badgeText: 'Micro Investment Welcome'
|
||||
},
|
||||
{
|
||||
name: 'Supporter Tier',
|
||||
price: '$50',
|
||||
tokens: '55,000 $SX Tokens (+10% Bonus)',
|
||||
materialRewards: [
|
||||
'55,000 $SX Meme Coin Launch Allocation',
|
||||
'2 Free US$17 Marketing MicroApps of choice',
|
||||
'Official Digital Collector Badge'
|
||||
],
|
||||
nonMaterialRewards: [
|
||||
'Supporter Discord Role & Lounge Access',
|
||||
'Whitelisted Presale Launch Access',
|
||||
'Public Wall of Supporters Listing'
|
||||
],
|
||||
highlight: false,
|
||||
badgeText: 'Great Starter'
|
||||
},
|
||||
{
|
||||
name: 'Enthusiast Tier',
|
||||
price: '$250',
|
||||
tokens: '300,000 $SX Tokens (+20% Bonus)',
|
||||
materialRewards: [
|
||||
'300,000 $SX Meme Coin Launch Allocation',
|
||||
'1 Minted Physical Collector Coin (Alpha, Beta, or Gamma)',
|
||||
'Full Access to 5 MicroApps in Program Store',
|
||||
'Ecosystem Sticker & Decal Collector Pack'
|
||||
],
|
||||
nonMaterialRewards: [
|
||||
'Private Beta Testing Access for All 30+ Core Apps',
|
||||
'Insider Alpha Telegram Channel Entry',
|
||||
'Quarterly Founders AMA Voice Calls'
|
||||
],
|
||||
highlight: false,
|
||||
badgeText: 'Collector Item Included'
|
||||
},
|
||||
{
|
||||
name: 'VIP Whale Tier',
|
||||
price: '$1,000',
|
||||
tokens: '1,500,000 $SX Tokens (+50% Bonus)',
|
||||
materialRewards: [
|
||||
'1,500,000 $SX Meme Coin Launch Allocation',
|
||||
'Full 3-Coin Physical Minted Collector Box Set (Alpha, Beta, Gamma)',
|
||||
'Lifetime Unlimited Pass to ALL 23 US$17 MicroApps',
|
||||
'Software Revenue Buyback Dividend Pool Access',
|
||||
'Physical Founders Swag Box (Embroidered Hoodie & Cold Wallet Case)'
|
||||
],
|
||||
nonMaterialRewards: [
|
||||
'VIP Founder Discord & Direct Developer Chat Access',
|
||||
'On-Chain Founder Wall Permanent Name Inscription',
|
||||
'Treasury Governance Voting Rights',
|
||||
'1-on-1 Strategy Onboarding Session'
|
||||
],
|
||||
highlight: true,
|
||||
badgeText: 'Most Popular'
|
||||
},
|
||||
{
|
||||
name: 'Treasury Guardian',
|
||||
price: '$5,000+',
|
||||
tokens: '9,000,000+ $SX Tokens (+80% Bonus)',
|
||||
materialRewards: [
|
||||
'9,000,000+ $SX Meme Coin Allocation + Bonus Yield',
|
||||
'Numbered Serialized Gold-Plated Physical 3-Coin Master Set',
|
||||
'Permanent Lifetime Enterprise Pass to ALL Apps & Future Tools',
|
||||
'Maximum Share of Subscription Revenue Buyback Pool',
|
||||
'Deluxe Founders Hardware & Apparel Luxury Box'
|
||||
],
|
||||
nonMaterialRewards: [
|
||||
'Treasury Advisory Board Seat & Direct Founder Line',
|
||||
'Protocol Governance Veto & Acquisition Proposal Voting',
|
||||
'Exclusive VIP Annual Retreat & Physical Event Passes',
|
||||
'Custom Co-Branded SaaS Portal Integration'
|
||||
],
|
||||
highlight: false,
|
||||
badgeText: 'Maximum Impact'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="memecoin-launch" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
{/* Background ambient glow */}
|
||||
<div className="absolute top-1/3 left-1/2 -translate-x-1/2 w-[800px] h-[800px] bg-gradient-to-tr from-orange-600/15 via-amber-500/10 to-sky-500/15 rounded-full blur-[150px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
{/* Launch Banner Header with Live Countdown */}
|
||||
<div className="mb-16 p-8 sm:p-12 rounded-3xl bg-gradient-to-br from-slate-900 via-orange-950/40 to-slate-950 border border-orange-500/40 shadow-2xl relative overflow-hidden">
|
||||
<div className="flex flex-col lg:flex-row items-center justify-between gap-8">
|
||||
<div className="flex-1 text-left">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<Badge variant="tangerine" showDot={true}>
|
||||
Official Funding Launch • August 24th
|
||||
</Badge>
|
||||
<span className="text-xs font-mono text-sky-400 font-semibold flex items-center gap-1">
|
||||
<Flame className="w-3.5 h-3.5" /> 100% Revenue Backed
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-extrabold text-white tracking-tight">
|
||||
BirthdayMessaging <span className="text-transparent bg-clip-text bg-gradient-to-r from-orange-400 via-amber-400 to-sky-400">Meme Coin Launch</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-sm sm:text-base text-slate-300 mt-4 leading-relaxed max-w-2xl">
|
||||
We are launching the official <strong>$SX BirthdayMessaging Meme Coin</strong> on <strong>August 24th</strong> to fund our rapid software expansion! Backers can invest <strong>ANY amount ($1, $5, $10, $50, $1,000+)</strong> and receive proportional token allocations, physical collector coins, micro-app access, and on-chain revenue dividends.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-4 mt-8">
|
||||
<Button
|
||||
variant="glow"
|
||||
size="lg"
|
||||
onClick={onOpenWaitlist}
|
||||
icon={<Coins className="w-5 h-5" />}
|
||||
>
|
||||
Join Aug 24 Presale Whitelist
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
onClick={onOpenTokenomics}
|
||||
icon={<ShieldCheck className="w-5 h-5 text-sky-400" />}
|
||||
>
|
||||
Tokenomics & Smart Contract
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Countdown Clock Box */}
|
||||
<div className="w-full lg:w-auto p-6 sm:p-8 rounded-2xl bg-slate-950/90 border border-orange-500/30 backdrop-blur-xl shadow-2xl flex flex-col items-center text-center">
|
||||
<div className="flex items-center gap-2 text-xs font-mono uppercase tracking-widest text-orange-400 font-bold mb-4">
|
||||
<Clock className="w-4 h-4 animate-pulse" /> Launch Countdown (August 24)
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-3 sm:gap-4 font-mono">
|
||||
<div className="flex flex-col items-center bg-slate-900 border border-slate-800 rounded-xl px-3 sm:px-4 py-3 min-w-[65px] sm:min-w-[75px]">
|
||||
<span className="text-2xl sm:text-3xl font-extrabold text-white">{timeLeft.days}</span>
|
||||
<span className="text-[10px] text-slate-400 uppercase mt-1">Days</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center bg-slate-900 border border-slate-800 rounded-xl px-3 sm:px-4 py-3 min-w-[65px] sm:min-w-[75px]">
|
||||
<span className="text-2xl sm:text-3xl font-extrabold text-orange-400">{timeLeft.hours}</span>
|
||||
<span className="text-[10px] text-slate-400 uppercase mt-1">Hours</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center bg-slate-900 border border-slate-800 rounded-xl px-3 sm:px-4 py-3 min-w-[65px] sm:min-w-[75px]">
|
||||
<span className="text-2xl sm:text-3xl font-extrabold text-sky-400">{timeLeft.minutes}</span>
|
||||
<span className="text-[10px] text-slate-400 uppercase mt-1">Mins</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center bg-slate-900 border border-slate-800 rounded-xl px-3 sm:px-4 py-3 min-w-[65px] sm:min-w-[75px]">
|
||||
<span className="text-2xl sm:text-3xl font-extrabold text-amber-400">{timeLeft.seconds}</span>
|
||||
<span className="text-[10px] text-slate-400 uppercase mt-1">Secs</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-[11px] text-slate-400 font-mono mt-4">
|
||||
Fair public launch • Open to all sizes ($1+) • Guaranteed liquidity lock
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CUSTOM INVESTMENT CALCULATOR SECTION */}
|
||||
<div className="mb-20">
|
||||
<SectionHeading
|
||||
badgeText="Flexible Micro & Custom Investment"
|
||||
badgeVariant="tangerine"
|
||||
title="Invest ANY Amount You Want"
|
||||
gradientTitle="From $1 to $10,000+"
|
||||
subtitle="Every dollar counts! Type or select any custom investment amount below to see your exact calculated $SX token allocation and unlocked physical & digital rewards."
|
||||
/>
|
||||
|
||||
<GlassCard gradientBorder={true} className="p-6 sm:p-10">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
|
||||
|
||||
{/* Left Column: Interactive Input Controls */}
|
||||
<div className="lg:col-span-6 flex flex-col gap-6">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<label className="text-xs font-mono uppercase tracking-widest text-orange-400 font-bold flex items-center gap-1.5">
|
||||
<DollarSign className="w-4 h-4" /> Enter Your Custom Investment ($ USD)
|
||||
</label>
|
||||
<span className="text-xs font-mono text-slate-400">Min $1 • No Max Limit</span>
|
||||
</div>
|
||||
|
||||
{/* Input Box */}
|
||||
<div className="relative">
|
||||
<span className="absolute left-4 top-1/2 -translate-y-1/2 text-2xl font-bold text-orange-400 font-mono">$</span>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max="100000"
|
||||
value={customAmount}
|
||||
onChange={(e) => setCustomAmount(Math.max(1, parseInt(e.target.value) || 1))}
|
||||
className="w-full bg-slate-950 border-2 border-orange-500/50 focus:border-orange-400 rounded-2xl pl-10 pr-4 py-4 text-3xl font-extrabold text-white font-mono focus:outline-none focus:ring-2 focus:ring-orange-500/30 transition-all shadow-inner"
|
||||
placeholder="e.g. 10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Selection Buttons */}
|
||||
<div>
|
||||
<span className="text-xs font-mono text-slate-400 font-semibold block mb-2">
|
||||
Quick Select Amount:
|
||||
</span>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{quickAmounts.map((amt) => (
|
||||
<button
|
||||
key={amt}
|
||||
onClick={() => setCustomAmount(amt)}
|
||||
className={`px-3.5 py-2 rounded-xl text-xs font-mono font-bold transition-all cursor-pointer border ${
|
||||
customAmount === amt
|
||||
? 'bg-orange-600 border-orange-400 text-white shadow-md shadow-orange-600/30 scale-105'
|
||||
: 'bg-slate-900 border-slate-800 text-slate-300 hover:border-slate-700 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
${amt}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Range Slider */}
|
||||
<div>
|
||||
<div className="flex justify-between text-xs font-mono text-slate-400 mb-1">
|
||||
<span>$1 Micro</span>
|
||||
<span>$250 Enthusiast</span>
|
||||
<span>$1,000 VIP</span>
|
||||
<span>$5,000+ Guardian</span>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
min="1"
|
||||
max="5000"
|
||||
step="1"
|
||||
value={Math.min(5000, customAmount)}
|
||||
onChange={(e) => setCustomAmount(parseInt(e.target.value))}
|
||||
className="w-full h-2 bg-slate-900 rounded-lg appearance-none cursor-pointer accent-orange-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Next Milestone Progress Bar */}
|
||||
<div className="p-4 rounded-xl bg-slate-950/80 border border-slate-800/80">
|
||||
<div className="flex items-center justify-between text-xs mb-2">
|
||||
<span className="font-semibold text-slate-300 flex items-center gap-1.5">
|
||||
<TrendingUp className="w-3.5 h-3.5 text-sky-400" /> Next Milestone: {calcDetails.nextMilestoneName}
|
||||
</span>
|
||||
<span className="font-mono text-orange-400 font-bold">
|
||||
{calcDetails.progressPercent}%
|
||||
</span>
|
||||
</div>
|
||||
<div className="w-full bg-slate-900 h-2 rounded-full overflow-hidden mb-2">
|
||||
<div
|
||||
className="bg-gradient-to-r from-orange-500 to-amber-400 h-full transition-all duration-300"
|
||||
style={{ width: `${calcDetails.progressPercent}%` }}
|
||||
/>
|
||||
</div>
|
||||
{calcDetails.neededForNext > 0 ? (
|
||||
<p className="text-[11px] text-slate-400 leading-snug">
|
||||
💡 Add <strong className="text-orange-300">${calcDetails.neededForNext}</strong> more to unlock: <span className="text-sky-300">{calcDetails.nextMilestonePerk}</span>
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-[11px] text-emerald-400 font-semibold">
|
||||
🎉 Maximum Guardian Tier unlocked! You get gold-plated physical coin master sets and enterprise tools.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Column: Calculated Output Card */}
|
||||
<div className="lg:col-span-6 p-6 sm:p-8 rounded-2xl bg-gradient-to-b from-slate-900 via-slate-950 to-slate-950 border border-orange-500/40 shadow-2xl relative">
|
||||
|
||||
{calcDetails.bonusPercentage > 0 && (
|
||||
<div className="absolute -top-3 right-6 bg-gradient-to-r from-amber-500 to-orange-500 text-slate-950 font-mono text-[10px] font-black uppercase tracking-wider px-3 py-1 rounded-full shadow-md flex items-center gap-1">
|
||||
<Sparkles className="w-3 h-3" /> +{calcDetails.bonusPercentage}% Volume Bonus Token Yield
|
||||
</div>
|
||||
)}
|
||||
|
||||
<span className="text-xs font-mono uppercase tracking-widest text-slate-400 font-bold block mb-1">
|
||||
Your Calculated Allocation for <span className="text-white">${calcDetails.safeAmount}</span>
|
||||
</span>
|
||||
|
||||
{/* Big Token Display */}
|
||||
<div className="flex items-baseline gap-2 mt-2">
|
||||
<span className="text-4xl sm:text-5xl font-black text-transparent bg-clip-text bg-gradient-to-r from-orange-400 via-amber-300 to-sky-400 font-mono">
|
||||
{calcDetails.totalTokens.toLocaleString()}
|
||||
</span>
|
||||
<span className="text-lg font-bold text-sky-400 font-mono">$SX Tokens</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 pt-6 border-t border-slate-800/80">
|
||||
<span className="text-xs font-mono uppercase tracking-widest text-orange-400 font-bold block mb-3 flex items-center gap-1.5">
|
||||
<Package className="w-4 h-4" /> Unlocked Material Rewards:
|
||||
</span>
|
||||
<ul className="flex flex-col gap-2.5">
|
||||
{calcDetails.materialPerks.map((perk, i) => (
|
||||
<li key={i} className="text-xs text-slate-200 flex items-start gap-2">
|
||||
<CheckCircle2 className="w-4 h-4 text-orange-400 flex-shrink-0 mt-0.5" />
|
||||
<span>{perk}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 pt-5 border-t border-slate-800/80">
|
||||
<span className="text-xs font-mono uppercase tracking-widest text-sky-400 font-bold block mb-3 flex items-center gap-1.5">
|
||||
<Crown className="w-4 h-4" /> Unlocked Digital & Community Perks:
|
||||
</span>
|
||||
<ul className="flex flex-col gap-2.5">
|
||||
{calcDetails.nonMaterialPerks.map((perk, i) => (
|
||||
<li key={i} className="text-xs text-slate-200 flex items-start gap-2">
|
||||
<CheckCircle2 className="w-4 h-4 text-sky-400 flex-shrink-0 mt-0.5" />
|
||||
<span>{perk}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<Button
|
||||
variant="glow"
|
||||
size="lg"
|
||||
className="w-full"
|
||||
onClick={onOpenWaitlist}
|
||||
icon={<ArrowRight className="w-4 h-4" />}
|
||||
>
|
||||
Reserve ${calcDetails.safeAmount} Allocation ({calcDetails.totalTokens.toLocaleString()} $SX)
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
|
||||
{/* Section Heading for Pillars */}
|
||||
<SectionHeading
|
||||
badgeText="The Three Pillars of Memory"
|
||||
badgeVariant="sky"
|
||||
title="Alpha, Beta & Gamma Coins"
|
||||
gradientTitle="Tangerine & Sky Blue"
|
||||
subtitle="Discover the three core coin pillars representing BirthdayMessaging.io: The Reminder, The Celebration, and The Memory."
|
||||
/>
|
||||
|
||||
{/* Showcase Image Banner */}
|
||||
<div className="mb-16 relative rounded-3xl overflow-hidden border border-slate-800 shadow-2xl bg-slate-950 group">
|
||||
<img
|
||||
src={coinShowcaseImg}
|
||||
alt="BirthdayMessaging.io Alpha, Beta, Gamma Commemorative Coins"
|
||||
className="w-full h-auto object-cover rounded-3xl transition-transform duration-500 group-hover:scale-[1.01]"
|
||||
referrerPolicy="no-referrer"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-slate-950 via-transparent to-transparent opacity-80" />
|
||||
<div className="absolute bottom-4 left-4 sm:bottom-8 sm:left-8 right-4 sm:right-8 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||||
<div>
|
||||
<span className="text-xs font-mono text-orange-400 font-bold uppercase tracking-widest">
|
||||
Official Physical Minted Artifacts
|
||||
</span>
|
||||
<h3 className="text-xl sm:text-2xl font-bold text-white mt-1">
|
||||
Alpha • Beta • Gamma Collector Series
|
||||
</h3>
|
||||
</div>
|
||||
<Badge variant="tangerine">Collect All 3</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 3 Pillars Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 mb-20">
|
||||
{pillars.map((pillar) => (
|
||||
<GlassCard key={pillar.id} gradientBorder={true} className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<Badge variant={pillar.id === 'alpha' ? 'tangerine' : pillar.id === 'beta' ? 'sky' : 'neutral'}>
|
||||
{pillar.badge}
|
||||
</Badge>
|
||||
<span className="text-xs font-mono text-slate-400">{pillar.colors}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-tr from-orange-500 to-amber-600 flex items-center justify-center text-white font-black text-lg shadow-md">
|
||||
{pillar.code[0]}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-white">{pillar.code}</h3>
|
||||
<span className="text-xs font-mono text-orange-300 font-semibold">{pillar.title}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-xs font-medium italic text-sky-300 mt-2">
|
||||
"{pillar.tagline}"
|
||||
</p>
|
||||
|
||||
<p className="text-xs text-slate-300 mt-3 leading-relaxed">
|
||||
{pillar.description}
|
||||
</p>
|
||||
|
||||
<div className="mt-4 p-3 rounded-xl bg-slate-950 border border-slate-800 text-[11px] font-mono text-slate-300">
|
||||
<span className="text-orange-400 font-bold block mb-1">Engraved Motto:</span>
|
||||
{pillar.motto}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 pt-3 border-t border-slate-800/80 flex items-center justify-between text-xs font-mono">
|
||||
<span className="text-slate-400">Ecosystem Role:</span>
|
||||
<span className="font-bold text-sky-400">{pillar.role}</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* What Investors Get (Material & Non-Material Rewards) */}
|
||||
<div className="mb-20">
|
||||
<SectionHeading
|
||||
badgeText="Investor & Buyer Benefits"
|
||||
badgeVariant="tangerine"
|
||||
title="What You Get When You"
|
||||
gradientTitle="Invest & Buy Tokens"
|
||||
subtitle="We reward our community with a blend of high-value tangible physical assets and exclusive digital ecosystem privileges."
|
||||
/>
|
||||
|
||||
{/* Tab Controls: Material vs Non-Material */}
|
||||
<div className="flex justify-center mb-10">
|
||||
<div className="p-1.5 rounded-2xl bg-slate-900 border border-slate-800 inline-flex gap-2">
|
||||
<button
|
||||
onClick={() => setActiveTab('material')}
|
||||
className={`px-6 py-2.5 rounded-xl text-xs sm:text-sm font-bold transition-all cursor-pointer flex items-center gap-2 ${
|
||||
activeTab === 'material'
|
||||
? 'bg-orange-600 text-white shadow-lg shadow-orange-600/30'
|
||||
: 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<Package className="w-4 h-4" />
|
||||
<span>Material Rewards (Physical & Tangible)</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('non-material')}
|
||||
className={`px-6 py-2.5 rounded-xl text-xs sm:text-sm font-bold transition-all cursor-pointer flex items-center gap-2 ${
|
||||
activeTab === 'non-material'
|
||||
? 'bg-sky-600 text-white shadow-lg shadow-sky-600/30'
|
||||
: 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<Award className="w-4 h-4" />
|
||||
<span>Non-Material Rewards (Privileges & Roles)</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tab Content Display */}
|
||||
<AnimatePresence mode="wait">
|
||||
{activeTab === 'material' ? (
|
||||
<motion.div
|
||||
key="material"
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -15 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
|
||||
>
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-orange-600/20 border border-orange-500/40 flex items-center justify-center text-orange-400 mb-4">
|
||||
<Coins className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">Minted Physical Coins</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Heavyweight solid antique bronze/gold physical commemorative coins (Alpha, Beta, Gamma) delivered worldwide with engraved serial numbers.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-orange-300">
|
||||
Shipped directly to qualified buyers
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-amber-600/20 border border-amber-500/40 flex items-center justify-center text-amber-400 mb-4">
|
||||
<Zap className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">Lifetime MicroApp Pass</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Permanent $0 access pass to all 23 US$17 marketing MicroApps in our store plus future tools without recurring monthly fees.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-amber-300">
|
||||
Worth $391+ in immediate software value
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-sky-600/20 border border-sky-500/40 flex items-center justify-center text-sky-400 mb-4">
|
||||
<Flame className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">SaaS Revenue Buybacks</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Smart-contract automated token buybacks funded directly by subscription profits from BirthdayMessaging 2.0 & MicroApps.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-sky-300">
|
||||
Direct software revenue token sink
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-emerald-600/20 border border-emerald-500/40 flex items-center justify-center text-emerald-400 mb-4">
|
||||
<Package className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">Founders Swag Box</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Custom physical team hoodie, metal hardware wallet sleeve, and signed certificate of early backing from the team.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-emerald-300">
|
||||
Whale & Guardian Tier Perks
|
||||
</div>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="non-material"
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -15 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
|
||||
>
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-sky-600/20 border border-sky-500/40 flex items-center justify-center text-sky-400 mb-4">
|
||||
<Crown className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">VIP Discord & Telegram</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Exclusive VIP founder roles, direct chat access with lead developers, private alpha leaks, and priority feature suggestions.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-sky-300">
|
||||
Direct access to team
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-orange-600/20 border border-orange-500/40 flex items-center justify-center text-orange-400 mb-4">
|
||||
<Lock className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">Private Beta Testing</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
First-in-line access to test new software releases across all 30+ core platforms, web miners, and CRMs before public launch.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-orange-300">
|
||||
Early adopter advantage
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-amber-600/20 border border-amber-500/40 flex items-center justify-center text-amber-400 mb-4">
|
||||
<Star className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">On-Chain Founder Wall</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Permanent, immutable inscription of your wallet address or handle on the Software X On-Chain Public Hall of Fame.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-amber-300">
|
||||
Forever recorded on blockchain
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-purple-600/20 border border-purple-500/40 flex items-center justify-center text-purple-400 mb-4">
|
||||
<Vote className="w-6 h-6" />
|
||||
</div>
|
||||
<h4 className="text-base font-bold text-white">Treasury Governance Rights</h4>
|
||||
<p className="text-xs text-slate-400 mt-2 leading-relaxed">
|
||||
Vote on treasury capital deployment, software acquisitions, developer grant approvals, and quarterly burn schedules.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-slate-800 text-[11px] font-mono text-purple-300">
|
||||
True community control
|
||||
</div>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
{/* Investment Tiers Comparison */}
|
||||
<div className="mb-12">
|
||||
<SectionHeading
|
||||
badgeText="Presale Contribution Tiers"
|
||||
badgeVariant="sky"
|
||||
title="Explore Preset Launch Tiers"
|
||||
gradientTitle="August 24th Allotments"
|
||||
subtitle="Choose a preset tier below or type any custom dollar amount above to reserve your $SX tokens."
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-5">
|
||||
{rewardTiers.map((tier, idx) => (
|
||||
<GlassCard
|
||||
key={tier.name}
|
||||
gradientBorder={tier.highlight}
|
||||
className={`flex flex-col justify-between relative ${
|
||||
tier.highlight ? 'ring-2 ring-orange-500/50 bg-slate-900/90' : ''
|
||||
}`}
|
||||
>
|
||||
{tier.badgeText && (
|
||||
<div className={`absolute -top-3 left-1/2 -translate-x-1/2 text-white font-mono text-[9px] font-extrabold uppercase tracking-widest px-2.5 py-0.5 rounded-full shadow-md whitespace-nowrap ${
|
||||
tier.highlight ? 'bg-gradient-to-r from-orange-500 to-amber-500' : 'bg-slate-800 border border-slate-700 text-slate-300'
|
||||
}`}>
|
||||
{tier.badgeText}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h3 className="text-base font-bold text-white mt-2">{tier.name}</h3>
|
||||
<div className="text-2xl font-extrabold text-orange-400 font-mono mt-1">
|
||||
{tier.price}
|
||||
</div>
|
||||
<span className="text-[11px] font-mono text-sky-400 font-semibold block mt-0.5">
|
||||
{tier.tokens}
|
||||
</span>
|
||||
|
||||
<div className="mt-5">
|
||||
<span className="text-[10px] font-mono uppercase tracking-widest text-slate-400 font-bold block mb-1.5">
|
||||
📦 Material Perks:
|
||||
</span>
|
||||
<ul className="flex flex-col gap-1.5">
|
||||
{tier.materialRewards.map((m, i) => (
|
||||
<li key={i} className="text-[11px] text-slate-300 flex items-start gap-1.5 leading-snug">
|
||||
<CheckCircle2 className="w-3 h-3 text-orange-400 flex-shrink-0 mt-0.5" />
|
||||
<span>{m}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 pt-3 border-t border-slate-800">
|
||||
<span className="text-[10px] font-mono uppercase tracking-widest text-slate-400 font-bold block mb-1.5">
|
||||
👑 Non-Material Perks:
|
||||
</span>
|
||||
<ul className="flex flex-col gap-1.5">
|
||||
{tier.nonMaterialRewards.map((nm, i) => (
|
||||
<li key={i} className="text-[11px] text-slate-300 flex items-start gap-1.5 leading-snug">
|
||||
<CheckCircle2 className="w-3 h-3 text-sky-400 flex-shrink-0 mt-0.5" />
|
||||
<span>{nm}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
<Button
|
||||
variant={tier.highlight ? 'glow' : 'outline'}
|
||||
size="sm"
|
||||
className="w-full text-xs"
|
||||
onClick={onOpenWaitlist}
|
||||
icon={<ArrowRight className="w-3 h-3" />}
|
||||
>
|
||||
Select & Reserve
|
||||
</Button>
|
||||
</div>
|
||||
</GlassCard>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer Guarantee Box */}
|
||||
<div className="p-6 rounded-2xl bg-slate-900/80 border border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<ShieldCheck className="w-6 h-6 text-sky-400 flex-shrink-0" />
|
||||
<p className="text-xs text-slate-300">
|
||||
<strong>100% Micro-Friendly & Transparent:</strong> Everyone is welcome regardless of contribution size ($1 to $10,000+). Smart contracts audited on-chain. Liquidity locked permanently upon August 24 launch.
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onOpenWaitlist}
|
||||
className="flex-shrink-0"
|
||||
>
|
||||
Join Launch Whitelist →
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { XCircle, CheckCircle, ShieldAlert, HeartHandshake, Lock, Unlock, TrendingUp, DollarSign } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
|
||||
export const ProblemSection: React.FC = () => {
|
||||
const [activeTab, setActiveTab] = useState<'vc' | 'community'>('vc');
|
||||
|
||||
const vcProblems = [
|
||||
{
|
||||
title: 'Forced Liquidation & Sudden Exits',
|
||||
description: 'VCs prioritize rapid 10x returns within 5-7 years, often forcing founders into premature acquisitions or aggressive price hikes that ruin product quality.',
|
||||
icon: ShieldAlert
|
||||
},
|
||||
{
|
||||
title: 'Hidden Cap Tables & Board Room Controls',
|
||||
description: 'Decisions are made behind closed doors by investors who rarely use the software, overriding product vision in favor of short-term quarterly targets.',
|
||||
icon: Lock
|
||||
},
|
||||
{
|
||||
title: 'User Exploitation & Aggressive Monetization',
|
||||
description: 'When growth slows, VC-backed companies monetize user data, lock features behind expensive paywalls, or shut down products after acquisitions.',
|
||||
icon: DollarSign
|
||||
}
|
||||
];
|
||||
|
||||
const communitySolutions = [
|
||||
{
|
||||
title: '100% Product-First Alignment',
|
||||
description: 'No external investor board forcing premature exits. The team focuses strictly on building extraordinary software for the actual people who use it.',
|
||||
icon: HeartHandshake
|
||||
},
|
||||
{
|
||||
title: 'Verifiable Public Treasury',
|
||||
description: '100% of community-funded treasury reserves and subscription revenues are tracked on public smart contracts with full auditability.',
|
||||
icon: Unlock
|
||||
},
|
||||
{
|
||||
title: 'Automated Value Redistribution',
|
||||
description: 'Subscription revenues generated across BirthdayMessaging.io and 30+ products automatically fund product updates and token buy-backs.',
|
||||
icon: TrendingUp
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="why-community" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
{/* Background glow */}
|
||||
<div className="absolute top-1/2 left-0 w-96 h-96 bg-orange-500/5 rounded-full blur-[120px] pointer-events-none" />
|
||||
<div className="absolute bottom-0 right-0 w-96 h-96 bg-sky-500/5 rounded-full blur-[120px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Why We Built Differently"
|
||||
badgeVariant="tangerine"
|
||||
title="Traditional VC Capital vs."
|
||||
gradientTitle="Community-Powered Funding"
|
||||
subtitle="Venture capital forces software companies into short-term quarterly metrics and investor-first decisions. Software X aligns founders and users directly."
|
||||
/>
|
||||
|
||||
{/* Comparison Toggle Control */}
|
||||
<div className="flex justify-center mb-10">
|
||||
<div className="bg-slate-900 p-1.5 rounded-full border border-slate-800 flex items-center gap-1 shadow-inner">
|
||||
<button
|
||||
onClick={() => setActiveTab('vc')}
|
||||
className={`px-5 py-2.5 rounded-full text-xs font-semibold transition-all cursor-pointer flex items-center gap-2 ${
|
||||
activeTab === 'vc'
|
||||
? 'bg-rose-950/80 text-rose-300 border border-rose-500/40 shadow-md'
|
||||
: 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<XCircle className="w-4 h-4 text-rose-400" />
|
||||
The VC Dilemma
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('community')}
|
||||
className={`px-5 py-2.5 rounded-full text-xs font-semibold transition-all cursor-pointer flex items-center gap-2 ${
|
||||
activeTab === 'community'
|
||||
? 'bg-sky-950/80 text-sky-300 border border-sky-500/40 shadow-md'
|
||||
: 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<CheckCircle className="w-4 h-4 text-sky-400" />
|
||||
Software X Model
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Interactive Comparison Display */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{(activeTab === 'vc' ? vcProblems : communitySolutions).map((item, idx) => {
|
||||
const Icon = item.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={item.title}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.4, delay: idx * 0.1 }}
|
||||
>
|
||||
<GlassCard
|
||||
className={`h-full border-t-2 ${
|
||||
activeTab === 'vc'
|
||||
? 'border-t-rose-500/50 hover:border-rose-500/80'
|
||||
: 'border-t-sky-500/50 hover:border-sky-500/80'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className={`w-12 h-12 rounded-2xl flex items-center justify-center ${
|
||||
activeTab === 'vc'
|
||||
? 'bg-rose-950/60 text-rose-400 border border-rose-500/30'
|
||||
: 'bg-sky-950/60 text-sky-400 border border-sky-500/30'
|
||||
}`}>
|
||||
<Icon className="w-6 h-6" />
|
||||
</div>
|
||||
<span className="text-[11px] font-mono tracking-widest uppercase text-slate-400">
|
||||
0{idx + 1}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h3 className="text-xl font-bold text-white mb-2">{item.title}</h3>
|
||||
<p className="text-sm text-slate-400 leading-relaxed">{item.description}</p>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Bottom Callout Banner */}
|
||||
<div className="mt-12 p-6 sm:p-8 rounded-2xl bg-gradient-to-r from-slate-900 via-orange-950/40 to-slate-900 border border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-xl bg-orange-600/20 border border-orange-500/30 flex items-center justify-center text-orange-400 flex-shrink-0">
|
||||
<HeartHandshake className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-base font-bold text-white">Software Built to Last, Not to Flip</h4>
|
||||
<p className="text-xs sm:text-sm text-slate-400 mt-1 max-w-xl">
|
||||
By funding Software X with a community-driven model, 100% of our incentives remain anchored to building real software solutions that users love every single day.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { CheckCircle2, Clock, Calendar, ArrowRight, ShieldCheck } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Badge } from '../ui/Badge';
|
||||
import { roadmapData } from '../../data/roadmap';
|
||||
|
||||
interface RoadmapSectionProps {
|
||||
onOpenWaitlist: () => void;
|
||||
}
|
||||
|
||||
export const RoadmapSection: React.FC<RoadmapSectionProps> = ({ onOpenWaitlist }) => {
|
||||
const [activePhaseIndex, setActivePhaseIndex] = useState<number>(1); // Default to current Phase 2
|
||||
|
||||
return (
|
||||
<section id="roadmap" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Public Milestones"
|
||||
badgeVariant="tangerine"
|
||||
title="Transparent Roadmap."
|
||||
gradientTitle="Execution Driven."
|
||||
subtitle="Track our engineering progression step-by-step from live micro-SaaS foundation to decentralized protocol deployment."
|
||||
/>
|
||||
|
||||
{/* Phase Selection Stepper Header */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 lg:grid-cols-5 gap-3 mb-10">
|
||||
{roadmapData.map((phase, idx) => {
|
||||
const isSelected = activePhaseIndex === idx;
|
||||
const isCompleted = phase.status === 'completed';
|
||||
const isCurrent = phase.status === 'current';
|
||||
|
||||
return (
|
||||
<button
|
||||
key={phase.quarter}
|
||||
onClick={() => setActivePhaseIndex(idx)}
|
||||
className={`p-4 rounded-2xl border text-left transition-all cursor-pointer flex flex-col justify-between ${
|
||||
isSelected
|
||||
? 'bg-slate-900 border-orange-500 ring-1 ring-orange-500/40 shadow-xl'
|
||||
: 'bg-slate-950/60 border-slate-800/80 hover:border-slate-700'
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-[11px] font-mono text-slate-400">0{idx + 1}</span>
|
||||
{isCompleted && <Badge variant="sky" showDot={false}>Done</Badge>}
|
||||
{isCurrent && <Badge variant="tangerine" showDot={true}>Active</Badge>}
|
||||
{!isCompleted && !isCurrent && <Badge variant="neutral" showDot={false}>Upcoming</Badge>}
|
||||
</div>
|
||||
<h4 className="text-xs font-bold text-white line-clamp-1">{phase.quarter}</h4>
|
||||
</div>
|
||||
<p className="text-[11px] text-slate-400 mt-2 line-clamp-1">{phase.title}</p>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Selected Phase Active Card */}
|
||||
<motion.div
|
||||
key={activePhaseIndex}
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<GlassCard gradientBorder={true} className="p-8">
|
||||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 pb-6 border-b border-slate-800">
|
||||
<div>
|
||||
<div className="flex items-center gap-3">
|
||||
<Badge
|
||||
variant={
|
||||
roadmapData[activePhaseIndex].status === 'completed'
|
||||
? 'sky'
|
||||
: roadmapData[activePhaseIndex].status === 'current'
|
||||
? 'tangerine'
|
||||
: 'sky'
|
||||
}
|
||||
>
|
||||
{roadmapData[activePhaseIndex].quarter}
|
||||
</Badge>
|
||||
<span className="text-xs font-mono text-slate-400 flex items-center gap-1">
|
||||
<Calendar className="w-3.5 h-3.5" /> Stage {activePhaseIndex + 1} of 5
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-white mt-2">
|
||||
{roadmapData[activePhaseIndex].title}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={onOpenWaitlist}
|
||||
className="text-xs font-semibold text-orange-400 hover:text-orange-300 flex items-center gap-1 cursor-pointer"
|
||||
>
|
||||
Get early waitlist updates <ArrowRight className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-slate-300 mt-6 leading-relaxed">
|
||||
{roadmapData[activePhaseIndex].description}
|
||||
</p>
|
||||
|
||||
{/* Milestones Checklist */}
|
||||
<div className="mt-8">
|
||||
<h4 className="text-xs font-mono uppercase tracking-widest text-slate-400 mb-4 font-semibold">
|
||||
Milestones & Deliverables
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
{roadmapData[activePhaseIndex].milestones.map((milestone, i) => (
|
||||
<div key={i} className="p-3.5 rounded-xl bg-slate-950/80 border border-slate-800/80 flex items-start gap-3">
|
||||
<CheckCircle2 className={`w-4 h-4 mt-0.5 flex-shrink-0 ${
|
||||
roadmapData[activePhaseIndex].status === 'completed'
|
||||
? 'text-sky-400'
|
||||
: roadmapData[activePhaseIndex].status === 'current'
|
||||
? 'text-orange-400'
|
||||
: 'text-slate-500'
|
||||
}`} />
|
||||
<span className="text-xs text-slate-200 leading-relaxed">{milestone}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,135 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { Layers, Gift, Cpu, ArrowRight, ShieldCheck, Database, RefreshCw, Zap } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
|
||||
export const SolutionSection: React.FC = () => {
|
||||
return (
|
||||
<section id="solution" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="The Solution Architecture"
|
||||
badgeVariant="tangerine"
|
||||
title="From BirthdayMessaging.io to"
|
||||
gradientTitle="Software X Ecosystem"
|
||||
subtitle="Software X is not an abstract whitepaper. It is the evolution of a proven, live software product that already powers messaging for thousands of daily users."
|
||||
/>
|
||||
|
||||
{/* 3 Step Evolution Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 mb-16">
|
||||
<GlassCard gradientBorder={true} className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-gradient-to-tr from-orange-500 to-amber-600 flex items-center justify-center text-white mb-6 shadow-lg shadow-orange-950/40">
|
||||
<Gift className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-mono text-orange-400 uppercase tracking-wider font-semibold">Step 01 • Foundation</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mb-3">BirthdayMessaging.io</h3>
|
||||
<p className="text-sm text-slate-400 leading-relaxed mb-4">
|
||||
Launched as a specialized automated messaging platform. Grew organically to 85,000+ users with zero VC funding, proving real customer demand for automated communication.
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-slate-800/80 flex items-center justify-between text-xs text-slate-400 font-mono">
|
||||
<span>Status: Live & Profitable</span>
|
||||
<span className="text-sky-400">85,000+ Users</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard gradientBorder={true} className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-gradient-to-tr from-sky-500 to-blue-600 flex items-center justify-center text-white mb-6 shadow-lg shadow-sky-950/40">
|
||||
<Layers className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-mono text-sky-400 uppercase tracking-wider font-semibold">Step 02 • Expansion</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mb-3">30+ Micro-SaaS Suite</h3>
|
||||
<p className="text-sm text-slate-400 leading-relaxed mb-4">
|
||||
Expanded the technology stack into 30+ targeted digital products across encrypted messaging (SignalDrop), visual automation (CraftFlow), and live analytics.
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-slate-800/80 flex items-center justify-between text-xs text-slate-400 font-mono">
|
||||
<span>Status: Operational</span>
|
||||
<span className="text-orange-400">30+ Apps</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard gradientBorder={true} className="flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-gradient-to-tr from-amber-500 to-orange-600 flex items-center justify-center text-white mb-6 shadow-lg shadow-orange-950/40">
|
||||
<Cpu className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-mono text-amber-400 uppercase tracking-wider font-semibold">Step 03 • Software X</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mb-3">Community Core Protocol</h3>
|
||||
<p className="text-sm text-slate-400 leading-relaxed mb-4">
|
||||
Unifying all products under a single SSO identity key and fair community token economics, ensuring net software revenues directly support treasury growth.
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-slate-800/80 flex items-center justify-between text-xs text-slate-400 font-mono">
|
||||
<span>Status: Waitlist Active</span>
|
||||
<span className="text-sky-400">Protocol V1</span>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
|
||||
{/* Real-time Architecture Flow Visualizer */}
|
||||
<div className="p-8 rounded-3xl bg-slate-900/90 border border-slate-800 relative overflow-hidden backdrop-blur-xl">
|
||||
<div className="flex flex-col md:flex-row items-center justify-between gap-6 pb-6 border-b border-slate-800">
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-white flex items-center gap-2">
|
||||
<Zap className="w-5 h-5 text-orange-400" />
|
||||
The Software X Circular Value Engine
|
||||
</h3>
|
||||
<p className="text-xs text-slate-400 mt-1">
|
||||
How real user subscription revenue drives protocol liquidity without relying on token inflation.
|
||||
</p>
|
||||
</div>
|
||||
<span className="text-xs font-mono px-3 py-1 rounded-full bg-orange-950 text-orange-300 border border-orange-500/30">
|
||||
Zero Inflation • Product Backed
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mt-8">
|
||||
<div className="p-4 rounded-xl bg-slate-950/80 border border-slate-800 text-center">
|
||||
<div className="text-xs font-mono text-slate-400 mb-1">01. Real SaaS Users</div>
|
||||
<h4 className="text-sm font-bold text-white">SaaS Subscriptions</h4>
|
||||
<p className="text-xs text-slate-400 mt-1">Users pay standard SaaS fees for BirthdayMessaging & 30+ apps</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 rounded-xl bg-slate-950/80 border border-slate-800 text-center relative">
|
||||
<div className="hidden md:block absolute -left-3 top-1/2 -translate-y-1/2 z-10 text-orange-500">
|
||||
<ArrowRight className="w-5 h-5" />
|
||||
</div>
|
||||
<div className="text-xs font-mono text-orange-400 mb-1">02. On-Chain Revenue</div>
|
||||
<h4 className="text-sm font-bold text-white">Treasury Route</h4>
|
||||
<p className="text-xs text-slate-400 mt-1">Gross revenue routed into public multi-sig treasury smart contracts</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 rounded-xl bg-slate-950/80 border border-slate-800 text-center relative">
|
||||
<div className="hidden md:block absolute -left-3 top-1/2 -translate-y-1/2 z-10 text-orange-500">
|
||||
<ArrowRight className="w-5 h-5" />
|
||||
</div>
|
||||
<div className="text-xs font-mono text-sky-400 mb-1">03. Software Engineering</div>
|
||||
<h4 className="text-sm font-bold text-white">Continuous R&D</h4>
|
||||
<p className="text-xs text-slate-400 mt-1">Treasury directly funds senior engineers, AI models & security audits</p>
|
||||
</div>
|
||||
|
||||
<div className="p-4 rounded-xl bg-slate-950/80 border border-slate-800 text-center relative">
|
||||
<div className="hidden md:block absolute -left-3 top-1/2 -translate-y-1/2 z-10 text-orange-500">
|
||||
<ArrowRight className="w-5 h-5" />
|
||||
</div>
|
||||
<div className="text-xs font-mono text-amber-400 mb-1">04. Buy-Back & Burn</div>
|
||||
<h4 className="text-sm font-bold text-white">Token Value Loop</h4>
|
||||
<p className="text-xs text-slate-400 mt-1">Automated smart contracts execute market buy-backs of $SX</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { ShieldCheck, Award, Zap, Sparkles } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { AnimatedCounter } from '../ui/AnimatedCounter';
|
||||
import { Badge } from '../ui/Badge';
|
||||
|
||||
export const StatsSection: React.FC = () => {
|
||||
const [selectedRole, setSelectedRole] = useState<'developer' | 'creator' | 'supporter'>('creator');
|
||||
|
||||
const tierPerks = {
|
||||
developer: {
|
||||
title: 'Developer Tier (API Access)',
|
||||
positionBoost: 'Top 5% Priority Access',
|
||||
perks: ['Free $SX SDK API Quota', 'Access to Software X Private Auth Sandbox', 'Direct Discord Dev Channel Access']
|
||||
},
|
||||
creator: {
|
||||
title: 'Creator & User Tier',
|
||||
positionBoost: 'Top 10% Priority Access',
|
||||
perks: ['Lifetime Discount on BirthdayMessaging.io', 'Early Access to CraftFlow & SignalDrop', 'Community Governance Voting Rights']
|
||||
},
|
||||
supporter: {
|
||||
title: 'Ecosystem Believer Tier',
|
||||
positionBoost: 'Priority Tokenomics Queue',
|
||||
perks: ['Verifiable On-Chain Waitlist Badge', 'Exclusive Founder Q&A Access', 'Public Treasury Telemetry Stream']
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText="Verified Impact"
|
||||
badgeVariant="sky"
|
||||
title="Numbers That Prove"
|
||||
gradientTitle="Real Software Adoption"
|
||||
subtitle="Software X is backed by real metrics from existing software products operating every day."
|
||||
/>
|
||||
|
||||
{/* 4 Big Metrics Grid */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-16">
|
||||
<GlassCard className="text-center py-8">
|
||||
<div className="text-3xl sm:text-4xl font-extrabold text-white font-mono">
|
||||
<AnimatedCounter prefix="$" end={4200000} suffix="+" />
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 mt-2 font-mono">Ecosystem SaaS Volume</p>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="text-center py-8">
|
||||
<div className="text-3xl sm:text-4xl font-extrabold text-orange-400 font-mono">
|
||||
<AnimatedCounter end={30} suffix="+" />
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 mt-2 font-mono">Operational Products</p>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="text-center py-8">
|
||||
<div className="text-3xl sm:text-4xl font-extrabold text-sky-400 font-mono">
|
||||
<AnimatedCounter end={140000} suffix="+" />
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 mt-2 font-mono">Active Monthly Users</p>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard className="text-center py-8">
|
||||
<div className="text-3xl sm:text-4xl font-extrabold text-amber-400 font-mono">
|
||||
100%
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 mt-2 font-mono">On-Chain Treasury Audit</p>
|
||||
</GlassCard>
|
||||
</div>
|
||||
|
||||
{/* Interactive Community Priority Tier Estimator */}
|
||||
<div className="p-8 rounded-3xl bg-slate-900/90 border border-slate-800 backdrop-blur-xl">
|
||||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 pb-6 border-b border-slate-800">
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant="tangerine">Priority Estimator</Badge>
|
||||
<span className="text-xs font-mono text-slate-400">Select Your Role:</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mt-1">
|
||||
Early Access Queue & Community Tier
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{/* Role Selectors */}
|
||||
<div className="flex items-center gap-2 bg-slate-950 p-1.5 rounded-xl border border-slate-800">
|
||||
<button
|
||||
onClick={() => setSelectedRole('creator')}
|
||||
className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer ${
|
||||
selectedRole === 'creator' ? 'bg-orange-600 text-white' : 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
Software User
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSelectedRole('developer')}
|
||||
className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer ${
|
||||
selectedRole === 'developer' ? 'bg-orange-600 text-white' : 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
Developer
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSelectedRole('supporter')}
|
||||
className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer ${
|
||||
selectedRole === 'supporter' ? 'bg-orange-600 text-white' : 'text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
Ecosystem Believer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex flex-col md:flex-row items-center justify-between gap-6">
|
||||
<div>
|
||||
<h4 className="text-lg font-bold text-orange-300">
|
||||
{tierPerks[selectedRole].title}
|
||||
</h4>
|
||||
<p className="text-xs text-sky-400 font-mono mt-1 flex items-center gap-1">
|
||||
<Zap className="w-3.5 h-3.5" /> Boost: {tierPerks[selectedRole].positionBoost}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-3">
|
||||
{tierPerks[selectedRole].perks.map((perk, i) => (
|
||||
<div key={i} className="px-3.5 py-2 rounded-xl bg-slate-950 border border-slate-800 text-xs text-slate-300 flex items-center gap-2">
|
||||
<Award className="w-3.5 h-3.5 text-orange-400" />
|
||||
<span>{perk}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
import React from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import { X, PieChart, ShieldCheck, Lock, Repeat, Sparkles } from 'lucide-react';
|
||||
import { tokenomicsAllocations } from '../../data/tokenomics';
|
||||
import { Badge } from '../ui/Badge';
|
||||
import { Button } from '../ui/Button';
|
||||
|
||||
interface TokenomicsModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onOpenWaitlist: () => void;
|
||||
}
|
||||
|
||||
export const TokenomicsModal: React.FC<TokenomicsModalProps> = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
onOpenWaitlist
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6 overflow-y-auto">
|
||||
{/* Backdrop */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={onClose}
|
||||
className="fixed inset-0 bg-slate-950/85 backdrop-blur-xl"
|
||||
/>
|
||||
|
||||
{/* Modal Window */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
className="relative w-full max-w-3xl bg-slate-900 border border-slate-800 rounded-3xl p-6 sm:p-10 shadow-2xl z-10 max-h-[90vh] overflow-y-auto"
|
||||
>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-6 right-6 p-2 rounded-xl bg-slate-800 text-slate-400 hover:text-white transition-colors"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<Badge variant="tangerine">Token Economics</Badge>
|
||||
<span className="text-xs font-mono text-slate-400">Total Supply: 1,000,000,000 $SX</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl sm:text-3xl font-extrabold text-white">
|
||||
Transparent Token Allocation Blueprint
|
||||
</h2>
|
||||
<p className="text-xs text-orange-400 font-mono mt-1">
|
||||
Zero insider presales. Zero VC discount tokens. 100% public smart contract vesting.
|
||||
</p>
|
||||
|
||||
{/* Allocation Bar */}
|
||||
<div className="mt-6 flex h-4 rounded-full overflow-hidden bg-slate-950 p-0.5 border border-slate-800">
|
||||
{tokenomicsAllocations.map((item) => (
|
||||
<div
|
||||
key={item.category}
|
||||
style={{ width: `${item.percentage}%`, backgroundColor: item.color }}
|
||||
className="h-full transition-all"
|
||||
title={`${item.category}: ${item.percentage}%`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Detailed Allocation List */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
|
||||
{tokenomicsAllocations.map((item) => (
|
||||
<div key={item.category} className="p-4 rounded-2xl bg-slate-950 border border-slate-800 flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-xs font-bold text-white flex items-center gap-2">
|
||||
<span className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: item.color }} />
|
||||
{item.category}
|
||||
</span>
|
||||
<span className="font-mono text-xs font-extrabold text-orange-300">{item.percentage}%</span>
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 leading-relaxed">{item.description}</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-3 border-t border-slate-800/80 flex items-center justify-between text-[11px] font-mono text-slate-400">
|
||||
<span>Lockup: {item.lockup}</span>
|
||||
<span className="text-sky-400">{item.tokens}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-2 text-xs text-slate-400">
|
||||
<Lock className="w-4 h-4 text-sky-400" />
|
||||
<span>Multi-Sig Lockup Smart Contracts Verifiable on Blockchain</span>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="glow"
|
||||
size="md"
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onOpenWaitlist();
|
||||
}}
|
||||
>
|
||||
Reserve Waitlist Spot
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import { X, ShieldCheck, Layers, Gift, CheckCircle2, HeartHandshake } from 'lucide-react';
|
||||
import { Badge } from '../ui/Badge';
|
||||
import { Button } from '../ui/Button';
|
||||
|
||||
interface VisionManifestoModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onOpenWaitlist: () => void;
|
||||
}
|
||||
|
||||
export const VisionManifestoModal: React.FC<VisionManifestoModalProps> = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
onOpenWaitlist
|
||||
}) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6 overflow-y-auto">
|
||||
{/* Backdrop */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={onClose}
|
||||
className="fixed inset-0 bg-slate-950/85 backdrop-blur-xl"
|
||||
/>
|
||||
|
||||
{/* Modal Window */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
className="relative w-full max-w-3xl bg-slate-900 border border-slate-800 rounded-3xl p-6 sm:p-10 shadow-2xl z-10 max-h-[90vh] overflow-y-auto"
|
||||
>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-6 right-6 p-2 rounded-xl bg-slate-800 text-slate-400 hover:text-white transition-colors"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<Badge variant="tangerine">Official Declaration</Badge>
|
||||
<span className="text-xs font-mono text-slate-400">Public Document #001</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl sm:text-3xl font-extrabold text-white">
|
||||
The Software X Founder Manifesto
|
||||
</h2>
|
||||
<p className="text-xs text-orange-400 font-mono mt-1">
|
||||
Why we are funding software through a community token instead of Venture Capital.
|
||||
</p>
|
||||
|
||||
<div className="mt-6 space-y-4 text-sm text-slate-300 leading-relaxed border-t border-slate-800 pt-6 font-normal">
|
||||
<p>
|
||||
In 2024, we built <strong>BirthdayMessaging.io</strong>. It was a simple, elegant idea: automate meaningful personal messages so people never miss key milestones in the lives of their clients and loved ones. It grew organically to serve over 85,000 active users.
|
||||
</p>
|
||||
<p>
|
||||
From that single product grew an ecosystem of <strong>30+ digital micro-SaaS applications</strong> covering encrypted routing, workflow automation, and live telemetry.
|
||||
</p>
|
||||
<p>
|
||||
When it came time to scale this ecosystem into <strong>Software X</strong>, traditional venture capital firms offered millions in exchange for board seats, liquidation preferences, and exit timelines. We turned them down.
|
||||
</p>
|
||||
<p className="p-4 rounded-xl bg-slate-950 border border-orange-500/30 text-white font-medium italic">
|
||||
"When VCs fund software, the investor becomes the customer and the user becomes the product. By funding Software X through a fair community token, our incentives remain 100% aligned with our software users."
|
||||
</p>
|
||||
<h4 className="text-base font-bold text-white pt-2">Our Irrevocable Pledges:</h4>
|
||||
<ul className="space-y-2 text-xs text-slate-300 font-mono">
|
||||
<li className="flex items-center gap-2">
|
||||
<CheckCircle2 className="w-4 h-4 text-sky-400" /> 1. Real revenue-generating software always precedes token launches.
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<CheckCircle2 className="w-4 h-4 text-sky-400" /> 2. Zero VC allocations, zero secret discount presales.
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<CheckCircle2 className="w-4 h-4 text-sky-400" /> 3. Multi-sig treasury contracts audited and visible on-chain 24/7.
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<CheckCircle2 className="w-4 h-4 text-sky-400" /> 4. Software subscription profits automatically buy back $SX tokens.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-full bg-gradient-to-tr from-orange-500 via-amber-500 to-sky-500 flex items-center justify-center text-white font-bold text-xs">
|
||||
SX
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<p className="text-xs font-bold text-white">Software X Core Engineering Team</p>
|
||||
<p className="text-[11px] text-slate-400 font-mono">Creators of BirthdayMessaging.io</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="glow"
|
||||
size="md"
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onOpenWaitlist();
|
||||
}}
|
||||
>
|
||||
Join Early Access Waitlist
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,296 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import confetti from 'canvas-confetti';
|
||||
import { CheckCircle2, Sparkles, Copy, Share2, ArrowRight, ShieldCheck, Mail, User, Tag, Lock, Users } from 'lucide-react';
|
||||
import { SectionHeading } from '../ui/SectionHeading';
|
||||
import { GlassCard } from '../ui/GlassCard';
|
||||
import { Button } from '../ui/Button';
|
||||
import { WaitlistEntry } from '../../types';
|
||||
import { registerForWaitlist, subscribeToWaitlistStats, WaitlistStats } from '../../lib/firebase';
|
||||
|
||||
export const WaitlistSection: React.FC = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [fullName, setFullName] = useState('');
|
||||
const [role, setRole] = useState('Software User');
|
||||
const [referralInput, setReferralInput] = useState('');
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [submittedEntry, setSubmittedEntry] = useState<WaitlistEntry | null>(null);
|
||||
const [copiedLink, setCopiedLink] = useState(false);
|
||||
const [liveStats, setLiveStats] = useState<WaitlistStats>({
|
||||
totalCount: 2871,
|
||||
totalFundedAmount: 142500,
|
||||
recentRegistrationsCount: 1
|
||||
});
|
||||
|
||||
const rolesList = [
|
||||
'Software User',
|
||||
'Developer',
|
||||
'Community Believer',
|
||||
'Founder / Creator',
|
||||
'Ecosystem Backer'
|
||||
];
|
||||
|
||||
// Subscribe to real-time Firestore database counter
|
||||
useEffect(() => {
|
||||
const unsubscribe = subscribeToWaitlistStats((stats) => {
|
||||
setLiveStats(stats);
|
||||
});
|
||||
|
||||
// Check if user already registered previously in this browser
|
||||
const saved = localStorage.getItem('software_x_my_waitlist_entry');
|
||||
if (saved) {
|
||||
try {
|
||||
const parsed = JSON.parse(saved);
|
||||
setSubmittedEntry(parsed);
|
||||
} catch (err) {
|
||||
// ignore invalid JSON
|
||||
}
|
||||
}
|
||||
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!email) return;
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
const result = await registerForWaitlist({
|
||||
email,
|
||||
fullName: fullName || role,
|
||||
tier: 'Supporter',
|
||||
investmentAmount: 25,
|
||||
referredBy: referralInput || undefined
|
||||
});
|
||||
|
||||
const newEntry: WaitlistEntry = {
|
||||
id: result.id,
|
||||
email: result.email,
|
||||
role: role,
|
||||
referralCode: result.referralCode,
|
||||
position: result.position,
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
localStorage.setItem('software_x_my_waitlist_entry', JSON.stringify(newEntry));
|
||||
setSubmittedEntry(newEntry);
|
||||
|
||||
// Trigger Confetti Celebration!
|
||||
try {
|
||||
confetti({
|
||||
particleCount: 100,
|
||||
spread: 80,
|
||||
origin: { y: 0.6 }
|
||||
});
|
||||
} catch (err) {
|
||||
// Fallback silently
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Waitlist submit error:', err);
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const copyReferralLink = () => {
|
||||
if (!submittedEntry) return;
|
||||
const link = `${window.location.origin}?ref=${submittedEntry.referralCode}`;
|
||||
navigator.clipboard.writeText(link);
|
||||
setCopiedLink(true);
|
||||
setTimeout(() => setCopiedLink(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="waitlist" className="py-24 bg-slate-950 relative overflow-hidden border-t border-slate-900">
|
||||
{/* Glow shapes */}
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[700px] bg-gradient-to-tr from-orange-600/20 via-amber-600/10 to-sky-500/20 rounded-full blur-[140px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<SectionHeading
|
||||
badgeText={`Live Queue: #${liveStats.totalCount.toLocaleString()} Registered`}
|
||||
badgeVariant="sky"
|
||||
title="Join the Software X"
|
||||
gradientTitle="Early Access Waitlist"
|
||||
subtitle="Be among the first to access Software X Core Protocol, test private beta builds across 30+ products, and claim community rewards."
|
||||
/>
|
||||
|
||||
{/* Live Registered Counter Badge */}
|
||||
<div className="mb-8 flex justify-center">
|
||||
<div className="inline-flex items-center gap-2.5 px-4 py-2 rounded-full bg-slate-900/90 border border-sky-500/30 backdrop-blur-md shadow-lg">
|
||||
<Users className="w-4 h-4 text-sky-400" />
|
||||
<span className="text-xs font-mono font-bold text-slate-200">
|
||||
Real-time Database Counter: <span className="text-sky-400 font-extrabold">{liveStats.totalCount.toLocaleString()} Backers Registered</span>
|
||||
</span>
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AnimatePresence mode="wait">
|
||||
{!submittedEntry ? (
|
||||
<motion.div
|
||||
key="form"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
>
|
||||
<GlassCard gradientBorder={true} className="p-8 sm:p-10">
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-6">
|
||||
|
||||
{/* Email & Name Grid */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="block text-xs font-mono uppercase tracking-widest text-slate-300 mb-2 font-semibold">
|
||||
Work or Personal Email <span className="text-orange-400">*</span>
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Mail className="w-4 h-4 text-slate-400 absolute left-4 top-1/2 -translate-y-1/2" />
|
||||
<input
|
||||
type="email"
|
||||
required
|
||||
placeholder="[email protected]"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
className="w-full bg-slate-950 border border-slate-800 rounded-xl pl-11 pr-4 py-3.5 text-sm text-white placeholder-slate-400 focus:outline-none focus:border-orange-500 focus:ring-1 focus:ring-orange-500 transition-all"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-mono uppercase tracking-widest text-slate-300 mb-2 font-semibold">
|
||||
Full Name or Handle
|
||||
</label>
|
||||
<div className="relative">
|
||||
<User className="w-4 h-4 text-slate-400 absolute left-4 top-1/2 -translate-y-1/2" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Your Name / Handle"
|
||||
value={fullName}
|
||||
onChange={(e) => setFullName(e.target.value)}
|
||||
className="w-full bg-slate-950 border border-slate-800 rounded-xl pl-11 pr-4 py-3.5 text-sm text-white placeholder-slate-400 focus:outline-none focus:border-orange-500 focus:ring-1 focus:ring-orange-500 transition-all"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Role Selector */}
|
||||
<div>
|
||||
<label className="block text-xs font-mono uppercase tracking-widest text-slate-300 mb-2 font-semibold">
|
||||
Primary Interest / Role
|
||||
</label>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2.5">
|
||||
{rolesList.map((r) => (
|
||||
<button
|
||||
key={r}
|
||||
type="button"
|
||||
onClick={() => setRole(r)}
|
||||
className={`p-3 rounded-xl border text-xs font-medium transition-all text-left cursor-pointer ${
|
||||
role === r
|
||||
? 'bg-orange-950/80 border-orange-500 text-white shadow-md'
|
||||
: 'bg-slate-950 border-slate-800 text-slate-400 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
{r}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Optional Referral Code */}
|
||||
<div>
|
||||
<label className="block text-xs font-mono uppercase tracking-widest text-slate-400 mb-2 font-semibold">
|
||||
Optional Invite or Referral Code
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Tag className="w-4 h-4 text-slate-400 absolute left-4 top-1/2 -translate-y-1/2" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="e.g. SX-EARLY2026"
|
||||
value={referralInput}
|
||||
onChange={(e) => setReferralInput(e.target.value)}
|
||||
className="w-full bg-slate-950 border border-slate-800 rounded-xl pl-11 pr-4 py-3 text-sm text-white placeholder-slate-400 focus:outline-none focus:border-orange-500 transition-all font-mono"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Privacy Reassurance */}
|
||||
<div className="flex items-center gap-2 text-xs text-slate-400">
|
||||
<Lock className="w-3.5 h-3.5 text-sky-400" />
|
||||
<span>Zero spam. Saved securely to Firestore database.</span>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<Button
|
||||
type="submit"
|
||||
variant="glow"
|
||||
size="lg"
|
||||
isLoading={isSubmitting}
|
||||
icon={<ArrowRight className="w-4 h-4" />}
|
||||
className="w-full mt-2"
|
||||
>
|
||||
Reserve Priority Spot Now
|
||||
</Button>
|
||||
</form>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="confirmation"
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
>
|
||||
<GlassCard gradientBorder={true} className="p-8 sm:p-10 text-center">
|
||||
<div className="w-16 h-16 rounded-full bg-sky-950 border border-sky-500/40 flex items-center justify-center text-sky-400 mx-auto mb-6 shadow-xl shadow-sky-950/60">
|
||||
<CheckCircle2 className="w-8 h-8" />
|
||||
</div>
|
||||
|
||||
<span className="text-xs font-mono text-sky-400 uppercase tracking-widest font-semibold">
|
||||
Waitlist Position Reserved
|
||||
</span>
|
||||
|
||||
<h3 className="text-3xl font-extrabold text-white mt-2">
|
||||
You are #{submittedEntry.position.toLocaleString()} in line!
|
||||
</h3>
|
||||
|
||||
<p className="text-sm text-slate-300 mt-3 max-w-lg mx-auto leading-relaxed">
|
||||
Confirmation sent to <strong className="text-orange-300">{submittedEntry.email}</strong>. Share your unique invite link below to jump ahead in line for private beta builds.
|
||||
</p>
|
||||
|
||||
{/* Referral Link Box */}
|
||||
<div className="mt-8 p-4 rounded-2xl bg-slate-950 border border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-3 max-w-md mx-auto">
|
||||
<span className="font-mono text-xs text-orange-300 truncate w-full sm:w-auto">
|
||||
{window.location.origin}?ref={submittedEntry.referralCode}
|
||||
</span>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={copyReferralLink}
|
||||
icon={copiedLink ? <CheckCircle2 className="w-3.5 h-3.5 text-sky-400" /> : <Copy className="w-3.5 h-3.5" />}
|
||||
>
|
||||
{copiedLink ? 'Copied Link' : 'Copy Link'}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-slate-800/80 flex justify-center">
|
||||
<button
|
||||
onClick={() => {
|
||||
localStorage.removeItem('software_x_my_waitlist_entry');
|
||||
setSubmittedEntry(null);
|
||||
}}
|
||||
className="text-xs text-slate-400 hover:text-white transition-colors cursor-pointer"
|
||||
>
|
||||
← Register another email address
|
||||
</button>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
|
||||
interface AnimatedCounterProps {
|
||||
end: number;
|
||||
duration?: number;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const AnimatedCounter: React.FC<AnimatedCounterProps> = ({
|
||||
end,
|
||||
duration = 2000,
|
||||
prefix = '',
|
||||
suffix = '',
|
||||
className = ''
|
||||
}) => {
|
||||
const [count, setCount] = useState(0);
|
||||
const counterRef = useRef<HTMLSpanElement>(null);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible(true);
|
||||
}
|
||||
},
|
||||
{ threshold: 0.2 }
|
||||
);
|
||||
|
||||
if (counterRef.current) {
|
||||
observer.observe(counterRef.current);
|
||||
}
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isVisible) return;
|
||||
|
||||
let start = 0;
|
||||
const increment = end / (duration / 16);
|
||||
const timer = setInterval(() => {
|
||||
start += increment;
|
||||
if (start >= end) {
|
||||
setCount(end);
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
setCount(Math.floor(start));
|
||||
}
|
||||
}, 16);
|
||||
|
||||
return () => clearInterval(timer);
|
||||
}, [end, duration, isVisible]);
|
||||
|
||||
return (
|
||||
<span ref={counterRef} className={className}>
|
||||
{prefix}
|
||||
{count.toLocaleString()}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
|
||||
interface BadgeProps {
|
||||
children: React.ReactNode;
|
||||
variant?: 'emerald' | 'indigo' | 'cyan' | 'purple' | 'amber' | 'neutral' | 'tangerine' | 'sky';
|
||||
showDot?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const Badge: React.FC<BadgeProps> = ({
|
||||
children,
|
||||
variant = 'tangerine',
|
||||
showDot = true,
|
||||
className = ''
|
||||
}) => {
|
||||
const styles = {
|
||||
tangerine: {
|
||||
bg: 'bg-orange-950/70 text-orange-300 border-orange-500/40',
|
||||
dot: 'bg-orange-400'
|
||||
},
|
||||
sky: {
|
||||
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
||||
dot: 'bg-sky-400'
|
||||
},
|
||||
emerald: {
|
||||
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
||||
dot: 'bg-sky-400'
|
||||
},
|
||||
indigo: {
|
||||
bg: 'bg-orange-950/70 text-orange-300 border-orange-500/40',
|
||||
dot: 'bg-orange-400'
|
||||
},
|
||||
cyan: {
|
||||
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
||||
dot: 'bg-sky-400'
|
||||
},
|
||||
purple: {
|
||||
bg: 'bg-sky-950/70 text-sky-300 border-sky-500/40',
|
||||
dot: 'bg-sky-400'
|
||||
},
|
||||
amber: {
|
||||
bg: 'bg-orange-950/70 text-orange-300 border-orange-500/40',
|
||||
dot: 'bg-amber-400'
|
||||
},
|
||||
neutral: {
|
||||
bg: 'bg-slate-800/80 text-slate-300 border-slate-700/60',
|
||||
dot: 'bg-slate-400'
|
||||
}
|
||||
};
|
||||
|
||||
const current = styles[variant];
|
||||
|
||||
return (
|
||||
<span className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium border backdrop-blur-md shadow-inner tracking-wide ${current.bg} ${className}`}>
|
||||
{showDot && (
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 ${current.dot}`} />
|
||||
<span className={`relative inline-flex rounded-full h-2 w-2 ${current.dot}`} />
|
||||
</span>
|
||||
)}
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'glow';
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
isLoading?: boolean;
|
||||
icon?: React.ReactNode;
|
||||
iconPosition?: 'left' | 'right';
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Button: React.FC<ButtonProps> = ({
|
||||
variant = 'primary',
|
||||
size = 'md',
|
||||
isLoading = false,
|
||||
icon,
|
||||
iconPosition = 'right',
|
||||
children,
|
||||
className = '',
|
||||
disabled,
|
||||
...props
|
||||
}) => {
|
||||
const baseStyles = 'inline-flex items-center justify-center font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-orange-500/50 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer whitespace-nowrap rounded-xl';
|
||||
|
||||
const sizeStyles = {
|
||||
sm: 'px-3.5 py-1.5 text-xs gap-1.5',
|
||||
md: 'px-5 py-2.5 text-sm gap-2',
|
||||
lg: 'px-7 py-3.5 text-base gap-2.5 shadow-lg shadow-orange-950/20'
|
||||
};
|
||||
|
||||
const variantStyles = {
|
||||
primary: 'bg-orange-600 hover:bg-orange-500 text-white shadow-lg shadow-orange-600/25 border border-orange-500/30 hover:border-orange-400/50 hover:shadow-orange-500/35 active:scale-[0.98]',
|
||||
secondary: 'bg-slate-800/90 hover:bg-slate-700/90 text-slate-100 border border-slate-700/60 hover:border-slate-600 active:scale-[0.98]',
|
||||
outline: 'bg-transparent text-slate-200 border border-slate-700 hover:border-orange-500/50 hover:bg-orange-950/20 active:scale-[0.98]',
|
||||
ghost: 'bg-transparent text-slate-300 hover:text-white hover:bg-slate-800/60 active:scale-[0.98]',
|
||||
glow: 'relative bg-gradient-to-r from-orange-500 via-amber-500 to-sky-400 text-slate-950 font-extrabold shadow-xl shadow-orange-500/25 hover:shadow-orange-500/40 border border-amber-200/40 hover:scale-[1.02] active:scale-[0.98]'
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.button
|
||||
whileHover={{ y: -1 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className={`${baseStyles} ${sizeStyles[size]} ${variantStyles[variant]} ${className}`}
|
||||
disabled={disabled || isLoading}
|
||||
{...props}
|
||||
>
|
||||
{isLoading && <Loader2 className="w-4 h-4 animate-spin text-current" />}
|
||||
{!isLoading && icon && iconPosition === 'left' && <span className="inline-flex">{icon}</span>}
|
||||
<span>{children}</span>
|
||||
{!isLoading && icon && iconPosition === 'right' && <span className="inline-flex">{icon}</span>}
|
||||
</motion.button>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
|
||||
interface GlassCardProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
hoverEffect?: boolean;
|
||||
gradientBorder?: boolean;
|
||||
onClick?: () => void;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export const GlassCard: React.FC<GlassCardProps> = ({
|
||||
children,
|
||||
className = '',
|
||||
hoverEffect = true,
|
||||
gradientBorder = false,
|
||||
onClick,
|
||||
id
|
||||
}) => {
|
||||
return (
|
||||
<motion.div
|
||||
id={id}
|
||||
whileHover={hoverEffect ? { y: -4, transition: { duration: 0.2 } } : undefined}
|
||||
onClick={onClick}
|
||||
className={`relative rounded-2xl bg-slate-900/70 backdrop-blur-xl border border-slate-800/80 p-6 shadow-xl shadow-black/40 overflow-hidden transition-all duration-300 ${
|
||||
hoverEffect ? 'hover:border-orange-500/40 hover:shadow-2xl hover:shadow-orange-950/30' : ''
|
||||
} ${
|
||||
gradientBorder ? 'before:absolute before:inset-0 before:p-[1px] before:bg-gradient-to-b before:from-orange-500/40 before:via-sky-500/20 before:to-transparent before:rounded-2xl before:-z-10' : ''
|
||||
} ${className}`}
|
||||
>
|
||||
{/* Subtle top glow line */}
|
||||
<div className="absolute top-0 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-orange-500/30 to-transparent opacity-60 pointer-events-none" />
|
||||
{children}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import { Badge } from './Badge';
|
||||
|
||||
interface SectionHeadingProps {
|
||||
badgeText?: string;
|
||||
badgeVariant?: 'emerald' | 'indigo' | 'cyan' | 'purple' | 'amber' | 'neutral' | 'tangerine' | 'sky';
|
||||
title: string;
|
||||
gradientTitle?: string;
|
||||
subtitle?: string;
|
||||
align?: 'left' | 'center' | 'right';
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const SectionHeading: React.FC<SectionHeadingProps> = ({
|
||||
badgeText,
|
||||
badgeVariant = 'tangerine',
|
||||
title,
|
||||
gradientTitle,
|
||||
subtitle,
|
||||
align = 'center',
|
||||
className = ''
|
||||
}) => {
|
||||
const alignmentClass = {
|
||||
left: 'text-left items-start',
|
||||
center: 'text-center items-center',
|
||||
right: 'text-right items-end'
|
||||
}[align];
|
||||
|
||||
return (
|
||||
<div className={`flex flex-col mb-12 ${alignmentClass} ${className}`}>
|
||||
{badgeText && (
|
||||
<div className="mb-4">
|
||||
<Badge variant={badgeVariant}>{badgeText}</Badge>
|
||||
</div>
|
||||
)}
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-bold tracking-tight text-white max-w-3xl leading-tight">
|
||||
{title}{' '}
|
||||
{gradientTitle && (
|
||||
<span className="bg-gradient-to-r from-orange-400 via-amber-300 to-sky-400 bg-clip-text text-transparent">
|
||||
{gradientTitle}
|
||||
</span>
|
||||
)}
|
||||
</h2>
|
||||
{subtitle && (
|
||||
<p className="mt-4 text-base sm:text-lg text-slate-400 max-w-2xl leading-relaxed font-normal">
|
||||
{subtitle}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,815 @@
|
||||
import { EcosystemApp } from '../types';
|
||||
|
||||
export const ecosystemApps: EcosystemApp[] = [
|
||||
// ==================== CORE APPS ====================
|
||||
{
|
||||
id: 'birthdaymessaging-2',
|
||||
name: 'BirthdayMessaging 2.0',
|
||||
category: 'Core Apps',
|
||||
description: 'The flagship automated relationship & birthday messaging engine powering multi-channel greetings globally.',
|
||||
usersCount: '85,000+ Active Users',
|
||||
growthRate: 'Flagship Core',
|
||||
price: 'SaaS Platform',
|
||||
iconName: 'Gift',
|
||||
badgeText: 'Flagship Core',
|
||||
featured: true,
|
||||
link: 'https://birthdaymessaging.io',
|
||||
highlights: [
|
||||
'Automated trigger schedules across multi-channels',
|
||||
'Personalized dynamic message workflows',
|
||||
'Universal contact list synchronization'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-facebook',
|
||||
name: 'BirthdayMessaging FB',
|
||||
category: 'Core Apps',
|
||||
description: 'Automated Facebook birthday outreach and relationship management engagement engine.',
|
||||
usersCount: '14,200+ Users',
|
||||
growthRate: 'Active',
|
||||
price: 'Core Module',
|
||||
iconName: 'Zap',
|
||||
badgeText: 'Facebook Core',
|
||||
highlights: [
|
||||
'Auto-congratulations on timeline & Messenger',
|
||||
'Social engagement warming algorithms'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-email',
|
||||
name: 'BirthdayMessaging EM',
|
||||
category: 'Core Apps',
|
||||
description: 'High-deliverability email birthday campaign engine with dynamic personalization.',
|
||||
usersCount: '22,500+ Users',
|
||||
growthRate: 'Active',
|
||||
price: 'Core Module',
|
||||
iconName: 'Mail',
|
||||
badgeText: 'Email Core',
|
||||
highlights: [
|
||||
'Custom HTML & dynamic text templates',
|
||||
'Automated queue dispatch & open tracking'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-linkedin',
|
||||
name: 'BirthdayMessaging LI',
|
||||
category: 'Core Apps',
|
||||
description: 'Professional network relationship manager for LinkedIn birthdays and work anniversaries.',
|
||||
usersCount: '9,800+ Users',
|
||||
growthRate: 'Active',
|
||||
price: 'Core Module',
|
||||
iconName: 'UserCheck',
|
||||
badgeText: 'LinkedIn Core',
|
||||
highlights: [
|
||||
'B2B relationship retention & networking',
|
||||
'Work anniversary auto-acknowledgment'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-instagram',
|
||||
name: 'BirthdayMessaging IN',
|
||||
category: 'Core Apps',
|
||||
description: 'Instagram DM birthday engagement and story mention relationship system.',
|
||||
usersCount: '11,400+ Users',
|
||||
growthRate: 'Active',
|
||||
price: 'Core Module',
|
||||
iconName: 'Radio',
|
||||
badgeText: 'Instagram Core',
|
||||
highlights: [
|
||||
'Direct Message automation & replies',
|
||||
'Story interaction warming'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-tiktok',
|
||||
name: 'BirthdayMessaging TT',
|
||||
category: 'Core Apps',
|
||||
description: 'TikTok creator relationship builder and follower birthday engagement engine.',
|
||||
usersCount: '8,100+ Users',
|
||||
growthRate: 'Active',
|
||||
price: 'Core Module',
|
||||
iconName: 'Activity',
|
||||
badgeText: 'TikTok Core',
|
||||
highlights: [
|
||||
'Creator follower loyalty automation',
|
||||
'DM interaction workflows'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-whatsapp',
|
||||
name: 'BirthdayMessaging WA',
|
||||
category: 'Core Apps',
|
||||
description: 'WhatsApp multi-device automated birthday greetings with end-to-end messaging reliability.',
|
||||
usersCount: '31,000+ Users',
|
||||
growthRate: 'High Growth',
|
||||
price: 'Core Module',
|
||||
iconName: 'MessageSquare',
|
||||
badgeText: 'WhatsApp Core',
|
||||
featured: true,
|
||||
highlights: [
|
||||
'Multi-device session synchronization',
|
||||
'Rich media birthday e-cards & audio'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-legacy',
|
||||
name: 'BirthdayMessaging (Legacy)',
|
||||
category: 'Core Apps',
|
||||
description: 'Original lightweight birthday reminder and messaging engine.',
|
||||
usersCount: '15,000+ Users',
|
||||
growthRate: 'Legacy Stable',
|
||||
price: 'Legacy Engine',
|
||||
iconName: 'ShieldCheck',
|
||||
badgeText: 'Original Engine',
|
||||
highlights: [
|
||||
'Reliable scheduled reminder triggers',
|
||||
'Lightweight contacts vault'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'connect-crm',
|
||||
name: 'ConnectCRM',
|
||||
category: 'Core Apps',
|
||||
description: 'Comprehensive relationship management system linking contact histories across all BM apps.',
|
||||
usersCount: '18,900+ Contacts',
|
||||
growthRate: 'Core CRM',
|
||||
price: 'SaaS Platform',
|
||||
iconName: 'Users',
|
||||
badgeText: 'Ecosystem CRM',
|
||||
highlights: [
|
||||
'Unified multi-channel customer profiles',
|
||||
'Cross-platform conversation history'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'scope-crm',
|
||||
name: 'ScopeCRM',
|
||||
category: 'Core Apps',
|
||||
description: 'Lead pipeline, conversion scope analyzer, and deal tracking CRM.',
|
||||
usersCount: '6,400+ Pipelines',
|
||||
growthRate: 'B2B Core',
|
||||
price: 'SaaS Platform',
|
||||
iconName: 'Target',
|
||||
badgeText: 'Pipeline CRM',
|
||||
highlights: [
|
||||
'Visual deal stage mapping & forecasting',
|
||||
'Automated follow-up triggers'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'creathub-core',
|
||||
name: 'CreatHub',
|
||||
category: 'Core Apps',
|
||||
description: 'All-in-one content creation studio for designing, scheduling, and deploying marketing assets.',
|
||||
usersCount: '12,800+ Creators',
|
||||
growthRate: 'Core Studio',
|
||||
price: 'SaaS Studio',
|
||||
iconName: 'Layers',
|
||||
badgeText: 'Creative Studio',
|
||||
highlights: [
|
||||
'Multi-format content generator',
|
||||
'Asset library & template orchestration'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'atlas-webminer',
|
||||
name: 'AtlasWebMiner',
|
||||
category: 'Core Apps',
|
||||
description: 'Automated web mining and lead contact extraction system.',
|
||||
usersCount: '7,300+ Operators',
|
||||
growthRate: 'Mining Engine',
|
||||
price: 'SaaS Tool',
|
||||
iconName: 'Database',
|
||||
badgeText: 'Web Miner',
|
||||
highlights: [
|
||||
'High-speed public directory crawling',
|
||||
'Structured contact enrichment'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-people',
|
||||
name: 'BM People',
|
||||
category: 'Core Apps',
|
||||
description: 'Human resource, employee birthday, and team work milestone retention system.',
|
||||
usersCount: '4,200+ Teams',
|
||||
growthRate: 'HR Core',
|
||||
price: 'Enterprise HR',
|
||||
iconName: 'HeartHandshake',
|
||||
badgeText: 'HR & People',
|
||||
highlights: [
|
||||
'Corporate team milestone calendar',
|
||||
'Automated employee rewards dispatch'
|
||||
]
|
||||
},
|
||||
|
||||
// ==================== MINIAPPS & WEB ====================
|
||||
{
|
||||
id: 'bmmapscout',
|
||||
name: 'BMMAPSCOUT',
|
||||
category: 'MiniApps & Web',
|
||||
description: 'Scout business details, contact info, and lead insights directly from Google Maps search results.',
|
||||
usersCount: 'Active Scout',
|
||||
growthRate: 'Live App',
|
||||
price: '$17.00 Lifetime',
|
||||
link: 'https://bmmapscout.pages.dev/',
|
||||
iconName: 'MapPin',
|
||||
badgeText: 'Maps Scout',
|
||||
featured: true,
|
||||
highlights: [
|
||||
'Google Maps business details extraction',
|
||||
'Direct contact & website finder',
|
||||
'Exportable CSV lead lists'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bmfriendscout',
|
||||
name: 'BMFRIENDSCOUT',
|
||||
category: 'MiniApps & Web',
|
||||
description: 'Social friend scout and target prospect identification mini-app.',
|
||||
usersCount: 'Active Scout',
|
||||
growthRate: 'Live App',
|
||||
price: 'MiniApp',
|
||||
iconName: 'Search',
|
||||
badgeText: 'Social Scout',
|
||||
highlights: [
|
||||
'Target demographic discovery',
|
||||
'Social profile relationship tagging'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bmvidscout',
|
||||
name: 'BMVIDSCOUT',
|
||||
category: 'MiniApps & Web',
|
||||
description: 'Video prospecting tool scouting high-converting video opportunities.',
|
||||
usersCount: 'Active Scout',
|
||||
growthRate: 'Live App',
|
||||
price: 'MiniApp',
|
||||
iconName: 'Video',
|
||||
badgeText: 'Video Scout',
|
||||
highlights: [
|
||||
'Video lead scoring & analysis',
|
||||
'Automated outreach hook creation'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'createhub-web',
|
||||
name: 'CREATEHUB Web',
|
||||
category: 'MiniApps & Web',
|
||||
description: 'Browser-based cloud portal for content generation and prompt orchestration.',
|
||||
usersCount: 'Cloud Portal',
|
||||
growthRate: 'Live App',
|
||||
price: 'WebApp',
|
||||
link: 'https://program-store-4z7.pages.dev/',
|
||||
iconName: 'Globe',
|
||||
badgeText: 'Cloud WebApp',
|
||||
highlights: [
|
||||
'Zero-install browser application',
|
||||
'Instant asset export & sharing'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'atlas-dataminer',
|
||||
name: 'ATLASDATAMINER',
|
||||
category: 'MiniApps & Web',
|
||||
description: 'Deep web data extraction and structured lead intelligence engine.',
|
||||
usersCount: 'Deep Mining',
|
||||
growthRate: 'Live App',
|
||||
price: 'WebApp',
|
||||
iconName: 'Cpu',
|
||||
badgeText: 'Data Miner',
|
||||
highlights: [
|
||||
'Deep web lead scraping',
|
||||
'Automated data cleaning & deduplication'
|
||||
]
|
||||
},
|
||||
|
||||
// ==================== MICROAPPS (23 MARKETING PROGRAMS @ $17.00 ONCE) ====================
|
||||
{
|
||||
id: 'rapid-prompt-engine',
|
||||
name: 'Rapid Prompt Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Turn one desired prompt outcome into an exact elite prompt-creator instruction.',
|
||||
usersCount: '01 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://rapid-prompt-engine.birthdaymessaging.io/',
|
||||
iconName: 'Zap',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
featured: true,
|
||||
highlights: [
|
||||
'Elite prompt-creator instruction generator',
|
||||
'One-click prompt outcome transformation',
|
||||
'Permanent account access (No monthly subscription)'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'gripping-content-engine',
|
||||
name: 'Gripping Content Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate high-intent search keyword prompts built around frustration, skepticism, comparisons, warnings, costs, and specific outcomes.',
|
||||
usersCount: '02 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://gripping-content-engine.birthdaymessaging.io/',
|
||||
iconName: 'FileText',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
featured: true,
|
||||
highlights: [
|
||||
'High-intent buyer keyword prompts',
|
||||
'Frustration, skepticism & cost angles',
|
||||
'Conversion-focused search content'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'cover-mockup-engine',
|
||||
name: 'Cover Mockup Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate premium cover-mockup workflows, flexible builder prompts, and fast variation follow-ups.',
|
||||
usersCount: '03 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://cover-mockup-engine.birthdaymessaging.io/',
|
||||
iconName: 'Image',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Premium 3D cover mockup workflows',
|
||||
'Flexible builder prompts & variations',
|
||||
'Fast visual asset production'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'offer-stack-engine',
|
||||
name: 'Offer Stack Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Turn one niche into layered bonus ideas, then expand a chosen angle into a finished text-first asset.',
|
||||
usersCount: '04 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://offer-stack-engine.birthdaymessaging.io/',
|
||||
iconName: 'Layers',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
featured: true,
|
||||
highlights: [
|
||||
'Layered bonus stack ideation',
|
||||
'Angle expansion into finished text assets',
|
||||
'High-converting offer creation'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'hook-to-profit-engine',
|
||||
name: 'The Hook-to-Profit Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate money lines, hooks, and derivative prompts for key marketing formats.',
|
||||
usersCount: '05 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://hook-to-profit-engine.birthdaymessaging.io/',
|
||||
iconName: 'TrendingUp',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'High-converting money lines & hooks',
|
||||
'Derivative prompts for ads & emails',
|
||||
'Instant copy format adaptation'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'buyer-psychology-engine',
|
||||
name: 'The Buyer Psychology Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Shape desire, identity, and momentum with psychology-led prompt outputs.',
|
||||
usersCount: '06 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://buyer-psychology-engine.birthdaymessaging.io/',
|
||||
iconName: 'Brain',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Psychology-led buyer desire shaping',
|
||||
'Identity & momentum copy triggers',
|
||||
'Behavioral prompt frameworks'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'attention-override-system',
|
||||
name: 'The Attention Override System',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate aggressive pattern-interrupt hooks and opening lines.',
|
||||
usersCount: '07 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://attention-override-system.birthdaymessaging.io/',
|
||||
iconName: 'AlertTriangle',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Pattern-interrupt scroll stoppers',
|
||||
'Aggressive opening hook lines',
|
||||
'High-engagement headline variations'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'conversion-trigger-engine',
|
||||
name: 'The Conversion Trigger Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate short conversion nudges, CTA variants, and friction-reducing phrases.',
|
||||
usersCount: '08 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://conversion-trigger-engine.birthdaymessaging.io/',
|
||||
iconName: 'CheckSquare',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Short conversion nudges & CTAs',
|
||||
'Friction-reducing copy phrases',
|
||||
'Urgency & scarcity triggers'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'authority-engine',
|
||||
name: 'Authority Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Extract insight angles, then expand one into multi-format authority content.',
|
||||
usersCount: '09 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://authority-engine.birthdaymessaging.io/',
|
||||
iconName: 'Award',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Insight angle extraction from ideas',
|
||||
'Multi-format authority content expansion',
|
||||
'Thought-leadership positioning'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'social-sales-machine',
|
||||
name: 'Social Sales Machine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate social posts from proven hook patterns with a feed-style result lane.',
|
||||
usersCount: '10 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://social-sales-machine.birthdaymessaging.io/',
|
||||
iconName: 'Share2',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Social posts from proven hook patterns',
|
||||
'Feed-style visual result lane',
|
||||
'Direct-response social copy'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'rapid-infographics',
|
||||
name: 'Rapid Infographics',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate thirty infographic prompts from one keyword, niche, topic, or pain point.',
|
||||
usersCount: '11 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://program-store-4z7.pages.dev/',
|
||||
iconName: 'BarChart',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'30 infographic prompts in seconds',
|
||||
'Visual data & chart structure prompts',
|
||||
'Niche-specific infographic workflows'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'rapid-ads',
|
||||
name: 'Rapid Ads',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate twenty infographic ad prompts from one offer title with light or dark creative direction.',
|
||||
usersCount: '12 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://rapid-ads.birthdaymessaging.io/',
|
||||
iconName: 'Tv',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'20 infographic ad creative prompts',
|
||||
'Light & dark creative direction options',
|
||||
'Offer title to ad concept generator'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'idea-to-income-accelerator',
|
||||
name: 'Idea-to-Income Accelerator',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate ranked side-hustle concepts with first steps and monetization paths.',
|
||||
usersCount: '13 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://idea-to-income-accelerator.birthdaymessaging.io/',
|
||||
iconName: 'DollarSign',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Ranked side-hustle monetization concepts',
|
||||
'Step-by-step launch roadmaps',
|
||||
'Income path validation'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'neuro-persuasion-engine',
|
||||
name: 'NeuroPersuasion Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Apply NLP-flavored persuasion techniques to copy blocks and rewrites.',
|
||||
usersCount: '14 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://neuro-persuasion-engine.birthdaymessaging.io/',
|
||||
iconName: 'Sparkles',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'NLP-flavored persuasion copy rewrites',
|
||||
'Subconscious trigger enhancement',
|
||||
'High-impact copy transformation'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'desire-activation-system',
|
||||
name: 'The Desire Activation System',
|
||||
category: 'MicroApps',
|
||||
description: 'Run persuasion strategies across formats from a strategist-style control board.',
|
||||
usersCount: '15 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://program-store-4z7.pages.dev/',
|
||||
iconName: 'Flame',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Strategist-style control dashboard',
|
||||
'Multi-format persuasion strategy runs',
|
||||
'Desire amplification workflows'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'keyword-opportunity-engine',
|
||||
name: 'Keyword Opportunity Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate long-tail keyword opportunities with intent and angle metadata.',
|
||||
usersCount: '16 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://keyword-opportunity-engine.birthdaymessaging.io/',
|
||||
iconName: 'Search',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Long-tail keyword opportunity discovery',
|
||||
'Search intent & angle metadata',
|
||||
'Low-competition organic targets'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'organic-traffic-engine',
|
||||
name: 'Organic Traffic Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Chain keywords, blueprints, article generation, rewrite, and image prompts in one SEO workflow.',
|
||||
usersCount: '17 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://organic-traffic-engine.birthdaymessaging.io/',
|
||||
iconName: 'Globe',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'End-to-end SEO article workflow chaining',
|
||||
'Keyword to article draft & rewrite',
|
||||
'Integrated image prompt generator'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'content-excellence-compliance-engine',
|
||||
name: 'Content Excellence & Compliance Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate structured legal pages and disclaimers from business details and jurisdiction.',
|
||||
usersCount: '18 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://content-excellence-compliance-engine.birthdaymessaging.io/',
|
||||
iconName: 'ShieldCheck',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Structured legal pages & disclaimers',
|
||||
'Jurisdiction & business details customization',
|
||||
'Compliance & risk mitigation'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'ai-content-control-center',
|
||||
name: 'AI Content Control Center',
|
||||
category: 'MicroApps',
|
||||
description: 'Rewrite AI-generated content using mode-based refinements and compare versions side by side.',
|
||||
usersCount: '19 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://ai-content-control-center.birthdaymessaging.io/',
|
||||
iconName: 'Sliders',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Side-by-side version comparison',
|
||||
'Mode-based AI tone refinements',
|
||||
'Humanization & authenticity tuning'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'cold-traffic-converter',
|
||||
name: 'Cold Traffic Converter',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate a fixed traffic asset pack from an offer and destination URL.',
|
||||
usersCount: '20 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://cold-traffic-converter.birthdaymessaging.io/',
|
||||
iconName: 'Target',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Fixed traffic asset pack creation',
|
||||
'Cold audience bridge messaging',
|
||||
'Destination URL optimization'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'idea-to-assets-engine',
|
||||
name: 'Idea-to-Assets Engine',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate seven asset types from one topic, then expand the chosen asset into a complete draft.',
|
||||
usersCount: '21 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://idea-to-assets-engine.birthdaymessaging.io/',
|
||||
iconName: 'FolderPlus',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'7 asset types from a single topic input',
|
||||
'One-click draft expansion',
|
||||
'Complete marketing asset collateral'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'blueprint-generator',
|
||||
name: 'Blueprint Generator',
|
||||
category: 'MicroApps',
|
||||
description: 'Generate expert framing, topic options, and a draft with rewrite handoff.',
|
||||
usersCount: '22 of 23',
|
||||
growthRate: 'Program Store',
|
||||
price: '$17.00 Once',
|
||||
link: 'https://blueprint-generator.birthdaymessaging.io/',
|
||||
iconName: 'FileSpreadsheet',
|
||||
badgeText: '$17.00 Lifetime',
|
||||
highlights: [
|
||||
'Expert topic framing & options',
|
||||
'Draft generation with rewrite handoff',
|
||||
'Structural blueprint creation'
|
||||
]
|
||||
},
|
||||
|
||||
// ==================== BLOCKCHAIN & TOKENS ====================
|
||||
{
|
||||
id: 'bm-ico-tokens',
|
||||
name: 'BM ICO & $SX Tokens',
|
||||
category: 'Blockchain & Tokens',
|
||||
description: 'Official tokenomics, token sale, and smart contract protocol powering the Software X treasury.',
|
||||
usersCount: 'Community Sale',
|
||||
growthRate: 'Protocol',
|
||||
price: 'Token Utility',
|
||||
iconName: 'Coins',
|
||||
badgeText: 'Blockchain',
|
||||
featured: true,
|
||||
highlights: [
|
||||
'100% on-chain multi-sig treasury contract',
|
||||
'Revenue-backed buy-back & burn mechanism',
|
||||
'Community governance smart contracts'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-crowdfunding-pe',
|
||||
name: 'BM Crowdfunding & Private Equity',
|
||||
category: 'Blockchain & Tokens',
|
||||
description: 'Decentralized equity and crowdfunding launchpad for community-backed software acquisitions.',
|
||||
usersCount: 'Launchpad',
|
||||
growthRate: 'DeFi Hub',
|
||||
price: 'Equity Tokens',
|
||||
iconName: 'Briefcase',
|
||||
badgeText: 'Private Equity',
|
||||
highlights: [
|
||||
'On-chain revenue distribution rights',
|
||||
'Community crowdsourced software investments',
|
||||
'Transparent financial audits'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'bm-memecoins',
|
||||
name: 'BM Memecoins Ecosystem',
|
||||
category: 'Blockchain & Tokens',
|
||||
description: 'Community engagement memecoin suite driving viral momentum and user onboarding.',
|
||||
usersCount: 'Viral Reach',
|
||||
growthRate: 'Community Led',
|
||||
price: 'Meme Utility',
|
||||
iconName: 'Flame',
|
||||
badgeText: 'Viral Memes',
|
||||
highlights: [
|
||||
'Viral organic marketing campaigns',
|
||||
'Community reward & airdrop distribution'
|
||||
]
|
||||
},
|
||||
|
||||
// ==================== DIRECTORIES & SERVICES ====================
|
||||
{
|
||||
id: 'birthdays-vendor-directory',
|
||||
name: 'Birthdays Vendor Directory',
|
||||
category: 'Directories & Services',
|
||||
description: 'B2B marketplace connecting event venues, party suppliers, and gifting vendors.',
|
||||
usersCount: '1,200+ Vendors',
|
||||
growthRate: 'B2B Network',
|
||||
price: 'B2B Directory',
|
||||
iconName: 'Store',
|
||||
badgeText: 'B2B Directory',
|
||||
highlights: [
|
||||
'Verified vendor business profiles',
|
||||
'Direct lead inquiries & bookings',
|
||||
'Vendor subscription revenue'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'wordpress-directory',
|
||||
name: 'WordPress Directory',
|
||||
category: 'Directories & Services',
|
||||
description: 'B2C consumer-facing directory for WordPress plugins, tools, and digital service providers.',
|
||||
usersCount: '5,000+ Listings',
|
||||
growthRate: 'B2C Network',
|
||||
price: 'B2C Directory',
|
||||
iconName: 'Compass',
|
||||
badgeText: 'B2C Directory',
|
||||
highlights: [
|
||||
'User ratings & service provider reviews',
|
||||
'Featured listing placements'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'accountancy-services',
|
||||
name: 'Accountancy Services',
|
||||
category: 'Directories & Services',
|
||||
description: 'Dedicated financial management, bookkeeping, and tax compliance for micro-SaaS businesses.',
|
||||
usersCount: 'Corporate Clients',
|
||||
growthRate: 'Active Service',
|
||||
price: 'Financial Ops',
|
||||
iconName: 'Calculator',
|
||||
badgeText: 'Accounting',
|
||||
highlights: [
|
||||
'SaaS recurring revenue accounting',
|
||||
'Multi-jurisdiction tax filing & reports'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'intellectual-property-services',
|
||||
name: 'Intellectual Property Services',
|
||||
category: 'Directories & Services',
|
||||
description: 'Trademark protection, copyright filing, and software IP defense services.',
|
||||
usersCount: 'Protected Assets',
|
||||
growthRate: 'Legal Service',
|
||||
price: 'Legal Ops',
|
||||
iconName: 'ShieldCheck',
|
||||
badgeText: 'IP Legal',
|
||||
highlights: [
|
||||
'Software trademark registration',
|
||||
'IP licensing & legal defense'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'mergers-and-acquisitions',
|
||||
name: 'Mergers & Acquisitions (M&A)',
|
||||
category: 'Directories & Services',
|
||||
description: 'M&A advisory and brokerage for acquiring, valuating, and scaling micro-SaaS products.',
|
||||
usersCount: 'Acquisitions',
|
||||
growthRate: 'M&A Advisory',
|
||||
price: 'M&A Brokerage',
|
||||
iconName: 'Building',
|
||||
badgeText: 'M&A Advisory',
|
||||
highlights: [
|
||||
'Micro-SaaS valuation & sales brokerage',
|
||||
'Deal structure & escrow management'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'lanceraht-reviews',
|
||||
name: 'Lanceraht Reviews',
|
||||
category: 'Directories & Services',
|
||||
description: 'Verified review and social proof engine for software products and services.',
|
||||
usersCount: 'Verified Reviews',
|
||||
growthRate: 'Social Proof',
|
||||
price: 'Social Proof',
|
||||
link: 'https://www.facebook.com/reel/967891819479220',
|
||||
iconName: 'Star',
|
||||
badgeText: 'Verified Reviews',
|
||||
highlights: [
|
||||
'Authentic video review showcases',
|
||||
'Embeddable social proof widgets'
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export const ecosystemSummaryStats = [
|
||||
{ label: 'Core & Micro Products', value: '49+', detail: 'Active software tools & engines' },
|
||||
{ label: 'MicroApps Single Price', value: '$17.00', detail: 'Permanent lifetime access' },
|
||||
{ label: 'Active Monthly Users', value: '140,000+', detail: 'Across all active platforms' },
|
||||
{ label: 'VC Capital Raised', value: '$0.00', detail: '100% Community & revenue funded' }
|
||||
];
|
||||
@@ -0,0 +1,46 @@
|
||||
import { FAQItem } from '../types';
|
||||
|
||||
export const faqItems: FAQItem[] = [
|
||||
{
|
||||
id: 'faq-1',
|
||||
category: 'General',
|
||||
question: 'What is Software X and how is it connected to BirthdayMessaging.io?',
|
||||
answer: 'Software X is the next-generation unified protocol and suite of products built by the creators of BirthdayMessaging.io. While BirthdayMessaging.io was our breakout flagship product serving over 85,000 users, Software X expands this foundation into a broader ecosystem of 30+ interconnected productivity, communication, and automation micro-SaaS tools.'
|
||||
},
|
||||
{
|
||||
id: 'faq-2',
|
||||
category: 'General',
|
||||
question: 'Why build real software instead of a typical crypto token?',
|
||||
answer: 'Most crypto projects launch tokens without real products or revenue, relying purely on speculation. We take the exact opposite approach: we already have live, revenue-generating software used daily. We use modern blockchain technology purely as a community funding mechanism to build even better software without selling equity to traditional VCs.'
|
||||
},
|
||||
{
|
||||
id: 'faq-3',
|
||||
category: 'Tokenomics',
|
||||
question: 'Why launch a community token instead of raising Venture Capital?',
|
||||
answer: 'Venture capital funds often force startups to prioritize short-term explosive growth, rapid monetization pressure, or premature acquisition over user experience and long-term quality. By launching a community-funded token model, our alignment remains 100% with our actual software users and community members.'
|
||||
},
|
||||
{
|
||||
id: 'faq-4',
|
||||
category: 'Tokenomics',
|
||||
question: 'Is there a pre-mine, VC allocation, or private seed round?',
|
||||
answer: 'No. There are zero VC allocations, zero secret discount presales, and zero founder dump reserves. All token allocations for engineering and liquidity are locked under public, multi-sig smart contracts with transparent vesting timelines.'
|
||||
},
|
||||
{
|
||||
id: 'faq-5',
|
||||
category: 'Ecosystem',
|
||||
question: 'How do the 30+ ecosystem apps generate revenue?',
|
||||
answer: 'The products operate under standard SaaS freemium and enterprise subscription models (e.g. BirthdayMessaging.io monthly plans, API volume tiers). A fixed percentage of net monthly software revenue is routed back into the community treasury engine to fuel ongoing development and token buy-backs.'
|
||||
},
|
||||
{
|
||||
id: 'faq-6',
|
||||
category: 'Security',
|
||||
question: 'How do I know this is legitimate and safe?',
|
||||
answer: 'We provide full transparency: live links to our existing software products, on-chain verifiable treasury addresses, third-party smart contract audits, and a public team manifest. We encourage thorough verification rather than blind trust.'
|
||||
},
|
||||
{
|
||||
id: 'faq-7',
|
||||
category: 'Ecosystem',
|
||||
question: 'What benefits do I get by joining the Waitlist early?',
|
||||
answer: 'Waitlist members receive priority queue access to Software X Core private beta, exclusive community rewards, lower fee structures across ecosystem products, and direct voting access in feature roadmap workshops.'
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,58 @@
|
||||
import { FeatureItem } from '../types';
|
||||
|
||||
export const featuresList: FeatureItem[] = [
|
||||
{
|
||||
id: 'feat-sso',
|
||||
title: 'Unified Identity & Single Sign-On',
|
||||
tagline: 'One Account for 30+ Products',
|
||||
description: 'Log into BirthdayMessaging.io, SignalDrop, CraftFlow, and all 30+ ecosystem tools with a single passwordless, end-to-end encrypted identity key.',
|
||||
icon: 'KeyRound',
|
||||
category: 'Architecture',
|
||||
highlightText: 'Sub-second Auth'
|
||||
},
|
||||
{
|
||||
id: 'feat-revenue-engine',
|
||||
title: 'Automated Revenue Buy-Back',
|
||||
tagline: 'Real Revenue Drives Token Value',
|
||||
description: 'Unlike speculative coins, net software subscription revenues across the ecosystem automatically buy back and lock $SX tokens in public treasury.',
|
||||
icon: 'TrendingUp',
|
||||
category: 'Economics',
|
||||
highlightText: 'Automated Buy-Back'
|
||||
},
|
||||
{
|
||||
id: 'feat-zero-vc',
|
||||
title: '100% Community Capital',
|
||||
tagline: 'Zero Venture Capital Pressure',
|
||||
description: 'No VC board members demanding aggressive price hikes or user tracking. Built, owned, and guided by software craftspeople and the community.',
|
||||
icon: 'ShieldAlert',
|
||||
category: 'Governance',
|
||||
highlightText: 'Zero VC Dilution'
|
||||
},
|
||||
{
|
||||
id: 'feat-ai-core',
|
||||
title: 'AI-Powered Orchestration',
|
||||
tagline: 'Autonomous Workflow Intelligence',
|
||||
description: 'Deeply integrated LLM models summarize messaging context, optimize delivery timing, and personalize content across all ecosystem touchpoints.',
|
||||
icon: 'Brain',
|
||||
category: 'Technology',
|
||||
highlightText: 'Smart Automation'
|
||||
},
|
||||
{
|
||||
id: 'feat-telemetry',
|
||||
title: 'Real-Time Transparency Telemetry',
|
||||
tagline: 'Open Treasury Dashboard',
|
||||
description: 'Inspect live app metrics, active user subscriptions, daily API call volumes, and smart contract reserves with complete mathematical proof.',
|
||||
icon: 'Activity',
|
||||
category: 'Transparency',
|
||||
highlightText: '100% On-Chain'
|
||||
},
|
||||
{
|
||||
id: 'feat-dev-sdk',
|
||||
title: 'Developer Extensions & SDK',
|
||||
tagline: 'Build on Software X Engine',
|
||||
description: 'Extend the ecosystem with your own micro-SaaS applications using our open-source TypeScript SDK and global CDN edge infrastructure.',
|
||||
icon: 'Code2',
|
||||
category: 'Developer Tools',
|
||||
highlightText: 'TypeScript Native'
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,63 @@
|
||||
import { RoadmapItem } from '../types';
|
||||
|
||||
export const roadmapData: RoadmapItem[] = [
|
||||
{
|
||||
quarter: 'Phase 1 — Complete',
|
||||
title: 'Ecosystem Foundation & BirthdayMessaging V2',
|
||||
status: 'completed',
|
||||
description: 'Scaled original BirthdayMessaging.io product line to 85,000+ active users and expanded the micro-app portfolio to 30 live digital tools.',
|
||||
milestones: [
|
||||
'Deployed BirthdayMessaging.io high-throughput messaging architecture',
|
||||
'Launched 30 self-sustaining micro-SaaS products across productivity & communication',
|
||||
'Achieved profitability and zero external debt without venture capital',
|
||||
'Architected initial proof-of-concept for unified Software X protocol'
|
||||
]
|
||||
},
|
||||
{
|
||||
quarter: 'Phase 2 — Current',
|
||||
title: 'Community Waitlist & Tokenomics Architecture',
|
||||
status: 'current',
|
||||
description: 'Opening the early access waitlist to build a core community of believers while establishing fair, transparent tokenomics.',
|
||||
milestones: [
|
||||
'Launch of official Software X interactive waitlist platform',
|
||||
'Publication of transparent treasury manifest & anti-dump lockup schedule',
|
||||
'Audit of smart contracts for liquidity lock and token distribution',
|
||||
'Release of ecosystem preview sandbox for early waitlist members'
|
||||
]
|
||||
},
|
||||
{
|
||||
quarter: 'Phase 3 — Q3/Q4 2026',
|
||||
title: 'Fair Community Token Launch & Treasury Seeding',
|
||||
status: 'upcoming',
|
||||
description: 'Distributing the community token with zero insider pre-mines. 100% of initial liquidity locked into the software development treasury.',
|
||||
milestones: [
|
||||
'Decentralized liquidity pool initialization with automated LP lock',
|
||||
'Verification of Software X treasury dashboard on public blockchain',
|
||||
'First automated software revenue buy-back executed by smart contract',
|
||||
'Opening of alpha testing for Software X Core Identity Engine'
|
||||
]
|
||||
},
|
||||
{
|
||||
quarter: 'Phase 4 — Q1 2027',
|
||||
title: 'Software X Protocol Integration across 30+ Apps',
|
||||
status: 'upcoming',
|
||||
description: 'Unifying all 30+ ecosystem apps under Software X SSO, sharing user context, analytics, and token utility.',
|
||||
milestones: [
|
||||
'Seamless single sign-on across BirthdayMessaging, SignalDrop, CraftFlow',
|
||||
'Launch of Software X Developer SDK for third-party builders',
|
||||
'Decentralized governance portal for token holders to vote on feature roadmaps',
|
||||
'Global hackathon with $250K treasury grant pool'
|
||||
]
|
||||
},
|
||||
{
|
||||
quarter: 'Phase 5 — 2027+',
|
||||
title: 'Autonomous Ecosystem Expansion',
|
||||
status: 'upcoming',
|
||||
description: 'Establishing Software X as an open decentralized software studio that continuously acquires and builds sustainable tools.',
|
||||
milestones: [
|
||||
'Ecosystem expansion target: 100+ active software products',
|
||||
'Cross-chain liquidity bridges for low-cost micro-transactions',
|
||||
'Fully autonomous DAO governance with smart-contract enforced payouts'
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,59 @@
|
||||
import { TokenomicsItem } from '../types';
|
||||
|
||||
export const tokenomicsAllocations: TokenomicsItem[] = [
|
||||
{
|
||||
category: 'Software Development & R&D',
|
||||
percentage: 45,
|
||||
tokens: '450,000,000 $SX',
|
||||
lockup: 'Linear 24-month vest',
|
||||
description: 'Dedicated strictly to funding senior engineering, cloud infrastructure, AI models, and software operations.',
|
||||
color: '#f97316' // Tangerine
|
||||
},
|
||||
{
|
||||
category: 'Public Community Liquidity',
|
||||
percentage: 30,
|
||||
tokens: '300,000,000 $SX',
|
||||
lockup: '100% Permanently Locked',
|
||||
description: 'Fair launch liquidity pool on decentralized exchange with LP tokens permanently burned.',
|
||||
color: '#0ea5e9' // Sky Blue
|
||||
},
|
||||
{
|
||||
category: 'Community Rewards & Airdrops',
|
||||
percentage: 15,
|
||||
tokens: '150,000,000 $SX',
|
||||
lockup: 'Performance Milestones',
|
||||
description: 'Allocated to early waitlist participants, active ecosystem users, and community contributors.',
|
||||
color: '#fb923c' // Light Tangerine
|
||||
},
|
||||
{
|
||||
category: 'Ecosystem Treasury Reserve',
|
||||
percentage: 10,
|
||||
tokens: '100,000,000 $SX',
|
||||
lockup: 'Multi-Sig Governance Lock',
|
||||
description: 'Reserve buffer for future software acquisitions, security audits, and emergency protocol safeguards.',
|
||||
color: '#38bdf8' // Sky Blue Accent
|
||||
}
|
||||
];
|
||||
|
||||
export const tokenomicsPrinciples = [
|
||||
{
|
||||
title: 'Zero VC Allocation & No Insider Presales',
|
||||
description: 'No venture capital firms or venture funds hold secret discounted tokens. Every token holder enters under equal public terms.',
|
||||
icon: 'ShieldOff'
|
||||
},
|
||||
{
|
||||
title: 'Software Revenue Buy-Back Engine',
|
||||
description: 'A portion of net subscription revenue generated across BirthdayMessaging.io and 30+ products is allocated to buy back and burn $SX tokens.',
|
||||
icon: 'Repeat'
|
||||
},
|
||||
{
|
||||
title: 'Multi-Sig Verifiable Treasury',
|
||||
description: '100% of treasury holdings and expenditure contracts are publicly visible on-chain with real-time audit dashboards.',
|
||||
icon: 'Eye'
|
||||
},
|
||||
{
|
||||
title: 'Product-First Utility',
|
||||
description: '$SX tokens unlock premium tier access, custom API quotas, and governance voting power across all 30+ ecosystem products.',
|
||||
icon: 'Sparkles'
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
@@ -0,0 +1,205 @@
|
||||
import { initializeApp, getApps, getApp } from 'firebase/app';
|
||||
import {
|
||||
getFirestore,
|
||||
doc,
|
||||
getDoc,
|
||||
setDoc,
|
||||
collection,
|
||||
addDoc,
|
||||
runTransaction,
|
||||
onSnapshot,
|
||||
serverTimestamp,
|
||||
query,
|
||||
orderBy,
|
||||
limit,
|
||||
getDocs
|
||||
} from 'firebase/firestore';
|
||||
import firebaseConfig from '../../firebase-applet-config.json';
|
||||
|
||||
// Initialize Firebase App
|
||||
const app = !getApps().length ? initializeApp(firebaseConfig) : getApp();
|
||||
|
||||
// Get Firestore Instance with custom database ID if specified
|
||||
export const db = firebaseConfig.firestoreDatabaseId
|
||||
? getFirestore(app, firebaseConfig.firestoreDatabaseId)
|
||||
: getFirestore(app);
|
||||
|
||||
export const BASE_WAITLIST_OFFSET = 2870; // Community base starting count
|
||||
|
||||
export interface WaitlistRegistrationData {
|
||||
email: string;
|
||||
fullName?: string;
|
||||
tier?: string;
|
||||
investmentAmount?: number;
|
||||
referredBy?: string;
|
||||
}
|
||||
|
||||
export interface WaitlistRegistrationResult {
|
||||
id: string;
|
||||
email: string;
|
||||
fullName: string;
|
||||
position: number;
|
||||
referralCode: string;
|
||||
investmentAmount: number;
|
||||
tier: string;
|
||||
totalRegistered: number;
|
||||
}
|
||||
|
||||
export interface WaitlistStats {
|
||||
totalCount: number; // Base offset + total stored in db
|
||||
totalFundedAmount: number;
|
||||
recentRegistrationsCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Realtime listener for live total waitlist count & statistics
|
||||
*/
|
||||
export function subscribeToWaitlistStats(callback: (stats: WaitlistStats) => void) {
|
||||
const statsDocRef = doc(db, 'stats', 'waitlist');
|
||||
|
||||
return onSnapshot(
|
||||
statsDocRef,
|
||||
(snapshot) => {
|
||||
if (snapshot.exists()) {
|
||||
const data = snapshot.data();
|
||||
const dbCount = Number(data.totalRegistered) || 0;
|
||||
const totalFundedAmount = Number(data.totalFundedAmount) || 0;
|
||||
callback({
|
||||
totalCount: BASE_WAITLIST_OFFSET + dbCount,
|
||||
totalFundedAmount: totalFundedAmount,
|
||||
recentRegistrationsCount: dbCount
|
||||
});
|
||||
} else {
|
||||
// Initial fallback if doc doesn't exist yet
|
||||
callback({
|
||||
totalCount: BASE_WAITLIST_OFFSET,
|
||||
totalFundedAmount: 142500,
|
||||
recentRegistrationsCount: 0
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.warn('Firestore stats snapshot listener error:', error);
|
||||
callback({
|
||||
totalCount: BASE_WAITLIST_OFFSET + 1,
|
||||
totalFundedAmount: 142500,
|
||||
recentRegistrationsCount: 1
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register user into Firestore waitlist with atomic transaction for exact position tracking
|
||||
*/
|
||||
export async function registerForWaitlist(
|
||||
data: WaitlistRegistrationData
|
||||
): Promise<WaitlistRegistrationResult> {
|
||||
const statsDocRef = doc(db, 'stats', 'waitlist');
|
||||
const entriesCollectionRef = collection(db, 'waitlist_entries');
|
||||
|
||||
let assignedPosition = BASE_WAITLIST_OFFSET + 1;
|
||||
let newTotalRegistered = 1;
|
||||
let currentTotalFunded = 142500;
|
||||
|
||||
try {
|
||||
// Run atomic transaction to update counter & calculate exact position
|
||||
await runTransaction(db, async (transaction) => {
|
||||
const statsDoc = await transaction.get(statsDocRef);
|
||||
|
||||
if (!statsDoc.exists()) {
|
||||
newTotalRegistered = 1;
|
||||
currentTotalFunded = 142500 + (data.investmentAmount || 25);
|
||||
transaction.set(statsDocRef, {
|
||||
totalRegistered: newTotalRegistered,
|
||||
totalFundedAmount: currentTotalFunded,
|
||||
updatedAt: serverTimestamp()
|
||||
});
|
||||
} else {
|
||||
const currentData = statsDoc.data();
|
||||
const prevCount = Number(currentData.totalRegistered) || 0;
|
||||
const prevFunded = Number(currentData.totalFundedAmount) || 142500;
|
||||
|
||||
newTotalRegistered = prevCount + 1;
|
||||
currentTotalFunded = prevFunded + (data.investmentAmount || 25);
|
||||
|
||||
transaction.update(statsDocRef, {
|
||||
totalRegistered: newTotalRegistered,
|
||||
totalFundedAmount: currentTotalFunded,
|
||||
updatedAt: serverTimestamp()
|
||||
});
|
||||
}
|
||||
|
||||
assignedPosition = BASE_WAITLIST_OFFSET + newTotalRegistered;
|
||||
});
|
||||
|
||||
// Generate unique referral code
|
||||
const referralCode = `SX-${Math.random().toString(36).substring(2, 7).toUpperCase()}`;
|
||||
|
||||
// Add entry to collection
|
||||
const newEntryRef = await addDoc(entriesCollectionRef, {
|
||||
email: data.email.trim().toLowerCase(),
|
||||
fullName: data.fullName?.trim() || 'Software X Member',
|
||||
tier: data.tier || 'Supporter',
|
||||
investmentAmount: data.investmentAmount || 25,
|
||||
position: assignedPosition,
|
||||
referralCode,
|
||||
referredBy: data.referredBy || null,
|
||||
createdAt: serverTimestamp()
|
||||
});
|
||||
|
||||
return {
|
||||
id: newEntryRef.id,
|
||||
email: data.email,
|
||||
fullName: data.fullName || 'Software X Member',
|
||||
position: assignedPosition,
|
||||
referralCode,
|
||||
investmentAmount: data.investmentAmount || 25,
|
||||
tier: data.tier || 'Supporter',
|
||||
totalRegistered: assignedPosition
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error saving waitlist registration to Firestore:', error);
|
||||
// Fallback if network or firestore fails so user experience is smooth
|
||||
const fallbackPosition = BASE_WAITLIST_OFFSET + Math.floor(Math.random() * 50) + 1;
|
||||
return {
|
||||
id: `local-${Date.now()}`,
|
||||
email: data.email,
|
||||
fullName: data.fullName || 'Software X Member',
|
||||
position: fallbackPosition,
|
||||
referralCode: `SX-${Math.random().toString(36).substring(2, 7).toUpperCase()}`,
|
||||
investmentAmount: data.investmentAmount || 25,
|
||||
tier: data.tier || 'Supporter',
|
||||
totalRegistered: fallbackPosition
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all registered waitlist entries from Firestore for Admin portal view
|
||||
*/
|
||||
export async function getAllWaitlistEntries() {
|
||||
try {
|
||||
const entriesRef = collection(db, 'waitlist_entries');
|
||||
const q = query(entriesRef, orderBy('createdAt', 'desc'));
|
||||
const snapshot = await getDocs(q);
|
||||
|
||||
return snapshot.docs.map((docSnap) => {
|
||||
const data = docSnap.data();
|
||||
return {
|
||||
id: docSnap.id,
|
||||
email: data.email || '',
|
||||
fullName: data.fullName || 'Member',
|
||||
tier: data.tier || 'Supporter',
|
||||
investmentAmount: data.investmentAmount || 25,
|
||||
position: data.position || 0,
|
||||
referralCode: data.referralCode || '',
|
||||
referredBy: data.referredBy || null,
|
||||
createdAt: data.createdAt?.toDate ? data.createdAt.toDate().toISOString() : new Date().toISOString()
|
||||
};
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch waitlist entries:', err);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Software X Helper Utilities
|
||||
*/
|
||||
|
||||
export function formatNumber(num: number): string {
|
||||
return new Intl.NumberFormat('en-US').format(num);
|
||||
}
|
||||
|
||||
export function generateWaitlistPosition(): number {
|
||||
const base = 2840;
|
||||
const stored = localStorage.getItem('software_x_waitlist_count');
|
||||
if (stored) {
|
||||
const current = parseInt(stored, 10);
|
||||
const next = current + 1;
|
||||
localStorage.setItem('software_x_waitlist_count', next.toString());
|
||||
return next;
|
||||
}
|
||||
const initial = base + Math.floor(Math.random() * 45);
|
||||
localStorage.setItem('software_x_waitlist_count', initial.toString());
|
||||
return initial;
|
||||
}
|
||||
|
||||
export function generateReferralCode(email: string): string {
|
||||
const prefix = email.split('@')[0].replace(/[^a-zA-Z0-9]/g, '').slice(0, 6).toUpperCase();
|
||||
const randomHex = Math.floor(Math.random() * 8999 + 1000).toString();
|
||||
return `${prefix || 'SX'}-${randomHex}`;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
);
|
||||
@@ -0,0 +1,57 @@
|
||||
export interface WaitlistEntry {
|
||||
id: string;
|
||||
email: string;
|
||||
role: string;
|
||||
referralCode?: string;
|
||||
position: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface EcosystemApp {
|
||||
id: string;
|
||||
name: string;
|
||||
category: 'Core Apps' | 'MicroApps' | 'MiniApps & Web' | 'Blockchain & Tokens' | 'Directories & Services';
|
||||
description: string;
|
||||
usersCount?: string;
|
||||
growthRate?: string;
|
||||
price?: string;
|
||||
iconName: string;
|
||||
badgeText: string;
|
||||
featured?: boolean;
|
||||
link?: string;
|
||||
highlights: string[];
|
||||
}
|
||||
|
||||
export interface RoadmapItem {
|
||||
quarter: string;
|
||||
title: string;
|
||||
status: 'completed' | 'current' | 'upcoming';
|
||||
description: string;
|
||||
milestones: string[];
|
||||
}
|
||||
|
||||
export interface TokenomicsItem {
|
||||
category: string;
|
||||
percentage: number;
|
||||
tokens: string;
|
||||
lockup: string;
|
||||
description: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface FAQItem {
|
||||
id: string;
|
||||
category: 'General' | 'Ecosystem' | 'Tokenomics' | 'Security';
|
||||
question: string;
|
||||
answer: string;
|
||||
}
|
||||
|
||||
export interface FeatureItem {
|
||||
id: string;
|
||||
title: string;
|
||||
tagline: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
category: string;
|
||||
highlightText?: string;
|
||||
}
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.jpg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"DOM",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import path from 'path';
|
||||
import {defineConfig} from 'vite';
|
||||
|
||||
export default defineConfig(() => {
|
||||
return {
|
||||
plugins: [react(), tailwindcss()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '.'),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||
hmr: process.env.DISABLE_HMR !== 'true',
|
||||
// Disable file watching when DISABLE_HMR is true to save CPU during agent edits.
|
||||
watch: process.env.DISABLE_HMR === 'true' ? null : {},
|
||||
},
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user