@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/dist/index.d.ts
CHANGED
|
@@ -1780,7 +1780,7 @@ declare function registersDoc(): string;
|
|
|
1780
1780
|
* `craft register check`: where a draft sits against the human baselines.
|
|
1781
1781
|
*
|
|
1782
1782
|
* A single short passage cannot be placed: at blurb length the registers
|
|
1783
|
-
* overlap too much (
|
|
1783
|
+
* overlap too much (the register separation report in the private craft corpus). Averaged over
|
|
1784
1784
|
* five paragraphs, every register pair separates on several features. So the
|
|
1785
1785
|
* check reads documents only, measures each blurb-sized paragraph with the
|
|
1786
1786
|
* same functions the baselines used, averages them, and compares the average
|
|
@@ -2307,8 +2307,8 @@ interface Fingerprint {
|
|
|
2307
2307
|
}
|
|
2308
2308
|
declare function fingerprint(s: Snapshot): Fingerprint;
|
|
2309
2309
|
/**
|
|
2310
|
-
* Chroma at which a ground's tint is unmistakable.
|
|
2311
|
-
* and
|
|
2310
|
+
* Chroma at which a ground's tint is unmistakable. An electrician's cream sits at 0.010
|
|
2311
|
+
* and a plumber's stone at 0.007, both warm paper; the plumber's
|
|
2312
2312
|
* porcelain (#F1F3F4) at 0.003 is a cool hint. A page ground is the largest
|
|
2313
2313
|
* area on the page and the eye adapts to it, so a tint far below what reads
|
|
2314
2314
|
* as a difference between two buttons still reads as warm or cool paper.
|
|
@@ -2659,7 +2659,7 @@ type EvidenceKind = (typeof EVIDENCE_KINDS)[number];
|
|
|
2659
2659
|
declare const CHANGE_CLASSES: readonly ["confirmed-correction", "design-hypothesis", "optional-refinement", "no-change"];
|
|
2660
2660
|
type ChangeClass = (typeof CHANGE_CLASSES)[number];
|
|
2661
2661
|
/**
|
|
2662
|
-
* What was done with a note in a reviewer's own record (
|
|
2662
|
+
* What was done with a note in a reviewer's own record (kept in the private craft corpus).
|
|
2663
2663
|
* take-reworded: the diagnosis is taken and the suggested wording rewritten,
|
|
2664
2664
|
* because a reviewer's lines are copy-checked like anyone's. partly: the aim
|
|
2665
2665
|
* is taken by a smaller or different change. known: already tracked.
|
|
@@ -2902,15 +2902,15 @@ declare function formatDirectionMatches(label: string, matches: DirectionMatch[]
|
|
|
2902
2902
|
declare const ESTATE_VERSION = 1;
|
|
2903
2903
|
/**
|
|
2904
2904
|
* Median fingerprint distance between two null pages built from the same
|
|
2905
|
-
* brief, across seven briefs and 1,330 pairs (calibration/null, 2026-09-23).
|
|
2905
|
+
* brief, across seven briefs and 1,330 pairs (the private corpus's calibration/null, 2026-09-23).
|
|
2906
2906
|
*/
|
|
2907
2907
|
declare const SIBLING_AT = 0.31;
|
|
2908
2908
|
interface EstateSite {
|
|
2909
|
-
/** Short kebab-case id: "
|
|
2909
|
+
/** Short kebab-case id: "electrician", "barber-studio". */
|
|
2910
2910
|
id: string;
|
|
2911
2911
|
client: string;
|
|
2912
2912
|
url: string;
|
|
2913
|
-
/** Where the site's source lives, if known: "
|
|
2913
|
+
/** Where the site's source lives, if known: "client-org/site-repo". */
|
|
2914
2914
|
repo?: string;
|
|
2915
2915
|
/** Absent for a direction registered before the site is built. */
|
|
2916
2916
|
fingerprint?: Fingerprint;
|
|
@@ -3060,7 +3060,7 @@ declare function groundName(o: Oklch): string;
|
|
|
3060
3060
|
/**
|
|
3061
3061
|
* The ground as a person would name it, with its temperature: "cream",
|
|
3062
3062
|
* "cool grey", "warm white", "cool dark". Every light neutral page used to be
|
|
3063
|
-
* "grey", which put
|
|
3063
|
+
* "grey", which put an electrician's cream and a plumber's porcelain under one word.
|
|
3064
3064
|
*/
|
|
3065
3065
|
declare function groundLabel(o: Oklch): string;
|
|
3066
3066
|
declare function shapeName(roundness: number | null): string;
|
|
@@ -3278,7 +3278,7 @@ declare const REVIEW_PHRASES: readonly ["great question", "of course!", "absolut
|
|
|
3278
3278
|
*
|
|
3279
3279
|
* A reason has to be specific enough that whoever reads the file next (a
|
|
3280
3280
|
* person, Claude, a future tool) cannot drift back to the category default
|
|
3281
|
-
* while following it. "Freight Display, because
|
|
3281
|
+
* while following it. "Freight Display, because the salon's photography needs to be
|
|
3282
3282
|
* the hero and the type needs to recede" passes. "Freight Display" does not,
|
|
3283
3283
|
* and neither does "a familiar structure so visitors feel comfortable".
|
|
3284
3284
|
*
|
package/dist/index.js
CHANGED
|
@@ -1990,7 +1990,7 @@ var COPY_TELLS = [
|
|
|
1990
1990
|
fixtures: {
|
|
1991
1991
|
flag: [
|
|
1992
1992
|
f("content/home.md", "Your options, in plain English."),
|
|
1993
|
-
//
|
|
1993
|
+
// A reviewer's draft lines, Pastel 986559 #12 and #13 (the diagnosis taken, the wording not).
|
|
1994
1994
|
f("content/clinics.md", "Tell us what's happening and we'll say plainly what we would take on."),
|
|
1995
1995
|
f("content/pricing.md", "DD's payment terms, plainly stated."),
|
|
1996
1996
|
f("content/clinics.md", "We explain our findings in plain terms."),
|
|
@@ -2116,7 +2116,7 @@ var COPY_TELLS = [
|
|
|
2116
2116
|
fixtures: {
|
|
2117
2117
|
flag: [
|
|
2118
2118
|
// From the portal's seeded prospect follow-ups, 2026-10-19.
|
|
2119
|
-
f("emails/followup.md", "Alright Dave, it's
|
|
2119
|
+
f("emails/followup.md", "Alright Dave, it's Sam. No pressure, have a look when you get a min."),
|
|
2120
2120
|
f("emails/followup.md", "All good if you're not fussed mate, I'll leave it there."),
|
|
2121
2121
|
f("emails/followup.md", "Carlo, built the shop a proper site."),
|
|
2122
2122
|
f("content/contact.md", "No worries, we'll get you sorted."),
|
|
@@ -2129,11 +2129,11 @@ var COPY_TELLS = [
|
|
|
2129
2129
|
f("content/home.md", "Proper planning saves a second visit."),
|
|
2130
2130
|
f("content/certificates.md", "Download a sorted list of certificates, sorted by date."),
|
|
2131
2131
|
f("content/directions.md", "At the junction, take the right then left turn."),
|
|
2132
|
-
//
|
|
2132
|
+
// A barber client's own approved line, and "mate" as a noun.
|
|
2133
2133
|
f("content/home.md", "Every cut starts with a proper chat about what you actually want."),
|
|
2134
2134
|
f("content/home.md", "It feels like getting a cut from a mate who knows what he is doing."),
|
|
2135
2135
|
f("emails/quote.md", "Have a look at the quote and ring me if Thursday does not work."),
|
|
2136
|
-
f("content/contact.md", "Give us a ring on
|
|
2136
|
+
f("content/contact.md", "Give us a ring on 01632 960123. We take a look at the fault before quoting."),
|
|
2137
2137
|
f("content/home.md", "Built to last, and made for older houses.")
|
|
2138
2138
|
]
|
|
2139
2139
|
}
|
|
@@ -2145,14 +2145,14 @@ var COPY_TELLS = [
|
|
|
2145
2145
|
severity: "warn",
|
|
2146
2146
|
surface: "copy",
|
|
2147
2147
|
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.",
|
|
2148
|
-
fix: "Scope by being precise about what is true, and leave the door open: 'Built and run by us for
|
|
2148
|
+
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.",
|
|
2149
2149
|
detect: phrases(CONFESSION, quoted),
|
|
2150
2150
|
fixtures: {
|
|
2151
2151
|
flag: [
|
|
2152
|
-
// Each one from the
|
|
2152
|
+
// Each one from the studio's own site, as a reviewer flagged it (Pastel 986559 #8, #12, #13).
|
|
2153
2153
|
f("content/clinics.md", "What this is and is not: a practice portal we built and run for one practice."),
|
|
2154
2154
|
f("content/clinics.md", "We have not yet built and run the digital systems of a practice with several clinicians."),
|
|
2155
|
-
f("content/home.md", "Including the client portal we run for
|
|
2155
|
+
f("content/home.md", "Including the client portal we run for a therapy practice. Our clinic experience so far is one practice."),
|
|
2156
2156
|
f("content/clinics.md", "Tell us what's happening and we'll say what we would and wouldn't take on."),
|
|
2157
2157
|
f("content/clinics.md", "We will say what carries over from this work and what we would need to learn first."),
|
|
2158
2158
|
f("content/clinics.md", "We will tell you where our experience applies directly and where it is close."),
|
|
@@ -2161,8 +2161,8 @@ var COPY_TELLS = [
|
|
|
2161
2161
|
f("content/mobile.md", "Mobile is our newest line, so we tell you what we have and haven't done.")
|
|
2162
2162
|
],
|
|
2163
2163
|
pass: [
|
|
2164
|
-
f("content/clinics.md", "Built and run by us for
|
|
2165
|
-
f("content/home.md", "The client portal we run for
|
|
2164
|
+
f("content/clinics.md", "Built and run by us for a therapy practice, a growing one whose clinicians work remotely."),
|
|
2165
|
+
f("content/home.md", "The client portal we run for a children's therapy practice."),
|
|
2166
2166
|
// Contractual facts, said as they are.
|
|
2167
2167
|
f("content/pricing.md", "Pay monthly is open to UK residents aged 18 and over, subject to status."),
|
|
2168
2168
|
f("content/pricing.md", "Your monthly payments do not buy the site; the buy-out price does."),
|
|
@@ -3952,7 +3952,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
3952
3952
|
generation: 1,
|
|
3953
3953
|
severity: "warn",
|
|
3954
3954
|
surface: "source",
|
|
3955
|
-
why: "When every block fades up on scroll, the motion stops meaning anything and the page feels slow.
|
|
3955
|
+
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.",
|
|
3956
3956
|
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.`,
|
|
3957
3957
|
detect: revealHits,
|
|
3958
3958
|
fixtures: {
|
|
@@ -3968,7 +3968,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
3968
3968
|
generation: 1,
|
|
3969
3969
|
severity: "warn",
|
|
3970
3970
|
surface: "source",
|
|
3971
|
-
why: "rounded-full on every button, badge and tag is the framework's friendliest default.
|
|
3971
|
+
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.",
|
|
3972
3972
|
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.`,
|
|
3973
3973
|
detect: pillHits,
|
|
3974
3974
|
fixtures: {
|
|
@@ -3983,7 +3983,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
3983
3983
|
generation: 1,
|
|
3984
3984
|
severity: "warn",
|
|
3985
3985
|
surface: "source",
|
|
3986
|
-
why: "A generator exports the whole shadcn/ui kit whether the site uses it or not.
|
|
3986
|
+
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.",
|
|
3987
3987
|
fix: "Delete the primitives nothing imports. Restyle the ones that stay so they belong to this site.",
|
|
3988
3988
|
detect: shadcnHits,
|
|
3989
3989
|
fixtures: {
|
|
@@ -4041,7 +4041,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
4041
4041
|
f3("components/Hero.tsx", `<span className="font-serif italic">reimagined</span>`),
|
|
4042
4042
|
f3("app/globals.css", `.hero h1 { font-style: italic; }`)
|
|
4043
4043
|
],
|
|
4044
|
-
pass: [f3("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in
|
|
4044
|
+
pass: [f3("components/Hero.tsx", `<h1 className="font-display text-6xl">Nails in Kettering</h1>
|
|
4045
4045
|
<p><em>Walk-ins</em> welcome.</p>`)]
|
|
4046
4046
|
}
|
|
4047
4047
|
},
|
|
@@ -4057,11 +4057,11 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
4057
4057
|
fixtures: {
|
|
4058
4058
|
flag: [
|
|
4059
4059
|
f3("components/Hero.tsx", `<span className="inline-flex rounded-full border px-3 py-1 text-xs">Now booking</span>
|
|
4060
|
-
<h1>Nails in
|
|
4060
|
+
<h1>Nails in Kettering</h1>`),
|
|
4061
4061
|
f3("components/Hero.tsx", `<span className={cn("rounded-full px-3 text-xs", "bg-rose-500/10")}>New</span>
|
|
4062
4062
|
<h1>Nails</h1>`)
|
|
4063
4063
|
],
|
|
4064
|
-
pass: [f3("components/Hero.tsx", `<h1>Nails in
|
|
4064
|
+
pass: [f3("components/Hero.tsx", `<h1>Nails in Kettering</h1>
|
|
4065
4065
|
<span className="inline-flex rounded-full border px-3 py-1 text-xs">Tag</span>`)]
|
|
4066
4066
|
}
|
|
4067
4067
|
},
|
|
@@ -4076,7 +4076,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
4076
4076
|
detect: heroCtaPairHits,
|
|
4077
4077
|
fixtures: {
|
|
4078
4078
|
flag: [
|
|
4079
|
-
//
|
|
4079
|
+
// A reviewer's #5 and #36 (Pastel 986559): the studio's own hero and process close.
|
|
4080
4080
|
f3(
|
|
4081
4081
|
"src/components/Hero.astro",
|
|
4082
4082
|
`<section class="hero">
|
|
@@ -4085,20 +4085,20 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
4085
4085
|
<a href="/work" class="btn btn-ghost">See our work</a>
|
|
4086
4086
|
</section>`
|
|
4087
4087
|
),
|
|
4088
|
-
// The null build's hero, verbatim in shape (
|
|
4088
|
+
// The null build's hero, verbatim in shape (an electrician brief's null pages, in the private dd-craft-corpus).
|
|
4089
4089
|
f3(
|
|
4090
4090
|
"index.html",
|
|
4091
4091
|
`<nav><a class="btn" href="#contact">Quote</a></nav>
|
|
4092
4092
|
<section id="hero" class="hero">
|
|
4093
|
-
<h1>Electricians in
|
|
4093
|
+
<h1>Electricians in Reading</h1>
|
|
4094
4094
|
<a href="#contact" class="btn btn-primary">Book a Free Quote</a>
|
|
4095
|
-
<a href="tel:+
|
|
4095
|
+
<a href="tel:+441632960210" class="btn btn-outline">Call 01632 960 210</a>
|
|
4096
4096
|
</section>`
|
|
4097
4097
|
),
|
|
4098
4098
|
f3(
|
|
4099
4099
|
"app/page.tsx",
|
|
4100
4100
|
`<section className="relative py-24">
|
|
4101
|
-
<h1 className="text-5xl">Nails in
|
|
4101
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
4102
4102
|
<div className="flex gap-4">
|
|
4103
4103
|
<Button asChild><a href="/book">Book now</a></Button>
|
|
4104
4104
|
<Button variant="outline">View treatments</Button>
|
|
@@ -4127,7 +4127,7 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
4127
4127
|
</header>`
|
|
4128
4128
|
),
|
|
4129
4129
|
f3("app/page.tsx", `<section className="py-24">
|
|
4130
|
-
<h1 className="text-5xl">Nails in
|
|
4130
|
+
<h1 className="text-5xl">Nails in Kettering</h1>
|
|
4131
4131
|
<a className="rounded bg-ink px-5 py-3" href="/book">Book now</a>
|
|
4132
4132
|
</section>
|
|
4133
4133
|
<section><a className="rounded bg-ink px-5 py-3" href="/prices">Prices</a></section>`)
|
|
@@ -5375,7 +5375,7 @@ var HOUSE = {
|
|
|
5375
5375
|
"stock-email-line": { tier: "review", label: "stock email line, start with the reason for writing and end with the next step" },
|
|
5376
5376
|
// New 2026-10-19 (founder): review first, like every new tell, until estate hits are read.
|
|
5377
5377
|
"matey-register": { tier: "review", label: "matey register, write plain and complete British English" },
|
|
5378
|
-
// New 2026-10-20 (founder, from
|
|
5378
|
+
// New 2026-10-20 (founder, from a reviewer's notes): review first, like every new tell.
|
|
5379
5379
|
"confession-line": { tier: "review", label: "confession line, scope the work by saying precisely what is true" },
|
|
5380
5380
|
// New 2026-10-23 (a 92EL report passed the gate with three): review, because a
|
|
5381
5381
|
// genuine disclaimer has the same shape. The gerund pair joined not-just-but.
|
|
@@ -7410,8 +7410,7 @@ var REGISTERS = [
|
|
|
7410
7410
|
note: "No public style authority exists for premium-brand prose. These directives are house judgement, to be revised as the estate grows."
|
|
7411
7411
|
},
|
|
7412
7412
|
{
|
|
7413
|
-
name: "Register separation, 2026-09-29",
|
|
7414
|
-
url: "calibration/copy-shape/report-registers.md",
|
|
7413
|
+
name: "Register separation, 2026-09-29 (report in the private craft corpus)",
|
|
7415
7414
|
note: "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."
|
|
7416
7415
|
}
|
|
7417
7416
|
]
|
|
@@ -16,13 +16,13 @@ import {
|
|
|
16
16
|
} from "./chunk-XSKLVEI6.js";
|
|
17
17
|
import {
|
|
18
18
|
loadPlaywright
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-OA2MBUJJ.js";
|
|
20
20
|
import "./chunk-JYNXGCYZ.js";
|
|
21
21
|
import {
|
|
22
22
|
toJson
|
|
23
23
|
} from "./chunk-QIEDBL4J.js";
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-2CCL5CO7.js";
|
|
25
|
+
import "./chunk-R4KPE4G5.js";
|
|
26
26
|
import "./chunk-QYBAVU3P.js";
|
|
27
27
|
|
|
28
28
|
// src/phone/viewports-cli.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domandigital/craft",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Doman Digital house craft standard as numbers: OKLCh colour ramps that snap to existing anchors, derived semantic tokens with measured WCAG and APCA contrast, one shared motion vocabulary for CSS and JS, and a base stylesheet. Zero dependencies.",
|
|
6
6
|
"license": "Apache-2.0",
|