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.
@@ -0,0 +1,222 @@
1
+ # Code Typography Reference
2
+
3
+ ## Table of Contents
4
+ 1. Monospace Font Selection
5
+ 2. Code Block Design
6
+ 3. Syntax Highlighting Accessibility
7
+ 4. Copy-to-Clipboard
8
+ 5. Responsive Code Blocks
9
+ 6. Inline Code Styling
10
+ 7. Diff Views
11
+ 8. Terminal Output
12
+ 9. Common Mistakes
13
+
14
+ ---
15
+
16
+ ## 1. Monospace Font Selection
17
+
18
+ | Font | Ligatures | Style | Best For |
19
+ |---|---|---|---|
20
+ | JetBrains Mono | Yes | Clean, geometric | General purpose, IDEs |
21
+ | Fira Code | Yes | Slightly rounded | Tutorials, docs |
22
+ | Source Code Pro | No | Adobe, professional | Enterprise, clean look |
23
+ | IBM Plex Mono | No | Corporate, legible | Documentation |
24
+ | Geist Mono | No | Vercel, modern | Next.js projects |
25
+ | Cascadia Code | Yes | Microsoft, playful | Terminals |
26
+
27
+ ```css
28
+ code, pre, .mono {
29
+ font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace;
30
+ font-feature-settings: 'liga' 1, 'calt' 1; /* enable ligatures */
31
+ font-variant-ligatures: common-ligatures;
32
+ }
33
+ ```
34
+
35
+ Ligatures: `=>` becomes ⇒, `!==` becomes ≢, `>=` becomes ≥. Enable for display, disable for editing if users copy code.
36
+
37
+ ---
38
+
39
+ ## 2. Code Block Design
40
+
41
+ ```css
42
+ pre {
43
+ background: var(--surface-1);
44
+ border: 1px solid var(--border);
45
+ border-radius: 8px;
46
+ padding: 1rem 1.25rem;
47
+ font-size: 0.875rem; /* 14px — slightly smaller than body */
48
+ line-height: 1.65; /* Looser than body text for readability */
49
+ overflow-x: auto;
50
+ tab-size: 2;
51
+ -moz-tab-size: 2;
52
+ }
53
+
54
+ /* Dark mode code blocks on light sites */
55
+ [data-theme="light"] pre {
56
+ background: oklch(0.14 0.02 230);
57
+ color: oklch(0.90 0.01 230);
58
+ }
59
+ ```
60
+
61
+ Line numbers (optional):
62
+ ```css
63
+ pre.line-numbers {
64
+ counter-reset: line;
65
+ padding-left: 3.5rem;
66
+ position: relative;
67
+ }
68
+ pre.line-numbers .line::before {
69
+ counter-increment: line;
70
+ content: counter(line);
71
+ position: absolute;
72
+ left: 1rem;
73
+ color: var(--text-muted);
74
+ font-size: 0.75rem;
75
+ user-select: none; /* don't copy line numbers */
76
+ }
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 3. Syntax Highlighting Accessibility
82
+
83
+ Every token color must have **minimum 3:1 contrast** against the code block background. Don't rely on color alone — use font-weight or font-style for emphasis.
84
+
85
+ | Token Type | Suggested OKLCH (dark bg) | Purpose |
86
+ |---|---|---|
87
+ | Keywords | `oklch(0.75 0.15 300)` | purple-ish, bold |
88
+ | Strings | `oklch(0.72 0.14 150)` | green |
89
+ | Numbers | `oklch(0.75 0.12 60)` | amber |
90
+ | Comments | `oklch(0.50 0.01 230)` | muted, italic |
91
+ | Functions | `oklch(0.78 0.10 230)` | blue |
92
+ | Variables | `oklch(0.85 0.01 230)` | near-white |
93
+
94
+ ```css
95
+ .token-keyword { color: oklch(0.75 0.15 300); font-weight: 600; }
96
+ .token-string { color: oklch(0.72 0.14 150); }
97
+ .token-comment { color: oklch(0.50 0.01 230); font-style: italic; }
98
+ ```
99
+
100
+ ---
101
+
102
+ ## 4. Copy-to-Clipboard
103
+
104
+ Position: top-right corner of the code block. Show on hover. Provide visual feedback.
105
+
106
+ ```jsx
107
+ function CopyButton({ code }) {
108
+ const [copied, setCopied] = useState(false);
109
+
110
+ return (
111
+ <button
112
+ onClick={() => {
113
+ navigator.clipboard.writeText(code);
114
+ setCopied(true);
115
+ setTimeout(() => setCopied(false), 2000);
116
+ }}
117
+ className="absolute top-2 right-2 p-1.5 rounded-md bg-white/5 hover:bg-white/10 text-xs text-muted"
118
+ aria-label="Copy code"
119
+ >
120
+ {copied ? 'Copied' : 'Copy'}
121
+ </button>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ---
127
+
128
+ ## 5. Responsive Code Blocks
129
+
130
+ Code blocks should **scroll horizontally** on mobile, never wrap. Terminal output CAN wrap.
131
+
132
+ ```css
133
+ pre {
134
+ overflow-x: auto;
135
+ white-space: pre; /* code: no wrap */
136
+ -webkit-overflow-scrolling: touch; /* smooth scroll on iOS */
137
+ }
138
+
139
+ pre.terminal {
140
+ white-space: pre-wrap; /* terminal: wrap is OK */
141
+ word-break: break-all;
142
+ }
143
+
144
+ /* Hide scrollbar but keep functionality */
145
+ pre::-webkit-scrollbar { height: 4px; }
146
+ pre::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
147
+ ```
148
+
149
+ On very small screens (< 375px), consider reducing code font-size to 12px.
150
+
151
+ ---
152
+
153
+ ## 6. Inline Code Styling
154
+
155
+ Inline code needs subtle visual distinction from body text:
156
+
157
+ ```css
158
+ code:not(pre code) {
159
+ background: var(--surface-2);
160
+ padding: 0.15em 0.4em;
161
+ border-radius: 4px;
162
+ font-size: 0.9em; /* slightly smaller than surrounding text */
163
+ font-weight: 500;
164
+ border: 1px solid var(--border);
165
+ }
166
+ ```
167
+
168
+ Never use inline code for emphasis. It's for code references (`useState`, `border-radius`, `GET /api/users`), not for highlighting words.
169
+
170
+ ---
171
+
172
+ ## 7. Diff Views
173
+
174
+ Use color + icon, not color alone (colorblind users):
175
+
176
+ ```css
177
+ .diff-add {
178
+ background: oklch(0.62 0.19 150 / 0.1);
179
+ border-left: 3px solid oklch(0.62 0.19 150);
180
+ }
181
+ .diff-add::before { content: '+'; color: oklch(0.62 0.19 150); }
182
+
183
+ .diff-remove {
184
+ background: oklch(0.55 0.22 25 / 0.1);
185
+ border-left: 3px solid oklch(0.55 0.22 25);
186
+ text-decoration: line-through;
187
+ opacity: 0.7;
188
+ }
189
+ .diff-remove::before { content: '-'; color: oklch(0.55 0.22 25); }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## 8. Terminal Output
195
+
196
+ Terminal/console styling should feel distinct from code:
197
+
198
+ ```css
199
+ .terminal {
200
+ background: oklch(0.08 0.01 230);
201
+ color: oklch(0.80 0.01 150); /* slight green tint for terminal feel */
202
+ font-family: 'JetBrains Mono', monospace;
203
+ padding: 1rem;
204
+ border-radius: 8px;
205
+ }
206
+ .terminal .prompt { color: oklch(0.65 0.10 230); } /* blue prompt */
207
+ .terminal .output { color: oklch(0.75 0.01 230); } /* neutral output */
208
+ .terminal .error { color: oklch(0.65 0.22 25); } /* red errors */
209
+ ```
210
+
211
+ ---
212
+
213
+ ## 9. Common Mistakes
214
+
215
+ - **Code font too large.** 14px for blocks, 0.9em for inline. Larger fights with body text.
216
+ - **No horizontal scroll on code blocks.** Wrapping code breaks readability. Always `overflow-x: auto`.
217
+ - **Syntax colors with < 3:1 contrast.** Comments especially — they tend to be too faint.
218
+ - **Color-only diff indication.** Always add + / - markers or icons alongside color.
219
+ - **Copying includes line numbers.** Use `user-select: none` on line number elements.
220
+ - **Same styling for code blocks and terminal.** They serve different purposes. Terminal gets darker bg, green tint.
221
+ - **`font-family: monospace` without named fonts.** Browsers default to Courier New which looks dated. Always specify a modern monospace font first.
222
+ - **No copy button.** Users shouldn't have to triple-click and drag to copy code.
@@ -0,0 +1,199 @@
1
+ # Dark Mode Reference
2
+
3
+ ## Table of Contents
4
+ 1. Preference Hierarchy
5
+ 2. CSS Custom Properties Approach
6
+ 3. Mode Transition
7
+ 4. Surface Elevation in Dark Mode
8
+ 5. Color Adjustments
9
+ 6. Image and Media Handling
10
+ 7. Testing Dark Mode
11
+ 8. Forced Colors and High Contrast
12
+ 9. Common Mistakes
13
+
14
+ ---
15
+
16
+ ## 1. Preference Hierarchy
17
+
18
+ System preference is the default. User override persists via localStorage. Never force dark mode without a toggle.
19
+
20
+ ```js
21
+ // Check system preference, then user override
22
+ const stored = localStorage.getItem('theme');
23
+ const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
24
+ const isDark = stored ? stored === 'dark' : systemDark;
25
+ document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
26
+ ```
27
+
28
+ ```css
29
+ /* System preference as base */
30
+ :root { color-scheme: light dark; }
31
+
32
+ /* Light (default) */
33
+ :root, [data-theme="light"] {
34
+ --surface-0: oklch(0.99 0.005 var(--hue));
35
+ --text-primary: oklch(0.15 0.02 var(--hue));
36
+ }
37
+
38
+ /* Dark */
39
+ [data-theme="dark"] {
40
+ --surface-0: oklch(0.11 0.02 var(--hue));
41
+ --text-primary: oklch(0.93 0.01 var(--hue));
42
+ }
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2. CSS Custom Properties Approach
48
+
49
+ Define all colors as CSS variables. Never hardcode hex in components. Dark mode is a variable swap, not a rewrite.
50
+
51
+ ```css
52
+ [data-theme="dark"] {
53
+ --surface-0: oklch(0.11 0.02 230); /* page bg */
54
+ --surface-1: oklch(0.14 0.02 230); /* card bg */
55
+ --surface-2: oklch(0.17 0.022 230); /* elevated bg */
56
+ --surface-3: oklch(0.20 0.024 230); /* hover bg */
57
+ --border: oklch(0.22 0.015 230);
58
+ --text-primary: oklch(0.93 0.01 230);
59
+ --text-secondary: oklch(0.62 0.02 230);
60
+ --text-muted: oklch(0.42 0.015 230);
61
+ }
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 3. Mode Transition
67
+
68
+ Never instant-swap. Use a 200ms opacity transition on the body. Disable transitions during the swap to prevent every element animating individually.
69
+
70
+ ```css
71
+ /* Add this class during theme switch, remove after 200ms */
72
+ .theme-transitioning * {
73
+ transition: none !important;
74
+ }
75
+
76
+ body {
77
+ transition: background-color 0.2s ease-out, color 0.2s ease-out;
78
+ }
79
+ ```
80
+
81
+ ```js
82
+ function toggleTheme() {
83
+ document.body.classList.add('theme-transitioning');
84
+ const next = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark';
85
+ document.documentElement.dataset.theme = next;
86
+ localStorage.setItem('theme', next);
87
+ requestAnimationFrame(() => {
88
+ requestAnimationFrame(() => {
89
+ document.body.classList.remove('theme-transitioning');
90
+ });
91
+ });
92
+ }
93
+ ```
94
+
95
+ ---
96
+
97
+ ## 4. Surface Elevation in Dark Mode
98
+
99
+ In dark mode, elevated surfaces get LIGHTER, not darker. This is the opposite of light mode where shadows darken surfaces. Without this, dark mode looks flat.
100
+
101
+ ```
102
+ Light mode elevation: surface-0 (lightest) → surface-3 (slightly darker)
103
+ Dark mode elevation: surface-0 (darkest) → surface-3 (slightly lighter)
104
+ ```
105
+
106
+ Shadows are nearly invisible in dark mode. Replace with surface lightness differentiation and subtle border glow:
107
+
108
+ ```css
109
+ [data-theme="dark"] .card {
110
+ background: var(--surface-1);
111
+ border: 1px solid oklch(1 0 0 / 0.06);
112
+ /* Shadow optional — use border + surface tint instead */
113
+ box-shadow: 0 0 0 1px oklch(1 0 0 / 0.03);
114
+ }
115
+ ```
116
+
117
+ ---
118
+
119
+ ## 5. Color Adjustments
120
+
121
+ Accent colors need lower chroma in dark mode. Full-saturation accents on dark backgrounds are harsh.
122
+
123
+ ```css
124
+ :root { --accent: oklch(0.55 0.25 250); } /* light: saturated */
125
+ [data-theme="dark"] { --accent: oklch(0.65 0.18 250); } /* dark: lighter, less chroma */
126
+ ```
127
+
128
+ Semantic colors also need adjustment:
129
+ - Success green: lighter, less saturated
130
+ - Error red: lighter to maintain contrast
131
+ - Warning amber: reduce chroma to avoid glowing
132
+
133
+ Text colors: minimum lightness 0.60 in OKLCH for body text on dark backgrounds. Below 0.55 looks washed out on cheap screens even if it passes WCAG.
134
+
135
+ ---
136
+
137
+ ## 6. Image and Media Handling
138
+
139
+ Dim images slightly in dark mode to reduce glare. SVGs should use currentColor or CSS variables.
140
+
141
+ ```css
142
+ [data-theme="dark"] img:not([data-no-dim]) {
143
+ filter: brightness(0.9) contrast(1.05);
144
+ }
145
+
146
+ [data-theme="dark"] svg { color: var(--text-primary); }
147
+ ```
148
+
149
+ For decorative images, consider `mix-blend-mode: luminosity` to desaturate:
150
+ ```css
151
+ [data-theme="dark"] .hero-image {
152
+ mix-blend-mode: luminosity;
153
+ opacity: 0.8;
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 7. Testing Dark Mode
160
+
161
+ Dark mode is not "invert the colors." Test these specifically:
162
+
163
+ 1. **Contrast ratios** — recheck all text/background pairs. WCAG ratios change.
164
+ 2. **Shadows** — are they visible? If not, use border or surface tint instead.
165
+ 3. **Form inputs** — autofill styling overrides your dark background. Fix with `-webkit-box-shadow: 0 0 0 1000px var(--surface-1) inset`.
166
+ 4. **Selection color** — `::selection` background needs to contrast with dark text highlight.
167
+ 5. **Scrollbar** — custom scrollbar thumb must be visible on dark track.
168
+ 6. **Third-party embeds** — iframes, maps, payment forms may not respect your dark mode.
169
+ 7. **Screenshots** — take a screenshot and look at it on a non-retina screen. Subtle contrast often vanishes.
170
+
171
+ ---
172
+
173
+ ## 8. Forced Colors and High Contrast
174
+
175
+ Windows High Contrast mode (`@media (forced-colors: active)`) overrides ALL custom colors. Your tinted neutrals, subtle borders, and custom focus rings will disappear.
176
+
177
+ ```css
178
+ @media (forced-colors: active) {
179
+ .card { border: 1px solid CanvasText; }
180
+ :focus-visible { outline: 2px solid Highlight; }
181
+ .btn-primary { border: 2px solid ButtonText; }
182
+ }
183
+ ```
184
+
185
+ Never use `forced-color-adjust: none` globally. Only on specific elements where you've provided a system-color fallback.
186
+
187
+ ---
188
+
189
+ ## 9. Common Mistakes
190
+
191
+ - **Instant theme swap without transition.** Jarring. Always fade (200ms).
192
+ - **Shadows that work in light but vanish in dark.** Replace with borders + surface tint.
193
+ - **Same accent chroma in both modes.** Reduce chroma for dark mode.
194
+ - **Checking contrast only in light mode.** Dark mode ratios are different — recheck.
195
+ - **`background: black` for dark mode.** Never pure black. Tint toward your hue.
196
+ - **Not testing autofill.** Browsers apply white backgrounds to autofilled inputs.
197
+ - **Not testing scrollbar.** Custom scrollbar may be invisible on dark backgrounds.
198
+ - **Storing theme in state instead of localStorage.** Causes flash of wrong theme on reload.
199
+ - **No `color-scheme: dark` declaration.** Browser UI elements (scrollbars, form controls) won't adapt without it.
@@ -0,0 +1,177 @@
1
+ # Internationalization Visual Patterns Reference
2
+
3
+ ## Table of Contents
4
+ 1. Logical Properties
5
+ 2. RTL Layout Mirroring
6
+ 3. Text Expansion by Language
7
+ 4. CJK Text Rendering
8
+ 5. Number and Currency Formatting
9
+ 6. Font Stacks for Multi-Language
10
+ 7. Icon Mirroring in RTL
11
+ 8. Common Mistakes
12
+
13
+ ---
14
+
15
+ ## 1. Logical Properties
16
+
17
+ Replace physical properties with logical ones. This makes RTL support automatic.
18
+
19
+ | Physical (avoid) | Logical (use) |
20
+ |---|---|
21
+ | `margin-left` | `margin-inline-start` |
22
+ | `margin-right` | `margin-inline-end` |
23
+ | `padding-left` | `padding-inline-start` |
24
+ | `text-align: left` | `text-align: start` |
25
+ | `float: left` | `float: inline-start` |
26
+ | `border-left` | `border-inline-start` |
27
+ | `left: 0` | `inset-inline-start: 0` |
28
+
29
+ ```css
30
+ /* Good: works in both LTR and RTL */
31
+ .sidebar { margin-inline-end: 2rem; padding-inline-start: 1rem; }
32
+
33
+ /* Bad: breaks in RTL */
34
+ .sidebar { margin-right: 2rem; padding-left: 1rem; }
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 2. RTL Layout Mirroring
40
+
41
+ Set `dir="auto"` on user-generated content. Set `dir="rtl"` on the `<html>` element for RTL languages.
42
+
43
+ ```html
44
+ <html lang="ar" dir="rtl">
45
+ ```
46
+
47
+ Flexbox and Grid automatically reverse in RTL when using logical properties. No extra CSS needed.
48
+
49
+ ```css
50
+ /* This works in both directions automatically */
51
+ .nav { display: flex; gap: 1rem; }
52
+ .card { display: grid; grid-template-columns: auto 1fr; }
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 3. Text Expansion by Language
58
+
59
+ English text expands significantly when translated. Design for the longest likely translation.
60
+
61
+ | Language | Expansion from English |
62
+ |---|---|
63
+ | German | +30-35% |
64
+ | French | +15-20% |
65
+ | Finnish | +30-40% |
66
+ | Russian | +15-25% |
67
+ | Chinese | -30-50% (shorter) |
68
+ | Japanese | -20-40% (shorter) |
69
+ | Arabic | +20-25% |
70
+
71
+ Rules:
72
+ - Never use fixed-width containers for translatable text.
73
+ - Buttons: use `min-width` not `width`. Allow text to wrap or grow.
74
+ - Navigation: test with German translations (longest common language).
75
+ - Truncate with `text-overflow: ellipsis` as a last resort, never as the design.
76
+
77
+ ```css
78
+ /* Good: grows with content */
79
+ .btn { min-width: 120px; padding-inline: 1.5rem; white-space: nowrap; }
80
+
81
+ /* Bad: text overflows in German */
82
+ .btn { width: 120px; }
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 4. CJK Text Rendering
88
+
89
+ Chinese, Japanese, and Korean text has different line-breaking and spacing rules.
90
+
91
+ ```css
92
+ /* Allow CJK text to break at any character */
93
+ .cjk-text {
94
+ line-break: auto;
95
+ word-break: keep-all; /* Korean: don't break within words */
96
+ overflow-wrap: break-word;
97
+ }
98
+
99
+ /* CJK doesn't need letter-spacing for readability */
100
+ :lang(zh), :lang(ja), :lang(ko) {
101
+ letter-spacing: 0;
102
+ }
103
+ ```
104
+
105
+ CJK text is denser — reduce line-height slightly:
106
+ ```css
107
+ :lang(zh), :lang(ja) { line-height: 1.7; } /* vs 1.5 for Latin */
108
+ ```
109
+
110
+ ---
111
+
112
+ ## 5. Number and Currency Formatting
113
+
114
+ Never hardcode currency symbols or number formats. Use `Intl.NumberFormat`.
115
+
116
+ ```js
117
+ // Automatic locale-aware formatting
118
+ new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(1234.56)
119
+ // → "$1,234.56"
120
+
121
+ new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(1234.56)
122
+ // → "1.234,56 €"
123
+
124
+ new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(1234)
125
+ // → "¥1,234"
126
+ ```
127
+
128
+ For dates: use `Intl.DateTimeFormat`, never manual formatting.
129
+
130
+ ---
131
+
132
+ ## 6. Font Stacks for Multi-Language
133
+
134
+ Include system fonts per script as fallbacks:
135
+
136
+ ```css
137
+ body {
138
+ font-family:
139
+ 'Your Custom Font', /* Latin */
140
+ 'Noto Sans SC', /* Simplified Chinese */
141
+ 'Noto Sans JP', /* Japanese */
142
+ 'Noto Sans KR', /* Korean */
143
+ 'Noto Sans Arabic', /* Arabic */
144
+ system-ui, sans-serif; /* Fallback */
145
+ }
146
+ ```
147
+
148
+ Google's Noto family covers every Unicode script. Use it as the universal fallback.
149
+
150
+ ---
151
+
152
+ ## 7. Icon Mirroring in RTL
153
+
154
+ Icons that imply direction MUST mirror in RTL. Icons that don't imply direction must NOT.
155
+
156
+ **Mirror in RTL:** arrows, back/forward, reply, undo/redo, text indent, send, search (if it implies reading direction), progress bars.
157
+
158
+ **Do NOT mirror:** play/pause, checkmarks, plus/minus, clock, globe, user, settings gear, download, external link.
159
+
160
+ ```css
161
+ [dir="rtl"] .icon-directional {
162
+ transform: scaleX(-1);
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## 8. Common Mistakes
169
+
170
+ - **Hardcoding `left`/`right` in CSS.** Use logical properties.
171
+ - **Fixed-width buttons.** They overflow in German/Finnish. Use `min-width`.
172
+ - **Testing only in English.** Design breaks with 35% longer strings.
173
+ - **`text-align: left` instead of `text-align: start`.** Breaks RTL.
174
+ - **Mirroring ALL icons in RTL.** Only directional icons should flip.
175
+ - **Hardcoding date formats.** `01/02/2026` means different dates in US vs UK. Use `Intl.DateTimeFormat`.
176
+ - **Not loading CJK fonts.** System fonts for CJK vary wildly. Include Noto Sans.
177
+ - **Ignoring `dir="auto"` on user content.** A Hebrew comment in an English page needs auto-detection.