From 85e30eaa227e1cb8215006f3ff92bd598576da18 Mon Sep 17 00:00:00 2001 From: Beast Date: Mon, 30 Mar 2026 20:01:14 +0800 Subject: [PATCH 01/41] wip: base redesign porting --- website/bun.lock | 52 +++-- website/package.json | 16 +- website/src/constants/footer-navigations.ts | 69 +++++-- website/src/i18n/en-US.json | 39 ++++ website/src/pages/v2/index.astro | 30 +++ website/src/v2/assets/brand/logo-long.svg | 6 + website/src/v2/components/layout/Layout.astro | 160 ++++++++++++++ .../v2/components/layout/footer/Footer.astro | 90 ++++++++ .../v2/components/layout/navbar/Navbar.astro | 187 +++++++++++++++++ website/src/v2/components/ui/Button.astro | 98 +++++++++ website/src/v2/components/ui/Eyebrow.astro | 41 ++++ .../src/v2/components/ui/FlareDivider.astro | 9 + website/src/v2/components/ui/PageGlow.astro | 21 ++ .../src/v2/components/ui/SectionHeader.astro | 26 +++ website/src/v2/components/ui/TextLink.astro | 22 ++ .../src/v2/constants/footer-navigations.ts | 83 ++++++++ website/src/v2/constants/site-navigations.ts | 8 + website/src/v2/scripts/home/ascii.ts | 44 ++++ website/src/v2/scripts/home/base-math.ts | 35 ++++ website/src/v2/scripts/home/blog-section.ts | 33 +++ .../src/v2/scripts/home/community-section.ts | 30 +++ .../src/v2/scripts/home/ecosystem-section.ts | 195 ++++++++++++++++++ website/src/v2/scripts/home/glitch.ts | 34 +++ website/src/v2/scripts/home/hero.ts | 50 +++++ website/src/v2/scripts/home/loader.ts | 71 +++++++ website/src/v2/scripts/home/mouse.ts | 32 +++ .../src/v2/scripts/home/problem-section.ts | 13 ++ .../src/v2/scripts/home/solution-section.ts | 59 ++++++ website/src/v2/scripts/home/ticker.ts | 28 +++ website/src/v2/scripts/shared/base.ts | 106 ++++++++++ .../src/v2/scripts/shared/get-wallet-link.ts | 13 ++ website/src/v2/styles/breakpoints.css | 7 + website/src/v2/styles/colors.css | 49 +++++ website/src/v2/styles/fonts.css | 93 +++++++++ website/src/v2/styles/global.css | 113 ++++++++++ website/src/v2/styles/size.css | 12 ++ 36 files changed, 1929 insertions(+), 45 deletions(-) create mode 100644 website/src/pages/v2/index.astro create mode 100644 website/src/v2/assets/brand/logo-long.svg create mode 100644 website/src/v2/components/layout/Layout.astro create mode 100644 website/src/v2/components/layout/footer/Footer.astro create mode 100644 website/src/v2/components/layout/navbar/Navbar.astro create mode 100644 website/src/v2/components/ui/Button.astro create mode 100644 website/src/v2/components/ui/Eyebrow.astro create mode 100644 website/src/v2/components/ui/FlareDivider.astro create mode 100644 website/src/v2/components/ui/PageGlow.astro create mode 100644 website/src/v2/components/ui/SectionHeader.astro create mode 100644 website/src/v2/components/ui/TextLink.astro create mode 100644 website/src/v2/constants/footer-navigations.ts create mode 100644 website/src/v2/constants/site-navigations.ts create mode 100644 website/src/v2/scripts/home/ascii.ts create mode 100644 website/src/v2/scripts/home/base-math.ts create mode 100644 website/src/v2/scripts/home/blog-section.ts create mode 100644 website/src/v2/scripts/home/community-section.ts create mode 100644 website/src/v2/scripts/home/ecosystem-section.ts create mode 100644 website/src/v2/scripts/home/glitch.ts create mode 100644 website/src/v2/scripts/home/hero.ts create mode 100644 website/src/v2/scripts/home/loader.ts create mode 100644 website/src/v2/scripts/home/mouse.ts create mode 100644 website/src/v2/scripts/home/problem-section.ts create mode 100644 website/src/v2/scripts/home/solution-section.ts create mode 100644 website/src/v2/scripts/home/ticker.ts create mode 100644 website/src/v2/scripts/shared/base.ts create mode 100644 website/src/v2/scripts/shared/get-wallet-link.ts create mode 100644 website/src/v2/styles/breakpoints.css create mode 100644 website/src/v2/styles/colors.css create mode 100644 website/src/v2/styles/fonts.css create mode 100644 website/src/v2/styles/global.css create mode 100644 website/src/v2/styles/size.css diff --git a/website/bun.lock b/website/bun.lock index 42b949f..781797a 100644 --- a/website/bun.lock +++ b/website/bun.lock @@ -5,19 +5,15 @@ "": { "name": "quantus-website", "dependencies": { - "@astrojs/mdx": "5.0.2", - "@astrojs/react": "5.0.1", - "@astrojs/sitemap": "3.7.1", + "@fontsource/geist": "^5.2.8", + "@fontsource/geist-mono": "^5.2.7", "@fontsource/ibm-plex-mono": "^5.2.7", "@fontsource/ibm-plex-sans": "^5.2.8", "@fontsource/inter": "^5.2.6", "@fontsource/prompt": "^5.2.6", "@lucide/astro": "^0.541.0", - "@playform/compress": "^0.2.1", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", - "@tailwindcss/typography": "^0.5.19", - "@tailwindcss/vite": "^4.1.12", "@tanstack/react-table": "^8.21.3", "astro": "6.0.7", "astro-seo": "^0.8.4", @@ -30,10 +26,15 @@ "react": "^19.2.0", "react-dom": "^19.2.0", "tailwind-merge": "^3.3.1", - "tailwindcss": "^4.1.12", "usehooks-ts": "^3.1.1", }, "devDependencies": { + "@astrojs/mdx": "5.0.2", + "@astrojs/react": "5.0.1", + "@astrojs/sitemap": "3.7.1", + "@playform/compress": "^0.2.1", + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.1.12", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", "prettier": "^3.6.2", @@ -41,6 +42,7 @@ "prettier-plugin-tailwindcss": "^0.6.14", "puppeteer-core": "^24.38.0", "schema-dts": "^1.1.5", + "tailwindcss": "^4.1.12", "unlighthouse": "^0.17.4", }, }, @@ -194,6 +196,10 @@ "@floating-ui/vue": ["@floating-ui/vue@1.1.11", "", { "dependencies": { "@floating-ui/dom": "^1.7.6", "@floating-ui/utils": "^0.2.11", "vue-demi": ">=0.13.0" } }, "sha512-HzHKCNVxnGS35r9fCHBc3+uCnjw9IWIlCPL683cGgM9Kgj2BiAl8x1mS7vtvP6F9S/e/q4O6MApwSHj8hNLGfw=="], + "@fontsource/geist": ["@fontsource/geist@5.2.8", "", {}, "sha512-pI54klK6vz8fVpAVyV+iODGLEzw73cs1XJqV9PIXgW8MYMmBcwK6lKKaWqJrNHwEx8ppz9cuhussb6arXQ/PVQ=="], + + "@fontsource/geist-mono": ["@fontsource/geist-mono@5.2.7", "", {}, "sha512-xVPVFISJg/K0VVd+aQN0Y7X/sw9hUcJPyDWFJ5GpyU3bHELhoRsJkPSRSHXW32mOi0xZCUQDOaPj1sqIFJ1FGg=="], + "@fontsource/ibm-plex-mono": ["@fontsource/ibm-plex-mono@5.2.7", "", {}, "sha512-MKAb8qV+CaiMQn2B0dIi1OV3565NYzp3WN5b4oT6LTkk+F0jR6j0ZN+5BKJiIhffDC3rtBULsYZE65+0018z9w=="], "@fontsource/ibm-plex-sans": ["@fontsource/ibm-plex-sans@5.2.8", "", {}, "sha512-eztSXjDhPhcpxNIiGTgMebdLP9qS4rWkysuE1V7c+DjOR0qiezaiDaTwQE7bTnG5HxAY/8M43XKDvs3cYq6ZYQ=="], @@ -1102,7 +1108,7 @@ "emmet": ["emmet@2.4.11", "", { "dependencies": { "@emmetio/abbreviation": "^2.3.3", "@emmetio/css-abbreviation": "^2.1.8" } }, "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ=="], - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], @@ -1994,7 +2000,7 @@ "streamx": ["streamx@2.23.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg=="], - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], @@ -2368,12 +2374,12 @@ "@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "astro/@astrojs/compiler": ["@astrojs/compiler@3.0.1", "", {}, "sha512-z97oYbdebO5aoWzuJ/8q5hLK232+17KcLZ7cJ8BCWk6+qNzVxn/gftC0KzMBUTD8WAaBkPpNSQK6PXLnNrZ0CA=="], - "boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - "boxen/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "cacheable-request/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], @@ -2386,6 +2392,8 @@ "clean-css/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], @@ -2454,8 +2462,6 @@ "speedline-core/@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="], - "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], "svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], @@ -2482,14 +2488,14 @@ "vscode-json-languageservice/jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], - "widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - "wrap-ansi/string-width": ["string-width@8.2.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw=="], "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], "yaml-language-server/yaml": ["yaml@2.7.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ=="], + "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], "zod-to-ts/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -2574,10 +2580,14 @@ "@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="], - "boxen/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "chrome-launcher/is-wsl/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -2612,8 +2622,6 @@ "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - "string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "svgo/css-tree/mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], "unifont/css-tree/mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], @@ -2624,7 +2632,9 @@ "vaul-vue/@vueuse/core/@vueuse/shared": ["@vueuse/shared@10.11.1", "", { "dependencies": { "vue-demi": ">=0.14.8" } }, "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA=="], - "widest-line/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "@astrojs/check/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -2705,5 +2715,9 @@ "@playform/compress/astro/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], "@playform/compress/astro/shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], + + "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], } } diff --git a/website/package.json b/website/package.json index f5c3c04..9dbbd5a 100644 --- a/website/package.json +++ b/website/package.json @@ -13,19 +13,15 @@ "format:write": "prettier --write ." }, "dependencies": { - "@astrojs/mdx": "5.0.2", - "@astrojs/react": "5.0.1", - "@astrojs/sitemap": "3.7.1", "@fontsource/ibm-plex-mono": "^5.2.7", "@fontsource/ibm-plex-sans": "^5.2.8", + "@fontsource/geist": "^5.2.8", + "@fontsource/geist-mono": "^5.2.7", "@fontsource/inter": "^5.2.6", "@fontsource/prompt": "^5.2.6", "@lucide/astro": "^0.541.0", - "@playform/compress": "^0.2.1", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", - "@tailwindcss/typography": "^0.5.19", - "@tailwindcss/vite": "^4.1.12", "@tanstack/react-table": "^8.21.3", "astro": "6.0.7", "astro-seo": "^0.8.4", @@ -38,15 +34,21 @@ "react": "^19.2.0", "react-dom": "^19.2.0", "tailwind-merge": "^3.3.1", - "tailwindcss": "^4.1.12", "usehooks-ts": "^3.1.1" }, "devDependencies": { + "tailwindcss": "^4.1.12", + "@astrojs/mdx": "5.0.2", + "@astrojs/react": "5.0.1", + "@astrojs/sitemap": "3.7.1", + "@playform/compress": "^0.2.1", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", "prettier": "^3.6.2", "prettier-plugin-astro": "^0.14.1", "prettier-plugin-tailwindcss": "^0.6.14", + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.1.12", "puppeteer-core": "^24.38.0", "schema-dts": "^1.1.5", "unlighthouse": "^0.17.4" diff --git a/website/src/constants/footer-navigations.ts b/website/src/constants/footer-navigations.ts index f9f4f3c..9c8b788 100644 --- a/website/src/constants/footer-navigations.ts +++ b/website/src/constants/footer-navigations.ts @@ -10,43 +10,74 @@ interface Navigation { export const FOOTER_NAVIGATIONS: Navigation[] = [ { - label: "footer.navigation.resources.title", + label: "v2.footer.sections.protocol", children: [ { - href: "https://t.me/quantusnetwork", - label: "footer.navigation.resources.community", + label: "v2.footer.links.whitepaper", + href: "https://www.quantus.com/whitepaper/", target: "_blank", - rel: "noopener noreferrer", + rel: "noopener", }, - // { href: "/tutorials", label: "footer.navigation.resources.tutorials" }, + { label: "v2.footer.links.technology", href: "/technology" }, { - href: "https://github.com/Quantus-Network/chain", - label: "footer.navigation.resources.documentation", + label: "v2.footer.links.network", + href: "https://explorer.quantus.com/", + target: "_blank", + rel: "noopener", + }, + { label: "v2.footer.links.wallet", href: "/wallet" }, + { + label: "v2.footer.links.research", + href: "https://research.quantus.com/", target: "_blank", - rel: "noopener noreferrer", + rel: "noopener", }, { - href: "https://t.me/quantustechsupport", - label: "footer.navigation.resources.tech_support", + label: "v2.footer.links.documentation", + href: "https://github.com/Quantus-Network/chain", target: "_blank", - rel: "noopener noreferrer", + rel: "noopener", }, ], }, { - label: "footer.navigation.info.title", + label: "v2.footer.sections.community", children: [ - { href: "/about/", label: "footer.navigation.info.company" }, - { href: "/blog/", label: "footer.navigation.info.blog" }, - // { href: "/audits", label: "footer.navigation.info.audits" }, { - href: "/terms-and-privacy/", - label: "footer.navigation.info.terms", + label: "v2.footer.links.telegram", + href: "https://t.me/quantusnetwork", + target: "_blank", + rel: "noopener", }, { - href: "/terms-and-privacy/#privacy", - label: "footer.navigation.info.privacy", + label: "v2.footer.links.x", + href: "https://x.com/QuantusNetwork", + target: "_blank", + rel: "noopener", }, + { + label: "v2.footer.links.instagram", + href: "https://www.instagram.com/quantusnetwork/", + target: "_blank", + rel: "noopener", + }, + { + label: "v2.footer.links.youtube", + href: "https://www.youtube.com/@QuantusNetwork", + target: "_blank", + rel: "noopener", + }, + ], + }, + { + label: "v2.footer.sections.company", + children: [ + { label: "v2.footer.links.about", href: "/about" }, + { label: "v2.footer.links.blog", href: "/blog" }, + { label: "v2.footer.links.podcast", href: "/community" }, + { label: "v2.footer.links.contact", href: "/about#contact" }, + { label: "v2.footer.links.privacy", href: "/privacy-policy" }, + { label: "v2.footer.links.terms", href: "/terms" }, ], }, ] as const; diff --git a/website/src/i18n/en-US.json b/website/src/i18n/en-US.json index b049943..9ffe589 100644 --- a/website/src/i18n/en-US.json +++ b/website/src/i18n/en-US.json @@ -1,4 +1,43 @@ { + "v2": { + "navbar": { + "about": "About", + "technology": "Technology", + "wallet": "Wallet", + "community": "Community", + "quantum-risk-checker": "Q-Day Checker", + "quan": "Quan" + }, + "footer": { + "brand": "QUANTUS", + "copyright": "© {year} Quantus Network.", + "rights": "All rights reserved.", + "built_on": "BUILT ON BELL TESTNET", + "sections": { + "protocol": "Protocol", + "community": "Community", + "company": "Company" + }, + "links": { + "whitepaper": "Whitepaper", + "technology": "Technology", + "network": "Network", + "wallet": "Wallet", + "research": "Research", + "documentation": "Documentation", + "telegram": "Telegram", + "x": "X (Twitter)", + "instagram": "Instagram", + "youtube": "YouTube", + "about": "About", + "blog": "Blog", + "podcast": "QDay Podcast", + "contact": "Contact", + "privacy": "Privacy Policy", + "terms": "Terms of Service" + } + } + }, "home": { "meta": { "title": "Quantus Network - Quantum-Secure Layer 1 Blockchain", diff --git a/website/src/pages/v2/index.astro b/website/src/pages/v2/index.astro new file mode 100644 index 0000000..99b1ec6 --- /dev/null +++ b/website/src/pages/v2/index.astro @@ -0,0 +1,30 @@ +--- +import Layout from "@/v2/components/layout/Layout.astro"; +import { createTranslator, getLocaleFromUrl } from "@/utils/i18n"; +import { createMetadata } from "@/utils/create-metadata"; +import { JsonLdGraph } from "@/utils/build-json-ld"; +import { + androidAppJsonLd, + iosAppJsonLd, + organizationJsonLd, + websiteJsonLd, +} from "@/constants/default-jsonld"; + +const locale = getLocaleFromUrl(Astro.url.pathname); +const t = await createTranslator(locale); + +const metadata = createMetadata({ + title: t("home.meta.title"), + description: t("home.meta.description"), + pathname: Astro.url.pathname, +}); + +const jsonLd = JsonLdGraph({ + "@context": "https://schema.org", + "@graph": [websiteJsonLd, organizationJsonLd, iosAppJsonLd, androidAppJsonLd], +}); +--- + + + + diff --git a/website/src/v2/assets/brand/logo-long.svg b/website/src/v2/assets/brand/logo-long.svg new file mode 100644 index 0000000..5630e01 --- /dev/null +++ b/website/src/v2/assets/brand/logo-long.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/website/src/v2/components/layout/Layout.astro b/website/src/v2/components/layout/Layout.astro new file mode 100644 index 0000000..7d5e034 --- /dev/null +++ b/website/src/v2/components/layout/Layout.astro @@ -0,0 +1,160 @@ +--- +import "../../styles/global.css"; + +// Main fonts +import "@fontsource/geist/300.css"; +import "@fontsource/geist/400.css"; +import "@fontsource/geist/500.css"; +import "@fontsource/geist-mono/300.css"; +import "@fontsource/geist-mono/400.css"; +import "@fontsource/geist-mono/500.css"; + +// Whitepapers Fonts +import "@fontsource/ibm-plex-sans/400.css"; +import "@fontsource/ibm-plex-sans/400-italic.css"; +import "@fontsource/ibm-plex-sans/700.css"; +import "@fontsource/ibm-plex-mono/300.css"; +import "@fontsource/ibm-plex-mono/400.css"; +import "@fontsource/ibm-plex-mono/500.css"; +import "@fontsource/ibm-plex-mono/700.css"; + +import Navbar from "./navbar/Navbar.astro"; +import Footer from "./footer/Footer.astro"; + +import { SEO, type SEOProps } from "astro-seo"; +import type { WithContext, Graph, Thing } from "schema-dts"; +import { + DEFAULT_LOCALE, + getLocaleFromUrl, + getTextDirection, + getAlternateUrls, + createTranslator, +} from "@/utils/i18n"; +import { generateBreadcrumbs } from "@/utils/build-json-ld"; +import { SITE_NAVIGATIONS } from "@/v2/constants/site-navigations"; +import CookieConsent from "@/components/ui/CookieConsent.astro"; +import Toast from "@/components/ui/Toast.astro"; +import env from "@/config"; + +interface Props extends SEOProps { + jsonLd?: WithContext | Graph; +} + +const { jsonLd, ...metadata } = Astro.props; + +const currentLocale = getLocaleFromUrl(Astro.url.pathname); +const t = await createTranslator(currentLocale); +const textDirection = getTextDirection(currentLocale); + +// Fix canonical for default locale duplicate content +let canonical = metadata.canonical; +const currentPath = Astro.url.pathname; + +if ( + currentLocale === DEFAULT_LOCALE && + currentPath.startsWith(`/${DEFAULT_LOCALE}`) +) { + const rootPath = currentPath.replace(`/${DEFAULT_LOCALE}`, "") || "/"; + canonical = `${env.SITE_BASE_URL}${rootPath}`; +} + +const alternates = getAlternateUrls(currentPath); +const languageAlternates = Object.entries(alternates).map(([lang, path]) => ({ + href: `${env.SITE_BASE_URL}${path}`, + hrefLang: lang, +})); + +const breadcrumbs = generateBreadcrumbs({ + pathname: currentPath, + locale: currentLocale, + siteBaseUrl: env.SITE_BASE_URL, + t, + navigations: SITE_NAVIGATIONS as any, + title: metadata.title, +}); +--- + + + + + + + + + + + {/* Resource hints for performance */} + + + + + + + diff --git a/website/src/v2/components/layout/footer/Footer.astro b/website/src/v2/components/layout/footer/Footer.astro new file mode 100644 index 0000000..5eee5e8 --- /dev/null +++ b/website/src/v2/components/layout/footer/Footer.astro @@ -0,0 +1,90 @@ +--- +import { FOOTER_NAVIGATIONS } from "@/constants/footer-navigations"; +import { applyStyles } from "@/utils/apply-styles"; +import { + createTranslator, + getLocaleFromUrl, + getLocalizedPath, +} from "@/utils/i18n"; + +const locale = getLocaleFromUrl(Astro.url.pathname); +const t = await createTranslator(locale); + +const year = new Date().getFullYear(); + +const currentPath = Astro.url.pathname; +const isCurrentPage = (href: string) => + currentPath === getLocalizedPath(locale, href); +--- + +
+ +
+
+
+
+ + +
+ + {t("v2.footer.brand")} + +
+ + {t("v2.footer.copyright", { year })} + + + {t("v2.footer.rights")} + +
+
+ + +
+
+ { + FOOTER_NAVIGATIONS.map((section) => ( +
+ + {t(section.label)} + + {section.children.map((link) => ( + + {t(link.label)} + + ))} +
+ )) + } +
+
+ + {t("v2.footer.built_on")} + +
+
+
diff --git a/website/src/v2/components/layout/navbar/Navbar.astro b/website/src/v2/components/layout/navbar/Navbar.astro new file mode 100644 index 0000000..e1df94a --- /dev/null +++ b/website/src/v2/components/layout/navbar/Navbar.astro @@ -0,0 +1,187 @@ +--- +import LogoLong from "@/v2/assets/brand/logo-long.svg"; +import { + createTranslator, + getLocaleFromUrl, + getLocalizedPath, +} from "@/utils/i18n"; +import { SITE_NAVIGATIONS } from "@/v2/constants/site-navigations"; + +const locale = getLocaleFromUrl(Astro.url.pathname); +const t = await createTranslator(locale); +--- + + + + diff --git a/website/src/v2/components/ui/Button.astro b/website/src/v2/components/ui/Button.astro new file mode 100644 index 0000000..c60a2db --- /dev/null +++ b/website/src/v2/components/ui/Button.astro @@ -0,0 +1,98 @@ +--- +import { applyStyles } from "@/utils/apply-styles"; + +export interface Props { + id?: string; + variant?: "primary" | "secondary" | "outline"; + size?: "small" | "medium" | "large"; + disabled?: boolean; + type?: "button" | "submit" | "reset"; + ariaLabel?: string; + ariaDescribedBy?: string; + class?: string; + onclick?: string; + href?: string; + target?: string; + rel?: string; +} + +const { + variant = "primary", + size = "medium", + disabled = false, + type = "button", + ariaLabel, + ariaDescribedBy, + class: className = "", + onclick, + href, + target, + rel, + ...rest +} = Astro.props; + +const baseClasses = + "font-cta-mono inline-flex items-center justify-center no-underline transition-[opacity,border-color,background-color,color] duration-200"; + +const variantClasses = { + primary: "border border-(--flare) bg-(--flare) text-(--void) hover:opacity-85", + secondary: + "border border-(--border-med) bg-(--void) text-(--content) hover:border-(--content-60)", + outline: + "border border-(--flare) bg-transparent text-(--flare) hover:bg-(--flare) hover:text-(--void)", +}[variant]; + +const sizeClasses = { + small: "px-3 py-2 text-[10px] tracking-[0.08em]", + medium: "px-6 py-3 text-[12px] tracking-[0.11em]", + large: "px-7 py-3.5 text-[13px] tracking-[0.12em]", +}[size]; + +const disabledClasses = disabled + ? "pointer-events-none cursor-not-allowed opacity-60" + : "cursor-pointer"; +--- + +{ + !href && ( + + ) +} + +{ + href && ( + + + + ) +} diff --git a/website/src/v2/components/ui/Eyebrow.astro b/website/src/v2/components/ui/Eyebrow.astro new file mode 100644 index 0000000..36ffd74 --- /dev/null +++ b/website/src/v2/components/ui/Eyebrow.astro @@ -0,0 +1,41 @@ +--- +import { applyStyles } from "@/utils/apply-styles"; + +interface Props { + variant?: Variant; + class?: string; + isSpan?: boolean; +} + +type Variant = "default" | "flare" | "muted"; + +const { + isSpan = true, + variant = "default", + class: className = "", +} = Astro.props; + +const variantClass = { + default: "text-(--content-35)", + flare: "text-(--flare)", + muted: "text-(--muted)", +}[variant]; + +const classes = applyStyles( + "font-mono-label block tracking-[0.2em]", + variantClass, + className, +); +--- + +{ + isSpan ? ( + + + + ) : ( +

+ +

+ ) +} diff --git a/website/src/v2/components/ui/FlareDivider.astro b/website/src/v2/components/ui/FlareDivider.astro new file mode 100644 index 0000000..ee698b5 --- /dev/null +++ b/website/src/v2/components/ui/FlareDivider.astro @@ -0,0 +1,9 @@ +--- +interface Props { + class?: string; +} + +const { class: className = "" } = Astro.props; +--- + +
diff --git a/website/src/v2/components/ui/PageGlow.astro b/website/src/v2/components/ui/PageGlow.astro new file mode 100644 index 0000000..2a9144a --- /dev/null +++ b/website/src/v2/components/ui/PageGlow.astro @@ -0,0 +1,21 @@ +--- +interface Props { + class?: string; +} + +const { class: className = "" } = Astro.props; +--- + +