@tidyfactor/design 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tidyfactor +52 -0
- package/AGENTS.md +75 -0
- package/CHANGELOG.md +210 -0
- package/LICENSE +17 -0
- package/README.ar.md +398 -0
- package/README.de.md +44 -0
- package/README.es.md +44 -0
- package/README.fa.md +44 -0
- package/README.fr.md +44 -0
- package/README.md +418 -0
- package/README.pt.md +44 -0
- package/README.zh.md +44 -0
- package/SKILL-REGISTRY.md +69 -0
- package/SKILL.md +46 -0
- package/VISION.md +43 -0
- package/assets/blog.png +0 -0
- package/assets/content_layout.png +0 -0
- package/assets/content_output.png +0 -0
- package/assets/dark.png +0 -0
- package/assets/dashboard_layout.png +0 -0
- package/assets/dashboard_output.png +0 -0
- package/assets/ecommerce_layout.png +0 -0
- package/assets/ecommerce_output.png +0 -0
- package/assets/github-social-preview-2.png +0 -0
- package/assets/github-social-preview.png +0 -0
- package/assets/hero-banner.png +0 -0
- package/assets/light.png +0 -0
- package/assets/media_layout.png +0 -0
- package/assets/media_output.png +0 -0
- package/assets/og-default.png +0 -0
- package/assets/video.png +0 -0
- package/bin/add-skill.js +31 -0
- package/bin/create-kit.js +372 -0
- package/bin/remove-skill.js +137 -0
- package/brand.json +279 -0
- package/memory/01-design-schools.md +85 -0
- package/memory/02-design-tokens.md +41 -0
- package/memory/03-narrative-conversion.md +47 -0
- package/memory/04-motion-principles.md +44 -0
- package/memory/05-component-anatomy.md +34 -0
- package/memory/06-quality-bar.md +83 -0
- package/memory/07-consistency-contract.md +33 -0
- package/memory/08-arabic-bilingual.md +54 -0
- package/memory/09-prototype-flow.md +36 -0
- package/memory/10-python-tooling.md +64 -0
- package/memory/11-brand-json-v2.md +86 -0
- package/memory/12-typography-matrix.md +31 -0
- package/memory/13-layout-archetypes.md +30 -0
- package/memory/14-nav-footer-catalog.md +26 -0
- package/memory/15-performance-budget.md +18 -0
- package/memory/16-design-movements-guide.md +1084 -0
- package/memory/17-storytelling-industries-ux.md +143 -0
- package/memory/18-design-decision-engine.md +81 -0
- package/package.json +64 -0
- package/references/commands/_template.md +27 -0
- package/references/commands/assets.md +35 -0
- package/references/commands/audit.md +15 -0
- package/references/commands/brand.md +85 -0
- package/references/commands/brief.md +107 -0
- package/references/commands/clone.md +26 -0
- package/references/commands/components.md +46 -0
- package/references/commands/dashboard.md +45 -0
- package/references/commands/deploy.md +45 -0
- package/references/commands/flow.md +44 -0
- package/references/commands/handoff.md +53 -0
- package/references/commands/i18n.md +64 -0
- package/references/commands/init.md +30 -0
- package/references/commands/layout.md +81 -0
- package/references/commands/motion.md +62 -0
- package/references/commands/nav-footer.md +54 -0
- package/references/commands/page.md +45 -0
- package/references/commands/palette.md +35 -0
- package/references/commands/perf.md +57 -0
- package/references/commands/retrofit.md +15 -0
- package/references/commands/school.md +41 -0
- package/references/commands/states.md +48 -0
- package/references/commands/study.md +98 -0
- package/references/commands/tokens.md +45 -0
- package/references/commands/typography.md +87 -0
- package/references/foundations/daisyui.md +44 -0
- package/references/foundations/hybrid.md +32 -0
- package/references/foundations/native.md +31 -0
- package/references/foundations/tailwind-utility.md +43 -0
- package/references/memory/01-design-schools.md +85 -0
- package/references/memory/02-design-tokens.md +41 -0
- package/references/memory/03-narrative-conversion.md +47 -0
- package/references/memory/04-motion-principles.md +44 -0
- package/references/memory/05-component-anatomy.md +34 -0
- package/references/memory/06-quality-bar.md +83 -0
- package/references/memory/07-consistency-contract.md +33 -0
- package/references/memory/08-arabic-bilingual.md +54 -0
- package/references/memory/09-prototype-flow.md +36 -0
- package/references/memory/10-python-tooling.md +64 -0
- package/references/memory/11-brand-json-v2.md +86 -0
- package/references/memory/12-typography-matrix.md +31 -0
- package/references/memory/13-layout-archetypes.md +30 -0
- package/references/memory/14-nav-footer-catalog.md +26 -0
- package/references/memory/15-performance-budget.md +18 -0
- package/references/memory/16-design-movements-guide.md +1084 -0
- package/references/memory/17-storytelling-industries-ux.md +143 -0
- package/references/memory/18-design-decision-engine.md +81 -0
- package/references/memory/architecture.md +39 -0
- package/references/memory/decision-points.md +50 -0
- package/references/memory/foundations.md +15 -0
- package/references/memory/quality-bar.md +20 -0
- package/references/tidyfactor-vision.md +66 -0
- package/references/workflow.md +49 -0
- package/references/workflows/audit-prototype.md +26 -0
- package/references/workflows/brief.md +30 -0
- package/references/workflows/clone-prototype.md +27 -0
- package/references/workflows/init-prototype.md +28 -0
- package/references/workflows/retrofit-prototype.md +25 -0
- package/scripts/__pycache__/_utils.cpython-312.pyc +0 -0
- package/scripts/_utils.py +60 -0
- package/scripts/build.py +194 -0
- package/scripts/check_alpha.py +52 -0
- package/scripts/extract_palette.py +139 -0
- package/scripts/generate_transitions.py +105 -0
- package/scripts/inspect_images.py +48 -0
- package/scripts/minify_assets.py +140 -0
- package/scripts/optimize_assets.py +91 -0
- package/scripts/optimize_images.py +176 -0
- package/scripts/prepare_images.py +67 -0
- package/scripts/remove_backgrounds.py +61 -0
- package/scripts/test_build.py +228 -0
- package/templates/design-system/base.css +75 -0
- package/templates/design-system/components.css +229 -0
- package/templates/design-system/interactions.js +31 -0
- package/templates/design-system/motion.js +42 -0
- package/templates/design-system/tokens.css +81 -0
- package/templates/design-system/utilities.css +47 -0
- package/templates/index.html +84 -0
- package/templates/proto-nav.js +56 -0
- package/tools/build-skill.js +126 -0
- package/tools/validate-skill.js +144 -0
- package/tools/validate_skill.py +121 -0
package/brand.json
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "TidyFactor Design",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"schemaVersion": "brand-core-v2",
|
|
5
|
+
"meta": {
|
|
6
|
+
"product": "TidyFactor Design System",
|
|
7
|
+
"tagline": "Code-Native Interactive Prototyping Engine",
|
|
8
|
+
"description": "A zero-bundler, framework-free design system and UI prototyping engine with pluggable CSS foundations and full Arabic/RTL support.",
|
|
9
|
+
"version": "1.4.0",
|
|
10
|
+
"lastUpdated": "2026-08-25"
|
|
11
|
+
},
|
|
12
|
+
"identity": {
|
|
13
|
+
"logo": {
|
|
14
|
+
"full": "assets/logo.svg",
|
|
15
|
+
"fullDark": "assets/logo-dark.svg",
|
|
16
|
+
"mark": "assets/logo-mark.svg",
|
|
17
|
+
"favicon": "assets/favicon.svg",
|
|
18
|
+
"minClearSpace": "1x logo-mark height on all sides",
|
|
19
|
+
"minSizePx": 24
|
|
20
|
+
},
|
|
21
|
+
"socialPreview": {
|
|
22
|
+
"ogImage": "assets/og-default.png",
|
|
23
|
+
"ogDimensions": "1200x630"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"voice": {
|
|
27
|
+
"tone": "confident, direct, teacher-not-salesperson",
|
|
28
|
+
"personality": [
|
|
29
|
+
"direct",
|
|
30
|
+
"practical",
|
|
31
|
+
"warm",
|
|
32
|
+
"no-fluff"
|
|
33
|
+
],
|
|
34
|
+
"registers": {
|
|
35
|
+
"professional": "Direct, precise, clear, task-focused for transactions and settings",
|
|
36
|
+
"casual": "Warm, encouraging, inviting for onboarding and feature discovery",
|
|
37
|
+
"error": "Empathetic, clear fix provided, zero blame",
|
|
38
|
+
"success": "Celebratory, concise, clear next step"
|
|
39
|
+
},
|
|
40
|
+
"readingLevel": "plain language, avoid jargon unless audience is technical",
|
|
41
|
+
"doNotUse": [
|
|
42
|
+
"synergy",
|
|
43
|
+
"leverage (as a verb)",
|
|
44
|
+
"revolutionary",
|
|
45
|
+
"game-changing",
|
|
46
|
+
"simply/just/easily"
|
|
47
|
+
],
|
|
48
|
+
"preferredPerson": "second person (you)"
|
|
49
|
+
},
|
|
50
|
+
"colors": {
|
|
51
|
+
"light": {
|
|
52
|
+
"background": "#FFFFFF",
|
|
53
|
+
"surface": "#F8FAFC",
|
|
54
|
+
"surface2": "#F1F5F9",
|
|
55
|
+
"border": "#E2E8F0",
|
|
56
|
+
"text": "#0F172A",
|
|
57
|
+
"textMuted": "#64748B",
|
|
58
|
+
"primary": "#4F46E5",
|
|
59
|
+
"primaryForeground": "#FFFFFF",
|
|
60
|
+
"secondary": "#06B6D4",
|
|
61
|
+
"secondaryForeground": "#FFFFFF",
|
|
62
|
+
"accent": "#F59E0B",
|
|
63
|
+
"success": "#12B76A",
|
|
64
|
+
"warning": "#F79009",
|
|
65
|
+
"danger": "#EF4444",
|
|
66
|
+
"info": "#4F46E5",
|
|
67
|
+
"codeBackground": "#F8FAFC"
|
|
68
|
+
},
|
|
69
|
+
"dark": {
|
|
70
|
+
"background": "#0F172A",
|
|
71
|
+
"surface": "#1E293B",
|
|
72
|
+
"surface2": "#334155",
|
|
73
|
+
"border": "#475569",
|
|
74
|
+
"text": "#F8FAFC",
|
|
75
|
+
"textMuted": "#94A3B8",
|
|
76
|
+
"primary": "#818CF8",
|
|
77
|
+
"primaryForeground": "#0F172A",
|
|
78
|
+
"secondary": "#22D3EE",
|
|
79
|
+
"secondaryForeground": "#0F172A",
|
|
80
|
+
"accent": "#FBBF24",
|
|
81
|
+
"success": "#34D399",
|
|
82
|
+
"warning": "#FBBF24",
|
|
83
|
+
"danger": "#F87171",
|
|
84
|
+
"info": "#818CF8",
|
|
85
|
+
"codeBackground": "#1E293B"
|
|
86
|
+
},
|
|
87
|
+
"chartPalette": [
|
|
88
|
+
"#4F46E5",
|
|
89
|
+
"#06B6D4",
|
|
90
|
+
"#F59E0B",
|
|
91
|
+
"#12B76A",
|
|
92
|
+
"#EF4444",
|
|
93
|
+
"#8B5CF6"
|
|
94
|
+
],
|
|
95
|
+
"contrastPolicy": "WCAG AA minimum (4.5:1 body text, 3:1 large text/UI) in both light and dark themes"
|
|
96
|
+
},
|
|
97
|
+
"typography": {
|
|
98
|
+
"families": {
|
|
99
|
+
"heading": {
|
|
100
|
+
"primary": "El Messiri",
|
|
101
|
+
"fallback": "Georgia, serif"
|
|
102
|
+
},
|
|
103
|
+
"body": {
|
|
104
|
+
"primary": "Tajawal",
|
|
105
|
+
"fallback": "Inter, system-ui, sans-serif"
|
|
106
|
+
},
|
|
107
|
+
"display": {
|
|
108
|
+
"primary": "Outfit",
|
|
109
|
+
"fallback": "system-ui, sans-serif"
|
|
110
|
+
},
|
|
111
|
+
"mono": {
|
|
112
|
+
"primary": "JetBrains Mono",
|
|
113
|
+
"fallback": "Menlo, monospace"
|
|
114
|
+
},
|
|
115
|
+
"arabicHeading": "El Messiri",
|
|
116
|
+
"arabicBody": "Tajawal"
|
|
117
|
+
},
|
|
118
|
+
"weights": {
|
|
119
|
+
"light": 300,
|
|
120
|
+
"regular": 400,
|
|
121
|
+
"medium": 500,
|
|
122
|
+
"semibold": 600,
|
|
123
|
+
"bold": 700
|
|
124
|
+
},
|
|
125
|
+
"scale": {
|
|
126
|
+
"xs": "12px",
|
|
127
|
+
"sm": "14px",
|
|
128
|
+
"base": "16px",
|
|
129
|
+
"lg": "18px",
|
|
130
|
+
"xl": "20px",
|
|
131
|
+
"2xl": "24px",
|
|
132
|
+
"3xl": "30px",
|
|
133
|
+
"4xl": "36px",
|
|
134
|
+
"5xl": "48px",
|
|
135
|
+
"6xl": "60px"
|
|
136
|
+
},
|
|
137
|
+
"lineHeight": {
|
|
138
|
+
"tight": 1.2,
|
|
139
|
+
"normal": 1.5,
|
|
140
|
+
"relaxed": 1.75
|
|
141
|
+
},
|
|
142
|
+
"letterSpacing": {
|
|
143
|
+
"tight": "-0.02em",
|
|
144
|
+
"normal": "0",
|
|
145
|
+
"wide": "0.02em"
|
|
146
|
+
},
|
|
147
|
+
"googleFontsUrl": "https://fonts.googleapis.com/css2?family=El+Messiri:wght@400;600;700&family=Outfit:wght@400;500;600;700&family=Tajawal:wght@300;400;500;700&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
148
|
+
},
|
|
149
|
+
"spacing": {
|
|
150
|
+
"baseUnit": "4px",
|
|
151
|
+
"scale": {
|
|
152
|
+
"0": "0px",
|
|
153
|
+
"1": "4px",
|
|
154
|
+
"2": "8px",
|
|
155
|
+
"3": "12px",
|
|
156
|
+
"4": "16px",
|
|
157
|
+
"6": "24px",
|
|
158
|
+
"8": "32px",
|
|
159
|
+
"12": "48px",
|
|
160
|
+
"16": "64px",
|
|
161
|
+
"24": "96px"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"radius": {
|
|
165
|
+
"none": "0px",
|
|
166
|
+
"sm": "6px",
|
|
167
|
+
"md": "12px",
|
|
168
|
+
"lg": "16px",
|
|
169
|
+
"xl": "24px",
|
|
170
|
+
"full": "9999px",
|
|
171
|
+
"default": "12px"
|
|
172
|
+
},
|
|
173
|
+
"shadows": {
|
|
174
|
+
"sm": "0 1px 2px rgba(0,0,0,0.06)",
|
|
175
|
+
"md": "0 4px 12px rgba(0,0,0,0.10)",
|
|
176
|
+
"lg": "0 12px 32px rgba(0,0,0,0.16)",
|
|
177
|
+
"focusRing": "0 0 0 3px color-mix(in srgb, var(--primary) 40%, transparent)"
|
|
178
|
+
},
|
|
179
|
+
"motion": {
|
|
180
|
+
"duration": {
|
|
181
|
+
"fast": "120ms",
|
|
182
|
+
"base": "200ms",
|
|
183
|
+
"slow": "400ms"
|
|
184
|
+
},
|
|
185
|
+
"easing": {
|
|
186
|
+
"standard": "cubic-bezier(0.4,0,0.2,1)",
|
|
187
|
+
"emphasized": "cubic-bezier(0.2,0,0,1)",
|
|
188
|
+
"spring": "cubic-bezier(0.34,1.56,0.64,1)"
|
|
189
|
+
},
|
|
190
|
+
"reducedMotion": "honor prefers-reduced-motion: disable scroll-driven and parallax effects, keep only opacity/color transitions",
|
|
191
|
+
"scope": "cinematic/scroll-driven motion is reserved for marketing surfaces only — never in docs, dashboard, or transactional UI"
|
|
192
|
+
},
|
|
193
|
+
"breakpoints": {
|
|
194
|
+
"sm": "640px",
|
|
195
|
+
"md": "768px",
|
|
196
|
+
"lg": "1024px",
|
|
197
|
+
"xl": "1280px",
|
|
198
|
+
"2xl": "1536px"
|
|
199
|
+
},
|
|
200
|
+
"iconography": {
|
|
201
|
+
"set": "lucide",
|
|
202
|
+
"strokeWidth": 1.75,
|
|
203
|
+
"sizes": {
|
|
204
|
+
"sm": "16px",
|
|
205
|
+
"md": "20px",
|
|
206
|
+
"lg": "24px"
|
|
207
|
+
},
|
|
208
|
+
"rule": "never mix icon sets on the same surface"
|
|
209
|
+
},
|
|
210
|
+
"components": {
|
|
211
|
+
"button": {
|
|
212
|
+
"radius": "radius.md",
|
|
213
|
+
"paddingX": "spacing.4",
|
|
214
|
+
"paddingY": "spacing.2",
|
|
215
|
+
"primaryBg": "colors.primary",
|
|
216
|
+
"primaryFg": "colors.primaryForeground",
|
|
217
|
+
"hoverOpacity": 0.9,
|
|
218
|
+
"disabledOpacity": 0.5
|
|
219
|
+
},
|
|
220
|
+
"input": {
|
|
221
|
+
"radius": "radius.sm",
|
|
222
|
+
"border": "colors.border",
|
|
223
|
+
"focusRing": "shadows.focusRing",
|
|
224
|
+
"background": "colors.surface"
|
|
225
|
+
},
|
|
226
|
+
"card": {
|
|
227
|
+
"radius": "radius.lg",
|
|
228
|
+
"border": "colors.border",
|
|
229
|
+
"background": "colors.surface",
|
|
230
|
+
"shadow": "shadows.sm"
|
|
231
|
+
},
|
|
232
|
+
"codeBlock": {
|
|
233
|
+
"background": "colors.codeBackground",
|
|
234
|
+
"radius": "radius.md",
|
|
235
|
+
"fontFamily": "typography.families.mono"
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
"localization": {
|
|
239
|
+
"defaultLocale": "en",
|
|
240
|
+
"supportedLocales": [
|
|
241
|
+
"en",
|
|
242
|
+
"ar"
|
|
243
|
+
],
|
|
244
|
+
"rtl": true,
|
|
245
|
+
"rtlLocales": [
|
|
246
|
+
"ar"
|
|
247
|
+
],
|
|
248
|
+
"mirrorOnRtl": [
|
|
249
|
+
"sidebar",
|
|
250
|
+
"breadcrumb",
|
|
251
|
+
"tableOfContents",
|
|
252
|
+
"iconsWithDirection"
|
|
253
|
+
],
|
|
254
|
+
"dateFormat": {
|
|
255
|
+
"en": "MMM D, YYYY",
|
|
256
|
+
"ar": "D MMMM YYYY"
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"accessibility": {
|
|
260
|
+
"minTouchTarget": "44px",
|
|
261
|
+
"focusVisible": "always visible, never suppressed with outline:none without a replacement",
|
|
262
|
+
"altTextPolicy": "required on every meaningful image; decorative images use alt=''"
|
|
263
|
+
},
|
|
264
|
+
"foundation": "native",
|
|
265
|
+
"school": "minimalist",
|
|
266
|
+
"usage": {
|
|
267
|
+
"sharedBy": [
|
|
268
|
+
"tidyfactor-design",
|
|
269
|
+
"tidyfactor-cinematic",
|
|
270
|
+
"future kits (Dashboard, Admin, LMS, Commerce)"
|
|
271
|
+
],
|
|
272
|
+
"rules": [
|
|
273
|
+
"Every surface reads tokens from this file — never hardcode a hex value or font name inline.",
|
|
274
|
+
"Brand colors (primary, logo) do not change between light/dark modes — only surface, background, border, and text tokens do.",
|
|
275
|
+
"If this file changes, regenerate dependent surfaces rather than manually patching colors.",
|
|
276
|
+
"Extend by adding new tokens, not by overriding existing ones per-surface."
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Design Schools & Movements — Quick Calibration Index
|
|
2
|
+
|
|
3
|
+
For complete operational rules, visual tokens, typography pairings, color systems, CSS rules, shadow styles, and anti-patterns across all 20 visual aesthetics, see:
|
|
4
|
+
👉 **[`memory/16-design-movements-guide.md`](16-design-movements-guide.md)** (All 20 Visual Movements & Design Tokens)
|
|
5
|
+
👉 **[`memory/17-storytelling-industries-ux.md`](17-storytelling-industries-ux.md)** (4 Storytelling Archetypes, 8 Industry Registers, 8 UX Philosophies)
|
|
6
|
+
👉 **[`memory/18-design-decision-engine.md`](18-design-decision-engine.md)** (9-Step Decision Tree & Anti-Design-Soup Constraint)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 🎨 20 Visual Aesthetics At-A-Glance Index
|
|
11
|
+
1. **Swiss Style**: Objective 12-column grid, sans-serif, high contrast.
|
|
12
|
+
2. **Flat Design**: 2D vector, zero shadows, vibrant color blocks.
|
|
13
|
+
3. **Material Design**: Paper/ink depth, elevation shadows, touch ripples.
|
|
14
|
+
4. **Minimalism**: Extreme negative space, typography focal point.
|
|
15
|
+
5. **Brutalism & Neo-Brutalism**: Hard 4px black offset shadows, 2px borders, pop colors.
|
|
16
|
+
6. **Bauhaus**: Primary color geometry (red/blue/yellow), form follows function.
|
|
17
|
+
7. **Skeuomorphism**: Tactile real-world textures, inner bevels, realistic depth.
|
|
18
|
+
8. **Glassmorphism**: Translucent frosted panels (`backdrop-filter: blur`), spatial layers.
|
|
19
|
+
9. **Maximalism**: Collage layering, kinetic typography, energetic multi-color.
|
|
20
|
+
10. **Industrial Style**: Monospaced data density, blueprint grids, telemetry dots.
|
|
21
|
+
11. **Bento Box UI**: Compartmentalized modular masonry grids, `rounded-2xl` tiles.
|
|
22
|
+
12. **Aurora UI**: Luminescent mesh gradients (`blur(60px)`), dark aura spotlights.
|
|
23
|
+
13. **Neumorphism**: Extruded surface shadows (`inset` + drop), monochromatic grounds.
|
|
24
|
+
14. **Corporate Memphis**: Friendly geometric characters, pastel panels, soft pills.
|
|
25
|
+
15. **Cyberpunk & Vaporwave**: Pitch black grounds, neon cyan/magenta, monospaced HUD.
|
|
26
|
+
16. **Claymorphism**: Soft 3D clay volumes, warm inner light reflections, rounded shapes.
|
|
27
|
+
17. **Isometric Design**: 30° 2D parallel projection vector worlds.
|
|
28
|
+
18. **Kinetic Typography**: Text as the animated hero visual (`clamp()` font scales).
|
|
29
|
+
19. **Organic / Amorphous UI**: Fluid blob shapes (`border-radius: 60% 40% ...`), natural tones.
|
|
30
|
+
20. **Frutiger Aero & Y2K**: Glossy glass buttons, lens flares, vibrant sky blue/lime gradients.
|
|
31
|
+
|
|
32
|
+
## Bauhaus
|
|
33
|
+
Geometric shapes as structural/decorative elements, primary-plus-black
|
|
34
|
+
palettes, function-follows-form typography. Fits: education, design tools,
|
|
35
|
+
brands wanting to signal craft/foundational thinking. Avoid: costume-party
|
|
36
|
+
Bauhaus (circles+triangles as decoration with no structural logic).
|
|
37
|
+
|
|
38
|
+
## Brutalism (web)
|
|
39
|
+
Raw, unstyled-looking HTML elements used deliberately, harsh contrast,
|
|
40
|
+
visible grid lines, monospace accents, intentionally "undesigned". Fits:
|
|
41
|
+
developer tools, portfolios, brands wanting to signal authenticity/anti-
|
|
42
|
+
polish. Avoid: actual unstyled defaults mistaken for the aesthetic —
|
|
43
|
+
brutalism is a considered choice, not the absence of one.
|
|
44
|
+
|
|
45
|
+
## Editorial / Broadsheet
|
|
46
|
+
Hairline rules, dense multi-column text, serif display, byline/dateline
|
|
47
|
+
conventions borrowed from print journalism. Fits: publications, long-form
|
|
48
|
+
content, thought-leadership brands. Avoid: applying hairline-column density
|
|
49
|
+
to a page that has nothing to say at that density (see `frontend-design`'s
|
|
50
|
+
warning on this as an overused AI-design default).
|
|
51
|
+
|
|
52
|
+
## Minimalism
|
|
53
|
+
Extreme restraint, one accent color maximum, huge whitespace, type doing
|
|
54
|
+
almost all the work. Fits: luxury, premium single-product brands. Avoid:
|
|
55
|
+
minimalism as an excuse for lack of a real design decision — every
|
|
56
|
+
remaining element must be precisely placed.
|
|
57
|
+
|
|
58
|
+
## Glassmorphism
|
|
59
|
+
Frosted-glass translucent panels, soft shadows, layered depth over a
|
|
60
|
+
blurred background. Fits: modern consumer apps, dashboards wanting a soft/
|
|
61
|
+
approachable data-density feel. Avoid: layering glass panels on glass
|
|
62
|
+
panels — contrast and legibility break down fast.
|
|
63
|
+
|
|
64
|
+
## Material-influenced
|
|
65
|
+
Elevation via shadow, clear touch targets, motion as spatial logic (things
|
|
66
|
+
move the way physical objects would). Fits: cross-platform app UI,
|
|
67
|
+
utilitarian dashboards. Avoid: importing Material's specific component
|
|
68
|
+
shapes wholesale when the brand wants its own identity — take the
|
|
69
|
+
principles, not the skin.
|
|
70
|
+
|
|
71
|
+
## Modern SaaS (Vercel/Linear-influenced)
|
|
72
|
+
Near-black or pure-white grounds, one saturated accent, monospace for data/
|
|
73
|
+
code, tight type scale, subtle gradient accents, generous but efficient
|
|
74
|
+
spacing. Fits: developer tools, B2B SaaS, technical dashboards. Avoid:
|
|
75
|
+
defaulting here just because the brief is "a SaaS product" — this look is
|
|
76
|
+
common enough now to read as generic if the brand has no other point of
|
|
77
|
+
view.
|
|
78
|
+
|
|
79
|
+
## Calibration: defaults to avoid unless the brief asks for them
|
|
80
|
+
Per `frontend-design`'s own calibration: warm-cream + terracotta-serif,
|
|
81
|
+
near-black + single acid-green/vermilion accent, and broadsheet-hairline-
|
|
82
|
+
columns applied regardless of subject are the three most common AI-design
|
|
83
|
+
tells right now. Choosing one deliberately because it fits the brief is
|
|
84
|
+
fine; landing on one by default is the failure mode `school` exists to
|
|
85
|
+
prevent.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Design Tokens — Reference for `tokens`
|
|
2
|
+
|
|
3
|
+
## Categories and what belongs in each
|
|
4
|
+
|
|
5
|
+
**Colors** — primary, secondary, accent; a light surface scale
|
|
6
|
+
(background/surface/surface-raised) and a dark equivalent if the project
|
|
7
|
+
supports both themes; semantic colors (success/warning/error/info) derived
|
|
8
|
+
from the palette, not generic red/green/yellow dropped in unrelated to the
|
|
9
|
+
brand.
|
|
10
|
+
|
|
11
|
+
**Typography** — a display family (used with restraint, per
|
|
12
|
+
`frontend-design`'s principle), a body family, optionally a mono/utility
|
|
13
|
+
family for data. A type scale (e.g. a 1.25 or 1.333 ratio from a base size)
|
|
14
|
+
— not arbitrary per-heading pixel values. Weight and letter-spacing as
|
|
15
|
+
named tokens tied to the scale, not per-instance tweaks.
|
|
16
|
+
|
|
17
|
+
**Spacing** — one consistent base unit (4px or 8px) and a small named scale
|
|
18
|
+
(`--space-1` through `--space-8` or similar) — every margin/padding/gap in
|
|
19
|
+
the project traces to this scale.
|
|
20
|
+
|
|
21
|
+
**Radius** — a small fixed set (e.g. none/sm/md/lg/full) — resist a
|
|
22
|
+
different radius value per component.
|
|
23
|
+
|
|
24
|
+
**Shadow** — a small fixed elevation set (e.g. sm/md/lg), consistent light
|
|
25
|
+
angle/color across all of them (usually a tint of the darkest neutral in
|
|
26
|
+
the palette, not pure black).
|
|
27
|
+
|
|
28
|
+
**Motion** — duration tokens (fast/base/slow) and easing tokens
|
|
29
|
+
(ease-out for entrances, ease-in for exits, a signature easing curve for
|
|
30
|
+
the brand's characteristic motion if `school` calls for one).
|
|
31
|
+
|
|
32
|
+
## Naming convention
|
|
33
|
+
`--color-*`, `--font-*`, `--space-*`, `--radius-*`, `--shadow-*`,
|
|
34
|
+
`--ease-*`/`--duration-*` — consistent prefixing so any command (or a human
|
|
35
|
+
reading the CSS) can immediately tell a value's category.
|
|
36
|
+
|
|
37
|
+
## Contrast policy
|
|
38
|
+
Every text/background pairing derived from tokens should pass WCAG AA
|
|
39
|
+
(4.5:1 for body text, 3:1 for large text/UI components) — check this when
|
|
40
|
+
`school` picks a direction with strong color contrast ambitions
|
|
41
|
+
(near-black grounds, saturated accents), not just at the end.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Narrative & Conversion — Reference for `page`/`dashboard`
|
|
2
|
+
|
|
3
|
+
## Hero as thesis
|
|
4
|
+
The opening of any page states its single job immediately — a headline, a
|
|
5
|
+
demo, a number, whatever form fits the subject. Never a generic "Welcome
|
|
6
|
+
to X" holding pattern. (Shared principle with `frontend-design`, applied
|
|
7
|
+
here as a persistent rule across every page in the prototype, not just one.)
|
|
8
|
+
|
|
9
|
+
## AIDA (Attention, Interest, Desire, Action)
|
|
10
|
+
A useful ordering check for marketing pages: does the hero earn Attention
|
|
11
|
+
specific to this audience? Does the next section build real Interest (not
|
|
12
|
+
generic feature bullets)? Does the page build Desire before it asks for
|
|
13
|
+
anything? Is the Action (CTA) singular and obvious, not competing with
|
|
14
|
+
three other asks on the same screen?
|
|
15
|
+
|
|
16
|
+
## StoryBrand-style framing
|
|
17
|
+
The visitor is the hero of their own story, not the brand. Copy and layout
|
|
18
|
+
should cast the product as the guide (the thing that helps), not the
|
|
19
|
+
protagonist. A page that talks entirely about the company/product without
|
|
20
|
+
naming the visitor's problem first usually reads as self-absorbed rather
|
|
21
|
+
than persuasive.
|
|
22
|
+
|
|
23
|
+
## Jobs-to-be-Done framing (for dashboards/app screens)
|
|
24
|
+
A dashboard screen's design should answer "what job is the person here to
|
|
25
|
+
do right now" before anything else — scanning for an anomaly, completing a
|
|
26
|
+
task, deciding on an action. Information hierarchy follows that job, not a
|
|
27
|
+
generic "show everything" density.
|
|
28
|
+
|
|
29
|
+
## Structural devices carry meaning, or they don't belong
|
|
30
|
+
Numbered steps, eyebrows, dividers — only use them where they encode
|
|
31
|
+
something real (an actual sequence, an actual category boundary). A
|
|
32
|
+
numbered "01/02/03" on three cards that aren't actually sequential is
|
|
33
|
+
decoration pretending to be information — cut it or fix the content to
|
|
34
|
+
actually be sequential.
|
|
35
|
+
|
|
36
|
+
## Gestalt basics worth naming
|
|
37
|
+
Proximity (related things grouped, unrelated things separated) and
|
|
38
|
+
continuity (aligned edges read as connected) do more consistency work than
|
|
39
|
+
almost any color/type decision — check these before reaching for a visual
|
|
40
|
+
fix when a page "feels off".
|
|
41
|
+
|
|
42
|
+
## CTA hierarchy
|
|
43
|
+
One primary action per page/screen, styled as the obvious next step;
|
|
44
|
+
secondary actions visually subordinate (not competing in size/color).
|
|
45
|
+
Repeating the same primary CTA at natural decision points down a long page
|
|
46
|
+
is a legitimate pattern — offering multiple *different* primary actions is
|
|
47
|
+
not.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Motion Principles — Reference for `motion`
|
|
2
|
+
|
|
3
|
+
Adapted from the classic animation principles, applied to UI motion rather
|
|
4
|
+
than character animation.
|
|
5
|
+
|
|
6
|
+
## Staging
|
|
7
|
+
One focal change communicated at a time. A section revealing five cards
|
|
8
|
+
simultaneously reads as noise; the same five staggered by ~60-80ms each
|
|
9
|
+
read as a considered sequence.
|
|
10
|
+
|
|
11
|
+
## Anticipation
|
|
12
|
+
A small pre-state before a bigger change helps the eye track what's about
|
|
13
|
+
to happen (a button's subtle scale-down before a bigger transition, a
|
|
14
|
+
skeleton before content pops in) — used sparingly, not on every
|
|
15
|
+
interaction.
|
|
16
|
+
|
|
17
|
+
## Ease-out for entrances, ease-in for exits
|
|
18
|
+
Things entering the screen should decelerate into place (ease-out);
|
|
19
|
+
things leaving should accelerate away (ease-in). Using the same easing
|
|
20
|
+
for both reads as mechanical rather than natural.
|
|
21
|
+
|
|
22
|
+
## Follow-through / slight overshoot
|
|
23
|
+
A very small overshoot-and-settle on an entrance (a card that slightly
|
|
24
|
+
overshoots its final position before settling) reads as more alive than a
|
|
25
|
+
purely linear arrival — use subtly, it's easy to overdo into "bouncy" and
|
|
26
|
+
undermine a restrained direction like Minimalism or Swiss.
|
|
27
|
+
|
|
28
|
+
## Secondary motion
|
|
29
|
+
A primary element moving (e.g. a hero image entering) can carry a small,
|
|
30
|
+
delayed secondary motion (a shadow settling a beat later, an accent
|
|
31
|
+
element trailing slightly) — this is what separates "orchestrated" motion
|
|
32
|
+
from "everything moves in lockstep".
|
|
33
|
+
|
|
34
|
+
## Restraint is a choice, not an absence
|
|
35
|
+
Per `frontend-design`: an orchestrated single moment usually lands harder
|
|
36
|
+
than scattered effects everywhere, and excess ambient animation is one of
|
|
37
|
+
the strongest tells that a design is AI-generated. `school`'s chosen
|
|
38
|
+
direction should determine how much motion is appropriate — Minimalism and
|
|
39
|
+
Swiss call for very little; Modern SaaS and Glassmorphism can carry more.
|
|
40
|
+
|
|
41
|
+
## Non-negotiable: `prefers-reduced-motion`
|
|
42
|
+
Every entrance/scroll/parallax effect in `motion.js` must check this media
|
|
43
|
+
query and fall back to instant or opacity-only transitions — applied
|
|
44
|
+
globally in the shared file, not per page.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Component Anatomy — Reference for `components`/`states`
|
|
2
|
+
|
|
3
|
+
## Atomic hierarchy (Atomic Design, adapted)
|
|
4
|
+
- **Atoms** — button, input, label, icon, badge. The smallest named unit;
|
|
5
|
+
never composed of other named components.
|
|
6
|
+
- **Molecules** — a form field (label + input + error text), a stat
|
|
7
|
+
(label + value + trend), a nav item (icon + label + active state).
|
|
8
|
+
- **Organisms** — a card, a data table, a navbar, a pricing tile, a modal.
|
|
9
|
+
Composed from atoms/molecules, still a single reusable named unit.
|
|
10
|
+
- **Templates** (this skill's `page`/`dashboard` output) — organisms
|
|
11
|
+
arranged into a page's actual layout. This is the one level that's
|
|
12
|
+
allowed to be page-specific — it's arrangement, not new styling.
|
|
13
|
+
|
|
14
|
+
A new visual need almost always belongs at the atom/molecule/organism
|
|
15
|
+
level, added once to `components.css`/the foundation library — not
|
|
16
|
+
invented at the template level.
|
|
17
|
+
|
|
18
|
+
## The full state matrix (apply per interactive component)
|
|
19
|
+
`default → hover → focus-visible → active/pressed → disabled`, plus where
|
|
20
|
+
relevant: `loading`, `empty`, `error`, `success`. A component "supports"
|
|
21
|
+
these states means each has an intentional look, not that the browser
|
|
22
|
+
default happens to apply.
|
|
23
|
+
|
|
24
|
+
## Naming discipline
|
|
25
|
+
One canonical name per real pattern. A "featured pricing card" and a
|
|
26
|
+
"testimonial card" that share 90% of their structure should be one `.card`
|
|
27
|
+
component with modifiers (`.card--featured`), not two components that will
|
|
28
|
+
quietly diverge over time.
|
|
29
|
+
|
|
30
|
+
## When something looks like it needs a new component but doesn't
|
|
31
|
+
If the only difference from an existing component is a token value (a
|
|
32
|
+
different accent color, a different size) — that's a modifier class or a
|
|
33
|
+
data attribute, not a new component. New components are for genuinely
|
|
34
|
+
different structure/behavior, not restyled instances.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Quality Bar — Auto-Reject Checklist for `audit`
|
|
2
|
+
|
|
3
|
+
A prototype fails review if any of these are true, regardless of how good individual pages look in isolation.
|
|
4
|
+
|
|
5
|
+
## Pre-Emit Self-Critique (1–5 Scores on 6 Axes)
|
|
6
|
+
Before handing back any output, score the artifact on 6 axes:
|
|
7
|
+
- **Philosophy (P)**: Opinionated stance vs generic template default.
|
|
8
|
+
- **Hierarchy (H)**: Clear visual weight & focal structure.
|
|
9
|
+
- **Execution (E)**: Clean layout alignment, zero inline overrides, valid tokens.
|
|
10
|
+
- **Specificity (S)**: Customized specifically to the subject's world/materials.
|
|
11
|
+
- **Restraint (R)**: Zero clutter, excess gradients, or fake cards.
|
|
12
|
+
- **Variety (V)**: Non-repetitive section rhythm across project pages.
|
|
13
|
+
|
|
14
|
+
*Any score < 3 triggers an automatic revision pass. Output must be stamped:*
|
|
15
|
+
`/* Pre-emit critique: P5 H4 E5 S4 R5 V5 */`
|
|
16
|
+
|
|
17
|
+
## Compositing & Blend Rules
|
|
18
|
+
- **The Blend Trap**: `mix-blend-mode` (multiply or screen) breaks on any element transformed by GSAP or CSS 3D transforms, creating a visible light/dark rectangle. Use background-removed transparent PNG cutouts (`rembg` + `Pillow`) for animated hero assets. Reserve `mix-blend-mode` strictly for static, untransformed imagery.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Structural (highest severity — breaks the skill's core promise)
|
|
22
|
+
- **Anti-Design-Soup Violation**: Combining more than 1 Primary School, 1 Secondary Influence, 1 Motion Language, 1 Storytelling Style, or 1 UX Philosophy on a single page (unless explicitly requested).
|
|
23
|
+
- Any page has an inline `<style>` block or `style="..."` attribute.
|
|
24
|
+
- Any page has a `<script>` block that isn't `src`-linked to a shared `design-system/*` file.
|
|
25
|
+
- A value (color, font-size, spacing, radius, shadow) appears as a literal in any page without tracing to a token.
|
|
26
|
+
- Two pages render visually different versions of "the same" component (drift), or two components that are 90%+ identical exist under different names (near-duplicate).
|
|
27
|
+
|
|
28
|
+
## The 16 Named AI Anti-Pattern Tells (Auto-Reject)
|
|
29
|
+
1. **Purple-Gradient Hero**: Purple-to-pink/blue background gradient with white centered text.
|
|
30
|
+
2. **Inter-Everywhere**: Single unpaired font family used across display and body.
|
|
31
|
+
3. **3-Column Feature Grid**: 3 equal columns with icon above 2-line heading above 3-line body.
|
|
32
|
+
4. **Card-in-Card**: Nested container cards with no semantic structural reason.
|
|
33
|
+
5. **Gradient Headline**: `background-clip: text` linear gradient fill on headlines.
|
|
34
|
+
6. **Side-Stripe Card**: 4–6px thick colored border on left edge of card.
|
|
35
|
+
7. **Full-Viewport Centered Hero**: `min-height: 100vh` centered short sentence + big CTA.
|
|
36
|
+
8. **Pure Black / Pure White**: Pure `#000000` or `#ffffff` flat surfaces (must use tinted neutrals).
|
|
37
|
+
9. **Default-Attractor Sameness**: Reusing the same macrostructure on consecutive project pages.
|
|
38
|
+
10. **Specimen Fall-Through**: Defaulting to editorial `01 - HELLO` specimen layout for SaaS/B2B.
|
|
39
|
+
11. **The AI Nav**: Wordmark left, 4-5 links center, CTA right, 1px bottom border.
|
|
40
|
+
12. **The AI Footer**: 4 columns (Product, Company, Resources, Legal) + social row + copyright line.
|
|
41
|
+
13. **Aurora-Blob Background**: Flowing organic mesh blobs in purple/cyan behind hero text.
|
|
42
|
+
14. **Floating-Orb Decoration**: 3D spheres or blurred circles drifting behind hero.
|
|
43
|
+
15. **Italic Headers**: Flipping one word in a headline to italic (`Built to <em>think</em>`) to "look editorial".
|
|
44
|
+
16. **Lazy-Loaded LCP**: Adding `loading="lazy"` to the main hero LCP image (tanks performance).
|
|
45
|
+
|
|
46
|
+
## Mechanical Anti-Slop & Anti-Generic UI (Rule 8)
|
|
47
|
+
- **Ubiquitous Eyebrows**: More than 1 eyebrow tag (uppercase tracking small label) per 3 sections (`count > ceil(sectionCount / 3)`).
|
|
48
|
+
- **Floating Mid-Screen Hero**: Hero top padding exceeds `pt-24` (6rem) on desktop; headline > 2 lines; subtext > 20 words / 4 lines; primary CTA not visible without scroll.
|
|
49
|
+
- **Wrapped CTA Buttons**: Primary CTA button text wraps to 2+ lines on desktop; CTA text > 3 words.
|
|
50
|
+
- **Duplicate CTA Intent**: Multiple CTAs with the same underlying intent (e.g. mixing "Contact us", "Get in touch", and "Let's talk" on one page).
|
|
51
|
+
- **Un-aligned Card CTAs**: Buttons in a card grid not pinned to the bottom (`mt-auto`), creating jagged horizontal lines.
|
|
52
|
+
- **Invented Metrics**: Inventing fake statistics (*"+47% conversion"*, *"trusted by 50,000+ teams"*)—must use real data or `—` metric placeholders.
|
|
53
|
+
- **Re-Drawn Fake Chrome**: Fake CSS browser window frames (red/yellow/green traffic lights wrapping an iframe) or fake IDE title bars.
|
|
54
|
+
- **Fake Div Screenshots**: Using `<div>` rectangles to fake product UI instead of real images or real component previews.
|
|
55
|
+
|
|
56
|
+
## ⛔ 11 Explicit Codex & AI-Slop Defect Bans
|
|
57
|
+
1. **Ghost Cards**: Pairing 1px border with soft wide drop shadows `box-shadow: 0 Npx Mpx ...` (M ≥ 16px). Pick a solid border OR a shadow under 8px blur, never both as decoration.
|
|
58
|
+
2. **Over-Rounding (32px+)**: Applying `border-radius: 24px/32px/40px` to rectangular cards and sections. Cards top out at 12–16px radius (pills strictly for tags/buttons).
|
|
59
|
+
3. **Decorative Grid Background Overlays**: Adding two-axis `linear-gradient(... 1px, transparent 1px)` grid background patterns unless the page is an actual map, blueprint, canvas, or measurement tool.
|
|
60
|
+
4. **Side-Stripe Accent Borders**: Colored `border-left` or `border-right` > 1px as a card/alert callout crutch. Rewrite with solid borders or subtle background tinting.
|
|
61
|
+
5. **Warm Cream / Sand Saturated Neutral Default**: Defaulting all body backgrounds to warm beige/sand (`#F5F2EB` or token names like `--sand`, `--cream`, `--paper`). Pick a true neutral or brand-derived hue tint.
|
|
62
|
+
6. **Side-by-Side Saturated Text Gradients**: Applying `background-clip: text` gradients for emphasis. Use weight, size, or solid accent color.
|
|
63
|
+
7. **Reflexive Glassmorphism**: Adding decorative blurs and glass cards without clear spatial/layering purpose.
|
|
64
|
+
8. **Numbered Section Markers on Non-Sequences**: Prefixing non-sequential sections with `01 / 02 / 03`. Sequence numbers earn their place only on real multi-step processes or timelines.
|
|
65
|
+
9. **Sketchy SVG Illustrations**: Using crude 5-30 path SVG illustrations or doodle filters as fallback graphics.
|
|
66
|
+
10. **Diagonal Stripe Background Overlays**: Using `repeating-linear-gradient(...)` stripe overlays in hero/section backgrounds.
|
|
67
|
+
11. **Disjointed Display Heading Letter-Spacing**: Using letter-spacing tighter than `-0.04em` on H1 display headings causing characters to collide.
|
|
68
|
+
|
|
69
|
+
## Optical Alignment & Typography Hygiene
|
|
70
|
+
- **Data Table Numbers**: Multi-digit metrics or numbers missing `font-variant-numeric: tabular-nums` or monospace font alignment.
|
|
71
|
+
- **Orphaned Headline Words**: Single hanging words on display headers missing `text-wrap: balance` or `text-wrap: pretty`.
|
|
72
|
+
- **Optical Offsets**: Inline icons adjacent to text baselines missing 1-2px vertical optical adjustment.
|
|
73
|
+
- **Sudden Dark Sections**: A random dark-mode section breaking an otherwise light-mode page (or vice versa), reading as a copy-paste AI artifact.
|
|
74
|
+
|
|
75
|
+
## Interaction Completeness
|
|
76
|
+
- An interactive component is missing hover, active (`scale-[0.98]`), focus-visible, or disabled states.
|
|
77
|
+
- Focus rings are invisible or use browser default instead of token-colored ring.
|
|
78
|
+
|
|
79
|
+
## Arabic / Bilingual & Accessibility Floor
|
|
80
|
+
- Arabic display type uses any family other than El Messiri (headings) / Tajawal (body).
|
|
81
|
+
- Contrast fails WCAG AA on any token-derived text/background pairing.
|
|
82
|
+
- Touch targets under 44px on mobile/touch viewports.
|
|
83
|
+
- `prefers-reduced-motion` not respected globally.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# The Consistency Contract — Why the Architecture Is Strict
|
|
2
|
+
|
|
3
|
+
This is the mechanism, stated once so every command can refer back to it
|
|
4
|
+
instead of re-justifying it each time.
|
|
5
|
+
|
|
6
|
+
## The problem this skill exists to solve
|
|
7
|
+
A designer (or an agent) building a website one page at a time, with each
|
|
8
|
+
page free to write its own CSS/JS, will drift — not from carelessness, but
|
|
9
|
+
because "just this once" always feels justified in the moment a page needs
|
|
10
|
+
something slightly different. At 5 pages the drift is invisible. At 50
|
|
11
|
+
pages it's the whole project.
|
|
12
|
+
|
|
13
|
+
## The rule
|
|
14
|
+
Structural separation, not review discipline, is what prevents drift: if a
|
|
15
|
+
page *cannot* carry its own styling logic (no `<style>`, no inline
|
|
16
|
+
`style=`, no per-page `.css`/`.js` file), then drift becomes structurally
|
|
17
|
+
impossible rather than merely discouraged. This is why `page`/`dashboard`
|
|
18
|
+
treat a missing component as a hard stop, not a judgment call — "just add
|
|
19
|
+
it inline this once" is exactly the failure mode being designed against.
|
|
20
|
+
|
|
21
|
+
## The escape valve
|
|
22
|
+
The rule only works long-term if extending the shared system stays easy —
|
|
23
|
+
if adding a genuinely new component to `components.css` were harder than
|
|
24
|
+
writing 10 lines of scoped CSS, people would route around the rule. The
|
|
25
|
+
`components` command exists specifically to make the correct path (extend
|
|
26
|
+
the shared system) faster than the wrong path (patch locally), not just
|
|
27
|
+
more virtuous.
|
|
28
|
+
|
|
29
|
+
## What `audit` is actually checking
|
|
30
|
+
Every finding in `audit`'s structural scan traces back to this contract:
|
|
31
|
+
inline styles, per-page scripts, untraced literal values, and near-
|
|
32
|
+
duplicate components are all the same underlying failure — a page solved
|
|
33
|
+
its own problem instead of extending the shared one.
|