@domandigital/craft 0.6.0 → 0.7.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/dist/audit.js CHANGED
@@ -1177,7 +1177,7 @@ const inter = Inter({ subsets: ["latin"] });`),
1177
1177
  severity: "warn",
1178
1178
  surface: "source",
1179
1179
  why: "Ban Inter and a model reaches for Inter Tight, DM Sans, Manrope, Space Grotesk or an Instrument/Fraunces serif. A swap inside the reflex list is not a decision.",
1180
- fix: "Same as reflex-font. If this face really is the right one, declare an exception with the reason and the evidence.",
1180
+ fix: "Pick the display face from the client's world (signage, packaging, the trade's lettering) and record why in art-direction.json. If this face really is the right one, declare an exception with the reason and the evidence.",
1181
1181
  detect: fontTell(REFLEX_FONTS_2),
1182
1182
  fixtures: {
1183
1183
  flag: [f2("src/styles.css", `@theme {
@@ -1609,15 +1609,16 @@ function makeSnapshot(patch = {}) {
1609
1609
  }
1610
1610
 
1611
1611
  // src/snapshot/fonts.ts
1612
+ var SYSTEM = /^(?:system-ui|-apple-system|BlinkMacSystemFont|ui-sans-serif|ui-serif|ui-monospace|ui-rounded|sans-serif|serif|monospace|cursive)$/i;
1612
1613
  function normaliseFamily(raw) {
1613
1614
  let name = raw.replace(/["']/g, "").trim();
1614
1615
  const next = name.match(/^__(.+?)(?:_Fallback)?_[0-9a-f]{5,8}$/i);
1615
1616
  if (next) name = next[1].replace(/_/g, " ");
1616
1617
  name = name.replace(/\s+Fallback$/i, "").replace(/\s+Variable$/i, "");
1618
+ if (SYSTEM.test(name)) return "system-ui";
1617
1619
  if (!/\s/.test(name) && (/[a-z][A-Z]/.test(name) || /^[a-z]+(?:-[a-z]+)+$/.test(name))) {
1618
1620
  name = name.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").replace(/\b([a-z])/g, (c) => c.toUpperCase()).replace(/\bDm\b/, "DM");
1619
1621
  }
1620
- if (/^(?:system-ui|-apple-system|BlinkMacSystemFont|ui-sans-serif|ui-serif|ui-monospace|sans-serif|serif|monospace)$/i.test(name)) return "system-ui";
1621
1622
  return name;
1622
1623
  }
1623
1624
  var KNOWN = {
@@ -1969,6 +1970,7 @@ function auditSnapshot(snapshot, options = {}) {
1969
1970
  // src/fingerprint/index.ts
1970
1971
  var FINGERPRINT_VERSION = 1;
1971
1972
  var CHROMATIC = 0.03;
1973
+ var MIN_ACCENT_AREA = 2e4;
1972
1974
  var oklch = (value) => {
1973
1975
  const parsed = parseColour(value);
1974
1976
  return parsed && parsed.alpha > 0.5 ? parsed.oklch : null;
@@ -1981,7 +1983,7 @@ function accentOf(s) {
1981
1983
  }
1982
1984
  const topButton = [...buttons].sort((a, b) => b[1] - a[1])[0];
1983
1985
  if (topButton) return oklch(topButton[0]);
1984
- const bg = s.colours.backgrounds.map((b) => ({ o: oklch(b.value), w: b.area })).filter((x) => x.o && x.o.c >= CHROMATIC).sort((a, b) => b.w - a.w)[0];
1986
+ const bg = s.colours.backgrounds.map((b) => ({ o: oklch(b.value), w: b.area })).filter((x) => x.o && x.o.c >= CHROMATIC && x.w >= MIN_ACCENT_AREA).sort((a, b) => b.w - a.w)[0];
1985
1987
  if (bg) return bg.o;
1986
1988
  const text = s.colours.text.map((t) => ({ o: oklch(t.value), w: t.chars })).filter((x) => x.o && x.o.c >= CHROMATIC).sort((a, b) => b.w - a.w)[0];
1987
1989
  return text ? text.o : null;
@@ -2176,13 +2178,18 @@ function collectInPage() {
2176
2178
  pushBlocks(root, 0);
2177
2179
  const header = document.querySelector("body > header, header");
2178
2180
  const h1 = document.querySelector("h1");
2181
+ const waiting = (c) => {
2182
+ const cs = style(c);
2183
+ const op = parseFloat(cs.opacity);
2184
+ return op < 0.1 || op < 1 && cs.transform !== "none" || c.hasAttribute("data-aos") || /\breveal\b|\bfade-?(?:in|up)\b|\banimate-on-scroll\b/i.test(typeof c.className === "string" ? c.className : "");
2185
+ };
2179
2186
  const hiddenAtLoad = (el) => {
2180
- const check = [el, ...Array.from(el.children).slice(0, 6)];
2181
- return check.some((c) => {
2182
- const cs = style(c);
2183
- const op = parseFloat(cs.opacity);
2184
- return op < 0.1 || op < 1 && cs.transform !== "none" || c.hasAttribute("data-aos") || /\breveal\b|\bfade-?(?:in|up)\b|\banimate-on-scroll\b/i.test(typeof c.className === "string" ? c.className : "");
2185
- });
2187
+ if ([el, ...Array.from(el.children).slice(0, 6)].some(waiting)) return true;
2188
+ const blocks2 = Array.from(el.querySelectorAll("div, article, li, figure, p, h2, h3")).slice(0, 200).filter((d) => {
2189
+ const b = box(d);
2190
+ return b.width > 100 && b.height > 40 && (d.textContent ?? "").trim().length > 12 && style(d).position !== "fixed";
2191
+ }).slice(0, 12);
2192
+ return blocks2.filter(waiting).length >= Math.min(2, blocks2.length) && blocks2.some(waiting);
2186
2193
  };
2187
2194
  const cardsIn = (section) => {
2188
2195
  let best = { cards: 0, iconCards: 0 };
@@ -2381,19 +2388,38 @@ async function snapshotPage(page, url, options = {}) {
2381
2388
  motion: { ...data.motion, introOverlay: early && !late }
2382
2389
  };
2383
2390
  }
2384
- async function snapshotUrl(url, options = {}) {
2385
- const pw = await loadPlaywright();
2391
+ async function launch(pw, url, options) {
2386
2392
  const env = globalThis.process?.env ?? {};
2387
2393
  const executablePath = options.executablePath ?? env.CRAFT_CHROMIUM ?? void 0;
2388
2394
  const host = new URL(url).hostname;
2389
2395
  const noProxy = [`localhost`, `127.0.0.1`, `::1`, ...(env.NO_PROXY ?? env.no_proxy ?? "").split(",")].map((h) => h.trim().replace(/^\*?\./, "")).filter(Boolean);
2390
2396
  const direct = /^(?:localhost|127\.|\[?::1\]?$)/.test(host) || noProxy.some((h) => host === h || host.endsWith(`.${h}`));
2391
2397
  const proxy = direct ? void 0 : env.HTTPS_PROXY ?? env.https_proxy;
2392
- const browser = await pw.chromium.launch({ headless: true, ...executablePath ? { executablePath } : {}, ...proxy ? { proxy: { server: proxy } } : {} });
2398
+ return pw.chromium.launch({ headless: true, ...executablePath ? { executablePath } : {}, ...proxy ? { proxy: { server: proxy } } : {} });
2399
+ }
2400
+ async function snapshotUrl(url, options = {}) {
2401
+ const [result] = await snapshotUrls([url], options);
2402
+ if (!result.snapshot) throw new Error(result.error);
2403
+ return result.snapshot;
2404
+ }
2405
+ async function snapshotUrls(urls, options = {}) {
2406
+ if (urls.length === 0) return [];
2407
+ const pw = await loadPlaywright();
2408
+ const browser = await launch(pw, urls[0], options);
2409
+ const out = [];
2393
2410
  try {
2394
- const page = await browser.newPage({ viewport: options.viewport ?? { width: 1440, height: 900 } });
2395
- await page.goto(url, { waitUntil: "domcontentloaded", timeout: options.timeoutMs ?? 45e3 });
2396
- return await snapshotPage(page, url, options);
2411
+ for (const url of urls) {
2412
+ const page = await browser.newPage({ viewport: options.viewport ?? { width: 1440, height: 900 } });
2413
+ try {
2414
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: options.timeoutMs ?? 45e3 });
2415
+ out.push({ url, snapshot: await snapshotPage(page, url, options) });
2416
+ } catch (error) {
2417
+ out.push({ url, error: error.message });
2418
+ } finally {
2419
+ await page.close?.();
2420
+ }
2421
+ }
2422
+ return out;
2397
2423
  } finally {
2398
2424
  await browser.close();
2399
2425
  }
@@ -2408,5 +2434,6 @@ export {
2408
2434
  loadPlaywright,
2409
2435
  overlayInPage,
2410
2436
  snapshotPage,
2411
- snapshotUrl
2437
+ snapshotUrl,
2438
+ snapshotUrls
2412
2439
  };