- root deno.json workspace (nodeModulesDir auto), npm versions registered once in imports, deno.lock; remove pnpm-lock/pnpm-workspace/root package.json; members keep minimal package.json (name/type/exports) - tasks: dev, typecheck (tsc 7.0.2 per member + deno check), lint/fmt (biome, useImportExtensions), test (vitest via deno), check:tokens, build (web + deno compile), ci, db:migrate/reset, gen:types - tsconfig base moved to config/ (no root tsconfig.json); deno types -> types/deno.d.ts; web drops baseUrl - server: Deno.serve entry with graceful shutdown, --role migrate|preflight|probe, WEB_ROOT static SPA hosting; drop @hono/node-server, tsx, esbuild build.mjs - logger: redact child() bindings and serialize err by message/stack; sync stdout destination; tests - relative imports get explicit extensions (sites/mp-sync paths left for follow-up) - crash-recovery tests spawn `deno run -A`; tasks tests use unique per-file schemas - single-container Dockerfile + entrypoint (migrate -> preflight -> api+worker watchdog), docker-compose.yml - docs: README, runbook, ADR-001 superseded, plan §1 validation row Co-Authored-By: Claude Fable 5.1 <[email protected]>
7.4 KiB
界面材质
迁入自 /opt/uhd_web
docs/features/(2026-09-27)。文中流媒体、播放器、落地页、套餐等段落是 uhd_web 的原始上下文,本项目没有这些页面,只作材质与 token 用法参考;以本目录 README 的约定为准。
样式入口是 app.css,具体色值与透明度只在 CSS 中维护。颜色 token 见设计 token,按钮与控件的用法见控件使用标准,三块壳下的实物陈列在开发态 /dev/ui。
设计原则
全站(用户中心、公共页、测速、流媒体)是同一套审美,改样式先对照这几条:
-
主色无彩。夜间是白、日间是墨。彩色只来自内容(海报、剧照),外加一种很淡的棱镜光。状态色
success/warning/destructive只表示状态,不做装饰。支付方式保留品牌色。 -
棱镜光只出现在三处:左上角的漏光
PrismLeak、主操作按钮沿边框转动的光谱环、流媒体入口(侧栏的播放键prism-ring与菜单里的三角prism-icon)。不再往别处加彩虹。 -
材质按层级只有三种:
- 贴边的用
pg-surface/pg-chrome; - 内容卡用
pg-slab,是磨砂面,好读优先; - 悬浮层用
pg-float,只有它用较深的投影。
不做边缘折射,也不在玻璃上再叠玻璃。
- 贴边的用
-
一个角色一种外观:
- 主操作是半透明胶囊加棱镜环,一屏只放一个;
- 次操作是描边胶囊;
- 选中态是静态的
pill-selected; - 分段控件的滑块是
seg-thumb。
全站没有实心按钮,也没有实心的选中块。
-
日夜两套,画面跟随页面。大图、横向滚动行两侧的渐隐和压暗层都取页面底色,不硬切成黑色。播放页永远是夜间,落地页暂时固定夜间。
-
同一种信息用同一种结构:
- 套餐卡的零件在公共定价页和订阅服务页共用;
- 电影和剧集详情页共用
DetailExtras; - 流媒体页面的内容区统一用
max-w-[1800px]加px-4 sm:px-6 lg:px-10,标题、海报行和顶栏对齐。
-
动效只做一次性的。入场、按压回弹、悬停反馈可以做;持续运动的装饰不做。主按钮的光谱环是唯一的例外,而且在减少动态效果时停转。
这些规则里能机器检查的,由 check-design-tokens.sh 在 deno task ci 中守住(见设计 token)。
结构
一个材质 = 一份固定配方 + 一组参数。配方写在 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 的触发条件和项目适配见前端规范。