# V3 设计哲学 > 清楚的内容层级,安静的主题色表面,少量有性格的形状,以及操作后恰到好处的回应。 本规范把现有 V3 与用户已确认的 **App 推荐计划** 视觉合并成可复用的设计方法。适用于后续 V3 页面、Web 设计原型和 Android 实现。版本:2026-09-09。 **先看成品,再看规则:** [已确认页面](../mockup/referral-plan/index.html) · [桌面预览](../mockup/referral-plan/desktop.png) · [手机预览](../mockup/referral-plan/mobile-preview.png) · [组件图鉴](../mockup/v3-design-system/index.html) · [可复制模板](../mockup/v3-design-system/starter.html)。 ## 三分钟接手 ### 记住这六条,就能画出同一种风格 1. **先确定页面在讲什么。** 标题、图形、任务和主操作指向同一个对象。例如推广页讲 Pixiv-Shaft App,就展示产品邀请与产品教程。不要用别的内容替代业务对象。 2. **大面积安静,小面积强调。** 底色轻微染色,卡片近中性,主按钮使用主题实色。状态色有明确含义;图标区和 Hero 才能适当活泼。 3. **用字号和留白组织阅读。** 页面标题 → 一句说明 → 主区 → 分区标题 → 卡片内容。标题明显大于正文,数字大于数字单位。装饰标签不是正文。 4. **圆角分工。** Hero 30、卡片 22、图标容器 17、按钮胶囊;少量异形用在图标或完成徽章。形状变化要能说明哪个元素重要。 5. **一个区域只有一个最强操作。** 主操作实色,次操作浅色,解释入口文字或描边。任务状态、条件、进度和按钮放在一起,让下一步一眼可见。 6. **轻轻回应,不持续表演。** 按下缩到 0.96、按钮圆角短暂变化、弹窗短距离入场。滚动时保持稳定,减少动态效果模式下取消装饰动画。 ### 直接开始的步骤 1. 写一句业务目标:谁来到这里、要完成什么、完成后发生什么。 2. 从下面的页面配方选一个;先放标题、主内容和主操作。 3. 打开图鉴看日夜与三套主题,复制 starter 的结构和组件。 4. 填入真实状态与清楚的按钮文案;再添加一个视觉记忆点。 5. 对照验收清单检查手机、深色、长文案与完整流程。 **交给下一位设计师或 Agent 的简短指令:** ```text 按 docs/v3-design-philosophy.md 设计 [页面名称]。 业务对象是 [对象];用户的主要目标是 [目标];主操作是 [动作]。 采用 [运营 / 管理 / 设置 / 内容] 配方,参考 App 推荐计划的留白、字级与形状关系。 Web 复用 mockup/v3-design-system/tokens.css 和 components.css;从 starter.html 开始。 Android 复用 witstudio 与 V3Palette,尺寸用 dp/sp,关键操作热区至少 48dp。 保持中性染色底、22px 卡片、层级明确的文字、胶囊动作、克制的异形与短促反馈。 提交深浅主题、手机与宽屏、正常/空/加载/错误/完成状态和可操作的主要流程。 英文和数字使用 Montserrat 的真实字重,中文用系统中文字体回退;按规范选字号、字重、行高与语义文字色。 先校验业务语义,再检查视觉一致性;遇到信息不足要明确示例或待定值。 ``` ### 广场(2026-09-16 起按 V3 语言实现) 广场列表、帖子详情和创建帖子是 V3「作品 / 内容」配方的普通页面,**不再是 Figma 专项**。[Five Degrees 的 Post 区域](https://www.figma.com/design/XIelCCTiUHLjsJ9BbLmFy3/Five-Degrees?node-id=10025-6103) 只保留为内容区元素顺序与信息层级的参考;字体、图标、表面、圆角、动效与状态全部复用本文档和 `witstudio`: - **字体**:Montserrat 400/500/600/700 承担英文与数字,中文走系统回退;广场不再携带 Inter 字体文件。 - **图标**:复用 app 现有图标(`ic_like_heart_*`、`ic_baseline_comment_24`、`chat_ic_emoji`、`ic_more_vert_black_24dp`、`ic_add_black_24dp`、`ic_close_black_24dp`、`ic_v3_chevron_24`),由 `V3Palette` 着色;不保留 Figma 导出的 `ic_plaza_figma_*`。 - **表面**:列表帖子**无界平铺**,与小说卡列表、评论列表同款:不套卡底、edge-to-edge,左右 16dp、上下 14dp 内边距,条目间只有通栏 hairline(`BottomDividerDecoration` + `hairline_divider`),点按用 `selectableItemBackground` 同款矩形涟漪;详情页帖子直接坐在 `v3_bg` 上(内容优先),评论同样无界平铺(与插画评论列表一致:无卡底、通栏 hairline、左右 16dp、上下 12dp),不做连通分段行;创建页字段放在 22dp 卡片内,引用入口是单个 20dp 分段行。图片格子 12dp 圆角、间距 4dp,单图 16dp。 - **回应**:32dp 视觉胶囊 + 48dp 触控热区;未选中 `alpha08` 底、次要文字色,选中 `alpha20` 底 + `alpha30` 描边 + `textAccent`;18sp 表情或同尺寸贴纸、14sp 等宽数字(`tnum`)。点赞心形按下一次 1.25 倍回弹,不循环。 - **顶栏与主操作**:三页 include `toolbar_layout.xml`;列表页顶栏中央放「全部 / 我的」MD3-E 连通分段(`bg_toolbar_segment_*`,同书签库),主操作是右下角实色胶囊 Extended FAB「发帖」,向下滚动收起、上滚出现;详情页保留标准「更多」菜单;创建页「发布」仍是标准菜单项。 - **状态**:首屏用 `FeedSkeletonView` 骨架(`PlazaSkeletonView`)而非文字;空 / 失败 / 不存在照 feeds 框架 `fragment_feed.xml` 的空态做:120dp 插画(空态 `empty_img`、错误 `ic_feed_error`)以 `textAccent` 60% 着色、一句 14sp 次要文字、至多一个主色胶囊动作,在列表区域居中;帖子详情评论为空时,同一套空态放在「评论 (0)」标签下方,最小高度 320dp,随列表滚动,不做成一行小字;分页加载与评论加载在列表底部显示进度,分页失败给「重试」胶囊。 - **底座**:广场帖子列表跑在 feeds 框架上(`PlazaFragment : FeedFragment`,数据源 `PlazaFeedSource`,变更与作用域在 `PlazaFeedController`):分页、下拉刷新、冷启磁盘首屏、骨架容器、空 / 失败态、断网恢复重试、翻页节流与预算全部由框架负责,页面只保留顶栏分段、FAB、V3 状态样式、广场自己的错误文案与弹窗;刷新圈只在用户下拉时转,自动刷新与作用域切换静默加载。帖子详情暂未迁移。 - **动效**:广场所有列表 `itemAnimator = null`,条目更新直接就位,不做入场淡入、交叉淡化或位移(与下载管理列表同一取舍,作者明确不要列表动画);只保留按钮与胶囊按下 0.96(胶囊 0.94)和点赞心形的一次回弹,系统关闭动画时跳过。 广场列表的评论预览使用 `V3Palette.alpha08` 叠加 `cardFill` 的主题派生底色,12dp 圆角;预览正文和回复入口以合成后的背景校正到至少 4.5:1 对比度,不使用白色或通用页面底色作为预览底。 广场举报使用独立 V3 页面,走「设置 / 表单」配方(2026-09-17 重做):页面标题 →「请选择举报原因…」一句说明 → 举报对象卡 → 三个分区 → 贴底主操作。举报对象卡是 22dp 卡片加 17/17/17/7 图标容器,举报帖子/评论显示帖子与作者编号,举报作者只显示作者编号。分区标题是 20sp 粗体加末端的「必选 / 选填」小标,不把条件写进标题括号里。十类原因含「广告内容」,原因必选且不预选,做成连通分段行(20/5 圆角、2dp 行隙、56dp 行高):控件仍是 `RadioButton` 保住读屏与分组语义,但系统圆点换成末端指示器——未选一圈描边,选中是实心主题色圆点加对勾,选中行同时换成主题浅底容器和强调文字。补充说明始终选填(包括其他原因),卡片底在外层容器上、输入框自身透明(两层圆角叠在一起会描出一圈深边),保持至少 168dp 高度与五行空间,字数计数在卡内右下。可选上传最多三张证据照片,做成三个等分方格,下一个空位本身就是虚线「添加」槽,不再挂一颗随照片数跳位的胶囊;每格右上是移除按钮,上传进度是格子底部的进度条。提交区贴底,上面压一条 hairline,失败说明用 danger 色留在按钮上方。提交成功后整页换成成功徽章(86dp 异形、绿色语义色、仅容器轻微倾斜)加标题与举报编号,而不是在原表单上改几个字。说明性正文和辅助文字一律用中性 `v3_text_2`,整页只有主操作、选中态和图标带主题色——长段落染成主题色会被读成链接。⚠️ `v3_text_3` 只有 33% alpha,压在 `cardFill` / `v3_surface_2` 上实测只有 **2.05:1**,不能拿来写「必选 / 选填」小标、字数计数、输入框提示这类承载信息的文字,它只配做纯装饰性的分区 eyebrow。页面内容可滚动、宽屏最多 720dp;提交中禁止重复操作,失败保留输入。原因行热区至少 48dp,放大字体允许换行。 屏蔽作者使用独立确认弹窗,内容是同一套图标容器加说明。顶栏的屏蔽名单打开完整管理页,基于 `FeedFragment + FeedSource + feedRenderer`,由 feeds 统一承担首屏骨架、下拉刷新、空态、失败重试与视图复用;列表之上常驻一张说明卡交代「屏蔽仅作用于广场」,空态因此只说「暂无屏蔽用户」。记录是一条横排卡片:首字母头像(接口没有头像字段,用主题浅底的首字承担识别位)→ 用户名与 UID → 末端的解除胶囊。胶囊有行宽上限(卡内宽度的 42%),放大字体下它自己换行,用户名列不会被挤成一列单字;解除按钮保持 48dp 热区,宽屏最多 720dp,列表不做条目动画。实现与验收见 [广场举报](plaza-moderation.md)。 所有帖子公开,不呈现可见范围设置;图片上限为 9 张,Linked Quest 对应 Pixiv 作品或用户引用。系统状态栏、键盘及字体放大使用 Android 原生能力。对照记录见 [广场设计验收](plaza-design-review.md)。 ### 版本历史与更新弹窗(2026-09-17 起按 V3 语言实现) `ceui.lisa.update` 整包按 V3 重做,是「下载 / 历史 / 管理」配方的样板: - **版本历史**跑在 feeds 框架上(`FragmentVersionHistory : FeedFragment`,数据源 `VersionHistorySource`)。 GitHub 的 releases 一次返回完整一页,`nextCursor` 恒为 null;首屏骨架(`VersionHistorySkeletonView` 画的是卡片内容而不是实心板)、下拉刷新、空态、失败重试与断网恢复重试全部由框架承担,页面只留 顶栏、720dp 限宽和卡片长相。列表 `itemAnimator = null`。 - 列表第一条是**紧凑汇总卡**:17/17/17/7 图标容器 + 「当前版本」+ 版本号(Montserrat 700、`tnum`), 一条 hairline 之下是状态行,整页唯一的实色主操作「更新到 vX.Y.Z」就在它下面。已是最新时**不摆按钮** (没有下一步就不该有一颗按不动的胶囊,改成绿色对勾加一句话);Google Play 渠道换成「请通过商店更新」。 - **发布卡**是 22dp 卡片:版本号 → 一枚状态小标(装着的那一版用主题浅底的「当前版本」,最新一版用中性 `v3_surface_2` 的「最新」,一张卡只有一枚)→ 右端日期 → Markdown 更新说明 → 末端「安装包大小 + 展开胶囊」。 说明默认折叠 6 行,展开入口是一颗 34dp 的次级胶囊加箭头——只画一行小字加箭头在满是 Markdown 的卡里 读不出是个按钮。按钮显不显示在**卡片自己的 `onMeasure` 里**按 `TextView.getLineCount()` 定 (绑定时先按文本长度猜一手,猜错才改一次可见性重量一遍):`post` 到下一帧再显隐会让卡片在滚动中 先矮一下再长高。⚠️ 正文**不能设 `ellipsize`**:设了之后 `Layout` 会被截到 `maxLines`、末行把剩下的 文字并进来,`getLineCount` / `getLineEnd` / `getEllipsisCount` 就全都测不出「完整内容有多少行」 (实测 6 行的卡不设 ellipsize 时 `lineCount` 是 14,设了就是 6,而省略号在多段 Spanned 上根本没画出来)。 - 更新说明里的**代码块**(如带 SHA 校验值的那几版)不用 Markwon 自带的 `codeBlockBackgroundColor`: 那个只给得了一个颜色,画出来是贴着文字边的直角灰板,压在 22dp 卡片里很突兀。改成自绘的 `LineBackgroundSpan`——12dp 圆角(首行末行各圆自己两个角)、左右 12dp 留白、上下各多画 6dp, 底色是卡底再混一层 8% 主题色(同广场的评论预览)。行内代码不套底,只用等宽加 `textAccent`。 - **更新弹窗**是 V3 弹窗配方:顶角 28dp 的 sheet,图标容器 + 标题 + 「4.9.2 → 4.9.3」版本对比 → 更新日志卡(高度有上限、自带渐隐边)→ 安装包名与大小 → 4dp 进度条 → 贴底的实色主操作 (下载 / 下载中 / 安装 / 重试,各自带图标)→ 「稍后」「跳过此版本」两个纯文字入口。下载一旦开始, 「跳过此版本」就收起。下载、校验与安装授权的逻辑没有改动。 - 两处的 Markdown 共用 `markwonFor(context)`:标题只比正文大一点,链接与行内代码走 `textAccent`, 代码块坐在 `v3_surface_2` 上。 ### 标签流(2026-09-23 起统一) 搜索发现、置顶/历史、作品详情与小说列表共用 `V3TagFlowView`,通用渲染下沉为 `witstudio.WitTagFlowView`;不再使用旧 `flowlayout-lib` 或在列表手写另一套标签。 胶囊底、描边、图标和原文从当前 `V3Palette` 派生,译文遵循「标签译文颜色」设置; 置顶与搜索历史正文只展示原文,已知官方译文仍可在长按菜单查看和复制。 原文与独立译文色都按当前主题的染色标签底校验对比度(至少 4.5:1),保留色相、校正亮度; 不能只用 HSL 亮度上限判断黄、绿等高感知亮度色是否可读。 英文使用真实 Montserrat Medium,中文系统回退;普通标签是 13sp、14dp 横向/6dp 纵向内边距、 按内容测量的约 32dp 可见胶囊,48dp 只作热区,落在上下各 8dp 的透明沿里(2026-09-24,#1148), 换行时相邻两行的透明沿用上下各 -4dp 边距互相叠入,可见胶囊行距与横向间距同为 8dp、行高 40dp, 首行上方与末行下方各留 4dp(2026-09-29;此前行距 16dp 被反馈过松)。重叠带的点击归下一行, 整片标签区没有死区;每颗标签的 View 仍是 48dp 高。紧凑小说卡 沿用原有密度。顶部搜索输入条内的标签保留 13sp 字号、14dp 横向/7dp 纵向内边距, 高度按内容测量,维持输入条原有尺寸。长标签允许换行,多行圆角封顶 24dp,避免底色变成椭圆;RTL 使用相对边距。 按压缩到 0.96,关闭系统动画时取消缩放。 搜索历史的删除是独立按钮,不能把整颗标签的点击改成删除。删除键和正文坐在**同一颗**可见胶囊里: 自身不画第二层底,只有 `textTag` 色「×」和按下的圆形涟漪,所以历史行与普通标签同为 32dp 可见高度(2026-09-24)。 按钮 32dp 宽、18dp 图标框(叉形约 10dp),叉离正文约 8dp、离胶囊末端约 14dp,与起始内边距对称; 高度随透明上下沿取满 48dp(2026-09-29;此前 48dp 宽让叉两侧各空出约 20dp,被反馈占地过大)。 删除前有确认弹窗,窄一点的热区误触代价可控。⚠️ 透明沿用 `InsetDrawable` 画时必须把它的 `getPadding` 置空:平台默认把 inset 报成 View 内边距,会覆盖条目自己的内边距,历史行因此被撑成 48dp 可见胶囊。 历史删除与搜索框标签的 「×」/ 长按删除均先打开 `WitDialog` 二次确认,正文写明目标;取消为普通操作,确认「删除」 使用 `WitDialogAction.ACTION_PROP_NEGATIVE`,确认前不改变数据或触发搜索。标签菜单统一提供 复制原文/已知译文、翻译、固定/取消固定、屏蔽/取消屏蔽;作者相关作品入口只由详情页提供。 ID、URL、作者搜索记录仍保留自己的路由与菜单,不按标签处理。组件能力与回归项见 [标签流迁移](tag-flow-migration.md)。 **置顶标签组合**(2026-09-26,对标 pixez#1364):组合在搜索结果页拼出来,所以置顶入口也放在那里—— 顶栏筛选左侧的图钉,描边 = 未置顶、实心 = 已置顶,一键置顶 chip 行里的全部标签(单个标签是一个词的特例)。 按词集合判定同一组合(「胡桃 原神」=「原神 胡桃」,含 `OR` 时才要求词序一致)。置顶与取消都不弹确认: 置顶回弹一次(0.6 → 过冲 → 1,420ms)+ 确认震动,Snackbar「已置顶「原神 + 胡桃」」带「查看」直达 「我置顶的内容」;取消轻缩一次,Snackbar 带「撤销」,原样写回旧行。关闭系统动画时只保留图标切换与震动。 组合不另建表,仍是 search_table 的一条置顶关键字;置顶页卡片标题写成「原神 + 胡桃」,「+」用 `textAccent`, 最多两行,副标题「N 个标签的组合」,预览取置顶时插画结果的头 3 张(chip 行改了但还没重搜时不带图)。 命中搜索风控的查询不显示图钉。筛选条件不随组合保存。 ### 动图逐帧(2026-09-29 起) 动图大图页页码位的玻璃小胶囊「逐帧」(及大图页 / 作品页「更多」里的「逐帧浏览与保存」)打开 `UgoiraFramesFragment`, 走「作品 / 内容」配方:舞台优先 → 时间码与帧信息 → 时间轴与播放控制 → 一个最强操作。交互取剪辑软件之长,语言仍是 V3: - **舞台**:26dp 容器(`cardFill` + hairline),完整显示当前帧,双指 / 双击放大看细节;单击播放 / 暂停,中央浮出一次玻璃图标随即淡出。 当前帧已标记时左上角一枚玻璃小标「已标记」。帧未就绪时先铺作品预览图 + 进度浮层(同动图播放器),失败给「重试」实色胶囊。 - **信息行**:22sp Montserrat 600 `tnum` 时间码(当前帧起点)+ 14sp 次要色总时长;下一行 12sp「第 N / M 帧 · 125 ms」。 有标记时末端出现「已标记 N 帧 ×」浅色胶囊,点按清除并给 Snackbar「撤销」。 - **时间轴**(`UgoiraTimelineView`,剪映式):固定居中播放头(2dp `v3_text_1` 细线 + 顶端圆点),胶片在其下滚动; **格宽 = 帧停留时长**,格间 2dp 缝、6dp 圆角;当前帧套 2.5dp `textAccent` 选框(实况照片选帧的那只框); 标记是格子上方 3dp 主题色圆点;下方刻度尺 11sp `v3_text_2`,主刻度间距 ≥ 64dp;两端 28dp 渐隐到 `v3_bg`。 拖动 / 惯性后吸附到帧中心,每跨一帧 `CLOCK_TICK` 震动;双指捏合缩放时间轴(播放头下时刻不动);轻点跳帧;长按标记。 读屏按 SeekBar 暴露,前后滚动动作逐帧步进,方向键同理。 - **播放控制**:标记 · 上一帧 · 64dp 实色圆播放 · 下一帧 · 速度(0.25× / 0.5× / 1× / 2× 循环,非 1× 时 `textAccent`); 按住上一帧 / 下一帧 500ms 后每 90ms 连续步进,走到头自动停。 - **主操作**:56dp 分享浅色圆 + 整宽 56dp 实色胶囊「保存此帧」,有标记时改为「保存 N 帧」(分享同样作用于标记帧); 按下 0.96 且圆角收到 15dp。保存成功舞台白闪一次(系统关闭动画时不闪)、按钮 1.6s「已保存」+ 对勾。 - **原画质**:保存与分享的是 pixiv 原帧 JPEG(原速目录,不含 RIFE 补帧,也不经 mp4 / GIF 再编码), 沿用插画命名模板加 `_frameNN` 后缀;万一只剩补帧版本,信息行如实标「含 AI 补帧」。 - 宽屏横放(≥ 600dp 且宽 > 高)时舞台在左、380dp 控制台在右;当前帧、标记与速度存 `SavedStateHandle`,旋转与进程回收后原位恢复。 - **片段(`[ ]` 裁剪,2026-09-29)**:舞台下方「选帧 | 片段」MD3-E 连通按钮组(复用 `LibraryFilterViews.connectedGroup`)。 片段模式下时间轴选中范围套一只主题实色括号框——上下 3dp 横梁 + 两端 16dp 把手(外角 8dp、内角直角,中间一条 `onPrimary` 握把线), 范围外胶片压一层 62% `v3_bg`,当前帧选框与标记点收起。把手热区 48dp,按帧边界吸附、每跨一帧震一下,拖到屏幕边 40dp 内胶片自动滚动; 拖动时舞台显示正在拖的那一端的帧,松手后播放头吸过去。片段至少两帧(一帧就是「选帧」,MP4 编码器也不收单帧)。 播放控制两端的「标记 / 速度」原位换成「设为起点 `[` / 设为终点 `]`」(把入 / 出点放到播放头;越过另一端时另一端退回首 / 末帧, 剪辑软件惯例),速度回到 1×,看到的节奏就是导出的节奏,播放只在范围内循环。信息行第二行改报「第 4–12 帧 · 共 9 帧 · 1.13 s」, 末端换成「GIF | MP4」连通组(默认跟「动图保存格式」设置,只在本页切换,不改全局设置)。主操作「导出 GIF / MP4」, 导出中按钮显示百分比并禁用;分享走同一条编码直接分享成品。导出跑在 ViewModel 上,旋转不打断;MP4 压不出来自动改 GIF 并如实提示。 成品进动图(Ugoira)存储桶,沿用动图命名模板加 `_clip04-12` 后缀。 ### 图片滤镜(2026-10-13 起) 看图页 AI 菜单与作品页「更多」里的「滤镜」打开 `ImageFilterFragment`,对象是作品的**当前这一页**,主操作「保存」。 沿用动图逐帧的「作品 / 内容」配方:舞台 → 「滤镜 | 调节」连通组(末端 48dp 重置,可 Snackbar 撤销)→ 面板 → 一条滑条 → 主操作。 - **舞台**:26dp 容器完整显示这一页;**按住看原图**,左上角浮出「原图」玻璃小标,进页后底部提示一次「按住图片对比原图」(关闭动画时不提示)。 加载中显示原图下载百分比,失败给「重试」实色胶囊。 - **滤镜条**:按来源分组横滑(人像清新 / 胶片 / 电影氛围 / 黑白),每组上方 11sp 600 `v3_text_2` 组标; 一格 = 64dp 缩略图(17dp 圆角,渲的就是这一页)+ 12sp 名字;选中 = 2.5dp `textAccent` 描边 + 名字转主题色 600。 名字只描述观感(奶油、CCD、电影青橙…),不出现 App、品牌或胶卷型号。 - **调节**:横滑胶囊列出 10 项,改过的胶囊带数值(「亮度 +20」);下方滑条,双向项用居中滑条、过 0 轻震,点末端数值复位。 两个面板叠放、不用的 INVISIBLE,切换时舞台高度不跳;原图没有强度,强度行收起但保留占位。 - **主操作**:56dp 分享浅色圆 + 整宽 56dp「保存」实色胶囊;保存成功舞台白闪、按钮 1.6s「已保存」+ 对勾。 成品进 Illust 桶、沿用插画命名模板加 `_filter_<滤镜>` 后缀,改过强度 / 调节再带 6 位参数指纹(同名 = 同一张图); 不透明图出 JPEG 95,带透明出 PNG。 - **性能约定**:滤镜 / 强度 / 调节先合成一只 33³ 3D LUT,预览与导出共用 `libshaft_filter.so` 同一个内核(所见即所得); 拖动中渲 1/4 像素草稿、停手 120ms 补清晰帧;新增滤镜只写 `ColorOp` 组合,不要在像素循环里加分支。 ## 哪些是固定的,哪些可以变化 | 固定关系 | 可以随页面变化 | | --- | --- | | 底 → 容器 → 内容 → 强调的层级 | 页面是否有 Hero、统计栏、导航或大图 | | 主题色与状态色分开 | 用户选择的主色、业务类型图标、有限的插图色 | | 大标题、清楚正文、弱化辅助信息 | 文案、标题行数、内容密度与页面长度 | | 胶囊操作与大小容器的圆角对比 | Hero 插图的对象、成功徽章的形状 | | 一个区域的主次操作可辨 | 不同任务、阅读与管理场景的动作种类 | | 稳定布局、及时反馈、完整状态 | 侧栏、单双栏与原生导航形态 | **V3 是项目的整体语言,MD3-E 提供表达手段。** 本规范中的 Montserrat、22px 卡片、特定配色与角度是项目选择,不是 Google 强制尺寸。色彩、形状、大小、运动和容器应帮助用户识别重点,基本交互保持熟悉;这与 [Google 的 Expressive 设计说明](https://design.google/library/expressive-material-design-google-research) 一致。 原有作品/作者页的沉浸式背景、环境光和图片优先仍然适合内容页;本次确认的推介页补充了适合运营、会员与管理页面的安静表面、大字标题和异形装饰。不要为所有页面强加同一个运营 Banner。 ## 文案:直接说明功能、条件与结果 页面文案采用克制、具体的产品语言。标题用于定位功能,说明交代条件,按钮标明动作,状态反馈报告结果。视觉上的表达由颜色、排版和形状承担。 - 页面名用「App 推荐计划」;任务用「发布 App 推荐帖」「邀请 3 位活跃好友」。避免把运营术语(如「拉新」「导流」)直接写给用户。 - 主视觉写「推荐 Pixiv-Shaft,领取 PRO 体验卡」,并在相邻说明中明确完成条件。奖励时长、期限与审核要求用准确数字。 - 成功反馈写「已提交」「已存入卡包」「已激活」,后接必要的预计时间或下一步。空态写「暂无体验卡」,再说明领取方式。 - 按钮用「领取体验卡」「查看卡包」「确认激活」。不写「收下回礼」「开始探索」「去看看」。 - 不使用「一起发光」「有了回响」「更多可能,现在开启」等口号、拟人或情感暗示。不要替用户宣称喜爱、感谢或受鼓舞。 - 英文标签只作分类与识别,如 `REFERRAL PROGRAM`、`EXPERIENCE PASS`、`7-DAY ACCESS`;不叠加英文情绪口号。 - 分享模板写产品用途、下载入口和必要的奖励说明,不捏造个人使用感受。真实体验由用户填写。 - 演示说明简洁可见:「当前为功能预览,任务与奖励均为示例,不影响账号权益。」接口、归因和服务端实现细节放在开发文档中。 ## 颜色:先命名用途,再选择颜色 ### 已确认参考值 新 Web 原型以 [tokens.css](../mockup/v3-design-system/tokens.css) 为共享源。以下是默认紫色方案;玫瑰与青绿只替换主题相关角色。新增主题必须分别检查深浅组合。 | Token | 浅色 | 深色 | 用在哪里 | | --- | --- | --- | --- | | `--bg` | `#F8F7FC` | `#101014` | 页面底 | | `--surface` | `#FFFFFF` | `#1B1A20` | 内容卡、面板、弹窗 | | `--surface-2` | `#F0EEF6` | `#24222B` | 分段选项底、弱背景 | | `--surface-3` | `#E9E5F2` | `#302B3A` | 轨道、层内弱分隔 | | `--ink` | `#262331` | `#F3EFFA` | 标题、正文与重要数值 | | `--muted` | `#716C80` | `#B0A8BD` | 次要说明与标签 | | `--primary` | `#6A4BC5` | `#C5AFFF` | 主操作、选中、强调 | | `--primary-ink` | `#FFFFFF` | `#30204E` | 实色主按钮文字 | | `--tint` / `--on-tint` | `#EAE2FF` / `#493478` | `#3C2E56` / `#DFD0FF` | 次按钮、图标底与其文字 | | `--hero` | `#EAE3F7` | `#282236` | 主视觉背景 | | `--on-hero` | `#625B72` | `#B0A8BD` | Hero 说明文字,与染色背景配对 | | `--line` | `#E7E3EE` | `#34303E` | 卡片与区域细描边 | | `--green` / `--green-bg` | `#386746` / `#E9F1E5` | `#B7D8AB` / `#283527` | 成功、已完成 | | `--glass` | 页面底色 84% 不透明 | 页面底色 84% 不透明 | 悬浮导航等覆盖层 | `on-hero` 是实测对比度后补充的角色:默认 `muted` 在浅色 Hero 上只有约 4.05:1,不能用于小字号正文;在 Hero 上使用更深的 `on-hero`。 另外提供 `danger / danger-bg`、`warning / warning-bg`、`info / info-bg` 成对角色,用于新页面的错误、注意和信息状态;它们是套件补齐的状态色,不冒充推介页已有组件。 ### 使用规则 - 页面大部分是 `bg` 和中性 `surface`。主题色优先用于主按钮、选择状态与少量引导标记。一个普通卡片不要同时使用彩色底、粗描边和浓阴影。 - 同一个颜色对一起使用,例如 `tint` 必须配 `on-tint`;不能把白字直接放在浅紫、浅绿上。深色主题的主按钮通常用深字。 - 成功 = 绿色,异常 = 对应状态色,同时给出图标或文字。类别图标的颜色不表示任务已完成。 - 原型 Hero 的奶油/紫色卡券是装饰插图色,不是会员等级或所有页面的全局强调色。线上 App 的 Premium 金色仍保持原有品牌语义。 - 玻璃只用于覆盖层和沉浸式内容,不给每张普通任务卡加模糊;不支持 blur 时仍需足够不透明的底。 - 对正文与按钮文字优先要求至少 4.5:1;大字号按平台规则检查。颜色要按**合成后的实际背景**测量,不按原始 HEX 猜测。 ## 字体与阅读节奏 小说阅读器的段间距以**当前正文渲染行高**为单位:1.0 等于一行,0.0 不额外留白; 翻页和滚动共用包含用户行距的固定正文行高,源文本中的空行至少占一正文行。 段间距统一四舍五入到整数像素后再排版和渲染,避免逐段累积误差。新默认值为 0.6 行; 已有阅读设置的用户按升级时的字体、字号和行距换算一次段间距(包括未调整段间距时的旧默认值), 在 0–2.5 行范围内保留原来的实际留白;只有空设置使用新默认值。 **Montserrat 是 V3 的英文、数字与品牌字体。** 中文搭配 Noto Sans SC 或系统中文字体(苹方 / 系统 sans-serif),保持中文笔画与 Montserrat 的几何感协调。Montserrat 没有中文字形,不要期望单设它就能改变中文。 Web 字体栈:`Montserrat, Noto Sans SC, PingFang SC, Microsoft YaHei, system sans-serif`。套件的 `fonts.css` 直接引用仓库已有 400/500/600/700/800 字重,因此离线不必回退英文;App 推介原型沿用 Google Fonts 加载机制并切换为 Montserrat。使用真实字重,`font-synthesis: none`,不要用描边或阴影假造粗体。 Android 复用 `app/src/main/res/font/montserrat_{regular,medium,semi_bold,bold,extra_bold}.ttf` 和 `textMontserrat*` 样式。中文由系统回退;复杂中文正文以可读性为主。只改变字体族不能形成层级,要同时指定以下字号、字重、颜色与行高。 | 角色 | 参考 Web | 建议 Android | 字重 / 行高 | 字体颜色与用法 | | --- | --- | --- | --- | --- | | 页面标题 | 32px,手机 28px | 28–32sp | 700 / 1.3–1.4 | `ink`,一个页面一级标题 | | Hero 主标题 | 36–40px,手机 28–31px | 28–36sp | 800 / 1.4 | `ink`;少量关键词可用 `on-tint`,最多两三行 | | 分区标题 | 20px,手机 19px | 20sp | 700 / 1.4 | `ink`,任务、权益、设置分组 | | 卡片标题 | 15–16px,手机 15px | 16sp | 600 / 1.5 | `ink`,信息行起点 | | 正文 | 套件 14–16px,原型 12–13px | 14–16sp | 400 / 1.7–1.9 | 关键说明 `ink`,次说明 `muted` | | 控件标签 | 套件 12–14px | 14sp | 600 / 1.4 | 主按钮 `primary-ink`;次按钮 `on-tint` | | 辅助说明 | 套件 11–12px | 12sp | 400–500 / 1.6 | `muted`,时间、来源、非关键标记 | | 核心数字 | 40–55px | 40–48sp | 600 / 1.1 | `ink`,单位 12–14px / 400 / `muted` | **原型仍有 7–10px 的英文装饰小字,这些仅属于插图与非关键标记。** 接入 Montserrat 时已把任务标题、正文和状态说明分别调整为 15–16、12–13、11px;可复用套件进一步以 14–16px 正文和 48px 热区作为起点,保留大小关系。金额、期限、条件、错误与操作不能缩到装饰字号。不要给整个中文标题套过大的负字距;Montserrat 的大数字可以略收紧(约 -1 至 -1.5px),进度与汇总用 `font-variant-numeric: tabular-nums`,避免更新时数字跳动。 Eyebrow(标题上方小标签)只用于少数主区,字距约 1.5–2px,内容简短;业务说明用中文正文。新增页面可以完全不使用英文。长标题换行,关键条件不省略,说明文字随系统字号增长。 ## 几何:空间、形状、层次 ### 空间尺度 基本节奏:**4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 48**。先选尺度,再按视觉对齐微调。以下尺寸是 CSS px;Android 同类布局使用 dp 并结合设备验证。 | 位置 | 桌面参考 | 手机参考 | | --- | --- | --- | | 页面水平留白 | 48,窄桌面 28 | 20,320px 屏可用 14–16 | | 标题区至 Hero | 28 | 23–24 | | Hero 内边距 | 32–36 | 24–26 | | Hero 至主内容 | 39–40 | 28–32 | | 主内容 / 侧栏间距 | 30 | 堆叠后 20–24 | | 普通卡片内边距 | 22–24 | 16–20 | | 图标与文字间距 | 12–15 | 11–12 | | 同组独立卡片间距 | 10–12 | 10–12 | | 不同分区间距 | 28–40 | 24–32 | ### 形状分工 | 元素 | 参考值 | 说明 | | --- | --- | --- | | Hero | 30,手机 26 | 全页最大的普通容器 | | 面板 / 汇总卡 | 24 | 比任务卡略舒展 | | 任务 / 内容卡 | 22,手机约 21 | 轻描边,无常驻重阴影 | | 底部 Sheet | 顶角 28–30 | 手机上贴底,桌面居中 | | 类别图标容器 | 40–48 尺寸;17/17/17/7 圆角 | 非对称仅点缀图标区;其它类型可用圆形 | | 成功徽章 | 约 86;32%/44%/34%/44% 圆角 | 完成后出现,可轻微转 -8° | | 主 / 次按钮 | 胶囊,按下可变为 15px 圆角 | 保持区域占位不变 | | 数字小标 | 12 | 数值、单位、类别有主次 | | 设置分段行 | 外角 20、内角 5、行隙 2 | 延续 `WitRowStyle`,不要为每行嵌套大卡 | Hero 插图可使用两张相互遮叠的票卡。推荐计划使用后层奶油色 PRO、前层紫色 MAX,两张卡均为 **7 天**,不叠加「PRO 体验」贴纸(2026-09-18)。票卡在独立区域内按完整画板等比缩放,轻微旋转 -8° / +8°,卡面名称、时长和旋转后的边角都保留在容器内;不再用负向偏移裁掉 MAX。手机先展示全宽标题与说明,下方邀请操作和插图在空间足够时并排,窄屏或字体放大时上下排列;宽屏可将正文与插图分列。正文、按钮和卡面互不遮挡,大字体时仍保持插图正常对比度。插图展示 PRO / MAX 的 7 天体验卡,具体任务与奖励规则由业务实现维护。 层次先用表面差异和细线建立。Web 通常 1px 描边;原生分段行沿用约 0.5dp、至少 1 像素的描边。阴影留给浮层与 Hero 装饰,普通列表接近零 elevation。 ## 布局配方:同一种语言,四种页面 | 页面 | 结构 | 表达重点 | | --- | --- | --- | | 运营 / 会员 / 引导 | 标题 → 一个 Hero → 分区 / 筛选 → 独立任务卡;宽屏加汇总侧栏 | 大标题、一处插图、明确回报与下一步 | | 下载 / 历史 / 管理 | 标题 + 紧凑汇总 → 筛选 → 列表 → 条件出现的批量动作 | 内容密度、稳定行高、进度与操作;通常无 Hero | | 设置 / 账户 | 标题 → 分组标题 → 连通分段行 → 必要说明 | 20/5 圆角关系、2dp 行隙、值与操作对齐 | | 作品 / 作者 / 阅读 | 内容主视觉 → 关键信息 → 轻容器与操作 | 图片/文字本身优先;环境色、覆盖层适量使用 | 动图在作品页与大图页共用静图的双指缩放、放大后平移和双击缩放手势,操作期间继续播放。作品页单击动图打开大图,大图页单击切换工具栏;播放、重试与加载浮层固定在画布上方,不跟随画面缩放。适应尺寸时单指滑动交还列表,放大后优先平移画面,到边缘再交还父容器。 作品详情的普通竖向插画在实际图片栏宽度至少 600dp 时,高度不超过所在列表的可用视口,按比例完整显示,允许两侧留白。此规则适用于高宽比大于 1、低于 2.5 的 `illust`;漫画、超长图和窄栏继续按自然比例滚动展示。预览与原图使用同一尺寸规则,折叠、分屏或窗口高度变化后重新测量,不以物理屏幕宽度判断。 原型宽屏画布参考:100px rail、主内容最大 1360px(含水平内边距)、内容与侧栏 `minmax(0,1fr) 300px`。1180px 以下可压缩留白;760–980px 收成单主列,汇总与说明并排;760px 以下手机单列,rail 收起,需要时使用底部导航。 这些是 Web 演示断点,**不是 Android WindowSizeClass 阈值**。Android 根据可用窗口与现有导航体系决定单双栏。浮动导航要预留内容底部间距和系统安全区,键盘出现时表单动作仍可到达。 ```text 运营页 / 宽屏 手机 ┌ rail ┬ 标题与说明 ─────────────┐ 标题与说明 │ │ Hero:文案 | 装饰插图 │ Hero:文案优先 │ ├ 主内容 ─────┬ 汇总侧栏 ─┤ 分区标题 + 筛选 │ │ 筛选 │ 核心数字 │ 卡片 / 卡片 / 卡片 │ │ 任务卡列表 │ 步骤说明 │ 汇总与辅助说明 └──────┴────────────┴───────────┘ 底部导航(按需要) ``` ### 平板内容页 [平板设计方案与交互原型](tablet-design/README.md) 展示同一套 V3 在画廊和发现页中的用法。两页共享设计套件的颜色与 Montserrat,内容页保留图片优先,不复制运营票卡或奖励文案。 作品卡采用 22px 圆角,图文专题采用 30/26px 主容器,详情按选择状态出现。是否双栏由当前窗口、导航、留白及两侧内容最小宽度共同决定;Web 原型在 1040px 且高度至少 480px 时展示画廊双栏,这不是 Android 标准断点。原生实施须重新计算 dp、系统 Insets 与铰链。 预览设置统一提供日夜、三种强调色和加载/失败状态;原型数据标识、返回焦点、窄屏及放大文字按同一验收清单检查。 ## 组件配方 ### Hero 业务标签 → 两行主标题 → 一两句价值说明 → 一个主按钮 → 必要条件。文案区约占宽屏一半,装饰区独立且 `aria-hidden`。手机优先保留文案和操作,减少插图或放在文字之后;不要靠缩小正文容纳插图。 标题示例「推荐 Pixiv-Shaft,领取 PRO 体验卡」;按钮示例「邀请好友」。用户在首屏就知道推广什么、要做什么。 ### 任务卡 / 操作卡 ```text [类别图标] 类别 · 状态 [7 天 PRO] 任务标题 一两句具体说明 完成条件 1/3 [主/次动作 →] ━━━━━──────────────── ``` 上层承载任务与回报,下层承载进度与下一步。图标 40–48;宽屏动作行对齐正文起点,窄屏可回到卡片左缘以保护进度和按钮。进度同时提供文字与数字,不用长度暗示未定义的百分比。 | 状态 | 呈现 | 动作 | | --- | --- | --- | | 未开始 | 中性状态、条件与奖励清楚 | 查看任务 / 开始 | | 进行中 | 有意义的计数或进度 | 查看进度 / 继续 | | 审核中 | 提交成功与反馈时间;不要伪造进度 | 查看审核 | | 需补充 | 问题原因、恢复方式 | 补充并提交 | | 可领取 / 可完成 | 成功色标记、完成计数、醒目动作 | 领取奖励 / 确认完成 | | 已领取 / 已完成 | 稳定完成标签与结果位置 | 查看卡包 / 查看结果 | ### 按钮、选择器与图标 - 主按钮:`primary + primary-ink`,实色胶囊;次按钮:`tint + on-tint`;低优先级入口:文字/描边。控件图标保持约 20–22px、线宽约 1.7,采用统一 SVG 或原生图标系统。 - 通用套件操作热区至少 48px;Android 至少 48dp。原型里的 38–44px 视觉控件可以保留外观,但生产实现应扩大真实热区。 - 筛选器:浅底连通组、选中项独立浅色容器,计数为次级小标。单选用 `aria-pressed` 或完整 tab 语义;如果使用 tab,必须实现键盘切换和面板关联。 - 同层按钮保持相近高度,文字长就换布局;不要把整行操作压成难读的小字。图标按钮提供名称,装饰图标不重复朗读文字。 - 分类 Tab 对应多页内容时,点击与左右滑动共用同一分页状态;指示滑块连续跟随拖动进度,反向拖动和取消手势也同步回退。各页保留独立滚动位置,长标签或大字体下让选中项保持可见。表情选择器的 Tab 统一靠起始侧排列,BottomSheet 的关闭按钮位于同一行末端。 每日推荐入口位于发现页「其他分类」,紧随「人气画师」,沿用主题色分类按钮;点击进入带标题和返回按钮的独立页面。首页推荐区只保留「推荐作品 / 热门标签」两个 Tab,并保留用户配置的顺序;两个 Tab 等分整行宽度(`fixed + fill`),标题在各自半区居中,保留至少 48dp 触控高度,不按内容宽度聚在整行中央。Lite 渠道不显示每日推荐入口(2026-09-18)。 官网发现(2026-09-19)在发现页「其他分类」增加独立入口,与原「发现」候选池并列。内容页使用标准工具栏、浅底分级选择条与现有作品瀑布流;全部 / 全年龄 / R-18 支持点击及左右滑动,各页独立保留列表和滚动位置。默认分级跟随当前 R-18 过滤设置;长标签与大字体时选择条可横向滚动,触控高度至少 48dp。缺少网页会话或网页账号与 App 不一致时,空态提示使用同一账号并提供「去登录」,工具栏菜单保留网页登录以便会话过期后重登。骨架、失败重试与分页状态沿用 feeds 框架。Lite 渠道与 Web 首页一样隐藏此入口。 ### 本地库筛选面板(2026-09-25,2026-09-28 重做) 收藏库与关注库共用一张「筛选与排序」Sheet(`BookmarkFilterSheet`,零件在 `LibraryFilterViews`)。 顺序按 Sheet 配方:标题(22sp Montserrat Bold)→ 当前状态(「共 N 件 · 已启用 K 项筛选」,13sp `v3_text_2`) → 条件 → 主操作。「清空」在标题行末端:有条件时是带重置图标的主题浅色胶囊;没有条件时退成一行 `v3_text_3` 文字、不可点(不用半透明胶囊,深色底上那只是一块污渍)。 **无界平铺**:条件分组不套卡片,直接铺在 Sheet 的 `v3_bg` 上,靠组标题(17sp / 700 `v3_text_1`)、 行标题(14sp / 600)和留白分层——组间 36dp、行间 20dp,不画分隔线。左右 24dp 留白与标题行对齐, 由每一行自己带;横滑行满宽,胶囊贴着屏幕边缘进出。卡片里再套选项容器只会层层叠灰盒子。 **每个选项都是独立容器**,不放进灰轨道(轨道里浮着一串文字时看不出哪里能点)。控件形状区分语义: - **≤ 4 个互斥档位**(页数、分级、AI、作品状态、排序方向、标签匹配方式)是 MD3-E 连通按钮组: 等分整行,段间 2dp 缝,外角全圆、内角 8dp;可见 40dp、上下 4dp 透明沿补足 48dp 热区。 - **更多互斥档位**(排序依据、人气、字数)是单选胶囊,换行排开;会随书架增长的**年份**单行横滑, 选中项滑出视野时自动滚回。 - **可叠加条件**(类型、画幅、标签、作者)是多选胶囊;**排除**用日夜 `v3_danger` 浅底 + 减号,不随主题色变; **开关**是整行热区 + MD3 开关(`MaterialSwitch`,仅这一个控件套 Material3 主题,颜色由 `V3Palette` 染回)。 - 胶囊可见 36dp、上下 6dp 透明沿;单行,超长标签省略。计数是小一号的 `v3_text_2` 次级小标, 标签译名同色跟在原名后面。 - 未选中性底 = `v3_surface_3` 合成在 Sheet 底上;**选中时形状与颜色一起变**:圆角从 10dp(连通组 8dp 内角) 变成全圆,底色换成 20% 主色合成在 Sheet 底上的浅色容器 + `textTag` 字色 + 600 字重,单/多选胶囊另带勾。 180ms 渐变,按下缩到 0.96。 **排序**拆成「依据」胶囊 + 「方向」连通组(`LibraryProfile.sortKeys`),不再把十几个「键 · 方向」 组合平铺。切换依据时落到它的默认方向(新→旧 / 高→低 / 最竖长 / 长→短);只有一个方向的依据 (浏览量、页数、标题、随机)收起方向组;再点一次「随机漫游」换种子重洗。 标签云默认铺 24 个,末尾是描边的「显示全部 N 个 / 收起」胶囊;在标签里搜索时全部铺开,已选和已排除的 钉在最前。底部主操作是整宽 56dp 实色胶囊(左右 24dp),按下圆角收到 15dp,文案始终带实时命中数。 露出哪几组由书架的 `LibraryProfile` 决定:关注库只有排序、最近投稿年份和取自最近作品的标签。 ### 发现页底部交流入口(2026-09-18) `FragmentCenter` 在榜单之后展示「交流与分享」,由原生 [DiscoverSocialSection](../app/src/main/java/ceui/pixiv/ui/discovery/DiscoverSocialSection.kt) 和 [DiscoverSocialArtView](../app/src/main/java/ceui/pixiv/ui/discovery/DiscoverSocialArtView.kt) 实现。聊天室使用叠放气泡,社区使用错落帖卡与心形贴片;装饰为静态 Canvas 图形,文字使用原生 TextView、Montserrat 与系统中文回退。两张卡各为一个可聚焦的按钮,箭头属于同一热区。只保留 `pressScale` 短促按压与涟漪,尊重系统动画设置。 所有强调色直接读取 `V3Palette.from(context)`:社区底为 `cardFill`,聊天室底为 `alpha20` 合成 `cardFill`,细描边为 `cardHairline`,插图使用 `primary` 与透明度色阶;文字从 `textAccent`、`onPrimary` 和日夜 `v3_text_*` 出发,按最终合成背景校正到至少 4.5:1。没有页面专属的固定紫色或另一套主色表。普通卡片没有阴影,轻微投影仅限插图。 模块随发现页滚动,沿用 `BottomSafeInsets`。可用宽度不足或字体放大时改为单列;正常字体下单卡使用左文右图,大字体下插图与文字上下排列,标题与按钮允许换行。聊天室和社区分别跳转 `TemplateRoute.CHAT` / `PLAZA`,在支持的渠道默认展示;侧边栏的两个旧入口、设置页的两个入口开关及对应存储字段均已移除。公开聊天室横幅仍由独立的通知开关控制,私信通知不受影响。社区是该入口的显示名,目标页仍为广场。标题、说明与操作文案覆盖简中、繁中、英、日、韩、俄、土七种语言。不增加在线人数、未读数或假动态。 ### 汇总面板与卡包 主数字 40–55,单位 11–14,标签放在数字旁或下方。只展示有业务价值的 1–3 个汇总项,来源和单位清楚。可用小星形填补留白,但它不能看起来像可点击设置。 卡包显示来源、权益长度、有效期、状态与一个动作。领取和激活语义分开;完成反馈说明结果存放在哪里。不要让无关页面继承 PRO 奖励、有效期等示例业务。 App 推介计划的任务与卡包始终在同一页展示(2026-09-18):手机在 Hero 下先展示奖励概览和卡包,再展示推荐任务;宽屏任务居左,奖励概览和卡包居右。卡片直接显示激活操作,空卡包显示领取条件;任务筛选仅影响任务列表。禁止用「查看卡包」替换任务列表、再重复整页顶部内容;领取反馈里的「查看卡包」和任务的「查看奖励」只滚动定位本页卡包。激活确认仍使用 Sheet。 ### 弹窗、表单与反馈 手机 Sheet 贴底、顶角 28;桌面约 480px 居中。顺序:标题 → 当前状态 → 条件/字段 → 主操作 → 可选次操作。超长内容内部滚动;支持返回/Escape、焦点留在弹窗、关闭后回到触发元素。 作品详情的「页面预览」在标题右侧放「用阅读器看」紧凑次级胶囊(2026-09-23,#1145),复用 `witstudio` 的主题浅底,采用 13sp / 500 标签、16dp 书本图标、左右 12dp 留白;可见胶囊约 32dp 高,透明上下沿保留 48dp 热区,避免按钮抢过标题。窄屏、长译文或字体放大导致同排放不下时,操作换到下一行,文字可换行。V2 / V3 共用此入口;单图不显示 `1 / 1`,阅读器入口放在「更多」菜单。离线快照只预览本地页面,阅读器内部的预览不重复显示阅读器入口。 作品详情与二级大图页底部的「下载 + 收藏」悬浮胶囊默认居中,可在设置里改为靠左 / 靠右(2026-09-24,#1090)。靠边时胶囊离屏幕边 20dp(与二级大图页那一行的左右留白对齐),横屏侧边导航栏或挖孔在同侧时再叠加其 inset,收藏心固定在贴屏幕边的外侧,其余段镜像排开,评论跳转段落在靠屏幕内侧的一端;「下载 / 收藏顺序」只在居中时生效,设置里也只在居中时露出。二级大图页胶囊靠右时,同一行的页码让到左侧。两页共用 `V3FabBarController.applyLayoutPreference`,底距规则不变。 小说阅读器的搜索结果行保留「序号 → 两行摘录 → 右下角全文位置」的层级(2026-09-23,#1138)。位置按命中起点占原文字符总数的比例向下取整,显示整数百分比,不随字号、分页或滚动模式变化;使用 12sp Montserrat Regular 与日夜 `v3_text_2` 灰色。百分比独占末端宽度,序号随位数和字体放大增宽,摘录占剩余空间;整行点击仍跳到该命中位置。 Android 的 `WitDialog` 菜单行以 52dp 为最小高度,长文案或字体放大时随文字增高,超高菜单由内容区滚动承接;不要固定行高裁切文字。字号与换行验收使用原生字体测量,覆盖 320dp 窄屏和 2 倍字体(2026-09-20,#1102)。 小说朗读设置使用同一套可滚动 `WitDialog` 和连通分段行,集中显示速度、高亮、自动跟随、双击跳转与常驻入口开关。高亮使用阅读器自身主题的高亮色;“从本页开始朗读”是至少 48dp 的次级胶囊,避让底部系统安全区,工具栏展开时收起并在菜单保留入口。只有朗读位置不在当前页面时显示常驻入口。自动跟随只移动当前小说的页面或滚动位置,双击从命中的段落开头重读(2026-09-23,#1139)。 小说阅读器的「文字颜色」位于配色下方,分别为每种阅读配色记住正文与章节标题的字色,支持恢复当前配色的默认字色(2026-09-23,#1142)。复用现有 HSV / HEX 取色器,在阅读背景上预览候选字色;确认后同时应用到翻页与滚动阅读,取消不保存。取色器标题与操作分行,预览及输入区随字体增高,窄屏、长译文和放大字体时由内容区滚动承接。 表单使用常驻标签、浅底圆角输入框、字段附近的错误原因。提交中避免重复操作,服务端完成后再呈现成功。网络失败保留已填内容并给出重试。 短暂 Toast 适合“已复制”等非阻断反馈;影响操作的错误保留在页面或字段旁。成功可用一次异形徽章,但应同时说明结果。空状态描述原因并提供一个真实可用动作;加载、空、错误不能都呈现为空列表。 破坏性操作使用语义危险色:广场菜单的「删除帖子」,以及「放弃草稿」「删除帖子」弹窗中的执行按钮采用 destructive 样式;Android 确认按钮复用 `WitDialogAction.ACTION_PROP_NEGATIVE`。「取消」「继续编辑」和弹窗正文保留普通样式,危险色跟随日夜资源,不随用户主色变化。 ### 带预览的选项选择器:插画列表布局(2026-10-08,#1214) 选项的差别是**视觉效果**时(布局、排版密度这类),选择器必须给每个选项画预览,不能只列名字。参照 [IllustListLayoutPicker](../app/src/main/java/ceui/pixiv/ui/settings/IllustListLayoutPicker.kt): - 容器用 `WitBottomSheet`:20sp / 700 标题 → 13sp `wit_text_2` 一句说明(作用范围)→ 2×2 选项卡,卡间距 12dp,内容超高时 sheet 内滚动。 - 入口两处:「设置 → 界面 → 插画列表布局」,以及插画卡长按菜单末项(就地换,不用钻设置)。从长按菜单改时当前列表立即重排,并把长按的那张卡留在原来的屏幕高度;其它列表回到前台时跟上。作品详情页底部的相关作品同样跟随;大图、简介、评论等区块始终整行贴边。 - 选项卡 = 22dp 内容卡:上半是示意预览(14dp 圆角「屏幕」,`wit_bg` 底),下面 15sp / 600 名称 + 12sp `wit_text_2` 一句规则(如「等宽不等高」)。选中 = `alpha10` 合成的主题浅底 + 2dp `textAccent` 描边 + 预览右上角主题色圆形勾;按下 0.96,选中后停 180ms 再收起(关闭动画时立即收起);读屏按单选项报「已选中」。 - 预览是代码绘制的示意图,不放截图:所有选项用**同一组**示例比例、同一套色块顺序,差别只剩排布本身。色块从 `wit_bg` 向主题色及其 ±30° 邻近色相混合出几档斜向渐变,夜间整体提亮约 0.22;底部 30% 渐隐暗示可滚动。多列预览固定 3 列,2 列在小卡里排不出可辨认的图案。 ### 可下载选项:小说阅读器「更多字体」(2026-10-10,#1060) 同一条「带预览」规则用在需要先下载的选项上。参照 [ReaderFontSheet](../app/src/main/java/ceui/pixiv/ui/novel/reader/ui/ReaderFontSheet.kt): - 入口是阅读设置「字体」横排末尾的「更多字体」chip;下载好的字体随后作为普通 chip 出现在同一排,切换不必再开面板。 - `WitBottomSheet`:标题 → 一句来源与授权说明 → 「简体中文 / 繁体中文 / 日文」单选分段(复用阅读设置的分段轨道与选中胶囊,按文案收紧、可横向滚动,48dp 热区)→ 连通分段行(外角 20、内角 5、行隙 2)→ 末尾 12sp 说明加「设置 GitHub 加速」文字入口。只把标题与分段钉在顶部,说明文字随列表滚动:一组近二十款时滚到底也能直接换组,横屏加大字号时顶部也不会把列表挤没。打开时落在当前所用字体那一组,否则按界面语言(繁体地区 → 繁体,其他中文 → 简体,其余 → 日文)。 - 分组按字符覆盖而不是字体名:简体组完整覆盖 GB 2312、繁体组完整覆盖 Big5 常用字、日文组完整覆盖 JIS 第一水准;不达标的字体(缺字会和系统字体混排跳字形)不收。 - 一行 = 16sp / 600 名称 → 20dp 高的字形预览 → 12sp 状态行(「13.1 MB · 未下载」、下载百分比、失败原因用 `v3_danger`)→ 下载中出现 4dp 主题色进度条。末端只放当前状态的唯一动作:未下载「下载」、失败「重试」(浅色胶囊),下载中取消(×),已下载删除(危险色图标),使用中换主题浅底并打主题实色圆勾。 - 预览是字体自己的轮廓转成的 VectorDrawable,未下载也能看到真实字形,跟随 `wit_text_1` 着色;示例简体「春眠不觉晓,处处闻啼鸟」、繁体「春眠不覺曉,處處聞啼鳥」、日文「ゆく河の流れは絶えずして」,同组每款同句。 - 下载在进程级仓库里跑,关掉面板不中断,再打开接上进度;选用已下载字体后停 180ms 收起。 ### 应用锁(2026-10-05,#1197) 独立模块 `:applock`([AppLockActivity](../applock/src/main/java/ceui/pixiv/applock/AppLockActivity.kt))。锁屏页讲的对象是「这个 App 被锁住了」,主操作只有一个「解锁」: - 版式按设置 / 账户配方,无 Hero、无插图:`wit_bg` 中性底 → 72dp 的 17/17/17/7 图标容器(锁形图标,`alpha15` 主题浅底 + `textAccent` 图标)→ 28sp / 700 标题「Pixiv-Shaft 已锁定」→ 15sp / 400 `wit_text_2` 说明 → 32dp 后 56dp 实色胶囊「解锁」(指纹图标随文字色)→ 验证出错时一行 13sp 状态文字(礼貌朗读区)。整列居中,文字最宽 400dp,大字体时整页滚动。 - 主题色经宿主 `AppThemeStyle` 套到锁屏页,与全 App 同一套 `V3Palette`;入场只做一次 350ms / 7dp 淡入上移,系统关闭动画时不做。 - 验证弹窗是系统 `BiometricPrompt`(指纹 / 面部 / 屏幕锁),不自绘密码键盘、不另设密码。进入锁定时自动弹一次;用户取消后停在锁屏页,不追着重弹。 - 锁屏页无动画盖上(滑入会露出底下页面);锁定时返回键把 App 退到后台,不露出内容。 - 设置入口在「账号」页单独一组:应用锁开关(开启前先验证一次)+ 开启后才出现的「自动锁定」(立即 / 1 / 5 / 15 分钟)。没有屏幕锁时弹窗说明原因并给「去设置」。 ## 动效 | 场景 | Web 建议 | 约束 | | --- | --- | --- | | 颜色与选中状态 | 160–200ms,标准缓动 | 不改变布局大小 | | 按压 | 0.96 scale,约 300ms 弹性近似 | 不让按钮逃离手指 | | 卡片入场 | 350ms,位移约 7px | 首次出现一次;最多少量错峰 35ms | | Sheet | 300ms,位移约 20px | 背景遮罩同步,无长距离飞入 | | 进度变化 | 约 500ms | 仅在真实数值变化后更新 | | 成功 | 轻微形状/尺度反馈一次 | 不循环抖动、不强制烟花 | 参考曲线 `cubic-bezier(.2,.85,.25,1.25)` 是 CSS 的弹性**近似**;Android 采用宿主支持的 spring/motion 实现,不能把曲线参数当物理弹簧参数照填。减少动态效果时关闭非必要位移/缩放,保留清楚状态。原生同时尊重系统动画设置。 ## Android 接手地图 | 设计角色 | 现有入口 | 实现注意 | | --- | --- | --- | | 页面底、基础表面、文字、语义色 | [`wit_colors.xml`](../witstudio/src/main/res/values/wit_colors.xml) 与 [夜间版本](../witstudio/src/main/res/values-night/wit_colors.xml) | 是现有 Android 基础色权威;透明表面需叠在正确底上 | | 用户主题强调、卡片底、细描边、强调文字 | [`V3Palette.kt`](../witstudio/src/main/java/ceui/pixiv/witstudio/theme/V3Palette.kt) | `V3Palette.from(context)` 从宿主主色派生;`textAccent` 有对比度校正 | | 主 / 次按钮底 | `V3Palette.pillPrimary / pillSecondary` | 正文色独立配套验证;工厂仅生成背景,不代表已处理全部控件状态 | | 代码搭页面的公共零件 | [`V3Views.kt`](../witstudio/src/main/java/ceui/pixiv/witstudio/theme/V3Views.kt) | `dp / label / card / rowShape / pillButton / iconTile / noticeCard / pressScale` 等;2026-09-17 从广场内部提升到 witstudio,新页面直接 import,不要再抄一份 | | Montserrat 字体文件 | [`witstudio/res/font`](../witstudio/src/main/res/font) | V3 的英文与数字字体归设计系统;Kotlin 里取字体一律走 `Context.v3Font(weight)`,别再 `ResourcesCompat.getFont(R.font.montserrat_*)` | | 设置分段行 | [`WitRowStyle.kt`](../witstudio/src/main/java/ceui/pixiv/witstudio/theme/WitRowStyle.kt) | 用 `rowBackground(index,total)`,整组完成后 `applyThemedRowBg(root)` | | 对话框 | [`witstudio/dialog`](../witstudio/src/main/java/ceui/pixiv/witstudio/dialog) | 复用已有 WitDialog 系列,避免造另一套不跟主题的弹窗 | | 底部选择器 | [`WitBottomSheet`](../witstudio/src/main/java/ceui/pixiv/witstudio/dialog/WitBottomSheet.kt) | 主题表面与安全区由 witstudio 管理,拖拽与嵌套滚动复用 Material;内容高度有界,分类使用有选中态的 tab,不用独立按钮拼接 | | 圆角 / 按压基础控件 | [`witstudio/widget`](../witstudio/src/main/java/ceui/pixiv/witstudio/widget) | 优先现有实现,补充而非复制整套基础设施 | | 现有 V3 资源别名 | [`app/values/colors.xml`](../app/src/main/res/values/colors.xml) | `v3_*` 基础色引用 `wit_*`;页面业务色不反向塞进通用 UI 库 | Web 参考值和 Android 当前基础色**不完全相同**,这里统一的是视觉关系。新规范不会自动重写全 App 颜色,也不要求把 Web 原型嵌入 WebView。新增全局角色应同时补日夜资源并检查既有使用处;页面局部表达从主题派生。 普通内容页需要与设置页对齐的顶栏时,复用 `fragment_settings_hub.xml` 的 Toolbar:`wrap_content`、`fitsSystemWindows=true`、宿主 `colorPrimary`、居中 18sp 标题和同款返回图标,并调用 `BaseFragment.applyToolbarInsets(activity, root)`。Material3 完整主题仅放在顶栏下方的内容容器,避免覆盖用户主色;不要用固定 Toolbar 高度再叠加状态栏 padding。真机对照设置页核验标题位置、顶栏高度和主题色。 独立内容页优先直接 include `toolbar_layout.xml`;顶栏消费 Insets 时,API 29 及以下通过现有 `ViewGroupCompat.installCompatInsetsDispatch` 保证内容区继续收到 Insets。页面跳转沿用统一宿主和系统预测性返回;只在草稿未保存、正在提交或面板需要收起时启用返回拦截,并随状态变化立即更新 enabled,禁止常开回调再在回调内部判断是否退出。`TemplateActivity` 显式开启 `enableOnBackInvokedCallback`,兼容 Android 13–15 的选择性启用机制。 至少验证预设主色中的紫/粉/青绿/亮黄和一个自定义 HEX。背景跟随主题不代表文字已经可读;尤其亮黄不能仅用固定 HSL 亮度猜测。字号用 sp,布局用 dp,支持字体缩放与 TalkBack。 [Android 官方无障碍建议](https://developer.android.com/guide/topics/ui/accessibility/apps) 提供文字对比度与触控尺寸依据。本规范将关键操作热区设为至少 48dp;旧原型的装饰小字与局部 44px 控件不是豁免。 ## 从空白到成稿:一个可复制的例子 以“本地下载管理”新页面为例: 1. 目标:用户看清下载状态并继续未完成任务;主操作「继续全部」。 2. 选管理配方:省去运营 Hero,用标题「下载管理」与紧凑汇总。 3. 筛选:全部 / 下载中 / 已完成;计数按真实列表计算。 4. 下载项:封面或类型图标 → 文件名与来源 → 已下载/总大小 → 进度 → 暂停/继续。失败项显示原因和重试。 5. 保留 V3 的中性染色底、22px 卡片、主题操作、清楚字级;需要批量选择时再出现浮动动作栏。 6. 用深色、亮黄主题、320px 窄屏、长文件名和大字级验证。 即使没有票卡、星形、PRO 或邀请任务,也应与推介页面看起来属于同一产品。这就是可迁移的设计语言。 ## 验收清单 - [ ] 标题、插图、任务与按钮的业务对象一致;示例数据、演示动作与真实能力标识清楚。 - [ ] 第一眼能指出页面目的和一个最强操作;说明不是靠 8px 小字才读得到。 - [ ] 中性表面占主导;主题、状态、装饰色分工明确;普通卡片无多重强调。 - [ ] 容器的 30/24/22/17 与胶囊层级可辨,设置行保留 20/5 的连通关系。 - [ ] 除装饰外文字不倾斜;长标题和关键条件不被插图、按钮或裁切遮挡。 - [ ] 深浅 × 紫/粉/青绿主题检查;Android 增加亮黄、自定义主色检查;实测文字对比度。 - [ ] 手机 320/390、平板 768、宽屏 1440 无非必要横向滚动;200% 字体/缩放仍可完成主流程。 - [ ] 加载、空、失败、处理中、成功、已完成状态均有解释和合适动作,不用静态假成功替代请求结果。 - [ ] 热区、焦点、键盘/返回、读屏、减少动态效果与安全区适配可用。 - [ ] 交接提供规范链接、tokens、组件/页面源文件、至少深浅两张预览和关键交互的验证结果。 ## 维护方式 这份文档是 **设计决策入口**;新 Web 原型的变量在 `mockup/v3-design-system/tokens.css`、基础组件在 `components.css`;Android 的运行时资源继续以 `witstudio` 为准。App 推介原型保留已确认的布局与自身样式;本次按用户要求同步采用 Montserrat 并完善字号层级,未重构为新组件库。 调整通用风格时同步更新规范、套件与图鉴;改变已确认页面的视觉另行按任务范围处理。只属于一页的业务,不上升为全局规范。新增规则要有一个可看的例子和明确适用范围,避免积累抽象形容词。 贴纸选择器的分段分类以小说阅读器设置为准:复用 reader segment 轨道与选中背景,42dp 视觉高度、48dp 触控高度,整体按文案收紧;选中底使用宿主主色。贴纸选择器不显示标题,左侧主题色文字关闭与右上角分类同排。滚动内容延伸到导航栏区域,由滚动容器自身的 bottom padding 保留到底后的安全距离,clipToPadding=false;不要给整张 sheet 垫出固定底部空白条。 聊天贴纸按独立图片展示:64dp 图像、无气泡背景与阴影,尺寸大于选择器的约 32dp 缩略图;引用内容使用独立主题浅色块,不能把依赖彩色气泡的白字直接放到页面底色上。 作品评论的「表情贴图」面板是两步发送(#1147,2026-09-24,学 LINE):第一次点只选中,格子外 2dp 间隙处出现主题主色 2dp 描边(16dp 圆角,与 12dp 圆角贴图同心),贴图右上角出现 26dp 主题主色圆底 + `onPrimary` 纸飞机;再点同一张才发送,点别的贴图移动选中,切到绘文字页、收起面板或弹出键盘时清空。描边与角标只做 180ms 透明度渐变,不改变格子尺寸。输入栏的发送按钮只发文字,不承担贴图确认。理由是评论公开挂在别人作品下、发送频率低,误发代价远高于多点一下;聊天与帖子回复的贴纸仍然点即发送,不套用这条。 聊天消息时间位于气泡内右下角:默认 11sp Montserrat Regular,短消息与正文末行共用一行,空间不足或 RTL 段落时在气泡内另起时间行。按真实文本、字号和失败标记测量,不向消息追加占位空格,不影响链接或复制内容。发出消息的时间使用气泡内浅色文字;收到消息使用主题次要文字色。贴纸与大表情保持无气泡,时间以小胶囊放在图像旁的右下方,不遮盖图像。分组时间条继续保留(2026-09-16)。 聊天与帖子详情底部回复共用同一份输入栏布局、主题样式和与键盘互相切换的内嵌贴纸面板,无标题/关闭行/遮罩;帖子详情直接编辑和发送回复,回复评论时在输入栏上方显示可取消的引用条,不打开创建帖子页。帖子贴纸继续用于回应帖子;卡片上的独立回应入口保留 bottom sheet。共用分类样式与网格,内嵌面板高度和安全区由现有 BottomPanelCoordinator 管理。 聊天与帖子回复栏在键盘、贴纸面板均收起时,背景延伸到系统导航栏底部,导航栏安全距离作为输入栏自身的 bottom padding;键盘打开时由根布局避让,贴纸面板打开时由面板承接安全距离,避免重复 padding 或露出页面底色(2026-09-16)。 共用输入栏的表情、发送按钮与输入框纵向居中;多行输入或字体放大导致输入框增高时,按钮继续居中,不贴底。导航栏安全 padding 位于整条输入栏之外的底部,不参与按钮对齐(2026-09-16)。 输入框不使用浮动标签,提示文字与输入文字均纵向居中。Material FilledBox 在普通和大字体下为标签预留的上下非对称 padding,在布局膨胀后均分;保留总 padding 与输入框高度,避免文字被上方标签留白挤到底部(2026-09-16)。 共用输入栏的表面从主题派生(2026-09-24):整条栏与内嵌贴纸面板同为 `V3Palette.cardFill`,顶部一条 `cardHairline`,不再用固定的 `v3_menu_bg` 深靛蓝;输入框比栏高一档,是主题色(夜 14% / 日 7%)合成在同一表面上的浅底,正文 `v3_text_1`、提示 `v3_text_2`、光标 `textAccent`。输入框禁用时(公屏关闭、帖子回复发送中)正文退到 `v3_text_2`,提示文字保持 `v3_text_2` 以便读到原因。表情按钮 48dp 热区、`textAccent` 着色;发送按钮 48dp 热区、四边 4dp inset 画出 40dp 正圆;发送按钮可用时是主题实色 + `onPrimary` 图标(亮黄等浅主题自动换深色图标),不可用时是同色相的 `alpha15` 浅底 + 45% `textAccent` 图标,不用半透明主色糊在栏上。 聊天长按消息的操作菜单坐在 `WitBottomSheet` 上(2026-09-24):顶部是与输入栏引用条同款的消息引用块(3dp 主题色强调条 + 主题浅底 16dp 容器,别人的消息带 `textAccent` 发送者名,正文 15sp 最多三行)→「复制 / 回复 / 转发」一组连通分段行(外角 20、内角 5、行隙 2,`cardFill` + hairline,行高至少 60dp)→ 隔开 12dp 的独立「删除」行。每行是 40dp 的 17/17/17/7 图标容器 + 16sp Medium 标签;常用操作只在图标容器上用主题色,删除的图标、容器与文字统一用日夜 `v3_danger`,不随主色变化,二次确认的「删除」同样是 destructive。颜色全部按聊天主题色运行时派生,不再让 Material 默认 sheet 底与 DayNight 文字色各跟各的(夜间曾出现白底白字)。