picasso-skill 1.0.0 → 1.2.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/README.md +70 -45
- package/agents/picasso.md +326 -0
- package/bin/install.mjs +54 -24
- package/package.json +5 -3
- package/skills/picasso/references/accessibility.md +172 -0
- package/skills/picasso/references/design-system.md +14 -14
- package/skills/picasso/references/generative-art.md +626 -32
- package/skills/picasso/references/motion-and-animation.md +2 -2
- package/skills/picasso/references/react-patterns.md +193 -91
- package/skills/picasso/references/responsive-design.md +349 -15
- package/skills/picasso/references/sensory-design.md +294 -50
- package/SKILL.md +0 -202
- package/references/anti-patterns.md +0 -95
- package/references/color-and-contrast.md +0 -174
- package/references/component-patterns.md +0 -113
- package/references/design-system.md +0 -176
- package/references/generative-art.md +0 -54
- package/references/interaction-design.md +0 -162
- package/references/motion-and-animation.md +0 -260
- package/references/react-patterns.md +0 -216
- package/references/responsive-design.md +0 -118
- package/references/sensory-design.md +0 -125
- package/references/spatial-design.md +0 -176
- package/references/typography.md +0 -168
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# Responsive Design Reference
|
|
2
|
-
|
|
3
|
-
## 1. Breakpoints
|
|
4
|
-
|
|
5
|
-
Use content-driven breakpoints, not device-driven. These are sensible defaults:
|
|
6
|
-
|
|
7
|
-
```css
|
|
8
|
-
/* Mobile first: no media query = mobile */
|
|
9
|
-
/* Small tablets / large phones */
|
|
10
|
-
@media (min-width: 640px) { }
|
|
11
|
-
/* Tablets / small laptops */
|
|
12
|
-
@media (min-width: 768px) { }
|
|
13
|
-
/* Laptops / desktops */
|
|
14
|
-
@media (min-width: 1024px) { }
|
|
15
|
-
/* Large desktops */
|
|
16
|
-
@media (min-width: 1280px) { }
|
|
17
|
-
/* Ultrawide */
|
|
18
|
-
@media (min-width: 1536px) { }
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## 2. Mobile-First Approach
|
|
22
|
-
|
|
23
|
-
Start with the mobile layout (single column, stacked). Add complexity at wider breakpoints. This ensures the core experience works everywhere before enhancements.
|
|
24
|
-
|
|
25
|
-
```css
|
|
26
|
-
/* Base: single column */
|
|
27
|
-
.grid { display: grid; gap: 1rem; }
|
|
28
|
-
|
|
29
|
-
/* Tablet: two columns */
|
|
30
|
-
@media (min-width: 768px) {
|
|
31
|
-
.grid { grid-template-columns: repeat(2, 1fr); }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/* Desktop: three columns */
|
|
35
|
-
@media (min-width: 1024px) {
|
|
36
|
-
.grid { grid-template-columns: repeat(3, 1fr); }
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## 3. Fluid Design
|
|
41
|
-
|
|
42
|
-
Use `clamp()` for font sizes, padding, and gaps that scale smoothly:
|
|
43
|
-
|
|
44
|
-
```css
|
|
45
|
-
.container {
|
|
46
|
-
padding: clamp(1rem, 4vw, 3rem);
|
|
47
|
-
max-width: 1200px;
|
|
48
|
-
margin: 0 auto;
|
|
49
|
-
}
|
|
50
|
-
h1 {
|
|
51
|
-
font-size: clamp(1.75rem, 4vw + 0.5rem, 3.5rem);
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## 4. Container Queries
|
|
56
|
-
|
|
57
|
-
For component-level responsiveness (when the component's width, not the viewport, should determine layout):
|
|
58
|
-
|
|
59
|
-
```css
|
|
60
|
-
.card-container {
|
|
61
|
-
container-type: inline-size;
|
|
62
|
-
}
|
|
63
|
-
@container (min-width: 400px) {
|
|
64
|
-
.card { display: grid; grid-template-columns: 1fr 2fr; }
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## 5. Touch Targets
|
|
69
|
-
|
|
70
|
-
Minimum touch target: 44x44px (WCAG) or 48x48px (Material). Apply to all interactive elements on mobile. If the visual element is smaller, use padding or `::before` pseudo-element to extend the hit area.
|
|
71
|
-
|
|
72
|
-
```css
|
|
73
|
-
.icon-button {
|
|
74
|
-
position: relative;
|
|
75
|
-
width: 24px;
|
|
76
|
-
height: 24px;
|
|
77
|
-
}
|
|
78
|
-
.icon-button::before {
|
|
79
|
-
content: '';
|
|
80
|
-
position: absolute;
|
|
81
|
-
inset: -12px; /* extends tap area to 48x48 */
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 6. Responsive Typography
|
|
86
|
-
|
|
87
|
-
Do not just shrink everything on mobile. Adjust the type scale:
|
|
88
|
-
- Mobile: use a smaller ratio (1.2) with a 15-16px base
|
|
89
|
-
- Desktop: use a larger ratio (1.25-1.333) with a 16-18px base
|
|
90
|
-
- Headings should scale more aggressively than body text
|
|
91
|
-
|
|
92
|
-
## 7. Navigation Patterns
|
|
93
|
-
|
|
94
|
-
- **Mobile (< 768px)**: Hamburger menu, bottom tab bar, or slide-out drawer
|
|
95
|
-
- **Tablet (768-1024px)**: Collapsed sidebar or icon-only navigation
|
|
96
|
-
- **Desktop (> 1024px)**: Full sidebar, top navigation bar, or mega-menu
|
|
97
|
-
|
|
98
|
-
## 8. Images
|
|
99
|
-
|
|
100
|
-
Use `srcset` and `sizes` for responsive images. Use `loading="lazy"` for below-the-fold images. Set `aspect-ratio` to prevent layout shift:
|
|
101
|
-
|
|
102
|
-
```css
|
|
103
|
-
img {
|
|
104
|
-
width: 100%;
|
|
105
|
-
height: auto;
|
|
106
|
-
aspect-ratio: 16 / 9;
|
|
107
|
-
object-fit: cover;
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## 9. Common Mistakes
|
|
112
|
-
|
|
113
|
-
- Hiding too much content on mobile (users expect the same information, just reorganized)
|
|
114
|
-
- Using `vw` units for text without a `clamp()` minimum (becomes unreadable on small screens)
|
|
115
|
-
- Horizontal scrolling on mobile (almost never acceptable)
|
|
116
|
-
- Fixed-position elements that cover too much of the mobile viewport
|
|
117
|
-
- Not testing at actual device widths (375px for iPhone SE, 390px for modern iPhones, 360px for Android)
|
|
118
|
-
- Tables that overflow on mobile (use horizontal scroll wrapper or reformat as stacked cards)
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# Sensory Design Reference
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
1. UI Sound Design
|
|
5
|
-
2. Haptic Feedback
|
|
6
|
-
3. Multi-Sensory Integration
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 1. UI Sound Design
|
|
11
|
-
|
|
12
|
-
### Why Sound
|
|
13
|
-
Sound provides confirmation that an action occurred, draws attention to important state changes, and adds personality to the interface. It is underused on the web but highly effective when applied with restraint.
|
|
14
|
-
|
|
15
|
-
### The Soundcn Pattern
|
|
16
|
-
Use inline base64 audio data URIs with the Web Audio API. This avoids external file loading, CORS issues, and runtime fetching. Each sound is a self-contained TypeScript module.
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
// sounds/click-soft.ts
|
|
20
|
-
export const clickSoftSound = "data:audio/wav;base64,UklGR..."; // base64 WAV
|
|
21
|
-
|
|
22
|
-
// hooks/use-sound.ts
|
|
23
|
-
import { useCallback, useRef } from 'react';
|
|
24
|
-
|
|
25
|
-
export function useSound(src: string) {
|
|
26
|
-
const audioContextRef = useRef<AudioContext | null>(null);
|
|
27
|
-
|
|
28
|
-
const play = useCallback(() => {
|
|
29
|
-
if (!audioContextRef.current) {
|
|
30
|
-
audioContextRef.current = new AudioContext();
|
|
31
|
-
}
|
|
32
|
-
const ctx = audioContextRef.current;
|
|
33
|
-
fetch(src)
|
|
34
|
-
.then(r => r.arrayBuffer())
|
|
35
|
-
.then(buf => ctx.decodeAudioData(buf))
|
|
36
|
-
.then(decoded => {
|
|
37
|
-
const source = ctx.createBufferSource();
|
|
38
|
-
source.buffer = decoded;
|
|
39
|
-
source.connect(ctx.destination);
|
|
40
|
-
source.start(0);
|
|
41
|
-
});
|
|
42
|
-
}, [src]);
|
|
43
|
-
|
|
44
|
-
return [play] as const;
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Usage
|
|
49
|
-
```tsx
|
|
50
|
-
import { useSound } from "@/hooks/use-sound";
|
|
51
|
-
import { clickSoftSound } from "@/sounds/click-soft";
|
|
52
|
-
|
|
53
|
-
function Button() {
|
|
54
|
-
const [play] = useSound(clickSoftSound);
|
|
55
|
-
return <button onClick={() => { play(); handleAction(); }}>Save</button>;
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### When to Use Sound
|
|
60
|
-
- **Button clicks**: soft, short click sound (50-100ms)
|
|
61
|
-
- **Success actions**: pleasant confirmation tone
|
|
62
|
-
- **Notifications**: attention-getting but not alarming chime
|
|
63
|
-
- **Errors**: subtle alert, not a harsh buzz
|
|
64
|
-
- **Toggle switches**: satisfying mechanical click
|
|
65
|
-
- **Transitions**: whoosh or swipe sound for page changes
|
|
66
|
-
|
|
67
|
-
### Rules
|
|
68
|
-
- Always provide a sound toggle in the UI (respect user preference)
|
|
69
|
-
- Keep sounds under 200ms for UI interactions
|
|
70
|
-
- Use the Web Audio API, not `<audio>` elements (lower latency)
|
|
71
|
-
- Sound volume should be subtle by default (0.3-0.5 of max)
|
|
72
|
-
- Never auto-play sounds on page load
|
|
73
|
-
- Source sounds from CC0 collections (Kenney, Freesound)
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## 2. Haptic Feedback
|
|
78
|
-
|
|
79
|
-
### The Vibration API
|
|
80
|
-
```javascript
|
|
81
|
-
// Check support
|
|
82
|
-
if ('vibrate' in navigator) {
|
|
83
|
-
// Simple tap (10ms pulse)
|
|
84
|
-
navigator.vibrate(10);
|
|
85
|
-
|
|
86
|
-
// Success pattern (two short pulses)
|
|
87
|
-
navigator.vibrate([10, 50, 10]);
|
|
88
|
-
|
|
89
|
-
// Error pattern (one longer pulse)
|
|
90
|
-
navigator.vibrate(30);
|
|
91
|
-
|
|
92
|
-
// Warning (three quick pulses)
|
|
93
|
-
navigator.vibrate([10, 30, 10, 30, 10]);
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### When to Use Haptics
|
|
98
|
-
- **Button press confirmation**: 10ms pulse on touch
|
|
99
|
-
- **Toggle switch**: 10ms pulse on state change
|
|
100
|
-
- **Destructive action confirmation**: 30ms pulse before confirmation dialog
|
|
101
|
-
- **Pull-to-refresh threshold**: 10ms pulse when the threshold is reached
|
|
102
|
-
- **Drag and drop**: 10ms pulse on pickup and drop
|
|
103
|
-
|
|
104
|
-
### Rules
|
|
105
|
-
- Gate behind feature detection (`'vibrate' in navigator`)
|
|
106
|
-
- Respect `prefers-reduced-motion` by disabling haptics when motion is reduced
|
|
107
|
-
- Keep durations very short (10-30ms for taps, never longer than 100ms)
|
|
108
|
-
- Do not use haptics for every interaction, only pivotal moments
|
|
109
|
-
- Mobile only: haptics have no effect on desktop
|
|
110
|
-
|
|
111
|
-
### iOS Considerations
|
|
112
|
-
The Vibration API has limited support on iOS Safari. For broader iOS support, use the experimental Haptic Feedback API or accept that haptics are Android-primary.
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## 3. Multi-Sensory Integration
|
|
117
|
-
|
|
118
|
-
The strongest UI moments combine visual, auditory, and haptic feedback simultaneously:
|
|
119
|
-
|
|
120
|
-
1. User taps "Complete" button
|
|
121
|
-
2. **Visual**: checkmark animation scales in with a satisfying bounce
|
|
122
|
-
3. **Sound**: soft success chime (100ms)
|
|
123
|
-
4. **Haptic**: double-pulse pattern (10ms, 50ms gap, 10ms)
|
|
124
|
-
|
|
125
|
-
This triple feedback creates a moment of certainty that a single visual change cannot match. Use it sparingly, for milestone moments (order placed, task completed, level achieved).
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# Spatial Design Reference
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
1. Spacing Scale
|
|
5
|
-
2. Grid Systems
|
|
6
|
-
3. Visual Hierarchy
|
|
7
|
-
4. Whitespace
|
|
8
|
-
5. Layout Patterns
|
|
9
|
-
6. Common Mistakes
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 1. Spacing Scale
|
|
14
|
-
|
|
15
|
-
Use a consistent spacing scale based on a 4px unit. Never use arbitrary values like 13px or 7px.
|
|
16
|
-
|
|
17
|
-
```css
|
|
18
|
-
:root {
|
|
19
|
-
--space-1: 0.25rem; /* 4px - tight inline gaps */
|
|
20
|
-
--space-2: 0.5rem; /* 8px - icon-to-text, compact lists */
|
|
21
|
-
--space-3: 0.75rem; /* 12px - form field padding */
|
|
22
|
-
--space-4: 1rem; /* 16px - standard element spacing */
|
|
23
|
-
--space-5: 1.25rem; /* 20px - card padding */
|
|
24
|
-
--space-6: 1.5rem; /* 24px - section padding */
|
|
25
|
-
--space-8: 2rem; /* 32px - group separation */
|
|
26
|
-
--space-10: 2.5rem; /* 40px - major section gaps */
|
|
27
|
-
--space-12: 3rem; /* 48px - large section spacing */
|
|
28
|
-
--space-16: 4rem; /* 64px - page-level spacing */
|
|
29
|
-
--space-20: 5rem; /* 80px - hero-level breathing room */
|
|
30
|
-
--space-24: 6rem; /* 96px - dramatic separation */
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### When to Use Which Size
|
|
35
|
-
- **1-2 (4-8px)**: Internal component spacing (icon + label, badge padding)
|
|
36
|
-
- **3-4 (12-16px)**: Component padding, list item spacing
|
|
37
|
-
- **5-6 (20-24px)**: Card padding, form group margins
|
|
38
|
-
- **8-10 (32-40px)**: Section separation within a page
|
|
39
|
-
- **12-16 (48-64px)**: Major content blocks, above/below fold
|
|
40
|
-
- **20-24 (80-96px)**: Hero areas, page-level breathing room
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## 2. Grid Systems
|
|
45
|
-
|
|
46
|
-
### CSS Grid Defaults
|
|
47
|
-
```css
|
|
48
|
-
.grid {
|
|
49
|
-
display: grid;
|
|
50
|
-
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
51
|
-
gap: var(--space-6);
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 12-Column Grid
|
|
56
|
-
For dashboard and editorial layouts:
|
|
57
|
-
```css
|
|
58
|
-
.page-grid {
|
|
59
|
-
display: grid;
|
|
60
|
-
grid-template-columns: repeat(12, 1fr);
|
|
61
|
-
gap: var(--space-6);
|
|
62
|
-
max-width: 1200px;
|
|
63
|
-
margin: 0 auto;
|
|
64
|
-
padding: 0 var(--space-6);
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Asymmetric Grids
|
|
69
|
-
For editorial and portfolio layouts, break the 12-column grid:
|
|
70
|
-
```css
|
|
71
|
-
.editorial-grid {
|
|
72
|
-
display: grid;
|
|
73
|
-
grid-template-columns: 2fr 1fr; /* 2:1 ratio */
|
|
74
|
-
gap: var(--space-8);
|
|
75
|
-
}
|
|
76
|
-
.portfolio-grid {
|
|
77
|
-
display: grid;
|
|
78
|
-
grid-template-columns: 3fr 2fr; /* golden-ish ratio */
|
|
79
|
-
gap: var(--space-6);
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## 3. Visual Hierarchy
|
|
86
|
-
|
|
87
|
-
Hierarchy is established through size, weight, color, and space. Not all four at once. Pick two.
|
|
88
|
-
|
|
89
|
-
### Hierarchy Techniques (in order of strength)
|
|
90
|
-
1. **Size difference**: The fastest way to establish priority
|
|
91
|
-
2. **Weight difference**: Bold vs. regular within the same size
|
|
92
|
-
3. **Color contrast**: Primary vs. secondary text color
|
|
93
|
-
4. **Spatial separation**: More space around important elements
|
|
94
|
-
5. **Position**: Top-left gets seen first (in LTR languages)
|
|
95
|
-
|
|
96
|
-
### Rules
|
|
97
|
-
- If everything is bold, nothing is bold. Limit bold to headings and key data points.
|
|
98
|
-
- If everything is the same size, the eye has nowhere to land. Vary size by at least 1.5x between hierarchy levels.
|
|
99
|
-
- Use secondary/tertiary text colors for supporting information (timestamps, metadata, helper text).
|
|
100
|
-
- Reduce visual weight of labels and increase weight of values in data-heavy UIs.
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## 4. Whitespace
|
|
105
|
-
|
|
106
|
-
Whitespace is not wasted space. It is a design element.
|
|
107
|
-
|
|
108
|
-
### Internal vs. External Spacing
|
|
109
|
-
- **Internal**: Padding inside a component (card padding, button padding). Relates to the component's own content.
|
|
110
|
-
- **External**: Margin between components. Relates to the component's relationship with siblings.
|
|
111
|
-
|
|
112
|
-
### Gestalt Grouping
|
|
113
|
-
Elements that are closer together are perceived as related. Use tighter spacing within groups and wider spacing between groups. The ratio between intra-group and inter-group spacing should be at least 2:1 (e.g., 8px within, 24px between).
|
|
114
|
-
|
|
115
|
-
### Generous vs. Dense
|
|
116
|
-
- **Generous**: Marketing pages, portfolios, editorial content. Use 80-120px between major sections.
|
|
117
|
-
- **Dense**: Dashboards, admin panels, data tables. Use 16-32px between sections but maintain consistent rhythm.
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## 5. Layout Patterns
|
|
122
|
-
|
|
123
|
-
### Centered Content
|
|
124
|
-
Max-width container with auto margins. Standard max-widths: 640px (narrow/reading), 960px (medium), 1200px (wide), 1440px (ultrawide).
|
|
125
|
-
|
|
126
|
-
### Sidebar + Main
|
|
127
|
-
```css
|
|
128
|
-
.layout {
|
|
129
|
-
display: grid;
|
|
130
|
-
grid-template-columns: 260px 1fr;
|
|
131
|
-
min-height: 100vh;
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Sticky Header + Scrollable Content
|
|
136
|
-
```css
|
|
137
|
-
.header { position: sticky; top: 0; z-index: 10; }
|
|
138
|
-
.main { overflow-y: auto; }
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Bento Grid
|
|
142
|
-
Irregular grid with varied cell sizes:
|
|
143
|
-
```css
|
|
144
|
-
.bento {
|
|
145
|
-
display: grid;
|
|
146
|
-
grid-template-columns: repeat(4, 1fr);
|
|
147
|
-
grid-auto-rows: 200px;
|
|
148
|
-
gap: var(--space-4);
|
|
149
|
-
}
|
|
150
|
-
.bento .featured {
|
|
151
|
-
grid-column: span 2;
|
|
152
|
-
grid-row: span 2;
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Overlap/Layer
|
|
157
|
-
Elements that break out of the grid create visual tension:
|
|
158
|
-
```css
|
|
159
|
-
.overlap-element {
|
|
160
|
-
position: relative;
|
|
161
|
-
z-index: 2;
|
|
162
|
-
margin-top: -3rem; /* pulls up into previous section */
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## 6. Common Mistakes
|
|
169
|
-
|
|
170
|
-
- Using inconsistent spacing values (17px here, 23px there)
|
|
171
|
-
- Centering everything on the page (creates a vertical highway with no anchor points)
|
|
172
|
-
- Not using max-width on content (text that spans 1400px is unreadable)
|
|
173
|
-
- Applying the same padding to all components regardless of their content
|
|
174
|
-
- Putting too many items in a row on mobile (three columns at 375px is almost never right)
|
|
175
|
-
- Using margin-top and margin-bottom on the same element (pick one direction, usually bottom, and stick with it throughout the project)
|
|
176
|
-
- Neglecting the space between the last element and the container edge
|
package/references/typography.md
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# Typography Reference
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
1. Font Selection
|
|
5
|
-
2. Type Scale
|
|
6
|
-
3. Font Pairing
|
|
7
|
-
4. Line Height and Spacing
|
|
8
|
-
5. OpenType Features
|
|
9
|
-
6. Pixel and Display Fonts
|
|
10
|
-
7. Web Font Loading
|
|
11
|
-
8. Common Mistakes
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 1. Font Selection
|
|
16
|
-
|
|
17
|
-
### Banned Defaults
|
|
18
|
-
Never use these as primary typefaces: Inter, Roboto, Arial, Helvetica, system-ui, sans-serif (as the only declaration), Space Grotesk (overused in AI contexts), or any font that ships as a browser default.
|
|
19
|
-
|
|
20
|
-
### Where to Find Good Fonts
|
|
21
|
-
- Google Fonts: vast but requires curation. Sort by trending, not popular.
|
|
22
|
-
- Bunny Fonts: privacy-friendly Google Fonts mirror.
|
|
23
|
-
- Fontshare: free, high-quality fonts from Indian Type Foundry.
|
|
24
|
-
- Atipo Foundry: distinctive display and text faces.
|
|
25
|
-
- CDN: `https://fonts.cdnfonts.com` for broader selection.
|
|
26
|
-
|
|
27
|
-
### Selection Criteria
|
|
28
|
-
A good typeface for a project should:
|
|
29
|
-
- Match the emotional register of the content (a legal dashboard should not use a playful rounded sans)
|
|
30
|
-
- Have sufficient weight range (at minimum: regular, medium, bold)
|
|
31
|
-
- Include tabular figures if displaying data
|
|
32
|
-
- Support the required character sets
|
|
33
|
-
- Feel distinct from the last 5 things you built
|
|
34
|
-
|
|
35
|
-
### The Geist System
|
|
36
|
-
Vercel's Geist family offers three complementary typefaces:
|
|
37
|
-
- **Geist Sans**: clean, geometric sans for UI text
|
|
38
|
-
- **Geist Mono**: monospaced for code and data
|
|
39
|
-
- **Geist Pixel**: bitmap-inspired display font with 5 variants (Square, Grid, Circle, Triangle, Line), useful for banners, experimental layouts, and product moments where typography becomes part of the interface language
|
|
40
|
-
|
|
41
|
-
Install via `npm i geist`. Each variant has its own CSS variable (e.g., `--font-geist-pixel-square`).
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 2. Type Scale
|
|
46
|
-
|
|
47
|
-
Use a modular scale. Pick a ratio and apply it consistently.
|
|
48
|
-
|
|
49
|
-
| Ratio | Name | Use Case |
|
|
50
|
-
|---|---|---|
|
|
51
|
-
| 1.125 | Major Second | Dense data UIs, admin panels |
|
|
52
|
-
| 1.200 | Minor Third | General purpose, balanced |
|
|
53
|
-
| 1.250 | Major Third | Most common, works broadly |
|
|
54
|
-
| 1.333 | Perfect Fourth | Editorial, generous spacing |
|
|
55
|
-
| 1.500 | Perfect Fifth | Display-heavy, marketing |
|
|
56
|
-
| 1.618 | Golden Ratio | High-impact landing pages |
|
|
57
|
-
|
|
58
|
-
### Calculating Sizes
|
|
59
|
-
Base size: 16px (1rem). Multiply up for headings, divide down for captions.
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
Caption: 0.75rem (12px)
|
|
63
|
-
Small: 0.875rem (14px)
|
|
64
|
-
Body: 1rem (16px)
|
|
65
|
-
Large: 1.125rem (18px)
|
|
66
|
-
H4: 1.25rem (20px)
|
|
67
|
-
H3: 1.563rem (25px)
|
|
68
|
-
H2: 1.953rem (31px)
|
|
69
|
-
H1: 2.441rem (39px)
|
|
70
|
-
Display: 3.052rem (49px)
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
For fluid type, use `clamp()`:
|
|
74
|
-
```css
|
|
75
|
-
h1 { font-size: clamp(2rem, 5vw + 1rem, 3.5rem); }
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 3. Font Pairing
|
|
81
|
-
|
|
82
|
-
### Principles
|
|
83
|
-
- Pair fonts with contrasting structures: a serif display with a sans body, or a geometric sans heading with a humanist sans body.
|
|
84
|
-
- Never pair fonts that are too similar (two geometric sans faces will fight).
|
|
85
|
-
- One display font is enough. Two is almost always too many.
|
|
86
|
-
- The body font does the heavy lifting. It must be supremely readable at 16px.
|
|
87
|
-
|
|
88
|
-
### Proven Pairs
|
|
89
|
-
- **Display serif + sans body**: Playfair Display / Source Sans 3
|
|
90
|
-
- **Geometric sans + humanist sans**: Outfit / Nunito Sans
|
|
91
|
-
- **Slab + grotesque**: Zilla Slab / Work Sans
|
|
92
|
-
- **Monospace accent + sans body**: JetBrains Mono / DM Sans
|
|
93
|
-
- **Variable display + clean body**: Instrument Serif / Instrument Sans
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## 4. Line Height and Spacing
|
|
98
|
-
|
|
99
|
-
| Context | Line Height | Letter Spacing |
|
|
100
|
-
|---|---|---|
|
|
101
|
-
| Body text | 1.5 to 1.6 | 0 to 0.01em |
|
|
102
|
-
| Headings (large) | 1.1 to 1.2 | -0.02 to -0.01em |
|
|
103
|
-
| Headings (small) | 1.2 to 1.3 | 0 |
|
|
104
|
-
| Captions | 1.4 | 0.02 to 0.05em |
|
|
105
|
-
| All caps text | 1.2 | 0.08 to 0.15em |
|
|
106
|
-
| Monospace/code | 1.5 to 1.7 | 0 |
|
|
107
|
-
|
|
108
|
-
### Paragraph Spacing
|
|
109
|
-
Use margin-bottom on paragraphs, not margin-top. Space between paragraphs should equal roughly the line-height value (1.5em works well). Never use `<br>` for spacing.
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## 5. OpenType Features
|
|
114
|
-
|
|
115
|
-
When the font supports them, enable:
|
|
116
|
-
```css
|
|
117
|
-
.body-text {
|
|
118
|
-
font-feature-settings: "liga" 1, "kern" 1;
|
|
119
|
-
font-variant-ligatures: common-ligatures;
|
|
120
|
-
}
|
|
121
|
-
.data-table {
|
|
122
|
-
font-variant-numeric: tabular-nums;
|
|
123
|
-
}
|
|
124
|
-
.legal-text {
|
|
125
|
-
font-variant-numeric: oldstyle-nums;
|
|
126
|
-
}
|
|
127
|
-
.heading {
|
|
128
|
-
font-feature-settings: "ss01" 1; /* Stylistic set */
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## 6. Pixel and Display Fonts
|
|
135
|
-
|
|
136
|
-
Pixel fonts are useful for specific moments: retro interfaces, game UIs, terminal aesthetics, or when the digital nature of the medium should be emphasized. They are not novelty fonts when used with system thinking.
|
|
137
|
-
|
|
138
|
-
Key principles for pixel fonts:
|
|
139
|
-
- Only use at sizes that align with the pixel grid (multiples of the font's design size)
|
|
140
|
-
- Disable anti-aliasing for crisp rendering: `font-smooth: never; -webkit-font-smoothing: none;`
|
|
141
|
-
- Pair with a clean sans for body text
|
|
142
|
-
- Use for headings, labels, badges, or UI accents, not paragraphs
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## 7. Web Font Loading
|
|
147
|
-
|
|
148
|
-
Use `font-display: swap` to prevent invisible text during load. Preload critical fonts:
|
|
149
|
-
|
|
150
|
-
```html
|
|
151
|
-
<link rel="preload" href="/fonts/display.woff2" as="font" type="font/woff2" crossorigin>
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Subset fonts to the characters actually used. For Google Fonts, append `&text=` with the specific characters or use `&subset=latin`.
|
|
155
|
-
|
|
156
|
-
Self-host when possible. CDN fonts introduce a third-party dependency and a DNS lookup.
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## 8. Common Mistakes
|
|
161
|
-
|
|
162
|
-
- Using more than 3 font families on a page
|
|
163
|
-
- Setting body text below 16px on desktop or 14px on mobile
|
|
164
|
-
- Applying letter-spacing to body text (it reduces readability)
|
|
165
|
-
- Using light (300) font weight for body text on low-contrast backgrounds
|
|
166
|
-
- Centering long paragraphs (center alignment works for 1-2 lines maximum)
|
|
167
|
-
- Forgetting to set `max-width` on text blocks (ideal: 60-75 characters per line, roughly 600-750px)
|
|
168
|
-
- Using all caps for more than a few words without increasing letter-spacing
|