diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2867484c..49d69e7a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
### 新增
- Organization OS 首页双循环:FreeOS 数据面与 openXYOS 控制面的实时状态、一键装配员工 / 打包回流 / 运行 org loop,以及边车离线时的启动恢复。
+- FreeOS 官网源码:`website/`(Vite + React 静态站,正式域名 https://freeos.cnxy.tech)。视觉与章节节奏对齐 XYAI Labs(天蓝→亮光、毛玻璃、01/02/…、底座 / 系统 / 生态),文案仍是 FreeOS 产品自己的话;圆形标志 + XYAI 机器人六姿态,无 Octop 红或章鱼形象。构建产物可整包上传到 `/www/wwwroot/freeos.cnxy.tech`。
### 变更
diff --git a/website/.gitignore b/website/.gitignore
new file mode 100644
index 00000000..62ccde41
--- /dev/null
+++ b/website/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+dist/
+*.tsbuildinfo
+.DS_Store
diff --git a/website/README.md b/website/README.md
new file mode 100644
index 00000000..8aa06f91
--- /dev/null
+++ b/website/README.md
@@ -0,0 +1,83 @@
+# FreeOS 官网
+
+正式地址:[https://freeos.cnxy.tech](https://freeos.cnxy.tech)
+
+本目录是 [FreeOS](https://github.com/XYAIStudio/FreeOS) 的营销站点源码:Vite + React + TypeScript,`npm run build` 产出可直接当网站根目录的静态文件。
+
+品牌:天蓝 → 亮光渐变、毛玻璃卡片、XYAI 蓝 `#0033FF` 点缀、圆形勾玉标志、XYAI 机器人六姿态。章节节奏对齐 [XYAI Labs](https://cnxy.ai/)(编号、中文大标题、底座 / 系统 / 生态),文案仍是 FreeOS 自己的产品故事,不声称本站是 XYOS Labs。不使用 Octop 红字标或章鱼形象。
+
+## 本地预览
+
+需要 Node.js 20+。
+
+```bash
+cd website
+npm install
+npm run dev
+```
+
+浏览器打开终端打印的本地地址(默认 `http://127.0.0.1:5173`)。点 Hero 里的机器人可轮换姿态。中 / EN 写在 `localStorage` 的 `freeos-locale`。
+
+```bash
+npm run build # 产出 website/dist/,根上就是 index.html
+npm run preview # 预览生产构建
+```
+
+## 构建产物
+
+`npm run build` 写入 **`website/dist/`**,结构类似:
+
+```
+website/dist/
+ index.html
+ favicon.png
+ logo.png
+ og.png
+ robots.txt
+ mascot/*.webp
+ assets/index-*.js
+ assets/index-*.css
+```
+
+`vite.config.ts` 使用相对 `base: './'`,把 `dist/` **里面的文件**拷到站点根即可,不要多套一层 `dist` 目录。
+
+本仓库根与 `website/` 都忽略 `dist/`,构建产物默认不提交。
+
+## 上传到用户服务器(宝塔 / aaPanel)
+
+父进程会把静态构建上传到已解析的域名根目录。
+
+| 项 | 值 |
+|---|---|
+| 公网地址 | `https://freeos.cnxy.tech` |
+| 服务器网站根 | `/www/wwwroot/freeos.cnxy.tech` |
+| 上传内容 | `website/dist/` **内的全部文件**(含 `index.html`、`assets/`、`mascot/`、图片) |
+| 结果 | `/www/wwwroot/freeos.cnxy.tech/index.html` 可被 Nginx/Apache 直接返回 |
+
+操作顺序(在有 Node 的机器上构建,再到面板上传;**不要把 SSH 密码或主机凭据写进仓库**):
+
+1. `cd website && npm ci && npm run build`
+2. 在宝塔「网站 → freeos.cnxy.tech → 根目录」确认为 `/www/wwwroot/freeos.cnxy.tech`
+3. 清空该目录里旧的站点文件(保留面板自己的配置,不要删服务器系统目录)
+4. 将 `website/dist/` 下所有文件上传到 `/www/wwwroot/freeos.cnxy.tech/`
+5. 浏览器打开 https://freeos.cnxy.tech 应看到首页,而不是目录列表
+
+静态站点即可,不必配 Node 反代。若面板默认目录索引,把默认文档设为 `index.html`。
+
+## GitHub Pages(可选,不是主发布路径)
+
+主站是 `freeos.cnxy.tech`。若仍要 Pages,把同一份 `dist/` 交给 Actions 或 `gh-pages` 即可。
+
+## 资源从哪来
+
+| 文件 | 来源 |
+|---|---|
+| `public/logo.png`、`favicon.png`、`og.png` | 仓库圆形标志(灰环 / 黄绿红勾玉 / 蓝水滴) |
+| `public/mascot/*.webp` | `dashboard/public/xyai-mascot-*.webp` 的副本 |
+
+## 内容边界
+
+- 产品事实以仓库 `README.md`、`docs/architecture-integration.md`、`docs/asset-loop.md` 为准。
+- Windows 安装包指向 [v0.0.1 Release](https://github.com/XYAIStudio/FreeOS/releases/tag/v0.0.1)。
+- 页脚按 `NOTICE` 致谢 Octop(MIT)与 openXYOS(Apache-2.0),不主张上游商标从属。
+- 视觉节奏参考 XYAI Labs 公开站的章节编号与玻璃质感,文案仍是 FreeOS 产品自己的话。
diff --git a/website/index.html b/website/index.html
new file mode 100644
index 00000000..bf1f8330
--- /dev/null
+++ b/website/index.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+ FreeOS — 让个人智能伙伴长成可治理的组织系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/package-lock.json b/website/package-lock.json
new file mode 100644
index 00000000..4ac11001
--- /dev/null
+++ b/website/package-lock.json
@@ -0,0 +1,1867 @@
+{
+ "name": "freeos-website",
+ "version": "0.0.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "freeos-website",
+ "version": "0.0.1",
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1"
+ },
+ "devDependencies": {
+ "@types/react": "^18.3.24",
+ "@types/react-dom": "^18.3.7",
+ "@vitejs/plugin-react": "^4.7.0",
+ "typescript": "~5.8.3",
+ "vite": "^6.3.5"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+ "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.7",
+ "@babel/helper-compilation-targets": "^7.29.7",
+ "@babel/helper-module-transforms": "^7.29.7",
+ "@babel/helpers": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/template": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+ "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@babel/types": "^7.29.8",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+ "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.29.7",
+ "@babel/helper-validator-option": "^7.29.7",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+ "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+ "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+ "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+ "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.8"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
+ "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
+ "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+ "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.8",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.8",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.8",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+ "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@napi-rs/lzma-linux-x64-gnu": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz",
+ "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^22.20 || ^24.12 || >=25"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.3.tgz",
+ "integrity": "sha512-w3Jnvi1ocaVm/c7yVPpfB98XeSRBMyzp6njL5MVVbGyXjpmUkN+s6Hp4t0PqhGCCaI1ZHMKXt/w0lA1RCaLVcw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.3.tgz",
+ "integrity": "sha512-uI/ESiaIbbRYAEhzy8PCUWDp1hB0bjAqM06mW9flOoNO4Q8DQpeoREhBR5Hegfl+wpXiguyJv6XSPzEN7OxyHQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.3.tgz",
+ "integrity": "sha512-oxhrd1jmXLwWZ83eQYDXxuqRdkqkzrjR3JobKeuUyfdNZo11FuQIvqEOZhyIT7OBHxXoGslDDjN0cQcM6T0TqQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.3.tgz",
+ "integrity": "sha512-7/YiIMghVE8DrxKvNdorAaJVdriOFgOIpdStnPx8ppx5zfTwC3jBCSEAIzB7JD5404m65THl6H93UTTVUvypmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.3.tgz",
+ "integrity": "sha512-GXFZRRoMAytaI5z6N3Zhfw0WL18Q0M8r95D5hlC4GqE/lGk8pbSJNUBoOWDfbm6dTciqHj2nU87tI5f6XhQiOg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.3.tgz",
+ "integrity": "sha512-77W+8X3ddYgPxUpB8nZFQs2Mq+wc4HVlcSRtApXLjYBcnPMkttrSnU8VwKQjeWYhMsITHFs5cWBQ8vz1Q+5RHQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.3.tgz",
+ "integrity": "sha512-FVkwK+iUC+mq+GipVK46rRVticfAPtvPUNlqlGXUDxdVk/UGjQiiiUVPUrEXdSpU2ufU0XxLGyTqDtBidDOVmg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.3.tgz",
+ "integrity": "sha512-+aGU1t3398yQOVj1Bz8o3e+KtswxAPvO+mtxtNdfXYMkXIHu7XhhkCD7/DEH9q8tF8uhDnMWvfpUKI8y1sZJsg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.3.tgz",
+ "integrity": "sha512-cR0kjpRXR2KJ2oQK8E2KTPtphs+b9hZ8IhTZubNryt/RsqgdOZBQ2Zq0q5UedtiIi0rs3jVhJh55RE1ZHUVGUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.3.tgz",
+ "integrity": "sha512-y1RYi4Q3/9ByVWSSt9kX2ustE0B7kFYbJ6zZdVZVyqopZs3yhCTwRfrjIX4vezUJInma/Gs6BOFDJg7yZmJ0IQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.3.tgz",
+ "integrity": "sha512-DNhEA5viIj3Z5bZLE4z4oV8N5ozWqDwyt7T6KG7VdLDJ0nW+rNOYlphBl4/3HQkK75qipPLsVOfStHHOwN9WSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.3.tgz",
+ "integrity": "sha512-17gQCqrIpXBX2Cmi9/TygnVOqGbzsba/iaqcYSL8FY7lNugg+7AiYNs5c5nKWD+NRQha36Sa0CqkJqH4XVHwnQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.3.tgz",
+ "integrity": "sha512-6LwVnZRIyINpdku/yOcI8Tm9YqLmhHK5emmlOOnW9tO0SYEm1FmKPcsSAGp0NBlqR2P04xaND4jvN6sTHqhq8A==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.3.tgz",
+ "integrity": "sha512-xMUqkTXlEUtI/p5AAukMwBRr1enU3efsTeF+bskeFfk8t1C9rcC8sLREcZXmTfAXEbvRdJVSonVJez3TMlbR3w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.3.tgz",
+ "integrity": "sha512-S3E94co9F9WRRqEaUoQZ38K1gCz6KiM+nL7/3ijq7fDGF3OznjS5TasgYITlvl27GQKtu4lOAOsr5MFwkijvOA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.3.tgz",
+ "integrity": "sha512-1QtRDwG42x5BJI3s9mxu5rEjDnfbSnk20HQ9/ylTAYnSwYwxMVb+Vgu34wzzTQ7ogqBybebgQNUDAvZVQ38DbA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.3.tgz",
+ "integrity": "sha512-BQhejF6ZXOpxbngiNTP12GCGQeaDVL2QXGeBVViKIYzFHM5RKxTxwUMB1fr1BeNFphFMpnRqC5QSXFSa4z6UQw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.3.tgz",
+ "integrity": "sha512-SXagRwnI2Wlwlitllu59UK/nGVbD1CKPcNqDplHwIC4BqJcpXFjD32d1R/RbuISa95HdQrZM3/7v4bKiowFaLA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.3.tgz",
+ "integrity": "sha512-2IPozoEALRCziGqE8O9KMK60PMu5TS1huv4fwoeCexj+WjmcwFtX9CTOVbfXCUqcELAubEwRFPYlzb/WvwY2HQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.3.tgz",
+ "integrity": "sha512-AoxqosUHT9IX54hFn2TiN6A7d6ZKTtE6pd2bqWtqkkNJ6HJGaU6FRouGX8L1O7R/ZwsnCnpQrHzb4pDEx+UHRQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.3.tgz",
+ "integrity": "sha512-d+CaftKgmkFBzCwezMqqy1d0QNNYugqLCMcYVQWBy5SS2YfeMP8Q8ripkgx9O8IyBXXLHrJ+aaCV4U96usv6Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.3.tgz",
+ "integrity": "sha512-xXlDF6nR1eOuXbdDy5Hl5fmtY7teUDevF/k0O7IPoZe4Tpmdv+lgdE5JRsnhQtt37ql9P0VF2kAN9a0OCZdo+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.3.tgz",
+ "integrity": "sha512-YtXAgLN+JP7Ay6qG3eWhc7IHMQPzLc8r3uvhAvlJIoCz/4Q32+Bl9Fmnywidh8v1GOIMmymjovfqY9ETAtysvA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.3.tgz",
+ "integrity": "sha512-WuWtSJRNo549vzcfZyEgfqb6zeSgn1F+UE5kQ+BCjzz0W4MGCjntUHkZVc1VRuAM7+ULaSyhiPxD1spyewFvkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.3.tgz",
+ "integrity": "sha512-+lIKX7O0+IGe7WuhATaAMMeT7B76vfhXH/l9wLQL+nvyhbw2ohYCKIdWL56JfDu75CWt5oKRP4QFH/jkMtBquA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.31",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz",
+ "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.28.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-beta.27",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.23",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.23.tgz",
+ "integrity": "sha512-le521dGVfxM7yRX0EikCoSz+rOK+hHzdDt/E7mG1jOJB/6WAAUuwVroLwaB7ApaUsz5Q0kFlDXLSA9MheUIfRQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.9",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz",
+ "integrity": "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.11.20",
+ "caniuse-lite": "^1.0.30001810",
+ "electron-to-chromium": "^1.5.420",
+ "node-releases": "^2.0.54",
+ "update-browserslist-db": "^1.3.2"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001810",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+ "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.428",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.428.tgz",
+ "integrity": "sha512-1JxbaFJj1bRKurj1uY3l4xxpU9kOUAUjcIgApj0qu1Pao5GhoIWI8iL0BeMYJ2njig1hBx0A7eKD9VGjH9wlHw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "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"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.19",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz",
+ "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.55",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.55.tgz",
+ "integrity": "sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.28",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+ "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.18",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.63.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.3.tgz",
+ "integrity": "sha512-1i2XreiAoMMXuPGD6Msj2xWrMMkHojNRKivInxGQcg7/1KuPuYlfUutLyh4drnOxUTHX9cHI4wFoat8D/NKaBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.9"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@napi-rs/lzma-linux-x64-gnu": "1.5.1",
+ "@rollup/rollup-android-arm-eabi": "4.63.3",
+ "@rollup/rollup-android-arm64": "4.63.3",
+ "@rollup/rollup-darwin-arm64": "4.63.3",
+ "@rollup/rollup-darwin-x64": "4.63.3",
+ "@rollup/rollup-freebsd-arm64": "4.63.3",
+ "@rollup/rollup-freebsd-x64": "4.63.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.63.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.63.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.63.3",
+ "@rollup/rollup-linux-arm64-musl": "4.63.3",
+ "@rollup/rollup-linux-loong64-gnu": "4.63.3",
+ "@rollup/rollup-linux-loong64-musl": "4.63.3",
+ "@rollup/rollup-linux-ppc64-gnu": "4.63.3",
+ "@rollup/rollup-linux-ppc64-musl": "4.63.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.63.3",
+ "@rollup/rollup-linux-riscv64-musl": "4.63.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.63.3",
+ "@rollup/rollup-linux-x64-gnu": "4.63.3",
+ "@rollup/rollup-linux-x64-musl": "4.63.3",
+ "@rollup/rollup-openbsd-x64": "4.63.3",
+ "@rollup/rollup-openharmony-arm64": "4.63.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.63.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.63.3",
+ "@rollup/rollup-win32-x64-gnu": "4.63.3",
+ "@rollup/rollup-win32-x64-msvc": "4.63.3",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+ "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
+ "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ }
+ }
+}
diff --git a/website/package.json b/website/package.json
new file mode 100644
index 00000000..12fc746f
--- /dev/null
+++ b/website/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "freeos-website",
+ "private": true,
+ "version": "0.0.1",
+ "type": "module",
+ "scripts": {
+ "dev": "vite --host",
+ "build": "tsc -b && vite build",
+ "preview": "vite preview --host"
+ },
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1"
+ },
+ "devDependencies": {
+ "@types/react": "^18.3.24",
+ "@types/react-dom": "^18.3.7",
+ "@vitejs/plugin-react": "^4.7.0",
+ "typescript": "~5.8.3",
+ "vite": "^6.3.5"
+ }
+}
diff --git a/website/public/apple-touch-icon.png b/website/public/apple-touch-icon.png
new file mode 100644
index 00000000..b9698d8a
Binary files /dev/null and b/website/public/apple-touch-icon.png differ
diff --git a/website/public/favicon.png b/website/public/favicon.png
new file mode 100644
index 00000000..2fc986e7
Binary files /dev/null and b/website/public/favicon.png differ
diff --git a/website/public/logo.png b/website/public/logo.png
new file mode 100644
index 00000000..2fc986e7
Binary files /dev/null and b/website/public/logo.png differ
diff --git a/website/public/mascot/empty.webp b/website/public/mascot/empty.webp
new file mode 100644
index 00000000..b6a4cc17
Binary files /dev/null and b/website/public/mascot/empty.webp differ
diff --git a/website/public/mascot/peek.webp b/website/public/mascot/peek.webp
new file mode 100644
index 00000000..cd926eae
Binary files /dev/null and b/website/public/mascot/peek.webp differ
diff --git a/website/public/mascot/tasks.webp b/website/public/mascot/tasks.webp
new file mode 100644
index 00000000..ef4e395b
Binary files /dev/null and b/website/public/mascot/tasks.webp differ
diff --git a/website/public/mascot/think.webp b/website/public/mascot/think.webp
new file mode 100644
index 00000000..2c0fd217
Binary files /dev/null and b/website/public/mascot/think.webp differ
diff --git a/website/public/mascot/type.webp b/website/public/mascot/type.webp
new file mode 100644
index 00000000..9a5159dc
Binary files /dev/null and b/website/public/mascot/type.webp differ
diff --git a/website/public/mascot/welcome.webp b/website/public/mascot/welcome.webp
new file mode 100644
index 00000000..4398ff7b
Binary files /dev/null and b/website/public/mascot/welcome.webp differ
diff --git a/website/public/og.png b/website/public/og.png
new file mode 100644
index 00000000..2fc986e7
Binary files /dev/null and b/website/public/og.png differ
diff --git a/website/public/robots.txt b/website/public/robots.txt
new file mode 100644
index 00000000..c2a49f4f
--- /dev/null
+++ b/website/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Allow: /
diff --git a/website/src/App.tsx b/website/src/App.tsx
new file mode 100644
index 00000000..1c75f2ea
--- /dev/null
+++ b/website/src/App.tsx
@@ -0,0 +1,453 @@
+import { useEffect, useMemo, useState } from "react";
+import { LINKS, copy, type Locale } from "./copy";
+
+const POSES = ["welcome", "empty", "peek", "think", "type", "tasks"] as const;
+type Pose = (typeof POSES)[number];
+
+const STORAGE_KEY = "freeos-locale";
+
+function mascotSrc(pose: Pose): string {
+ return `./mascot/${pose}.webp`;
+}
+
+function readLocale(): Locale {
+ const stored = localStorage.getItem(STORAGE_KEY);
+ if (stored === "en" || stored === "zh") return stored;
+ return "zh";
+}
+
+function IconGitHub() {
+ return (
+
+ );
+}
+
+function IconDownload() {
+ return (
+
+ );
+}
+
+function DualLoop({ locale }: { locale: Locale }) {
+ const t = copy[locale].engines;
+ return (
+
+
+ 01
+ {t.flowOut}
+
+
+
+ 02
+ {t.flowAssemble}
+
+
+
+
+ 04
+ {t.flowSpawn}
+
+
+
+ 03
+ {t.flowBack}
+
+
+ );
+}
+
+export default function App() {
+ const [locale, setLocale] = useState("zh");
+ const [navOpen, setNavOpen] = useState(false);
+ const [heroPose, setHeroPose] = useState("welcome");
+ const [openFaq, setOpenFaq] = useState(0);
+
+ useEffect(() => {
+ setLocale(readLocale());
+ }, []);
+
+ useEffect(() => {
+ document.documentElement.lang = locale === "zh" ? "zh-CN" : "en";
+ localStorage.setItem(STORAGE_KEY, locale);
+ }, [locale]);
+
+ const t = copy[locale];
+ const poseAlts = useMemo(
+ () => ({
+ welcome: t.hero.mascotAlt,
+ empty: locale === "zh" ? "XYAI 机器人展示空白工作区" : "XYAI robot holding an empty workspace",
+ peek: locale === "zh" ? "XYAI 机器人探头问候" : "XYAI robot peeking over the edge",
+ think: locale === "zh" ? "XYAI 机器人思考" : "XYAI robot thinking",
+ type: locale === "zh" ? "XYAI 机器人在笔记本上工作" : "XYAI robot typing on a laptop",
+ tasks: locale === "zh" ? "XYAI 机器人出示数字同事卡片" : "XYAI robot holding a colleague card",
+ }),
+ [locale, t.hero.mascotAlt],
+ );
+
+ const cycleHero = () => {
+ setHeroPose((current) => POSES[(POSES.indexOf(current) + 1) % POSES.length]);
+ };
+
+ const closeNav = () => setNavOpen(false);
+
+ return (
+
+
+ {t.skip}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t.hero.eyebrow}
+
+
+ {t.hero.headline[0]}
+ {t.hero.headline[1]}
+
+
+ {t.hero.promise}
+ {t.hero.times}
+ {t.hero.org}
+
+
{t.hero.lead}
+
+
+ {t.hero.chips.map((chip) => (
+ - {chip}
+ ))}
+
+
+
+
+ {t.hero.mascotHint}
+
+
+
+
+
+
+
+
{t.stackHead.kicker}
+
{t.stackHead.title}
+
{t.stackHead.lead}
+
+
+ {t.stack.map((item) => (
+
+
+ {item.no} / {item.layer}
+
+ {item.name}
+ {item.text}
+
+ ))}
+
+
+
+
+
+
{t.engines.kicker}
+
{t.engines.title}
+
{t.engines.lead}
+
+
+
+
+ {t.engines.dataLicense}
+ {t.engines.dataTitle}
+ {t.engines.dataBody}
+
+
+
+ {t.engines.controlLicense}
+ {t.engines.controlTitle}
+ {t.engines.controlBody}
+
+
+
+ {t.engines.note}
+
+
+
+
+
+
{t.capabilities.kicker}
+
{t.capabilities.title}
+
{t.capabilities.lead}
+
+
})
+
+
+ {t.capabilities.groups.map((group) => (
+
+
{group.title}
+
+ {group.items.map((item) => (
+
+ {item.tag}
+ {item.name}
+ {item.text}
+
+ ))}
+
+
+ ))}
+
+
+
+
+
+
{t.download.kicker}
+
{t.download.title}
+
{t.download.lead}
+
+
+
+
+ {t.download.allReleases} →
+
+
+
+
+ - {t.download.stepsTitle}
+ {t.download.steps.map((step, i) => (
+ -
+ {String(i + 1).padStart(2, "0")}
+ {step}
+
+ ))}
+
+
+
{t.download.cliTitle}
+
{t.download.cliHint}
+
+
+ {`git clone ${LINKS.github}.git
+cd FreeOS
+uv sync
+uv run freeos org loop run`}
+
+
+
{t.download.dataNote}
+
+
+
+
+
+
+
{t.loop.kicker}
+
{t.loop.title}
+
{t.loop.lead}
+
+
+ {t.loop.steps.map((step, i) => (
+ -
+ {String(i + 1).padStart(2, "0")}
+
{step.title}
+ {step.text}
+
+ ))}
+
+
+
{t.loop.lifeTitle}
+
+ {t.loop.life.map((stage) => (
+ - {stage}
+ ))}
+
+
{t.loop.lifeNote}
+
+
+
+
+
+
+ {t.faq.kicker}
+
{t.faq.title}
+
+
})
+
+
+ {t.faq.items.map((item, i) => {
+ const open = openFaq === i;
+ return (
+
+
+ {open ?
{item.a}
: null}
+
+ );
+ })}
+
+
+
+
+
+ {t.proof.kicker}
+
{t.proof.title}
+
+
+ {t.proof.items.map((item, i) => (
+
+ {String(i + 1).padStart(2, "0")}
+ {item.title}
+ {item.text}
+
+ ))}
+
+
+
+
+
+ {t.cta.title}
+ {t.cta.lead}
+
+
+
+
+
+
+ );
+}
diff --git a/website/src/copy.ts b/website/src/copy.ts
new file mode 100644
index 00000000..33e4bace
--- /dev/null
+++ b/website/src/copy.ts
@@ -0,0 +1,376 @@
+export type Locale = "zh" | "en";
+
+export const LINKS = {
+ site: "https://freeos.cnxy.tech",
+ github: "https://github.com/XYAIStudio/FreeOS",
+ releases: "https://github.com/XYAIStudio/FreeOS/releases/latest",
+ releaseTag: "https://github.com/XYAIStudio/FreeOS/releases/tag/v0.0.1",
+ windowsAmd64:
+ "https://github.com/XYAIStudio/FreeOS/releases/download/v0.0.1/FreeOS-desktop-windows-amd64-0.0.1.exe",
+ windowsArm64:
+ "https://github.com/XYAIStudio/FreeOS/releases/download/v0.0.1/FreeOS-desktop-windows-arm64-0.0.1.exe",
+ openxyos: "https://github.com/XYAIStudio/openXYOS",
+ openxyosSite: "https://openxyos.cnxy.tech/?lang=zh-CN",
+ octopUpstream: "https://github.com/TencentCloud/Octop",
+ notice: "https://github.com/XYAIStudio/FreeOS/blob/main/NOTICE",
+ architecture:
+ "https://github.com/XYAIStudio/FreeOS/blob/main/docs/architecture-integration.md",
+ assetLoop: "https://github.com/XYAIStudio/FreeOS/blob/main/docs/asset-loop.md",
+} as const;
+
+export const copy = {
+ zh: {
+ langName: "中文",
+ skip: "跳到正文",
+ nav: {
+ engines: "双引擎",
+ capabilities: "能力",
+ download: "下载",
+ loop: "闭环",
+ faq: "问答",
+ },
+ stackHead: {
+ kicker: "00 / 节奏",
+ title: "数据面、控制面、自生长闭环",
+ lead: "一层把同事跑在你的机器上,一层用蓝图和治理把组织养大,一条闭环让下一轮自己长出来。",
+ },
+ stack: [
+ { no: "CORE 00", layer: "底座", name: "FreeOS 数据面", text: "把智能体跑在你自己的机器上。" },
+ { no: "SYSTEM 01", layer: "系统", name: "openXYOS 控制面", text: "用蓝图、治理和人才市场把同事养大。" },
+ { no: "LOOP ∞", layer: "生态", name: "自生长闭环", text: "生产、装配、回馈,下一轮自己长出来。" },
+ ],
+ manifesto: "不是再装一个聊天壳,而是让组织自己长出下一位同事。",
+ brandAlt: "FreeOS 圆形标志:灰环、黄绿红勾玉、蓝色水滴",
+ hero: {
+ eyebrow: "FreeOS · 开源 · 自托管 · v0.0.1",
+ title: "FreeOS",
+ headline: ["让个人智能伙伴", "长成可治理的组织系统"],
+ promise: "懂你、帮你、陪你成长的智能伙伴",
+ times: "×",
+ org: "人机共融组织操作系统",
+ lead: "数据面跑起来,控制面长起来。可验证、可交付,数据留在你的机器上。",
+ download: "下载 Windows 安装包",
+ github: "打开 GitHub",
+ chips: ["可验证", "可交付", "数据本地"],
+ mascotHint: "点一下换个姿态",
+ mascotAlt: "XYAI 机器人欢迎姿态",
+ },
+ proof: {
+ kicker: "看得见 · 验得过 · 可决定",
+ title: "每一步都看得见、验得过、可决定",
+ items: [
+ { title: "看得见", text: "打开即可聊天,不必先登录。" },
+ { title: "验得过", text: "出站、删除、支付、生产变更默认拒绝。" },
+ { title: "可决定", text: "同一条动作经人批准,execute 才为 true。" },
+ ],
+ },
+ engines: {
+ kicker: "01 / 双引擎",
+ title: "一个运行时底座,长出可治理的组织系统",
+ lead: "数据面负责跑起来,控制面负责长起来。两边互补,不是换皮:一边生产会干活的智能体,一边用蓝图、治理和人才市场把它们养大,再喂回运行时。",
+ dataTitle: "FreeOS 数据面",
+ dataLicense: "MIT · 源自 Octop 运行时",
+ dataBody: "多智能体聊天、技能、插件、MCP、记忆、定时任务、工作区与飞书 / 钉钉 / Discord 等 IM——真正把同事跑起来的那一层。",
+ controlTitle: "openXYOS 控制面",
+ controlLicense: "Apache-2.0 · 组织操作系统",
+ controlBody: "多租户、组织建模、模块目录、智能体蓝图、治理引擎与人才市场——决定谁能进组织、能做什么、如何升级。",
+ flowOut: "生产 AI 员工 · 技能 · 插件 · MCP",
+ flowAssemble: "装配进 openXYOS 模块与人才市场",
+ flowBack: "蓝图 · 治理 · 人才回馈",
+ flowSpawn: "再孵化或升级运行时智能体",
+ note: "两边互不替代:openXYOS 不接管聊天,FreeOS 不假装自己是上游商标。",
+ },
+ capabilities: {
+ kicker: "02 / 能力",
+ title: "个人伙伴的手,组织操作系统的骨",
+ lead: "可验证的运行时能力,加上可交付的组织治理。全部用 FreeOS 自己的语言来说。",
+ groups: [
+ {
+ title: "数据面 · 把智能体跑在你机器上",
+ items: [
+ { tag: "RUNTIME", name: "多智能体", text: "每位用户可养多位同事:独立工作区、模型、人格与对话。" },
+ { tag: "SKILL", name: "技能与插件", text: "SKILL.md、专家库、第三方插件,把一次性对话沉淀成可复用能力。" },
+ { tag: "MCP", name: "MCP / 连接器", text: "OAuth 与 MCP 网关接入外部服务,工具走同一条审批路径。" },
+ { tag: "MEMORY", name: "记忆与定时任务", text: "记忆随工作区迁移;Cron 把值班、汇报、巡检交给数字同事。" },
+ { tag: "CHANNEL", name: "IM 通道", text: "飞书、钉钉、QQ、Discord、企业微信与控制台共用一条处理链路。" },
+ ],
+ },
+ {
+ title: "控制面 · 把同事放进可治理的组织",
+ items: [
+ { tag: "BLUEPRINT", name: "组织蓝图", text: "openxyos.agent-blueprint.v1 编译成可聊天的 FreeOS 智能体。" },
+ { tag: "GOVERN", name: "治理与审批", text: "出站、删除、支付、生产变更默认拒绝,人批准后才 execute=true。" },
+ { tag: "MODULE", name: "模块目录", text: "按租户启停模块;技能可发布为草稿,从不自动上线。" },
+ { tag: "TALENT", name: "人才市场", text: "数字同事沿 draft → market → recruit → shadow → active 成长。" },
+ { tag: "TENANT", name: "租户隔离", text: "一个租户一套工作区 / 沙箱,不靠提示词假装隔离。" },
+ ],
+ },
+ ],
+ },
+ download: {
+ kicker: "03 / 下载",
+ title: "Windows 用户:下载、安装、打开即用",
+ lead: "官网 freeos.cnxy.tech 只负责介绍。安装包从 GitHub Releases 下载,内置组织控制台,不必再装 Node。第一次启动会解压内置环境,可能要一两分钟。",
+ amd64: "Windows 64 位",
+ amd64Meta: "amd64 · .exe 安装包",
+ arm64: "Windows ARM",
+ arm64Meta: "arm64 · Surface / ARM 电脑",
+ allReleases: "查看全部 Releases",
+ stepsTitle: "四步开始",
+ steps: [
+ "打开 v0.0.1 Release,下载 amd64 或 arm64 安装包。",
+ "双击安装。程序会写入「程序文件」,并创建开始菜单与桌面快捷方式。",
+ "打开 FreeOS。解压完成后直接进入可用会话——先聊,不必先登录。",
+ "保存、导出或发布到账号时再注册。侧栏 Organization 默认打开。",
+ ],
+ dataNote: "数据默认在 %USERPROFILE%\\.freeos(可用 FREEOS_HOME 改)。卸载不会删除用户数据目录。",
+ cliTitle: "开发者:一条命令跑通闭环",
+ cliHint: "克隆仓库后:",
+ },
+ loop: {
+ kicker: "04 / 闭环",
+ title: "组织会自己长出下一位同事",
+ lead: "freeos org loop run 是产品路径,不是演示脚本。它把蓝图变成可聊天的员工,走完生命周期,再把资产装回控制面,并证明高风险工具仍然被拦住。",
+ steps: [
+ { title: "生产", text: "数据面产出 AI 员工、技能、插件和 MCP,注册成真正能在聊天里叫到的智能体。" },
+ { title: "装配", text: "资产打成 freeos.asset-pack.v1,写入 openXYOS 形状的员工、人才、插件与模块草稿。" },
+ { title: "回馈", text: "组织树、蓝图、治理策略、模块目录和人才市场再进口到 FreeOS。" },
+ { title: "升级", text: "下一位同事被孵化或升档。循环可重复,每次多一点可用能力。" },
+ ],
+ lifeTitle: "数字同事怎么转正",
+ life: ["草稿", "上市", "招募", "见习", "在职", "离任"],
+ lifeNote: "见习只读并受治理;转正后才打开岗位定时任务。离任会收回密钥,并把记忆归档到组织知识库。",
+ },
+ faq: {
+ kicker: "05 / 问答",
+ title: "先把关系讲清楚",
+ items: [
+ {
+ q: "FreeOS 和 Octop、openXYOS 是什么关系?",
+ a: "FreeOS 是独立开源宿主。数据面从 Octop(MIT)派生,控制面来自 openXYOS(Apache-2.0)。它们互补,不是互相换皮。FreeOS 不隶属、不代言腾讯云、Octop 或 XYOS 商标。",
+ },
+ {
+ q: "Windows 打开后为什么不用登录?",
+ a: "第一次进入是本地可用会话。聊天、试用组织能力不必先注册。只有保存、导出或发布到账号时才需要登录。",
+ },
+ {
+ q: "我的对话和文件存在哪?",
+ a: "默认 %USERPROFILE%\\.freeos。旧版 ~/.octop 仍会被识别。数据留在你的机器上,不经过 freeos.cnxy.tech。",
+ },
+ {
+ q: "高风险操作真的会被拦住吗?",
+ a: "会。出站、删除、支付、生产变更默认拒绝。必须有人批准同一条动作,execute 才会变成 true。侧车宕机也不会放行。",
+ },
+ {
+ q: "许可证怎么选?",
+ a: "宿主与桥接代码是 MIT;vendored 的 modules/openxyos 是 Apache-2.0。完整声明见仓库 NOTICE,请保留版权与许可文本。",
+ },
+ {
+ q: "没有 Windows 也能用吗?",
+ a: "可以。仓库提供源码路径:uv run freeos init && uv run freeos run。macOS / Linux 桌面包也在同一 Release。官网把 Windows 安装包放在最前面,因为那是非开发者的主路径。",
+ },
+ ],
+ },
+ cta: {
+ title: "在自己的电脑上,养一支会成长的 AI 队伍",
+ lead: "从 freeos.cnxy.tech 了解产品,到 GitHub 下载安装包,或从源码跑通 org loop。每一步都看得见、验得过、可决定。",
+ download: "下载 v0.0.1",
+ github: "Star / Fork",
+ openxyos: "了解 openXYOS",
+ },
+ footer: {
+ blurb: "自托管多智能体 OS,能生产并回收自己的 AI 员工。官网 freeos.cnxy.tech。",
+ product: "产品",
+ home: "官网",
+ legal: "许可与致谢",
+ links: {
+ releases: "Releases",
+ docs: "集成架构",
+ loop: "闭环说明",
+ notice: "NOTICE",
+ octop: "Octop 上游(MIT)",
+ openxyos: "openXYOS(Apache-2.0)",
+ },
+ attrib:
+ "数据面派生自 Octop(MIT,Copyright Octop contributors)。控制面来自 openXYOS(Apache-2.0,Copyright Xiongyuan Technology and XYOS contributors)。FreeOS 是独立项目,不主张与腾讯云、Tencent、Octop、XYAIStudio 或 XYOS 的商标从属关系。残留的 octop 标识符仅为兼容别名。",
+ copyright: "© 2026 XYAI Labs 与 FreeOS 贡献者",
+ },
+ },
+ en: {
+ langName: "EN",
+ skip: "Skip to content",
+ nav: {
+ engines: "Engines",
+ capabilities: "Capabilities",
+ download: "Download",
+ loop: "The loop",
+ faq: "FAQ",
+ },
+ stackHead: {
+ kicker: "00 / Rhythm",
+ title: "Data plane, control plane, self-growth loop",
+ lead: "One layer runs colleagues on your machine. One layer raises the organization. One loop grows the next round.",
+ },
+ stack: [
+ { no: "CORE 00", layer: "Base", name: "FreeOS data plane", text: "Run agents on your own machine." },
+ { no: "SYSTEM 01", layer: "System", name: "openXYOS control plane", text: "Raise colleagues with blueprints, governance, and talent." },
+ { no: "LOOP ∞", layer: "Loop", name: "Self-growth cycle", text: "Produce, assemble, feed back — the next round grows itself." },
+ ],
+ manifesto: "Not another chat shell — an organization that grows its next colleague.",
+ brandAlt: "FreeOS circular mark: gray ring, yellow green red magatama, blue teardrop",
+ hero: {
+ eyebrow: "FreeOS · Open source · Self-hosted · v0.0.1",
+ title: "FreeOS",
+ headline: ["Grow a personal partner", "into a governed organization OS"],
+ promise: "Understands you, helps you, grows with you",
+ times: "×",
+ org: "an OS for human–AI organizations",
+ lead: "The data plane runs. The control plane grows. Verifiable, deliverable, data stays on your machine.",
+ download: "Download for Windows",
+ github: "View GitHub",
+ chips: ["Verifiable", "Deliverable", "Data stays local"],
+ mascotHint: "Tap to switch pose",
+ mascotAlt: "XYAI robot in the welcome pose",
+ },
+ proof: {
+ kicker: "Visible · Verifiable · Decidable",
+ title: "Visible, verifiable, decidable — at every step",
+ items: [
+ { title: "Visible", text: "Chat on first launch. No login wall." },
+ { title: "Verifiable", text: "Outbound, delete, pay, and prod default-deny." },
+ { title: "Decidable", text: "execute becomes true only after a human approves that same action." },
+ ],
+ },
+ engines: {
+ kicker: "01 / Engines",
+ title: "One runtime base. An organization system that grows.",
+ lead: "The data plane runs. The control plane grows. They complement each other: one produces working agents, the other raises them with blueprints, governance, and talent, then feeds them back.",
+ dataTitle: "FreeOS data plane",
+ dataLicense: "MIT · derived from the Octop runtime",
+ dataBody: "Multi-agent chat, skills, plugins, MCP, memory, cron, workspaces, and IM channels such as Feishu, DingTalk, and Discord — the layer that actually runs colleagues.",
+ controlTitle: "openXYOS control plane",
+ controlLicense: "Apache-2.0 · organization OS",
+ controlBody: "Multi-tenancy, org modeling, module catalog, agent blueprints, governance, and the talent market — who joins, what they may do, how they level up.",
+ flowOut: "Produce employees, skills, plugins, MCP",
+ flowAssemble: "Assemble into openXYOS modules and talent",
+ flowBack: "Blueprints, governance, talent feed back",
+ flowSpawn: "Spawn or upgrade runtime agents",
+ note: "Neither side replaces the other. openXYOS does not take over chat. FreeOS does not claim upstream trademarks.",
+ },
+ capabilities: {
+ kicker: "02 / Capabilities",
+ title: "A companion’s hands. An organization OS’s bones.",
+ lead: "A verifiable runtime, plus deliverable org governance — spoken in FreeOS’s own voice.",
+ groups: [
+ {
+ title: "Data plane · agents on your machine",
+ items: [
+ { tag: "RUNTIME", name: "Multi-agent", text: "Each user can raise several colleagues, each with a workspace, model, persona, and threads." },
+ { tag: "SKILL", name: "Skills & plugins", text: "SKILL.md, an expert library, and third-party plugins turn one-off chats into reusable capability." },
+ { tag: "MCP", name: "MCP / connectors", text: "OAuth and an MCP gateway reach external services. Tools share one approval path." },
+ { tag: "MEMORY", name: "Memory & cron", text: "Memory travels with the workspace. Cron hands patrols, reports, and shifts to digital colleagues." },
+ { tag: "CHANNEL", name: "IM channels", text: "Feishu, DingTalk, QQ, Discord, WeCom, and the console share one processing pipeline." },
+ ],
+ },
+ {
+ title: "Control plane · colleagues inside a governed org",
+ items: [
+ { tag: "BLUEPRINT", name: "Org blueprints", text: "openxyos.agent-blueprint.v1 compiles into chat-ready FreeOS agents." },
+ { tag: "GOVERN", name: "Governance", text: "Outbound, delete, pay, and prod stay denied until a human approves the same action digest." },
+ { tag: "MODULE", name: "Module catalog", text: "Enable modules per tenant. Published skills stay drafts — never auto-on." },
+ { tag: "TALENT", name: "Talent market", text: "Colleagues grow draft → market → recruit → shadow → active." },
+ { tag: "TENANT", name: "Tenant isolation", text: "One tenant, one workspace/sandbox. Prompts are not a tenancy boundary." },
+ ],
+ },
+ ],
+ },
+ download: {
+ kicker: "03 / Download",
+ title: "Windows: download, install, open, and use",
+ lead: "freeos.cnxy.tech is the product site. Installers come from GitHub Releases and bundle the organization console — no extra Node. First launch unpacks a runtime and may take a minute or two.",
+ amd64: "Windows 64-bit",
+ amd64Meta: "amd64 · .exe installer",
+ arm64: "Windows ARM",
+ arm64Meta: "arm64 · Surface and ARM PCs",
+ allReleases: "All releases",
+ stepsTitle: "Four steps",
+ steps: [
+ "Open the v0.0.1 release and download the amd64 or arm64 installer.",
+ "Run it. Files land in Program Files, with Start Menu and desktop shortcuts.",
+ "Open FreeOS. After unpacking you land in a usable session — chat first, no login.",
+ "Register only when you save, export, or publish to an account. Organization is on by default.",
+ ],
+ dataNote: "Data lives in %USERPROFILE%\\.freeos (override with FREEOS_HOME). Uninstall does not delete that directory.",
+ cliTitle: "Developers: run the loop in one command",
+ cliHint: "After cloning the repo:",
+ },
+ loop: {
+ kicker: "04 / The loop",
+ title: "The organization grows its next colleague",
+ lead: "freeos org loop run is the product path, not a demo. It turns a blueprint into a chat-addressable employee, walks the lifecycle, applies assets back to the control plane, and proves high-risk tools still stop.",
+ steps: [
+ { title: "Produce", text: "The data plane emits employees, skills, plugins, and MCP, registered as real chat agents." },
+ { title: "Assemble", text: "Packs become freeos.asset-pack.v1 and land on openXYOS-shaped employee, talent, plugin, and module drafts." },
+ { title: "Feed back", text: "Org tree, blueprints, policies, the module catalog, and talent import back into FreeOS." },
+ { title: "Upgrade", text: "The next colleague is spawned or promoted. Repeat. Each cycle adds usable capability." },
+ ],
+ lifeTitle: "How a digital colleague is promoted",
+ life: ["Draft", "Market", "Recruit", "Shadow", "Active", "Offboard"],
+ lifeNote: "Shadow is read-only and governed. Cron from job duties turns on only when active. Offboard revokes secrets and archives memory into org knowledge.",
+ },
+ faq: {
+ kicker: "05 / FAQ",
+ title: "The relationships, plainly",
+ items: [
+ {
+ q: "How does FreeOS relate to Octop and openXYOS?",
+ a: "FreeOS is an independent host. The data plane is derived from Octop (MIT). The control plane comes from openXYOS (Apache-2.0). They complement each other. FreeOS is not affiliated with, endorsed by, or a trademark stand-in for Tencent Cloud, Octop, or XYOS.",
+ },
+ {
+ q: "Why is there no login on first launch?",
+ a: "The first session is local and ready. Chat and try organization features without registering. Sign in only when you save, export, or publish to an account.",
+ },
+ {
+ q: "Where do chats and files live?",
+ a: "Default %USERPROFILE%\\.freeos. Legacy ~/.octop is still recognized. Data stays on your machine; it does not pass through freeos.cnxy.tech.",
+ },
+ {
+ q: "Do high-risk tools actually block?",
+ a: "Yes. Outbound, delete, pay, and prod default-deny. execute becomes true only after a human approves that same action. A down sidecar does not fail open.",
+ },
+ {
+ q: "Which license applies?",
+ a: "The host and bridge are MIT. The vendored modules/openxyos tree is Apache-2.0. See NOTICE in the repository and keep copyright and license texts.",
+ },
+ {
+ q: "Can I use it without Windows?",
+ a: "Yes. From source: uv run freeos init && uv run freeos run. macOS and Linux desktop builds are on the same release. This page leads with Windows because that is the non-developer path.",
+ },
+ ],
+ },
+ cta: {
+ title: "Grow an AI workforce on your own computer",
+ lead: "Read the product at freeos.cnxy.tech, download from GitHub, or run the org loop from source. Visible, verifiable, decidable at every step.",
+ download: "Download v0.0.1",
+ github: "Star / Fork",
+ openxyos: "About openXYOS",
+ },
+ footer: {
+ blurb: "A self-hosted multi-agent OS that grows its own AI workforce. Official site: freeos.cnxy.tech.",
+ product: "Product",
+ home: "Website",
+ legal: "License & credit",
+ links: {
+ releases: "Releases",
+ docs: "Architecture",
+ loop: "Loop guide",
+ notice: "NOTICE",
+ octop: "Octop upstream (MIT)",
+ openxyos: "openXYOS (Apache-2.0)",
+ },
+ attrib:
+ "Data plane derived from Octop (MIT, Copyright Octop contributors). Control plane from openXYOS (Apache-2.0, Copyright Xiongyuan Technology and XYOS contributors). FreeOS is independent and claims no affiliation with Tencent Cloud, Tencent, Octop, XYAIStudio, or XYOS trademarks. Remaining octop identifiers are compatibility aliases.",
+ copyright: "© 2026 XYAI Labs and FreeOS contributors",
+ },
+ },
+} as const;
diff --git a/website/src/main.tsx b/website/src/main.tsx
new file mode 100644
index 00000000..693ac2e7
--- /dev/null
+++ b/website/src/main.tsx
@@ -0,0 +1,10 @@
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import App from "./App";
+import "./styles.css";
+
+createRoot(document.getElementById("root")!).render(
+
+
+ ,
+);
diff --git a/website/src/styles.css b/website/src/styles.css
new file mode 100644
index 00000000..51e3d9f2
--- /dev/null
+++ b/website/src/styles.css
@@ -0,0 +1,1120 @@
+:root {
+ --blue: #0033ff;
+ --blue-deep: #0050c8;
+ --sky: #7dd3fc;
+ --azure: #38bdf8;
+ --ice: #e0f2fe;
+ --blue-soft: rgba(224, 242, 254, 0.72);
+ --blue-wash: rgba(240, 249, 255, 0.55);
+ --ink: #0c1222;
+ --muted: #3d5270;
+ --line: rgba(255, 255, 255, 0.7);
+ --paper: #f0f9ff;
+ --white: #ffffff;
+ --yellow: #f5d000;
+ --green: #22c55e;
+ --red: #ef4444;
+ --glass: rgba(255, 255, 255, 0.46);
+ --glass-strong: rgba(255, 255, 255, 0.62);
+ --shadow: 0 16px 48px rgba(14, 165, 233, 0.1);
+ --highlight: inset 0 1px 0 rgba(255, 255, 255, 0.9);
+ --radius: 22px;
+ --max: 1180px;
+ color-scheme: light;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ margin: 0;
+ color: var(--ink);
+ min-height: 100vh;
+ background:
+ radial-gradient(1100px 640px at 8% -8%, rgba(125, 211, 252, 0.72), transparent 58%),
+ radial-gradient(880px 520px at 96% 4%, rgba(186, 230, 253, 0.85), transparent 52%),
+ radial-gradient(700px 420px at 70% 88%, rgba(224, 242, 254, 0.7), transparent 60%),
+ linear-gradient(180deg, #7dd3fc 0%, #bae6fd 18%, #e0f2fe 42%, #f0f9ff 68%, #ffffff 100%);
+ background-attachment: fixed;
+ font-family: "Noto Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
+ "WenQuanYi Micro Hei", "Droid Sans Fallback", sans-serif;
+ line-height: 1.65;
+ -webkit-font-smoothing: antialiased;
+}
+
+h1,
+h2,
+h3,
+h4,
+.brand span,
+.btn,
+.eyebrow {
+ font-family: Sora, "Noto Sans SC", sans-serif;
+}
+
+a {
+ color: var(--blue);
+ text-decoration: none;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+ display: block;
+}
+
+button,
+a {
+ -webkit-tap-highlight-color: transparent;
+}
+
+.skip {
+ position: absolute;
+ left: 12px;
+ top: -40px;
+ z-index: 40;
+ background: var(--blue);
+ color: #fff;
+ padding: 8px 12px;
+ border-radius: 8px;
+}
+
+.skip:focus {
+ top: 12px;
+}
+
+.orbits {
+ pointer-events: none;
+ position: fixed;
+ inset: 0;
+ overflow: hidden;
+ z-index: 0;
+}
+
+.orbits .wash {
+ position: absolute;
+ inset: -18% auto auto -8%;
+ width: 70vw;
+ height: 70vw;
+ border-radius: 50%;
+ background: radial-gradient(circle, rgba(255, 255, 255, 0.55), transparent 68%);
+}
+
+.orbits .arc {
+ position: absolute;
+ top: -8rem;
+ right: -6rem;
+ width: min(46rem, 90vw);
+ height: min(46rem, 90vw);
+ border-radius: 50%;
+ border: 1px solid transparent;
+}
+
+.orbits .yellow {
+ border-color: rgba(245, 208, 0, 0.28);
+ transform: rotate(-18deg);
+}
+
+.orbits .green {
+ border-color: rgba(34, 197, 94, 0.2);
+ transform: rotate(28deg) scale(0.86);
+}
+
+.orbits .red {
+ border-color: rgba(239, 68, 68, 0.16);
+ transform: rotate(68deg) scale(0.72);
+}
+
+.page {
+ position: relative;
+ z-index: 1;
+}
+
+.nav {
+ position: sticky;
+ top: 0;
+ z-index: 20;
+ display: flex;
+ align-items: center;
+ gap: 24px;
+ min-height: 68px;
+ padding: 0 28px;
+ background: rgba(255, 255, 255, 0.38);
+ backdrop-filter: blur(22px) saturate(1.4);
+ -webkit-backdrop-filter: blur(22px) saturate(1.4);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.55);
+ box-shadow: 0 8px 30px rgba(14, 165, 233, 0.06);
+}
+
+.brand {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: var(--ink);
+ font-weight: 700;
+ letter-spacing: -0.03em;
+ font-size: 1.1rem;
+}
+
+.brand img {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ box-shadow: 0 0 0 1px rgba(154, 160, 166, 0.45);
+}
+
+.links {
+ display: flex;
+ gap: 22px;
+ margin-right: auto;
+}
+
+.links a {
+ color: var(--muted);
+ font-size: 0.95rem;
+}
+
+.links a:hover {
+ color: var(--blue);
+}
+
+.nav-actions {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.lang {
+ display: flex;
+ padding: 3px;
+ border: 1px solid rgba(255, 255, 255, 0.7);
+ border-radius: 999px;
+ background: rgba(255, 255, 255, 0.45);
+ backdrop-filter: blur(12px);
+}
+
+.lang button {
+ border: 0;
+ background: transparent;
+ color: var(--muted);
+ border-radius: 999px;
+ padding: 4px 10px;
+ font: inherit;
+ cursor: pointer;
+}
+
+.lang button.on {
+ background: var(--blue);
+ color: #fff;
+}
+
+.nav-git {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ background: var(--blue);
+ color: #fff;
+ border-radius: 999px;
+ padding: 8px 14px;
+ font-weight: 600;
+}
+
+.nav-git svg,
+.btn svg {
+ width: 16px;
+ height: 16px;
+}
+
+.menu {
+ display: none;
+ width: 40px;
+ height: 40px;
+ border: 1px solid rgba(255, 255, 255, 0.7);
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.5);
+ backdrop-filter: blur(12px);
+}
+
+.menu span {
+ display: block;
+ width: 16px;
+ height: 1.5px;
+ margin: 5px auto;
+ background: var(--ink);
+}
+
+.menu.open span:first-child {
+ transform: translateY(3.25px) rotate(45deg);
+}
+
+.menu.open span:last-child {
+ transform: translateY(-3.25px) rotate(-45deg);
+}
+
+.hero,
+.section,
+.manifesto,
+.cta,
+.footer {
+ width: min(var(--max), calc(100% - 40px));
+ margin: 0 auto;
+}
+
+.hero {
+ display: grid;
+ grid-template-columns: 1.05fr 0.95fr;
+ gap: 32px;
+ align-items: center;
+ padding: 64px 0 40px;
+}
+
+.eyebrow {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ margin: 0 0 16px;
+ padding: 6px 12px 6px 6px;
+ border-radius: 999px;
+ background: rgba(255, 255, 255, 0.5);
+ backdrop-filter: blur(16px);
+ border: 1px solid rgba(255, 255, 255, 0.75);
+ box-shadow: var(--highlight);
+ color: var(--blue-deep);
+ font-size: 0.82rem;
+ font-weight: 600;
+}
+
+.eyebrow img {
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+}
+
+.hero h1 {
+ margin: 0;
+ font-size: clamp(2.15rem, 4.8vw, 3.55rem);
+ line-height: 1.18;
+ letter-spacing: -0.035em;
+ font-weight: 800;
+}
+
+.headline-l1,
+.headline-l2 {
+ display: block;
+}
+
+.headline-l2 {
+ color: var(--blue-deep);
+}
+
+.promise {
+ margin: 22px 0 0;
+ font-size: clamp(1.35rem, 3vw, 1.85rem);
+ line-height: 1.35;
+ font-weight: 650;
+ letter-spacing: -0.03em;
+}
+
+.promise .times {
+ display: inline-block;
+ margin: 0 0.35em;
+ color: var(--blue);
+}
+
+.promise .org-line {
+ display: inline;
+}
+
+.lead {
+ margin: 18px 0 0;
+ color: var(--muted);
+ max-width: 38rem;
+ font-size: 1.05rem;
+}
+
+.hero-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ margin-top: 28px;
+}
+
+.btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ min-height: 46px;
+ padding: 0 18px;
+ border-radius: 999px;
+ font-weight: 650;
+ border: 1px solid transparent;
+}
+
+.btn.primary {
+ background: var(--blue);
+ color: #fff;
+}
+
+.btn.primary:hover {
+ background: var(--blue-deep);
+}
+
+.btn.ghost {
+ background: rgba(255, 255, 255, 0.5);
+ backdrop-filter: blur(14px);
+ color: var(--ink);
+ border-color: rgba(255, 255, 255, 0.75);
+ box-shadow: var(--highlight);
+}
+
+.chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ padding: 0;
+ margin: 22px 0 0;
+ list-style: none;
+}
+
+.chips li {
+ background: rgba(255, 255, 255, 0.48);
+ backdrop-filter: blur(12px);
+ border: 1px solid rgba(255, 255, 255, 0.7);
+ color: var(--blue-deep);
+ border-radius: 999px;
+ padding: 6px 12px;
+ font-size: 0.84rem;
+}
+
+.hero-mascot {
+ margin: 0;
+ text-align: center;
+}
+
+.hero-mascot button {
+ width: 100%;
+ border: 1px solid rgba(255, 255, 255, 0.75);
+ background: rgba(255, 255, 255, 0.42);
+ backdrop-filter: blur(24px) saturate(1.35);
+ -webkit-backdrop-filter: blur(24px) saturate(1.35);
+ box-shadow: var(--shadow), var(--highlight);
+ border-radius: 40px;
+ cursor: pointer;
+ padding: 12px;
+}
+
+.hero-mascot img {
+ margin: 0 auto;
+ max-height: 460px;
+ object-fit: contain;
+}
+
+.hero-mascot figcaption {
+ color: var(--muted);
+ font-size: 0.82rem;
+ margin-top: 8px;
+}
+
+.section {
+ padding: 88px 0 12px;
+}
+
+.heading {
+ max-width: 42rem;
+ margin-bottom: 36px;
+}
+
+.heading.split {
+ display: flex;
+ justify-content: space-between;
+ align-items: end;
+ gap: 24px;
+ max-width: none;
+}
+
+.heading small,
+.steps-title,
+.life h3,
+.cli p:first-child {
+ display: block;
+ color: var(--blue);
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ font-size: 0.78rem;
+ margin-bottom: 10px;
+}
+
+.heading h2,
+.cta h2 {
+ margin: 0 0 12px;
+ font-size: clamp(1.85rem, 3.6vw, 2.75rem);
+ letter-spacing: -0.035em;
+ line-height: 1.22;
+ font-weight: 800;
+ text-wrap: balance;
+}
+
+.heading p {
+ margin: 0;
+ color: var(--muted);
+}
+
+.cap-mascot {
+ width: 180px;
+ flex: none;
+}
+
+.engine-pair {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 18px;
+ align-items: stretch;
+}
+
+.manifesto {
+ margin: 8px auto 0;
+ padding: 36px 32px;
+ text-align: center;
+ background: rgba(255, 255, 255, 0.42);
+ backdrop-filter: blur(24px) saturate(1.4);
+ -webkit-backdrop-filter: blur(24px) saturate(1.4);
+ border: 1px solid rgba(255, 255, 255, 0.78);
+ border-radius: 28px;
+ box-shadow: var(--shadow), var(--highlight);
+}
+
+.manifesto-text {
+ margin: 0 auto;
+ max-width: 38rem;
+ font-size: clamp(1.28rem, 2.6vw, 1.75rem);
+ font-weight: 700;
+ line-height: 1.45;
+ letter-spacing: -0.03em;
+ text-wrap: balance;
+}
+
+.stack-section {
+ padding-top: 64px;
+}
+
+.stack {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 14px;
+}
+
+.stack article {
+ background: var(--glass);
+ backdrop-filter: blur(20px) saturate(1.3);
+ -webkit-backdrop-filter: blur(20px) saturate(1.3);
+ border: 1px solid rgba(255, 255, 255, 0.72);
+ border-radius: var(--radius);
+ padding: 22px 22px 24px;
+ box-shadow: var(--shadow), var(--highlight);
+}
+
+.stack small {
+ display: block;
+ color: var(--blue);
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ font-size: 0.78rem;
+ font-family: Sora, "Noto Sans SC", sans-serif;
+ margin-bottom: 10px;
+}
+
+.stack h3 {
+ margin: 0 0 8px;
+ font-size: 1.28rem;
+ letter-spacing: -0.03em;
+}
+
+.stack p {
+ margin: 0;
+ color: var(--muted);
+}
+
+.engine {
+ background: var(--glass-strong);
+ backdrop-filter: blur(22px) saturate(1.35);
+ -webkit-backdrop-filter: blur(22px) saturate(1.35);
+ border: 1px solid rgba(255, 255, 255, 0.74);
+ border-radius: var(--radius);
+ padding: 22px 22px 28px;
+ box-shadow: var(--shadow), var(--highlight);
+}
+
+.engine img {
+ width: 160px;
+ margin: 0 auto 8px;
+}
+
+.engine small {
+ color: var(--muted);
+ font-size: 0.78rem;
+}
+
+.engine h3 {
+ margin: 6px 0 10px;
+ font-size: 1.35rem;
+}
+
+.engine p,
+.cap-cards p,
+.loop-steps p,
+.faq-item p,
+.life p,
+.data-note {
+ color: var(--muted);
+ margin: 0;
+}
+
+.cycle {
+ margin-top: 18px;
+ display: grid;
+ grid-template-columns: 1fr 56px 1fr;
+ grid-template-rows: auto 40px auto;
+ gap: 10px 12px;
+ padding: 22px;
+ background: var(--glass);
+ backdrop-filter: blur(24px) saturate(1.4);
+ -webkit-backdrop-filter: blur(24px) saturate(1.4);
+ border: 1px solid rgba(255, 255, 255, 0.75);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow), var(--highlight);
+}
+
+.cycle-cell {
+ background: rgba(255, 255, 255, 0.42);
+ border: 1px solid rgba(255, 255, 255, 0.7);
+ border-radius: 16px;
+ padding: 16px 18px;
+ min-height: 92px;
+}
+
+.cycle-cell em {
+ display: block;
+ color: var(--blue);
+ font-style: normal;
+ font-weight: 700;
+ font-family: Sora, sans-serif;
+ font-size: 0.78rem;
+ margin-bottom: 6px;
+}
+
+.cycle-cell span {
+ color: var(--ink);
+ font-weight: 650;
+ line-height: 1.4;
+}
+
+.cycle-cell.out {
+ grid-column: 1;
+ grid-row: 1;
+}
+
+.cycle-cell.assemble {
+ grid-column: 3;
+ grid-row: 1;
+ background: rgba(224, 242, 254, 0.55);
+}
+
+.cycle-cell.back {
+ grid-column: 3;
+ grid-row: 3;
+ background: rgba(186, 230, 253, 0.4);
+}
+
+.cycle-cell.spawn {
+ grid-column: 1;
+ grid-row: 3;
+ background: rgba(255, 255, 255, 0.55);
+}
+
+.cycle-arrow {
+ position: relative;
+}
+
+.cycle-arrow.east {
+ grid-column: 2;
+ grid-row: 1;
+}
+
+.cycle-arrow.south {
+ grid-column: 3;
+ grid-row: 2;
+}
+
+.cycle-arrow.west {
+ grid-column: 2;
+ grid-row: 3;
+}
+
+.cycle-arrow.north {
+ grid-column: 1;
+ grid-row: 2;
+}
+
+.cycle-arrow.east::before,
+.cycle-arrow.west::before,
+.cycle-arrow.south::before,
+.cycle-arrow.north::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ margin: auto;
+}
+
+.cycle-arrow.east::before,
+.cycle-arrow.west::before {
+ width: 36px;
+ height: 2px;
+ background: var(--blue);
+}
+
+.cycle-arrow.east::after,
+.cycle-arrow.west::after,
+.cycle-arrow.south::after,
+.cycle-arrow.north::after {
+ content: "";
+ position: absolute;
+ width: 8px;
+ height: 8px;
+ border-right: 2px solid var(--blue);
+ border-top: 2px solid var(--blue);
+}
+
+.cycle-arrow.east::after {
+ right: 6px;
+ top: 50%;
+ transform: translateY(-50%) rotate(45deg);
+}
+
+.cycle-arrow.west::after {
+ left: 6px;
+ top: 50%;
+ transform: translateY(-50%) rotate(-135deg);
+}
+
+.cycle-arrow.south::before,
+.cycle-arrow.north::before {
+ width: 2px;
+ height: 22px;
+ background: var(--blue);
+}
+
+.cycle-arrow.south::after {
+ left: 50%;
+ bottom: 4px;
+ transform: translateX(-50%) rotate(135deg);
+}
+
+.cycle-arrow.north::after {
+ left: 50%;
+ top: 4px;
+ transform: translateX(-50%) rotate(-45deg);
+}
+
+.engine-note {
+ margin: 18px 0 0;
+ color: var(--muted);
+ font-size: 0.92rem;
+}
+
+.cap-groups {
+ display: grid;
+ gap: 36px;
+}
+
+.cap-group h3 {
+ margin: 0 0 14px;
+ font-size: 1.15rem;
+}
+
+.cap-cards {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 12px;
+}
+
+.cap-cards article,
+.dl-card,
+.loop-steps li,
+.faq-item,
+.cli,
+.steps {
+ background: var(--glass-strong);
+ backdrop-filter: blur(20px) saturate(1.3);
+ -webkit-backdrop-filter: blur(20px) saturate(1.3);
+ border: 1px solid rgba(255, 255, 255, 0.72);
+ border-radius: 18px;
+ box-shadow: var(--highlight);
+}
+
+.cap-cards article {
+ padding: 18px;
+}
+
+.cap-tag {
+ display: inline-block;
+ margin-bottom: 8px;
+ color: var(--blue);
+ font-family: Sora, sans-serif;
+ font-size: 0.7rem;
+ font-weight: 700;
+ letter-spacing: 0.1em;
+}
+
+.cap-cards h4 {
+ margin: 0 0 8px;
+}
+
+.proof-grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 14px;
+}
+
+.proof-card {
+ padding: 22px 22px 24px;
+ background: var(--glass-strong);
+ backdrop-filter: blur(20px) saturate(1.3);
+ -webkit-backdrop-filter: blur(20px) saturate(1.3);
+ border: 1px solid rgba(255, 255, 255, 0.74);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow), var(--highlight);
+}
+
+.proof-card em {
+ display: block;
+ color: var(--blue);
+ font-style: normal;
+ font-weight: 700;
+ font-family: Sora, sans-serif;
+ font-size: 0.78rem;
+ letter-spacing: 0.08em;
+ margin-bottom: 10px;
+}
+
+.proof-card h3 {
+ margin: 0 0 8px;
+ font-size: 1.25rem;
+ letter-spacing: -0.03em;
+}
+
+.dl-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 16px;
+}
+
+.dl-card {
+ padding: 22px;
+ color: inherit;
+ box-shadow: var(--shadow);
+ transition: transform 160ms ease;
+}
+
+.dl-card:hover {
+ transform: translateY(-3px);
+}
+
+.dl-card img {
+ width: 168px;
+ margin: 0 auto 12px;
+}
+
+.dl-card b {
+ display: block;
+ font-size: 1.25rem;
+}
+
+.dl-card span,
+.center-link a {
+ color: var(--muted);
+}
+
+.center-link {
+ text-align: center;
+ margin: 18px 0 28px;
+}
+
+.steps-cli {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 16px;
+}
+
+.steps,
+.cli {
+ margin: 0;
+ padding: 22px;
+}
+
+.steps {
+ list-style: none;
+}
+
+.steps li,
+.loop-steps li {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ gap: 10px;
+ align-items: start;
+}
+
+.steps li + li,
+.loop-steps li + li {
+ margin-top: 14px;
+}
+
+.steps-title {
+ display: block;
+ grid-column: 1 / -1;
+ margin-bottom: 8px;
+}
+
+.steps em,
+.loop-steps em {
+ color: var(--blue);
+ font-style: normal;
+ font-weight: 700;
+ font-family: Sora, sans-serif;
+}
+
+.cli small {
+ color: var(--muted);
+}
+
+.cli pre {
+ overflow: auto;
+ background: #0c1222;
+ color: #e8edff;
+ border-radius: 14px;
+ padding: 16px;
+ margin: 12px 0;
+ font-size: 0.86rem;
+ white-space: pre;
+ line-height: 1.65;
+}
+
+.data-note {
+ font-size: 0.88rem;
+}
+
+.loop-steps {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 12px;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.loop-steps li {
+ display: block;
+ padding: 20px;
+}
+
+.loop-steps h3 {
+ margin: 8px 0;
+}
+
+.life {
+ margin-top: 28px;
+}
+
+.life ol {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ padding: 0;
+ margin: 0 0 12px;
+ list-style: none;
+}
+
+.life li {
+ background: rgba(255, 255, 255, 0.5);
+ backdrop-filter: blur(12px);
+ border: 1px solid rgba(255, 255, 255, 0.72);
+ border-radius: 999px;
+ padding: 8px 14px;
+ font-weight: 650;
+}
+
+.life li:nth-child(5) {
+ background: var(--blue);
+ color: #fff;
+ border-color: var(--blue);
+}
+
+.faq-list {
+ display: grid;
+ gap: 10px;
+}
+
+.faq-item button {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ gap: 16px;
+ text-align: left;
+ border: 0;
+ background: transparent;
+ color: inherit;
+ font: inherit;
+ font-weight: 650;
+ padding: 18px 20px;
+ cursor: pointer;
+}
+
+.faq-item p {
+ padding: 0 20px 18px;
+}
+
+.cta {
+ margin: 72px auto;
+ text-align: center;
+ background: rgba(255, 255, 255, 0.5);
+ backdrop-filter: blur(26px) saturate(1.4);
+ -webkit-backdrop-filter: blur(26px) saturate(1.4);
+ border: 1px solid rgba(255, 255, 255, 0.78);
+ border-radius: 32px;
+ padding: 48px 24px 56px;
+ box-shadow: var(--shadow), var(--highlight);
+}
+
+.cta img {
+ width: 150px;
+ margin: 0 auto 8px;
+}
+
+.cta .hero-actions {
+ justify-content: center;
+}
+
+.footer {
+ padding: 36px 0 56px;
+ color: var(--muted);
+ font-size: 0.92rem;
+}
+
+.footer-top {
+ display: grid;
+ grid-template-columns: 1.4fr 1fr 1fr;
+ gap: 24px;
+ margin-bottom: 24px;
+}
+
+.footer b {
+ display: block;
+ color: var(--ink);
+ margin-bottom: 10px;
+}
+
+.footer-top a {
+ display: block;
+ color: var(--muted);
+ margin: 6px 0;
+}
+
+.footer .brand {
+ margin-bottom: 10px;
+}
+
+.attrib {
+ border-top: 1px solid var(--line);
+ padding-top: 18px;
+ font-size: 0.82rem;
+}
+
+@media (max-width: 980px) {
+ .hero,
+ .engine-pair,
+ .dl-grid,
+ .steps-cli,
+ .loop-steps,
+ .footer-top,
+ .heading.split,
+ .cap-cards,
+ .cycle,
+ .stack,
+ .proof-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .cycle {
+ grid-template-rows: none;
+ }
+
+ .cycle-cell.out,
+ .cycle-cell.assemble,
+ .cycle-cell.back,
+ .cycle-cell.spawn,
+ .cycle-arrow {
+ grid-column: auto;
+ grid-row: auto;
+ }
+
+ .cycle-arrow {
+ display: none;
+ }
+
+ .links {
+ display: none;
+ position: absolute;
+ inset: 68px 16px auto;
+ z-index: 25;
+ background: rgba(255, 255, 255, 0.94);
+ backdrop-filter: blur(24px) saturate(1.4);
+ -webkit-backdrop-filter: blur(24px) saturate(1.4);
+ border: 1px solid rgba(255, 255, 255, 0.88);
+ border-radius: 16px;
+ padding: 16px;
+ flex-direction: column;
+ box-shadow: var(--shadow);
+ }
+
+ .links.open {
+ display: flex;
+ }
+
+ .menu {
+ display: inline-block;
+ }
+
+ .nav-git span,
+ .nav-git {
+ display: none;
+ }
+
+ .heading.split {
+ display: block;
+ }
+
+ .cap-mascot {
+ display: none;
+ }
+
+ .hero {
+ padding-top: 36px;
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ html {
+ scroll-behavior: auto;
+ }
+
+ .loop-dot,
+ .dl-card {
+ animation: none !important;
+ transition: none !important;
+ }
+}
diff --git a/website/src/vite-env.d.ts b/website/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/website/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/website/tsconfig.app.json b/website/tsconfig.app.json
new file mode 100644
index 00000000..b382d79f
--- /dev/null
+++ b/website/tsconfig.app.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
+}
diff --git a/website/tsconfig.json b/website/tsconfig.json
new file mode 100644
index 00000000..d32ff682
--- /dev/null
+++ b/website/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "files": [],
+ "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
+}
diff --git a/website/tsconfig.node.json b/website/tsconfig.node.json
new file mode 100644
index 00000000..a8a6056c
--- /dev/null
+++ b/website/tsconfig.node.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2022",
+ "lib": ["ES2022"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/website/vite.config.ts b/website/vite.config.ts
new file mode 100644
index 00000000..f61cbf5c
--- /dev/null
+++ b/website/vite.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+
+export default defineConfig({
+ plugins: [react()],
+ // Relative URLs so `dist/` works at domain root or a GitHub Pages project path.
+ base: "./",
+});