@domandigital/craft 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/licences.json ADDED
@@ -0,0 +1,104 @@
1
+ {
2
+ "licences": [
3
+ {
4
+ "name": "Basteleur",
5
+ "subject": "face",
6
+ "licence": "OFL-1.1",
7
+ "multiClient": "yes",
8
+ "checked": "2026-09-24",
9
+ "source": "https://velvetyne.fr/fonts/basteleur/",
10
+ "note": "Velvetyne, designed by Keussel. Keep the OFL notice with the font files."
11
+ },
12
+ {
13
+ "name": "Gulax",
14
+ "subject": "face",
15
+ "licence": "OFL-1.1",
16
+ "multiClient": "yes",
17
+ "checked": "2026-09-24",
18
+ "source": "https://velvetyne.fr/fonts/gulax/",
19
+ "note": "Velvetyne. Keep the OFL notice with the font files."
20
+ },
21
+ {
22
+ "name": "Le Murmure",
23
+ "subject": "face",
24
+ "licence": "OFL-1.1",
25
+ "multiClient": "yes",
26
+ "checked": "2026-09-24",
27
+ "source": "https://velvetyne.fr/fonts/le-murmure/",
28
+ "note": "Velvetyne. Keep the OFL notice with the font files."
29
+ },
30
+ {
31
+ "name": "Blaze Type",
32
+ "subject": "foundry",
33
+ "licence": "commercial",
34
+ "multiClient": "per-site",
35
+ "cap": 10,
36
+ "checked": "2026-09-24",
37
+ "source": "https://blazetype.eu/eula",
38
+ "note": "The EULA sells a professional licence for 1 to 10 websites, and lets an agency buy in a client's name at the listed price. Its /license page says one licence covers every domain; the EULA is the contract, so buy per client."
39
+ },
40
+ {
41
+ "name": "Power Type",
42
+ "subject": "foundry",
43
+ "licence": "commercial",
44
+ "multiClient": "unverified",
45
+ "checked": "2026-09-24",
46
+ "source": "https://power-type.com/eula",
47
+ "note": "Research on 2026-09-11 reported a Super License capped at 10 self-hosted domains. The EULA page did not load when checked; read it before relying on the cap."
48
+ },
49
+ {
50
+ "name": "Grilli Type",
51
+ "subject": "foundry",
52
+ "licence": "commercial",
53
+ "multiClient": "per-site",
54
+ "checked": "2026-09-24",
55
+ "source": "https://www.grillitype.com/information",
56
+ "note": "Web licences cover any number of domains controlled by the licensee, priced by monthly visitors, so a client site needs the client's own licence. Unlimited tiers start at $10,000 per style."
57
+ },
58
+ {
59
+ "name": "Phosphor",
60
+ "subject": "icons",
61
+ "licence": "MIT",
62
+ "multiClient": "yes",
63
+ "checked": "2026-09-24",
64
+ "source": "https://github.com/phosphor-icons/core/blob/main/LICENSE",
65
+ "note": "Six weights. The icon-tile tells treat it exactly as they treat Lucide: the library is not the tell, the tinted tile is."
66
+ },
67
+ {
68
+ "name": "Tabler Icons",
69
+ "subject": "icons",
70
+ "licence": "MIT",
71
+ "multiClient": "yes",
72
+ "checked": "2026-09-24",
73
+ "source": "https://github.com/tabler/tabler-icons/blob/main/LICENSE",
74
+ "note": "One stroke grid across the set."
75
+ },
76
+ {
77
+ "name": "Iconoir",
78
+ "subject": "icons",
79
+ "licence": "MIT",
80
+ "multiClient": "yes",
81
+ "checked": "2026-09-24",
82
+ "source": "https://github.com/iconoir-icons/iconoir/blob/main/LICENSE",
83
+ "note": "Smaller set, no paid tier."
84
+ },
85
+ {
86
+ "name": "Unicons",
87
+ "subject": "icons",
88
+ "licence": "IconScout Simple License",
89
+ "multiClient": "yes",
90
+ "checked": "2026-09-24",
91
+ "source": "https://github.com/Iconscout/unicons/blob/master/LICENSE",
92
+ "note": "IconScout's free set, personal and commercial use, attribution optional."
93
+ },
94
+ {
95
+ "name": "IconScout premium",
96
+ "subject": "icons",
97
+ "licence": "commercial",
98
+ "multiClient": "per-site",
99
+ "checked": "2026-09-24",
100
+ "source": "https://iconscout.com/licenses",
101
+ "note": "Each licence covers a single end product. Never in a tool, template or shared kit (create-site, craft, a house component library), even modified. Record the assets each site uses. Assets come from different contributors, so take one site's set from one contributor."
102
+ }
103
+ ]
104
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@domandigital/craft",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "description": "The Doman Digital house craft standard as numbers: OKLCh colour ramps that snap to existing anchors, derived semantic tokens with measured WCAG and APCA contrast, one shared motion vocabulary for CSS and JS, and a base stylesheet. Zero dependencies.",
6
6
  "license": "Apache-2.0",
@@ -8,21 +8,28 @@
8
8
  "main": "dist/index.cjs",
9
9
  "module": "dist/index.js",
10
10
  "types": "dist/index.d.ts",
11
+ "sideEffects": [
12
+ "./css/*.css"
13
+ ],
11
14
  "bin": {
12
15
  "craft": "dist/cli.js"
13
16
  },
14
17
  "exports": {
15
18
  ".": {
16
- "types": "./dist/index.d.ts",
17
- "import": "./dist/index.js",
19
+ "import": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
18
23
  "require": {
19
24
  "types": "./dist/index.d.cts",
20
25
  "default": "./dist/index.cjs"
21
26
  }
22
27
  },
23
28
  "./audit": {
24
- "types": "./dist/audit.d.ts",
25
- "import": "./dist/audit.js",
29
+ "import": {
30
+ "types": "./dist/audit.d.ts",
31
+ "default": "./dist/audit.js"
32
+ },
26
33
  "require": {
27
34
  "types": "./dist/audit.d.cts",
28
35
  "default": "./dist/audit.cjs"
@@ -43,6 +50,7 @@
43
50
  "README.md",
44
51
  "STANDARD.md",
45
52
  "word-lists.json",
53
+ "licences.json",
46
54
  "css",
47
55
  "dist"
48
56
  ],
@@ -52,7 +60,7 @@
52
60
  "vitest": "^2.1.9"
53
61
  },
54
62
  "engines": {
55
- "node": ">=20"
63
+ "node": ">=22.12"
56
64
  },
57
65
  "repository": {
58
66
  "type": "git",
@@ -79,6 +87,6 @@
79
87
  "build": "tsup",
80
88
  "typecheck": "tsc --noEmit",
81
89
  "test": "vitest run",
82
- "docs": "tsup && node scripts/write-catalogue.mjs && node scripts/write-word-lists.mjs"
90
+ "docs": "tsup && node scripts/write-catalogue.mjs && node scripts/write-word-lists.mjs && node scripts/write-licences.mjs"
83
91
  }
84
92
  }
package/word-lists.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "catalogueVersion": "2026.09.8",
2
+ "catalogueVersion": "2026.09.9",
3
3
  "lists": {
4
4
  "aiWords": [
5
5
  "tapestry",
@@ -1,112 +0,0 @@
1
- import {
2
- snapshotUrl
3
- } from "./chunk-TSKRBIOC.js";
4
- import {
5
- describeTypicality,
6
- loadNull,
7
- typicality
8
- } from "./chunk-APO4BT2F.js";
9
- import {
10
- SOURCE_FILE,
11
- finish,
12
- loadExceptions,
13
- parseFlags,
14
- readPaths
15
- } from "./chunk-JKIDWHG3.js";
16
- import {
17
- fingerprint
18
- } from "./chunk-QMYERCBB.js";
19
- import {
20
- SNAPSHOT_VERSION,
21
- auditSnapshot,
22
- scanSource
23
- } from "./chunk-3NGWXZZE.js";
24
-
25
- // src/audit/cli.ts
26
- import { existsSync, readFileSync, writeFileSync } from "fs";
27
- import { resolve } from "path";
28
- var fmt = (o) => o ? `oklch(${o.l.toFixed(3)} ${o.c.toFixed(3)} ${o.h.toFixed(1)})` : "none";
29
- function describeFingerprint(fp) {
30
- return [
31
- "Fingerprint",
32
- ` accent ${fmt(fp.accent)}`,
33
- ` ground ${fmt(fp.ground)}`,
34
- ` display ${fp.display.family} (${fp.display.class})`,
35
- ` body ${fp.body.family} (${fp.body.class})`,
36
- ` roundness ${fp.roundness === null ? "no buttons" : fp.roundness.toFixed(2)}`,
37
- ` motion ${Math.round(fp.motion * 100)}% of sections below the fold reveal on scroll`,
38
- ` effects ${fp.effects.join(", ") || "none"}`,
39
- ` layout ${fp.layout.join(" > ") || "none"}`
40
- ].join("\n");
41
- }
42
- function merge(a, b) {
43
- const byTell = { ...a.summary.byTell };
44
- for (const [k, v] of Object.entries(b.summary.byTell)) byTell[k] = (byTell[k] ?? 0) + v;
45
- return {
46
- catalogueVersion: a.catalogueVersion,
47
- findings: [...a.findings, ...b.findings],
48
- rejectedExceptions: a.rejectedExceptions,
49
- excepted: [...a.excepted, ...b.excepted],
50
- suppressed: [...a.suppressed, ...b.suppressed],
51
- summary: {
52
- files: a.summary.files + b.summary.files,
53
- findings: a.summary.findings + b.summary.findings,
54
- byGeneration: { 1: a.summary.byGeneration[1] + b.summary.byGeneration[1], 2: a.summary.byGeneration[2] + b.summary.byGeneration[2], 3: a.summary.byGeneration[3] + b.summary.byGeneration[3] },
55
- byTell,
56
- blocking: a.summary.blocking + b.summary.blocking
57
- }
58
- };
59
- }
60
- function readSnapshot(path) {
61
- const data = JSON.parse(readFileSync(path, "utf8"));
62
- if (data.version !== SNAPSHOT_VERSION) throw new Error(`${path} is snapshot version ${String(data.version)}; this craft reads ${SNAPSHOT_VERSION}`);
63
- return data;
64
- }
65
- async function runAudit(command, args, io) {
66
- try {
67
- const flags = parseFlags(args);
68
- if (typeof flags === "string") throw new Error(flags);
69
- const target = flags.positional[0];
70
- if (!target) throw new Error(`usage: craft ${command} <url${command === "audit" ? " | snapshot.json" : ""}>`);
71
- const viewport = flags.width || flags.height ? { width: Number(flags.width ?? 1440), height: Number(flags.height ?? 900) } : void 0;
72
- const local = resolve(io.cwd, target);
73
- const snapshot = command === "audit" && /\.json$/i.test(target) && existsSync(local) ? readSnapshot(local) : await snapshotUrl(target, { viewport });
74
- if (flags.out) writeFileSync(resolve(io.cwd, flags.out), `${JSON.stringify(snapshot, null, 2)}
75
- `);
76
- if (command === "snapshot") {
77
- if (!flags.out) io.out(JSON.stringify(snapshot, null, 2));
78
- else io.out(`craft snapshot: ${snapshot.url} saved to ${flags.out}`);
79
- return 0;
80
- }
81
- const exceptions = loadExceptions(flags, flags.repo ? resolve(io.cwd, flags.repo) : io.cwd);
82
- let report = auditSnapshot(snapshot, { exceptions });
83
- if (flags.repo) {
84
- const repo = resolve(io.cwd, flags.repo);
85
- report = merge(scanSource(readPaths(["."], repo, SOURCE_FILE), { exceptions }), report);
86
- }
87
- const fp = fingerprint(snapshot);
88
- const nulls = flags.null ? flags.null.split(",").map((p) => loadNull(p.trim(), io.cwd)) : [];
89
- const typical = nulls.length ? typicality(fp, nulls.flatMap((m, i) => m.runs.map((r) => nulls.length > 1 ? { ...r, id: `${i + 1}/${r.id}` } : r))) : null;
90
- if (flags.json) {
91
- io.out(JSON.stringify({ report, fingerprint: fp, typicality: typical, snapshot: flags.out ?? null }, null, 2));
92
- return report.summary.blocking > 0 || flags.strict && report.summary.findings > 0 ? 1 : 0;
93
- }
94
- const code = finish(report, { ...flags, json: false }, `craft audit ${snapshot.url}`, io);
95
- io.out("");
96
- io.out(describeFingerprint(fp));
97
- if (typical) {
98
- io.out("");
99
- io.out(describeTypicality(typical, nulls.reduce((s, m) => s + m.runs.length, 0), nulls.length));
100
- }
101
- return code;
102
- } catch (error) {
103
- io.err(`craft: ${error.message}`);
104
- return 2;
105
- }
106
- }
107
-
108
- export {
109
- describeFingerprint,
110
- merge,
111
- runAudit
112
- };
@@ -1,15 +0,0 @@
1
- import {
2
- describeFingerprint,
3
- merge,
4
- runAudit
5
- } from "./chunk-U2JTFQKO.js";
6
- import "./chunk-TSKRBIOC.js";
7
- import "./chunk-APO4BT2F.js";
8
- import "./chunk-JKIDWHG3.js";
9
- import "./chunk-QMYERCBB.js";
10
- import "./chunk-3NGWXZZE.js";
11
- export {
12
- describeFingerprint,
13
- merge,
14
- runAudit
15
- };
@@ -1,16 +0,0 @@
1
- import {
2
- formatMatches,
3
- formatPairs,
4
- loadEstate,
5
- runEstate
6
- } from "./chunk-2NQFIDLE.js";
7
- import "./chunk-APO4BT2F.js";
8
- import "./chunk-JKIDWHG3.js";
9
- import "./chunk-QMYERCBB.js";
10
- import "./chunk-3NGWXZZE.js";
11
- export {
12
- formatMatches,
13
- formatPairs,
14
- loadEstate,
15
- runEstate
16
- };