@erclx/canon 5.62.0 → 5.63.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/create-skill/references/skill-practice.md +1 -0
  4. package/claude/skills/design-record/references/design.md +1 -1
  5. package/claude/skills/design-taste/REQUIREMENT.md +2 -1
  6. package/claude/skills/design-taste/SKILL.md +6 -5
  7. package/claude/skills/design-taste/references/adopted.md +136 -8
  8. package/claude/skills/design-taste/references/craft.md +1 -1
  9. package/claude/skills/design-taste/references/kinds.md +8 -2
  10. package/claude/skills/design-taste/references/preflight.md +3 -3
  11. package/claude/skills/design-taste/references/tells.md +26 -5
  12. package/claude/skills/plan-feature/SKILL.md +2 -2
  13. package/claude/skills/plan-feature/references/plan.md +24 -3
  14. package/claude/skills/review-craft/SKILL.md +1 -1
  15. package/claude/skills/role-worker/SKILL.md +2 -1
  16. package/claude/skills/ui-checklist/SKILL.md +1 -1
  17. package/claude/skills/ui-craft/REQUIREMENT.md +29 -0
  18. package/claude/skills/ui-craft/SKILL.md +44 -0
  19. package/{governance/rules/ui → claude/skills/ui-craft/references}/a11y.md +0 -10
  20. package/claude/skills/ui-craft/references/adopted.md +27 -0
  21. package/{governance/rules/ui/surface-capture.md → claude/skills/ui-craft/references/capture.md} +0 -10
  22. package/{governance/rules/ui/ux-controls.md → claude/skills/ui-craft/references/controls.md} +3 -10
  23. package/claude/skills/ui-craft/references/copy.md +45 -0
  24. package/{governance/rules/ui → claude/skills/ui-craft/references}/forms.md +0 -9
  25. package/{governance/rules/ui → claude/skills/ui-craft/references}/keyboard.md +0 -10
  26. package/{governance/rules/ui → claude/skills/ui-craft/references}/motion.md +0 -10
  27. package/{governance/rules/ui → claude/skills/ui-craft/references}/pointer.md +0 -10
  28. package/{governance/rules/ui/ux-completeness.md → claude/skills/ui-craft/references/states.md} +0 -10
  29. package/claude/skills/ux-audit/SKILL.md +1 -1
  30. package/claude/skills/write-human/references/adopted.md +4 -1
  31. package/docs/agents/install-and-sync.md +2 -2
  32. package/docs/target/migrations.md +3 -3
  33. package/docs/target/sync.md +3 -2
  34. package/docs/workflow/skill-map.md +1 -0
  35. package/docs/workflow/visual-design-workflow.md +2 -2
  36. package/governance/detect.toml +1 -45
  37. package/governance/ledger/lib/test-scope.md +1 -1
  38. package/governance/ledger/{ui → skills/ui-craft}/a11y.md +3 -3
  39. package/governance/ledger/{ui/surface-capture.md → skills/ui-craft/capture.md} +3 -3
  40. package/governance/ledger/{ui/ux-controls.md → skills/ui-craft/controls.md} +12 -7
  41. package/governance/ledger/skills/ui-craft/copy.md +102 -0
  42. package/governance/ledger/{ui → skills/ui-craft}/forms.md +3 -3
  43. package/governance/ledger/{ui → skills/ui-craft}/keyboard.md +3 -3
  44. package/governance/ledger/{ui → skills/ui-craft}/motion.md +3 -3
  45. package/governance/ledger/{ui → skills/ui-craft}/pointer.md +3 -3
  46. package/governance/ledger/{ui/ux-completeness.md → skills/ui-craft/states.md} +3 -3
  47. package/governance/ledger/ui/craft.md +19 -0
  48. package/governance/renames.toml +17 -3
  49. package/governance/rules/lib/test-scope.md +1 -1
  50. package/governance/rules/ui/craft.md +22 -0
  51. package/governance/splits.toml +0 -2
  52. package/package.json +1 -1
  53. package/src/claude/cases/misc.ts +5 -0
  54. package/src/claude/skills-audit.ts +150 -12
  55. package/src/commands/claude.ts +5 -0
  56. package/src/commands/tooling.ts +4 -1
  57. package/src/gate/measures.ts +4 -3
  58. package/src/gov/audit.ts +6 -1
  59. package/src/inventory/subjects.ts +1 -1
  60. package/src/tooling/package.ts +22 -13
  61. package/tooling/web/reference.md +3 -1
  62. package/governance/ledger/ui/copy.md +0 -49
  63. package/governance/ledger/ui/design-taste.md +0 -19
  64. package/governance/ledger/ui/interface-casing.md +0 -47
  65. package/governance/ledger/ui/link-behavior.md +0 -29
  66. package/governance/rules/ui/copy.md +0 -28
  67. package/governance/rules/ui/design-taste.md +0 -18
  68. package/governance/rules/ui/interface-casing.md +0 -29
  69. package/governance/rules/ui/link-behavior.md +0 -19
  70. /package/tooling/web/{configs → seeds}/e2e/home.spec.ts +0 -0
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: ui-craft
3
+ description: Carries the behavior practice for rendered UI, being accessibility, keyboard and pointer operation, forms, motion, controls, state coverage, interface copy, and the capture a rendered change owes, routed from the kind of change to the references it reads. Use before building or changing a component, a page, a form, or any rendered surface, when judging one in review, or when asked "is this accessible", "what states does this need", "how should this form validate", "what should the button say", or "what do I capture after this change". Do NOT use for how a surface looks, being layout, type, color, and the layer order, which is `design-taste`, or for the design folder and its references, which is `design-record`.
4
+ metadata:
5
+ family: build
6
+ ---
7
+
8
+ # UI craft
9
+
10
+ A rendered change that skips this practice ships a control a keyboard cannot reach, a list with no empty state, or an error that names the fault and never the fix, and none of it fails a build. The references below carry the rules. This body routes a change to the ones it reads.
11
+
12
+ Load this before building rather than after, since a missing state or a trapped focus is cheaper to design in than to retrofit.
13
+
14
+ ## Read by the change
15
+
16
+ Read every reference on the always row for any rendered change, then each row the change matches.
17
+
18
+ | The change | Read |
19
+ | ------------------------------------------------------------------ | ------------------------------------- |
20
+ | Any rendered change | `a11y.md`, `keyboard.md`, `states.md` |
21
+ | A click, press, drag, gesture, or popover dismissal | `pointer.md` |
22
+ | A form, a field, validation, or a sign-in step | `forms.md` |
23
+ | An animation, transition, autoplay, or carousel | `motion.md` |
24
+ | A destructive action, an edit cancel, or a hover or disabled state | `controls.md` |
25
+ | A rendered string, heading, label, or link | `copy.md` |
26
+ | A rendered surface has changed and is about to be handed over | `capture.md` |
27
+
28
+ Each name sits under `${CLAUDE_SKILL_DIR}/references/`. A row's reference is read whole, since its sections name the cases a change reaches without saying so.
29
+
30
+ ## Hold the floor over taste
31
+
32
+ The references state a floor, and no aesthetic choice trades against it. A contrast ratio, a focus ring, or a state the design leaves out is restored before the look is judged, and `design-taste` decides the look inside that floor.
33
+
34
+ ## Sources
35
+
36
+ Read `${CLAUDE_SKILL_DIR}/references/adopted.md` only when extending this guidance or arguing against a rule in it. It names the authorities the references draw on and where each bullet's source row sits.
37
+
38
+ ## What this delegates
39
+
40
+ - How a surface looks, being the layer order, the coherence locks, and the defaults a model reaches for: `design-taste`
41
+ - The accepted designs under the design folder and how a reference lands there: `design-record`
42
+ - The visual checklist a reviewer reads beside the screenshots: `ui-checklist`
43
+ - Reading source for roughness a rule does not state: `ux-audit`
44
+ - Prose on the surface beyond its interface copy: the `write-human` skill
@@ -1,13 +1,3 @@
1
- ---
2
- description: Semantics, text alternatives, contrast, and reflow for rendered UI
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- - '**/*.css'
9
- ---
10
-
11
1
  # Accessibility standards
12
2
 
13
3
  ## Semantics
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: Adopted and declined
3
+ description: The authorities the ui-craft references draw on, and where the per-bullet source rows for each reference sit
4
+ ---
5
+
6
+ # Adopted and declined
7
+
8
+ Every bullet in a reference has its own source row in a ledger outside the plugin, so this record names the authorities once and points at the rows. A reader arguing against one bullet opens its ledger, and a session extending a reference adds the row there in the same change.
9
+
10
+ ## Authorities
11
+
12
+ Each field below names the source its references cite, and a house choice covers a threshold or a scope no source states.
13
+
14
+ - **Web accessibility.** The W3C's [WCAG 2.2](https://www.w3.org/TR/WCAG22/) and the [ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/) back the accessibility, keyboard, pointer, and motion references.
15
+ - **CSS behavior.** [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS) and the CSS specifications back the focus ring, `color-scheme`, and overflow bullets.
16
+ - **Native targets.** Apple's and Android's platform guidelines back the native touch target figures in `pointer.md`.
17
+ - **Forms and copy.** The [GOV.UK Design System](https://design-system.service.gov.uk/) and its style guide back `forms.md` and the copy and casing sections of `copy.md`.
18
+ - **Usability research.** The [Nielsen Norman Group](https://www.nngroup.com/articles/) backs most of `states.md`, part of `controls.md`, and the link sections of `copy.md`.
19
+ - **Capture.** `capture.md` is a house procedure, with its reflow width taken from the WCAG reflow criterion `a11y.md` cites.
20
+
21
+ ## Where the rows sit
22
+
23
+ The rows sit in the toolkit's own repository rather than the plugin, one ledger per reference and one table row per bullet under the H2 the bullet sits under. The toolkit's skill audit fails a reference whose bullets and rows disagree in count under any heading, and a target never carries the rows.
24
+
25
+ ## Declined
26
+
27
+ Each ledger carries its own `## Declined` list, recording the bullets cut or reworded when the source rules were last rewritten. The move into this skill changed no bullet's wording, so it declined nothing.
@@ -1,13 +1,3 @@
1
- ---
2
- description: Require a capture against a running preview after a rendered surface changes
3
- paths:
4
- - '**/routes/**/*.{tsx,jsx,vue,svelte,astro}'
5
- - '**/pages/**/*.{tsx,jsx,vue,svelte,astro}'
6
- - '**/app/**/page.{tsx,jsx}'
7
- - '**/components/**/*.{tsx,jsx,vue,svelte,astro}'
8
- - '**/*.html'
9
- ---
10
-
11
1
  # Surface capture standards
12
2
 
13
3
  ## What a surface is
@@ -1,13 +1,3 @@
1
- ---
2
- description: Destructive actions, edit cancel, and element states for interactive controls
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- - '**/*.css'
9
- ---
10
-
11
1
  # UX controls standards
12
2
 
13
3
  ## Destructive actions
@@ -21,5 +11,8 @@ paths:
21
11
  - Never flash an intermediate state, such as a light frame before a dark theme or a layout jump before data arrives. Reserve the space or settle it first.
22
12
  - Say why a control is disabled, in text beside it or a tooltip, and keep it focusable through `aria-disabled` when the reason matters.
23
13
  - Declare `color-scheme` on `:root` to match each theme, so scrollbars and form controls follow the theme instead of staying light.
14
+
15
+ ## Hover and focus effects
16
+
24
17
  - Keep content shown on hover or focus dismissible without moving the pointer, hoverable, and visible until the trigger leaves or the person dismisses it (WCAG 1.4.13).
25
18
  - Change no context, such as navigating, submitting, or moving focus, when a control gains focus or changes value, unless the person was told first (WCAG 3.2.1, 3.2.2).
@@ -0,0 +1,45 @@
1
+ # UI copy standards
2
+
3
+ ## Punctuation
4
+
5
+ - Write no em dash (`—`) or semicolon in rendered copy. Use a comma or a period, or restructure the sentence.
6
+ - Add no trailing punctuation to a button label or a short action string.
7
+
8
+ ## Button copy
9
+
10
+ - Label a button with the verb of the action it performs, such as `Save` or `Delete`, never with filler such as `Click to delete`.
11
+
12
+ ## Error messages
13
+
14
+ - Tell the person how to fix the error, such as `Enter an email address` over `Email is invalid`.
15
+ - Keep an error message to one short sentence in plain language, with no technical jargon or error codes.
16
+
17
+ ## Placeholder text
18
+
19
+ - Never use placeholder text as a label, a hint, or an example. Put a format example such as `name@example.com` in hint text under the label.
20
+
21
+ ## Sentence case
22
+
23
+ - Use sentence case for rendered headings, labels, nav items, tab titles, and dialog titles, since title case on every heading reads as a template default.
24
+ - Keep the original casing of a proper noun or product name, such as `GitHub`, `macOS`, or `TypeScript`.
25
+
26
+ ## Uppercase labels
27
+
28
+ - Keep small uppercase labels above headings to `ceil(sections / 3)`, the first screen counting as one. Delete the extra labels, since position already names a section.
29
+
30
+ ## Where it applies
31
+
32
+ - Apply the same casing to interface copy kept outside the globs, such as a locale file, which this rule never fires on.
33
+
34
+ ## Overriding
35
+
36
+ - Depart from sentence case only where the case needs it, such as an acronym, a brand mark, or a set-in-caps identity the design chose on purpose.
37
+
38
+ ## Default target
39
+
40
+ - Open a link in the same tab. Reserve `target="_blank"` for a page the person must consult while finishing a task in the current one.
41
+ - Never add `target="_blank"` as a default for every external link.
42
+
43
+ ## mailto: links
44
+
45
+ - Open a `mailto:` link in the same tab. It hands off to the mail client rather than replacing the page, so a new tab leaves an empty tab behind.
@@ -1,12 +1,3 @@
1
- ---
2
- description: Form validation timing, submission, error placement, and derived state for rendered forms
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- ---
9
-
10
1
  # Form standards
11
2
 
12
3
  ## Validation timing
@@ -1,13 +1,3 @@
1
- ---
2
- description: Focus styles, keyboard operation, composite widgets, and focus management for rendered UI
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- - '**/*.css'
9
- ---
10
-
11
1
  # Keyboard and focus standards
12
2
 
13
3
  ## Focus styles
@@ -1,13 +1,3 @@
1
- ---
2
- description: Moving content controls and the reduced-motion preference for rendered UI
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- - '**/*.css'
9
- ---
10
-
11
1
  # Motion standards
12
2
 
13
3
  ## Moving content
@@ -1,13 +1,3 @@
1
- ---
2
- description: Pointer actions, gestures, outside-press dismissal, and target size for rendered UI
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- - '**/*.css'
9
- ---
10
-
11
1
  # Pointer standards
12
2
 
13
3
  ## Pointer actions
@@ -1,13 +1,3 @@
1
- ---
2
- description: UX completeness checklist for interactive components and views
3
- paths:
4
- - '**/*.tsx'
5
- - '**/*.jsx'
6
- - '**/*.astro'
7
- - '**/*.html'
8
- - '**/*.css'
9
- ---
10
-
11
1
  # UX completeness standards
12
2
 
13
3
  ## Feedback
@@ -36,7 +36,7 @@ For each surface, look for:
36
36
  3. **Inconsistencies**: spacing, tone of voice, interaction patterns, icon use, keyboard affordances
37
37
  4. **Roughness in daily use**: friction, redundant steps, unclear affordances, ambiguous labels
38
38
 
39
- Use `canon/DESIGN.md` as ground truth for intent where it exists. Observations only, no implementation suggestions or fixes. Take what consistent interaction means from the `ui` rules in `.claude/rules/`, and skip that when the project installed none.
39
+ Use `canon/DESIGN.md` as ground truth for intent where it exists. Observations only, no implementation suggestions or fixes. Take what consistent interaction means from the `ui-craft` skill's references.
40
40
 
41
41
  Where Step 1 found a committed capture for this surface, judge composed output (spacing, overlap, contrast, wrapping) against it rather than inferring layout from markup. Where none exists, judge from source and say so in that surface's findings, since a source read cannot see what only a render shows.
42
42
 
@@ -5,7 +5,10 @@ description: Which external writing patterns this skill adopted, which it declin
5
5
 
6
6
  # Source material
7
7
 
8
- Two external writing skills were read as source material for this one. The first catalogs 31 patterns of machine-sounding prose. The second layers document mode, sentence construction, information density, and ambiguity prevention.
8
+ Two external writing skills were read as source material for this one.
9
+
10
+ - **[humanizer](https://github.com/blader/humanizer)** catalogs 31 patterns of machine-sounding prose
11
+ - **An unidentified second skill** layers document mode, sentence construction, information density, and ambiguity prevention. No record of the read named it, so it carries no link.
9
12
 
10
13
  Neither was imported wholesale, and one measurement settles why. Read this before adding a rule from outside this corpus, and extend the position below rather than deriving a second one.
11
14
 
@@ -62,11 +62,11 @@ After a rename the new name shows as `missing` when the stamp records a stack, a
62
62
 
63
63
  ## Tooling
64
64
 
65
- - `canon tooling diff <stack> [target]` is the read-only comparison, exiting 1 on any difference
65
+ - `canon tooling diff <stack> [target]` is the read-only comparison, exiting 1 on any difference, and it reads a dependency on a later major than the stack pins as `ahead`, which counts as no change
66
66
  - A `--json` refusal answers `{ ok: false, reason, message }`, so branch on the record
67
67
  - `withheld` entries are `{ rel, stack, present }`, hold every `.github/` file below the git root, and count toward no exit
68
68
  - `present` marks a copy an earlier sync left, which is reported and never deleted
69
- - `canon tooling sync <stack> [target]` writes only under `--write`. `--check` reports and exits 0, and a headless run with neither flag exits 1.
69
+ - `canon tooling sync <stack> [target]` writes only under `--write`. `--check` reports and exits 0, and a headless run with neither flag exits 1. It never installs over an `ahead` dependency.
70
70
 
71
71
  ### Drift cause and the write hold
72
72
 
@@ -187,12 +187,12 @@ A web project's `e2e/screenshot.ts` is a config. It now loads `CASES` from a see
187
187
  - Evidence now defaults to `e2e/evidence/`. Set `export const EVIDENCE_ROOT = 'evidence'` in `e2e/capture/cases.ts` to keep a committed baseline at the old path.
188
188
  - A run from a folder with no `e2e/capture/cases.ts` exits 1 and names the file.
189
189
 
190
- ## Add the rules a split left behind, once
190
+ ## Fold the ui rules onto one pointer, once
191
191
 
192
- The splits created `pointer` and `ux-controls`, and sync refreshes only held rules. `canon gov sync` now names the missing partner of `keyboard.md` and `ux-completeness.md` on every run and adds nothing itself. `a11y.md` gained two bullets and lost none, so it needs no partner.
192
+ Eleven ui rules moved unchanged into the `ui-craft` skill, being `a11y`, `keyboard`, `pointer`, `forms`, `motion`, `ux-controls`, `ux-completeness`, `surface-capture`, `copy`, `interface-casing`, and `link-behavior`. Update the plugin, then sync, which folds each one you hold and `design-taste.md` onto one `craft.md` pointer without local edits.
193
193
 
194
194
  ```bash
195
- canon gov install --add pointer,ux-controls --yes .
195
+ canon gov sync .
196
196
  ```
197
197
 
198
198
  ## Group a long paths section in `CLAUDE.md`, once
@@ -45,6 +45,7 @@ Add `--json` for a machine-readable report and `--exit-code` to fail CI when a t
45
45
  - Seed docs such as `CLAUDE.md` and `canon/REQUIREMENTS.md`: merge by hand, keeping the project's customizations
46
46
  - Installed governance rules: `canon gov sync <path>`, which adds no new rules and reports coverage afterward
47
47
  - Tooling configs and seeds: read differences with `canon tooling diff <stack> <path>`, then `canon tooling sync <stack> <path> --write`, which holds an edited config and copies each seed once
48
+ - Tooling dependencies: a dependency on a later major than the stack pins reads as `ahead`, and sync leaves it
48
49
  - Index regeneration: `canon indexes regen`
49
50
 
50
51
  After `canon gov sync` applies, it lists each rule it copied with its globs and how many project files match. A `ui/` rule adds a pointer to `/canon:ux-audit`. `--json` writes `{ "coverage": [{ "rule", "paths", "files", "ui" }] }` to stdout, empty when nothing was copied, with `files` null outside git. The report never changes the exit code.
@@ -59,13 +60,13 @@ A project can also opt out of one golden file without leaving the stack. Each ve
59
60
 
60
61
  ```bash
61
62
  canon tooling decline .github/workflows/readme-screenshot.yml --reason "no screenshots here"
62
- canon tooling customize e2e/home.spec.ts
63
+ canon tooling customize e2e/screenshot.ts
63
64
  canon tooling lift .github/workflows/readme-screenshot.yml
64
65
  ```
65
66
 
66
67
  - `decline` keeps sync and inject from writing the file again, and leaves a copy the project still holds in place
67
68
  - `customize` keeps the project's copy of a config through every write, and `diff` exits 1 once the stack ships a newer golden copy
68
- - A seed cannot be customized, since sync never overwrites one
69
+ - A seed cannot be customized, since sync never overwrites one, and the starter `e2e/home.spec.ts` is one
69
70
  - `lift` hands the file back, so the next sync writes it
70
71
 
71
72
  These verbs are the only writers of the record in `canon/config/config.json`, so never edit it there by hand.
@@ -45,6 +45,7 @@ Groups run in the order a project meets them. Every name `canon claude skills li
45
45
  | `canon:search-craft` | Before searching outside the project |
46
46
  | `canon:systematic-debugging` | A test fails or a bug surfaces |
47
47
  | `canon:design-taste` | Drafting or judging an interface |
48
+ | `canon:ui-craft` | Building or judging a component's behavior |
48
49
  | `canon:ui-checklist` | After a UI change, to list what to check |
49
50
 
50
51
  ## Check the work before it leaves the branch
@@ -19,8 +19,8 @@ Canon runs a UI feature through one loop. A plan cites the design, a worker buil
19
19
 
20
20
  The worker opens each cited reference, light and dark, before its first edit to that surface. It takes sizes, spacing, and colors from the frame HTML rather than the image, and reports a reference that does not resolve instead of building without it.
21
21
 
22
- - The ui rules fire as a family on the files the worker edits, and `governance/rules/ui/` holds the set.
23
- - The `surface-capture` rule has the worker capture the full page in every theme the surface ships, against a preview server and never a dev server.
22
+ - The `craft` rule fires on the files the worker edits and loads `ui-craft` for behavior and `design-taste` for look.
23
+ - The `ui-craft` capture reference has the worker capture the full page in every theme the surface ships, against a preview server and never a dev server.
24
24
  - It sets the widths too, being 320 plus each breakpoint in `canon/DESIGN.md` for a layout case, and one width for a state case.
25
25
 
26
26
  ## Self-check
@@ -160,54 +160,10 @@ deps = [
160
160
  ]
161
161
  files = ["**/migrations", "**/schema.prisma", "**/*.sql"]
162
162
 
163
- ["copy"]
164
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
165
- files = ["index.html", "*/index.html"]
166
-
167
- ["a11y"]
168
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
169
- files = ["index.html", "*/index.html"]
170
-
171
- ["keyboard"]
172
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
173
- files = ["index.html", "*/index.html"]
174
-
175
- ["pointer"]
176
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
177
- files = ["index.html", "*/index.html"]
178
-
179
- ["forms"]
180
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
181
- files = ["index.html", "*/index.html"]
182
-
183
- ["ux-completeness"]
184
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
185
- files = ["index.html", "*/index.html"]
186
-
187
- ["ux-controls"]
188
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
189
- files = ["index.html", "*/index.html"]
190
-
191
- ["surface-capture"]
192
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
193
- files = ["index.html", "*/index.html"]
194
-
195
- ["link-behavior"]
196
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
197
- files = ["index.html", "*/index.html"]
198
-
199
- ["design-taste"]
163
+ ["craft"]
200
164
  deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
201
165
  files = ["canon/DESIGN.md", "index.html", "*/index.html"]
202
166
 
203
- ["interface-casing"]
204
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
205
- files = ["index.html", "*/index.html"]
206
-
207
- ["motion"]
208
- deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
209
- files = ["index.html", "*/index.html"]
210
-
211
167
  ["design-reference"]
212
168
  deps = []
213
169
  files = ["canon/design/*/"]
@@ -25,7 +25,7 @@ The field is browser test automation, and the authority is the Playwright docume
25
25
  | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
26
26
  | A script, not the suite | House choice: a suite run answers a question about the page only through assertions written for another question, and costs the whole run | 2026-10-18 |
27
27
  | No `fullyParallel` | [Parallelism](https://playwright.dev/docs/test-parallel): by default "Tests in a single file are run in order, in the same worker process", and parallel tests "cannot share any state or global variables" | 2026-10-18 |
28
- | Pointer to `surface-capture` | House choice: a pointer to the rule that owns capture scope, claiming no practice of its own | 2026-10-18 |
28
+ | Pointer to `ui-craft` | House choice: a pointer to the skill that owns capture scope, claiming no practice of its own | 2026-10-18 |
29
29
  | Pointer to `e2e-reliability` | House choice: a pointer to the rule that owns waits and guards, claiming no practice of its own | 2026-10-18 |
30
30
 
31
31
  ## Declined
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: Accessibility rule ledger
3
- description: Sources for governance/rules/ui/a11y.md, one row per bullet
2
+ title: Accessibility reference ledger
3
+ description: Sources for claude/skills/ui-craft/references/a11y.md, one row per bullet
4
4
  ---
5
5
 
6
- # Accessibility rule ledger
6
+ # Accessibility reference ledger
7
7
 
8
8
  The field is web accessibility, and the authority is the W3C, through WCAG 2.2 and its Understanding documents, the WAI tutorials, and the ARIA notes. The keyboard and focus half of the old rule moved to `keyboard.md`, whose ledger records those bullets.
9
9
 
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: Surface capture rule ledger
3
- description: Sources for governance/rules/ui/surface-capture.md, one row per bullet
2
+ title: Surface capture reference ledger
3
+ description: Sources for claude/skills/ui-craft/references/capture.md, one row per bullet
4
4
  ---
5
5
 
6
- # Surface capture rule ledger
6
+ # Surface capture reference ledger
7
7
 
8
8
  The rule states canon's own evidence procedure for a rendered change, so most rows are house choices naming the bug the bullet prevents. The 320 floor rests on WCAG 2.2, and each explanation the old rule carried moved into a row here.
9
9
 
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: UX controls rule ledger
3
- description: Sources for governance/rules/ui/ux-controls.md, one row per bullet
2
+ title: UX controls reference ledger
3
+ description: Sources for claude/skills/ui-craft/references/controls.md, one row per bullet
4
4
  ---
5
5
 
6
- # UX controls rule ledger
6
+ # UX controls reference ledger
7
7
 
8
8
  The field is interaction design, and the authorities are the Nielsen Norman Group, WCAG 2.2, Primer, Cloudscape, MDN, and web.dev. These bullets were split from `ux-completeness.md`.
9
9
 
@@ -16,11 +16,16 @@ The field is interaction design, and the authorities are the Nielsen Norman Grou
16
16
 
17
17
  ## Element states
18
18
 
19
+ | Bullet | Source | Read |
20
+ | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
21
+ | Distinct interaction states | [Visibility of system status](https://www.nngroup.com/articles/visibility-system-status/): "Did the system actually catch that button press", and an element with no pressed or hover response leaves the person unable to tell | 2026-10-18 |
22
+ | Say why a control is disabled | [Cloudscape, Disabled and read-only states](https://cloudscape.design/patterns/general/disabled-and-read-only-states/): "Use disabled reasons where adequate context is not provided through disabled button or label text", and `aria-disabled="true"` is used "so that it will remain focusable" | 2026-10-23 |
23
+ | Declare `color-scheme` | [MDN, color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme): the user agent adapts "The default colors of scrollbars and other interaction UI" and "The default colors of form controls", and the page opts in by declaring it on the `:root` element | 2026-10-23 |
24
+ | No intermediate flash | [Cumulative Layout Shift](https://web.dev/articles/cls): "Unexpected layout shifts can disrupt the user experience", caused by content "dynamically added to the page before existing content" | 2026-10-18 |
25
+
26
+ ## Hover and focus effects
27
+
19
28
  | Bullet | Source | Read |
20
29
  | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
21
- | Distinct interaction states | [Visibility of system status](https://www.nngroup.com/articles/visibility-system-status/): "Did the system actually catch that button press", and an element with no pressed or hover response leaves the person unable to tell | 2026-10-18 |
22
- | Say why a control is disabled | [Cloudscape, Disabled and read-only states](https://cloudscape.design/patterns/general/disabled-and-read-only-states/): "Use disabled reasons where adequate context is not provided through disabled button or label text", and `aria-disabled="true"` is used "so that it will remain focusable" | 2026-10-23 |
23
- | Declare `color-scheme` | [MDN, color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme): the user agent adapts "The default colors of scrollbars and other interaction UI" and "The default colors of form controls", and the page opts in by declaring it on the `:root` element | 2026-10-23 |
24
30
  | Hover and focus content | [Understanding Content on Hover or Focus](https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus.html): additional content is "Dismissible" without moving hover or focus, "Hoverable" so the pointer can move over it, and "Persistent" until "the hover or focus trigger is removed, the user dismisses it, or its information is no longer valid" | 2026-10-23, WCAG 2.2 |
25
31
  | No change of context on focus or input | [Understanding On Focus](https://www.w3.org/WAI/WCAG22/Understanding/on-focus.html): "When any user interface component receives focus, it does not initiate a change of context". [Understanding On Input](https://www.w3.org/WAI/WCAG22/Understanding/on-input.html): changing a setting does not cause one "unless the user has been advised of the behavior before using the component" | 2026-10-23, WCAG 2.2 |
26
- | No intermediate flash | [Cumulative Layout Shift](https://web.dev/articles/cls): "Unexpected layout shifts can disrupt the user experience", caused by content "dynamically added to the page before existing content" | 2026-10-18 |
@@ -0,0 +1,102 @@
1
+ ---
2
+ title: UI copy reference ledger
3
+ description: Sources for claude/skills/ui-craft/references/copy.md, one row per bullet
4
+ ---
5
+
6
+ # UI copy reference ledger
7
+
8
+ The reference joins three rules, and its sections keep their order, so each source below covers a run of them.
9
+
10
+ Content design governs the first four sections, where the authority for researched interface copy is the GOV.UK Design System and its style guide.
11
+
12
+ The four casing sections rest on the GOV.UK style guide, which sets sentence case for every heading and title, and canon set the label count and the scope bullets itself. The two link sections are interaction design, sourced from the Nielsen Norman Group's research on new windows and tabs.
13
+
14
+ ## Punctuation
15
+
16
+ | Bullet | Source | Read |
17
+ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
18
+ | No em dash or semicolon | House choice: both read as generated copy in an interface, and a comma, a period, or a split sentence carries the same meaning in a shorter line | 2026-10-18 |
19
+ | No trailing label punctuation | [Button](https://design-system.service.gov.uk/components/button/): every example label, such as "Start now", "Sign in", and "Continue", carries no trailing punctuation | 2026-10-18 |
20
+
21
+ ## Button copy
22
+
23
+ | Bullet | Source | Read |
24
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
25
+ | The action's verb | [Button](https://design-system.service.gov.uk/components/button/): "Write button text in sentence case, describing the action it performs" | 2026-10-18 |
26
+
27
+ ## Error messages
28
+
29
+ | Bullet | Source | Read |
30
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
31
+ | Say how to fix it | [Error message](https://design-system.service.gov.uk/components/error-message/): "Describe what has happened and tell them how to fix it", and "'Enter your first name' is clearer, more direct and natural than 'First name must have an entry'" | 2026-10-18 |
32
+ | Short and plain | [Error message](https://design-system.service.gov.uk/components/error-message/): "The message must be in plain English, use positive language and get to the point", with no "technical jargon like 'form post error'" | 2026-10-18 |
33
+
34
+ ## Placeholder text
35
+
36
+ | Bullet | Source | Read |
37
+ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
38
+ | No placeholder, a hint instead | [Text input](https://design-system.service.gov.uk/components/text-input/): "Do not use placeholder text in place of a label, or for hints or examples", since "it vanishes when the user starts typing" and "not all screen readers read it out" | 2026-10-18 |
39
+
40
+ ## Sentence case
41
+
42
+ | Bullet | Source | Read |
43
+ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
44
+ | Sentence case | [A to Z of GOV.UK style](https://www.gov.uk/guidance/style-guide/a-to-z-of-gov-uk-style): "Always use sentence case, even in page titles and service names" | 2026-10-18 |
45
+ | Proper nouns keep casing | [A to Z of GOV.UK style](https://www.gov.uk/guidance/style-guide/a-to-z-of-gov-uk-style): "The exceptions to this are proper nouns" | 2026-10-18 |
46
+
47
+ ## Uppercase labels
48
+
49
+ | Bullet | Source | Read |
50
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
51
+ | Label count | House choice: an uppercase eyebrow over every section is the template tell `design-taste` reaches past, and the count makes the cap checkable against a page | 2026-10-18 |
52
+
53
+ ## Where it applies
54
+
55
+ | Bullet | Source | Read |
56
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------- |
57
+ | Copy outside the globs | House choice: a locale file holds the same rendered strings, so title case there ships with no rule firing on it | 2026-10-18 |
58
+
59
+ ## Overriding
60
+
61
+ | Bullet | Source | Read |
62
+ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
63
+ | Depart where needed | House choice: an acronym or brand mark lowered to sentence case misnames it, the same reason GOV.UK keeps "proper nouns" as its one exception | 2026-10-18 |
64
+
65
+ ## Default target
66
+
67
+ | Bullet | Source | Read |
68
+ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
69
+ | Same tab, new tab by task | [Opening links in new browser windows and tabs](https://www.nngroup.com/articles/new-browser-windows-and-tabs/): "There is generally one good reason to open a page in a new window, and that is that the user will need to refer to that content in order to complete a task in another window" | 2026-10-18 |
70
+ | No blanket external new tab | [Opening links in new browser windows and tabs](https://www.nngroup.com/articles/new-browser-windows-and-tabs/): "New windows or tabs prevent the use of the Back button" and "can cause disorientation" | 2026-10-18 |
71
+
72
+ ## mailto: links
73
+
74
+ | Bullet | Source | Read |
75
+ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
76
+ | `mailto:` same tab | House choice: the link opens the mail client and leaves the page in place, so `target="_blank"` only adds an empty tab the person must close | 2026-10-18 |
77
+
78
+ ## Declined
79
+
80
+ Every bullet the rewrite removed or reshaped, grouped by why.
81
+
82
+ ### Contradicted by the source
83
+
84
+ - Replaced "show format examples over instructions in placeholder text" with the hint text bullet, since GOV.UK says not to use a placeholder "for hints or examples".
85
+ - Cut "reserve instructions for labels or helper text", which the new placeholder bullet now carries.
86
+
87
+ ### Merged or reworded
88
+
89
+ - Merged the imperative verb and padded phrasing bullets. The `Save` over `Save changes` example went, since GOV.UK adds words "to better describe the action".
90
+ - Merged "keep messages short and actionable" and "one sentence maximum" into the plain language bullet.
91
+ - Reworded the error example to `Enter an email address`, the instruction form GOV.UK prefers over a description.
92
+ - Folded "treat title case on every heading as a template tell" into the sentence case bullet as its reason.
93
+ - Shortened the uppercase label bullet under 200 characters, keeping the `ceil(sections / 3)` count and the delete remedy.
94
+ - Reworded the scope bullet from a statement of what the rule covers to the directive a session can act on.
95
+
96
+ ### Cut without a check
97
+
98
+ - Cut "treat the count as a judgment, since a glob cannot check it", which tells a session nothing it can verify against a line.
99
+
100
+ ### Rewritten to what the source says
101
+
102
+ - Reworded the new tab exception from "a destination that would discard in-progress work" to a page the person must consult while finishing a task, the one reason NN/g names.
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: Forms rule ledger
3
- description: Sources for governance/rules/ui/forms.md, one row per bullet
2
+ title: Forms reference ledger
3
+ description: Sources for claude/skills/ui-craft/references/forms.md, one row per bullet
4
4
  ---
5
5
 
6
- # Forms rule ledger
6
+ # Forms reference ledger
7
7
 
8
8
  The field is form design inside interaction design, and the authority for researched form patterns is the GOV.UK Design System, with WCAG 2.2 for the two authentication criteria. NN/g was read beside it and disagrees on validation timing, recorded under `## Declined`.
9
9
 
@@ -1,9 +1,9 @@
1
1
  ---
2
- title: Keyboard rule ledger
3
- description: Sources for governance/rules/ui/keyboard.md, one row per bullet
2
+ title: Keyboard reference ledger
3
+ description: Sources for claude/skills/ui-craft/references/keyboard.md, one row per bullet
4
4
  ---
5
5
 
6
- # Keyboard rule ledger
6
+ # Keyboard reference ledger
7
7
 
8
8
  The field is web accessibility, and the authorities are the W3C, through WCAG 2.2 and the ARIA Authoring Practices Guide, MDN for CSS behavior, and the platform guidelines from Apple and Android for native targets. Every bullet here was split from `a11y.md`.
9
9