# 前端设计系统 Runbook > 适用:`deploy/tksea-portal/` 下所有 HTML 静态页(含 public portal + 7 个 admin 页) > 建立时间:2026-06-03 > 来源:把原本「像 demo」的多页 HTML 升级为对齐宿主 sub2api Vue+Tailwind teal/slate 体系的 Linear/Vercel 信息建筑派设计系统。 ## 1. 文件结构 ``` deploy/tksea-portal/ ├── portal.css # 真设计系统 (777 行) — 唯一新视觉真源 ├── portal.js # window.Sub2ApiPortal — toast / icon / nav / theme / drawer ├── admin-common.css # 4KB legacy shim — 老类名映射到新 token ├── admin-common.js # 313 行原 nav 渲染契约(未动) ├── index.html # public portal (light) ├── admin/ │ ├── index.html # admin 入口 │ ├── logical-groups.html │ ├── route-health.html │ ├── accounts.html │ ├── providers.html │ └── batch-import.html # → /portal/admin-batch-import.html 1.5KB redirect └── admin-batch-import.html # 旧地址实页(历史兼容) ``` **新页面 = `portal.css` + `portal.js` + 自己的 `
Section Name

页面主标题

副标题描述,用 token 控制字号行高。

API Root

-

...
``` ## 4. 组件 API ### 4.1 `
` ```html

label

0

``` ### 4.2 `
` `.statusbar` 是统一的提示条;颜色用 `data-tone="success|warning|danger|note|neutral"` 或直接 class `tone-healthy|tone-cooldown|tone-failing|tone-disabled|tone-ready|tone-note|tone-warn`。 ### 4.3 Portal 图标 ```js Portal.icons.shield.mount("#icon-slot"); // 渲染 22px lucide stroke 1.75 Portal.icons.group.mount("#icon-slot", { size: 18 }); ``` 可用:`home / group / route / health / account / provider / import / check / x / alert / info / copy / edit / trash / plus / refresh / download / upload / eye / eyeoff / play / pause / search / filter / shield / activity / package / key / send / log-out / external-link / arrow-right / chevron-right` ### 4.4 Toast ```js Portal.toast("保存成功", { tone: "success", duration: 3000 }); Portal.toast("拉取失败", { tone: "danger" }); ``` ### 4.5 Copy ```js Portal.copyText(value, { success: "已复制", failure: "复制失败" }); ``` ### 4.6 Theme ```js Portal.theme.set("dark" | "light" | "auto"); // 写入 localStorage + html[data-theme] Portal.theme.get(); // 当前生效 theme ``` ### 4.7 Modern Nav ```js Portal.renderModernAdminNav(container, currentKey); // 渲染带 SVG icon + 渐变 hover 的现代 nav;并存于 AdminCommon.renderAdminNav 之上 ``` ## 5. 关键约束 1. **不要破坏测试契约字符串**:`logical_group` / `shadow_host_id` / `matched_account_state` / `account_resolution` / `package_tier` / `visibility_scope` / `gpt-5.4` / `MiniMax-M2.7-highspeed` / `deepseek-chat` / `Batch Import Admin` / `route_status` / `cooldown_seconds` / `failover_threshold` / `Smoke Logical Group` / `Smoke Provider Account` / `smoke-admin` / `smoke-route-primary` 等 70+ 字符串必须在 HTML 中出现(前端门禁 grep 断言)。 2. **不要修改 `admin-common.js`**:保留 `window.Sub2ApiAdminCommon` 的全局 API 契约。`portal.js` 是叠加层,不是替代层。 3. **不要使用 emoji / 渐变紫 / generic stock photo**:用 SVG icon + token 调色板。 4. **不要写裸 `style="color:#xxx"`**:用 `var(--text-muted)` 等 token。 5. **JS 引用 DOM ID 时**:新增的 page-hero / stat-card ID 必须和 `getElementById()` 调用对应。修改 stat-card label 时同步检查 JS 里的引用。 ## 6. 测试门禁 ```bash cd /home/long/project/sub2api-cn-relay-manager bash scripts/test/test_tksea_portal_assets.sh # 70+ 字符串契约断言 bash scripts/test/verify_frontend_smoke.sh # chromium headless 渲染 7 页 + public bash scripts/acceptance/verify_frontend_acceptance_matrix.sh # 总入口 ``` 修改任何 `deploy/tksea-portal/*.html` / `portal.css` / `portal.js` / `admin-common.css` 后必须三门都过。 ## 7. 截图 evidence ```bash # 启动本地 server(端口 8765,映射 /portal/* → deploy/tksea-portal/*) python3 /tmp/portal_server.py & # 截图 8 个页面 mkdir -p /tmp/portal-screenshots for url in \ "/portal/admin/index.html" \ "/portal/admin/logical-groups.html" \ "/portal/admin/route-health.html" \ "/portal/admin/accounts.html" \ "/portal/admin/providers.html" \ "/portal/admin-batch-import.html" \ "/portal/admin/batch-import.html" \ "/portal/index.html"; do name=$(basename "$url" .html) google-chrome --headless --disable-gpu --no-sandbox --hide-scrollbars \ --window-size=1440,2400 --virtual-time-budget=4000 \ --screenshot=/tmp/portal-screenshots/${name}.png \ "http://127.0.0.1:8765${url}" done ``` ## 8. 常见错误 - **重复 ``**:原页有 inline `` 紧跟 `