@mohammadhprp/system-prompt 0.11.2 → 0.12.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/framework/agents/researcher.md +1 -1
- package/framework/mcps/github-mcp/README.md +1 -1
- package/framework/mcps/github-mcp/configs/.env.example +1 -1
- package/framework/plugins/ponytail/README.md +1 -1
- package/framework/plugins/ponytail/capabilities.md +1 -1
- package/framework/references/standards/pull-requests.md +1 -1
- package/framework/skills/README.md +3 -3
- package/framework/skills/diagram-design/SKILL.md +1 -1
- package/framework/skills/effective-html/SKILL.md +63 -0
- package/framework/skills/effective-html/examples.md +19 -0
- package/framework/skills/effective-html/references/charts-and-data.md +32 -0
- package/framework/skills/effective-html/references/creative-direction.md +48 -0
- package/framework/skills/effective-html/references/design-artifact.md +78 -0
- package/framework/skills/effective-html/references/diagrams.md +68 -0
- package/framework/skills/effective-html/references/documents-and-presentations.md +28 -0
- package/framework/skills/effective-html/references/html-diagram.md +43 -0
- package/framework/skills/effective-html/references/html-plan.md +40 -0
- package/framework/skills/effective-html/references/html-prototype.md +97 -0
- package/framework/skills/effective-html/references/html-wireframe.md +81 -0
- package/framework/skills/effective-html/references/html.md +72 -0
- package/framework/skills/effective-html/references/interfaces.md +17 -0
- package/framework/skills/great-interface/SKILL.md +43 -0
- package/framework/skills/great-interface/references/animations.md +205 -0
- package/framework/skills/great-interface/references/better-accessibility.md +106 -0
- package/framework/skills/great-interface/references/better-colors.md +100 -0
- package/framework/skills/great-interface/references/better-interface.md +132 -0
- package/framework/skills/great-interface/references/better-layout.md +76 -0
- package/framework/skills/great-interface/references/better-typography.md +157 -0
- package/framework/skills/great-interface/references/better-ui.md +107 -0
- package/framework/skills/great-interface/references/better-writing.md +109 -0
- package/framework/skills/great-interface/references/choosing-fonts.md +64 -0
- package/framework/skills/great-interface/references/color-formats.md +90 -0
- package/framework/skills/great-interface/references/color-usage.md +118 -0
- package/framework/skills/great-interface/references/contrast.md +79 -0
- package/framework/skills/great-interface/references/css-cheat-sheet.md +65 -0
- package/framework/skills/great-interface/references/details-and-accessibility.md +119 -0
- package/framework/skills/great-interface/references/enter-exit.md +147 -0
- package/framework/skills/great-interface/references/explain-interface.md +126 -0
- package/framework/skills/great-interface/references/find-the-effect.md +94 -0
- package/framework/skills/great-interface/references/focus-and-keyboard.md +131 -0
- package/framework/skills/great-interface/references/forms.md +84 -0
- package/framework/skills/great-interface/references/from-an-image.md +55 -0
- package/framework/skills/great-interface/references/grouping-and-alignment.md +123 -0
- package/framework/skills/great-interface/references/hit-areas.md +94 -0
- package/framework/skills/great-interface/references/icon-transitions.md +102 -0
- package/framework/skills/great-interface/references/icons.md +110 -0
- package/framework/skills/great-interface/references/interface-review.md +148 -0
- package/framework/skills/great-interface/references/motion-and-zoom.md +79 -0
- package/framework/skills/great-interface/references/no-browser.md +73 -0
- package/framework/skills/great-interface/references/palette-generation.md +104 -0
- package/framework/skills/great-interface/references/palette-structure.md +76 -0
- package/framework/skills/great-interface/references/performance.md +88 -0
- package/framework/skills/great-interface/references/picker.md +76 -0
- package/framework/skills/great-interface/references/read-the-system.md +178 -0
- package/framework/skills/great-interface/references/removed-signals.md +38 -0
- package/framework/skills/great-interface/references/review-format.md +46 -0
- package/framework/skills/great-interface/references/scope-resolution.md +88 -0
- package/framework/skills/great-interface/references/screen-readers.md +101 -0
- package/framework/skills/great-interface/references/semantics-and-aria.md +84 -0
- package/framework/skills/great-interface/references/spacing-and-adaptivity.md +159 -0
- package/framework/skills/great-interface/references/spacing-and-sizing.md +121 -0
- package/framework/skills/great-interface/references/surfaces.md +219 -0
- package/framework/skills/great-interface/references/token-naming.md +97 -0
- package/framework/skills/great-interface/references/variable-fonts-and-opentype.md +105 -0
- package/framework/skills/great-interface/references/variant.md +104 -0
- package/framework/skills/great-interface/references/wrapping-and-punctuation.md +55 -0
- package/framework/skills/taste/SKILL.md +47 -0
- package/framework/skills/taste/examples.md +73 -0
- package/framework/skills/taste/references/brandkit.md +793 -0
- package/framework/skills/taste/references/design-taste-frontend-v1.md +221 -0
- package/framework/skills/taste/references/design-taste-frontend.md +1201 -0
- package/framework/skills/taste/references/full-output-enforcement.md +44 -0
- package/framework/skills/taste/references/gpt-taste.md +69 -0
- package/framework/skills/taste/references/high-end-visual-design.md +93 -0
- package/framework/skills/taste/references/image-to-code.md +1223 -0
- package/framework/skills/taste/references/imagegen-frontend-mobile.md +1460 -0
- package/framework/skills/taste/references/imagegen-frontend-web.md +982 -0
- package/framework/skills/taste/references/industrial-brutalist-ui.md +87 -0
- package/framework/skills/taste/references/minimalist-ui.md +80 -0
- package/framework/skills/taste/references/redesign-existing-projects.md +173 -0
- package/framework/skills/taste/references/stitch-design-taste-design.md +121 -0
- package/framework/skills/taste/references/stitch-design-taste.md +179 -0
- package/package.json +1 -1
- package/src/agent-configs.js +6 -2
- package/src/catalog.js +3 -2
- package/src/cli.js +82 -2
- package/src/doctor.js +84 -0
- package/src/installer.js +337 -154
- package/framework/skills/brand-guidelines/LICENSE.txt +0 -202
- package/framework/skills/brand-guidelines/SKILL.md +0 -73
- package/framework/skills/lavish/SKILL.md +0 -67
- package/framework/skills/lavish/examples.md +0 -31
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Surfaces
|
|
2
|
+
|
|
3
|
+
Border radius, optical alignment, shadows and image outlines.
|
|
4
|
+
|
|
5
|
+
## Concentric border radius
|
|
6
|
+
|
|
7
|
+
When nesting rounded elements, the outer radius must equal the inner radius plus the padding between them:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
outerRadius = innerRadius + padding
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The rule matters most when nested surfaces sit close together. Past `24px` of padding, treat the layers as separate surfaces and choose each radius independently rather than forcing concentric math.
|
|
14
|
+
|
|
15
|
+
### Example
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
/* Good: concentric radii */
|
|
19
|
+
.card {
|
|
20
|
+
border-radius: 20px; /* 12 + 8 */
|
|
21
|
+
padding: 8px;
|
|
22
|
+
}
|
|
23
|
+
.card-inner {
|
|
24
|
+
border-radius: 12px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Bad: same radius on both */
|
|
28
|
+
.card {
|
|
29
|
+
border-radius: 12px;
|
|
30
|
+
padding: 8px;
|
|
31
|
+
}
|
|
32
|
+
.card-inner {
|
|
33
|
+
border-radius: 12px;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Tailwind example
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
// Good: outer radius accounts for padding
|
|
41
|
+
<div className="rounded-2xl p-2"> {/* 16px radius, 8px padding */}
|
|
42
|
+
<div className="rounded-lg"> {/* 8px radius = 16 - 8 ✓ */}
|
|
43
|
+
...
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
// Bad: same radius on both
|
|
48
|
+
<div className="rounded-xl p-2">
|
|
49
|
+
<div className="rounded-xl"> {/* same radius, looks off */}
|
|
50
|
+
...
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Mismatched radii on closely nested surfaces are a common source of visual tension. Calculate concentrically where the layers share a visible, even inset. Keep an established component token where they are independent or the padding is deliberately asymmetric.
|
|
56
|
+
|
|
57
|
+
## Optical alignment
|
|
58
|
+
|
|
59
|
+
When geometric centering looks off, align optically instead.
|
|
60
|
+
|
|
61
|
+
### Buttons with text + icon
|
|
62
|
+
|
|
63
|
+
Where an icon makes symmetric padding look unbalanced, use slightly less on the icon side. A starting point:
|
|
64
|
+
`icon-side padding = text-side padding - 2px`.
|
|
65
|
+
|
|
66
|
+
```css
|
|
67
|
+
/* Good: less padding on icon side */
|
|
68
|
+
.button-with-icon {
|
|
69
|
+
padding-inline-start: 16px;
|
|
70
|
+
padding-inline-end: 14px; /* trailing icon side = text side - 2px */
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Bad: equal padding looks like icon is pushed too far right */
|
|
74
|
+
.button-with-icon {
|
|
75
|
+
padding-inline: 16px;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// Tailwind
|
|
81
|
+
<button className="ps-4 pe-3.5 flex items-center gap-2">
|
|
82
|
+
<span>Continue</span>
|
|
83
|
+
<ArrowRightIcon />
|
|
84
|
+
</button>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Play button triangles
|
|
88
|
+
|
|
89
|
+
Play icons are triangular and their geometric center is not their visual center. Shift slightly right:
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
/* Good: optically centered */
|
|
93
|
+
.play-button svg {
|
|
94
|
+
transform: translateX(2px); /* physical correction to the glyph itself */
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Bad: geometrically centered but looks off */
|
|
98
|
+
.play-button svg {
|
|
99
|
+
/* no adjustment */
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Asymmetric icons (stars, arrows, carets)
|
|
104
|
+
|
|
105
|
+
Some icons carry uneven visual weight. The best fix is adjusting the SVG directly, so the component needs no extra margin or padding.
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
// Best: fix in the SVG itself
|
|
109
|
+
// Adjust the viewBox or path to visually center the icon
|
|
110
|
+
|
|
111
|
+
// Fallback: adjust with margin
|
|
112
|
+
<span className="translate-x-px">
|
|
113
|
+
<StarIcon />
|
|
114
|
+
</span>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Shadows instead of borders
|
|
118
|
+
|
|
119
|
+
Where **buttons, cards and containers** use a border for depth or elevation, replace it with a subtle `box-shadow`. Shadows use transparency, so they adapt to any background where solid borders do not. That matters most over images or multiple background colors, which a fixed border color was never designed for.
|
|
120
|
+
|
|
121
|
+
**Never apply this to dividers**, meaning `border-b`, `border-t` and side borders, or any border whose purpose is layout separation rather than depth. Those stay borders.
|
|
122
|
+
|
|
123
|
+
### Shadow as border (light mode)
|
|
124
|
+
|
|
125
|
+
Three layers. The first acts as a 1px border ring, the second adds subtle lift, the third ambient depth:
|
|
126
|
+
|
|
127
|
+
```css
|
|
128
|
+
:root {
|
|
129
|
+
--shadow-border:
|
|
130
|
+
0px 0px 0px 1px oklch(0 0 0 / 0.06),
|
|
131
|
+
0px 1px 2px -1px oklch(0 0 0 / 0.06),
|
|
132
|
+
0px 2px 4px 0px oklch(0 0 0 / 0.04);
|
|
133
|
+
--shadow-border-hover:
|
|
134
|
+
0px 0px 0px 1px oklch(0 0 0 / 0.08),
|
|
135
|
+
0px 1px 2px -1px oklch(0 0 0 / 0.08),
|
|
136
|
+
0px 2px 4px 0px oklch(0 0 0 / 0.06);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Shadow as border (dark mode)
|
|
141
|
+
|
|
142
|
+
In dark mode, simplify to one white ring, since layered depth shadows are invisible on dark backgrounds:
|
|
143
|
+
|
|
144
|
+
```css
|
|
145
|
+
/* Dark mode: adapt to whatever setup the project uses
|
|
146
|
+
(prefers-color-scheme, class, data attribute, etc.) */
|
|
147
|
+
--shadow-border: 0 0 0 1px oklch(1 0 0 / 0.08);
|
|
148
|
+
--shadow-border-hover: 0 0 0 1px oklch(1 0 0 / 0.13);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Usage with hover transition
|
|
152
|
+
|
|
153
|
+
Apply the variable and add `transition-[box-shadow]` for a smooth hover:
|
|
154
|
+
|
|
155
|
+
```css
|
|
156
|
+
.card {
|
|
157
|
+
box-shadow: var(--shadow-border);
|
|
158
|
+
transition-property: box-shadow;
|
|
159
|
+
transition-duration: 150ms;
|
|
160
|
+
transition-timing-function: ease-out;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.card:hover {
|
|
164
|
+
box-shadow: var(--shadow-border-hover);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### When to use shadows vs. borders
|
|
169
|
+
|
|
170
|
+
| Use shadows | Use borders |
|
|
171
|
+
| --- | --- |
|
|
172
|
+
| Cards, containers with depth | Dividers between list items |
|
|
173
|
+
| Buttons with bordered styles | Table cell boundaries |
|
|
174
|
+
| Elevated elements (dropdowns, modals) | Form input outlines (for accessibility) |
|
|
175
|
+
| Elements on varied backgrounds | Hairline separators in dense UI |
|
|
176
|
+
| Hover/focus states for lift effect | |
|
|
177
|
+
|
|
178
|
+
## Image outlines
|
|
179
|
+
|
|
180
|
+
Add a `1px` outline at low opacity to images for consistent depth, especially where other elements use borders or shadows.
|
|
181
|
+
|
|
182
|
+
### Color rules (non-negotiable)
|
|
183
|
+
|
|
184
|
+
- **Light mode**: pure black, `oklch(0 0 0 / 0.1)`.
|
|
185
|
+
- **Dark mode**: pure white, `oklch(1 0 0 / 0.1)`.
|
|
186
|
+
- Never a near-black or near-white from the project palette, such as slate-900, zinc-900, `#0a0a0a`, `#111827`, or `#f5f5f7`. Tinted outlines pick up the surrounding surface color and read as dirt on the image edge.
|
|
187
|
+
- Never match the outline to the project's accent or ink color. The outline is a neutral separator, not a themed element.
|
|
188
|
+
|
|
189
|
+
### Light mode
|
|
190
|
+
|
|
191
|
+
```css
|
|
192
|
+
img {
|
|
193
|
+
outline: 1px solid oklch(0 0 0 / 0.1);
|
|
194
|
+
outline-offset: -1px; /* draw the ring just inside the image edge */
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Dark mode
|
|
199
|
+
|
|
200
|
+
```css
|
|
201
|
+
img {
|
|
202
|
+
outline: 1px solid oklch(1 0 0 / 0.1);
|
|
203
|
+
outline-offset: -1px;
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Tailwind with dark mode
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
<img
|
|
211
|
+
className="outline outline-1 -outline-offset-1 outline-black/10 dark:outline-white/10"
|
|
212
|
+
src={src}
|
|
213
|
+
alt={alt}
|
|
214
|
+
/>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Use `outline-black/10` and `outline-white/10` specifically, not `outline-slate-*`, `outline-zinc-*`, `outline-neutral-*`, or any tinted scale.
|
|
218
|
+
|
|
219
|
+
**Why outline instead of border?** `outline` never affects layout, adding no width or height at any offset, and `outline-offset: -1px` draws the ring just inside the image edge so it hugs the corner radius.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Token naming
|
|
2
|
+
|
|
3
|
+
Naming is what makes a palette usable by anyone who did not build it. For which ramps exist and what each step does, see [palette-structure.md](palette-structure.md).
|
|
4
|
+
|
|
5
|
+
## Two tiers
|
|
6
|
+
|
|
7
|
+
**Primitives** name a value. They are the ramp, named by hue and step: `--blue-500`, `--neutral-200`. A primitive describes what the color *is*, so it never changes meaning between themes and is never applied directly in a component.
|
|
8
|
+
|
|
9
|
+
**Semantics** name a job. They point at a primitive and take the name of the role they fill: `--color-text-secondary`, `--color-border-subtle`. Components only ever reference this tier.
|
|
10
|
+
|
|
11
|
+
```css
|
|
12
|
+
:root {
|
|
13
|
+
/* Tier 1: primitives, named by appearance. Never used directly. */
|
|
14
|
+
--blue-500: #3b82f6;
|
|
15
|
+
--neutral-200: #e5e7eb;
|
|
16
|
+
--neutral-700: #374151;
|
|
17
|
+
|
|
18
|
+
/* Tier 2: semantics, named by role. This is what components use. */
|
|
19
|
+
--color-accent-solid: var(--blue-500);
|
|
20
|
+
--color-border: var(--neutral-200);
|
|
21
|
+
--color-text-secondary: var(--neutral-700);
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The tiering is what makes theming possible. Dark mode, a white-label theme and an increased-contrast variant all repoint the semantic tier, leaving the primitives and every component untouched. A codebase applying `--blue-500` directly in components has no theming seam. Adding one later means auditing every usage to work out which meant "the accent" and which just wanted blue.
|
|
26
|
+
|
|
27
|
+
Add a third, component-level tier (`--color-button-danger-bg`) only where a component genuinely and intentionally diverges from the system. One component token is a documented exception; twenty mean the semantic tier is missing roles.
|
|
28
|
+
|
|
29
|
+
## The role inventory
|
|
30
|
+
|
|
31
|
+
A system is complete when every role below has a token. Build against this list rather than adding tokens as components demand them, or the palette ends up shaped like whichever screen came first.
|
|
32
|
+
|
|
33
|
+
| Group | Roles |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| Surfaces | page background, surface, raised (menus, popovers), sunken (inputs, wells), overlay scrim |
|
|
36
|
+
| Text | primary, secondary, disabled, inverse, on-accent |
|
|
37
|
+
| Borders | subtle, default, strong, focus ring, separator |
|
|
38
|
+
| Accent | subtle background, border, solid, solid hover, text |
|
|
39
|
+
| Status | per status shipped: subtle background, border, solid, text |
|
|
40
|
+
|
|
41
|
+
Separator and border are separate roles even when they share a value today. A separator divides content; a border encloses a control. They diverge the first time someone restyles inputs, and a system that conflated them gets untangled at that moment.
|
|
42
|
+
|
|
43
|
+
## Naming grammar
|
|
44
|
+
|
|
45
|
+
Use one shape and never deviate: `--color-{role}-{variant}-{state}`.
|
|
46
|
+
|
|
47
|
+
```css
|
|
48
|
+
--color-bg-surface
|
|
49
|
+
--color-text-secondary
|
|
50
|
+
--color-border-strong
|
|
51
|
+
--color-accent-solid-hover
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Pick one word per concept and use only that word. Consistency matters more than the vocabulary. A reader who has seen `--color-text-primary` must be able to guess `--color-text-disabled` without looking:
|
|
55
|
+
|
|
56
|
+
| Concept | Pick one | Never mix in |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| Foreground | `text` | `fg`, `foreground`, `content`, `ink` |
|
|
59
|
+
| Background | `bg` | `background`, `surface` as a synonym, `fill` |
|
|
60
|
+
| Edge | `border` | `stroke`, `outline`, `line` |
|
|
61
|
+
| Brand color | `accent` | `primary`, `brand`, `theme` used interchangeably |
|
|
62
|
+
|
|
63
|
+
Reserve `primary` for exactly one meaning. `--color-text-primary` for body text beside `--color-primary` for the brand is the most common naming collision there is, and it makes every `primary` token ambiguous until you open its definition. Use `accent` for the brand and let `primary` mean "the most prominent of its group".
|
|
64
|
+
|
|
65
|
+
## Anti-patterns
|
|
66
|
+
|
|
67
|
+
| Name | Problem | Instead |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| `--color-blue-button` | Appearance at the semantic tier; lies the moment the brand changes | `--color-accent-solid` |
|
|
70
|
+
| `--color-sidebar-gray` | Named for where it was used first; the second usage makes it nonsense | `--color-bg-surface` |
|
|
71
|
+
| `--color-light-gray` | Lies in dark mode, where it is the dark one | `--neutral-200` as a primitive |
|
|
72
|
+
| `--color-text-2` | Numbered semantics carry no meaning; nobody can guess what `3` would be | `--color-text-secondary` |
|
|
73
|
+
| `--color-gray-hover` | Mixes a hue with a state and belongs to no tier | `--color-bg-surface-hover` |
|
|
74
|
+
| `--blue-500` used in a component | Skips the semantic tier and removes the theming seam | Point a semantic token at it |
|
|
75
|
+
|
|
76
|
+
Every one of them is a case of **Use a token only in its role**. See [color-usage.md](color-usage.md).
|
|
77
|
+
|
|
78
|
+
## In Tailwind projects
|
|
79
|
+
|
|
80
|
+
Tailwind v4 generates utilities from `@theme`, so names declared there become the API. Declare primitives and semantics in the same block; the `--color-*` namespace is what produces `bg-*`, `text-*` and `border-*`:
|
|
81
|
+
|
|
82
|
+
```css
|
|
83
|
+
@theme {
|
|
84
|
+
/* Primitives */
|
|
85
|
+
--color-brand-50: #eff6ff;
|
|
86
|
+
--color-brand-500: #3b82f6;
|
|
87
|
+
--color-brand-900: #1e3a8a;
|
|
88
|
+
|
|
89
|
+
/* Semantics: what templates should use */
|
|
90
|
+
--color-accent-solid: var(--color-brand-500);
|
|
91
|
+
--color-text-secondary: var(--color-neutral-700);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
That yields `bg-accent-solid` and `text-secondary` alongside `bg-brand-500`. Both are reachable, so the discipline is a convention rather than a constraint. Templates use the semantic utilities, and a raw `bg-brand-500` in a component is the thing to flag.
|
|
96
|
+
|
|
97
|
+
Opacity modifiers work on either tier, as in `bg-accent-solid/50`. But a color carrying alpha cannot be contrast-checked against a static background, because what it renders depends on what sits behind it. Use solid tokens for anything with text on it.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Variable fonts and OpenType
|
|
2
|
+
|
|
3
|
+
What a font file can do beyond drawing letters and how to reach those abilities from CSS.
|
|
4
|
+
|
|
5
|
+
## Static vs variable
|
|
6
|
+
|
|
7
|
+
- **Static font:** one weight and one style per file. Regular, medium and bold is three files.
|
|
8
|
+
- **Variable font:** a whole range in one file. Any value in it works, such as `font-weight: 589`.
|
|
9
|
+
|
|
10
|
+
A variable font is not automatically better. At one or two weights, static files can be smaller. At several weights, optical sizes, or custom axes, a variable font usually wins.
|
|
11
|
+
|
|
12
|
+
## Load intended weights and styles
|
|
13
|
+
|
|
14
|
+
Use a weight or style the active family does not provide and the browser may synthesize it, so load the faces the design uses. `none` disables weight, style, small-cap, superscript and subscript synthesis together and can erase distinctions when the real face is unavailable. Verify the whole fallback stack and every emphasis state before setting it.
|
|
15
|
+
|
|
16
|
+
```css
|
|
17
|
+
.brand-wordmark {
|
|
18
|
+
/* Safe only after this isolated treatment is verified */
|
|
19
|
+
font-synthesis: none;
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For body and interface text, keep synthesis enabled unless a verified font setup supplies every requested form. If only one mode is unwanted, use the specific longhand (`font-synthesis-weight`, `font-synthesis-style` and related properties) instead of the blanket shorthand.
|
|
24
|
+
|
|
25
|
+
## Axes
|
|
26
|
+
|
|
27
|
+
Variable-font controls, each with a four-letter tag. A font supports only the axes its designer included.
|
|
28
|
+
|
|
29
|
+
| Axis | Tag | Controls |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| Weight | `wght` | Stroke thickness (like `font-weight`) |
|
|
32
|
+
| Optical size | `opsz` | Details and spacing tuned for the display size |
|
|
33
|
+
| Width | `wdth` | Glyph width |
|
|
34
|
+
| Slant | `slnt` | Slant angle |
|
|
35
|
+
| Custom | e.g. `GRAD` (Roboto Flex) | Whatever the designer built |
|
|
36
|
+
|
|
37
|
+
Inter's variable file exposes only `wght` and `opsz`.
|
|
38
|
+
|
|
39
|
+
Optical sizes predate variable fonts, and many families still ship them as separate files. Heldane Text is sturdier and more spaced for reading sizes, Heldane Display finer for large ones.
|
|
40
|
+
|
|
41
|
+
## Properties over axis tags
|
|
42
|
+
|
|
43
|
+
When a property exists, use it. `font-weight` keeps working when a non-variable fallback renders, where `font-variation-settings` silently does nothing. Save raw tags for custom axes with no property of their own:
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
/* Good: common axes use the properties */
|
|
47
|
+
.heading {
|
|
48
|
+
font-weight: 650;
|
|
49
|
+
font-optical-sizing: auto;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Good: custom axis with no property of its own */
|
|
53
|
+
.heading-grade {
|
|
54
|
+
font-variation-settings: "GRAD" 80;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Bad: weight via raw tag breaks on fallback fonts */
|
|
58
|
+
.heading {
|
|
59
|
+
font-variation-settings: "wght" 650;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## OpenType features
|
|
64
|
+
|
|
65
|
+
OpenType is the standard behind almost every modern font. Features are extra built-in options and, unlike axes, work the same on static and variable fonts. A font ships only the features its designer included.
|
|
66
|
+
|
|
67
|
+
| Tag | Feature |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `tnum` | Tabular numbers: every digit the same width |
|
|
70
|
+
| `zero` | Slashed zero: `0` distinct from `O` |
|
|
71
|
+
| `liga` | Ligatures: joins pairs like "fi" into one shape |
|
|
72
|
+
| `ss01`–`ss20` | Stylistic sets (numbered slots) |
|
|
73
|
+
| `cv01`–`cv99` | Character variants (numbered slots) |
|
|
74
|
+
|
|
75
|
+
Same rule as axes. Prefer the `font-variant-*` properties and reserve `font-feature-settings` for tags with no property:
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
/* Good: common features use the properties */
|
|
79
|
+
.price {
|
|
80
|
+
font-variant-numeric: tabular-nums;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Good: slashed zero via the property too */
|
|
84
|
+
.id {
|
|
85
|
+
font-variant-numeric: slashed-zero;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Good: niche feature with no property of its own */
|
|
89
|
+
.logo {
|
|
90
|
+
font-feature-settings: "ss01" 1;
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Tabular numbers matter for changing values. Without them each digit has a different width and the layout shifts as values update.
|
|
95
|
+
|
|
96
|
+
## Small caps, superscripts, subscripts
|
|
97
|
+
|
|
98
|
+
- **Small capitals:** uppercase letters drawn at a smaller size. Enable real ones with `font-variant-caps`.
|
|
99
|
+
- **Superscripts** sit above the normal line, the 2 in x², and **subscripts** below it, as in H₂O. Enable proper glyphs with `font-variant-position`.
|
|
100
|
+
|
|
101
|
+
Both require the font to include the glyphs.
|
|
102
|
+
|
|
103
|
+
## Stylistic sets and character variants
|
|
104
|
+
|
|
105
|
+
`ss01` = stylistic set, slot 01. `cv11` = character variant, slot 11. What each slot does differs font to font, which is why they are numbered, not named. Check the font's docs. In Inter, `ss01` switches to open digits and `cv11` swaps in a single-story `a`.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Variants
|
|
2
|
+
|
|
3
|
+
This skill takes one described piece of UI and builds three versions that differ on purpose. They go behind a picker in the real page, so you can flip between them and choose.
|
|
4
|
+
|
|
5
|
+
Every other skill here judges. This one produces candidates and hands the decision back. Reviewing existing UI is `interface-review` and `better-interface`, and it does not pick the winner.
|
|
6
|
+
|
|
7
|
+
## Different answers, not different tints
|
|
8
|
+
|
|
9
|
+
Three variants that differ in accent color teach nothing. You flip between them, see no real choice and the run is wasted.
|
|
10
|
+
|
|
11
|
+
So each variant is a different answer to the same brief, on an axis this collection owns:
|
|
12
|
+
|
|
13
|
+
| Axis | Owner | What varies |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Structure | `better-layout` | Grouping, order, column count, what collapses |
|
|
16
|
+
| Density | `better-layout` | Spacing scale, hit areas, how much fits |
|
|
17
|
+
| Emphasis | `better-colors` | Where filled color goes, what recedes |
|
|
18
|
+
| Type | `better-typography` | Scale steps, weight contrast, measure |
|
|
19
|
+
| Voice | `better-writing` | Labels, tone, how much copy |
|
|
20
|
+
|
|
21
|
+
Pick **one primary axis** and give each variant a different position on it. Secondary choices follow from it rather than varying on their own. A dense variant may need a smaller type step, and that is coherence, not a second axis.
|
|
22
|
+
|
|
23
|
+
Varying every axis at once produces three unattributable results. You learn which you liked, not what made it work, so the next piece starts from nothing.
|
|
24
|
+
|
|
25
|
+
## The floor every variant clears
|
|
26
|
+
|
|
27
|
+
A variant that wins on looks and fails an escalation trigger is not a candidate. It is a bug with a nice surface.
|
|
28
|
+
|
|
29
|
+
Before a variant enters the picker it clears `better-interface`'s escalation triggers. Every control has an accessible name, keyboard reaches everything a pointer does, focus is visible, nothing clips at 320px and no meaning rides on color alone.
|
|
30
|
+
|
|
31
|
+
That floor is identical across variants. It is not an axis and never trades against one. Where a direction can only work by breaking it, say so and drop the direction.
|
|
32
|
+
|
|
33
|
+
## 1. Scope one piece
|
|
34
|
+
|
|
35
|
+
One piece of UI per run. "The dashboard" is not a piece; the metric card is. Where the brief spans several, name the one the others hang off, say why and offer the rest as later runs.
|
|
36
|
+
|
|
37
|
+
Restate the brief in one sentence: what the thing is, where it renders, what it has to do.
|
|
38
|
+
|
|
39
|
+
## 2. Learn the ground
|
|
40
|
+
|
|
41
|
+
Variants have to look like they could ship tomorrow, so read what they stand on:
|
|
42
|
+
|
|
43
|
+
- The styling system, the component library and any motion library.
|
|
44
|
+
- The tokens: color, spacing, radius, type scale, easing.
|
|
45
|
+
- The product's density and voice. A dense professional tool bounds how far the boldest variant may go.
|
|
46
|
+
- Where the piece renders: against what background, beside which neighbours, at which widths.
|
|
47
|
+
|
|
48
|
+
With no project to read, use neutral grays, one accent and the system font stack, and say that is what you did.
|
|
49
|
+
|
|
50
|
+
## 3. Name the axis before writing code
|
|
51
|
+
|
|
52
|
+
Default to three variants. Go to five only when asked, or when the space is genuinely wide. Past five nobody compares, they scroll.
|
|
53
|
+
|
|
54
|
+
Write the set down first, a name and an axis position each. Names say what the direction is, so `Quiet`, `Editorial`, `Dense`, never `Option A`.
|
|
55
|
+
|
|
56
|
+
This step is done when no two variants share a position and you can state each one's axis in a phrase.
|
|
57
|
+
|
|
58
|
+
## 4. Build it into the real page
|
|
59
|
+
|
|
60
|
+
A variant looks fine in isolation, which is why isolation is the wrong place to judge it. Host the variants on the page that will actually contain the piece, with the real chrome, the real neighbours and realistic data.
|
|
61
|
+
|
|
62
|
+
Select with a URL search param (`?variant=quiet`), so every variant is a link you can send someone. A floating control sets it; [picker.md]() holds the spec.
|
|
63
|
+
|
|
64
|
+
Render one variant at a time, full size. Thumbnails distort spacing and scale, and spacing is usually the thing you are choosing between.
|
|
65
|
+
|
|
66
|
+
Where no page can host it, build one self-contained HTML file and keep the same picker.
|
|
67
|
+
|
|
68
|
+
Give every variant real content: product-shaped copy, plausible names and the number of items the page will really carry. Lorem ipsum and three rows make every structure look good.
|
|
69
|
+
|
|
70
|
+
## 5. Present the tradeoffs and stop
|
|
71
|
+
|
|
72
|
+
Flip through every variant yourself first. Each one renders, each interaction responds, the console is clean.
|
|
73
|
+
|
|
74
|
+
Then hand the decision over:
|
|
75
|
+
|
|
76
|
+
| Variant | Axis position | Right when | Costs |
|
|
77
|
+
| --- | --- | --- | --- |
|
|
78
|
+
| Quiet | Lowest visual weight | The page is used daily | Least memorable |
|
|
79
|
+
| Editorial | Largest type, most space | The moment deserves weight | Eats vertical space |
|
|
80
|
+
|
|
81
|
+
Say where the picker is running, which key flips it and which width you judged at. The answer can change between 375px and 1440px.
|
|
82
|
+
|
|
83
|
+
Never mark a favourite in the table. Asked directly, answer from how often the piece is seen and from the product's personality, not from which one you enjoyed building.
|
|
84
|
+
|
|
85
|
+
## 6. Promote one, delete the rest
|
|
86
|
+
|
|
87
|
+
On a choice: build that variant properly where it belongs, following the project's own conventions, then delete the others and the harness.
|
|
88
|
+
|
|
89
|
+
Asked for another round instead, keep the harness and run step 3 again, taking new positions around the direction you leaned toward.
|
|
90
|
+
|
|
91
|
+
Until promotion, the harness never imports from production and production never imports from the harness.
|
|
92
|
+
|
|
93
|
+
## Before you finish
|
|
94
|
+
|
|
95
|
+
| Mistake | Fix |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| Variants differ only in accent color or copy | Move one to a different position on the primary axis, or cut it |
|
|
98
|
+
| Every axis varies at once | Vary one; let the rest follow from it |
|
|
99
|
+
| Judged on a blank route | Host them on the page that will contain the piece |
|
|
100
|
+
| Lorem ipsum, three rows, "Jane Doe" | Real copy and the item count the page will really carry |
|
|
101
|
+
| The boldest variant skips keyboard or focus | Clear the floor or drop the direction |
|
|
102
|
+
| A favourite marked in the table | State each variant's cost and let the user choose |
|
|
103
|
+
| Picker restyled with the project's tokens | Keep it visibly outside the design system |
|
|
104
|
+
| Harness left behind after promotion | Delete it unless asked to keep it |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Wrapping and punctuation
|
|
2
|
+
|
|
3
|
+
Where lines start, where they end, where they break and which characters they use.
|
|
4
|
+
|
|
5
|
+
## Measure (line length)
|
|
6
|
+
|
|
7
|
+
Long lines make it harder for the eye to find the start of the next. For long-form text, aim for 60–75 characters per line.
|
|
8
|
+
|
|
9
|
+
Any unit works. `65ch` measures characters directly, one `ch` being the width of the `0` in the current font, and a pixel or rem cap is just as good. At a `16px` body size the 60–75 character range lands roughly between `560px` and `680px` depending on the font, so Tailwind's `max-w-xl` (`576px`) and `max-w-2xl` (`672px`) both fit. What matters is that a cap exists and the line length sits in range. Recheck it if the body font size changes.
|
|
10
|
+
|
|
11
|
+
## Alignment
|
|
12
|
+
|
|
13
|
+
`text-align` controls where each line starts and ends. `justify` stretches spaces until both edges line up, which works in specific editorial layouts and nowhere else in an interface.
|
|
14
|
+
|
|
15
|
+
## Wrapping
|
|
16
|
+
|
|
17
|
+
| Property | Use |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `text-wrap: balance` | Distributes text evenly across multiple lines |
|
|
20
|
+
| `text-wrap: pretty` | Avoids leaving a single short word on the final line |
|
|
21
|
+
| `overflow-wrap: break-word` | Lets long words, links and IDs break before escaping the container |
|
|
22
|
+
| `white-space: nowrap` | Keeps labels and badges on one line where a break looks broken |
|
|
23
|
+
|
|
24
|
+
Use `balance` on headings and `pretty` on descriptions. Skip both in long-form text, because browsers ignore `balance` past a few lines anyway, and evening out a whole paragraph wastes space and makes it harder to read.
|
|
25
|
+
|
|
26
|
+
## Truncation
|
|
27
|
+
|
|
28
|
+
- Single line: `text-overflow: ellipsis`, which needs `overflow: hidden` and `white-space: nowrap`.
|
|
29
|
+
- Multiple lines: `line-clamp` allows any number of lines before the ellipsis.
|
|
30
|
+
|
|
31
|
+
Truncation hides content. Where the missing text matters, make the full value available in a tooltip or an expanded view.
|
|
32
|
+
|
|
33
|
+
## Case
|
|
34
|
+
|
|
35
|
+
`text-transform` changes how case appears without changing the underlying text. Write copy naturally and control presentation with CSS, so a redesign never means rewriting copy.
|
|
36
|
+
|
|
37
|
+
## Smart punctuation
|
|
38
|
+
|
|
39
|
+
Keyboard characters are not always the best characters:
|
|
40
|
+
|
|
41
|
+
| Instead of | Use |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| Straight quotes `"..."` | Curly quotes that curve around the text (keep straight quotes in code) |
|
|
44
|
+
| Hyphen in ranges | En dash: `2010–2020` |
|
|
45
|
+
| Two hyphens for an aside | Em dash character |
|
|
46
|
+
| Three periods `...` | The single ellipsis character `…` |
|
|
47
|
+
| Regular space in `16 px` | ` ` so the value never breaks apart |
|
|
48
|
+
| Uncontrolled word breaks | `­` to mark where a word may break |
|
|
49
|
+
|
|
50
|
+
## Internationalization
|
|
51
|
+
|
|
52
|
+
Two refinements for mixed-direction text:
|
|
53
|
+
|
|
54
|
+
- **Long paragraphs align by their own language.** A one- or two-line snippet follows the surrounding UI's direction. A paragraph of three or more lines aligns to its own script instead, so an English paragraph stays start-aligned LTR even inside an RTL interface. `text-align: start` with the correct `lang`/`dir` on the paragraph element handles this.
|
|
55
|
+
- **Never reverse digits.** Numbers keep their order in every direction, so a phone number or "541" reads identically in RTL. Browsers handle this through the Unicode bidi algorithm. Never fight it with manual reordering, and wrap mixed number and text values in `<bdi>` where adjacent RTL text disturbs them.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: taste
|
|
3
|
+
description: One skill for the full taste spectrum. Covers anti-slop frontend design (landing pages, portfolios, redesigns, premium and minimalist UI, GSAP motion), image generation and image-to-code direction (web, mobile, brand kits), full-output enforcement, and Google Stitch design systems. Read the brief, pick the matching reference below, and follow it end to end. Do not auto-apply every reference at once.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TASTE — Unified Design Quality Skill
|
|
7
|
+
|
|
8
|
+
You are an elite frontend design engineer and art director. This skill bundles every taste discipline into one entry point. Each reference below is a complete playbook for one domain.
|
|
9
|
+
|
|
10
|
+
## How to use
|
|
11
|
+
|
|
12
|
+
1. **Read the brief first.** Do not fire all references at once.
|
|
13
|
+
2. **Route to the matching reference** using the table below.
|
|
14
|
+
3. **Follow that reference end to end** — its directives override generic defaults.
|
|
15
|
+
4. When a task spans domains (e.g. redesign an existing site that also needs new imagery), apply the relevant references in sequence and reconcile conflicting rules by task priority.
|
|
16
|
+
|
|
17
|
+
## Reference library
|
|
18
|
+
|
|
19
|
+
| When the task is… | Use |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Anti-slop frontend for landing pages, portfolios, redesigns (current default) | [design-taste-frontend.md](references/design-taste-frontend.md) |
|
|
22
|
+
| Exact backward-compatible v1 taste behavior (original baseline) | [design-taste-frontend-v1.md](references/design-taste-frontend-v1.md) |
|
|
23
|
+
| Awwwards-level design engineering with GSAP motion, randomization, bento grids | [gpt-taste.md](references/gpt-taste.md) |
|
|
24
|
+
| High-end agency visual design — fonts, spacing, shadows, motion choreography | [high-end-visual-design.md](references/high-end-visual-design.md) |
|
|
25
|
+
| Premium utilitarian minimalism — warm monochrome, editorial type, flat bento | [minimalist-ui.md](references/minimalist-ui.md) |
|
|
26
|
+
| Industrial brutalism / tactical telemetry UI — Swiss print, CRT terminals | [industrial-brutalist-ui.md](references/industrial-brutalist-ui.md) |
|
|
27
|
+
| Upgrading an existing project to premium quality (audit-first, no rewrites) | [redesign-existing-projects.md](references/redesign-existing-projects.md) |
|
|
28
|
+
| Completeness of output — no truncation, no placeholders, no skipped sections | [full-output-enforcement.md](references/full-output-enforcement.md) |
|
|
29
|
+
| Generating website section reference images, then implementing them | [image-to-code.md](references/image-to-code.md) |
|
|
30
|
+
| Generating website design-reference images (one image per section) | [imagegen-frontend-web.md](references/imagegen-frontend-web.md) |
|
|
31
|
+
| Generating mobile app screen concepts and flows (images only) | [imagegen-frontend-mobile.md](references/imagegen-frontend-mobile.md) |
|
|
32
|
+
| Generating premium brand-kit / identity-system boards (images only) | [brandkit.md](references/brandkit.md) |
|
|
33
|
+
| Generating a semantic DESIGN.md for Google Stitch | [stitch-design-taste.md](references/stitch-design-taste.md) |
|
|
34
|
+
| Reference DESIGN.md output produced by the Stitch skill | [stitch-design-taste-design.md](references/stitch-design-taste-design.md) |
|
|
35
|
+
|
|
36
|
+
## Cross-cutting rules
|
|
37
|
+
|
|
38
|
+
Every reference shares these baseline principles; specific rules in a reference override these:
|
|
39
|
+
|
|
40
|
+
- Never output the same layout or aesthetic twice in a row.
|
|
41
|
+
- Reject the LLM defaults: Inter, Lucide/Feather icons, purple-blue AI gradients, three equal feature cards, centered hero over dark mesh, generic glassmorphism, `h-screen` (use `min-h-[100dvh]`).
|
|
42
|
+
- Animate only `transform` and `opacity`. No layout-triggering properties.
|
|
43
|
+
- No emojis in code, markup, text content, or alt text.
|
|
44
|
+
- No pure black (`#000000`) — use off-black, charcoal, or zinc-950.
|
|
45
|
+
- Prefer distinctive type (Geist, Outfit, Cabinet Grotesk, Satoshi, Fraunces, Instrument Serif) over generic fonts.
|
|
46
|
+
- Verify dependency availability before importing third-party libraries.
|
|
47
|
+
- Generate the `<design_plan>` / design-read step before writing any code where the reference requires it.
|