picasso-skill 1.6.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -32
- package/agents/picasso.md +14 -2
- package/commands/backlog.md +34 -0
- package/commands/variants.md +18 -0
- package/package.json +1 -1
- package/references/animation-performance.md +244 -0
- package/references/brand-and-identity.md +136 -0
- package/references/code-typography.md +222 -0
- package/references/dark-mode.md +199 -0
- package/references/i18n-visual-patterns.md +177 -0
- package/references/images-and-media.md +222 -0
- package/references/loading-and-states.md +258 -0
- package/references/micro-interactions.md +291 -0
- package/references/navigation-patterns.md +247 -0
- package/references/tables-and-forms.md +227 -0
- package/skills/picasso/SKILL.md +35 -2
- package/skills/picasso/references/animation-performance.md +244 -0
- package/skills/picasso/references/brand-and-identity.md +136 -0
- package/skills/picasso/references/code-typography.md +222 -0
- package/skills/picasso/references/dark-mode.md +199 -0
- package/skills/picasso/references/i18n-visual-patterns.md +177 -0
- package/skills/picasso/references/images-and-media.md +222 -0
- package/skills/picasso/references/loading-and-states.md +258 -0
- package/skills/picasso/references/micro-interactions.md +291 -0
- package/skills/picasso/references/navigation-patterns.md +247 -0
- package/skills/picasso/references/tables-and-forms.md +227 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
|
|
8
|
+
32 reference domains • 40+ commands • 11,000+ lines of actionable design intelligence<br/>
|
|
9
9
|
Every interface looks like a senior design engineer spent days on it.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
@@ -36,7 +36,7 @@ Existing design skills are shallow. They tell you to "use good typography" witho
|
|
|
36
36
|
|
|
37
37
|
### Depth That No Other Skill Matches
|
|
38
38
|
|
|
39
|
-
Picasso covers **
|
|
39
|
+
Picasso covers **32 specialized reference domains**, each with concrete rules, specific values, and ready-to-use code. This isn't a collection of vague principles -- it's an engineering specification for beautiful interfaces.
|
|
40
40
|
|
|
41
41
|
| Domain | What You Get |
|
|
42
42
|
|---|---|
|
|
@@ -61,6 +61,16 @@ Picasso covers **20 specialized reference domains**, each with concrete rules, s
|
|
|
61
61
|
| **UX Writing** | Error message formula (what + why + fix), button label rules (verb + object), translation expansion percentages, terminology consistency |
|
|
62
62
|
| **Style Presets** | 22 curated visual presets with hex values, font pairings, border-radius, and signature UI elements, mapped to moods |
|
|
63
63
|
| **Performance Optimization** | Vercel's 45 React/Next.js rules across 7 priority tiers with BAD/GOOD code examples |
|
|
64
|
+
| **Navigation Patterns** | Breadcrumbs with ARIA, sidebar collapse, tabs vs button groups, mobile bottom bar vs hamburger, sticky headers, mega menus, skip links |
|
|
65
|
+
| **Tables & Forms** | Sortable tables with `aria-sort`, responsive strategies, inline editing, multi-select, form validation (blur/submit/real-time), multi-step forms |
|
|
66
|
+
| **Loading & States** | Duration rules (<1s/1-3s/3s+/10s+), skeleton shimmer CSS, 5 empty state types, error boundaries, retry with backoff, offline detection |
|
|
67
|
+
| **Dark Mode** | Preference hierarchy, surface elevation (lighter = higher), mode transitions, accent adjustment, image dimming, forced-colors, autofill fix |
|
|
68
|
+
| **Images & Media** | AVIF/WebP/SVG decision tree, srcset/sizes, CLS prevention, favicon multi-format, OG images (1200x630), video backgrounds |
|
|
69
|
+
| **Micro-Interactions** | IntersectionObserver scroll animations, View Transitions API, magnetic cursors, gesture detection (swipe/pinch), animation budget (max 3 concurrent) |
|
|
70
|
+
| **i18n Visual Patterns** | Logical properties for RTL, text expansion by language (+35% German), CJK rendering, Noto font stacks, icon mirroring rules |
|
|
71
|
+
| **Brand & Identity** | Logo sizing (min 24px), clear space rules, lockup variants, 60-30-10 brand color usage, when to bend brand rules |
|
|
72
|
+
| **Animation Performance** | Compositor-only properties (transform + opacity only), will-change lifecycle, layout thrashing batching, `contain` property, GPU hints |
|
|
73
|
+
| **Code Typography** | JetBrains Mono/Fira Code selection, syntax highlighting contrast (3:1 min), code block design, copy button UX, diff views, terminal styling |
|
|
64
74
|
|
|
65
75
|
### The AI-Slop Firewall
|
|
66
76
|
|
|
@@ -272,10 +282,10 @@ We compared Picasso against every publicly available AI design skill as of April
|
|
|
272
282
|
|
|
273
283
|
| Metric | Picasso | Anthropic frontend-design | Impeccable | Taste Skill | Generic skills |
|
|
274
284
|
|---|---|---|---|---|---|
|
|
275
|
-
| **Reference domains** | **
|
|
276
|
-
| **Total lines of guidance** | **
|
|
285
|
+
| **Reference domains** | **32** | 1 | 7 | 1 | 1-3 |
|
|
286
|
+
| **Total lines of guidance** | **11,000+** | ~120 | ~2,500 | ~200 | 50-300 |
|
|
277
287
|
| **Anti-pattern rules** | **50+** | ~10 | ~30 | ~5 | 0-5 |
|
|
278
|
-
| **Steering commands** | **
|
|
288
|
+
| **Steering commands** | **40+** | 0 | 20 | 0 | 0-3 |
|
|
279
289
|
| **ARIA patterns documented** | **12 widgets** | 0 | 0 | 0 | 0 |
|
|
280
290
|
| **React performance rules** | **45 (Vercel)** | 0 | 0 | 0 | 0 |
|
|
281
291
|
| **Chart/data viz guidance** | **Full matrix** | None | None | None | None |
|
|
@@ -336,6 +346,12 @@ npx picasso-skill --cursor
|
|
|
336
346
|
# Install for Codex
|
|
337
347
|
npx picasso-skill --codex
|
|
338
348
|
|
|
349
|
+
# Install for OpenClaw
|
|
350
|
+
npx picasso-skill --openclaw
|
|
351
|
+
|
|
352
|
+
# Or via ClawHub marketplace
|
|
353
|
+
clawhub install picasso
|
|
354
|
+
|
|
339
355
|
# Custom path
|
|
340
356
|
npx picasso-skill --path ./my-skills
|
|
341
357
|
```
|
|
@@ -378,14 +394,15 @@ Picasso ships as both a **skill** (knowledge base) and an **agent** (autonomous
|
|
|
378
394
|
|
|
379
395
|
| | Skill | Agent |
|
|
380
396
|
|---|---|---|
|
|
381
|
-
| **What it is** |
|
|
397
|
+
| **What it is** | 32 reference files of design intelligence | Autonomous design auditor with anti-slop gate |
|
|
382
398
|
| **How it works** | Loaded into context when designing | Runs as a sub-process with its own tools |
|
|
383
|
-
| **When it runs** | When you ask for design help |
|
|
384
|
-
| **Can audit code** | Only when asked |
|
|
385
|
-
| **Can run axe-core** | No | Yes |
|
|
386
|
-
| **Can screenshot pages** | No | Yes (via Playwright) |
|
|
387
|
-
| **Can auto-fix issues** | No | Yes |
|
|
399
|
+
| **When it runs** | When you ask for design help | On explicit commands (/audit, /roast, /godmode, etc.) |
|
|
400
|
+
| **Can audit code** | Only when asked | Yes, with structured scoring |
|
|
401
|
+
| **Can run axe-core** | No | Yes (via CLI) |
|
|
402
|
+
| **Can screenshot pages** | No | Yes (via Playwright MCP) |
|
|
403
|
+
| **Can auto-fix issues** | No | Yes (with pre-flight git/test checks) |
|
|
388
404
|
| **Can enforce design system** | No | Yes (greps for token violations) |
|
|
405
|
+
| **Enforces anti-slop gate** | Via SKILL.md instructions | Yes, mandatory before any code generation |
|
|
389
406
|
|
|
390
407
|
---
|
|
391
408
|
|
|
@@ -481,6 +498,10 @@ GODMODE Complete: 42 → 87 (+45 points), 47 files modified, 23 issues fixed
|
|
|
481
498
|
| `/mood-board` | Generate interactive HTML mood board from adjectives |
|
|
482
499
|
| `/design-system-sync` | Detect and auto-fix drift between DESIGN.md and actual code |
|
|
483
500
|
| `/preset <name>` | Apply a curated preset (linear, stripe, vercel, notion, brutalist, etc.) |
|
|
501
|
+
| `/quick-audit` | 5-minute fast audit: 6 binary pass/fail checks (font, color, layout, spacing, a11y, anti-slop) |
|
|
502
|
+
| `/autorefine` | Binary evaluation loop: 6 criteria, mutate one thing at a time, iterate to 95%+ pass rate |
|
|
503
|
+
| `/backlog` | Create persistent design debt backlog with impact-priority scoring in `.picasso-backlog.md` |
|
|
504
|
+
| `/variants` | Generate 2-3 distinct visual directions for A/B comparison with code previews |
|
|
484
505
|
|
|
485
506
|
### Advanced
|
|
486
507
|
|
|
@@ -505,27 +526,39 @@ GODMODE Complete: 42 → 87 (+45 points), 47 files modified, 23 issues fixed
|
|
|
505
526
|
## References
|
|
506
527
|
|
|
507
528
|
```
|
|
508
|
-
references/
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
+
references/ # 32 files, 9,300+ lines
|
|
530
|
+
anti-patterns.md # 50+ banned patterns (THE MOST IMPORTANT FILE)
|
|
531
|
+
typography.md # Type systems, font pairing, scales, OpenType, vertical rhythm
|
|
532
|
+
color-and-contrast.md # OKLCH, tinted neutrals, dark mode, 60-30-10, dangerous combos
|
|
533
|
+
spatial-design.md # 4px spacing scale, grids, hierarchy, Squint Test
|
|
534
|
+
depth-and-elevation.md # Dual shadows, layering, shadow scale, z-index, hover patterns
|
|
535
|
+
motion-and-animation.md # Duration rule, easing curves, staggering, text morphing
|
|
536
|
+
micro-interactions.md # Scroll animations, View Transitions, gestures, magnetic cursors
|
|
537
|
+
animation-performance.md # Compositor-only props, will-change, layout thrashing, contain
|
|
538
|
+
interaction-design.md # 8 states, forms, focus, Popover API, dropdown positioning
|
|
539
|
+
navigation-patterns.md # Breadcrumbs, sidebar, tabs, bottom bar, mega menus, skip links
|
|
540
|
+
tables-and-forms.md # Sortable tables, inline editing, validation, multi-step forms
|
|
541
|
+
loading-and-states.md # Skeletons, error boundaries, 5 empty state types, offline
|
|
542
|
+
responsive-design.md # Input method detection, safe areas, container queries
|
|
543
|
+
dark-mode.md # Preference hierarchy, elevation, transitions, testing
|
|
544
|
+
images-and-media.md # Format selection, srcset, favicons, OG images, video
|
|
545
|
+
brand-and-identity.md # Logo sizing, brand color 60-30-10, lockup variants
|
|
546
|
+
i18n-visual-patterns.md # RTL, logical properties, text expansion, CJK, Noto stacks
|
|
547
|
+
code-typography.md # Monospace fonts, syntax highlighting, code blocks, diff views
|
|
548
|
+
sensory-design.md # soundcn, web-haptics, multi-sensory integration
|
|
549
|
+
react-patterns.md # Server Components, composition, state management, styling
|
|
550
|
+
design-system.md # 9-section DESIGN.md format, theme generation, tokens
|
|
551
|
+
generative-art.md # Philosophy-first process, p5.js, seeded randomness
|
|
552
|
+
component-patterns.md # 40+ components, state matrix, compound patterns
|
|
553
|
+
ux-psychology.md # Gestalt, Fitts's/Hick's/Miller's/Jakob's Law, F/Z-pattern
|
|
554
|
+
ux-writing.md # Error formula, button labels, empty states, terminology
|
|
555
|
+
data-visualization.md # Chart selection matrix, dashboard layouts, Tufte
|
|
556
|
+
conversion-design.md # Landing pages, CTAs, pricing, onboarding, notifications
|
|
557
|
+
accessibility-wcag.md # 12 ARIA patterns, WCAG 2.2, SPA focus, accessible tables
|
|
558
|
+
modern-css-performance.md # Nesting, :has(), @layer, View Transitions, Tailwind v4
|
|
559
|
+
performance-optimization.md # 45 Vercel rules across 7 priority tiers
|
|
560
|
+
style-presets.md # 22 visual presets with OKLCH values and font pairings
|
|
561
|
+
tools-catalog.md # torph, soundcn, Lucide, Facehash, better-icons
|
|
529
562
|
```
|
|
530
563
|
|
|
531
564
|
---
|
package/agents/picasso.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: picasso
|
|
3
|
-
description: "
|
|
3
|
+
description: "Senior design engineer agent that audits, enforces, and improves frontend UI quality. Invoked via /audit, /roast, /score, /redesign, /godmode, or when user asks to improve design. Supports Playwright screenshots for visual validation. Enforces mandatory anti-slop gate before any design code generation. 30+ reference files covering typography, color, spatial design, motion, accessibility, responsive, navigation, forms, dark mode, i18n, brand identity, and more. For proactive auto-review on file changes, configure hooks in settings.json."
|
|
4
4
|
tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
@@ -112,6 +112,8 @@ The interview is skipped when:
|
|
|
112
112
|
- User says "just do it" or "skip the interview" or provides a detailed enough prompt
|
|
113
113
|
- Proactive mode (triggered by file changes) -- never interview, just audit
|
|
114
114
|
|
|
115
|
+
**CRITICAL: Even when the interview is skipped, Phase 0b (Anti-Slop Gate) MUST still run for any design generation task.** The interview captures preferences. The gate ensures quality. They are independent. Skipping one does not skip the other. The only commands that bypass BOTH are pure audit commands (`/audit`, `/score`, `/quick-audit`, `/roast`) which do not generate code.
|
|
116
|
+
|
|
115
117
|
### Re-running the Interview
|
|
116
118
|
|
|
117
119
|
User can run `/picasso` at any time to redo the interview and regenerate `.picasso.md`.
|
|
@@ -383,9 +385,17 @@ When invoked with `/polish`, `/redesign`, or when the user says "fix it":
|
|
|
383
385
|
|
|
384
386
|
**BEFORE ANY CODE CHANGES:** Run the Anti-Slop Gate (Phase 0b). Write out your commitments. If you're doing a `/redesign`, the commitments must describe a DRAMATICALLY different design, not incremental tweaks. The goal is transformation, not iteration.
|
|
385
387
|
|
|
388
|
+
### Pre-Flight Checks (before ANY auto-fix)
|
|
389
|
+
|
|
390
|
+
1. **Check git status** — run `git status`. If there are uncommitted changes, WARN the user: "You have uncommitted changes. Auto-fix will modify files. Commit or stash first?"
|
|
391
|
+
2. **Count affected files** — if auto-fix would touch more than 10 files, list them and ask for confirmation before proceeding.
|
|
392
|
+
3. **Run existing tests** — if a test command exists (`package.json` scripts.test), run it BEFORE fixing. If tests fail before your changes, note it. If tests pass before but fail after, REVERT your changes immediately.
|
|
393
|
+
|
|
394
|
+
### Fix Execution
|
|
395
|
+
|
|
386
396
|
1. Start with Critical issues, then High, then Medium
|
|
387
397
|
2. Make the smallest change that fixes the issue
|
|
388
|
-
3. Preserve existing design intent
|
|
398
|
+
3. Preserve existing design intent — improve, don't redesign (unless `/redesign`)
|
|
389
399
|
4. After fixing, re-run the audit to verify the score improved
|
|
390
400
|
5. Show a before/after diff summary
|
|
391
401
|
6. **Re-run the 3-Second Test** on screenshots. If it still looks AI-generated, you're not done.
|
|
@@ -498,6 +508,8 @@ When the user invokes these commands, execute the corresponding workflow:
|
|
|
498
508
|
| `/godmode` | The ultimate command: interview + audit + score + roast + fix everything + before/after report |
|
|
499
509
|
| `/quick-audit` | 5-minute fast audit: font, color, spacing, a11y, anti-slop — skip the deep dive |
|
|
500
510
|
| `/autorefine` | Binary evaluation loop: define 6 criteria, mutate one thing at a time, iterate to 95%+ pass rate |
|
|
511
|
+
| `/backlog` | Create persistent design debt backlog with impact-priority scoring in .picasso-backlog.md |
|
|
512
|
+
| `/variants` | Generate 2-3 distinct visual directions for A/B comparison with previews |
|
|
501
513
|
|
|
502
514
|
## /godmode -- The Ultimate Design Transformation
|
|
503
515
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Run the Picasso /backlog command -- create and manage a persistent design debt backlog.
|
|
2
|
+
|
|
3
|
+
Create or update `.picasso-backlog.md` in the project root.
|
|
4
|
+
|
|
5
|
+
Steps:
|
|
6
|
+
1. Run /quick-audit to get current pass/fail status
|
|
7
|
+
2. Run /score to get quantified baseline
|
|
8
|
+
3. For each failing category, create a backlog item with:
|
|
9
|
+
- Severity: critical / high / medium / low
|
|
10
|
+
- Impact: estimated /score improvement (+N points)
|
|
11
|
+
- Files: which files need changes
|
|
12
|
+
- Fix: one-line description of what to change
|
|
13
|
+
4. Sort items by impact descending (highest score improvement first)
|
|
14
|
+
5. Write to `.picasso-backlog.md`
|
|
15
|
+
|
|
16
|
+
Format:
|
|
17
|
+
```markdown
|
|
18
|
+
# Picasso Design Backlog
|
|
19
|
+
Generated: [date] | Baseline Score: [N]/100
|
|
20
|
+
|
|
21
|
+
## Critical
|
|
22
|
+
- [ ] **Replace pure grays with tinted neutrals** (+6 pts) — globals.css, tailwind.config — Change #808080 to oklch(0.55 0.02 var(--hue))
|
|
23
|
+
|
|
24
|
+
## High
|
|
25
|
+
- [ ] **Add prefers-reduced-motion guard** (+4 pts) — globals.css — Wrap animations in @media (prefers-reduced-motion: no-preference)
|
|
26
|
+
|
|
27
|
+
## Medium
|
|
28
|
+
- [ ] **Fix transition:all instances** (+2 pts) — 3 files — Specify exact properties
|
|
29
|
+
|
|
30
|
+
## Low
|
|
31
|
+
- [ ] **Add skip link** (+1 pt) — layout.tsx — Add visually hidden skip-to-content link
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If `.picasso-backlog.md` already exists, update it: mark completed items as done, add new findings, recalculate impacts.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Run the Picasso /variants command -- generate 2-3 distinct visual directions for A/B comparison.
|
|
2
|
+
|
|
3
|
+
Steps:
|
|
4
|
+
1. Read the current project's design context (.picasso.md, DESIGN.md, or infer from code)
|
|
5
|
+
2. Generate 2-3 genuinely different aesthetic directions. NOT slight variations -- each must differ in at least 3 of: font, color palette, layout structure, border-radius philosophy, motion intensity
|
|
6
|
+
3. For each direction:
|
|
7
|
+
- Name it (e.g., "Editorial Minimalist", "Dark Terminal", "Warm Organic")
|
|
8
|
+
- List the 5 key design tokens (font, accent color, radius, shadow style, spacing density)
|
|
9
|
+
- Describe what makes it distinctive in 1-2 sentences
|
|
10
|
+
- Show a code snippet of one component (e.g., a card or button) in that style
|
|
11
|
+
4. Present all directions to the user and ask which to pursue
|
|
12
|
+
5. If Playwright is available, generate a quick HTML preview of each direction
|
|
13
|
+
|
|
14
|
+
Rules:
|
|
15
|
+
- Each direction must pass the 3-second anti-slop test independently
|
|
16
|
+
- No two directions can share the same font
|
|
17
|
+
- At least one direction must be surprising or unconventional
|
|
18
|
+
- Always include one "safe" option and one "bold" option
|
package/package.json
CHANGED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Animation Performance Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
1. Compositor-Only Properties
|
|
5
|
+
2. Will-Change Best Practices
|
|
6
|
+
3. Layout Thrashing
|
|
7
|
+
4. IntersectionObserver vs Scroll Events
|
|
8
|
+
5. Web Animations API
|
|
9
|
+
6. Performance Measurement
|
|
10
|
+
7. Testing on Low-End Devices
|
|
11
|
+
8. Contain Property
|
|
12
|
+
9. Common Mistakes
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Compositor-Only Properties
|
|
17
|
+
|
|
18
|
+
Only two CSS properties can be animated without triggering layout or paint: **transform** and **opacity**. Everything else causes reflow.
|
|
19
|
+
|
|
20
|
+
| Property | Layout | Paint | Composite | Animate? |
|
|
21
|
+
|---|---|---|---|---|
|
|
22
|
+
| `transform` | No | No | Yes | **Yes** |
|
|
23
|
+
| `opacity` | No | No | Yes | **Yes** |
|
|
24
|
+
| `filter` | No | Yes | Yes | Carefully |
|
|
25
|
+
| `background-color` | No | Yes | No | Avoid |
|
|
26
|
+
| `width`, `height` | Yes | Yes | No | **Never** |
|
|
27
|
+
| `top`, `left` | Yes | Yes | No | **Never** |
|
|
28
|
+
| `margin`, `padding` | Yes | Yes | No | **Never** |
|
|
29
|
+
| `border-radius` | No | Yes | No | Avoid |
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
/* Good: compositor-only */
|
|
33
|
+
.slide-in {
|
|
34
|
+
transform: translateX(-100%);
|
|
35
|
+
opacity: 0;
|
|
36
|
+
transition: transform 300ms var(--ease-out), opacity 300ms var(--ease-out);
|
|
37
|
+
}
|
|
38
|
+
.slide-in.active {
|
|
39
|
+
transform: translateX(0);
|
|
40
|
+
opacity: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Bad: triggers layout on every frame */
|
|
44
|
+
.slide-in-bad {
|
|
45
|
+
left: -100%;
|
|
46
|
+
transition: left 300ms ease;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 2. Will-Change Best Practices
|
|
53
|
+
|
|
54
|
+
`will-change` promotes an element to its own compositor layer. This speeds up animation but consumes GPU memory.
|
|
55
|
+
|
|
56
|
+
Rules:
|
|
57
|
+
- Add `will-change` BEFORE the animation starts (e.g., on hover, not in the animation itself).
|
|
58
|
+
- Remove it AFTER the animation completes.
|
|
59
|
+
- Never use `will-change: all` — it promotes everything.
|
|
60
|
+
- Never apply it to more than 10 elements simultaneously.
|
|
61
|
+
- Don't put it in your stylesheet permanently.
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
// Good: apply before, remove after
|
|
65
|
+
element.addEventListener('mouseenter', () => {
|
|
66
|
+
element.style.willChange = 'transform';
|
|
67
|
+
});
|
|
68
|
+
element.addEventListener('transitionend', () => {
|
|
69
|
+
element.style.willChange = 'auto';
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
/* Acceptable: for elements that are ALWAYS animated (e.g., loading spinners) */
|
|
75
|
+
.spinner { will-change: transform; }
|
|
76
|
+
|
|
77
|
+
/* Bad: permanent will-change on static elements */
|
|
78
|
+
.card { will-change: transform, opacity; } /* don't do this */
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 3. Layout Thrashing
|
|
84
|
+
|
|
85
|
+
Reading layout properties then writing them in a loop forces the browser to recalculate layout on every iteration.
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
// BAD: layout thrashing (read-write-read-write)
|
|
89
|
+
elements.forEach(el => {
|
|
90
|
+
const height = el.offsetHeight; // READ — forces layout
|
|
91
|
+
el.style.height = height + 10 + 'px'; // WRITE — invalidates layout
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// GOOD: batch reads, then batch writes
|
|
95
|
+
const heights = elements.map(el => el.offsetHeight); // all reads first
|
|
96
|
+
elements.forEach((el, i) => {
|
|
97
|
+
el.style.height = heights[i] + 10 + 'px'; // all writes after
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Properties that trigger forced layout when read: `offsetHeight`, `offsetWidth`, `getBoundingClientRect()`, `scrollTop`, `clientHeight`, `getComputedStyle()`.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 4. IntersectionObserver vs Scroll Events
|
|
106
|
+
|
|
107
|
+
| | `scroll` event | IntersectionObserver |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| Performance | Fires every pixel, blocks main thread | Async, fires on threshold crossing |
|
|
110
|
+
| Throttling | Manual (requestAnimationFrame) | Built-in |
|
|
111
|
+
| Use case | Scroll-linked animation (position) | Visibility detection (enter/exit) |
|
|
112
|
+
| Recommendation | Almost never | Almost always |
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
// Good: IntersectionObserver for reveal animations
|
|
116
|
+
const observer = new IntersectionObserver(
|
|
117
|
+
(entries) => {
|
|
118
|
+
entries.forEach(entry => {
|
|
119
|
+
entry.target.classList.toggle('visible', entry.isIntersecting);
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
{ threshold: 0.1 }
|
|
123
|
+
);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For scroll-linked animations where you need exact scroll position, use the Scroll-Driven Animations API:
|
|
127
|
+
|
|
128
|
+
```css
|
|
129
|
+
@keyframes fade-in {
|
|
130
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
131
|
+
to { opacity: 1; transform: translateY(0); }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.scroll-reveal {
|
|
135
|
+
animation: fade-in linear;
|
|
136
|
+
animation-timeline: view();
|
|
137
|
+
animation-range: entry 0% entry 100%;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 5. Web Animations API
|
|
144
|
+
|
|
145
|
+
For complex JS-driven animations, use WAAPI instead of manual `requestAnimationFrame`:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
element.animate(
|
|
149
|
+
[
|
|
150
|
+
{ transform: 'translateY(20px)', opacity: 0 },
|
|
151
|
+
{ transform: 'translateY(0)', opacity: 1 }
|
|
152
|
+
],
|
|
153
|
+
{
|
|
154
|
+
duration: 300,
|
|
155
|
+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
|
|
156
|
+
fill: 'forwards'
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Benefits over CSS: programmable, cancellable, can read progress, can reverse.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 6. Performance Measurement
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
// Measure animation frame rate
|
|
169
|
+
let frames = 0;
|
|
170
|
+
let lastTime = performance.now();
|
|
171
|
+
|
|
172
|
+
function countFrames() {
|
|
173
|
+
frames++;
|
|
174
|
+
const now = performance.now();
|
|
175
|
+
if (now - lastTime >= 1000) {
|
|
176
|
+
console.log(`FPS: ${frames}`);
|
|
177
|
+
frames = 0;
|
|
178
|
+
lastTime = now;
|
|
179
|
+
}
|
|
180
|
+
requestAnimationFrame(countFrames);
|
|
181
|
+
}
|
|
182
|
+
requestAnimationFrame(countFrames);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Chrome DevTools:
|
|
186
|
+
1. Performance tab → Record → interact with animations → Stop
|
|
187
|
+
2. Look for long frames (> 16ms) in the flame chart
|
|
188
|
+
3. Rendering tab → Paint flashing (green = repaint, should be minimal)
|
|
189
|
+
4. Rendering tab → Layer borders (orange = composited layers)
|
|
190
|
+
|
|
191
|
+
Target: 60fps = 16.67ms per frame. If ANY frame takes > 33ms, users perceive jank.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 7. Testing on Low-End Devices
|
|
196
|
+
|
|
197
|
+
Your M-series Mac is not representative. Test with:
|
|
198
|
+
- **Chrome DevTools CPU throttling:** Performance tab → CPU → 6x slowdown
|
|
199
|
+
- **Network throttling:** Slow 3G preset to test loading animations
|
|
200
|
+
- **Real device:** Test on a 3-year-old Android phone if possible
|
|
201
|
+
|
|
202
|
+
If an animation stutters at 6x CPU throttle, reduce:
|
|
203
|
+
1. Number of concurrent animations
|
|
204
|
+
2. Element count being animated
|
|
205
|
+
3. Complexity of each animation
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 8. Contain Property
|
|
210
|
+
|
|
211
|
+
`contain` tells the browser what NOT to recalculate when an element changes.
|
|
212
|
+
|
|
213
|
+
```css
|
|
214
|
+
/* Isolate layout/paint to this element */
|
|
215
|
+
.card {
|
|
216
|
+
contain: layout paint;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Full isolation — best for off-screen or independent components */
|
|
220
|
+
.widget {
|
|
221
|
+
contain: strict; /* = size + layout + paint + style */
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Content containment — layout + paint + style (most common) */
|
|
225
|
+
.list-item {
|
|
226
|
+
contain: content;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Use `contain: content` on repeated elements (list items, cards) to prevent layout changes from propagating to siblings.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 9. Common Mistakes
|
|
235
|
+
|
|
236
|
+
- **Animating `width`/`height`/`top`/`left`.** Use `transform: translate/scale` instead.
|
|
237
|
+
- **`will-change` on everything.** Max 10 elements. Remove after animation completes.
|
|
238
|
+
- **`addEventListener('scroll')` for visibility.** Use IntersectionObserver.
|
|
239
|
+
- **Reading layout properties in animation loops.** Batch reads before writes.
|
|
240
|
+
- **Testing only on fast hardware.** Use Chrome CPU throttling at 6x.
|
|
241
|
+
- **No frame budget awareness.** 16ms per frame. If your JS takes 20ms, you drop frames.
|
|
242
|
+
- **CSS `transition: all`.** Transitions every property including layout triggers.
|
|
243
|
+
- **Forgetting `contain` on repeated elements.** One card's layout change recalculates the entire list.
|
|
244
|
+
- **`requestAnimationFrame` without cancellation.** Always store the ID and `cancelAnimationFrame` on cleanup.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Brand and Identity Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
1. Logo Sizing Rules
|
|
5
|
+
2. Logo Placement
|
|
6
|
+
3. Logo Lockup Variants
|
|
7
|
+
4. Brand Color Usage
|
|
8
|
+
5. Brand Typography
|
|
9
|
+
6. Consistency Across Pages
|
|
10
|
+
7. When to Bend Brand Rules
|
|
11
|
+
8. Common Mistakes
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Logo Sizing Rules
|
|
16
|
+
|
|
17
|
+
- **Minimum size:** 24px height for icon-only, 32px height for full logo. Below this it's illegible.
|
|
18
|
+
- **Clear space:** Minimum clear space around logo = the height of the logo's icon element. No text or elements may intrude.
|
|
19
|
+
- **Typical sizes by context:**
|
|
20
|
+
|
|
21
|
+
| Context | Height |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Favicon | 32px |
|
|
24
|
+
| Mobile header | 28-32px |
|
|
25
|
+
| Desktop header | 32-40px |
|
|
26
|
+
| Footer | 24-28px |
|
|
27
|
+
| Hero/marketing | 48-64px |
|
|
28
|
+
| App splash | 80-120px |
|
|
29
|
+
|
|
30
|
+
```css
|
|
31
|
+
.logo { height: 32px; width: auto; } /* maintain aspect ratio */
|
|
32
|
+
.logo-icon { height: 28px; width: 28px; }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Logo Placement
|
|
38
|
+
|
|
39
|
+
- **Header:** top-left for LTR, top-right for RTL. Always links to homepage.
|
|
40
|
+
- **Footer:** bottom-left or bottom-center. Smaller than header.
|
|
41
|
+
- **Marketing pages:** centered for hero sections, left-aligned for navigation.
|
|
42
|
+
- **Loading/splash:** centered vertically and horizontally.
|
|
43
|
+
|
|
44
|
+
The header logo is the most important. It should be the first visual element the user sees, but not dominate the page. Keep it slim.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 3. Logo Lockup Variants
|
|
49
|
+
|
|
50
|
+
Every brand needs at least 3 logo variants:
|
|
51
|
+
|
|
52
|
+
1. **Full lockup:** icon + wordmark (for headers, marketing)
|
|
53
|
+
2. **Icon only:** for favicons, app icons, small spaces, mobile headers
|
|
54
|
+
3. **Wordmark only:** for editorial/text-heavy contexts
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
// Responsive logo: icon on mobile, full on desktop
|
|
58
|
+
<Link href="/" className="flex items-center gap-2">
|
|
59
|
+
<img src="/logo-icon.svg" alt="" className="h-7 w-7" />
|
|
60
|
+
<span className="hidden sm:inline text-sm font-bold tracking-tight">Brand Name</span>
|
|
61
|
+
</Link>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 4. Brand Color Usage
|
|
67
|
+
|
|
68
|
+
Follow the 60-30-10 rule with brand colors:
|
|
69
|
+
- **60%** — neutral surfaces (backgrounds, cards). Brand color should NOT be the 60%.
|
|
70
|
+
- **30%** — supporting colors (borders, secondary text, section backgrounds).
|
|
71
|
+
- **10%** — brand/accent color (CTAs, active states, highlights). This is where brand color goes.
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
:root {
|
|
75
|
+
--brand: oklch(0.55 0.25 250); /* Primary brand color — use at 10% */
|
|
76
|
+
--brand-subtle: oklch(0.95 0.03 250); /* Tinted background — use sparingly */
|
|
77
|
+
--brand-on-dark: oklch(0.70 0.18 250); /* Lighter variant for dark backgrounds */
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Never use brand color as background for large areas (hero sections, full-width bars) unless the brand is specifically known for it (like Spotify's green). Large saturated surfaces are fatiguing.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 5. Brand Typography
|
|
86
|
+
|
|
87
|
+
If the brand has a custom/licensed font, use it for headings only. Body text should be a readable, web-optimized font.
|
|
88
|
+
|
|
89
|
+
```css
|
|
90
|
+
/* Brand font for headings */
|
|
91
|
+
h1, h2, h3 { font-family: 'Brand Display', var(--font-body); }
|
|
92
|
+
|
|
93
|
+
/* Readable font for body */
|
|
94
|
+
body { font-family: 'DM Sans', system-ui, sans-serif; }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the brand font isn't available for web, find the closest web-safe alternative:
|
|
98
|
+
- Futura → use Outfit or Jost
|
|
99
|
+
- Helvetica Neue → use Inter (only acceptable here) or Geist
|
|
100
|
+
- Garamond → use EB Garamond or Cormorant
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 6. Consistency Across Pages
|
|
105
|
+
|
|
106
|
+
Every page should share:
|
|
107
|
+
- Same header and footer (identical, not "similar")
|
|
108
|
+
- Same color palette (no page-specific colors)
|
|
109
|
+
- Same typography scale
|
|
110
|
+
- Same border-radius philosophy
|
|
111
|
+
- Same spacing scale
|
|
112
|
+
|
|
113
|
+
Variation should come from layout and content, not from inconsistent styling. A dashboard page and a marketing page can look different through layout while sharing the same design tokens.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 7. When to Bend Brand Rules
|
|
118
|
+
|
|
119
|
+
Strict brand adherence isn't always right:
|
|
120
|
+
- **Data-dense dashboards:** Brand color as accent only. Don't fight with data colors.
|
|
121
|
+
- **Error states:** Use standard red for errors, not brand color. Users need instant recognition.
|
|
122
|
+
- **Third-party embeds:** Payment forms, maps, chat widgets have their own styling. Don't fight it.
|
|
123
|
+
- **Dark mode:** Brand color may need lightness/chroma adjustment to maintain contrast.
|
|
124
|
+
- **Accessibility:** If brand colors don't meet WCAG contrast, accessibility wins.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 8. Common Mistakes
|
|
129
|
+
|
|
130
|
+
- **Logo too small in the header.** Minimum 28px height. Users need to identify the brand instantly.
|
|
131
|
+
- **Brand color as full-width background.** Fatiguing. Use at 10% ratio maximum.
|
|
132
|
+
- **Different fonts on every page.** Pick 2 fonts and use them everywhere.
|
|
133
|
+
- **Logo without clear space.** Crowded logos look unprofessional. Enforce minimum padding.
|
|
134
|
+
- **No icon-only variant.** Mobile needs a compact logo. Don't just shrink the full lockup.
|
|
135
|
+
- **Brand color unchanged in dark mode.** Adjust lightness and chroma for dark backgrounds.
|
|
136
|
+
- **Inconsistent border radius between pages.** One sharp page and one rounded page = two brands.
|