小优化,产品愿景,视觉规范,交互和导航大版本
This commit is contained in:
417
docs/art-agent/UX-STYLE-GUIDE.md
Normal file
417
docs/art-agent/UX-STYLE-GUIDE.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# EPEEKit 交互体验指南
|
||||
|
||||
> 设计语言:**青绿山水 · 科技幽谷**
|
||||
> 核心意境:深山幽谷中的科技圣地 — 自然的宁静与数字的精密共存
|
||||
> 更新日期:2026-04-16
|
||||
|
||||
## 实现状态说明
|
||||
|
||||
每个特性标注实现状态:
|
||||
- ✅ **已实现** — 代码完整落地,与文档描述一致
|
||||
- 🔶 **基本实现** — 核心功能已落地,细节有微小偏差(不影响体验)
|
||||
- ⬜ **未实现** — 仅有文档描述,无对应代码
|
||||
|
||||
---
|
||||
|
||||
## 1. 设计哲学
|
||||
|
||||
每一次交互都是一次"与山水对话":
|
||||
|
||||
| 操作 | 意象 | 动效语言 | 状态 |
|
||||
|------|------|----------|------|
|
||||
| 发送消息 | 投石入水 | 按钮弹缩 → 气泡飞入 → 涟漪扩散 | ✅ |
|
||||
| AI 回复 | 云雾凝聚 | 模糊→清晰 → 文字逐行显现 | ✅ |
|
||||
| 收藏图片 | 萤火点亮 | 星标亮起 → 金色粒子飘散 | ✅ |
|
||||
| 滚动浏览 | 穿行雾中 | 内容在雾气边缘隐现 | ✅ |
|
||||
| 等待加载 | 溪水潺潺 | 石青流光 + 水波纹脉冲 | ✅ |
|
||||
| 图片揭示 | 水墨晕染 | clip-path 圆形从中心扩展 | ✅ |
|
||||
| 会话切换 | 翻山越岭 | 内容滑出/滑入 | ✅ |
|
||||
|
||||
科技感不通过赛博朋克的锐利线条传递,而是通过"精密点阵 × 自然粒子"的融合 —
|
||||
就像在深山中发现了一座用水晶和苔藓构建的数据中心。
|
||||
|
||||
---
|
||||
|
||||
## 2. 色彩体系 ✅
|
||||
|
||||
### 主色调
|
||||
|
||||
| 语义 | 变量名 | 色值 | 色彩隐喻 | 状态 |
|
||||
|------|--------|------|---------|------|
|
||||
| 背景主色 | `--bg-primary` | `#0C1210` | 深山暗处 | ✅ |
|
||||
| 背景次级 | `--bg-secondary` | `#131E1A` | 苔藓暗绿 / 山石基底 | ✅ |
|
||||
| 背景三级 | `--bg-tertiary` | `#1C2A24` | 松烟绿 / 远山中层 | ✅ |
|
||||
| 卡片表面 | `--bg-card` | `rgba(16, 30, 24, 0.65)` | 半透明山岩 | ✅ |
|
||||
| 主高亮色 | `--accent` | `#4DB8A4` | 石青绿 — 千里江山图的石青 | ✅ |
|
||||
| 高亮 hover | `--accent-hover` | `#6CD4BE` | 石青亮态 | ✅ |
|
||||
| 辅助高亮 | `--accent-secondary` | `#3A8FB7` | 石绿蓝 — 千里江山图的石绿 | ✅ |
|
||||
| 热门/警告 | `--hot` | `#C4654A` | 赭石红 — 点景人物/宫殿暖色 | ✅ |
|
||||
| 文字主色 | `--text-primary` | `#E0E8E2` | 微泛绿的月白 | ✅ |
|
||||
| 文字次级 | `--text-secondary` | `#7A9485` | 青灰绿 | ✅ |
|
||||
| 边框色 | `--border` | `rgba(77, 184, 164, 0.12)` | 石青半透明 | ✅ |
|
||||
| 发光边框 | `--border-glow` | `rgba(77, 184, 164, 0.25)` | 石青发光态 | ✅ |
|
||||
| 雾气基础 | `--mist` | `rgba(77, 184, 164, 0.06)` | 云雾底色 | ✅ |
|
||||
| 赭金点缀 | `--gold` | `#B8935A` | 收藏星标等极少量暖色 | ✅ |
|
||||
|
||||
### 色彩来源
|
||||
|
||||
石青(`#4DB8A4`)和石绿蓝(`#3A8FB7`)取自《千里江山图》中使用的矿物质颜料色,
|
||||
经现代演绎降低饱和度,在深色 UI 中不过于刺眼。
|
||||
赭石红(`#C4654A`)来源于画中点景人物和宫殿使用的暖色颜料。
|
||||
|
||||
**实现文件**: `globals.css` `:root` 第 4-18 行
|
||||
|
||||
---
|
||||
|
||||
## 3. 信息层级体系
|
||||
|
||||
### 3.1 排版重量体系(7 级) ✅
|
||||
|
||||
| 层级 | CSS 类 | 大小 | 字重 | 字间距 | 视觉手段 | 状态 |
|
||||
|------|--------|------|------|--------|----------|------|
|
||||
| Display | `.typo-display` | 32px | 300 | -0.02em | 石青→石绿蓝渐变填色 | ✅ |
|
||||
| H1 | `.typo-h1` | 24px | 700 | -0.01em | 底部石青细线装饰 | ✅ |
|
||||
| H2 | `.typo-h2` | 18px | 600 | 0 | 左侧 3px 石青竖线标记 | ✅ |
|
||||
| Body | 默认 | 14px | 400 | 0.01em | 标准 | ✅ |
|
||||
| Body Strong | `.typo-strong` | 14px | 600 | 0 | 石青色 | ✅ |
|
||||
| Caption | `.typo-caption` | 12px | 400 | 0.02em | text-secondary | ✅ |
|
||||
| Micro | `.typo-micro` | 11px | 600 | 0.04em | 大写 + 加宽字间距 | ✅ |
|
||||
|
||||
关键区分手段:Display 使用渐变文字而非纯色,H1 与 H2 各有独立视觉标记(底线 vs 竖线),
|
||||
不仅靠字号大小区分层级。
|
||||
|
||||
**实现文件**: `globals.css` 第 33-102 行
|
||||
**使用位置**: `typo-display`(欢迎页/登录页)、`typo-h1`(ProfileModal 用户名)、`typo-h2`(Gallery 详情标题)、`typo-strong`(侧栏/Gallery 区域标题、ProfileModal 记忆标题)、`typo-caption`(时间戳/记忆条数)、`typo-micro`(标签/分组标签/New 标记)
|
||||
|
||||
### 3.2 表面层级系统(Surface Elevation) ✅
|
||||
|
||||
4 级表面,每升一级 backdrop-blur +8px、border 亮度 +0.06、box-shadow 扩展 +4px:
|
||||
|
||||
| 层级 | CSS 类 | 用途 | 隐喻 | 状态 |
|
||||
|------|--------|------|------|------|
|
||||
| Surface-0 | — | 页面背景 `#0C1210` | 深渊 | ✅ |
|
||||
| Surface-1 | `.surface-1` | 侧栏/主区域 | 山脚(bg-secondary + 微弱内发光) | ✅ |
|
||||
| Surface-2 | `.surface-2` | 卡片/消息气泡 | 山腰(glass-panel + 更强模糊 + 微上移阴影) | ✅ |
|
||||
| Surface-3 | `.surface-3` | 弹窗/下拉/tooltip | 山顶(强模糊 + 明显阴影 + 更亮边框) | ✅ |
|
||||
|
||||
**实现文件**: `globals.css` 第 106-133 行
|
||||
**使用位置**: 侧栏(surface-1)、消息气泡/回到底部按钮(surface-2)、下拉菜单/弹窗(surface-3)
|
||||
|
||||
> 注:文档定义的 `.glass-panel` 与 `.surface-2` 视觉上等价,实际组件统一使用 surface-* 系列。`glass-panel` 保留为兼容。
|
||||
|
||||
### 3.3 用户消息 vs 助手消息 ✅
|
||||
|
||||
| 维度 | 用户消息 | 助手消息 | 状态 |
|
||||
|------|----------|----------|------|
|
||||
| 对齐 | 右对齐 | 左对齐 | ✅ |
|
||||
| 背景 | 石青渐变(accent/8 → accent/15) | glass-panel(Surface-2) | ✅ |
|
||||
| 圆角 | 左上方切角(几何感) | 标准圆角 | ✅ |
|
||||
| 边框 | 无 | 左侧 2px 石青竖线(山泉流水) | ✅ |
|
||||
| 入场动画 | 投石入水(从下方飞入) | 云雾凝聚(blur 消散) | ✅ |
|
||||
|
||||
**实现文件**: `chat-messages.tsx` 第 69-74 行、`globals.css` `.user-bubble` 类
|
||||
|
||||
---
|
||||
|
||||
## 4. 科技质感
|
||||
|
||||
### 4.1 环境粒子(Ambient Particles) ✅
|
||||
|
||||
背景云雾之上叠加"深山萤火"粒子层:
|
||||
|
||||
- 数量:15-20 个小光点
|
||||
- 颜色:石青色,opacity 0.15-0.3
|
||||
- 行为:缓慢随机漂浮 + 偶尔闪烁(opacity 脉冲)
|
||||
- 实现:React 组件 + useMemo 随机化 + CSS animation
|
||||
- 空态时粒子增多至 ~28 个,营造"未探索的深山"感
|
||||
|
||||
**实现文件**: `components/ui/ambient-particles.tsx`
|
||||
**接入位置**: `page.tsx`(首页,count 根据空态切换)、`login/page.tsx`、`gallery/page.tsx`
|
||||
|
||||
### 4.2 网格底纹(Subtle Grid) ✅
|
||||
|
||||
Surface-0 背景叠加极淡的点阵网格(opacity: 0.03),
|
||||
几乎不可见但传递"精密、数字化"的潜意识感知,与云雾层形成"自然 × 科技"张力。
|
||||
|
||||
**实现文件**: `globals.css` `body::before` 第 136-145 行
|
||||
|
||||
### 4.3 数据流光(Data Stream) ✅
|
||||
|
||||
AI 思考/生成时,输入栏上方出现一条横向流光:
|
||||
|
||||
- 石青色光带从左向右流动,高度 2px
|
||||
- 思考时慢速、生成图片时加速
|
||||
- 意象:山间溪流 / 数据脉搏
|
||||
|
||||
**实现文件**: `components/ui/data-stream.tsx`、`globals.css` `.data-stream` / `-slow` / `-fast`
|
||||
**接入位置**: `chat-input.tsx` 第 202 行
|
||||
|
||||
---
|
||||
|
||||
## 5. 微交互图鉴
|
||||
|
||||
所有微交互使用 framer-motion 实现,统一动画参数定义在 `motion-presets.ts` 中。
|
||||
|
||||
### 5.1 发送消息 — "投石入水" ✅
|
||||
|
||||
1. 发送按钮 `scale(0.85)` → spring 弹回(`sendBounce`)
|
||||
2. 消息气泡从输入栏位置飞入对话区(translateY + opacity)
|
||||
3. 到达目标位置时涟漪扩散(`RippleLayer` 石青色圆环 scale + fade out)
|
||||
4. 输入栏清空后边框发光脉冲一次(水面恢复平静)
|
||||
|
||||
**实现文件**: `chat-input.tsx`(sendBounce + useRipple)、`ripple-effect.tsx`、`motion-presets.ts`
|
||||
|
||||
### 5.2 AI 回复 — "云雾凝聚" ✅
|
||||
|
||||
1. 消息气泡 `blur(8px)` → `blur(0)` 凝聚显现
|
||||
2. 文字逐行显示时 opacity 阶梯(新行更亮,旧行渐稳)
|
||||
3. 图片结果:石青色模糊占位 → blur 消散 + scale 1.02→1.0(拨开云雾)
|
||||
|
||||
**实现文件**: `motion-presets.ts` `assistantEnter`、`chat-messages.tsx` `StreamingLines` 组件
|
||||
|
||||
### 5.3 收藏图片 — "萤火点亮" ✅
|
||||
|
||||
1. 星标 outline → filled,赭金色
|
||||
2. 点击瞬间散出 5-7 个微小金色粒子(萤火被惊起)
|
||||
3. 粒子向四周飘散并淡出(stagger + random 偏移)
|
||||
|
||||
**实现文件**: `components/ui/firefly-burst.tsx`、`image-grid.tsx` `FavoriteButton`
|
||||
|
||||
### 5.4 图片加载 — "水墨晕染" ✅
|
||||
|
||||
1. 占位:石青渐变块 + 呼吸脉冲(`.stone-placeholder`)
|
||||
2. 加载完成:`clip-path: circle()` 从中心扩展到全图(水墨滴入纸面)
|
||||
|
||||
**实现文件**: `globals.css` `.stone-placeholder`、`motion-presets.ts` `inkReveal`、`image-grid.tsx` `ImageReveal`
|
||||
|
||||
### 5.5 输入框 — "水面感应" ✅
|
||||
|
||||
- 空态:底部淡石青线
|
||||
- 获焦:边框从中心向两端扩展点亮(水面波纹展开)
|
||||
- 输入时:边框亮度随文字长度微增(蓄力)
|
||||
- 可发送态:发送按钮缓慢脉冲发光(准备就绪)
|
||||
|
||||
**实现文件**: `globals.css` `.water-focus-line` / `.water-focus-active`、`chat-input.tsx` boxShadow 联动
|
||||
|
||||
### 5.6 Hover 状态 ✅
|
||||
|
||||
- 按钮:`translateY(-1px)` + shadow 加深(浮起感)
|
||||
- 卡片:border-glow + 底部向上内发光渐变
|
||||
- 侧栏会话项:左侧 2px 石青竖线 slide-in
|
||||
|
||||
**实现文件**: `globals.css` `.btn-hover-lift`(第 466-472 行)、`.neon-border`(第 195-204 行)、`.session-hover-line`(第 474-493 行)
|
||||
|
||||
### 5.7 滚动到底部 — "落叶归根" ✅
|
||||
|
||||
- 形状:水滴形(椭圆切割 border-radius)
|
||||
- 出现:spring 从下方弹入
|
||||
- 石青半透明背景 + 雾气边框
|
||||
|
||||
**实现文件**: `page.tsx` scroll-btn、`motion-presets.ts` `scrollBtnEnter`
|
||||
|
||||
### 5.8 会话切换 — "翻山越岭" ✅
|
||||
|
||||
- 当前对话向上/向下滑出
|
||||
- 新对话从对应方向滑入
|
||||
- 过渡 250ms ease-out
|
||||
- 使用 `AnimatePresence mode="wait"` + `sessionSlide` 变体
|
||||
|
||||
**实现文件**: `page.tsx` AnimatePresence 包裹聊天内容区、`motion-presets.ts` `sessionSlide`
|
||||
|
||||
---
|
||||
|
||||
## 6. 状态与反馈
|
||||
|
||||
### 6.1 Loading 体系 ✅
|
||||
|
||||
| 场景 | 表现 | 状态 |
|
||||
|------|------|------|
|
||||
| 骨架屏 | shimmer 渐变(bg-tertiary → bg-secondary),左→右扫描 | ✅ |
|
||||
| 内联加载 | 三个石青圆点"水波纹"式依次涌起(scale Y 变化) | ✅ |
|
||||
| 全屏加载 | 中心放射状云雾凝聚(涟漪环 + 核心光点 + 呼吸脉冲) | ✅ |
|
||||
| AI 生成中 | 数据流光(输入栏上方 2px 流动光带) | ✅ |
|
||||
|
||||
**实现文件**: `globals.css` `.skeleton-shimmer`、`.wave-dot`、`.mist-loader`、`.data-stream`
|
||||
**接入位置**: `image-grid.tsx`、`chat-messages.tsx`、`app-context.tsx`、`chat-input.tsx`
|
||||
|
||||
### 6.2 空态设计 ✅
|
||||
|
||||
- Display 级渐变文字欢迎语
|
||||
- "快速开始"建议卡片(stagger 入场)
|
||||
- 萤火粒子增多营造氛围
|
||||
|
||||
**实现文件**: `page.tsx` isEmptyState 分支
|
||||
|
||||
### 6.3 Error 状态 ✅
|
||||
|
||||
- 赭石红色调但保持优雅(非大红色块)
|
||||
- 微弱横向震动(translateX ±2px,2 次)
|
||||
- 自动消失时向上飘散淡出(`errorFloat` 变体 + 4s 定时清除)
|
||||
|
||||
**实现文件**: `globals.css` `.error-shake`、`motion-presets.ts` `errorFloat`、`login/page.tsx`
|
||||
|
||||
---
|
||||
|
||||
## 7. 动效语言
|
||||
|
||||
### 7.1 时序原则 ✅
|
||||
|
||||
| 类别 | 时长 | 缓动 |
|
||||
|------|------|------|
|
||||
| 即时反馈(hover/press) | 150-200ms | ease |
|
||||
| 状态过渡(展开/折叠) | 250ms | ease-in-out |
|
||||
| 云烟效果(淡入/淡出) | 400-600ms | ease |
|
||||
| 环境动效(背景漂移) | 45-60s | ease-in-out infinite |
|
||||
| Spring 物理(弹缩) | stiffness: 400, damping: 25 | spring |
|
||||
|
||||
### 7.2 编排原则 ✅
|
||||
|
||||
- **先快后慢**:触发瞬间最快,收尾最慢(模拟自然物理)
|
||||
- **层次递进**:多元素入场使用 stagger(50-80ms 间隔),从近到远
|
||||
- **克制优先**:微交互幅度小(1-3px 位移、0.95-1.05 缩放),避免分散注意力
|
||||
- **自然衰减**:所有粒子效果都应以 opacity → 0 结束,不突兀消失
|
||||
|
||||
### 7.3 统一动画参数(motion-presets.ts) ✅
|
||||
|
||||
```typescript
|
||||
// Spring 物理参数
|
||||
spring: { stiffness: 400, damping: 25 }
|
||||
springGentle: { stiffness: 200, damping: 20 }
|
||||
|
||||
// 入场动画
|
||||
fadeIn: { opacity: [0, 1], transition: { duration: 0.2 } }
|
||||
slideUp: { opacity: [0, 1], y: [8, 0], transition: { duration: 0.2 } }
|
||||
mistReveal: { filter: ["blur(8px)", "blur(0px)"], opacity: [0, 1], duration: 0.4 }
|
||||
|
||||
// 按钮反馈
|
||||
buttonTap: { scale: 0.85 }
|
||||
sendBounce: { scale: [1, 0.85, 1.05, 1], transition: { duration: 0.3 } }
|
||||
|
||||
// 涟漪/粒子
|
||||
ripple: { scale: [0, 2.5], opacity: [0.4, 0], duration: 0.6 }
|
||||
sparkle: { scale: [0, 1, 0], opacity: [0, 1, 0], duration: 0.8 }
|
||||
|
||||
// 会话切换
|
||||
sessionSlide: { enter → center → exit, y ±30, duration: 0.25 }
|
||||
|
||||
// Error 飘散
|
||||
errorFloat: { exit → opacity: 0, y: -12, duration: 0.5 }
|
||||
```
|
||||
|
||||
**实现文件**: `components/ui/motion-presets.ts`
|
||||
|
||||
---
|
||||
|
||||
## 8. 视觉效果
|
||||
|
||||
### 8.1 山雾玻璃面板 ✅
|
||||
|
||||
```css
|
||||
.glass-panel {
|
||||
background:
|
||||
linear-gradient(165deg, rgba(16, 30, 24, 0.15) 0%, transparent 50%),
|
||||
rgba(16, 30, 24, 0.55);
|
||||
backdrop-filter: blur(24px) saturate(1.1);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
```
|
||||
|
||||
**实现文件**: `globals.css` 第 185-192 行(定义)
|
||||
> 注:组件统一使用 `.surface-2`(等价视觉),`.glass-panel` 保留为兼容别名。
|
||||
|
||||
### 8.2 云烟缭绕边框 ✅
|
||||
|
||||
选中态组件的动态边框:
|
||||
- 常态:石青微弱均匀静态发光
|
||||
- hover:conic-gradient 6s 缓慢旋转(40-50% 宽弧段),模拟云烟缭绕
|
||||
- 移开:opacity 600ms 平滑淡散
|
||||
|
||||
**实现文件**: `globals.css` `.glow-border` + `@property --glow-angle` + `mistSpin`(第 206-285 行)
|
||||
**使用位置**: `top-nav.tsx` 活跃 Tab、`session-list.tsx` 当前会话
|
||||
|
||||
### 8.3 山雾背景 ✅
|
||||
|
||||
多层缓慢漂移云雾(远景层 60s / 近景层 45s),
|
||||
两层不同速率和方向模拟远山/近山视差。
|
||||
|
||||
**实现文件**: `globals.css` `.fog-layer-far` / `.fog-layer-near`(第 162-182 行)
|
||||
**挂载位置**: `ambient-particles.tsx` 组件内渲染两个雾层 div
|
||||
|
||||
### 8.4 雾气滚动边缘 ✅
|
||||
|
||||
主要滚动区域顶底渐变遮罩(36px 渐变区域),内容消失在云雾中。
|
||||
|
||||
**实现文件**: `globals.css` `.fog-scroll`(第 288-303 行)
|
||||
**使用位置**: `page.tsx` 对话滚动区、`session-list.tsx` 会话列表
|
||||
|
||||
---
|
||||
|
||||
## 9. 布局架构
|
||||
|
||||
### 整体结构 ✅
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────────┐
|
||||
│ Top Nav (56px) — Surface-1 + 毛玻璃 │
|
||||
├──────────┬────────────────────────────────────────────┤
|
||||
│ 侧边栏 │ 主内容区(对话 / 资源库) │
|
||||
│ (280px) │ (flex-1) │
|
||||
│ Surface-1 │ ┌──────────────────────────────────────┐ │
|
||||
│ 会话列表 │ │ 对话消息 / 图片网格 │ │
|
||||
│ 标签筛选 │ │ (fog-scroll 雾气边缘) │ │
|
||||
│ │ └──────────────────────────────────────┘ │
|
||||
│ │ 数据流光条(AI 活动时可见) │
|
||||
│ │ 输入区 — 水面感应 │
|
||||
└──────────┴────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**实现文件**: `page.tsx`(首页布局)
|
||||
|
||||
### 间距系统 ✅
|
||||
|
||||
- 面板间间距:0(紧贴,用边框分隔)
|
||||
- 卡片网格间距:16px
|
||||
- 内容区内边距:20px
|
||||
- 面板内边距:16px
|
||||
|
||||
### 响应式断点 ✅
|
||||
|
||||
| 断点 | 布局 |
|
||||
|------|------|
|
||||
| ≥768px (md) | 双栏:侧边栏(280px) + 主内容区(flex-1) |
|
||||
| <768px | 单栏:侧边栏为固定抽屉 + 主内容区全宽 |
|
||||
|
||||
**实现文件**: `sidebar.tsx`(md 断点切换固定/内联)、`app-context.tsx`(`window.innerWidth < 768` 初始折叠)
|
||||
|
||||
---
|
||||
|
||||
## 10. 技术实现
|
||||
|
||||
### 依赖
|
||||
|
||||
- `framer-motion`:微交互动画引擎(spring 物理、stagger、AnimatePresence)
|
||||
- `tailwindcss v4`:工具类样式
|
||||
- CSS 自定义属性:设计 token
|
||||
- CSS `@property`:可动画角度属性(云烟边框)
|
||||
|
||||
### 文件结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/ui/
|
||||
│ ├── ambient-particles.tsx — 环境萤火粒子 ✅
|
||||
│ ├── data-stream.tsx — 数据流光条 ✅
|
||||
│ ├── ripple-effect.tsx — 涟漪效果 ✅
|
||||
│ ├── firefly-burst.tsx — 萤火粒子爆发 ✅
|
||||
│ └── motion-presets.ts — 统一动画参数 ✅
|
||||
├── app/globals.css — 设计 token + 工具类 ✅
|
||||
└── ...existing components — 集成微交互
|
||||
```
|
||||
|
||||
### 性能约束
|
||||
|
||||
- 环境粒子使用 React + CSS animation,不引入 Canvas
|
||||
- 所有动画使用 transform/opacity,避免触发 layout
|
||||
- 粒子总数不超过 30 个
|
||||
- 背景动效使用 `will-change: transform` 提示 GPU 加速
|
||||
- framer-motion 使用 `layout` 动画时限制在必要组件
|
||||
Reference in New Issue
Block a user