From 05f2882e938201716b40b3c2bcbdb46b885f8ff6 Mon Sep 17 00:00:00 2001 From: zhutao <1812073942@qq.com> Date: Fri, 12 Dec 2025 18:00:15 +0800 Subject: [PATCH] 1 --- .env.development | 2 + .env.production | 2 + .gitignore | 25 + README.md | 11 + index.html | 19 + package.json | 28 + pnpm-lock.yaml | 1268 +++++++++++++++++ src/App.tsx | 84 ++ src/api/service.ts | 39 + src/api/wxchat.ts | 25 + src/components/Screen1Hook.tsx | 281 ++++ src/components/Screen2Upload.tsx | 205 +++ src/components/Screen3Analysis.tsx | 253 ++++ src/components/Screen4Payment.tsx | 285 ++++ src/components/Screen5Report.tsx | 512 +++++++ src/main.tsx | 6 + src/store/user-store.ts | 36 + src/styles/globals.css | 185 +++ src/styles/index.css | 2093 ++++++++++++++++++++++++++++ src/types/index.d.ts | 3 + src/utils/http/error.ts | 13 + src/utils/http/request.ts | 68 + src/wx/wxLogin.ts | 48 + src/wx/wxPay.ts | 23 + src/wx/wxShare.ts | 82 ++ tsconfig.app.json | 35 + tsconfig.json | 6 + vite.config.ts | 25 + 28 files changed, 5662 insertions(+) create mode 100644 .env.development create mode 100644 .env.production create mode 100644 .gitignore create mode 100644 README.md create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/App.tsx create mode 100644 src/api/service.ts create mode 100644 src/api/wxchat.ts create mode 100644 src/components/Screen1Hook.tsx create mode 100644 src/components/Screen2Upload.tsx create mode 100644 src/components/Screen3Analysis.tsx create mode 100644 src/components/Screen4Payment.tsx create mode 100644 src/components/Screen5Report.tsx create mode 100644 src/main.tsx create mode 100644 src/store/user-store.ts create mode 100644 src/styles/globals.css create mode 100644 src/styles/index.css create mode 100644 src/types/index.d.ts create mode 100644 src/utils/http/error.ts create mode 100644 src/utils/http/request.ts create mode 100644 src/wx/wxLogin.ts create mode 100644 src/wx/wxPay.ts create mode 100644 src/wx/wxShare.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..8611e4b --- /dev/null +++ b/.env.development @@ -0,0 +1,2 @@ +VITE_APPID=wxbc438492e3efab70 #appid +VITE_WEB_URL=https://ting.lifebanktech.com diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..8611e4b --- /dev/null +++ b/.env.production @@ -0,0 +1,2 @@ +VITE_APPID=wxbc438492e3efab70 #appid +VITE_WEB_URL=https://ting.lifebanktech.com diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1698cec --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +*dist +*xiaoling_dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md new file mode 100644 index 0000000..e98d5f7 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ + + # H5活动落地页设计 + + This is a code bundle for H5活动落地页设计. The original project is available at https://www.figma.com/design/ony5Rjg3GoqH4QHmTSRILU/H5%E6%B4%BB%E5%8A%A8%E8%90%BD%E5%9C%B0%E9%A1%B5%E8%AE%BE%E8%AE%A1. + + ## Running the code + + Run `npm i` to install the dependencies. + + Run `npm run dev` to start the development server. + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..0735378 --- /dev/null +++ b/index.html @@ -0,0 +1,19 @@ + + + + + + 效灵AI + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..bc19622 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "ai", + "version": "0.1.0", + "private": true, + "dependencies": { + "axios": "^1.13.2", + "immer": "^11.0.1", + "lucide-react": "^0.487.0", + "motion": "^12.23.26", + "qs": "^6.14.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-hot-toast": "^2.6.0", + "weixin-js-sdk": "^1.6.5", + "zustand": "^5.0.9" + }, + "devDependencies": { + "@types/node": "^20.10.0", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react-swc": "^3.10.2", + "vite": "6.3.5" + }, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..5c16ad9 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1268 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + axios: + specifier: ^1.13.2 + version: 1.13.2 + immer: + specifier: ^11.0.1 + version: 11.0.1 + lucide-react: + specifier: ^0.487.0 + version: 0.487.0(react@18.3.1) + motion: + specifier: ^12.23.26 + version: 12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + qs: + specifier: ^6.14.0 + version: 6.14.0 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-hot-toast: + specifier: ^2.6.0 + version: 2.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + weixin-js-sdk: + specifier: ^1.6.5 + version: 1.6.5 + zustand: + specifier: ^5.0.9 + version: 5.0.9(@types/react@19.2.7)(immer@11.0.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) + devDependencies: + '@types/node': + specifier: ^20.10.0 + version: 20.19.26 + '@types/react': + specifier: ^19.2.7 + version: 19.2.7 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.7) + '@vitejs/plugin-react-swc': + specifier: ^3.10.2 + version: 3.11.0(vite@6.3.5(@types/node@20.19.26)) + vite: + specifier: 6.3.5 + version: 6.3.5(@types/node@20.19.26) + +packages: + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + cpu: [x64] + os: [win32] + + '@swc/core-darwin-arm64@1.15.3': + resolution: {integrity: sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.15.3': + resolution: {integrity: sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.15.3': + resolution: {integrity: sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.15.3': + resolution: {integrity: sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.15.3': + resolution: {integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.15.3': + resolution: {integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.15.3': + resolution: {integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.15.3': + resolution: {integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.15.3': + resolution: {integrity: sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.15.3': + resolution: {integrity: sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.15.3': + resolution: {integrity: sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/node@20.19.26': + resolution: {integrity: sha512-0l6cjgF0XnihUpndDhk+nyD3exio3iKaYROSgvh/qSevPXax3L8p5DBRFjbvalnwatGgHEQn2R88y2fA3g4irg==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.7': + resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + + '@vitejs/plugin-react-swc@3.11.0': + resolution: {integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==} + peerDependencies: + vite: ^4 || ^5 || ^6 || ^7 + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + framer-motion@12.23.26: + resolution: {integrity: sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + goober@2.1.18: + resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} + peerDependencies: + csstype: ^3.0.10 + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + immer@11.0.1: + resolution: {integrity: sha512-naDCyggtcBWANtIrjQEajhhBEuL9b0Zg4zmlWK2CzS6xCWSE39/vvf4LqnMjUAWHBhot4m9MHCM/Z+mfWhUkiA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lucide-react@0.487.0: + resolution: {integrity: sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + motion-dom@12.23.23: + resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==} + + motion-utils@12.23.6: + resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + + motion@12.23.26: + resolution: {integrity: sha512-Ll8XhVxY8LXMVYTCfme27WH2GjBrCIzY4+ndr5QKxsK+YwCtOi2B/oBi5jcIbik5doXuWT/4KKDOVAZJkeY5VQ==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-hot-toast@2.6.0: + resolution: {integrity: sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16' + react-dom: '>=16' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + 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 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + weixin-js-sdk@1.6.5: + resolution: {integrity: sha512-Gph1WAWB2YN/lMOFB/ymb+hbU/wYazzJgu6PMMktCy9cSCeW5wA6Zwt0dpahJbJ+RJEwtTv2x9iIu0U4enuVSQ==} + + zustand@5.0.9: + resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + +snapshots: + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rollup/rollup-android-arm-eabi@4.53.3': + optional: true + + '@rollup/rollup-android-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-x64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.3': + optional: true + + '@swc/core-darwin-arm64@1.15.3': + optional: true + + '@swc/core-darwin-x64@1.15.3': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.3': + optional: true + + '@swc/core-linux-arm64-gnu@1.15.3': + optional: true + + '@swc/core-linux-arm64-musl@1.15.3': + optional: true + + '@swc/core-linux-x64-gnu@1.15.3': + optional: true + + '@swc/core-linux-x64-musl@1.15.3': + optional: true + + '@swc/core-win32-arm64-msvc@1.15.3': + optional: true + + '@swc/core-win32-ia32-msvc@1.15.3': + optional: true + + '@swc/core-win32-x64-msvc@1.15.3': + optional: true + + '@swc/core@1.15.3': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.25 + optionalDependencies: + '@swc/core-darwin-arm64': 1.15.3 + '@swc/core-darwin-x64': 1.15.3 + '@swc/core-linux-arm-gnueabihf': 1.15.3 + '@swc/core-linux-arm64-gnu': 1.15.3 + '@swc/core-linux-arm64-musl': 1.15.3 + '@swc/core-linux-x64-gnu': 1.15.3 + '@swc/core-linux-x64-musl': 1.15.3 + '@swc/core-win32-arm64-msvc': 1.15.3 + '@swc/core-win32-ia32-msvc': 1.15.3 + '@swc/core-win32-x64-msvc': 1.15.3 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.25': + dependencies: + '@swc/counter': 0.1.3 + + '@types/estree@1.0.8': {} + + '@types/node@20.19.26': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.2.3(@types/react@19.2.7)': + dependencies: + '@types/react': 19.2.7 + + '@types/react@19.2.7': + dependencies: + csstype: 3.2.3 + + '@vitejs/plugin-react-swc@3.11.0(vite@6.3.5(@types/node@20.19.26))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.27 + '@swc/core': 1.15.3 + vite: 6.3.5(@types/node@20.19.26) + transitivePeerDependencies: + - '@swc/helpers' + + asynckit@0.4.0: {} + + axios@1.13.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + csstype@3.2.3: {} + + delayed-stream@1.0.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.25.12: + 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 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + follow-redirects@1.15.11: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + framer-motion@12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + motion-dom: 12.23.23 + motion-utils: 12.23.6 + tslib: 2.8.1 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + 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 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + goober@2.1.18(csstype@3.2.3): + dependencies: + csstype: 3.2.3 + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + immer@11.0.1: {} + + js-tokens@4.0.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lucide-react@0.487.0(react@18.3.1): + dependencies: + react: 18.3.1 + + math-intrinsics@1.1.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + motion-dom@12.23.23: + dependencies: + motion-utils: 12.23.6 + + motion-utils@12.23.6: {} + + motion@12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + framer-motion: 12.23.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tslib: 2.8.1 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + nanoid@3.3.11: {} + + object-inspect@1.13.4: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + proxy-from-env@1.1.0: {} + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-hot-toast@2.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + csstype: 3.2.3 + goober: 2.1.18(csstype@3.2.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + rollup@4.53.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 + fsevents: 2.3.3 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + source-map-js@1.2.1: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tslib@2.8.1: {} + + undici-types@6.21.0: {} + + use-sync-external-store@1.6.0(react@18.3.1): + dependencies: + react: 18.3.1 + optional: true + + vite@6.3.5(@types/node@20.19.26): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 20.19.26 + fsevents: 2.3.3 + + weixin-js-sdk@1.6.5: {} + + zustand@5.0.9(@types/react@19.2.7)(immer@11.0.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): + optionalDependencies: + '@types/react': 19.2.7 + immer: 11.0.1 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..65a38b9 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,84 @@ +import {useEffect, useState} from 'react'; +import {Screen1Hook} from './components/Screen1Hook'; +import {Screen2Upload} from './components/Screen2Upload'; +import {Screen3Analysis} from './components/Screen3Analysis'; +import {Screen4Payment} from './components/Screen4Payment'; +import {Screen5Report} from './components/Screen5Report'; +import wxLogin from "@/wx/wxLogin"; +import toast, {Toaster} from "react-hot-toast"; +import wxShare from "@/wx/wxShare"; +import {enterpriseAnalyzeApi} from "@/api/service"; +import {useUserStore} from "@/store/user-store"; + +export default function App() { + const userStore = useUserStore() + //初始化 + const [init, setInit] = useState(false) + const [currentScreen, setCurrentScreen] = useState(1); + + /** + * 步骤往下 + */ + const handleNextScreen = () => { + setCurrentScreen(prev => Math.min(prev + 1, 5)); + }; + + /** + * 上传文件 + */ + const handleUpload = async (file) => { + handleNextScreen() + let res = await enterpriseAnalyzeApi({ + analys_image: file, + analys_type: null, + }) as any + if (res.analysis_result.analyze_ret != "success") { + toast.error("请重新上传结构清晰的组织架构图") + setCurrentScreen(prev => prev = 2) + return + } + userStore.setAnalysis(res) + handleNextScreen() + }; + + const handlePayment = () => { + handleNextScreen(); + }; + + /** + * 授权 + */ + useEffect(() => { + wxLogin().then(() => { + setInit(true) + wxShare().then() + }) + }, []); + + if (!init) { + return <> + } + + return ( + <> + +
+ {/* 背景色 */} +
+
+
+ + {/* Main content */} +
+ {currentScreen === 1 && } + {currentScreen === 2 && } + {currentScreen === 3 && } + {currentScreen === 4 && } + {currentScreen === 5 && } +
+ +
+ + ); +} diff --git a/src/api/service.ts b/src/api/service.ts new file mode 100644 index 0000000..dd86835 --- /dev/null +++ b/src/api/service.ts @@ -0,0 +1,39 @@ +import request from "@/utils/http/request"; + + +type EnterpriseAnalyzeApi = { + analys_image: File, + analys_type: string, +} + +/** + * 企业架构图分析 + */ +export function enterpriseAnalyzeApi(data: EnterpriseAnalyzeApi) { + let formData = new FormData() + formData.append("analys_image", data.analys_image) + formData.append("analys_type", data.analys_type) + return request.post("/enterprise/analyze", formData); +} + + +type SubmitContactInfoApi = { + record_id: string | number, + contact_name: string, + contact_phone: string, + enterprise_name: string +} + +/** + * 提交联系方式 + */ +export function submitContactInfoApi(data: SubmitContactInfoApi) { + return request.post("/enterprise/submit_contact_info", data) +} + +/** + * 创建分析订单 + */ +export function createAnalyzeOrderApi(data:{record_id:number | string}) { + return request.post("/analysis_order/create",data) +} \ No newline at end of file diff --git a/src/api/wxchat.ts b/src/api/wxchat.ts new file mode 100644 index 0000000..a79aa0c --- /dev/null +++ b/src/api/wxchat.ts @@ -0,0 +1,25 @@ +import request from "@/utils/http/request"; + +/** + * 微信授权 + * @param data + * @constructor + */ +export function Login(data: any): Promise { + return request.post('/login', data) +} + +/** + * 获取jssdk + * @param params + */ +export function getJsSdk(params: any): Promise { + return request.get('/get_jssdk', params) +} + +/** + * 获取微信分享文案配置 + */ +export function getShareConfig() { + return request.get("/get_share_config") +} \ No newline at end of file diff --git a/src/components/Screen1Hook.tsx b/src/components/Screen1Hook.tsx new file mode 100644 index 0000000..161e8bc --- /dev/null +++ b/src/components/Screen1Hook.tsx @@ -0,0 +1,281 @@ +import {motion} from 'motion/react'; +import {useEffect, useState} from 'react'; +import {Brain, Cpu, Database, Sparkles, TrendingDown, Zap} from 'lucide-react'; + +interface Screen1HookProps { + onNext: () => void; +} + +export function Screen1Hook({onNext}: Screen1HookProps) { + const [count, setCount] = useState(1000); + const [typedText, setTypedText] = useState(''); + const fullText = '你的企业,正在为「低效」支付多少冤枉钱?'; + + useEffect(() => { + // Typewriter effect + let index = 0; + const timer = setInterval(() => { + if (index <= fullText.length) { + setTypedText(fullText.slice(0, index)); + index++; + } else { + clearInterval(timer); + } + }, 80); + + return () => clearInterval(timer); + }, []); + + useEffect(() => { + // Counter animation + const timer = setInterval(() => { + setCount(prev => prev + Math.floor(Math.random() * 3)); + }, 2000); + + return () => clearInterval(timer); + }, []); + + return ( +
+ {/* Animated background elements */} + + + + {/* AI Brain with orbiting icons */} + + {/* Central AI Brain with breathing effect */} + + {/* Glow effect */} + + + {/* Brain icon */} +
+ +
+ + {/* Orbiting icons */} + {[ + {Icon: Sparkles, delay: 0, color: '#00F0FF'}, + {Icon: Cpu, delay: 1, color: '#7B61FF'}, + {Icon: Database, delay: 2, color: '#00F0FF'}, + {Icon: Zap, delay: 3, color: '#7B61FF'}, + ].map((item, index) => ( + + + + + + + + ))} +
+ + {/* Particle effects */} + {Array.from({length: 8}).map((_, i) => ( + + ))} + + + {/* Main title with typewriter effect */} + + {typedText} + + + + {/* Subtitle */} + + AI时代,1个懂AI的员工 > 5个传统员工
上传组织架构图,AI一键测算你的 + 隐形降本空间 +
+ + {/* Counter */} + + + 今日已有 + + {count.toLocaleString()} + + 位老板获取了降本方案 + + + {/* CTA Button */} + + {/* Flowing light effect */} + + + 立即测算能省多少钱 + + + + + {/* Trust indicators */} + +
+
+ 银行级加密 +
+
+
+ 3秒出结果 +
+
+
+ 数据即时销毁 +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/Screen2Upload.tsx b/src/components/Screen2Upload.tsx new file mode 100644 index 0000000..c572913 --- /dev/null +++ b/src/components/Screen2Upload.tsx @@ -0,0 +1,205 @@ +import {motion} from 'motion/react'; +import {type ChangeEvent, useState} from 'react'; +import {FileImage, Shield, Upload} from 'lucide-react'; + +interface Screen2UploadProps { + onSuccess: (file:File) => void; +} + +const templates = [ + {id: 'ecommerce', name: '电商型', icon: '🛒'}, + {id: 'traditional', name: '传统型', icon: '🏢'}, + {id: 'tech', name: '科技型', icon: '💻'}, +]; + +export function Screen2Upload(props: Screen2UploadProps) { + // const userStore = useUserStore() + const [scanning, setScanning] = useState(false); + const [selectedTemplate, setSelectedTemplate] = useState(null); + + const handleFileSelect = async (e: ChangeEvent) => { + const file = e.target.files?.[0]; + if (file) { + props.onSuccess(file) + } + }; + + // const handleTemplateSelect = (templateId: string) => { + // if (scanning) return; + // setSelectedTemplate(templateId); + // }; + + + return ( +
+ + {/* Title */} + + 上传您的组织架构图 + + + + AI将智能分析各岗位的优化潜力 + + + {/* Upload area */} + + {scanning ? ( + // Scanning animation +
+ {/* Pulsing background */} + + + {/* Scanning line */} + + + {/* Content */} + + +

正在扫描架构图...

+ + {/* Selected template info */} + {selectedTemplate && ( + + {templates.find(t => t.id === selectedTemplate)?.icon} + {templates.find(t => t.id === selectedTemplate)?.name} + + )} +
+
+ ) : ( + // Upload interface +
+ +

拖拽图片到此处

+

+ +
+ +
+
+ )} + + {/* Corner decorations */} +
+
+
+
+ + + {/* Divider */} + {/**/} + {/*
*/} + {/* 选择分析类型*/} + {/*
*/} + {/**/} + + {/* Templates */} + {/**/} + {/* {templates.map((template, index) => (*/} + {/* handleTemplateSelect(template.id)}*/} + {/* whileHover={{scale: 1.05}}*/} + {/* whileTap={{scale: 0.95}}*/} + {/* >*/} + {/* {template.icon}*/} + {/* {template.name}*/} + {/* */} + {/* ))}*/} + {/**/} + + {/* Privacy notice */} + + + 银行级数据加密,仅用于测算,分析后立即销毁 + +
+ ); +} \ No newline at end of file diff --git a/src/components/Screen3Analysis.tsx b/src/components/Screen3Analysis.tsx new file mode 100644 index 0000000..ef2d3d8 --- /dev/null +++ b/src/components/Screen3Analysis.tsx @@ -0,0 +1,253 @@ +import {motion} from 'motion/react'; +import {useEffect, useState} from 'react'; +import {Brain, Cpu, TrendingUp, Zap} from 'lucide-react'; + + +const analysisSteps = [ + { dept: '组织架构', message: '发现重复劳动节点...', icon: '🎨' }, + { dept: 'AI替代方案', message: 'AI替代率 85%...', icon: '✍️' }, + { dept: 'AI优化方案', message: '智能接入可节省 70%...', icon: '💬' }, + { dept: 'AI优化空间', message: '数据分析优化空间 60%...', icon: '📊' }, + { dept: 'AI部署方案', message: '自动化流程提升 75%...', icon: '⚙️' }, +]; + +export function Screen3Analysis() { + const [currentStep, setCurrentStep] = useState(0); + const [nodes, setNodes] = useState>([]); + + useEffect(() => { + // Generate random nodes + const newNodes = Array.from({ length: 15 }, (_, i) => ({ + x: Math.random() * 100, + y: Math.random() * 100, + id: i, + })); + setNodes(newNodes); + }, []); + + useEffect(() => { + // Progress through analysis steps + const timer = setInterval(() => { + setCurrentStep((prev) => { + if (prev < analysisSteps.length - 1) { + return prev + 1; + } else { + clearInterval(timer); + return prev; + } + }); + }, 800); + + return () => clearInterval(timer); + }, []); + + return ( +
+ {/* Radar scanning effect */} +
+ + + + {/* Rotating radar beam */} + +
+ + {/* Node visualization */} +
+ {nodes.map((node) => ( + + {/* Pulse effect */} + + + ))} +
+ + {/* Central AI brain */} + +
+ + + + + {/* Orbiting icons */} + {[Cpu, Zap, TrendingUp].map((Icon, index) => ( + + +
+ +
+
+
+ ))} +
+
+ + {/* Analysis progress */} +
+ {analysisSteps.map((step, index) => ( + + {step.icon} +
+
正在分析{step.dept}
+
{step.message}
+
+ {index === currentStep && ( + + )} + {index < currentStep && ( +
+ + + +
+ )} +
+ ))} +
+ + {/* Status text */} + +

AI深度分析中,请稍候...

+
+ + {/* Progress bar */} + + + +
+ ); +} diff --git a/src/components/Screen4Payment.tsx b/src/components/Screen4Payment.tsx new file mode 100644 index 0000000..e78f348 --- /dev/null +++ b/src/components/Screen4Payment.tsx @@ -0,0 +1,285 @@ +import {motion} from 'motion/react'; +import {useEffect, useState} from 'react'; +import {AlertCircle, Check, Lock, Sparkles, TrendingDown, Users} from 'lucide-react'; +import {createAnalyzeOrderApi} from "@/api/service"; +import {wxPay} from "@/wx/wxPay"; +import {useUserStore} from "@/store/user-store"; +import toast from "react-hot-toast"; + +interface Screen4PaymentProps { + onPayment: () => void; +} + +const testimonials = [ + '某杭州电商公司使用后,设计部成本降低60%', + '某深圳外贸公司使用后,客服响应速度提升5倍', + '某上海科技公司使用后,年度成本节省120万', +]; + +export function Screen4Payment({onPayment}: Screen4PaymentProps) { + const userStore = useUserStore() + const [countdown, setCountdown] = useState(599); // 9:59 + const [currentTestimonial, setCurrentTestimonial] = useState(0); + //防抖 + let debounce = true + + /** + * 创建订单,吊起微信支付 + */ + const onCreateOrder = async () => { + if (!debounce) return + debounce = false + let res = await createAnalyzeOrderApi({ + record_id: userStore.analysis.record_id + }); + wxPay(res).then((state) => { + debounce = true + if (state) { + onPayment() + } else { + toast.error("支付失败") + } + }) + } + + useEffect(() => { + const timer = setInterval(() => { + setCountdown((prev) => (prev > 0 ? prev - 1 : 0)); + }, 1000); + return () => clearInterval(timer); + }, []); + + useEffect(() => { + const timer = setInterval(() => { + setCurrentTestimonial((prev) => (prev + 1) % testimonials.length); + }, 3000); + return () => clearInterval(timer); + }, []); + + const minutes = Math.floor(countdown / 60); + const seconds = countdown % 60; + + return ( +
+ {/* Blurred background report preview */} +
+
+
+
+
+
+
+
+
+ + {/* Main content */} + + {/* Alert header */} + + + 分析完成! + + + {/* Blurred teaser */} + + {/* Blur overlay with preview data */} +
+ +
+ +

预计年度节省

+
+ ¥ {userStore.analysis.analysis_result.analyze_data.annual_savings_cost} +
+
+ +

效率提升

+
+ {userStore.analysis.analysis_result.analyze_data.efficiency_improvement} % +
+
+
+
+ +
+
+

经测算,您的企业每年由于员工不使用AI

+

额外支出成本约为

+
+ ¥???{','}??? +
+
+ +
+ +
+

优化后,预计每年可节省

+
+ ¥???{','}??? +
+
+
+ + + {/* Unlock section */} + +
+ +

解锁完整报告

+
+ +
+ {[ + '各部门AI替代率精准评估', + '具体的降本金额明细', + '推荐的AI工具组合清单', + ].map((item, index) => ( + +
+ +
+ {item} +
+ ))} +
+ + {/* Price */} +
+
+ ¥999 + 限时特惠 +
+
+ ¥ + + 9.9 + +
+
+ + {/* Payment button */} + + + + + + + 微信支付 ¥9.9 解锁报告 + + + + {/* Countdown */} + + + + 优惠将在{' '} + + {String(minutes).padStart(2, '0')}:{String(seconds).padStart(2, '0')} + {' '} + 后失效 + + +
+ + {/* Trust indicators */} + + + + {testimonials[currentTestimonial]} + + + + {/* Footer guarantees */} + +
+ + 安全支付 +
+
+ + 1000+企业选择 +
+
+ + 平均节省40% +
+
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/Screen5Report.tsx b/src/components/Screen5Report.tsx new file mode 100644 index 0000000..c22532a --- /dev/null +++ b/src/components/Screen5Report.tsx @@ -0,0 +1,512 @@ +import {AnimatePresence, motion} from 'motion/react'; +import {FormEvent, useState} from 'react'; +import {ArrowRight, CheckCircle, FileText, Gift, MessageSquare, Sparkles, Users, X, Zap} from 'lucide-react'; +import {submitContactInfoApi} from "@/api/service"; +import {useUserStore} from "@/store/user-store"; + +export function Screen5Report() { + const userStore = useUserStore() + const [formData, setFormData] = useState({ + name: '', + phone: '', + company: '', + }); + const [showReport, setShowReport] = useState(false); + const [showAdvisorModal, setShowAdvisorModal] = useState(false); + + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + + await submitContactInfoApi({ + contact_name: formData.name, + contact_phone: formData.phone, + enterprise_name: formData.company, + record_id: userStore.analysis.record_id, + }) + setShowReport(true); + }; + + if (!showReport) { + return ( +
+ + {/* Success icon */} + +
+ +
+
+ + + 报告已生成! + + + + 请输入接收人信息以存档 + + + {/* Form */} + +
+ + setFormData({...formData, name: e.target.value})} + /> +
+ +
+ + setFormData({...formData, phone: e.target.value})} + /> +
+ +
+ + setFormData({...formData, company: e.target.value})} + /> +
+ + + + 查看报告 + +
+
+
+ ); + } + + return ( +
+ + {/* Header */} + +

AI降本增效诊断报告

+

为 {formData.company || formData.name} 定制

+
+ + {/* Summary cards */} +
+ +
年度额外支出
+
+ ¥{userStore.analysis.analysis_result.analyze_data.annual_original_cost} +
+
+ + +
预计年节省
+
+ ¥{userStore.analysis.analysis_result.analyze_data.annual_savings_cost} +
+
+
+ + {/* Department analysis */} + +

+ + 各部门优化分析 +

+ +
+ { + userStore.analysis.analysis_result.analyze_data.analyze_postion_detail.map((dept: any, index) => { + let level = 0; // 0低,1普通,2高 + if (dept.replace_save_rate < 30) { + level = 0 + } else if (dept.replace_save_rate < 70) { + level = 1 + } else { + level = 2 + } + return ( + +
+
+
+ {dept.position} + {level == 2 && ( + 急需优化 + )} +
+
+ {dept.original_number}人 → {dept.replace_with_ai_number}人 + AI +
+
+
+
+ -{dept.replace_save_rate}% +
+
成本降低
+
+
+ + {/* Progress bar */} +
+ +
+
+ ) + }) + } + +
+
+ + {/* AI Tools recommendation */} + +

+ + 推荐AI工具组合 +

+ +
+ {['文案生成AI', '设计辅助AI', '智能客服系统', '数据分析AI', '自动化运营工具', '会议记录AI'].map( + (tool, index) => ( + + {tool} + + ) + )} +
+
+ + {/* CTA section - Redesigned */} + + {/* Animated background pattern */} + + +
+ + +

知道问题了,不知道怎么落地?

+
+ +

+ 专属AI顾问为您提供 +
+ 行业定制版AI工具包 + 员工培训方案 +

+ + setShowAdvisorModal(true)} + > + + 立即咨询专属AI顾问 + + + + + + 限时赠送《2025企业AI工具白皮书》 + +
+
+
+ + {/* Floating Action Button */} + setShowAdvisorModal(true)} + > + + 点击获取 1对1定制化AI落地方案 + + {/* Ripple effect */} + + + {/* Glow effect */} + + + + {/* Advisor Modal */} + + {showAdvisorModal && ( + + {/* Backdrop */} + setShowAdvisorModal(false)} + /> + + {/* Modal */} + + {/* Close button */} + + + {/* Animated icon */} + + + + + + + {/* Content */} + +

添加专属AI顾问

+

+ 扫描下方二维码,即可获得: +

+ +
+ {[ + '1对1定制化AI落地方案', + '行业专属AI工具包推荐', + '全员AI技能培训指导', + '《2025企业AI工具白皮书》PDF', + ].map((item, index) => ( + +
+ +
+ {item} +
+ ))} +
+ + {/* QR Code */} + +
+ +
+
+ + + 顾问微信二维码,长按识别添加 +
+ 添加后回复「{formData.company || formData.name}」 +
+ 立即获取专属方案 +
+
+
+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..7ea4efd --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,6 @@ +import {createRoot} from "react-dom/client"; +import App from "./App"; +import "./styles/index.css"; + +createRoot(document.getElementById("root")!).render(); + \ No newline at end of file diff --git a/src/store/user-store.ts b/src/store/user-store.ts new file mode 100644 index 0000000..8a26a84 --- /dev/null +++ b/src/store/user-store.ts @@ -0,0 +1,36 @@ +import {create} from 'zustand'; +import {createJSONStorage, persist} from 'zustand/middleware'; +import {immer} from 'zustand/middleware/immer'; + +interface State { + token: string, + analysis: any, +} + +type Action = { + setToken: (value: string) => void, + setAnalysis: (value: any) => void, +} + +export const useUserStore = create()( + persist( + immer((set) => ({ + token: "", + analysis: null, + setToken(val) { + set((state) => { + state.token = val + }) + }, + setAnalysis(val) { + set((state) => { + state.analysis = val + }) + } + })), + { + name: 'zustand_storage', + storage: createJSONStorage(() => localStorage), + } + ) +) \ No newline at end of file diff --git a/src/styles/globals.css b/src/styles/globals.css new file mode 100644 index 0000000..13cd23e --- /dev/null +++ b/src/styles/globals.css @@ -0,0 +1,185 @@ +@custom-variant dark (&:is(.dark *)); + +:root { + --font-size: 16px; + --background: #ffffff; + --foreground: oklch(0.145 0 0); + --card: #ffffff; + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: #030213; + --primary-foreground: oklch(1 0 0); + --secondary: oklch(0.95 0.0058 264.53); + --secondary-foreground: #030213; + --muted: #ececf0; + --muted-foreground: #717182; + --accent: #e9ebef; + --accent-foreground: #030213; + --destructive: #d4183d; + --destructive-foreground: #ffffff; + --border: rgba(0, 0, 0, 0.1); + --input: transparent; + --input-background: #f3f3f5; + --switch-background: #cbced4; + --font-weight-medium: 500; + --font-weight-normal: 400; + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: #030213; + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.145 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.145 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: oklch(0.269 0 0); + --input: oklch(0.269 0 0); + --ring: oklch(0.439 0 0); + --font-weight-medium: 500; + --font-weight-normal: 400; + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(0.269 0 0); + --sidebar-ring: oklch(0.439 0 0); +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-input-background: var(--input-background); + --color-switch-background: var(--switch-background); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + + body { + @apply bg-background text-foreground; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } +} + +/** + * Base typography. This is not applied to elements which have an ancestor with a Tailwind text class. + */ +@layer base { + :where(:not(:has([class*=' text-']), :not(:has([class^='text-'])))) { + h1 { + font-size: var(--text-2xl); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + h2 { + font-size: var(--text-xl); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + h3 { + font-size: var(--text-lg); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + h4 { + font-size: var(--text-base); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + label { + font-size: var(--text-base); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + button { + font-size: var(--text-base); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + input { + font-size: var(--text-base); + font-weight: var(--font-weight-normal); + line-height: 1.5; + } + } +} + +html { + font-size: var(--font-size); +} diff --git a/src/styles/index.css b/src/styles/index.css new file mode 100644 index 0000000..a4d9af5 --- /dev/null +++ b/src/styles/index.css @@ -0,0 +1,2093 @@ +/*! tailwindcss v4.1.3 | MIT License | https://tailwindcss.com */ +@layer properties { + @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) { + *, :before, :after, ::backdrop { + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-translate-z: 0; + --tw-rotate-x: rotateX(0); + --tw-rotate-y: rotateY(0); + --tw-rotate-z: rotateZ(0); + --tw-skew-x: skewX(0); + --tw-skew-y: skewY(0); + --tw-space-y-reverse: 0; + --tw-border-style: solid; + --tw-gradient-position: initial; + --tw-gradient-from: #0000; + --tw-gradient-via: #0000; + --tw-gradient-to: #0000; + --tw-gradient-stops: initial; + --tw-gradient-via-stops: initial; + --tw-gradient-from-position: 0%; + --tw-gradient-via-position: 50%; + --tw-gradient-to-position: 100%; + --tw-font-weight: initial; + --tw-shadow: 0 0 #0000; + --tw-shadow-color: initial; + --tw-shadow-alpha: 100%; + --tw-inset-shadow: 0 0 #0000; + --tw-inset-shadow-color: initial; + --tw-inset-shadow-alpha: 100%; + --tw-ring-color: initial; + --tw-ring-shadow: 0 0 #0000; + --tw-inset-ring-color: initial; + --tw-inset-ring-shadow: 0 0 #0000; + --tw-ring-inset: initial; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-offset-shadow: 0 0 #0000; + --tw-blur: initial; + --tw-brightness: initial; + --tw-contrast: initial; + --tw-grayscale: initial; + --tw-hue-rotate: initial; + --tw-invert: initial; + --tw-opacity: initial; + --tw-saturate: initial; + --tw-sepia: initial; + --tw-drop-shadow: initial; + --tw-drop-shadow-color: initial; + --tw-drop-shadow-alpha: 100%; + --tw-drop-shadow-size: initial; + --tw-backdrop-blur: initial; + --tw-backdrop-brightness: initial; + --tw-backdrop-contrast: initial; + --tw-backdrop-grayscale: initial; + --tw-backdrop-hue-rotate: initial; + --tw-backdrop-invert: initial; + --tw-backdrop-opacity: initial; + --tw-backdrop-saturate: initial; + --tw-backdrop-sepia: initial; + --tw-duration: initial; + } + } +} + +@layer theme { + :root, :host { + --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --color-red-400: oklch(.704 .191 22.216); + --color-red-500: oklch(.637 .237 25.331); + --color-orange-400: oklch(.75 .183 55.934); + --color-orange-500: oklch(.705 .213 47.604); + --color-yellow-400: oklch(.852 .199 91.936); + --color-yellow-500: oklch(.795 .184 86.047); + --color-green-400: oklch(.792 .209 151.711); + --color-gray-300: oklch(.872 .01 258.338); + --color-gray-400: oklch(.707 .022 261.325); + --color-gray-500: oklch(.551 .027 264.364); + --color-gray-600: oklch(.446 .03 256.802); + --color-gray-800: oklch(.278 .033 256.848); + --color-black: #000; + --color-white: #fff; + --spacing: .25rem; + --container-sm: 24rem; + --container-md: 28rem; + --container-xl: 36rem; + --container-2xl: 42rem; + --text-xs: .75rem; + --text-xs--line-height: calc(1 / .75); + --text-sm: .875rem; + --text-sm--line-height: calc(1.25 / .875); + --text-base: 1rem; + --text-lg: 1.125rem; + --text-lg--line-height: calc(1.75 / 1.125); + --text-xl: 1.25rem; + --text-xl--line-height: calc(1.75 / 1.25); + --text-2xl: 1.5rem; + --text-2xl--line-height: calc(2 / 1.5); + --text-3xl: 1.875rem; + --text-3xl--line-height: calc(2.25 / 1.875); + --text-4xl: 2.25rem; + --text-4xl--line-height: calc(2.5 / 2.25); + --text-5xl: 3rem; + --text-5xl--line-height: 1; + --text-6xl: 3.75rem; + --text-6xl--line-height: 1; + --font-weight-normal: 400; + --font-weight-medium: 500; + --radius-2xl: 1rem; + --radius-3xl: 1.5rem; + --blur-sm: 8px; + --blur-md: 12px; + --blur-xl: 24px; + --blur-2xl: 40px; + --blur-3xl: 64px; + --default-transition-duration: .15s; + --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1); + --default-font-family: var(--font-sans); + --default-font-feature-settings: var(--font-sans--font-feature-settings); + --default-font-variation-settings: var(--font-sans--font-variation-settings); + --default-mono-font-family: var(--font-mono); + --default-mono-font-feature-settings: var(--font-mono--font-feature-settings); + --default-mono-font-variation-settings: var(--font-mono--font-variation-settings); + } +} + +@layer base { + *, :after, :before, ::backdrop { + box-sizing: border-box; + border: 0 solid; + margin: 0; + padding: 0; + } + + ::file-selector-button { + box-sizing: border-box; + border: 0 solid; + margin: 0; + padding: 0; + } + + html, :host { + -webkit-text-size-adjust: 100%; + tab-size: 4; + line-height: 1.5; + font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); + font-feature-settings: var(--default-font-feature-settings, normal); + font-variation-settings: var(--default-font-variation-settings, normal); + -webkit-tap-highlight-color: transparent; + } + + body { + line-height: inherit; + } + + hr { + height: 0; + color: inherit; + border-top-width: 1px; + } + + abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + } + + h1, h2, h3, h4, h5, h6 { + font-size: inherit; + font-weight: inherit; + } + + a { + color: inherit; + -webkit-text-decoration: inherit; + -webkit-text-decoration: inherit; + text-decoration: inherit; + } + + b, strong { + font-weight: bolder; + } + + code, kbd, samp, pre { + font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); + font-feature-settings: var(--default-mono-font-feature-settings, normal); + font-variation-settings: var(--default-mono-font-variation-settings, normal); + font-size: 1em; + } + + small { + font-size: 80%; + } + + sub, sup { + vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + } + + sub { + bottom: -.25em; + } + + sup { + top: -.5em; + } + + table { + text-indent: 0; + border-color: inherit; + border-collapse: collapse; + } + + :-moz-focusring { + outline: auto; + } + + progress { + vertical-align: baseline; + } + + summary { + display: list-item; + } + + ol, ul, menu { + list-style: none; + } + + img, svg, video, canvas, audio, iframe, embed, object { + vertical-align: middle; + display: block; + } + + img, video { + max-width: 100%; + height: auto; + } + + button, input, select, optgroup, textarea { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + opacity: 1; + background-color: #0000; + border-radius: 0; + } + + ::file-selector-button { + font: inherit; + font-feature-settings: inherit; + font-variation-settings: inherit; + letter-spacing: inherit; + color: inherit; + opacity: 1; + background-color: #0000; + border-radius: 0; + } + + :where(select:is([multiple], [size])) optgroup { + font-weight: bolder; + } + + :where(select:is([multiple], [size])) optgroup option { + padding-inline-start: 20px; + } + + ::file-selector-button { + margin-inline-end: 4px; + } + + ::placeholder { + opacity: 1; + color: currentColor; + } + + @supports (color: color-mix(in lab, red, red)) { + ::placeholder { + color: color-mix(in oklab, currentColor 50%, transparent); + } + } + + textarea { + resize: vertical; + } + + ::-webkit-search-decoration { + -webkit-appearance: none; + } + + ::-webkit-date-and-time-value { + min-height: 1lh; + text-align: inherit; + } + + ::-webkit-datetime-edit { + display: inline-flex; + } + + ::-webkit-datetime-edit-fields-wrapper { + padding: 0; + } + + ::-webkit-datetime-edit { + padding-block: 0; + } + + ::-webkit-datetime-edit-year-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-month-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-day-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-hour-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-minute-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-second-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-millisecond-field { + padding-block: 0; + } + + ::-webkit-datetime-edit-meridiem-field { + padding-block: 0; + } + + :-moz-ui-invalid { + box-shadow: none; + } + + button, input:where([type="button"], [type="reset"], [type="submit"]) { + appearance: button; + } + + ::file-selector-button { + appearance: button; + } + + ::-webkit-inner-spin-button { + height: auto; + } + + ::-webkit-outer-spin-button { + height: auto; + } + + [hidden]:where(:not([hidden="until-found"])) { + display: none !important; + } + + * { + border-color: var(--border); + outline-color: var(--ring); + } + + @supports (color: color-mix(in lab, red, red)) { + * { + outline-color: color-mix(in oklab, var(--ring) 50%, transparent); + } + } + + body { + background-color: var(--background); + color: var(--foreground); + } + + * { + border-color: var(--border); + outline-color: var(--ring); + } + + @supports (color: color-mix(in lab, red, red)) { + * { + outline-color: color-mix(in oklab, var(--ring) 50%, transparent); + } + } + + body { + background-color: var(--background); + color: var(--foreground); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) h1 { + font-size: var(--text-2xl); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) h2 { + font-size: var(--text-xl); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) h3 { + font-size: var(--text-lg); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) h4, :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) label, :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) button { + font-size: var(--text-base); + font-weight: var(--font-weight-medium); + line-height: 1.5; + } + + :where(:not(:has([class*=" text-"]), :not(:has([class^="text-"])))) input { + font-size: var(--text-base); + font-weight: var(--font-weight-normal); + line-height: 1.5; + } +} + +@layer utilities { + .pointer-events-none { + pointer-events: none; + } + + .absolute { + position: absolute; + } + + .fixed { + position: fixed; + } + + .relative { + position: relative; + } + + .inset-0 { + inset: calc(var(--spacing) * 0); + } + + .inset-x-0 { + inset-inline: calc(var(--spacing) * 0); + } + + .top-0 { + top: calc(var(--spacing) * 0); + } + + .top-1\/2 { + top: 50%; + } + + .top-1\/4 { + top: 25%; + } + + .top-4 { + top: calc(var(--spacing) * 4); + } + + .right-0 { + right: calc(var(--spacing) * 0); + } + + .right-1\/4 { + right: 25%; + } + + .right-4 { + right: calc(var(--spacing) * 4); + } + + .bottom-0 { + bottom: calc(var(--spacing) * 0); + } + + .bottom-1\/4 { + bottom: 25%; + } + + .bottom-6 { + bottom: calc(var(--spacing) * 6); + } + + .left-0 { + left: calc(var(--spacing) * 0); + } + + .left-1\/2 { + left: 50%; + } + + .left-1\/4 { + left: 25%; + } + + .z-10 { + z-index: 10; + } + + .z-50 { + z-index: 50; + } + + .mx-auto { + margin-inline: auto; + } + + .my-8 { + margin-block: calc(var(--spacing) * 8); + } + + .-mt-4 { + margin-top: calc(var(--spacing) * -4); + } + + .-mt-5 { + margin-top: calc(var(--spacing) * -5); + } + + .mt-1 { + margin-top: calc(var(--spacing) * 1); + } + + .mt-2 { + margin-top: calc(var(--spacing) * 2); + } + + .mt-4 { + margin-top: calc(var(--spacing) * 4); + } + + .mt-6 { + margin-top: calc(var(--spacing) * 6); + } + + .mt-12 { + margin-top: calc(var(--spacing) * 12); + } + + .mb-1 { + margin-bottom: calc(var(--spacing) * 1); + } + + .mb-2 { + margin-bottom: calc(var(--spacing) * 2); + } + + .mb-3 { + margin-bottom: calc(var(--spacing) * 3); + } + + .mb-4 { + margin-bottom: calc(var(--spacing) * 4); + } + + .mb-6 { + margin-bottom: calc(var(--spacing) * 6); + } + + .mb-8 { + margin-bottom: calc(var(--spacing) * 8); + } + + .mb-12 { + margin-bottom: calc(var(--spacing) * 12); + } + + .-ml-4 { + margin-left: calc(var(--spacing) * -4); + } + + .-ml-5 { + margin-left: calc(var(--spacing) * -5); + } + + .ml-1 { + margin-left: calc(var(--spacing) * 1); + } + + .block { + display: block; + } + + .flex { + display: flex; + } + + .grid { + display: grid; + } + + .hidden { + display: none; + } + + .inline-block { + display: inline-block; + } + + .h-1 { + height: calc(var(--spacing) * 1); + } + + .h-2 { + height: calc(var(--spacing) * 2); + } + + .h-3 { + height: calc(var(--spacing) * 3); + } + + .h-4 { + height: calc(var(--spacing) * 4); + } + + .h-5 { + height: calc(var(--spacing) * 5); + } + + .h-6 { + height: calc(var(--spacing) * 6); + } + + .h-8 { + height: calc(var(--spacing) * 8); + } + + .h-10 { + height: calc(var(--spacing) * 10); + } + + .h-12 { + height: calc(var(--spacing) * 12); + } + + .h-14 { + height: calc(var(--spacing) * 14); + } + + .h-16 { + height: calc(var(--spacing) * 16); + } + + .h-20 { + height: calc(var(--spacing) * 20); + } + + .h-24 { + height: calc(var(--spacing) * 24); + } + + .h-32 { + height: calc(var(--spacing) * 32); + } + + .h-48 { + height: calc(var(--spacing) * 48); + } + + .h-64 { + height: calc(var(--spacing) * 64); + } + + .h-72 { + height: calc(var(--spacing) * 72); + } + + .h-96 { + height: calc(var(--spacing) * 96); + } + + .h-full { + height: 100%; + } + + .h-px { + height: 1px; + } + + .min-h-\[6rem\] { + min-height: 6rem; + } + + .min-h-screen { + min-height: 100vh; + } + + .w-1 { + width: calc(var(--spacing) * 1); + } + + .w-2 { + width: calc(var(--spacing) * 2); + } + + .w-2\/3 { + width: 66.6667%; + } + + .w-3 { + width: calc(var(--spacing) * 3); + } + + .w-4 { + width: calc(var(--spacing) * 4); + } + + .w-5 { + width: calc(var(--spacing) * 5); + } + + .w-6 { + width: calc(var(--spacing) * 6); + } + + .w-8 { + width: calc(var(--spacing) * 8); + } + + .w-10 { + width: calc(var(--spacing) * 10); + } + + .w-12 { + width: calc(var(--spacing) * 12); + } + + .w-14 { + width: calc(var(--spacing) * 14); + } + + .w-16 { + width: calc(var(--spacing) * 16); + } + + .w-20 { + width: calc(var(--spacing) * 20); + } + + .w-24 { + width: calc(var(--spacing) * 24); + } + + .w-32 { + width: calc(var(--spacing) * 32); + } + + .w-48 { + width: calc(var(--spacing) * 48); + } + + .w-64 { + width: calc(var(--spacing) * 64); + } + + .w-80 { + width: calc(var(--spacing) * 80); + } + + .w-96 { + width: calc(var(--spacing) * 96); + } + + .w-full { + width: 100%; + } + + .max-w-2xl { + max-width: var(--container-2xl); + } + + .max-w-\[90vw\] { + max-width: 90vw; + } + + .max-w-md { + max-width: var(--container-md); + } + + .max-w-sm { + max-width: var(--container-sm); + } + + .max-w-xl { + max-width: var(--container-xl); + } + + .flex-1 { + flex: 1; + } + + .flex-shrink-0 { + flex-shrink: 0; + } + + .origin-left { + transform-origin: 0; + } + + .-translate-x-1\/2 { + --tw-translate-x: calc(calc(1 / 2 * 100%) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } + + .transform { + transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y); + } + + .cursor-pointer { + cursor: pointer; + } + + .grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .flex-col { + flex-direction: column; + } + + .items-baseline { + align-items: baseline; + } + + .items-center { + align-items: center; + } + + .justify-between { + justify-content: space-between; + } + + .justify-center { + justify-content: center; + } + + .gap-1 { + gap: calc(var(--spacing) * 1); + } + + .gap-2 { + gap: calc(var(--spacing) * 2); + } + + .gap-3 { + gap: calc(var(--spacing) * 3); + } + + .gap-4 { + gap: calc(var(--spacing) * 4); + } + + .gap-6 { + gap: calc(var(--spacing) * 6); + } + + :where(.space-y-3 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse))); + } + + :where(.space-y-4 > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse))); + } + + .overflow-hidden { + overflow: hidden; + } + + .overflow-x-hidden { + overflow-x: hidden; + } + + .rounded { + border-radius: .25rem; + } + + .rounded-2xl { + border-radius: var(--radius-2xl); + } + + .rounded-3xl { + border-radius: var(--radius-3xl); + } + + .rounded-full { + border-radius: 3.40282e38px; + } + + .rounded-lg { + border-radius: var(--radius); + } + + .rounded-xl { + border-radius: calc(var(--radius) + 4px); + } + + .rounded-tl-2xl { + border-top-left-radius: var(--radius-2xl); + } + + .rounded-tr-2xl { + border-top-right-radius: var(--radius-2xl); + } + + .rounded-br-2xl { + border-bottom-right-radius: var(--radius-2xl); + } + + .rounded-bl-2xl { + border-bottom-left-radius: var(--radius-2xl); + } + + .border { + border-style: var(--tw-border-style); + border-width: 1px; + } + + .border-2 { + border-style: var(--tw-border-style); + border-width: 2px; + } + + .border-t-2 { + border-top-style: var(--tw-border-style); + border-top-width: 2px; + } + + .border-r-2 { + border-right-style: var(--tw-border-style); + border-right-width: 2px; + } + + .border-b-2 { + border-bottom-style: var(--tw-border-style); + border-bottom-width: 2px; + } + + .border-l-2 { + border-left-style: var(--tw-border-style); + border-left-width: 2px; + } + + .border-dashed { + --tw-border-style: dashed; + border-style: dashed; + } + + .border-\[\#00F0FF\] { + border-color: #00f0ff; + } + + .border-\[\#00F0FF\]\/30 { + border-color: oklab(87.0045% -.136493 -.0575878 / .3); + } + + .border-\[\#00F0FF\]\/50 { + border-color: oklab(87.0045% -.136493 -.0575878 / .5); + } + + .border-\[\#7B61FF\] { + border-color: #7b61ff; + } + + .border-\[\#7B61FF\]\/30 { + border-color: oklab(60.5679% .0582184 -.216332 / .3); + } + + .border-\[\#7B61FF\]\/50 { + border-color: oklab(60.5679% .0582184 -.216332 / .5); + } + + .border-gray-600 { + border-color: var(--color-gray-600); + } + + .border-gray-800 { + border-color: var(--color-gray-800); + } + + .border-orange-500\/30 { + border-color: color-mix(in srgb, oklch(.705 .213 47.604) 30%, transparent); + } + + @supports (color: color-mix(in lab, red, red)) { + .border-orange-500\/30 { + border-color: color-mix(in oklab, var(--color-orange-500) 30%, transparent); + } + } + + .border-red-500\/30 { + border-color: color-mix(in srgb, oklch(.637 .237 25.331) 30%, transparent); + } + + @supports (color: color-mix(in lab, red, red)) { + .border-red-500\/30 { + border-color: color-mix(in oklab, var(--color-red-500) 30%, transparent); + } + } + + .border-white { + border-color: var(--color-white); + } + + .border-yellow-500\/30 { + border-color: color-mix(in srgb, oklch(.795 .184 86.047) 30%, transparent); + } + + @supports (color: color-mix(in lab, red, red)) { + .border-yellow-500\/30 { + border-color: color-mix(in oklab, var(--color-yellow-500) 30%, transparent); + } + } + + .border-t-transparent { + border-top-color: #0000; + } + + .bg-\[\#0A0F24\] { + background-color: #0a0f24; + } + + .bg-\[\#00F0FF\] { + background-color: #00f0ff; + } + + .bg-\[\#00F0FF\]\/5 { + background-color: oklab(87.0045% -.136493 -.0575878 / .05); + } + + .bg-\[\#00F0FF\]\/10 { + background-color: oklab(87.0045% -.136493 -.0575878 / .1); + } + + .bg-\[\#00F0FF\]\/20 { + background-color: oklab(87.0045% -.136493 -.0575878 / .2); + } + + .bg-\[\#7B61FF\]\/20 { + background-color: oklab(60.5679% .0582184 -.216332 / .2); + } + + .bg-black\/80 { + background-color: #000c; + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-black\/80 { + background-color: color-mix(in oklab, var(--color-black) 80%, transparent); + } + } + + .bg-gray-300 { + background-color: var(--color-gray-300); + } + + .bg-gray-800 { + background-color: var(--color-gray-800); + } + + .bg-green-400 { + background-color: var(--color-green-400); + } + + .bg-orange-400 { + background-color: var(--color-orange-400); + } + + .bg-orange-500\/10 { + background-color: color-mix(in srgb, oklch(.705 .213 47.604) 10%, transparent); + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-orange-500\/10 { + background-color: color-mix(in oklab, var(--color-orange-500) 10%, transparent); + } + } + + .bg-red-400 { + background-color: var(--color-red-400); + } + + .bg-red-500 { + background-color: var(--color-red-500); + } + + .bg-red-500\/10 { + background-color: color-mix(in srgb, oklch(.637 .237 25.331) 10%, transparent); + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-red-500\/10 { + background-color: color-mix(in oklab, var(--color-red-500) 10%, transparent); + } + } + + .bg-white { + background-color: var(--color-white); + } + + .bg-white\/5 { + background-color: #ffffff0d; + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/5 { + background-color: color-mix(in oklab, var(--color-white) 5%, transparent); + } + } + + .bg-white\/10 { + background-color: #ffffff1a; + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/10 { + background-color: color-mix(in oklab, var(--color-white) 10%, transparent); + } + } + + .bg-white\/20 { + background-color: #fff3; + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-white\/20 { + background-color: color-mix(in oklab, var(--color-white) 20%, transparent); + } + } + + .bg-yellow-400 { + background-color: var(--color-yellow-400); + } + + .bg-yellow-500\/10 { + background-color: color-mix(in srgb, oklch(.795 .184 86.047) 10%, transparent); + } + + @supports (color: color-mix(in lab, red, red)) { + .bg-yellow-500\/10 { + background-color: color-mix(in oklab, var(--color-yellow-500) 10%, transparent); + } + } + + .bg-gradient-to-b { + --tw-gradient-position: to bottom in oklab; + background-image: linear-gradient(var(--tw-gradient-stops)); + } + + .bg-gradient-to-br { + --tw-gradient-position: to bottom right in oklab; + background-image: linear-gradient(var(--tw-gradient-stops)); + } + + .bg-gradient-to-l { + --tw-gradient-position: to left in oklab; + background-image: linear-gradient(var(--tw-gradient-stops)); + } + + .bg-gradient-to-r { + --tw-gradient-position: to right in oklab; + background-image: linear-gradient(var(--tw-gradient-stops)); + } + + .from-\[\#0A0F24\] { + --tw-gradient-from: #0a0f24; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-\[\#00F0FF\] { + --tw-gradient-from: #00f0ff; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-\[\#00F0FF\]\/0 { + --tw-gradient-from: oklab(0% 0 0 / 0); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-\[\#00F0FF\]\/20 { + --tw-gradient-from: oklab(87.0045% -.136493 -.0575878 / .2); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-\[\#7B61FF\] { + --tw-gradient-from: #7b61ff; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-\[\#7B61FF\]\/10 { + --tw-gradient-from: oklab(60.5679% .0582184 -.216332 / .1); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-\[\#7B61FF\]\/20 { + --tw-gradient-from: oklab(60.5679% .0582184 -.216332 / .2); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-orange-500 { + --tw-gradient-from: var(--color-orange-500); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-red-400 { + --tw-gradient-from: var(--color-red-400); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-red-500 { + --tw-gradient-from: var(--color-red-500); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .from-red-500\/20 { + --tw-gradient-from: color-mix(in srgb, oklch(.637 .237 25.331) 20%, transparent); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + @supports (color: color-mix(in lab, red, red)) { + .from-red-500\/20 { + --tw-gradient-from: color-mix(in oklab, var(--color-red-500) 20%, transparent); + } + } + + .from-transparent { + --tw-gradient-from: transparent; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .via-\[\#00F0FF\] { + --tw-gradient-via: #00f0ff; + --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + + .via-\[\#00F0FF\]\/80 { + --tw-gradient-via: oklab(87.0045% -.136493 -.0575878 / .8); + --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + + .via-gray-600 { + --tw-gradient-via: var(--color-gray-600); + --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + + .via-transparent { + --tw-gradient-via: transparent; + --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + + .via-white\/30 { + --tw-gradient-via: #ffffff4d; + --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-via-stops); + } + + @supports (color: color-mix(in lab, red, red)) { + .via-white\/30 { + --tw-gradient-via: color-mix(in oklab, var(--color-white) 30%, transparent); + } + } + + .to-\[\#00F0FF\] { + --tw-gradient-to: #00f0ff; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-\[\#00F0FF\]\/0 { + --tw-gradient-to: oklab(0% 0 0 / 0); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-\[\#00F0FF\]\/5 { + --tw-gradient-to: oklab(87.0045% -.136493 -.0575878 / .05); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-\[\#00F0FF\]\/10 { + --tw-gradient-to: oklab(87.0045% -.136493 -.0575878 / .1); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-\[\#00F0FF\]\/20 { + --tw-gradient-to: oklab(87.0045% -.136493 -.0575878 / .2); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-\[\#1a1f3a\] { + --tw-gradient-to: #1a1f3a; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-\[\#7B61FF\] { + --tw-gradient-to: #7b61ff; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-gray-600 { + --tw-gradient-to: var(--color-gray-600); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-gray-800 { + --tw-gradient-to: var(--color-gray-800); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-orange-400 { + --tw-gradient-to: var(--color-orange-400); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-red-500 { + --tw-gradient-to: var(--color-red-500); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .to-red-500\/5 { + --tw-gradient-to: color-mix(in srgb, oklch(.637 .237 25.331) 5%, transparent); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + @supports (color: color-mix(in lab, red, red)) { + .to-red-500\/5 { + --tw-gradient-to: color-mix(in oklab, var(--color-red-500) 5%, transparent); + } + } + + .to-transparent { + --tw-gradient-to: transparent; + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + + .bg-clip-text { + background-clip: text; + } + + .p-4 { + padding: calc(var(--spacing) * 4); + } + + .p-6 { + padding: calc(var(--spacing) * 6); + } + + .p-8 { + padding: calc(var(--spacing) * 8); + } + + .px-2 { + padding-inline: calc(var(--spacing) * 2); + } + + .px-4 { + padding-inline: calc(var(--spacing) * 4); + } + + .px-6 { + padding-inline: calc(var(--spacing) * 6); + } + + .px-8 { + padding-inline: calc(var(--spacing) * 8); + } + + .px-12 { + padding-inline: calc(var(--spacing) * 12); + } + + .py-0\.5 { + padding-block: calc(var(--spacing) * .5); + } + + .py-1 { + padding-block: calc(var(--spacing) * 1); + } + + .py-2 { + padding-block: calc(var(--spacing) * 2); + } + + .py-3 { + padding-block: calc(var(--spacing) * 3); + } + + .py-4 { + padding-block: calc(var(--spacing) * 4); + } + + .py-5 { + padding-block: calc(var(--spacing) * 5); + } + + .py-12 { + padding-block: calc(var(--spacing) * 12); + } + + .pb-32 { + padding-bottom: calc(var(--spacing) * 32); + } + + .text-center { + text-align: center; + } + + .text-left { + text-align: left; + } + + .text-right { + text-align: right; + } + + .align-middle { + vertical-align: middle; + } + + .text-2xl { + font-size: var(--text-2xl); + line-height: var(--tw-leading, var(--text-2xl--line-height)); + } + + .text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } + + .text-4xl { + font-size: var(--text-4xl); + line-height: var(--tw-leading, var(--text-4xl--line-height)); + } + + .text-5xl { + font-size: var(--text-5xl); + line-height: var(--tw-leading, var(--text-5xl--line-height)); + } + + .text-6xl { + font-size: var(--text-6xl); + line-height: var(--tw-leading, var(--text-6xl--line-height)); + } + + .text-lg { + font-size: var(--text-lg); + line-height: var(--tw-leading, var(--text-lg--line-height)); + } + + .text-sm { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + } + + .text-xl { + font-size: var(--text-xl); + line-height: var(--tw-leading, var(--text-xl--line-height)); + } + + .text-xs { + font-size: var(--text-xs); + line-height: var(--tw-leading, var(--text-xs--line-height)); + } + + .font-medium { + --tw-font-weight: var(--font-weight-medium); + font-weight: var(--font-weight-medium); + } + + .whitespace-nowrap { + white-space: nowrap; + } + + .text-\[\#0A0F24\] { + color: #0a0f24; + } + + .text-\[\#00F0FF\] { + color: #00f0ff; + } + + .text-\[\#00F0FF\]\/50 { + color: oklab(87.0045% -.136493 -.0575878 / .5); + } + + .text-\[\#7B61FF\] { + color: #7b61ff; + } + + .text-gray-300 { + color: var(--color-gray-300); + } + + .text-gray-400 { + color: var(--color-gray-400); + } + + .text-gray-500 { + color: var(--color-gray-500); + } + + .text-gray-600 { + color: var(--color-gray-600); + } + + .text-green-400 { + color: var(--color-green-400); + } + + .text-orange-400 { + color: var(--color-orange-400); + } + + .text-red-400 { + color: var(--color-red-400); + } + + .text-transparent { + color: #0000; + } + + .text-white { + color: var(--color-white); + } + + .text-white\/90 { + color: #ffffffe6; + } + + @supports (color: color-mix(in lab, red, red)) { + .text-white\/90 { + color: color-mix(in oklab, var(--color-white) 90%, transparent); + } + } + + .text-yellow-400 { + color: var(--color-yellow-400); + } + + .line-through { + text-decoration-line: line-through; + } + + .opacity-10 { + opacity: .1; + } + + .opacity-20 { + opacity: .2; + } + + .opacity-30 { + opacity: .3; + } + + .opacity-50 { + opacity: .5; + } + + .shadow-2xl { + --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, #00000040); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + + .shadow-\[0_0_10px_rgba\(0\,240\,255\,0\.8\)\] { + --tw-shadow: 0 0 10px var(--tw-shadow-color, #00f0ffcc); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + + .shadow-\[0_0_30px_rgba\(0\,240\,255\,0\.3\)\] { + --tw-shadow: 0 0 30px var(--tw-shadow-color, #00f0ff4d); + box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + } + + .blur-2xl { + --tw-blur: blur(var(--blur-2xl)); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + } + + .blur-3xl { + --tw-blur: blur(var(--blur-3xl)); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + } + + .blur-sm { + --tw-blur: blur(var(--blur-sm)); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + } + + .blur-xl { + --tw-blur: blur(var(--blur-xl)); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + } + + .backdrop-blur-md { + --tw-backdrop-blur: blur(var(--blur-md)); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + } + + .backdrop-blur-sm { + --tw-backdrop-blur: blur(var(--blur-sm)); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + } + + .transition { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + + .transition-all { + transition-property: all; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + + .transition-colors { + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + + .duration-300 { + --tw-duration: .3s; + transition-duration: .3s; + } + + .select-none { + -webkit-user-select: none; + user-select: none; + } + + @media (hover: hover) { + .hover\:border-\[\#7B61FF\]:hover { + border-color: #7b61ff; + } + } + + @media (hover: hover) { + .hover\:bg-\[\#00F0FF\]\/30:hover { + background-color: oklab(87.0045% -.136493 -.0575878 / .3); + } + } + + @media (hover: hover) { + .hover\:bg-\[\#7B61FF\]\/30:hover { + background-color: oklab(60.5679% .0582184 -.216332 / .3); + } + } + + @media (hover: hover) { + .hover\:text-white:hover { + color: var(--color-white); + } + } + + .focus\:border-\[\#00F0FF\]:focus { + border-color: #00f0ff; + } + + .focus\:outline-none:focus { + --tw-outline-style: none; + outline-style: none; + } + + @media (width >= 48rem) { + .md\:text-3xl { + font-size: var(--text-3xl); + line-height: var(--tw-leading, var(--text-3xl--line-height)); + } + } + + @media (width >= 48rem) { + .md\:text-4xl { + font-size: var(--text-4xl); + line-height: var(--tw-leading, var(--text-4xl--line-height)); + } + } +} + +:root { + --font-size: 16px; + --background: #fff; + --foreground: oklch(.145 0 0); + --card: #fff; + --card-foreground: oklch(.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(.145 0 0); + --primary: #030213; + --primary-foreground: oklch(1 0 0); + --secondary: oklch(.95 .0058 264.53); + --secondary-foreground: #030213; + --muted: #ececf0; + --muted-foreground: #717182; + --accent: #e9ebef; + --accent-foreground: #030213; + --destructive: #d4183d; + --destructive-foreground: #fff; + --border: #0000001a; + --input: transparent; + --input-background: #f3f3f5; + --switch-background: #cbced4; + --font-weight-medium: 500; + --font-weight-normal: 400; + --ring: oklch(.708 0 0); + --chart-1: oklch(.646 .222 41.116); + --chart-2: oklch(.6 .118 184.704); + --chart-3: oklch(.398 .07 227.392); + --chart-4: oklch(.828 .189 84.429); + --chart-5: oklch(.769 .188 70.08); + --radius: .625rem; + --sidebar: oklch(.985 0 0); + --sidebar-foreground: oklch(.145 0 0); + --sidebar-primary: #030213; + --sidebar-primary-foreground: oklch(.985 0 0); + --sidebar-accent: oklch(.97 0 0); + --sidebar-accent-foreground: oklch(.205 0 0); + --sidebar-border: oklch(.922 0 0); + --sidebar-ring: oklch(.708 0 0); +} + +.dark { + --background: oklch(.145 0 0); + --foreground: oklch(.985 0 0); + --card: oklch(.145 0 0); + --card-foreground: oklch(.985 0 0); + --popover: oklch(.145 0 0); + --popover-foreground: oklch(.985 0 0); + --primary: oklch(.985 0 0); + --primary-foreground: oklch(.205 0 0); + --secondary: oklch(.269 0 0); + --secondary-foreground: oklch(.985 0 0); + --muted: oklch(.269 0 0); + --muted-foreground: oklch(.708 0 0); + --accent: oklch(.269 0 0); + --accent-foreground: oklch(.985 0 0); + --destructive: oklch(.396 .141 25.723); + --destructive-foreground: oklch(.637 .237 25.331); + --border: oklch(.269 0 0); + --input: oklch(.269 0 0); + --ring: oklch(.439 0 0); + --font-weight-medium: 500; + --font-weight-normal: 400; + --chart-1: oklch(.488 .243 264.376); + --chart-2: oklch(.696 .17 162.48); + --chart-3: oklch(.769 .188 70.08); + --chart-4: oklch(.627 .265 303.9); + --chart-5: oklch(.645 .246 16.439); + --sidebar: oklch(.205 0 0); + --sidebar-foreground: oklch(.985 0 0); + --sidebar-primary: oklch(.488 .243 264.376); + --sidebar-primary-foreground: oklch(.985 0 0); + --sidebar-accent: oklch(.269 0 0); + --sidebar-accent-foreground: oklch(.985 0 0); + --sidebar-border: oklch(.269 0 0); + --sidebar-ring: oklch(.439 0 0); +} + +html { + font-size: var(--font-size); +} + +@property --tw-translate-x { + syntax: "*"; + inherits: false; + initial-value: 0; +} + +@property --tw-translate-y { + syntax: "*"; + inherits: false; + initial-value: 0; +} + +@property --tw-translate-z { + syntax: "*"; + inherits: false; + initial-value: 0; +} + +@property --tw-rotate-x { + syntax: "*"; + inherits: false; + initial-value: rotateX(0); +} + +@property --tw-rotate-y { + syntax: "*"; + inherits: false; + initial-value: rotateY(0); +} + +@property --tw-rotate-z { + syntax: "*"; + inherits: false; + initial-value: rotateZ(0); +} + +@property --tw-skew-x { + syntax: "*"; + inherits: false; + initial-value: skewX(0); +} + +@property --tw-skew-y { + syntax: "*"; + inherits: false; + initial-value: skewY(0); +} + +@property --tw-space-y-reverse { + syntax: "*"; + inherits: false; + initial-value: 0; +} + +@property --tw-border-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} + +@property --tw-gradient-position { + syntax: "*"; + inherits: false +} + +@property --tw-gradient-from { + syntax: ""; + inherits: false; + initial-value: #0000; +} + +@property --tw-gradient-via { + syntax: ""; + inherits: false; + initial-value: #0000; +} + +@property --tw-gradient-to { + syntax: ""; + inherits: false; + initial-value: #0000; +} + +@property --tw-gradient-stops { + syntax: "*"; + inherits: false +} + +@property --tw-gradient-via-stops { + syntax: "*"; + inherits: false +} + +@property --tw-gradient-from-position { + syntax: ""; + inherits: false; + initial-value: 0%; +} + +@property --tw-gradient-via-position { + syntax: ""; + inherits: false; + initial-value: 50%; +} + +@property --tw-gradient-to-position { + syntax: ""; + inherits: false; + initial-value: 100%; +} + +@property --tw-font-weight { + syntax: "*"; + inherits: false +} + +@property --tw-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} + +@property --tw-shadow-color { + syntax: "*"; + inherits: false +} + +@property --tw-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} + +@property --tw-inset-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} + +@property --tw-inset-shadow-color { + syntax: "*"; + inherits: false +} + +@property --tw-inset-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} + +@property --tw-ring-color { + syntax: "*"; + inherits: false +} + +@property --tw-ring-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} + +@property --tw-inset-ring-color { + syntax: "*"; + inherits: false +} + +@property --tw-inset-ring-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} + +@property --tw-ring-inset { + syntax: "*"; + inherits: false +} + +@property --tw-ring-offset-width { + syntax: ""; + inherits: false; + initial-value: 0; +} + +@property --tw-ring-offset-color { + syntax: "*"; + inherits: false; + initial-value: #fff; +} + +@property --tw-ring-offset-shadow { + syntax: "*"; + inherits: false; + initial-value: 0 0 #0000; +} + +@property --tw-blur { + syntax: "*"; + inherits: false +} + +@property --tw-brightness { + syntax: "*"; + inherits: false +} + +@property --tw-contrast { + syntax: "*"; + inherits: false +} + +@property --tw-grayscale { + syntax: "*"; + inherits: false +} + +@property --tw-hue-rotate { + syntax: "*"; + inherits: false +} + +@property --tw-invert { + syntax: "*"; + inherits: false +} + +@property --tw-opacity { + syntax: "*"; + inherits: false +} + +@property --tw-saturate { + syntax: "*"; + inherits: false +} + +@property --tw-sepia { + syntax: "*"; + inherits: false +} + +@property --tw-drop-shadow { + syntax: "*"; + inherits: false +} + +@property --tw-drop-shadow-color { + syntax: "*"; + inherits: false +} + +@property --tw-drop-shadow-alpha { + syntax: ""; + inherits: false; + initial-value: 100%; +} + +@property --tw-drop-shadow-size { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-blur { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-brightness { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-contrast { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-grayscale { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-hue-rotate { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-invert { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-opacity { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-saturate { + syntax: "*"; + inherits: false +} + +@property --tw-backdrop-sepia { + syntax: "*"; + inherits: false +} + +@property --tw-duration { + syntax: "*"; + inherits: false +} diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..b1cc5ec --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,3 @@ + +declare module "weixin-js-sdk" + diff --git a/src/utils/http/error.ts b/src/utils/http/error.ts new file mode 100644 index 0000000..6524b5f --- /dev/null +++ b/src/utils/http/error.ts @@ -0,0 +1,13 @@ +import qs from "qs"; + +/** + * 错误处理 + */ +export function errorHand() { + window.localStorage.removeItem("zustand_storage") + let location = window.location + let query = qs.parse(location.href.split('?')[1]) + delete query.code + let query2 = qs.stringify(query) + window.location.href = location.origin + location.pathname + '?' + query2 +} \ No newline at end of file diff --git a/src/utils/http/request.ts b/src/utils/http/request.ts new file mode 100644 index 0000000..c003113 --- /dev/null +++ b/src/utils/http/request.ts @@ -0,0 +1,68 @@ +import axios, {type AxiosRequestHeaders, type AxiosResponse} from "axios" +import {errorHand} from "@/utils/http/error"; +import {useUserStore} from "@/store/user-store"; +import toast from "react-hot-toast"; + +const instance = axios.create({ + baseURL: import.meta.env.VITE_WEB_URL + "/api", + timeout: 1000*300, +}) + +//拦截器 +instance.interceptors.request.use((config) => { + //当数据为formData,自动修改请求头 + if ((config.data instanceof FormData)) { + config.headers["Content-Type"] = "multipart/form-data" + } + let token = useUserStore.getState().token + if (token) { + (config.headers as AxiosRequestHeaders).Authorization = `Bearer ${token}` + } + + return config +}) + +instance.interceptors.response.use((response: AxiosResponse) => { + const {code, data, message} = response.data + + if (code === 1) { + return data + } else if (code === 0) { + toast.error(message) + return Promise.reject(new Error(message)) + } else { + if (code === 401 || code === 403) { + errorHand() + } else { + toast.error(message) + } + } +}, error => { + if (error.code === 'ECONNABORTED') { + toast.error('网速较慢,请耐心等待'); + error.config.timeout = 1000 * 60 * 3 + return instance(error.config) + } else if (error.message === 'Network Error') { + toast.error('网络中断'); + return Promise.reject() + } else { + toast.error('网络异常'); + return Promise.reject() + } +}) + + +//封装post,get +function requestPost(url: string, data = {}) { + return instance.post(url, data) +} + +function requestGet(url: string, params = {}) { + return instance.get(url, {params}) +} + +const request = { + get: requestGet, + post: requestPost +} +export default request \ No newline at end of file diff --git a/src/wx/wxLogin.ts b/src/wx/wxLogin.ts new file mode 100644 index 0000000..5e0cc60 --- /dev/null +++ b/src/wx/wxLogin.ts @@ -0,0 +1,48 @@ +import qs from "qs" +import {Login} from "@/api/wxchat"; +import {useUserStore} from "@/store/user-store"; + +/** + * snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid) + * snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 ) + */ +const scope: Array = ['snsapi_base', 'snsapi_userinfo'] +const appid = import.meta.env.VITE_APPID +let locationUrl: string = window.location.href +let webUrl: string = locationUrl.split("?")[0] + + +export default function (): Promise { + return new Promise((resolve) => { + let token = useUserStore.getState().token + if (token) { + resolve(true) + return + } + let query = qs.parse(locationUrl.split('?')[1]) + if (query.code) { + Login({ + wx_code: query.code, + ...query + }).then(res => { + if (!res.accessToken) { + delete query.code + delete query.state + webUrl = webUrl + qs.stringify(query) + hrefLogin(webUrl) + return + } + useUserStore.getState().setToken(res.accessToken); + resolve(true) + }) + } else { + hrefLogin(locationUrl) + } + }) +} + +//防止登录时,多次在url沙上添加code +function hrefLogin(redirectUrl: string) { + redirectUrl = encodeURIComponent(redirectUrl) + window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirectUrl}&response_type=code&scope=${scope[1]}#wechat_redirect` +} \ No newline at end of file diff --git a/src/wx/wxPay.ts b/src/wx/wxPay.ts new file mode 100644 index 0000000..abe78e5 --- /dev/null +++ b/src/wx/wxPay.ts @@ -0,0 +1,23 @@ +import wx from "weixin-js-sdk" + + +//打开支付,会返回回调,1为支付成功,2为取消支付 +export function wxPay(payInfoConfig: any): Promise { + return new Promise((resolve) => { + + wx.chooseWXPay({ + timestamp: payInfoConfig['timestamp'], // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 + nonceStr: payInfoConfig['nonceStr'], // 支付签名随机串,不长于 32 位 + package: payInfoConfig['package'], // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*) + signType: payInfoConfig['signType'], // 微信支付V3的传入RSA,微信支付V2的传入格式与V2统一下单的签名格式保持一致 + paySign: payInfoConfig['paySign'], // 支付签名 + success: function () { + resolve(true) + }, + cancel: function (err: any) { + console.log(err) + resolve(false) + } + }) + }) +} \ No newline at end of file diff --git a/src/wx/wxShare.ts b/src/wx/wxShare.ts new file mode 100644 index 0000000..8f6fda3 --- /dev/null +++ b/src/wx/wxShare.ts @@ -0,0 +1,82 @@ +import wx from "weixin-js-sdk" +import {getJsSdk, getShareConfig} from "@/api/wxchat"; +import qs from "qs" + +export default async function () { + let isWeXin = navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1 + if (!isWeXin) return + let query = qs.parse(window.location.search.split('?')[1]) + delete query.code + //默认分享路径 + // let defaultHref = window.location.origin + window.location.pathname + '?' + qs.stringify(query) + let data = await getJsSdk({ + url: window.location.href + }) + let shareConfig = await getShareConfig() as any + + const shareDataObj = { + title: shareConfig.share_title, + desc: shareConfig.share_sub_title, + link: window.location.href, + imgUrl: 'https://keyang2.tuzuu.com/%E6%95%88%E7%81%B5/logo.jpg' + } + wx.config({ + debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 + appId: data.jssdk.appId, // 必填,公众号的唯一标识 + timestamp: data.jssdk.timestamp, // 必填,生成签名的时间戳 + nonceStr: data.jssdk.nonceStr, // 必填,生成签名的随机串 + signature: data.jssdk.signature,// 必填,签名 + jsApiList: data.jssdk.jsApiList, // 必填,需要使用的JS接口列表 + openTagList: ['wx-open-launch-weapp'] + }) + wx.ready(function () { + if (wx.updateAppMessageShareData) { + wx.updateAppMessageShareData({ + title: shareDataObj.title, + desc: shareDataObj.desc, + link: shareDataObj.link, + imgUrl: shareDataObj.imgUrl, + success: () => { + console.log('分享朋友成功') + }, + }) + } + if (wx.updateTimelineShareData) { + wx.updateTimelineShareData({ + title: shareDataObj.title, + link: shareDataObj.link, + imgUrl: shareDataObj.imgUrl, + success: () => { + console.log('分享朋友圈') + }, + }) + } + if (wx.onMenuShareAppMessage) { + wx.onMenuShareAppMessage({ + + title: shareDataObj.title, + desc: shareDataObj.desc, + link: shareDataObj.link, + imgUrl: shareDataObj.imgUrl, + success: () => { + console.log('旧版本分享朋友成功') + }, + cancel: () => { + } + }) + } + if (wx.onMenuShareTimeline) { + wx.onMenuShareTimeline({ + title: shareDataObj.title, + link: shareDataObj.link, + imgUrl: shareDataObj.imgUrl, + success: () => { + console.log('旧版本分享朋友圈') + }, + cancel: () => { + } + }) + } + }) + +} diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..099e0de --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], + "module": "ESNext", + "types": [ + "vite/client" + ], + "skipLibCheck": true, + /* Bundler mode */ + "moduleResolution": "node", + "verbatimModuleSyntax": false, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + /* Linting */ + "noUnusedLocals": false, + "noUnusedParameters": false, + "baseUrl": "./", + "paths": { + "@/*": [ + "src/*" + ] + } + }, + "include": [ + "src" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..67d9d9c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,6 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + ] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..ab634af --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,25 @@ +import {defineConfig} from 'vite'; +import react from '@vitejs/plugin-react-swc'; +import {resolve} from "path"; + +const pathResolve = (dir: string): any => { + return resolve(__dirname, ".", dir) +} +const alias: Record = { + '@': pathResolve("src") +} + +export default defineConfig({ + plugins: [ + react(), + ], + server: { + host: true, + }, + resolve: { + alias + }, + build: { + outDir: './xiaoling_dist', + } +}); \ No newline at end of file