mcpField
P
pencilplaybook

pencilplaybook

github.com/stevembarclay设计与 UI5361 次安装31 周前更新
代码仓库

关于 pencilplaybook

pencilplaybook 是用于 Pencil 界面设计的技能,通过配置流程和可复用布局脚手架指导屏幕制作,适合设计应用及营销页面的设计人员。它还包含画布尺寸检查、设计指南和品牌变量工作流。

主要功能

  1. 01配置与入门说明
  2. 02九种可复用布局脚手架
  3. 03画布尺寸验证
  4. 04设计指南与令牌工作流

适用场景

  1. 01搭建应用仪表盘或数据表格
  2. 02按 390×844px 设计移动屏幕
  3. 03设计营销页面并在 390px 宽度检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/stevembarclay/pencilplaybook --skill pencilplaybook

安装后在 Claude Code 中输入/pencilplaybook确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
CHANGELOG.md
LICENSE
onboarding.md
README.md
setup.md
.claude/skills/best-in-world-strategy/references/
question-bank.md
.claude/skills/skill-creator/
LICENSE.txt
.claude/skills/skill-creator/scripts/
init_skill.py
quick_validate.py
package_skill.py
presets/
grove.json
ember.json
material.json
midnight.json
bloom.json
volt.json
minimal.json
references/
tool-reference.md

详细介绍

Pencil Pro

主要解析规则

首次使用前必须配置此技能。

如果用户说“运行 PencilPlaybook 设置向导”或要求设置或配置 PencilPlaybook: → 阅读 .claude/skills/pencilplaybook/setup.md 并严格按照其中的说明操作。

如果用户说“使用 PencilPlaybook 构建我的第一个屏幕”或要求开始设计: → 阅读 .claude/skills/pencilplaybook/onboarding.md 并严格按照其中的说明操作。

已配置的分辨率:(运行设置以配置)

如果现有 .pen 文件中的屏幕根节点与已配置的分辨率不匹配,请在编辑前指出。若画布尺寸有误,切勿直接在其上构建而不说明偏差。

常见例外 — 营销页面: 无论应用分辨率如何,均按 1440px 设计。营销页面会在各种浏览器宽度下展示——按 1440px 设计,并在 390px 下验证。


会话启动(每次 Pencil 会话)

1. get_editor_state()                           — check active document and selection
2. open_document("path/to/your-file.pen")       — open target file
3. get_guidelines(topic="web-app")              — load design guidelines
4. set_variables(<token map below>)             — inject brand tokens
5. get_variables()                              — confirm tokens stored
6. snapshot_layout()                            — verify canvas dimensions

你的 token 映射 — 在每次会话开始时,使用此对象运行 set_variables。变量可能不会在不同的 Claude Code 会话之间保留。

{
  "color-primary":        "YOUR_HEX",
  "color-primary-dark":   "YOUR_HEX",
  "color-accent":         "YOUR_HEX",
  "color-background":     "YOUR_HEX",
  "color-surface":        "YOUR_HEX",
  "color-border":         "YOUR_HEX",
  "color-text":           "YOUR_HEX",
  "color-text-muted":     "YOUR_HEX",
  "color-success":        "YOUR_HEX",
  "color-warning":        "YOUR_HEX",
  "color-error":          "YOUR_HEX",
  "font-sans":            "YOUR_FONT",
  "font-mono":            "YOUR_FONT",
  "font-serif":           "YOUR_FONT",
  "spacing-card":         "24",
  "spacing-gap-sm":       "8",
  "spacing-gap-md":       "16",
  "spacing-gap-lg":       "24",
  "spacing-gap-xl":       "32",
  "content-max-width":    "YOUR_VALUE",
  "sidebar-width":        "YOUR_VALUE"
}

运行 set_variables 后,调用 get_variables() 确认所有 token 均已存储。


脚手架脚本

九个脚手架脚本,涵盖最常见的布局类型。使用前先运行设置向导,填入下方的尺寸和颜色值。


脚手架 A — 应用仪表盘

指标、KPI、活动动态、监控

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG", display:"flex", flexDirection:"column"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:32})
statsBar=I("pageArea", {name:"StatsBar", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:80, bg:"STATS_BG", display:"flex", alignItems:"center", gap:24, px:32})
contentWrap=I("pageArea", {name:"ContentWrap", y:144, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_A, display:"flex", justifyContent:"center", p:32})
contentInner=I("contentWrap", {name:"ContentInner", width:SCAFFOLD_CONTENT_MAX, display:"flex", flexDirection:"column", gap:24})

脚手架完成后:运行 snapshot_layout(),确认 pageArea.width 和 contentInner.width 正确。


脚手架 B — 应用列表 / 队列

表格、资源库、队列、用户管理

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:32})
commandStrip=I("pageArea", {name:"CommandStrip", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:52, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", gap:16, px:32})
tableWrap=I("pageArea", {name:"TableWrap", y:116, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_B, display:"flex", justifyContent:"center", px:32, pt:24})
tableInner=I("tableWrap", {name:"TableInner", width:SCAFFOLD_CONTENT_MAX, display:"flex", flexDirection:"column", gap:0})
tableHeader=I("tableInner", {name:"TableHeader", width:SCAFFOLD_CONTENT_MAX, height:40, bg:"TABLE_HEADER_BG", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center"})

脚手架 C — 应用详情 / 审核

双面板详情视图、审核流程、并排布局

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR"})
actionBar=I("pageArea", {name:"ActionBar", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:56, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR"})
contentWrap=I("pageArea", {name:"ContentWrap", y:120, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_C, display:"flex", justifyContent:"center"})
contentInner=I("contentWrap", {name:"ContentInner", width:SCAFFOLD_CONTENT_MAX, height:SCAFFOLD_CONTENT_HEIGHT_C, display:"flex", gap:0})
leftPanel=I("contentInner", {name:"LeftPanel", width:SCAFFOLD_LEFT_PANEL, height:SCAFFOLD_CONTENT_HEIGHT_C, bg:"SURFACE_COLOR", borderRight:"1px solid BORDER_COLOR"})
rightPanel=I("contentInner", {name:"RightPanel", width:SCAFFOLD_RIGHT_PANEL, height:SCAFFOLD_CONTENT_HEIGHT_C, bg:"PAGE_BG", p:24, display:"flex", flexDirection:"column", gap:20})

注意:左右分栏默认约为 40/60。根据功能调整——常见比例:40/60、38/62、50/50。


脚手架 D — 营销页面

落地页、产品页——无论应用画布尺寸如何,始终为 1440px 宽

navbar=I("root", {name:"Navbar", width:1440, height:72, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:80})
heroSection=I("root", {name:"HeroSection", y:72, width:1440, height:600, bg:"HERO_BG", display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center"})
heroContent=I("heroSection", {name:"HeroContent", width:SCAFFOLD_MARKETING_CONTENT_MAX, display:"flex", flexDirection:"column", alignItems:"center", gap:24})
section1=I("root", {name:"Section1", y:672, width:1440, height:480, bg:"SURFACE_COLOR", display:"flex", flexDirection:"column", alignItems:"center", py:80})
section1Content=I("section1", {name:"Section1Content", width:SCAFFOLD_MARKETING_CONTENT_MAX})

营销页面采用移动优先设计。按 1440px 设计,并在交付前验证 390px 宽度下的布局。


脚手架 E — 模态框 / 对话框

确认操作、破坏性操作、快速编辑表单、侧边预览面板

先运行脚手架 A、B 或 C。然后在 pageArea 上叠加此模态框——不要将其插入根节点。

backdrop=I("pageArea", {name:"ModalBackdrop", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"rgba(0,0,0,0.48)", display:"flex", alignItems:"center", justifyContent:"center"})
modal=I("backdrop", {name:"Modal", width:480, bg:"SURFACE_COLOR", borderRadius:8, border:"1px solid BORDER_COLOR", display:"flex", flexDirection:"column", overflow:"hidden"})
modalHeader=I("modal", {name:"ModalHeader", height:56, px:24, display:"flex", alignItems:"center", justifyContent:"space-between", borderBottom:"1px solid BORDER_COLOR"})
modalBody=I("modal", {name:"ModalBody", px:24, py:20, display:"flex", flexDirection:"column", gap:16})
modalFooter=I("modal", {name:"ModalFooter", height:60, px:24, display:"flex", alignItems:"center", justifyContent:"flex-end", gap:12, borderTop:"1px solid BORDER_COLOR"})

脚手架完成后:运行 snapshot_layout(),确认模态框可见且居中。根据使用场景调整模态框宽度:380px(紧凑型确认框)、480px(标准表单)、600px(宽表单)、720px(详情 / 预览)。


脚手架 F — 向导 / 步骤条

多步骤表单、引导流程、设置步骤、结账

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:32})
stepperBar=I("pageArea", {name:"StepperBar", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:60, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"center"})
contentWrap=I("pageArea", {name:"ContentWrap", y:124, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_F, display:"flex", justifyContent:"center", px:32, pt:32})
contentInner=I("contentWrap", {name:"ContentInner", width:640, display:"flex", flexDirection:"column", gap:24})
actionFooter=I("pageArea", {name:"ActionFooter", y:SCAFFOLD_WIZARD_FOOTER_Y, width:SCAFFOLD_PAGE_AREA_WIDTH, height:72, bg:"SURFACE_COLOR", borderTop:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"space-between", px:32})

注意:ContentInner 默认宽 640px,适用于专注的单列表单。在 ActionFooter 中将返回按钮放在左侧、下一步 / 提交按钮放在右侧(justifyContent:"space-between")。


脚手架 G — 移动屏幕

390×844px(iPhone 14 标准尺寸)。所有移动屏幕均使用此脚手架——尺寸为硬编码,无需设置值。

statusBar=I("root", {name:"StatusBar", width:390, height:44, bg:"PAGE_BG"})
navBar=I("root", {name:"NavBar", y:44, width:390, height:56, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:16})
scrollContent=I("root", {name:"ScrollContent", y:100, width:390, height:688, bg:"PAGE_BG", display:"flex", flexDirection:"column", overflow:"hidden"})
contentPad=I("scrollContent", {name:"ContentPad", width:390, display:"flex", flexDirection:"column", gap:16, px:16, pt:16})
bottomNav=I("root", {name:"BottomNav", y:788, width:390, height:56, bg:"SURFACE_COLOR", borderTop:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"space-around"})

注意:如果不显示系统界面,请移除 statusBar 并将 navBar.y 设为 0。对于没有标签导航的应用,请移除 bottomNav。此脚手架中的触控目标必须至少为 44×44px。


脚手架 H — 表单 / 数据录入

设置页、个人资料编辑、大量数据录入——单列居中表单

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"space-between", px:32})
formWrap=I("pageArea", {name:"FormWrap", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_H, display:"flex", justifyContent:"center", px:32, pt:32})
formInner=I("formWrap", {name:"FormInner", width:600, display:"flex", flexDirection:"column", gap:28})
formSection=I("formInner", {name:"FormSection1", display:"flex", flexDirection:"column", gap:16})
formActions=I("formInner", {name:"FormActions", display:"flex", gap:12, justifyContent:"flex-end"})

注意:FormInner 默认宽 600px。简单流程使用 480px,宽版双列布局使用 800px。在 formInner 内添加更多 FormSection 节点,以对相关字段分组。


脚手架 I — 空状态 / 引导步骤

无数据视图、首次使用提示、功能发现、空白占位屏幕

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR"})
emptyCenter=I("pageArea", {name:"EmptyCenter", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_H, display:"flex", alignItems:"center", justifyContent:"center"})
emptyContent=I("emptyCenter", {name:"EmptyContent", width:400, display:"flex", flexDirection:"column", alignItems:"center", gap:20})
illustrationArea=I("emptyContent", {name:"IllustrationArea", width:200, height:160, borderRadius:12, bg:"SURFACE_COLOR", border:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"center"})
textStack=I("emptyContent", {name:"TextStack", width:400, display:"flex", flexDirection:"column", alignItems:"center", gap:8})
emptyActions=I("emptyContent", {name:"EmptyActions", display:"flex", gap:12})

注意:将 IllustrationArea 替换为 G("illustrationArea", "ai", "your prompt") 以生成插图。空状态文案应简短:一个标题(16–18px)、一行辅助说明(14px,弱化显示)、一个主要 CTA。


核心工作流

工作流 1:画布考古

适用场景:“这个 .pen 文件里有什么?”或准备编辑一个你最近没处理过的文件时。

1. open_document("path/to/file.pen")
2. get_editor_state()                         — get root node IDs
3. batch_get(patterns=["*"])                  — read full node tree
4. snapshot_layout()                          — see computed dimensions

阅读 batch_get 的输出,梳理:有哪些屏幕、各自的尺寸、正在使用哪些令牌,以及哪些元素的命名清晰、哪些不清晰。先在脑中建立模型,再进行任何更改。

**检查画布尺寸:**任何与已配置分辨率不符的屏幕,都是旧版画布,或是为其他目标而构建的。请记录下来。如果要重新设计,请使用上方的脚手架,在目标分辨率下重建。


工作流 2:设计令牌传播

适用场景:品牌颜色或字体发生变化,需要在现有 .pen 文件中同步更新时。

步骤 1 — 检查当前值:

search_all_unique_properties(parentIds=["root"])

查找所有旧令牌值的实例。

步骤 2 — 替换:

replace_all_matching_properties(
  parentIds=["root"],
  matchProperty="bg",
  matchValue="#OLD_VALUE",
  newValue="#NEW_VALUE"
)

对使用已更改令牌的每种属性类型(bg、color、borderColor 等)分别运行一次。

步骤 3 — 截图验证:

get_screenshot(nodeId="[root or key screen id]")

常见的令牌传播场景:

  • 颜色更改:分别替换 bg、color、borderColor、fill
  • 字体更改:替换所有文本节点中的 fontFamily
  • 间距更改:替换特定的 gap、p、px、py 值——请谨慎操作;许多元素可能出于不同的结构原因而共用相同的数值

工作流 3:画布空间管理

适用场景:向现有 .pen 文件添加新屏幕时。

find_empty_space_on_canvas(
  direction="right",
  desiredWidth=SCAFFOLD_CANVAS_WIDTH,
  desiredHeight=SCAFFOLD_CANVAS_HEIGHT
)

将返回的 x/y 坐标用作新屏幕根框架的位置。

多屏幕 .pen 文件的约定:

  • 屏幕从左到右排列,每列放置一个屏幕
  • 屏幕之间的水平间距约为 120px
  • 同一屏幕的相关状态纵向堆叠,间距约为 80px
  • 屏幕命名格式:"Screen N — [Name] ([state])"——例如 "Screen 2 — User Profile (edit mode)"

工作流 4:获取风格指南(新页面类型)

适用场景:构建应用尚未设计过的页面类型时。

1. get_style_guide_tags()
2. get_style_guide(tags=["enterprise", "dashboard", "minimal", "professional"])

风格指南提供灵感——如果与设计系统存在风格冲突,以设计系统为准。保留:构图规范、留白模式、数据密度处理方式。舍弃:任何与既定视觉语言冲突的内容。


工作流 5:批量检查属性

适用场景:检查 .pen 文件的一致性,或准备替换令牌时。

search_all_unique_properties(
  parentIds=["root"],
  propertyNames=["bg", "color", "fontFamily", "fontSize", "gap"]
)

用于查找本应使用令牌的硬编码十六进制值、异常字体大小,或破坏网格的间距值。


工作流 6:版本快照(保护你的工作)

适用场景:进行重大重新设计、重构或切换文件之前。

提示词模板:

Using PencilPlaybook, create a version snapshot comment at the top of the
current canvas. Include: current date/time, list of all screens, active
design tokens summary, and a short note of what is about to change.

这相当于一个轻量级撤销检查点,有助于在多个 .pen 文件之间保持一致性。请在以下操作前运行:

  • 在大型文件中传播令牌
  • 进行结构重构(更改布局、拆分面板)
  • 移交给其他会话或协作者

工具参考

快速查阅——完整参数文档见 references/tool-reference.md。

工具适用场景
get_editor_state每次会话开始时
open_document打开 .pen 文件;输入 "new" 可新建空白画布
get_guidelines加载设计规则(应用屏幕使用 topic="web-app")
get_style_guide_tags查看可用的灵感标签
get_style_guide获取新页面类型的灵感
batch_get读取节点树——用于画布考古
batch_design创建、更新、复制、移动、删除节点
snapshot_layout每次搭建脚手架后验证计算所得的尺寸
get_screenshot每个主要构建步骤后进行视觉检查
get_variables检查当前令牌状态
set_variables注入品牌令牌
find_empty_space_on_canvas放置新屏幕,避免重叠
search_all_unique_properties替换令牌前检查所有值
replace_all_matching_properties批量替换令牌
export_nodes开发人员接手前导出为 PNG/PDF

屏幕命名与版本控制

文件内命名:

  • "Screen N — [Feature] ([state])"
  • "Screen 1 — Dashboard (empty)" / "Screen 1 — Dashboard (populated)"
  • 迭代:添加后缀 [v2 post-feedback] — 不要创建新文件

迭代时切勿创建新的 .pen 文件。 将带版本号的屏幕添加到同一文件中。

文件命名:

mockups/<feature>-v1.pen        — initial design
mockups/<feature>-redesign.pen  — full redesign (significant divergence)

与利益相关方分享后,避免重命名 .pen 文件——这会导致交接文档中的引用失效。


感知设计默认值

用于在 Pencil 中构建组件的速查表。这些默认值有科学依据——除非你的设计系统另有规定,否则请使用这些默认值。

字体排印
属性尺寸范围默认值原因
字间距56px+(展示文字)−0.03em大字号下字腔看起来更开阔
字间距32–48px(标题)−0.015em适度收紧
字间距14–18px(正文)0(正常)字体通常针对这一范围进行了优化
字间距10–12px(说明文字)+0.015em小字号下字腔会变窄
行高正文至少为 1.5×WCAG SC 1.4.12
行高标题1.1–1.2×更紧凑,提升视觉密度
行长正文45–75 个字符(65ch 为最佳)Baymard Institute
最小字号任意文字10px小于 10px 时,屏幕上的文字难以辨认
颜色
属性默认值原因
禁用状态不透明度40%50% 会产生有竞争感的虚影;40% 则能充分弱化。(MD3,Workday)
悬停亮度变化至少 8%在大多数显示器上,低于 8% 时难以察觉。(NNGroup)
深色表面正文颜色#E2E8F0 或 #F1F5F9在非常深的背景上使用纯白会产生光晕。标题可使用白色。(APCA)
非文本对比度至少 3:1图标、边框、表单控件与相邻颜色之间的对比度。(WCAG 2.2 SC 1.4.11)
文本对比度至少 4.5:1正文。大号文字(24px+ 或 18.66px+ 粗体):3:1。(WCAG AA)
动效
属性默认值原因
最短时长100ms低于此时长,动效难以察觉——应直接切换
标准时长200–300ms适用于大多数 UI 过渡
最长时长400ms仅用于复杂编排。切勿超过 500ms。
进入缓动cubic-bezier(0, 0, 0.2, 1)减速——让进入的元素平稳停下
退出缓动cubic-bezier(0.4, 0, 1, 1)加速——让离开的元素迅速消失
标准缓动cubic-bezier(0.4, 0, 0.2, 1)用于屏幕内重新定位
间距
属性默认值原因
触控目标(移动设备)44×44pxApple HIG 的工程目标
触控目标(桌面设备最小值)24×24pxWCAG 2.2 SC 2.5.8 的最低要求
按钮高度(主要按钮)40–44px提供舒适的点击目标
按钮高度(紧凑型)32px适用于密集型 UI 和次要操作
边框圆角(卡片)最大 8px>8px 会显得偏消费级或随意
边框圆角(按钮)6px对应外侧 8px 圆角、内缩 2px 后的卡片内侧圆角
焦点环偏移2px圆环半径 = 组件圆角 + 2px(WCAG 2.2 SC 2.4.13)
图标
属性默认值原因
最小尺寸16×16px小于 16px 时,图标在 1x 密度下会失去清晰度
描边粗细1.5px(标准),2px(强调)与文本的粗细层级保持一致
视觉对齐圆形图标下移 1px相较于方形边界,圆形看起来会悬浮
触控目标内边距使用透明点击区域扩展至 44×44px图标视觉尺寸可以是 20px,点击目标为 44px

常见错误

错误修正方法
未配置的 SKILL.md首次使用前运行 run the PencilPlaybook setup wizard
使用了错误的分辨率构建每次搭建脚手架后都检查 snapshot_layout()
使用硬编码的十六进制值,而非令牌每次会话都先运行 set_variables
将所有屏幕放在一个超大画板中为每个屏幕分别创建画板。使用 find_empty_space_on_canvas 进行布局
凭感觉替换令牌使用 search_all_unique_properties + replace_all_matching_properties
凭记忆描述 .pen 文件内容先运行 batch_get。绝不要臆测文件内容
脚手架搭建后跳过 snapshot_layout在你基于损坏的结构继续构建前,发现 0px 尺寸问题
单次 batch_design 调用超过 25 个操作将大型构建拆分为多次调用

边缘情况

Claude 忽略你的令牌时

如果某项设计决策与配置的令牌映射不符(颜色错误、字体大小随意、擅自使用十六进制值):

  1. 明确指出:“这个颜色不在令牌映射中。请使用会话开始时设置的变量中的 color-primary。”
  2. 运行 get_variables(),确认令牌确实已设置——如果映射为空,说明跳过了 set_variables。重新运行会话启动流程。
  3. 运行 search_all_unique_properties(parentIds=["root"], propertyNames=["bg","color"]),找出混入的硬编码值,然后批量替换。

如果 Claude 仍在擅自编造值:暂停,在提示词中大声重读 SKILL.md——“使用 PencilPlaybook,[指令]”——重新锚定技能上下文。


从损坏的脚手架中恢复

症状:snapshot_layout() 显示某个节点的 width: 0 或 height: 0。

原因:几乎总是以下情况之一:

  • 弹性容器没有明确尺寸,且没有能迫使其扩展的子项
  • 父级没有明确宽度,子项却在其中使用了 width:"fill_container"
  • 绝对定位节点的 x/y 坐标冲突或缺失

修复步骤:

1. snapshot_layout()                          — identify the 0px node
2. batch_get(nodeIds=["[broken-node-id]"])    — inspect its properties
3. U("[broken-node-id]", {width: N, height: N}) — add explicit dimensions
4. snapshot_layout()                          — confirm fixed before continuing

如果脚手架损坏严重,无法修补:删除根画板(D("frame-id")),使用 get_editor_state() 确认状态干净,然后从头重新搭建脚手架。


多画布项目

在同一会话中处理多个 .pen 文件时:

  • 令牌不会在文件之间保留。 每次调用 open_document 都需要重新运行 set_variables。将令牌映射保存在 SKILL.md 中,并在每次打开文件时粘贴。
  • 编辑每个文件前都运行 Canvas Archaeology。 绝不要凭记忆臆测文件结构——始终先运行 batch_get(patterns=["*"])。
  • 一次处理一个文件。 不要交错对两个已打开文件调用 batch_design。完成文件 A 的工作后,再打开文件 B。
  • 确保跨文件一致性。 如果某个组件出现在多个文件中,请使用完全相同的节点名称。名称不一致会导致令牌传播和审计脚本不可靠。

评论

支持 Markdown