@harness-engineering/cli 1.6.2 → 1.8.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 (180) hide show
  1. package/dist/agents/personas/documentation-maintainer.yaml +3 -1
  2. package/dist/agents/personas/performance-guardian.yaml +23 -0
  3. package/dist/agents/personas/planner.yaml +27 -0
  4. package/dist/agents/personas/verifier.yaml +30 -0
  5. package/dist/agents/skills/claude-code/align-documentation/SKILL.md +13 -0
  6. package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +25 -1
  7. package/dist/agents/skills/claude-code/cleanup-dead-code/skill.yaml +5 -2
  8. package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +12 -0
  9. package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +67 -1
  10. package/dist/agents/skills/claude-code/enforce-architecture/skill.yaml +5 -2
  11. package/dist/agents/skills/claude-code/harness-accessibility/SKILL.md +281 -0
  12. package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +51 -0
  13. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +119 -72
  14. package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +4 -2
  15. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +76 -4
  16. package/dist/agents/skills/claude-code/harness-brainstorming/skill.yaml +2 -0
  17. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +487 -234
  18. package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +15 -2
  19. package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +226 -0
  20. package/dist/agents/skills/claude-code/harness-codebase-cleanup/skill.yaml +64 -0
  21. package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +35 -6
  22. package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +1 -1
  23. package/dist/agents/skills/claude-code/harness-design/SKILL.md +265 -0
  24. package/dist/agents/skills/claude-code/harness-design/skill.yaml +53 -0
  25. package/dist/agents/skills/claude-code/harness-design-mobile/SKILL.md +336 -0
  26. package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +49 -0
  27. package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +282 -0
  28. package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +50 -0
  29. package/dist/agents/skills/claude-code/harness-design-web/SKILL.md +360 -0
  30. package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +52 -0
  31. package/dist/agents/skills/claude-code/harness-docs-pipeline/SKILL.md +460 -0
  32. package/dist/agents/skills/claude-code/harness-docs-pipeline/skill.yaml +69 -0
  33. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +73 -8
  34. package/dist/agents/skills/claude-code/harness-execution/skill.yaml +1 -0
  35. package/dist/agents/skills/claude-code/harness-hotspot-detector/SKILL.md +32 -6
  36. package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +1 -1
  37. package/dist/agents/skills/claude-code/harness-i18n/SKILL.md +484 -0
  38. package/dist/agents/skills/claude-code/harness-i18n/skill.yaml +54 -0
  39. package/dist/agents/skills/claude-code/harness-i18n-process/SKILL.md +388 -0
  40. package/dist/agents/skills/claude-code/harness-i18n-process/skill.yaml +43 -0
  41. package/dist/agents/skills/claude-code/harness-i18n-workflow/SKILL.md +512 -0
  42. package/dist/agents/skills/claude-code/harness-i18n-workflow/skill.yaml +53 -0
  43. package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +51 -6
  44. package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +35 -1
  45. package/dist/agents/skills/claude-code/harness-knowledge-mapper/SKILL.md +46 -5
  46. package/dist/agents/skills/claude-code/harness-knowledge-mapper/skill.yaml +1 -1
  47. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +19 -1
  48. package/dist/agents/skills/claude-code/harness-perf/SKILL.md +37 -8
  49. package/dist/agents/skills/claude-code/harness-perf/skill.yaml +3 -0
  50. package/dist/agents/skills/claude-code/harness-perf-tdd/SKILL.md +17 -4
  51. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +57 -3
  52. package/dist/agents/skills/claude-code/harness-planning/skill.yaml +2 -0
  53. package/dist/agents/skills/claude-code/harness-release-readiness/SKILL.md +29 -9
  54. package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +562 -0
  55. package/dist/agents/skills/claude-code/harness-roadmap/skill.yaml +43 -0
  56. package/dist/agents/skills/claude-code/harness-security-review/SKILL.md +36 -2
  57. package/dist/agents/skills/claude-code/harness-security-review/skill.yaml +8 -6
  58. package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +1 -1
  59. package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +1267 -0
  60. package/dist/agents/skills/claude-code/harness-soundness-review/skill.yaml +48 -0
  61. package/dist/agents/skills/claude-code/harness-test-advisor/SKILL.md +35 -6
  62. package/dist/agents/skills/claude-code/harness-verification/SKILL.md +66 -0
  63. package/dist/agents/skills/claude-code/harness-verification/skill.yaml +1 -0
  64. package/dist/agents/skills/claude-code/harness-verify/SKILL.md +37 -0
  65. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +15 -1
  66. package/dist/agents/skills/claude-code/validate-context-engineering/SKILL.md +12 -0
  67. package/dist/agents/skills/gemini-cli/harness-accessibility/SKILL.md +281 -0
  68. package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +51 -0
  69. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +119 -72
  70. package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +4 -2
  71. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +226 -0
  72. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/skill.yaml +64 -0
  73. package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +35 -6
  74. package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +1 -1
  75. package/dist/agents/skills/gemini-cli/harness-design/SKILL.md +265 -0
  76. package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +53 -0
  77. package/dist/agents/skills/gemini-cli/harness-design-mobile/SKILL.md +336 -0
  78. package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +49 -0
  79. package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +282 -0
  80. package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +50 -0
  81. package/dist/agents/skills/gemini-cli/harness-design-web/SKILL.md +360 -0
  82. package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +52 -0
  83. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/SKILL.md +460 -0
  84. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/skill.yaml +69 -0
  85. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/SKILL.md +32 -6
  86. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +1 -1
  87. package/dist/agents/skills/gemini-cli/harness-i18n/SKILL.md +484 -0
  88. package/dist/agents/skills/gemini-cli/harness-i18n/skill.yaml +54 -0
  89. package/dist/agents/skills/gemini-cli/harness-i18n-process/SKILL.md +388 -0
  90. package/dist/agents/skills/gemini-cli/harness-i18n-process/skill.yaml +43 -0
  91. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/SKILL.md +512 -0
  92. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/skill.yaml +53 -0
  93. package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +51 -6
  94. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/SKILL.md +46 -5
  95. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/skill.yaml +1 -1
  96. package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +37 -8
  97. package/dist/agents/skills/gemini-cli/harness-perf/skill.yaml +3 -0
  98. package/dist/agents/skills/gemini-cli/harness-perf-tdd/SKILL.md +17 -4
  99. package/dist/agents/skills/gemini-cli/harness-release-readiness/SKILL.md +29 -9
  100. package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +562 -0
  101. package/dist/agents/skills/gemini-cli/harness-roadmap/skill.yaml +43 -0
  102. package/dist/agents/skills/gemini-cli/harness-security-review/skill.yaml +8 -6
  103. package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +1 -1
  104. package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +1267 -0
  105. package/dist/agents/skills/gemini-cli/harness-soundness-review/skill.yaml +48 -0
  106. package/dist/agents/skills/gemini-cli/harness-test-advisor/SKILL.md +35 -6
  107. package/dist/agents/skills/node_modules/.bin/vitest +2 -2
  108. package/dist/agents/skills/shared/design-knowledge/anti-patterns/color.yaml +106 -0
  109. package/dist/agents/skills/shared/design-knowledge/anti-patterns/layout.yaml +109 -0
  110. package/dist/agents/skills/shared/design-knowledge/anti-patterns/motion.yaml +109 -0
  111. package/dist/agents/skills/shared/design-knowledge/anti-patterns/typography.yaml +112 -0
  112. package/dist/agents/skills/shared/design-knowledge/industries/creative.yaml +80 -0
  113. package/dist/agents/skills/shared/design-knowledge/industries/ecommerce.yaml +80 -0
  114. package/dist/agents/skills/shared/design-knowledge/industries/emerging-tech.yaml +83 -0
  115. package/dist/agents/skills/shared/design-knowledge/industries/fintech.yaml +80 -0
  116. package/dist/agents/skills/shared/design-knowledge/industries/healthcare.yaml +80 -0
  117. package/dist/agents/skills/shared/design-knowledge/industries/lifestyle.yaml +80 -0
  118. package/dist/agents/skills/shared/design-knowledge/industries/saas.yaml +80 -0
  119. package/dist/agents/skills/shared/design-knowledge/industries/services.yaml +80 -0
  120. package/dist/agents/skills/shared/design-knowledge/palettes/curated.yaml +234 -0
  121. package/dist/agents/skills/shared/design-knowledge/platform-rules/android.yaml +125 -0
  122. package/dist/agents/skills/shared/design-knowledge/platform-rules/flutter.yaml +144 -0
  123. package/dist/agents/skills/shared/design-knowledge/platform-rules/ios.yaml +106 -0
  124. package/dist/agents/skills/shared/design-knowledge/platform-rules/web.yaml +102 -0
  125. package/dist/agents/skills/shared/design-knowledge/typography/pairings.yaml +274 -0
  126. package/dist/agents/skills/shared/i18n-knowledge/accessibility/intersection.yaml +142 -0
  127. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/encoding.yaml +67 -0
  128. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/formatting.yaml +106 -0
  129. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/layout.yaml +80 -0
  130. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/pluralization.yaml +80 -0
  131. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/string-handling.yaml +106 -0
  132. package/dist/agents/skills/shared/i18n-knowledge/frameworks/android-resources.yaml +47 -0
  133. package/dist/agents/skills/shared/i18n-knowledge/frameworks/apple-strings.yaml +47 -0
  134. package/dist/agents/skills/shared/i18n-knowledge/frameworks/backend-patterns.yaml +50 -0
  135. package/dist/agents/skills/shared/i18n-knowledge/frameworks/flutter-intl.yaml +47 -0
  136. package/dist/agents/skills/shared/i18n-knowledge/frameworks/i18next.yaml +47 -0
  137. package/dist/agents/skills/shared/i18n-knowledge/frameworks/react-intl.yaml +47 -0
  138. package/dist/agents/skills/shared/i18n-knowledge/frameworks/vue-i18n.yaml +47 -0
  139. package/dist/agents/skills/shared/i18n-knowledge/industries/ecommerce.yaml +66 -0
  140. package/dist/agents/skills/shared/i18n-knowledge/industries/fintech.yaml +66 -0
  141. package/dist/agents/skills/shared/i18n-knowledge/industries/gaming.yaml +69 -0
  142. package/dist/agents/skills/shared/i18n-knowledge/industries/healthcare.yaml +66 -0
  143. package/dist/agents/skills/shared/i18n-knowledge/industries/legal.yaml +66 -0
  144. package/dist/agents/skills/shared/i18n-knowledge/locales/ar.yaml +41 -0
  145. package/dist/agents/skills/shared/i18n-knowledge/locales/de.yaml +35 -0
  146. package/dist/agents/skills/shared/i18n-knowledge/locales/en.yaml +32 -0
  147. package/dist/agents/skills/shared/i18n-knowledge/locales/es.yaml +35 -0
  148. package/dist/agents/skills/shared/i18n-knowledge/locales/fi.yaml +35 -0
  149. package/dist/agents/skills/shared/i18n-knowledge/locales/fr.yaml +35 -0
  150. package/dist/agents/skills/shared/i18n-knowledge/locales/he.yaml +41 -0
  151. package/dist/agents/skills/shared/i18n-knowledge/locales/hi.yaml +35 -0
  152. package/dist/agents/skills/shared/i18n-knowledge/locales/it.yaml +32 -0
  153. package/dist/agents/skills/shared/i18n-knowledge/locales/ja.yaml +38 -0
  154. package/dist/agents/skills/shared/i18n-knowledge/locales/ko.yaml +38 -0
  155. package/dist/agents/skills/shared/i18n-knowledge/locales/nl.yaml +32 -0
  156. package/dist/agents/skills/shared/i18n-knowledge/locales/pl.yaml +35 -0
  157. package/dist/agents/skills/shared/i18n-knowledge/locales/pt.yaml +32 -0
  158. package/dist/agents/skills/shared/i18n-knowledge/locales/ru.yaml +35 -0
  159. package/dist/agents/skills/shared/i18n-knowledge/locales/sv.yaml +32 -0
  160. package/dist/agents/skills/shared/i18n-knowledge/locales/th.yaml +35 -0
  161. package/dist/agents/skills/shared/i18n-knowledge/locales/tr.yaml +35 -0
  162. package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hans.yaml +38 -0
  163. package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hant.yaml +35 -0
  164. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/i18next-mcp.yaml +56 -0
  165. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lingo-dev.yaml +56 -0
  166. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lokalise.yaml +60 -0
  167. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/tolgee.yaml +60 -0
  168. package/dist/agents/skills/shared/i18n-knowledge/testing/locale-testing.yaml +107 -0
  169. package/dist/agents/skills/shared/i18n-knowledge/testing/pseudo-localization.yaml +86 -0
  170. package/dist/bin/harness.js +64 -4
  171. package/dist/{chunk-UDWGSL3T.js → chunk-3JWCBVUZ.js} +3 -3
  172. package/dist/{chunk-IUFFBBYV.js → chunk-LNI4T7R6.js} +179 -61
  173. package/dist/{chunk-USEYPS7F.js → chunk-SJECMKSS.js} +2250 -40
  174. package/dist/{dist-4MYPT3OE.js → dist-BDO5GFEM.js} +295 -14
  175. package/dist/{dist-RBZXXJHG.js → dist-NT3GXHQZ.js} +95 -1
  176. package/dist/index.d.ts +266 -7
  177. package/dist/index.js +7 -3
  178. package/dist/validate-cross-check-2OPGCGGU.js +7 -0
  179. package/package.json +7 -7
  180. package/dist/validate-cross-check-CPEPNLOD.js +0 -7
@@ -0,0 +1,48 @@
1
+ name: harness-soundness-review
2
+ version: "1.0.0"
3
+ description: Deep soundness analysis of specs and plans with auto-fix and convergence loop
4
+ cognitive_mode: meticulous-verifier
5
+ triggers:
6
+ - manual
7
+ platforms:
8
+ - claude-code
9
+ - gemini-cli
10
+ tools:
11
+ - Bash
12
+ - Read
13
+ - Write
14
+ - Edit
15
+ - Glob
16
+ - Grep
17
+ cli:
18
+ command: harness skill run harness-soundness-review
19
+ args:
20
+ - name: path
21
+ description: Project root path
22
+ required: false
23
+ - name: mode
24
+ description: Review mode — "spec" for spec soundness or "plan" for plan soundness
25
+ required: true
26
+ mcp:
27
+ tool: run_skill
28
+ input:
29
+ skill: harness-soundness-review
30
+ path: string
31
+ type: rigid
32
+ phases:
33
+ - name: check
34
+ description: Run all checks for the current mode and classify findings
35
+ required: true
36
+ - name: fix
37
+ description: Auto-fix inferrable issues and log changes
38
+ required: true
39
+ - name: converge
40
+ description: Re-run checks, compare issue counts, loop or stop
41
+ required: true
42
+ - name: surface
43
+ description: Present remaining issues to user for resolution
44
+ required: true
45
+ state:
46
+ persistent: false
47
+ files: []
48
+ depends_on: []
@@ -13,8 +13,23 @@
13
13
 
14
14
  ## Prerequisites
15
15
 
16
- A knowledge graph must exist at `.harness/graph/`. Run `harness scan` if no graph is available.
17
- If the graph exists but code has changed since the last scan, re-run `harness scan` first — stale graph data leads to inaccurate results.
16
+ A knowledge graph at `.harness/graph/` enables full analysis. If no graph exists,
17
+ the skill uses static analysis fallbacks (see Graph Availability section).
18
+ Run `harness scan` to enable graph-enhanced analysis.
19
+
20
+ ### Graph Availability
21
+
22
+ Before starting, check if `.harness/graph/graph.json` exists.
23
+
24
+ **If graph exists:** Check staleness — compare `.harness/graph/metadata.json`
25
+ scanTimestamp against `git log -1 --format=%ct` (latest commit timestamp).
26
+ If graph is more than 10 commits behind (`git log --oneline <scanTimestamp>..HEAD | wc -l`),
27
+ run `harness scan` to refresh before proceeding. (Staleness sensitivity: **Medium**)
28
+
29
+ **If graph exists and is fresh (or refreshed):** Use graph tools as primary strategy.
30
+
31
+ **If no graph exists:** Output "Running without graph (run `harness scan` to
32
+ enable full analysis)" and use fallback strategies for all subsequent steps.
18
33
 
19
34
  ## Process
20
35
 
@@ -43,6 +58,20 @@ For each changed file, use graph traversal to find test files:
43
58
 
44
59
  3. **Co-change tests**: Check `co_changes_with` edges for test files that historically change alongside the modified files.
45
60
 
61
+ #### Fallback (without graph)
62
+
63
+ When no graph is available, use naming conventions, import parsing, and git history:
64
+
65
+ 1. **Tier 1 — Filename convention matching**: For each changed file `foo.ts`, search for:
66
+ - `foo.test.ts`, `foo.spec.ts` (same directory)
67
+ - `__tests__/foo.ts`, `__tests__/foo.test.ts`
68
+ - Test files in a parallel `tests/` directory mirroring the source path
69
+ 2. **Tier 2 — Import-linked tests**: Parse test files' import statements (grep for `import.*from` in `*.test.*` and `*.spec.*` files). If a test file imports the changed file, it belongs in Tier 2 (if not already in Tier 1).
70
+ 3. **Tier 3 — Co-change correlated tests**: Use `git log --format="%H" --name-only` to find test files that frequently change in the same commit as the target file. Files that co-change in >2 commits are co-change correlated.
71
+ 4. **Rank**: Tier 1 = direct filename match, Tier 2 = import-linked tests, Tier 3 = co-change correlated tests. Output the same tiered format as the graph version.
72
+
73
+ > Fallback completeness: ~80% — naming conventions and imports catch most mappings; misses dynamic imports and indirect coverage.
74
+
46
75
  ### Phase 3: PRIORITIZE — Rank and Generate Commands
47
76
 
48
77
  Organize tests into three tiers:
@@ -85,7 +114,7 @@ npx vitest run tests/services/auth.test.ts tests/types/user.test.ts tests/routes
85
114
 
86
115
  ## Harness Integration
87
116
 
88
- - **`harness scan`** — Must run before this skill to ensure graph is current.
117
+ - **`harness scan`** — Recommended before this skill for full graph-enhanced analysis. If graph is missing, skill uses naming convention and import parsing fallbacks.
89
118
  - **`harness validate`** — Run after acting on findings to verify project health.
90
119
  - **Graph tools** — This skill uses `query_graph`, `get_impact`, and `get_relationships` MCP tools.
91
120
 
@@ -95,7 +124,7 @@ npx vitest run tests/services/auth.test.ts tests/types/user.test.ts tests/routes
95
124
  - Executable run commands generated for quick and full test runs
96
125
  - Coverage gaps flagged for changed files with no test coverage
97
126
  - Report follows the structured output format
98
- - All findings are backed by graph query evidence, not heuristics
127
+ - All findings are backed by graph query evidence (with graph) or systematic static analysis (without graph)
99
128
 
100
129
  ## Examples
101
130
 
@@ -122,8 +151,8 @@ Output:
122
151
 
123
152
  ## Gates
124
153
 
125
- - **No advice without graph.** If no graph exists, fall back to: "Run all tests in the same directory as changed files."
126
- - **Always include Tier 1.** Direct test coverage is non-negotiable — always recommend running these.
154
+ - **Graph preferred, fallback available.** If no graph exists, use naming conventions, import parsing, and git co-change analysis to identify relevant tests. Do not stop — produce the best test selection possible.
155
+ - **Always include Tier 1.** Direct test coverage is non-negotiable — always recommend running these (whether found via graph or naming conventions).
127
156
 
128
157
  ## Escalation
129
158
 
@@ -6,9 +6,9 @@ case `uname` in
6
6
  esac
7
7
 
8
8
  if [ -z "$NODE_PATH" ]; then
9
- export NODE_PATH="/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_@types+node@22.19.15_yaml@2.8.2/node_modules/vitest/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_@types+node@22.19.15_yaml@2.8.2/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/node_modules"
9
+ export NODE_PATH="/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_yaml@2.8.2/node_modules/vitest/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_yaml@2.8.2/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/node_modules"
10
10
  else
11
- export NODE_PATH="/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_@types+node@22.19.15_yaml@2.8.2/node_modules/vitest/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_@types+node@22.19.15_yaml@2.8.2/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/node_modules:$NODE_PATH"
11
+ export NODE_PATH="/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_yaml@2.8.2/node_modules/vitest/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/vitest@4.0.18_yaml@2.8.2/node_modules:/home/runner/work/harness-engineering/harness-engineering/node_modules/.pnpm/node_modules:$NODE_PATH"
12
12
  fi
13
13
  if [ -x "$basedir/node" ]; then
14
14
  exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
@@ -0,0 +1,106 @@
1
+ description: "Color anti-patterns — common mistakes that harm accessibility, consistency, and brand integrity"
2
+
3
+ patterns:
4
+ - name: "Hardcoded color values instead of tokens"
5
+ severity: warning
6
+ scope: all
7
+ detect:
8
+ method: "Grep for hex (#xxx, #xxxxxx), rgb(), rgba(), hsl(), hsla() values in component code that are not defined in tokens.json"
9
+ exclude: ["test files", "fixture files", "storybook stories"]
10
+ reason: "Hardcoded colors bypass the design token system, creating inconsistency and making global palette changes impossible without find-and-replace."
11
+ instead: "Reference design tokens: use CSS custom properties (var(--color-primary)), Tailwind classes (text-primary), or platform token bindings."
12
+ strictness:
13
+ permissive: info
14
+ standard: warn
15
+ strict: error
16
+
17
+ - name: "Insufficient contrast ratio (WCAG AA)"
18
+ severity: error
19
+ scope: all
20
+ detect:
21
+ method: "Calculate contrast ratio between foreground text color and background color"
22
+ threshold: "< 4.5:1 for normal text, < 3:1 for large text (18px+ or 14px+ bold)"
23
+ reason: "Low contrast text is unreadable for users with low vision, color blindness, or in bright ambient light. WCAG 2.1 Level AA requires 4.5:1 minimum."
24
+ instead: "Use pre-validated contrast pairs from the palette. Check ratios with a contrast checker before committing."
25
+ strictness:
26
+ permissive: info
27
+ standard: warn
28
+ strict: error
29
+
30
+ - name: "Color as the only differentiator"
31
+ severity: error
32
+ scope: all
33
+ detect:
34
+ method: "Check for status indicators, form validation, or interactive states that rely solely on color change"
35
+ context: "Success/error/warning states, required field indicators, active/inactive toggles"
36
+ reason: "Approximately 8% of men and 0.5% of women have color vision deficiency. Color-only indicators are invisible to them."
37
+ instead: "Combine color with a secondary indicator: icons, text labels, patterns, or border changes. Error states should include both red color AND an error icon/message."
38
+ strictness:
39
+ permissive: info
40
+ standard: warn
41
+ strict: error
42
+
43
+ - name: "Too many colors in a single view"
44
+ severity: warning
45
+ scope: all
46
+ detect:
47
+ method: "Count distinct non-neutral hues in a single screen or component"
48
+ threshold: "> 5 distinct hues (excluding neutrals/grays)"
49
+ reason: "Excessive color variety creates visual noise, weakens brand identity, and makes it harder for users to learn the color semantics of the interface."
50
+ instead: "Limit to 1-2 brand colors + 1 accent + semantic colors (success/warning/error/info). Use neutrals for everything else."
51
+ strictness:
52
+ permissive: info
53
+ standard: warn
54
+ strict: warn
55
+
56
+ - name: "Pure black (#000000) on pure white (#ffffff)"
57
+ severity: info
58
+ scope: web
59
+ detect:
60
+ css_properties: ["color", "background-color"]
61
+ values: ["#000000 on #ffffff", "#000 on #fff"]
62
+ reason: "Maximum contrast (21:1) can cause eye strain during extended reading, especially on bright displays. High contrast also creates harsh vibration at text edges."
63
+ instead: "Use near-black (e.g., #0f172a, #18181b) on near-white (e.g., #fafafa, #f8fafc) for a comfortable reading experience while maintaining excellent contrast ratios."
64
+ strictness:
65
+ permissive: info
66
+ standard: info
67
+ strict: warn
68
+
69
+ - name: "Opacity/alpha for semantic colors"
70
+ severity: warning
71
+ scope: all
72
+ detect:
73
+ method: "Check for rgba() or opacity applied to semantic colors (success, error, warning)"
74
+ context: "Background fills behind status text, badge backgrounds"
75
+ reason: "Transparent semantic colors shift hue depending on what's behind them. A red error badge over a blue card becomes purple, confusing the semantic meaning."
76
+ instead: "Use solid, pre-defined tint colors for semantic backgrounds (e.g., red-50 for error background, green-50 for success) instead of applying opacity to the base color."
77
+ strictness:
78
+ permissive: info
79
+ standard: warn
80
+ strict: warn
81
+
82
+ - name: "Brand colors used for destructive actions"
83
+ severity: warning
84
+ scope: all
85
+ detect:
86
+ method: "Check if primary brand color is applied to delete, remove, or destructive action buttons"
87
+ reason: "Using the brand color for destructive actions creates cognitive dissonance — the color that means 'go/primary' also means 'danger'. Users learn to hesitate on all primary-colored actions."
88
+ instead: "Reserve red (or a distinct danger color) for destructive actions. Primary brand color is for constructive actions only."
89
+ strictness:
90
+ permissive: info
91
+ standard: warn
92
+ strict: warn
93
+
94
+ - name: "Gradient text without fallback"
95
+ severity: info
96
+ scope: web
97
+ detect:
98
+ css_properties: ["background-clip", "-webkit-background-clip"]
99
+ values: ["text"]
100
+ absent: ["color fallback"]
101
+ reason: "Gradient text using background-clip: text has inconsistent browser support and can disappear entirely if the gradient fails to render."
102
+ instead: "Always set a solid color fallback before the gradient declaration. Test in all target browsers."
103
+ strictness:
104
+ permissive: info
105
+ standard: info
106
+ strict: warn
@@ -0,0 +1,109 @@
1
+ description: "Layout anti-patterns — common mistakes in spacing, composition, and responsive design"
2
+
3
+ patterns:
4
+ - name: "Inconsistent spacing values"
5
+ severity: warning
6
+ scope: all
7
+ detect:
8
+ method: "Check for margin/padding values that don't align with the spacing scale defined in tokens.json"
9
+ context: "Custom pixel values like 13px, 7px, 22px that don't match the 4px/8px grid or token scale"
10
+ reason: "Arbitrary spacing values create visual noise. Elements that are 'almost aligned' feel more wrong than elements that are clearly different."
11
+ instead: "Use spacing tokens from the design system scale (e.g., 4, 8, 12, 16, 24, 32, 48, 64). Every spacing value should reference a token."
12
+ strictness:
13
+ permissive: info
14
+ standard: warn
15
+ strict: warn
16
+
17
+ - name: "Content wider than 80ch for reading"
18
+ severity: warning
19
+ scope: web
20
+ detect:
21
+ method: "Check max-width of text content containers"
22
+ threshold: "> 80ch or > 720px without max-width constraint"
23
+ context: "Applies to prose/article content, not dashboards or data tables"
24
+ reason: "Lines longer than 65-80 characters are hard to track from the end of one line to the beginning of the next. Reading speed and comprehension drop significantly."
25
+ instead: "Set max-width: 65ch to 75ch for prose content. Use wider layouts only for data-dense views like dashboards and tables."
26
+ strictness:
27
+ permissive: info
28
+ standard: warn
29
+ strict: warn
30
+
31
+ - name: "Fixed pixel widths on containers"
32
+ severity: warning
33
+ scope: web
34
+ detect:
35
+ css_properties: ["width"]
36
+ values: ["px values on layout containers"]
37
+ exclude: ["max-width", "min-width", "icons", "avatars"]
38
+ reason: "Fixed-width containers break on screen sizes they weren't designed for. A 1200px container is unusable on a 1024px laptop."
39
+ instead: "Use relative units (%, rem, ch) or max-width constraints. Let containers be fluid within min/max bounds."
40
+ strictness:
41
+ permissive: info
42
+ standard: warn
43
+ strict: warn
44
+
45
+ - name: "Missing touch targets on mobile"
46
+ severity: error
47
+ scope: mobile
48
+ detect:
49
+ method: "Check interactive element dimensions"
50
+ threshold: "< 44x44px (iOS) or < 48x48dp (Android)"
51
+ context: "Buttons, links, toggles, checkboxes, and other tappable elements"
52
+ reason: "Small touch targets cause mis-taps, frustration, and accessibility failures. WCAG 2.5.8 requires minimum 24x24 CSS pixels, but platform guidelines recommend 44-48px."
53
+ instead: "Ensure all interactive elements have a minimum tappable area of 44x44px (iOS) or 48x48dp (Android). Use padding to increase hit area without changing visual size."
54
+ strictness:
55
+ permissive: info
56
+ standard: warn
57
+ strict: error
58
+
59
+ - name: "Horizontal scrolling on mobile"
60
+ severity: error
61
+ scope: all
62
+ detect:
63
+ method: "Check for content overflow causing horizontal scroll on viewports < 375px"
64
+ context: "Excludes intentional horizontal scroll components like carousels and code blocks"
65
+ reason: "Unintended horizontal scroll breaks the vertical reading flow and confuses users. It often indicates a layout bug."
66
+ instead: "Use overflow-x: hidden on the body, ensure all images have max-width: 100%, and test layouts at 320px minimum viewport width."
67
+ strictness:
68
+ permissive: info
69
+ standard: warn
70
+ strict: error
71
+
72
+ - name: "Z-index escalation"
73
+ severity: warning
74
+ scope: web
75
+ detect:
76
+ method: "Check for z-index values"
77
+ threshold: "> 100 or more than 10 distinct z-index values in the codebase"
78
+ reason: "Z-index wars create unpredictable stacking. When values escalate to 9999, every new overlay needs 99999, and the system becomes unmaintainable."
79
+ instead: "Define a z-index scale in tokens (e.g., base: 0, dropdown: 10, sticky: 20, modal: 30, toast: 40, tooltip: 50). Never use arbitrary values."
80
+ strictness:
81
+ permissive: info
82
+ standard: warn
83
+ strict: warn
84
+
85
+ - name: "Nested scroll containers"
86
+ severity: warning
87
+ scope: all
88
+ detect:
89
+ method: "Check for scrollable elements inside other scrollable elements"
90
+ context: "Especially problematic when both scroll in the same direction"
91
+ reason: "Nested scrolling creates confusing interaction — users don't know which container will scroll when they swipe. Trackpad momentum makes it worse."
92
+ instead: "Flatten the layout so only one element scrolls at a time. If nested scroll is unavoidable, ensure they scroll in different directions (e.g., vertical page + horizontal carousel)."
93
+ strictness:
94
+ permissive: info
95
+ standard: warn
96
+ strict: warn
97
+
98
+ - name: "Magic number breakpoints"
99
+ severity: info
100
+ scope: web
101
+ detect:
102
+ method: "Check for media query breakpoints that don't match standard device widths or design system breakpoints"
103
+ values: ["arbitrary values like 743px, 1023px, 867px"]
104
+ reason: "Non-standard breakpoints are hard to reason about and don't correspond to real device classes. They suggest the layout was 'fixed' at a specific size rather than designed responsively."
105
+ instead: "Use standard breakpoints (640, 768, 1024, 1280, 1536) or define custom breakpoints in the design system tokens and reuse them consistently."
106
+ strictness:
107
+ permissive: info
108
+ standard: info
109
+ strict: warn
@@ -0,0 +1,109 @@
1
+ description: "Motion and animation anti-patterns — common mistakes in transitions, animations, and interactive feedback"
2
+
3
+ patterns:
4
+ - name: "Animation without prefers-reduced-motion"
5
+ severity: error
6
+ scope: all
7
+ detect:
8
+ method: "Check for CSS animations or transitions without a @media (prefers-reduced-motion: reduce) override"
9
+ context: "Applies to all non-essential animations. Essential animations (progress indicators, loading states) should reduce, not remove."
10
+ reason: "Motion can trigger vestibular disorders, migraines, and seizures. WCAG 2.3.3 requires respecting user motion preferences."
11
+ instead: "Wrap animations in a motion-safe media query or provide a prefers-reduced-motion: reduce override that disables or minimizes the animation."
12
+ strictness:
13
+ permissive: info
14
+ standard: warn
15
+ strict: error
16
+
17
+ - name: "Animations longer than 500ms"
18
+ severity: warning
19
+ scope: all
20
+ detect:
21
+ css_properties: ["animation-duration", "transition-duration"]
22
+ threshold: "> 500ms"
23
+ exclude: ["page transitions", "skeleton loaders", "progress bars"]
24
+ reason: "Long animations feel sluggish and block user interaction. Users perceive delays over 400ms as 'slow'. Interface animations should feel instant and responsive."
25
+ instead: "Keep UI transitions between 150-300ms. Use 200ms as the default. Reserve longer durations (300-500ms) for complex multi-element orchestrations."
26
+ strictness:
27
+ permissive: info
28
+ standard: warn
29
+ strict: warn
30
+
31
+ - name: "Linear easing on UI transitions"
32
+ severity: info
33
+ scope: all
34
+ detect:
35
+ css_properties: ["transition-timing-function", "animation-timing-function"]
36
+ values: ["linear"]
37
+ context: "Flagged for UI element transitions, not progress bars or loading animations"
38
+ reason: "Linear motion feels mechanical and unnatural. Real objects accelerate and decelerate — interfaces should too."
39
+ instead: "Use ease-out for entrances (elements arriving), ease-in for exits (elements leaving), and ease-in-out for state changes. Default: cubic-bezier(0.4, 0, 0.2, 1)."
40
+ strictness:
41
+ permissive: info
42
+ standard: info
43
+ strict: warn
44
+
45
+ - name: "Auto-playing animation loops"
46
+ severity: warning
47
+ scope: all
48
+ detect:
49
+ css_properties: ["animation-iteration-count"]
50
+ values: ["infinite"]
51
+ context: "Excludes loading spinners and progress indicators that are temporary"
52
+ reason: "Infinite animation loops are distracting, increase CPU/GPU usage, and can trigger motion sensitivity issues. They compete with content for attention."
53
+ instead: "Play animations once on entrance, or limit to 3 iterations. If continuous animation is needed, provide a pause control and respect prefers-reduced-motion."
54
+ strictness:
55
+ permissive: info
56
+ standard: warn
57
+ strict: error
58
+
59
+ - name: "Scroll-jacking"
60
+ severity: error
61
+ scope: web
62
+ detect:
63
+ method: "Check for JavaScript that overrides native scroll behavior (custom scroll speed, snap-to-section, parallax scroll hijacking)"
64
+ exclude: ["scroll-snap-type CSS (native)", "smooth-scroll for anchor links"]
65
+ reason: "Overriding native scroll breaks user expectations, disables accessibility features (keyboard scroll, screen reader navigation), and creates motion sickness. It is the single most complained-about UX pattern."
66
+ instead: "Use native CSS scroll-snap for section snapping. For parallax, use CSS transform with will-change, not scroll event listeners. Never change scroll speed or direction."
67
+ strictness:
68
+ permissive: warn
69
+ standard: error
70
+ strict: error
71
+
72
+ - name: "Flash or strobe effects"
73
+ severity: error
74
+ scope: all
75
+ detect:
76
+ method: "Check for elements that flash more than 3 times per second"
77
+ threshold: "> 3 flashes per second"
78
+ reason: "Flashing content can cause seizures in people with photosensitive epilepsy. WCAG 2.3.1 requires no more than 3 flashes per second."
79
+ instead: "Avoid flashing entirely. If attention is needed, use a subtle pulse (opacity 0.8-1.0) at no more than 2 cycles per second."
80
+ strictness:
81
+ permissive: warn
82
+ standard: error
83
+ strict: error
84
+
85
+ - name: "Entrance animations on above-the-fold content"
86
+ severity: warning
87
+ scope: web
88
+ detect:
89
+ method: "Check for fade-in, slide-in, or scale animations on elements visible in the initial viewport"
90
+ context: "Hero sections, navigation, primary CTAs"
91
+ reason: "Animating content that should be immediately visible delays the user's ability to orient and act. It adds perceived load time to an already-loaded page."
92
+ instead: "Show above-the-fold content immediately. Reserve entrance animations for below-the-fold content revealed on scroll (intersection observer pattern)."
93
+ strictness:
94
+ permissive: info
95
+ standard: warn
96
+ strict: warn
97
+
98
+ - name: "Transition on color-scheme change"
99
+ severity: info
100
+ scope: web
101
+ detect:
102
+ method: "Check for transitions applied during dark/light mode toggle that affect all elements"
103
+ context: "Global transition: all on :root or body during theme switch"
104
+ reason: "Transitioning every element's colors during theme change causes a jarring ripple effect and high paint cost. Individual element transitions compound into visual chaos."
105
+ instead: "Apply transition only to background-color and color on specific containers (body, main sections), not globally. Or use instant switch with no transition."
106
+ strictness:
107
+ permissive: info
108
+ standard: info
109
+ strict: info
@@ -0,0 +1,112 @@
1
+ description: "Typography anti-patterns — common mistakes that degrade readability, hierarchy, and brand consistency"
2
+
3
+ patterns:
4
+ - name: "System font in user-facing UI"
5
+ severity: warning
6
+ scope: all
7
+ detect:
8
+ css_properties: ["font-family"]
9
+ values: ["system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif", "serif", "monospace"]
10
+ context: "Only flagged when used as the sole font-family without a branded font preceding it in the stack"
11
+ reason: "System fonts vary across platforms, creating inconsistent brand identity. Users on Windows see Segoe UI while macOS users see SF Pro — the product looks different on every device."
12
+ instead: "Declare a branded font first in the stack with system fonts as fallbacks: `font-family: 'Inter', system-ui, sans-serif`"
13
+ strictness:
14
+ permissive: info
15
+ standard: warn
16
+ strict: warn
17
+
18
+ - name: "More than 3 font families on a single page"
19
+ severity: warning
20
+ scope: all
21
+ detect:
22
+ method: "Count distinct font-family values in rendered page"
23
+ threshold: 3
24
+ reason: "Multiple typefaces create visual noise and weaken typographic hierarchy. Each additional font competes for attention."
25
+ instead: "Use a single font family with weight/size variation for hierarchy, or a deliberate display + body pairing (max 2-3 families including monospace)."
26
+ strictness:
27
+ permissive: info
28
+ standard: warn
29
+ strict: warn
30
+
31
+ - name: "Body text below 14px / 0.875rem"
32
+ severity: error
33
+ scope: all
34
+ detect:
35
+ css_properties: ["font-size"]
36
+ threshold: "< 14px or < 0.875rem"
37
+ context: "Applies to body/paragraph text, not labels or captions"
38
+ reason: "Text below 14px is difficult to read on mobile devices and fails accessibility guidelines for users with low vision."
39
+ instead: "Use 16px (1rem) as the body text baseline. Use 14px only for secondary labels and metadata."
40
+ strictness:
41
+ permissive: info
42
+ standard: warn
43
+ strict: error
44
+
45
+ - name: "Line height below 1.4 for body text"
46
+ severity: warning
47
+ scope: all
48
+ detect:
49
+ css_properties: ["line-height"]
50
+ threshold: "< 1.4"
51
+ context: "Applies to body/paragraph text with font-size >= 14px"
52
+ reason: "Tight line height reduces readability, especially for longer passages. Users with dyslexia or cognitive disabilities are disproportionately affected."
53
+ instead: "Use line-height 1.5-1.6 for body text. Display headings can use tighter spacing (1.1-1.2)."
54
+ strictness:
55
+ permissive: info
56
+ standard: warn
57
+ strict: warn
58
+
59
+ - name: "All-caps body text"
60
+ severity: warning
61
+ scope: all
62
+ detect:
63
+ css_properties: ["text-transform"]
64
+ values: ["uppercase"]
65
+ context: "Flagged when applied to paragraphs or text blocks longer than 50 characters"
66
+ reason: "ALL CAPS reduces reading speed by 10-20% because word shapes become uniform rectangles. Acceptable for short labels and headings, not for body content."
67
+ instead: "Reserve text-transform: uppercase for buttons, labels, and section headers under 30 characters."
68
+ strictness:
69
+ permissive: info
70
+ standard: warn
71
+ strict: warn
72
+
73
+ - name: "Insufficient heading size contrast"
74
+ severity: warning
75
+ scope: all
76
+ detect:
77
+ method: "Compare h1-h6 font sizes — flag when adjacent heading levels differ by less than 20%"
78
+ threshold: "< 1.2x ratio between adjacent levels"
79
+ reason: "When heading sizes are too similar, the visual hierarchy collapses. Users cannot scan the page structure at a glance."
80
+ instead: "Use a consistent type scale ratio (1.2 minor third, 1.25 major third, or 1.333 perfect fourth) to ensure clear size differentiation."
81
+ strictness:
82
+ permissive: info
83
+ standard: warn
84
+ strict: warn
85
+
86
+ - name: "Justified text without hyphenation"
87
+ severity: info
88
+ scope: web
89
+ detect:
90
+ css_properties: ["text-align"]
91
+ values: ["justify"]
92
+ absent: ["hyphens: auto"]
93
+ reason: "Justified text without hyphenation creates uneven word spacing ('rivers of white') that disrupts reading flow, especially in narrow columns."
94
+ instead: "Use text-align: left for most content. If justified text is required, enable CSS hyphens: auto and ensure column width is at least 45 characters."
95
+ strictness:
96
+ permissive: info
97
+ standard: info
98
+ strict: warn
99
+
100
+ - name: "Font weight below 400 for body text"
101
+ severity: warning
102
+ scope: all
103
+ detect:
104
+ css_properties: ["font-weight"]
105
+ threshold: "< 400"
106
+ context: "Applies to body/paragraph text"
107
+ reason: "Light and thin font weights (100-300) reduce legibility on low-resolution screens and for users with vision impairments."
108
+ instead: "Use font-weight 400 (regular) as the minimum for body text. Light weights are acceptable only for large display text (24px+)."
109
+ strictness:
110
+ permissive: info
111
+ standard: warn
112
+ strict: error
@@ -0,0 +1,80 @@
1
+ name: "Creative"
2
+ description: "Expressive, editorial design with bold typography, intentional whitespace, and distinctive visual identity"
3
+
4
+ styles:
5
+ primary: "Editorial layouts with strong typographic hierarchy and intentional use of whitespace as a design element"
6
+ secondary: "Portfolio-driven presentation with immersive imagery, grid-breaking layouts, and art-directed content"
7
+ avoid: ["Generic stock photography that undermines creative credibility", "Template-feeling layouts that contradict the creative message", "Overly uniform grids that feel corporate rather than curated", "Decorative effects without purpose (gratuitous parallax, unnecessary animation)"]
8
+
9
+ palette:
10
+ primary:
11
+ - name: "Charcoal"
12
+ hex: "#1a1a1a"
13
+ usage: "Primary text, editorial headlines, strong contrast backgrounds"
14
+ - name: "Off-Black"
15
+ hex: "#2d2d2d"
16
+ usage: "Secondary surfaces, navigation backgrounds, card overlays"
17
+ - name: "Warm White"
18
+ hex: "#faf8f5"
19
+ usage: "Page backgrounds, content surfaces, breathing space"
20
+ accent:
21
+ - name: "Coral 500"
22
+ hex: "#f97066"
23
+ usage: "Primary accent, CTAs, highlighted portfolio items"
24
+ - name: "Electric Blue"
25
+ hex: "#3b82f6"
26
+ usage: "Links, interactive elements, secondary accent"
27
+ - name: "Saffron"
28
+ hex: "#e8a838"
29
+ usage: "Awards, featured work, premium tier indicators"
30
+ neutral:
31
+ - name: "Stone 800"
32
+ hex: "#292524"
33
+ usage: "Body text, primary readable content"
34
+ - name: "Stone 400"
35
+ hex: "#a8a29e"
36
+ usage: "Captions, metadata, subtle labels"
37
+ - name: "Stone 100"
38
+ hex: "#f5f5f4"
39
+ usage: "Section dividers, subtle background shifts"
40
+ - name: "White"
41
+ hex: "#ffffff"
42
+ usage: "Image framing, overlay text backgrounds, modal surfaces"
43
+ semantic:
44
+ success: "#22c55e"
45
+ warning: "#f59e0b"
46
+ error: "#ef4444"
47
+ info: "#6366f1"
48
+
49
+ typography:
50
+ display:
51
+ families: ["Instrument Serif", "Playfair Display", "Fraunces"]
52
+ weights: [400, 700, 900]
53
+ characteristics: "Expressive serif typefaces with distinctive character for headlines. High contrast between thick and thin strokes creates visual drama at large sizes."
54
+ body:
55
+ families: ["Inter", "Geist", "DM Sans"]
56
+ weights: [400, 500]
57
+ characteristics: "Clean sans-serif paired with serif display creates editorial contrast. Body type should recede, letting display type and imagery lead."
58
+ mono:
59
+ families: ["Geist Mono", "Space Mono"]
60
+ usage: "Code examples in case studies, technical specifications, date stamps on editorial content"
61
+
62
+ anti_patterns:
63
+ - pattern: "Using generic stock photography on a creative portfolio or agency site"
64
+ reason: "Stock imagery directly contradicts the message of original creative work; it signals inauthenticity"
65
+ instead: "Use original photography, custom illustrations, or carefully art-directed imagery that reflects actual creative capability"
66
+ - pattern: "Uniform grid layouts for all content types"
67
+ reason: "Creative sites should demonstrate design range; predictable grids feel template-driven and corporate"
68
+ instead: "Vary layout rhythm with full-bleed images, asymmetric grids, and intentional whitespace; let content dictate layout"
69
+ - pattern: "Autoplay background video on every page"
70
+ reason: "Overuse dilutes impact, increases load time, and creates accessibility issues; it becomes wallpaper rather than storytelling"
71
+ instead: "Use video intentionally for hero moments or case study intros; provide play controls and poster frames"
72
+ - pattern: "Cramming every project into the portfolio with equal weight"
73
+ reason: "Undifferentiated project lists signal lack of editorial judgment; the portfolio itself is a design artifact"
74
+ instead: "Curate 8-12 best projects with clear hierarchy; feature 2-3 as hero case studies with deeper storytelling"
75
+ - pattern: "Tiny body text to appear more 'design-forward'"
76
+ reason: "Sacrificing readability for aesthetics alienates users and fails accessibility standards"
77
+ instead: "Use generous body text (16px+) and let typographic hierarchy, spacing, and weight create sophistication"
78
+
79
+ examples:
80
+ reference_sites: ["pentagram.com", "itsnicethat.com", "awwwards.com", "siteinspire.com", "creativeboom.com"]