taste-lint 0.2.0 → 0.3.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/README.md +5 -3
- package/data/config.schema.json +7 -0
- package/data/rules/copywriting/copywriting-anthropomorphism.yaml +4 -3
- package/data/rules/copywriting/copywriting-antithesis-frame.yaml +21 -0
- package/data/rules/copywriting/copywriting-click-here-links.yaml +4 -3
- package/data/rules/copywriting/copywriting-conditions-first.yaml +2 -2
- package/data/rules/copywriting/copywriting-copula-avoidance.yaml +21 -0
- package/data/rules/copywriting/copywriting-error-descriptions.yaml +2 -2
- package/data/rules/copywriting/copywriting-filler-words.yaml +4 -3
- package/data/rules/copywriting/copywriting-latinisms.yaml +6 -4
- package/data/rules/copywriting/copywriting-nominalisations.yaml +4 -3
- package/data/rules/copywriting/copywriting-participle-tail.yaml +21 -0
- package/data/rules/copywriting/copywriting-passive-voice.yaml +4 -3
- package/data/rules/copywriting/copywriting-promotional-docs-voice.yaml +4 -3
- package/data/rules/copywriting/copywriting-requirements-language.yaml +2 -2
- package/data/rules/copywriting/copywriting-searchable-headings.yaml +2 -2
- package/data/rules/copywriting/copywriting-tee-up.yaml +21 -0
- package/data/rules/copywriting/copywriting-temporal-words.yaml +4 -3
- package/data/rules/craft/craft-atmosphere-gradient.yaml +28 -0
- package/data/rules/craft/craft-default-indigo.yaml +28 -0
- package/data/rules/motion/motion-will-change-misuse.yaml +28 -0
- package/data/rules/product/product-nested-modals.yaml +1 -1
- package/data/rules/product/product-select-for-few-options.yaml +1 -1
- package/dist/cli.js +186 -37
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +185 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,15 +40,17 @@ Checks bill your key and cache between runs. `--dry-run` previews the cost first
|
|
|
40
40
|
|
|
41
41
|
## What it checks
|
|
42
42
|
|
|
43
|
-
- **Motion:** `transition-all`, ease-in, linear easing, transitions over 300ms, entrances from scale zero.
|
|
44
|
-
- **Copy:** “click here” links, “successfully” toasts, emoji in UI,
|
|
43
|
+
- **Motion:** `transition-all` and `transition: all`, ease-in, linear easing, transitions over 300ms, entrances from scale zero, `framer-motion` imports.
|
|
44
|
+
- **Copy:** the [ghostwriter](https://github.com/mblode/agent-skills/tree/main/skills/ghostwriter) structure tells (participle tails, “it’s not X, it’s Y”, “Here’s the thing”), “click here” links, “successfully” toasts, emoji in UI, nominalisations, anthropomorphism, long sentences that chain clauses.
|
|
45
45
|
- **Typography:** straight quotes, three-dot ellipses, hyphens for dashes, `x` for ×, missing space before a unit, light weights on small body text, uppercase without tracking.
|
|
46
46
|
- **Under review:** vague errors, empty states with no action, bare “Confirm” labels, claims with nothing to check, missing error states. These go to [Jev by TypeSafe AI](https://docs.typesafe.ai/introduction), which answers with a probability.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
28 checks block. 125 more report and never fail a run. They are pattern ports nobody has yet watched on a real codebase, and Jev questions no labelled corpus has yet promoted. See [usage](https://blode.co/taste-lint/docs/usage) for how promotion works.
|
|
49
49
|
|
|
50
50
|
Profiles scope a run: `product` (tsx, jsx, css), `writing` (md, mdx, README), `instructions` (AGENTS.md, skills, plans), `all`.
|
|
51
51
|
|
|
52
|
+
Add your own voice with a rule pack: `"rules": ["$GHOSTWRITER_HOME/taste-lint"]` in `taste-lint.config.json` checks drafts against your [ghostwriter](https://github.com/mblode/agent-skills/tree/main/skills/ghostwriter) profile.
|
|
53
|
+
|
|
52
54
|
## Docs
|
|
53
55
|
|
|
54
56
|
<p>
|
package/data/config.schema.json
CHANGED
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
"smartQuotesAtBuild": {
|
|
15
15
|
"type": "boolean"
|
|
16
16
|
},
|
|
17
|
+
"rules": {
|
|
18
|
+
"description": "Extra rule directories, laid out like data/rules (domain folders of YAML rules). Paths resolve from the scan root; a leading ~ and $VARS expand, so a voice pack can live in $GHOSTWRITER_HOME.",
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
17
24
|
"components": {
|
|
18
25
|
"type": "object",
|
|
19
26
|
"additionalProperties": false,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/voice-no-anthropomorphism.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/voice-no-anthropomorphism.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired.
|
|
2
3
|
id: copywriting-anthropomorphism
|
|
3
4
|
title: Software described as thinking, wanting or knowing
|
|
4
5
|
categoryId: machine-prose
|
|
5
6
|
source:
|
|
6
7
|
{
|
|
7
8
|
repo: mblode/agent-skills,
|
|
8
|
-
path: skills/
|
|
9
|
-
line:
|
|
9
|
+
path: skills/ghostwriter/references/docs.md,
|
|
10
|
+
line: 13,
|
|
10
11
|
}
|
|
11
12
|
unit: [paragraph]
|
|
12
13
|
mechanical:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ghostwriter/references/tells.md (structure tells).
|
|
2
|
+
id: copywriting-antithesis-frame
|
|
3
|
+
title: Sets up a claim by denying one nobody made
|
|
4
|
+
categoryId: machine-prose
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ghostwriter/references/tells.md,
|
|
9
|
+
line: 12,
|
|
10
|
+
}
|
|
11
|
+
unit: [paragraph]
|
|
12
|
+
mechanical:
|
|
13
|
+
regex: "(?<![\"“‘'])\\bnot (?:just|only|merely) (?:a |an |the |about )?[\\w-]+(?: [\\w-]+){0,4}[,;]? but\\b|(?<![\"“‘'])\\b(?:it|this|that)(?:['’]s| is)(?: not|n['’]t) (?:just |only )?(?:about )?[^.!?,;]{1,40}[.,;] (?:it|this|that)(?:['’]s| is)\\b"
|
|
14
|
+
flags: giu
|
|
15
|
+
severity: minor
|
|
16
|
+
fix:
|
|
17
|
+
hint: >-
|
|
18
|
+
Say the positive thing. "It's not a tool, it's a workflow" becomes "It's a workflow."
|
|
19
|
+
preconditions: { notInCode: true }
|
|
20
|
+
status: active
|
|
21
|
+
handWritten: [mechanical, fix, preconditions]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/format-descriptive-links.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/format-descriptive-links.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired. and taste-training
|
|
2
3
|
# full-stack-audit.tsx (click-here).
|
|
3
4
|
id: copywriting-click-here-links
|
|
4
5
|
title: Link text that names nothing
|
|
@@ -6,8 +7,8 @@ categoryId: actionable-cta
|
|
|
6
7
|
source:
|
|
7
8
|
{
|
|
8
9
|
repo: mblode/agent-skills,
|
|
9
|
-
path: skills/
|
|
10
|
-
line:
|
|
10
|
+
path: skills/ghostwriter/references/docs.md,
|
|
11
|
+
line: 21,
|
|
11
12
|
}
|
|
12
13
|
unit: [jsx-text]
|
|
13
14
|
mechanical:
|
|
@@ -3,8 +3,8 @@ title: An instruction hides its prerequisite after the action
|
|
|
3
3
|
categoryId: page-structure
|
|
4
4
|
source:
|
|
5
5
|
repo: mblode/agent-skills
|
|
6
|
-
path: skills/
|
|
7
|
-
line:
|
|
6
|
+
path: skills/ghostwriter/references/docs.md
|
|
7
|
+
line: 15
|
|
8
8
|
ruleId: structure-conditions-first
|
|
9
9
|
unit:
|
|
10
10
|
- paragraph
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ghostwriter/references/tells.md (structure tells).
|
|
2
|
+
id: copywriting-copula-avoidance
|
|
3
|
+
title: Dresses up "is" or "has"
|
|
4
|
+
categoryId: machine-prose
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ghostwriter/references/tells.md,
|
|
9
|
+
line: 13,
|
|
10
|
+
}
|
|
11
|
+
unit: [paragraph]
|
|
12
|
+
mechanical:
|
|
13
|
+
regex: "(?<![\"“‘'])\\b(?:serves|stands) as (?:a|an|the)\\b|(?<![\"“‘'])\\bboasts\\b"
|
|
14
|
+
flags: giu
|
|
15
|
+
severity: minor
|
|
16
|
+
fix:
|
|
17
|
+
hint: >-
|
|
18
|
+
Write "is" or "has". "The index serves as a cache" becomes "The index is a cache."
|
|
19
|
+
preconditions: { notInCode: true }
|
|
20
|
+
status: review-only
|
|
21
|
+
handWritten: [mechanical, fix, preconditions]
|
|
@@ -3,8 +3,8 @@ title: An error explanation provides no recovery guidance
|
|
|
3
3
|
categoryId: reference-reading
|
|
4
4
|
source:
|
|
5
5
|
repo: mblode/agent-skills
|
|
6
|
-
path: skills/
|
|
7
|
-
line:
|
|
6
|
+
path: skills/ghostwriter/references/docs.md
|
|
7
|
+
line: 19
|
|
8
8
|
ruleId: code-error-descriptions
|
|
9
9
|
unit:
|
|
10
10
|
- paragraph
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/clarity-defaults.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/clarity-defaults.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired. (cut filler) and the lesson
|
|
2
3
|
# edit-one-lens-at-a-time.mdx.
|
|
3
4
|
id: copywriting-filler-words
|
|
4
5
|
title: Intensifiers and filler that add nothing
|
|
@@ -6,8 +7,8 @@ categoryId: machine-prose
|
|
|
6
7
|
source:
|
|
7
8
|
{
|
|
8
9
|
repo: mblode/agent-skills,
|
|
9
|
-
path: skills/
|
|
10
|
-
line:
|
|
10
|
+
path: skills/ghostwriter/references/docs.md,
|
|
11
|
+
line: 17,
|
|
11
12
|
}
|
|
12
13
|
unit: [paragraph, jsx-text]
|
|
13
14
|
mechanical:
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/clarity-no-latin.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/clarity-no-latin.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired. Review-only:
|
|
3
|
+
# ghostwriter keeps "plain words" but no longer bans Latin abbreviations outright.
|
|
2
4
|
id: copywriting-latinisms
|
|
3
5
|
title: Latin abbreviation in running text
|
|
4
6
|
categoryId: reader-first-framing
|
|
5
7
|
source:
|
|
6
8
|
{
|
|
7
9
|
repo: mblode/agent-skills,
|
|
8
|
-
path: skills/
|
|
9
|
-
line:
|
|
10
|
+
path: skills/ghostwriter/references/docs.md,
|
|
11
|
+
line: 17,
|
|
10
12
|
}
|
|
11
13
|
unit: [paragraph, heading]
|
|
12
14
|
mechanical:
|
|
@@ -21,5 +23,5 @@ preconditions:
|
|
|
21
23
|
docType:
|
|
22
24
|
[tutorial, howto, reference, explanation, agent-instructions, lesson],
|
|
23
25
|
}
|
|
24
|
-
status:
|
|
26
|
+
status: review-only
|
|
25
27
|
handWritten: [mechanical, fix, preconditions]
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/clarity-no-nominalizations.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/clarity-no-nominalizations.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired.
|
|
2
3
|
id: copywriting-nominalisations
|
|
3
4
|
title: Verb buried in a noun
|
|
4
5
|
categoryId: reader-first-framing
|
|
5
6
|
source:
|
|
6
7
|
{
|
|
7
8
|
repo: mblode/agent-skills,
|
|
8
|
-
path: skills/
|
|
9
|
-
line:
|
|
9
|
+
path: skills/ghostwriter/references/docs.md,
|
|
10
|
+
line: 17,
|
|
10
11
|
}
|
|
11
12
|
unit: [paragraph, jsx-text]
|
|
12
13
|
mechanical:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ghostwriter/references/tells.md (structure tells).
|
|
2
|
+
id: copywriting-participle-tail
|
|
3
|
+
title: Sentence ends in a participle tail
|
|
4
|
+
categoryId: machine-prose
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ghostwriter/references/tells.md,
|
|
9
|
+
line: 16,
|
|
10
|
+
}
|
|
11
|
+
unit: [paragraph]
|
|
12
|
+
mechanical:
|
|
13
|
+
regex: "(?<![\"“‘']),\\s+(?:ensuring|highlighting|underscoring|showcasing|emphasi[sz]ing|reinforcing|cementing|solidifying|fostering|signall?ing)\\b"
|
|
14
|
+
flags: giu
|
|
15
|
+
severity: minor
|
|
16
|
+
fix:
|
|
17
|
+
hint: >-
|
|
18
|
+
Keep the fact and cut at the comma. "Tests run on every push, ensuring quality" becomes "Tests run on every push."
|
|
19
|
+
preconditions: { notInCode: true }
|
|
20
|
+
status: active
|
|
21
|
+
handWritten: [mechanical, fix, preconditions]
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/voice-defaults.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/voice-defaults.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired. (active voice, present tense).
|
|
2
3
|
id: copywriting-passive-voice
|
|
3
4
|
title: Passive voice where the actor is known
|
|
4
5
|
categoryId: machine-prose
|
|
5
6
|
source:
|
|
6
7
|
{
|
|
7
8
|
repo: mblode/agent-skills,
|
|
8
|
-
path: skills/
|
|
9
|
-
line:
|
|
9
|
+
path: skills/ghostwriter/references/docs.md,
|
|
10
|
+
line: 13,
|
|
10
11
|
}
|
|
11
12
|
unit: [paragraph, heading]
|
|
12
13
|
mechanical:
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/voice-defaults.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/voice-defaults.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired. (professional, not promotional).
|
|
2
3
|
id: copywriting-promotional-docs-voice
|
|
3
4
|
title: Marketing voice inside documentation
|
|
4
5
|
categoryId: evidence-over-claims
|
|
5
6
|
source:
|
|
6
7
|
{
|
|
7
8
|
repo: mblode/agent-skills,
|
|
8
|
-
path: skills/
|
|
9
|
-
line:
|
|
9
|
+
path: skills/ghostwriter/references/docs.md,
|
|
10
|
+
line: 13,
|
|
10
11
|
}
|
|
11
12
|
unit: [paragraph, heading]
|
|
12
13
|
mechanical:
|
|
@@ -3,8 +3,8 @@ title: A requirement presented as a recommendation
|
|
|
3
3
|
categoryId: reader-first-framing
|
|
4
4
|
source:
|
|
5
5
|
repo: mblode/agent-skills
|
|
6
|
-
path: skills/
|
|
7
|
-
line:
|
|
6
|
+
path: skills/ghostwriter/references/docs.md
|
|
7
|
+
line: 13
|
|
8
8
|
ruleId: voice-requirements-language
|
|
9
9
|
unit:
|
|
10
10
|
- paragraph
|
|
@@ -3,8 +3,8 @@ title: A documentation heading names no topic or action
|
|
|
3
3
|
categoryId: page-structure
|
|
4
4
|
source:
|
|
5
5
|
repo: mblode/agent-skills
|
|
6
|
-
path: skills/
|
|
7
|
-
line:
|
|
6
|
+
path: skills/ghostwriter/references/docs.md
|
|
7
|
+
line: 21
|
|
8
8
|
ruleId: nav-searchable-headings
|
|
9
9
|
unit:
|
|
10
10
|
- heading
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ghostwriter/references/tells.md (structure tells).
|
|
2
|
+
id: copywriting-tee-up
|
|
3
|
+
title: Tees up a point instead of stating it
|
|
4
|
+
categoryId: machine-prose
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ghostwriter/references/tells.md,
|
|
9
|
+
line: 15,
|
|
10
|
+
}
|
|
11
|
+
unit: [paragraph]
|
|
12
|
+
mechanical:
|
|
13
|
+
regex: "(?<![\"“‘'])\\bhere['’]s the (?:thing|kicker|catch|deal|twist)\\b|(?<![\"“‘'])\\bthe (?:kicker|catch|twist)\\?|(?<![\"“‘'])\\bwhat struck me (?:was|is)\\b|(?<![\"“‘'])\\blet that sink in\\b"
|
|
14
|
+
flags: giu
|
|
15
|
+
severity: minor
|
|
16
|
+
fix:
|
|
17
|
+
hint: >-
|
|
18
|
+
Delete the tee-up and state the thing.
|
|
19
|
+
preconditions: { notInCode: true }
|
|
20
|
+
status: active
|
|
21
|
+
handWritten: [mechanical, fix, preconditions]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# Ported from mblode/agent-skills skills/docs-writing/rules/hygiene-no-temporal.md
|
|
1
|
+
# Ported from mblode/agent-skills skills/docs-writing/rules/hygiene-no-temporal.md, now
|
|
2
|
+
# skills/ghostwriter/references/docs.md after docs-writing was retired. and
|
|
2
3
|
# rules/hygiene-update-metadata.md.
|
|
3
4
|
id: copywriting-temporal-words
|
|
4
5
|
title: Wording anchored to the time of writing
|
|
@@ -6,8 +7,8 @@ categoryId: reference-reading
|
|
|
6
7
|
source:
|
|
7
8
|
{
|
|
8
9
|
repo: mblode/agent-skills,
|
|
9
|
-
path: skills/
|
|
10
|
-
line:
|
|
10
|
+
path: skills/ghostwriter/references/docs.md,
|
|
11
|
+
line: 23,
|
|
11
12
|
}
|
|
12
13
|
unit: [paragraph, heading]
|
|
13
14
|
mechanical:
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ui-design/direction/aesthetic-direction.md (slop signals).
|
|
2
|
+
id: craft-atmosphere-gradient
|
|
3
|
+
title: Purple or cyan gradient used as atmosphere
|
|
4
|
+
categoryId: generic-decoration
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ui-design/direction/aesthetic-direction.md,
|
|
9
|
+
line: 12,
|
|
10
|
+
}
|
|
11
|
+
scope:
|
|
12
|
+
include: ["**/*.tsx", "**/*.jsx"]
|
|
13
|
+
unit: [source]
|
|
14
|
+
mechanical:
|
|
15
|
+
regex: "\\bbg-(?:gradient-to|linear-to|radial)-?[\\w-]*[^\"'`\\n]*?\\b(?:from|via|to)-(?:purple|violet|fuchsia|indigo|cyan)-\\d{2,3}\\b|\\b(?:from|via)-(?:purple|violet|fuchsia|indigo|cyan)-\\d{2,3}\\b[^\"'`\\n]*?\\bbg-(?:gradient-to|linear-to|radial)"
|
|
16
|
+
flags: gu
|
|
17
|
+
severity: minor
|
|
18
|
+
fix:
|
|
19
|
+
hint: >-
|
|
20
|
+
Give the surface a content or brand role, or remove the gradient. Purple and cyan washes are the most common AI-generated backdrop.
|
|
21
|
+
status: review-only
|
|
22
|
+
review:
|
|
23
|
+
applicability: A class list pairs a gradient background with purple, violet, fuchsia, indigo or cyan stops.
|
|
24
|
+
exceptions: Brand colours, data visualisation ramps, and illustrations where the gradient carries meaning.
|
|
25
|
+
evidence: The brand palette and what the gradient surface contains.
|
|
26
|
+
verification: Confirm the gradient carries a brand or content role, or replace it with a flat surface from the theme.
|
|
27
|
+
sourceHash: 696321dfa9cb90a6d31bba628bba33aecf23ff4aaadd3516ca2a2eea4e6219e1
|
|
28
|
+
handWritten: [mechanical, fix, review, scope]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ui-design/guidelines/colors.md.
|
|
2
|
+
id: craft-default-indigo
|
|
3
|
+
title: Indigo accent that looks like a template default
|
|
4
|
+
categoryId: colour-system
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ui-design/guidelines/colors.md,
|
|
9
|
+
line: 5,
|
|
10
|
+
}
|
|
11
|
+
scope:
|
|
12
|
+
include: ["**/*.tsx", "**/*.jsx", "**/*.css"]
|
|
13
|
+
unit: [source]
|
|
14
|
+
mechanical:
|
|
15
|
+
regex: "\\b(?:bg|text|border|ring|from|via|to|fill|stroke|outline|accent|shadow|decoration)-indigo-\\d{2,3}\\b"
|
|
16
|
+
flags: gu
|
|
17
|
+
severity: minor
|
|
18
|
+
fix:
|
|
19
|
+
hint: >-
|
|
20
|
+
Pick an accent from the brand, or use the theme's primary token. Indigo is the colour every starter template ships with.
|
|
21
|
+
status: review-only
|
|
22
|
+
review:
|
|
23
|
+
applicability: Components use Tailwind indigo classes as the accent colour.
|
|
24
|
+
exceptions: A brand that is indigo, or a project whose theme already standardises on indigo.
|
|
25
|
+
evidence: The brand colour in the theme or design tokens, and how many components use indigo.
|
|
26
|
+
verification: Confirm indigo is the brand choice, or replace it with the theme's primary token.
|
|
27
|
+
sourceHash: cdd85836ef30c0827d41e0a07ed549a3b5a3d120b6f1aa39cf259aff87a8d0e8
|
|
28
|
+
handWritten: [mechanical, fix, review, scope]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Hand-cut from mblode/agent-skills skills/ui-animation/references/performance-deep-dive.md.
|
|
2
|
+
id: motion-will-change-misuse
|
|
3
|
+
title: will-change promotes a property the compositor cannot animate
|
|
4
|
+
categoryId: motion-restraint
|
|
5
|
+
source:
|
|
6
|
+
{
|
|
7
|
+
repo: mblode/agent-skills,
|
|
8
|
+
path: skills/ui-animation/references/performance-deep-dive.md,
|
|
9
|
+
line: 161,
|
|
10
|
+
}
|
|
11
|
+
scope:
|
|
12
|
+
include: ["**/*.css", "**/*.scss", "**/*.tsx", "**/*.jsx"]
|
|
13
|
+
unit: [source]
|
|
14
|
+
mechanical:
|
|
15
|
+
regex: "will-change\\s*:\\s*[\"'`]?(?!\\s*(?:transform|opacity|auto)\\s*[\"'`]?\\s*[;},!])[a-z-]+|\\bwill-change-(?:scroll|contents|\\[(?!transform|opacity)[^\\]]+\\])"
|
|
16
|
+
flags: giu
|
|
17
|
+
severity: minor
|
|
18
|
+
fix:
|
|
19
|
+
hint: >-
|
|
20
|
+
Promote only transform or opacity, and only while the motion runs. Each promoted layer costs compositor memory.
|
|
21
|
+
status: review-only
|
|
22
|
+
review:
|
|
23
|
+
applicability: A stylesheet or class list sets will-change to a property other than transform or opacity.
|
|
24
|
+
exceptions: Measured scroll-performance fixes with a comment explaining the choice.
|
|
25
|
+
evidence: The declaration, the element it applies to, and whether it is toggled around the animation.
|
|
26
|
+
verification: Restrict will-change to transform or opacity and set it only during the animation.
|
|
27
|
+
sourceHash: f3f43c733bac58c4e64f13c769f7a360c39c0d446c886f79d929e76ae8b5fdfc
|
|
28
|
+
handWritten: [mechanical, fix, review, scope]
|
|
@@ -29,4 +29,4 @@ review:
|
|
|
29
29
|
exceptions: JSX nesting alone does not prove simultaneous visibility; mutually exclusive steps and nonmodal surfaces are exceptions.
|
|
30
30
|
evidence: Both open-state transitions, modal primitive implementations, and focus and Escape behavior.
|
|
31
31
|
verification: Open the second step using the keyboard; confirm one modal owns focus and Escape closes the intended surface.
|
|
32
|
-
sourceHash:
|
|
32
|
+
sourceHash: 9aab069ba1b93ab405a9741cd6d1e026eb08442ff881587b4f84a612653a2fbb
|
|
@@ -27,4 +27,4 @@ review:
|
|
|
27
27
|
exceptions: Dynamically loaded options, dependent choices, or a documented platform constraint can require a select.
|
|
28
28
|
evidence: The complete option source, dynamic branches, and the task requiring comparison.
|
|
29
29
|
verification: Confirm all choices remain available and selection, keyboard input, and form submission work.
|
|
30
|
-
sourceHash:
|
|
30
|
+
sourceHash: 9aab069ba1b93ab405a9741cd6d1e026eb08442ff881587b4f84a612653a2fbb
|