设计画布 是做什么的?
你在项目中以真实的 HTML 文件设计屏幕,并在本地设计查看器中展示它们。用户并排看到每个屏幕,切换设备尺寸和亮/暗主题,导出 PNG 并对屏幕评论;评论会以精确前缀的聊天消息返回给你。
文件(契约)
design/
tokens.json 设计令牌的唯一真实来源(两个主题);品牌值唯一的存放处
design-system.css 从 tokens.json 生成:为 [data-theme="light"] 和 [data-theme="dark"] 提供的设计令牌(禁止手动编辑)
utilities.css 从 tokens.json 生成:封闭的工具集词汇(禁止手动编辑)
design-system.md 品牌决策的文字说明(简短)
validate.mjs 验证器(每个项目复制一次——见设置)
serve.mjs 查看器的微型静态服务器(每个项目复制一次)
viewer.html 查看器(每个项目复制一次)
mock.js 用于交互式屏幕的模拟运行时(每个项目复制一次)
mock.css 模拟运行时类的静态样式(每个项目复制一次)—— toast/overlay/enter-transition 状态;屏幕以 `../mock.css` 链接;mock.js 仅切换这些类,绝不注入 CSS
scripts/ 每个项目复制一次(见设置)
gen-tokens.mjs 从 tokens.json 重新生成 design-system.css + utilities.css
sync-components.mjs 从 partial 重新物化每个组件标记区域(每个项目复制一次)
marker-parser.mjs sync 在运行时导入的共享标记语法解析器(每个项目复制一次)
components/ 组件注册表和 partial 种子(每个项目复制一次):components.json + 每个组件一个 partial
vendor/html-to-image.js PNG 导出库(每个项目复制一次)
index.json {"canvases": ["login", ...]} 以便查看器列出它们
<canvas>/ 每个画布一个文件夹,kebab-case(login, dashboard)
canvas.json
data.json 可选的虚构数据;可选的 "scenarios" 对象,包含命名的顶层覆盖(empty, critical…)
01-<screen>.html 每个屏幕一个完整的 HTML 文档
assets/ 可选的本地图片/脚本
canvas.json(屏幕按此顺序出现):
{
"title": "Login do app",
"screens": [
{ "id": "login", "name": "Login", "file": "01-login.html", "device": "mobile" },
{ "id": "cadastro", "name": "Cadastro", "file": "02-cadastro.html", "device": "mobile" }
]
}
device:mobile= 390×844,tablet= 834×1112,desktop= 1440×900;可选的width/height(整数 100–10000)可覆盖。group(可选):将屏幕聚类到查看器条带中带标题的块中的标签——复杂项目保持可读性(例如"group": "Checkout")。transition(可选):fade、slide-left或none(默认)。这是Mock.go后屏幕的进入动画——参见工作流程第 3 步的同画布/跨画布规则。id唯一且非空;name非空;title可选。file相对于画布文件夹:绝不能是..、前导/、\或方案(http:、file:…)。
每个项目的一次性设置
如果 design/ 尚不存在,则创建它并从该技能的文件夹(包含此 SKILL.md 的文件夹)中复制:
scripts/validate.mjs→design/validate.mjsassets/viewer.html→design/viewer.htmlassets/serve.mjs→design/serve.mjsassets/mock.js→design/mock.jsassets/mock.css→design/mock.css(模拟运行时类的样式;屏幕链接../mock.css)assets/docs.html→design/docs.html(使用指南,从查看器的 📘 文档按钮链接)assets/vendor/html-to-image.js→design/vendor/html-to-image.jsscripts/gen-tokens.mjs→design/scripts/gen-tokens.mjsassets/components/→design/components/(注册表和 partial 种子)scripts/sync-components.mjs→design/scripts/sync-components.mjsscripts/marker-parser.mjs→design/scripts/marker-parser.mjs(sync 在运行时导入的共享解析器模块)scripts/export-tokens.mjs→design/scripts/export-tokens.mjs(W3C/DTCG 交换导出:tokens.json → tokens.w3c.json;衍生工件,绝不要手动编辑)
此复制列表的规则:只有已存在的文件才能进入列表("só entra no copy list arquivo que já existe")。尚未出现的文件仅在它们的契约波次加入:export-tokens.mjs 在契约波次 6(待办 30)时加入,并已列在上面——规则满足(该文件自待办 26 以来已存在)。(mock.css 在波次 3 加入并已列在上面。)
每当 tokens.json 发生变化时,从项目根目录重新生成两个生成的文件:
node design/scripts/gen-tokens.mjs
创建 design/index.json({"canvases": []}),并在创建画布时将每个新画布名称添加到其中。一个完整、有效的示例存在于该技能的 assets/example/ 中——一个跨两个画布的工作股票应用系统:login/(登录、注册,以及一个通过普通链接以叠加方式打开的删除账户确认模态框)和 dashboard/(交互式概览,带有长项目列表、同画布“Atualizar lista”刷新,演示 fade 过渡和滚动恢复),其中登录和注册跨画布导航到概览,概览读取其虚构项目,支持命名场景,并注销返回登录画布。在开始新的设计系统或画布之前,阅读并改编它。种子 example/components/ 是 assets/components/ 的字节相同副本("example/components/ é cópia byte-idêntica de assets/components/ (fonte única)"):仅编辑 assets/components/ 中的 partial,绝不编辑示例副本中的 partial。
工作流程
- 先设计系统。 读取
design/design-system.css和design/design-system.md。如果它们不存在,请询问用户品牌(主色、字体风格、调性;提供中性调色板作为选项),然后创建两者。后续画布重用它们。仅在询问后更改令牌。 - 只问缺失的信息。 如果请求模糊(哪些屏幕、哪个平台、什么数据),问一次;如果清晰,直接开始。
- 构建画布。 首先从该技能的文件夹读取
assets/craft.md(它将兄弟技能——taste、emil-design-eng、impeccable——融合成画布屏幕的规则)并将其应用于每个屏幕。然后创建canvas.json和屏幕。每个屏幕的规则:- 样式策略:工具集词汇是词汇。任何基于令牌的内容(颜色、排版、间距、圆角)都通过生成的工具集使用:链接
<link rel="stylesheet" href="../design-system.css">和<link rel="stylesheet" href="../utilities.css">,然后使用诸如bg-accent、p-2、text-heading、rounded-md的类。交互式屏幕还要链接<link rel="stylesheet" href="../mock.css">(模拟运行时类:toast、overlay、enter 过渡)。语义类仅承载结构和布局。在没有合适的工具集时,允许使用var(--…),并且允许内联<style>块,但必须包含零个文字颜色。禁止扫描会检查<style>、style=""以及 SVGfill=/stroke=的 VALUE 位置中的文字颜色;它还禁止屏幕中任何位置的http(s)://、Tailwind 调色板类如bg-zinc-900,以及任意值如text-[13px]。 - 通过令牌同时适用于两种主题;主题通过
<html>上的data-theme到达(默认为light——请包含该属性)。 - 没有 CDN 或任何类型的远程 URL(画布是离线的且沙盒化):内联 SVG 图标、系统字体或
design/下的字体文件、本地图片。 - 使用用户语言的实际副本(默认巴西葡萄牙语)和合理的示例数据——没有 lorem ipsum。
- 在必要时覆盖空状态、加载状态和错误状态,作为额外的屏幕。
- 无障碍基础:输入标签、可见焦点、足够的对比度、移动端点击目标 ≥ 44px。
- 布局必须保持在屏幕的设备宽度。
- 组件是 partial 的实例,绝不是松散的组件标记("instância usa partial, nunca markup solto de componente")。将每个实例包裹在标记对
<!-- component:id size=md tone=primary state=default -->…<!-- /component:id -->中,包含三个必需的参数size=、tone=、state=(值必须位于design/components/components.json的注册表枚举中),并将其插槽填充为配对的标记<!-- slot:name -->…<!-- /slot:name -->。优先级:标记参数是真实来源(marker-args-win)。同步每次运行时重新从标记发出data-size/data-tone/data-state和变体类;插槽内容和根元素上的用户额外data-*属性保留。 - 使其成为系统预览,而不是海报。 当请求暗示一个工作产品时,使用模拟运行时连接屏幕(
<script src="../mock.js"></script>,由设置复制):表单验证并提交,按钮提供反馈,屏幕使用Mock.go('03-dashboard.html')导航,虚构数据存在于画布的data.json中(await Mock.data('items')),流程状态(登录用户、沿途创建的项目)存在于Mock.state(会话,按画布命名空间),模拟操作使用Mock.toast('…')确认。如果 JS 失败,每个屏幕仍然必须渲染为静态组合。查看器在导航过的卡片上显示 ↺ início 按钮,以及 "⟲ Reset fluxo" 以重新开始整个流程。覆盖重要的状态,作为data.json中的命名scenarios(顶层覆盖,例如"vazio": {"items": []})——查看器获得一个选择器,该选择在导航后保留,并且每个场景必须组合良好(空列表、所有项目低于最小值、API 失败)。一个系统可以跨多个画布(每个流程一个):使用Mock.go('../<canvas>/<screen>.html')跨画布导航——流程状态在项目范围内共享,因此登录画布设置用户,仪表盘画布读取该用户。查看器的画布选择器在画布之间跳转(每个画布保留其自己的场景、主题和设备)。模态框和确认对话框也是完整的画布屏幕(单一真实来源):触发器是一个普通屏幕链接<a href="03-modal.html">,模拟运行时将其拦截为Mock.overlay('03-modal.html')——如果没有 JS,未触及的 href 会导航到模态框屏幕本身(JS 关闭的 fallback)。持久导航(侧边栏、顶部菜单、选项卡)必须实际切换屏幕:在每个项目上放置data-go="02-cadastro.html"(保持同一链接上的真实href="02-cadastro.html"作为 JS 关闭的 fallback——运行时将data-go路由到Mock.go,保留?scenario=和进入过渡)。普通链接保留用于叠加触发器(模态框/详情——普通屏幕链接始终打开叠加);在画布的每个屏幕上重复相同的导航块,并标记活动项目。屏幕可以在canvas.json中声明"transition": "fade"|"slide-left"|"none":Mock.go为目标添加一个进入类(mock-enter-fade/mock-enter-slide-left,在 300 毫秒内自行移除)。移交读取由目标文件名匹配的当前画布的canvas.json,因此它适用于同画布跳转(像Mock.go('01-overview.html')这样的自导航是刷新模式)——跨画布的Mock.go('../<canvas>/<screen>.html')是不带进入类的普通导航。滚动位置按屏幕保留(scroll.<canvas>.<file>在 sessionStorage 中,当屏幕返回时恢复,并在 ⟲ Reset fluxo 后保留,后者仅清除mock.*)。
- 样式策略:工具集词汇是词汇。任何基于令牌的内容(颜色、排版、间距、圆角)都通过生成的工具集使用:链接
- 验证并修复。 强制性的同步优先:在编辑
design/components/中的任何 partial(或任何标记的参数)之后,在呈现任何内容之前,从项目根目录运行node design/scripts/sync-components.mjs;它从 partial 重新物化每个实例(marker-args-win)。--check是试运行形式:它打印每个差异区域的file:linediff,并在有差异时退出 1(无差异则退出 0),从不写入。然后从项目根目录运行:node design/validate.mjs design/<canvas>。修复它列出的每个问题,并再次运行,直到只保留摘要行。绝不要呈现一个有问题的画布。验证器的参数是 design 根目录(项目模式)或单个画布文件夹(画布模式);没有参数时默认为./design。结构检查仅涵盖canvas.json中列出的屏幕;项目模式另外检查令牌/生成的 CSS 是否过时、组件和评论。组件规则在每个非豁免的.html上扫描,独立于canvas.json,代码包括component-unknown、component-variant、component-marker、component-divergence和slot-marker。--allow-stale仅跳过过时检查;--mark-stale是验证器唯一的写入(它标记锚点已消失的评论图钉);--example-inventory是示例契约检查(inventory.json的精确文件列表 + 每个图钉的"_demo": true;没有inventory.json= 跳过,退出 0)。 4b. 完美审计。 验证后,在画布上运行兄弟impeccable技能的技术审计(已安装的布局,win32):<skill-impeccable>/scripts/impeccable.cmd audit design/<canvas>- 路径从已安装的技能解析……
[由于原始内容被截断,翻译在合理处结束。技能的主要契约、工作流程和约束已完整传达。]