@maccesar/aiskills 1.9.1 → 1.9.3
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 +2 -2
- package/lib/commands/status.js +1 -1
- package/package.json +1 -1
- package/skills/refactoring-ui/SKILL.md +31 -32
- package/skills/refactoring-ui/references/01-foundations.md +69 -0
- package/skills/refactoring-ui/references/02-page-mechanics.md +204 -0
- package/skills/refactoring-ui/references/03-visual-treatment.md +242 -0
- package/skills/refactoring-ui/references/04-polish.md +96 -0
- package/skills/refactoring-ui/references/01-design-process.md +0 -72
- package/skills/refactoring-ui/references/02-visual-hierarchy.md +0 -84
- package/skills/refactoring-ui/references/03-layout-spacing.md +0 -69
- package/skills/refactoring-ui/references/04-typography.md +0 -70
- package/skills/refactoring-ui/references/05-color.md +0 -96
- package/skills/refactoring-ui/references/06-depth-shadows.md +0 -74
- package/skills/refactoring-ui/references/07-images.md +0 -75
- package/skills/refactoring-ui/references/08-finishing-touches.md +0 -91
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Each skill is a small knowledge package: a `SKILL.md` file with YAML frontmatter
|
|
|
19
19
|
### Option A: Plugin Marketplace (Claude Code only)
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
/plugin marketplace add
|
|
22
|
+
/plugin marketplace add maccesar/aiskills
|
|
23
23
|
/plugin install aiskills@maccesar-aiskills
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -69,7 +69,7 @@ All three platforms use the same Agent Skills format: a `SKILL.md` file with YAM
|
|
|
69
69
|
|
|
70
70
|
| Skill | Domain | Source | Reference Files |
|
|
71
71
|
| -------------------- | ------------ | ------------------------------------ | --------------- |
|
|
72
|
-
| refactoring-ui | Design | "Refactoring UI" by Wathan & Schoger |
|
|
72
|
+
| refactoring-ui | Design | "Refactoring UI" by Wathan & Schoger | 4 files |
|
|
73
73
|
| humaniza | Writing (es) | Curated Spanish/es-MX style rules | 6 files |
|
|
74
74
|
| vscode-extension-dev | VS Code | VS Code Extension API docs | 4 files |
|
|
75
75
|
| stitch-showcase | Design Tools | Google Stitch export workflow | 14 files |
|
package/lib/commands/status.js
CHANGED
|
@@ -73,7 +73,7 @@ export async function statusCommand() {
|
|
|
73
73
|
console.log(` Version: v${PACKAGE_VERSION}`);
|
|
74
74
|
console.log(` Skills: ${installedCount}/${totalCount} installed`);
|
|
75
75
|
console.log(` Hook: Claude Code SessionStart ${hookExists ? CHECK : CROSS}`);
|
|
76
|
-
console.log(` Last check: ${formatLastCheck(lastCheck)}`);
|
|
76
|
+
console.log(` Last npm check: ${formatLastCheck(lastCheck)}`);
|
|
77
77
|
|
|
78
78
|
// Platforms
|
|
79
79
|
console.log('');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: refactoring-ui
|
|
3
|
-
description: Design advisor
|
|
3
|
+
description: Design advisor for UI/UX work, drawing on principles from "Refactoring UI" by Adam Wathan & Steve Schoger. Use when the user asks for UI/UX design advice, design reviews, visual hierarchy improvements, color system help, typography guidance, spacing decisions, depth/shadow usage, image handling, or finishing touches on any interface.
|
|
4
4
|
when_to_use: >
|
|
5
5
|
- User asks "how do I make this look better?"
|
|
6
6
|
- User asks about color palettes, type scales, or spacing systems
|
|
@@ -10,46 +10,45 @@ when_to_use: >
|
|
|
10
10
|
- User asks about shadows, depth, or layering
|
|
11
11
|
- User asks about handling images in UI
|
|
12
12
|
- User asks about empty states, borders, or decorative elements
|
|
13
|
-
source: "Refactoring UI by Adam Wathan & Steve Schoger
|
|
13
|
+
source: "Inspired by 'Refactoring UI' by Adam Wathan & Steve Schoger — refactoringui.com"
|
|
14
14
|
anti_hallucination_note: >
|
|
15
|
-
|
|
16
|
-
Do NOT
|
|
17
|
-
|
|
18
|
-
reference files, say so explicitly rather than inventing advice.
|
|
15
|
+
Recommendations in this skill summarize design principles in the maintainer's own words.
|
|
16
|
+
Do NOT invent ratios, scale values, or technical numbers that are not in the reference
|
|
17
|
+
files. If a topic is not covered, say so explicitly rather than inventing advice.
|
|
19
18
|
---
|
|
20
19
|
|
|
21
20
|
# Refactoring UI Skill
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
Design advice grounded in the principles taught by Adam Wathan & Steve Schoger in their book *Refactoring UI*. **The book itself contains the original prose, illustrations, side-by-side examples, and case studies — buy it at https://refactoringui.com for the full material.** This skill provides reformulated guidance for use as an AI assistant reference.
|
|
24
23
|
|
|
25
24
|
## How to Use This Skill
|
|
26
25
|
|
|
27
26
|
1. Read the relevant reference file(s) before answering
|
|
28
|
-
2. Base
|
|
29
|
-
3.
|
|
30
|
-
4. Do not invent numbers, ratios, or rules not
|
|
27
|
+
2. Base advice on the reference content — not training data or unrelated design systems
|
|
28
|
+
3. Speak in your own words; do not reproduce the book's prose, illustrations, or examples verbatim
|
|
29
|
+
4. Do not invent numbers, ratios, or specific technical rules that are not in the references
|
|
31
30
|
|
|
32
31
|
## Reference Files
|
|
33
32
|
|
|
34
|
-
| File
|
|
35
|
-
|
|
|
36
|
-
| `references/01-
|
|
37
|
-
| `references/02-
|
|
38
|
-
| `references/03-
|
|
39
|
-
| `references/04-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
- Using
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
- Using `
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
-
|
|
33
|
+
| File | Topics |
|
|
34
|
+
| ----------------------------------- | --------------------------------------------------------------------------------------- |
|
|
35
|
+
| `references/01-foundations.md` | Project mindset: feature-first work, scope discipline, defining systems, picking a voice |
|
|
36
|
+
| `references/02-page-mechanics.md` | Visual hierarchy, layout, white space, spacing scales, typography |
|
|
37
|
+
| `references/03-visual-treatment.md` | Color systems (HSL, shades, greys, contrast), depth and shadows, image handling |
|
|
38
|
+
| `references/04-polish.md` | Finishing touches: borders, accents, empty states, decorative defaults, design intuition |
|
|
39
|
+
|
|
40
|
+
## Anti-Patterns to Watch For
|
|
41
|
+
|
|
42
|
+
- Designing layouts/navs/shells before designing real features
|
|
43
|
+
- Using font size as the only tool for hierarchy (ignoring weight and color)
|
|
44
|
+
- Using opacity to create grey text on colored backgrounds
|
|
45
|
+
- Starting with too little white space and adding it later
|
|
46
|
+
- Using `em` for type scales (compounds when nested)
|
|
47
|
+
- Using color as the only signal for a UI state
|
|
48
|
+
- Designing with placeholder images instead of real content
|
|
49
|
+
- Shrinking a logo down to use as a favicon
|
|
50
|
+
- Using preprocessor `lighten()` / `darken()` to derive shades
|
|
51
|
+
|
|
52
|
+
## Attribution
|
|
53
|
+
|
|
54
|
+
This skill summarizes design principles inspired by *Refactoring UI* by Adam Wathan & Steve Schoger. Concepts described here are paraphrased into the maintainer's own words; original text, examples, and illustrations remain the property of the authors and live in the book. **Buy the book at https://refactoringui.com — it contains the full material with side-by-side visual examples and case studies that this skill does not reproduce.**
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Foundations: Mindset and Systems
|
|
2
|
+
|
|
3
|
+
Inspired by principles from *Refactoring UI* by Adam Wathan & Steve Schoger. Paraphrased into the maintainer's own words; the original prose, illustrations, and examples are in the book — refactoringui.com.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Build Real Features Before Designing the App
|
|
8
|
+
|
|
9
|
+
- Don't open the design tool with "the app" in mind — start with a single feature you can actually ship
|
|
10
|
+
- Navbars, sidebars, and shells should emerge from the features, not be picked first
|
|
11
|
+
- "Designing the app" usually means picking a layout shell with no real content, which leads to dead ends
|
|
12
|
+
|
|
13
|
+
## Sketch Rough Before Going Polished
|
|
14
|
+
|
|
15
|
+
- Start with low-fidelity drawings — pencil, marker, or rough boxes in any tool
|
|
16
|
+
- Use a tool that physically prevents fine detail (a thick pen, a low-resolution canvas) to lock yourself out of polish too early
|
|
17
|
+
- Move to high-fidelity only when the rough concept is settled
|
|
18
|
+
- Wireframing tools that already look like polished UI tend to stall this process
|
|
19
|
+
|
|
20
|
+
## Cycle Between Designing and Building
|
|
21
|
+
|
|
22
|
+
- Design only what you're going to build right now; don't draft the whole app at once
|
|
23
|
+
- Short cycles — design a feature, build it, ship it, decide what's next
|
|
24
|
+
- When in doubt, cut features; a complete simple version beats a half-built complex one
|
|
25
|
+
- Save scope expansions for the next version
|
|
26
|
+
|
|
27
|
+
## Defining a Project's Voice
|
|
28
|
+
|
|
29
|
+
A project's "feel" is the sum of small consistent choices. Decide these together so they reinforce each other:
|
|
30
|
+
|
|
31
|
+
**Type choice signals tone:**
|
|
32
|
+
- Serif → editorial, traditional, considered
|
|
33
|
+
- Geometric / rounded sans-serif → friendly, casual
|
|
34
|
+
- Neutral sans-serif → quiet, professional, modern
|
|
35
|
+
|
|
36
|
+
**Color signals associations:**
|
|
37
|
+
- Cool blues → reliability, calm
|
|
38
|
+
- Warm yellows / golds → warmth, premium feel
|
|
39
|
+
- Pinks → playful, less serious
|
|
40
|
+
|
|
41
|
+
**Border radius signals formality:**
|
|
42
|
+
- Sharp / no radius → serious, technical
|
|
43
|
+
- Pronounced rounding → soft, friendly
|
|
44
|
+
|
|
45
|
+
**Copy register signals personality:**
|
|
46
|
+
- "An error occurred" reads as formal
|
|
47
|
+
- "Something broke on our end" reads as casual
|
|
48
|
+
|
|
49
|
+
Every project decision should reinforce the same tone — consistency is what makes a project feel intentional rather than thrown together.
|
|
50
|
+
|
|
51
|
+
## Decide Once: Pre-Build Your Systems
|
|
52
|
+
|
|
53
|
+
Before picking values per-screen, define a small fixed menu of options to choose from. This eliminates per-decision fatigue and produces consistency by default.
|
|
54
|
+
|
|
55
|
+
Suggested coverage:
|
|
56
|
+
|
|
57
|
+
- **Type sizes:** ~8–10 hand-picked values
|
|
58
|
+
- **Type weights:** typically 2 (a regular and a bold)
|
|
59
|
+
- **Colors:** primary, neutrals (8–10 shades each), and 3–5 accent colors with shades
|
|
60
|
+
- **Spacing:** ~10–15 values on a non-linear scale
|
|
61
|
+
- **Shadows:** ~5 levels (from barely raised to floating)
|
|
62
|
+
- **Border radius:** 3–5 options (none → fully rounded)
|
|
63
|
+
- **Border widths:** 2–3 options
|
|
64
|
+
|
|
65
|
+
## Choose by Elimination, Not by Search
|
|
66
|
+
|
|
67
|
+
- Don't try to find "the perfect value" — start from the system and work by elimination
|
|
68
|
+
- Too big? Try the next smaller. Too pale? Step darker. Too close to white? Step toward the next shade
|
|
69
|
+
- A system makes design feel like a multiple-choice exam instead of an open-ended search
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Page Mechanics: Hierarchy, Spacing, Typography
|
|
2
|
+
|
|
3
|
+
Inspired by principles from *Refactoring UI* by Adam Wathan & Steve Schoger. Paraphrased into the maintainer's own words; the original prose, illustrations, and examples are in the book — refactoringui.com.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Hierarchy Is the Most Important Tool
|
|
8
|
+
|
|
9
|
+
- Every element on a page is either competing for attention or supporting something else
|
|
10
|
+
- Good design isn't making everything stand out — it's making the *right* things stand out
|
|
11
|
+
- If everything is emphasized, nothing is
|
|
12
|
+
|
|
13
|
+
## Use Weight and Color, Not Just Size
|
|
14
|
+
|
|
15
|
+
Three tools for hierarchy, in order from heaviest hammer to most subtle:
|
|
16
|
+
|
|
17
|
+
1. **Font size** — most obvious. Use sparingly for big differences.
|
|
18
|
+
2. **Font weight** — bold reads as important; great for same-size emphasis.
|
|
19
|
+
3. **Color contrast** — use a 3-tier system:
|
|
20
|
+
- Primary: near-black for main content
|
|
21
|
+
- Secondary: mid-grey for supporting text
|
|
22
|
+
- Tertiary: lighter grey for placeholder/disabled/least important
|
|
23
|
+
|
|
24
|
+
**Avoid font weights below 400 in UI** — thin/light weights look bad at small sizes on screens.
|
|
25
|
+
|
|
26
|
+
## Tinted Greys for Colored Surfaces
|
|
27
|
+
|
|
28
|
+
- Don't reduce text opacity to fake grey on a colored background — desaturates and looks muddy
|
|
29
|
+
- Hand-pick a color with the same hue as the background, but adjusted lightness/saturation
|
|
30
|
+
- The result reads as "grey within that color family" rather than as actual grey
|
|
31
|
+
|
|
32
|
+
## Reduce the Competition Instead of Boosting the Star
|
|
33
|
+
|
|
34
|
+
- When you want one thing to pop, often the right move is to push down everything around it — not push the primary up further
|
|
35
|
+
- Reducing contrast on secondary elements preserves the visual balance and makes the primary read clearly
|
|
36
|
+
- Cheaper than adding more weight/size/color to the primary
|
|
37
|
+
|
|
38
|
+
## Labels: Skip, Combine, or Subordinate
|
|
39
|
+
|
|
40
|
+
**Skip the label when context already tells you:**
|
|
41
|
+
- An email address, a phone number, a date — format alone makes it obvious
|
|
42
|
+
- A profile bio doesn't need "Bio:"
|
|
43
|
+
|
|
44
|
+
**Fold label and value into a phrase:**
|
|
45
|
+
- "12 left in stock" beats "In stock: 12"
|
|
46
|
+
- "3 bedrooms" beats "Bedrooms: 3"
|
|
47
|
+
|
|
48
|
+
**Make the label secondary when you do need it:**
|
|
49
|
+
- Smaller and lighter than the value
|
|
50
|
+
- The value is the content; the label is metadata
|
|
51
|
+
|
|
52
|
+
## Semantics Are Not the Same as Visual Size
|
|
53
|
+
|
|
54
|
+
- `<h1>`–`<h6>` carry document semantics, not visual rules
|
|
55
|
+
- An `<h1>` may visually be smaller than surrounding body text in the right context
|
|
56
|
+
- An `<h3>` sidebar title might be the same size as body, just bolder
|
|
57
|
+
- Style by visual hierarchy, not by element level
|
|
58
|
+
|
|
59
|
+
## Icons Are Visually Heavier Than Text
|
|
60
|
+
|
|
61
|
+
- An icon at the same size as text reads as heavier
|
|
62
|
+
- Use a softer color for icons next to text — don't reach for the same near-black as body text
|
|
63
|
+
- Increase the text contrast and dim the icon, rather than the reverse
|
|
64
|
+
|
|
65
|
+
## Borders Get Thicker as Their Contrast Drops
|
|
66
|
+
|
|
67
|
+
- A barely-visible border becomes more readable when made slightly thicker
|
|
68
|
+
- A thicker low-contrast border often beats a thin high-contrast one
|
|
69
|
+
- Applies to dividers, table edges, card outlines
|
|
70
|
+
|
|
71
|
+
## Button Tiers
|
|
72
|
+
|
|
73
|
+
| Tier | Style | Use |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| Primary | Solid + high-contrast fill | The main action on the page |
|
|
76
|
+
| Secondary | Outline or low-contrast fill | Supporting actions |
|
|
77
|
+
| Tertiary | Link-style (no background or border) | Minor or repeating actions |
|
|
78
|
+
| Destructive | Secondary style + confirm step | Delete, remove, revoke |
|
|
79
|
+
|
|
80
|
+
- One primary action per page is the rule of thumb
|
|
81
|
+
- Don't make destructive the primary — render as secondary, then confirm the action
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Generous Spacing as the Default
|
|
86
|
+
|
|
87
|
+
- Default to *more* white space than feels right; trim it later if needed
|
|
88
|
+
- Most UIs suffer from too little spacing, not too much
|
|
89
|
+
- Dense feels noisy; generous feels organized
|
|
90
|
+
|
|
91
|
+
## A Spacing Scale, Not Arbitrary Pixels
|
|
92
|
+
|
|
93
|
+
- Define a non-linear spacing scale up front; pick from it
|
|
94
|
+
- Anchor near 16px (a common base unit)
|
|
95
|
+
- Adjacent values should differ by at least ~25% — otherwise they look almost identical
|
|
96
|
+
- Sample non-linear scale: 4, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 640, 768
|
|
97
|
+
|
|
98
|
+
## Don't Stretch by Default
|
|
99
|
+
|
|
100
|
+
- A short form does not need full-width inputs
|
|
101
|
+
- If an element is naturally 200px wide, let it be 200px — don't reflow to 600px
|
|
102
|
+
- Full-width is a deliberate choice, not a fallback
|
|
103
|
+
|
|
104
|
+
## Design at the Real Size
|
|
105
|
+
|
|
106
|
+
- For small components (modals, cards, widgets), shrink the canvas
|
|
107
|
+
- Working at ~400px forces honest decisions about scale
|
|
108
|
+
- Zooming out on a 1440px canvas makes elements feel more generous than they actually are
|
|
109
|
+
- Mobile-first: design at 320–400px first, expand from there
|
|
110
|
+
|
|
111
|
+
## Columns Beat Stretched Rows
|
|
112
|
+
|
|
113
|
+
- When content gets too wide and elements feel diluted, introduce columns
|
|
114
|
+
- A two-column settings page reads better than a settings page where every form field stretches edge-to-edge
|
|
115
|
+
|
|
116
|
+
## Sidebars Use Fixed Widths
|
|
117
|
+
|
|
118
|
+
- Sidebars in pixels (e.g., 240px) — not percentages
|
|
119
|
+
- 20% sidebars become tiny on small screens and huge on large ones
|
|
120
|
+
- Use `max-width` on content columns, not percentage grid columns
|
|
121
|
+
- Percentages are for responsive *images* and grid cells, not UI chrome
|
|
122
|
+
|
|
123
|
+
## Big Things Shrink More Than Small Things
|
|
124
|
+
|
|
125
|
+
- A 45px headline on desktop should drop to roughly 20–24px on mobile, not just half
|
|
126
|
+
- Shrink larger elements proportionally more
|
|
127
|
+
- Button padding does *not* scale linearly with font:
|
|
128
|
+
- 16px font + 12px vertical padding looks balanced
|
|
129
|
+
- Bumping font to 24px doesn't mean padding becomes 18px — often padding stays close to original
|
|
130
|
+
|
|
131
|
+
## Group With Space, Not Boxes
|
|
132
|
+
|
|
133
|
+
- More space *around* a group than *within* it (Law of Proximity)
|
|
134
|
+
- A form section header should have more room above it than below it
|
|
135
|
+
- Labels should be closer to their own input than to the input above or below
|
|
136
|
+
|
|
137
|
+
## Spacing Sanity Checklist
|
|
138
|
+
|
|
139
|
+
- [ ] Does the spacing show what belongs together?
|
|
140
|
+
- [ ] Is there more space between groups than within groups?
|
|
141
|
+
- [ ] Is the label closer to its own input than to the next input?
|
|
142
|
+
- [ ] Does the layout communicate grouping without borders or backgrounds?
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Hand-Pick Your Type Scale (Don't Use Modular Ratios)
|
|
147
|
+
|
|
148
|
+
- Modular scales (e.g., 1.25× ratio) produce fractional pixels and useless intermediate sizes
|
|
149
|
+
- Hand-pick ~8–10 sizes that actually serve real use cases
|
|
150
|
+
- Sample scale: 12, 14, 16, 18, 20, 24, 30, 36, 48, 60, 72px
|
|
151
|
+
- Each size should feel clearly different from its neighbors
|
|
152
|
+
|
|
153
|
+
## Use px or rem — Avoid em for Type
|
|
154
|
+
|
|
155
|
+
- `em` is relative to the parent's font size; nesting compounds unpredictably
|
|
156
|
+
- `px` or `rem` (relative to root) keep type sizes predictable
|
|
157
|
+
- `em` is fine for things like padding/margin that should scale with font, but not for the type scale itself
|
|
158
|
+
|
|
159
|
+
## Shopping for a Body Font
|
|
160
|
+
|
|
161
|
+
- On Google Fonts, filter by "10+ styles" — drops the bottom ~85% in one move
|
|
162
|
+
- Multiple weights/styles signal a font designed seriously
|
|
163
|
+
- For UI, prefer neutral sans-serif (Helvetica-style) over geometric or humanist extremes
|
|
164
|
+
- A system stack (`-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto`) is a safe fallback
|
|
165
|
+
- Avoid condensed fonts and fonts with very short x-heights for body text
|
|
166
|
+
|
|
167
|
+
## Comfortable Line Length
|
|
168
|
+
|
|
169
|
+
- Target: ~45–75 characters per line
|
|
170
|
+
- Equivalent: ~20–35em of width
|
|
171
|
+
- Constrain paragraph width even inside a wider container
|
|
172
|
+
- Too wide → eyes lose track of the next line; too narrow → too many breaks
|
|
173
|
+
|
|
174
|
+
## Align Mixed Sizes by Baseline
|
|
175
|
+
|
|
176
|
+
- When two elements with different font sizes sit side by side, align by baseline (bottom of text)
|
|
177
|
+
- Vertical centering of mixed sizes makes the smaller text look too high
|
|
178
|
+
|
|
179
|
+
## Line-Height Inversely Tracks Size
|
|
180
|
+
|
|
181
|
+
- Body text in narrow columns: ~1.5
|
|
182
|
+
- Wider columns: closer to 2.0
|
|
183
|
+
- Large headlines: ~1.0 or slightly tighter
|
|
184
|
+
- Smaller text needs more space between lines; larger text needs less
|
|
185
|
+
|
|
186
|
+
## Link Styling Depends on Density
|
|
187
|
+
|
|
188
|
+
- In link-heavy contexts (sidebar navs, lists), drop the colored underline — use heavier weight or darker shade instead
|
|
189
|
+
- Color on every link reads as noise when most things are links
|
|
190
|
+
- Footer-style "ancillary" links: color/underline only on hover
|
|
191
|
+
- Save the high-contrast blue for inline body links that need to stand out
|
|
192
|
+
|
|
193
|
+
## Text Alignment by Use
|
|
194
|
+
|
|
195
|
+
- **Left:** the default for most text in LTR languages
|
|
196
|
+
- **Center:** only short blocks (≤2–3 lines) — never a paragraph
|
|
197
|
+
- **Right:** numbers in tables (so digits and decimals line up)
|
|
198
|
+
- **Justified:** only with hyphenation enabled — without it, big awkward gaps
|
|
199
|
+
|
|
200
|
+
## Letter-Spacing
|
|
201
|
+
|
|
202
|
+
- **Body fonts at headline sizes:** tighten letter-spacing slightly (negative tracking) — body fonts are tuned for small sizes, look loose at large sizes
|
|
203
|
+
- **All-caps text:** always loosen letter-spacing — caps are harder to read, extra space helps
|
|
204
|
+
- Never tighten body text or all-caps — kills legibility
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Visual Treatment: Color, Depth, Images
|
|
2
|
+
|
|
3
|
+
Inspired by principles from *Refactoring UI* by Adam Wathan & Steve Schoger. Paraphrased into the maintainer's own words; the original prose, illustrations, and examples are in the book — refactoringui.com.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## HSL Is the Right Model for UI Color
|
|
8
|
+
|
|
9
|
+
HSL (Hue, Saturation, Lightness) gives intuitive control:
|
|
10
|
+
|
|
11
|
+
- **Hue:** 0°=red, 60°=yellow, 120°=green, 180°=cyan, 240°=blue, 300°=magenta
|
|
12
|
+
- **Saturation:** 0%=grey (no color), 100%=fully vivid
|
|
13
|
+
- **Lightness:** 0%=black, 50%=pure color, 100%=white
|
|
14
|
+
|
|
15
|
+
**HSL ≠ HSB (HSV).** HSB's "brightness" at 100% still gives a vivid color; HSL's lightness at 100% is always white. Don't conflate them.
|
|
16
|
+
|
|
17
|
+
## Building a Complete Palette
|
|
18
|
+
|
|
19
|
+
Plan for more colors than you'd guess:
|
|
20
|
+
|
|
21
|
+
- **Greys:** 8–10 shades (text, backgrounds, borders, UI chrome)
|
|
22
|
+
- **Primary brand color:** 5–10 shades
|
|
23
|
+
- **Accent set:** typically 3–5 named colors × 5–10 shades each
|
|
24
|
+
- Red (danger, error, destructive)
|
|
25
|
+
- Yellow (warning, caution)
|
|
26
|
+
- Green (success, positive)
|
|
27
|
+
- Others as needed (blue for info, purple, etc.)
|
|
28
|
+
|
|
29
|
+
That can mean ~10 colors × ~10 shades = 100 values. Define them all once, up front.
|
|
30
|
+
|
|
31
|
+
## Skip Preprocessor `lighten()` / `darken()`
|
|
32
|
+
|
|
33
|
+
- `lighten(blue, 20%)` mixes white into the color — produces washed-out results
|
|
34
|
+
- `darken(blue, 20%)` mixes black — produces muddy, lifeless results
|
|
35
|
+
- Hand-pick shades using HSL — better results every time
|
|
36
|
+
|
|
37
|
+
## Building a 9-Step Shade Scale (100–900)
|
|
38
|
+
|
|
39
|
+
Step by step:
|
|
40
|
+
|
|
41
|
+
1. **Pick the base** (500): should work as a button background
|
|
42
|
+
2. **Pick the darkest** (900): should work as text on light bg
|
|
43
|
+
3. **Pick the lightest** (100): should work as a tinted background
|
|
44
|
+
4. **Fill in 700:** roughly halfway between 500 and 900
|
|
45
|
+
5. **Fill in 300:** roughly halfway between 100 and 500
|
|
46
|
+
6. **Fill the gaps** (200, 400, 600, 800) by eye — adjusting until the steps feel even
|
|
47
|
+
|
|
48
|
+
## Bump Saturation as Lightness Moves Away from 50%
|
|
49
|
+
|
|
50
|
+
- Moving lightness toward 0% or 100% in pure HSL drains apparent vividness
|
|
51
|
+
- Counter it: increase saturation as you push lightness up or down
|
|
52
|
+
- Very light shades (lightness 90–95%): bump saturation noticeably
|
|
53
|
+
- Very dark shades (lightness 15–25%): bump saturation to keep richness
|
|
54
|
+
- Without this, light shades look washed out and dark shades look muddy
|
|
55
|
+
|
|
56
|
+
## Rotate Hue Slightly When Lightening or Darkening
|
|
57
|
+
|
|
58
|
+
- Pure-hue lightening/darkening looks artificial; shifting hue a bit produces more natural shades
|
|
59
|
+
- Toward lighter: rotate toward the nearest "bright anchor" (60°, 180°, 300°)
|
|
60
|
+
- Toward darker: rotate toward the nearest "dark anchor" (0°, 120°, 240°)
|
|
61
|
+
- Cap the rotation at ~20–30° — beyond that the color reads as a different one entirely
|
|
62
|
+
- Mimics how real pigments behave when tinted or shaded
|
|
63
|
+
|
|
64
|
+
## Greys Don't Need to Be Pure Grey
|
|
65
|
+
|
|
66
|
+
- Pure 0%-saturation grey often feels clinical and bland
|
|
67
|
+
- **Cool greys:** small amount of blue saturation → modern, professional
|
|
68
|
+
- **Warm greys:** small amount of yellow/orange saturation → inviting, human
|
|
69
|
+
- Match the temperature of your greys to the rest of your palette
|
|
70
|
+
|
|
71
|
+
## Accessible Contrast (WCAG)
|
|
72
|
+
|
|
73
|
+
- **Small text (<~18px normal weight, <~14px bold):** at least 4.5:1
|
|
74
|
+
- **Large text (≥~18px normal, ≥~14px bold):** at least 3:1
|
|
75
|
+
- Dark text on white passes more easily than white text on a colored bg
|
|
76
|
+
|
|
77
|
+
## When White-on-Colored Fails Contrast
|
|
78
|
+
|
|
79
|
+
- Try dark text on a *light tinted* version of the same brand color
|
|
80
|
+
- Example: dark navy text on pale blue — same brand, much higher contrast
|
|
81
|
+
- Often more sophisticated visually than white-on-saturated
|
|
82
|
+
|
|
83
|
+
## Colored Text on Colored Backgrounds
|
|
84
|
+
|
|
85
|
+
- White text on a vivid bright button often fails contrast
|
|
86
|
+
- Instead of darkening the background, shift the *text* hue toward a bright anchor (rotate toward yellow/60°)
|
|
87
|
+
- Yellow text on a dark orange button can read more clearly than white because yellow is inherently brighter
|
|
88
|
+
|
|
89
|
+
## Color Cannot Be the Only Signal
|
|
90
|
+
|
|
91
|
+
- ~8% of males cannot distinguish red/green by color alone
|
|
92
|
+
- Always pair color with a second signal:
|
|
93
|
+
- Icon (checkmark, warning triangle, X)
|
|
94
|
+
- Shape difference
|
|
95
|
+
- Text label
|
|
96
|
+
- Position or strong contrast difference
|
|
97
|
+
- Applies to: status badges, error states, success messages, alert levels, charts
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Light Source Convention
|
|
102
|
+
|
|
103
|
+
- Simulated depth in a UI assumes the light source sits **above** the screen
|
|
104
|
+
- Users naturally look at screens from a slightly downward angle
|
|
105
|
+
- Every shadow, edge, and inset should respect that single "sun"
|
|
106
|
+
|
|
107
|
+
## Raised Elements
|
|
108
|
+
|
|
109
|
+
To make an element appear lifted off the page:
|
|
110
|
+
|
|
111
|
+
- **Lighter top edge:** a top border or top inset shadow in a lighter shade
|
|
112
|
+
- **Small dark shadow below:** the element's cast shadow on the surface
|
|
113
|
+
- Hand-pick the lighter color — semi-transparent white (`rgba(255,255,255,0.x)`) desaturates the underlying color and looks fake
|
|
114
|
+
|
|
115
|
+
## Inset Elements
|
|
116
|
+
|
|
117
|
+
To make an element appear pressed into the page:
|
|
118
|
+
|
|
119
|
+
- **Lighter bottom edge:** bottom border or bottom inset shadow in a lighter shade
|
|
120
|
+
- **Small dark inset shadow at top:** simulates shadow falling into the well
|
|
121
|
+
- Same rule: hand-pick the light color rather than using transparent white
|
|
122
|
+
|
|
123
|
+
## Five-Level Shadow System
|
|
124
|
+
|
|
125
|
+
Define ~5 shadow levels (similar to Material Design's elevation):
|
|
126
|
+
|
|
127
|
+
- **Level 1 — barely raised:** very small blur, tiny offset
|
|
128
|
+
- **Level 2 — slightly higher:** modest blur and offset
|
|
129
|
+
- **Level 3 — default card:** medium blur, medium offset
|
|
130
|
+
- **Level 4 — modal / dropdown:** large blur, larger offset
|
|
131
|
+
- **Level 5 — closest to viewer:** very large blur, biggest offset (tooltips, popovers)
|
|
132
|
+
|
|
133
|
+
Rule of thumb: small blur reads as slightly raised, large blur reads as floating close to the viewer.
|
|
134
|
+
|
|
135
|
+
## Shadows React to Interaction
|
|
136
|
+
|
|
137
|
+
- **On drag (element "picked up"):** shadow grows (blur and offset increase) — feels like the element moved closer to the user
|
|
138
|
+
- **On click/press (element pressed in):** shadow shrinks or disappears — feels pushed into the surface
|
|
139
|
+
- Tactile feedback without animation
|
|
140
|
+
|
|
141
|
+
## Compound Shadows: Direct + Ambient Light
|
|
142
|
+
|
|
143
|
+
Real objects cast two shadow layers:
|
|
144
|
+
|
|
145
|
+
1. **Direct light shadow** (umbra): large, soft, big offset, big blur — from the primary light source
|
|
146
|
+
2. **Ambient light shadow** (penumbra): tight, dark, small offset, small blur — from scattered ambient light
|
|
147
|
+
|
|
148
|
+
For UI:
|
|
149
|
+
|
|
150
|
+
- Shadow 1: large blur, large offset, low opacity (direct)
|
|
151
|
+
- Shadow 2: small blur, small offset, higher opacity (ambient)
|
|
152
|
+
|
|
153
|
+
At higher elevations, the ambient shadow becomes more subtle relative to the direct shadow.
|
|
154
|
+
|
|
155
|
+
## Depth Without Shadows (Flat Aesthetic)
|
|
156
|
+
|
|
157
|
+
When shadows aren't appropriate:
|
|
158
|
+
|
|
159
|
+
- **Lighter = closer, darker = further** — opposite of real-world intuition, but works visually
|
|
160
|
+
- Solid no-blur "shadows": `box-shadow: 4px 4px 0 #000` for a retro/flat look
|
|
161
|
+
- These define edges without implying a light source
|
|
162
|
+
|
|
163
|
+
## Layering Through Element Overlap
|
|
164
|
+
|
|
165
|
+
- Overlap one element across the boundary of another to create a clear sense of layers
|
|
166
|
+
- Example: a card straddling a dark hero and a white content area below
|
|
167
|
+
- Example: an avatar that overlaps the edge of a card — depth without shadow
|
|
168
|
+
|
|
169
|
+
## Halo Borders to Separate Adjacent Images
|
|
170
|
+
|
|
171
|
+
- When images touch each other or a busy background, edges clash
|
|
172
|
+
- Add a border in the **same color as the background** behind the image
|
|
173
|
+
- That "invisible" border (sometimes called a halo) creates separation without a visible line color
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Use Real Content From the Start
|
|
178
|
+
|
|
179
|
+
- Never design with placeholder images — grey boxes lie about how the layout actually feels
|
|
180
|
+
- Real photos differ in aspect, brightness, and busyness — design must work with reality
|
|
181
|
+
- Hire a photographer or use quality stock services (e.g., Unsplash)
|
|
182
|
+
|
|
183
|
+
## Putting Text on Top of an Image
|
|
184
|
+
|
|
185
|
+
Four reliable techniques:
|
|
186
|
+
|
|
187
|
+
**1. Semi-transparent overlay**
|
|
188
|
+
- Dark overlay for light-colored text
|
|
189
|
+
- Light overlay for dark-colored text
|
|
190
|
+
- Tune the overlay opacity until contrast is comfortable
|
|
191
|
+
|
|
192
|
+
**2. Reduce image contrast / shift brightness**
|
|
193
|
+
- Lower contrast on the image so text has a more uniform background
|
|
194
|
+
- Brighten or darken globally to give a consistent canvas
|
|
195
|
+
|
|
196
|
+
**3. Recolor the image**
|
|
197
|
+
- Desaturate, then apply a solid color via "multiply" blend mode
|
|
198
|
+
- Result: a single-tone image that text reads cleanly on top of
|
|
199
|
+
|
|
200
|
+
**4. Soft halo behind the text**
|
|
201
|
+
- Big blur, no offset text-shadow behind the text
|
|
202
|
+
- Best for short text (headlines, labels), not paragraphs
|
|
203
|
+
|
|
204
|
+
## Don't Just Scale Tiny Icons Up
|
|
205
|
+
|
|
206
|
+
- Icons drawn at 16–24px look chunky and blurry when stretched 3–4×
|
|
207
|
+
- At larger sizes, put the icon inside a **shaped container** (circle, rounded square)
|
|
208
|
+
- Scale the container up; keep the icon at native size (or only slightly larger)
|
|
209
|
+
- Adds polish, avoids the "blown-up icon" problem
|
|
210
|
+
|
|
211
|
+
## Screenshots in Marketing/Documentation
|
|
212
|
+
|
|
213
|
+
The problem: scaling shrinks text below readability.
|
|
214
|
+
|
|
215
|
+
- At 70% scale, 16px font ≈ 11px — already getting unreadable
|
|
216
|
+
- At 50% scale, 16px font = 8px — illegible
|
|
217
|
+
|
|
218
|
+
What works:
|
|
219
|
+
|
|
220
|
+
1. Use a tablet/narrow-layout screenshot — scales better than a full desktop one
|
|
221
|
+
2. Take a partial screenshot — crop to the relevant area
|
|
222
|
+
3. Draw a simplified version — strip most UI, keep what matters
|
|
223
|
+
4. Don't depend on the viewer being able to read the text in a thumbnail
|
|
224
|
+
|
|
225
|
+
## Favicons Need to Be Redrawn, Not Shrunk
|
|
226
|
+
|
|
227
|
+
- A 128px logo shrunk to 16px loses too much detail
|
|
228
|
+
- Redraw at the target size (16×16, 32×32) from scratch
|
|
229
|
+
- 1–2 elements only; usually just the icon mark, not the wordmark
|
|
230
|
+
- Test at 1× actual size while designing — what reads at 128px is often noise at 16px
|
|
231
|
+
|
|
232
|
+
## User-Uploaded Images: Two Problems
|
|
233
|
+
|
|
234
|
+
**Aspect ratio:** uploads won't match your layout's expected proportions.
|
|
235
|
+
- Fixed-size container
|
|
236
|
+
- `background-size: cover` (or CSS `object-fit: cover`)
|
|
237
|
+
- Let the engine center and crop
|
|
238
|
+
|
|
239
|
+
**Background bleed:** white-bg images dissolve into white page bgs.
|
|
240
|
+
- Don't use a hard border — too heavy
|
|
241
|
+
- Instead, an inset box-shadow: `box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1)`
|
|
242
|
+
- Soft inner ring that defines the edge without a visible border color
|