Files
EmailBill/.opencode/skills/pancli-design/SKILL.md
SunCheng 1a3d0658bb
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 20s
Docker Build & Deploy / Deploy to Production (push) Successful in 8s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
fix
2026-02-04 15:31:22 +08:00

19 KiB

name, description, license, compatibility, metadata
name description license compatibility metadata
pancli-design 专业的设计技能,用于使用 pancli (pencil tools) 创建现代化、一致的 EmailBill 移动端 UI 设计 MIT Requires pencil_* tools (batch_design, batch_get, etc.)
author version generatedBy lastUpdated source
EmailBill Design Team 2.0.0 opencode 2026-02-03 .pans/v2.pen 日历设计 (亮色/暗色)

pancli-design - EmailBill UI 设计系统

专业的设计技能,用于使用 pancli (pencil tools) 创建现代化、一致的移动端 UI 设计。

何时使用此技能

总是使用此技能当:

  • 使用 pancli 创建新的 UI 界面或组件
  • 修改现有的 .pen 设计文件
  • 处理亮色/暗色主题设计
  • 为 EmailBill 项目设计移动端优先的界面

触发条件:

  • 用户提到 "画设计图"、"设计"、"UI"、"界面"、"pancli"、".pen"
  • 任务涉及 pencil_* 工具
  • 创建视觉原型或模型

核心设计原则

1. 现代移动端优先设计

核心规范:

  • 移动视口: 375px 宽度 (iPhone SE 基准)
  • 安全区域: 尊重 iOS/Android 安全区域边距
  • 交互元素最小触摸目标: 44x44px
  • 间距基于 8px 网格: 4px, 8px, 12px, 16px, 24px, 32px
  • 卡片阴影: 0 2px 12px rgba(0,0,0,0.08) (亮色模式)

反 AI 设计痕迹检查清单:

  • 使用 "Dashboard", "Lorem Ipsum" 等通用占位符
  • 使用过饱和的颜色或生硬的渐变
  • 使用装饰性字体 (Comic Sans, Papyrus)
  • 使用代码库中的真实中文业务术语
  • 使用克制的配色和柔和的阴影
  • 使用专业的系统字体

2. 统一色彩系统

色彩分层:

  • 背景层: 页面背景 → 卡片背景 → 强调背景 (三层递进)
  • 文本层: 主文本 → 次要文本 → 三级文本 (三级层次)
  • 语义色: 红色(支出/危险) → 黄色(警告) → 绿色(收入/成功) → 蓝色(主操作/信息)

颜色使用规则:

  • 始终使用语义颜色变量,避免硬编码十六进制值
  • 支出/负数统一使用红色 #FF6B6B,收入/正数使用绿色系
  • 主操作按钮统一使用蓝色 #3B82F6
  • 避免纯黑 (#000000) 或纯白 (#FFFFFF) 文本,使用柔和的色调
  • 暗色模式下减少阴影强度或完全移除
  • 详细色值参见文末"快速参考"表格

3. 排版系统

字体栈:

  • 标题: 'Bricolage Grotesque' - 用于大数值、章节标题
  • 正文: 'DM Sans' - 用于界面文本、说明
  • 数字: 'DIN Alternate' - 用于金额、数据显示
  • 备选: -apple-system, 'PingFang SC' - 系统默认字体

排版原则:

  • 使用真实中文业务术语,避免 Lorem Ipsum
  • 行高: 1.4-1.6 保证可读性
  • 数字数据使用等宽字体 (tabular-nums)
  • 字号遵循比例系统,避免任意数值
  • 详细字号比例参见文末"快速参考"表格

4. 组件库

设计原则:

  • 所有尺寸和间距基于 8px 网格系统
  • 圆角: 12px (小按钮), 16px/20px (卡片), 22px/28px (圆形按钮)
  • 交互元素最小触摸目标: 44x44px
  • 详细组件规格参见文末"快速参考"表格

卡片设计 (基于 statsCard, tCard):

统计卡片 (大卡片):
  - 背景: #F6F7F8 (亮色), #18181B (暗色)
  - 内边距: 20px
  - 圆角: 20px
  - 间距: 12px (元素之间)
  - 布局: 垂直

交易卡片 (列表卡片):
  - 背景: #F6F7F8 (亮色), #18181B (暗色)  
  - 内边距: 16px
  - 圆角: 16px
  - 间距: 14px (水平元素)
  - 高度: 自适应内容

按钮 (基于实际设计):

图标按钮 (通知按钮):
  - 尺寸: 44x44px
  - 圆角: 22px (完全圆形)
  - 背景: #F5F5F5 (亮色), #27272A (暗色)
  - 图标大小: 20px
  
标签按钮:
  - 内边距: 6px 10px / 6px 12px
  - 圆角: 12px
  - 字体: DM Sans 13px/500
  - 颜色:
    - 温暖色: #FFFBEB (亮色), #451A03 (暗色)
    - 绿色: #F0FDF4 (亮色), #064E3B (暗色)
    - 蓝色: #E0E7FF (亮色), #312E81 (暗色)

悬浮按钮 (FAB):
  - 尺寸: 56x56px
  - 圆角: 28px
  - 背景: #3B82F6
  - 描边: 4px 白色边框
  - 阴影: 提升效果

图标与文字:

图标容器:
  - 尺寸: 44x44px
  - 圆角: 22px
  - 背景: #FFFFFF (亮色), #27272A (暗色)
  - 图标: 20px (lucide 字体)
  - 颜色: #FF6B6B (星标), #FCD34D (咖啡)

章节标题:
  - 字体: Bricolage Grotesque 18px/700
  - 颜色: #1A1A1A (亮色), #F4F4F5 (暗色)
  
大数值:
  - 字体: Bricolage Grotesque 32px/800
  - 颜色: #1A1A1A (亮色), #F4F4F5 (暗色)

布局模式 (基于 Calendar 结构):

页面容器: 402px (设计视口), 垂直布局, 24px 内边距
头部区域: 水平布局, 两端对齐, 8px 24px 内边距
内容区域: 垂直布局, 24px 内边距, 12-16px 间距

关键布局原则:

  • 遵循 Flex 容器模式 (见下方"5. 布局模式")
  • 导航栏背景必须透明 (:deep(.van-nav-bar) { background: transparent !important; })
  • 尊重安全区域 (env(safe-area-inset-bottom))

5. 布局模式

页面结构 (Flex 容器):

.page-container-flex:
  - display: flex
  - flex-direction: column
  - height: 100%
  - overflow: hidden
  
  结构:
    1. van-nav-bar (固定高度)
    2. van-tabs 或 sticky-header
    3. scroll-content (flex: 1, overflow-y: auto)
    4. bottom-button 或 van-tabbar (固定)

导航栏背景透明化 (项目标准模式):

/* 所有页面统一设置 */
:deep(.van-nav-bar) {
  background: transparent !important;
}

关键要求:

  • 页面容器必须有明确的背景色
  • 必须使用 :deep() 选择器覆盖 Vant 样式
  • 必须添加 !important 标记
  • <style scoped> 块中添加此规则

安全区域处理:

/* iPhone 刘海底部内边距 */
padding-bottom: env(safe-area-inset-bottom, 0px);

/* 状态栏顶部内边距 */
padding-top: max(0px, calc(env(safe-area-inset-top, 0px) * 0.75));

固定元素:

.sticky-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--van-background-2);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
  margin: 12px;
  padding: 12px 16px;
}

6. 交互模式

触摸反馈:

  • 激活状态: 点击时 scale(0.95)
  • 涟漪效果: 使用 Vant 内置触摸反馈
  • 悬停状态: 12% 透明度叠加 (网页端)

加载状态:

van-pull-refresh:
  - 用于顶层可滚动内容
  - 最小高度: calc(100vh - nav - tabbar)
  
van-loading:
  - 容器内居中
  - 尺寸: 内联 24px, 页面 32px

空状态:

van-empty:
  - 图标: 60px 大小
  - 描述: 14px, var(--van-text-color-2)
  - 内边距: 垂直 48px

悬浮操作:

van-floating-bubble:
  - 图标大小: 24px
  - 位置: 右下角, 距底部 100px (避开 tabbar)
  - 磁吸: 贴靠 x 轴边缘

7. 数据可视化

预算进度条:

渐变逻辑:
  支出 (0% → 100%):
    - 0%:  #40a9ff (安全蓝)
    - 40%: #36cfc9 (青色过渡)
    - 70%: #faad14 (警告黄)
    - 100%: #ff4d4f (危险红)
  
  收入 (0% → 100%):
    - 0%:  #f5222d (深红 - 未开始)
    - 45%: #ffcccc (浅红)
    - 50%: #f0f2f5 (中性灰)
    - 55%: #bae7ff (浅蓝)
    - 100%: #1890ff (深蓝 - 达成)

金额显示:

.amount {
  font-family: 'DIN Alternate', system-ui;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.expense { color: var(--van-danger-color); }
.income { color: var(--van-success-color); }

图表 (如果使用):

  • 折线图: 2px 笔画, 圆角连接
  • 柱状图: 8px 圆角, 4px 间距
  • 颜色: 使用语义色阶
  • 网格线: 1px, 8% 透明度

8. 主题切换 (亮色/暗色)

实现策略:

// 自动检测系统偏好
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches
theme.value = isDark ? 'dark' : 'light'
document.documentElement.setAttribute('data-theme', theme.value)

设计文件要求:

  • 必须同时创建亮色和暗色变体
  • 使用 Vant 的主题变量 (自动切换)
  • 测试对比度: WCAG AA 最低标准 (文本 4.5:1)
  • 暗色模式适配:
    • 减少卡片阴影至 0 2px 8px rgba(0,0,0,0.24)
    • 增加边框对比度
    • 白色文本柔化至 #e5e5e5

pancli 工作流:

1. 先创建亮色主题设计
2. 复制帧用于暗色模式
3. 使用 replace_all_matching_properties 批量更新:
   - 背景颜色
   - 文本颜色
   - 边框颜色
4. 手动调整阴影和叠加
5. 命名帧: "[屏幕名称] - Light" / "[屏幕名称] - Dark"

9. 命名约定

帧名称:

格式: [模块] - [屏幕] - [变体]

示例:
  ✅ Budget - List View - Light
  ✅ Budget - Edit Dialog - Dark
  ✅ Transaction - Card Component
  ✅ Statistics - Chart Section
  
  ❌ Screen1
  ❌ Frame_Copy_2
  ❌ New Design

组件层级:

可复用组件:
  - 前缀 "Component/"
  - 示例: "Component/BudgetCard"
  
屏幕:
  - 按模块分组
  - 示例: "Budget/ListView", "Budget/EditForm"

10. 质量检查清单

设计完成前必检项:

  • 同时创建亮色和暗色主题
  • 使用真实中文业务术语 (无占位文本)
  • 交互元素 ≥ 44x44px
  • 间距遵循 8px 网格
  • 使用语义颜色变量 (非硬编码)
  • 导航栏背景透明 (:deep(.van-nav-bar))
  • 帧命名: 模块-屏幕-变体 格式
  • 可复用组件标记 reusable: true
  • 两种主题截图验证

无障碍标准:

  • 正文对比度 ≥ 4.5:1
  • 大文本对比度 ≥ 3:1 (18px+)
  • 触摸目标间距 ≥ 8px

PANCLI 工作流程

阶段 1: 设置与风格选择

// 1. 获取编辑器状态
pencil_get_editor_state(include_schema: true)

// 2. 获取设计指南
pencil_get_guidelines(topic: "landing-page") // 或 "design-system"

// 3. 选择合适的风格指南
pencil_get_style_guide_tags() // 获取可用标签

// 4. 使用标签获取风格指南
pencil_get_style_guide(tags: [
  "mobile",        // 必需
  "webapp",        // 类应用界面
  "modern",        // 简洁, 现代
  "minimal",       // 避免杂乱
  "professional",  // 商业环境
  "blue",          // 主色提示
  "fintech"        // 如果可用
])

阶段 2: 创建亮色主题设计

// 5. 读取现有组件 (如果有)
pencil_batch_get(
  filePath: "designs/emailbill.pen",
  patterns: [{ reusable: true }],
  readDepth: 2
)

// 6. 创建亮色主题屏幕
pencil_batch_design(
  filePath: "designs/emailbill.pen",
  operations: `
    screen=I(document, {
      type: "frame",
      name: "Budget - List View - Light",
      width: 375,
      height: 812,
      fill: "#FFFFFF",
      layout: "vertical",
      placeholder: true
    })
    
    navbar=I(screen, {
      type: "frame",
      name: "Navbar",
      width: "fill_container",
      height: 44,
      fill: "transparent",
      layout: "horizontal",
      padding: [12, 16, 12, 16]
    })
    
    title=I(navbar, {
      type: "text",
      content: "预算管理",
      fontSize: 16,
      fontWeight: "600",
      textColor: "#1A1A1A"
    })
    
    // ... 更多操作
  `
)

阶段 3: 创建暗色主题变体

// 7. 复制亮色主题帧
pencil_batch_design(
  operations: `
    darkScreen=C("light-screen-id", document, {
      name: "Budget - List View - Dark",
      positionDirection: "right",
      positionPadding: 48
    })
  `
)

// 8. 批量替换暗色主题颜色
pencil_replace_all_matching_properties(
  parents: ["dark-screen-id"],
  properties: {
    fillColor: [
      { from: "#FFFFFF", to: "#09090B" },   // 页面背景
      { from: "#F6F7F8", to: "#18181B" },   // 卡片背景
      { from: "#F5F5F5", to: "#27272A" }    // 边框
    ],
    textColor: [
      { from: "#1A1A1A", to: "#F4F4F5" },   // 主文本
      { from: "#6B7280", to: "#A1A1AA" },   // 次要
      { from: "#9CA3AF", to: "#71717A" }    // 三级
    ]
  }
)

// 9. 手动调整暗色模式阴影 (如需要)
pencil_batch_design(
  operations: `
    U("dark-card-id", {
      shadow: {
        x: 0,
        y: 2,
        blur: 8,
        color: "rgba(0,0,0,0.24)"
      }
    })
  `
)

阶段 4: 验证

// 10. 对两种主题截图
pencil_get_screenshot(nodeId: "light-screen-id")
pencil_get_screenshot(nodeId: "dark-screen-id")

// 11. 检查布局问题
pencil_snapshot_layout(
  parentId: "light-screen-id",
  problemsOnly: true
)

// 12. 验证所有唯一属性
pencil_search_all_unique_properties(
  parents: ["light-screen-id"],
  properties: ["fillColor", "textColor", "fontSize"]
)

代码库实际示例

示例 1: 预算卡片组件

组件结构:
  BudgetCard (375x120px)
    ├─ CardBackground (#ffffff, 16px 圆角, 阴影)
    ├─ HeaderRow (水平布局)
    │   ├─ CategoryName (16px, 600 粗细)
    │   └─ PeriodLabel (12px, 次要颜色)
    ├─ ProgressBar (基于比例渐变)
    │   └─ ProgressFill (高度: 8px, 圆角: 4px)
    ├─ AmountRow (水平布局, 两端对齐)
    │   ├─ CurrentAmount (DIN, 18px, 危险色)
    │   ├─ LimitAmount (DIN, 14px, 次要)
    │   └─ RemainingAmount (DIN, 14px, 成功色)
    └─ FooterActions (可选, 储蓄按钮)

pancli 实现:

card=I(parent, {
  type: "frame",
  name: "BudgetCard",
  width: "fill_container",
  height: 120,
  fill: "#ffffff",
  cornerRadius: [16, 16, 16, 16],
  shadow: { x: 0, y: 2, blur: 12, color: "rgba(0,0,0,0.08)" },
  stroke: { color: "#ebedf0", thickness: 1 },
  padding: [16, 16, 16, 16],
  layout: "vertical",
  gap: 12,
  placeholder: true
})

header=I(card, {
  type: "frame",
  layout: "horizontal",
  width: "fill_container",
  height: "hug_contents"
})

categoryName=I(header, {
  type: "text",
  content: "日常开销",
  fontSize: 16,
  fontWeight: "600",
  textColor: "#323233"
})

// 带渐变的进度条
progressBar=I(card, {
  type: "frame",
  width: "fill_container",
  height: 8,
  fill: "#f0f0f0",
  cornerRadius: [4, 4, 4, 4]
})

progressFill=I(progressBar, {
  type: "frame",
  width: "75%", // 75% 进度示例
  height: 8,
  fill: "linear-gradient(90deg, #40a9ff 0%, #faad14 100%)",
  cornerRadius: [4, 4, 4, 4]
})

示例 2: 带日期选择器的固定头部

固定头部模式 (来自 BudgetView):
  ├─ 位置: sticky, top: 0
  ├─ 背景: var(--van-background-2)
  ├─ 圆角: 12px
  ├─ 阴影: 0 2px 8px rgba(0,0,0,0.04)
  ├─ 内边距: 12px 16px
  ├─ 内容: "2024年1月" + 下拉箭头图标

示例 3: 滑动删除列表项

van-swipe-cell 模式:
  ├─ 内容: BudgetCard 组件
  ├─ 右侧操作: 删除按钮
  │   ├─ 宽度: 60px
  │   ├─ 背景: var(--van-danger-color)
  │   ├─ 文本: "删除"
  │   └─ 全高 (100%)

避免的反模式

不要这样做:

// 通用 AI 生成内容
title=I(navbar, {
  type: "text",
  content: "Dashboard", // ❌ 使用 "预算管理" 代替
  fontSize: 20,         // ❌ 按字号比例使用 16px
  fontWeight: "bold"    // ❌ 使用数字值 600
})

// 不一致的间距
card=I(parent, {
  padding: [15, 13, 17, 14] // ❌ 使用 8px 网格: [16, 16, 16, 16]
})

// 硬编码颜色而非语义
amount=I(card, {
  textColor: "#ff0000" // ❌ 使用 var(--van-danger-color) 或 "#ee0a24"
})

// 缺少暗色模式
// ❌ 只创建亮色主题没有暗色变体

// 糟糕的命名
frame=I(document, {
  name: "Frame_123" // ❌ 使用 "Budget - List View - Light"
})

应该这样做:

// 真实业务术语
title=I(navbar, {
  type: "text",
  content: "预算管理",
  fontSize: 16,
  fontWeight: "600",
  textColor: "#323233"
})

// 一致的 8px 网格间距
card=I(parent, {
  padding: [16, 16, 16, 16],
  gap: 12
})

// 语义颜色变量
amount=I(card, {
  textColor: "#ee0a24", // 一致的危险色
  fontFamily: "DIN Alternate"
})

// 总是创建两种主题
lightScreen=I(document, { name: "Budget - List - Light" })
darkScreen=C(lightScreen, document, { 
  name: "Budget - List - Dark",
  positionDirection: "right"
})

// 清晰的描述性名称
card=I(parent, {
  name: "BudgetCard",
  reusable: true
})

委派与任务管理

使用此技能时:

// 委派设计任务时加载此技能
delegate_task(
  category: "visual-engineering",
  load_skills: ["pancli-design", "frontend-ui-ux"],
  description: "创建预算列表屏幕设计",
  prompt: `
    任务: 为 EmailBill 应用创建移动端预算列表屏幕设计
    
    预期结果:
    - 375x812px 亮色主题设计
    - 暗色主题变体 (复制并适配)
    - 可复用的 BudgetCard 组件
    - 两种主题的截图验证
    
    必需工具:
    - pencil_get_style_guide_tags
    - pencil_get_style_guide
    - pencil_batch_design
    - pencil_batch_get
    - pencil_replace_all_matching_properties
    - pencil_get_screenshot
    
    必须做:
    - 严格遵循 pancli-design 技能指南
    - 使用真实中文业务术语 (预算, 账单, 分类)
    - 创建亮色和暗色两种主题
    - 使用 8px 网格间距系统
    - 遵循 Vant UI 组件模式
    - 使用 模块-屏幕-变体 格式命名帧
    - 使用语义颜色变量
    - 数字显示应用 DIN Alternate
    - 导航栏背景必须设置为透明 (:deep(.van-nav-bar) { background: transparent !important; })
    - 截图验证
    
    不得做:
    - 使用 Lorem Ipsum 或占位文本
    - 只创建亮色主题没有暗色变体
    - 使用任意间距 (必须遵循 8px 网格)
    - 硬编码颜色 (使用语义变量)
    - 使用通用 "Dashboard" 标签
    - 跳过截图验证
    - 创建名为 "Frame_1", "Copy" 等的帧
    
    上下文:
    - 移动视口: 375px 宽度
    - 设计系统: 基于 Vant UI
    - 配色方案: #1989fa 主色, #ee0a24 危险, #07c160 成功
    - 字体: 中文系统默认, 数字 DIN Alternate
    - designs/emailbill.pen 中的现有组件 (用 batch_get 检查)
  `,
  run_in_background: false
)

快速参考

颜色面板 (基于实际 v2.pen 设计):

名称 亮色 暗色 用途
页面背景 #FFFFFF #09090B 页面背景
卡片背景 #F6F7F8 #18181B 卡片表面
强调背景 #F5F5F5 #27272A 按钮, 图标容器
主文本 #1A1A1A #F4F4F5 主要文本
次要文本 #6B7280 #A1A1AA 次要文本
三级文本 #9CA3AF #71717A 三级文本
主色 #3B82F6 #3B82F6 操作, FAB
红色 #FF6B6B #FF6B6B 支出, 警告
黄色 #FCD34D #FCD34D 警告
绿色 #F0FDF4 #064E3B 收入标签
蓝色 #E0E7FF #312E81 信息标签

排版比例:

用途 字体 大小 粗细
大数值 Bricolage Grotesque 32px 800
页面标题 DM Sans 24px 500
章节标题 Bricolage Grotesque 18px 700
正文 DM Sans 15px 600
说明 DM Sans 13px 500
微型标签 DM Sans 12px 600

组件规格:

  • 容器内边距: 24px (主区域), 20px (卡片), 16px (小卡片)
  • 间距比例: 2px, 4px, 8px, 12px, 14px, 16px
  • 圆角: 12px (标签), 16px/20px (卡片), 22px/28px (圆形按钮)
  • 图标: 20px
  • 图标按钮: 44x44px
  • FAB 按钮: 56x56px
  • 触摸目标: 最小 44x44px
  • 设计视口: 402px 宽度

版本: 2.0.0
最后更新: 2026-02-04
维护者: EmailBill 设计团队