- 从 HMS 基座复制 apps/web/ (React + Ant Design + Vite + TypeScript) - 管理端自动代理 API 到 localhost:3000 (vite.config.ts) - 更新 scripts/dev.sh 支持三端启动: backend/admin/app - 登录验证通过, 用户管理/角色权限/审计日志等页面正常 - 添加 .gitignore 排除 node_modules/dist
58 KiB
暖记 (Warm Notes) — 完整设计规格文档
由 od-llm-design-spec v3.0 从 Open Design 原型稿导出 导出日期:2026-06-02 覆盖:14 个移动端页面 + 6 个平板变体 + 6 个桌面变体
目录
- 设计 Token 系统
- 共享组件库
- 页面设计规格 — 移动端 (390×844)
- 页面设计规格 — 平板端 (1024×768)
- 页面设计规格 — 桌面端 (1440×900)
- 交互行为规范
- 常见实现偏差清单
- CSS :root 参考实现
1. 设计 Token 系统
颜色系统 — 主题1:暖阳 (Warm Sun) [默认]
| Token | 值 | 用途 |
|---|---|---|
--bg |
#FFF8F0 |
页面背景 — 暖白奶油色,绝不是纯白 #FFF |
--surface |
#FFFFFF |
卡片/面板/弹窗背景 |
--surface-warm |
#FFF3E6 |
暖色表面 — 选中态、hover态、装饰背景 |
--fg |
#2D2420 |
主文字 — 暖棕黑 |
--fg-2 |
#5C4F47 |
次要文字 |
--muted |
#7A6D63 |
辅助/说明文字 |
--meta |
#8B7E74 |
元数据/极淡文字 |
--border |
#E8DDD4 |
标准边框 |
--border-soft |
#F0E8DF |
柔和边框 |
--accent |
#E07A5F |
主强调色 — 赤陶珊瑚色 |
--accent-on |
#FFF8F0 |
accent 上文字色 |
--accent-hover |
#D06A4F |
accent hover 态 |
--accent-active |
#C05A3F |
accent active/pressed 态 |
--accent-glow |
rgba(224,122,95,0.25) |
accent 发光阴影色 |
--secondary |
#81B29A |
辅助色 — 鼠尾草绿 |
--secondary-soft |
#D4E8DC |
绿色淡背景 |
--tertiary |
#F2CC8F |
装饰色 — 暖金色 |
--tertiary-soft |
#FBE8C8 |
金色淡背景 |
--rose |
#D4A5A5 |
玫瑰粉 |
--rose-soft |
#F0DADA |
玫瑰淡背景 |
--success |
#5A9E7E |
成功态 |
--warn |
#D4A843 |
警告态 |
--danger |
#C93D3D |
危险/错误态 |
颜色系统 — 主题2:松风 (Pine Wind)
激活方式:<html data-theme="pine"> 或 <body data-theme="pine">
| Token | 值 | 变化说明 |
|---|---|---|
--bg |
#F2F3F0 |
冷灰白 |
--surface |
#FFFFFF |
不变 |
--surface-warm |
#E9EAE6 |
冷灰暖面 |
--fg |
#23272F |
冷灰黑 |
--accent |
#4A7B9D |
钢蓝色 |
--secondary |
#5B9E7A |
森林绿 |
--tertiary |
#C49A3C |
琥珀金 |
暗色模式
通过 @media (prefers-color-scheme: dark) 自动激活,两套主题各有独立暗色 token。暖阳暗色 --bg: #1A1614,松风暗色 --bg: #14161C。
字体排版
| Token | 值 | 用途 |
|---|---|---|
--font-display |
"Quicksand", "Nunito", "SF Pro Rounded", sans-serif |
标题/展示字体 |
--font-body |
"Nunito", -apple-system, "Segoe UI", system-ui, sans-serif |
正文 |
--font-mono |
ui-monospace, "JetBrains Mono", monospace |
代码/等宽 |
--font-handwritten |
"Caveat", "Kalam", cursive |
手写体装饰 |
字号阶梯:
--text-xs: 11px — 标签/极小文字--text-sm: 13px — 辅助说明--text-base: 15px — 正文(默认)--text-md: 17px — 小标题--text-lg: 20px — 区块标题--text-xl: 24px — 页面标题--text-2xl: 30px — 大标题--text-3xl: 38px — 展示标题--text-4xl: 48px — 超大标题
行高: --leading-body: 1.6(正文)、--leading-tight: 1.25(标题)
间距系统
4px 基准:4, 8, 12, 16, 20, 24, 32, 40, 48 px
圆角
| Token | 值 | 适用 |
|---|---|---|
--radius-sm |
10px | 小元素、输入框 |
--radius-md |
16px | 卡片 |
--radius-lg |
22px | 大面板 |
--radius-xl |
28px | 底部弹窗 |
--radius-pill |
9999px | 按钮、标签 |
阴影
| Token | 值 | 适用 |
|---|---|---|
--elev-soft |
0 2px 12px rgba(45,36,32,0.06) |
卡片默认 |
--elev-medium |
0 4px 20px rgba(45,36,32,0.08) |
悬浮元素 |
--elev-float |
0 8px 32px rgba(45,36,32,0.12) |
弹窗/模态 |
--shadow-accent |
0 4px 14px rgba(224,122,95,0.25) |
accent 按钮阴影 |
动画
| Token | 值 |
|---|---|
--motion-fast |
150ms |
--motion-base |
250ms |
--ease-bounce |
cubic-bezier(0.34, 1.56, 0.64, 1) |
--ease-standard |
cubic-bezier(0.2, 0, 0, 1) |
布局常量
| Token | 值 | 说明 |
|---|---|---|
--container-max |
390px | 移动端容器宽度 |
--safe-top |
54px | 顶部安全区(Dynamic Island) |
--safe-bottom |
34px | 底部安全区(Home Indicator) |
--tab-height |
56px | 底部 Tab 栏高度 |
--touch-min |
44px | 最小触控目标(WCAG) |
2. 共享组件库
2.1 Dynamic Island
- 位置:
position: absolute; top: 12px; left: 50%; transform: translateX(-50%); - 尺寸:
width: 126px; height: 36px - 样式:
background: #000; border-radius: 20px; z-index: 200 - 注意: 所有页面共享,
z-index: 200确保在最顶层
2.2 底部 Tab 栏
- 位置:
position: absolute; bottom: 0; left: 0; right: 0; - 高度:
calc(var(--tab-height) + var(--safe-bottom))= 56 + 34 = 90px - 结构:
display: flex; justify-content: space-around; - 背景:
var(--surface)+border-top: 1px solid var(--border-soft) - z-index: 100
Tab 项(5个):
| Tab | 图标 | 文字 | 特殊样式 |
|---|---|---|---|
| 首页 | 房屋 | "首页" | — |
| 日历 | 日历 | "日历" | — |
| 写日记 | 加号 | "写日记" | 中央凸起按钮:width:44px; height:44px; border-radius:50%; background:var(--accent); margin-top:-16px; box-shadow:var(--shadow-accent) |
| 发现 | 放大镜 | "发现" | — |
| 我的 | 人像 | "我的" | — |
活跃态: color: var(--accent);非活跃:color: var(--muted)
Tab 图标尺寸: svg { width: 24px; height: 24px }
Tab 文字: font-size: var(--text-xs) = 11px; font-weight: 500
2.3 内容区(Content Area)
- 位置:
position: absolute; top: 0; left: 0; right: 0; bottom: calc(var(--tab-height) + var(--safe-bottom)) - 滚动:
overflow-y: auto; scrollbar-width: none - 内边距:
padding: 0 var(--space-5); padding-top: calc(var(--safe-top) + var(--space-2))
2.4 顶部导航栏
- 结构:
display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5) - 标题:
font-family: var(--font-display); font-size: var(--text-xl); font-weight: 700 - 操作按钮:
width: var(--touch-min)=44px; height: 44px; border-radius: var(--radius-pill)
2.5 卡片(Card)
- 背景:
var(--surface) - 圆角:
var(--radius-md) = 16px - 内边距:
var(--space-5) = 20px - 阴影:
var(--elev-soft) - 边框:
1px solid var(--border-soft)
2.6 按钮
| 类型 | 背景 | 文字色 | 圆角 | 特殊 |
|---|---|---|---|---|
| Primary | var(--accent) |
var(--accent-on) |
var(--radius-pill) |
hover: var(--accent-hover) + translateY(-1px) |
| Secondary | var(--surface) |
var(--fg) |
var(--radius-pill) |
border: 1.5px solid var(--border) |
| Ghost | transparent | var(--muted) |
— | hover: color: var(--accent) |
通用按钮: padding: 14px 28px; font-family: var(--font-display); font-size: var(--text-md)=17px; font-weight: 600
Active 态: transform: scale(0.97)
2.7 芯片/标签(Chip)
- 样式:
display: inline-flex; padding: 6px 14px; border-radius: var(--radius-pill); font-size: var(--text-sm)=13px - 默认:
background: var(--surface); color: var(--fg-2); border: 1px solid var(--border) - 活跃:
background: var(--accent); color: var(--accent-on); border-color: var(--accent)
2.8 心情选择器
5 种标准心情: 开心(😊)、平静(😐)、难过(😢)、生气(😡)、思考(🤔)
首页心情栏样式:
- 容器:
background: var(--surface); border-radius: var(--radius-md); padding: var(--space-4) var(--space-5); box-shadow: var(--elev-soft) - 选项:
display: flex; flex-direction: column; align-items: center; gap: 4px; padding: var(--space-2); min-width: 44px; min-height: 44px - Emoji 字号:
28px - 标签字号:
11px; color: var(--muted) - 选中态:
background: var(--surface-warm); .label { color: var(--accent); font-weight: 600 }
2.9 Home Indicator
- 样式:
width: 134px; height: 5px; background: var(--fg); opacity: 0.2; border-radius: 3px - 位置:
position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); z-index: 101
2.10 动画类
| 类名 | 动画 | 参数 |
|---|---|---|
.anim-fade |
fadeIn | 0.5s var(--ease-standard) — 从 translateY(12px) 到 translateY(0) |
.anim-slide |
slideUp | 0.6s var(--ease-bounce) — 从 translateY(40px) 到 translateY(0) |
.anim-scale |
scaleIn | 0.4s var(--ease-bounce) — 从 scale(0.9) 到 scale(1) |
3. 页面设计规格
页面 01:启动页 (Splash)
文件: screens/splash.html
尺寸: 390 × 844px(iPhone 15 Pro,固定视口,不可滚动)
背景: linear-gradient(165deg, var(--bg) 0%, var(--tertiary-soft) 40%, color-mix(in oklab, var(--accent), transparent 50%) 100%)
视觉层级
- 第一眼: 中央 App 图标 + 名称
- 第二眼: 手写标语 + 底部按钮
完整布局树
body (390×844, overflow:hidden)
├── .deco.deco-star × 3 // 装饰星星,SVG,absolute定位
│ ├── 尺寸: 28×28px, opacity: 0.25
│ └── 动画: float 4s ease-in-out infinite
├── .deco.deco-circle × 2 // 装饰圆点
│ ├── 尺寸: 80×80 / 50×50px, opacity: 0.12
│ └── 动画: float 5s reverse
├── .splash-content // 中央内容,absolute 居中
│ ├── transform: translate(-50%,-50%), top:50%, left:50%
│ ├── 动画: scaleIn 0.8s ease-bounce
│ ├── .app-icon // App 图标
│ │ ├── 尺寸: 120×120px
│ │ ├── 圆角: 32px
│ │ ├── 背景: linear-gradient(135deg, var(--accent) → var(--tertiary))
│ │ ├── 阴影: 0 8px 32px var(--shadow-accent)
│ │ ├── ::after 高光: 右上角白色半透明圆形
│ │ └── SVG: 56×56px 笔记本+勾选图标
│ ├── .app-name "暖记"
│ │ └── font: 42px/700 Quicksand, letter-spacing: 2px
│ └── .app-tagline "用温暖的方式,记录每一天"
│ └── font: var(--text-md)=17px Nunito, color: var(--muted)
├── .splash-bottom // 底部区域
│ ├── bottom: calc(var(--safe-bottom) + 40px)
│ ├── .splash-handwritten-tagline "每一页,都是你的故事"
│ │ └── font: Caveat 22px, color: var(--accent)
│ ├── .enter-btn "开始记录"
│ │ ├── padding: 16px 48px, min-height: 44px
│ │ ├── background: var(--accent), color: var(--accent-on)
│ │ ├── 圆角: var(--radius-pill)
│ │ ├── 阴影: 0 4px 20px var(--shadow-accent)
│ │ ├── 内含 SVG 箭头图标 (20×20)
│ │ └── hover: translateY(-2px); active: scale(0.97)
│ └── .hint "每一天都值得被温柔记录"
│ └── font-size: var(--text-sm)=13px, color: var(--meta)
└── .home-indicator // 底部横条
└── width:134px, height:5px, opacity:0.2
交互行为
- "开始记录" 按钮: 点击跳转至首页或登录页
- 装饰元素动画: 持续浮动,不影响交互
- 页面不可滚动
页面 02:引导页 (Onboarding)
文件: screens/onboarding.html
尺寸: 390 × 844px
背景: var(--bg)
视觉层级
- 第一眼: 中央插图(圆形 260×260)
- 第二眼: 标题文字 + 描述
- 第三眼: 底部圆点指示器 + 按钮
完整布局树
body (390×844, overflow:hidden)
├── .skip-btn // "跳过" 按钮
│ ├── position: absolute, top: calc(54+8)px, right: 20px
│ ├── font-size: var(--text-base)=15px, color: var(--muted)
│ └── min-height: 44px
├── .slides-wrapper (width: 300%, display:flex)
│ ├── transform: translateX(-N×390px) // 滑动切换
│ ├── transition: 0.5s cubic-bezier(0.34,1.56,0.64,1)
│ ├── .slide.step-1 (390×844) // 第1页
│ │ ├── padding: calc(54+48)px 32px calc(34+120)px
│ │ ├── .page-num "01" (120px/800, opacity:0.04)
│ │ ├── .slide-illustration // 圆形插图
│ │ │ ├── 尺寸: 260×260px, border-radius: 50%
│ │ │ ├── 背景: linear-gradient(135deg, surface-warm → accent半透明)
│ │ │ ├── ::after 虚线边框: 2px dashed var(--border), 旋转动画20s
│ │ │ └── SVG: 140×140px 笔记本+笔+爱心图标
│ │ ├── .slide-title "用手账的方式记录每一天"
│ │ │ └── font: var(--text-2xl)=30px/700 Quicksand
│ │ └── .slide-desc
│ │ └── font: var(--text-base)=15px, color: var(--muted), max-width: 280px
│ ├── .slide.step-2 // 第2页:贴纸装饰
│ │ └── (结构相同,插图背景用 secondary-soft)
│ └── .slide.step-3 // 第3页:成长轨迹
│ └── (结构相同,插图背景用 tertiary-soft)
├── .onboarding-bottom // 底部固定控制
│ ├── position: absolute, bottom: calc(34+24)px
│ ├── .dots // 页码指示器
│ │ ├── .dot (8×8, border-radius:50%, bg:var(--border))
│ │ └── .dot.active (width:28px, border-radius:4px, bg:var(--accent))
│ └── .next-btn "下一步" / "开始使用"
│ ├── width:100%, padding:16px, min-height:44px
│ ├── background:var(--accent), color:var(--accent-on)
│ └── box-shadow: 0 4px 20px var(--shadow-accent)
└── .home-indicator
交互行为
- 滑动切换:
.slides-wrapper通过translateX整体移动,一次 390px - "跳过" 按钮: 直接跳到最后一页
- 最后一页: 按钮文字变为"开始使用"
- 指示器动画: active dot 从 8px 展开到 28px,
var(--ease-bounce)弹性效果
页面 03:登录/注册 (Login)
文件: screens/login.html
尺寸: 390 × 844px
背景: var(--bg)
视觉层级
- 第一眼: 顶部品牌区域 — Logo + 名称 + 标语
- 第二眼: 表单输入区
- 第三眼: 社交登录按钮
完整布局树
body (390×844, overflow:hidden, display:flex, flex-direction:column)
├── .brand-area // 上半部分品牌区
│ ├── flex: 0 0 auto
│ ├── 背景: linear-gradient(180deg, var(--bg) → var(--tertiary-soft))
│ ├── padding: calc(54+24)px 24px 32px, text-align:center
│ ├── .deco × 5 // 装饰元素 (dots/wave/flower)
│ │ └── absolute 定位, opacity:0.2
│ ├── .logo-wrap (80×80px, 居中)
│ │ ├── .logo-notebook (64×72px, border:3px solid var(--accent), border-radius:6px/10px)
│ │ ├── .logo-spine (3×72px, bg:var(--accent))
│ │ └── .logo-heart (18×18px, clip-path 心形)
│ ├── .brand-title "暖记" (32px/700 Quicksand)
│ └── .brand-tagline "用温暖记录每一天" (18px/500 Caveat, color:var(--accent))
├── .form-area // 下半部分表单
│ ├── flex: 1
│ ├── padding: 24px 24px 32px
│ ├── 背景: var(--bg), 圆角: 28px 28px 0 0
│ ├── margin-top: -16px, z-index:5
│ ├── .form-title "欢迎回来" / "创建账号"
│ │ └── 20px/700 Quicksand, text-align:center
│ ├── form#loginForm
│ │ ├── .register-fields (默认display:none, 注册时显示)
│ │ │ └── 昵称输入框
│ │ ├── 手机号输入框
│ │ │ └── height:50px, padding:0 16px 0 46px, border-radius:pill
│ │ ├── 密码输入框 (仅注册)
│ │ │ └── 右侧眼睛切换按钮
│ │ ├── 验证码输入框
│ │ │ ├── 右侧"获取验证码"按钮 (padding:8px 14px, color:var(--accent))
│ │ │ └── 倒计时逻辑:60s
│ │ ├── 协议勾选 (仅注册)
│ │ └── .btn-login "登录" / "注册"
│ │ ├── width:100%, min-height:50px
│ │ ├── background:var(--accent), color:var(--bg)
│ │ ├── font: 18px/700 Quicksand
│ │ └── hover: translateY(-1px) + shadow
│ ├── .divider "其他登录方式"
│ ├── .social-row (display:flex, gap:24px, justify-content:center)
│ │ ├── .social-btn.wechat (56×56圆形, bg:#07C160)
│ │ ├── .social-btn.apple (56×56圆形, bg:#1D1D1F)
│ │ └── .social-btn.google (56×56圆形, bg:var(--surface))
│ └── .bottom-link "还没有账号?立即注册"
│ └── color:var(--accent), font-weight:600
└── .home-indicator
交互行为
- 登录/注册切换: 点击"立即注册" → 添加
.is-register类 → 显示昵称+密码+协议字段,隐藏登录专属字段 - 验证码倒计时: 点击"获取验证码" → 60s 倒计时,按钮禁用
- 密码显示/隐藏: 眼睛图标切换
type="password"/type="text" - 手机号输入: 只允许数字
[^0-9]过滤 - 第三方登录: 微信(绿)、Apple(黑)、Google(白) 三个 56px 圆形按钮
页面 04:首页日记流 (Home Daily)
文件: screens/home-daily.html
尺寸: 390 × 844px
背景: var(--bg)
底部 Tab 栏: 首页 Tab 激活
视觉层级
- 第一眼: 问候语 + 日期
- 第二眼: 连续记录徽章 + 心情选择器
- 第三眼: "今天的日记" 渐变卡片
- 第四眼: 统计卡片 + 日记列表
完整布局树
body (390×844)
├── .content-area // 可滚动内容区
│ ├── top:0, bottom:calc(56+34)=90px
│ ├── padding: 0 20px, padding-top: calc(54+8)=62px
│ │
│ ├── .greeting // 问候区
│ │ ├── display:flex, justify-between
│ │ ├── .greeting-left
│ │ │ ├── .greeting-date "2026年5月31日 · 星期日" (13px/500, var(--muted))
│ │ │ └── .greeting-text "下午好,<span>小暖</span>"
│ │ │ └── font: 30px/700 Quicksand, span:color:var(--accent)
│ │ └── .greeting-search-btn // 搜索按钮
│ │ ├── 44×44, border-radius:pill
│ │ ├── bg:var(--surface), shadow:var(--elev-soft)
│ │ └── SVG 放大镜 20×20
│ │
│ ├── .streak-badge "连续记录 12 天" // 连续记录徽章
│ │ ├── display:inline-flex, padding:6px 14px
│ │ ├── bg:var(--tertiary-soft), border-radius:pill
│ │ └── color:#B8860B, font:13px/600
│ │
│ ├── .mood-section // 心情选择器
│ │ ├── bg:var(--surface), border-radius:16px
│ │ ├── padding:16px 20px, shadow:var(--elev-soft)
│ │ ├── .mood-header
│ │ │ ├── 左: "今天心情如何?" (Caveat 17px/600)
│ │ │ └── 右: 天气 "☀ 晴 26°" (13px, var(--muted))
│ │ └── .mood-options (display:flex, justify-between)
│ │ └── 5个 .mood-opt (各44×44min, 28px emoji + 11px label)
│ │
│ ├── .today-card // "今天的日记" 渐变卡片
│ │ ├── background: linear-gradient(135deg, var(--accent) → var(--tertiary))
│ │ ├── border-radius: 22px, padding: 24px
│ │ ├── 装饰: 两个白色半透明圆形 (::before 120px, ::after 80px)
│ │ ├── .label "今天的日记" (Caveat 13px, rgba(255,248,240,0.85))
│ │ ├── .title "写点什么吧..." (24px/700, var(--accent-on))
│ │ ├── .prompt "记录一个温暖的瞬间..." (13px, rgba(255,248,240,0.75))
│ │ └── .write-btn // 写按钮(右下角浮动)
│ │ ├── absolute, bottom:20px, right:20px
│ │ ├── 48×48, border-radius:50%
│ │ ├── bg:white, shadow:0 4px 12px
│ │ └── SVG: 22×22 加号, color:var(--accent)
│ │
│ ├── .quick-stats // 三栏统计
│ │ ├── display:flex, gap:12px
│ │ ├── .stat-card × 3 (flex:1)
│ │ │ ├── bg:var(--surface), border-radius:16px
│ │ │ ├── padding:16px, text-align:center
│ │ │ ├── .num: 30px/700 Quicksand
│ │ │ │ ├── 第一个: color:var(--accent) "28 本月日记"
│ │ │ │ ├── 第二个: color:var(--secondary) "12 连续天数"
│ │ │ │ └── 第三个: color:var(--fg) "156 总日记数"
│ │ │ └── .label: 11px, var(--muted)
│ │
│ ├── .recent-header // "最近记录" 标题
│ │ ├── h3: 20px/700 Quicksand "最近记录"
│ │ └── a: 13px/500, color:var(--accent) "查看全部"
│ │
│ ├── .entry-card × 4 // 日记卡片列表
│ │ ├── display:flex, gap:16px
│ │ ├── bg:var(--surface), border-radius:16px, padding:16px
│ │ ├── shadow:var(--elev-soft), border:1px solid var(--border-soft)
│ │ ├── hover: translateY(-1px), active: scale(0.98)
│ │ ├── .entry-preview (72×72, border-radius:10px)
│ │ │ └── emoji 内容,bg:var(--surface-warm) 或变体
│ │ ├── .entry-info (flex:1)
│ │ │ ├── .entry-date: 11px, var(--muted)
│ │ │ ├── .entry-title: 15px/600 Quicksand, 单行省略
│ │ │ └── .entry-excerpt: 13px, var(--muted), 2行省略
│ │ └── .entry-mood: 16px emoji
│ │
│ └── .empty-state (默认display:none)
│
├── nav.tab-bar // 底部Tab栏
│ └── 5个tab (首页激活)
├── .dynamic-island
└── .home-indicator
交互行为
- 心情选择: 点击切换
.selected类,背景变为var(--surface-warm),label 变为 accent 色 - "今天的日记" 卡片: hover 上浮 2px,active 缩放 0.98
- 写按钮(圆形+号): hover 放大到 1.1 倍
- 日记卡片: 点击进入日记详情/编辑器
- 搜索按钮: 链接到
search.html
页面 05:手账编辑器 (Editor)
文件: screens/editor.html
尺寸: 390 × 844px
背景: var(--bg)
无 Tab 栏 — 全屏编辑模式
视觉层级
- 第一眼: 顶部工具栏(返回/日期/保存)
- 第二眼: 中央画布区域(点阵背景 + 日记内容)
- 第三眼: 底部工具栏(贴纸/模板/画笔/照片/文字/更多)
完整布局树
body (390×844, overflow:hidden)
│
├── .editor-topbar // 顶部工具栏
│ ├── position:absolute, top:0, left:0, right:0
│ ├── height: calc(54+44)=98px
│ ├── bg:var(--surface), border-bottom:1px solid var(--border-soft)
│ ├── z-index:100
│ ├── padding-top: var(--safe-top)=54px
│ ├── .topbar-left: 返回按钮 (SVG 箭头, min:36×36)
│ ├── .topbar-center: "5月31日 · 周日" (15px/600 Quicksand)
│ └── .topbar-right
│ ├── .topbar-undo-redo: 撤销/重做按钮 (18px SVG)
│ ├── .autosave-status: "已保存" (11px, color:var(--success), 绿点)
│ ├── 标签按钮 (SVG, min:36×36)
│ └── .save-btn "保存" (padding:6px 16px, bg:var(--accent))
│
├── .date-strip // 日期+心情条
│ ├── position:absolute, top:98px
│ ├── height:40px, bg:var(--surface)
│ ├── .date-info: "14:32 · 晴 26°" (13px, var(--muted))
│ └── .mood-quick: 5个 .mood-mini (24×24圆形, emoji 12px)
│ └── 选中态: border-color:var(--accent), bg:var(--surface-warm)
│
├── .canvas-area // 画布区域
│ ├── position:absolute
│ ├── top: calc(54+44+40)=138px
│ ├── bottom: 72px
│ ├── left:12px, right:12px
│ ├── bg:var(--surface), border-radius:16px
│ ├── shadow:var(--elev-soft), border:1px solid var(--border-soft)
│ ├── padding:20px
│ ├── .canvas-grid: 点阵背景 (24×24px 间距, 1px圆点, opacity:0.5)
│ ├── .washi-tape: 和纸胶带装饰
│ │ ├── absolute, top:12px, right:30px
│ │ ├── 90×20px, rotate(-8deg), opacity:0.8
│ │ └── repeating-linear-gradient 45deg条纹
│ ├── .placed-sticker × 2: 放置的贴纸 (32px emoji, absolute)
│ └── .journal-content
│ ├── .journal-title: 输入框 (24px/700, border:none)
│ ├── .format-bar: 文字格式工具
│ │ ├── B/I/U 按钮 (36×36, active:bg:var(--accent))
│ │ ├── 颜色点 (20×20圆形) × 4: 黑/accent/绿/蓝
│ │ └── 对齐方式按钮
│ ├── textarea.journal-body
│ │ └── 15px, line-height:1.8, resize:none, min-height:200px
│ └── .placed-photo: 照片占位 (100%×140px, border-radius:10px)
│
├── .editor-toolbar // 底部工具栏
│ ├── position:absolute, bottom:0
│ ├── height:72px (含safe-bottom)
│ ├── bg:var(--surface), border-top:1px solid var(--border-soft)
│ ├── z-index:100
│ └── .toolbar-main: 6个工具按钮
│ ├── .tool-btn (min:36×36, flex-direction:column)
│ │ ├── SVG: 20×20
│ │ └── label: 10px/500
│ ├── 贴纸 | 模板 | 画笔 | 照片 | 文字 | 更多
│ └── hover: color:var(--accent), bg:var(--surface-warm)
│
├── .tool-panel#stickerPanel // 贴纸面板(展开式)
│ ├── position:absolute, bottom:72px
│ ├── max-height:260px, overflow-y:auto
│ ├── bg:var(--surface), border-top:1px solid var(--border-soft)
│ ├── 默认: translateY(100%), 打开: translateY(0)
│ ├── transition: 0.25s ease-bounce
│ ├── .panel-tabs: 7个分类标签 (热门/可爱/植物/天气/节日/手绘/校园)
│ │ ├── padding:8px 16px, min-height:44px
│ │ ├── bg:var(--surface-warm), active: bg:var(--accent)
│ │ └── overflow-x:auto
│ └── .sticker-grid: 5列网格
│ └── .sticker-item: 正方形, 24px emoji, hover:scale(1.1)
│
├── .brush-panel // 画笔面板(底部抽屉 280px)
│ ├── 圆角: 22px 22px 0 0
│ ├── .brush-panel-handle: 36×4px 拖拽指示条
│ ├── .brush-tools-row: 钢笔/铅笔/马克笔/橡皮 (4个工具)
│ │ └── active: border:2px solid var(--accent)
│ ├── .brush-size-row: 粗细滑块 (1-20px)
│ ├── .brush-colors-row: 8色 + 更多按钮
│ │ └── 24×24圆形, active: border-color:var(--fg)
│ └── .brush-opacity-row: 透明度滑块 (仅马克笔启用)
│ └── disabled 态: opacity:0.35, pointer-events:none
│
├── .tag-panel // 标签面板(底部抽屉 200px)
│ ├── 圆角: 22px 22px 0 0
│ ├── .tag-selected-area: 已选标签 pills
│ │ └── .tag-pill: bg:var(--surface-warm), color:var(--accent), 右侧×删除
│ ├── .tag-input: 44px高输入框
│ └── .tag-suggest-row: 推荐标签 (#日常/#学习/#读书 等)
│ └── min-height:44px, hover: border-color:var(--accent)
│
└── .dynamic-island
交互行为
- 工具面板切换: 点击底部工具按钮 → 关闭其他面板 → 展开对应面板(translateY 动画)
- 画笔面板: 打开时显示半透明遮罩层(opacity:0.3),点击遮罩关闭
- 画笔工具切换: 不同工具设置不同默认粗细(钢笔2px、铅笔3px、马克笔8px、橡皮10px)
- 马克笔: 唯一启用透明度滑块的工具
- 标签面板: Enter 添加标签,自动加
#前缀;点击推荐标签添加并隐藏 - 自动保存: 顶部显示"已保存"绿色状态
- 贴纸放置: 从网格点击贴纸 → 放入画布,absolute 定位,可拖动
页面 06:日历视图 (Calendar)
文件: screens/calendar.html
尺寸: 390 × 844px
底部 Tab 栏: 日历 Tab 激活
视觉层级
- 第一眼: 月份标题 + 导航按钮
- 第二眼: 心情概览柱状图
- 第三眼: 7列日历网格(含心情圆点)
- 第四眼: 当日时间线
完整布局树
body (390×844)
├── .content-area (bottom:90px)
│ │
│ ├── .month-header // 月份标题
│ │ ├── .month-title "2026年5月" (30px/700)
│ │ └── .month-nav: 上/下月按钮 (44×44圆形, border:1.5px)
│ │
│ ├── .view-toggle // 视图切换
│ │ ├── display:flex, bg:var(--surface), border-radius:pill
│ │ ├── padding:3px, border:1px solid var(--border-soft)
│ │ └── 3个按钮: "月视图" | "周视图" | "时间轴"
│ │ └── active: bg:var(--accent), color:var(--accent-on)
│ │
│ ├── .mood-summary // 心情概览
│ │ ├── bg:var(--surface), border-radius:16px, padding:20px
│ │ ├── h4 "本月心情概览" (15px/600)
│ │ ├── .mood-bar-chart (height:80px, display:flex, align-items:flex-end)
│ │ │ └── 5个 .mood-bar (flex:1, border-radius:6px 6px 0 0)
│ │ │ ├── 开心: height:65%, bg:var(--secondary)
│ │ │ ├── 平静: height:45%, bg:var(--tertiary)
│ │ │ ├── 难过: height:20%, bg:#5B7DB1
│ │ │ ├── 生气: height:10%, bg:var(--accent)
│ │ │ └── 思考: height:15%, bg:#8B7E74
│ │ └── .mood-labels (各 flex:1, text-align:center, 11px)
│ │
│ ├── .weekday-row // 星期行
│ │ └── grid 7列, 11px/500, var(--meta)
│ │
│ ├── .calendar-grid // 日历网格
│ │ ├── grid 7列, gap:4px
│ │ └── .cal-day (aspect-ratio:1, min-height:44px)
│ │ ├── 正常: 13px, border-radius:10px, hover:bg:var(--surface-warm)
│ │ ├── .empty: 空白占位
│ │ ├── .today: bg:var(--accent), color:var(--accent-on), font-weight:700
│ │ ├── .selected: bg:var(--surface-warm), border:2px solid var(--accent)
│ │ ├── .mood-dot: 6×6圆形, absolute bottom:4px
│ │ │ ├── .happy: var(--secondary)
│ │ │ ├── .love: var(--accent)
│ │ │ ├── .calm: var(--tertiary)
│ │ │ ├── .sad: #5B7DB1
│ │ │ └── .tired: #8B7E74
│ │ └── .entry-indicator: 5×5圆形, absolute top:3px right:5px, bg:var(--accent)
│ │
│ ├── .timeline-section // 当日时间线
│ │ ├── .timeline-header: "5月31日 · 今天" + "3条记录"
│ │ └── .timeline-item × 3
│ │ ├── display:flex, gap:16px, position:relative
│ │ ├── .timeline-line: 2px宽, absolute left:19px, bg:var(--border)
│ │ ├── .timeline-dot: 40×40圆形, 18px emoji
│ │ │ └── bg:var(--surface), border:2px solid var(--border-soft)
│ │ └── .timeline-content: 卡片 (border-radius:16px, padding:16px)
│ │ ├── .tl-time: 11px, var(--muted)
│ │ ├── .tl-title: 15px/600 Quicksand
│ │ └── .tl-excerpt: 13px, var(--muted), 2行省略
│ │
│ └── .empty-day (默认hidden)
│
├── nav.tab-bar (日历激活)
├── .dynamic-island
└── .home-indicator
交互行为
- 月份切换: 上/下月按钮
- 视图切换: 月视图/周视图/时间轴(pill 形态 segmented control)
- 日期选择: 点击日期添加
.selected类,today + selected 特殊样式 - 时间线条目: 点击进入日记详情
- 心情柱状图: 高度按百分比,transition 动画
页面 07:心情追踪 (Mood Tracker)
文件: screens/mood-tracker.html
尺寸: 390 × 844px
底部 Tab 栏: "我的" Tab 激活
完整布局树
body (390×844)
├── .content-area (bottom:90px)
│ │
│ ├── .page-title "心情与天气" (30px/700 Quicksand)
│ │
│ ├── .today-mood-card // 今日心情卡片
│ │ ├── background: linear-gradient(135deg, var(--accent) → var(--tertiary))
│ │ ├── border-radius: 22px, padding: 24px
│ │ ├── 装饰圆: 100px, rgba(255,255,255,0.12), 右上角
│ │ ├── .label "今日心情 · 5月31日" (手写体, rgba白0.85)
│ │ ├── emoji: 52px
│ │ ├── .mood-text: "开心" (accent-on色)
│ │ └── .mood-subtitle: "阳光灿烂的一天" (rgba白0.75)
│ │
│ ├── .weather-card // 天气卡片
│ │ ├── bg:var(--surface), border-radius:16px
│ │ ├── 标题 "今日天气"
│ │ └── 5个天气按钮 (flex, gap:12px)
│ │ ├── aspect-ratio:1, border-radius:16px, border:2px
│ │ ├── 28px emoji + 11px label
│ │ ├── 选项: 晴/多云/雨/雪/风
│ │ └── 选中态: border-color:var(--accent) + bg:var(--surface-warm)
│ │
│ ├── .mood-chart-card // 心情趋势图
│ │ ├── bg:var(--surface), border-radius:16px
│ │ ├── 标题 "心情趋势"
│ │ ├── 周期选择 pills: 7天/30天/3个月
│ │ └── 柱状图 (height:120px, gap:3px)
│ │ └── 7根柱子 (max-width:14px), 日期标签(9px)
│ │
│ ├── .stats-grid // 2×2 统计网格
│ │ ├── display:grid, 2列, gap:12px
│ │ └── 4个统计卡片: emoji(28px) + 数值(text-xl/700) + 描述(text-xs)
│ │
│ └── .insight-card // 心情洞察
│ ├── 标题 "心情洞察"
│ └── 3个洞察项: 36px圆形图标(彩色bg) + 标题 + 详情
│
├── nav.tab-bar ("我的"激活)
├── .dynamic-island
└── .home-indicator
页面 08:周视图 (Weekly)
文件: screens/weekly.html
尺寸: 390 × 844px
底部 Tab 栏: 日历 Tab 激活
完整布局树
body (390×844)
├── .content-area (bottom:90px)
│ │
│ ├── .week-header // 周标题
│ │ ├── "本周概览" (30px/700)
│ │ └── 上一周/下一周按钮 (44×44圆形)
│ │
│ ├── .week-strip // 7天横向卡片
│ │ ├── display:grid, 7列, gap:4px
│ │ └── 每个日期: padding:12px上下, border-radius:16px
│ │ ├── 星期名 (11px, var(--meta))
│ │ ├── 日期数字 (20px/700 Quicksand)
│ │ ├── 心情emoji (16px)
│ │ ├── today: bg:var(--accent), color:var(--accent-on)
│ │ └── 有日记指示器: 4px accent 圆点
│ │
│ ├── .week-summary // 本周总结卡片
│ │ ├── bg:var(--surface), border-radius:16px
│ │ ├── 3个统计: 记录天数/日记数/贴纸数
│ │ └── 心情分布条: height:8px, pill圆角
│ │ └── 3段: secondary(开心) : tertiary(平静) : #5B7DB1(难过)
│ │
│ └── .day-cards × 3 // 日记条目卡片
│ ├── bg:var(--surface), border-radius:16px, padding:16px
│ ├── 头部: 日期 + 心情/天气emoji
│ ├── 正文: 3行省略, line-height:1.6
│ ├── 标签pills: 3px 10px padding, 彩色背景
│ └── 照片占位: 80px高, gradient bg
│
├── nav.tab-bar (日历激活)
├── .dynamic-island
└── .home-indicator
页面 09:月度统计 (Monthly)
文件: screens/monthly.html
尺寸: 390 × 844px
底部 Tab 栏: 日历 Tab 激活
完整布局树
body (390×844)
├── .content-area (bottom:90px)
│ │
│ ├── .month-header: "2026年5月" + 上下月按钮
│ │
│ ├── .month-grid-card // 月度热力图
│ │ ├── bg:var(--surface), border-radius:16px
│ │ ├── weekday 行: 7列, 11px
│ │ └── grid: 7列, gap:3px, 每格 aspect-ratio:1
│ │ ├── 每格: 日期 + 心情emoji(10px)
│ │ ├── 心情背景色映射:
│ │ │ ├── 开心: var(--secondary-soft)
│ │ │ ├── 爱: var(--rose-soft)
│ │ │ ├── 平静: var(--tertiary-soft)
│ │ │ ├── 难过: #D4DDE8
│ │ │ └── 疲惫: #E8E4E0
│ │ ├── today: outline:var(--accent)
│ │ └── hover: scale(1.1)
│ │
│ ├── .month-summary // 月度统计 2×2 网格
│ │ ├── 4个统计卡片, 各有彩色背景
│ │ └── emoji(24px) + 数值(text-xl/700, 彩色) + label(text-xs)
│ │
│ └── .highlights // 本月精选
│ └── 3个精选卡片: 48px圆形emoji + 日期+标题 + badge pill
│
├── nav.tab-bar (日历激活)
├── .dynamic-island
└── .home-indicator
页面 10:贴纸素材 (Stickers)
文件: screens/stickers.html
尺寸: 390 × 844px
无 Tab 栏 — 全屏浏览模式
完整布局树
body (390×844)
├── .content-area (全屏, padding:20px)
│ │
│ ├── .top-bar // 顶部导航
│ │ ├── 返回按钮 (44×44圆形, bg:var(--surface))
│ │ └── 标题 "贴纸素材" (居中)
│ │
│ ├── .search-box // 搜索框
│ │ ├── pill形状, bg:var(--surface)
│ │ ├── 20px 搜索图标 + 输入框
│ │ └── focus: border-color:var(--accent)
│ │
│ ├── .category-tabs // 分类标签 (横向滚动)
│ │ ├── 推荐/可爱/植物/手绘/校园/节日/文字/和纸胶带
│ │ ├── padding:8px 18px, min-height:44px
│ │ └── active: bg:var(--accent)
│ │
│ ├── .featured-pack // 精选贴纸包
│ │ ├── gradient bg, border-radius:22px, padding:20px
│ │ ├── 72px 图标区 (白色bg, 36px emoji)
│ │ ├── 标题 + 描述
│ │ └── "限时免费" 标签 (secondary bg)
│ │
│ ├── .pack-grid // 贴纸包列表 (2列)
│ │ └── 卡片: 100px预览区 + 名称 + 数量 + 价格
│ │
│ └── .sticker-selection // 单个贴纸选择 (4列网格)
│ ├── gap:12px, aspect-ratio:1
│ ├── 32px emoji, bg:var(--surface)
│ ├── hover: scale(1.08) + accent border
│ └── 爱心收藏按钮: hover时右上角出现, rose色
│
├── .dynamic-island
└── .home-indicator
页面 11:模板库 (Templates)
文件: screens/templates.html
尺寸: 390 × 844px
无 Tab 栏 — 全屏浏览模式
完整布局树
body (390×844)
├── .content-area (全屏, padding:20px)
│ │
│ ├── .top-bar: 返回 + "模板库" 标题
│ │
│ ├── .view-selector // 视图类型选择
│ │ └── 3个等宽按钮 (emoji 28px + label)
│ │ ├── 日视图/周视图/月视图
│ │ └── active: border:var(--accent) + bg:var(--surface-warm)
│ │
│ └── .template-list (gap:16px) // 模板列表 (5个模板)
│ └── 每个模板卡片:
│ ├── .preview-area (height:200px)
│ │ └── gradient 背景 + 布局示意 (文字行/照片/网格/日历)
│ ├── .meta (padding:16px 20px)
│ │ ├── 左: 名称 + 描述
│ │ └── 右: "使用" 按钮 (accent pill, padding:8px 20px)
│ └── .tags (padding:0 20px 16px)
│ └── 彩色标签 pills (如 "学生专属" secondary-soft)
│
├── .dynamic-island
└── .home-indicator
页面 12:发现页 (Discover)
文件: screens/discover.html
尺寸: 390 × 844px
底部 Tab 栏: 发现 Tab 激活
完整布局树
body (390×844)
├── .content-area (bottom:90px)
│ │
│ ├── .search-bar // 搜索框
│ │ ├── pill形状, bg:var(--surface), padding:12px 16px
│ │ └── focus: border-color:var(--accent)
│ │
│ ├── .inspiration-card // 每日推荐卡片
│ │ ├── background: linear-gradient(135deg, var(--accent) → var(--tertiary))
│ │ ├── border-radius:22px, padding:20px
│ │ ├── 装饰圆 × 2 (120px右上, 80px左下, rgba白)
│ │ ├── .label "今日推荐" (uppercase, letter-spacing:0.5px)
│ │ ├── 80px缩略图 (rgba白0.2 bg, backdrop-filter:blur 4px, 36px emoji)
│ │ ├── 标题 (white, 20px/700)
│ │ └── 作者 (rgba白0.75)
│ │
│ ├── .hot-topics // 热门话题
│ │ ├── 标题 "热门话题"
│ │ └── 横向滚动 chips: #期末备考 #读书笔记 #旅行手账 #美食日记 #校园生活 #自我成长
│ │ └── active: bg:var(--accent)
│ │
│ ├── .featured-templates // 精选模板 (2列网格)
│ │ └── 卡片: 96px缩略图(彩色bg, 32px emoji) + 名称 + 使用人数
│ │
│ └── .expert-diaries // 达人日记 (纵向列表)
│ └── 卡片: 44px头像(彩色bg, 20px emoji) + 用户名 + 标题(单行省略) + 预览(2行省略) + 点赞数
│
├── nav.tab-bar (发现激活)
├── .dynamic-island
└── .home-indicator
页面 13:搜索页 (Search)
文件: screens/search.html
尺寸: 390 × 844px
无 Tab 栏 — 全屏搜索模式
完整布局树
body (390×844)
├── .search-header (z-index:100) // 固定搜索头部
│ ├── height: calc(54+52)=106px
│ ├── bg:var(--surface), border-bottom:1px
│ ├── 返回按钮 (44px pill)
│ ├── 搜索输入框 (44px高, pill形状, bg:var(--surface-warm))
│ └── 取消按钮 (accent色文字)
│
├── .search-content (滚动内容)
│ │
│ ├── [搜索前状态]
│ │ ├── .search-history: "最近搜索" + "清除" + 标签pills
│ │ └── .hot-searches: "热门搜索" + 标签pills
│ │
│ └── [搜索后状态]
│ ├── 结果 tabs: 全部/日记/模板/标签
│ │ └── active: accent文字 + 3px accent下划线
│ ├── 日记结果: 卡片(标题含高亮标记, tertiary-soft bg + accent text)
│ ├── 模板结果: 2列网格卡片
│ └── 标签结果: 更大的标签pills (10px 20px padding)
│
├── .dynamic-island
└── .home-indicator
页面 14:个人中心 (Profile)
文件: screens/profile.html
尺寸: 390 × 844px
底部 Tab 栏: "我的" Tab 激活
完整布局树
body (390×844)
├── .content-area (bottom:90px)
│ │
│ ├── .profile-header // 用户信息 (居中)
│ │ ├── 80px 头像 (gradient bg: accent→tertiary, 36px emoji)
│ │ ├── 用户名 (24px/700 Quicksand)
│ │ └── 签名 (13px, var(--muted))
│ │
│ ├── .stats-bar // 统计条
│ │ ├── bg:var(--surface), border-radius:16px, padding:16px
│ │ ├── display:flex, 4等分, border-soft 分割线
│ │ └── 各项: 数值(text-xl/700, 彩色) + 标签(text-xs)
│ │ ├── 总日记: accent色
│ │ ├── 连续天数: secondary色
│ │ ├── 本月日记: fg色
│ │ └── 贴纸数: fg色
│ │
│ ├── .badges-section // 成就徽章
│ │ ├── 标题 "成就徽章" (20px/700)
│ │ └── 横向滚动行 (gap:12px)
│ │ └── 每个徽章: 80px宽, 56px圆形图标(彩色bg, 24px emoji) + 名称(11px)
│ │ ├── 已获得: 全彩色
│ │ └── 未获得: border-soft bg, opacity:0.5
│ │
│ ├── .settings-card // 设置列表
│ │ ├── bg:var(--surface), border-radius:16px
│ │ └── 设置项: flex row, padding:16px 20px, min-height:44px
│ │ ├── 左: 36px图标(彩色bg, 18px emoji)
│ │ ├── 中: 标题 + 副标题
│ │ └── 右: toggle开关 或 右箭头
│ │ └── toggle: 44×26px, pill圆角, accent bg(开)/border(关)
│ │ └── 20px白色圆, 18px translateX 切换动画
│ │
│ └── .more-settings // 更多设置
│ └── 导出数据 / 意见反馈 / 关于(版本1.0.0)
│
├── nav.tab-bar ("我的"激活)
├── .dynamic-island
└── .home-indicator
4. 平板端变体
平板通用布局规则 (1024×768)
核心变化: 底部 Tab 栏 → 左侧固定侧边导航栏(240px)
侧边栏结构:
.sidebar (width:240px, position:fixed, height:100%)
├── 品牌Logo + App名称
├── 导航项: 首页/日历/心情追踪/贴纸/模板/发现
├── "写日记" 按钮 (accent色, pill形状)
└── 底部: 用户头像 + 连续天数
内容区: margin-left:240px, 可用宽度 = 784px
各页面布局差异:
平板首页 (tablet/home-daily.html)
- 布局模式: 侧边栏 + 单列内容
.top-row: 2列网格 (1fr 1fr) — 心情选择器和今日卡片并排(移动端纵向堆叠).quick-stats: 3列统计卡片.entries-grid: 2列日记卡片网格(移动端单列)
平板编辑器 (tablet/editor.html)
- 三栏布局:
侧边栏 | 画布 | 右侧工具面板(320px) - 画布:
max-width:640px,min-height:600px,overflow-y:auto - 右侧面板: 固定320px, 包含标签页(贴纸/画笔/模板/标签/背景)
- 贴纸网格: 5列
- 无底部工具栏 — 工具全部移到右侧面板
平板日历 (tablet/calendar.html)
- 两栏布局:
月视图(flex:1) | 时间线(固定340px) - 左侧: 心情柱状图 + 7列日历网格(可独立滚动)
- 右侧: 选中日期的时间线(
border-left分割,可独立滚动)
平板发现 (tablet/discover.html)
- 2列网格:
grid-template-columns: 1fr 1fr - 左列: 热门话题 + 达人日记
- 右列: 精选模板(2列网格) + 每日推荐
平板登录 (tablet/login.html)
- 居中卡片: 540px宽, 480px高
- 水平分割: 左品牌区(240px, gradient) | 右表单区(flex:1)
- 无侧边栏,无Tab栏
平板搜索 (tablet/search.html)
- 全屏搜索: 无侧边栏
- 固定搜索栏(64px高) + 滚动结果(max-width:900px)
- 日记结果: 2列网格, 模板结果: 4列网格
5. 桌面端变体
桌面通用布局规则 (1440×900)
在平板侧边栏基础上增加 macOS 风格状态栏(顶部红黄绿信号灯 + App 标题 + 时钟)
桌面独有元素:
.desktop-statusbar: 顶部固定栏,macOS 交通灯.desktop-topbar: 页面内顶部栏,显示页面标题 + 操作按钮
各页面布局差异:
| 页面 | 布局 | 与平板的关键区别 |
|---|---|---|
| 首页 | 侧边栏 + 主内容 + 右面板(380px) | 右面板含统计+趋势图+洞察(平板无) |
| 编辑器 | 侧边栏 + 工具条(64px) + 画布 + 面板(360px) | 新增独立工具条(64px),面板更宽(360px) |
| 日历 | 侧边栏 + 统计面板(280px) + 月视图 + 时间线(360px) | 新增左侧统计面板,三栏分屏 |
| 发现 | 侧边栏 + 3列网格 | 3列(平板2列),hero横幅推荐卡 |
| 登录 | 60%品牌区 + 40%表单区 全屏分割 | 品牌区含3个特性卡片(平板无) |
| 搜索 | 侧边栏 + 3列结果 | 恢复侧边栏(平板无),3列结果(平板2列) |
跨平台响应规则总结
| 特性 | 移动端 (390×844) | 平板 (1024×768) | 桌面 (1440×900) |
|---|---|---|---|
| 导航 | 底部 Tab 栏(90px) | 左侧边栏(240px) | 左侧边栏(240px) + macOS 状态栏 |
| 内容列数 | 1列 | 2列 | 2-3列 |
| 滚动 | 内容区垂直滚动 | 有限滚动,适配视口 | 有限滚动,适配视口 |
| 安全区 | safe-top:54px, safe-bottom:34px | 无 | 32px top padding |
| 触控目标 | ≥44px | ≥44px | ≥36px |
| 搜索页 | 全屏覆盖,无侧边栏 | 全屏,无侧边栏 | 有侧边栏 |
| 登录页 | 全屏纵向堆叠 | 居中卡片(540px),水平分割 | 60/40全屏分割 + 特性卡片 |
| 编辑器工具 | 底部工具栏 + 底部弹窗 | 右侧面板(320px) + 标签页 | 工具条(64px) + 右面板(360px) |
| 日历详情 | 内联/底部展示 | 右侧时间线(340px) | 左统计(280px) + 右时间线(360px) |
注意: 每个变体都是固定尺寸的独立 mockup,不使用 CSS 媒体查询实现响应式。
6. 交互行为规范
6.1 主题切换
- 通过
js/theme-switcher.js实现 - 支持暖阳(Warm)/松风(Pine)双主题
- 暗色模式跟随系统
prefers-color-scheme - 切换方式:
data-theme="pine"或data-theme="warm"
6.2 页面切换动画
- 进入:
.anim-fade— opacity 0→1 + translateY(12px→0),0.5s - 重要元素:
.anim-slide— translateY(40px→0),0.6s ease-bounce - 卡片/图标:
.anim-scale— scale(0.9→1),0.4s ease-bounce - 延迟: 级联延迟
animation-delay: 0.1s, 0.15s, 0.2s...
6.3 触摸反馈
- 按钮:
active: scale(0.97)— 按压缩小 - 卡片:
hover: translateY(-1px)— 悬浮上浮 - 重要卡片:
hover: translateY(-2px)— 更明显上浮 - 圆形按钮:
hover: scale(1.1)— 放大反馈
6.4 底部面板交互模式
- 展开动画:
transform: translateY(100%) → translateY(0),0.25s ease-bounce - 遮罩层:
background: rgba(45,36,32,0.3),点击关闭面板 - 面板类型: 贴纸面板(max-height:260px)、画笔面板(280px)、标签面板(200px)
6.5 无障碍规范
- 触控目标: 所有可交互元素 ≥ 44×44px(
var(--touch-min)) - 焦点环:
box-shadow: var(--focus-ring) = 0 0 0 3px rgba(224,122,95,0.45) - ARIA 标签: 所有按钮含
aria-label,装饰元素含aria-hidden="true" - 语义 HTML: Tab 栏使用
role="tablist"+role="tab",面板使用role="dialog" - 动效偏好:
@media (prefers-reduced-motion: reduce)关闭所有动画
7. 常见实现偏差清单
以下是 Claude Code 等 LLM 在实现时最常犯的错误,必须逐一对照。
7.1 颜色偏差(最高频)
| 错误 | 正确 |
|---|---|
页面背景用 #FFFFFF |
必须用 #FFF8F0(var(--bg)),这是暖色奶油白 |
Card 背景用 #FFF8F0 |
Card 用 #FFFFFF(var(--surface)),和页面背景形成层次 |
| 强调色用蓝色 | 强调色是赤陶珊瑚 #E07A5F(var(--accent)),不是蓝色 |
| 所有文字用纯黑 | 文字分4级:#2D2420(主) #5C4F47(次) #7A6D63(辅) #8B7E74(极淡) |
边框用浅灰 #E0E0E0 |
边框是暖灰 #E8DDD4,带棕调 |
7.2 布局偏差
| 错误 | 正确 |
|---|---|
| Tab 栏高度只有 56px | Tab 栏高度 = 56px + 34px安全区 = 90px |
| 内容区底部到 Tab 栏顶部 | bottom: calc(var(--tab-height) + var(--safe-bottom)) |
| Tab 栏中间按钮和其他一样 | 中间"写日记"按钮凸出 Tab 栏 16px,圆形背景,独立阴影 |
| 日记卡片左对齐文字 | .entry-title 需要 white-space:nowrap; text-overflow:ellipsis 单行省略 |
| 日历格间距不均匀 | .calendar-grid 使用 grid-template-columns: repeat(7, 1fr); gap: 4px |
7.3 交互偏差
| 错误 | 正确 |
|---|---|
| 按钮无 hover 态 | 所有按钮必须有 hover 变化(颜色变化或位移) |
| 按钮无 active 态 | active: transform: scale(0.97) 按压反馈 |
| 面板突然出现 | 面板使用 translateY 滑入动画,0.25s ease-bounce |
| 面板无遮罩 | 展开面板必须显示半透明遮罩,点击遮罩关闭 |
| 心情选择无反馈 | 选中态需 bg:var(--surface-warm) + label 变 accent 色 |
7.4 字体偏差
| 错误 | 正确 |
|---|---|
| 标题用 Nunito | 标题用 Quicksand(var(--font-display)),圆角感更强 |
| 所有文字一个大小 | 严格遵循 9 级字号阶梯(11-48px) |
| 手写标签用 Nunito | 手写标签用 Caveat(var(--font-handwritten)) |
| 行高统一 1.5 | 正文 1.6,标题 1.25 |
7.5 间距偏差
| 错误 | 正确 |
|---|---|
| 所有间距用 8px | 使用 4px 基准的 9 级间距系统(4,8,12,16,20,24,32,40,48px) |
| 卡片内边距用 16px | Card 内边距 var(--space-5) = 20px |
| 内容区无安全区 | 顶部 padding 必须包含 var(--safe-top)=54px |
7.6 圆角偏差
| 错误 | 正确 |
|---|---|
| 所有圆角 8px | 圆角分4级:10px(小) 16px(卡片) 22px(大面板) 9999px(按钮) |
| Tab 栏中按钮圆角 16px | 凸出按钮必须是正圆形 border-radius: 50% |
8. CSS :root 参考实现
可直接复制到项目 CSS 文件中的完整 token 定义:
:root {
/* Surface */
--bg: #FFF8F0;
--surface: #FFFFFF;
--surface-warm: #FFF3E6;
/* Foreground */
--fg: #2D2420;
--fg-2: #5C4F47;
--muted: #7A6D63;
--meta: #8B7E74;
/* Border */
--border: #E8DDD4;
--border-soft: #F0E8DF;
/* Accent */
--accent: #E07A5F;
--accent-on: #FFF8F0;
--accent-hover: #D06A4F;
--accent-active: #C05A3F;
--accent-glow: rgba(224, 122, 95, 0.25);
/* Secondary & Tertiary */
--secondary: #81B29A;
--secondary-soft: #D4E8DC;
--tertiary: #F2CC8F;
--tertiary-soft: #FBE8C8;
/* Rose */
--rose: #D4A5A5;
--rose-soft: #F0DADA;
/* Semantic */
--success: #5A9E7E;
--warn: #D4A843;
--danger: #C93D3D;
/* Typography */
--font-display: "Quicksand", "Nunito", "SF Pro Rounded", -apple-system, system-ui, sans-serif;
--font-body: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
--font-mono: ui-monospace, "JetBrains Mono", monospace;
--font-handwritten: "Caveat", "Kalam", cursive;
--text-xs: 11px;
--text-sm: 13px;
--text-base: 15px;
--text-md: 17px;
--text-lg: 20px;
--text-xl: 24px;
--text-2xl: 30px;
--text-3xl: 38px;
--text-4xl: 48px;
--leading-body: 1.6;
--leading-tight: 1.25;
/* Spacing */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
/* Radius */
--radius-sm: 10px;
--radius-md: 16px;
--radius-lg: 22px;
--radius-xl: 28px;
--radius-pill: 9999px;
/* Elevation */
--elev-soft: 0 2px 12px rgba(45, 36, 32, 0.06);
--elev-medium: 0 4px 20px rgba(45, 36, 32, 0.08);
--elev-float: 0 8px 32px rgba(45, 36, 32, 0.12);
--shadow-accent: 0 4px 14px rgba(224, 122, 95, 0.25);
--shadow-accent-hover: 0 6px 20px rgba(224, 122, 95, 0.35);
--shadow-input-focus: 0 0 0 3px rgba(224, 122, 95, 0.2);
--focus-ring: 0 0 0 3px rgba(224, 122, 95, 0.45);
--bg-frosted: rgba(255, 248, 240, 0.85);
/* Touch */
--touch-min: 44px;
/* Motion */
--motion-fast: 150ms;
--motion-base: 250ms;
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
/* Layout */
--container-max: 390px;
--safe-top: 54px;
--safe-bottom: 34px;
--tab-height: 56px;
--theme-name: "暖阳";
}
/* Theme: 松风 */
[data-theme="pine"] {
--bg: #F2F3F0;
--surface: #FFFFFF;
--surface-warm: #E9EAE6;
--fg: #23272F;
--fg-2: #484E58;
--muted: #6E7380;
--meta: #8A8F9A;
--border: #D5D2CD;
--border-soft: #E3E1DC;
--accent: #4A7B9D;
--accent-on: #FFFFFF;
--accent-hover: #3F6A8A;
--accent-active: #345A78;
--accent-glow: rgba(74, 123, 157, 0.25);
--secondary: #5B9E7A;
--secondary-soft: #D6E8DE;
--tertiary: #C49A3C;
--tertiary-soft: #F0E4C8;
--rose: #7A8B6A;
--rose-soft: #E0E8D8;
--elev-soft: 0 2px 12px rgba(35, 39, 47, 0.06);
--elev-medium: 0 4px 20px rgba(35, 39, 47, 0.08);
--elev-float: 0 8px 32px rgba(35, 39, 47, 0.12);
--focus-ring: 0 0 0 3px rgba(74, 123, 157, 0.45);
--shadow-accent: 0 4px 14px rgba(74, 123, 157, 0.25);
--shadow-input-focus: 0 0 0 3px rgba(74, 123, 157, 0.2);
--bg-frosted: rgba(242, 243, 240, 0.85);
--theme-name: "松风";
}
文档结束 — 此规格文档覆盖暖记 App 全部 14 个移动端页面 + 12 个多平台变体的完整设计定义。 任何实现偏差应以本文档为准。