VOZEB-UI-FOUNDATION-01 — OceanWay Liquid Glass 视觉与原型基础
Task ID: VOZEB-UI-FOUNDATION-01
目标用户结果: 先确认一套可持续的 OceanWay 风格、页面原型和共享组件边界,再开始全项目 UI 改造
Feature ID / Atomic Requirement IDs: HOME-P0-001;SPACE-P0-001..005;EXEC-P0-001;ADM-P0-001..004(仅作视觉承载范围,不改变业务语义)
Base SHA: d0037e99bbbec29f59e320d5ee6ba3fc8daeb6fe
必须阅读: DESIGN.md;VOZEB-BOOTSTRAP-01;Ocean OS / Ocean Air 设计系统;当前 VOZEB 页面与组件
允许修改: DESIGN.md、本任务稿、独立原型与视觉候选;不进入业务服务和数据模型
禁止修改: 生产系统、真实数据库、真实密钥、Retail 事实域和已冻结的上游设计 Artifact
范围: 视觉方向、颜色/字体/圆角/边界/动效 Token、组件契约、原型页面与验收清单
非目标: 全项目页面迁移、后端重构、数据迁移、权限/计费变更、部署和发布
已冻结契约与数据模型: 继续沿用 VOZEB 的功能、路由、服务端数据和权限;本任务只改变表现层候选
安全与数据限制: 仅使用本地源码和合成数据;浏览器不持久化业务数据或密钥
验收命令: pnpm -C web test;pnpm -C web typecheck;pnpm -C web lint;pnpm -C web build;桌面/移动端视觉回归
人工决策点: 用户确认视觉方向、原型范围和组件清单后,另建项目级迁移 Task Packet
交付物: 候选设计系统、组件契约、原型验收清单、已知缺口登记1. 现状结论
当前首页已经有一轮 Liquid Glass 视觉 Spike,但它只应被视为候选实现:
- 背景是一个单实例、动态加载 OGL 的 SoftAurora-inspired 海流 Canvas,并提供 CSS 动态渐变回退;主 Agent 玻璃层使用一个本地 vendored React Bits GlassSurface,其他卡片使用 CSS 玻璃;
- DOM 内容仍可交互,左侧导航和 OceanWay Logo 保留;
- 该 Spike 的测试和构建已通过,但尚未完成设计确认;
/canvas/:id的水合阶段现在使用单一OceanLoadingShell,沿用画布最终几何(顶栏、状态、缩放 dock、底部工具 dock 和网格),不再渲染三块旧式CanvasRefreshShell填充。该修复仍属于候选视觉证据,不改变画布业务行为。
2. 选定方向
Quiet Ocean Air / Liquid Glass
目标是“安静、浅色、透明、专业”,而不是高亮炫技:
- 浅蓝灰动态背景提供空间深度,但不成为内容;
- 玻璃表面只承载导航、Agent、浮层和少数状态控件;
- 图片、节点、列表和表格保持内容优先,不全部玻璃化;
- 文本使用深中性灰,蓝色只表达动作、焦点和选中图形;
- 边界由一条随背景明暗变化的 hairline 表达,禁止多层描边和固定左上高光;
- 圆角连续、同心,禁止同一组件同时使用不同几何语法;
- 动效解释状态和空间连续性,不使用持续漂浮或霓虹光晕。
3. 参考系统的职责
| 参考 | 采用内容 | 不采用内容 |
|---|---|---|
| Apple DESIGN.md | 系统字体气质、近黑文字、低噪声层级、细边界、克制动作色 | 顶部产品导航、营销页大色块、装饰性渐变 |
| Miro DESIGN.md | 无限画布的空间操控、稳定工具位置、媒体优先 | 黄色/粉彩品牌色、便签隐喻、全局胶囊按钮 |
| Linear DESIGN.md | 紧凑命令层级、细线和精确焦点 | 紫色强调、暗色营销壳、Issue 术语 |
OceanWay Logo、中文字体回退、业务文案、路由和权限始终优先于参考系统。
实现层当前采用 React Bits 官方固定快照
GlassSurface
源码副本:它用 SVG feDisplacementMap/feColorMatrix 和
backdrop-filter 提供单面折射、色散与模糊,Safari/Firefox 自动回退到 CSS。React Bits
是复制源码式组件库,不引入整库运行时;本项目将其包在 src/components/ocean 的
OceanGlassSurface 适配器中,首页 Agent 是首个实例,许可证边界记录在
web/THIRD_PARTY_NOTICES.md。
首页材质控制沿用 liquid-glass-react 的参数语义,但由项目自己的适配层统一收敛:
| 控制 | 取值 | 当前实现 |
|---|---|---|
Blur Amount | 0..1 | React Bits blur 与 CSS 回退 8..56px blur 共用解析值;首页默认 0.55 → 34px,确保后景可辨识地柔化 |
Saturation | 0..200% | React Bits CSS 变量 saturate() 与 CSS 卡片共用解析值 |
Chromatic Aberration | 0..1 | 仅在显式启用 SVG distortion 时映射 React Bits RGB distortionScale/channel offset;首页默认 CSS-first,避免跨浏览器色偏 |
Elasticity | 0..1 | 仅显式启用的 Agent 指针弹簧位移,最大 8px;其他表面默认为 0 |
React Bits 没有原生弹性字段,因此弹性落在语义 DOM 的交互层;CSS fallback、减少透明度
与强制颜色模式共用同一组解析后的范围和状态。首页首屏只创建一个由
OceanAmbientBackground 拥有的 WebGL2 上下文,OGL 在首帧绘制后延迟加载;React Bits
GlassSurface 本身不引入 WebGL。浏览器不支持 WebGL 或请求减少透明度时,自动保留轻量 CSS
动态渐变。
Foundation v1 的复合 kit 也已收敛为 view-model-only 视觉候选入口:OceanAssetPicker、
OceanPromptBrowser、OceanWorkGallery、OceanAdminTable/OceanAdminDetailDrawer、
OceanCanvasKit、OceanDramaEditor、OceanAuthKit 和 OceanInstallWizardKit。它们覆盖 ready、
loading、refreshing、empty、error、forbidden、锁定、提交中、步骤阻断、selection/preview、移动端
fallback 等表现,只负责状态、布局、焦点和动效,不读取 store、不请求 API,不创建
Operation/Billing Entry,也不持久化 Canvas/Drama 状态;页面 adapter 通过窄 props 和 callback
接入既有 VOZEB 事实。该候选实现仍保持
DESIGN_CANDIDATE / REVIEW_REQUIRED / NOT_FROZEN,不代表目标路由已替换。
媒体预览统一由 MediaFrame 的显式 kind(image / video / audio /
document)承载;Asset、Work、Drama 和 Canvas 候选不会根据 URL 猜测媒体类型。
跨页 AssetPicker 可通过 selectedItems 补齐当前页之外的已选 view model,ID 仍是
选择事实,分页、归属校验和持久化继续由页面 adapter 负责。
4. 视觉 Token v0.2(候选)
机器可读候选 Token 见 VOZEB-UI-FOUNDATION-01.tokens.json。
在设计评审通过前,它不能替代现有 Ocean OS 便携式 Token,也不能直接驱动全项目组件。
颜色角色
| Token | Ocean Air | Abyss | 语义 |
|---|---|---|---|
canvas | #F3F6FA | #11161D | 页面基底 |
surface | #F8FAFC | #1A2028 | 内容表面 |
surface-soft | #EAF0F6 | #242D37 | 弱分区 |
glass | rgba(248,250,252,.20) | rgba(27,33,42,.38) | 液态玻璃底色 |
ink | #1D2025 | #F5F7FA | 主文字 |
ink-secondary | #5C6570 | #B8C1CC | 次级文字 |
ink-quiet | #64707C | #8D98A5 | 辅助文字 |
edge | rgba(46,61,78,.14) | rgba(232,241,250,.14) | hairline / 分隔 |
action | #2F7FD3 | #0A84FF | 图形动作/焦点 |
action-fill | #1F5F9C | #0874DF | 白字实心动作 |
success | #34C759 | #34C759 | 成功/健康 |
warning | #C98919 | #D9A441 | 警告 |
danger | #D84A4A | #FF6B6B | 错误/危险 |
硬规则:action 不用于普通可读文字;实心白字按钮使用 action-fill;绿色只表达成功;危险和警告必须同时有
图标或文案;不得出现紫色 AI 渐变、霓虹边缘或蓝色段落文字。
字体与字级
UI: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", sans-serif
Display: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Display", "PingFang SC", sans-serif
Prompt 24 / 1.40 / 400
Page title 22 / 1.30 / 600
Section 16 / 1.40 / 600
Body 14 / 1.50 / 400
UI label 13 / 1.35 / 500
Metadata 12 / 1.40 / 400字重只使用 400 / 500 / 600;不使用 700 以上制造廉价的“加粗高级感”。
几何与深度
control 14px · card 18px · panel 24px · agent 30px · sidebar 30px · pill 999px
结构间距 4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 48 / 64React Bits GlassSurface 外层只保留一条低对比 hairline;静态 CSS 卡片同样只允许一条 低对比 1px border,不能再叠加 inset 白线。阴影仅用于悬浮层和 Drawer,默认卡片不使用 大阴影。
5. 共享组件契约
| 组件 | 必须负责 | 不得负责 |
|---|---|---|
OceanWorkspaceShell | 视口、层级、背景 Canvas、左侧导航 | 页面业务、数据请求 |
OceanSidebar | 目的地、账户、健康状态、移动端 Drawer 入口 | 内容列表和业务统计 |
OceanGlassSurface | 单一材质、DOM 语义层、React Bits/CSS fallback | 自行添加第二个边框或光源 |
OceanAgentComposer | 提示词、四种能力、附件入口、示例与发送 | 直接决定后端模型或计费 |
OceanUtilityControl | 图标按钮、Segment、次级操作、焦点状态 | 常驻蓝色高亮 |
OceanContentCard | 最近画布、项目、媒体预览 | 伪造业务统计 |
OceanContextRail | 项目/素材/通知辅助信息 | 抢占主任务宽度 |
OceanStatusCluster | 健康、加载、成功、失败摘要 | 仅靠颜色表达状态 |
OceanCanvasStage | 无限画布与编辑器交互 | 首页玻璃背景 |
OceanLoadingShell | 与最终布局同形的加载占位与过渡 | 旧版三块填充或第二套视觉 |
OceanAuthKit | 认证字段、注册门禁、邮箱验证码/MFA、策略提示、错误/锁定/无权限状态 | Session、密码和登录策略 |
OceanInstallWizardKit | 三步安装导航、检查状态、客户端内存令牌字段和动作槽位 | 数据库检查、安装写入和管理员创建 |
所有可交互组件至少定义 default / hover / pressed / focus-visible / disabled / loading / empty / error 中适用的状态,并支持键盘、触摸、Reduced Motion 和
Reduced Transparency。
当前已落地的可复用入口位于 web/src/components/ocean/index.ts,包括
OceanAgentComposer、OceanGlassSurface、OceanGlassCard、
OceanAmbientBackground、Foundation Shell primitives 以及 Spotlight、Tilt、Magnetic、
Reveal、ShinyText、BlurText、DiaTextReveal、ClickSpark、GlareHover、AnimatedList、CountUp、GradientText、
GradualBlur、LogoLoop、PixelSwap、RotatingText、ScrollExpand 动效原语。首页只负责
传入 VOZEB 的数据与导航回调,不在页面内重新实现这些交互。复合候选入口还包括
OceanAssetPicker、OceanWorkGallery、OceanAdminTable、OceanCanvasKit、OceanDramaEditor、
OceanAuthKit 和 OceanInstallWizardKit。AuthKit 的 firstUser、registrationEnabled、
emailRegistrationEnabled、mfaRequired 和 inviteError 只补充原 VOZEB 的视图语义;
InstallWizardKit 通过 showInstallToken 打开客户端内存字段,不接受令牌值 prop,避免
服务端渲染时把安装 Secret 序列化到 HTML。校验、Session、数据库检查和写入仍由页面
adapter 负责。
组件实验室的 candidate shelf 同时登记尚未接入页面的 React Bits 候选动效,并标注
CSS / Motion / OGL 成本与静态回退。轻量 CSS/局部 DOM 适配器已经在实验室提供真实预览,
但仍保持候选状态;SlicedWaves 等 WebGL 背景不会在业务页自动挂载,也不会与页面级
OceanAmbientBackground 叠加 renderer。页面级 WebGL context loss 会隐藏失效 canvas、切换
CSS fallback,并在同一挂载周期内禁止重新创建 renderer;恢复事件只记录 fallback 状态,重新
挂载才重新申请上下文。
VOZEB inventory 的每一条未适配记录也提供一个由 readiness / layer 驱动的非业务
“契约预览”骨架,用来确认卡片、状态线、控制器边界和来源路径确实进入实验室。该骨架
不实例化 store、API、权限或 Canvas 状态机,不能被视为业务组件已经实现。旧名
OceanParticleBackground 兼容导出单独登记为 legacy,新页面仍只使用
OceanAmbientBackground。
admin/admin-retail-migration-section.tsx 是 OceanWay 迁移阶段新增的 Admin domain
extension,不计入 VOZEB-PRO 原始组件数量;它仅作为来源和边界记录进入实验室。
浅色 Ocean Air 与深色 Abyss 共用上述组件契约。运行时由
global-ocean-air-theme.css 提供两套语义变量,桌面端主题入口放在现有左侧栏,移动端
沿用移动导航抽屉底部的 AnimatedThemeToggler;首页与组件实验室右上角只保留服务、通知
和账户状态,不重复放置主题开关;OGL 背景在切换时更新 uniform,不重新创建页面级 WebGL
上下文。
6. 原型页面与状态
原型阶段只验证以下页面,不扩展业务范围:
/:Home。左侧栏、宽度受控的 Agent、最近画布和一个辅助区域;Agent 不是全宽横条。/canvas:Canvas 列表。沿用同一壳层,但不叠加 Home 的全屏玻璃 compositor。/canvas/:id:VOZEB 画布交互。加载阶段直接使用OceanLoadingShell的最终几何,不能闪现旧块。- 响应式:
1440×900、1280×720、1024×768、390×844。
每个页面都要检查:浅色/深色、空/加载/错误、键盘焦点、滚动、WebGL 不可用、 Reduced Motion、Reduced Transparency 和无水平溢出。
6.1 客观运行证据(不替代人工视觉验收)
在当前候选工作树 d0037e99bbbec29f59e320d5ee6ba3fc8daeb6fe 上补做了精确视口
smoke check:
- 首页
1440×900:单个背景 Canvas、webgl/active、无水平溢出;滚动内容容器后仍为 单个 Canvas 且上下文保持 active。 - 首页
1024×768:单个背景 Canvas、webgl/active、无水平溢出;Agent 外层宽度约638px,滚动后无新增 Canvas。 - 组件实验室
1440×900与1024×768:各自单个 MoltenMetal Canvas、231 条清单项、 17 类真实 Ocean/VOZEB motion marker(含 DiaTextReveal)、无水平溢出。 - 组件实验室主题切换:浅色与深色均完成渲染,切换不新增 Canvas 且无水平溢出。
- Foundation smoke E2E:新增
web/e2e/foundation-v1.spec.ts,覆盖首页 Agent 交互、组件 实验室清单/动效/Overlay、桌面主题切换、390/430 移动端导航,以及 Reduced Motion 下的 CSS/WebGL 降级。使用本地系统 Chrome(Chromium 项目 + mobile-390/mobile-430)运行结果为12 total: 10 passed / 2 skipped(含 3 个安装 setup 用例);移动端跳过的是按设计只在桌面执行一次的 Reduced Motion 重复用例。 文件 Provider 的互动通知 409 是已登记的能力限制,E2E 仅在该 Provider 下用空通知响应隔离, PostgreSQL 运行仍走真实接口。默认 Playwright bundled browser 在当前机器未安装,因此这条 证据不等同于 CI/browser bundle 验收。
上述是 DOM/运行时事实,不能替代第 7 节由用户完成的视觉判断;第 7 节复选项仍保持 未冻结状态。
当前仍有一个不影响运行时的客观整理项:home-workspace.module.css 中部分候选页面专用
阴影、媒体遮罩和透明度仍写成局部 rgba/white 字面值,而不是 Ocean semantic token。
这些值没有在本轮自动替换,以免改变尚未由用户确认的视觉候选;应在 Foundation 冻结前由
单独 token-cleanup 任务处理并增加来源白名单测试。
7. 原型验收清单
- 页面上只有一个动态背景源和一个主 Agent GlassSurface;静态卡片不创建独立 WebGL 上下文。
- 玻璃表面没有双边框、内外嵌套描边或固定左上角高光。
- Agent 具备明确宽度边界,内部没有第二个“输入框大卡片”。
- 文本全部使用中性文字色,蓝色只出现在允许的动作图形/按钮/焦点上。
-
/canvas/:id不再显示旧版CanvasRefreshShell填充块(候选实现,待用户视觉确认)。 - 1440/1280/1024/390 视口均无水平溢出,滚动不会留下渲染残影。
- SVG filter 不可用时仍可交互,且只出现一套 CSS fallback 表面。
- Reduced Motion/Transparency 下不依赖动画或透明度才能读懂状态。
- 控件命中区、焦点和错误恢复路径符合项目可访问性规则。
8. 阶段闸门
本任务完成后只形成 DESIGN_CANDIDATE / REVIEW_REQUIRED / NOT_FROZEN。只有用户确认
本方向和组件清单后,才建立下一个独立任务包:
本候选的 source/tree/license、最终变更边界和 Gate 1 待确认项见
VOZEB-UI-FOUNDATION-01-CLOSEOUT.md。
VOZEB-UI-MIGRATION-02
按页面切片迁移 → 共享组件实现 → 独立测试 → 全项目视觉回归在确认前,不做全项目替换、不改后端契约、不改数据库、不做部署或发布。