@trentapps/manager-protocol 1.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.
Files changed (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +639 -0
  3. package/dist/analyzers/ArchitectureDetector.d.ts +44 -0
  4. package/dist/analyzers/ArchitectureDetector.d.ts.map +1 -0
  5. package/dist/analyzers/ArchitectureDetector.js +218 -0
  6. package/dist/analyzers/ArchitectureDetector.js.map +1 -0
  7. package/dist/analyzers/CSSAnalyzer.d.ts +284 -0
  8. package/dist/analyzers/CSSAnalyzer.d.ts.map +1 -0
  9. package/dist/analyzers/CSSAnalyzer.js +1180 -0
  10. package/dist/analyzers/CSSAnalyzer.js.map +1 -0
  11. package/dist/analyzers/index.d.ts +5 -0
  12. package/dist/analyzers/index.d.ts.map +1 -0
  13. package/dist/analyzers/index.js +5 -0
  14. package/dist/analyzers/index.js.map +1 -0
  15. package/dist/cli.d.ts +8 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +174 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/design-system/index.d.ts +6 -0
  20. package/dist/design-system/index.d.ts.map +1 -0
  21. package/dist/design-system/index.js +6 -0
  22. package/dist/design-system/index.js.map +1 -0
  23. package/dist/design-system/tokens.d.ts +106 -0
  24. package/dist/design-system/tokens.d.ts.map +1 -0
  25. package/dist/design-system/tokens.js +554 -0
  26. package/dist/design-system/tokens.js.map +1 -0
  27. package/dist/engine/AuditLogger.d.ts +506 -0
  28. package/dist/engine/AuditLogger.d.ts.map +1 -0
  29. package/dist/engine/AuditLogger.js +1491 -0
  30. package/dist/engine/AuditLogger.js.map +1 -0
  31. package/dist/engine/GitHubApprovalManager.d.ts +123 -0
  32. package/dist/engine/GitHubApprovalManager.d.ts.map +1 -0
  33. package/dist/engine/GitHubApprovalManager.js +347 -0
  34. package/dist/engine/GitHubApprovalManager.js.map +1 -0
  35. package/dist/engine/GitHubClient.d.ts +183 -0
  36. package/dist/engine/GitHubClient.d.ts.map +1 -0
  37. package/dist/engine/GitHubClient.js +411 -0
  38. package/dist/engine/GitHubClient.js.map +1 -0
  39. package/dist/engine/RateLimiter.d.ts +81 -0
  40. package/dist/engine/RateLimiter.d.ts.map +1 -0
  41. package/dist/engine/RateLimiter.js +215 -0
  42. package/dist/engine/RateLimiter.js.map +1 -0
  43. package/dist/engine/RuleDependencyAnalyzer.d.ts +73 -0
  44. package/dist/engine/RuleDependencyAnalyzer.d.ts.map +1 -0
  45. package/dist/engine/RuleDependencyAnalyzer.js +475 -0
  46. package/dist/engine/RuleDependencyAnalyzer.js.map +1 -0
  47. package/dist/engine/RulesEngine.d.ts +176 -0
  48. package/dist/engine/RulesEngine.d.ts.map +1 -0
  49. package/dist/engine/RulesEngine.js +705 -0
  50. package/dist/engine/RulesEngine.js.map +1 -0
  51. package/dist/engine/TaskManager.d.ts +174 -0
  52. package/dist/engine/TaskManager.d.ts.map +1 -0
  53. package/dist/engine/TaskManager.js +663 -0
  54. package/dist/engine/TaskManager.js.map +1 -0
  55. package/dist/engine/index.d.ts +11 -0
  56. package/dist/engine/index.d.ts.map +1 -0
  57. package/dist/engine/index.js +13 -0
  58. package/dist/engine/index.js.map +1 -0
  59. package/dist/index.d.ts +21 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +29 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/rules/architecture.d.ts +9 -0
  64. package/dist/rules/architecture.d.ts.map +1 -0
  65. package/dist/rules/architecture.js +322 -0
  66. package/dist/rules/architecture.js.map +1 -0
  67. package/dist/rules/azure.d.ts +7 -0
  68. package/dist/rules/azure.d.ts.map +1 -0
  69. package/dist/rules/azure.js +136 -0
  70. package/dist/rules/azure.js.map +1 -0
  71. package/dist/rules/compliance.d.ts +9 -0
  72. package/dist/rules/compliance.d.ts.map +1 -0
  73. package/dist/rules/compliance.js +286 -0
  74. package/dist/rules/compliance.js.map +1 -0
  75. package/dist/rules/condition-optimizer.d.ts +151 -0
  76. package/dist/rules/condition-optimizer.d.ts.map +1 -0
  77. package/dist/rules/condition-optimizer.js +479 -0
  78. package/dist/rules/condition-optimizer.js.map +1 -0
  79. package/dist/rules/css.d.ts +10 -0
  80. package/dist/rules/css.d.ts.map +1 -0
  81. package/dist/rules/css.js +1777 -0
  82. package/dist/rules/css.js.map +1 -0
  83. package/dist/rules/field-standards.d.ts +1172 -0
  84. package/dist/rules/field-standards.d.ts.map +1 -0
  85. package/dist/rules/field-standards.js +908 -0
  86. package/dist/rules/field-standards.js.map +1 -0
  87. package/dist/rules/flask.d.ts +7 -0
  88. package/dist/rules/flask.d.ts.map +1 -0
  89. package/dist/rules/flask.js +142 -0
  90. package/dist/rules/flask.js.map +1 -0
  91. package/dist/rules/index.d.ts +827 -0
  92. package/dist/rules/index.d.ts.map +1 -0
  93. package/dist/rules/index.js +556 -0
  94. package/dist/rules/index.js.map +1 -0
  95. package/dist/rules/ml-ai.d.ts +7 -0
  96. package/dist/rules/ml-ai.d.ts.map +1 -0
  97. package/dist/rules/ml-ai.js +148 -0
  98. package/dist/rules/ml-ai.js.map +1 -0
  99. package/dist/rules/operational.d.ts +9 -0
  100. package/dist/rules/operational.d.ts.map +1 -0
  101. package/dist/rules/operational.js +318 -0
  102. package/dist/rules/operational.js.map +1 -0
  103. package/dist/rules/patterns.d.ts +568 -0
  104. package/dist/rules/patterns.d.ts.map +1 -0
  105. package/dist/rules/patterns.js +1359 -0
  106. package/dist/rules/patterns.js.map +1 -0
  107. package/dist/rules/security.d.ts +9 -0
  108. package/dist/rules/security.d.ts.map +1 -0
  109. package/dist/rules/security.js +848 -0
  110. package/dist/rules/security.js.map +1 -0
  111. package/dist/rules/shared-patterns.d.ts +268 -0
  112. package/dist/rules/shared-patterns.d.ts.map +1 -0
  113. package/dist/rules/shared-patterns.js +556 -0
  114. package/dist/rules/shared-patterns.js.map +1 -0
  115. package/dist/rules/storage.d.ts +13 -0
  116. package/dist/rules/storage.d.ts.map +1 -0
  117. package/dist/rules/storage.js +672 -0
  118. package/dist/rules/storage.js.map +1 -0
  119. package/dist/rules/stripe.d.ts +7 -0
  120. package/dist/rules/stripe.d.ts.map +1 -0
  121. package/dist/rules/stripe.js +133 -0
  122. package/dist/rules/stripe.js.map +1 -0
  123. package/dist/rules/testing.d.ts +7 -0
  124. package/dist/rules/testing.d.ts.map +1 -0
  125. package/dist/rules/testing.js +135 -0
  126. package/dist/rules/testing.js.map +1 -0
  127. package/dist/rules/ux.d.ts +9 -0
  128. package/dist/rules/ux.d.ts.map +1 -0
  129. package/dist/rules/ux.js +280 -0
  130. package/dist/rules/ux.js.map +1 -0
  131. package/dist/rules/websocket.d.ts +7 -0
  132. package/dist/rules/websocket.d.ts.map +1 -0
  133. package/dist/rules/websocket.js +128 -0
  134. package/dist/rules/websocket.js.map +1 -0
  135. package/dist/server.d.ts +43 -0
  136. package/dist/server.d.ts.map +1 -0
  137. package/dist/server.js +1967 -0
  138. package/dist/server.js.map +1 -0
  139. package/dist/supervisor/AgentSupervisor.d.ts +195 -0
  140. package/dist/supervisor/AgentSupervisor.d.ts.map +1 -0
  141. package/dist/supervisor/AgentSupervisor.js +569 -0
  142. package/dist/supervisor/AgentSupervisor.js.map +1 -0
  143. package/dist/supervisor/ManagedServerRegistry.d.ts +185 -0
  144. package/dist/supervisor/ManagedServerRegistry.d.ts.map +1 -0
  145. package/dist/supervisor/ManagedServerRegistry.js +729 -0
  146. package/dist/supervisor/ManagedServerRegistry.js.map +1 -0
  147. package/dist/supervisor/ProjectTracker.d.ts +210 -0
  148. package/dist/supervisor/ProjectTracker.d.ts.map +1 -0
  149. package/dist/supervisor/ProjectTracker.js +709 -0
  150. package/dist/supervisor/ProjectTracker.js.map +1 -0
  151. package/dist/supervisor/index.d.ts +6 -0
  152. package/dist/supervisor/index.d.ts.map +1 -0
  153. package/dist/supervisor/index.js +6 -0
  154. package/dist/supervisor/index.js.map +1 -0
  155. package/dist/testing/index.d.ts +11 -0
  156. package/dist/testing/index.d.ts.map +1 -0
  157. package/dist/testing/index.js +12 -0
  158. package/dist/testing/index.js.map +1 -0
  159. package/dist/testing/rule-tester.d.ts +217 -0
  160. package/dist/testing/rule-tester.d.ts.map +1 -0
  161. package/dist/testing/rule-tester.examples.d.ts +57 -0
  162. package/dist/testing/rule-tester.examples.d.ts.map +1 -0
  163. package/dist/testing/rule-tester.examples.js +375 -0
  164. package/dist/testing/rule-tester.examples.js.map +1 -0
  165. package/dist/testing/rule-tester.js +381 -0
  166. package/dist/testing/rule-tester.js.map +1 -0
  167. package/dist/testing/rule-validator.d.ts +141 -0
  168. package/dist/testing/rule-validator.d.ts.map +1 -0
  169. package/dist/testing/rule-validator.js +640 -0
  170. package/dist/testing/rule-validator.js.map +1 -0
  171. package/dist/types/index.d.ts +1282 -0
  172. package/dist/types/index.d.ts.map +1 -0
  173. package/dist/types/index.js +386 -0
  174. package/dist/types/index.js.map +1 -0
  175. package/dist/utils/errors.d.ts +86 -0
  176. package/dist/utils/errors.d.ts.map +1 -0
  177. package/dist/utils/errors.js +171 -0
  178. package/dist/utils/errors.js.map +1 -0
  179. package/dist/utils/index.d.ts +7 -0
  180. package/dist/utils/index.d.ts.map +1 -0
  181. package/dist/utils/index.js +7 -0
  182. package/dist/utils/index.js.map +1 -0
  183. package/dist/utils/rate-limiting.d.ts +268 -0
  184. package/dist/utils/rate-limiting.d.ts.map +1 -0
  185. package/dist/utils/rate-limiting.js +403 -0
  186. package/dist/utils/rate-limiting.js.map +1 -0
  187. package/dist/utils/shared.d.ts +306 -0
  188. package/dist/utils/shared.d.ts.map +1 -0
  189. package/dist/utils/shared.js +464 -0
  190. package/dist/utils/shared.js.map +1 -0
  191. package/dist/utils/shell.d.ts +22 -0
  192. package/dist/utils/shell.d.ts.map +1 -0
  193. package/dist/utils/shell.js +29 -0
  194. package/dist/utils/shell.js.map +1 -0
  195. package/package.json +67 -0
@@ -0,0 +1,1777 @@
1
+ /**
2
+ * Enterprise Agent Supervisor - CSS Rules
3
+ *
4
+ * Comprehensive rules for CSS code quality, accessibility, performance,
5
+ * maintainability, and modern best practices.
6
+ */
7
+ export const cssRules = [
8
+ // ============================================================================
9
+ // CSS ORGANIZATION RULES (css-001 to css-009)
10
+ // ============================================================================
11
+ {
12
+ id: 'css-001',
13
+ name: 'Externalize Inline Styles',
14
+ description: 'Inline styles should be moved to external stylesheets',
15
+ type: 'ux',
16
+ enabled: true,
17
+ priority: 850,
18
+ conditions: [
19
+ { field: 'cssSource', operator: 'equals', value: 'inline' }
20
+ ],
21
+ conditionLogic: 'all',
22
+ actions: [
23
+ { type: 'warn', message: 'Inline styles should be externalized for cacheability and maintainability' }
24
+ ],
25
+ riskWeight: 15,
26
+ tags: ['css', 'inline-styles', 'best-practices']
27
+ },
28
+ {
29
+ id: 'css-002',
30
+ name: 'Avoid Duplicate CSS Rules',
31
+ description: 'Prevent creation of duplicate CSS rules',
32
+ type: 'architecture',
33
+ enabled: true,
34
+ priority: 900,
35
+ conditions: [
36
+ { field: 'hasDuplicates', operator: 'equals', value: true }
37
+ ],
38
+ conditionLogic: 'all',
39
+ actions: [
40
+ { type: 'deny', message: 'Duplicate CSS rules detected - use existing class instead' }
41
+ ],
42
+ riskWeight: 20,
43
+ tags: ['css', 'duplicates', 'dry']
44
+ },
45
+ {
46
+ id: 'css-003',
47
+ name: 'Promote Reusable Patterns to Global',
48
+ description: 'Common patterns should be global styles',
49
+ type: 'architecture',
50
+ enabled: true,
51
+ priority: 750,
52
+ conditions: [
53
+ { field: 'isReusablePattern', operator: 'equals', value: true },
54
+ { field: 'isGlobal', operator: 'not_equals', value: true }
55
+ ],
56
+ conditionLogic: 'all',
57
+ actions: [
58
+ { type: 'warn', message: 'Reusable CSS pattern detected - consider making global' }
59
+ ],
60
+ riskWeight: 10,
61
+ tags: ['css', 'global-styles', 'design-system']
62
+ },
63
+ {
64
+ id: 'css-004',
65
+ name: 'Organize CSS by Component',
66
+ description: 'CSS should be organized by component or feature',
67
+ type: 'architecture',
68
+ enabled: true,
69
+ priority: 700,
70
+ conditions: [
71
+ { field: 'hasMixedConcerns', operator: 'equals', value: true }
72
+ ],
73
+ conditionLogic: 'all',
74
+ actions: [
75
+ { type: 'warn', message: 'CSS mixes multiple components - organize by component/feature' }
76
+ ],
77
+ riskWeight: 8,
78
+ tags: ['css', 'organization', 'architecture']
79
+ },
80
+ {
81
+ id: 'css-005',
82
+ name: 'Use CSS Layers for Cascade Control',
83
+ description: 'Use @layer for better cascade control in large projects',
84
+ type: 'architecture',
85
+ enabled: true,
86
+ priority: 650,
87
+ conditions: [
88
+ { field: 'isLargeStylesheet', operator: 'equals', value: true },
89
+ { field: 'usesLayers', operator: 'not_equals', value: true }
90
+ ],
91
+ conditionLogic: 'all',
92
+ actions: [
93
+ { type: 'warn', message: 'Consider using @layer for cascade control in large stylesheets' }
94
+ ],
95
+ riskWeight: 5,
96
+ tags: ['css', 'layers', 'cascade', 'modern']
97
+ },
98
+ // ============================================================================
99
+ // CSS SPECIFICITY RULES (css-010 to css-019)
100
+ // ============================================================================
101
+ {
102
+ id: 'css-010',
103
+ name: 'Avoid ID Selectors',
104
+ description: 'ID selectors have high specificity and should be avoided',
105
+ type: 'architecture',
106
+ enabled: true,
107
+ priority: 880,
108
+ conditions: [
109
+ { field: 'hasIdSelector', operator: 'equals', value: true }
110
+ ],
111
+ conditionLogic: 'all',
112
+ actions: [
113
+ { type: 'warn', message: 'Avoid ID selectors - use classes for styling' }
114
+ ],
115
+ riskWeight: 15,
116
+ tags: ['css', 'specificity', 'best-practices']
117
+ },
118
+ {
119
+ id: 'css-011',
120
+ name: 'Avoid !important',
121
+ description: '!important should be avoided as it breaks cascade',
122
+ type: 'architecture',
123
+ enabled: true,
124
+ priority: 920,
125
+ conditions: [
126
+ { field: 'hasImportant', operator: 'equals', value: true }
127
+ ],
128
+ conditionLogic: 'all',
129
+ actions: [
130
+ { type: 'deny', message: 'Avoid !important - refactor CSS to use proper specificity' }
131
+ ],
132
+ riskWeight: 25,
133
+ tags: ['css', 'important', 'specificity']
134
+ },
135
+ {
136
+ id: 'css-012',
137
+ name: 'Limit Selector Depth',
138
+ description: 'Deep selector nesting creates brittle CSS',
139
+ type: 'architecture',
140
+ enabled: true,
141
+ priority: 800,
142
+ conditions: [
143
+ { field: 'selectorDepth', operator: 'greater_than', value: 3 }
144
+ ],
145
+ conditionLogic: 'all',
146
+ actions: [
147
+ { type: 'warn', message: 'Selector nesting too deep (>3 levels) - use BEM or flat classes' }
148
+ ],
149
+ riskWeight: 12,
150
+ tags: ['css', 'specificity', 'nesting']
151
+ },
152
+ {
153
+ id: 'css-013',
154
+ name: 'Avoid Chained Classes',
155
+ description: 'Excessive class chaining increases specificity unnecessarily',
156
+ type: 'architecture',
157
+ enabled: true,
158
+ priority: 780,
159
+ conditions: [
160
+ { field: 'chainedClassCount', operator: 'greater_than', value: 3 }
161
+ ],
162
+ conditionLogic: 'all',
163
+ actions: [
164
+ { type: 'warn', message: 'Avoid chaining more than 3 classes - use a single descriptive class' }
165
+ ],
166
+ riskWeight: 10,
167
+ tags: ['css', 'specificity', 'selectors']
168
+ },
169
+ {
170
+ id: 'css-014',
171
+ name: 'Use :where() for Low Specificity',
172
+ description: 'Use :where() to reduce specificity when needed',
173
+ type: 'architecture',
174
+ enabled: true,
175
+ priority: 680,
176
+ conditions: [
177
+ { field: 'needsLowSpecificity', operator: 'equals', value: true },
178
+ { field: 'usesWhere', operator: 'not_equals', value: true }
179
+ ],
180
+ conditionLogic: 'all',
181
+ actions: [
182
+ { type: 'warn', message: 'Consider :where() for easily overridable defaults' }
183
+ ],
184
+ riskWeight: 5,
185
+ tags: ['css', 'specificity', 'where', 'modern']
186
+ },
187
+ // ============================================================================
188
+ // CSS VARIABLE RULES (css-020 to css-029)
189
+ // ============================================================================
190
+ {
191
+ id: 'css-020',
192
+ name: 'Use CSS Variables for Colors',
193
+ description: 'Color values should use CSS custom properties',
194
+ type: 'ux',
195
+ enabled: true,
196
+ priority: 780,
197
+ conditions: [
198
+ { field: 'hasHardcodedColor', operator: 'equals', value: true },
199
+ { field: 'usesCssVariables', operator: 'not_equals', value: true }
200
+ ],
201
+ conditionLogic: 'all',
202
+ actions: [
203
+ { type: 'warn', message: 'Use CSS variables for colors (e.g., var(--color-primary))' }
204
+ ],
205
+ riskWeight: 8,
206
+ tags: ['css', 'variables', 'colors', 'theming']
207
+ },
208
+ {
209
+ id: 'css-021',
210
+ name: 'Use CSS Variables for Spacing',
211
+ description: 'Spacing values should use CSS custom properties',
212
+ type: 'ux',
213
+ enabled: true,
214
+ priority: 760,
215
+ conditions: [
216
+ { field: 'hasHardcodedSpacing', operator: 'equals', value: true },
217
+ { field: 'spacingValue', operator: 'greater_than', value: 8 }
218
+ ],
219
+ conditionLogic: 'all',
220
+ actions: [
221
+ { type: 'warn', message: 'Use CSS variables for spacing (e.g., var(--spacing-md))' }
222
+ ],
223
+ riskWeight: 6,
224
+ tags: ['css', 'variables', 'spacing']
225
+ },
226
+ {
227
+ id: 'css-022',
228
+ name: 'Use CSS Variables for Typography',
229
+ description: 'Typography values should use CSS custom properties',
230
+ type: 'ux',
231
+ enabled: true,
232
+ priority: 770,
233
+ conditions: [
234
+ { field: 'hasHardcodedTypography', operator: 'equals', value: true }
235
+ ],
236
+ conditionLogic: 'all',
237
+ actions: [
238
+ { type: 'warn', message: 'Use CSS variables for typography (e.g., var(--font-size-lg))' }
239
+ ],
240
+ riskWeight: 6,
241
+ tags: ['css', 'variables', 'typography']
242
+ },
243
+ {
244
+ id: 'css-023',
245
+ name: 'Use CSS Variables for Shadows',
246
+ description: 'Box shadows should use CSS custom properties',
247
+ type: 'ux',
248
+ enabled: true,
249
+ priority: 740,
250
+ conditions: [
251
+ { field: 'hasHardcodedShadow', operator: 'equals', value: true }
252
+ ],
253
+ conditionLogic: 'all',
254
+ actions: [
255
+ { type: 'warn', message: 'Use CSS variables for shadows (e.g., var(--shadow-md))' }
256
+ ],
257
+ riskWeight: 5,
258
+ tags: ['css', 'variables', 'shadows']
259
+ },
260
+ {
261
+ id: 'css-024',
262
+ name: 'Use CSS Variables for Border Radius',
263
+ description: 'Border radius values should be consistent',
264
+ type: 'ux',
265
+ enabled: true,
266
+ priority: 730,
267
+ conditions: [
268
+ { field: 'hasHardcodedRadius', operator: 'equals', value: true }
269
+ ],
270
+ conditionLogic: 'all',
271
+ actions: [
272
+ { type: 'warn', message: 'Use CSS variables for border-radius (e.g., var(--radius-md))' }
273
+ ],
274
+ riskWeight: 4,
275
+ tags: ['css', 'variables', 'radius']
276
+ },
277
+ {
278
+ id: 'css-025',
279
+ name: 'Use CSS Variables for Transitions',
280
+ description: 'Transition durations should be consistent',
281
+ type: 'ux',
282
+ enabled: true,
283
+ priority: 720,
284
+ conditions: [
285
+ { field: 'hasHardcodedTransition', operator: 'equals', value: true }
286
+ ],
287
+ conditionLogic: 'all',
288
+ actions: [
289
+ { type: 'warn', message: 'Use CSS variables for transitions (e.g., var(--transition-speed))' }
290
+ ],
291
+ riskWeight: 4,
292
+ tags: ['css', 'variables', 'transitions', 'animation']
293
+ },
294
+ {
295
+ id: 'css-026',
296
+ name: 'Use CSS Variables for Z-Index',
297
+ description: 'Z-index values should be managed centrally',
298
+ type: 'architecture',
299
+ enabled: true,
300
+ priority: 800,
301
+ conditions: [
302
+ { field: 'hasHardcodedZIndex', operator: 'equals', value: true },
303
+ { field: 'zIndexValue', operator: 'greater_than', value: 10 }
304
+ ],
305
+ conditionLogic: 'all',
306
+ actions: [
307
+ { type: 'warn', message: 'Use CSS variables for z-index to prevent stacking conflicts' }
308
+ ],
309
+ riskWeight: 10,
310
+ tags: ['css', 'variables', 'z-index', 'stacking']
311
+ },
312
+ // ============================================================================
313
+ // CSS NAMING RULES (css-030 to css-039)
314
+ // ============================================================================
315
+ {
316
+ id: 'css-030',
317
+ name: 'Use Semantic Class Names',
318
+ description: 'Class names should describe purpose, not appearance',
319
+ type: 'ux',
320
+ enabled: true,
321
+ priority: 720,
322
+ conditions: [
323
+ { field: 'hasNonSemanticName', operator: 'equals', value: true }
324
+ ],
325
+ conditionLogic: 'all',
326
+ actions: [
327
+ { type: 'warn', message: 'Use semantic class names (e.g., .card-header not .blue-box)' }
328
+ ],
329
+ riskWeight: 8,
330
+ tags: ['css', 'naming', 'semantics']
331
+ },
332
+ {
333
+ id: 'css-031',
334
+ name: 'Follow BEM Convention',
335
+ description: 'Complex components should use BEM naming',
336
+ type: 'architecture',
337
+ enabled: true,
338
+ priority: 700,
339
+ conditions: [
340
+ { field: 'isComplexComponent', operator: 'equals', value: true },
341
+ { field: 'usesBEM', operator: 'not_equals', value: true }
342
+ ],
343
+ conditionLogic: 'all',
344
+ actions: [
345
+ { type: 'warn', message: 'Consider BEM naming for complex components (.block__element--modifier)' }
346
+ ],
347
+ riskWeight: 5,
348
+ tags: ['css', 'naming', 'bem']
349
+ },
350
+ {
351
+ id: 'css-032',
352
+ name: 'Avoid Generic Class Names',
353
+ description: 'Class names like .container, .wrapper should be namespaced',
354
+ type: 'architecture',
355
+ enabled: true,
356
+ priority: 750,
357
+ conditions: [
358
+ { field: 'hasGenericClassName', operator: 'equals', value: true }
359
+ ],
360
+ conditionLogic: 'all',
361
+ actions: [
362
+ { type: 'warn', message: 'Avoid generic class names - namespace to prevent conflicts (.my-component__container)' }
363
+ ],
364
+ riskWeight: 8,
365
+ tags: ['css', 'naming', 'conflicts']
366
+ },
367
+ {
368
+ id: 'css-033',
369
+ name: 'Consistent Naming Convention',
370
+ description: 'Use consistent naming (kebab-case, camelCase, etc.)',
371
+ type: 'architecture',
372
+ enabled: true,
373
+ priority: 680,
374
+ conditions: [
375
+ { field: 'hasMixedNamingConvention', operator: 'equals', value: true }
376
+ ],
377
+ conditionLogic: 'all',
378
+ actions: [
379
+ { type: 'warn', message: 'Use consistent naming convention throughout the stylesheet' }
380
+ ],
381
+ riskWeight: 5,
382
+ tags: ['css', 'naming', 'consistency']
383
+ },
384
+ // ============================================================================
385
+ // CSS UTILITY RULES (css-040 to css-049)
386
+ // ============================================================================
387
+ {
388
+ id: 'css-040',
389
+ name: 'Use Utility Classes When Available',
390
+ description: 'Prefer utility classes over custom CSS when using utility framework',
391
+ type: 'ux',
392
+ enabled: true,
393
+ priority: 740,
394
+ conditions: [
395
+ { field: 'hasUtilityFramework', operator: 'equals', value: true },
396
+ { field: 'canUseUtility', operator: 'equals', value: true }
397
+ ],
398
+ conditionLogic: 'all',
399
+ actions: [
400
+ { type: 'warn', message: 'Use utility class instead of custom CSS' }
401
+ ],
402
+ riskWeight: 5,
403
+ tags: ['css', 'utilities', 'tailwind']
404
+ },
405
+ {
406
+ id: 'css-041',
407
+ name: 'Avoid Redundant Utility Combinations',
408
+ description: 'Simplify utility class combinations',
409
+ type: 'architecture',
410
+ enabled: true,
411
+ priority: 700,
412
+ conditions: [
413
+ { field: 'hasRedundantUtilities', operator: 'equals', value: true }
414
+ ],
415
+ conditionLogic: 'all',
416
+ actions: [
417
+ { type: 'warn', message: 'Simplify utility class combination or extract to component class' }
418
+ ],
419
+ riskWeight: 4,
420
+ tags: ['css', 'utilities', 'simplification']
421
+ },
422
+ // ============================================================================
423
+ // CSS PERFORMANCE RULES (css-050 to css-069)
424
+ // ============================================================================
425
+ {
426
+ id: 'css-050',
427
+ name: 'Avoid Universal Selectors',
428
+ description: 'Universal selectors (*) have performance implications',
429
+ type: 'architecture',
430
+ enabled: true,
431
+ priority: 820,
432
+ conditions: [
433
+ { field: 'hasUniversalSelector', operator: 'equals', value: true }
434
+ ],
435
+ conditionLogic: 'all',
436
+ actions: [
437
+ { type: 'warn', message: 'Avoid universal selectors (*) for performance' }
438
+ ],
439
+ riskWeight: 10,
440
+ tags: ['css', 'performance', 'selectors']
441
+ },
442
+ {
443
+ id: 'css-051',
444
+ name: 'Limit Animation Complexity',
445
+ description: 'Complex animations should be optimized',
446
+ type: 'ux',
447
+ enabled: true,
448
+ priority: 750,
449
+ conditions: [
450
+ { field: 'hasComplexAnimation', operator: 'equals', value: true },
451
+ { field: 'usesWillChange', operator: 'not_equals', value: true }
452
+ ],
453
+ conditionLogic: 'all',
454
+ actions: [
455
+ { type: 'warn', message: 'Complex animations should use will-change or transform for performance' }
456
+ ],
457
+ riskWeight: 8,
458
+ tags: ['css', 'performance', 'animation']
459
+ },
460
+ {
461
+ id: 'css-052',
462
+ name: 'Avoid Expensive Selectors',
463
+ description: 'Attribute selectors and :nth-child can be slow',
464
+ type: 'architecture',
465
+ enabled: true,
466
+ priority: 780,
467
+ conditions: [
468
+ { field: 'hasExpensiveSelector', operator: 'equals', value: true }
469
+ ],
470
+ conditionLogic: 'all',
471
+ actions: [
472
+ { type: 'warn', message: 'Complex attribute selectors can be slow - consider adding a class' }
473
+ ],
474
+ riskWeight: 8,
475
+ tags: ['css', 'performance', 'selectors']
476
+ },
477
+ {
478
+ id: 'css-053',
479
+ name: 'Use transform for Animations',
480
+ description: 'Prefer transform/opacity over layout-triggering properties',
481
+ type: 'ux',
482
+ enabled: true,
483
+ priority: 800,
484
+ conditions: [
485
+ { field: 'animatesLayoutProperty', operator: 'equals', value: true }
486
+ ],
487
+ conditionLogic: 'all',
488
+ actions: [
489
+ { type: 'warn', message: 'Animating width/height/margin causes layout thrashing - use transform instead' }
490
+ ],
491
+ riskWeight: 12,
492
+ tags: ['css', 'performance', 'animation', 'layout']
493
+ },
494
+ {
495
+ id: 'css-054',
496
+ name: 'Avoid Forced Reflows',
497
+ description: 'Certain property combinations cause forced reflows',
498
+ type: 'architecture',
499
+ enabled: true,
500
+ priority: 820,
501
+ conditions: [
502
+ { field: 'causesReflow', operator: 'equals', value: true }
503
+ ],
504
+ conditionLogic: 'all',
505
+ actions: [
506
+ { type: 'warn', message: 'This CSS pattern may cause forced reflows - batch DOM reads/writes' }
507
+ ],
508
+ riskWeight: 10,
509
+ tags: ['css', 'performance', 'reflow']
510
+ },
511
+ {
512
+ id: 'css-055',
513
+ name: 'Use contain for Paint Isolation',
514
+ description: 'Use CSS containment for complex components',
515
+ type: 'architecture',
516
+ enabled: true,
517
+ priority: 700,
518
+ conditions: [
519
+ { field: 'isComplexComponent', operator: 'equals', value: true },
520
+ { field: 'usesContain', operator: 'not_equals', value: true }
521
+ ],
522
+ conditionLogic: 'all',
523
+ actions: [
524
+ { type: 'warn', message: 'Consider contain: layout style for paint isolation in complex components' }
525
+ ],
526
+ riskWeight: 5,
527
+ tags: ['css', 'performance', 'contain', 'modern']
528
+ },
529
+ {
530
+ id: 'css-056',
531
+ name: 'Avoid box-shadow on Scroll',
532
+ description: 'Large box-shadows during scroll hurt performance',
533
+ type: 'ux',
534
+ enabled: true,
535
+ priority: 750,
536
+ conditions: [
537
+ { field: 'hasLargeShadow', operator: 'equals', value: true },
538
+ { field: 'isScrollableContext', operator: 'equals', value: true }
539
+ ],
540
+ conditionLogic: 'all',
541
+ actions: [
542
+ { type: 'warn', message: 'Large box-shadows in scrollable areas hurt performance - consider alternatives' }
543
+ ],
544
+ riskWeight: 8,
545
+ tags: ['css', 'performance', 'shadow', 'scroll']
546
+ },
547
+ {
548
+ id: 'css-057',
549
+ name: 'Limit filter/backdrop-filter Usage',
550
+ description: 'Filters are GPU-intensive',
551
+ type: 'ux',
552
+ enabled: true,
553
+ priority: 740,
554
+ conditions: [
555
+ { field: 'hasFilter', operator: 'equals', value: true },
556
+ { field: 'filterCount', operator: 'greater_than', value: 2 }
557
+ ],
558
+ conditionLogic: 'all',
559
+ actions: [
560
+ { type: 'warn', message: 'Multiple filters are GPU-intensive - use sparingly' }
561
+ ],
562
+ riskWeight: 8,
563
+ tags: ['css', 'performance', 'filter', 'gpu']
564
+ },
565
+ {
566
+ id: 'css-058',
567
+ name: 'Use content-visibility for Offscreen Content',
568
+ description: 'Improve render performance with content-visibility',
569
+ type: 'architecture',
570
+ enabled: true,
571
+ priority: 680,
572
+ conditions: [
573
+ { field: 'isLongList', operator: 'equals', value: true },
574
+ { field: 'usesContentVisibility', operator: 'not_equals', value: true }
575
+ ],
576
+ conditionLogic: 'all',
577
+ actions: [
578
+ { type: 'warn', message: 'Consider content-visibility: auto for offscreen content' }
579
+ ],
580
+ riskWeight: 5,
581
+ tags: ['css', 'performance', 'content-visibility', 'modern']
582
+ },
583
+ // ============================================================================
584
+ // CSS ACCESSIBILITY RULES (css-060 to css-079)
585
+ // ============================================================================
586
+ {
587
+ id: 'css-060',
588
+ name: 'Ensure Focus Visibility',
589
+ description: 'Interactive elements must have visible focus styles',
590
+ type: 'ux',
591
+ enabled: true,
592
+ priority: 900,
593
+ conditions: [
594
+ { field: 'isInteractiveElement', operator: 'equals', value: true },
595
+ { field: 'hasFocusStyles', operator: 'not_equals', value: true }
596
+ ],
597
+ conditionLogic: 'all',
598
+ actions: [
599
+ { type: 'warn', message: 'Interactive elements need visible focus styles for accessibility' }
600
+ ],
601
+ riskWeight: 15,
602
+ tags: ['css', 'accessibility', 'focus', 'wcag']
603
+ },
604
+ {
605
+ id: 'css-061',
606
+ name: 'Avoid Hiding Outline',
607
+ description: 'outline: none without replacement is an accessibility issue',
608
+ type: 'ux',
609
+ enabled: true,
610
+ priority: 880,
611
+ conditions: [
612
+ { field: 'removesOutline', operator: 'equals', value: true },
613
+ { field: 'providesAlternativeFocus', operator: 'not_equals', value: true }
614
+ ],
615
+ conditionLogic: 'all',
616
+ actions: [
617
+ { type: 'deny', message: 'Do not hide outline without providing alternative focus indicator' }
618
+ ],
619
+ riskWeight: 20,
620
+ tags: ['css', 'accessibility', 'outline', 'focus', 'wcag']
621
+ },
622
+ {
623
+ id: 'css-062',
624
+ name: 'Respect Reduced Motion',
625
+ description: 'Animations should respect prefers-reduced-motion',
626
+ type: 'ux',
627
+ enabled: true,
628
+ priority: 840,
629
+ conditions: [
630
+ { field: 'hasAnimation', operator: 'equals', value: true },
631
+ { field: 'respectsReducedMotion', operator: 'not_equals', value: true }
632
+ ],
633
+ conditionLogic: 'all',
634
+ actions: [
635
+ { type: 'warn', message: 'Animations should respect @media (prefers-reduced-motion: reduce)' }
636
+ ],
637
+ riskWeight: 12,
638
+ tags: ['css', 'accessibility', 'animation', 'motion', 'wcag']
639
+ },
640
+ {
641
+ id: 'css-063',
642
+ name: 'Ensure Color Contrast',
643
+ description: 'Text must have sufficient color contrast (WCAG 2.1 AA)',
644
+ type: 'ux',
645
+ enabled: true,
646
+ priority: 920,
647
+ conditions: [
648
+ { field: 'hasTextColor', operator: 'equals', value: true },
649
+ { field: 'meetsContrastRatio', operator: 'not_equals', value: true }
650
+ ],
651
+ conditionLogic: 'all',
652
+ actions: [
653
+ { type: 'deny', message: 'Text color does not meet WCAG 2.1 AA contrast ratio (4.5:1 for normal text)' }
654
+ ],
655
+ riskWeight: 25,
656
+ tags: ['css', 'accessibility', 'contrast', 'color', 'wcag']
657
+ },
658
+ {
659
+ id: 'css-064',
660
+ name: 'Minimum Touch Target Size',
661
+ description: 'Touch targets should be at least 44x44px',
662
+ type: 'ux',
663
+ enabled: true,
664
+ priority: 850,
665
+ conditions: [
666
+ { field: 'isInteractiveElement', operator: 'equals', value: true },
667
+ { field: 'touchTargetSize', operator: 'less_than', value: 44 }
668
+ ],
669
+ conditionLogic: 'all',
670
+ actions: [
671
+ { type: 'warn', message: 'Touch targets should be at least 44x44px for accessibility' }
672
+ ],
673
+ riskWeight: 12,
674
+ tags: ['css', 'accessibility', 'touch', 'mobile', 'wcag']
675
+ },
676
+ {
677
+ id: 'css-065',
678
+ name: 'Avoid Text in Images',
679
+ description: 'Text should not be embedded in background images',
680
+ type: 'ux',
681
+ enabled: true,
682
+ priority: 800,
683
+ conditions: [
684
+ { field: 'hasBackgroundImage', operator: 'equals', value: true },
685
+ { field: 'containsTextInImage', operator: 'equals', value: true }
686
+ ],
687
+ conditionLogic: 'all',
688
+ actions: [
689
+ { type: 'warn', message: 'Avoid text in background images - use real text for accessibility' }
690
+ ],
691
+ riskWeight: 10,
692
+ tags: ['css', 'accessibility', 'images', 'text']
693
+ },
694
+ {
695
+ id: 'css-066',
696
+ name: 'Support High Contrast Mode',
697
+ description: 'Ensure styles work in Windows High Contrast Mode',
698
+ type: 'ux',
699
+ enabled: true,
700
+ priority: 780,
701
+ conditions: [
702
+ { field: 'usesCustomColors', operator: 'equals', value: true },
703
+ { field: 'supportsHighContrast', operator: 'not_equals', value: true }
704
+ ],
705
+ conditionLogic: 'all',
706
+ actions: [
707
+ { type: 'warn', message: 'Consider @media (forced-colors: active) for High Contrast Mode support' }
708
+ ],
709
+ riskWeight: 8,
710
+ tags: ['css', 'accessibility', 'high-contrast', 'wcag']
711
+ },
712
+ {
713
+ id: 'css-067',
714
+ name: 'Avoid display:none for Active Content',
715
+ description: 'display:none hides content from screen readers',
716
+ type: 'ux',
717
+ enabled: true,
718
+ priority: 820,
719
+ conditions: [
720
+ { field: 'hidesActiveContent', operator: 'equals', value: true },
721
+ { field: 'usesDisplayNone', operator: 'equals', value: true }
722
+ ],
723
+ conditionLogic: 'all',
724
+ actions: [
725
+ { type: 'warn', message: 'display:none hides from screen readers - use .visually-hidden if content should be accessible' }
726
+ ],
727
+ riskWeight: 10,
728
+ tags: ['css', 'accessibility', 'screen-reader', 'hidden']
729
+ },
730
+ {
731
+ id: 'css-068',
732
+ name: 'Readable Line Length',
733
+ description: 'Line length should be 45-75 characters for readability',
734
+ type: 'ux',
735
+ enabled: true,
736
+ priority: 720,
737
+ conditions: [
738
+ { field: 'isTextContent', operator: 'equals', value: true },
739
+ { field: 'lineLength', operator: 'greater_than', value: 80 }
740
+ ],
741
+ conditionLogic: 'all',
742
+ actions: [
743
+ { type: 'warn', message: 'Limit line length to ~75 characters for readability (use max-width: 65ch)' }
744
+ ],
745
+ riskWeight: 6,
746
+ tags: ['css', 'accessibility', 'readability', 'typography']
747
+ },
748
+ {
749
+ id: 'css-069',
750
+ name: 'Minimum Text Size',
751
+ description: 'Body text should be at least 16px',
752
+ type: 'ux',
753
+ enabled: true,
754
+ priority: 850,
755
+ conditions: [
756
+ { field: 'isBodyText', operator: 'equals', value: true },
757
+ { field: 'fontSize', operator: 'less_than', value: 16 }
758
+ ],
759
+ conditionLogic: 'all',
760
+ actions: [
761
+ { type: 'warn', message: 'Body text should be at least 16px (1rem) for readability' }
762
+ ],
763
+ riskWeight: 10,
764
+ tags: ['css', 'accessibility', 'typography', 'font-size']
765
+ },
766
+ {
767
+ id: 'css-070',
768
+ name: 'Use focus-visible for Focus Styles',
769
+ description: 'Use :focus-visible instead of :focus for better UX',
770
+ type: 'ux',
771
+ enabled: true,
772
+ priority: 750,
773
+ conditions: [
774
+ { field: 'usesFocusPseudo', operator: 'equals', value: true },
775
+ { field: 'usesFocusVisible', operator: 'not_equals', value: true }
776
+ ],
777
+ conditionLogic: 'all',
778
+ actions: [
779
+ { type: 'warn', message: 'Consider :focus-visible instead of :focus to show focus only for keyboard users' }
780
+ ],
781
+ riskWeight: 5,
782
+ tags: ['css', 'accessibility', 'focus', 'focus-visible']
783
+ },
784
+ // ============================================================================
785
+ // CSS RESPONSIVE DESIGN RULES (css-080 to css-089)
786
+ // ============================================================================
787
+ {
788
+ id: 'css-080',
789
+ name: 'Use Relative Units',
790
+ description: 'Prefer rem/em over px for better accessibility',
791
+ type: 'ux',
792
+ enabled: true,
793
+ priority: 760,
794
+ conditions: [
795
+ { field: 'usesPxForFontSize', operator: 'equals', value: true }
796
+ ],
797
+ conditionLogic: 'all',
798
+ actions: [
799
+ { type: 'warn', message: 'Use rem/em instead of px for font-size to respect user preferences' }
800
+ ],
801
+ riskWeight: 8,
802
+ tags: ['css', 'responsive', 'units', 'accessibility']
803
+ },
804
+ {
805
+ id: 'css-081',
806
+ name: 'Mobile-First Media Queries',
807
+ description: 'Use min-width media queries for mobile-first approach',
808
+ type: 'architecture',
809
+ enabled: true,
810
+ priority: 700,
811
+ conditions: [
812
+ { field: 'usesMaxWidthMediaQuery', operator: 'equals', value: true }
813
+ ],
814
+ conditionLogic: 'all',
815
+ actions: [
816
+ { type: 'warn', message: 'Consider mobile-first approach with min-width media queries' }
817
+ ],
818
+ riskWeight: 5,
819
+ tags: ['css', 'responsive', 'mobile-first', 'media-queries']
820
+ },
821
+ {
822
+ id: 'css-082',
823
+ name: 'Use Fluid Typography',
824
+ description: 'Use clamp() for responsive typography',
825
+ type: 'ux',
826
+ enabled: true,
827
+ priority: 680,
828
+ conditions: [
829
+ { field: 'hasFixedFontSize', operator: 'equals', value: true },
830
+ { field: 'usesClamp', operator: 'not_equals', value: true }
831
+ ],
832
+ conditionLogic: 'all',
833
+ actions: [
834
+ { type: 'warn', message: 'Consider clamp() for fluid typography (e.g., font-size: clamp(1rem, 2vw + 1rem, 2rem))' }
835
+ ],
836
+ riskWeight: 4,
837
+ tags: ['css', 'responsive', 'typography', 'clamp', 'modern']
838
+ },
839
+ {
840
+ id: 'css-083',
841
+ name: 'Avoid Fixed Widths',
842
+ description: 'Fixed widths break responsive design',
843
+ type: 'ux',
844
+ enabled: true,
845
+ priority: 780,
846
+ conditions: [
847
+ { field: 'hasFixedWidth', operator: 'equals', value: true },
848
+ { field: 'widthValue', operator: 'greater_than', value: 300 }
849
+ ],
850
+ conditionLogic: 'all',
851
+ actions: [
852
+ { type: 'warn', message: 'Avoid fixed widths on container elements - use max-width and percentages' }
853
+ ],
854
+ riskWeight: 10,
855
+ tags: ['css', 'responsive', 'width', 'layout']
856
+ },
857
+ {
858
+ id: 'css-084',
859
+ name: 'Use Container Queries',
860
+ description: 'Container queries for component-level responsiveness',
861
+ type: 'architecture',
862
+ enabled: true,
863
+ priority: 650,
864
+ conditions: [
865
+ { field: 'isReusableComponent', operator: 'equals', value: true },
866
+ { field: 'usesContainerQueries', operator: 'not_equals', value: true }
867
+ ],
868
+ conditionLogic: 'all',
869
+ actions: [
870
+ { type: 'warn', message: 'Consider @container queries for component-level responsive design' }
871
+ ],
872
+ riskWeight: 4,
873
+ tags: ['css', 'responsive', 'container-queries', 'modern']
874
+ },
875
+ {
876
+ id: 'css-085',
877
+ name: 'Use Logical Properties',
878
+ description: 'Logical properties support RTL layouts',
879
+ type: 'ux',
880
+ enabled: true,
881
+ priority: 700,
882
+ conditions: [
883
+ { field: 'usesPhysicalProperties', operator: 'equals', value: true }
884
+ ],
885
+ conditionLogic: 'all',
886
+ actions: [
887
+ { type: 'warn', message: 'Consider logical properties (margin-inline, padding-block) for RTL support' }
888
+ ],
889
+ riskWeight: 5,
890
+ tags: ['css', 'responsive', 'logical-properties', 'rtl', 'i18n']
891
+ },
892
+ {
893
+ id: 'css-086',
894
+ name: 'Responsive Images',
895
+ description: 'Images should be responsive',
896
+ type: 'ux',
897
+ enabled: true,
898
+ priority: 800,
899
+ conditions: [
900
+ { field: 'hasImageStyles', operator: 'equals', value: true },
901
+ { field: 'imagesAreResponsive', operator: 'not_equals', value: true }
902
+ ],
903
+ conditionLogic: 'all',
904
+ actions: [
905
+ { type: 'warn', message: 'Add max-width: 100% and height: auto for responsive images' }
906
+ ],
907
+ riskWeight: 8,
908
+ tags: ['css', 'responsive', 'images']
909
+ },
910
+ {
911
+ id: 'css-087',
912
+ name: 'Use aspect-ratio',
913
+ description: 'Use aspect-ratio for consistent proportions',
914
+ type: 'ux',
915
+ enabled: true,
916
+ priority: 680,
917
+ conditions: [
918
+ { field: 'usesPaddingHack', operator: 'equals', value: true }
919
+ ],
920
+ conditionLogic: 'all',
921
+ actions: [
922
+ { type: 'warn', message: 'Use aspect-ratio instead of padding hack for aspect ratios' }
923
+ ],
924
+ riskWeight: 5,
925
+ tags: ['css', 'responsive', 'aspect-ratio', 'modern']
926
+ },
927
+ // ============================================================================
928
+ // CSS DARK MODE / THEMING RULES (css-090 to css-099)
929
+ // ============================================================================
930
+ {
931
+ id: 'css-090',
932
+ name: 'Support Color Scheme Preference',
933
+ description: 'Support prefers-color-scheme for dark mode',
934
+ type: 'ux',
935
+ enabled: true,
936
+ priority: 750,
937
+ conditions: [
938
+ { field: 'hasCustomColors', operator: 'equals', value: true },
939
+ { field: 'supportsColorScheme', operator: 'not_equals', value: true }
940
+ ],
941
+ conditionLogic: 'all',
942
+ actions: [
943
+ { type: 'warn', message: 'Consider supporting @media (prefers-color-scheme: dark)' }
944
+ ],
945
+ riskWeight: 6,
946
+ tags: ['css', 'dark-mode', 'color-scheme', 'theming']
947
+ },
948
+ {
949
+ id: 'css-091',
950
+ name: 'Use color-scheme Property',
951
+ description: 'Set color-scheme for system UI elements',
952
+ type: 'ux',
953
+ enabled: true,
954
+ priority: 700,
955
+ conditions: [
956
+ { field: 'supportsDarkMode', operator: 'equals', value: true },
957
+ { field: 'usesColorScheme', operator: 'not_equals', value: true }
958
+ ],
959
+ conditionLogic: 'all',
960
+ actions: [
961
+ { type: 'warn', message: 'Add color-scheme: light dark for system UI elements in dark mode' }
962
+ ],
963
+ riskWeight: 4,
964
+ tags: ['css', 'dark-mode', 'color-scheme']
965
+ },
966
+ {
967
+ id: 'css-092',
968
+ name: 'Dark Mode Contrast Check',
969
+ description: 'Ensure dark mode maintains contrast ratios',
970
+ type: 'ux',
971
+ enabled: true,
972
+ priority: 850,
973
+ conditions: [
974
+ { field: 'isDarkModeRule', operator: 'equals', value: true },
975
+ { field: 'meetsDarkModeContrast', operator: 'not_equals', value: true }
976
+ ],
977
+ conditionLogic: 'all',
978
+ actions: [
979
+ { type: 'warn', message: 'Dark mode colors must maintain WCAG contrast ratios' }
980
+ ],
981
+ riskWeight: 12,
982
+ tags: ['css', 'dark-mode', 'contrast', 'accessibility']
983
+ },
984
+ {
985
+ id: 'css-093',
986
+ name: 'Avoid Pure Black in Dark Mode',
987
+ description: 'Pure black (#000) is harsh in dark mode',
988
+ type: 'ux',
989
+ enabled: true,
990
+ priority: 680,
991
+ conditions: [
992
+ { field: 'isDarkModeRule', operator: 'equals', value: true },
993
+ { field: 'usesPureBlack', operator: 'equals', value: true }
994
+ ],
995
+ conditionLogic: 'all',
996
+ actions: [
997
+ { type: 'warn', message: 'Avoid pure black (#000) in dark mode - use dark gray (#121212) for less eye strain' }
998
+ ],
999
+ riskWeight: 5,
1000
+ tags: ['css', 'dark-mode', 'colors', 'ux']
1001
+ },
1002
+ // ============================================================================
1003
+ // CSS MAINTAINABILITY RULES (css-100 to css-109)
1004
+ // ============================================================================
1005
+ {
1006
+ id: 'css-100',
1007
+ name: 'Limit Rule Complexity',
1008
+ description: 'Rules with too many properties should be split',
1009
+ type: 'architecture',
1010
+ enabled: true,
1011
+ priority: 680,
1012
+ conditions: [
1013
+ { field: 'propertyCount', operator: 'greater_than', value: 15 }
1014
+ ],
1015
+ conditionLogic: 'all',
1016
+ actions: [
1017
+ { type: 'warn', message: 'CSS rule has too many properties (>15) - consider splitting into smaller rules' }
1018
+ ],
1019
+ riskWeight: 8,
1020
+ tags: ['css', 'maintainability', 'complexity']
1021
+ },
1022
+ {
1023
+ id: 'css-101',
1024
+ name: 'Remove Unused CSS',
1025
+ description: 'Detect and flag potentially unused CSS rules',
1026
+ type: 'architecture',
1027
+ enabled: true,
1028
+ priority: 650,
1029
+ conditions: [
1030
+ { field: 'isPotentiallyUnused', operator: 'equals', value: true }
1031
+ ],
1032
+ conditionLogic: 'all',
1033
+ actions: [
1034
+ { type: 'warn', message: 'CSS rule may be unused - verify and remove if not needed' }
1035
+ ],
1036
+ riskWeight: 5,
1037
+ tags: ['css', 'unused', 'cleanup']
1038
+ },
1039
+ {
1040
+ id: 'css-102',
1041
+ name: 'Avoid Magic Numbers',
1042
+ description: 'Avoid unexplained numeric values in CSS',
1043
+ type: 'architecture',
1044
+ enabled: true,
1045
+ priority: 660,
1046
+ conditions: [
1047
+ { field: 'hasMagicNumbers', operator: 'equals', value: true }
1048
+ ],
1049
+ conditionLogic: 'all',
1050
+ actions: [
1051
+ { type: 'warn', message: 'Avoid magic numbers - use CSS variables or add comments explaining values' }
1052
+ ],
1053
+ riskWeight: 6,
1054
+ tags: ['css', 'maintainability', 'magic-numbers']
1055
+ },
1056
+ {
1057
+ id: 'css-103',
1058
+ name: 'Avoid Vendor Prefixes',
1059
+ description: 'Use autoprefixer instead of manual vendor prefixes',
1060
+ type: 'architecture',
1061
+ enabled: true,
1062
+ priority: 750,
1063
+ conditions: [
1064
+ { field: 'hasVendorPrefix', operator: 'equals', value: true }
1065
+ ],
1066
+ conditionLogic: 'all',
1067
+ actions: [
1068
+ { type: 'warn', message: 'Avoid manual vendor prefixes - use autoprefixer in build process' }
1069
+ ],
1070
+ riskWeight: 6,
1071
+ tags: ['css', 'maintainability', 'vendor-prefix', 'build']
1072
+ },
1073
+ {
1074
+ id: 'css-104',
1075
+ name: 'Comment Complex Selectors',
1076
+ description: 'Complex selectors should have comments',
1077
+ type: 'architecture',
1078
+ enabled: true,
1079
+ priority: 640,
1080
+ conditions: [
1081
+ { field: 'hasComplexSelector', operator: 'equals', value: true },
1082
+ { field: 'hasComment', operator: 'not_equals', value: true }
1083
+ ],
1084
+ conditionLogic: 'all',
1085
+ actions: [
1086
+ { type: 'warn', message: 'Add comment explaining complex selector purpose' }
1087
+ ],
1088
+ riskWeight: 4,
1089
+ tags: ['css', 'maintainability', 'comments']
1090
+ },
1091
+ // ============================================================================
1092
+ // CSS PRINT RULES (css-110 to css-114)
1093
+ // ============================================================================
1094
+ {
1095
+ id: 'css-110',
1096
+ name: 'Consider Print Styles',
1097
+ description: 'Important pages should have print styles',
1098
+ type: 'ux',
1099
+ enabled: true,
1100
+ priority: 600,
1101
+ conditions: [
1102
+ { field: 'isPrintableContent', operator: 'equals', value: true },
1103
+ { field: 'hasPrintStyles', operator: 'not_equals', value: true }
1104
+ ],
1105
+ conditionLogic: 'all',
1106
+ actions: [
1107
+ { type: 'warn', message: 'Consider adding @media print styles for printable content' }
1108
+ ],
1109
+ riskWeight: 4,
1110
+ tags: ['css', 'print', 'media-queries']
1111
+ },
1112
+ {
1113
+ id: 'css-111',
1114
+ name: 'Hide Non-Essential Elements in Print',
1115
+ description: 'Navigation and ads should be hidden in print',
1116
+ type: 'ux',
1117
+ enabled: true,
1118
+ priority: 580,
1119
+ conditions: [
1120
+ { field: 'isPrintRule', operator: 'equals', value: true },
1121
+ { field: 'hidesNonEssential', operator: 'not_equals', value: true }
1122
+ ],
1123
+ conditionLogic: 'all',
1124
+ actions: [
1125
+ { type: 'warn', message: 'Hide navigation, ads, and interactive elements in print styles' }
1126
+ ],
1127
+ riskWeight: 3,
1128
+ tags: ['css', 'print', 'cleanup']
1129
+ },
1130
+ // ============================================================================
1131
+ // MODERN CSS RULES (css-120 to css-129)
1132
+ // ============================================================================
1133
+ {
1134
+ id: 'css-120',
1135
+ name: 'Use CSS Grid for Layouts',
1136
+ description: 'Prefer Grid over floats for complex layouts',
1137
+ type: 'architecture',
1138
+ enabled: true,
1139
+ priority: 720,
1140
+ conditions: [
1141
+ { field: 'usesFloatLayout', operator: 'equals', value: true }
1142
+ ],
1143
+ conditionLogic: 'all',
1144
+ actions: [
1145
+ { type: 'warn', message: 'Use CSS Grid instead of floats for complex layouts' }
1146
+ ],
1147
+ riskWeight: 8,
1148
+ tags: ['css', 'grid', 'layout', 'modern']
1149
+ },
1150
+ {
1151
+ id: 'css-121',
1152
+ name: 'Use Flexbox for Alignment',
1153
+ description: 'Prefer Flexbox for alignment tasks',
1154
+ type: 'architecture',
1155
+ enabled: true,
1156
+ priority: 700,
1157
+ conditions: [
1158
+ { field: 'usesOldAlignmentHacks', operator: 'equals', value: true }
1159
+ ],
1160
+ conditionLogic: 'all',
1161
+ actions: [
1162
+ { type: 'warn', message: 'Use Flexbox for vertical centering and alignment' }
1163
+ ],
1164
+ riskWeight: 6,
1165
+ tags: ['css', 'flexbox', 'alignment', 'modern']
1166
+ },
1167
+ {
1168
+ id: 'css-122',
1169
+ name: 'Use gap Instead of Margins',
1170
+ description: 'Use gap property for spacing in flex/grid',
1171
+ type: 'architecture',
1172
+ enabled: true,
1173
+ priority: 680,
1174
+ conditions: [
1175
+ { field: 'usesFlexOrGrid', operator: 'equals', value: true },
1176
+ { field: 'usesMarginForGap', operator: 'equals', value: true }
1177
+ ],
1178
+ conditionLogic: 'all',
1179
+ actions: [
1180
+ { type: 'warn', message: 'Use gap property instead of margins for spacing in flex/grid' }
1181
+ ],
1182
+ riskWeight: 5,
1183
+ tags: ['css', 'gap', 'flexbox', 'grid', 'modern']
1184
+ },
1185
+ {
1186
+ id: 'css-123',
1187
+ name: 'Use CSS Custom Properties',
1188
+ description: 'Use CSS variables for dynamic theming',
1189
+ type: 'architecture',
1190
+ enabled: true,
1191
+ priority: 750,
1192
+ conditions: [
1193
+ { field: 'hasRepeatedValue', operator: 'equals', value: true },
1194
+ { field: 'usesCssVariables', operator: 'not_equals', value: true }
1195
+ ],
1196
+ conditionLogic: 'all',
1197
+ actions: [
1198
+ { type: 'warn', message: 'Extract repeated values into CSS custom properties' }
1199
+ ],
1200
+ riskWeight: 6,
1201
+ tags: ['css', 'variables', 'custom-properties', 'modern']
1202
+ },
1203
+ {
1204
+ id: 'css-124',
1205
+ name: 'Use min()/max()/clamp()',
1206
+ description: 'Use comparison functions for responsive values',
1207
+ type: 'ux',
1208
+ enabled: true,
1209
+ priority: 660,
1210
+ conditions: [
1211
+ { field: 'hasMediaQueryForSize', operator: 'equals', value: true }
1212
+ ],
1213
+ conditionLogic: 'all',
1214
+ actions: [
1215
+ { type: 'warn', message: 'Consider min()/max()/clamp() instead of media queries for responsive sizing' }
1216
+ ],
1217
+ riskWeight: 4,
1218
+ tags: ['css', 'responsive', 'clamp', 'modern']
1219
+ },
1220
+ {
1221
+ id: 'css-125',
1222
+ name: 'Use :is() for Grouping',
1223
+ description: 'Use :is() to reduce selector repetition',
1224
+ type: 'architecture',
1225
+ enabled: true,
1226
+ priority: 640,
1227
+ conditions: [
1228
+ { field: 'hasRepetitiveSelectorGroups', operator: 'equals', value: true }
1229
+ ],
1230
+ conditionLogic: 'all',
1231
+ actions: [
1232
+ { type: 'warn', message: 'Use :is() pseudo-class to group and simplify selectors' }
1233
+ ],
1234
+ riskWeight: 3,
1235
+ tags: ['css', 'selectors', 'is', 'modern']
1236
+ },
1237
+ // ============================================================================
1238
+ // CSS CONSISTENCY RULES (css-130 to css-149)
1239
+ // ============================================================================
1240
+ // --- Naming Convention Consistency ---
1241
+ {
1242
+ id: 'css-130',
1243
+ name: 'Enforce BEM Naming Convention',
1244
+ description: 'Ensure consistent BEM naming (block__element--modifier)',
1245
+ type: 'architecture',
1246
+ enabled: true,
1247
+ priority: 720,
1248
+ conditions: [
1249
+ { field: 'projectUsesBEM', operator: 'equals', value: true },
1250
+ { field: 'followsBEMPattern', operator: 'not_equals', value: true }
1251
+ ],
1252
+ conditionLogic: 'all',
1253
+ actions: [
1254
+ { type: 'warn', message: 'Class name does not follow BEM convention (block__element--modifier). Use .block, .block__element, or .block--modifier pattern.' }
1255
+ ],
1256
+ riskWeight: 8,
1257
+ tags: ['css', 'naming', 'bem', 'consistency']
1258
+ },
1259
+ {
1260
+ id: 'css-131',
1261
+ name: 'Enforce SMACSS Naming Convention',
1262
+ description: 'Ensure consistent SMACSS naming (l-, is-, js-, etc.)',
1263
+ type: 'architecture',
1264
+ enabled: true,
1265
+ priority: 720,
1266
+ conditions: [
1267
+ { field: 'projectUsesSMACSS', operator: 'equals', value: true },
1268
+ { field: 'followsSMACSPattern', operator: 'not_equals', value: true }
1269
+ ],
1270
+ conditionLogic: 'all',
1271
+ actions: [
1272
+ { type: 'warn', message: 'Class name does not follow SMACSS convention. Use prefixes: l- (layout), is- (state), js- (JavaScript hooks).' }
1273
+ ],
1274
+ riskWeight: 8,
1275
+ tags: ['css', 'naming', 'smacss', 'consistency']
1276
+ },
1277
+ {
1278
+ id: 'css-132',
1279
+ name: 'Enforce OOCSS Naming Convention',
1280
+ description: 'Ensure consistent OOCSS naming (object-oriented CSS)',
1281
+ type: 'architecture',
1282
+ enabled: true,
1283
+ priority: 720,
1284
+ conditions: [
1285
+ { field: 'projectUsesOOCSS', operator: 'equals', value: true },
1286
+ { field: 'followsOOCSSPattern', operator: 'not_equals', value: true }
1287
+ ],
1288
+ conditionLogic: 'all',
1289
+ actions: [
1290
+ { type: 'warn', message: 'Class name does not follow OOCSS convention. Separate structure from skin, container from content.' }
1291
+ ],
1292
+ riskWeight: 7,
1293
+ tags: ['css', 'naming', 'oocss', 'consistency']
1294
+ },
1295
+ {
1296
+ id: 'css-133',
1297
+ name: 'Enforce kebab-case for Class Names',
1298
+ description: 'Class names should use kebab-case (lowercase with hyphens)',
1299
+ type: 'architecture',
1300
+ enabled: true,
1301
+ priority: 700,
1302
+ conditions: [
1303
+ { field: 'hasNonKebabCaseName', operator: 'equals', value: true }
1304
+ ],
1305
+ conditionLogic: 'all',
1306
+ actions: [
1307
+ { type: 'warn', message: 'Class names should use kebab-case (e.g., .my-component not .myComponent or .my_component).' }
1308
+ ],
1309
+ riskWeight: 6,
1310
+ tags: ['css', 'naming', 'kebab-case', 'consistency']
1311
+ },
1312
+ {
1313
+ id: 'css-134',
1314
+ name: 'Consistent Selector Naming Pattern',
1315
+ description: 'Detect mixed naming conventions in the same stylesheet',
1316
+ type: 'architecture',
1317
+ enabled: true,
1318
+ priority: 750,
1319
+ conditions: [
1320
+ { field: 'hasMixedNamingPatterns', operator: 'equals', value: true }
1321
+ ],
1322
+ conditionLogic: 'all',
1323
+ actions: [
1324
+ { type: 'deny', message: 'Mixed naming conventions detected. Standardize on one convention (BEM, SMACSS, kebab-case) throughout the stylesheet.' }
1325
+ ],
1326
+ riskWeight: 15,
1327
+ tags: ['css', 'naming', 'consistency', 'architecture']
1328
+ },
1329
+ // --- Property Ordering Consistency ---
1330
+ {
1331
+ id: 'css-135',
1332
+ name: 'Enforce Property Ordering (Grouped)',
1333
+ description: 'Properties should be ordered by group: positioning, display, box model, typography, visual, misc',
1334
+ type: 'architecture',
1335
+ enabled: true,
1336
+ priority: 680,
1337
+ conditions: [
1338
+ { field: 'propertyOrderStyle', operator: 'equals', value: 'grouped' },
1339
+ { field: 'followsGroupedPropertyOrder', operator: 'not_equals', value: true }
1340
+ ],
1341
+ conditionLogic: 'all',
1342
+ actions: [
1343
+ { type: 'warn', message: 'Properties should be ordered by group: 1) Positioning (position, top, z-index), 2) Display (display, flex, grid), 3) Box Model (width, margin, padding), 4) Typography (font, color), 5) Visual (background, border), 6) Misc (cursor, overflow).' }
1344
+ ],
1345
+ riskWeight: 5,
1346
+ tags: ['css', 'property-order', 'consistency', 'grouped']
1347
+ },
1348
+ {
1349
+ id: 'css-136',
1350
+ name: 'Enforce Property Ordering (Alphabetical)',
1351
+ description: 'Properties should be ordered alphabetically',
1352
+ type: 'architecture',
1353
+ enabled: true,
1354
+ priority: 680,
1355
+ conditions: [
1356
+ { field: 'propertyOrderStyle', operator: 'equals', value: 'alphabetical' },
1357
+ { field: 'followsAlphabeticalPropertyOrder', operator: 'not_equals', value: true }
1358
+ ],
1359
+ conditionLogic: 'all',
1360
+ actions: [
1361
+ { type: 'warn', message: 'Properties should be ordered alphabetically for consistency.' }
1362
+ ],
1363
+ riskWeight: 5,
1364
+ tags: ['css', 'property-order', 'consistency', 'alphabetical']
1365
+ },
1366
+ {
1367
+ id: 'css-137',
1368
+ name: 'Inconsistent Property Ordering Pattern',
1369
+ description: 'Detect mixed property ordering styles in the same stylesheet',
1370
+ type: 'architecture',
1371
+ enabled: true,
1372
+ priority: 700,
1373
+ conditions: [
1374
+ { field: 'hasMixedPropertyOrdering', operator: 'equals', value: true }
1375
+ ],
1376
+ conditionLogic: 'all',
1377
+ actions: [
1378
+ { type: 'warn', message: 'Mixed property ordering detected. Choose one style (grouped or alphabetical) and apply consistently.' }
1379
+ ],
1380
+ riskWeight: 8,
1381
+ tags: ['css', 'property-order', 'consistency']
1382
+ },
1383
+ // --- Unit Consistency ---
1384
+ {
1385
+ id: 'css-138',
1386
+ name: 'Consistent Font Size Units',
1387
+ description: 'Font sizes should use consistent units (rem preferred)',
1388
+ type: 'ux',
1389
+ enabled: true,
1390
+ priority: 780,
1391
+ conditions: [
1392
+ { field: 'hasMixedFontSizeUnits', operator: 'equals', value: true }
1393
+ ],
1394
+ conditionLogic: 'all',
1395
+ actions: [
1396
+ { type: 'warn', message: 'Mixed font-size units detected. Use rem consistently for accessibility (allows user font scaling).' }
1397
+ ],
1398
+ riskWeight: 10,
1399
+ tags: ['css', 'units', 'consistency', 'font-size', 'accessibility']
1400
+ },
1401
+ {
1402
+ id: 'css-139',
1403
+ name: 'Consistent Spacing Units',
1404
+ description: 'Spacing (margin, padding, gap) should use consistent units',
1405
+ type: 'architecture',
1406
+ enabled: true,
1407
+ priority: 740,
1408
+ conditions: [
1409
+ { field: 'hasMixedSpacingUnits', operator: 'equals', value: true }
1410
+ ],
1411
+ conditionLogic: 'all',
1412
+ actions: [
1413
+ { type: 'warn', message: 'Mixed spacing units detected (px, rem, em). Standardize on rem or design system tokens for consistent spacing scale.' }
1414
+ ],
1415
+ riskWeight: 8,
1416
+ tags: ['css', 'units', 'consistency', 'spacing']
1417
+ },
1418
+ {
1419
+ id: 'css-140',
1420
+ name: 'Consistent Line Height Units',
1421
+ description: 'Line heights should use unitless values or consistent units',
1422
+ type: 'ux',
1423
+ enabled: true,
1424
+ priority: 720,
1425
+ conditions: [
1426
+ { field: 'hasMixedLineHeightUnits', operator: 'equals', value: true }
1427
+ ],
1428
+ conditionLogic: 'all',
1429
+ actions: [
1430
+ { type: 'warn', message: 'Mixed line-height units detected. Use unitless values (e.g., 1.5) for predictable scaling with font-size changes.' }
1431
+ ],
1432
+ riskWeight: 7,
1433
+ tags: ['css', 'units', 'consistency', 'line-height', 'typography']
1434
+ },
1435
+ {
1436
+ id: 'css-141',
1437
+ name: 'Consistent Border Width Units',
1438
+ description: 'Border widths should use consistent units',
1439
+ type: 'architecture',
1440
+ enabled: true,
1441
+ priority: 660,
1442
+ conditions: [
1443
+ { field: 'hasMixedBorderWidthUnits', operator: 'equals', value: true }
1444
+ ],
1445
+ conditionLogic: 'all',
1446
+ actions: [
1447
+ { type: 'warn', message: 'Mixed border-width units detected. Use px for thin borders or design tokens for consistency.' }
1448
+ ],
1449
+ riskWeight: 5,
1450
+ tags: ['css', 'units', 'consistency', 'border']
1451
+ },
1452
+ {
1453
+ id: 'css-142',
1454
+ name: 'Use Zero Without Units',
1455
+ description: 'Zero values should not have units (0 not 0px)',
1456
+ type: 'architecture',
1457
+ enabled: true,
1458
+ priority: 650,
1459
+ conditions: [
1460
+ { field: 'hasZeroWithUnits', operator: 'equals', value: true }
1461
+ ],
1462
+ conditionLogic: 'all',
1463
+ actions: [
1464
+ { type: 'warn', message: 'Zero values should be unitless (0 not 0px, 0rem). This reduces file size and is the recommended practice.' }
1465
+ ],
1466
+ riskWeight: 3,
1467
+ tags: ['css', 'units', 'consistency', 'zero']
1468
+ },
1469
+ // --- Color Format Consistency ---
1470
+ {
1471
+ id: 'css-143',
1472
+ name: 'Consistent Color Format (Hex)',
1473
+ description: 'Colors should use consistent format (hex preferred)',
1474
+ type: 'architecture',
1475
+ enabled: true,
1476
+ priority: 720,
1477
+ conditions: [
1478
+ { field: 'projectColorFormat', operator: 'equals', value: 'hex' },
1479
+ { field: 'usesNonHexColor', operator: 'equals', value: true }
1480
+ ],
1481
+ conditionLogic: 'all',
1482
+ actions: [
1483
+ { type: 'warn', message: 'Non-hex color format detected. Use hex format (#rgb or #rrggbb) consistently for this project.' }
1484
+ ],
1485
+ riskWeight: 6,
1486
+ tags: ['css', 'colors', 'consistency', 'hex']
1487
+ },
1488
+ {
1489
+ id: 'css-144',
1490
+ name: 'Consistent Color Format (RGB/RGBA)',
1491
+ description: 'Colors should use consistent format (rgb/rgba preferred)',
1492
+ type: 'architecture',
1493
+ enabled: true,
1494
+ priority: 720,
1495
+ conditions: [
1496
+ { field: 'projectColorFormat', operator: 'equals', value: 'rgb' },
1497
+ { field: 'usesNonRgbColor', operator: 'equals', value: true }
1498
+ ],
1499
+ conditionLogic: 'all',
1500
+ actions: [
1501
+ { type: 'warn', message: 'Non-rgb color format detected. Use rgb()/rgba() format consistently for this project.' }
1502
+ ],
1503
+ riskWeight: 6,
1504
+ tags: ['css', 'colors', 'consistency', 'rgb']
1505
+ },
1506
+ {
1507
+ id: 'css-145',
1508
+ name: 'Consistent Color Format (HSL/HSLA)',
1509
+ description: 'Colors should use consistent format (hsl/hsla preferred)',
1510
+ type: 'architecture',
1511
+ enabled: true,
1512
+ priority: 720,
1513
+ conditions: [
1514
+ { field: 'projectColorFormat', operator: 'equals', value: 'hsl' },
1515
+ { field: 'usesNonHslColor', operator: 'equals', value: true }
1516
+ ],
1517
+ conditionLogic: 'all',
1518
+ actions: [
1519
+ { type: 'warn', message: 'Non-hsl color format detected. Use hsl()/hsla() format consistently for this project.' }
1520
+ ],
1521
+ riskWeight: 6,
1522
+ tags: ['css', 'colors', 'consistency', 'hsl']
1523
+ },
1524
+ {
1525
+ id: 'css-146',
1526
+ name: 'Mixed Color Formats Detected',
1527
+ description: 'Detect inconsistent color formats in the same stylesheet',
1528
+ type: 'architecture',
1529
+ enabled: true,
1530
+ priority: 750,
1531
+ conditions: [
1532
+ { field: 'hasMixedColorFormats', operator: 'equals', value: true }
1533
+ ],
1534
+ conditionLogic: 'all',
1535
+ actions: [
1536
+ { type: 'warn', message: 'Mixed color formats detected (hex, rgb, hsl). Standardize on one format for maintainability. Consider HSL for easier color manipulation.' }
1537
+ ],
1538
+ riskWeight: 10,
1539
+ tags: ['css', 'colors', 'consistency', 'format']
1540
+ },
1541
+ {
1542
+ id: 'css-147',
1543
+ name: 'Use Modern Color Syntax',
1544
+ description: 'Use modern color syntax (rgb/hsl without commas)',
1545
+ type: 'architecture',
1546
+ enabled: true,
1547
+ priority: 650,
1548
+ conditions: [
1549
+ { field: 'usesLegacyColorSyntax', operator: 'equals', value: true }
1550
+ ],
1551
+ conditionLogic: 'all',
1552
+ actions: [
1553
+ { type: 'warn', message: 'Consider modern color syntax: rgb(255 0 0 / 50%) instead of rgba(255, 0, 0, 0.5) for cleaner code.' }
1554
+ ],
1555
+ riskWeight: 3,
1556
+ tags: ['css', 'colors', 'consistency', 'modern']
1557
+ },
1558
+ {
1559
+ id: 'css-148',
1560
+ name: 'Use Hex Shorthand When Possible',
1561
+ description: 'Use 3-character hex when possible (#fff not #ffffff)',
1562
+ type: 'architecture',
1563
+ enabled: true,
1564
+ priority: 620,
1565
+ conditions: [
1566
+ { field: 'hasExpandableHex', operator: 'equals', value: true }
1567
+ ],
1568
+ conditionLogic: 'all',
1569
+ actions: [
1570
+ { type: 'warn', message: 'Use shorthand hex when possible (#fff instead of #ffffff) for conciseness.' }
1571
+ ],
1572
+ riskWeight: 2,
1573
+ tags: ['css', 'colors', 'consistency', 'hex', 'shorthand']
1574
+ },
1575
+ // --- Vendor Prefix Consistency ---
1576
+ {
1577
+ id: 'css-149',
1578
+ name: 'Consistent Vendor Prefix Ordering',
1579
+ description: 'Vendor prefixes should be ordered consistently (-webkit, -moz, -ms, unprefixed)',
1580
+ type: 'architecture',
1581
+ enabled: true,
1582
+ priority: 700,
1583
+ conditions: [
1584
+ { field: 'hasVendorPrefix', operator: 'equals', value: true },
1585
+ { field: 'hasInconsistentPrefixOrder', operator: 'equals', value: true }
1586
+ ],
1587
+ conditionLogic: 'all',
1588
+ actions: [
1589
+ { type: 'warn', message: 'Vendor prefixes should be ordered: -webkit-, -moz-, -ms-, then unprefixed standard property last.' }
1590
+ ],
1591
+ riskWeight: 6,
1592
+ tags: ['css', 'vendor-prefix', 'consistency', 'order']
1593
+ },
1594
+ {
1595
+ id: 'css-150',
1596
+ name: 'Missing Standard Property After Vendor Prefix',
1597
+ description: 'Vendor-prefixed properties must include the unprefixed version',
1598
+ type: 'architecture',
1599
+ enabled: true,
1600
+ priority: 780,
1601
+ conditions: [
1602
+ { field: 'hasVendorPrefix', operator: 'equals', value: true },
1603
+ { field: 'hasMissingUnprefixedProperty', operator: 'equals', value: true }
1604
+ ],
1605
+ conditionLogic: 'all',
1606
+ actions: [
1607
+ { type: 'deny', message: 'Vendor-prefixed property missing unprefixed fallback. Always include the standard property for future compatibility.' }
1608
+ ],
1609
+ riskWeight: 15,
1610
+ tags: ['css', 'vendor-prefix', 'consistency', 'fallback']
1611
+ },
1612
+ {
1613
+ id: 'css-151',
1614
+ name: 'Incomplete Vendor Prefix Set',
1615
+ description: 'When using vendor prefixes, include all relevant prefixes',
1616
+ type: 'architecture',
1617
+ enabled: true,
1618
+ priority: 720,
1619
+ conditions: [
1620
+ { field: 'hasVendorPrefix', operator: 'equals', value: true },
1621
+ { field: 'hasIncompletePrefixSet', operator: 'equals', value: true }
1622
+ ],
1623
+ conditionLogic: 'all',
1624
+ actions: [
1625
+ { type: 'warn', message: 'Incomplete vendor prefix set. Consider using autoprefixer or include all necessary prefixes (-webkit-, -moz-, -ms-).' }
1626
+ ],
1627
+ riskWeight: 8,
1628
+ tags: ['css', 'vendor-prefix', 'consistency', 'complete']
1629
+ },
1630
+ {
1631
+ id: 'css-152',
1632
+ name: 'Deprecated Vendor Prefix',
1633
+ description: 'Avoid vendor prefixes that are no longer needed',
1634
+ type: 'architecture',
1635
+ enabled: true,
1636
+ priority: 700,
1637
+ conditions: [
1638
+ { field: 'hasDeprecatedVendorPrefix', operator: 'equals', value: true }
1639
+ ],
1640
+ conditionLogic: 'all',
1641
+ actions: [
1642
+ { type: 'warn', message: 'Deprecated vendor prefix detected. This prefix is no longer needed for modern browsers (flexbox, border-radius, box-shadow, etc.).' }
1643
+ ],
1644
+ riskWeight: 5,
1645
+ tags: ['css', 'vendor-prefix', 'deprecated', 'cleanup']
1646
+ },
1647
+ // --- Design Token Validation ---
1648
+ {
1649
+ id: 'css-153',
1650
+ name: 'Validate Against Design Tokens',
1651
+ description: 'Property values should match design system tokens',
1652
+ type: 'ux',
1653
+ enabled: true,
1654
+ priority: 800,
1655
+ conditions: [
1656
+ { field: 'hasDesignTokens', operator: 'equals', value: true },
1657
+ { field: 'valueMatchesDesignToken', operator: 'not_equals', value: true }
1658
+ ],
1659
+ conditionLogic: 'all',
1660
+ actions: [
1661
+ { type: 'warn', message: 'Value does not match design tokens. Use design system values for consistency (colors, spacing, typography).' }
1662
+ ],
1663
+ riskWeight: 12,
1664
+ tags: ['css', 'design-tokens', 'consistency', 'design-system']
1665
+ },
1666
+ {
1667
+ id: 'css-154',
1668
+ name: 'Non-Standard Spacing Value',
1669
+ description: 'Spacing values should match the spacing scale',
1670
+ type: 'architecture',
1671
+ enabled: true,
1672
+ priority: 750,
1673
+ conditions: [
1674
+ { field: 'hasSpacingScale', operator: 'equals', value: true },
1675
+ { field: 'spacingMatchesScale', operator: 'not_equals', value: true }
1676
+ ],
1677
+ conditionLogic: 'all',
1678
+ actions: [
1679
+ { type: 'warn', message: 'Spacing value does not match the spacing scale. Use standard increments (4px, 8px, 16px, 24px, 32px, etc.) or design tokens.' }
1680
+ ],
1681
+ riskWeight: 8,
1682
+ tags: ['css', 'spacing', 'consistency', 'design-tokens']
1683
+ },
1684
+ {
1685
+ id: 'css-155',
1686
+ name: 'Non-Standard Font Size',
1687
+ description: 'Font sizes should match the type scale',
1688
+ type: 'ux',
1689
+ enabled: true,
1690
+ priority: 760,
1691
+ conditions: [
1692
+ { field: 'hasTypeScale', operator: 'equals', value: true },
1693
+ { field: 'fontSizeMatchesScale', operator: 'not_equals', value: true }
1694
+ ],
1695
+ conditionLogic: 'all',
1696
+ actions: [
1697
+ { type: 'warn', message: 'Font size does not match the type scale. Use standard sizes (12px, 14px, 16px, 18px, 20px, 24px, etc.) or design tokens.' }
1698
+ ],
1699
+ riskWeight: 8,
1700
+ tags: ['css', 'typography', 'consistency', 'design-tokens']
1701
+ },
1702
+ // --- CSS Linting Integration Suggestions ---
1703
+ {
1704
+ id: 'css-156',
1705
+ name: 'Suggest Stylelint Integration',
1706
+ description: 'Recommend Stylelint for automated CSS linting',
1707
+ type: 'architecture',
1708
+ enabled: true,
1709
+ priority: 650,
1710
+ conditions: [
1711
+ { field: 'hasStylelintConfig', operator: 'not_equals', value: true },
1712
+ { field: 'cssFileCount', operator: 'greater_than', value: 5 }
1713
+ ],
1714
+ conditionLogic: 'all',
1715
+ actions: [
1716
+ { type: 'warn', message: 'Consider adding Stylelint for automated CSS linting. Create .stylelintrc.json with rules for naming, ordering, and format consistency.' }
1717
+ ],
1718
+ riskWeight: 5,
1719
+ tags: ['css', 'linting', 'stylelint', 'tooling']
1720
+ },
1721
+ {
1722
+ id: 'css-157',
1723
+ name: 'Suggest CSS Modules or Scoped Styles',
1724
+ description: 'Recommend scoped CSS for component isolation',
1725
+ type: 'architecture',
1726
+ enabled: true,
1727
+ priority: 680,
1728
+ conditions: [
1729
+ { field: 'hasComponentArchitecture', operator: 'equals', value: true },
1730
+ { field: 'usesScopedStyles', operator: 'not_equals', value: true }
1731
+ ],
1732
+ conditionLogic: 'all',
1733
+ actions: [
1734
+ { type: 'warn', message: 'Consider CSS Modules or scoped styles for component isolation. This prevents naming conflicts and improves maintainability.' }
1735
+ ],
1736
+ riskWeight: 6,
1737
+ tags: ['css', 'architecture', 'css-modules', 'scoped']
1738
+ },
1739
+ {
1740
+ id: 'css-158',
1741
+ name: 'Suggest PostCSS for Processing',
1742
+ description: 'Recommend PostCSS for CSS processing and transformation',
1743
+ type: 'architecture',
1744
+ enabled: true,
1745
+ priority: 640,
1746
+ conditions: [
1747
+ { field: 'hasPostCSSConfig', operator: 'not_equals', value: true },
1748
+ { field: 'hasVendorPrefix', operator: 'equals', value: true }
1749
+ ],
1750
+ conditionLogic: 'all',
1751
+ actions: [
1752
+ { type: 'warn', message: 'Consider using PostCSS with autoprefixer to automatically handle vendor prefixes. This ensures consistent prefix handling.' }
1753
+ ],
1754
+ riskWeight: 4,
1755
+ tags: ['css', 'tooling', 'postcss', 'autoprefixer']
1756
+ },
1757
+ {
1758
+ id: 'css-159',
1759
+ name: 'Suggest Prettier for CSS Formatting',
1760
+ description: 'Recommend Prettier for consistent CSS formatting',
1761
+ type: 'architecture',
1762
+ enabled: true,
1763
+ priority: 620,
1764
+ conditions: [
1765
+ { field: 'hasPrettierConfig', operator: 'not_equals', value: true },
1766
+ { field: 'hasInconsistentFormatting', operator: 'equals', value: true }
1767
+ ],
1768
+ conditionLogic: 'all',
1769
+ actions: [
1770
+ { type: 'warn', message: 'Consider using Prettier for consistent CSS formatting. This enforces property ordering, spacing, and formatting automatically.' }
1771
+ ],
1772
+ riskWeight: 3,
1773
+ tags: ['css', 'tooling', 'prettier', 'formatting']
1774
+ }
1775
+ ];
1776
+ export default cssRules;
1777
+ //# sourceMappingURL=css.js.map