@domandigital/craft 0.21.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/CHARACTER.md +134 -3
  3. package/COPY.md +10 -3
  4. package/PRINCIPLES.md +9 -0
  5. package/README.md +20 -1
  6. package/design-review.schema.json +156 -0
  7. package/dist/{audit-LQ2TDISV.js → audit-CDMZ6JHT.js} +3 -3
  8. package/dist/audit.cjs +258 -10
  9. package/dist/audit.js +258 -10
  10. package/dist/{chunk-6DRBFDWT.js → chunk-D6TAYXOS.js} +1 -1
  11. package/dist/{chunk-G47ZCBD5.js → chunk-IAU4ZAIU.js} +2 -2
  12. package/dist/{chunk-STWH5EYU.js → chunk-ICEG4S56.js} +5 -5
  13. package/dist/{chunk-BYXDX66D.js → chunk-JT2NLOQI.js} +4 -4
  14. package/dist/{chunk-FNB3NP57.js → chunk-KH56TEFK.js} +5 -5
  15. package/dist/{chunk-DE2ZAV4G.js → chunk-MLYHSPF7.js} +166 -3
  16. package/dist/{chunk-ONA73THJ.js → chunk-NV6FKMID.js} +93 -8
  17. package/dist/{chunk-4WAIOZ4W.js → chunk-WTR77PEM.js} +14 -14
  18. package/dist/{chunk-BQ7H23QP.js → chunk-XSKLVEI6.js} +109 -2
  19. package/dist/{cli-YSGPGQ7R.js → cli-223CUNU3.js} +9 -9
  20. package/dist/{cli-XAWJWK7I.js → cli-3QV4FKM4.js} +6 -6
  21. package/dist/{cli-PBCU7Z64.js → cli-4PXDNTZX.js} +4 -4
  22. package/dist/{cli-7QL26YPR.js → cli-6SMNHOCJ.js} +1 -1
  23. package/dist/{cli-5VHX5EJF.js → cli-7PPDBN6N.js} +5 -5
  24. package/dist/{cli-5QI6NIZN.js → cli-CQUORKMC.js} +6 -6
  25. package/dist/{cli-EYHRJJAX.js → cli-FKWJF4V4.js} +8 -5
  26. package/dist/{cli-RHDNHL4U.js → cli-IQ5U76AZ.js} +5 -5
  27. package/dist/cli.js +3 -3
  28. package/dist/index.cjs +261 -10
  29. package/dist/index.d.cts +49 -3
  30. package/dist/index.d.ts +49 -3
  31. package/dist/index.js +260 -10
  32. package/dist/phone.cjs +57 -7
  33. package/dist/phone.d.cts +28 -2
  34. package/dist/phone.d.ts +28 -2
  35. package/dist/phone.js +54 -7
  36. package/dist/{viewports-cli-XYYX4SKV.js → viewports-cli-H6UIUMBC.js} +43 -82
  37. package/package.json +1 -1
  38. package/word-lists.json +11 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @domandigital/craft
2
2
 
3
+ ## 0.22.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 68f65c3: <!-- copy-ok: names the phrases the release starts catching --> craft learns from Eunice Ordor's design and copy reviews (catalogue 2026.10.5). Her 73-note review of the new Doman Digital site is the first record in a reviewer corpus (`reviews/` in the repository; the schema test keeps each record to `design-review.schema.json`), and CHARACTER.md writes up the principles it teaches. `design-review.schema.json` gains optional fields for a reviewer's own record: `reviewer`, `date`, `source` and `rulings` on the review, and `source`, `verdict`, `founderRuling`, `principle` and `tells` on a note; `REVIEW_VERDICTS` is exported. Two new review-tier tells: `hero-cta-pair` (source and rendered) reports two buttons side by side in a hero, found in 140 of 140 null-build heroes, and `confession-line` reports copy that scopes a business by what it has not done or will not do ("What this is and is not", "we have not yet built", "our experience so far is one practice"). `plain-english`, already blocking, now covers the whole family the founder banned on 20 October 2026: bare "plainly" and "in plain terms/language/words", with licence text ("plainly marked") let through. `review-phrase` adds "plain" as a self-description ("a plain recommendation").
8
+
9
+ ## 0.22.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 3902169: The every-viewport measure counts phone screens to the footer (DOM-1052, part of DOM-772): page height at 375 x 667 over 667, with lazy images loaded. `screens` sets a length budget per route, route pattern or prefix (`{ "/": 6.5, "/services/*": 6, "/areas/[town]": 5, "*": 9 }`, the most specific wins), on `measureViewports`, `measureRoute`, `measureSite` and `viewports.json`. A route over its budget fails a new `screens` check ("page too long for a phone"), baselined like the others; with no budget the count is only reported. `ViewportsResult.screens` and the measured file carry the count, `craft viewports` and `craft phone-first --measured` print it for every route, and `screenBudgetFor`, `checkScreenBudgets` and `formatScreens` are exported. The Bellerose home page ran 12.7 phone screens against a target of 6.5.
14
+
3
15
  ## 0.21.0
4
16
 
5
17
  ### Minor Changes
package/CHARACTER.md CHANGED
@@ -632,6 +632,135 @@ back as `change`, ask for what is `hold`, find out what is `gather-evidence`,
632
632
  and leave what is `no-change`. When a note names something that was not
633
633
  inspected, look before you act on it.
634
634
 
635
+ ### Eunice's review of the DD site, 2026-10-19
636
+
637
+ Eunice Ordor reviewed the preview of Doman Digital's own new site on Pastel
638
+ (canvas 986559) on 18 and 19 October 2026: 73 comments across the home,
639
+ services, work, Sensphere case, clinics, who-we-help, process, pricing, plans
640
+ and contact pages. The whole review is kept, note by note, in
641
+ [`reviews/eunice-ordor/2026-10-19-dd-site.json`](https://github.com/Doman-Digital/dd-packages/blob/main/packages/craft/reviews/eunice-ordor/2026-10-19-dd-site.json)
642
+ in the repository:
643
+ her words as she wrote them, what she proposed, what was done with it, the
644
+ founder's ruling where one was needed, and the principle each note teaches. The
645
+ founder went through it on 20 October 2026. As in "Where it came from" above,
646
+ four things are kept apart.
647
+
648
+ #### What she saw
649
+
650
+ Twelve notes are praise, and they are a record of what to keep: the structure
651
+ and type, the four routes in, the who-we-help page ("a site that reads as a van
652
+ roof"), the Chair and Blade case, the six-step process and the responsibility
653
+ matrix. The rest name problems. These matter beyond this one site:
654
+
655
+ - Two equal buttons in the hero (#5), and again on the process page (#36).
656
+ - Confession lines: "What this is and is not", "We have not yet built and
657
+ run...", "Our clinic experience so far is one practice" (#8, #13), and a
658
+ defensive caveat under the clinic questions (#10).
659
+ - Summary pages that send the reader elsewhere for the substance: services
660
+ cards that are a line of nouns and a link (#66 to #69), a homepage case card
661
+ with none of the case's proof (#19), a pricing page that charges £95 and £165
662
+ a month and never says what either buys (#40, #48), and a /work page where
663
+ nothing says we still run any of it (#57).
664
+ - Every /work line states the problem and leaves the result on another page
665
+ (#56).
666
+ - Tiers that make the same promise at two volumes, so the extra £1,000 reads as
667
+ better writing (#39).
668
+ - A price that looks steep until the maths is shown: £165 a month is £95 of
669
+ care and £70 of website (#43).
670
+ - Closed lists where the work is open: the hero sub-line and route 3 narrowed
671
+ to bookings and enquiries (#2, #6, #25).
672
+ - A page that contradicts itself: the Sensphere form said both that enquiries
673
+ reach the inbox and that details stay out of one (#15), and a process step
674
+ said "paid" for a product that had been retired (#22).
675
+ - On a phone, the hero image crops badly (#55).
676
+
677
+ #### What she proposed
678
+
679
+ Specific wording for most notes, and three larger changes: a hero slideshow of
680
+ client systems (#3), a call to action after several sections (#50, #51, #70),
681
+ and a social media card (#72). Her diagnoses were nearly all right. Her wording
682
+ often used the patterns COPY.md blocks. Four of her comments blocked at
683
+ <!-- copy-ok: quoting the reviewer's draft line -->
684
+ catalogue 2026.10.4 ("No licence, no lock-in" in #42 is one), and eight do once
685
+ the plain-English family is widened.
686
+
687
+ #### The founder's rulings, 20 October 2026
688
+
689
+ - One button in the hero and on each closing section.
690
+ - On a phone the first screen is ours: the headline, the sub-line and one
691
+ button. Another client's brand never opens it. The slideshow is declined
692
+ (#3).
693
+ - No confession lines, no "what we are not", and nobody declined in advance.
694
+ It is an open shop: be honest by being precise, keep it open-ended, and stop
695
+ being absolute.
696
+ <!-- copy-ok: naming the banned adverb -->
697
+ - The adverb "plainly" and its kin are banned, with "plain English".
698
+ - Cut "Our clinic experience so far is one practice" (#8). On the clinics page
699
+ keep "Built and run by us", and describe what Sensphere is: a growing
700
+ practice whose clinicians work remotely (#13).
701
+ - A testimonial (#9) is reworded only once its author approves the new words.
702
+ - Held for their own decisions: e-commerce as a sector (#27), a clinic
703
+ subscription with its own price (#49), response times (#54) and social media
704
+ (#72). Verqan stays off /work (#59). Quarterly packs are declined for the
705
+ site (#53).
706
+
707
+ #### The principles
708
+
709
+ Each id is what a note's `principle` field names in the record.
710
+
711
+ - `open-shop`: precise, never confessional or absolute. Scope is shown by
712
+ exact claims ("the portal we run for Sensphere"), and a contractual fact is
713
+ said as what the buyer gets. `confession-line` reports the shapes for
714
+ review.
715
+ - `summary-pages-carry-substance`: a page that summarises carries a sentence
716
+ of what happens, so nobody has to click away to learn what we do.
717
+ - `problem-then-result`: every case line ends on the result, from the proof
718
+ ledger, or on a description of what now happens.
719
+ - `one-hero-cta`: one button in the hero and on each closing section, with the
720
+ second route as a text link. `hero-cta-pair` reports the pair.
721
+ - `text-links-not-cta-bands`: where a section needs a next step, a text link
722
+ at its end answers "what next", and the page keeps one closing button.
723
+ `cta-band-stock` already reports the band.
724
+ - `tiers-by-what-the-site-carries`: each tier names a different business need
725
+ (one service and a form; several services, comparison and booking), never a
726
+ bigger version of the same promise.
727
+ - `show-the-price-maths`: where a price looks steep, show the split that makes
728
+ it fair (£95 of care plus £70 of website), and put the commercial model where
729
+ the buyer reads.
730
+ - `lists-as-pattern-examples-invitation`: name the pattern, give examples, then
731
+ invite the case we have not met. A closed list of four reads as a menu.
732
+ - `first-phone-screen-is-ours`: the first screen on a phone is the business's
733
+ own headline, line and button. A client's brand, however good the work, comes
734
+ after it and is framed as our work.
735
+ - `no-self-contradiction`: read a page against itself before it ships. Two
736
+ lines that disagree cost more trust than either line earns.
737
+ - `the-work-continues`: the site sells a relationship that carries on, so a
738
+ case, a step or a summary says what we still run.
739
+
740
+ #### The counter-lesson
741
+
742
+ Her diagnoses beat Claude's defaults. Claude's first pass on this review would
743
+ have kept the "What this is and is not" sentence, the two hero buttons, the
744
+ noun-list service cards and three proof numbers in a row. Each is a default
745
+ craft names (`confession-line`, `hero-cta-pair`, the summary-card pattern,
746
+ `stats-row`). Where the question is "does this read as decided and generous to
747
+ the buyer", she was right. Where it is "is it true, and is it allowed", the
748
+ proof ledger and the house rules held: she asked for promises that are not
749
+ live yet (#53, #54, #72), and her replacement wording goes through copy-check
750
+ like anyone's. A reviewer's diagnosis is taken on its merits; her
751
+ words are copy, and copy is checked.
752
+
753
+ #### Feeding later reviews in
754
+
755
+ Every later review, hers or another reviewer's, goes through the
756
+ `reviewer-intake` skill in claude-kit: pull the canvas, keep each note whole,
757
+ classify it, check its facts against the proof ledger, brand facts and Linear,
758
+ write the record under `reviews/<reviewer>/`, and propose tells or fixtures for
759
+ what recurs. `src/__tests__/reviews.test.ts` holds each record to the schema
760
+ and to this file, and fires every tell a note taught on the words it flagged.
761
+ See [reviews/README.md](https://github.com/Doman-Digital/dd-packages/blob/main/packages/craft/reviews/README.md);
762
+ the corpus stays in the repository and is left out of the npm package.
763
+
635
764
  ## Declaring an exception
636
765
 
637
766
  Doman Digital's own brand is violet. A hue rule with no way to say so flags the
@@ -1341,7 +1470,7 @@ Generated from the package. Run `pnpm --filter @domandigital/craft run docs`
1341
1470
  after changing an entry; a test fails until you do.
1342
1471
 
1343
1472
  <!-- craft:catalogue:start -->
1344
- Catalogue version `2026.10.4`, 72 tells.
1473
+ Catalogue version `2026.10.5`, 74 tells.
1345
1474
 
1346
1475
  | Id | Gen | Surface | Severity | Tell | Why it is a default |
1347
1476
  | --- | --- | --- | --- | --- | --- |
@@ -1360,6 +1489,7 @@ Catalogue version `2026.10.4`, 72 tells.
1360
1489
  | `cream-palette` | 2 | source + rendered | warn | Cream ground | Once white-and-violet was named, models moved to a warm off-white: parchment, linen, oat. It reads as 'tasteful' in the same way everywhere. |
1361
1490
  | `italic-serif-display` | 2 | source + rendered | warn | Italic serif display | A serif heading with one italic word ('Beauty, reimagined') is the second wave's signature move. |
1362
1491
  | `hero-eyebrow-chip` | 2 | source + rendered | warn | Eyebrow chip above the hero | A small bordered pill ('New · Now booking') above the headline is in almost every generated hero. |
1492
+ | `hero-cta-pair` | 1 | source + rendered | warn | Two buttons in the hero | A filled button beside an outline or ghost one ('Get a free quote' / 'See our plans') is in 140 of 140 heroes Claude builds for a brief. Two equal asks make the visitor choose before they know anything, and say nobody decided what the page is for. |
1363
1493
  | `icon-tile-stack` | 2 | source | warn | Icon in a tinted tile | A library icon in a soft rounded square, stacked above a heading, is the stock card header. |
1364
1494
  | `bento-grid` | 2 | source | warn | Bento grid | Mixed-size tiles in a grid became the default 'features' layout of the second wave. |
1365
1495
  | `radial-spotlight-glow` | 2 | source + rendered | warn | Radial glow | A soft blurred blob or radial spotlight behind the hero is atmosphere without a subject. |
@@ -1371,14 +1501,15 @@ Catalogue version `2026.10.4`, 72 tells.
1371
1501
  | `stock-phrase` | 1 | copy | warn | Stock phrase | Phrases every generated services page uses. They fill space where a fact should be. |
1372
1502
  | `ai-phrase` | 1 | copy | warn | AI phrase | Let's dive in, here's the thing, at its core, seamless, rest assured: the phrase list of the house copy rules. A reader has seen each one in a thousand generated pages. |
1373
1503
  | `plainer-word` | 1 | copy | warn | A plainer word exists | Empower, leverage, harness, delve: each stands in for a plainer verb, and the swap is a reliable sign nobody chose the word. |
1374
- | `plain-english` | 2 | copy | warn | 'Plain English' | Told to avoid jargon, a model announces that it is avoiding jargon. 'Explained plainly' swaps a synonym and keeps the tell. |
1504
+ | `plain-english` | 2 | copy | warn | 'Plain English' | Told to avoid jargon, a model announces that it is avoiding jargon: 'in plain English', 'stated plainly', 'we'll tell you plainly', 'in plain terms'. The founder bans the whole family (20 October 2026); a reader takes it as filler. |
1375
1505
  | `buzzword` | 1 | copy | warn | Buzzword | Cutting-edge, world-class, reach out, turnkey: corporate filler older than any model, and still the first thing a model writes about a business it knows nothing about. |
1376
1506
  | `negative-reassurance` | 1 | copy | warn | Negative reassurance | 'No hidden fees', 'no surprises', 'never locked in' reassure by naming the fear, and plant it in a reader who did not have it. |
1377
1507
  | `vague-word` | 1 | copy | warn | Vague word | Innovative, scalable, end-to-end, solutions: each can be true, and each is used where the writer had nothing specific to say. |
1378
- | `review-phrase` | 1 | copy | warn | Review-tier phrase | Truly, genuinely, clear, ultimately, 'the single most', 'bar none': normal English once, and a tell when they stack. The house rules keep them for review, never blocking. |
1508
+ | `review-phrase` | 1 | copy | warn | Review-tier phrase | Truly, genuinely, clear, ultimately, 'a plain recommendation', 'the single most', 'bar none': normal English once, and a tell when they stack. The house rules keep them for review, never blocking. |
1379
1509
  | `sales-tagline` | 1 | copy | warn | Sales tagline | 'So your budget goes where it counts', 'Real results', 'pages that convert': advert lines that sound like a pitch and say nothing a reader can check. |
1380
1510
  | `outcome-promise` | 1 | copy | warn | Outcome promise | 'We'll turn that into enquiries', 'once the first areas are working', 'competitors you can outdo': a hoped-for result written as if it were delivered. Rankings and enquiries depend on things nobody controls. |
1381
1511
  | `matey-register` | 2 | copy | warn | Matey register | 'Alright Dave,', 'no worries, we'll get you sorted', 'Quick one:', 'have look at': a put-on, over-familiar British voice, with the small words clipped out. A model asked to sound British writes it; the UK is broad, and a client reads it as cringe and a little rude. |
1512
+ | `confession-line` | 2 | copy | warn | Confession line | '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. |
1382
1513
  | `hollow-imperative` | 1 | copy | warn | Hollow imperative | 'Discover', 'Experience', 'Transform your' as the opening verb of a heading or button is a call to action with nothing in it. |
1383
1514
  | `rhetorical-opener` | 1 | copy | warn | Rhetorical question opener | 'Looking for...?', 'Tired of...?', 'Ready to...?' opens with the model guessing at the reader instead of telling them something. |
1384
1515
  | `em-dash` | 2 | copy | warn | Em dash | Generated copy leans on the em dash to join clauses. House copy does not use it. |
package/COPY.md CHANGED
@@ -57,7 +57,8 @@ A single hit fails the check. These are not judgment calls.
57
57
  `in today's rapidly evolving…`, `increasingly digital`,
58
58
  `whether you're a X or a Y`, `seamless(ly)`, `unlock your…`,
59
59
  `meaningful impact`, `foster collaboration`, `empower`, `leverage`,
60
- `harness`, `delve`, `a comprehensive guide to`, `plain English`.
60
+ `harness`, `delve`, `a comprehensive guide to`, `plain English`,
61
+ `plainly`, `in plain terms`, `in plain language`.
61
62
 
62
63
  Also blocking: `in the event that`, `at no additional cost to you`, `rest
63
64
  assured`, `it is worth noting that`, `when it comes to`, `we've got you
@@ -78,7 +79,12 @@ exists. Name the mechanism: "Your team can publish without us", not "we
78
79
  empower your team".
79
80
 
80
81
  `plain English` has one house replacement: **"properly explained"**.
81
- "Explained plainly" swaps a synonym and keeps the tell.
82
+ "Explained plainly" swaps a synonym and keeps the tell, and so do "stated
83
+ plainly", "we'll tell you plainly" and "in plain terms": the whole family
84
+ blocks (founder, 20 October 2026). Drop the adverb and say the thing. Licence
85
+ text ("must be plainly marked") is let through. `plain` and `clear` describing
86
+ the copy itself ("a plain recommendation", "clear pricing") are review tier,
87
+ in `review-phrase`: say what the reader actually gets.
82
88
 
83
89
  ## Review tier
84
90
 
@@ -87,9 +93,10 @@ person reading decides which instance earns its place.
87
93
 
88
94
  | Tell | What it catches |
89
95
  | --- | --- |
90
- | `review-phrase` | truly, genuinely, deeply, ultimately, clear and clearly ("a clear next step", "clear pricing": say what the reader actually gets), great question, absolutely, one-size-fits-all, and superlative over-claiming: "the single most", "by far the most", "hands down the", "arguably the best", "bar none" |
96
+ | `review-phrase` | truly, genuinely, deeply, ultimately, clear and clearly ("a clear next step", "clear pricing": say what the reader actually gets), plain as a self-description ("plain answers", "a plain recommendation"), great question, absolutely, one-size-fits-all, and superlative over-claiming: "the single most", "by far the most", "hands down the", "arguably the best", "bar none" |
91
97
  | `sales-tagline` | advert lines that say nothing a reader can check: "so your budget goes where it counts", "real results", "results that matter", "work harder for you", "pages that convert" |
92
98
  | `matey-register` | the put-on British voice: "Alright Dave,", "cheers mate", "no worries", "we'll get you sorted", "proper good", "give me a shout", "chuffed", "Right then,"; and clipped speech that drops the small words: "have look at", "give it go", "Quick one:", "built you a site". Write plain, complete British English |
99
+ | `confession-line` | scoping the business by what it has not done, will not do or is not: "What this is and is not", "we have not yet built", "our clinic experience so far is one practice", "what we would and wouldn't take on", "who we don't work with". It's an open shop: be honest by being precise ("the portal we run for Sensphere") and keep the door open. Contractual facts (eligibility, who runs what) stay, said as what the buyer gets |
93
100
  | `outcome-promise` | a hoped-for result written as delivered: "we'll turn that into enquiries", "once the first areas are working", "competitors you can outdo", "exactly what convinces", "guaranteed rankings", "you'll get more". Promise the work; measure and report the results |
94
101
  | `ai-vocabulary` | tapestry, testament, realm, elevate, nestled, meticulous, unparalleled, moreover; and underscore, showcasing, pivotal, measured 10 to 14 times over-used in post-2022 text |
95
102
  | `stock-email-line` | the form-email opener and closer: "I hope this email finds you well", "hope you're having a great week", "let me know if you have any questions", "don't hesitate to contact us". Start with the reason for writing; end with the next step and who to ask |
package/PRINCIPLES.md CHANGED
@@ -129,3 +129,12 @@ a stakeholder's observation, the visitor problem under it, the proposed fix and
129
129
  the evidence are judged apart, and the smallest change that answers the problem
130
130
  wins. "The existing design is already appropriate" is a result. See
131
131
  [Reviewing a proposed change](./CHARACTER.md#reviewing-a-proposed-change).
132
+
133
+ Her review of Doman Digital's own new site (18 and 19 October 2026, 73 notes)
134
+ is kept whole in the reviewer corpus, with the founder's rulings of 20 October,
135
+ and it adds eleven principles and two tells. The main ones: an open shop is honest
136
+ by being precise, never by confessing what it has not done; a summary page
137
+ carries the substance; a case line ends on its result; a hero has one button;
138
+ and the first screen on a phone belongs to the business. Every later review of
139
+ hers feeds craft the same way. See
140
+ [Eunice's review of the DD site](./CHARACTER.md#eunices-review-of-the-dd-site-2026-10-19).
package/README.md CHANGED
@@ -121,6 +121,12 @@ no change is needed. Evidence only reported by an audit or a stakeholder cannot
121
121
  make a problem observed, and a width nobody looked at stays unknown. See
122
122
  [Reviewing a proposed change](./CHARACTER.md#reviewing-a-proposed-change).
123
123
 
124
+ A reviewer's own review is kept whole in the same shape, in the repository's
125
+ reviewer corpus (`packages/craft/reviews/`, left out of the npm package), with
126
+ what was done with each note and the principle it teaches. Eunice Ordor's
127
+ review of the DD site is the first. See
128
+ [Eunice's review of the DD site](./CHARACTER.md#eunices-review-of-the-dd-site-2026-10-19).
129
+
124
130
  `--snapshot` accepts saved files and preview or production URLs. Drift fails
125
131
  with `--strict`; declared estate comparisons stay advisory. Version 1 files
126
132
  still validate with a warning. See [CHARACTER.md](./CHARACTER.md) for the full
@@ -371,6 +377,13 @@ the one loaded page in place:
371
377
  `tel:` link.
372
378
  - **On a landscape phone (844 x 390):** header and fixed layers leave at least
373
379
  half the height.
380
+ - **Page length (phone screens):** page height at 375 x 667 over 667, to the
381
+ footer (lazy images loaded). A phone page has a length budget (the Bellerose
382
+ home page ran 12.7 screens against a target of 6.5). Set one per route or
383
+ route pattern with `screens`; a route over its budget fails the `screens`
384
+ check, and with no budget the count is only reported. Keys are a route
385
+ (`/`), a pattern (`/areas/[town]`), a prefix (`/services/*`, the route and
386
+ everything under it) or `*`; the most specific wins.
374
387
  - **At 1440 and 1920:** body lines are at most 80 characters (width over the
375
388
  `ch` of the element's own font) and no image is stretched past its file.
376
389
 
@@ -384,10 +397,16 @@ test.use(PHONE);
384
397
  test(`every viewport: ${route}`, async ({ page }) => {
385
398
  await page.goto(route);
386
399
  // Resizes this page in place; writes phone-first/measured/<route>.json.
387
- await measureViewports(page, { route, mainAction: ".hero a" });
400
+ await measureViewports(page, { route, mainAction: ".hero a", screens: { "/": 6.5, "/services/*": 6 } });
388
401
  });
389
402
  ```
390
403
 
404
+ `result.screens` holds the count, and it is written to the measured file;
405
+ `craft viewports` and `craft phone-first --measured` print it for every route
406
+ (`phone screens to the footer: / 5.8 of 6.5`). In `viewports.json` the budget is
407
+ `"screens": { "/": 6.5, "/services/*": 6 }`; in create-site's
408
+ `site.programme.json` it is `measure.screens`.
409
+
391
410
  `measureViewports` works on the page the suite opened and signed in, so a
392
411
  portal keeps its fixtures. `measureRoute(open, { route, mainAction })` does
393
412
  both halves for such a page: `open("phone")` and `open("wide")` return the
@@ -20,6 +20,67 @@
20
20
  "type": "string",
21
21
  "minLength": 1
22
22
  },
23
+ "reviewer": {
24
+ "type": "string",
25
+ "minLength": 1,
26
+ "description": "The person whose review this is, when the file is their record. Each note's raisedBy still says who raised it."
27
+ },
28
+ "date": {
29
+ "type": "string",
30
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
31
+ "description": "The day the review was given."
32
+ },
33
+ "source": {
34
+ "type": "object",
35
+ "description": "Where the review came from, when it is a reviewer's own record (a reviewer corpus under reviews/).",
36
+ "required": [
37
+ "tool"
38
+ ],
39
+ "properties": {
40
+ "tool": {
41
+ "type": "string",
42
+ "minLength": 1,
43
+ "description": "pastel, a document, a call, an email."
44
+ },
45
+ "canvas": {
46
+ "type": [
47
+ "integer",
48
+ "string"
49
+ ]
50
+ },
51
+ "link": {
52
+ "type": "string"
53
+ },
54
+ "comments": {
55
+ "type": "integer",
56
+ "minimum": 0
57
+ },
58
+ "from": {
59
+ "type": "string"
60
+ },
61
+ "to": {
62
+ "type": "string"
63
+ }
64
+ }
65
+ },
66
+ "rulings": {
67
+ "type": "object",
68
+ "description": "Who made the final calls recorded in each note's founderRuling, and when.",
69
+ "required": [
70
+ "by",
71
+ "date"
72
+ ],
73
+ "properties": {
74
+ "by": {
75
+ "type": "string",
76
+ "minLength": 1
77
+ },
78
+ "date": {
79
+ "type": "string",
80
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
81
+ }
82
+ }
83
+ },
23
84
  "notes": {
24
85
  "type": "array",
25
86
  "items": {
@@ -414,6 +475,101 @@
414
475
  }
415
476
  }
416
477
  }
478
+ },
479
+ "source": {
480
+ "type": "object",
481
+ "description": "Where the note was left: the tool, and the reference that finds it again.",
482
+ "required": [
483
+ "tool"
484
+ ],
485
+ "properties": {
486
+ "tool": {
487
+ "type": "string",
488
+ "minLength": 1
489
+ },
490
+ "canvas": {
491
+ "type": [
492
+ "integer",
493
+ "string"
494
+ ]
495
+ },
496
+ "comment": {
497
+ "type": [
498
+ "integer",
499
+ "string"
500
+ ],
501
+ "description": "The comment's number as the reviewer sees it."
502
+ },
503
+ "commentId": {
504
+ "type": [
505
+ "integer",
506
+ "string"
507
+ ]
508
+ },
509
+ "url": {
510
+ "type": "string",
511
+ "description": "The page the note was left on."
512
+ },
513
+ "at": {
514
+ "type": "string",
515
+ "description": "When it was left, ISO 8601."
516
+ }
517
+ }
518
+ },
519
+ "verdict": {
520
+ "enum": [
521
+ "praise",
522
+ "take",
523
+ "take-reworded",
524
+ "partly",
525
+ "decline",
526
+ "founder-decision",
527
+ "known"
528
+ ],
529
+ "description": "What was done with the note. take-reworded: the diagnosis is taken and the suggested wording rewritten (it is copy-checked like any other). partly: the aim is taken, by a smaller or different change. known: already tracked, no change here."
530
+ },
531
+ "founderRuling": {
532
+ "type": "object",
533
+ "required": [
534
+ "date",
535
+ "ruling"
536
+ ],
537
+ "properties": {
538
+ "date": {
539
+ "type": "string",
540
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
541
+ },
542
+ "ruling": {
543
+ "type": "string",
544
+ "minLength": 1
545
+ }
546
+ },
547
+ "description": "The founder's call where the note needed one, stated as the decision and nothing more."
548
+ },
549
+ "principle": {
550
+ "type": "string",
551
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
552
+ "description": "The id of the principle the note teaches, as written up in CHARACTER.md."
553
+ },
554
+ "tells": {
555
+ "type": "array",
556
+ "description": "Craft tells the note informed. With text, the words that tell must fire on.",
557
+ "items": {
558
+ "type": "object",
559
+ "required": [
560
+ "id"
561
+ ],
562
+ "properties": {
563
+ "id": {
564
+ "type": "string",
565
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
566
+ },
567
+ "text": {
568
+ "type": "string",
569
+ "minLength": 1
570
+ }
571
+ }
572
+ }
417
573
  }
418
574
  }
419
575
  }
@@ -9,10 +9,10 @@ import {
9
9
  snapshotPage,
10
10
  snapshotUrl,
11
11
  snapshotUrls
12
- } from "./chunk-6DRBFDWT.js";
12
+ } from "./chunk-D6TAYXOS.js";
13
13
  import "./chunk-JYNXGCYZ.js";
14
- import "./chunk-DE2ZAV4G.js";
15
- import "./chunk-ONA73THJ.js";
14
+ import "./chunk-MLYHSPF7.js";
15
+ import "./chunk-NV6FKMID.js";
16
16
  import "./chunk-QYBAVU3P.js";
17
17
  export {
18
18
  PROVENANCE_BUDGET_MS,