@domandigital/craft 0.13.0 → 0.15.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 +24 -0
- package/CHARACTER.md +272 -39
- package/COPY.md +5 -0
- package/README.md +19 -1
- package/art-direction.schema.json +428 -25
- package/dist/{audit-5TYDYRXV.js → audit-MTUC24XU.js} +3 -2
- package/dist/audit.cjs +674 -92
- package/dist/audit.d.cts +15 -1
- package/dist/audit.d.ts +15 -1
- package/dist/audit.js +674 -92
- package/dist/{chunk-IMB4V34S.js → chunk-2IQ5OXFR.js} +7 -7
- package/dist/{chunk-GMVXADJ6.js → chunk-LFNSB6W7.js} +711 -92
- package/dist/{chunk-3VTPI7BU.js → chunk-MUVFECFC.js} +74 -96
- package/dist/chunk-OQXTQQAU.js +27 -0
- package/dist/{chunk-ZLDA2SYB.js → chunk-OUQ25LY2.js} +47 -6
- package/dist/{chunk-K2BZN4GA.js → chunk-QU6Q2QZZ.js} +49 -14
- package/dist/chunk-QYBAVU3P.js +6 -0
- package/dist/{chunk-ESCVTKPN.js → chunk-RXXRXV3V.js} +9 -26
- package/dist/{chunk-CZDOMIVS.js → chunk-WUACK2HX.js} +2 -1
- package/dist/chunk-YDURAOYR.js +711 -0
- package/dist/cli-22TSWAX6.js +21 -0
- package/dist/cli-5ACKICBO.js +22 -0
- package/dist/{cli-DRKAMFAH.js → cli-7OZCYOQY.js} +89 -22
- package/dist/{cli-J5ECRCD4.js → cli-FCKHYAVZ.js} +40 -16
- package/dist/{cli-ILH7OO5G.js → cli-FLG3ZCAF.js} +6 -4
- package/dist/cli.js +3 -2
- package/dist/generate.js +6 -0
- package/dist/index.cjs +1618 -328
- package/dist/index.d.cts +619 -58
- package/dist/index.d.ts +619 -58
- package/dist/index.js +1555 -328
- package/dist/migrate-VIFAYIBM.js +9 -0
- package/package.json +1 -1
- package/word-lists.json +1 -1
- package/dist/chunk-ZZ5CKOJP.js +0 -295
- package/dist/cli-BKJMLD3H.js +0 -18
- package/dist/cli-N2IDXH7W.js +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @domandigital/craft
|
|
2
2
|
|
|
3
|
+
## 0.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 74f0aed: Add art direction version 2 with customer job maps, per-page hierarchy and
|
|
8
|
+
reasons tied to the job. Record and compare declared directions before build,
|
|
9
|
+
print job-only research prompts, and validate order and token drift against
|
|
10
|
+
saved snapshots or preview URLs. Existing version 1 files remain valid with a
|
|
11
|
+
warning; the report requires all three layers before marking reasons decided.
|
|
12
|
+
|
|
13
|
+
Estate entries registered before build have no fingerprint. `EstateSite.fingerprint`
|
|
14
|
+
is now optional; rendered comparisons skip those entries until a snapshot is added.
|
|
15
|
+
|
|
16
|
+
- 006c97d: Expose pure shape measurements for short copy and add resumable calibration
|
|
17
|
+
tooling with frozen human baselines. This is a measurement foundation: no new
|
|
18
|
+
copy tells or blocking rules ship. Incomplete generation cannot approve a
|
|
19
|
+
feature for the catalogue.
|
|
20
|
+
|
|
21
|
+
## 0.14.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- 8686cf1: Phase N, specificity. `specificity(text, brief?)` counts what only this business could have written: names, places, numbers, prices, dates, contact details and trade nouns, with Title Case and shouted lines read without their capitals and stock figures ("24/7", "100%", "5-star") masked. A brief's own terms are recognised wherever they appear. Snapshots now record each section's `text` and the `firstScreenText` a visitor reads before scrolling, leaving out navigation, buttons, links and footers. Two new tells, both `warn`: `generic-hero-claim` (copy and rendered, home page only: the headline and the line under it name nothing particular) and `unproven-claim` (rendered: a claim of standing such as "trusted" or "fully qualified" with no review, rating, registration number or accreditation in its section or the one either side). `craft copy compare <ours> --competitor <theirs>` lists the hero and service sentences on each page that hold no specific the other page lacks. The catalogue table no longer prints "rendered + rendered" for rendered-only tells.
|
|
26
|
+
|
|
3
27
|
## 0.13.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
package/CHARACTER.md
CHANGED
|
@@ -9,16 +9,15 @@ Inter, a glass card over the hero, a strip of logos, three icon cards, every
|
|
|
9
9
|
section fading up on scroll. None of those is wrong. Together they say nobody
|
|
10
10
|
chose anything.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Decide the page grammar; never reward strangeness
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
Section order, the primary action and what leads are decisions with reasons
|
|
15
|
+
tied to the visitor's job. A conventional order is allowed and never penalised.
|
|
16
|
+
What fails is an order nobody chose. Navigation, legibility and speed remain
|
|
17
|
+
the floor in STANDARD.md and the page audit.
|
|
18
18
|
|
|
19
|
-
Character
|
|
20
|
-
|
|
21
|
-
show, and where a real business has something of its own to draw on.
|
|
19
|
+
Character also comes from the display face, accent, shape, motif and one
|
|
20
|
+
signature moment, with evidence from the client's world.
|
|
22
21
|
|
|
23
22
|
## Three signals, and a reason behind every choice
|
|
24
23
|
|
|
@@ -57,36 +56,222 @@ cleaned and should stay clean.
|
|
|
57
56
|
|
|
58
57
|
## Declaring the direction
|
|
59
58
|
|
|
60
|
-
`art-direction.json`
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
Version 2 of `art-direction.json` records three layers in order:
|
|
60
|
+
|
|
61
|
+
1. **Job.** What the visitor needs to do, under what pressure, with the
|
|
62
|
+
functional, emotional and social sides shown by reviews, enquiries,
|
|
63
|
+
conversations or search evidence. Quote the customer's words and record
|
|
64
|
+
whether consideration is low, considered or high, with evidence.
|
|
65
|
+
2. **Hierarchy.** For each page type, decide the primary action and its
|
|
66
|
+
positions, the section order, what leads and the visitor's journey. Each
|
|
67
|
+
reason must use this client's job. The primary action reason also names the
|
|
68
|
+
consideration level or an objection that explains where the ask sits.
|
|
69
|
+
3. **Tokens.** The seven expressive choices (accent, ground, display, body,
|
|
70
|
+
shape, motif, signature), each with evidence from the client's world.
|
|
71
|
+
|
|
72
|
+
This fictional example is also the executable fixture at
|
|
73
|
+
`src/__tests__/fixtures/direction-v2.json`. Its customer quotes are invented
|
|
74
|
+
fixture data, not research to reuse for a real client.
|
|
64
75
|
|
|
65
76
|
```json
|
|
66
77
|
{
|
|
67
|
-
"version":
|
|
68
|
-
"client": "
|
|
69
|
-
"brief": "A
|
|
78
|
+
"version": 2,
|
|
79
|
+
"client": "Copper Lane Electrical (fictional)",
|
|
80
|
+
"brief": "A local electrician in Brackley repairing dangerous electrical faults for tenants and homeowners.",
|
|
70
81
|
"sources": [
|
|
71
|
-
{
|
|
82
|
+
{
|
|
83
|
+
"id": "review",
|
|
84
|
+
"kind": "review",
|
|
85
|
+
"note": "The socket started sparking tonight. I need the fault fixed today without being overcharged. I want an exact call-out price before I ring. I need to reassure my landlord that the repair is safe."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "van",
|
|
89
|
+
"kind": "livery",
|
|
90
|
+
"note": "The van carries copper lettering on white panels, with square painted borders.",
|
|
91
|
+
"colours": [
|
|
92
|
+
"#a64720",
|
|
93
|
+
"#ffffff"
|
|
94
|
+
],
|
|
95
|
+
"lettering": "Square slab lettering and compact supporting text."
|
|
96
|
+
}
|
|
72
97
|
],
|
|
98
|
+
"job": {
|
|
99
|
+
"statement": {
|
|
100
|
+
"verb": "find",
|
|
101
|
+
"object": "an electrician who can repair a dangerous sparking socket",
|
|
102
|
+
"context": "tonight without being overcharged for the call-out"
|
|
103
|
+
},
|
|
104
|
+
"functional": {
|
|
105
|
+
"value": "The socket started sparking tonight and needs the fault fixed today.",
|
|
106
|
+
"evidence": [
|
|
107
|
+
"review"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"emotional": {
|
|
111
|
+
"value": "They worry about being overcharged and want an exact call-out price.",
|
|
112
|
+
"evidence": [
|
|
113
|
+
"review"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"social": {
|
|
117
|
+
"value": "They need to reassure their landlord that the repair is safe.",
|
|
118
|
+
"evidence": [
|
|
119
|
+
"review"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"consideration": {
|
|
123
|
+
"value": "low",
|
|
124
|
+
"because": "The socket started sparking tonight, leaving minutes to arrange the repair.",
|
|
125
|
+
"evidence": [
|
|
126
|
+
"review"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
"objections": [
|
|
130
|
+
"being overcharged for the call-out",
|
|
131
|
+
"not knowing whether the repair is safe"
|
|
132
|
+
],
|
|
133
|
+
"language": [
|
|
134
|
+
"The socket started sparking tonight",
|
|
135
|
+
"I want an exact call-out price before I ring"
|
|
136
|
+
],
|
|
137
|
+
"evidence": [
|
|
138
|
+
"review"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"hierarchy": {
|
|
142
|
+
"home": {
|
|
143
|
+
"primaryAction": {
|
|
144
|
+
"value": "Call for a repair",
|
|
145
|
+
"positions": [
|
|
146
|
+
"hero",
|
|
147
|
+
"footer-cta"
|
|
148
|
+
],
|
|
149
|
+
"because": "The low consideration job needs a sparking socket repaired tonight, so the call is offered immediately and again after the price."
|
|
150
|
+
},
|
|
151
|
+
"order": [
|
|
152
|
+
{
|
|
153
|
+
"role": "hero",
|
|
154
|
+
"because": "The sparking socket needs repair tonight, so availability comes first."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"role": "pricing",
|
|
158
|
+
"because": "Callers expect a price before they ring, so pricing comes before asking again."
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"role": "footer-cta",
|
|
162
|
+
"because": "Once the call-out price is clear, they can arrange the socket repair."
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"lead": {
|
|
166
|
+
"value": "Socket repairs tonight",
|
|
167
|
+
"subordinate": [
|
|
168
|
+
"planned rewires"
|
|
169
|
+
],
|
|
170
|
+
"because": "The dangerous sparking socket is urgent, so tonight repairs lead ahead of planned rewires."
|
|
171
|
+
},
|
|
172
|
+
"journey": [
|
|
173
|
+
{
|
|
174
|
+
"stage": "reassure",
|
|
175
|
+
"because": "The dangerous socket needs a safe repair, so reassure the tenant first."
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"stage": "act",
|
|
179
|
+
"because": "Once the call-out price is clear, arrange the repair before tonight ends."
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
},
|
|
73
184
|
"choices": {
|
|
74
185
|
"accent": {
|
|
75
|
-
"value": "#
|
|
76
|
-
"because": "The
|
|
77
|
-
"evidence": [
|
|
186
|
+
"value": "#a64720",
|
|
187
|
+
"because": "The van carries copper lettering, so the same copper colour marks calls to action.",
|
|
188
|
+
"evidence": [
|
|
189
|
+
"van"
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
"ground": {
|
|
193
|
+
"value": "#ffffff",
|
|
194
|
+
"because": "The van has white panels behind its lettering, so the page ground follows those panels.",
|
|
195
|
+
"evidence": [
|
|
196
|
+
"van"
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
"display": {
|
|
200
|
+
"value": "Roboto Slab",
|
|
201
|
+
"because": "The square slab lettering on the van gives headlines their squared forms.",
|
|
202
|
+
"evidence": [
|
|
203
|
+
"van"
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
"body": {
|
|
207
|
+
"value": "Source Sans 3",
|
|
208
|
+
"because": "The compact supporting text on the van keeps longer details readable at small sizes.",
|
|
209
|
+
"evidence": [
|
|
210
|
+
"van"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
"shape": {
|
|
214
|
+
"value": "square corners",
|
|
215
|
+
"because": "The painted borders on the van are square, so the buttons keep those corners.",
|
|
216
|
+
"evidence": [
|
|
217
|
+
"van"
|
|
218
|
+
]
|
|
78
219
|
}
|
|
79
|
-
}
|
|
220
|
+
},
|
|
221
|
+
"exceptions": []
|
|
80
222
|
}
|
|
81
223
|
```
|
|
82
224
|
|
|
83
|
-
`craft direction validate`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
225
|
+
`craft direction validate` checks each layer and reports its decisions
|
|
226
|
+
separately. The job and every declared page hierarchy must be complete, with
|
|
227
|
+
at least five of seven tokens decided, before the reason signal can pass in
|
|
228
|
+
`craft report`. Version 1 files remain valid with a warning and cannot settle
|
|
229
|
+
that signal until their job and hierarchy have been recorded.
|
|
230
|
+
|
|
231
|
+
A reason needs at least eight words. Token reasons cite a declared source and
|
|
232
|
+
mention what it shows; job parts cite customer voice. Hierarchy reasons use
|
|
233
|
+
content words from the job. This is a wording check, not a semantic model:
|
|
234
|
+
review whether each reason actually explains the decision. Preferences, mood
|
|
235
|
+
boards, proposals and category defaults such as "industry standard" or
|
|
236
|
+
"a familiar layout" fail. "Callers expect a price before they ring" can pass
|
|
237
|
+
when it answers this job's objection about being overcharged.
|
|
238
|
+
|
|
239
|
+
A `reference` source records its outside category in `category`; a reference
|
|
240
|
+
from the client's trade or a competitor's website fails. URL references warn
|
|
241
|
+
that their category still needs review. The validator cannot identify a
|
|
242
|
+
competitor from an arbitrary URL alone.
|
|
243
|
+
|
|
244
|
+
Start research with `craft direction research --brief "<who, where, what>"`.
|
|
245
|
+
It prints job questions and explicitly forbids descriptions of category
|
|
246
|
+
websites or visual inspiration from them. `--visual` adds a separate prompt
|
|
247
|
+
for references from outside the category. It does not call a model.
|
|
248
|
+
|
|
249
|
+
CTA positions are a list: one or repeated asks are both valid. No universal
|
|
250
|
+
position, F/Z pattern or fixed hero checklist is imposed. Snapshots measure
|
|
251
|
+
vertical section order, not gaze paths; the evidence does not establish a
|
|
252
|
+
universal CTA placement rule.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
craft direction init --client "Copper Lane" --brief "<who, where, what>"
|
|
256
|
+
craft direction validate --direction art-direction.json
|
|
257
|
+
craft estate add --id copper-lane --direction art-direction.json --estate estate.json
|
|
258
|
+
craft direction validate --estate estate.json
|
|
259
|
+
craft direction validate --snapshot http://localhost:3000 --page home --strict
|
|
260
|
+
craft estate compare --estate estate.json --directions
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
`--snapshot` accepts a saved snapshot, staging URL or live URL. It checks the
|
|
264
|
+
hierarchy entry selected by `--page` (home by default) against section roles,
|
|
265
|
+
and checks token values against the fingerprint. Drift warns; `--strict`
|
|
266
|
+
makes drift fail. A snapshot without section roles says order is unmeasured.
|
|
267
|
+
|
|
268
|
+
Directions can be registered before a site renders. These entries have no
|
|
269
|
+
fingerprint and are omitted from rendered comparisons until a snapshot is
|
|
270
|
+
added. `--directions` ranks declared pairs and names shared colours, fonts,
|
|
271
|
+
shape and order. It is advisory, including under `--strict`, until calibrated;
|
|
272
|
+
sharing a conventional order is a prompt to review reasons, not a verdict.
|
|
273
|
+
Accent and ground use the rendered comparison's shared thresholds, ΔE_OK
|
|
274
|
+
0.06 and 0.03. The calibration notes are in ROADMAP.md.
|
|
90
275
|
|
|
91
276
|
It also reads the display and body faces against the licence register
|
|
92
277
|
(`src/direction/licences.ts`, exported as `licences.json`) and warns on a face
|
|
@@ -103,7 +288,7 @@ choices decided.
|
|
|
103
288
|
|
|
104
289
|
`craft direction propose` reads the dominant colours off each source's PNG
|
|
105
290
|
photo, ranks accent candidates away from the reflex violet band and from the
|
|
106
|
-
rest of the estate (`--estate` a folder of snapshots), and drafts choices.
|
|
291
|
+
rest of the estate (`--estate` a folder of snapshots or estate register), and drafts choices.
|
|
107
292
|
Every draft reason starts `PROPOSED:`, which validate rejects: a person looks
|
|
108
293
|
at the van, agrees the green is the van's green, and says so in their own
|
|
109
294
|
words.
|
|
@@ -250,6 +435,52 @@ abstract blob from a diagram needs an SVG's path data or its pixels, which a
|
|
|
250
435
|
cross-origin picture does not give the page, and no flag case has been proved
|
|
251
436
|
reliable. It stays on the list until one is.
|
|
252
437
|
|
|
438
|
+
### Specificity
|
|
439
|
+
|
|
440
|
+
A page built from no brief could belong to anyone, because the model had
|
|
441
|
+
nothing particular to say. Specificity counts what only this business could
|
|
442
|
+
have written: names, places, numbers, prices, dates, contact details, and
|
|
443
|
+
the nouns of the trade (`TRADE_NOUNS`, a seed list). Two rules keep the
|
|
444
|
+
count honest. A Title Case or shouted line's capitals are not read as names
|
|
445
|
+
("Quality You Can Trust" is not a proper noun), and the figures every site
|
|
446
|
+
uses ("24/7", "100%", "5-star", "No. 1") are masked before counting. A text
|
|
447
|
+
is generic when it has no specific other than trade nouns and fewer than two
|
|
448
|
+
of those: one trade noun ("quality plumbing you can trust") is what every
|
|
449
|
+
competitor also says.
|
|
450
|
+
|
|
451
|
+
A snapshot now records the page's text: each section's headings,
|
|
452
|
+
paragraphs, list items and quotes (`text`), and what a visitor reads before
|
|
453
|
+
scrolling (`firstScreenText`), leaving out navigation, a header without the
|
|
454
|
+
headline, footers and the words on buttons and links. Two tells read it:
|
|
455
|
+
|
|
456
|
+
- `generic-hero-claim`: the home page's first screen names nothing
|
|
457
|
+
particular. Also a copy tell, on a literal `<h1>` and the paragraph under
|
|
458
|
+
it in the home page's source (a root route file such as `app/page.tsx`, a
|
|
459
|
+
top-level `index.html`, or a hero or home component). Every other page's
|
|
460
|
+
headline is a label ("Privacy policy", "Boiler repairs"), not a claim, and
|
|
461
|
+
is not judged.
|
|
462
|
+
- `unproven-claim`: a claim of standing ("trusted", "fully qualified",
|
|
463
|
+
"award-winning", "5-star service") with no review, rating, quoted
|
|
464
|
+
testimonial, registration number or accreditation (by name, or as a logo
|
|
465
|
+
whose alt text or file name names it) in its section or the one either
|
|
466
|
+
side.
|
|
467
|
+
|
|
468
|
+
A brief sharpens the count: its own terms (the business's name, its town,
|
|
469
|
+
its trade) are recognised wherever they appear, even opening a sentence or
|
|
470
|
+
in a shouted heading. The tells run without one. `craft copy compare <ours>
|
|
471
|
+
--competitor <theirs>` uses one, from `--brief`, `art-direction.json` or a
|
|
472
|
+
null model's `null.json`, and lists the hero and service sentences on each
|
|
473
|
+
page that hold no specific the other page lacks: a town both name, or a
|
|
474
|
+
trade noun both use, is shared; the business's name, its prices and its
|
|
475
|
+
jobs are its own. It is a measure for a person to read and always exits 0.
|
|
476
|
+
|
|
477
|
+
The limits, stated so nobody reads more into a pass than is there: a place
|
|
478
|
+
in a Title Case heading ("Boiler Repairs In Brackley") is not recognised
|
|
479
|
+
without a brief, a headline whose words come from data (`{site.headline}`)
|
|
480
|
+
is not read in source, and "specific" means particular, not true. `craft
|
|
481
|
+
copy claims` is where a figure gets checked. Snapshots taken before craft
|
|
482
|
+
recorded text have none, and neither tell judges them.
|
|
483
|
+
|
|
253
484
|
## The counterfactual
|
|
254
485
|
|
|
255
486
|
A list of tells goes stale; the model does not. So signal 2 asks the model
|
|
@@ -622,7 +853,7 @@ Generated from the package. Run `pnpm --filter @domandigital/craft run docs`
|
|
|
622
853
|
after changing an entry; a test fails until you do.
|
|
623
854
|
|
|
624
855
|
<!-- craft:catalogue:start -->
|
|
625
|
-
Catalogue version `2026.09.
|
|
856
|
+
Catalogue version `2026.09.12`, 68 tells.
|
|
626
857
|
|
|
627
858
|
| Id | Gen | Surface | Severity | Tell | Why it is a default |
|
|
628
859
|
| --- | --- | --- | --- | --- | --- |
|
|
@@ -682,14 +913,16 @@ Catalogue version `2026.09.11`, 66 tells.
|
|
|
682
913
|
| `repeated-sentence` | 1 | copy | warn | Repeated sentence | The same sentence on two pages, or the same nine words lightly edited, is one of the strongest signs a document was assembled rather than written. |
|
|
683
914
|
| `heading-shape` | 2 | copy | warn | One heading shape | Headings that all share one shape ('X, and Y', 'X, because Y', 'Keep, rewrite, consolidate, retire') read as a template filled in section by section. |
|
|
684
915
|
| `heading-echo` | 2 | copy | warn | Heading echoed | A heading repeated word for word as the first line under it spends the reader's attention twice on the same words. |
|
|
685
|
-
| `
|
|
686
|
-
| `
|
|
687
|
-
| `
|
|
688
|
-
| `
|
|
689
|
-
| `
|
|
690
|
-
| `
|
|
691
|
-
| `
|
|
692
|
-
| `stock-
|
|
693
|
-
| `
|
|
694
|
-
| `
|
|
916
|
+
| `generic-hero-claim` | 1 | copy + rendered | warn | Headline that fits any business | The first thing a visitor reads on the home page names no place, no person, no price and no job, so it would fit every competitor's site unchanged. A model writes it when it has nothing particular to say. |
|
|
917
|
+
| `cta-band-stock` | 1 | rendered | warn | Stock call-to-action band | A full-width coloured band with a centred heading, one line and one or two buttons is what a model closes every section run with. It asks for the booking the same way on every site. |
|
|
918
|
+
| `pricing-trio-popular` | 1 | rendered | warn | Three-tier pricing with a popular badge | Three price cards with the middle one badged 'Most popular' is the SaaS pricing page, applied to a plumber or a salon whether or not anyone chose the middle option. |
|
|
919
|
+
| `testimonial-avatar-carousel` | 1 | rendered | warn | Avatar testimonial carousel | Round headshots over quotes in a sliding carousel is the stock testimonial block. Most visitors see the first slide only, and stock or AI faces make every quote read as invented. |
|
|
920
|
+
| `faq-accordion-closer` | 2 | rendered | warn | FAQ accordion as the closer | Ending the page on a collapsed FAQ, often followed only by a band, is the model's default page ending. The answers a buyer needs are hidden behind clicks at the point they decide. |
|
|
921
|
+
| `stats-row` | 1 | rendered | warn | Row of big numbers | Three or four large figures in a row (500+ clients, 98% satisfaction, 10 years) is the stock proof block, and the numbers are often round, unsourced or invented. |
|
|
922
|
+
| `centred-everything` | 2 | rendered | warn | Every section centred | When almost every section stacks a centred heading over centred text, the page has no reading line and every block looks like the one before. It is the layout nothing was decided for. |
|
|
923
|
+
| `stock-photo` | 1 | rendered | warn | Stock photography | A picture from a stock library is the picture every other site in the trade can use. It shows a job the client did not do, in a kitchen that is not theirs, and a visitor who has seen it before stops believing the rest. |
|
|
924
|
+
| `stock-avatar` | 1 | rendered | warn | Stock or placeholder faces | Round portraits from a placeholder-face service or a stock library next to reviews make every quote read as invented, and some of those faces are generated people who do not exist. |
|
|
925
|
+
| `ai-image` | 2 | rendered | warn | Generated image | The file itself says a model made it (its XMP or Content Credentials name a trained-model source). A generated picture stands in for work the client did not photograph, and anyone can read the label. |
|
|
926
|
+
| `no-real-imagery` | 1 | rendered | warn | No photograph on the page | A page with no photograph at all, only icons and illustrations, is the page a model builds when it has no assets. Icon tiles stand in for the evidence a buyer looks for: the work, the premises, the people. |
|
|
927
|
+
| `unproven-claim` | 1 | rendered | warn | Claim with no proof next to it | "Trusted", "fully qualified" and "award-winning" ask the visitor to take the business's word for it. A page built with no reviews and no registration number makes the claim anyway, with nothing beside it. |
|
|
695
928
|
<!-- craft:catalogue:end -->
|
package/COPY.md
CHANGED
|
@@ -102,6 +102,7 @@ person reading decides which instance earns its place.
|
|
|
102
102
|
| `inline-label-list` | three or more bullets in a row opening "**Label:**", where the label repeats the line |
|
|
103
103
|
| `prompt-context` | "This article uses the attached Perplexity research file as the primary source", "the attached research is right to say", "the attached brief asks": the model naming what it was given. A web page has no attachment. **Zero in anything published** |
|
|
104
104
|
| `placeholder` | "[Insert client name]", lorem ipsum, `TODO_PLACEHOLDER`. Fine in a draft commit; **zero in anything delivered** |
|
|
105
|
+
| `generic-hero-claim` | on the home page (a root route file, a top-level `index.html`, or a hero or home component), a literal `<h1>` and the paragraph under it that name no place, person, number, price or job: "Quality you can trust", "Your vision, our expertise". One trade noun is not enough ("quality plumbing"); two are ("boiler and radiator repairs"). Also read on the rendered first screen by `craft audit` |
|
|
105
106
|
|
|
106
107
|
### Style is not evidence
|
|
107
108
|
|
|
@@ -218,6 +219,10 @@ Hyphenated compounds count as one word. Not automated.
|
|
|
218
219
|
sourced or UNSOURCED. A claim is sourced, corrected or cut, never re-cited
|
|
219
220
|
from memory. The copy check cannot do this part: a false figure in clean
|
|
220
221
|
prose passes every tell.
|
|
222
|
+
- **Proof sits next to the claim it backs.** "Trusted", "fully qualified",
|
|
223
|
+
"award-winning" and "5-star service" need a review, a rating or an
|
|
224
|
+
accreditation in the same section or the one either side of it. `craft
|
|
225
|
+
audit` reports each one that has none (`unproven-claim`, a warning).
|
|
221
226
|
|
|
222
227
|
## CTA rule
|
|
223
228
|
|
package/README.md
CHANGED
|
@@ -94,6 +94,24 @@ reason, in `art-direction.json`:
|
|
|
94
94
|
{ "exceptions": [{ "tell": "ai-violet", "because": "Violet is on the van, the cards and the fascia." }] }
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
Art direction v2 records the customer's job, a hierarchy for each page type,
|
|
98
|
+
and seven expressive tokens, with reasons and evidence. Begin with job
|
|
99
|
+
research, then hierarchy, then tokens:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx craft direction research --brief "An electrician in Brackley repairing dangerous faults for local households"
|
|
103
|
+
npx craft direction init --client "Copper Lane" --brief "<who, where, what they do>"
|
|
104
|
+
npx craft direction validate --estate estate.json
|
|
105
|
+
npx craft estate add --id copper-lane --direction art-direction.json --estate estate.json
|
|
106
|
+
npx craft estate compare --estate estate.json --directions
|
|
107
|
+
npx craft direction validate --snapshot http://localhost:3000 --page home --strict
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`--snapshot` accepts saved files and preview or production URLs. Drift fails
|
|
111
|
+
with `--strict`; declared estate comparisons stay advisory. Version 1 files
|
|
112
|
+
still validate with a warning. See [CHARACTER.md](./CHARACTER.md) for the full
|
|
113
|
+
v2 example and the meaning of each layer.
|
|
114
|
+
|
|
97
115
|
### In CI
|
|
98
116
|
|
|
99
117
|
```bash
|
|
@@ -163,7 +181,7 @@ console.log(formatReport(report, "craft scan"));
|
|
|
163
181
|
|
|
164
182
|
## The anchor guarantee
|
|
165
183
|
|
|
166
|
-
Every hex you pass in comes back out unchanged
|
|
184
|
+
Every hex you pass in comes back out unchanged, the same string, byte for byte.
|
|
167
185
|
That is what lets a live site adopt this without a single pixel moving. Only the
|
|
168
186
|
steps you never picked by hand are generated.
|
|
169
187
|
|