Initial commit

This commit is contained in:
User
2026-08-14 14:17:48 +02:00
commit 52dc765da4
46 changed files with 6318 additions and 0 deletions
+9
View File
@@ -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"
+8
View File
@@ -0,0 +1,8 @@
node_modules/
build/
dist/
coverage/
.DS_Store
*.log
.env*
!.env.example
+20
View File
@@ -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`
+807
View File
@@ -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=="],
}
}
+12
View File
@@ -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": ""
}
+25
View File
@@ -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" }
}
}
}
}
+14
View File
@@ -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
View File
@@ -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>
+6
View File
@@ -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"]
}
+38
View File
@@ -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
View File
@@ -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

+178
View File
@@ -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>
);
};
+213
View File
@@ -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>
);
};
+118
View File
@@ -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>
);
};
+184
View File
@@ -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: &lt;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>
);
};
+257
View File
@@ -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>
);
};
+146
View File
@@ -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>
);
};
+128
View File
@@ -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>
);
};
+135
View File
@@ -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>
);
};
+138
View File
@@ -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>
);
};
+115
View File
@@ -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>
);
};
+296
View File
@@ -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>
);
};
+64
View File
@@ -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>
);
};
+64
View File
@@ -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>
);
};
+55
View File
@@ -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>
);
};
+37
View File
@@ -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>
);
};
+51
View File
@@ -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>
);
};
+815
View File
@@ -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' }
];
+46
View File
@@ -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.'
}
];
+58
View File
@@ -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'
}
];
+63
View File
@@ -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'
]
}
];
+59
View File
@@ -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'
}
];
+1
View File
@@ -0,0 +1 @@
@import "tailwindcss";
+205
View File
@@ -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 [];
}
}
+27
View File
@@ -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}`;
}
+10
View File
@@ -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>,
);
+57
View File
@@ -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;
}
+16
View File
@@ -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;
}
+26
View File
@@ -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
}
}
+22
View File
@@ -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 : {},
},
};
});