@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/CHANGELOG.md +35 -0
- package/CHARACTER.md +9 -1
- package/COPY.md +6 -2
- package/README.md +40 -0
- package/dist/{audit-EGDNWSQB.js → audit-5QWFLZ6L.js} +6 -3
- package/dist/audit.cjs +279 -16
- package/dist/audit.d.cts +81 -4
- package/dist/audit.d.ts +81 -4
- package/dist/audit.js +278 -16
- package/dist/{chunk-3NGWXZZE.js → chunk-AL6MRG6V.js} +40 -3
- package/dist/{chunk-2NQFIDLE.js → chunk-CDAJUS5U.js} +13 -11
- package/dist/{chunk-JKIDWHG3.js → chunk-J3QUROJ5.js} +299 -32
- package/dist/chunk-JYNXGCYZ.js +75 -0
- package/dist/{chunk-APO4BT2F.js → chunk-LHGY43LL.js} +11 -7
- package/dist/chunk-PU5G5DUC.js +206 -0
- package/dist/{chunk-QMYERCBB.js → chunk-PZ4MF2VV.js} +19 -7
- package/dist/{chunk-JWHC67ZS.js → chunk-S3NZAVU6.js} +121 -1
- package/dist/{chunk-TSKRBIOC.js → chunk-ULPI335S.js} +181 -13
- package/dist/chunk-ZKVJ7K6X.js +19 -0
- package/dist/cli-2DY3V3SF.js +17 -0
- package/dist/{cli-PRWTNFVP.js → cli-C3JLFXMG.js} +5 -4
- package/dist/cli-QM2AQQMF.js +19 -0
- package/dist/{cli-ADQQURNR.js → cli-ZB2VJ7CY.js} +25 -17
- package/dist/{cli-2WBGTBKD.js → cli-ZPJIWVEP.js} +15 -80
- package/dist/cli.js +2 -2
- package/dist/index.cjs +486 -9
- package/dist/index.d.cts +364 -6
- package/dist/index.d.ts +364 -6
- package/dist/index.js +462 -9
- package/licences.json +104 -0
- package/package.json +15 -7
- package/word-lists.json +1 -1
- package/dist/chunk-U2JTFQKO.js +0 -112
- package/dist/cli-EK3GSAOW.js +0 -15
- package/dist/cli-VQUNNIZM.js +0 -16
package/dist/index.d.cts
CHANGED
|
@@ -706,7 +706,13 @@ declare const DENSITY_NAMES: DensityName[];
|
|
|
706
706
|
* to a report and judged again later without a browser. Capturing one needs a
|
|
707
707
|
* browser (see `@domandigital/craft/audit`); judging one does not.
|
|
708
708
|
*/
|
|
709
|
-
|
|
709
|
+
/**
|
|
710
|
+
* 2 adds `role` and `geometry` per section, `rhythmVariance` for the page and
|
|
711
|
+
* the screenshot measures in `visual`. All four are optional: a version 1
|
|
712
|
+
* snapshot reads as version 2 without them (see `readSnapshot`), and nothing
|
|
713
|
+
* that judged a v1 snapshot judges it differently.
|
|
714
|
+
*/
|
|
715
|
+
declare const SNAPSHOT_VERSION = 2;
|
|
710
716
|
interface SnapshotColour {
|
|
711
717
|
/** `rgb(r, g, b)` or `rgba(r, g, b, a)`, as the browser computed it. */
|
|
712
718
|
value: string;
|
|
@@ -745,6 +751,27 @@ interface SnapshotControl {
|
|
|
745
751
|
text: string;
|
|
746
752
|
}
|
|
747
753
|
type SectionKind = "hero" | "logos" | "stats" | "cards" | "marquee" | "text" | "other";
|
|
754
|
+
/**
|
|
755
|
+
* What a section is for, finer than `kind`. `kind` keeps its version 1
|
|
756
|
+
* meaning because the rendered tells, the null models and the estate were
|
|
757
|
+
* calibrated on it; `role` is what component-level comparison reads.
|
|
758
|
+
*/
|
|
759
|
+
type SectionRole = SectionKind | "cta-band" | "footer-cta" | "pricing" | "testimonials" | "faq" | "process" | "features" | "team" | "contact";
|
|
760
|
+
/** How a section is laid out, measured, not judged. */
|
|
761
|
+
interface SectionGeometry {
|
|
762
|
+
/** Share of the section's text blocks that are centred, 0 to 1. */
|
|
763
|
+
centredShare: number;
|
|
764
|
+
/** Content area balance about the vertical centre line: 1 mirror-even, 0 all on one side. */
|
|
765
|
+
mirrorSymmetry: number;
|
|
766
|
+
/** Share of the section's area with no text, image or control in it, 0 to 1. */
|
|
767
|
+
whitespaceRatio: number;
|
|
768
|
+
/** Width the content spans, over the viewport width. */
|
|
769
|
+
contentWidthRatio: number;
|
|
770
|
+
/** The painted background behind the section, as computed. */
|
|
771
|
+
background: string;
|
|
772
|
+
/** Buttons and button-styled links in the section. */
|
|
773
|
+
controls: number;
|
|
774
|
+
}
|
|
748
775
|
interface SnapshotSection {
|
|
749
776
|
top: number;
|
|
750
777
|
height: number;
|
|
@@ -757,6 +784,26 @@ interface SnapshotSection {
|
|
|
757
784
|
iconCards: number;
|
|
758
785
|
/** Hidden at load, waiting for a scroll to reveal it. */
|
|
759
786
|
hiddenAtLoad: boolean;
|
|
787
|
+
/** Version 2. */
|
|
788
|
+
role?: SectionRole;
|
|
789
|
+
/** Version 2. */
|
|
790
|
+
geometry?: SectionGeometry;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Measures of the rendered pixels, from a full-page screenshot (capped at
|
|
794
|
+
* `height`). None of them passes or fails anything: they describe.
|
|
795
|
+
*/
|
|
796
|
+
interface SnapshotVisual {
|
|
797
|
+
/** Hasler and Süsstrunk (2003) colourfulness, M = σ_rgyb + 0.3 μ_rgyb, on 0-255 channels. Grey is 0. */
|
|
798
|
+
colourfulness: number;
|
|
799
|
+
/** Share of sampled pixels on a luminance edge: a complexity proxy, 0 to 1. */
|
|
800
|
+
edgeDensity: number;
|
|
801
|
+
/** 1 minus the mean luminance difference between each pixel and its left-right mirror, 0 to 1. */
|
|
802
|
+
symmetry: number;
|
|
803
|
+
width: number;
|
|
804
|
+
height: number;
|
|
805
|
+
/** Pixels actually read: large pages are sampled on a grid. */
|
|
806
|
+
sampled: number;
|
|
760
807
|
}
|
|
761
808
|
interface SnapshotGradient {
|
|
762
809
|
/** Colour stops, as computed. */
|
|
@@ -811,6 +858,12 @@ interface Snapshot {
|
|
|
811
858
|
sections: SnapshotSection[];
|
|
812
859
|
effects: SnapshotEffects;
|
|
813
860
|
motion: SnapshotMotion;
|
|
861
|
+
/** Version 2: coefficient of variation of the section heights. Null with fewer than two sections. */
|
|
862
|
+
rhythmVariance?: number | null;
|
|
863
|
+
/** Version 2: absent when the page could not be screenshotted. */
|
|
864
|
+
visual?: SnapshotVisual;
|
|
865
|
+
/** Set when a version 1 snapshot was read and upgraded in memory. */
|
|
866
|
+
migratedFrom?: 1;
|
|
814
867
|
/** The design-system measures trawl has collected since v7, kept so it can switch to this. */
|
|
815
868
|
metrics: {
|
|
816
869
|
fontSizes: number[];
|
|
@@ -1031,7 +1084,7 @@ interface CheckReport {
|
|
|
1031
1084
|
* Bumped whenever an entry is added, removed or its detection changes, so a
|
|
1032
1085
|
* report can say which list it was judged against.
|
|
1033
1086
|
*/
|
|
1034
|
-
declare const CATALOGUE_VERSION = "2026.09.
|
|
1087
|
+
declare const CATALOGUE_VERSION = "2026.09.9";
|
|
1035
1088
|
declare const CATALOGUE: readonly Tell[];
|
|
1036
1089
|
declare function tellById(id: string): Tell | undefined;
|
|
1037
1090
|
/**
|
|
@@ -1112,6 +1165,31 @@ interface HouseRule {
|
|
|
1112
1165
|
declare const HOUSE: Readonly<Record<string, HouseRule>>;
|
|
1113
1166
|
/** The house rule for a copy tell. Unknown ids are review, so a new tell never blocks. */
|
|
1114
1167
|
declare function houseRule(id: string, name?: string): HouseRule;
|
|
1168
|
+
/**
|
|
1169
|
+
* What a repo may and may not do to the house gate.
|
|
1170
|
+
*
|
|
1171
|
+
* A repo can raise a tell's severity in `craft.config.json`, or except a
|
|
1172
|
+
* design tell in `art-direction.json`. It cannot lower the blocking tier: a
|
|
1173
|
+
* `warn` or `off` there, or an exception naming a blocking tell, would let one
|
|
1174
|
+
* line and one sentence switch off a rule COPY.md calls not a judgment call,
|
|
1175
|
+
* in every commit that repo makes. `chatbot-residue` is the sharpest case: it
|
|
1176
|
+
* is evidence of a paste, and no client reason makes a paste acceptable.
|
|
1177
|
+
*
|
|
1178
|
+
* A genuine one-off (a style guide quoting an em dash, a testimonial) takes
|
|
1179
|
+
* `copy-ok` on its line: local, in the diff a reviewer reads, and listed in
|
|
1180
|
+
* every report. A rule that is wrong for everyone is changed here.
|
|
1181
|
+
*/
|
|
1182
|
+
declare const HOUSE_LOCKED = "the house blocking tier cannot be lowered by a repo. A genuine one-off takes copy-ok on its line; a rule that is wrong is changed in craft's house.ts and COPY.md";
|
|
1183
|
+
declare function holdHouseBlocks<E extends {
|
|
1184
|
+
tell: string;
|
|
1185
|
+
}, O extends {
|
|
1186
|
+
level: string;
|
|
1187
|
+
}>(exceptions: E[], severity: Record<string, O>): {
|
|
1188
|
+
exceptions: E[];
|
|
1189
|
+
severity: Record<string, O>;
|
|
1190
|
+
refused: E[];
|
|
1191
|
+
refusedSeverity: string[];
|
|
1192
|
+
};
|
|
1115
1193
|
|
|
1116
1194
|
/**
|
|
1117
1195
|
* Protected facts: what a rewrite must never lose or invent.
|
|
@@ -1188,6 +1266,190 @@ declare function namedSources(sentence: string): string[];
|
|
|
1188
1266
|
declare function findClaims(files: SourceFile[]): ClaimsReport;
|
|
1189
1267
|
declare function formatClaims(report: ClaimsReport, label?: string): string;
|
|
1190
1268
|
|
|
1269
|
+
/**
|
|
1270
|
+
* Baselines: adopt craft on a repo that already has findings, and fail only
|
|
1271
|
+
* on new ones.
|
|
1272
|
+
*
|
|
1273
|
+
* A finding is keyed on its tell, its path and a hash of its excerpt with the
|
|
1274
|
+
* whitespace collapsed, never on its line: an edit above a known finding
|
|
1275
|
+
* moves it, and a moved finding is not a new one. Keys are counted, so a file
|
|
1276
|
+
* with two identical findings and a baseline of one reports the second.
|
|
1277
|
+
*
|
|
1278
|
+
* Pure. The command line reads and writes the file.
|
|
1279
|
+
*/
|
|
1280
|
+
|
|
1281
|
+
declare const BASELINE_VERSION = 1;
|
|
1282
|
+
interface BaselineEntry {
|
|
1283
|
+
tell: string;
|
|
1284
|
+
path: string;
|
|
1285
|
+
/** FNV-1a of the excerpt, whitespace collapsed. */
|
|
1286
|
+
excerpt: string;
|
|
1287
|
+
count: number;
|
|
1288
|
+
}
|
|
1289
|
+
interface Baseline {
|
|
1290
|
+
version: typeof BASELINE_VERSION;
|
|
1291
|
+
catalogueVersion: string;
|
|
1292
|
+
entries: BaselineEntry[];
|
|
1293
|
+
}
|
|
1294
|
+
/** The key a finding is matched on. Also the SARIF partial fingerprint. */
|
|
1295
|
+
declare function findingKey(f: Finding): string;
|
|
1296
|
+
/** Every finding in a report, as a baseline. */
|
|
1297
|
+
declare function createBaseline(report: CheckReport): Baseline;
|
|
1298
|
+
/** Validate a parsed baseline file. */
|
|
1299
|
+
declare function parseBaseline(data: unknown, source?: string): Baseline;
|
|
1300
|
+
/**
|
|
1301
|
+
* The report without the findings the baseline already knows about.
|
|
1302
|
+
* `baselined` is how many were removed, so the output can say so: a
|
|
1303
|
+
* baseline that hides findings silently is a hole.
|
|
1304
|
+
*/
|
|
1305
|
+
declare function applyBaseline(report: CheckReport, baseline: Baseline): CheckReport & {
|
|
1306
|
+
baselined: number;
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* `craft.config.json`: what a repo tells craft about itself.
|
|
1311
|
+
*
|
|
1312
|
+
* Pure: the command line reads the file and hands the parsed JSON here. The
|
|
1313
|
+
* design choices live in `art-direction.json`; this file is about the tool:
|
|
1314
|
+
* which paths are not the site, where the copy is, and a repo's own decisions
|
|
1315
|
+
* about a tell's severity.
|
|
1316
|
+
*
|
|
1317
|
+
* {
|
|
1318
|
+
* "ignore": ["docs/archive/**", "*.stories.tsx"],
|
|
1319
|
+
* "copyPaths": ["content", "src/app"],
|
|
1320
|
+
* "severity": {
|
|
1321
|
+
* "ai-violet": { "level": "off", "because": "The client's shopfront has been this violet since 1998." },
|
|
1322
|
+
* "em-dash": { "level": "block", "because": "House style for this client bans them outright." }
|
|
1323
|
+
* }
|
|
1324
|
+
* }
|
|
1325
|
+
*
|
|
1326
|
+
* A severity change needs a `because`, like an exception in
|
|
1327
|
+
* `art-direction.json`, and for the same reason: a tell switched off with no
|
|
1328
|
+
* reason is a guard nobody can audit. `off` becomes an exception, so the
|
|
1329
|
+
* report still lists what it silenced.
|
|
1330
|
+
*/
|
|
1331
|
+
|
|
1332
|
+
type SeverityLevel = "warn" | "block" | "off";
|
|
1333
|
+
interface SeverityOverride {
|
|
1334
|
+
level: SeverityLevel;
|
|
1335
|
+
because: string;
|
|
1336
|
+
}
|
|
1337
|
+
interface CraftConfig {
|
|
1338
|
+
/** Glob patterns for paths that are not the site. Added to `DEFAULT_IGNORE`. */
|
|
1339
|
+
ignore: string[];
|
|
1340
|
+
/** Where `craft copy` looks when no path is given. */
|
|
1341
|
+
copyPaths?: string[];
|
|
1342
|
+
severity: Record<string, SeverityOverride>;
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* Agent and tool folders: instructions for the people and models building
|
|
1346
|
+
* the site, not copy a visitor reads. Always ignored by a directory walk.
|
|
1347
|
+
*/
|
|
1348
|
+
declare const DEFAULT_IGNORE: string[];
|
|
1349
|
+
/**
|
|
1350
|
+
* Validate a parsed `craft.config.json`. Throws with the file name and the
|
|
1351
|
+
* key at fault: a config that half-applies is worse than one that stops the
|
|
1352
|
+
* run.
|
|
1353
|
+
*/
|
|
1354
|
+
declare function parseCraftConfig(data: unknown, knownTells: ReadonlySet<string>, source?: string): CraftConfig;
|
|
1355
|
+
/**
|
|
1356
|
+
* A glob as a regular expression over a `/`-separated relative path.
|
|
1357
|
+
* `*` is one segment's worth, `**` any depth, `?` one character. A pattern
|
|
1358
|
+
* with no `/` matches a file or folder of that name anywhere; otherwise it is
|
|
1359
|
+
* anchored at the repo root. Anything under a matched folder matches too.
|
|
1360
|
+
*/
|
|
1361
|
+
declare function globToRegExp(glob: string): RegExp;
|
|
1362
|
+
/** A matcher for a set of globs. Paths are normalised to `/` before matching. */
|
|
1363
|
+
declare function ignoreMatcher(patterns: string[]): (path: string) => boolean;
|
|
1364
|
+
/** `off` entries, as exceptions: applied, and listed as silenced in the report. */
|
|
1365
|
+
declare function severityExceptions(config: CraftConfig): TellException[];
|
|
1366
|
+
/** `warn` and `block` entries, applied to a finished report. */
|
|
1367
|
+
declare function applySeverity(report: CheckReport, config: CraftConfig): CheckReport;
|
|
1368
|
+
|
|
1369
|
+
/**
|
|
1370
|
+
* A report as SARIF 2.1.0, for GitHub code scanning and any other tool that
|
|
1371
|
+
* reads it. Pure.
|
|
1372
|
+
*
|
|
1373
|
+
* One rule per tell the report names, carrying the tell's `why` and `fix`.
|
|
1374
|
+
* `block` findings are errors, `warn` findings warnings. A finding on a
|
|
1375
|
+
* rendered page has the URL as its location and no line: GitHub code
|
|
1376
|
+
* scanning only shows results in files of the repo, so those appear in the
|
|
1377
|
+
* SARIF file but not in the Security tab.
|
|
1378
|
+
*/
|
|
1379
|
+
|
|
1380
|
+
interface SarifTell {
|
|
1381
|
+
id: string;
|
|
1382
|
+
name: string;
|
|
1383
|
+
why: string;
|
|
1384
|
+
fix: string;
|
|
1385
|
+
}
|
|
1386
|
+
interface SarifOptions {
|
|
1387
|
+
/** The catalogue, for each rule's description. */
|
|
1388
|
+
tells: readonly SarifTell[];
|
|
1389
|
+
/** Where a reader learns more. */
|
|
1390
|
+
informationUri?: string;
|
|
1391
|
+
}
|
|
1392
|
+
declare function toSarif(report: CheckReport, options: SarifOptions): {
|
|
1393
|
+
$schema: string;
|
|
1394
|
+
version: "2.1.0";
|
|
1395
|
+
runs: {
|
|
1396
|
+
tool: {
|
|
1397
|
+
driver: {
|
|
1398
|
+
name: string;
|
|
1399
|
+
version: string;
|
|
1400
|
+
informationUri: string;
|
|
1401
|
+
rules: {
|
|
1402
|
+
fullDescription?: {
|
|
1403
|
+
text: string;
|
|
1404
|
+
} | undefined;
|
|
1405
|
+
help?: {
|
|
1406
|
+
text: string;
|
|
1407
|
+
} | undefined;
|
|
1408
|
+
id: string;
|
|
1409
|
+
name: string;
|
|
1410
|
+
shortDescription: {
|
|
1411
|
+
text: string;
|
|
1412
|
+
};
|
|
1413
|
+
}[];
|
|
1414
|
+
};
|
|
1415
|
+
};
|
|
1416
|
+
results: {
|
|
1417
|
+
ruleId: string;
|
|
1418
|
+
ruleIndex: number;
|
|
1419
|
+
level: "error" | "warning";
|
|
1420
|
+
message: {
|
|
1421
|
+
text: string;
|
|
1422
|
+
};
|
|
1423
|
+
locations: {
|
|
1424
|
+
physicalLocation: {
|
|
1425
|
+
region?: {
|
|
1426
|
+
startLine: number;
|
|
1427
|
+
snippet: {
|
|
1428
|
+
text: string;
|
|
1429
|
+
};
|
|
1430
|
+
} | undefined;
|
|
1431
|
+
artifactLocation: {
|
|
1432
|
+
uri: string;
|
|
1433
|
+
};
|
|
1434
|
+
};
|
|
1435
|
+
}[];
|
|
1436
|
+
partialFingerprints: {
|
|
1437
|
+
"craftFinding/v1": string;
|
|
1438
|
+
};
|
|
1439
|
+
}[];
|
|
1440
|
+
}[];
|
|
1441
|
+
};
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* The `--json` contract. Every JSON document a craft command prints carries
|
|
1445
|
+
* `schemaVersion`, so a script reading it can refuse a shape it does not
|
|
1446
|
+
* know instead of misreading it. Bump it when a field is removed or changes
|
|
1447
|
+
* meaning; adding a field is not a bump.
|
|
1448
|
+
*/
|
|
1449
|
+
declare const JSON_SCHEMA_VERSION = 1;
|
|
1450
|
+
/** A command's JSON output, versioned. */
|
|
1451
|
+
declare function toJson(data: object): string;
|
|
1452
|
+
|
|
1191
1453
|
/**
|
|
1192
1454
|
* The rendered detection path for tells that can be seen on a live page.
|
|
1193
1455
|
*
|
|
@@ -1227,6 +1489,41 @@ type FontClass = "serif" | "sans" | "mono" | "script" | "system";
|
|
|
1227
1489
|
declare function normaliseFamily(raw: string): string;
|
|
1228
1490
|
declare function fontClass(family: string): FontClass;
|
|
1229
1491
|
|
|
1492
|
+
/**
|
|
1493
|
+
* Read a saved snapshot of any version this craft understands. Pure.
|
|
1494
|
+
*
|
|
1495
|
+
* Version 2 only added optional fields, so a version 1 snapshot is a valid
|
|
1496
|
+
* version 2 snapshot without them. It is marked `migratedFrom: 1` so a report
|
|
1497
|
+
* can say which measures it lacks, rather than reading their absence as zero.
|
|
1498
|
+
*/
|
|
1499
|
+
|
|
1500
|
+
declare const READABLE_SNAPSHOT_VERSIONS: readonly [1, 2];
|
|
1501
|
+
declare function readSnapshot(data: unknown, source?: string): Snapshot;
|
|
1502
|
+
|
|
1503
|
+
/**
|
|
1504
|
+
* Measures of a screenshot's pixels. Pure: RGBA in, numbers out, no decoder
|
|
1505
|
+
* and no browser, so it is tested on synthetic images.
|
|
1506
|
+
*
|
|
1507
|
+
* Only measures that need no model are here, after Miniukovich and De Angeli
|
|
1508
|
+
* (2015, "Computation of interface aesthetics"): colourfulness, an edge-density
|
|
1509
|
+
* complexity proxy, and left-right symmetry. None of them is a verdict. A
|
|
1510
|
+
* sober site and a busy one can both be decided; these say which it is.
|
|
1511
|
+
*/
|
|
1512
|
+
|
|
1513
|
+
interface RgbaImage {
|
|
1514
|
+
width: number;
|
|
1515
|
+
height: number;
|
|
1516
|
+
/** Row-major, 4 bytes a pixel. */
|
|
1517
|
+
rgba: Uint8Array;
|
|
1518
|
+
}
|
|
1519
|
+
/** A luminance step, on 0-255, that counts as an edge. About a 12% contrast change. */
|
|
1520
|
+
declare const EDGE_STEP = 32;
|
|
1521
|
+
/**
|
|
1522
|
+
* Colourfulness, edge density and symmetry. Images over `maxSamples` pixels
|
|
1523
|
+
* are read on a regular grid, and edges are taken between grid neighbours.
|
|
1524
|
+
*/
|
|
1525
|
+
declare function visualMeasures(img: RgbaImage, maxSamples?: number): SnapshotVisual;
|
|
1526
|
+
|
|
1230
1527
|
/**
|
|
1231
1528
|
* A fingerprint: the handful of choices that make a site look like itself,
|
|
1232
1529
|
* reduced to something two sites can be compared on.
|
|
@@ -1241,9 +1538,24 @@ declare function fontClass(family: string): FontClass;
|
|
|
1241
1538
|
* Pure. Built from a Snapshot, so it describes what a visitor gets.
|
|
1242
1539
|
*/
|
|
1243
1540
|
|
|
1244
|
-
|
|
1541
|
+
/**
|
|
1542
|
+
* 2 adds `sections` (role and geometry in running order). A version 1
|
|
1543
|
+
* fingerprint, or one from a version 1 snapshot, has none, and every
|
|
1544
|
+
* comparison involving it uses `layout` exactly as version 1 did, so the null
|
|
1545
|
+
* models and the estate register compare as they were calibrated until they
|
|
1546
|
+
* are re-snapshotted.
|
|
1547
|
+
*/
|
|
1548
|
+
declare const FINGERPRINT_VERSION = 2;
|
|
1549
|
+
/** One section as layout comparison sees it. */
|
|
1550
|
+
interface FingerprintSection {
|
|
1551
|
+
role: SectionRole;
|
|
1552
|
+
/** Share of centred text, 0 to 1. */
|
|
1553
|
+
centred: number;
|
|
1554
|
+
/** Content width over viewport width, 0 to 1. */
|
|
1555
|
+
width: number;
|
|
1556
|
+
}
|
|
1245
1557
|
interface Fingerprint {
|
|
1246
|
-
version:
|
|
1558
|
+
version: 1 | 2;
|
|
1247
1559
|
/** The most prominent chromatic colour: button fills first, then painted area, then text. */
|
|
1248
1560
|
accent: Oklch | null;
|
|
1249
1561
|
ground: Oklch;
|
|
@@ -1263,6 +1575,8 @@ interface Fingerprint {
|
|
|
1263
1575
|
effects: string[];
|
|
1264
1576
|
/** Section kinds in running order, hero first. */
|
|
1265
1577
|
layout: SectionKind[];
|
|
1578
|
+
/** Version 2: present when every section carries a role and geometry. */
|
|
1579
|
+
sections?: FingerprintSection[];
|
|
1266
1580
|
}
|
|
1267
1581
|
declare function fingerprint(s: Snapshot): Fingerprint;
|
|
1268
1582
|
interface FingerprintDistance {
|
|
@@ -1292,6 +1606,8 @@ declare const DISTANCE_WEIGHTS: {
|
|
|
1292
1606
|
readonly effects: 0.1;
|
|
1293
1607
|
readonly layout: 0.1;
|
|
1294
1608
|
};
|
|
1609
|
+
/** Layout distance, 0 to 1: by role and geometry when both have them, else by kind as in version 1. */
|
|
1610
|
+
declare function layoutDistance(a: Fingerprint, b: Fingerprint): number;
|
|
1295
1611
|
declare function fingerprintDistance(a: Fingerprint, b: Fingerprint): FingerprintDistance;
|
|
1296
1612
|
/**
|
|
1297
1613
|
* The nearest neighbours of a fingerprint in a set, closest first. Typicality
|
|
@@ -1361,7 +1677,7 @@ declare function isCream({ l, c, h }: Oklch): boolean;
|
|
|
1361
1677
|
/** The faces a model picks when the brief does not name one. */
|
|
1362
1678
|
declare const REFLEX_FONTS_1: readonly ["Inter", "Roboto", "Open Sans", "Poppins", "Montserrat", "Lato"];
|
|
1363
1679
|
/** What models moved to once Inter was named and banned. */
|
|
1364
|
-
declare const REFLEX_FONTS_2: readonly ["Inter Tight", "DM Sans", "Manrope", "Space Grotesk", "Plus Jakarta Sans", "Outfit", "Geist", "Sora", "Instrument Sans", "Instrument Serif", "Fraunces", "Playfair Display", "Cormorant Garamond", "DM Serif Display"];
|
|
1680
|
+
declare const REFLEX_FONTS_2: readonly ["Inter Tight", "DM Sans", "Manrope", "Space Grotesk", "Plus Jakarta Sans", "Outfit", "Geist", "Cal Sans", "Sora", "Instrument Sans", "Instrument Serif", "Fraunces", "Playfair Display", "Cormorant Garamond", "DM Serif Display"];
|
|
1365
1681
|
/** Above this many scroll reveals in one scan, reveal is the default, not a choice. */
|
|
1366
1682
|
declare const REVEAL_LIMIT = 12;
|
|
1367
1683
|
/** Above this many fully rounded shapes in one scan, the pill is the shape language by accident. */
|
|
@@ -1504,6 +1820,48 @@ declare function initDirection(input: {
|
|
|
1504
1820
|
exceptions?: ArtDirection["exceptions"];
|
|
1505
1821
|
}): ArtDirection;
|
|
1506
1822
|
|
|
1823
|
+
/**
|
|
1824
|
+
* What each face and icon set is licensed for, checked against the licensor's
|
|
1825
|
+
* own page. A face a client site ships without a licence covering that site is
|
|
1826
|
+
* a commercial risk the site owner carries, so `craft direction validate` warns
|
|
1827
|
+
* on a display or body face this register does not know, or knows only as
|
|
1828
|
+
* capped or unverified. Unverified is never a pass.
|
|
1829
|
+
*
|
|
1830
|
+
* This is a register of facts, not a shortlist. Nothing here is proposed to a
|
|
1831
|
+
* site: a face chosen because it is on this list is the agency's own reflex
|
|
1832
|
+
* font (CHARACTER.md, "Distance from the estate"). A face enters the register
|
|
1833
|
+
* after a site has chosen it for a reason and someone has read its licence.
|
|
1834
|
+
*
|
|
1835
|
+
* `licences.json` is generated from this file for tools outside the package.
|
|
1836
|
+
* Regenerate it with `pnpm --filter @domandigital/craft run docs`.
|
|
1837
|
+
*/
|
|
1838
|
+
type LicenceSubject = "face" | "foundry" | "icons";
|
|
1839
|
+
/**
|
|
1840
|
+
* Whether one purchase covers the sites Doman Digital builds for unrelated
|
|
1841
|
+
* clients. `yes`: it does. `capped`: up to `cap` sites. `per-site`: each client
|
|
1842
|
+
* site needs its own licence, in the client's name. `unverified`: nobody has
|
|
1843
|
+
* read the licensor's own terms yet.
|
|
1844
|
+
*/
|
|
1845
|
+
type MultiClient = "yes" | "capped" | "per-site" | "unverified";
|
|
1846
|
+
interface LicenceEntry {
|
|
1847
|
+
/** The family name as CSS sets it, or the foundry or icon set's own name. */
|
|
1848
|
+
name: string;
|
|
1849
|
+
subject: LicenceSubject;
|
|
1850
|
+
licence: string;
|
|
1851
|
+
multiClient: MultiClient;
|
|
1852
|
+
/** How many sites one licence covers, when `multiClient` is `capped`. */
|
|
1853
|
+
cap?: number;
|
|
1854
|
+
/** When the licensor's page was read, ISO date. */
|
|
1855
|
+
checked: string;
|
|
1856
|
+
/** The licensor's own page. Never an aggregator. */
|
|
1857
|
+
source: string;
|
|
1858
|
+
note: string;
|
|
1859
|
+
}
|
|
1860
|
+
declare const LICENCES: readonly LicenceEntry[];
|
|
1861
|
+
/** The register entry for a face, by the family name CSS sets. */
|
|
1862
|
+
declare function faceLicence(family: string): LicenceEntry | undefined;
|
|
1863
|
+
declare function licencesJson(): string;
|
|
1864
|
+
|
|
1507
1865
|
/**
|
|
1508
1866
|
* Proposing an art direction from the client's world.
|
|
1509
1867
|
*
|
|
@@ -1820,4 +2178,4 @@ declare function characterReport(input: CharacterInputs, copyTells?: Set<string>
|
|
|
1820
2178
|
|
|
1821
2179
|
declare function retrofitPlan(report: CharacterReport, direction?: ArtDirection | null): string;
|
|
1822
2180
|
|
|
1823
|
-
export { AI_PHRASES, AI_VIOLET, AI_WORDS, type AccentFork, type AccentForkOptions, type Action, type Area, type ArtDirection, BUZZWORDS, CATALOGUE, CATALOGUE_VERSION, CHOICE_KEYS, type CandidateKind, type CharacterInputs, type CharacterReport, type CheckOptions, type CheckReport, type CheckRestraintInput, type ChoiceKey, type Claim, type ClaimsReport, type ContrastCheck, type ContrastReport, type CopyTell, type CraftTokensInput, type CraftTokensResult, DENSITIES, DENSITY_NAMES, DIRECTION_VERSION, DISTANCE_WEIGHTS, DURATION_MS, DURATION_S, type DensityCssOptions, type DensityName, type DirectionChoice, type DirectionProblem, type DirectionReport, type DirectionSource, type DurationName, EASE, EASE_TUPLE, ESTATE_VERSION, EXIT_RATIO, type EaseName, type EmitCssOptions, type EstateMatch, type EstatePair, type EstateRegister, type EstateSite, FINGERPRINT_VERSION, type Fact, type FactComparison, type FactKind, type Finding, type Fingerprint, type FingerprintDistance, type FluidSpaceOptions, type FluidTypeOptions, type FluidTypeResult, type FontClass, type Gamut, type Generation, HOUSE, HOUSE_BUDGET, HOUSE_TYPE, type HarvestCandidate, type HarvestOptions, type Hit, type HouseRule, type HouseTier, LIGHTNESS_CURVE, MIN_DECIDED, MIN_RUNS, type MotionDecision, type MotionKind, NEGATIVE_REASSURANCE, NULL_VERSION, type NullModel, type NullRun, type Oklch, type OklchToHexOptions, PILL_LIMIT, PLAINER_WORDS, PROPOSED, type PaletteColour, type Proposal, type ProposeInput, RAMP_STEPS, REFLEX_FONTS_1, REFLEX_FONTS_2, RENDERED_PATHS, REVEAL_LIMIT, REVIEW_PHRASES, type Ramp, type RampFromAnchorsOptions, type RampOptions, type RampStep, type RestraintBudget, type RestraintReport, type RestraintSeverity, type RestraintViolation, type Rgb, SCALE, SHADCN_LIMIT, SHADCN_PRIMITIVES, SIBLING_AT, SNAPSHOT_VERSION, SOURCE_KINDS, SPACE_STEPS, SPRING, STOCK_PHRASES, type SectionKind, type SectionRhythmOptions, type SemanticInput, type SemanticResult, type Severity, type ShouldAnimateInput, type SignalResult, type Snapshot, type SnapshotColour, type SnapshotControl, type SnapshotEffects, type SnapshotFont, type SnapshotGradient, type SnapshotHeading, type SnapshotMotion, type SnapshotPatch, type SnapshotSection, type SourceFile, type SourceKind, type SourceTell, type SpaceStep, type Surface, TELL_HEAVY, TYPE_STEPS, TYPICAL_AT, type TailwindPreset, type Tell, type TellException, type TypeStep, type Typicality, VAGUE_WORDS, type ValidateContext, type Verdict, accentFork, addSite, apcaContrast, applyHouseGate, auditSnapshot, catalogueTable, characterReport, checkCopy, checkPair, checkRestraint, choicesOf, compareFacts, compareToEstate, craftTokens, deltaEOk, deltaEOkHex, densityCss, densityTokens, emitCss, emptyEstate, estatePairs, exitDuration, extractHtml, findClaims, findColours, fingerprint, fingerprintDistance, fluidClamp, fluidSpace, fluidType, fontClass, formatClaims, formatComparison, formatHex, formatReport, groundName, harvest, hexToOklch, houseRule, hueName, hueSwatch, inP3Gamut, inSrgbGamut, initDirection, isAiViolet, isCream, makeSnapshot, motionTokens, namedSources, nearest, normaliseFamily, nullPrompt, oklchToHex, oklchToRgb, paletteFromPixels, parseColour, parseHex, propose, protectedFacts, ramp, rampFromAnchors, retrofitPlan, runTell, scanSource, sectionRhythm, semantic, shapeName, sharedParts, shouldAnimate, siblingLine, tailwindV3Preset, tailwindV4Theme, tellById, toGamut, typeFeatureTokens, typicality, validateDirection, visibleText, wcagContrast, wordListsJson };
|
|
2181
|
+
export { AI_PHRASES, AI_VIOLET, AI_WORDS, type AccentFork, type AccentForkOptions, type Action, type Area, type ArtDirection, BASELINE_VERSION, BUZZWORDS, type Baseline, type BaselineEntry, CATALOGUE, CATALOGUE_VERSION, CHOICE_KEYS, type CandidateKind, type CharacterInputs, type CharacterReport, type CheckOptions, type CheckReport, type CheckRestraintInput, type ChoiceKey, type Claim, type ClaimsReport, type ContrastCheck, type ContrastReport, type CopyTell, type CraftConfig, type CraftTokensInput, type CraftTokensResult, DEFAULT_IGNORE, DENSITIES, DENSITY_NAMES, DIRECTION_VERSION, DISTANCE_WEIGHTS, DURATION_MS, DURATION_S, type DensityCssOptions, type DensityName, type DirectionChoice, type DirectionProblem, type DirectionReport, type DirectionSource, type DurationName, EASE, EASE_TUPLE, EDGE_STEP, ESTATE_VERSION, EXIT_RATIO, type EaseName, type EmitCssOptions, type EstateMatch, type EstatePair, type EstateRegister, type EstateSite, FINGERPRINT_VERSION, type Fact, type FactComparison, type FactKind, type Finding, type Fingerprint, type FingerprintDistance, type FingerprintSection, type FluidSpaceOptions, type FluidTypeOptions, type FluidTypeResult, type FontClass, type Gamut, type Generation, HOUSE, HOUSE_BUDGET, HOUSE_LOCKED, HOUSE_TYPE, type HarvestCandidate, type HarvestOptions, type Hit, type HouseRule, type HouseTier, JSON_SCHEMA_VERSION, LICENCES, LIGHTNESS_CURVE, type LicenceEntry, type LicenceSubject, MIN_DECIDED, MIN_RUNS, type MotionDecision, type MotionKind, type MultiClient, NEGATIVE_REASSURANCE, NULL_VERSION, type NullModel, type NullRun, type Oklch, type OklchToHexOptions, PILL_LIMIT, PLAINER_WORDS, PROPOSED, type PaletteColour, type Proposal, type ProposeInput, RAMP_STEPS, READABLE_SNAPSHOT_VERSIONS, REFLEX_FONTS_1, REFLEX_FONTS_2, RENDERED_PATHS, REVEAL_LIMIT, REVIEW_PHRASES, type Ramp, type RampFromAnchorsOptions, type RampOptions, type RampStep, type RestraintBudget, type RestraintReport, type RestraintSeverity, type RestraintViolation, type Rgb, type RgbaImage, SCALE, SHADCN_LIMIT, SHADCN_PRIMITIVES, SIBLING_AT, SNAPSHOT_VERSION, SOURCE_KINDS, SPACE_STEPS, SPRING, STOCK_PHRASES, type SarifOptions, type SarifTell, type SectionGeometry, type SectionKind, type SectionRhythmOptions, type SectionRole, type SemanticInput, type SemanticResult, type Severity, type SeverityLevel, type SeverityOverride, type ShouldAnimateInput, type SignalResult, type Snapshot, type SnapshotColour, type SnapshotControl, type SnapshotEffects, type SnapshotFont, type SnapshotGradient, type SnapshotHeading, type SnapshotMotion, type SnapshotPatch, type SnapshotSection, type SnapshotVisual, type SourceFile, type SourceKind, type SourceTell, type SpaceStep, type Surface, TELL_HEAVY, TYPE_STEPS, TYPICAL_AT, type TailwindPreset, type Tell, type TellException, type TypeStep, type Typicality, VAGUE_WORDS, type ValidateContext, type Verdict, accentFork, addSite, apcaContrast, applyBaseline, applyHouseGate, applySeverity, auditSnapshot, catalogueTable, characterReport, checkCopy, checkPair, checkRestraint, choicesOf, compareFacts, compareToEstate, craftTokens, createBaseline, deltaEOk, deltaEOkHex, densityCss, densityTokens, emitCss, emptyEstate, estatePairs, exitDuration, extractHtml, faceLicence, findClaims, findColours, findingKey, fingerprint, fingerprintDistance, fluidClamp, fluidSpace, fluidType, fontClass, formatClaims, formatComparison, formatHex, formatReport, globToRegExp, groundName, harvest, hexToOklch, holdHouseBlocks, houseRule, hueName, hueSwatch, ignoreMatcher, inP3Gamut, inSrgbGamut, initDirection, isAiViolet, isCream, layoutDistance, licencesJson, makeSnapshot, motionTokens, namedSources, nearest, normaliseFamily, nullPrompt, oklchToHex, oklchToRgb, paletteFromPixels, parseBaseline, parseColour, parseCraftConfig, parseHex, propose, protectedFacts, ramp, rampFromAnchors, readSnapshot, retrofitPlan, runTell, scanSource, sectionRhythm, semantic, severityExceptions, shapeName, sharedParts, shouldAnimate, siblingLine, tailwindV3Preset, tailwindV4Theme, tellById, toGamut, toJson, toSarif, typeFeatureTokens, typicality, validateDirection, visibleText, visualMeasures, wcagContrast, wordListsJson };
|