@ domandigital/ craft (中文(简体) )
多曼数字屋工艺标准,作为数字.
OKLCH 彩色斜坡, 以显示您已经上船的颜色, 语义符号来源 与测量的 WCAG 财务报告和审定财务报表 APCA 对比,一个运动词汇,由 CSS 和 JS,一个基底样式表,和一个扫描仪,可以发现AI在源头和复制. 零运行时间依赖关系.
读取 原则.md 为什么每个规则都是规则.
安装
pnpm add @domandigital/craft
使用
import { craftTokens } from "@domandigital/craft";
const { css, report, ramps } = craftTokens({
// Steps you already ship come back byte-identical.
accent: { 400: "#a78bfa", 500: "#7050f5", 600: "#6e4ce8" },
bgCanvas: "#04060e",
bgSurface: "#0b1120",
bgElevated: "#151c2e",
textPrimary: "#ecf2ff",
textSecondary: "#b7c3d9",
textMuted: "#8e9cb5",
borderSubtle: "rgba(184, 198, 219, 0.16)",
borderStrong: "rgba(184, 198, 219, 0.28)",
success: "#3fb98a",
warning: "#d6a14a",
danger: "#e26d6d",
info: "#5aa7e8",
});
if (report.failures.length > 0) {
// Fails the house bar (4.5:1 AND |Lc| 60). Surface it; do not ship past it.
console.warn(report.failures.map((f) => f.note).join("\n"));
}
写入 css 输入已执行的文件并导入。 然后,有一次, 在你的全球
样式表 :
@import "@domandigital/craft/craft.css";
craft.css 不需要建设步骤 和Tailwind一起工作或没有 Tailwind.
在 Tailwind v4 上, 也导入主题桥:
@import "@domandigital/craft/craft.tailwind.css";
在 Tailwind v3 上添加预设:
const { tailwindV3Preset } = require("@domandigital/craft");
module.exports = { presets: [tailwindV3Preset()] };
标准本身
标准.md 是十二节的房屋标准,每个数字 所援引的规则,包括一节关于蓄意 没有 一个规则。 内容 在每次测试运行时,都把犬科数字与代码进行比较,所以 文档不能从哪艘船上漂出.
字符: 查找 AI 外观
标准问地表是否造得好. 查尔斯·姆德 问是否有人决定它是什么样子, 或它是否是一个模型构建 没有人告诉它.
npx craft scan # markup, components, stylesheets
npx craft scan --staged # pre-commit: the git index only
npx craft copy app content
npx craft tells list
每一个发现的名字 显示,它的一代(1: Indigo, Inter, 玻璃; 2: 奶油,
斜拉索 眉毛芯片 便当 线条 以及该做什么 每个
告诉船只一个警告。 一个真正是紫罗兰的品牌宣布了它
原因,在 art-direction.json数字 :
{ "exceptions": [{ "tell": "ai-violet", "because": "Violet is on the van, the cards and the fascia." }] }
艺术方向v2记录客户的工作, 每个页面类型的层次, 和7个表达式符号, 并附有理由和证据。 从工作开始 研究,然后是等级,然后是符号:
npx craft direction research --brief "An electrician in Brackley repairing dangerous faults for local households"
npx craft direction init --client "Copper Lane" --brief "<who, where, what they do>"
npx craft direction validate --estate estate.json
npx craft estate add --id copper-lane --direction art-direction.json --estate estate.json
npx craft estate compare --estate estate.json --directions
npx craft direction validate --snapshot http://localhost:3000 --page home --strict
页面也可记录 confidence: 其决定的宽度在
和它提供的证据, 每一个都有理由. craft direction validate
报告所观察到的、推断的或未知的,以及它为何重要和
无分. 不需要任何证据 肖像 幻灯片,
电话按钮或分区顺序。 见 决策信心。 。 。 .
页面上的反馈是相对于访问者的. craft direction review --notes design-review.json 保持刚才的言语, 访客的问题在它下面, 什么是
证据和最小的可辨别变化 都说得很清楚
并且可以得出结论:
无需改动。 仅由审计或利益攸关方报告的证据不能
发现一个问题, 宽度没有人知道。 见
审查拟议的变动。 。 。 .
复议员自己的复议 保持相同的状态 保持私人状态 保存在这个存放处外的复议官证 以及每件案的处理情况 说明和它教导的原则。 工作室评论员对工作室的评论 自己的网站是第一个。 见 对工作室自己网站的审查。 。 。 .
--snapshot 接受保存的文件和预览或生产 URL。 漂流失败
与 --strict; 已申报的地产比较仍为咨询。 版本 1 文件
仍然通过警告来验证。 见 查尔斯·姆德 全文
v2 示例和每层的含义.
在CI语中
npx craft scan --baseline craft-baseline.json --update-baseline # once: adopt today's findings
npx craft scan --baseline craft-baseline.json --strict --sarif craft.sarif
npx craft audit --pages https://example.com/sitemap.xml --viewport 390,1440
--baseline基准尚未确定。 A 类 查找被按键于它的分录、路径和摘录上, 绝不是它的行, 所以编辑 超越已知的发现并不成为新的发现。 输出显示有多少人知道 发现它漏掉了.--sarif <file>为 GitHub 代码扫描编写 SARIF 2.1.0。 对a 的审计结果 已制成的页面包含 URL, 不是文件, 因此代码扫描不会显示它们 .--json输出总是带schemaVersion(目前为一.--pages对一个站点地图(或站点地图索引,深一层)中的每个 URL 进行审计 或 URL 文件;--viewport对每个宽度进行审计。 一页 将不加载为未计量,但失败--strict。 。 。 .
craft.config.json 在还原根中,拥有什么 飞行器应该知道
复发. .claude, (中文(简体) ), .agents 财务报告和审定财务报表 .cursor 从来没有人走过, 配置与否.
{
"ignore": ["docs/archive/**", "*.stories.tsx"],
"copyPaths": ["content", "src/app"],
"severity": {
"em-dash": { "level": "block", "because": "This client's style guide bans them outright." }
}
}
严重程度变化需要 because像一个例外. off 用作
因此,报告列举了它沉默的内容.
下 craft copy --gate,回购可以提高 副本告诉,但决不降低
房子挡住一层 A 类 warn 或者说 off 这里或作为一个屏蔽消息
例外情况 art-direction.json,被拒绝,并列入报告。 A 类
真正的一次性起飞 copy-ok 在它的线.
复制
警务处 是房屋复制标准: 屏蔽层, 复检
级,读取整个文档的密度级,代之以写出什么.
craft copy --gate 应用房屋政策,所以屏蔽级失败
运行。 如果标准块不阻断一个短语, 测试失败 .
npx craft copy --gate content # the house gate: exit 1 on the blocking tier
npx craft copy compare draft.md rewrite.md # facts a rewrite lost or added
npx craft copy claims content # every price, figure, date and named source, to check
无法判断一个数字是否真实. craft copy claims 每个列表
句子读取一个可以验证的事实,标记 sourced (资料来源是:
名称)或 UNSOURCED,对于一个人检查与主要来源。 这个
总是出0:核对表,而不是判决.
在选定的登记册(平面、说服力、温暖和文学)中写作,阅读
在起草和检查之后的完成文件之前简短。 见 REGISTERS.md。 。 。 .
npx craft register brief warm # what to do before drafting
npx craft register check letter.md --as warm # five paragraphs or more; never fails
代码中的相同检查 :
import { checkCopy, formatReport, scanSource } from "@domandigital/craft";
const report = scanSource([{ path: "app/page.tsx", text }]);
console.log(formatReport(report, "craft scan"));
锚定担保
你传入的每个螺旋都出来了 不变 相同的字符串 字节. 这就是让一个现场 采用这个,没有像素移动。 只有 你从未亲手选择的步数是生成的.
它会告诉你,你没有要求
report.failures 列出清除 WCAG AA 、 但漏掉的每对文字
房屋 APCA 栏, 这是失败模式, WCAG 只检查无法看到 。 这个
重音分叉作为 CSS 注释发布其测量比率,所以选择是
可核查,而不是断言.
建造由漂移护卫折叠的门
只有两张支票 Doman-Digital/dd-drift-guards (由 git 标签支撑)
从0.18.0起,在少数客户端(repos)中是工艺的一部分。 其他三个警卫
这里已经存在: 克制(lcheckRestraint),减少动议(a)
限制规则)和艺术方向(craft direction, (中文(简体) ), craft estate) (中文(简体) ).
gradientContrast(text, gradient, beneath): CSS 梯度上的案文 案例轴-核心和灯塔标记"不完整",从未得分. 这是复合材料 该梯度在下方,并评分文本,WCAG和APCA, 面对最坏的一点。 最坏的一点是沿着每一段进行取样,而不是 仅在站点:黑白梯度上的中灰色文字清除4.5:1 在两端,中间约1:1, 漂移的护卫 版本通过。 硬站点( A)#000 50%, #fff 50%)是浏览器的跳动 涂料没有混合,所以没有取样。 WCAG没有定义梯度方法,所以这是手动的 规则,而不是符合要求的要求.checkPhotoReview(text, { minScore, required }): 打开一个建在 报告halide review --json写作。 它需要报告的文本(在 没有),从不运行卤化物。 一个微弱的图像甚至会失败 短篇报告失败,而不是读作 "没有报告".
门户的电话第一门
标准ARD.md 第10节作为登录后应用的大门,例如客户端
门户(门户标准规则10,DOM-775). 创建网站 measure.mjs 财务报告和审定财务报表
mobile-first.mjs 对一个网站做同样的工作; 门户的页面需要一个
登录用户和固定数据, 仅限门户自己的 Playwright 套接字
可以设置,所以大门来 成两半.
传送门的套房打开了每个关键路由 : PHONE (375 x 812,触摸)和
措施:
import { test } from "@playwright/test";
import { PHONE, measurePhone } from "@domandigital/craft/phone";
test.use(PHONE);
for (const route of ["/portal", "/portal/invoices"]) {
test(`phone first: ${route}`, async ({ page }) => {
await page.goto(route);
await measurePhone(page, { route }); // writes phone-first/measured/portal-invoices.json
});
}
礛 craft phone-first --measured phone-first/measured 判断每一个路线,
和源文件夹 phone-first.json 名称,与 repo 基线相对应:
- 静态 : (单位:千美元)
max-width媒体查询(任何拼写、范围语法)或a 尾风max-*:变量失败。 一个真正的例外mobile-first-ok: <reason>在其行或上行,或整个文件 内phone-first.jsonexceptions作为{ "file", "reason" }。在尾风上 3 应用,/NN对任意性的不透明度var()颜色也失败( 请在下面检查 4) . - 测量为375px: 页面滚动侧向(相对于版式)
视图端口: 在移动模拟下
innerWidth长出一页,所以 永不显示卷轴),无width=device-width视图元, 44 x 44 下的目标( 句子内的链接可以豁免; 字段标签) counts),16px以下或48px以下的文本字段;12px以下的文本;a 断开h1。 。 。 .
phone-first.baseline.json 列出一个 repo 已经中断的内容, 每个文件计数
和每个路由(数字折叠,所以固定日期不将一个按钮分割为
(见E/CN.4/Sub.2/2003/L.31)。 门在基线没有列出的任何东西上都失败了,而且
(b) 基准,所主张的比现有基准要多,因此只缩小:
在同一公关中降低计数. --update-baseline 写入基线
使当前运行通过; 当闸门进入时运行一次, 然后运行一次
只为降低计数。 它保存着每个入口 reason。 。 。 .
4次检查,有传送门标准的电话课
2026年10月的手机修正 背后的原因就在于门户标准
(单位:千美元)references/phone-faults.md, DOM-1044) (中文(简体) ). 这四个人造出大门
拒绝(DOM-1053).
-
基线只收缩. 运行比较基线和基准 分支的复制件在条目主机上没有失败, 或者在更高端 计数。 将所入之处取出. 其中一个方法就是命名为例外: 非空条目
reason(第三方联合调查不能重新召集,a (仅限破坏性形式)。 旧基线,无reason,读前. 在主干线缩小之前离开主干线的分支 看起来像是它加的 条目:合并主干线.{ "route": "/admin/content", "check": "text", "element": "<p> \"Sign in\"", "count": 14, "reason": "Sanity Studio's sign-in dialog, third-party UI" }基础是
origin/main或者拉动请求的目标分支GITHUB_BASE_REF已设定,或--base <ref>跑者必须能看到 它:与actions/checkout,使用时fetch-depth: 0运行git fetch origin main先说 如果无法看到基地 大门失效 说得没错,它从不跳过 每条入口都带有reason,当碱基还没有基线时(牵引请求带来 ),和"出票"(它打印出一张便条)外. -
每道所测. 与
--measured,测量的路线是 gate的路线列表. 应用程序的每一个页面路径都必须在其中. 页面来了 从下个应用程序文件夹( N)appDir; 遗漏, 任何source调用文件夹app并且从routesManifest,一个已建成的应用程序app-path-routes-manifest.json. 路线组、平行槽、私人 文件夹和截取路径不是自己的页面。 测量路线 覆盖打开的页面:/portal/projects/p1?theme=dark覆盖/portal/projects/[id]字面标签/portal/projects/[id]; 静态兄弟, 如/portal/projects/new没有。 无法测量的一页( 一个只重定向) 进入excludeRoutes唯一的出路,有原因;"/admin/*"取一个前缀 和它下的所有东西。 无端的条目,或命名为无页,失败. 当找不到有页面的应用文件夹时, 运行后会打印路由覆盖 未检查.{ "source": ["app", "components"], "excludeRoutes": [{ "route": "/portal/projects", "reason": "redirects to /portal; measured there" }] } -
球场高48px. 48px 下的文本字段、 选择或文本区域失败 页:1
field检查("44px高,48px下 (使用 min-h-12))"),匹配门户 第5条。 直到现在,门只在44px以下失败,因为 目标。 可配置 :fieldHeightPx内floors,用于measurePhone, (中文(简体) ),measureViewports, (中文(简体) ),measureSite财务报告和审定财务报表viewports.json;默认为 48.await measureViewports(page, { route, floors: { fieldHeightPx: 44 } }); // the old gate -
尾风 3
var()不透明. 尾风 3 无法应用/NN对 a 不透明var()颜色和发射没有CSS,所以bg-[var(--bg-1)]/95离开固定的栏杆 透明。 在 Tailwind 3 应用程序上, 源扫描失败var\([^)]*\)\]/[0-9]+。该版本按source文件夹 已安装node_modules/tailwindcss,否则在最接近的状态中宣布范围package.json; 设置"tailwind": 3或者说4内phone-first.json那时 无法找到它。 Tailwind 4支持语法,没有被扫描. 这是一个 错误而不是风格,所以mobile-first-ok评论不能作为借口; 文件级别exceptions仍然在输入.
每个取景点
375分机是楼层(STANDARD.md 第10节,DOM-787)。 这个 每道取景器都通过梯子取出一页(320、375、390、430, 风景 844 x 390, 768, 1024, 1280, 1440, 1920, 电话按顺序排列和在 在16到32px步骤中从320到1920的宽度扫描,重新调整大小 已装入的页面 :
- 任意宽度 : 边向滚动,可视文本取自其他可见文本,a
剪接页标题( e)
h1),和12px下的文本. 失败指定准确 宽度 :(at 320-352, 400)。 。 。 . - 短电话(375 x 667): 主要行动
mainAction一个选择者, global 或每个路线)位于第一个屏幕上或被固定;固定和粘度 层加在一起,最多覆盖屏幕的25%;图像不超过 比显示的宽2.5倍( e)oversized) 或窄于显示 (单位:千美元)upscaled); 类似电话、电子邮件或电话号码的字段type="tel", (中文(简体) ),type="email"或一个inputmode; 名称、电子邮件、电话或 地址字段载autocomplete;文本中的英国电话号码是tel:链接. - 在风景电话(844 x 390)上: 标题和固定层至少离开 半个高.
- 页面长度( 电话屏幕 ) : 页面高度为375x667,超过667
页脚( 懒人的图像已装入) 。 电话页有长度预算( 一个客户端家)
页面运行了12.7个屏幕,而目标为6.5。 每条路线设置一条或
路由图案
screens; 超出预算的路径失败screens检查,如果没有预算,则只报告数字。 钥匙是一条路线 (单位:千美元)/页:1/areas/[town]),一个前缀(/services/*,路线和 下方的一切)或*;最具体的赢家. - 14时40分和19时20分: 体行最多80个字符(宽于
ch的字体),并且没有图像被拖过它的文件.
每个阈值都有一个房屋违约(DEFAULT_THRESHOLDS)并且可以成为
每个站点或门户都覆没.
import { PHONE, measureViewports } from "@domandigital/craft/phone";
test.use(PHONE);
test(`every viewport: ${route}`, async ({ page }) => {
await page.goto(route);
// Resizes this page in place; writes phone-first/measured/<route>.json.
await measureViewports(page, { route, mainAction: ".hero a", screens: { "/": 6.5, "/services/*": 6 } });
});
result.screens 保留计数,并写入所计量的文件;
craft viewports 财务报告和审定财务报表 craft phone-first --measured 按每条路线打印
(单位:千美元)phone screens to the footer: / 5.8 of 6.5) (中文(简体) ). 单位 viewports.json 预算是
"screens": { "/": 6.5, "/services/*": 6 }; 在创建网站
site.programme.json 这是 measure.screens。 。 。 .
measureViewports 工作在网页上 套房打开和签名,所以
门户保存它的固定装置. measureRoute(open, { route, mainAction }) 已经
这两分之一的页: open("phone") 财务报告和审定财务报表 open("wide") 返回
路径打开并签名, a PHONE (单位:千美元) DESKTOP 和两者
一半被合并并写出一次(DOM-835). measureSite(browser, { base, routes }) 打开每个
路由本身、电话上的一半和桌面上的一半
一,对于一个页面,任何人都可以打开: 创建网站的 measure.mjs 用起来.
craft viewports --url <base> --route / 命令行相同: 它
并据此判断
phone-first.baseline.json。新检查的基线是375px:
列出已有的失败( 每元素一行并检查, 有宽度)
因此,一个宽度的失败不是新的失败,而是新的失败
失败,以及声称有超过失败的基线.
craft phone-first --measured 判断相同的文件,并继续努力
仅测量到375与 measurePhone。 。 。 .
API 密码
| 区域 | 出口 |
|---|---|
| 颜色空间 | hexToOklch, (中文(简体) ), oklchToHex, (中文(简体) ), toGamut, (中文(简体) ), inSrgbGamut, (中文(简体) ), inP3Gamut, (中文(简体) ), deltaEOk, (中文(简体) ), deltaEOkHex |
| 倾斜 | ramp, (中文(简体) ), rampFromAnchors, (中文(简体) ), RAMP_STEPS, (中文(简体) ), LIGHTNESS_CURVE |
| 对比度 | wcagContrast, (中文(简体) ), apcaContrast, (中文(简体) ), checkPair, (中文(简体) ), gradientContrast, (中文(简体) ), gradientStops |
| 摄影 | checkPhotoReview |
| 语义 | semantic, (中文(简体) ), accentFork |
| 动议 | EASE, (中文(简体) ), EASE_TUPLE, (中文(简体) ), DURATION_MS, (中文(简体) ), DURATION_S, (中文(简体) ), SPRING, (中文(简体) ), SCALE, (中文(简体) ), exitDuration, (中文(简体) ), shouldAnimate |
| 类型 | fluidType, (中文(简体) ), fluidClamp, (中文(简体) ), typeFeatureTokens, (中文(简体) ), HOUSE_TYPE, (中文(简体) ), TYPE_STEPS |
| 空间 | fluidSpace, (中文(简体) ), sectionRhythm, (中文(简体) ), SPACE_STEPS |
| 密度 | densityCss, (中文(简体) ), densityTokens, (中文(简体) ), DENSITIES |
| 限制 | checkRestraint, (中文(简体) ), HOUSE_BUDGET |
| 尾风 | tailwindV3Preset (v3), (英语), tailwindV4Theme 编号 : craft.tailwind.css 页:1 |
| 释放 | craftTokens, (中文(简体) ), emitCss, (中文(简体) ), motionTokens |
| 字符 | scanSource, (中文(简体) ), checkCopy, (中文(简体) ), formatReport, (中文(简体) ), CATALOGUE, (中文(简体) ), CATALOGUE_VERSION, (中文(简体) ), catalogueTable, (中文(简体) ), runTell, (中文(简体) ), tellById |
| 字符颜色 | parseColour, (中文(简体) ), findColours, (中文(简体) ), isAiViolet, (中文(简体) ), isCream, (中文(简体) ), AI_VIOLET |
| 字符列表 | REFLEX_FONTS_1, (中文(简体) ), REFLEX_FONTS_2, (中文(简体) ), SHADCN_PRIMITIVES, (中文(简体) ), AI_WORDS, (中文(简体) ), STOCK_PHRASES, (中文(简体) ), REVEAL_LIMIT, (中文(简体) ), PILL_LIMIT, (中文(简体) ), SHADCN_LIMIT |
许可证
阿帕奇 - 2.0
通过设计审查,比较拟议的旋转木马用途 comparisons; 共享
部件名称不再证明重复 。 较小规模的执行不会
自动选择更好的设计。 受保护的中继审查可保留
报告时明确标明出版物资产 publicationReady: false。 。 。 .
见CHARACTER.md,“背景和从后一结果中学习”.
开启相片被选为渲染相序:在填充幻灯片计数或覆盖每项服务之前,对其质量和收成进行比较. 见 选择其位置在序列中的照片 一个客户端的开机照片的后续 及其限制.