impeccable 的 Craft Floor(工艺底线):方向定稿后、动手改 UI 之前的机械核查清单与禁用模式全集
【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable
本文讲解 impeccable 技能包(本仓库根目录
skill/SKILL.src.md及其多编辑器分发副本)中的核心参考文档 Craft Floor。它回答一个几乎所有 AI 生成界面都会翻车的问题:当视觉方向已经拍板、模型正要开始写代码时,靠什么把产出钉在“像个专业设计师交付的作品”这条底线之上?读完你会掌握 impeccable 的“Verify 九项核查”与“Refuse 禁用清单”的完整内容、它们的数值与判断规则、以及它们与设计检测器 Hook、Finish Reviewer 子代理之间的分工,能直接把这套底线套用到你自己的 AI 前端生成流程中。
Craft Floor 是 impeccable 在“方向已定、开始动手”这个转折点上加载的一份质量契约。SKILL.md 的 Setup 流程把它列为编辑 UI 前必读的第三步,而本仓库的 skill-behavior 测试会用真实 LLM 走一遍工作流,断言模型确实在写代码前读到了craft-floor.md——比如文档记载bolder refinement场景中模型依次读取bolder.md、craft-floor.md与当前页面文件后才动手。这篇文章即围绕该文档展开,把“底线”两个字拆成可执行、可核对的条目,并用仓库里的 Hook、检测器与评审 Agent 印证它在整条流水线中的位置。
Craft Floor 是什么:加载时机、优先级与“不宣布清单”
先看文档开头的三句总纲(原文 craft-floor.md):
在方向定稿之后加载它,并且在动手构建时不要宣布这份清单。一份已固定的简报(pinned brief)或已承诺的视觉世界(committed visual world)优先于这里的一切;你自己的习惯不优先于它。当设计 Hook 处于激活状态时,它已经在你编辑的同时强制实施了下面这些机械检查:去处理它的发现,而不是把每一条规则重新审计一遍。
这里规定了三个关键语义:
- 加载时机:仅在“方向(direction)已定稿”之后、真正开始编辑 UI 之前加载。SKILL.md 明确“Do not load it for planning-only work”——纯规划阶段不许读它,因为它携带的是执行纪律而非规划工具。
- 静默执行:加载后不要向用户宣布清单。清单是内化的操作底线,不是用来展示的仪式;宣布它等于把工艺降格为表演。
- 优先级(overrides):优先级从高到低是“已固定的简报/已承诺的视觉世界 > 本清单 > 模型自己的习惯”。换言之,craft floor 是可被简报覆写的默认值,但永远不能反过来被模型个人的审美偏好覆盖。这与 SKILL.md 的“The brief wins”原则一脉相承。
- 与 Hook 的分工:当项目的设计检测器 Hook 开启(见 hooks.md)时,那些机械可查的项已经由 Hook 在你每次编辑后自动探测并回报。此时正确动作是“处理它的 findings”,而不是把每条规则再手动重审一遍——重复审计是浪费,是文档明令禁止的“re-auditing each rule”。
文档标题叫 “Craft floor” 而非 “Craft standard”,词义已经说明它定位:地板(最低可接受线),不是天花板。天花板由各个方向卡片上的 QUALITY BAR(品质门槛)承担;地板则负责“无论方向如何,都不能跌破的机械底线”。全篇最后一句呼应了这一点:“The floor holds the mechanics; it never picks the direction.”(地板掌握机制,从不替你做方向选择。)
Verify:九项“对着成品”的核查,一次渲染、批量执行
Verify 部分的每一个条目都强调是对构建结果的检查(a check on the built result),不是对意图的检查。你不能声称“我本意是想做得有对比度”,你要对着渲染出来的真实像素说话。同时文档要求把它们放进同一批(batched)检查轮次里一起跑,而不是拆成多次截图往返——因为所有检查共享同一次渲染(desktop 与 mobile 一起),SKILL.md 的“Build fully, inspect once with a batched round”正是同一纪律。
逐条展开如下:
1. 对比度(Contrast)
- 正文与占位符文本对比度 ≥4.5:1,大号文本 ≥3:1(对应 WCAG AA 的标准阈值,其中占位符 placeholder 被明确列入,是多数生成页面漏检的重灾区)。
- 在彩色表面上,次级文本要从该色相(that hue)或前景色中“染”出,永远不要直接用灰色。灰字压在彩色卡片上是生成模型的标志性失误——灰色不属于任何调色板,它只是“没想好”的默认值。
2. 纵深(Depth)
- 阴影必须携带偏移量(offset)和柔化模糊(soft blur),即符合真实光影的投射。
- 零偏移的彩色光晕只是装饰(a zero-offset colored halo is decoration),不是阴影。这在检测器中对应 glow 类规则(tests/fixtures/antipatterns 目录下可见
glow.html、radial-spotlight-glow.html等探测样本)。
3. 间距(Spacing)
- 节奏法则:紧凑的分组、慷慨的分隔、标题上方留白大于标题下方留白。
- 关键要求:“Read the computed values.”——不要相信你写的 margin 值,要读浏览器计算后的实际值,因为盒模型叠加、line-height 继承都可能让意图落空。
4. 字体排印(Type)
- 正文行长(measure)65–75ch。
- 展示级字号上限6rem(display max 6rem)。
- 字距下限-0.04em(tracking floor),即负字距最多收到 -0.04em,防止“挤成一团”的极端负字距(仓库 fixture 中
extreme-negative-tracking.html正是这类探测样本)。 - 标题要平衡(balanced),层级要有明显的字号与字重梯度(obvious scale and weight steps)——不能让 H2 和正文长得像双胞胎。
- 必须在每个断点下用真实文案跑一遍(run the real copy at every breakpoint),修掉一切溢出。假文字/lorem 掩盖的换行问题会在真实内容涌入时爆发。
5. 动效(Motion)
- 页面只允许一个“作者刻意设计”的动效时刻(one authored moment),而不是到处散落的特效,更不是每个 section 都来一套一模一样的入场动画。
- 缓动使用指数级 ease-out,且元素应从一个本来就可见的默认状态出发(不要先隐藏再弹出,制造无意义的延迟)。
- 动画视野要突破 transform 与 opacity 的舒适区:
blur、backdrop-filter、clip-path、mask、shadow都属于可选调色板——前提是它们保持流畅(stay smooth)。这与参考文档 animate.md、overdrive命令的技术野心一脉相承,但 craft floor 给它们套上了“克制”的缰绳。
6. 状态与真实内容(States)
- 全状态覆盖:hover、disabled、loading、error、empty一个不能少。
- 再加上:真实内容(不是演示占位)、可用的控件、响应式组合、键盘焦点(keyboard focus)。第五项意味着:一个只能鼠标点击、键盘 Tab 后焦点消失的页面,在这一条直接不合格。
7. 浏览器原生界面(Browser surfaces)
这是全文最有洞察力的一条,值得单独展开。文档指出:“你没画的那部分,同样要背负你的设计。”文本选区颜色、输入光标(caret)、自定义滚动条、焦点环(focus ring)、下划线偏移量(underline offset)、以及表格数据里的数字字形(tabular numerals)——这些都由浏览器默认值接管,而默认值不属于任何设计系统。你必须从调色板出发为它们逐一设主题(theme them from the palette)。文档特别点评:
这是“页面是被建造出来的”还是“被拼装出来的”最廉价的信号,也是模型最容易跳过的检查。(This is the cheapest signal that a page was built rather than assembled, and the one models skip most reliably.)
生成模型天然只关心自己写下的那部分 DOM,原生选区颜色、数字等宽对齐这类“继承自 UA stylesheet”的细节几乎必然被漏掉,因此这条成了人工复核的高性价比抓手。
8. 文案(Copy)
- 使用产品自己的语言,而不是套话。
- 控件名要说清它执行的动作(按钮不能叫“点击这里”,要叫“保存草稿”)。
- 错误信息要说清问题与恢复路径(errors name the problem and the recovery)——“出错了”不是错误信息,“无法连接服务器,请检查网络后重试”才是。这与 UX 文案专项命令
clarify的目标一致(见 clarify.md)。
9. 覆盖度(Coverage)
- 简报中的每一条需求都必须在页面上存在、且在数秒内可被发现(present and findable within seconds)。埋在折叠深处、藏在悬停态里的关键需求等同于缺失。这与 finish 评审的“fidelity 矩阵”直接衔接:缺失的必达元素是 material fix。
Refuse:不是“禁止”,而是“必须挣回来”的默认值
Refuse 部分开宗明义地定义了整份清单的哲学:
这些是该类别的默认值,不是禁令:简报自己的措辞可以为其中任何一项赎身(the brief's own words can earn any of them)。当一个轴是自由的而你去抓取其中某一项,说明你根本没有在做决定;意识到这一点意味着重写该元素,而不是把它软化。
这句话值得放慢读三遍。它的意思是:当方向没有约束某个轴时,你“顺手”用了这些模式 = 你没有决策,你在偷懒。而补救不是给这个卡片加点圆角、把红色调淡一点的“softening”,而是重写它。反过来,如果简报明确要新粗野主义(neobrutalism)、要玻璃拟态,那这些模式就正当——所以下面是“defaults(默认值)”而非“bans(绝对禁令)”,唯一的例外是 kicker/eyebrow,那条是真正的 ban。分两组看:
页面脚手架(Page scaffolds):默认拒绝
- “图标 + 标题 + 正文”的同尺寸卡片阵列作为页面结构。文档直言“卡片是懒惰者的容器(Cards are the lazy container),嵌套卡片永远错误”。这是 AI 生成 landing page 最泛滥的配方,一屏四张等大卡片几乎就是“没设计”的代名词。
- hero-metric 模板:大数字 + 小标签 + 支持性统计 + 一个强调色。这是 SaaS 首页的刻板印象,默认拒绝。
- 标题上方的 kicker 或 eyebrow(眉题):文档明确这是ban,不是 default:“no brief earns it back”(没有任何简报能把它赎回来)。“标题自己扛得起自己的分量;删掉那个小标签,让标题自己说话。”(The heading carries its own weight; delete the label and let the heading speak.)值得注意的是检测器对这条的机械判定充满语义细节——仓库的 fixture kicker-above-heading.html 展示了“Should flag / Should pass”两组样例:追踪字距的大写小标签会被判违规,但面包屑、日期行、文章元数据、法律条文编号、步骤指示器、应用面板状态标签等携带真实信息的内容性标签不算 kicker;纯大写字距未放大写的标签也不算;带
data-impeccable-allow-kickers显式标记的品牌系统可豁免。这恰好印证 craft floor 的立场——机械规则之外,边界需要判断力。 - 章节编号(01 / 02 / 03):默认拒绝,除非序列本身承载读者需要的信息(例如教程步骤、操作顺序)。装饰性的序号是廉价的结构假装。
- 为既不需要打断、也不需要受保护焦点的任务开模态框:模态框有两大正当理由——打断用户当前流程、或保护焦点(如不可跳过的确认)。两者都不沾的任务开弹窗,纯属给用户添堵。
表面习惯(Surface habits):默认拒绝
- 渐变文字。强调应该来自字重或字号,而不是给文字糊一层彩虹。方向世界里视觉重复的
gradient类 fixture(如dark-gradient-ground.html、oklch-neon-text.html)即探测样本。 - 作为装饰的玻璃拟态与模糊(glass and blur as decoration rather than as a specific effect)——只有在模糊有具体功能目的(内容遮挡、层级分离)时才成立。
- 卡片、列表项、引用块、提示条上的彩色
border-left/border-right超过 1px。大于 1px 的彩色侧边条是“贴了标签的矩形”,不是设计。 - 硬偏移阴影(
box-shadow: 4px 4px 0)用在并非真正新粗野主义(neobrutalist)的世界里。文档毒舌地点评:“零模糊的块状阴影是戏服(costume),不是纵深系统;一个没有选择它的世界,永远不能把它当作默认值挣回来。” - 用迷你趋势图(sparklines)、进度环(progress rings)和软阴影圆角矩形来“代替”真实内容。占位即欺骗。
- 把等宽字体当“技术感”戏服——monospace 只允许用于代码、数据或度量,不能用来给页面贴“我很极客”的标签。
- 用系统展示字体(Impact、Arial Black、平台无衬线体)充当自有世界页面的 display 主声部。文档要求:去获取并自托管一款字型性格与已批准字样相符的字体;“离得最近的已安装字体是失败,不是 fallback。”(the closest installed font is a failure, not a fallback.)仓库的字体索引数据 font-index.json 与检测器的
overused-font规则(见 hooks.md)正是为揪出这类“默认字体当个性”而存在。 - 用 Unicode 字符或 emoji 充当图标系统。图标必须被绘制:来自真实图标库或手写 SVG,且保持一致的描边与字重(one consistent stroke and weight)。
- 用几何蒙版冒充有机轮廓:用圆形、多边形或径向渐变裁剪近似照片主体的边缘,是“廉价版效果”,比干脆不做更难读。正确做法是从真实图像导出 alpha 蒙版,或产出一张剪裁好的素材。Finish Reviewer 的 Truth 检查会点名检测器的
organic-clip-path与buried-rasterfindings——正是这条规则的机械化。 - 按“类别”而非“场景”决定明暗主题(light or dark picked by category)。要从使用场景挑:谁在用、在哪用、处于什么环境光下。SaaS 后台不等于必须亮色,创意展示不等于必须暗色。
在流水线中的位置:与 Hook、Detector、Finish Reviewer 的分工
craft floor 之所以重要,恰恰因为它是**“检测器扫不到的反射”的存放处**。hooks.md 原文写得很清楚:
Every hook is a mechanical pass. The reflexes no scanner catches live in craft-floor.md, which the skill loads before it edits UI, so they apply whether or not a hook is wired.(每个 Hook 都是一次机械扫描。扫描器抓不到的反射存在于 craft-floor.md 中,技能在编辑 UI 之前就会加载它,因此无论 Hook 是否接线,它们都生效。)
也就是说,系统内存在三层防线,各自覆盖不同颗粒度:
- Per-edit Hook(即时机械层):在
.tsx/.jsx/.html/.vue/.svelte/.astro/.css等设计相关文件每次编辑后运行,回报第一梯队的机械问题——坏图、溢出裁剪、对比度与可读性失败、渐变文字、光晕阴影、设计系统漂移等(完整规则分层见 hooks.md)。 - Craft Floor(判断层):本文档。覆盖“卡片阵列是不是偷懒”“这个序号有没有信息量”“这个模态框该不该存在”“灰色是不是偷懒的次级色”这类无法写成确定性规则的审美判断。它在每次编辑 UI 前被加载,无论 Hook 是否激活都成立;没有自动 Hook 的会话,
context.mjs会在结尾发出一条MANUAL_DETECTOR_REQUIRED指令要求手动跑一次检测作为兜底。 - Stop 深度扫描:在会话结束事件上把全量规则集跑一遍本会话改过的所有 UI 文件,去重后一次性回报剩余的品味类问题。
在流水线的另一端,impeccable-finish-reviewer 这个收尾评审子代理把 craft floor 直接设为它的Check 6 Floor:它会把截图与 Refuse 清单逐项对照——kicker/eyebrow、新粗野主义世界之外的硬偏移阴影、字符图标、系统展示字体、渐变文字、侧边条等,任何被禁元素都是 material fix,即使它与 comp 完全一致也不行——因为“构建者写下它之前已经加载了同一条禁令,对 comp 的忠实不能授权地板所拒绝的东西”。文档里还记录了一个辛辣的反面教材:“最近两次 live 会话带着五个 kicker 过了评审,而评审者从未看过它。”这正是 floor 检查存在的原因——Hook 覆盖不到的 harness(无 Hook 会话)会把整份责任压在评审代理对这份清单的执行上。
此外还有两条纪律值得注意:
- degraded/documenter.md 的“不 canonize”原则:文档化代理绝不能把 craft-floor 的禁用项写进 DESIGN.md 变成系统规则——kicker、非新粗野主义世界的硬偏移阴影、字符图标、系统展示字体一旦被“风格化归档”,一次违规就变成了“家传风格”。文档记载真实事故:一个 live 会话发明了五个 kicker,documenter 随后把它们写成了 DESIGN.md 的规范,违规就此升级为 house style。禁用项永远记为“构建携带的缺陷”,而非未来页面的设计系统规则。
- live 模式的自由态同样受约束:live.md 规定当
event.action为impeccable(freeform)时,从 SKILL.md 的设计规则 + craft-floor 出发工作;为 source-preview 目标写全新标记前也要先加载它,且生成 variant 时“按构造”遵守对比度、间距与字体的底线,完整验证留到 accept 时一次跑完。
面向不同模式(Persuade / Operate / Read / Experience)的共同底座
SKILL.md 把界面工作按访问者成功形态分成四个模式:Persuade(说服与转化,landing/marketing)、Operate(任务完成,应用/仪表盘)、Read(阅读理解,文档/长文)、Experience(沉浸体验,作品集/展览)。operate.md 明确指出它的精要活在 SKILL.md 的模式定义加 craft-floor 里,本文件只是 Operate 面上的纵深扩展。换句话说,craft floor 是四模式共享的地板:Persuade 页不能因为“要大胆”就跌破对比度,Operate 面不能因为“要高效”就交出灰色次级文本,Experience 不能因为“要沉浸”就纵容零偏移光晕。模式决定天花板的形状,地板对所有人一样高。
如何在你的项目里应用这套底线
craft floor 的价值并不绑定 impeccable 全家桶,把它当作一份可迁移的“动手前自检契约”同样成立:
- 把它加载在“方向定稿后、写第一行 UI 前”,而不是设计讨论阶段——先解决“做什么方向”,再上地板检查“方向执行得干不干净”。
- 不向团队宣布清单,把 Verify 项合并进同一批渲染检查(桌面 + 移动一次跑完),逐项对照计算值而非目测。
- 用 Refuse 清单做代码审查的减法过滤:看到同尺寸卡片阵列、hero 大数字、标题上的小眉题、渐变色文字、emoji 图标时,先问“这页的方向世界里这些是否被简报挣回来了?”挣不回来就重写元素,而不是调色软化。
- 给浏览器原生界面补主题——这是投入产出比最高的一条:
:selection、caret-color、scrollbar 样式、:focus-visible、下划线的text-underline-offset、表格的font-variant-numeric: tabular-nums,一次调色板主题化,整页“人工建造感”立涨。 - 若你使用本仓库的 impeccable 技能,把这条底线交给 Hook 与 Finish Reviewer 去执行:启用
hooks(见 hooks.md 的动作表on/off/status/ignore-*),并在收尾时让impeccable-finish-reviewer跑它的 Floor 检查;对机械问题信 Hook 的 findings 即可,把人工判断力留给 Hook 扫不到的部分。
结语:地板管机制,天花板管野心
Craft floor 用一句话收束全部内容:
The floor holds the mechanics; it never picks the direction. With every check green, spend the page on the committed world, and when torn between refined and committed, commit.
(地板掌握机制,它从不替你选择方向。当每一项检查都通过后,把整页的预算花在已经承诺的视觉世界上;当你在“精致”与“忠于承诺的世界”之间犹豫时——忠于承诺。)
这最后半句是整个 impeccable 设计哲学中最锋利的一刀:AI 生成界面最常见的死因不是“不精致”,而是在自由轴上抓取了最安全、最不需要决策的默认模式。craft floor 的 Verify 让你不会把糟糕的机制交给用户,Refuse 让你不会用懒惰的脚手架冒充设计,而最终那句 “when torn between refined and committed, commit” 把 Agent 从“讨好式打磨”中拽出来,推向真正有立场的设计决策。
【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考