picasso-skill 1.1.0 → 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.
package/bin/install.mjs CHANGED
@@ -1,43 +1,56 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { existsSync, mkdirSync, cpSync, readdirSync } from "fs";
3
+ import { existsSync, mkdirSync, cpSync, readdirSync, readFileSync } from "fs";
4
4
  import { resolve, join, dirname } from "path";
5
5
  import { fileURLToPath } from "url";
6
6
 
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
  const packageRoot = resolve(__dirname, "..");
9
9
  const skillSource = join(packageRoot, "skills", "picasso");
10
+ const agentSource = join(packageRoot, "agents", "picasso.md");
10
11
 
11
12
  const args = process.argv.slice(2);
12
13
  const command = args[0] || "install";
13
14
 
14
15
  if (command === "help" || command === "--help" || command === "-h") {
15
16
  console.log(`
16
- picasso-skill - The ultimate AI design skill
17
+ picasso-skill - The ultimate AI design skill + agent
17
18
 
18
19
  Usage:
19
- npx picasso-skill Install to current project (.claude/skills/)
20
- npx picasso-skill --global Install globally (~/.claude/skills/)
21
- npx picasso-skill --cursor Install for Cursor (.cursor/skills/)
22
- npx picasso-skill --codex Install for Codex (~/.codex/skills/)
20
+ npx picasso-skill Install skill + agent to current project
21
+ npx picasso-skill --global Install globally (~/.claude/)
22
+ npx picasso-skill --skill-only Install skill only (no agent)
23
+ npx picasso-skill --cursor Install skill for Cursor
24
+ npx picasso-skill --codex Install skill for Codex
23
25
  npx picasso-skill --agents Install to .agents/skills/
24
26
  npx picasso-skill --path DIR Install to a custom directory
27
+
28
+ What gets installed:
29
+ .claude/skills/picasso/ Skill (knowledge base: 13 reference files)
30
+ .claude/agents/picasso.md Agent (autonomous design auditor)
25
31
  `);
26
32
  process.exit(0);
27
33
  }
28
34
 
29
- let targetDir;
35
+ const isGlobal = args.includes("--global") || args.includes("-g");
36
+ const skillOnly = args.includes("--skill-only");
37
+ const home = process.env.HOME || process.env.USERPROFILE;
38
+
39
+ let skillDir;
40
+ let agentDir;
30
41
 
31
- if (args.includes("--global") || args.includes("-g")) {
32
- const home = process.env.HOME || process.env.USERPROFILE;
33
- targetDir = join(home, ".claude", "skills", "picasso");
42
+ if (isGlobal) {
43
+ skillDir = join(home, ".claude", "skills", "picasso");
44
+ agentDir = join(home, ".claude", "agents");
34
45
  } else if (args.includes("--cursor")) {
35
- targetDir = join(process.cwd(), ".cursor", "skills", "picasso");
46
+ skillDir = join(process.cwd(), ".cursor", "skills", "picasso");
47
+ agentDir = null; // Cursor doesn't support agents
36
48
  } else if (args.includes("--codex")) {
37
- const home = process.env.HOME || process.env.USERPROFILE;
38
- targetDir = join(home, ".codex", "skills", "picasso");
49
+ skillDir = join(home, ".codex", "skills", "picasso");
50
+ agentDir = null;
39
51
  } else if (args.includes("--agents")) {
40
- targetDir = join(process.cwd(), ".agents", "skills", "picasso");
52
+ skillDir = join(process.cwd(), ".agents", "skills", "picasso");
53
+ agentDir = null;
41
54
  } else if (args.includes("--path")) {
42
55
  const pathIdx = args.indexOf("--path");
43
56
  const customPath = args[pathIdx + 1];
@@ -45,36 +58,53 @@ if (args.includes("--global") || args.includes("-g")) {
45
58
  console.error("Error: --path requires a directory argument");
46
59
  process.exit(1);
47
60
  }
48
- targetDir = resolve(customPath, "picasso");
61
+ skillDir = resolve(customPath, "picasso");
62
+ agentDir = null;
49
63
  } else {
50
64
  // Default: project-level Claude Code
51
- targetDir = join(process.cwd(), ".claude", "skills", "picasso");
65
+ skillDir = join(process.cwd(), ".claude", "skills", "picasso");
66
+ agentDir = join(process.cwd(), ".claude", "agents");
52
67
  }
53
68
 
54
- console.log(`\n Installing Picasso skill to: ${targetDir}\n`);
69
+ if (skillOnly) agentDir = null;
70
+
71
+ console.log(`\n Installing Picasso to: ${skillDir}\n`);
55
72
 
56
73
  try {
57
- mkdirSync(targetDir, { recursive: true });
58
- mkdirSync(join(targetDir, "references"), { recursive: true });
74
+ // Install skill
75
+ mkdirSync(skillDir, { recursive: true });
76
+ mkdirSync(join(skillDir, "references"), { recursive: true });
59
77
 
60
- // Copy SKILL.md
61
- cpSync(join(skillSource, "SKILL.md"), join(targetDir, "SKILL.md"));
78
+ cpSync(join(skillSource, "SKILL.md"), join(skillDir, "SKILL.md"));
62
79
 
63
- // Copy all reference files
64
80
  const refs = readdirSync(join(skillSource, "references"));
65
81
  for (const ref of refs) {
66
82
  cpSync(
67
83
  join(skillSource, "references", ref),
68
- join(targetDir, "references", ref)
84
+ join(skillDir, "references", ref)
69
85
  );
70
86
  }
71
87
 
72
- console.log(` Done! Installed ${1 + refs.length} files:`);
88
+ console.log(` Skill installed (${1 + refs.length} files):`);
73
89
  console.log(` SKILL.md`);
74
90
  for (const ref of refs) {
75
91
  console.log(` references/${ref}`);
76
92
  }
93
+
94
+ // Install agent
95
+ if (agentDir && existsSync(agentSource)) {
96
+ mkdirSync(agentDir, { recursive: true });
97
+ cpSync(agentSource, join(agentDir, "picasso.md"));
98
+ console.log(`\n Agent installed:`);
99
+ console.log(` ${join(agentDir, "picasso.md")}`);
100
+ }
101
+
77
102
  console.log(`\n Picasso is ready. Start designing.\n`);
103
+
104
+ if (agentDir) {
105
+ console.log(` The Picasso agent will automatically audit your frontend code.`);
106
+ console.log(` You can also invoke it manually with /audit, /critique, or /polish.\n`);
107
+ }
78
108
  } catch (err) {
79
109
  console.error(` Error installing: ${err.message}`);
80
110
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "picasso-skill",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "The ultimate AI design skill for producing distinctive, production-grade frontend interfaces",
5
5
  "bin": {
6
6
  "picasso-skill": "./bin/install.mjs"
@@ -32,6 +32,7 @@
32
32
  "files": [
33
33
  "bin/",
34
34
  "skills/",
35
+ "agents/",
35
36
  "LICENSE"
36
37
  ]
37
38
  }
@@ -0,0 +1,245 @@
1
+ # Accessibility & WCAG 2.2 Reference
2
+
3
+ ## 1. ARIA Patterns Catalog
4
+
5
+ ### Dialog / Modal
6
+ - `role="dialog"`, `aria-modal="true"`, `aria-labelledby` (title)
7
+ - Tab/Shift+Tab cycle within dialog (focus trap), Escape closes
8
+ - On open: focus first focusable element. On close: return focus to trigger.
9
+
10
+ ```html
11
+ <div role="dialog" aria-modal="true" aria-labelledby="dlg-title">
12
+ <h2 id="dlg-title">Confirm Delete</h2>
13
+ <p>This action cannot be undone.</p>
14
+ <button>Cancel</button>
15
+ <button>Delete</button>
16
+ </div>
17
+ ```
18
+
19
+ ### Tabs
20
+ - `tablist` > `tab` + `tabpanel`
21
+ - `aria-selected="true|false"` on each tab, `aria-controls` linking tab to panel
22
+ - Left/Right arrows between tabs, Home/End to first/last
23
+
24
+ ### Accordion
25
+ - Heading elements containing `<button>` triggers
26
+ - `aria-expanded="true|false"` on button, `aria-controls` pointing to content
27
+ - Enter/Space toggles section
28
+
29
+ ### Combobox / Autocomplete
30
+ - `role="combobox"` on input, popup uses `listbox`
31
+ - `aria-expanded`, `aria-controls`, `aria-activedescendant`, `aria-autocomplete`
32
+ - Down Arrow opens/navigates popup, Escape closes, Enter selects
33
+
34
+ ### Menu / Menubar
35
+ - `menu`/`menubar` > `menuitem`, `menuitemcheckbox`, `menuitemradio`
36
+ - `aria-haspopup`, `aria-expanded` on submenu triggers
37
+ - Arrow keys navigate, Enter/Space activates, Escape closes submenu
38
+
39
+ ### Listbox
40
+ - `listbox` > `option`
41
+ - `aria-selected`, `aria-multiselectable` for multi-select
42
+ - Up/Down arrows, Home/End, type-ahead character navigation
43
+
44
+ ### Tree View
45
+ - `tree` > `treeitem` (nested groups use `group` role)
46
+ - `aria-expanded` on parent nodes, `aria-level`, `aria-setsize`, `aria-posinset`
47
+ - Right expands/enters child, Left collapses/moves to parent
48
+
49
+ ### Toolbar
50
+ - `toolbar` on container, `aria-orientation`
51
+ - Arrow keys between controls (roving tabindex), Tab moves out entirely
52
+
53
+ ### Feed
54
+ - `feed` > `article` on each entry
55
+ - `aria-busy` while loading, `aria-setsize`/`aria-posinset` on articles
56
+ - Page Down/Up between articles
57
+
58
+ ### Alert / Alert Dialog
59
+ - `role="alert"` (non-modal): implicitly `aria-live="assertive"`. No focus change.
60
+ - `role="alertdialog"` (modal): follows dialog focus trap pattern.
61
+
62
+ ### Breadcrumb
63
+ - `<nav aria-label="Breadcrumb">` with ordered list
64
+ - `aria-current="page"` on current page link
65
+
66
+ ### Disclosure
67
+ - `<button aria-expanded="false" aria-controls="content-id">` toggles content
68
+ - Enter/Space toggles expansion
69
+
70
+ ---
71
+
72
+ ## 2. Focus Management for SPAs
73
+
74
+ ### Route Change Announcements
75
+ ```html
76
+ <div aria-live="polite" class="sr-only" id="route-announcer"></div>
77
+ ```
78
+ Update textContent on route change: "Products page loaded".
79
+
80
+ ### Focus Restoration
81
+ Move focus to `<h1>` of new view (add `tabindex="-1"`) or main content landmark. On modal close, restore focus to trigger element.
82
+
83
+ ### Skip Links
84
+ ```html
85
+ <a href="#main" class="skip-link">Skip to main content</a>
86
+ <main id="main" tabindex="-1">...</main>
87
+ ```
88
+
89
+ ### Focus Trapping
90
+ Contain Tab/Shift+Tab within overlays. Use `inert` attribute on background content (modern browsers) or manage via JS. On last focusable element, Tab wraps to first.
91
+
92
+ ### Roving Tabindex
93
+ Only one child has `tabindex="0"` at a time; all others `tabindex="-1"`. On arrow key, swap values and `.focus()`. Alternative: `aria-activedescendant` on container.
94
+
95
+ ---
96
+
97
+ ## 3. Accessible Forms
98
+
99
+ ### Error Handling
100
+ ```html
101
+ <input id="email" aria-invalid="true" aria-describedby="email-err" aria-required="true">
102
+ <span id="email-err" role="alert">Please enter a valid email address.</span>
103
+ ```
104
+
105
+ - `aria-invalid="true"` on fields with errors.
106
+ - `aria-describedby` linking to error message.
107
+ - `role="alert"` for immediate screen reader announcement.
108
+ - On submit, move focus to first invalid field.
109
+
110
+ ### Required Fields
111
+ Use both `required` (native) and `aria-required="true"`. Pair with visible asterisk + legend.
112
+
113
+ ### Field Descriptions
114
+ ```html
115
+ <label for="pw">Password</label>
116
+ <input id="pw" type="password" aria-describedby="pw-hint">
117
+ <p id="pw-hint">Must be at least 8 characters with one number.</p>
118
+ ```
119
+
120
+ ### Autocomplete Attributes
121
+ Use `autocomplete` values: `name`, `email`, `tel`, `street-address`, `postal-code`, `cc-number`, etc.
122
+
123
+ ### Group Labeling
124
+ ```html
125
+ <fieldset>
126
+ <legend>Payment Method</legend>
127
+ <label><input type="radio" name="pay" value="card"> Credit Card</label>
128
+ <label><input type="radio" name="pay" value="paypal"> PayPal</label>
129
+ </fieldset>
130
+ ```
131
+
132
+ ### Accessible Date Pickers
133
+ Prefer native `<input type="date">`. For custom: `role="grid"` calendar, arrow key navigation, Enter to select, Escape to close, label each cell with full date.
134
+
135
+ ---
136
+
137
+ ## 4. WCAG 2.2 New Criteria
138
+
139
+ ### Target Size Minimum (2.5.8 -- Level AA)
140
+ All interactive targets must be at least **24x24 CSS pixels**.
141
+
142
+ ```css
143
+ button, a, input, select, [role="button"] {
144
+ min-width: 24px;
145
+ min-height: 24px;
146
+ }
147
+ ```
148
+
149
+ ### Dragging Alternatives (2.5.7 -- Level AA)
150
+ Every drag-and-drop operation must have a single-pointer alternative (click/tap). Sortable lists must also support "Move Up"/"Move Down" buttons.
151
+
152
+ ### Focus Appearance (2.4.11 -- Level AA)
153
+ Focus indicators: minimum **2px perimeter outline** with **3:1 contrast ratio** between focused and unfocused states.
154
+
155
+ ```css
156
+ :focus-visible {
157
+ outline: 2px solid #005fcc;
158
+ outline-offset: 2px;
159
+ }
160
+ ```
161
+
162
+ ### Consistent Help (3.2.6 -- Level A)
163
+ Help mechanisms must appear in the **same relative order** across all pages.
164
+
165
+ ---
166
+
167
+ ## 5. Screen Reader Dynamic Content
168
+
169
+ ### aria-live Regions
170
+ ```html
171
+ <div aria-live="polite" aria-atomic="true">3 results found</div>
172
+ <div aria-live="assertive">Session expiring in 30 seconds</div>
173
+ ```
174
+ - `polite`: announced after current speech.
175
+ - `assertive`: interrupts (use sparingly).
176
+ - `aria-atomic="true"`: reads entire region, not just changed text.
177
+
178
+ ### Status Messages (WCAG 4.1.3)
179
+ ```html
180
+ <div role="status">File uploaded successfully.</div>
181
+ ```
182
+
183
+ ### Loading States
184
+ ```html
185
+ <div role="status" aria-live="polite">Loading results...</div>
186
+ <table aria-busy="true">...</table>
187
+ ```
188
+ Set `aria-busy="true"` during update, `false` when complete.
189
+
190
+ ### Progress Updates
191
+ ```html
192
+ <div role="progressbar" aria-valuenow="65" aria-valuemin="0" aria-valuemax="100"
193
+ aria-label="Upload progress">65%</div>
194
+ ```
195
+
196
+ ---
197
+
198
+ ## 6. Accessible Data Tables
199
+
200
+ ### Complex Headers
201
+ ```html
202
+ <th id="q1" scope="col">Q1</th>
203
+ <th id="revenue" scope="row">Revenue</th>
204
+ <td headers="q1 revenue">$1.2M</td>
205
+ ```
206
+
207
+ ### Sortable Columns
208
+ ```html
209
+ <th aria-sort="ascending" scope="col">
210
+ <button>Name <span aria-hidden="true">&uarr;</span></button>
211
+ </th>
212
+ ```
213
+ Values: `ascending`, `descending`, `none`. Only one column sorted at a time.
214
+
215
+ ### Expandable Rows
216
+ Parent row: `aria-expanded="true|false"`. Use `aria-level`, `aria-setsize`, `aria-posinset` for treegrid.
217
+
218
+ ### Responsive Tables
219
+ - **Reflow:** Transform cells into stacked blocks with `data-label` + CSS `::before` for headers.
220
+ - **Scroll:** `tabindex="0"`, `role="region"`, `aria-label="Scrollable table"`.
221
+
222
+ ---
223
+
224
+ ## 7. Accessible Drag and Drop
225
+
226
+ ### Keyboard Alternatives (WCAG 2.5.7)
227
+ ```html
228
+ <li aria-roledescription="sortable item">
229
+ Item A
230
+ <button aria-label="Move Item A up">Up</button>
231
+ <button aria-label="Move Item A down">Down</button>
232
+ </li>
233
+ ```
234
+
235
+ ### Live Region Announcements
236
+ ```html
237
+ <div aria-live="assertive" class="sr-only" id="dnd-status"></div>
238
+ ```
239
+ - On grab: "Grabbed Item A. Current position 2 of 5."
240
+ - On move: "Item A moved to position 3 of 5."
241
+ - On drop: "Item A dropped at position 3 of 5."
242
+ - On cancel: "Reorder cancelled. Item A returned to position 2."
243
+
244
+ ### Modern Pattern
245
+ `aria-grabbed`/`aria-dropeffect` are deprecated. Use `aria-roledescription="draggable"`, `aria-pressed`/`aria-selected` for state, and live regions for announcements. Space/Enter to grab/drop, arrow keys to reposition, Escape to cancel.
@@ -4,92 +4,181 @@ This is the most important reference file. These are the patterns that make AI-g
4
4
 
5
5
  ---
6
6
 
7
+ ## The AI Slop Fingerprint
8
+
9
+ Any 3 or more of these together = AI slop. Stop and redesign.
10
+
11
+ - Inter/Roboto + purple-to-blue gradient + centered hero + 3 equal feature cards + "Build the future of work" headline
12
+ - `bg-indigo-500` as default accent (the Tailwind feedback loop)
13
+ - Uniform 8px or 16px border-radius on everything
14
+ - Generic `box-shadow: 0 4px 6px rgba(0,0,0,0.1)` on every card
15
+ - Same page structure: hero > 3 cards > testimonials > pricing > CTA
16
+ - Gradient text (`background-clip: text`) that fails accessibility
17
+ - Abstract 3D blobs or stock photos of people smiling at laptops
18
+ - Everything perfectly centered on a vertical axis
19
+ - Uniform spacing with no density variation between sections
20
+ - Fade-in-on-scroll applied identically to every element
21
+ - Feature icons from Lucide/Heroicons in tinted circles
22
+ - "Trusted by 10,000+ teams" with grayed-out logos nobody recognizes
23
+
24
+ **The test:** Show someone a screenshot without context. If they say "AI-generated" in 3 seconds, it fails. The fingerprint is not any single choice -- it is the combination of defaults that signals zero human judgment.
25
+
26
+ ---
27
+
7
28
  ## Typography Anti-Patterns
8
29
 
9
- - **Inter everywhere.** The default safe choice. It signals "I did not think about fonts."
10
- - **Roboto, Arial, Helvetica, system-ui as primary.** Same problem.
11
- - **Space Grotesk on repeat.** Overused in AI/crypto contexts. Pick something else.
12
- - **Light (300) weight for body text.** Hard to read on most screens.
13
- - **Centered paragraphs.** Center alignment works for 1-2 lines (headings, quotes). Never for body text.
14
- - **No max-width on text.** Lines spanning 1400px are unreadable. Cap at 600-750px for body text.
15
- - **All caps without letter-spacing.** All-caps text needs 0.08-0.15em spacing to be legible.
30
+ - **Inter everywhere.** Signals "I did not think about fonts."
31
+ - **Roboto, Arial, Helvetica, system-ui as primary.** System defaults, not design decisions.
32
+ - **Space Grotesk on repeat.** Overused in AI/crypto contexts.
33
+ - **Light (300) weight for body text.** Hard to read. 400 minimum for body, 500+ for small text.
34
+ - **Centered paragraphs.** Center alignment works for 1-2 lines only. Never for body text.
35
+ - **No max-width on text.** Cap at 600-750px for body (45-75 characters per line).
36
+ - **All caps without letter-spacing.** Needs 0.08-0.15em spacing to be legible.
16
37
  - **More than 3 font families.** Two is ideal. Three is the maximum.
17
- - **Font size under 14px for body text.** Especially on mobile.
38
+ - **Font size under 14px for body text.** 16px is a safe default.
39
+ - **Same font weight for everything.** Use at least 3 distinct weights for hierarchy.
40
+ - **Line-height of 1.5 for all text.** Headings: 1.1-1.2. Body: 1.5-1.7. Small text: 1.6-1.8.
41
+ - **No optical size adjustment.** Display text: lighter weight, tighter tracking. Small UI text: heavier, looser tracking.
18
42
 
19
43
  ---
20
44
 
21
45
  ## Color Anti-Patterns
22
46
 
23
- - **Purple gradient on white background.** The signature AI slop aesthetic.
24
- - **Pure black text (#000000).** Always use tinted near-black (e.g., oklch(0.15 0.02 260)).
25
- - **Pure gray (#808080, #cccccc).** Always tint neutrals toward the palette hue.
26
- - **Gray text on colored backgrounds.** Creates low contrast and looks washed out.
27
- - **Full-saturation brand colors for large surfaces.** Reserve maximum chroma for small accents. Large areas need reduced saturation.
28
- - **Too many accent colors.** One primary, one secondary maximum. More creates visual chaos.
29
- - **Using opacity instead of actual color values.** opacity:0.5 on colored elements creates inconsistent results depending on background.
30
- - **No dark mode consideration.** Even if not implementing dark mode, design with the possibility in mind.
47
+ - **Purple gradient on white background.** The signature AI slop aesthetic. If your first instinct is purple-to-blue, stop.
48
+ - **`bg-indigo-500`, `bg-violet-500`, `bg-purple-500` as primary.** The Tailwind default palette trap.
49
+ - **Pure black text (#000000).** Use tinted near-black (e.g., `oklch(0.15 0.02 260)`).
50
+ - **Pure gray (#808080, #cccccc).** Tint neutrals toward the palette hue.
51
+ - **Gray text on colored backgrounds.** Low contrast, washed out. Use white or a very light tint.
52
+ - **Full-saturation brand colors for large surfaces.** Reserve max chroma for small accents. Large areas need reduced saturation.
53
+ - **Too many accent colors.** One primary, one secondary maximum.
54
+ - **Using opacity instead of actual color values.** `opacity:0.5` creates inconsistent results. Define explicit tokens.
55
+ - **No dark mode consideration.** Use CSS custom properties from the start.
56
+ - **Gradient text without a solid fallback.** Breaks in selection, high contrast mode, some browsers.
57
+ - **Rainbow or multi-stop gradients.** Two stops maximum. Four or more is a circus.
31
58
 
32
59
  ---
33
60
 
34
61
  ## Layout Anti-Patterns
35
62
 
36
- - **Everything centered vertically and horizontally.** Creates a lifeless vertical highway. Use left-aligned content with intentional centering for specific elements.
37
- - **Cards nested inside cards.** One level of card is usually enough. Nesting creates visual confusion about hierarchy.
38
- - **Wrapping everything in cards.** Not every piece of content needs a container with rounded corners and a shadow. Sometimes flat sections, dividers, or whitespace work better.
39
- - **Uniform rounded corners on everything.** Vary border-radius by context: pills for tags (999px), subtle rounding for cards (8-12px), sharper for data elements (4px).
40
- - **Equal spacing everywhere.** Groups need tighter internal spacing and wider external spacing. Without this, there is no visual structure.
41
- - **Three or four equal columns at every breakpoint.** Asymmetric grids (2:1, 3:2) are more interesting and create clearer hierarchy.
63
+ - **Everything centered vertically and horizontally.** Creates a lifeless vertical highway. Use left-aligned content with intentional centering.
64
+ - **Three-column equal-width feature grid as default.** The most common AI layout. Make one card dominant (2:1 split) or use a different structure.
65
+ - **Same page structure every time.** Hero > cards > testimonials > pricing > CTA. Break the pattern: split-screen, bento grid, horizontal scroll, text-as-hero.
66
+ - **No spatial surprises.** Every section on the same grid. Professional sites break the grid -- full-bleed images, asymmetric splits, oversized pull quotes.
67
+ - **No density variation.** Some sections should feel spacious (hero, CTA), others dense (feature lists, data tables, pricing).
68
+ - **No overlapping elements or grid breaks.** Elements that bleed outside containers add depth and interest.
69
+ - **Uniform card sizing in grids.** Primary item should be visually dominant. Featured card taller/wider.
70
+ - **Cards nested inside cards.** One level is usually enough.
71
+ - **Wrapping everything in cards.** Sometimes flat sections, dividers, or whitespace work better.
72
+ - **Equal spacing everywhere.** Groups need tighter internal spacing and wider external spacing.
42
73
  - **Content that could belong to any product.** If the layout has no personality, the design is not done.
74
+ - **Sticky header over 80px.** Keep slim (48-56px) or hide on scroll-down.
75
+
76
+ ---
77
+
78
+ ## Shadow Anti-Patterns
79
+
80
+ - **Same shadow on every elevated element.** `shadow-md` on cards, modals, dropdowns, and buttons is not a system.
81
+ - **No shadow hierarchy.** Define 3-4 levels: subtle (tooltips), moderate (cards, dropdowns), dramatic (modals, drawers).
82
+ - **Shadows invisible in dark mode.** `rgba(0,0,0,0.1)` disappears on dark backgrounds. Use inner glows, border effects, or background lightness differentiation.
83
+ - **Shadows instead of background-color for elevation.** Elevation is often better communicated through surface tint, not shadows.
84
+ - **Hard-edged shadows.** Small blur + high opacity = 2005. Modern shadows: large blur (20-40px), low opacity (0.03-0.08).
85
+ - **Colored shadows that do not match the element.** A blue button with gray shadow looks disconnected. Use the element's hue at low opacity.
86
+
87
+ ---
88
+
89
+ ## Border Radius Anti-Patterns
90
+
91
+ - **Uniform 8px or 16px on everything.** Border radius is a system, not one value.
92
+ - **No hierarchy.** Pills for tags (999px), generous for modals (16-24px), subtle for cards (8-12px), sharp for data (2-4px), sharp for marketing (0-2px).
93
+ - **Nested radius not accounting for padding.** Inner radius = outer radius minus padding. Card with `16px` radius and `8px` padding = inner element at `8px` radius.
94
+ - **Rounded corners on elements flush with container edges.** Touching corners should be 0 radius.
95
+ - **Mixing rounded and sharp in the same component.** Button at `8px` next to input at `0px` = two design systems colliding.
43
96
 
44
97
  ---
45
98
 
46
99
  ## Motion Anti-Patterns
47
100
 
48
- - **Bounce/elastic easing.** Feels dated and gimmicky. Use ease-out curves.
49
- - **Animating everything on the page.** Creates visual noise. Animate the important moments.
50
- - **transition: all 0.3s.** Animates properties you did not intend. Be specific: `transition: opacity 0.2s, transform 0.3s`.
51
- - **No loading feedback.** User clicks a button and nothing happens for 2 seconds. Always show progress.
52
- - **Spinner for content areas.** Use skeleton screens instead. Spinners should be reserved for small inline actions.
53
- - **Animation without prefers-reduced-motion handling.** Always provide a reduced-motion path.
101
+ - **Bounce/elastic easing.** Dated. Use ease-out for entrances, ease-in for exits.
102
+ - **Animating everything.** Animate important moments only: state changes, entrances, user-initiated actions.
103
+ - **transition: all 0.3s.** Be specific: `transition: opacity 0.2s ease-out, transform 0.3s ease-out`.
104
+ - **Uniform fade-in-on-scroll.** Stagger timing. Vary animation type. Let some elements just be there.
105
+ - **No loading feedback.** Always show progress on async actions.
106
+ - **Spinner for content areas.** Use skeleton screens. Spinners for small inline actions only.
107
+ - **No prefers-reduced-motion handling.** Wrap motion in `@media (prefers-reduced-motion: no-preference)`.
108
+ - **Duration over 500ms for UI transitions.** 150-300ms for most interactions. 300-500ms for large layout changes.
109
+ - **Animating layout properties (width, height, top, left).** Triggers reflows. Animate `transform` and `opacity` only.
54
110
 
55
111
  ---
56
112
 
57
113
  ## Interaction Anti-Patterns
58
114
 
59
115
  - **Placeholder text as the only label.** Disappears on focus. Inaccessible.
60
- - **outline: none without replacement.** Keyboard users lose all orientation.
116
+ - **outline: none without replacement.** Replace with a custom focus ring, never remove it.
61
117
  - **Hover-only interactions.** Must have keyboard and touch equivalents.
62
- - **Custom scrollbars that break native behavior.** Users expect scrolling to work natively.
63
- - **Toast notifications for errors.** They disappear. Use inline error messages instead.
64
- - **Alert/confirm dialogs for minor actions.** Blocking the entire page for "Are you sure?" on non-destructive actions.
65
- - **No focus trapping in modals.** Tab key escapes the modal and the user gets lost.
66
- - **Links that look like buttons and buttons that look like links.** Use the correct element for the correct purpose.
118
+ - **Custom scrollbars that break native behavior.** Custom thin scrollbars fine. Custom scroll physics not.
119
+ - **Toast notifications for errors.** They disappear. Use inline errors. Toasts for confirmations only.
120
+ - **Alert/confirm dialogs for minor actions.** Do not block the page for non-destructive actions.
121
+ - **No focus trapping in modals.** Tab key must stay within the modal.
122
+ - **Links that look like buttons, buttons that look like links.** `<a>` navigates. `<button>` acts.
123
+ - **Disabled buttons with no explanation.** Show inline validation or tooltip for why the action is unavailable.
124
+ - **Click targets smaller than 44x44px on mobile.** 44px minimum per Apple and Google guidelines.
67
125
 
68
126
  ---
69
127
 
70
- ## Code Anti-Patterns
128
+ ## Content / Copy Anti-Patterns
71
129
 
72
- - **div soup.** Use semantic HTML: nav, main, section, article, aside, header, footer.
73
- - **Inline styles for everything.** Use CSS variables, modules, or Tailwind. Inline styles cannot be overridden or themed.
74
- - **!important everywhere.** If specificity requires !important, the CSS architecture is broken.
75
- - **z-index: 9999.** Use a z-index scale (1, 10, 20, 30...) with named CSS variables.
76
- - **Fixed pixel values for everything.** Use rem for typography and spacing, em for component-internal sizing, px only for borders and shadows.
77
- - **console.log left in production.** Clean it up.
130
+ - **"Lorem ipsum" in final deliverables.** Design without content is decoration.
131
+ - **Stock photo people smiling at laptops.** Use contextual illustrations, product screenshots, or abstract art.
132
+ - **"Click here" link text.** Describe the destination: "View documentation."
133
+ - **"Submit" button text.** Use the specific action: "Create account", "Send message", "Save changes."
134
+ - **Walls of text without hierarchy.** Break with headings, spacing, and visual rhythm.
135
+ - **Generic headlines.** "Build the future of work." "Your all-in-one platform." "Scale without limits." These say nothing. Use a specific value proposition.
136
+ - **AI-telltale words.** "Delve", "pivotal", "seamless", "leverage", "cutting-edge", "elevate", "harness", "robust", "streamline", "utilize." If you would not say it in conversation, do not write it.
137
+ - **Hedge language.** "May help you", "might improve." Commit to the claim or do not make it.
138
+ - **Unrealistic demo data.** Not $1M revenue and 99.99% uptime. Use $47,230 and 99.93%. Not "John Doe" -- use "Sarah Chen" or "Marcus Rivera."
139
+ - **Broken Unsplash placeholder links.** `unsplash.com/random` links rot. Use solid color blocks or local assets.
140
+ - **Exclamation marks in UI copy.** "Welcome!" "Success!" Save enthusiasm for genuinely exciting moments.
78
141
 
79
142
  ---
80
143
 
81
- ## Content Anti-Patterns
144
+ ## Code Anti-Patterns
82
145
 
83
- - **"Lorem ipsum" in final deliverables.** Use real or realistic content. Design without content is decoration.
84
- - **Stock photo people smiling at laptops.** If using imagery, make it contextual.
85
- - **"Click here" link text.** Links should describe their destination: "View documentation" not "Click here".
86
- - **"Submit" button text.** Use the specific action: "Create account", "Send message", "Save changes".
87
- - **Walls of text without hierarchy.** Break content with headings, spacing, and visual rhythm.
146
+ - **div soup.** Use semantic HTML: `nav`, `main`, `section`, `article`, `aside`, `header`, `footer`.
147
+ - **Inline styles for everything.** Use CSS variables, modules, or Tailwind.
148
+ - **!important everywhere.** If needed, the CSS architecture is broken.
149
+ - **z-index: 9999.** Use a scale with named variables: `--z-dropdown: 10`, `--z-modal: 20`, `--z-toast: 30`.
150
+ - **Fixed pixel values for everything.** `rem` for typography/spacing, `em` for component internals, `px` for borders/shadows.
151
+ - **console.log left in production.**
152
+ - **Tailwind class strings over 200 characters.** Extract to a component or use `@apply`.
153
+ - **Hardcoded color values instead of CSS custom properties.** `bg-[#6366f1]` in 40 files means 40 edits for a brand change.
154
+ - **No responsive behavior.** Test at 320px, 768px, and 1440px minimum.
88
155
 
89
156
  ---
90
157
 
91
158
  ## The Overall Pattern to Avoid
92
159
 
93
- The "AI slop" aesthetic is recognizable by its combination of: Inter/Roboto font, purple/blue gradient accents, evenly spaced centered layouts, uniform card grids with identical rounded corners, and generic stock imagery. Any single element might be fine in isolation. Together, they signal "an AI made this with zero human judgment."
160
+ The AI slop aesthetic: Inter/Roboto + purple/blue gradient + centered layouts + uniform card grids + identical rounded corners + generic shadows + stock imagery. Any single element is fine in isolation. Together they signal zero human judgment.
161
+
162
+ The antidote is intentionality. Every choice -- font, color, spacing, layout, animation, shadow, radius, copy -- should be a conscious decision tied to the specific context. If you cannot explain why you chose it, you defaulted.
163
+
164
+ ---
94
165
 
95
- The antidote is intentionality. Every choice (font, color, spacing, layout, animation) should be a conscious decision tied to the specific context of what you are building.
166
+ ## Professional Alternatives (Quick Reference)
167
+
168
+ | AI Default | Professional Alternative |
169
+ |---|---|
170
+ | Inter / Roboto | Satoshi, Cabinet Grotesk, Plus Jakarta Sans, Outfit, General Sans, Switzer |
171
+ | Purple-to-blue gradient | Single brand hue + tinted neutrals (monochromatic palette) |
172
+ | 3-column equal cards | Asymmetric grid with primary card dominant (2:1 or 3:2 split) |
173
+ | Centered everything | Left-aligned content with intentional centering for heroes/CTAs only |
174
+ | Uniform 8px radius | Context-appropriate: 0-2px marketing, 8-12px cards, 16-24px modals, 999px tags |
175
+ | `0 4px 6px rgba(0,0,0,0.1)` | Elevation-based shadow scale with 3-4 distinct levels |
176
+ | Hero > Cards > Testimonials > CTA | Split-screen, bento grid, horizontal scroll, text-as-hero, editorial layout |
177
+ | Fade-in everything identically | Staggered entrance with varied timing, direction, and type per element |
178
+ | "Scale without limits" | Specific claim with real metric: "Process 10k invoices in 3 minutes" |
179
+ | `bg-indigo-500` accent | A hue reflecting the brand, not Tailwind's default palette |
180
+ | Generic box icons in circles | Custom illustrations, product screenshots, or no icons at all |
181
+ | "Trusted by 10,000+ teams" | Real customer logos with permission, or skip entirely |
182
+ | Uniform section spacing | Varied density: spacious heroes, dense feature grids, breathing room at CTAs |
183
+ | Same shadow on everything | Shadow hierarchy: none flat, subtle cards, medium dropdowns, heavy modals |
184
+ | Stock laptop photos | Product screenshots, hand-drawn illustrations, or abstract geometric art |