@domandigital/craft 0.23.2 → 0.24.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 +11 -5
- package/CHARACTER.md +96 -96
- package/COPY.md +2 -2
- package/PRINCIPLES.md +5 -5
- package/README.md +8 -8
- package/REGISTERS.md +3 -3
- package/design-review.schema.json +1 -1
- package/dist/{audit-SWLTAEDO.js → audit-Q73WGKMS.js} +3 -3
- package/dist/audit.cjs +22 -22
- package/dist/audit.js +22 -22
- package/dist/{chunk-A5M4AOMY.js → chunk-2CCL5CO7.js} +14 -14
- package/dist/{chunk-FBGXUVZU.js → chunk-4HPAMB52.js} +4 -4
- package/dist/{chunk-A5OYA2BG.js → chunk-6TOY3FAT.js} +5 -5
- package/dist/{chunk-E2ZYFBQX.js → chunk-GJZ4Y5PT.js} +5 -5
- package/dist/{chunk-NK6AAY7O.js → chunk-OA2MBUJJ.js} +1 -1
- package/dist/{chunk-CB4QDMH2.js → chunk-OOT4QLO3.js} +14 -14
- package/dist/{chunk-QNX7CROK.js → chunk-PXJKYMXF.js} +2 -2
- package/dist/{chunk-ZTHVOXZF.js → chunk-R4KPE4G5.js} +9 -9
- package/dist/{cli-BA3IVSMR.js → cli-766R2BUR.js} +5 -5
- package/dist/{cli-T5L55IWF.js → cli-CE7ENNNG.js} +6 -6
- package/dist/{cli-UPO4PR3Z.js → cli-DTJOOTNM.js} +3 -3
- package/dist/{cli-O2IEHB5Q.js → cli-EQJITFVE.js} +4 -4
- package/dist/{cli-ATLKYXPU.js → cli-SD2BJSGP.js} +6 -6
- package/dist/{cli-ZMLKL2NT.js → cli-TBBXUECM.js} +5 -5
- package/dist/{cli-BP4JLNAU.js → cli-TV2IJ5TV.js} +2 -3
- package/dist/{cli-7IAFZ6CV.js → cli-U3SPFILJ.js} +9 -9
- package/dist/cli.js +3 -3
- package/dist/index.cjs +23 -24
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +23 -24
- package/dist/{viewports-cli-Y4HPKZLI.js → viewports-cli-SOOHAD5D.js} +3 -3
- package/package.json +1 -1
package/REGISTERS.md
CHANGED
|
@@ -29,8 +29,8 @@ nominalisations, pronoun openers, paired phrases, contractions, person and
|
|
|
29
29
|
passive voice. Names, figures and specifics are left out, because they say
|
|
30
30
|
what a text is about, not how it is written.
|
|
31
31
|
|
|
32
|
-
It needs five paragraphs of two to eight sentences each. In
|
|
33
|
-
|
|
32
|
+
It needs five paragraphs of two to eight sentences each. In the register
|
|
33
|
+
separation report (kept in the private craft corpus), single passages from different
|
|
34
34
|
registers overlap too much to place (26 of 258 pair tests separate), while
|
|
35
35
|
five-paragraph averages separate every register pair (78 of 258). Anything
|
|
36
36
|
shorter gets the brief, not a measurement.
|
|
@@ -157,7 +157,7 @@ Generated from `src/register/registers.ts` by
|
|
|
157
157
|
**Sources:**
|
|
158
158
|
|
|
159
159
|
- house judgement: No public style authority exists for premium-brand prose. These directives are house judgement, to be revised as the estate grows.
|
|
160
|
-
-
|
|
160
|
+
- Register separation, 2026-09-29 (report in the private craft corpus): Literary prose (Gutenberg) carries about twice the comma density of the other human registers, the one feature that separated it from all four. Longer, jointed sentences are normal here.
|
|
161
161
|
|
|
162
162
|
**Always:** Every register keeps the COPY.md blocking tier and the proof rule. Draft first, then run `craft copy <file>` on the draft.
|
|
163
163
|
<!-- craft:registers:end -->
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"source": {
|
|
34
34
|
"type": "object",
|
|
35
|
-
"description": "Where the review came from, when it is a reviewer's own record (a reviewer corpus
|
|
35
|
+
"description": "Where the review came from, when it is a reviewer's own record (a reviewer corpus, such as the one kept in the private craft corpus).",
|
|
36
36
|
"required": [
|
|
37
37
|
"tool"
|
|
38
38
|
],
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
snapshotPage,
|
|
10
10
|
snapshotUrl,
|
|
11
11
|
snapshotUrls
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OA2MBUJJ.js";
|
|
13
13
|
import "./chunk-JYNXGCYZ.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-2CCL5CO7.js";
|
|
15
|
+
import "./chunk-R4KPE4G5.js";
|
|
16
16
|
import "./chunk-QYBAVU3P.js";
|
|
17
17
|
export {
|
|
18
18
|
PROVENANCE_BUDGET_MS,
|
package/dist/audit.cjs
CHANGED
|
@@ -507,7 +507,7 @@ var COPY_TELLS = [
|
|
|
507
507
|
fixtures: {
|
|
508
508
|
flag: [
|
|
509
509
|
f("content/home.md", "Your options, in plain English."),
|
|
510
|
-
//
|
|
510
|
+
// A reviewer's draft lines, Pastel 986559 #12 and #13 (the diagnosis taken, the wording not).
|
|
511
511
|
f("content/clinics.md", "Tell us what's happening and we'll say plainly what we would take on."),
|
|
512
512
|
f("content/pricing.md", "DD's payment terms, plainly stated."),
|
|
513
513
|
f("content/clinics.md", "We explain our findings in plain terms."),
|
|
@@ -633,7 +633,7 @@ var COPY_TELLS = [
|
|
|
633
633
|
fixtures: {
|
|
634
634
|
flag: [
|
|
635
635
|
// From the portal's seeded prospect follow-ups, 2026-10-19.
|
|
636
|
-
f("emails/followup.md", "Alright Dave, it's
|
|
636
|
+
f("emails/followup.md", "Alright Dave, it's Sam. No pressure, have a look when you get a min."),
|
|
637
637
|
f("emails/followup.md", "All good if you're not fussed mate, I'll leave it there."),
|
|
638
638
|
f("emails/followup.md", "Carlo, built the shop a proper site."),
|
|
639
639
|
f("content/contact.md", "No worries, we'll get you sorted."),
|
|
@@ -646,11 +646,11 @@ var COPY_TELLS = [
|
|
|
646
646
|
f("content/home.md", "Proper planning saves a second visit."),
|
|
647
647
|
f("content/certificates.md", "Download a sorted list of certificates, sorted by date."),
|
|
648
648
|
f("content/directions.md", "At the junction, take the right then left turn."),
|
|
649
|
-
//
|
|
649
|
+
// A barber client's own approved line, and "mate" as a noun.
|
|
650
650
|
f("content/home.md", "Every cut starts with a proper chat about what you actually want."),
|
|
651
651
|
f("content/home.md", "It feels like getting a cut from a mate who knows what he is doing."),
|
|
652
652
|
f("emails/quote.md", "Have a look at the quote and ring me if Thursday does not work."),
|
|
653
|
-
f("content/contact.md", "Give us a ring on
|
|
653
|
+
f("content/contact.md", "Give us a ring on 01632 960123. We take a look at the fault before quoting."),
|
|
654
654
|
f("content/home.md", "Built to last, and made for older houses.")
|
|
655
655
|
]
|
|
656
656
|
}
|
|
@@ -662,14 +662,14 @@ var COPY_TELLS = [
|
|
|
662
662
|
severity: "warn",
|
|
663
663
|
surface: "copy",
|
|
664
664
|
why: "'What this is and is not', 'we have not yet built', 'our experience so far is one practice', 'what we would and wouldn't take on': a model scopes a business by confessing its limits. It reads as small print, and it turns a buyer away before they make contact.",
|
|
665
|
-
fix: "Scope by being precise about what is true, and leave the door open: 'Built and run by us for
|
|
665
|
+
fix: "Scope by being precise about what is true, and leave the door open: 'Built and run by us for a children's therapy practice whose clinicians work across several sites.' Keep contractual facts (eligibility, who runs what) and say them as what the buyer gets.",
|
|
666
666
|
detect: phrases(CONFESSION, quoted),
|
|
667
667
|
fixtures: {
|
|
668
668
|
flag: [
|
|
669
|
-
// Each one from the
|
|
669
|
+
// Each one from the studio's own site, as a reviewer flagged it (Pastel 986559 #8, #12, #13).
|
|
670
670
|
f("content/clinics.md", "What this is and is not: a practice portal we built and run for one practice."),
|
|
671
671
|
f("content/clinics.md", "We have not yet built and run the digital systems of a practice with several clinicians."),
|
|
672
|
-
f("content/home.md", "Including the client portal we run for
|
|
672
|
+
f("content/home.md", "Including the client portal we run for a therapy practice. Our clinic experience so far is one practice."),
|
|
673
673
|
f("content/clinics.md", "Tell us what's happening and we'll say what we would and wouldn't take on."),
|
|
674
674
|
f("content/clinics.md", "We will say what carries over from this work and what we would need to learn first."),
|
|
675
675
|
f("content/clinics.md", "We will tell you where our experience applies directly and where it is close."),
|
|
@@ -678,8 +678,8 @@ var COPY_TELLS = [
|
|
|
678
678
|
f("content/mobile.md", "Mobile is our newest line, so we tell you what we have and haven't done.")
|
|
679
679
|
],
|
|
680
680
|
pass: [
|
|
681
|
-
f("content/clinics.md", "Built and run by us for
|
|
682
|
-
f("content/home.md", "The client portal we run for
|
|
681
|
+
f("content/clinics.md", "Built and run by us for a therapy practice, a growing one whose clinicians work remotely."),
|
|
682
|
+
f("content/home.md", "The client portal we run for a children's therapy practice."),
|
|
683
683
|
// Contractual facts, said as they are.
|
|
684
684
|
f("content/pricing.md", "Pay monthly is open to UK residents aged 18 and over, subject to status."),
|
|
685
685
|
f("content/pricing.md", "Your monthly payments do not buy the site; the buy-out price does."),
|
|
@@ -2604,7 +2604,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2604
2604
|
generation: 1,
|
|
2605
2605
|
severity: "warn",
|
|
2606
2606
|
surface: "source",
|
|
2607
|
-
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow.
|
|
2607
|
+
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow. One salon client's site had 70, the studio's own 40, a therapy practice's 27.",
|
|
2608
2608
|
fix: `Keep one gated signature moment per page (STANDARD section 7) and let the rest arrive still. The limit here is ${REVEAL_LIMIT} per scan.`,
|
|
2609
2609
|
detect: revealHits,
|
|
2610
2610
|
fixtures: {
|
|
@@ -2620,7 +2620,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2620
2620
|
generation: 1,
|
|
2621
2621
|
severity: "warn",
|
|
2622
2622
|
surface: "source",
|
|
2623
|
-
why: "rounded-full on every button, badge and tag is the framework's friendliest default.
|
|
2623
|
+
why: "rounded-full on every button, badge and tag is the framework's friendliest default. One salon client's site had 162, the studio's own 125. A shape used everywhere is not a shape language.",
|
|
2624
2624
|
fix: `Choose the shape language on purpose (and record it), then use the pill only where it means something. The limit here is ${PILL_LIMIT} per scan.`,
|
|
2625
2625
|
detect: pillHits,
|
|
2626
2626
|
fixtures: {
|
|
@@ -2635,7 +2635,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2635
2635
|
generation: 1,
|
|
2636
2636
|
severity: "warn",
|
|
2637
2637
|
surface: "source",
|
|
2638
|
-
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not.
|
|
2638
|
+
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not. One client's journal site ships a full set under its own book, vine and petal assets.",
|
|
2639
2639
|
fix: "Delete the primitives nothing imports. Restyle the ones that stay so they belong to this site.",
|
|
2640
2640
|
detect: shadcnHits,
|
|
2641
2641
|
fixtures: {
|
|
@@ -2693,7 +2693,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2693
2693
|
f3("components/Hero.tsx", `<span className="font-serif italic">reimagined</span>`),
|
|
2694
2694
|
f3("app/globals.css", `.hero h1 { font-style: italic; }`)
|
|
2695
2695
|
],
|
|
2696
|
-
pass: [f3("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in
|
|
2696
|
+
pass: [f3("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in Kettering</h1>
|
|
2697
2697
|
<p><em>Walk-ins</em> welcome.</p>`)]
|
|
2698
2698
|
}
|
|
2699
2699
|
},
|
|
@@ -2709,11 +2709,11 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2709
2709
|
fixtures: {
|
|
2710
2710
|
flag: [
|
|
2711
2711
|
f3("components/Hero.tsx", `<span className="inline-flex rounded-full border px-3 py-1 text-xs">Now booking</span>
|
|
2712
|
-
<h1>Nails in
|
|
2712
|
+
<h1>Nails in Kettering</h1>`),
|
|
2713
2713
|
f3("components/Hero.tsx", `<span className={cn("rounded-full px-3 text-xs", "bg-rose-500/10")}>New</span>
|
|
2714
2714
|
<h1>Nails</h1>`)
|
|
2715
2715
|
],
|
|
2716
|
-
pass: [f3("components/Hero.tsx", `<h1>Nails in
|
|
2716
|
+
pass: [f3("components/Hero.tsx", `<h1>Nails in Kettering</h1>
|
|
2717
2717
|
<span className="inline-flex rounded-full border px-3 py-1 text-xs">Tag</span>`)]
|
|
2718
2718
|
}
|
|
2719
2719
|
},
|
|
@@ -2728,7 +2728,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2728
2728
|
detect: heroCtaPairHits,
|
|
2729
2729
|
fixtures: {
|
|
2730
2730
|
flag: [
|
|
2731
|
-
//
|
|
2731
|
+
// A reviewer's #5 and #36 (Pastel 986559): the studio's own hero and process close.
|
|
2732
2732
|
f3(
|
|
2733
2733
|
"src/components/Hero.astro",
|
|
2734
2734
|
`<section class="hero">
|
|
@@ -2737,20 +2737,20 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2737
2737
|
<a href="/work" class="btn btn-ghost">See our work</a>
|
|
2738
2738
|
</section>`
|
|
2739
2739
|
),
|
|
2740
|
-
// The null build's hero, verbatim in shape (
|
|
2740
|
+
// The null build's hero, verbatim in shape (an electrician brief's null pages, in the private dd-craft-corpus).
|
|
2741
2741
|
f3(
|
|
2742
2742
|
"index.html",
|
|
2743
2743
|
`<nav><a class="btn" href="#contact">Quote</a></nav>
|
|
2744
2744
|
<section id="hero" class="hero">
|
|
2745
|
-
<h1>Electricians in
|
|
2745
|
+
<h1>Electricians in Reading</h1>
|
|
2746
2746
|
<a href="#contact" class="btn btn-primary">Book a Free Quote</a>
|
|
2747
|
-
<a href="tel:+
|
|
2747
|
+
<a href="tel:+441632960210" class="btn btn-outline">Call 01632 960 210</a>
|
|
2748
2748
|
</section>`
|
|
2749
2749
|
),
|
|
2750
2750
|
f3(
|
|
2751
2751
|
"app/page.tsx",
|
|
2752
2752
|
`<section className="relative py-24">
|
|
2753
|
-
<h1 className="text-5xl">Nails in
|
|
2753
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
2754
2754
|
<div className="flex gap-4">
|
|
2755
2755
|
<Button asChild><a href="/book">Book now</a></Button>
|
|
2756
2756
|
<Button variant="outline">View treatments</Button>
|
|
@@ -2779,7 +2779,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2779
2779
|
</header>`
|
|
2780
2780
|
),
|
|
2781
2781
|
f3("app/page.tsx", `<section className="py-24">
|
|
2782
|
-
<h1 className="text-5xl">Nails in
|
|
2782
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
2783
2783
|
<a className="rounded bg-ink px-5 py-3" href="/book">Book now</a>
|
|
2784
2784
|
</section>
|
|
2785
2785
|
<section><a className="rounded bg-ink px-5 py-3" href="/prices">Prices</a></section>`)
|
|
@@ -3555,7 +3555,7 @@ var HOUSE = {
|
|
|
3555
3555
|
"stock-email-line": { tier: "review", label: "stock email line, start with the reason for writing and end with the next step" },
|
|
3556
3556
|
// New 2026-10-19 (founder): review first, like every new tell, until estate hits are read.
|
|
3557
3557
|
"matey-register": { tier: "review", label: "matey register, write plain and complete British English" },
|
|
3558
|
-
// New 2026-10-20 (founder, from
|
|
3558
|
+
// New 2026-10-20 (founder, from a reviewer's notes): review first, like every new tell.
|
|
3559
3559
|
"confession-line": { tier: "review", label: "confession line, scope the work by saying precisely what is true" },
|
|
3560
3560
|
// New 2026-10-23 (a 92EL report passed the gate with three): review, because a
|
|
3561
3561
|
// genuine disclaimer has the same shape. The gerund pair joined not-just-but.
|
package/dist/audit.js
CHANGED
|
@@ -472,7 +472,7 @@ var COPY_TELLS = [
|
|
|
472
472
|
fixtures: {
|
|
473
473
|
flag: [
|
|
474
474
|
f("content/home.md", "Your options, in plain English."),
|
|
475
|
-
//
|
|
475
|
+
// A reviewer's draft lines, Pastel 986559 #12 and #13 (the diagnosis taken, the wording not).
|
|
476
476
|
f("content/clinics.md", "Tell us what's happening and we'll say plainly what we would take on."),
|
|
477
477
|
f("content/pricing.md", "DD's payment terms, plainly stated."),
|
|
478
478
|
f("content/clinics.md", "We explain our findings in plain terms."),
|
|
@@ -598,7 +598,7 @@ var COPY_TELLS = [
|
|
|
598
598
|
fixtures: {
|
|
599
599
|
flag: [
|
|
600
600
|
// From the portal's seeded prospect follow-ups, 2026-10-19.
|
|
601
|
-
f("emails/followup.md", "Alright Dave, it's
|
|
601
|
+
f("emails/followup.md", "Alright Dave, it's Sam. No pressure, have a look when you get a min."),
|
|
602
602
|
f("emails/followup.md", "All good if you're not fussed mate, I'll leave it there."),
|
|
603
603
|
f("emails/followup.md", "Carlo, built the shop a proper site."),
|
|
604
604
|
f("content/contact.md", "No worries, we'll get you sorted."),
|
|
@@ -611,11 +611,11 @@ var COPY_TELLS = [
|
|
|
611
611
|
f("content/home.md", "Proper planning saves a second visit."),
|
|
612
612
|
f("content/certificates.md", "Download a sorted list of certificates, sorted by date."),
|
|
613
613
|
f("content/directions.md", "At the junction, take the right then left turn."),
|
|
614
|
-
//
|
|
614
|
+
// A barber client's own approved line, and "mate" as a noun.
|
|
615
615
|
f("content/home.md", "Every cut starts with a proper chat about what you actually want."),
|
|
616
616
|
f("content/home.md", "It feels like getting a cut from a mate who knows what he is doing."),
|
|
617
617
|
f("emails/quote.md", "Have a look at the quote and ring me if Thursday does not work."),
|
|
618
|
-
f("content/contact.md", "Give us a ring on
|
|
618
|
+
f("content/contact.md", "Give us a ring on 01632 960123. We take a look at the fault before quoting."),
|
|
619
619
|
f("content/home.md", "Built to last, and made for older houses.")
|
|
620
620
|
]
|
|
621
621
|
}
|
|
@@ -627,14 +627,14 @@ var COPY_TELLS = [
|
|
|
627
627
|
severity: "warn",
|
|
628
628
|
surface: "copy",
|
|
629
629
|
why: "'What this is and is not', 'we have not yet built', 'our experience so far is one practice', 'what we would and wouldn't take on': a model scopes a business by confessing its limits. It reads as small print, and it turns a buyer away before they make contact.",
|
|
630
|
-
fix: "Scope by being precise about what is true, and leave the door open: 'Built and run by us for
|
|
630
|
+
fix: "Scope by being precise about what is true, and leave the door open: 'Built and run by us for a children's therapy practice whose clinicians work across several sites.' Keep contractual facts (eligibility, who runs what) and say them as what the buyer gets.",
|
|
631
631
|
detect: phrases(CONFESSION, quoted),
|
|
632
632
|
fixtures: {
|
|
633
633
|
flag: [
|
|
634
|
-
// Each one from the
|
|
634
|
+
// Each one from the studio's own site, as a reviewer flagged it (Pastel 986559 #8, #12, #13).
|
|
635
635
|
f("content/clinics.md", "What this is and is not: a practice portal we built and run for one practice."),
|
|
636
636
|
f("content/clinics.md", "We have not yet built and run the digital systems of a practice with several clinicians."),
|
|
637
|
-
f("content/home.md", "Including the client portal we run for
|
|
637
|
+
f("content/home.md", "Including the client portal we run for a therapy practice. Our clinic experience so far is one practice."),
|
|
638
638
|
f("content/clinics.md", "Tell us what's happening and we'll say what we would and wouldn't take on."),
|
|
639
639
|
f("content/clinics.md", "We will say what carries over from this work and what we would need to learn first."),
|
|
640
640
|
f("content/clinics.md", "We will tell you where our experience applies directly and where it is close."),
|
|
@@ -643,8 +643,8 @@ var COPY_TELLS = [
|
|
|
643
643
|
f("content/mobile.md", "Mobile is our newest line, so we tell you what we have and haven't done.")
|
|
644
644
|
],
|
|
645
645
|
pass: [
|
|
646
|
-
f("content/clinics.md", "Built and run by us for
|
|
647
|
-
f("content/home.md", "The client portal we run for
|
|
646
|
+
f("content/clinics.md", "Built and run by us for a therapy practice, a growing one whose clinicians work remotely."),
|
|
647
|
+
f("content/home.md", "The client portal we run for a children's therapy practice."),
|
|
648
648
|
// Contractual facts, said as they are.
|
|
649
649
|
f("content/pricing.md", "Pay monthly is open to UK residents aged 18 and over, subject to status."),
|
|
650
650
|
f("content/pricing.md", "Your monthly payments do not buy the site; the buy-out price does."),
|
|
@@ -2569,7 +2569,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2569
2569
|
generation: 1,
|
|
2570
2570
|
severity: "warn",
|
|
2571
2571
|
surface: "source",
|
|
2572
|
-
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow.
|
|
2572
|
+
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow. One salon client's site had 70, the studio's own 40, a therapy practice's 27.",
|
|
2573
2573
|
fix: `Keep one gated signature moment per page (STANDARD section 7) and let the rest arrive still. The limit here is ${REVEAL_LIMIT} per scan.`,
|
|
2574
2574
|
detect: revealHits,
|
|
2575
2575
|
fixtures: {
|
|
@@ -2585,7 +2585,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2585
2585
|
generation: 1,
|
|
2586
2586
|
severity: "warn",
|
|
2587
2587
|
surface: "source",
|
|
2588
|
-
why: "rounded-full on every button, badge and tag is the framework's friendliest default.
|
|
2588
|
+
why: "rounded-full on every button, badge and tag is the framework's friendliest default. One salon client's site had 162, the studio's own 125. A shape used everywhere is not a shape language.",
|
|
2589
2589
|
fix: `Choose the shape language on purpose (and record it), then use the pill only where it means something. The limit here is ${PILL_LIMIT} per scan.`,
|
|
2590
2590
|
detect: pillHits,
|
|
2591
2591
|
fixtures: {
|
|
@@ -2600,7 +2600,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2600
2600
|
generation: 1,
|
|
2601
2601
|
severity: "warn",
|
|
2602
2602
|
surface: "source",
|
|
2603
|
-
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not.
|
|
2603
|
+
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not. One client's journal site ships a full set under its own book, vine and petal assets.",
|
|
2604
2604
|
fix: "Delete the primitives nothing imports. Restyle the ones that stay so they belong to this site.",
|
|
2605
2605
|
detect: shadcnHits,
|
|
2606
2606
|
fixtures: {
|
|
@@ -2658,7 +2658,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2658
2658
|
f3("components/Hero.tsx", `<span className="font-serif italic">reimagined</span>`),
|
|
2659
2659
|
f3("app/globals.css", `.hero h1 { font-style: italic; }`)
|
|
2660
2660
|
],
|
|
2661
|
-
pass: [f3("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in
|
|
2661
|
+
pass: [f3("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in Kettering</h1>
|
|
2662
2662
|
<p><em>Walk-ins</em> welcome.</p>`)]
|
|
2663
2663
|
}
|
|
2664
2664
|
},
|
|
@@ -2674,11 +2674,11 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2674
2674
|
fixtures: {
|
|
2675
2675
|
flag: [
|
|
2676
2676
|
f3("components/Hero.tsx", `<span className="inline-flex rounded-full border px-3 py-1 text-xs">Now booking</span>
|
|
2677
|
-
<h1>Nails in
|
|
2677
|
+
<h1>Nails in Kettering</h1>`),
|
|
2678
2678
|
f3("components/Hero.tsx", `<span className={cn("rounded-full px-3 text-xs", "bg-rose-500/10")}>New</span>
|
|
2679
2679
|
<h1>Nails</h1>`)
|
|
2680
2680
|
],
|
|
2681
|
-
pass: [f3("components/Hero.tsx", `<h1>Nails in
|
|
2681
|
+
pass: [f3("components/Hero.tsx", `<h1>Nails in Kettering</h1>
|
|
2682
2682
|
<span className="inline-flex rounded-full border px-3 py-1 text-xs">Tag</span>`)]
|
|
2683
2683
|
}
|
|
2684
2684
|
},
|
|
@@ -2693,7 +2693,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2693
2693
|
detect: heroCtaPairHits,
|
|
2694
2694
|
fixtures: {
|
|
2695
2695
|
flag: [
|
|
2696
|
-
//
|
|
2696
|
+
// A reviewer's #5 and #36 (Pastel 986559): the studio's own hero and process close.
|
|
2697
2697
|
f3(
|
|
2698
2698
|
"src/components/Hero.astro",
|
|
2699
2699
|
`<section class="hero">
|
|
@@ -2702,20 +2702,20 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2702
2702
|
<a href="/work" class="btn btn-ghost">See our work</a>
|
|
2703
2703
|
</section>`
|
|
2704
2704
|
),
|
|
2705
|
-
// The null build's hero, verbatim in shape (
|
|
2705
|
+
// The null build's hero, verbatim in shape (an electrician brief's null pages, in the private dd-craft-corpus).
|
|
2706
2706
|
f3(
|
|
2707
2707
|
"index.html",
|
|
2708
2708
|
`<nav><a class="btn" href="#contact">Quote</a></nav>
|
|
2709
2709
|
<section id="hero" class="hero">
|
|
2710
|
-
<h1>Electricians in
|
|
2710
|
+
<h1>Electricians in Reading</h1>
|
|
2711
2711
|
<a href="#contact" class="btn btn-primary">Book a Free Quote</a>
|
|
2712
|
-
<a href="tel:+
|
|
2712
|
+
<a href="tel:+441632960210" class="btn btn-outline">Call 01632 960 210</a>
|
|
2713
2713
|
</section>`
|
|
2714
2714
|
),
|
|
2715
2715
|
f3(
|
|
2716
2716
|
"app/page.tsx",
|
|
2717
2717
|
`<section className="relative py-24">
|
|
2718
|
-
<h1 className="text-5xl">Nails in
|
|
2718
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
2719
2719
|
<div className="flex gap-4">
|
|
2720
2720
|
<Button asChild><a href="/book">Book now</a></Button>
|
|
2721
2721
|
<Button variant="outline">View treatments</Button>
|
|
@@ -2744,7 +2744,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
2744
2744
|
</header>`
|
|
2745
2745
|
),
|
|
2746
2746
|
f3("app/page.tsx", `<section className="py-24">
|
|
2747
|
-
<h1 className="text-5xl">Nails in
|
|
2747
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
2748
2748
|
<a className="rounded bg-ink px-5 py-3" href="/book">Book now</a>
|
|
2749
2749
|
</section>
|
|
2750
2750
|
<section><a className="rounded bg-ink px-5 py-3" href="/prices">Prices</a></section>`)
|
|
@@ -3520,7 +3520,7 @@ var HOUSE = {
|
|
|
3520
3520
|
"stock-email-line": { tier: "review", label: "stock email line, start with the reason for writing and end with the next step" },
|
|
3521
3521
|
// New 2026-10-19 (founder): review first, like every new tell, until estate hits are read.
|
|
3522
3522
|
"matey-register": { tier: "review", label: "matey register, write plain and complete British English" },
|
|
3523
|
-
// New 2026-10-20 (founder, from
|
|
3523
|
+
// New 2026-10-20 (founder, from a reviewer's notes): review first, like every new tell.
|
|
3524
3524
|
"confession-line": { tier: "review", label: "confession line, scope the work by saying precisely what is true" },
|
|
3525
3525
|
// New 2026-10-23 (a 92EL report passed the gate with three): review, because a
|
|
3526
3526
|
// genuine disclaimer has the same shape. The gerund pair joined not-just-but.
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
parseFile,
|
|
10
10
|
sentencesOf,
|
|
11
11
|
specificity
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-R4KPE4G5.js";
|
|
13
13
|
import {
|
|
14
14
|
SNAPSHOT_VERSION
|
|
15
15
|
} from "./chunk-QYBAVU3P.js";
|
|
@@ -1170,7 +1170,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1170
1170
|
generation: 1,
|
|
1171
1171
|
severity: "warn",
|
|
1172
1172
|
surface: "source",
|
|
1173
|
-
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow.
|
|
1173
|
+
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow. One salon client's site had 70, the studio's own 40, a therapy practice's 27.",
|
|
1174
1174
|
fix: `Keep one gated signature moment per page (STANDARD section 7) and let the rest arrive still. The limit here is ${REVEAL_LIMIT} per scan.`,
|
|
1175
1175
|
detect: revealHits,
|
|
1176
1176
|
fixtures: {
|
|
@@ -1186,7 +1186,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1186
1186
|
generation: 1,
|
|
1187
1187
|
severity: "warn",
|
|
1188
1188
|
surface: "source",
|
|
1189
|
-
why: "rounded-full on every button, badge and tag is the framework's friendliest default.
|
|
1189
|
+
why: "rounded-full on every button, badge and tag is the framework's friendliest default. One salon client's site had 162, the studio's own 125. A shape used everywhere is not a shape language.",
|
|
1190
1190
|
fix: `Choose the shape language on purpose (and record it), then use the pill only where it means something. The limit here is ${PILL_LIMIT} per scan.`,
|
|
1191
1191
|
detect: pillHits,
|
|
1192
1192
|
fixtures: {
|
|
@@ -1201,7 +1201,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1201
1201
|
generation: 1,
|
|
1202
1202
|
severity: "warn",
|
|
1203
1203
|
surface: "source",
|
|
1204
|
-
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not.
|
|
1204
|
+
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not. One client's journal site ships a full set under its own book, vine and petal assets.",
|
|
1205
1205
|
fix: "Delete the primitives nothing imports. Restyle the ones that stay so they belong to this site.",
|
|
1206
1206
|
detect: shadcnHits,
|
|
1207
1207
|
fixtures: {
|
|
@@ -1259,7 +1259,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1259
1259
|
f("components/Hero.tsx", `<span className="font-serif italic">reimagined</span>`),
|
|
1260
1260
|
f("app/globals.css", `.hero h1 { font-style: italic; }`)
|
|
1261
1261
|
],
|
|
1262
|
-
pass: [f("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in
|
|
1262
|
+
pass: [f("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in Kettering</h1>
|
|
1263
1263
|
<p><em>Walk-ins</em> welcome.</p>`)]
|
|
1264
1264
|
}
|
|
1265
1265
|
},
|
|
@@ -1275,11 +1275,11 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1275
1275
|
fixtures: {
|
|
1276
1276
|
flag: [
|
|
1277
1277
|
f("components/Hero.tsx", `<span className="inline-flex rounded-full border px-3 py-1 text-xs">Now booking</span>
|
|
1278
|
-
<h1>Nails in
|
|
1278
|
+
<h1>Nails in Kettering</h1>`),
|
|
1279
1279
|
f("components/Hero.tsx", `<span className={cn("rounded-full px-3 text-xs", "bg-rose-500/10")}>New</span>
|
|
1280
1280
|
<h1>Nails</h1>`)
|
|
1281
1281
|
],
|
|
1282
|
-
pass: [f("components/Hero.tsx", `<h1>Nails in
|
|
1282
|
+
pass: [f("components/Hero.tsx", `<h1>Nails in Kettering</h1>
|
|
1283
1283
|
<span className="inline-flex rounded-full border px-3 py-1 text-xs">Tag</span>`)]
|
|
1284
1284
|
}
|
|
1285
1285
|
},
|
|
@@ -1294,7 +1294,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1294
1294
|
detect: heroCtaPairHits,
|
|
1295
1295
|
fixtures: {
|
|
1296
1296
|
flag: [
|
|
1297
|
-
//
|
|
1297
|
+
// A reviewer's #5 and #36 (Pastel 986559): the studio's own hero and process close.
|
|
1298
1298
|
f(
|
|
1299
1299
|
"src/components/Hero.astro",
|
|
1300
1300
|
`<section class="hero">
|
|
@@ -1303,20 +1303,20 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1303
1303
|
<a href="/work" class="btn btn-ghost">See our work</a>
|
|
1304
1304
|
</section>`
|
|
1305
1305
|
),
|
|
1306
|
-
// The null build's hero, verbatim in shape (
|
|
1306
|
+
// The null build's hero, verbatim in shape (an electrician brief's null pages, in the private dd-craft-corpus).
|
|
1307
1307
|
f(
|
|
1308
1308
|
"index.html",
|
|
1309
1309
|
`<nav><a class="btn" href="#contact">Quote</a></nav>
|
|
1310
1310
|
<section id="hero" class="hero">
|
|
1311
|
-
<h1>Electricians in
|
|
1311
|
+
<h1>Electricians in Reading</h1>
|
|
1312
1312
|
<a href="#contact" class="btn btn-primary">Book a Free Quote</a>
|
|
1313
|
-
<a href="tel:+
|
|
1313
|
+
<a href="tel:+441632960210" class="btn btn-outline">Call 01632 960 210</a>
|
|
1314
1314
|
</section>`
|
|
1315
1315
|
),
|
|
1316
1316
|
f(
|
|
1317
1317
|
"app/page.tsx",
|
|
1318
1318
|
`<section className="relative py-24">
|
|
1319
|
-
<h1 className="text-5xl">Nails in
|
|
1319
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
1320
1320
|
<div className="flex gap-4">
|
|
1321
1321
|
<Button asChild><a href="/book">Book now</a></Button>
|
|
1322
1322
|
<Button variant="outline">View treatments</Button>
|
|
@@ -1345,7 +1345,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1345
1345
|
</header>`
|
|
1346
1346
|
),
|
|
1347
1347
|
f("app/page.tsx", `<section className="py-24">
|
|
1348
|
-
<h1 className="text-5xl">Nails in
|
|
1348
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
1349
1349
|
<a className="rounded bg-ink px-5 py-3" href="/book">Book now</a>
|
|
1350
1350
|
</section>
|
|
1351
1351
|
<section><a className="rounded bg-ink px-5 py-3" href="/prices">Prices</a></section>`)
|
|
@@ -2566,7 +2566,7 @@ var HOUSE = {
|
|
|
2566
2566
|
"stock-email-line": { tier: "review", label: "stock email line, start with the reason for writing and end with the next step" },
|
|
2567
2567
|
// New 2026-10-19 (founder): review first, like every new tell, until estate hits are read.
|
|
2568
2568
|
"matey-register": { tier: "review", label: "matey register, write plain and complete British English" },
|
|
2569
|
-
// New 2026-10-20 (founder, from
|
|
2569
|
+
// New 2026-10-20 (founder, from a reviewer's notes): review first, like every new tell.
|
|
2570
2570
|
"confession-line": { tier: "review", label: "confession line, scope the work by saying precisely what is true" },
|
|
2571
2571
|
// New 2026-10-23 (a 92EL report passed the gate with three): review, because a
|
|
2572
2572
|
// genuine disclaimer has the same shape. The gerund pair joined not-just-but.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
snapshotUrl,
|
|
3
3
|
snapshotUrls
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OA2MBUJJ.js";
|
|
5
5
|
import {
|
|
6
6
|
describeTypicality,
|
|
7
7
|
loadNull
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GJZ4Y5PT.js";
|
|
9
9
|
import {
|
|
10
10
|
SOURCE_FILE,
|
|
11
11
|
finish,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
parseFlags,
|
|
15
15
|
prepareReport,
|
|
16
16
|
readPaths
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-OOT4QLO3.js";
|
|
18
18
|
import {
|
|
19
19
|
toJson
|
|
20
20
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
rhythmOf,
|
|
29
29
|
scanSource,
|
|
30
30
|
typicality
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-2CCL5CO7.js";
|
|
32
32
|
|
|
33
33
|
// src/audit/cli.ts
|
|
34
34
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
formatDirectionMatches,
|
|
5
5
|
summariseDirection,
|
|
6
6
|
validateDirection
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PXJKYMXF.js";
|
|
8
8
|
import {
|
|
9
9
|
loadNull
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-GJZ4Y5PT.js";
|
|
11
11
|
import {
|
|
12
12
|
parseFlags
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-OOT4QLO3.js";
|
|
14
14
|
import {
|
|
15
15
|
toJson
|
|
16
16
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
rhythmOf,
|
|
31
31
|
shapeName,
|
|
32
32
|
temperatureName
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-2CCL5CO7.js";
|
|
34
34
|
|
|
35
35
|
// src/estate/cli.ts
|
|
36
36
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -133,7 +133,7 @@ async function snapshotOf(target, cwd) {
|
|
|
133
133
|
return snap;
|
|
134
134
|
}
|
|
135
135
|
if (!/^https?:\/\//.test(target)) throw new Error(`${target} is neither a URL, a snapshot file, nor a site in the register`);
|
|
136
|
-
const { snapshotUrl } = await import("./audit-
|
|
136
|
+
const { snapshotUrl } = await import("./audit-Q73WGKMS.js");
|
|
137
137
|
return snapshotUrl(target);
|
|
138
138
|
}
|
|
139
139
|
var line = (distance, sibling, shared) => `${distance.toFixed(2)}${sibling ? " SIBLING" : ""}${shared.length ? ` shares ${shared.join(", ")}` : ""}`;
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-OQXTQQAU.js";
|
|
4
4
|
import {
|
|
5
5
|
parseFlags
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OOT4QLO3.js";
|
|
7
7
|
import {
|
|
8
8
|
toJson
|
|
9
9
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -22,10 +22,10 @@ import {
|
|
|
22
22
|
hueSwatch,
|
|
23
23
|
nullPrompt,
|
|
24
24
|
scanSource
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-2CCL5CO7.js";
|
|
26
26
|
import {
|
|
27
27
|
extractStrings
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-R4KPE4G5.js";
|
|
29
29
|
|
|
30
30
|
// src/null/cli.ts
|
|
31
31
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "fs";
|
|
@@ -120,7 +120,7 @@ async function build(flags, io) {
|
|
|
120
120
|
const toShoot = ids.filter((id) => existsSync(join(pages, `${id}.html`)) && !existsSync(join(shots, `${id}.json`)));
|
|
121
121
|
if (toShoot.length) {
|
|
122
122
|
io.out(`craft null: snapshotting ${toShoot.length} page${toShoot.length === 1 ? "" : "s"}`);
|
|
123
|
-
const { snapshotUrls } = await import("./audit-
|
|
123
|
+
const { snapshotUrls } = await import("./audit-Q73WGKMS.js");
|
|
124
124
|
const results = await snapshotUrls(toShoot.map((id) => pathToFileURL(join(pages, `${id}.html`)).href));
|
|
125
125
|
results.forEach((r, i) => {
|
|
126
126
|
const id = toShoot[i];
|
|
@@ -241,7 +241,7 @@ async function importPages(flags, io) {
|
|
|
241
241
|
const toShoot = pages.filter((p) => !existsSync(join(shots, `${p.id}.json`)));
|
|
242
242
|
if (toShoot.length) {
|
|
243
243
|
io.out(`craft null: snapshotting ${toShoot.length} page${toShoot.length === 1 ? "" : "s"} from ${flags.builder}`);
|
|
244
|
-
const { snapshotUrls } = await import("./audit-
|
|
244
|
+
const { snapshotUrls } = await import("./audit-Q73WGKMS.js");
|
|
245
245
|
const servers = /* @__PURE__ */ new Map();
|
|
246
246
|
try {
|
|
247
247
|
for (const p of toShoot) if (!servers.has(p.root)) servers.set(p.root, await serveDir(p.root));
|