Files
UHD_Media_Tool/docs/design/interface-materials.md
T
umtandClaude Fable 5.1 b22c440139 chore: scaffold monorepo and migrate uhd_web design system (W0-A)
- pnpm workspace: apps/{web,server}, packages/{contracts,db,domain,adapters,tasks,agent,testkit}
- server: Hono + zod-openapi, API Key auth with scopes, redacting pino logger, SSE event bus with replay, worker heartbeat
- db: Kysely + pg, file migrator, 0001_init (settings/api_key/audit_event/outbox_event)
- web: React Router 7 SPA console shell with 12 workspace placeholders, uhd_web tokens/ui/guard scripts
- docs: ADR-001 (Node over Deno), dev runbook, design system rules

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-27 17:36:26 +08:00

105 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 界面材质
> 迁入自 /opt/uhd_web `docs/features/`(2026-09-27)。文中流媒体、播放器、落地页、套餐等段落是 uhd_web 的原始上下文,本项目没有这些页面,只作材质与 token 用法参考;以本目录 README 的约定为准。
样式入口是 [app.css](../../apps/web/app/app.css),具体色值与透明度只在 CSS 中维护。颜色 token 见[设计 token](design-tokens.md),按钮与控件的用法见[控件使用标准](ui-controls.md),三块壳下的实物陈列在开发态 `/dev/ui`。
## 设计原则
全站(用户中心、公共页、测速、流媒体)是同一套审美,改样式先对照这几条:
1. **主色无彩**。夜间是白、日间是墨。彩色只来自内容(海报、剧照),外加一种很淡的棱镜光。状态色 `success` / `warning` / `destructive` 只表示状态,不做装饰。支付方式保留品牌色。
2. **棱镜光只出现在三处**:左上角的漏光 `PrismLeak`、主操作按钮沿边框转动的光谱环、流媒体入口(侧栏的播放键 `prism-ring` 与菜单里的三角 `prism-icon`)。不再往别处加彩虹。
3. **材质按层级只有三种**:
- 贴边的用 `pg-surface` / `pg-chrome`;
- 内容卡用 `pg-slab`,是磨砂面,好读优先;
- 悬浮层用 `pg-float`,只有它用较深的投影。
不做边缘折射,也不在玻璃上再叠玻璃。
4. **一个角色一种外观**:
- 主操作是半透明胶囊加棱镜环,一屏只放一个;
- 次操作是描边胶囊;
- 选中态是静态的 `pill-selected`;
- 分段控件的滑块是 `seg-thumb`。
全站没有实心按钮,也没有实心的选中块。
5. **日夜两套,画面跟随页面**。大图、横向滚动行两侧的渐隐和压暗层都取页面底色,不硬切成黑色。播放页永远是夜间,落地页暂时固定夜间。
6. **同一种信息用同一种结构**:
- 套餐卡的零件在公共定价页和订阅服务页共用;
- 电影和剧集详情页共用 `DetailExtras`;
- 流媒体页面的内容区统一用 `max-w-[1800px]` 加 `px-4 sm:px-6 lg:px-10`,标题、海报行和顶栏对齐。
7. **动效只做一次性的**。入场、按压回弹、悬停反馈可以做;持续运动的装饰不做。主按钮的光谱环是唯一的例外,而且在减少动态效果时停转。
这些规则里能机器检查的,由 [check-design-tokens.sh](../../apps/web/scripts/check-design-tokens.sh) 在 `pnpm run ci` 中守住(见[设计 token](design-tokens.md#规则))。
## 结构
一个材质 = 一份固定配方 + 一组参数。配方写在 class 里(哪几层、怎么叠),参数是 `:root` 上的 `--mat-<材质>-<部位>`:
| 部位 | 含义 |
|---|---|
| `bg` / `rgb` | 底色(surface 用 rgb 三元组配 `--pg-surface-alpha`,其余是完整颜色或整段 background 值) |
| `sheen` / `reflection` / `glow` | 顶部光泽、斜向反光带、鼠标辉光,整段渐变 |
| `blur` | backdrop-filter 值 |
| `border` / `hairline` | 边 |
| `highlight` / `shade` | 上沿内高光、下沿内暗线 |
| `shadow` | 外投影(配方里各层形状不同的材质,这一项存整条 box-shadow 列表) |
| `solid` | blur 不可用或需要不透明时的实心兜底 |
材质分三组:
- 播放器与媒体区:`surface`、`pill`;
- 门户:`slab`、`chrome`、`float`,以及按钮用的 `pill-primary` / `pill-secondary` / `pill-selected` 和分段滑块 `seg-thumb`;
- 更新提示胶囊:`notice`。
浅色门户、深色门户与流媒体的差别都只是参数覆盖,不各自重写声明。换皮做平面材质时,把 blur 设成 none、光泽设成透明、投影收掉即可,class 不动。
| 场景 | 样式 |
|---|---|
| 贴边的 header、筛选栏、播放器底栏 | `pg-surface`,模糊与底色,不叠加悬浮面板的泛光亮线 |
| 悬浮层:下拉菜单、弹出框、下拉选择、对话框、抽屉、错误卡 | `pg-float`,全站唯一。菜单类 `rounded-2xl`,对话框 `rounded-3xl`,调用处不改底色、边框、投影。菜单里再弹出的子菜单、手机底部抽屉加 `pg-float-solid`(不透明),避免透出下面一层 |
| 药丸 HUD、徽章等小型悬浮元素 | `pg-pill` |
新组件先确认它是贴边、内容还是悬浮,再复用对应样式。滚动行卡片本体和高频跟随鼠标的进度气泡不加背景模糊。
## 门户材质
`pg-slab` 用于外层内容卡,`pg-chrome` 用于侧栏、顶栏和贴边操作条,`pg-float` 用于悬浮面板;嵌套的子卡保持轻填充,避免多重玻璃。Dialog / Card 原语自带的 utilities 可能覆盖 components 层的材质类,要核对最终的 class 合并和层叠,不要继续叠加透明度补丁。
内容卡是磨砂面,不追求透明:背景模糊只让底下的明暗和淡彩柔和地渗进来,层次靠亮棱边、顶部内高光和轻投影区分。投影只用贴边一层加很淡的环境一层,日间更轻(`--shadow-card` 按日夜分别给值)。页面底层是 `bg-page-glow` 的无彩明暗光斑,不铺网格。`PrismLeak` 在每个页面外壳各放一个(落地页与播放页除外),浓度与叠加方式见 `--mat-leak-*`。
主操作 `pill-primary`:
- 一圈光谱沿边框转动,6 秒一圈,内侧透一层很淡的同色光;
- 悬停时变亮,禁用或减少动态效果时停转;
- 参数是 `--mat-pill-primary-*` 与 `--prism-*`。
次操作 `pill-secondary` 与选中态 `pill-selected` 分别由 `--mat-pill-secondary-*`、`--mat-pill-selected-*` 控制。按下回弹 `scale(0.96~0.97)`。
动效:
- 页面入场用 `motion-safe:animate-blur-in`(失焦到清晰,填充模式 backwards,播完不留 filter,避免破坏 fixed 定位的子元素)。
- 需要鼠标反馈的卡片(套餐卡)挂 `.pg-spotlight`,并用 `rippleMove` 写入 `--mx/--my`。光在卡面底色之上、文字之下,亮度参数是 `--mat-spotlight`,只在能悬停的设备上出现。
- `.pg-beam` 巡边光只留给少数常驻小徽标。
## 流媒体大图
流媒体首页与详情页的大图通栏显示,跟随日夜:
- 压暗层(`.hero-vignette` 与各层渐变)取页面底色:夜间压暗配浅色字,日间提亮配深色字。
- 整个画面层在下沿渐隐成透明,露出页面的底色与光斑,和下面的内容连成一片。
- 渐隐加在不缩放的外层,ken-burns 放大时不会裁出硬边。
详情页的标题区向上压进渐隐区,海报、规格徽章和按钮在首屏内。
画面层下面垫一层页面底色,加载占位 `BackdropSkeleton` 用同一个盒子、同样的渐隐。这样图片没到、数据没到的时候,顶栏下面也不会先露出后面的棱镜漏光再被盖掉,切换首页和详情页时顶栏颜色不跳。
列表页(电影、剧集、收藏、合集、演职人员)不做色带:标题、筛选条和内容坐在同一张页面底上。吸顶筛选条 `StickyFilterBar` 平时透明,滚到顶栏下面吸住之后才出现磨砂底,和顶栏连成一条。
## 其他
- 侧栏的选中项由滑块(`seg-thumb`)承担主要形态,导航文字与 hover 保持清晰;分组展开、滚动和路由变化都会影响滑块位置。
- 改支付界面的样式时,要覆盖确认、二维码、错误与返回路径。套餐的优惠金额从价格推导,不写死。交易摘要用现有的 RemarkText 展示,不为排版改写后端摘要的含义。
主动使用 Taste 的触发条件和项目适配见[前端规范](../architecture.md)。