@domandigital/craft 0.18.2 → 0.19.1
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 +13 -0
- package/CHARACTER.md +77 -6
- package/README.md +1 -1
- package/STANDARD.md +48 -18
- package/dist/{audit-4SFSLCKY.js → audit-43PC4LMS.js} +3 -3
- package/dist/audit.cjs +24 -3
- package/dist/audit.d.cts +30 -1
- package/dist/audit.d.ts +30 -1
- package/dist/audit.js +24 -3
- package/dist/{chunk-DARKHE6A.js → chunk-37ARRJAD.js} +18 -7
- package/dist/{chunk-6TSDYETQ.js → chunk-4LJFZH2I.js} +29 -2
- package/dist/{chunk-4QWEAL4G.js → chunk-CZ7KT452.js} +93 -1
- package/dist/{chunk-O5B5ELJH.js → chunk-DUUDGR56.js} +14 -13
- package/dist/{chunk-NTIPJ5U7.js → chunk-OKVHWXYV.js} +3 -3
- package/dist/{chunk-ZUYERAFM.js → chunk-ORFILP5L.js} +5 -5
- package/dist/{chunk-RJVG5KA6.js → chunk-P37LLKL4.js} +38 -10
- package/dist/{chunk-SL5VZJ2J.js → chunk-VDUIIWG7.js} +3 -2
- package/dist/{chunk-WFB6F3BN.js → chunk-WK2WMWTH.js} +107 -9
- package/dist/{cli-GXIW7F3E.js → cli-3P44X6E3.js} +6 -6
- package/dist/{cli-JZRQBCD4.js → cli-4D7Q5BCE.js} +6 -6
- package/dist/{cli-MDW7JTEF.js → cli-7OUA6ZSE.js} +6 -6
- package/dist/{cli-V44QEVS6.js → cli-AACBHRUG.js} +10 -10
- package/dist/{cli-BN4IT6N2.js → cli-L3VGKWZH.js} +4 -4
- package/dist/{cli-Y7Y5IROK.js → cli-TH76ATN3.js} +5 -5
- package/dist/{cli-JB4X5LAG.js → cli-VPARW6FY.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.cjs +279 -14
- package/dist/index.d.cts +111 -10
- package/dist/index.d.ts +111 -10
- package/dist/index.js +267 -14
- package/licences.json +27 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -74,6 +74,7 @@ __export(index_exports, {
|
|
|
74
74
|
MOOD: () => MOOD,
|
|
75
75
|
NEGATIVE_REASSURANCE: () => NEGATIVE_REASSURANCE,
|
|
76
76
|
NULL_VERSION: () => NULL_VERSION,
|
|
77
|
+
OPENING_BANDS: () => OPENING_BANDS,
|
|
77
78
|
PAGE_TYPES: () => PAGE_TYPES,
|
|
78
79
|
PILL_LIMIT: () => PILL_LIMIT,
|
|
79
80
|
PLAINER_WORDS: () => PLAINER_WORDS,
|
|
@@ -117,6 +118,9 @@ __export(index_exports, {
|
|
|
117
118
|
STOCK_PHRASES: () => STOCK_PHRASES,
|
|
118
119
|
STUDY_WORDS: () => STUDY_WORDS,
|
|
119
120
|
TELL_HEAVY: () => TELL_HEAVY,
|
|
121
|
+
TEMPERATURE_FULL: () => TEMPERATURE_FULL,
|
|
122
|
+
TEMPERATURE_NAMED: () => TEMPERATURE_NAMED,
|
|
123
|
+
TEMPERATURE_WEIGHT: () => TEMPERATURE_WEIGHT,
|
|
120
124
|
TRADE_NOUNS: () => TRADE_NOUNS,
|
|
121
125
|
TYPE_STEPS: () => TYPE_STEPS,
|
|
122
126
|
TYPICAL_AT: () => TYPICAL_AT,
|
|
@@ -128,6 +132,7 @@ __export(index_exports, {
|
|
|
128
132
|
applyHouseGate: () => applyHouseGate,
|
|
129
133
|
applySeverity: () => applySeverity,
|
|
130
134
|
auditSnapshot: () => auditSnapshot,
|
|
135
|
+
bandOf: () => bandOf,
|
|
131
136
|
briefTerms: () => briefTerms,
|
|
132
137
|
calibrate: () => calibrate,
|
|
133
138
|
catalogueTable: () => catalogueTable,
|
|
@@ -191,10 +196,14 @@ __export(index_exports, {
|
|
|
191
196
|
globToRegExp: () => globToRegExp,
|
|
192
197
|
gradientContrast: () => gradientContrast,
|
|
193
198
|
gradientStops: () => gradientStops,
|
|
199
|
+
groundDistance: () => groundDistance,
|
|
200
|
+
groundLabel: () => groundLabel,
|
|
194
201
|
groundName: () => groundName,
|
|
202
|
+
groundTemperature: () => groundTemperature,
|
|
195
203
|
harvest: () => harvest,
|
|
196
204
|
hedgeCount: () => hedgeCount,
|
|
197
205
|
hedgedClose: () => hedgedClose,
|
|
206
|
+
heroDistance: () => heroDistance,
|
|
198
207
|
hexToOklch: () => hexToOklch,
|
|
199
208
|
holdHouseBlocks: () => holdHouseBlocks,
|
|
200
209
|
houseRule: () => houseRule,
|
|
@@ -242,6 +251,8 @@ __export(index_exports, {
|
|
|
242
251
|
renderedOrder: () => renderedOrder,
|
|
243
252
|
researchPrompt: () => researchPrompt,
|
|
244
253
|
retrofitPlan: () => retrofitPlan,
|
|
254
|
+
rhythmDistance: () => rhythmDistance,
|
|
255
|
+
rhythmOf: () => rhythmOf,
|
|
245
256
|
runTell: () => runTell,
|
|
246
257
|
scanProvenance: () => scanProvenance,
|
|
247
258
|
scanSource: () => scanSource,
|
|
@@ -268,6 +279,7 @@ __export(index_exports, {
|
|
|
268
279
|
tailwindV3Preset: () => tailwindV3Preset,
|
|
269
280
|
tailwindV4Theme: () => tailwindV4Theme,
|
|
270
281
|
tellById: () => tellById,
|
|
282
|
+
temperatureName: () => temperatureName,
|
|
271
283
|
toGamut: () => toGamut,
|
|
272
284
|
toJson: () => toJson,
|
|
273
285
|
toSarif: () => toSarif,
|
|
@@ -4332,8 +4344,100 @@ function markupParts(file) {
|
|
|
4332
4344
|
function textNodeIsProse(body) {
|
|
4333
4345
|
return /[a-zA-Z]{2,}/.test(body) && /\s/.test(body.trim()) || /[a-zA-Z]{4,}[.!?]/.test(body);
|
|
4334
4346
|
}
|
|
4347
|
+
var FRONT_MATTER_PROSE = /* @__PURE__ */ new Set(["title", "description"]);
|
|
4348
|
+
var KEY_LINE = /^(\s*)(?:-\s+)?([A-Za-z][\w-]*)[ \t]*:[ \t]*/;
|
|
4349
|
+
var BLOCK_SCALAR = /^(?:[|>][+-]?\d*|[|>]\d+[+-]?)$/;
|
|
4350
|
+
function readFrontKey(line) {
|
|
4351
|
+
const m = KEY_LINE.exec(line);
|
|
4352
|
+
if (!m) return null;
|
|
4353
|
+
return { indent: m[1].length, name: m[2], valueAt: m[0].length, value: line.slice(m[0].length) };
|
|
4354
|
+
}
|
|
4355
|
+
function indentOf(line) {
|
|
4356
|
+
let i = 0;
|
|
4357
|
+
while (i < line.length && (line[i] === " " || line[i] === " ")) i += 1;
|
|
4358
|
+
return i;
|
|
4359
|
+
}
|
|
4360
|
+
function commentAt(value) {
|
|
4361
|
+
if (value.startsWith("#")) return 0;
|
|
4362
|
+
const found = /[ \t]+#/.exec(value);
|
|
4363
|
+
return found ? found.index : -1;
|
|
4364
|
+
}
|
|
4365
|
+
function keepSpan(line, from, to) {
|
|
4366
|
+
const start = Math.max(0, Math.min(from, line.length));
|
|
4367
|
+
const end = Math.max(start, Math.min(to, line.length));
|
|
4368
|
+
return " ".repeat(start) + line.slice(start, end) + " ".repeat(line.length - end);
|
|
4369
|
+
}
|
|
4370
|
+
function quoteEnd(line, from, quote) {
|
|
4371
|
+
for (let i = from; i < line.length; i += 1) {
|
|
4372
|
+
if (quote === '"' && line[i] === "\\") {
|
|
4373
|
+
i += 1;
|
|
4374
|
+
continue;
|
|
4375
|
+
}
|
|
4376
|
+
if (quote === "'" && line[i] === "'" && line[i + 1] === "'") {
|
|
4377
|
+
i += 1;
|
|
4378
|
+
continue;
|
|
4379
|
+
}
|
|
4380
|
+
if (line[i] === quote) return i;
|
|
4381
|
+
}
|
|
4382
|
+
return -1;
|
|
4383
|
+
}
|
|
4384
|
+
function maskFrontMatter(block) {
|
|
4385
|
+
const lines = block.split("\n");
|
|
4386
|
+
const out = lines.map((line) => blank(line));
|
|
4387
|
+
for (let i = 1; i < lines.length; ) {
|
|
4388
|
+
const line = lines[i];
|
|
4389
|
+
if (line === "---" || line === "...") break;
|
|
4390
|
+
const key = readFrontKey(line);
|
|
4391
|
+
if (!key || !FRONT_MATTER_PROSE.has(key.name.toLowerCase())) {
|
|
4392
|
+
i += 1;
|
|
4393
|
+
continue;
|
|
4394
|
+
}
|
|
4395
|
+
const quote = key.value.startsWith('"') ? '"' : key.value.startsWith("'") ? "'" : "";
|
|
4396
|
+
if (quote) {
|
|
4397
|
+
let cursor = key.valueAt + 1;
|
|
4398
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4399
|
+
const current = lines[i];
|
|
4400
|
+
const end = quoteEnd(current, cursor, quote);
|
|
4401
|
+
out[i] = keepSpan(current, cursor, end === -1 ? current.length : end);
|
|
4402
|
+
i += 1;
|
|
4403
|
+
cursor = 0;
|
|
4404
|
+
if (end !== -1) break;
|
|
4405
|
+
}
|
|
4406
|
+
continue;
|
|
4407
|
+
}
|
|
4408
|
+
const hash = commentAt(key.value);
|
|
4409
|
+
const body = (hash === -1 ? key.value : key.value.slice(0, hash)).trim();
|
|
4410
|
+
if (BLOCK_SCALAR.test(body)) {
|
|
4411
|
+
i += 1;
|
|
4412
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4413
|
+
const current = lines[i];
|
|
4414
|
+
if (current.trim() !== "" && indentOf(current) <= key.indent) break;
|
|
4415
|
+
if (current.trim()) out[i] = current;
|
|
4416
|
+
i += 1;
|
|
4417
|
+
}
|
|
4418
|
+
continue;
|
|
4419
|
+
}
|
|
4420
|
+
if (body === "" || body === "~" || /^null$/i.test(body) || body.startsWith("[") || body.startsWith("{")) {
|
|
4421
|
+
i += 1;
|
|
4422
|
+
continue;
|
|
4423
|
+
}
|
|
4424
|
+
out[i] = keepSpan(line, key.valueAt, hash === -1 ? line.length : key.valueAt + hash);
|
|
4425
|
+
i += 1;
|
|
4426
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4427
|
+
const current = lines[i];
|
|
4428
|
+
if (current.trim() === "" || indentOf(current) <= key.indent) break;
|
|
4429
|
+
if (!/^\s*#/.test(current)) {
|
|
4430
|
+
const cut = commentAt(current);
|
|
4431
|
+
out[i] = cut === -1 ? current : keepSpan(current, 0, cut);
|
|
4432
|
+
}
|
|
4433
|
+
i += 1;
|
|
4434
|
+
}
|
|
4435
|
+
}
|
|
4436
|
+
const masked = out.join("\n");
|
|
4437
|
+
return masked.length === block.length ? masked : blank(block);
|
|
4438
|
+
}
|
|
4335
4439
|
function proseBlocks(file) {
|
|
4336
|
-
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/,
|
|
4440
|
+
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/, (block) => maskFrontMatter(block)).replace(/<!--[\s\S]*?-->/g, blank);
|
|
4337
4441
|
return [{ path: file.path, text: masked, offset: 0 }];
|
|
4338
4442
|
}
|
|
4339
4443
|
function isData(path) {
|
|
@@ -5321,7 +5425,7 @@ var RENDERED_PATHS = {
|
|
|
5321
5425
|
};
|
|
5322
5426
|
|
|
5323
5427
|
// src/fingerprint/index.ts
|
|
5324
|
-
var FINGERPRINT_VERSION =
|
|
5428
|
+
var FINGERPRINT_VERSION = 3;
|
|
5325
5429
|
var CHROMATIC = 0.03;
|
|
5326
5430
|
var MIN_ACCENT_AREA = 2e4;
|
|
5327
5431
|
var oklch = (value) => {
|
|
@@ -5357,6 +5461,24 @@ function median(values) {
|
|
|
5357
5461
|
const mid = Math.floor(sorted.length / 2);
|
|
5358
5462
|
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
5359
5463
|
}
|
|
5464
|
+
var FULL_WIDTH_IMAGE = 0.8;
|
|
5465
|
+
function heroOf(s) {
|
|
5466
|
+
const h1 = s.headings.find((h) => h.level === 1);
|
|
5467
|
+
const inside = (top, x) => top >= x.top && top < x.top + x.height;
|
|
5468
|
+
const index = (() => {
|
|
5469
|
+
const withH1 = h1 ? s.sections.findIndex((x) => x.kind === "hero" && inside(h1.top, x)) : -1;
|
|
5470
|
+
return withH1 >= 0 ? withH1 : s.sections.findIndex((x) => x.kind === "hero");
|
|
5471
|
+
})();
|
|
5472
|
+
if (index < 0) return void 0;
|
|
5473
|
+
const section = s.sections[index];
|
|
5474
|
+
const headline = h1 && inside(h1.top, section) ? { sizePx: h1.sizePx, weight: h1.weight, class: fontClass(normaliseFamily(h1.family)), italic: h1.italic || h1.italicPart } : null;
|
|
5475
|
+
if (!s.images) return { headline };
|
|
5476
|
+
const picture2 = s.images.filter((i) => (i.role === "photo" || i.role === "illustration") && (i.section === index || i.section === null && inside(i.top, section))).sort((a, b) => b.width * b.height - a.width * a.height)[0];
|
|
5477
|
+
if (!picture2) return { headline, image: "none" };
|
|
5478
|
+
if (picture2.left === void 0) return { headline };
|
|
5479
|
+
const image = picture2.width >= FULL_WIDTH_IMAGE * s.viewport.width ? "full" : picture2.left + picture2.width / 2 < s.viewport.width / 2 ? "left" : "right";
|
|
5480
|
+
return { headline, image };
|
|
5481
|
+
}
|
|
5360
5482
|
function fingerprint(s) {
|
|
5361
5483
|
const effects = [];
|
|
5362
5484
|
if (s.effects.glass > 0) effects.push("glass-panel");
|
|
@@ -5368,6 +5490,7 @@ function fingerprint(s) {
|
|
|
5368
5490
|
if (s.effects.eyebrowChip) effects.push("hero-eyebrow-chip");
|
|
5369
5491
|
if (s.motion.introOverlay) effects.push("intro-cinematic");
|
|
5370
5492
|
const below = s.sections.filter((x) => x.top > s.viewport.height).length;
|
|
5493
|
+
const hero = heroOf(s);
|
|
5371
5494
|
return {
|
|
5372
5495
|
version: FINGERPRINT_VERSION,
|
|
5373
5496
|
accent: accentOf(s),
|
|
@@ -5391,10 +5514,28 @@ function fingerprint(s) {
|
|
|
5391
5514
|
carousel: x.carousel ?? false,
|
|
5392
5515
|
figures: x.figures ?? 0
|
|
5393
5516
|
}))
|
|
5394
|
-
} : {}
|
|
5517
|
+
} : {},
|
|
5518
|
+
...hero ? { hero } : {}
|
|
5395
5519
|
};
|
|
5396
5520
|
}
|
|
5397
|
-
var
|
|
5521
|
+
var WARM_HUE = [
|
|
5522
|
+
[330, 360],
|
|
5523
|
+
[0, 130]
|
|
5524
|
+
];
|
|
5525
|
+
var COOL_HUE = [[160, 310]];
|
|
5526
|
+
var TEMPERATURE_FULL = 6e-3;
|
|
5527
|
+
var TEMPERATURE_NAMED = 0.4;
|
|
5528
|
+
function groundTemperature(o) {
|
|
5529
|
+
const h = (o.h % 360 + 360) % 360;
|
|
5530
|
+
const within = (bands) => bands.some(([lo, hi]) => h >= lo && h < hi);
|
|
5531
|
+
const strength = Math.min(1, o.c / TEMPERATURE_FULL);
|
|
5532
|
+
return within(WARM_HUE) ? strength : within(COOL_HUE) ? -strength : 0;
|
|
5533
|
+
}
|
|
5534
|
+
function temperatureName(o) {
|
|
5535
|
+
const t = groundTemperature(o);
|
|
5536
|
+
return t >= TEMPERATURE_NAMED ? "warm" : t <= -TEMPERATURE_NAMED ? "cool" : "neutral";
|
|
5537
|
+
}
|
|
5538
|
+
var DISTANCE_WEIGHTS = { accent: 0.2, type: 0.2, ground: 0.1, shape: 0.1, motion: 0.05, effects: 0.1, layout: 0.1, rhythm: 0.1, hero: 0.05 };
|
|
5398
5539
|
function levenshtein(a, b, cost = (x, y) => x === y ? 0 : 1) {
|
|
5399
5540
|
const row = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
5400
5541
|
for (let i = 1; i <= a.length; i += 1) {
|
|
@@ -5421,18 +5562,62 @@ function layoutDistance(a, b) {
|
|
|
5421
5562
|
return longest === 0 ? 0 : levenshtein(a.layout, b.layout) / longest;
|
|
5422
5563
|
}
|
|
5423
5564
|
var clamp = (n) => Math.max(0, Math.min(1, n));
|
|
5565
|
+
function bandOf(l) {
|
|
5566
|
+
return l < 0.4 ? "dark" : l >= 0.75 ? "light" : "mid";
|
|
5567
|
+
}
|
|
5568
|
+
function rhythmOf(fp) {
|
|
5569
|
+
if (!fp.sections) return null;
|
|
5570
|
+
const out = [];
|
|
5571
|
+
for (const s of fp.sections) {
|
|
5572
|
+
if (s.background === void 0) return null;
|
|
5573
|
+
const band = bandOf((s.background ?? fp.ground).l);
|
|
5574
|
+
if (out[out.length - 1] !== band) out.push(band);
|
|
5575
|
+
}
|
|
5576
|
+
return out;
|
|
5577
|
+
}
|
|
5578
|
+
var OPENING_BANDS = 3;
|
|
5579
|
+
function rhythmDistance(a, b) {
|
|
5580
|
+
const ra = rhythmOf(a);
|
|
5581
|
+
const rb = rhythmOf(b);
|
|
5582
|
+
if (!ra || !rb) return null;
|
|
5583
|
+
const over = (x, y) => {
|
|
5584
|
+
const longest = Math.max(x.length, y.length);
|
|
5585
|
+
return longest === 0 ? 0 : levenshtein(x, y) / longest;
|
|
5586
|
+
};
|
|
5587
|
+
return (over(ra.slice(0, OPENING_BANDS), rb.slice(0, OPENING_BANDS)) + over(ra, rb)) / 2;
|
|
5588
|
+
}
|
|
5589
|
+
var HEADLINE_OCTAVES = 1;
|
|
5590
|
+
function heroSection(fp) {
|
|
5591
|
+
return fp.sections?.find((s) => s.role === "hero");
|
|
5592
|
+
}
|
|
5593
|
+
function heroDistance(a, b) {
|
|
5594
|
+
const sa = heroSection(a);
|
|
5595
|
+
const sb = heroSection(b);
|
|
5596
|
+
if (!sa || !sb) return null;
|
|
5597
|
+
const parts2 = [Math.abs(sa.centred - sb.centred), clamp(Math.abs(sa.width - sb.width) / 0.5)];
|
|
5598
|
+
const ha = a.hero?.headline;
|
|
5599
|
+
const hb = b.hero?.headline;
|
|
5600
|
+
if (ha && hb) parts2.push(0.5 * (ha.class === hb.class ? 0 : 1) + 0.5 * clamp(Math.abs(Math.log2(ha.sizePx / hb.sizePx)) / HEADLINE_OCTAVES));
|
|
5601
|
+
else if (a.hero && b.hero && (ha || hb)) parts2.push(1);
|
|
5602
|
+
if (a.hero?.image && b.hero?.image) parts2.push(a.hero.image === b.hero.image ? 0 : 1);
|
|
5603
|
+
return parts2.reduce((s, p) => s + p, 0) / parts2.length;
|
|
5604
|
+
}
|
|
5424
5605
|
function faceDistance(a, b) {
|
|
5425
5606
|
if (a.family.toLowerCase() === b.family.toLowerCase()) return 0;
|
|
5426
5607
|
return a.class === b.class ? 0.5 : 1;
|
|
5427
5608
|
}
|
|
5428
5609
|
var ACCENT_SCALE = 0.3;
|
|
5429
5610
|
var GROUND_SCALE = 0.15;
|
|
5611
|
+
var TEMPERATURE_WEIGHT = 0.6;
|
|
5430
5612
|
var SHARED_PART = 0.2;
|
|
5431
5613
|
var ACCENT_SHARED = ACCENT_SCALE * SHARED_PART;
|
|
5432
5614
|
var GROUND_SHARED = GROUND_SCALE * SHARED_PART;
|
|
5615
|
+
function groundDistance(a, b) {
|
|
5616
|
+
return clamp(deltaEOk(a, b) / GROUND_SCALE + TEMPERATURE_WEIGHT * Math.abs(groundTemperature(a) - groundTemperature(b)) / 2);
|
|
5617
|
+
}
|
|
5433
5618
|
function fingerprintDistance(a, b) {
|
|
5434
5619
|
const accent = a.accent && b.accent ? clamp(deltaEOk(a.accent, b.accent) / ACCENT_SCALE) : a.accent || b.accent ? 1 : 0;
|
|
5435
|
-
const ground =
|
|
5620
|
+
const ground = groundDistance(a.ground, b.ground);
|
|
5436
5621
|
const type = 0.6 * faceDistance(a.display, b.display) + 0.4 * faceDistance(a.body, b.body);
|
|
5437
5622
|
const shape = a.roundness === null || b.roundness === null ? a.roundness === b.roundness ? 0 : 0.5 : clamp(Math.abs(a.roundness - b.roundness) / 0.5);
|
|
5438
5623
|
const motion = clamp(Math.abs(a.motion - b.motion));
|
|
@@ -5440,9 +5625,18 @@ function fingerprintDistance(a, b) {
|
|
|
5440
5625
|
const shared = a.effects.filter((e) => b.effects.includes(e)).length;
|
|
5441
5626
|
const effects = union.size === 0 ? 0 : 1 - shared / union.size;
|
|
5442
5627
|
const layout = layoutDistance(a, b);
|
|
5443
|
-
const
|
|
5444
|
-
const
|
|
5445
|
-
|
|
5628
|
+
const rhythm = rhythmDistance(a, b);
|
|
5629
|
+
const hero = heroDistance(a, b);
|
|
5630
|
+
const parts2 = { accent, ground, type, shape, motion, effects, layout, rhythm, hero };
|
|
5631
|
+
let sum = 0;
|
|
5632
|
+
let weight = 0;
|
|
5633
|
+
for (const k of Object.keys(DISTANCE_WEIGHTS)) {
|
|
5634
|
+
const p = parts2[k];
|
|
5635
|
+
if (p === null) continue;
|
|
5636
|
+
sum += DISTANCE_WEIGHTS[k] * p;
|
|
5637
|
+
weight += DISTANCE_WEIGHTS[k];
|
|
5638
|
+
}
|
|
5639
|
+
return { total: Math.round(sum / weight * 1e3) / 1e3, parts: parts2 };
|
|
5446
5640
|
}
|
|
5447
5641
|
function nearest(target2, set, k = set.length) {
|
|
5448
5642
|
return set.map((item) => ({ id: item.id, distance: fingerprintDistance(target2, item.fingerprint) })).sort((x, y) => x.distance.total - y.distance.total).slice(0, k);
|
|
@@ -5520,6 +5714,12 @@ function groundName(o) {
|
|
|
5520
5714
|
if (o.l >= 0.97 && o.c < 0.012) return "white";
|
|
5521
5715
|
return o.c < 0.02 ? "grey" : "tinted";
|
|
5522
5716
|
}
|
|
5717
|
+
function groundLabel(o) {
|
|
5718
|
+
const name = groundName(o);
|
|
5719
|
+
if (name === "cream" || name === "tinted") return name;
|
|
5720
|
+
const temperature = temperatureName(o);
|
|
5721
|
+
return temperature === "neutral" ? name : `${temperature} ${name}`;
|
|
5722
|
+
}
|
|
5523
5723
|
function shapeName(roundness) {
|
|
5524
5724
|
if (roundness === null) return "no buttons";
|
|
5525
5725
|
if (roundness >= 0.45) return "pill";
|
|
@@ -8794,6 +8994,33 @@ var LICENCES = [
|
|
|
8794
8994
|
checked: "2026-09-24",
|
|
8795
8995
|
source: "https://iconscout.com/licenses",
|
|
8796
8996
|
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."
|
|
8997
|
+
},
|
|
8998
|
+
{
|
|
8999
|
+
name: "Saira Semi Condensed",
|
|
9000
|
+
subject: "face",
|
|
9001
|
+
licence: "OFL-1.1",
|
|
9002
|
+
multiClient: "yes",
|
|
9003
|
+
checked: "2026-10-09",
|
|
9004
|
+
source: "https://github.com/google/fonts/blob/main/ofl/sairasemicondensed/OFL.txt",
|
|
9005
|
+
note: "Copyright 2016 The Saira Project Authors (omnibus.type@gmail.com), reserved font name Saira. Keep the OFL notice with the font files; a modified build may not be called Saira. Chosen for Doman Digital's own site (DOM-397, 9 October 2026)."
|
|
9006
|
+
},
|
|
9007
|
+
{
|
|
9008
|
+
name: "Public Sans",
|
|
9009
|
+
subject: "face",
|
|
9010
|
+
licence: "OFL-1.1",
|
|
9011
|
+
multiClient: "yes",
|
|
9012
|
+
checked: "2026-10-09",
|
|
9013
|
+
source: "https://github.com/google/fonts/blob/main/ofl/publicsans/OFL.txt",
|
|
9014
|
+
note: "Copyright 2015 The Public Sans Project Authors (https://github.com/uswds/public-sans). Keep the OFL notice with the font files. Chosen for Doman Digital's own site (DOM-397, 9 October 2026)."
|
|
9015
|
+
},
|
|
9016
|
+
{
|
|
9017
|
+
name: "Martian Mono",
|
|
9018
|
+
subject: "face",
|
|
9019
|
+
licence: "OFL-1.1",
|
|
9020
|
+
multiClient: "yes",
|
|
9021
|
+
checked: "2026-10-09",
|
|
9022
|
+
source: "https://github.com/google/fonts/blob/main/ofl/martianmono/OFL.txt",
|
|
9023
|
+
note: "Copyright 2021 The Martian Mono Project Authors (https://github.com/evilmartians/mono). Keep the OFL notice with the font files. Chosen for Doman Digital's own site (DOM-397, 9 October 2026)."
|
|
8797
9024
|
}
|
|
8798
9025
|
];
|
|
8799
9026
|
function faceLicence(family) {
|
|
@@ -9160,7 +9387,7 @@ var PART_AREA = {
|
|
|
9160
9387
|
effects: { area: "effects", choice: "motif" },
|
|
9161
9388
|
motion: { area: "motion", choice: "signature" }
|
|
9162
9389
|
};
|
|
9163
|
-
var DEFAULTS = /^(?:ground )?(?:white|grey)(?: ground)?$|no scroll reveals|no reveals|accent (?:none|neutral)|^no buttons|shape no buttons
|
|
9390
|
+
var DEFAULTS = /^(?:ground )?(?:white|grey|light)(?: ground)?$|no scroll reveals|no reveals|accent (?:none|neutral)|^no buttons|shape no buttons|^light page throughout$/;
|
|
9164
9391
|
function designFindings(findings, copyTells) {
|
|
9165
9392
|
return (findings?.findings ?? []).filter((f4) => !copyTells.has(f4.tell));
|
|
9166
9393
|
}
|
|
@@ -9267,7 +9494,7 @@ function areaOfShared(part) {
|
|
|
9267
9494
|
if (/accent|ground/.test(part)) return "colour";
|
|
9268
9495
|
if (/buttons/.test(part)) return "shape";
|
|
9269
9496
|
if (/reveal/.test(part)) return "motion";
|
|
9270
|
-
if (/running order/.test(part)) return "layout";
|
|
9497
|
+
if (/running order|hero|page throughout/.test(part)) return "layout";
|
|
9271
9498
|
return "effects";
|
|
9272
9499
|
}
|
|
9273
9500
|
function choiceOfShared(part) {
|
|
@@ -9277,7 +9504,7 @@ function choiceOfShared(part) {
|
|
|
9277
9504
|
if (/ground/.test(part)) return "ground";
|
|
9278
9505
|
if (/buttons/.test(part)) return "shape";
|
|
9279
9506
|
if (/reveal/.test(part)) return "signature";
|
|
9280
|
-
return /running order/.test(part) ? void 0 : "motif";
|
|
9507
|
+
return /running order|hero|page throughout/.test(part) ? void 0 : "motif";
|
|
9281
9508
|
}
|
|
9282
9509
|
|
|
9283
9510
|
// src/calibrate/index.ts
|
|
@@ -9384,19 +9611,45 @@ function addSite(register, site) {
|
|
|
9384
9611
|
const sites = [...register.sites.filter((s) => s.id !== site.id), site].sort((a, b) => a.id.localeCompare(b.id));
|
|
9385
9612
|
return { version: ESTATE_VERSION, sites };
|
|
9386
9613
|
}
|
|
9614
|
+
function sharedGround(a, b) {
|
|
9615
|
+
const [x, y] = [groundLabel(a.ground), groundLabel(b.ground)];
|
|
9616
|
+
if (x === y) return `${x} ground`;
|
|
9617
|
+
const temperature = temperatureName(a.ground);
|
|
9618
|
+
if (temperature !== "neutral" && temperature === temperatureName(b.ground)) return `${temperature} ground`;
|
|
9619
|
+
return `${a.ground.l < 0.3 ? "dark" : "light"} ground`;
|
|
9620
|
+
}
|
|
9621
|
+
function sharedRhythm(a, b) {
|
|
9622
|
+
const bands = rhythmOf(a) ?? [];
|
|
9623
|
+
const word = (band) => band;
|
|
9624
|
+
if (bands.length <= 1) return `${bands[0] ? word(bands[0]) : "light"} page throughout`;
|
|
9625
|
+
const second = bands[1] === "mid" ? "mid-tone band" : `${word(bands[1])} band`;
|
|
9626
|
+
return `${word(bands[0])} hero then ${second}`;
|
|
9627
|
+
}
|
|
9628
|
+
function sharedHero(a, b) {
|
|
9629
|
+
const hero = a.sections?.find((s) => s.role === "hero");
|
|
9630
|
+
const placement = hero && hero.centred >= 0.5 ? "centred" : "left-aligned";
|
|
9631
|
+
const headline = a.hero?.headline && b.hero?.headline && a.hero.headline.class === b.hero.headline.class ? `${a.hero.headline.class} ` : "";
|
|
9632
|
+
const image = a.hero?.image && a.hero.image === b.hero?.image && a.hero.image !== "none" ? `, ${a.hero.image === "full" ? "full-width picture" : `photo ${a.hero.image}`}` : "";
|
|
9633
|
+
return `${placement} ${headline}hero${image}`;
|
|
9634
|
+
}
|
|
9387
9635
|
function sharedParts(a, b, d = fingerprintDistance(a, b)) {
|
|
9388
9636
|
const out = [];
|
|
9389
|
-
const close = (k) =>
|
|
9637
|
+
const close = (k) => {
|
|
9638
|
+
const p = d.parts[k];
|
|
9639
|
+
return p !== null && p <= SHARED_PART;
|
|
9640
|
+
};
|
|
9390
9641
|
if (close("accent")) out.push(a.accent || b.accent ? `${hueName(a.accent)} accent` : "no accent");
|
|
9391
9642
|
if (close("type")) {
|
|
9392
9643
|
if (a.display.family === b.display.family) out.push(`${a.display.family} headline`);
|
|
9393
9644
|
if (a.body.family === b.body.family) out.push(`${a.body.family} body`);
|
|
9394
9645
|
}
|
|
9395
|
-
if (close("ground")) out.push(
|
|
9646
|
+
if (close("ground")) out.push(sharedGround(a, b));
|
|
9396
9647
|
if (close("shape")) out.push(`${shapeName(a.roundness)} buttons`);
|
|
9397
9648
|
if (close("motion")) out.push(a.motion > 0 || b.motion > 0 ? "scroll reveals" : "no reveals");
|
|
9398
9649
|
if (close("effects") && a.effects.length) out.push(a.effects.filter((e) => b.effects.includes(e)).join(", "));
|
|
9399
|
-
if (close("
|
|
9650
|
+
if (close("hero")) out.push(sharedHero(a, b));
|
|
9651
|
+
if (close("rhythm")) out.push(sharedRhythm(a, b));
|
|
9652
|
+
if (close("layout")) out.push("same running order");
|
|
9400
9653
|
return out;
|
|
9401
9654
|
}
|
|
9402
9655
|
function compareToEstate(target2, register, options = {}) {
|
|
@@ -9536,6 +9789,7 @@ function retrofitPlan(report2, direction) {
|
|
|
9536
9789
|
MOOD,
|
|
9537
9790
|
NEGATIVE_REASSURANCE,
|
|
9538
9791
|
NULL_VERSION,
|
|
9792
|
+
OPENING_BANDS,
|
|
9539
9793
|
PAGE_TYPES,
|
|
9540
9794
|
PILL_LIMIT,
|
|
9541
9795
|
PLAINER_WORDS,
|
|
@@ -9579,6 +9833,9 @@ function retrofitPlan(report2, direction) {
|
|
|
9579
9833
|
STOCK_PHRASES,
|
|
9580
9834
|
STUDY_WORDS,
|
|
9581
9835
|
TELL_HEAVY,
|
|
9836
|
+
TEMPERATURE_FULL,
|
|
9837
|
+
TEMPERATURE_NAMED,
|
|
9838
|
+
TEMPERATURE_WEIGHT,
|
|
9582
9839
|
TRADE_NOUNS,
|
|
9583
9840
|
TYPE_STEPS,
|
|
9584
9841
|
TYPICAL_AT,
|
|
@@ -9590,6 +9847,7 @@ function retrofitPlan(report2, direction) {
|
|
|
9590
9847
|
applyHouseGate,
|
|
9591
9848
|
applySeverity,
|
|
9592
9849
|
auditSnapshot,
|
|
9850
|
+
bandOf,
|
|
9593
9851
|
briefTerms,
|
|
9594
9852
|
calibrate,
|
|
9595
9853
|
catalogueTable,
|
|
@@ -9653,10 +9911,14 @@ function retrofitPlan(report2, direction) {
|
|
|
9653
9911
|
globToRegExp,
|
|
9654
9912
|
gradientContrast,
|
|
9655
9913
|
gradientStops,
|
|
9914
|
+
groundDistance,
|
|
9915
|
+
groundLabel,
|
|
9656
9916
|
groundName,
|
|
9917
|
+
groundTemperature,
|
|
9657
9918
|
harvest,
|
|
9658
9919
|
hedgeCount,
|
|
9659
9920
|
hedgedClose,
|
|
9921
|
+
heroDistance,
|
|
9660
9922
|
hexToOklch,
|
|
9661
9923
|
holdHouseBlocks,
|
|
9662
9924
|
houseRule,
|
|
@@ -9704,6 +9966,8 @@ function retrofitPlan(report2, direction) {
|
|
|
9704
9966
|
renderedOrder,
|
|
9705
9967
|
researchPrompt,
|
|
9706
9968
|
retrofitPlan,
|
|
9969
|
+
rhythmDistance,
|
|
9970
|
+
rhythmOf,
|
|
9707
9971
|
runTell,
|
|
9708
9972
|
scanProvenance,
|
|
9709
9973
|
scanSource,
|
|
@@ -9730,6 +9994,7 @@ function retrofitPlan(report2, direction) {
|
|
|
9730
9994
|
tailwindV3Preset,
|
|
9731
9995
|
tailwindV4Theme,
|
|
9732
9996
|
tellById,
|
|
9997
|
+
temperatureName,
|
|
9733
9998
|
toGamut,
|
|
9734
9999
|
toJson,
|
|
9735
10000
|
toSarif,
|