Files
lixi d2867826d3
CI / docs-build (push) Successful in 55s
docs: M3 开工分析 8 份报告入档 + ADR-016~021 拍板决策
- iteration-3 报告 01-08(PM 拆解/后端/Flutter/RC 首个 CERTIFIED/UI/埋点/证据基线/Git)
- ADR-016 自托管 MinIO 起步预留迁云(用户确认现无云存储)、ADR-017 patbond-community
  :8084 + media 归 user + 作者信息跨 schema 只读、ADR-018 范围裁剪(话题剪出/单层评论)、
  ADR-019 幂等按域(PUT/DELETE + request_hash)、ADR-020 聚合 feed_viewed/字典 v3/
  北极星不变/队列三项升第一波、ADR-021 Git 修订(main 更正/PR 情形触发/首发布重建 main/
  防泄漏 grep 先行)
- mkdocs 挂「第三迭代」导航,build --strict 通过

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-08 16:02:53 +08:00

272 lines
25 KiB
Markdown
Raw Permalink 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.
# 05 · 第三迭代 社区 UI 设计规范
> 作者:UI Designer
> 日期:2026-09-08
> 迭代:Iteration 3「M3 社区」
> 素材来源:`AI宠物_iOS_UI设计稿.html`(品牌正典,ADR-005)、`patbond-flutter/lib/core/theme/app_theme.dart`(已落地 token)、`lib/widgets/common.dart`RemoteImage / SectionCard / TagPill DEBT-1 修复版 / EmptyState)、`lib/core/widgets/`M2 落位的 PetAvatar / RecordTypeDot / EmptyStateIllustration)、社区 demo 现状(`lib/features/home/home_page.dart`、`lib/features/post/post_detail_page.dart`、`lib/features/create/create_page.dart`)、一迭代 04/12 号与二迭代 05 号 UI 报告(规范基线)
> 性质:开工前设计规范;只定规格,不改代码
---
## 0. 正典设计语言提炼(社区相关)
### 0.1 正典「首页 · Feed」画框已给出的语言(本规范全部延续)
| 正典元素 | 描述 | 对应 Flutter 现状 |
| --- | --- | --- |
| `feed-card` | 白底卡、`border` 1px、圆角 18、图片通栏出血(卡内零 padding 贴边) | `_PostCard` 已按此实现(圆角随 Card 主题为 24) |
| `feed-user` | 头像 28 + 名字(12/w600 ink)+ 元信息「2 小时前 · 柴犬」(10 muted) | 已实现(头像 38,元信息 bodySmall |
| `feed-img` | 单图通栏,`peach` 占位底 | `RemoteImage`loading 即 surfaceTint 块)已一致 |
| `feed-caption` | 正文 11、色 `#6B5A4A`(即 `inkSoft` 的正典出处)、行高 1.5 | 已实现(bodyMedium ink;正文色比正典更深,可接受) |
| `feed-actions` | ❤ 数字(coral+ 💬 数字 / 分享(muted | ActionChip/Chip 实现,点赞红用了 `Colors.red`(脱离色板,§5.2 修订) |
| `stories` | brandGradient 2px 渐变环头像 + 「发布」首位入口 | `_StoryRow` 已实现 |
| `search-bar` | 白底 border 描边圆角 14 搜索条 | TextField 主题已覆盖 |
| `chip` / `chip.active` | 胶囊筛选;选中态 coral 实底白字(2.75:1 不达 AA,二迭代 D7 已裁决弃用,改 surfaceTint + primaryDark | ChoiceChip 主题派生 |
| 求助帖形态 | 正典第二张 feed 卡有图无操作行,元信息带「求助专区」分区标记 | 未实现分区标记 |
### 0.2 社区 demo 现状评估(哪些视觉可保留)
| Demo 现状 | 判定 |
| --- | --- |
| `_PostCard` 骨架(头部行 → 图 → 正文 2 行截断 → 操作行) | **保留**,升级为共享 `PostCard` 三形态(§3.1);修订点:点赞 `Colors.red``error`(§5.2)、操作行触控补足 44、元信息 muted → `inkSoft`DEBT-2 |
| `post_detail_page` 作者卡 + `FilledButton.tonal` 关注钮、TagPill 话题、评论气泡(36 头像 + SectionCard 14)、底部固定输入条 | **保留**,评论气泡升共享 `CommentTile`(§3.4);头图 1:1 单图改为多图适配(§2.2) |
| `create_page` 上传卡(空/上传中/已选三态)、话题 InputChip、生成完成后的发布表单(标题/正文/话题/位置/发布钮) | **表单与话题交互保留**并迁移为社区发布页骨架;AI 生成流程(风格选择、`_GenerationProgress`)属 AI 创作域,不进 M3 发布页 |
| `home_page` Feed/服务 SegmentedButton 分段、`_StoryRow`、搜索过滤 | **保留**M3 Feed 只在 Feed 段内扩展 |
### 0.3 正典未覆盖(详见 §6 待拍板清单)
图片九宫格(正典 feed 卡仅单图)、纯文字帖形态、帖子详情页与评论区、社区发布页(正典「AI 创作」是生成器不是发帖器)、上传进度、草稿、话题聚合页、个人主页/关注关系、骨架屏。以上均为本规范新增提案。
---
## 1. 页面族总览
```text
首页 TabFeed 段)
└─ P1 Feed 流(story 环 + 帖子卡列表 + 骨架屏/空态)
├─ P2 帖子详情(媒体区 + 作者卡 + 正文 + 话题 + 操作行 + 评论区 + 底部输入条)
├─ P3 发布页(push 全屏;媒体选择九宫格 + 正文 + 话题 + 上传进度 + 草稿)
├─ P4 话题页(话题头 + 该话题 Feed 复用 P1 卡)
└─ P5 个人主页(用户头 + 关注/粉丝 + TA 的帖子;PM 若裁剪关注域则按 §6 D5 降级)
```
通用排版 token(延续一、二迭代规范,不新造):
- 页面内边距 `EdgeInsets.fromLTRB(16, 12, 16, 28)`(与现有 Tab 页一致);间距刻度 4 / 8 / 12 / 16 / 24 / 32
- 圆角:卡片 `AppRadius.xl`(24Card 主题默认)、输入框 `lg`(18)、九宫格单格 `sm`(12)、chip `pill`
- 字级:分区标题 `titleLarge` 18/w800;卡内标题 `titleMedium` 15/w700;正文 `bodyMedium` 14/1.5;次级 12 **`inkSoft`**(不用 `muted`,§5.3 DEBT-2
- Bottom sheet 沿用既有骨架(handle + 标题行 + 内容 + 全宽提交,`viewInsets.bottom` 适配)
- 错误三层模型沿用:字段 `errorText` / 区块 `InlineErrorBanner` + 重试 / 瞬态 SnackBar
---
## 2. 页面规范
### 2.1 P1 Feed 流
结构自上而下:天气条 + 问候卡 + 搜索条 + 分段钮(既有,不动)→ `_StoryRow`(既有)→ 帖子卡列表(`PostCard`,卡间距 16)。下拉刷新既有 `RefreshIndicator`;触底加载更多:列表尾 24 高居中 `CircularProgressIndicator``primary`),到底后显示「没有更多了」12 `inkSoft` 居中,上下留白 16。
**帖子卡三形态**(同一 `PostCard` 组件,按媒体数分支):
| 形态 | 媒体区 | 其余结构 |
| --- | --- | --- |
| 单图 | 通栏出血 `AspectRatio 4:3`(既有),竖长图裁切 `BoxFit.cover` | 头部行(PetAvatar sm32 + 名字 14/w700 + 元信息 12 inkSoft「2 小时前 · #柴犬圈」)→ 媒体 → 正文 bodyMedium ≤2 行截断 → 操作行 |
| 多图 | `PostMediaGrid`(§3.2)嵌在水平 padding 14 内(不出血,与九宫格圆角配合) | 同上 |
| 纯文字 | 无媒体区;正文放宽至 ≤6 行截断,字号升 15/1.6(补偿视觉重量);超行尾随「全文」`primaryStrong` 14/w600 | 同上 |
**操作行**(替换 demo 的 ActionChip/Chip 混排):`LikeButton`(§3.5+ 评论钮(`chat_bubble_outline` 20 `inkSoft` + 计数 13/w600 `inkSoft`)+ 收藏钮(同规格,bookmark 图标)+ 右端分享 `ios_share_outlined` 20 `inkSoft`。每钮触控 44×44(图标 20 + padding 撑足),间距 4,行高 48,水平 padding 14。
**状态**:首载 = `FeedSkeleton`(§3.73 张;空态 = `EmptyStateIllustration``forum_outlined`、「还没有动态」、说明「关注的毛孩子们还没发帖,去逛逛话题吧」、CTA「发布第一条」→ P3);搜索空态沿用既有 `EmptyState`;加载失败 = `InlineErrorBanner` + 重试。
### 2.2 P2 帖子详情 【评论区为新增提案,待拍板】
demo 骨架保留,修订媒体区与评论区:
| 区块 | 规格 |
| --- | --- |
| AppBar | 既有(标题「社区动态」16/w800 + 分享 action |
| 媒体区 | 单图:原比例展示,高度钳制 [宽×0.75, 宽×1.33];多图:`PageView` 横滑轮播 1:1 + 底部中央页码指示(当前点 `primaryStrong` 6×6、其余 `border` 5×5,间距 6;同时右上角「2/9」角标:`ink` 实底胶囊 + 白字 12/w700,13.50:1);点击全屏大图浏览(黑底、双击缩放、下滑关闭) |
| 作者卡 | 既有 SectionCard + `FilledButton.tonal` 关注钮保留;关注双态:未关注 = tonalsurfaceTint 底 + primaryDark 字 7.98:1)文案「+ 关注」;已关注 = `OutlinedButton`border 描边 + `inkSoft` 字 6.59:1)文案「已关注」,点按弹确认「不再关注 TA?」 |
| 正文 | bodyMedium 14/1.6 全文;话题 `TopicChip`(§3.6Wrap 8/8;「发布于 …」12 `inkSoft` |
| 操作行 | 与 P1 同一套组件(LikeButton + 评论锚点钮 + 收藏),demo 的 FilledButton.tonalIcon 形态弃用,统一卡片外裸排 |
| 评论区 | 「评论 (N)」`titleLarge``CommentTile` 列表(§3.4,间距 12);空态:居中 `chat_bubble_outline` 36 `muted`(纯装饰,muted 合法)+「还没有评论,来抢沙发」12 `inkSoft`,上下留白 32;分页触底加载同 P1 |
| 底部输入条 | demo 形态保留:`surface` 底 + 顶部 `border` 1px 分隔线(demo 缺分隔线,补上)+ TextFieldisDense+ `IconButton.filled` 发送(`primaryStrong` 底白图标 4.49:1;空文本时禁用态:`ink` 12% 底 + 38% 图标,主题既定禁用惯例);发送中按钮内 18 转圈锁尺寸 |
### 2.3 P3 发布页 【设计稿未覆盖,本规范为新增提案,待拍板】
push 全屏页(媒体多、需防误触丢稿,不用 sheet)。AppBar:左「取消」TextButton`ink`)、标题「发布动态」、右「发布」`FilledButton`(高 40,水平 padding 20;不可发布时禁用态)。
```text
┌ 媒体选择区 ──────────────────────┐
│ [图1][图2][] │ PostMediaGrid 编辑态(§3.2):已选图 1:1
│ │ 预览 + 右上删除角标;「+」虚线格;最多 9 张
└──────────────────────────────────┘
↓ 16
正文 TextFieldmultiline 6 行高起步自增,maxLength 1000
计数器「128/1000」12 inkSoft 右下(超限 error
↓ 12
话题行:已选 TopicChip(带删除角标)+ 「+ 话题」ActionChip → 话题选择 sheet
(搜索 + 热门话题列表;demo 的 AlertDialog 输入弃用)
↓ 12
位置 ListTiledemo 保留,选填)
↓ 底部安全区上方
「已自动保存草稿 ✓」12 inkSoft(保存动作后淡入,3s 淡出)
```
- **可发布条件**:正文非空或媒体 ≥1。
- **上传进度态**:点「发布」后媒体逐张上传,每格叠加进度覆盖层(§3.3);全部完成前「发布」钮转圈锁定;单张失败 → 该格 error 角标 + 整页顶部 `InlineErrorBanner`「第 3 张图片上传失败」+ 格内点按重试;全败/接口失败不清空内容。
- **草稿**:内容变更后静默自动保存(防抖 2s);点「取消」且有内容 → `AlertDialog`「保留草稿?」【保留 / 不保留 / 继续编辑】;再次进入发布页时若有草稿则恢复并显示顶部提示条(surfaceTint 底圆角 sm12:「已恢复上次草稿」12 `primaryDark` + 右侧「清空」TextButton)。草稿仅本机单份,覆盖式保存。
### 2.4 P4 话题页 【设计稿未覆盖,本规范为新增提案,待拍板】
push 页。话题头(canvas 底直排,非卡片):`#柴犬圈` `headlineSmall 22 ink` + 「1234 条动态 · 56 人参与」12 `inkSoft` + 右侧「关注话题」钮(与 P2 关注双态同规格)→ 24 → 该话题 Feed(P1 的 `PostCard` 列表原样复用,含骨架/空态/加载更多)。空态文案「这个话题还没有动态,来发第一条」+ CTA → P3(预填该话题)。
### 2.5 P5 个人主页 / 关注关系 【设计稿未覆盖,新增提案;PM 若裁剪关注域,本页降级见 §6 D5】
push 页。用户头部(正典「我的」`profile-head` 语言横排):头像 64`PetAvatar` 组件复用,无徽标)+ 昵称 `titleLarge` + ID/加入天数 12 `inkSoft`;其下统计行三等分(正典 `stat-row` 语言):动态数 / 关注数 / 粉丝数——数值 15/w800 `ink`、标签 12 `inkSoft`,关注/粉丝可点进列表页;右侧或其下「关注」钮(P2 同款双态)。之后「TA 的动态」`titleLarge` + `PostCard` 列表。
关注/粉丝列表页:`ListTile` 式行(头像 44 + 昵称 14/w700 + 简介 12 `inkSoft` + 尾部关注双态小钮高 36),行高 64,触控达标。
**若 PM 裁剪关注关系**:P5 保留头部(无关注钮、统计行只留「动态数」)+ 帖子列表;P2 作者卡关注钮整个不渲染(不留占位)。
---
## 3. 新组件规格(7 个)
### 3.1 `PostCard``lib/core/widgets/post_card.dart`
§2.1 三形态的唯一出口,`home_page` 私有 `_PostCard` 升级迁移。构成:Card 主题默认 + `InkWell` 整卡进 P2;头部行 padding 14;操作行组件化(LikeButton / 计数钮)。求助/分区帖在元信息尾追加 `TagPill(accent)` 小标(正典「求助专区」语义,7.07:1)。
### 3.2 `PostMediaGrid` 图片九宫格(`lib/core/widgets/post_media_grid.dart`
展示态 + 编辑态一个组件(编辑态多「+」格与删除角标)。
- **列数规则**1 图不走网格(由 PostCard/详情页按 §2 单图规格处理);2、4 图 → 2 列;3、5–9 图 → 3 列。全部 1:1 `BoxFit.cover`,格间距 4,单格圆角 `sm`(12)`RemoteImage` 复用(loading surfaceTint 块 / 失败 pets 图标兜底)。
- **"+N" 折叠角标**Feed 卡超 9 图理论不出现,接口若返回超 9 张:第 9 格叠 `ink.withAlpha(204)`(80%) scrim + 白字「+3」20/w800 居中(合成最亮白图仍 7.10:160% scrim 仅 3.88:1 不达标,弃用))。
- **编辑态**:末尾「+」格——`border` 1.5px 虚线、圆角 12、居中 `add_photo_alternate_outlined` 24 `inkSoft`;满 9 张隐藏。删除角标:格右上角 22 圆、`ink` 80% 实底 + 白 close 图标 14(非文字 7.10:1),触控热区扩至 32。长按拖拽排序(可选实现,见 §6 D9)。
- **状态**:展示格点按 → 全屏浏览(初始页为所点格);编辑格点按 → 预览/替换菜单。
### 3.3 `UploadProgressOverlay` 上传进度指示(同文件或 `upload_progress_overlay.dart`
叠加在编辑态九宫格单格上的进度层,四态:
| 态 | 视觉 |
| --- | --- |
| 排队 | scrim `ink` 40% + 白字「等待中」12/w600(合成后底 ≈#8B7F79 亮于 40% 实际值;按 80% 局部字条处理:文字衬 `ink` 80% 胶囊底,7.10:1 |
| 上传中 | scrim `ink` 40% + 居中白色环形进度 36`CircularProgressIndicator` value 态,白轨 24% + 白值条;非文字对白图标准由 scrim 保底)+ 下方百分比白字 11/w700 衬 `ink` 80% 胶囊 |
| 成功 | scrim 淡出 150ms,无残留角标 |
| 失败 | scrim `error` 12% + 中央 `error_outline` 24 `errorDark`(6.50:1 于白底)+ 底部通栏字条 `errorDark` 实底 + 白字「重试」11/w700;整格点按重试 |
页级汇总:发布钮上方细线性进度 `LinearProgressIndicator`——值条 `primaryStrong`、轨道 `surfaceTint`3.80:1 ≥ 非文字 3:1+ 左侧「正在上传 2/5」12 `inkSoft`
### 3.4 `CommentTile` 评论条目(`lib/core/widgets/comment_tile.dart`
demo 气泡形态升共享:`PetAvatar sm32`(demo 36 收敛到组件尺寸档)+ 10 + 气泡(`surface` 底、`border` 1px、圆角 16、padding 12):作者名 13/w700 `ink` → 4 → 内容 bodyMedium 14/1.5 → 6 → 底行(时间 11 `inkSoft` + 右端点赞:heart 16 + 计数 11,未赞 `inkSoft`/已赞 `error`,触控 44 靠 padding 撑足)。楼中楼回复(若 PM 纳入范围):气泡内下方缩进块 `canvas` 底圆角 12 padding 10,「@昵称:内容」13,最多显 2 条 + 「查看全部 N 条回复」12 `primaryStrong`(白卡内 4.49:1)。长按气泡 → 操作 sheet(回复/复制/举报,举报为社区合规必备项)。
### 3.5 `LikeButton` 点赞/收藏交互钮(`lib/core/widgets/like_button.dart`
点赞与收藏同一组件(图标与语义色参数化)。
- **静态规格**:图标 20 + 计数 13/w600,间距 4;未激活:`favorite_border` / `bookmark_border` + 计数均 `inkSoft`6.59:1);激活:`favorite` 实心 `error`(图标非文字 4.99:1+ 计数 `errorDark`6.50:1);收藏激活用 `accentDark`(7.40:1,图标与字同色)。**修订**:demo 的 `Colors.red``#F44336`,白底 3.13:1 且脱离色板)弃用。
- **乐观更新视觉**(配合 §4 策略):点按即刻翻转状态 + 计数 ±1;激活动画 = 图标 scale 1 → 1.25 → 1 弹性 240ms + 实心色淡入;取消动画 = 仅 120ms 颜色渐出,无缩放(降低视觉噪音)。计数变化不做滚动动画(数字直接替换,避免回滚时二次滚动)。
- **回滚态**:失败回滚时**禁用过渡动画**,状态直接跳回 + SnackBar「操作失败,请重试」;详见 §4。
### 3.6 `TopicChip` 话题 chip`lib/core/widgets/topic_chip.dart`
**与 TagPill 的关系**TagPill(DEBT-1 修复版)是静态语义标签,无点击态、字 11、padding 10/6;话题需要可点击、可删除(发布页)、更大触控,故独立组件、**视觉同族**——底色同款 8% 淡染 + 深变体字,直接复用 `TagPill._defaultInkFor` 同一映射(映射常量建议随本工单从 TagPill 提为共享导出,两组件一处取色)。
- **规格**:高 32(垂直方向由父容器留 6 补至 44 触控带),padding 12/0,圆角 `pill`,「#话题名」13/w600;默认色族 `primary`8% 底 + `primaryDark` 字 8.74:1)。点按 → P4 话题页,`InkWell` pill ripple。
- **编辑态**(发布页):尾部 16 close 图标(`primaryDark`),点删除;被预填(从话题页进入)时不可删除、色族转 `accent`
- demo 中 `InputChip`/`ActionChip` 话题混用形态弃用,统一本组件;「+ 话题」添加钮保留 ActionChip 形态。
### 3.7 `FeedSkeleton` 骨架屏(`lib/core/widgets/feed_skeleton.dart`
- **单元结构**(模拟单图卡):Card 默认底内——头部行(32 圆 + 两条圆角横条 12/8 高、宽 40%/24%)→ 4:3 通栏块 → 两条正文横条(宽 90%/60%)。块色 `surfaceTint`,底为白卡(1.18:1,装饰性占位不受对比度约束)。
- **动效**:整体不透明度 0.6 ↔ 1.0 呼吸循环 1200ms(不做横扫高光,实现轻);尊重系统「减弱动态效果」设置时静止在 1.0。
- **用途**P1/P4 首载 3 张;P2 评论区首载 2 个(气泡形骨架:32 圆 + 圆角 16 矩形块高 72)。
---
## 4. 乐观更新视觉反馈与回滚闪烁抑制(点赞/收藏/关注通用)
1. **即时反馈**:点按瞬间本地翻转状态并播放激活/取消动画(§3.5),不等接口。
2. **连点合并(闪烁抑制第一层)**:交互层防抖 600ms——连续点按只做本地翻转动画,仅将「最终状态」发给接口;in-flight 期间再次点按不发新请求,记录期望终态,返回后对账。
3. **回滚静默化(第二层)**:接口失败回滚时,a) 若激活动画未播完,等播完再回滚(避免动画中途反转的抖动);b) 回滚本身零动画、直接跳变;c) 计数与状态一次性成对恢复,不出现「心已灭计数未减」的中间帧;d) 同帧只弹一条 SnackBar(多目标失败合并文案)。
4. **对账不打扰(第三层)**:接口成功返回的权威计数若与本地乐观值不同(他人同时点赞),静默替换数字,不播任何动画。
5. 关注钮乐观更新同策略;回滚时按钮从「已关注」直接跳回「+ 关注」+ SnackBar。
---
## 5. 色彩无障碍自查(WCAG AA,程序精算)
计算方法:WCAG 2.x 相对亮度公式;8% 淡底按 `withAlpha(20)`7.84%)与白底合成;scrim 合成按最不利底(纯白图)计算。正文阈值 4.5:1,大字 3:1,非文字 3:1。
### 5.1 本规范用到的全部新增/关键组合
| 组合(用途) | 对比度 | 判定 |
| --- | --- | --- |
| `ink` / `surface`(正文、页码角标白字于 ink 实底 13.50 同值) | 13.50 | 达标 |
| `inkSoft` / `surface``canvas``surfaceTint`(全部次级信息文字) | 6.59 / 6.21 / 5.58 | 达标 |
| 白字 / `ink` 80% scrim 合成白图(+N 角标、删除角标、上传百分比胶囊) | 7.10 | 达标 |
| 白字 / `ink` 60% scrim 合成白图 | 3.88 | **不达标,弃用**(§3.2 一律 80% |
| 白字 / `primaryStrong`(发送钮、发布钮) | 4.49 | 达标(一迭代已裁决按 ≈4.5 采纳) |
| `primaryStrong` / `surface`(白卡内「全文」「查看全部回复」链接字) | 4.49 | 达标 |
| `primaryStrong` / `canvas`(canvas 直排底上的链接字) | 4.23 | **贴线不过**——canvas 底文字链接一律改 `primaryDark`8.88:1);`primaryStrong` 文字仅限白卡内(§5.2 新规则) |
| `primaryStrong` 值条 / `surfaceTint` 轨道(上传线性进度,非文字) | 3.80 | 达标(≥3) |
| `primaryDark` / primary 8% 底、`surfaceTint`TopicChip 字、草稿恢复条、tonal 关注钮) | 8.74 / 7.98 | 达标 |
| `accentDark` / accent 8% 底、`surface`(分区小标、收藏激活态) | 7.07 / 7.40 | 达标 |
| `error` / `surface`(点赞激活图标,非文字) | 4.99 | 达标 |
| `errorDark` / `surface`、error 淡底(点赞计数、上传失败字) | 6.50 / 5.78 | 达标 |
| `Colors.red #F44336` / `surface`demo 点赞现状) | 3.13 | 图标勉强 3:1 但脱离色板且伴随计数字不达标,**修订为 error 族**(§3.5 |
| 页码指示点 `primaryStrong` / 白图最不利底(非文字) | 4.49 | 达标(另有 ink 胶囊「2/9」双通道兜底) |
| 骨架块 `surfaceTint` / `surface` | 1.18 | 装饰性占位,不受约束 |
### 5.2 修订与新规则(本规范裁决点)
| 事项 | 处置 |
| --- | --- |
| 点赞 `Colors.red` | 全部替换为 `error`(激活图标)+ `errorDark`(伴随计数),收编进色板 |
| `primaryStrong` 于 canvas 4.23:1 | 新规则:**`primaryStrong` 作文字色仅限 `surface` 白卡内**canvas/surfaceTint 底文字链接与强调字用 `primaryDark`。二迭代已有页面按此规则在 M3 回归中顺手核(影响面小,见 §7) |
| scrim 浓度 | 图片上承字 scrim 统一 `ink` 80%withAlpha 204),禁用更浅档承载文字 |
### 5.3 DEBT-2muted 色)触发场景与规避
M3 是**次级信息文字密度最高**的一族页面(时间戳、计数、元信息、上传状态、字数计数器满屏皆是),是 DEBT-2 的重灾区。demo 三页现全部用 `bodySmall`(默认 `muted` 3.36:1)承载这些信息,**照抄即触发**。规避方案沿二迭代 05 号 §5.4 既定路线:
- 本页面族**所有承载信息**的次级文字(帖子时间、评论时间、计数、「没有更多了」、上传状态、草稿提示、话题统计、字数计数器)一律显式 `inkSoft`(三底 5.58–6.59 全达标);操作行未激活图标同用 `inkSoft`
- `muted` 仅限:输入占位符(评论框、正文框 hint)、禁用态、纯装饰图标(评论空态大图标)。
- 全局 `bodySmall` 默认色是否切 `inkSoft` 的议题仍挂账(二迭代 D9 遗留),M3 不做全局翻修;但 M3 新页面从落笔起就不产生新债。
---
## 6. 与正典出入 / 待拍板清单
| # | 事项 | 性质 |
| --- | --- | --- |
| D1 | 图片九宫格 + 纯文字帖形态(正典 feed 卡仅单图有图形态);列数规则 2/4→2 列、其余→3 列 | 设计稿未覆盖,新增提案 |
| D2 | 帖子详情评论区整套(CommentTile、楼中楼、长按操作 sheet 含举报);楼中楼是否入 M3 范围随 PM 拍板 | 设计稿未覆盖,新增提案 |
| D3 | 发布页整页(正典只有 AI 创作生成器):push 全屏而非 sheet、上传进度四态、草稿自动保存/恢复交互 | 设计稿未覆盖,新增提案 |
| D4 | 话题页整页 + TopicChip 独立组件(与 TagPill 同色系分工:TagPill 静态标签 / TopicChip 可交互) | 设计稿未覆盖,新增提案 |
| D5 | 个人主页 + 关注关系(关注双态钮、关注/粉丝列表);PM 裁剪时的降级形态已备(§2.5 末段) | 设计稿未覆盖,新增提案 |
| D6 | 点赞激活色 `Colors.red``error`/`errorDark`;收藏激活 → `accentDark` | 现状修订(脱离色板 + 3.13:1) |
| D7 | 新规则:`primaryStrong` 文字仅限白卡内,canvas/tint 底改 `primaryDark`(4.23:1 实测贴线不过) | 无障碍修订 |
| D8 | 乐观更新三层闪烁抑制策略(600ms 防抖合并 / 回滚零动画 / 对账静默),需客户端与埋点侧确认「合并后只报最终态」的事件口径 | 交互提案,跨角色确认 |
| D9 | 九宫格编辑态长按拖拽排序:建议 M3 可选(不阻塞),砍掉不影响主流程 | 范围裁剪建议 |
| D10 | 骨架屏引入(正典无 loading 语言;呼吸动效尊重减弱动态设置) | 设计稿未覆盖,新增提案 |
| D11 | 详情页多图采用「轮播 + 页码」而非九宫格平铺(沉浸浏览优先);Feed 卡多图才用九宫格 | 形态裁决,待确认 |
---
## 7. 交付验收对照(供开发/QA)
- [ ] 7 个新组件(PostCard / PostMediaGrid / UploadProgressOverlay / CommentTile / LikeButton / TopicChip / FeedSkeleton)落位 `lib/core/widgets/`;话题/标签深变体色映射全 app 仅存一份(TagPill 现映射提为共享)。
- [ ] P1P5 均具备 loading(骨架或转圈)/ empty / error / retry 态;错误三层模型与前两迭代一致。
- [ ] 本规范全部文字组合按 §5.1 达 AA;图片上承字仅用 `ink` 80% scrim`Colors.red` 在社区页面族零残留;canvas 底无 `primaryStrong` 文字。
- [ ] 次级信息文字全部 `inkSoft``muted` 仅出现在占位/禁用/纯装饰(DEBT-2 不新增欠账)。
- [ ] 点赞/收藏/关注乐观更新按 §4:连点只发终态、回滚零动画、失败必有 SnackBar;无「计数与状态不成对」的中间帧。
- [ ] 发布页:上传单张失败可单独重试且不清空内容;取消必经草稿确认;触控目标全数 ≥44×44。
- [ ] 骨架与激活动画在系统「减弱动态效果」开启时降级为静态/瞬变。
---
**UI Designer** · 2026-09-08