baldart 5.0.1 → 5.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/CHANGELOG.md +157 -0
- package/README.md +6 -6
- package/VERSION +1 -1
- package/framework/.claude/agents/CHANGELOG.md +90 -0
- package/framework/.claude/agents/REGISTRY.md +5 -5
- package/framework/.claude/agents/coder.md +3 -3
- package/framework/.claude/agents/remotion-animator-orchestrator.md +4 -3
- package/framework/.claude/agents/senior-researcher.md +166 -151
- package/framework/.claude/agents/ui-expert.md +4 -10
- package/framework/.claude/agents/ui-quality-critic.md +27 -11
- package/framework/.claude/skills/design-system-init/CHANGELOG.md +5 -0
- package/framework/.claude/skills/design-system-init/SKILL.md +2 -2
- package/framework/.claude/skills/e2e-review/CHANGELOG.md +5 -0
- package/framework/.claude/skills/e2e-review/SKILL.md +2 -2
- package/framework/.claude/skills/frontend-design/CHANGELOG.md +20 -0
- package/framework/.claude/skills/frontend-design/SKILL.md +39 -216
- package/framework/.claude/skills/gamification-design/CHANGELOG.md +5 -0
- package/framework/.claude/skills/gamification-design/SKILL.md +2 -2
- package/framework/.claude/skills/prd/CHANGELOG.md +16 -0
- package/framework/.claude/skills/prd/SKILL.md +1 -1
- package/framework/.claude/skills/prd/references/discovery-phase.md +5 -1
- package/framework/.claude/skills/prd/references/research-phase.md +32 -12
- package/framework/.claude/skills/research/CHANGELOG.md +9 -0
- package/framework/.claude/skills/research/SKILL.md +94 -0
- package/framework/.claude/skills/research/assets/report-compare.template.md +50 -0
- package/framework/.claude/skills/research/assets/report-decision.template.md +42 -0
- package/framework/.claude/skills/research/assets/report-deep.template.md +61 -0
- package/framework/.claude/skills/research/assets/report-regulatory.template.md +44 -0
- package/framework/.claude/skills/research/references/playbook.md +112 -0
- package/framework/.claude/skills/research/scripts/rebuild-research-index.mjs +77 -0
- package/framework/.claude/skills/ui-design/CHANGELOG.md +60 -1
- package/framework/.claude/skills/ui-design/SKILL.md +127 -75
- package/framework/.claude/skills/ui-design/references/anti-slop.md +106 -0
- package/framework/.claude/skills/ui-design/references/craft-standards.md +259 -0
- package/framework/.claude/skills/ui-design/references/design-brief.md +92 -0
- package/framework/.claude/skills/ui-design/references/design-directions.md +188 -0
- package/framework/.claude/skills/ui-design/references/evaluation.md +125 -165
- package/framework/.claude/skills/ui-design/references/generation.md +125 -92
- package/framework/.claude/skills/ui-design/references/inventory.md +9 -2
- package/framework/.claude/skills/ui-design/scripts/craft-check.mjs +248 -0
- package/framework/agents/component-manifest-schema.md +1 -1
- package/framework/agents/design-system-protocol.md +6 -6
- package/framework/agents/index.md +3 -0
- package/framework/agents/research-protocol.md +228 -0
- package/framework/agents/skills-mapping.md +42 -23
- package/framework/docs/PROJECT-CONFIGURATION.md +28 -5
- package/framework/templates/baldart.config.template.yml +6 -0
- package/framework/templates/research-index.template.md +13 -0
- package/framework/templates/research-sources.CHANGELOG.md +14 -0
- package/framework/templates/research-sources.template.md +31 -0
- package/package.json +1 -1
- package/src/commands/configure.js +27 -1
- package/src/commands/doctor.js +82 -0
- package/src/commands/update.js +48 -1
- package/src/utils/__tests__/classify-divergence.test.js +42 -0
- package/src/utils/git.js +45 -9
- package/src/utils/research-library.js +92 -0
- package/src/utils/symlinks.js +3 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# Craft Standards — always-on rules for every generated surface
|
|
2
|
+
|
|
3
|
+
These are the non-negotiable craft rules the generator applies while producing
|
|
4
|
+
mockups (Step C) and the evaluator verifies (Step D). They are **binding on
|
|
5
|
+
every option**, in every direction, in both registers — aesthetic direction
|
|
6
|
+
changes *what* you design, never *how well*.
|
|
7
|
+
|
|
8
|
+
> **Numeric SSOT rule.** Type-scale ratios, contrast targets (WCAG + APCA),
|
|
9
|
+
> spacing scales, and density tiers live in
|
|
10
|
+
> [`framework/agents/design-system-protocol.md`](../../../../agents/design-system-protocol.md)
|
|
11
|
+
> § "Reference Tables" — cite those values verbatim, never restate from memory.
|
|
12
|
+
> This file adds the craft rules *not* covered there.
|
|
13
|
+
>
|
|
14
|
+
> Distilled in part from [impeccable](https://github.com/pbakaus/impeccable)
|
|
15
|
+
> (Apache-2.0, © Paul Bakaus),
|
|
16
|
+
> [taste-skill](https://github.com/Leonxlnx/taste-skill) (MIT, © Leonxlnx) and
|
|
17
|
+
> [open-design](https://github.com/nexu-io/open-design) (Apache-2.0, nexu-io).
|
|
18
|
+
>
|
|
19
|
+
> **Precedence.** The project's own contract wins on conflict: design-system
|
|
20
|
+
> tokens (`tokens-reference.md`) > `${paths.ui_guidelines}` + the skill overlay
|
|
21
|
+
> > these craft standards. Craft rules cover everything the project does not
|
|
22
|
+
> explicitly override.
|
|
23
|
+
|
|
24
|
+
## Typography
|
|
25
|
+
|
|
26
|
+
- **One scale.** Pick ONE ratio from the protocol § Type scale and derive every
|
|
27
|
+
size from it — 6–9 deliberate steps max. Extra hierarchy comes from weight,
|
|
28
|
+
color, and spacing, not new sizes.
|
|
29
|
+
- **Line length**: body text 65–75ch (`max-w-[65ch]` or equivalent). Apply
|
|
30
|
+
`text-wrap: balance` on h1–h3, `text-wrap: pretty` on prose.
|
|
31
|
+
- **Display ceiling**: hero/display headings cap at `clamp()` max ≤ 6rem
|
|
32
|
+
(~96px). Above that the page is shouting, not designing. Keep any `clamp()`
|
|
33
|
+
bounded: max ≤ ~2.5× min.
|
|
34
|
+
- **Headline discipline**: H1 max 2 lines at desktop. A 4-line hero headline is
|
|
35
|
+
a font-size error, never a copy-length error — plan scale and copy together.
|
|
36
|
+
- **Tracking — the single most-skipped rule in AI-generated design.** Body
|
|
37
|
+
(14–18px) `0` · small text (11–13px) `+0.01–0.02em` · UI labels `+0.02em` ·
|
|
38
|
+
**ALL-CAPS `+0.06–0.1em` (required — the 0.06em floor is the empirical
|
|
39
|
+
typographic lower bound)** · headings 32px+ `−0.01–0.02em` · display 48px+
|
|
40
|
+
`−0.02–0.03em`, never below `−0.04em`. ALL-CAPS without positive tracking
|
|
41
|
+
looks cramped; display without negative tracking looks loose — the two most
|
|
42
|
+
reliable slop tells. ALL-CAPS body text is banned; never `text-align:
|
|
43
|
+
justify`.
|
|
44
|
+
- **Three-weight system**: Read (400/450) · Emphasize (510/550) · Announce
|
|
45
|
+
(590/600). Weight 700+ is rarely needed — reach for size/color/space first.
|
|
46
|
+
- **Pairing**: pair on a contrast axis (serif + sans, geometric + humanist,
|
|
47
|
+
display + mono) or use one family in multiple weights. Never pair fonts that
|
|
48
|
+
are similar-but-not-identical.
|
|
49
|
+
- **Emphasis**: italic or bold of the SAME family. Never inject a serif word
|
|
50
|
+
into a sans headline for "flair" — mixed-family emphasis reads amateur.
|
|
51
|
+
- **Italic descender clearance**: italic display words containing `y g j p q`
|
|
52
|
+
need `leading-[1.1]` minimum plus bottom padding — `leading-none` clips them.
|
|
53
|
+
- **Light-on-dark compensation**: on dark surfaces bump line-height by
|
|
54
|
+
0.05–0.1, add 0.01–0.02em letter-spacing, and optionally drop body weight one
|
|
55
|
+
notch (400 → 350). Light text visually thickens.
|
|
56
|
+
|
|
57
|
+
## Color
|
|
58
|
+
|
|
59
|
+
- **Contrast is zero-tolerance.** Every text/background pair meets the
|
|
60
|
+
protocol § Color contrast targets (body ≥ 4.5:1, large ≥ 3:1, UI ≥ 3:1 —
|
|
61
|
+
APCA as secondary gate). Placeholder text counts as content. Every `bg-*`
|
|
62
|
+
utility has an explicit paired `text-*`. Light-gray-for-elegance is the
|
|
63
|
+
single biggest reason AI designs read as hard to use.
|
|
64
|
+
- **Gray-on-color is banned.** Gray text over a colored background looks
|
|
65
|
+
washed out — use a darker shade of the background's own hue, or a
|
|
66
|
+
transparency of the text color.
|
|
67
|
+
- **Color proportions**: neutrals carry 70–90% of pixels · ONE accent at
|
|
68
|
+
5–10% · semantic colors 0–5% · pure-effect color < 1%. Never invent a second
|
|
69
|
+
accent. **Ration the accent to ≤ 2 visible uses per screen** (typical pair:
|
|
70
|
+
one chip/eyebrow + the primary CTA — links, hover states and focus rings
|
|
71
|
+
count). A fuller commitment is a deliberate direction choice (see
|
|
72
|
+
`design-brief.md` § Color commitment), never a drift. Once chosen, the
|
|
73
|
+
accent is consistent page-wide — a warm-grey page does not sprout a blue CTA
|
|
74
|
+
in section 7.
|
|
75
|
+
- **Tinted neutrals.** Pure gray is dead: tint neutrals 0.005–0.015 chroma
|
|
76
|
+
toward the brand hue (OKLCH). Prefer OKLCH for any new palette work.
|
|
77
|
+
- **Dark surfaces**: never pure `#000000` / `#ffffff` — off-black and
|
|
78
|
+
off-white keep depth. Dark mode is not inversion: build a 3-step surface
|
|
79
|
+
scale (≈15% / 20% / 25% lightness) and let depth come from surface
|
|
80
|
+
lightness, not shadow.
|
|
81
|
+
- **Alpha is a design smell.** Heavy use of transparency usually means an
|
|
82
|
+
incomplete palette — name the actual surface colors.
|
|
83
|
+
|
|
84
|
+
## Spacing, layout & hierarchy
|
|
85
|
+
|
|
86
|
+
- **One spacing scale** from the protocol § Spacing scale (base-4 preferred
|
|
87
|
+
for product UI). Arbitrary off-scale values (`p-[13px]`) are token
|
|
88
|
+
violations.
|
|
89
|
+
- **Rhythm**: 8–12px between tight siblings, 48–96px between sections.
|
|
90
|
+
Consistent gaps between similar elements — monotonous identical spacing
|
|
91
|
+
everywhere is its own tell.
|
|
92
|
+
- **Hierarchy math**: a strong size jump is ≥ 3:1; below 2:1 the hierarchy is
|
|
93
|
+
weak. The best hierarchy combines 2–3 dimensions at once (size + weight +
|
|
94
|
+
color/space), never size alone.
|
|
95
|
+
- **Layout mechanics**: Flexbox for 1D, Grid for 2D. Breakpoint-free grids via
|
|
96
|
+
`repeat(auto-fit, minmax(280px, 1fr))` where content allows. Semantic
|
|
97
|
+
z-index scale (dropdown → sticky → modal-backdrop → modal → toast →
|
|
98
|
+
tooltip), never `z-[999]`.
|
|
99
|
+
- **Cards are the lazy answer.** Use a card only when a bounded, repeatable
|
|
100
|
+
unit is truly the best affordance. Nested cards are always wrong.
|
|
101
|
+
- **Layout-family diversity**: a section layout family appears max twice per
|
|
102
|
+
page and never 3× consecutively (image+text zigzag caps at 2 in a row). A
|
|
103
|
+
landing page with 8 sections needs ≥ 4 distinct layout families.
|
|
104
|
+
- **Bento cell count = content count.** A grid with an empty filler tile was
|
|
105
|
+
planned wrong — reshape the grid instead of pasting a blank cell. Give 2–3
|
|
106
|
+
cells real visual variation (image / gradient / pattern), not uniform
|
|
107
|
+
white-on-white.
|
|
108
|
+
- **Viewport discipline**: `min-h-[100dvh]` never `h-screen` (iOS Safari).
|
|
109
|
+
Text never overflows or clips — the viewport is part of the design.
|
|
110
|
+
Dropdowns inside `overflow: hidden` containers get clipped: use
|
|
111
|
+
`<dialog>`, the popover API, `position: fixed`, or a portal.
|
|
112
|
+
- **Touch targets**: honor the protocol § Density tiers (touch-primary ⇒
|
|
113
|
+
Comfortable tier, 44px). When a control must render smaller, expand the hit
|
|
114
|
+
area with a pseudo-element.
|
|
115
|
+
|
|
116
|
+
## States — the 8-state taxonomy
|
|
117
|
+
|
|
118
|
+
Every interactive component ships **default · hover · focus · active ·
|
|
119
|
+
disabled · loading · error** — plus the surface-level **empty** state. Never
|
|
120
|
+
design only the happy path:
|
|
121
|
+
|
|
122
|
+
- Loading = skeletons that mirror real layout dimensions exactly (a
|
|
123
|
+
wrong-height skeleton *causes* layout shift), not spinners. Thresholds:
|
|
124
|
+
0–300ms no indicator at all · past ~15s show a "taking longer than
|
|
125
|
+
expected" fallback.
|
|
126
|
+
- Empty states teach the interface (what goes here + the CTA that fills it).
|
|
127
|
+
- Error states answer three questions: what happened · why (if knowable) ·
|
|
128
|
+
what the user can do — localized (`identity.language`), with the user's
|
|
129
|
+
input preserved. Never a bare "Invalid input".
|
|
130
|
+
- Focus is visible and styled (≥ 3:1 contrast on the indicator), not the
|
|
131
|
+
browser default leaking through a restyled component.
|
|
132
|
+
- Edge state: extreme volume, 200-char titles, RTL, partial network — a
|
|
133
|
+
populated-only mockup hides the layout's real failure modes.
|
|
134
|
+
|
|
135
|
+
## Cognitive load (Laws of UX, operational numbers)
|
|
136
|
+
|
|
137
|
+
- **Proximity**: variable vertical rhythm — 8–12px within a group, 32–48px
|
|
138
|
+
between groups. Uniform spacing reads as nothing being grouped.
|
|
139
|
+
- **Hick's Law**: cap any single decision screen at 3–5 visible primary
|
|
140
|
+
options.
|
|
141
|
+
- **Choice overload**: pricing 3–4 tiers with exactly one marked recommended ·
|
|
142
|
+
product grids 6–9 hero cards above the fold · settings ≤ 5 named groups ·
|
|
143
|
+
nav ≤ 5 top-level items.
|
|
144
|
+
- **Tesler's Law**: complexity is conserved — the design decision is *where*
|
|
145
|
+
it lives (defaults, progressive disclosure), not whether to eliminate it.
|
|
146
|
+
- Working memory holds ~4 chunks: never ask the user to carry more across a
|
|
147
|
+
flow.
|
|
148
|
+
|
|
149
|
+
## Motion
|
|
150
|
+
|
|
151
|
+
- **The 100/300/500 rule**: 100–150ms instant feedback (hover, press) ·
|
|
152
|
+
200–300ms state changes · 300–500ms layout moves · 500–800ms entrances
|
|
153
|
+
(brand surfaces only). Exits run ~75% of the paired entrance. Below ~80ms
|
|
154
|
+
motion isn't perceived — don't spend it. Mobile runs 20–30% shorter than
|
|
155
|
+
desktop.
|
|
156
|
+
- **Curve vs spring**: a curve for opacity/color, a spring for
|
|
157
|
+
position/scale/rotation. Animate only when the user moves through space,
|
|
158
|
+
time, or state (navigation, container expansion, progress, gesture
|
|
159
|
+
follow-through) — never to teach, decorate, or signal "premium".
|
|
160
|
+
- **Easing**: ease-out with exponential curves (quart/quint/expo family). No
|
|
161
|
+
bounce, no elastic, no `linear`/`ease-in-out` defaults — pick a deliberate
|
|
162
|
+
cubic-bezier.
|
|
163
|
+
- **Motion must be motivated.** Valid reasons: hierarchy, storytelling,
|
|
164
|
+
feedback, state transition. "It looked cool" is not one — if you cannot
|
|
165
|
+
state the reason in one sentence, drop the animation.
|
|
166
|
+
- **The uniform reflex is the tell, not motion itself.** One identical
|
|
167
|
+
entrance applied to every section reads as AI grammar; but shipping a page
|
|
168
|
+
with zero motion to avoid it is also wrong. One well-orchestrated entrance
|
|
169
|
+
with staggered reveals beats scattered micro-interactions.
|
|
170
|
+
- **Reveal animations enhance already-visible content.** Never gate content
|
|
171
|
+
visibility on a class-triggered transition: transitions pause in hidden tabs
|
|
172
|
+
and headless renderers, and the section ships blank.
|
|
173
|
+
- **Register budgets**: product surfaces 150–250ms, no orchestrated page-load
|
|
174
|
+
sequences; brand surfaces may spend one entrance sequence. Marquee ≤ 1 per
|
|
175
|
+
page.
|
|
176
|
+
- **Mechanics**: animate `transform`/`opacity` only. Never
|
|
177
|
+
`window.addEventListener("scroll")` and never continuous input values
|
|
178
|
+
(mouse, scroll progress) in framework state — use the animation library's
|
|
179
|
+
motion values. `prefers-reduced-motion` support is not optional.
|
|
180
|
+
|
|
181
|
+
## Forms (always-on, every project)
|
|
182
|
+
|
|
183
|
+
- `<label>` associated via `htmlFor`/`id` (never wrap-only).
|
|
184
|
+
- `autocomplete=` on every personal-data field (`email | tel | given-name |
|
|
185
|
+
family-name | street-address | postal-code | cc-number | one-time-code` …).
|
|
186
|
+
- Validate **on blur**, re-validate on submit — never on every keystroke.
|
|
187
|
+
- Errors actionable ("Email manca @ — esempio: nome@dominio.it"), with
|
|
188
|
+
`aria-invalid` + `aria-describedby`; `role="alert"` only when the error
|
|
189
|
+
appears dynamically.
|
|
190
|
+
- `inputMode=` when it differs from `type` (SMS codes: `type="text"
|
|
191
|
+
inputMode="numeric"`).
|
|
192
|
+
- Paste handling normalizes whitespace/format BEFORE validating.
|
|
193
|
+
- Submit disabled only **after** a failed attempt, never pre-emptively.
|
|
194
|
+
|
|
195
|
+
## Performance Gates (Core Web Vitals 2026) — canonical home
|
|
196
|
+
|
|
197
|
+
Production-grade frontend ships within CWV budgets by design, not after
|
|
198
|
+
Lighthouse complains. (This section moved here from the retired
|
|
199
|
+
`frontend-design` generator — this is now the canonical reference, cited by
|
|
200
|
+
`ui-expert`.)
|
|
201
|
+
|
|
202
|
+
| Metric | Good | Poor | What it measures |
|
|
203
|
+
|---|---|---|---|
|
|
204
|
+
| **LCP** | ≤ 2.5s | > 4.0s | Largest Contentful Paint — usually hero image or H1 |
|
|
205
|
+
| **INP** | ≤ 200ms | > 500ms | Interaction to Next Paint |
|
|
206
|
+
| **CLS** | ≤ 0.1 | > 0.25 | Cumulative Layout Shift |
|
|
207
|
+
| TTFB | ≤ 0.8s | > 1.8s | Subset of LCP (~40% of budget) |
|
|
208
|
+
| FCP | ≤ 1.8s | > 3.0s | Diagnostic only |
|
|
209
|
+
|
|
210
|
+
**LCP image — the only correct pattern:**
|
|
211
|
+
|
|
212
|
+
```html
|
|
213
|
+
<!-- in <head> — preload + fetchpriority for the hero -->
|
|
214
|
+
<link rel="preload" as="image"
|
|
215
|
+
href="/hero.avif"
|
|
216
|
+
imagesrcset="/hero-800.avif 800w, /hero-1600.avif 1600w"
|
|
217
|
+
imagesizes="100vw"
|
|
218
|
+
fetchpriority="high">
|
|
219
|
+
|
|
220
|
+
<!-- in body — picture with AVIF/WebP/fallback + explicit dimensions -->
|
|
221
|
+
<picture>
|
|
222
|
+
<source srcset="/hero.avif" type="image/avif">
|
|
223
|
+
<source srcset="/hero.webp" type="image/webp">
|
|
224
|
+
<img src="/hero.jpg" alt="..."
|
|
225
|
+
fetchpriority="high"
|
|
226
|
+
width="1600" height="900">
|
|
227
|
+
</picture>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Never** `loading="lazy"` on the LCP image; **never** client-render it
|
|
231
|
+
post-hydration.
|
|
232
|
+
|
|
233
|
+
**INP**: break tasks > 50ms with `await scheduler.yield()` (fallback
|
|
234
|
+
`setTimeout 0`) · debounce input handlers to one frame when they trigger
|
|
235
|
+
expensive recomputes · move CPU-bound work to Web Workers · no `setInterval`
|
|
236
|
+
polling (use stale-while-revalidate).
|
|
237
|
+
|
|
238
|
+
**CLS — zero unexpected shift**: every `<img>`/`<iframe>`/`<video>` declares
|
|
239
|
+
`width`+`height` or `aspect-ratio` · web fonts use `font-display: optional` OR
|
|
240
|
+
`size-adjust` + metric overrides · skeletons mirror real dimensions · inserted
|
|
241
|
+
UI (banners, notices) reserves space upfront via `min-height`.
|
|
242
|
+
|
|
243
|
+
## Modern CSS (2025–2026)
|
|
244
|
+
|
|
245
|
+
Default to platform features instead of JS shims:
|
|
246
|
+
|
|
247
|
+
- **Container queries** (`@container` + `container-type: inline-size`) for any
|
|
248
|
+
component living in variable-width contexts; viewport `@media` only for
|
|
249
|
+
app-shell layout.
|
|
250
|
+
- **`:has()`** to collapse state that exists only for styling — visual
|
|
251
|
+
reactions to DOM state, never business logic.
|
|
252
|
+
- **View Transitions API** for SPA navigation and shared-element morphs (full
|
|
253
|
+
pattern: `motion-design` skill references).
|
|
254
|
+
- **Subgrid** for cross-row content alignment inside cards.
|
|
255
|
+
- **Logical properties** (`margin-inline-start`, `padding-block`) whenever RTL
|
|
256
|
+
or vertical writing modes are conceivable — free i18n.
|
|
257
|
+
- **`color-mix()`** to derive hover/focus/disabled from semantic tokens
|
|
258
|
+
(`color-mix(in oklch, var(--color-action-primary) 90%, black)`).
|
|
259
|
+
- **`@scope`** to scope styles to a subtree without specificity wars.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Design Brief — Step C.0: Design Read & Direction Lock
|
|
2
|
+
|
|
3
|
+
Most AI-generated UIs fail not because of bad code, but because of skipped
|
|
4
|
+
thinking. This step converts the inputs (discovery answers, user brief,
|
|
5
|
+
context screenshots, `identity.*`) into a locked design intent BEFORE any
|
|
6
|
+
HTML is generated. It costs one short block of reasoning and prevents the
|
|
7
|
+
dominant failure mode: generating three layouts of the same unexamined
|
|
8
|
+
default.
|
|
9
|
+
|
|
10
|
+
> Distilled from [impeccable](https://github.com/pbakaus/impeccable)
|
|
11
|
+
> (Apache-2.0, © Paul Bakaus) and
|
|
12
|
+
> [taste-skill](https://github.com/Leonxlnx/taste-skill) (MIT, © Leonxlnx).
|
|
13
|
+
|
|
14
|
+
## 1. Classify the register
|
|
15
|
+
|
|
16
|
+
| Register | Definition | Consequences |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| **Brand** | Design IS the product's voice: landing, marketing, hero surfaces, campaign pages | Bolder type ratio (protocol § Type scale, ≥ 1.25) · one orchestrated entrance allowed · color commitment may exceed Restrained · restraint without intent reads as mediocre — go big or go home |
|
|
19
|
+
| **Product** | Design SERVES the task: app screens, dashboards, forms, settings | Fixed rem scale, ratio 1.125–1.2 · Restrained color (accent = actions/selection/state only, never decoration) · motion 150–250ms, no page-load sequences · **the slop test flips: the bar is *earned familiarity*, not distinctiveness** — the tool should disappear into the task; strangeness without purpose is the failure mode |
|
|
20
|
+
|
|
21
|
+
Mixed features (a landing + an app screen) classify per-screen.
|
|
22
|
+
|
|
23
|
+
## 2. Determine the regime
|
|
24
|
+
|
|
25
|
+
| Regime | When | What varies across the 3 options |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| **In-context** | `features.has_design_system: true`, OR the feature lands inside an existing app shell (context screenshots exist) | Layout, hierarchy, information architecture, interaction pattern, density — the project's visual language (tokens, type, palette) is FIXED. Context fidelity is king |
|
|
28
|
+
| **Exploration** | Greenfield surface, new product, standalone page with no binding language | Aesthetic direction — each option takes a DIFFERENT named direction from `design-directions.md`, each with its own typography/palette/composition |
|
|
29
|
+
|
|
30
|
+
Never explore aesthetics on an in-context run: proposing a new visual
|
|
31
|
+
language for one screen of an existing product is drift, not creativity.
|
|
32
|
+
|
|
33
|
+
## 3. Set the three dials
|
|
34
|
+
|
|
35
|
+
`DESIGN_VARIANCE` (how far from convention) · `MOTION_INTENSITY` ·
|
|
36
|
+
`VISUAL_DENSITY` — each 1–10. Canonical names; never invent aliases.
|
|
37
|
+
|
|
38
|
+
| Signal | VARIANCE | MOTION | DENSITY |
|
|
39
|
+
|---|---|---|---|
|
|
40
|
+
| Brand register, launch/campaign | 7–9 | 6–8 | 3–4 |
|
|
41
|
+
| Brand register, trust-first / public-sector / regulated | 3–4 | 2–3 | 4–5 |
|
|
42
|
+
| Product register (default) | 3–5 | 2–4 | 5–7 |
|
|
43
|
+
| Product register, data-heavy power tool | 2–4 | 1–3 | 7–9 |
|
|
44
|
+
| Explicit "make it bold/memorable" from the user | +2 | +1 | — |
|
|
45
|
+
|
|
46
|
+
Quiet constraints override every dial: accessibility-first briefs, kids
|
|
47
|
+
audiences, public sector → drop VARIANCE and MOTION to the low band and say
|
|
48
|
+
so in the Design Read. Dials gate downstream rules ("motion claimed, motion
|
|
49
|
+
shown": if MOTION > 4 the page must actually move — otherwise lower the dial
|
|
50
|
+
and ship clean static).
|
|
51
|
+
|
|
52
|
+
## 4. Emit the Design Read (mandatory, one line + assignments)
|
|
53
|
+
|
|
54
|
+
Before generating, output — to the user in interactive mode, to the state
|
|
55
|
+
file always:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Design Read: <page kind> for <audience>, <register> register, <regime>
|
|
59
|
+
regime, dials V<x>/M<y>/D<z>, leaning <design system | direction family>.
|
|
60
|
+
Options: A = <direction/layout hypothesis> · B = … · C = …
|
|
61
|
+
Color commitment: <Restrained | Committed | Full | Drenched> (reference: <named real-world anchor>)
|
|
62
|
+
Dark/light: <choice> — <the one-sentence physical scene that forces it>
|
|
63
|
+
Anti-references: <what this must NOT look like — e.g. "not SaaS-cream, not dark-glow">
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Rules:
|
|
67
|
+
|
|
68
|
+
- **Ambiguity → exactly ONE question.** If the read is genuinely ambiguous
|
|
69
|
+
("Linear-clean or Awwwards-experimental?"), ask one crisp question with the
|
|
70
|
+
two poles — never a battery of questions, and never guess silently.
|
|
71
|
+
Assert-then-confirm beats menu-with-escape: "This reads as Restrained
|
|
72
|
+
product UI — confirm?" When invoked from `/prd`, the discovery answers
|
|
73
|
+
usually make the read unambiguous: do NOT re-ask what discovery already
|
|
74
|
+
answered. (Decision-gate mechanics per runtime:
|
|
75
|
+
`framework/agents/runtime-portability-protocol.md`.)
|
|
76
|
+
- **Run the two-altitude slop test** on your own read (`anti-slop.md`): if
|
|
77
|
+
the direction you "naturally" landed on is the first- or second-order
|
|
78
|
+
reflex for this category, reject it and pick deliberately.
|
|
79
|
+
- **Rotation check**: read the state file / previous designs in
|
|
80
|
+
`${paths.prd_dir}` for the last exploration run's direction and display
|
|
81
|
+
font — do not repeat them (`design-directions.md` § Rotation rule).
|
|
82
|
+
- **Anti-references are part of the brief.** Ask for them in discovery if
|
|
83
|
+
absent; they are the cheapest signal the user can give.
|
|
84
|
+
|
|
85
|
+
## 5. What C.0 hands to generation (C.1)
|
|
86
|
+
|
|
87
|
+
- The Design Read block (above), persisted in the state file under
|
|
88
|
+
`## UI Design` → `design_read`.
|
|
89
|
+
- Per-option: direction name (exploration) or layout/IA hypothesis
|
|
90
|
+
(in-context), color commitment, register, dials.
|
|
91
|
+
- The reflex-reject outcomes: which defaults were considered and refused
|
|
92
|
+
(one line — this keeps the generator honest and the evaluator informed).
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Design Directions — the aesthetic vocabulary for exploration
|
|
2
|
+
|
|
3
|
+
The curated menu of named aesthetic directions, font pools, and palette
|
|
4
|
+
strategies used at **Step C.0 (Direction Lock)** when the run is in
|
|
5
|
+
**exploration regime** (no binding design system / new surface — see
|
|
6
|
+
`design-brief.md` § Regime). In **in-context regime** this file is consulted
|
|
7
|
+
only for craft vocabulary — the project's own visual language always wins.
|
|
8
|
+
|
|
9
|
+
> Distilled from [taste-skill](https://github.com/Leonxlnx/taste-skill) (MIT,
|
|
10
|
+
> © Leonxlnx), [impeccable](https://github.com/pbakaus/impeccable)
|
|
11
|
+
> (Apache-2.0, © Paul Bakaus) and
|
|
12
|
+
> [open-design](https://github.com/nexu-io/open-design) (Apache-2.0, nexu-io).
|
|
13
|
+
|
|
14
|
+
## How to use this menu
|
|
15
|
+
|
|
16
|
+
1. Classify register + read the brief (`design-brief.md`), THEN pick.
|
|
17
|
+
2. In exploration regime, each of the 3 options takes a **different**
|
|
18
|
+
direction from this menu (or a deliberate hybrid, named in the rationale).
|
|
19
|
+
3. **One system per project**: if the brief reads as a real design system
|
|
20
|
+
(Material, Fluent, Carbon, Polaris, Primer, GOV.UK/USWDS, Radix, shadcn),
|
|
21
|
+
honor that language — never recreate its CSS from imagination and never mix
|
|
22
|
+
two systems.
|
|
23
|
+
4. **Rotation rule**: never reuse the same direction or the same display font
|
|
24
|
+
family across consecutive exploration runs in the same project — check the
|
|
25
|
+
state file for the previous run's direction.
|
|
26
|
+
5. **Identity preservation wins**: reflex-reject lists below apply to
|
|
27
|
+
*greenfield defaults*, never to an existing brand's established choices.
|
|
28
|
+
|
|
29
|
+
## The direction menu
|
|
30
|
+
|
|
31
|
+
Each direction: when it fits · typography · palette · composition · motion ·
|
|
32
|
+
what kills it.
|
|
33
|
+
|
|
34
|
+
### 1. Editorial Luxury
|
|
35
|
+
Warm paper canvas (`#FDFBF7` family — a *deliberate* opt-in, see the beige
|
|
36
|
+
ban below), muted sage/espresso accents, one refined display serif from the
|
|
37
|
+
rotation pool + humanist sans body, generous whitespace, film-grain noise at
|
|
38
|
+
`opacity-[0.03]`. Fits: premium consumer, craft brands, magazines. Motion:
|
|
39
|
+
slow reveals (400–500ms), no bounce. Killed by: brass/clay/oxblood accents
|
|
40
|
+
(the banned battery), Fraunces/Instrument Serif, more than one decoration
|
|
41
|
+
layer.
|
|
42
|
+
|
|
43
|
+
### 2. Ethereal Glass (OLED)
|
|
44
|
+
Near-black canvas (`#050505`), radial gradient mesh far behind content,
|
|
45
|
+
vantablack cards with `backdrop-blur-2xl` and `white/10` hairlines,
|
|
46
|
+
white-on-black type. Fits: dev-tools, AI products *when deliberately chosen*,
|
|
47
|
+
premium hardware. Motion: slow parallax, glow-on-hover. Killed by: purple/blue
|
|
48
|
+
"trust" gradients, colored box-shadow glows, gradient text.
|
|
49
|
+
|
|
50
|
+
### 3. Soft Structuralism
|
|
51
|
+
Silver-grey/white surfaces, bold grotesk display, diffused ambient shadows,
|
|
52
|
+
concentric radii ("double-bezel": outer shell `ring-1 ring-black/5 p-1.5
|
|
53
|
+
rounded-[2rem]`, inner core `rounded-[calc(2rem-0.375rem)]`). Fits: modern
|
|
54
|
+
SaaS brand surfaces that must feel engineered. Motion: custom cubic-bezier
|
|
55
|
+
(`cubic-bezier(0.32, 0.72, 0, 1)`), never linear/ease-in-out. Killed by:
|
|
56
|
+
default shadows, mixed radius systems.
|
|
57
|
+
|
|
58
|
+
### 4. Warm Minimal (Notion/Linear editorial)
|
|
59
|
+
Warm monochrome: canvas `#FFFFFF`/`#F7F6F3`, borders `#EAEAEA`, ink
|
|
60
|
+
`#111111`, secondary `#787774`; spot pastels only as paired text/bg chips
|
|
61
|
+
(Pale Red `#FDEBEC`/`#9F2F2D`, Pale Blue `#E1F3FE`/`#1F6C9F`, Pale Green
|
|
62
|
+
`#EDF3EC`/`#346538`, Pale Yellow `#FBF3DB`/`#956400`); black CTA, radius
|
|
63
|
+
4–6px, no shadow. Fits: product register, docs, tools. Motion: 150–200ms
|
|
64
|
+
state changes only. Killed by: decorative color, hero theatrics.
|
|
65
|
+
|
|
66
|
+
### 5. Swiss Industrial Print
|
|
67
|
+
Paper `#F4F4F0`/`#EAE8E3`, ink `#050505`, ONE accent (Aviation Red
|
|
68
|
+
`#E61919`), macro-type `clamp(4rem, 10vw, 15rem)` uppercase with tight
|
|
69
|
+
leading (0.85–0.95), mono micro-labels (+0.05–0.1em tracking), radius 0
|
|
70
|
+
absolute, mathematical hairlines (`display: grid; gap: 1px` with contrasting
|
|
71
|
+
backgrounds). Fits: portfolios, manifestos, industrial/logistics brands.
|
|
72
|
+
Killed by: rounded corners, soft shadows, second accent.
|
|
73
|
+
|
|
74
|
+
### 6. Tactical Telemetry (CRT)
|
|
75
|
+
Dark `#0A0A0A`/`#121212`, phosphor text `#EAEAEA`, same single red, Terminal
|
|
76
|
+
Green `#4AF626` reserved for exactly ONE element, mono type, ASCII framing
|
|
77
|
+
(`[ SYSTEMS ]`), scanline via `repeating-linear-gradient`. Fits: dev/infra
|
|
78
|
+
products, dashboards with attitude. Mutually exclusive with #5 — pick one.
|
|
79
|
+
Killed by: glassmorphism, gradients, more than one green element.
|
|
80
|
+
|
|
81
|
+
### 7. Terminal-Native Product
|
|
82
|
+
Dense data UI on dark 3-step surface scale (≈15/20/25% lightness), tabular
|
|
83
|
+
numerals, base-4 spacing, Compact density tier, restrained accent for state
|
|
84
|
+
only. Fits: consoles, analytics, power-user tools (product register). Motion:
|
|
85
|
+
120–200ms, zero entrances. Killed by: marketing theatrics, spacious hero
|
|
86
|
+
sections.
|
|
87
|
+
|
|
88
|
+
### 8. Cold Luxury
|
|
89
|
+
Silver-grey + chrome + smoke; thin display type with wide optical margins,
|
|
90
|
+
monochrome photography, hairline dividers. Fits: fashion, architecture,
|
|
91
|
+
high-end services. Killed by: warm beige drift, script fonts.
|
|
92
|
+
|
|
93
|
+
### 9. Earthy Rotation (Forest / Black & Tan / Terracotta + Slate / Olive + Brick + Paper / Cobalt + Cream)
|
|
94
|
+
The rotation pool for premium-consumer briefs that must NOT collapse into
|
|
95
|
+
beige+brass: deep green + bone + amber; or black + tan; or terracotta +
|
|
96
|
+
slate; or olive + brick + paper; or cobalt + cream. Pick ONE family, carry it
|
|
97
|
+
with conviction (Committed strategy, below). Killed by: mixing two families,
|
|
98
|
+
gray-on-color text.
|
|
99
|
+
|
|
100
|
+
### 10. Drenched Brand
|
|
101
|
+
The surface IS the color: one saturated brand color carries 60%+ of pixels
|
|
102
|
+
("Klim orange" energy), type in near-black or paper-white, zero secondary
|
|
103
|
+
accent. Fits: bold brand surfaces, campaign pages, portfolios. Requires real
|
|
104
|
+
contrast discipline (APCA check on every pair). Killed by: timidity — a
|
|
105
|
+
drenched page with gray hedging reads broken.
|
|
106
|
+
|
|
107
|
+
### 11. Kinetic Type / Display-Led
|
|
108
|
+
Golden-ratio scale (protocol § Type scale), type AS the imagery, macro
|
|
109
|
+
headlines, scroll-driven reveals (one orchestrated sequence). Fits: launches,
|
|
110
|
+
events, editorial features (brand register, MOTION dial ≥ 7). Killed by:
|
|
111
|
+
competing imagery, more than 2 type families.
|
|
112
|
+
|
|
113
|
+
### 12. Playful Toy
|
|
114
|
+
Saturated pops on light canvas, chunky rounded geometry (one radius system:
|
|
115
|
+
all-soft 12–16px), springy micro-interactions (spring for position/scale),
|
|
116
|
+
illustrated spot assets. Fits: consumer onboarding, education, kids (with
|
|
117
|
+
a11y quiet-constraint override). Killed by: pastel wash without contrast,
|
|
118
|
+
bounce easing everywhere.
|
|
119
|
+
|
|
120
|
+
## Color commitment axis (choose per option, name it in the rationale)
|
|
121
|
+
|
|
122
|
+
- **Restrained** — tinted neutrals + one accent ≤ 10% of pixels (product
|
|
123
|
+
register default).
|
|
124
|
+
- **Committed** — one saturated color carries 30–60% of the surface.
|
|
125
|
+
- **Full palette** — 3–4 named color roles, each with a job.
|
|
126
|
+
- **Drenched** — the surface is the color (direction #10).
|
|
127
|
+
|
|
128
|
+
Name a real-world reference before picking ("Stripe purple-on-white
|
|
129
|
+
restraint", "Klim #ff4500 drench") — **unnamed ambition becomes beige**.
|
|
130
|
+
|
|
131
|
+
## Dark vs light — the scene sentence
|
|
132
|
+
|
|
133
|
+
Dark vs light is never a default. Before choosing, write one sentence of
|
|
134
|
+
physical scene: *who* uses this, *where*, under *what ambient light*, in
|
|
135
|
+
*what mood*. If the sentence doesn't force the answer, it is not concrete
|
|
136
|
+
enough yet — sharpen it, then decide.
|
|
137
|
+
|
|
138
|
+
## Reflex-reject lists (greenfield defaults only)
|
|
139
|
+
|
|
140
|
+
### The LILA rule (color)
|
|
141
|
+
The "AI purple / blue glow" aesthetic is refused as a default: no
|
|
142
|
+
violet-indigo gradients, no cyan-on-dark glow, none of the default-Tailwind
|
|
143
|
+
indigo accents (`anti-slop.md` § Absolute bans). Use neutral bases
|
|
144
|
+
(zinc/slate/stone, tinted toward brand hue) with ONE high-contrast accent
|
|
145
|
+
(emerald, electric blue, deep rose, burnt orange). Override: the brand
|
|
146
|
+
genuinely IS purple → embrace it with intent.
|
|
147
|
+
|
|
148
|
+
### The premium-consumer beige ban (color)
|
|
149
|
+
For premium-consumer briefs (cookware, wellness, artisan, luxury, DTC home),
|
|
150
|
+
the default is warm beige/cream + brass/clay/oxblood + espresso text — banned
|
|
151
|
+
as a default, including the hex families `#f5f1ea #f7f5f1 #fbf8f1 #efeae0
|
|
152
|
+
#ece6db #faf7f1 #e8dfcb` (bg), `#b08947 #b6553a #9a2436 #9c6e2a #bc7c3a
|
|
153
|
+
#7d5621` (accent). Rotate through the Earthy Rotation (#9) or Cold Luxury
|
|
154
|
+
(#8) instead. Warmth is carried by accent + typography + imagery, not by the
|
|
155
|
+
body background. Related: the whole warm-neutral band (OKLCH L 0.84–0.97,
|
|
156
|
+
C < 0.06, hue 40–100) reads as cream/sand/paper regardless of token name —
|
|
157
|
+
token names like `--paper`, `--cream`, `--sand`, `--bone` are tells in
|
|
158
|
+
themselves. Editorial Luxury (#1) may opt into warm paper *deliberately* —
|
|
159
|
+
say so in the rationale and rotate next time.
|
|
160
|
+
|
|
161
|
+
### Serif discipline (typography)
|
|
162
|
+
Serif is very discouraged as a default. "It feels creative/premium/editorial"
|
|
163
|
+
is NOT a reason — "creative brief = serif" is the single most-tested AI tell.
|
|
164
|
+
**Banned as defaults: Fraunces and Instrument Serif.** If a serif is
|
|
165
|
+
genuinely justified (rare), rotate from: PP Editorial New, GT Sectra, Tiempos
|
|
166
|
+
Headline, Recoleta, Cormorant Garamond, EB Garamond, Canela, Domaine Display,
|
|
167
|
+
Playfair Display (never twice in a row).
|
|
168
|
+
|
|
169
|
+
### Font reflex-reject (typography)
|
|
170
|
+
Before locking a font, run the 4-step selection: (1) three concrete brand
|
|
171
|
+
words (not "modern/elegant" — "warm, mechanical, opinionated"); (2) list your
|
|
172
|
+
3 reflex picks and reject them; (3) browse a real catalog thinking of the
|
|
173
|
+
brand as a physical object ("a museum caption", "a 1970s terminal manual");
|
|
174
|
+
(4) if the final pick equals the original reflex, start over. Reflex list to
|
|
175
|
+
reject as defaults: Inter · Roboto · Arial · system-ui (product register may
|
|
176
|
+
override: earned familiarity) · Space Grotesk · Space Mono · IBM Plex family
|
|
177
|
+
· DM Sans/Serif · Outfit · Plus Jakarta Sans · Instrument Sans/Serif ·
|
|
178
|
+
Fraunces · Newsreader · Lora · Crimson · Playfair · Cormorant · Syne.
|
|
179
|
+
Sans pools to rotate: Geist, Satoshi, Cabinet Grotesk, General Sans, Inter
|
|
180
|
+
Tight (as body under a distinctive display). Pairings that work: Geist +
|
|
181
|
+
Geist Mono · Satoshi + JetBrains Mono · Cabinet Grotesk + Inter Tight.
|
|
182
|
+
|
|
183
|
+
### Aesthetic-lane rejects (composition)
|
|
184
|
+
Saturated whole-lane defaults to refuse at first reflex: the
|
|
185
|
+
**editorial-typographic** lane (italic display serif + small mono labels +
|
|
186
|
+
ruled three-column separators + monochrome restraint) and the
|
|
187
|
+
**SaaS-dark-glow** lane (dark hero, mesh gradient, glass cards). Both may be
|
|
188
|
+
*chosen* — after passing the second-order slop test (`anti-slop.md`).
|