diff --git a/site/.npmrc b/site/.npmrc new file mode 100644 index 00000000..6971e863 --- /dev/null +++ b/site/.npmrc @@ -0,0 +1,2 @@ +ignore-workspace=true +lockfile-dir=. diff --git a/site/README.md b/site/README.md new file mode 100644 index 00000000..2cb954c4 --- /dev/null +++ b/site/README.md @@ -0,0 +1,63 @@ +# Prompt Optimizer 官网 + +本目录是 `always200.com` 对应的独立官网工程。 + +它与产品站、文档站彻底分离: + +- `always200.com`:官网(当前目录) +- `docs.always200.com`:文档站(`mkdocs/`) +- `prompt.always200.com`:产品站(根项目) + +## 目录职责 + +- 技术栈:独立 Vite 静态站 +- 部署目标:独立 Vercel 项目 +- Vercel Root Directory:`site/` +- 官网不复用根项目的业务代码、UI 组件和构建链路 +- 官网保留自己的 `package.json`、`pnpm-lock.yaml`、`vercel.json` + +## 本地运行 + +在 `site/` 目录内执行: + +```bash +pnpm install +pnpm dev +``` + +启动后访问终端输出的地址,默认通常是: + +- `http://127.0.0.1:5173/` + +如果端口被占用,Vite 会自动切换到其他端口。 + +## 语言切换 + +- 默认支持中文与英文两种官网文案 +- 首次访问会根据浏览器语言自动选择中文或英文 +- 用户手动切换语言后,会记住选择,后续访问优先使用上次手动选择 +- 当前官网采用单页静态渲染,不额外引入前端 i18n 框架 + +## 本地构建与静态预览 + +```bash +pnpm build +python -m http.server 8011 -d dist +``` + +访问: + +- `http://127.0.0.1:8011/` + +## 路由说明 + +- `/`:官网首页 +- `/docs`:跳转到 `https://docs.always200.com/` +- `/docs/:path*`:跳转到 `https://docs.always200.com/:path*` + +## 部署 + +- 独立 Vercel 项目 +- Root Directory:`site/` +- 正式域名:`always200.com` +- `www.always200.com` 建议在 Vercel Dashboard 中跳转到 `always200.com` diff --git a/site/index.html b/site/index.html new file mode 100644 index 00000000..baa45399 --- /dev/null +++ b/site/index.html @@ -0,0 +1,27 @@ + + + + + + Prompt Optimizer | 提示词优化,不该只靠感觉 + + + + + + + + + + + + +
+ + diff --git a/site/package.json b/site/package.json new file mode 100644 index 00000000..8f2b56b7 --- /dev/null +++ b/site/package.json @@ -0,0 +1,14 @@ +{ + "name": "prompt-optimizer-site", + "private": true, + "version": "0.1.0", + "packageManager": "pnpm@10.6.1", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^7.1.7" + } +} diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml new file mode 100644 index 00000000..2332d3d5 --- /dev/null +++ b/site/pnpm-lock.yaml @@ -0,0 +1,673 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + vite: + specifier: ^7.1.7 + version: 7.3.1(@types/node@22.19.15)(jiti@2.6.1)(yaml@2.8.2) + +packages: + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + 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 + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + 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.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + 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'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + 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 + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + +snapshots: + + '@esbuild/aix-ppc64@0.27.4': + optional: true + + '@esbuild/android-arm64@0.27.4': + optional: true + + '@esbuild/android-arm@0.27.4': + optional: true + + '@esbuild/android-x64@0.27.4': + optional: true + + '@esbuild/darwin-arm64@0.27.4': + optional: true + + '@esbuild/darwin-x64@0.27.4': + optional: true + + '@esbuild/freebsd-arm64@0.27.4': + optional: true + + '@esbuild/freebsd-x64@0.27.4': + optional: true + + '@esbuild/linux-arm64@0.27.4': + optional: true + + '@esbuild/linux-arm@0.27.4': + optional: true + + '@esbuild/linux-ia32@0.27.4': + optional: true + + '@esbuild/linux-loong64@0.27.4': + optional: true + + '@esbuild/linux-mips64el@0.27.4': + optional: true + + '@esbuild/linux-ppc64@0.27.4': + optional: true + + '@esbuild/linux-riscv64@0.27.4': + optional: true + + '@esbuild/linux-s390x@0.27.4': + optional: true + + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': + optional: true + + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': + optional: true + + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': + optional: true + + '@esbuild/sunos-x64@0.27.4': + optional: true + + '@esbuild/win32-arm64@0.27.4': + optional: true + + '@esbuild/win32-ia32@0.27.4': + optional: true + + '@esbuild/win32-x64@0.27.4': + optional: true + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@types/estree@1.0.8': {} + + '@types/node@22.19.15': + dependencies: + undici-types: 6.21.0 + optional: true + + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fsevents@2.3.3: + optional: true + + jiti@2.6.1: + optional: true + + nanoid@3.3.11: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + + source-map-js@1.2.1: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + undici-types@6.21.0: + optional: true + + vite@7.3.1(@types/node@22.19.15)(jiti@2.6.1)(yaml@2.8.2): + dependencies: + esbuild: 0.27.4 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.8 + rollup: 4.59.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.15 + fsevents: 2.3.3 + jiti: 2.6.1 + yaml: 2.8.2 + + yaml@2.8.2: + optional: true diff --git a/site/pnpm-workspace.yaml b/site/pnpm-workspace.yaml new file mode 100644 index 00000000..3334c0e4 --- /dev/null +++ b/site/pnpm-workspace.yaml @@ -0,0 +1 @@ +packages: [] diff --git a/site/public/images/demo/knowledge-graph-extractor.png b/site/public/images/demo/knowledge-graph-extractor.png new file mode 100644 index 00000000..79b6c33d Binary files /dev/null and b/site/public/images/demo/knowledge-graph-extractor.png differ diff --git a/site/public/images/favicon.png b/site/public/images/favicon.png new file mode 100644 index 00000000..28f4397f Binary files /dev/null and b/site/public/images/favicon.png differ diff --git a/site/public/images/logo.png b/site/public/images/logo.png new file mode 100644 index 00000000..e142037f Binary files /dev/null and b/site/public/images/logo.png differ diff --git a/site/public/images/og-cover.png b/site/public/images/og-cover.png new file mode 100644 index 00000000..79b6c33d Binary files /dev/null and b/site/public/images/og-cover.png differ diff --git a/site/src/main.js b/site/src/main.js new file mode 100644 index 00000000..59d137d9 --- /dev/null +++ b/site/src/main.js @@ -0,0 +1,815 @@ +import './styles.css' + +const STORAGE_KEY = 'prompt-optimizer-site-locale' +const THEME_STORAGE_KEY = 'prompt-optimizer-site-theme' +const SUPPORTED_LOCALES = ['zh-CN', 'en'] +const THEME_MODES = ['system', 'dark', 'light'] + +const translations = { + 'zh-CN': { + htmlLang: 'zh-CN', + title: 'Prompt Optimizer | 提示词优化,应该基于真实结果', + description: '在一个工作台里完成提示词优化、真实测试、结果评估与建议应用。', + brandAriaLabel: 'Prompt Optimizer 官网首页', + nav: { + product: '产品', + docs: '文档', + github: 'GitHub', + githubLabel: '开源仓库', + themeAria: '切换主题模式', + themeLabels: { + system: '自动', + dark: '深', + light: '浅' + }, + locale: 'EN', + localeAria: '切换到英文', + menuAria: '切换导航菜单' + }, + hero: { + eyebrow: '开源提示词工作台', + titleTop: '提示词优化', + titleMid: '应该基于', + titleBottom: '真实结果', + lead: '在一个工作台里完成优化、测试、评估,让建议回到当前提示词。', + primary: '打开产品', + secondary: '查看文档', + stats: [ + { value: '4 步闭环', label: '从测试到应用' }, + { value: '多工作区', label: '单条、变量、上下文' }, + { value: '结果证据', label: '改动基于输出' } + ], + visualLabel: '结果闭环', + visualTitle: '左改右测,结论回流', + visualSummary: '左侧改提示词,右侧看结果,再把结论带回工作区。', + visualTags: ['左侧工作区', '右侧测试', '单结果评估'], + screenshotBadge: '工作台预览', + screenshotAlt: 'Prompt Optimizer 工作台截图' + }, + value: { + kicker: '为什么不同', + title: '不是改字工具,而是结果驱动的工作台', + lead: '先看真实输出,再决定提示词到底要不要改。', + manifestoLabel: '结果优先', + manifestoTitle: '先看结果,再决定修改', + manifestoBody: '它把分析、评估、对比和应用建议收进同一条可回溯的工作流。', + principles: [ + { + index: '01', + title: '改动必须回应输出', + body: '不是润色文本,而是修正结果偏差。', + tags: ['分析', '评估', '应用'] + }, + { + index: '02', + title: '任务边界要清楚', + body: '分析、评估、对比各自独立建模。' + }, + { + index: '03', + title: '结论要能继续迭代', + body: '输出结论最终要回到当前工作区。' + } + ] + }, + workflow: { + kicker: '工作方式', + title: '用一次闭环,把改动落回真实结果', + lead: '左侧设计提示词,右侧验证结果,再把结论收回来。', + steps: [ + { + label: '工作区', + title: '设计层', + body: '在左侧持续改写当前可编辑提示词。' + }, + { + label: '测试', + title: '执行层', + body: '在右侧用真实输入和模型配置跑结果。' + }, + { + label: '回流', + title: '决策层', + body: '把结果收敛成可继续应用的改动建议。' + } + ] + }, + scenario: { + kicker: '工作区覆盖', + title: '适配不同的提示词结构', + lead: '单条提示词、变量模板和上下文链路,都能放进同一套验证流程。', + columns: { + type: '结构类型', + fit: '适用内容', + capability: '关键能力' + }, + cards: [ + { + label: '单条提示词', + title: 'system / user 单提示词', + body: '适合优化角色、规则与输出格式。', + tags: ['system', 'user', '聚焦分析'] + }, + { + label: '变量模板', + title: '变量模板', + body: '把主题、语气和角色收进模板后再验证。', + tags: ['占位变量', '真实输入', '模板复用'] + }, + { + label: '上下文链路', + title: '多消息上下文', + body: '当 system、user 与上下文共同影响结果时仍可分析。', + tags: ['system + user', '上下文', '多消息'] + } + ] + }, + access: { + kicker: '开放与入口', + title: '开源可信,也能立刻开始', + lead: '看清它的开放能力,再选最顺手的入口。', + proof: { + label: 'GitHub 仓库', + title: 'linshenkx/prompt-optimizer', + body: '同一套产品能力覆盖 Web、桌面版、自托管、Docker 和 MCP。', + facts: ['AGPL-3.0', 'Web / Desktop / Extension', 'Docker / MCP'], + primary: '查看 GitHub', + secondary: '下载 Release' + }, + entries: [ + { + title: '在线产品', + body: '直接进入工作台开始优化。', + href: 'https://prompt.always200.com' + }, + { + title: '下载桌面版', + body: '从 Releases 获取安装包。', + href: 'https://github.com/linshenkx/prompt-optimizer/releases' + }, + { + title: 'Chrome 插件', + body: '从 Chrome Web Store 安装入口。', + href: 'https://chromewebstore.google.com/detail/prompt-optimizer/cakkkhboolfnadechdlgdcnjammejlna' + }, + { + title: 'Docker / MCP', + body: '适合自托管和外部集成。', + href: 'https://docs.always200.com/deployment/docker-basic/' + } + ] + }, + footer: { + title: 'Prompt Optimizer', + body: '让提示词优化回到真实结果。', + product: '产品', + docs: '文档', + github: 'GitHub' + } + }, + en: { + htmlLang: 'en', + title: 'Prompt Optimizer | Prompt optimization should follow real outputs', + description: 'One workspace for prompt iteration, real testing, result evaluation, and applying improvements.', + brandAriaLabel: 'Prompt Optimizer website home', + nav: { + product: 'Product', + docs: 'Docs', + github: 'GitHub', + githubLabel: 'Open-source repository', + themeAria: 'Switch theme mode', + themeLabels: { + system: 'Auto', + dark: 'Dark', + light: 'Light' + }, + locale: '中文', + localeAria: 'Switch to Chinese', + menuAria: 'Toggle navigation menu' + }, + hero: { + eyebrow: 'Open-source prompt workspace', + titleTop: 'Prompt optimization', + titleMid: 'should follow', + titleBottom: 'real outputs', + lead: 'Iterate, test, evaluate, and return changes in one workspace.', + primary: 'Open Product', + secondary: 'Read Docs', + stats: [ + { value: '4-Step', label: 'From test to apply' }, + { value: 'Multi-Workspace', label: 'Single, variable, context' }, + { value: 'Evidence-Based', label: 'Edits follow outputs' } + ], + visualLabel: 'Closed Loop', + visualTitle: 'Edit left, test right', + visualSummary: 'Refine the prompt, inspect the result, then send the conclusion back.', + visualTags: ['Editable workspace', 'Real test run', 'Result evaluation'], + screenshotBadge: 'Workspace preview', + screenshotAlt: 'Prompt Optimizer workspace screenshot' + }, + value: { + kicker: 'Why it is different', + title: 'Not a rewrite toy, but an output-driven workspace', + lead: 'See the output first, then decide whether the prompt should change.', + manifestoLabel: 'Result First', + manifestoTitle: 'Look at the result before the rewrite', + manifestoBody: 'It keeps analysis, evaluation, compare, and apply actions inside one traceable loop.', + principles: [ + { + index: '01', + title: 'Edits must answer the output', + body: 'The goal is not prettier wording, but better execution.', + tags: ['Analysis', 'Evaluation', 'Apply'] + }, + { + index: '02', + title: 'Action boundaries stay clear', + body: 'Analysis, evaluation, and compare are modeled separately.' + }, + { + index: '03', + title: 'Findings should keep iterating', + body: 'Every conclusion should flow back into the editable workspace.' + } + ] + }, + workflow: { + kicker: 'How it works', + title: 'Close the loop from edit to real result', + lead: 'Design on the left, validate on the right, then fold the conclusion back.', + steps: [ + { + label: 'Workspace', + title: 'Design layer', + body: 'Keep refining the editable prompt in the left workspace.' + }, + { + label: 'Run', + title: 'Execution layer', + body: 'Use real inputs and model settings on the right.' + }, + { + label: 'Return', + title: 'Decision layer', + body: 'Turn results into changes that can be applied back.' + } + ] + }, + scenario: { + kicker: 'Workspace coverage', + title: 'Handle more than a single prompt string', + lead: 'Single prompts, variable templates, and context chains all fit into the same validation loop.', + columns: { + type: 'Structure', + fit: 'Best for', + capability: 'Key capability' + }, + cards: [ + { + label: 'Single prompt', + title: 'System / user single prompt', + body: 'Best for roles, rules, and output instructions.', + tags: ['system', 'user', 'focused analysis'] + }, + { + label: 'Variables', + title: 'Variable templates', + body: 'Validate reusable templates with real values.', + tags: ['variables', 'real input', 'reuse'] + }, + { + label: 'Context chain', + title: 'Multi-message context', + body: 'Useful when system, user, and context all affect the result.', + tags: ['system + user', 'context', 'multi-message'] + } + ] + }, + access: { + kicker: 'Open and access', + title: 'Open-source credibility with immediate entry points', + lead: 'Check the open surface first, then choose the path that fits you.', + proof: { + label: 'GitHub repository', + title: 'linshenkx/prompt-optimizer', + body: 'The same product surface spans web, desktop, self-hosting, Docker, and MCP.', + facts: ['AGPL-3.0', 'Web / Desktop / Extension', 'Docker / MCP'], + primary: 'View on GitHub', + secondary: 'Download Releases' + }, + entries: [ + { + title: 'Web App', + body: 'Open the workspace and start optimizing.', + href: 'https://prompt.always200.com' + }, + { + title: 'Desktop Downloads', + body: 'Get installers and archives from Releases.', + href: 'https://github.com/linshenkx/prompt-optimizer/releases' + }, + { + title: 'Chrome Extension', + body: 'Install it from the Chrome Web Store.', + href: 'https://chromewebstore.google.com/detail/prompt-optimizer/cakkkhboolfnadechdlgdcnjammejlna' + }, + { + title: 'Docker / MCP', + body: 'Best for self-hosting and integrations.', + href: 'https://docs.always200.com/deployment/docker-basic/' + } + ] + }, + footer: { + title: 'Prompt Optimizer', + body: 'Bring prompt optimization back to real outputs.', + product: 'Product', + docs: 'Docs', + github: 'GitHub' + } + } +} + +function normalizeLocale(locale) { + if (!locale) return 'zh-CN' + if (locale.startsWith('zh')) return 'zh-CN' + return 'en' +} + +function getInitialLocale() { + const storedLocale = window.localStorage.getItem(STORAGE_KEY) + if (storedLocale && SUPPORTED_LOCALES.includes(storedLocale)) { + return storedLocale + } + + const browserLocale = normalizeLocale(navigator.language || navigator.languages?.[0] || 'zh-CN') + return SUPPORTED_LOCALES.includes(browserLocale) ? browserLocale : 'zh-CN' +} + +function normalizeThemeMode(themeMode) { + if (THEME_MODES.includes(themeMode)) return themeMode + return 'system' +} + +function getInitialThemeMode() { + return normalizeThemeMode(window.localStorage.getItem(THEME_STORAGE_KEY) || 'system') +} + +function resolveTheme(themeMode) { + if (themeMode === 'light' || themeMode === 'dark') return themeMode + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' +} + +function getNextThemeMode(themeMode) { + if (themeMode === 'system') return 'dark' + if (themeMode === 'dark') return 'light' + return 'system' +} + +function renderLocaleButton(copy) { + return ` + + ` +} + +function renderThemeButton(copy, themeMode) { + return ` + + ` +} + +function renderThemeIcon(themeMode) { + if (themeMode === 'dark') { + return ` + + + + ` + } + + if (themeMode === 'light') { + return ` + + + + + ` + } + + return ` + + + + + + ` +} + +function renderGithubPill(copy) { + return ` + + + ${copy.nav.github} + GitHub stars + + ` +} + +function renderNav(copy, themeMode) { + return ` + ${copy.nav.product} + ${copy.nav.docs} + ${renderGithubPill(copy)} + ${renderThemeButton(copy, themeMode)} + ${renderLocaleButton(copy)} + ` +} + +function renderStats(stats) { + return stats + .map( + (item) => ` +
+ ${item.value} + ${item.label} +
+ ` + ) + .join('') +} + +function renderPills(items, className = '') { + return items.map((item) => `${item}`).join('') +} + +function renderApp(locale, themeMode) { + const copy = translations[locale] + const resolvedTheme = resolveTheme(themeMode) + + document.documentElement.lang = copy.htmlLang + document.documentElement.dataset.locale = locale + document.documentElement.dataset.theme = resolvedTheme + document.documentElement.dataset.themeMode = themeMode + document.title = copy.title + + const descriptionMeta = document.querySelector('meta[name="description"]') + const ogDescriptionMeta = document.querySelector('meta[property="og:description"]') + const ogTitleMeta = document.querySelector('meta[property="og:title"]') + const themeColorMeta = document.querySelector('meta[name="theme-color"]') + + if (descriptionMeta) descriptionMeta.setAttribute('content', copy.description) + if (ogDescriptionMeta) ogDescriptionMeta.setAttribute('content', copy.description) + if (ogTitleMeta) ogTitleMeta.setAttribute('content', copy.title) + if (themeColorMeta) themeColorMeta.setAttribute('content', resolvedTheme === 'dark' ? '#081120' : '#f8fbfe') + + document.querySelector('#app').innerHTML = ` +
+ + + + +
+
+
+
+ + ${copy.hero.eyebrow} +
+

+ ${copy.hero.titleTop} + ${copy.hero.titleMid} + ${copy.hero.titleBottom} +

+

${copy.hero.lead}

+ +
+ ${renderStats(copy.hero.stats)} +
+
+ +
+
+ ${copy.hero.visualLabel} +

${copy.hero.visualTitle}

+
+
+
${copy.hero.screenshotBadge}
+ ${copy.hero.screenshotAlt} +
+
+ ${copy.hero.visualSummary} +
+ ${renderPills(copy.hero.visualTags)} +
+
+
+
+ +
+
+
+

${copy.value.kicker}

+

${copy.value.title}

+

${copy.value.lead}

+
+ ${copy.value.manifestoLabel} +

${copy.value.manifestoTitle}

+

${copy.value.manifestoBody}

+
+
+
+ ${copy.value.principles + .map( + (principle, index) => ` +
+ ${principle.index} +
+

${principle.title}

+

${principle.body}

+ ${ + principle.tags + ? ` +
+ ${renderPills(principle.tags)} +
+ ` + : '' + } +
+
+ ` + ) + .join('')} +
+
+
+ +
+
+

${copy.workflow.kicker}

+

${copy.workflow.title}

+

${copy.workflow.lead}

+
+
+ ${copy.workflow.steps + .map( + (step, index) => ` +
+
+ 0${index + 1} +
+
+ ${step.label} +

${step.title}

+

${step.body}

+
+
+ ` + ) + .join('')} +
+
+ +
+
+
+

${copy.scenario.kicker}

+

${copy.scenario.title}

+

${copy.scenario.lead}

+
+
+
+ ${copy.scenario.columns.type} + ${copy.scenario.columns.fit} + ${copy.scenario.columns.capability} +
+ ${copy.scenario.cards + .map( + (card, index) => ` +
+
+ 0${index + 1} + ${card.label} +
+
+

${card.title}

+

${card.body}

+
+
+ ${renderPills(card.tags)} +
+
+ ` + ) + .join('')} +
+
+
+ +
+
+

${copy.access.kicker}

+

${copy.access.title}

+

${copy.access.lead}

+
+ +
+ ${copy.access.entries + .map( + (entry, index) => ` + + ${entry.title} + ${entry.body} + + ` + ) + .join('')} +
+
+
+ + +
+ ` + + bindInteractions(locale, themeMode) + bindRevealAnimations() + bindMotionEffects() +} + +function bindInteractions(locale, themeMode) { + const menuButton = document.querySelector('.site-menu-button') + const nav = document.querySelector('.site-nav') + + if (menuButton && nav) { + menuButton.addEventListener('click', () => { + const expanded = menuButton.getAttribute('aria-expanded') === 'true' + menuButton.setAttribute('aria-expanded', String(!expanded)) + nav.classList.toggle('site-nav--open', !expanded) + }) + } + + document.querySelectorAll('[data-locale-toggle="true"]').forEach((button) => { + button.addEventListener('click', () => { + const nextLocale = locale === 'zh-CN' ? 'en' : 'zh-CN' + window.localStorage.setItem(STORAGE_KEY, nextLocale) + currentLocale = nextLocale + renderApp(currentLocale, currentThemeMode) + }) + }) + + document.querySelectorAll('[data-theme-toggle="true"]').forEach((button) => { + button.addEventListener('click', () => { + const nextThemeMode = getNextThemeMode(themeMode) + window.localStorage.setItem(THEME_STORAGE_KEY, nextThemeMode) + currentThemeMode = nextThemeMode + renderApp(currentLocale, currentThemeMode) + }) + }) +} + +function bindRevealAnimations() { + const revealTargets = document.querySelectorAll('[data-reveal]') + + if (!revealTargets.length) return + + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches + + if (prefersReducedMotion) { + revealTargets.forEach((node) => node.classList.add('is-visible')) + return + } + + requestAnimationFrame(() => { + requestAnimationFrame(() => { + revealTargets.forEach((node) => node.classList.add('is-visible')) + }) + }) +} + +function bindMotionEffects() { + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches + const prefersFinePointer = window.matchMedia('(pointer: fine)').matches + + if (prefersReducedMotion || !prefersFinePointer) return + + const clamp = (value, min, max) => Math.min(max, Math.max(min, value)) + + const bindPointerSurface = (selector, prefix, maxTilt = 6, maxShift = 16) => { + const element = document.querySelector(selector) + if (!element) return + + const reset = () => { + element.style.setProperty(`--${prefix}-pointer-x`, '50%') + element.style.setProperty(`--${prefix}-pointer-y`, '50%') + element.style.setProperty(`--${prefix}-tilt-x`, '0deg') + element.style.setProperty(`--${prefix}-tilt-y`, '0deg') + element.style.setProperty(`--${prefix}-shift-x`, '0px') + element.style.setProperty(`--${prefix}-shift-y`, '0px') + } + + const update = (event) => { + const rect = element.getBoundingClientRect() + const px = clamp(((event.clientX - rect.left) / rect.width) * 100, 0, 100) + const py = clamp(((event.clientY - rect.top) / rect.height) * 100, 0, 100) + const nx = clamp((px - 50) / 50, -1, 1) + const ny = clamp((py - 50) / 50, -1, 1) + + element.style.setProperty(`--${prefix}-pointer-x`, `${px.toFixed(2)}%`) + element.style.setProperty(`--${prefix}-pointer-y`, `${py.toFixed(2)}%`) + element.style.setProperty(`--${prefix}-tilt-x`, `${(-ny * maxTilt).toFixed(2)}deg`) + element.style.setProperty(`--${prefix}-tilt-y`, `${(nx * maxTilt).toFixed(2)}deg`) + element.style.setProperty(`--${prefix}-shift-x`, `${(nx * maxShift).toFixed(2)}px`) + element.style.setProperty(`--${prefix}-shift-y`, `${(ny * maxShift).toFixed(2)}px`) + } + + reset() + element.addEventListener('pointermove', update) + element.addEventListener('pointerleave', reset) + } + + bindPointerSurface('.hero', 'hero', 5.5, 18) + bindPointerSurface('.proof-strip', 'proof', 3.5, 10) +} + +let currentLocale = getInitialLocale() +let currentThemeMode = getInitialThemeMode() + +const colorSchemeMedia = window.matchMedia('(prefers-color-scheme: dark)') + +if (typeof colorSchemeMedia.addEventListener === 'function') { + colorSchemeMedia.addEventListener('change', () => { + if (currentThemeMode === 'system') { + renderApp(currentLocale, currentThemeMode) + } + }) +} + +renderApp(currentLocale, currentThemeMode) diff --git a/site/src/styles.css b/site/src/styles.css new file mode 100644 index 00000000..60a73031 --- /dev/null +++ b/site/src/styles.css @@ -0,0 +1,2052 @@ +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700;800&family=Sora:wght@500;600;700;800&display=swap'); + +:root { + color-scheme: light; + --page-top: #fbfdff; + --page-bottom: #f1f5fb; + --page-grid: rgba(148, 163, 184, 0.08); + --glow-left: rgba(56, 189, 248, 0.2); + --glow-right: rgba(37, 99, 235, 0.14); + --surface: rgba(255, 255, 255, 0.82); + --surface-strong: rgba(255, 255, 255, 0.94); + --surface-alt: rgba(247, 250, 255, 0.92); + --text: #091120; + --text-strong: #07101d; + --muted: #52657c; + --muted-strong: #334155; + --line: rgba(148, 163, 184, 0.22); + --line-strong: rgba(37, 99, 235, 0.2); + --accent: #2563eb; + --accent-2: #0ea5e9; + --shadow-sm: 0 12px 28px rgba(15, 23, 42, 0.06); + --shadow-md: 0 22px 54px rgba(15, 23, 42, 0.08); + --shadow-lg: 0 34px 80px rgba(15, 23, 42, 0.14); + --header-bg: rgba(255, 255, 255, 0.78); + --header-border: rgba(148, 163, 184, 0.24); + --header-shadow: 0 18px 40px rgba(15, 23, 42, 0.08); + --nav-text: #4b5d74; + --nav-text-strong: #091120; + --nav-hover-bg: rgba(255, 255, 255, 0.92); + --nav-hover-border: rgba(148, 163, 184, 0.22); + --hero-bg: linear-gradient(132deg, #07101f 0%, #0d1a31 48%, #091223 100%); + --hero-border: rgba(37, 99, 235, 0.18); + --hero-inner-border: rgba(191, 219, 254, 0.1); + --hero-grid: rgba(148, 163, 184, 0.08); + --hero-text: #f8fbff; + --hero-muted: #a8bbd8; + --hero-chip-bg: rgba(255, 255, 255, 0.06); + --hero-chip-border: rgba(148, 163, 184, 0.18); + --hero-shot-border: rgba(96, 165, 250, 0.16); + --hero-shot-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(96, 165, 250, 0.04)); + --hero-shot-shadow: 0 26px 58px rgba(2, 6, 23, 0.28); + --hero-divider: rgba(148, 163, 184, 0.16); + --workflow-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(244, 248, 255, 0.96)); + --workflow-border: rgba(148, 163, 184, 0.22); + --workflow-line: rgba(37, 99, 235, 0.24); + --workflow-text: #0b1626; + --workflow-muted: #51637a; + --matrix-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(247, 250, 255, 0.92)); + --matrix-head-bg: rgba(37, 99, 235, 0.045); + --repo-bg: linear-gradient(135deg, rgba(8, 15, 28, 0.96), rgba(14, 24, 44, 0.94)); + --repo-border: rgba(96, 165, 250, 0.18); + --repo-text: #f8fbff; + --repo-muted: #a8bbd8; + --repo-chip-bg: rgba(255, 255, 255, 0.06); + --repo-chip-border: rgba(125, 211, 252, 0.16); + --entry-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(247, 250, 255, 0.92)); + --entry-hover-bg: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(245, 249, 255, 0.96)); +} + +html[data-theme='dark'] { + color-scheme: dark; + --page-top: #030813; + --page-bottom: #07101c; + --page-grid: rgba(96, 165, 250, 0.08); + --glow-left: rgba(56, 189, 248, 0.14); + --glow-right: rgba(37, 99, 235, 0.16); + --surface: rgba(9, 16, 29, 0.78); + --surface-strong: rgba(10, 18, 33, 0.92); + --surface-alt: rgba(11, 19, 36, 0.9); + --text: #f4f8ff; + --text-strong: #ffffff; + --muted: #9fb0c8; + --muted-strong: #d6e2f7; + --line: rgba(96, 165, 250, 0.14); + --line-strong: rgba(125, 211, 252, 0.22); + --shadow-sm: 0 12px 28px rgba(2, 6, 23, 0.2); + --shadow-md: 0 22px 56px rgba(2, 6, 23, 0.28); + --shadow-lg: 0 32px 78px rgba(2, 6, 23, 0.42); + --header-bg: rgba(8, 13, 24, 0.74); + --header-border: rgba(96, 165, 250, 0.16); + --header-shadow: 0 18px 38px rgba(2, 6, 23, 0.32); + --nav-text: #d6e1f5; + --nav-text-strong: #f8fbff; + --nav-hover-bg: rgba(255, 255, 255, 0.05); + --nav-hover-border: rgba(96, 165, 250, 0.16); + --hero-bg: linear-gradient(132deg, #040a14 0%, #0a1324 48%, #050c18 100%); + --hero-border: rgba(96, 165, 250, 0.16); + --hero-inner-border: rgba(191, 219, 254, 0.06); + --hero-grid: rgba(96, 165, 250, 0.08); + --hero-text: #f8fbff; + --hero-muted: #9fb0cb; + --hero-chip-bg: rgba(255, 255, 255, 0.04); + --hero-chip-border: rgba(96, 165, 250, 0.14); + --hero-shot-border: rgba(96, 165, 250, 0.18); + --hero-shot-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(96, 165, 250, 0.04)); + --hero-shot-shadow: 0 30px 64px rgba(2, 6, 23, 0.42); + --hero-divider: rgba(96, 165, 250, 0.14); + --workflow-bg: linear-gradient(180deg, rgba(7, 13, 24, 0.9), rgba(10, 17, 30, 0.92)); + --workflow-border: rgba(96, 165, 250, 0.14); + --workflow-line: rgba(125, 211, 252, 0.28); + --workflow-text: #f8fbff; + --workflow-muted: #9fb0cb; + --matrix-bg: linear-gradient(180deg, rgba(8, 15, 28, 0.92), rgba(10, 18, 34, 0.9)); + --matrix-head-bg: rgba(255, 255, 255, 0.03); + --repo-bg: linear-gradient(135deg, rgba(6, 11, 20, 0.98), rgba(12, 21, 38, 0.96)); + --repo-border: rgba(125, 211, 252, 0.18); + --repo-text: #f8fbff; + --repo-muted: #b7c7de; + --repo-chip-bg: rgba(255, 255, 255, 0.04); + --repo-chip-border: rgba(125, 211, 252, 0.14); + --entry-bg: linear-gradient(180deg, rgba(9, 16, 29, 0.92), rgba(10, 18, 33, 0.88)); + --entry-hover-bg: linear-gradient(180deg, rgba(10, 18, 33, 0.94), rgba(13, 22, 40, 0.9)); +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + overflow-x: clip; +} + +body { + margin: 0; + min-width: 320px; + font-family: 'Noto Sans SC', sans-serif; + color: var(--text); + background: + radial-gradient(circle at 10% 8%, var(--glow-left), transparent 18%), + radial-gradient(circle at 86% 10%, var(--glow-right), transparent 22%), + linear-gradient(180deg, var(--page-top) 0%, var(--page-bottom) 100%); + background-attachment: fixed; + overflow-x: clip; +} + +html[data-locale='en'] body { + font-family: 'Sora', 'Noto Sans SC', sans-serif; +} + +html[data-locale='zh-CN'] .hero h1, +html[data-locale='zh-CN'] .section h2, +html[data-locale='zh-CN'] .value-manifesto h3, +html[data-locale='zh-CN'] .value-principle__body h3, +html[data-locale='zh-CN'] .workflow-node h3, +html[data-locale='zh-CN'] .scenario-row__body h3 { + font-family: 'Noto Sans SC', sans-serif; +} + +a { + color: inherit; + text-decoration: none; +} + +img { + display: block; + max-width: 100%; +} + +button { + font: inherit; +} + +figure { + margin: 0; +} + +#app { + min-height: 100vh; +} + +.site-shell { + position: relative; + isolation: isolate; + width: min(1240px, calc(100vw - 32px)); + margin: 0 auto; + padding: 22px 0 64px; +} + +.site-background { + position: absolute; + inset: 0; + z-index: -1; + overflow: hidden; + pointer-events: none; +} + +.site-glow { + position: absolute; + filter: blur(56px); + opacity: 0.55; +} + +.site-glow--left { + top: 72px; + left: -80px; + width: 320px; + height: 320px; + background: radial-gradient(circle, var(--glow-left) 0%, transparent 72%); + animation: siteGlowDriftLeft 18s ease-in-out infinite; +} + +.site-glow--right { + top: 28px; + right: -56px; + width: 380px; + height: 380px; + background: radial-gradient(circle, var(--glow-right) 0%, transparent 74%); + animation: siteGlowDriftRight 22s ease-in-out infinite; +} + +.site-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(var(--page-grid) 1px, transparent 1px), + linear-gradient(90deg, var(--page-grid) 1px, transparent 1px); + background-size: 56px 56px; + mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.55), transparent 88%); + animation: siteGridShift 30s linear infinite; +} + +.site-header { + position: sticky; + top: 14px; + z-index: 30; + display: flex; + align-items: center; + justify-content: space-between; + gap: 18px; + padding: 14px 18px; + border: 1px solid var(--header-border); + border-radius: 24px; + background: var(--header-bg); + backdrop-filter: blur(18px); + box-shadow: var(--header-shadow); +} + +.site-brand { + display: inline-flex; + align-items: center; + gap: 12px; + min-width: 0; +} + +.site-brand__logo { + width: 34px; + height: 34px; + border-radius: 12px; + box-shadow: 0 10px 22px rgba(37, 99, 235, 0.16); +} + +.site-brand__text { + font-family: 'Sora', sans-serif; + font-size: 1rem; + font-weight: 700; + letter-spacing: -0.02em; + white-space: nowrap; +} + +.site-menu-button { + display: none; + width: 44px; + height: 44px; + padding: 10px; + border: 1px solid var(--header-border); + border-radius: 14px; + background: var(--surface-strong); + color: var(--nav-text-strong); + cursor: pointer; +} + +.site-menu-button span { + display: block; + height: 2px; + margin: 5px 0; + border-radius: 999px; + background: currentColor; +} + +.site-nav { + display: flex; + align-items: center; + gap: 10px; +} + +.site-nav a, +.theme-switch, +.locale-switch { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 42px; + padding: 0 14px; + border: 1px solid transparent; + border-radius: 999px; + color: var(--nav-text); + background: transparent; + font-size: 0.92rem; + font-weight: 600; + transition: + color 180ms ease, + border-color 180ms ease, + background-color 180ms ease, + box-shadow 180ms ease, + transform 180ms ease; + cursor: pointer; +} + +.site-nav a:hover, +.theme-switch:hover, +.locale-switch:hover { + color: var(--nav-text-strong); + background: var(--nav-hover-bg); + border-color: var(--nav-hover-border); + box-shadow: var(--shadow-sm); + transform: translateY(-1px); +} + +.github-pill { + display: inline-flex; + align-items: center; + gap: 10px; + min-height: 42px; + padding: 0 8px 0 10px; + border: 1px solid var(--header-border); + border-radius: 999px; + background: var(--surface-strong); + color: var(--nav-text-strong); + box-shadow: var(--shadow-sm); + transition: + transform 180ms ease, + box-shadow 180ms ease, + border-color 180ms ease; +} + +.github-pill:hover { + transform: translateY(-1px); + border-color: var(--line-strong); + box-shadow: var(--shadow-md); +} + +.github-pill__icon { + display: inline-flex; + width: 18px; + height: 18px; +} + +.github-pill__icon svg { + width: 100%; + height: 100%; +} + +.github-pill__text { + font-size: 0.92rem; + font-weight: 700; +} + +.github-pill__badge { + height: 20px; + border-radius: 999px; +} + +.theme-switch { + gap: 8px; + background: var(--surface-strong); + border-color: var(--header-border); + color: var(--nav-text-strong); +} + +.theme-switch__icon { + display: inline-flex; + width: 16px; + height: 16px; +} + +.theme-switch__icon svg { + width: 100%; + height: 100%; +} + +.theme-switch__label, +.locale-switch { + font-family: 'Sora', sans-serif; + font-size: 0.8rem; + font-weight: 700; + letter-spacing: 0.04em; +} + +.section { + position: relative; + margin-top: 44px; +} + +.section-head { + max-width: 760px; +} + +.section-head--center { + margin: 0 auto; + text-align: center; +} + +.section-kicker { + margin: 0 0 12px; + color: var(--accent); + font-family: 'Sora', sans-serif; + font-size: 0.76rem; + font-weight: 700; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +html[data-locale='zh-CN'] .section-kicker, +html[data-locale='zh-CN'] .eyebrow, +html[data-locale='zh-CN'] .signal-label, +html[data-locale='zh-CN'] .value-manifesto__label, +html[data-locale='zh-CN'] .proof-strip__label { + letter-spacing: 0.04em; +} + +.section h2 { + margin: 0; + font-family: 'Sora', sans-serif; + font-size: clamp(2rem, 2.9vw, 3rem); + line-height: 1.08; + letter-spacing: -0.05em; + text-wrap: balance; +} + +.section-lead { + max-width: 32rem; + margin: 14px 0 0; + color: var(--muted); + line-height: 1.75; +} + +[data-reveal] { + opacity: 0; + filter: blur(10px); + transform: translate3d(0, 24px, 0); + transition: + opacity 680ms cubic-bezier(0.22, 1, 0.36, 1), + transform 680ms cubic-bezier(0.22, 1, 0.36, 1), + filter 760ms cubic-bezier(0.22, 1, 0.36, 1); + transition-delay: var(--reveal-delay, 0ms); + will-change: opacity, transform, filter; +} + +[data-reveal].is-visible { + opacity: 1; + filter: blur(0); + transform: translate3d(0, 0, 0); +} + +.button { + display: inline-flex; + align-items: center; + justify-content: center; + position: relative; + min-height: 50px; + padding: 0 22px; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--surface-strong); + color: var(--text-strong); + font-weight: 700; + overflow: hidden; + transition: + transform 180ms ease, + box-shadow 180ms ease, + border-color 180ms ease, + background-color 180ms ease; +} + +.button:hover { + transform: translateY(-1px); + border-color: var(--line-strong); + box-shadow: var(--shadow-sm); +} + +.button--primary { + border-color: transparent; + background: linear-gradient(135deg, var(--accent), var(--accent-2)); + color: #ffffff; + box-shadow: 0 18px 34px rgba(37, 99, 235, 0.22); +} + +.button--primary::before { + content: ''; + position: absolute; + inset: -2px auto -2px -28%; + width: 34%; + background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.7) 52%, transparent 100%); + opacity: 0; + transform: skewX(-20deg) translateX(-180%); + transition: + transform 720ms cubic-bezier(0.22, 1, 0.36, 1), + opacity 320ms ease; + pointer-events: none; +} + +.button--primary:hover::before { + opacity: 0.88; + transform: skewX(-20deg) translateX(430%); +} + +.hero { + position: relative; + --hero-pointer-x: 50%; + --hero-pointer-y: 50%; + --hero-tilt-x: 0deg; + --hero-tilt-y: 0deg; + --hero-shift-x: 0px; + --hero-shift-y: 0px; + display: grid; + grid-template-columns: minmax(0, 0.95fr) minmax(500px, 1.05fr); + gap: 44px; + margin-top: 28px; + padding: 46px 44px; + border: 1px solid var(--hero-border); + border-radius: 40px; + background: var(--hero-bg); + box-shadow: var(--shadow-lg); + perspective: 1600px; + overflow: hidden; +} + +.hero::before { + content: ''; + position: absolute; + inset: 0; + background-image: + linear-gradient(var(--hero-grid) 1px, transparent 1px), + linear-gradient(90deg, var(--hero-grid) 1px, transparent 1px); + background-size: 42px 42px; + background-position: 0 0; + mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.74), transparent 94%); + opacity: 0.5; + animation: heroGridDrift 24s linear infinite; + pointer-events: none; +} + +.hero::after { + content: ''; + position: absolute; + inset: 14px; + border-radius: 28px; + box-shadow: inset 0 0 0 1px var(--hero-inner-border); + background: + radial-gradient(circle at var(--hero-pointer-x, 50%) var(--hero-pointer-y, 50%), rgba(96, 165, 250, 0.16), transparent 24%), + radial-gradient(circle at 84% 22%, rgba(59, 130, 246, 0.12), transparent 18%); + pointer-events: none; +} + +.hero-copy, +.hero-visual { + position: relative; + z-index: 1; +} + +.hero-copy { + display: grid; + align-content: start; + color: var(--hero-text); +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 10px; + width: fit-content; + padding: 10px 16px; + border: 1px solid var(--hero-chip-border); + border-radius: 999px; + background: var(--hero-chip-bg); + color: var(--hero-text); + font-family: 'Sora', sans-serif; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; +} + +.eyebrow img { + width: 16px; + height: 16px; + border-radius: 999px; +} + +.hero-title { + display: grid; + gap: 4px; + margin: 22px 0 0; +} + +.hero-title__line { + display: block; + max-width: 100%; +} + +.hero-title__line--top { + color: var(--hero-text); + font-family: 'Sora', sans-serif; + font-size: clamp(2.4rem, 3.3vw, 3.65rem); + font-weight: 700; + line-height: 1; + letter-spacing: -0.055em; +} + +.hero-title__line--mid { + color: #9cc8ff; + font-family: 'Sora', sans-serif; + font-size: clamp(1.05rem, 1.25vw, 1.26rem); + font-weight: 700; + line-height: 1.18; + letter-spacing: 0.04em; +} + +.hero-title__line--bottom { + color: transparent; + font-family: 'Sora', sans-serif; + font-size: clamp(4rem, 5.55vw, 6rem); + font-weight: 800; + line-height: 0.92; + letter-spacing: -0.06em; + background: linear-gradient(135deg, #f8fbff 0%, #d7e6ff 42%, #5cbcff 100%); + background-size: 180% 100%; + background-position: 0% 50%; + -webkit-background-clip: text; + background-clip: text; + filter: drop-shadow(0 16px 30px rgba(37, 99, 235, 0.18)); + animation: heroTitleShift 11s ease-in-out infinite; +} + +html[data-locale='zh-CN'] .hero-title__line { + white-space: nowrap; +} + +.hero-lead { + max-width: 24rem; + margin: 20px 0 0; + color: var(--hero-muted); + line-height: 1.72; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 28px; +} + +.hero .button { + background: var(--hero-chip-bg); + border-color: var(--hero-chip-border); + color: var(--hero-text); + box-shadow: none; +} + +.hero .button:hover { + border-color: rgba(125, 211, 252, 0.28); + box-shadow: 0 16px 30px rgba(2, 6, 23, 0.18); +} + +.hero .button--primary { + border-color: transparent; + background: linear-gradient(135deg, var(--accent), var(--accent-2)); + color: #ffffff; + box-shadow: 0 20px 38px rgba(37, 99, 235, 0.28); +} + +.hero-proof { + display: grid; + grid-template-columns: repeat(3, minmax(0, max-content)); + gap: 22px; + align-items: start; + width: fit-content; + max-width: 100%; + margin-top: 28px; + padding-top: 18px; + border-top: 1px solid var(--hero-divider); +} + +.hero-stat { + position: relative; + display: grid; + gap: 4px; + padding-top: 10px; + animation: heroStatFloat 7s ease-in-out infinite; +} + +.hero-stat::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 28px; + height: 1px; + background: linear-gradient(90deg, rgba(125, 211, 252, 0.95), transparent 100%); +} + +.hero-stat:nth-child(2) { + animation-delay: 0.5s; +} + +.hero-stat:nth-child(3) { + animation-delay: 1s; +} + +.hero-stat strong { + color: #7dd3fc; + font-family: 'Sora', sans-serif; + font-size: 0.98rem; + font-weight: 800; + letter-spacing: -0.02em; +} + +.hero-stat span { + color: var(--hero-muted); + font-size: 0.78rem; + line-height: 1.45; +} + +.hero-visual { + display: grid; + align-content: start; + gap: 14px; + color: var(--hero-text); +} + +.hero-visual__meta { + display: flex; + align-items: baseline; + gap: 12px; + padding: 0 2px; +} + +.hero-visual__meta p { + margin: 0; + color: var(--hero-muted); + font-size: 0.82rem; + line-height: 1.35; +} + +.signal-label, +.value-manifesto__label, +.proof-strip__label, +.workflow-index, +.workflow-card__label, +.scenario-card__label { + display: inline-flex; + align-items: center; + justify-content: center; + width: fit-content; + min-height: 30px; + padding: 0 12px; + border-radius: 999px; + font-family: 'Sora', sans-serif; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; +} + +.signal-label { + border: 1px solid rgba(125, 211, 252, 0.14); + background: rgba(43, 195, 255, 0.08); + color: #7dd3fc; +} + +.hero-shot { + position: relative; + padding: 18px; + border: 1px solid var(--hero-shot-border); + border-radius: 30px; + background: var(--hero-shot-bg); + box-shadow: var(--hero-shot-shadow); + overflow: hidden; + transform: + translate3d(var(--hero-shift-x, 0px), calc(var(--hero-shift-y, 0px) * -0.55), 0) + rotateX(var(--hero-tilt-x, 0deg)) + rotateY(var(--hero-tilt-y, 0deg)); + transform-style: preserve-3d; + transition: + transform 220ms ease, + box-shadow 220ms ease, + border-color 220ms ease; + will-change: transform, box-shadow; +} + +.hero-shot::before { + content: ''; + position: absolute; + inset: -12% auto -18% -34%; + z-index: 0; + width: 44%; + background: linear-gradient(90deg, transparent 0%, rgba(96, 165, 250, 0.05) 24%, rgba(125, 211, 252, 0.25) 52%, rgba(255, 255, 255, 0.1) 64%, transparent 100%); + filter: blur(8px); + opacity: 0.9; + transform: skewX(-24deg); + animation: heroScanSweep 7.5s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite; + pointer-events: none; +} + +.hero-shot::after { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.08), transparent 26%, transparent 76%, rgba(255, 255, 255, 0.04)), + repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.035) 1px, transparent 1px, transparent 6px); + pointer-events: none; +} + +.hero-shot__badge { + position: absolute; + top: -14px; + left: 18px; + z-index: 2; + display: inline-flex; + align-items: center; + min-height: 30px; + padding: 0 12px; + border: 1px solid var(--hero-chip-border); + border-radius: 999px; + background: rgba(5, 11, 20, 0.9); + color: var(--hero-text); + font-family: 'Sora', sans-serif; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + box-shadow: 0 12px 30px rgba(2, 6, 23, 0.24); + animation: badgeFloat 6s ease-in-out infinite; +} + +.hero-shot img { + position: relative; + z-index: 1; + width: 100%; + border: 1px solid rgba(96, 165, 250, 0.1); + border-radius: 22px; + transform: translateZ(18px); +} + +.hero-caption { + display: grid; + gap: 10px; + max-width: 29rem; + padding: 0 2px; +} + +.hero-caption strong { + color: var(--hero-text); + font-size: 0.86rem; + font-weight: 500; + line-height: 1.56; +} + +.hero-caption__tags, +.value-principle__tags, +.proof-strip__facts, +.scenario-row__tags { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.hero-caption__tags span, +.value-principle__tags span, +.proof-strip__facts span, +.scenario-row__tags span { + display: inline-flex; + align-items: center; + min-height: 26px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--surface-strong); + color: var(--muted-strong); + font-size: 0.72rem; + font-weight: 600; +} + +.hero-caption__tags span { + border-color: var(--hero-chip-border); + background: var(--hero-chip-bg); + color: var(--hero-muted); + transition: + transform 180ms ease, + border-color 180ms ease, + background-color 180ms ease; +} + +.hero:hover .hero-caption__tags span:nth-child(odd) { + transform: translateY(-2px); +} + +.hero:hover .hero-caption__tags span:nth-child(even) { + transform: translateY(1px); +} + +.section--value { + padding: 8px 4px 0; +} + +.value-layout { + display: grid; + grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr); + gap: 48px; + align-items: start; +} + +.value-head { + margin-bottom: 0; + max-width: 28rem; +} + +.value-head .section-lead { + max-width: 24rem; +} + +.value-manifesto { + margin-top: 28px; + padding-top: 18px; + border-top: 1px solid var(--line); +} + +.value-manifesto__label { + border: 1px solid var(--line); + background: var(--surface-alt); + color: var(--accent); +} + +.value-manifesto h3 { + margin: 18px 0 12px; + max-width: 10ch; + font-size: clamp(1.7rem, 2.2vw, 2.25rem); + line-height: 1.08; + letter-spacing: -0.05em; +} + +.value-manifesto p { + max-width: 24rem; + margin: 0; + color: var(--muted); + line-height: 1.8; +} + +.value-principles { + display: grid; + border-top: 1px solid var(--line); +} + +.value-principle { + display: grid; + grid-template-columns: 72px minmax(0, 1fr); + gap: 18px; + padding: 22px 0; + border-bottom: 1px solid var(--line); +} + +.value-principle__index { + color: rgba(37, 99, 235, 0.48); + font-family: 'Sora', sans-serif; + font-size: 0.84rem; + font-weight: 800; + letter-spacing: 0.12em; +} + +.value-principle__body h3 { + margin: 0 0 8px; + font-size: 1.08rem; + line-height: 1.42; +} + +.value-principle__body p { + margin: 0; + color: var(--muted); + line-height: 1.72; +} + +.value-principle__tags { + margin-top: 12px; +} + +.button--light { + border-color: var(--repo-chip-border); + background: rgba(255, 255, 255, 0.04); + color: var(--repo-text); + box-shadow: none; +} + +.button--light:hover { + background: rgba(255, 255, 255, 0.08); + border-color: rgba(125, 211, 252, 0.28); + box-shadow: 0 18px 34px rgba(2, 6, 23, 0.22); +} + +.section--workflow { + position: relative; + padding: 38px 36px 34px; + border: 1px solid var(--workflow-border); + border-radius: 34px; + background: var(--workflow-bg); + box-shadow: var(--shadow-md); + overflow: hidden; +} + +.section--workflow::before { + content: ''; + position: absolute; + inset: auto 10% 10% 10%; + height: 180px; + background: radial-gradient(circle at 50% 50%, rgba(96, 165, 250, 0.12), transparent 68%); + filter: blur(24px); + opacity: 0.55; + pointer-events: none; +} + +.workflow-head { + max-width: 42rem; +} + +.workflow-head .section-lead { + max-width: 34rem; + margin-left: auto; + margin-right: auto; +} + +.workflow-line { + position: relative; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 30px; + margin-top: 42px; + padding-top: 8px; +} + +.workflow-line::before { + content: ''; + position: absolute; + top: 20px; + left: 6%; + right: 6%; + height: 1px; + background: linear-gradient(90deg, transparent 0%, var(--workflow-line) 12%, var(--workflow-line) 88%, transparent 100%); +} + +.workflow-line::after { + content: ''; + position: absolute; + top: 18px; + left: 8%; + width: 18%; + height: 4px; + border-radius: 999px; + background: linear-gradient(90deg, transparent 0%, rgba(59, 130, 246, 0.96) 35%, rgba(125, 211, 252, 0.88) 58%, transparent 100%); + filter: blur(0.3px); + opacity: 0.92; + animation: workflowSignalHorizontal 4.8s ease-in-out infinite; +} + +.workflow-node { + position: relative; + display: grid; + gap: 18px; +} + +.workflow-node--2 { + margin-top: 28px; +} + +.workflow-node--3 { + margin-top: 10px; +} + +.workflow-node__marker { + position: relative; + z-index: 1; + display: flex; + align-items: center; + min-height: 40px; +} + +.workflow-node__marker::before { + content: ''; + position: absolute; + left: 14px; + top: 50%; + width: 12px; + height: 12px; + border-radius: 999px; + background: linear-gradient(135deg, var(--accent), var(--accent-2)); + box-shadow: 0 0 0 10px rgba(37, 99, 235, 0.12); + transform: translate(-50%, -50%); + animation: workflowPulse 2.8s ease-in-out infinite; +} + +.workflow-node__marker::after { + content: ''; + position: absolute; + left: 14px; + top: 50%; + width: 24px; + height: 24px; + border: 1px solid rgba(96, 165, 250, 0.26); + border-radius: 999px; + transform: translate(-50%, -50%) scale(0.82); + opacity: 0.76; + animation: workflowRing 2.8s ease-out infinite; +} + +.workflow-node--2 .workflow-node__marker::before, +.workflow-node--2 .workflow-node__marker::after { + animation-delay: 0.48s; +} + +.workflow-node--3 .workflow-node__marker::before, +.workflow-node--3 .workflow-node__marker::after { + animation-delay: 0.96s; +} + +.workflow-index { + position: relative; + z-index: 1; + margin-left: 30px; + border: 1px solid var(--workflow-border); + background: var(--surface-strong); + color: var(--accent); +} + +.workflow-node__body { + display: grid; + gap: 12px; + max-width: 18rem; + padding-left: 2px; + transition: transform 180ms ease; +} + +.workflow-card__label { + border: 1px solid var(--workflow-border); + background: transparent; + color: var(--accent); +} + +.workflow-node h3 { + margin: 0; + color: var(--workflow-text); + font-size: clamp(1.18rem, 1.5vw, 1.42rem); + line-height: 1.24; + letter-spacing: -0.04em; +} + +.workflow-node p { + max-width: 17rem; + margin: 0; + color: var(--workflow-muted); + line-height: 1.72; +} + +.workflow-node:hover .workflow-node__body { + transform: translateY(-2px); +} + +.section--scenario { + padding-top: 4px; +} + +.scenario-layout { + display: grid; + grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr); + gap: 34px; + align-items: start; +} + +.scenario-head { + max-width: 26rem; + padding-top: 10px; +} + +.scenario-head .section-lead { + max-width: 23rem; +} + +.scenario-matrix { + border: 1px solid var(--line); + border-radius: 30px; + background: var(--matrix-bg); + box-shadow: var(--shadow-md); + overflow: hidden; +} + +.scenario-matrix__head, +.scenario-row { + display: grid; + grid-template-columns: minmax(220px, 0.88fr) minmax(250px, 1fr) minmax(260px, 1.08fr); + gap: 20px; + align-items: center; +} + +.scenario-matrix__head { + padding: 18px 24px; + background: var(--matrix-head-bg); + color: var(--muted); + font-family: 'Sora', sans-serif; + font-size: 0.76rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.scenario-row { + padding: 22px 24px; + border-top: 1px solid var(--line); + transition: background-color 180ms ease; +} + +.scenario-row:hover { + background: rgba(255, 255, 255, 0.04); +} + +.scenario-row__meta { + display: grid; + gap: 10px; +} + +.scenario-row__index { + color: rgba(37, 99, 235, 0.48); + font-family: 'Sora', sans-serif; + font-size: 0.8rem; + font-weight: 800; + letter-spacing: 0.12em; +} + +.scenario-card__label { + border: 1px solid var(--line); + background: var(--surface-alt); + color: var(--accent); +} + +.scenario-row__body h3 { + margin: 0 0 7px; + color: var(--text-strong); + font-size: 1.04rem; + line-height: 1.36; +} + +.scenario-row__body p { + max-width: 22rem; + margin: 0; + color: var(--muted); + line-height: 1.7; +} + +.scenario-row__tags { + align-content: start; +} + +.scenario-row__tags span { + background: transparent; +} + +.section--access { + margin-top: 54px; +} + +.section--access .section-head { + max-width: 31rem; +} + +.proof-strip { + position: relative; + --proof-pointer-x: 50%; + --proof-pointer-y: 50%; + --proof-tilt-x: 0deg; + --proof-tilt-y: 0deg; + --proof-shift-x: 0px; + --proof-shift-y: 0px; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(220px, auto); + gap: 26px; + align-items: center; + margin-top: 26px; + padding: 30px 30px 28px; + border: 1px solid var(--repo-border); + border-radius: 32px; + background: var(--repo-bg); + color: var(--repo-text); + box-shadow: var(--shadow-lg); + transform: + perspective(1200px) + translate3d(calc(var(--proof-shift-x, 0px) * 0.2), calc(var(--proof-shift-y, 0px) * -0.2), 0) + rotateX(calc(var(--proof-tilt-x, 0deg) * 0.35)) + rotateY(calc(var(--proof-tilt-y, 0deg) * 0.35)); + transition: + transform 220ms ease, + box-shadow 220ms ease, + border-color 220ms ease; + overflow: hidden; +} + +.proof-strip::before { + content: ''; + position: absolute; + inset: 0; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 26%, transparent 74%, rgba(255, 255, 255, 0.04)), + radial-gradient(circle at var(--proof-pointer-x, 50%) var(--proof-pointer-y, 50%), rgba(96, 165, 250, 0.16), transparent 28%), + radial-gradient(circle at 82% 16%, rgba(96, 165, 250, 0.14), transparent 30%); + pointer-events: none; +} + +.proof-strip::after { + content: ''; + position: absolute; + inset: -36% auto -36% -20%; + width: 34%; + background: linear-gradient(90deg, transparent 0%, rgba(96, 165, 250, 0.08) 28%, rgba(125, 211, 252, 0.28) 52%, transparent 100%); + filter: blur(12px); + opacity: 0.8; + transform: skewX(-24deg); + animation: proofSweep 9.4s ease-in-out infinite; + pointer-events: none; +} + +.proof-strip__main, +.proof-strip__actions { + position: relative; + z-index: 1; +} + +.proof-strip__top { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 18px; +} + +.proof-strip__title { + display: grid; + gap: 10px; +} + +.proof-strip__label { + border: 1px solid var(--repo-chip-border); + background: var(--repo-chip-bg); + color: #9cc8ff; +} + +.proof-strip__title strong { + font-family: 'Sora', sans-serif; + font-size: clamp(1.22rem, 1.6vw, 1.52rem); + font-weight: 700; + letter-spacing: -0.03em; +} + +.proof-strip__stars { + height: 28px; + border-radius: 999px; + flex-shrink: 0; +} + +.proof-strip p { + max-width: 38rem; + margin: 14px 0 0; + color: var(--repo-muted); + line-height: 1.75; +} + +.proof-strip__facts { + margin-top: 16px; +} + +.proof-strip__facts span { + border-color: var(--repo-chip-border); + background: var(--repo-chip-bg); + color: var(--repo-muted); +} + +.proof-strip__actions { + display: grid; + gap: 12px; +} + +.proof-strip__actions .button { + min-width: 220px; +} + +.entry-shelf { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 14px; + margin-top: 18px; +} + +.entry-card { + position: relative; + display: grid; + gap: 10px; + min-height: 148px; + padding: 20px 18px; + border: 1px solid var(--line); + border-radius: 24px; + background: var(--entry-bg); + box-shadow: var(--shadow-sm); + overflow: hidden; + transition: + transform 180ms ease, + box-shadow 180ms ease, + border-color 180ms ease, + background-color 180ms ease; +} + +.entry-card::before { + content: ''; + position: absolute; + inset: 0 auto auto 0; + width: 100%; + height: 3px; + background: linear-gradient(90deg, rgba(37, 99, 235, 0.58), rgba(14, 165, 233, 0)); + opacity: 0.7; + transform-origin: left center; + animation: entrySignal 6s ease-in-out infinite; +} + +.entry-card::after { + content: ''; + position: absolute; + right: 18px; + bottom: 18px; + width: 28px; + height: 28px; + border: 1px solid var(--line); + border-radius: 999px; + background: rgba(37, 99, 235, 0.04); + opacity: 0; + transform: translate3d(-6px, 6px, 0); + transition: + opacity 180ms ease, + transform 180ms ease, + border-color 180ms ease, + background-color 180ms ease; +} + +.entry-card:hover { + transform: translateY(-2px); + border-color: var(--line-strong); + background: var(--entry-hover-bg); + box-shadow: var(--shadow-md); +} + +.entry-card:hover::after { + opacity: 1; + transform: translate3d(0, 0, 0); + border-color: var(--line-strong); + background: rgba(37, 99, 235, 0.08); +} + +.entry-card:nth-child(2)::before { + animation-delay: 0.6s; +} + +.entry-card:nth-child(3)::before { + animation-delay: 1.2s; +} + +.entry-card:nth-child(4)::before { + animation-delay: 1.8s; +} + +.entry-card strong { + position: relative; + z-index: 1; + color: var(--text-strong); + font-size: 1rem; + line-height: 1.36; +} + +.entry-card span { + position: relative; + z-index: 1; + max-width: 15ch; + color: var(--muted); + font-size: 0.92rem; + line-height: 1.68; +} + +.site-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + margin-top: 38px; + padding: 22px 6px 8px; + border-top: 1px solid var(--line); +} + +.site-footer__copy { + display: grid; + gap: 6px; +} + +.site-footer__copy strong { + font-family: 'Sora', sans-serif; + font-size: 1rem; + font-weight: 700; +} + +.site-footer__copy p { + margin: 0; + color: var(--muted); + font-size: 0.92rem; +} + +.site-footer__links { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; + gap: 10px; +} + +.site-footer__links a { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 40px; + padding: 0 14px; + border: 1px solid transparent; + border-radius: 999px; + color: var(--muted-strong); + font-size: 0.92rem; + font-weight: 600; + transition: + color 180ms ease, + border-color 180ms ease, + background-color 180ms ease, + box-shadow 180ms ease; +} + +.site-footer__links a:hover { + color: var(--text-strong); + background: var(--surface-strong); + border-color: var(--line); + box-shadow: var(--shadow-sm); +} + +.site-footer .theme-switch, +.site-footer .locale-switch { + min-height: 40px; +} + +@keyframes siteGlowDriftLeft { + 0%, + 100% { + transform: translate3d(0, 0, 0) scale(1); + opacity: 0.52; + } + 50% { + transform: translate3d(28px, 20px, 0) scale(1.08); + opacity: 0.7; + } +} + +@keyframes siteGlowDriftRight { + 0%, + 100% { + transform: translate3d(0, 0, 0) scale(1); + opacity: 0.48; + } + 50% { + transform: translate3d(-32px, 26px, 0) scale(1.1); + opacity: 0.66; + } +} + +@keyframes siteGridShift { + 0% { + background-position: 0 0, 0 0; + } + 100% { + background-position: 0 56px, 56px 0; + } +} + +@keyframes heroGridDrift { + 0% { + background-position: 0 0, 0 0; + } + 100% { + background-position: 0 42px, 42px 0; + } +} + +@keyframes heroTitleShift { + 0%, + 100% { + background-position: 0% 50%; + filter: drop-shadow(0 16px 30px rgba(37, 99, 235, 0.18)); + } + 50% { + background-position: 100% 50%; + filter: drop-shadow(0 20px 40px rgba(37, 99, 235, 0.28)); + } +} + +@keyframes heroScanSweep { + 0%, + 14% { + transform: translate3d(-180%, 0, 0) skewX(-24deg); + opacity: 0; + } + 22% { + opacity: 0.95; + } + 46% { + transform: translate3d(340%, 0, 0) skewX(-24deg); + opacity: 0.7; + } + 100% { + transform: translate3d(340%, 0, 0) skewX(-24deg); + opacity: 0; + } +} + +@keyframes badgeFloat { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-3px); + } +} + +@keyframes heroStatFloat { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-3px); + } +} + +@keyframes workflowPulse { + 0%, + 100% { + box-shadow: 0 0 0 10px rgba(37, 99, 235, 0.1); + transform: translate(-50%, -50%) scale(1); + } + 50% { + box-shadow: 0 0 0 16px rgba(37, 99, 235, 0.05); + transform: translate(-50%, -50%) scale(1.08); + } +} + +@keyframes workflowRing { + 0% { + opacity: 0.72; + transform: translate(-50%, -50%) scale(0.78); + } + 70% { + opacity: 0; + transform: translate(-50%, -50%) scale(1.5); + } + 100% { + opacity: 0; + transform: translate(-50%, -50%) scale(1.5); + } +} + +@keyframes workflowSignalHorizontal { + 0% { + transform: translateX(0); + opacity: 0; + } + 12% { + opacity: 1; + } + 72% { + opacity: 0.95; + } + 100% { + transform: translateX(392%); + opacity: 0; + } +} + +@keyframes workflowSignalVertical { + 0% { + transform: translateY(0); + opacity: 0; + } + 14% { + opacity: 1; + } + 72% { + opacity: 0.92; + } + 100% { + transform: translateY(360%); + opacity: 0; + } +} + +@keyframes proofSweep { + 0%, + 12% { + transform: translate3d(-180%, 0, 0) skewX(-24deg); + opacity: 0; + } + 24% { + opacity: 0.86; + } + 52% { + transform: translate3d(420%, 0, 0) skewX(-24deg); + opacity: 0.72; + } + 100% { + transform: translate3d(420%, 0, 0) skewX(-24deg); + opacity: 0; + } +} + +@keyframes entrySignal { + 0%, + 100% { + opacity: 0.52; + transform: scaleX(0.48); + } + 50% { + opacity: 0.9; + transform: scaleX(1); + } +} + +@media (max-width: 1100px) { + .site-shell { + width: min(100vw - 24px, 1240px); + } + + .hero { + grid-template-columns: 1fr; + gap: 30px; + padding: 40px 34px; + } + + .hero-visual { + max-width: 820px; + } + + .value-layout, + .scenario-layout { + grid-template-columns: 1fr; + gap: 28px; + } + + .scenario-head { + max-width: 38rem; + padding-top: 0; + } + + .proof-strip { + grid-template-columns: 1fr; + } + + .proof-strip__actions { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .proof-strip__actions .button { + min-width: 0; + width: 100%; + } + + .entry-shelf { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 920px) { + .site-shell { + width: min(100vw - 18px, 1240px); + padding-top: 14px; + } + + .site-header { + padding: 12px 14px; + border-radius: 20px; + } + + .site-menu-button { + display: inline-flex; + align-items: center; + justify-content: center; + } + + .site-nav { + position: absolute; + top: calc(100% + 10px); + left: 0; + right: 0; + display: none; + flex-direction: column; + align-items: stretch; + padding: 14px; + border: 1px solid var(--header-border); + border-radius: 20px; + background: var(--header-bg); + backdrop-filter: blur(18px); + box-shadow: var(--header-shadow); + } + + .site-nav--open { + display: flex; + } + + .site-nav a, + .github-pill, + .theme-switch, + .locale-switch { + width: 100%; + justify-content: space-between; + } + + .hero { + padding: 34px 24px; + border-radius: 32px; + } + + .hero-title__line--top { + font-size: clamp(2rem, 7vw, 3.1rem); + } + + .hero-title__line--bottom { + font-size: clamp(3rem, 12vw, 4.8rem); + } + + .hero-proof { + grid-template-columns: repeat(2, minmax(0, max-content)); + gap: 16px 20px; + } + + .section { + margin-top: 36px; + } + + .section--workflow { + padding: 32px 24px; + } + + .workflow-line { + grid-template-columns: 1fr; + gap: 26px; + margin-top: 34px; + padding: 2px 0 0 6px; + } + + .workflow-line::before { + top: 0; + bottom: 0; + left: 13px; + right: auto; + width: 1px; + height: auto; + background: linear-gradient(180deg, transparent 0%, var(--workflow-line) 12%, var(--workflow-line) 88%, transparent 100%); + } + + .workflow-line::after { + top: 0; + left: 11px; + width: 4px; + height: 22%; + background: linear-gradient(180deg, transparent 0%, rgba(59, 130, 246, 0.95) 34%, rgba(125, 211, 252, 0.9) 56%, transparent 100%); + animation: workflowSignalVertical 4.8s ease-in-out infinite; + } + + .workflow-node, + .workflow-node--2, + .workflow-node--3 { + margin-top: 0; + } + + .workflow-node__marker { + min-height: 32px; + } + + .workflow-node__body { + max-width: none; + padding-left: 22px; + } + + .workflow-node p { + max-width: none; + } + + .scenario-matrix { + border-radius: 24px; + } + + .scenario-matrix__head { + display: none; + } + + .scenario-row { + grid-template-columns: 1fr; + gap: 14px; + padding: 20px 18px; + } + + .scenario-row__body p { + max-width: none; + } + + .scenario-row__tags span { + background: var(--surface-alt); + } + + .proof-strip { + padding: 26px 22px 24px; + border-radius: 28px; + } + + .proof-strip__top { + flex-direction: column; + align-items: flex-start; + } + + .proof-strip__actions { + grid-template-columns: 1fr; + } + + .site-footer { + flex-direction: column; + align-items: flex-start; + } + + .site-footer__links { + justify-content: flex-start; + } +} + +@media (max-width: 680px) { + .site-shell { + width: calc(100vw - 14px); + padding-bottom: 42px; + } + + .site-brand__text { + font-size: 0.92rem; + } + + .hero { + margin-top: 20px; + padding: 30px 18px 24px; + gap: 24px; + } + + .hero-title { + gap: 6px; + margin-top: 16px; + } + + .hero-title__line--mid { + font-size: 0.98rem; + } + + .hero-lead { + max-width: 18rem; + } + + .hero-actions { + display: grid; + grid-template-columns: 1fr; + } + + .hero-actions .button { + width: 100%; + } + + .hero-proof { + grid-template-columns: 1fr; + gap: 12px; + } + + .hero-shot { + padding: 14px; + border-radius: 24px; + transform: none; + } + + .hero-shot img { + border-radius: 16px; + } + + .section h2 { + font-size: clamp(1.62rem, 8vw, 2.18rem); + } + + .section-lead, + .value-manifesto p, + .workflow-node p, + .scenario-row__body p, + .proof-strip p, + .entry-card span { + line-height: 1.64; + } + + .section--workflow { + padding: 28px 18px; + } + + .entry-shelf { + grid-template-columns: 1fr; + } + + .entry-card { + min-height: 132px; + } + + .site-footer__links { + width: 100%; + } + + .site-footer__links a, + .site-footer .theme-switch, + .site-footer .locale-switch { + width: 100%; + justify-content: center; + } +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } + + [data-reveal] { + opacity: 1 !important; + transform: none !important; + } +} diff --git a/site/vercel.json b/site/vercel.json new file mode 100644 index 00000000..fcdfff6c --- /dev/null +++ b/site/vercel.json @@ -0,0 +1,19 @@ +{ + "buildCommand": "pnpm build", + "outputDirectory": "dist", + "redirects": [ + { + "source": "/docs", + "destination": "https://docs.always200.com/", + "permanent": true + }, + { + "source": "/docs/:path*", + "destination": "https://docs.always200.com/:path*", + "permanent": true + } + ], + "github": { + "silent": true + } +}