核心重构 — 去除 channel 字段,引入 sourceAccount 模型: - 从 ImportedEvent、Rule、EnhancedRule、OcrRule 等接口中彻底移除 channel 字段 - rules.ts 中 resolveChannelAccount → resolveSourceAccount,规则匹配与账户解析不再依赖渠道概念 - dedup.ts 重写去重逻辑:从基于渠道匹配改为基于交易对手(counterparty)匹配,支持相同金额/交易对手/时间窗口的多级置信度判断 - transferRecognizer.ts 增加资产负债表账户校验,确保转账双方均为 Assets/Liabilities 类账户 - 全局替换影响:types、rules、ocr、adapters、adapters-migrations、所有服务层和测试 新增基础设施: - domain/constants.ts — 统一常量定义(支付包名、截图关键词、去重参数、方向检测函数 detectDirection()),消除 OCR/SMS/截图等模块的重复定义 - domain/channelConfig.ts — 渠道配置系统(支付宝/微信/银行),支持按包名和名称查找 - domain/pipelineSingleton.ts — 共享 BillPipeline 单例,解决 importStore/automationStore 的互斥锁共享问题 - domain/transactionBuilder.ts — 统一交易构建入口 buildAndSaveTransaction(),同时服务手动录入和无障碍监听 OCR 增强: - 新增账单详情页解析(parseDetailPageBill),支持支付宝/微信详情页结构化提取 - checkIsDetailPage() 识别详情页特征词,防止误提取(如"消费1次"被误读为金额) - 金额正则支持千分位逗号分隔,商户名正则改用 lookahead 边界匹配 - 时间解析支持中文格式(年月日)和跨年推断 - OcrProcessor 新增详情页路由,跳过 Layer 1 规则匹配 UI 全面升级: - 主题重设计:accent 色从绿色改为靛蓝(#4F46E5),深色模式适配 OLED 纯黑,引入 Quicksand/Caveat 字体 - 新增 commonStyles.ts 统一 chip/input/modal 等通用样式 - 首页 Bento 网格布局:净资产英雄卡片 + 定期账单/月度统计并排展示 - 报表新增周报标签页,月报整合日历视图(支持点击查看当日交易明细) - TrendLine 图表从 View 条形图重写为 SVG 贝塞尔曲线 - CategoryPicker 从水平滚动改为 4 列网格 + emoji 图标 - Button/Card 增加 press 缩放动画 管道与自动化改进: - automationPipeline.ts 新增 handleIncomingBillEvent() 实时账单处理(悬浮账单卡片 + 前台 Alert 确认) - 新增无障碍文本直解析 parseAndProcessAccessibilityTexts(),微信/支付宝详情页绕过 OCR - rules.ts 新增智能还款检测(花呗/信用卡还款自动路由)和退款视为收入处理 - metadataStore 默认规则精简为 6 条通用规则,移除约 20 条个人化硬编码规则 存储与同步: - storePersistence.ts 原子写入 + 崩溃恢复 + 重试机制 - 备份升级到 v2 格式,包含 settings 和 metadata - 同步路径统一从 mobile.bean 改为 main.bean - _layout.tsx 启动时自动迁移旧 mobile.bean 到 main.bean 其他: - 删除独立日历页面,功能合并到报表月报标签 - i18n 清理:移除渠道相关翻译,新增 50+ 翻译键 - docs/android-build-guide.md 重写为 APK 体积优化指南 - 新增 design-system/beancount-mobile/MASTER.md 设计系统文档 - 测试全面更新覆盖以上所有变更
207 lines
5.1 KiB
Markdown
207 lines
5.1 KiB
Markdown
# Design System Master File
|
|
|
|
> **LOGIC:** When building a specific page, first check `design-system/pages/[page-name].md`.
|
|
> If that file exists, its rules **override** this Master file.
|
|
> If not, strictly follow the rules below.
|
|
|
|
---
|
|
|
|
**Project:** beancount-mobile
|
|
**Generated:** 2026-07-16 16:32:57
|
|
**Category:** Personal Finance Tracker
|
|
|
|
---
|
|
|
|
## Global Rules
|
|
|
|
### Color Palette
|
|
|
|
| Role | Hex | CSS Variable |
|
|
|------|-----|--------------|
|
|
| Primary | `#1E40AF` | `--color-primary` |
|
|
| On Primary | `#FFFFFF` | `--color-on-primary` |
|
|
| Secondary | `#3B82F6` | `--color-secondary` |
|
|
| Accent/CTA | `#059669` | `--color-accent` |
|
|
| Background | `#0F172A` | `--color-background` |
|
|
| Foreground | `#FFFFFF` | `--color-foreground` |
|
|
| Muted | `#101A34` | `--color-muted` |
|
|
| Border | `rgba(255,255,255,0.08)` | `--color-border` |
|
|
| Destructive | `#DC2626` | `--color-destructive` |
|
|
| Ring | `#1E40AF` | `--color-ring` |
|
|
|
|
**Color Notes:** Trust blue + profit green on dark
|
|
|
|
### Typography
|
|
|
|
- **Heading Font:** Caveat
|
|
- **Body Font:** Quicksand
|
|
- **Mood:** handwritten, personal, friendly, casual, warm, charming
|
|
- **Google Fonts:** [Caveat + Quicksand](https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;600;700&family=Quicksand:wght@300;400;500;600;700&display=swap)
|
|
|
|
**CSS Import:**
|
|
```css
|
|
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;600;700&family=Quicksand:wght@300;400;500;600;700&display=swap');
|
|
```
|
|
|
|
### Spacing Variables
|
|
|
|
| Token | Value | Usage |
|
|
|-------|-------|-------|
|
|
| `--space-xs` | `4px` / `0.25rem` | Tight gaps |
|
|
| `--space-sm` | `8px` / `0.5rem` | Icon gaps, inline spacing |
|
|
| `--space-md` | `16px` / `1rem` | Standard padding |
|
|
| `--space-lg` | `24px` / `1.5rem` | Section padding |
|
|
| `--space-xl` | `32px` / `2rem` | Large gaps |
|
|
| `--space-2xl` | `48px` / `3rem` | Section margins |
|
|
| `--space-3xl` | `64px` / `4rem` | Hero padding |
|
|
|
|
### Shadow Depths
|
|
|
|
| Level | Value | Usage |
|
|
|-------|-------|-------|
|
|
| `--shadow-sm` | `0 1px 2px rgba(0,0,0,0.05)` | Subtle lift |
|
|
| `--shadow-md` | `0 4px 6px rgba(0,0,0,0.1)` | Cards, buttons |
|
|
| `--shadow-lg` | `0 10px 15px rgba(0,0,0,0.1)` | Modals, dropdowns |
|
|
| `--shadow-xl` | `0 20px 25px rgba(0,0,0,0.15)` | Hero images, featured cards |
|
|
|
|
---
|
|
|
|
## Component Specs
|
|
|
|
### Buttons
|
|
|
|
```css
|
|
/* Primary Button */
|
|
.btn-primary {
|
|
background: #059669;
|
|
color: white;
|
|
padding: 12px 24px;
|
|
border-radius: 8px;
|
|
font-weight: 600;
|
|
transition: all 200ms ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
opacity: 0.9;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
/* Secondary Button */
|
|
.btn-secondary {
|
|
background: transparent;
|
|
color: #1E40AF;
|
|
border: 2px solid #1E40AF;
|
|
padding: 12px 24px;
|
|
border-radius: 8px;
|
|
font-weight: 600;
|
|
transition: all 200ms ease;
|
|
cursor: pointer;
|
|
}
|
|
```
|
|
|
|
### Cards
|
|
|
|
```css
|
|
.card {
|
|
background: #0F172A;
|
|
border-radius: 12px;
|
|
padding: 24px;
|
|
box-shadow: var(--shadow-md);
|
|
transition: all 200ms ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.card:hover {
|
|
box-shadow: var(--shadow-lg);
|
|
transform: translateY(-2px);
|
|
}
|
|
```
|
|
|
|
### Inputs
|
|
|
|
```css
|
|
.input {
|
|
padding: 12px 16px;
|
|
border: 1px solid #E2E8F0;
|
|
border-radius: 8px;
|
|
font-size: 16px;
|
|
transition: border-color 200ms ease;
|
|
}
|
|
|
|
.input:focus {
|
|
border-color: #1E40AF;
|
|
outline: none;
|
|
box-shadow: 0 0 0 3px #1E40AF20;
|
|
}
|
|
```
|
|
|
|
### Modals
|
|
|
|
```css
|
|
.modal-overlay {
|
|
background: rgba(0, 0, 0, 0.5);
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
.modal {
|
|
background: white;
|
|
border-radius: 16px;
|
|
padding: 32px;
|
|
box-shadow: var(--shadow-xl);
|
|
max-width: 500px;
|
|
width: 90%;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Style Guidelines
|
|
|
|
**Style:** Dark Mode (OLED)
|
|
|
|
**Keywords:** Dark theme, low light, high contrast, deep black, midnight blue, eye-friendly, OLED, night mode, power efficient
|
|
|
|
**Best For:** Night-mode apps, coding platforms, entertainment, eye-strain prevention, OLED devices, low-light
|
|
|
|
**Key Effects:** Minimal glow (text-shadow: 0 0 10px), dark-to-light transitions, low white emission, high readability, visible focus
|
|
|
|
### Page Pattern
|
|
|
|
**Pattern Name:** Interactive Product Demo
|
|
|
|
- **CTA Placement:** Above fold
|
|
- **Section Order:** Hero > Features > CTA
|
|
|
|
---
|
|
|
|
## Anti-Patterns (Do NOT Use)
|
|
|
|
- ❌ Pure white backgrounds
|
|
|
|
### Additional Forbidden Patterns
|
|
|
|
- ❌ **Emojis as icons** — Use SVG icons (Heroicons, Lucide, Simple Icons)
|
|
- ❌ **Missing cursor:pointer** — All clickable elements must have cursor:pointer
|
|
- ❌ **Layout-shifting hovers** — Avoid scale transforms that shift layout
|
|
- ❌ **Low contrast text** — Maintain 4.5:1 minimum contrast ratio
|
|
- ❌ **Instant state changes** — Always use transitions (150-300ms)
|
|
- ❌ **Invisible focus states** — Focus states must be visible for a11y
|
|
|
|
---
|
|
|
|
## Pre-Delivery Checklist
|
|
|
|
Before delivering any UI code, verify:
|
|
|
|
- [ ] No emojis used as icons (use SVG instead)
|
|
- [ ] All icons from consistent icon set (Heroicons/Lucide)
|
|
- [ ] `cursor-pointer` on all clickable elements
|
|
- [ ] Hover states with smooth transitions (150-300ms)
|
|
- [ ] Light mode: text contrast 4.5:1 minimum
|
|
- [ ] Focus states visible for keyboard navigation
|
|
- [ ] `prefers-reduced-motion` respected
|
|
- [ ] Responsive: 375px, 768px, 1024px, 1440px
|
|
- [ ] No content hidden behind fixed navbars
|
|
- [ ] No horizontal scroll on mobile
|