dreative 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -35
- package/dist/cli/index.js +8 -8
- package/dist/server/preview.js +73 -73
- package/dist/shared/design.js +3 -0
- package/dist/ui/index.html +11 -11
- package/package.json +44 -44
- package/skill/dreative/DESIGN.md +478 -358
- package/skill/dreative/SKILL.md +119 -108
- package/skill/dreative/skills/3d.md +134 -131
- package/skill/dreative/skills/cinematic.md +180 -0
- package/skill/dreative/skills/immersive.md +220 -0
- package/skill/dreative/skills/interaction.md +131 -126
- package/skill/dreative/skills/motion.md +147 -125
- package/skill/dreative/skills/refined.md +99 -0
- package/dist/server/ai.js +0 -177
package/skill/dreative/DESIGN.md
CHANGED
|
@@ -1,358 +1,478 @@
|
|
|
1
|
-
# Dreative Design Doctrine
|
|
2
|
-
|
|
3
|
-
You MUST read this file before servicing any `propose-skeletons`, `propose-variants`,
|
|
4
|
-
`design-page`, or `edit-element` request, and run §12 before every respond. It exists
|
|
5
|
-
because LLM-designed UIs converge on one templated look. Every rule corrects a known
|
|
6
|
-
model default; none is a suggestion. Requests may carry a `plan` (Dreative's
|
|
7
|
-
pre-computed decision: dials, per-section layout families, budgets, lints) — execute
|
|
8
|
-
the plan, apply this doctrine to everything the plan doesn't specify. When
|
|
9
|
-
`plan.skills` names specialist skills (`motion`, `3d`, `interaction`), the matching
|
|
10
|
-
`skills/<name>.md` files extend this doctrine for that request — read them first;
|
|
11
|
-
where they go deeper than a section here, they win.
|
|
12
|
-
|
|
13
|
-
## 1. Register: the first decision
|
|
14
|
-
|
|
15
|
-
Every page is one of two registers. Misclassifying it is the biggest single error.
|
|
16
|
-
|
|
17
|
-
**BRAND** (design IS the product): landing pages, marketing, portfolios, campaign
|
|
18
|
-
pages, about pages, long-form content. Bar = distinctiveness. A visitor should ask
|
|
19
|
-
"how was this made?", not "which AI made this?". Average is no longer findable;
|
|
20
|
-
restraint without intent reads as mediocre. Go big or go home.
|
|
21
|
-
|
|
22
|
-
**PRODUCT** (design SERVES the product): app UI, dashboards, settings, tables, tools,
|
|
23
|
-
authenticated surfaces. Bar = earned familiarity. Would a user fluent in Linear,
|
|
24
|
-
Figma, Notion, Stripe trust this instantly, or pause at every subtly-off component?
|
|
25
|
-
Failure mode is not flatness, it is strangeness without purpose. The tool should
|
|
26
|
-
disappear into the task.
|
|
27
|
-
|
|
28
|
-
Pick by the page's job, not the project. One app can hold both registers.
|
|
29
|
-
|
|
30
|
-
## 2. The design read and the slop tests
|
|
31
|
-
|
|
32
|
-
Before generating, state a one-line read: "<page kind> for <audience>, <vibe>
|
|
33
|
-
language, leaning <aesthetic family>". If the request carries a `brief`, obey it —
|
|
34
|
-
it is the user's explicit direction.
|
|
35
|
-
|
|
36
|
-
Then run three tests on your intended output; restart if any fails:
|
|
37
|
-
|
|
38
|
-
1. **First-order reflex**: could someone guess your palette + theme from the category
|
|
39
|
-
alone ("cookware → cream + brass", "devtool → dark + mono")? That's the
|
|
40
|
-
training-data default. Rework. The three most-shipped default aesthetics: warm
|
|
41
|
-
cream + high-contrast serif + terracotta accent; near-black + acid-green/vermilion;
|
|
42
|
-
broadsheet hairline-rules-and-columns. Where the brief leaves an axis free, never
|
|
43
|
-
spend that freedom on one of these.
|
|
44
|
-
2. **Second-order reflex**: could someone guess it from category + anti-reference
|
|
45
|
-
("fintech that's not navy → terminal-dark", "SaaS that's not cream → editorial
|
|
46
|
-
serif + mono labels")? The trap one tier deeper. Rework again.
|
|
47
|
-
3. **Competitor sentence**: describe what you're about to build as a competitor would
|
|
48
|
-
describe theirs. If the sentence fits the modal page in the category, restart.
|
|
49
|
-
|
|
50
|
-
### The working process: commit before code
|
|
51
|
-
|
|
52
|
-
Never design by accretion. Two passes:
|
|
53
|
-
|
|
54
|
-
1. **Commit** — before any code, write a compact spec: 4-6 named colors (hex/OKLCH),
|
|
55
|
-
2+ type roles with actual font names, a one-sentence layout description per
|
|
56
|
-
section, and ONE **signature element** — the single memorable move (an
|
|
57
|
-
interaction, a typographic device, a composition) that carries the page's
|
|
58
|
-
distinctiveness. Spend your boldness there; keep everything around it disciplined
|
|
59
|
-
and quiet. Ground choices in the subject's world: its materials, instruments,
|
|
60
|
-
artifacts, and vernacular ("a coffee brand's world: burlap, roast curves,
|
|
61
|
-
thermometers, cupping notes") — not in web-design tropes.
|
|
62
|
-
2. **Review** — test the spec against the slop tests below. If any part could apply
|
|
63
|
-
to any similar project, revise that part. Only then build.
|
|
64
|
-
|
|
65
|
-
**Hero thesis:** open with the most characteristic thing in the subject's world —
|
|
66
|
-
a headline, an image, a live demo, an interactive moment. Whatever form fits.
|
|
67
|
-
|
|
68
|
-
### Aesthetic presets (brief.aesthetic)
|
|
69
|
-
|
|
70
|
-
- `minimal` — Linear-clean: restrained neutrals, one accent, generous space.
|
|
71
|
-
- `editorial` — magazine: strong type hierarchy, asymmetric grid, real imagery.
|
|
72
|
-
NOTE: editorial is ONE lane, not the default "tasteful" answer. The
|
|
73
|
-
serif-italic + mono-labels + ruled-columns look is now saturated AI grammar.
|
|
74
|
-
- `premium` — confident type, rich imagery, refined motion, zero clutter.
|
|
75
|
-
- `playful` — bold committed color, springy motion, asymmetry, still disciplined.
|
|
76
|
-
- `brutalist` — raw 1px borders, mono, flat color, radius 0, no shadows/gradients.
|
|
77
|
-
- `dark-tech` — off-black surfaces, restrained neon, terminal cues used sparingly.
|
|
78
|
-
- `trust` — public-sector/regulated: symmetric, motion ≤2, maximum legibility.
|
|
79
|
-
|
|
80
|
-
### The three dials (1-10, resolved in `plan.dials`)
|
|
81
|
-
|
|
82
|
-
- `variance` — 1 symmetry → 10 masonry/offsets/20vw empty zones. >4 forbids the
|
|
83
|
-
centered-hero default. Any asymmetry collapses to clean single-column < 768px.
|
|
84
|
-
- `motion` — 1 static → 10 scroll choreography. >3 requires reduced-motion fallbacks.
|
|
85
|
-
- `density` — 1 art-gallery (py-32+) → 10 cockpit (hairlines, tabular-nums, no cards).
|
|
86
|
-
|
|
87
|
-
## 3. Typography
|
|
88
|
-
|
|
89
|
-
**Font selection procedure (brand register, never skip):**
|
|
90
|
-
1. Write three physical-object brand-voice words ("warm, mechanical, opinionated" —
|
|
91
|
-
never "modern" or "elegant").
|
|
92
|
-
2. List the three fonts you'd reach for by reflex. Reject any on the ban list below.
|
|
93
|
-
3. Pick for the brand as a physical object (museum caption, 1970s terminal manual,
|
|
94
|
-
concert poster, mid-century receipt). Reject the first thing that "looks designy".
|
|
95
|
-
4. If the final pick matches the original reflex, start over.
|
|
96
|
-
|
|
97
|
-
**Reflex-reject fonts (training-data defaults, banned as defaults):** Fraunces,
|
|
98
|
-
Newsreader, Lora, Crimson (all), Playfair Display, Cormorant (all), Syne, IBM Plex
|
|
99
|
-
(all), Space Mono, Space Grotesk, Inter, DM Sans/Serif, Outfit, Plus Jakarta Sans,
|
|
100
|
-
Instrument Sans/Serif. Inter/system stacks ARE legitimate in the product register
|
|
101
|
-
and for trust briefs. When an existing app already uses one, identity-preservation
|
|
102
|
-
wins — keep it.
|
|
103
|
-
|
|
104
|
-
**Serif discipline:** "creative/premium brief = serif" is the most-tested AI tell.
|
|
105
|
-
Default is sans display. Serif only when the brief is genuinely editorial/luxury/
|
|
106
|
-
publication AND you can articulate why this serif fits this brand. Emphasis inside a
|
|
107
|
-
headline = italic/bold of the SAME family, never a serif word dropped into a sans
|
|
108
|
-
headline. Italic display words with descenders (y g j p q) need `leading-[1.1]`+ and
|
|
109
|
-
bottom padding reserve.
|
|
110
|
-
|
|
111
|
-
**Scale — pick by register:**
|
|
112
|
-
- Brand: fluid `clamp()` headings, ratio ≥1.25 between steps, clamp max ≤ 6rem and
|
|
113
|
-
≤ 2.5× its min. Display tracking floor −0.04em (tighter = letters touch).
|
|
114
|
-
- Product: fixed rem scale, ratio 1.125–1.2, one family in 3-4 weights is usually
|
|
115
|
-
right. No fluid type in app UI — no major design system uses it.
|
|
116
|
-
- Both: body ≥ 16px and fixed; 45–75ch measure (`max-width: 65ch`); headings
|
|
117
|
-
`text-wrap: balance`, prose `text-wrap: pretty`; ≤ 2-3 families total; never pair
|
|
118
|
-
two similar sans — contrast on a real axis (serif+sans, geometric+humanist) or use
|
|
119
|
-
one family.
|
|
120
|
-
|
|
121
|
-
**Details that read as craft:** line-height 1.1–1.2 headings, 1.5–1.7 body; ALL-CAPS
|
|
122
|
-
labels get `letter-spacing: 0.05–0.12em`; `tabular-nums` on data columns; vertical
|
|
123
|
-
rhythm = spacing in multiples of the body line-box (16px × 1.5 → 24px grid);
|
|
124
|
-
light-on-dark text compensates on three axes: +0.05–0.1 line-height, +0.01–0.02em
|
|
125
|
-
tracking, one weight step down (400→350 effect). `font-display: swap`, preload only
|
|
126
|
-
the critical weight, variable font when using 3+ weights.
|
|
127
|
-
|
|
128
|
-
## 4. Color
|
|
129
|
-
|
|
130
|
-
**Use OKLCH.** `oklch(L C H)` is perceptually uniform. Build ramps by holding
|
|
131
|
-
chroma+hue and varying lightness; reduce chroma near white/black. The hue is a brand
|
|
132
|
-
decision — never blue-250 or warm-60 by reflex.
|
|
133
|
-
|
|
134
|
-
**Pick a color strategy before picking colors:**
|
|
135
|
-
- **Restrained** — tinted neutrals + one accent ≤10% visual weight. Product floor.
|
|
136
|
-
- **Committed** — one saturated color carries 30-60% of the surface. Brand default
|
|
137
|
-
for identity-driven pages.
|
|
138
|
-
- **Full palette** — 3-4 named roles used deliberately. Campaigns, data viz.
|
|
139
|
-
- **Drenched** — the surface IS the color. Brand heroes.
|
|
140
|
-
|
|
141
|
-
Name a real reference before committing ("Stripe purple-on-white restraint", "Klim
|
|
142
|
-
#ff4500 drench", "Vercel pure-black monochrome"). Unnamed ambition becomes beige.
|
|
143
|
-
On brand surfaces, palette IS voice — don't hedge a Committed palette with neutral
|
|
144
|
-
edges. On product surfaces, accent = primary action + selection + state, never
|
|
145
|
-
decoration, with a full semantic state vocabulary (hover/focus/active/disabled/
|
|
146
|
-
selected/loading/error/warning/success/info) and a second neutral layer for
|
|
147
|
-
sidebars/panels.
|
|
148
|
-
|
|
149
|
-
**Mechanics:**
|
|
150
|
-
- Tinted neutrals: chroma 0.005–0.015 toward THIS brand's hue. Pure gray is dead;
|
|
151
|
-
reflex-warm or reflex-cool tinting is the monoculture move.
|
|
152
|
-
- 60-30-10 by visual weight: 60% neutral surface, 30% text/borders, 10% accent.
|
|
153
|
-
Accents work because they are rare.
|
|
154
|
-
- One accent, one neutral family, locked page-wide and project-wide. No blue CTA
|
|
155
|
-
appearing in section 7 of a warm-gray page.
|
|
156
|
-
- Contrast: body 4.5:1 (AAA 7:1 target for hero copy), large text 3:1, UI components
|
|
157
|
-
3:1, placeholders 4.5:1. Gray text on colored backgrounds looks washed out — use a
|
|
158
|
-
darker shade of the background's own hue or alpha of the text color. Audit every
|
|
159
|
-
CTA and form before responding.
|
|
160
|
-
- No pure #000/#fff. Dark mode is not inverted light mode: depth from a 3-step
|
|
161
|
-
surface-lightness scale (≈15/20/25% L, brand hue, chroma constant), desaturate
|
|
162
|
-
accents slightly, reduce body weight. Redefine only semantic tokens for dark.
|
|
163
|
-
- Heavy alpha usage = incomplete palette. Define explicit overlay colors.
|
|
164
|
-
|
|
165
|
-
**Banned palettes as default reaches:** AI-purple/violet gradients + glow; the
|
|
166
|
-
premium-artisan cream/sand/beige bg (#f5f1ea family, OKLCH L .84-.97 C<.06 hue
|
|
167
|
-
40-100) + brass/clay/oxblood accents + espresso text — token names like --cream,
|
|
168
|
-
--sand, --bone are tells in themselves. Alternatives to rotate: cold luxury
|
|
169
|
-
(silver/chrome/smoke), forest + bone + amber, true black + tan, cobalt + cream,
|
|
170
|
-
terracotta + slate, olive + brick + paper, monochrome + one saturated pop. "Warmth"
|
|
171
|
-
is carried by accent, type, and imagery — not by a beige body background.
|
|
172
|
-
Override: a palette is fine when the existing brand or explicit brief names it.
|
|
173
|
-
When redesigning an extracted app, its `theme` colors are the brand — preserve.
|
|
174
|
-
|
|
175
|
-
## 5. Layout
|
|
176
|
-
|
|
177
|
-
**Hard rules (failing any = broken work):**
|
|
178
|
-
- Hero fits the initial viewport: headline ≤ 2 lines, subtext ≤ 20 words, CTA visible
|
|
179
|
-
without scroll, top padding ≤ pt-24. 4-line headline is a font-size error. Max 4
|
|
180
|
-
text elements (one eyebrow OR brand strip, headline, subtext, CTAs 1+1). Trust
|
|
181
|
-
strips, pricing teasers, feature bullets, avatar rows: all move below the hero.
|
|
182
|
-
- Hero needs a real visual. Text + gradient blob is a placeholder, not a hero.
|
|
183
|
-
- variance > 4 forbids centered-hero-over-gradient: split 50/50, left-content/
|
|
184
|
-
right-asset, or asymmetric whitespace. Centered is fine for manifesto/launch copy.
|
|
185
|
-
- Nav: one line at desktop, height 64–72px (cap 80px).
|
|
186
|
-
- A layout family appears at most ONCE per page; 8 sections need ≥ 4 families. Max 2
|
|
187
|
-
consecutive image+text zigzags. No 3-identical-cards row, ever — asymmetric grid,
|
|
188
|
-
2-col, bento, or horizontal scroll instead.
|
|
189
|
-
- Bento: exactly as many cells as content (no filler tiles); 2-3 cells carry real
|
|
190
|
-
visual variation (image/tint/pattern), never all white-on-white text.
|
|
191
|
-
- Cards only when elevation = hierarchy; otherwise border-t/divide-y/whitespace.
|
|
192
|
-
Nested cards are always wrong. Tint shadows to the background hue.
|
|
193
|
-
- Lists > 5 items: group into chunks, 2-col card grid, tabs, or marquee — never one
|
|
194
|
-
hairline-divided stack, never border-t AND border-b per row.
|
|
195
|
-
- Split-header pattern (big left headline + small floating right paragraph) banned
|
|
196
|
-
as default; stack vertically at 65ch.
|
|
197
|
-
- Grid over flex-math (`grid-cols-3 gap-6`, never `w-[calc(33%-1rem)]`);
|
|
198
|
-
`repeat(auto-fit, minmax(280px, 1fr))` for breakpoint-free card grids;
|
|
199
|
-
`min-h-[100dvh]` never `h-screen`; explicit mobile collapse per section; contain
|
|
200
|
-
at `max-w-7xl mx-auto`; semantic z-index scale, no z-[999].
|
|
201
|
-
- ONE radius system: all-sharp, all-soft (12-16px), or documented mixed rule
|
|
202
|
-
("buttons pill, cards 16, inputs 8"). Cards never above 16px radius.
|
|
203
|
-
- Spacing has rhythm: vary generous separations against tight groupings on a
|
|
204
|
-
consistent base unit; brand surfaces use fluid `clamp()` spacing that breathes.
|
|
205
|
-
- Structure encodes truth, never decoration: numbering, eyebrows, dividers, and
|
|
206
|
-
labels appear only when they say something true about the content (a real
|
|
207
|
-
sequence, a real category). If removing the device loses nothing, remove it.
|
|
208
|
-
- Product register: responsive behavior is structural (collapse sidebar, responsive
|
|
209
|
-
table), not fluid type.
|
|
210
|
-
|
|
211
|
-
## 6. Motion
|
|
212
|
-
|
|
213
|
-
Every animation answers "what does this communicate?" — hierarchy, storytelling,
|
|
214
|
-
feedback, or state change. "It looked cool" = delete it.
|
|
215
|
-
|
|
216
|
-
**The 100/300/500 rule:** 100-150ms instant feedback (press, toggle) · 200-300ms
|
|
217
|
-
state changes (menu, tooltip, hover) · 300-500ms layout changes (accordion, modal)
|
|
218
|
-
· 500-800ms entrances (hero reveal, brand only). Exits run ~75% of enter duration.
|
|
219
|
-
Feedback over 500ms feels laggy. Micro-interactions target the 80ms "feels instant"
|
|
220
|
-
threshold.
|
|
221
|
-
|
|
222
|
-
**Easing:** ease-out exponential only — `cubic-bezier(0.25,1,0.5,1)` quart,
|
|
223
|
-
`cubic-bezier(0.22,1,0.36,1)` quint, `cubic-bezier(0.16,1,0.3,1)` expo. Bounce and
|
|
224
|
-
elastic are dated; banned.
|
|
225
|
-
|
|
226
|
-
**Register:** brand = one well-orchestrated hero entrance beats scattered
|
|
227
|
-
micro-interactions; the uniform fade-and-rise on every scrolled section is the
|
|
228
|
-
saturated AI tell. Some brands skip entrance motion entirely — restraint as voice.
|
|
229
|
-
Product = 150-250ms, state-conveying only, zero page-load choreography.
|
|
230
|
-
|
|
231
|
-
**Mechanics:** animate transform/opacity by default; blur/backdrop-filter/clip-path/
|
|
232
|
-
masks/shadow allowed when they materially improve the effect, bounded to small areas,
|
|
233
|
-
verified smooth. Never casually animate width/height/top/left/margins (use FLIP or
|
|
234
|
-
grid-template-rows). Sibling stagger `calc(var(--i) * 50ms)` capped at ~500ms total.
|
|
235
|
-
IntersectionObserver (unobserve after firing), CSS scroll-driven animations, or
|
|
236
|
-
Motion/GSAP scroll tools — `window.addEventListener("scroll")` is a hard ban. Reveals
|
|
237
|
-
enhance an already-visible default; never gate content visibility on a JS-triggered
|
|
238
|
-
class (hidden tabs and headless renderers ship blank sections). Max one marquee per
|
|
239
|
-
page. `prefers-reduced-motion: reduce` alternative for everything. Optimistic UI for
|
|
240
|
-
low-stakes actions; never for payments or destructive ops.
|
|
241
|
-
|
|
242
|
-
## 7. Imagery
|
|
243
|
-
|
|
244
|
-
When the brief implies imagery (restaurant, hotel, product, travel, fashion,
|
|
245
|
-
portfolio), zero images is a bug, not restraint. Even a minimalist page needs 2-3
|
|
246
|
-
real images. Priority: (1) image-gen tool if available in your environment, at the
|
|
247
|
-
section's aspect ratio; (2) real photography —
|
|
248
|
-
`https://picsum.photos/seed/<descriptive-seed>/<w>/<h>` always resolves; Unsplash
|
|
249
|
-
only with verified photo IDs (guessed IDs 404 into broken placeholders); (3)
|
|
250
|
-
clearly-labeled placeholder slots + tell the user what's needed. Search for the
|
|
251
|
-
brand's physical object ("hand-cut pasta on a scratched wooden table"), not the
|
|
252
|
-
category ("Italian food"). One decisive photo beats five mediocre ones. Alt text
|
|
253
|
-
carries voice.
|
|
254
|
-
|
|
255
|
-
Banned: div-built fake screenshots/terminals/dashboards (the #1 AI tell), hand-drawn
|
|
256
|
-
"sketchy" SVG illustrations, `feTurbulence` paper-grain, repeating-gradient stripe
|
|
257
|
-
backgrounds, decorative grid-line overlays, hand-rolled icon paths. Icons from ONE
|
|
258
|
-
library (Phosphor/Radix/Tabler/HugeIcons; Lucide only on request), one strokeWidth
|
|
259
|
-
globally. Logo walls: real SVG marks (`https://cdn.simpleicons.org/<slug>`) or
|
|
260
|
-
generated monograms — logos only, no category captions, below the hero.
|
|
261
|
-
|
|
262
|
-
## 8. Content and copy
|
|
263
|
-
|
|
264
|
-
≤ 8-word section headlines, ≤ 25-word subtext, one copy register per page, quotes
|
|
265
|
-
≤ 3 lines with name + role attribution. No filler verbs (elevate, seamless, unleash,
|
|
266
|
-
revolutionize). No fake-precise numbers unless real or labeled mock; use believable
|
|
267
|
-
messy data ("47.2%", not "99.99%"). No "Jane Doe"/"Acme"/generic avatars — realistic
|
|
268
|
-
locale-appropriate names, credible invented brands. Re-read every visible string
|
|
269
|
-
before responding; rewrite anything grammatically broken, cutely meta, or
|
|
270
|
-
performative-craftsman ("From the field", "We respect the French ones"). Plain
|
|
271
|
-
beats clever. Data-dump tables on marketing pages → top 3-5 + "view all".
|
|
272
|
-
|
|
273
|
-
**UX writing:** write from the user's side of the screen — name things by what
|
|
274
|
-
people control and recognize, never by how the system is built. Active voice ("Save
|
|
275
|
-
changes", not "Submit"). Action names stay consistent through the flow (button
|
|
276
|
-
"Publish" → toast "Published"). Errors and empty states are direction, not mood:
|
|
277
|
-
say what happened and what to do next; never apologize vaguely. Sentence case,
|
|
278
|
-
plain verbs, no filler.
|
|
279
|
-
|
|
280
|
-
## 9. States and interaction (product floor)
|
|
281
|
-
|
|
282
|
-
Every interactive component ships default/hover/focus/active/disabled/loading/error.
|
|
283
|
-
Skeletons shaped like the final layout, not centered spinners. Empty states teach
|
|
284
|
-
the interface. Errors inline for forms, toasts only for transient events. Labels
|
|
285
|
-
above inputs; placeholder-as-label never; helper text present. `:active` gives
|
|
286
|
-
tactile press (`scale-[0.98]`). Same button shape, form vocabulary, and icon style
|
|
287
|
-
on every screen — if "save" looks different in two places, one is wrong. Modals are
|
|
288
|
-
usually laziness; exhaust inline/progressive first. Dropdowns escape
|
|
289
|
-
overflow-hidden ancestors via popover API/position-fixed/portal. Touch targets
|
|
290
|
-
≥ 44px. Never disable zoom.
|
|
291
|
-
|
|
292
|
-
## 10. Banned AI tells (match-and-refuse)
|
|
293
|
-
|
|
294
|
-
- **Em-dash (—) and en-dash separators (–): zero anywhere visible.** Periods,
|
|
295
|
-
commas, colons, plain hyphens.
|
|
296
|
-
- Eyebrow kickers (small caps tracked labels above headings) on every section — max
|
|
297
|
-
1 per 3 sections, and only as a deliberate system. Numbered section markers
|
|
298
|
-
(`01 · About`) unless the content is a real sequence.
|
|
299
|
-
- Side-stripe borders (border-left > 1px as accent) — full hairline border, 4-8%
|
|
300
|
-
background tint, or leading glyph instead.
|
|
301
|
-
- Gradient text (background-clip). Glassmorphism as default. Hero-metric template
|
|
302
|
-
(big number + label + gradient accent). Identical icon+heading+text card grids.
|
|
303
|
-
- 1px border + soft ≥16px drop shadow on the same element ("ghost card") — pick one.
|
|
304
|
-
- Hero version labels (BETA, V0.6), scroll cues ("↓ scroll to explore"),
|
|
305
|
-
locale/weather strips, decoration strips (`DESIGN · BUILD · SHIP`), vertical
|
|
306
|
-
rotated text, custom cursors, decorative status dots, pills overlaid on photos,
|
|
307
|
-
fake photo credits, version footers on marketing pages, "Quietly trusted by".
|
|
308
|
-
- Duplicate CTA intent: one label per intent per page ("Get in touch" + "Let's
|
|
309
|
-
talk" = fail). CTA labels never wrap at desktop; 1-3 words.
|
|
310
|
-
- Middle-dot separators rationed to 1 per line. Never hover-scale on `<img>`
|
|
311
|
-
elements (animate the card's border/background/shadow instead).
|
|
312
|
-
- Headline text that overflows its container at any breakpoint — test the actual
|
|
313
|
-
copy; the viewport is part of the design.
|
|
314
|
-
|
|
315
|
-
## 11. Redesign and preservation (extracted apps)
|
|
316
|
-
|
|
317
|
-
Dreative pages usually come FROM a real app. Detect the mode: preserve (evolve the
|
|
318
|
-
existing brand) vs overhaul (new language, same content/IA). When preserving: keep
|
|
319
|
-
route slugs, nav labels, form field names, logo, legal copy; extract brand tokens
|
|
320
|
-
before applying §4 (a purple brand stays purple); apply modernisation levers in
|
|
321
|
-
order — typography → spacing/rhythm → color recalibration → motion layer → hero
|
|
322
|
-
recomposition → full replacement only when unsalvageable. Honor existing
|
|
323
|
-
accessibility wins and analytics hooks. Preserve prior element-level edits when
|
|
324
|
-
`previousFile` is set.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
1
|
+
# Dreative Design Doctrine
|
|
2
|
+
|
|
3
|
+
You MUST read this file before servicing any `propose-skeletons`, `propose-variants`,
|
|
4
|
+
`design-page`, or `edit-element` request, and run §12 before every respond. It exists
|
|
5
|
+
because LLM-designed UIs converge on one templated look. Every rule corrects a known
|
|
6
|
+
model default; none is a suggestion. Requests may carry a `plan` (Dreative's
|
|
7
|
+
pre-computed decision: dials, per-section layout families, budgets, lints) — execute
|
|
8
|
+
the plan, apply this doctrine to everything the plan doesn't specify. When
|
|
9
|
+
`plan.skills` names specialist skills (`motion`, `3d`, `interaction`), the matching
|
|
10
|
+
`skills/<name>.md` files extend this doctrine for that request — read them first;
|
|
11
|
+
where they go deeper than a section here, they win.
|
|
12
|
+
|
|
13
|
+
## 1. Register: the first decision
|
|
14
|
+
|
|
15
|
+
Every page is one of two registers. Misclassifying it is the biggest single error.
|
|
16
|
+
|
|
17
|
+
**BRAND** (design IS the product): landing pages, marketing, portfolios, campaign
|
|
18
|
+
pages, about pages, long-form content. Bar = distinctiveness. A visitor should ask
|
|
19
|
+
"how was this made?", not "which AI made this?". Average is no longer findable;
|
|
20
|
+
restraint without intent reads as mediocre. Go big or go home.
|
|
21
|
+
|
|
22
|
+
**PRODUCT** (design SERVES the product): app UI, dashboards, settings, tables, tools,
|
|
23
|
+
authenticated surfaces. Bar = earned familiarity. Would a user fluent in Linear,
|
|
24
|
+
Figma, Notion, Stripe trust this instantly, or pause at every subtly-off component?
|
|
25
|
+
Failure mode is not flatness, it is strangeness without purpose. The tool should
|
|
26
|
+
disappear into the task.
|
|
27
|
+
|
|
28
|
+
Pick by the page's job, not the project. One app can hold both registers.
|
|
29
|
+
|
|
30
|
+
## 2. The design read and the slop tests
|
|
31
|
+
|
|
32
|
+
Before generating, state a one-line read: "<page kind> for <audience>, <vibe>
|
|
33
|
+
language, leaning <aesthetic family>". If the request carries a `brief`, obey it —
|
|
34
|
+
it is the user's explicit direction.
|
|
35
|
+
|
|
36
|
+
Then run three tests on your intended output; restart if any fails:
|
|
37
|
+
|
|
38
|
+
1. **First-order reflex**: could someone guess your palette + theme from the category
|
|
39
|
+
alone ("cookware → cream + brass", "devtool → dark + mono")? That's the
|
|
40
|
+
training-data default. Rework. The three most-shipped default aesthetics: warm
|
|
41
|
+
cream + high-contrast serif + terracotta accent; near-black + acid-green/vermilion;
|
|
42
|
+
broadsheet hairline-rules-and-columns. Where the brief leaves an axis free, never
|
|
43
|
+
spend that freedom on one of these.
|
|
44
|
+
2. **Second-order reflex**: could someone guess it from category + anti-reference
|
|
45
|
+
("fintech that's not navy → terminal-dark", "SaaS that's not cream → editorial
|
|
46
|
+
serif + mono labels")? The trap one tier deeper. Rework again.
|
|
47
|
+
3. **Competitor sentence**: describe what you're about to build as a competitor would
|
|
48
|
+
describe theirs. If the sentence fits the modal page in the category, restart.
|
|
49
|
+
|
|
50
|
+
### The working process: commit before code
|
|
51
|
+
|
|
52
|
+
Never design by accretion. Two passes:
|
|
53
|
+
|
|
54
|
+
1. **Commit** — before any code, write a compact spec: 4-6 named colors (hex/OKLCH),
|
|
55
|
+
2+ type roles with actual font names, a one-sentence layout description per
|
|
56
|
+
section, and ONE **signature element** — the single memorable move (an
|
|
57
|
+
interaction, a typographic device, a composition) that carries the page's
|
|
58
|
+
distinctiveness. Spend your boldness there; keep everything around it disciplined
|
|
59
|
+
and quiet. Ground choices in the subject's world: its materials, instruments,
|
|
60
|
+
artifacts, and vernacular ("a coffee brand's world: burlap, roast curves,
|
|
61
|
+
thermometers, cupping notes") — not in web-design tropes.
|
|
62
|
+
2. **Review** — test the spec against the slop tests below. If any part could apply
|
|
63
|
+
to any similar project, revise that part. Only then build.
|
|
64
|
+
|
|
65
|
+
**Hero thesis:** open with the most characteristic thing in the subject's world —
|
|
66
|
+
a headline, an image, a live demo, an interactive moment. Whatever form fits.
|
|
67
|
+
|
|
68
|
+
### Aesthetic presets (brief.aesthetic)
|
|
69
|
+
|
|
70
|
+
- `minimal` — Linear-clean: restrained neutrals, one accent, generous space.
|
|
71
|
+
- `editorial` — magazine: strong type hierarchy, asymmetric grid, real imagery.
|
|
72
|
+
NOTE: editorial is ONE lane, not the default "tasteful" answer. The
|
|
73
|
+
serif-italic + mono-labels + ruled-columns look is now saturated AI grammar.
|
|
74
|
+
- `premium` — confident type, rich imagery, refined motion, zero clutter.
|
|
75
|
+
- `playful` — bold committed color, springy motion, asymmetry, still disciplined.
|
|
76
|
+
- `brutalist` — raw 1px borders, mono, flat color, radius 0, no shadows/gradients.
|
|
77
|
+
- `dark-tech` — off-black surfaces, restrained neon, terminal cues used sparingly.
|
|
78
|
+
- `trust` — public-sector/regulated: symmetric, motion ≤2, maximum legibility.
|
|
79
|
+
|
|
80
|
+
### The three dials (1-10, resolved in `plan.dials`)
|
|
81
|
+
|
|
82
|
+
- `variance` — 1 symmetry → 10 masonry/offsets/20vw empty zones. >4 forbids the
|
|
83
|
+
centered-hero default. Any asymmetry collapses to clean single-column < 768px.
|
|
84
|
+
- `motion` — 1 static → 10 scroll choreography. >3 requires reduced-motion fallbacks.
|
|
85
|
+
- `density` — 1 art-gallery (py-32+) → 10 cockpit (hairlines, tabular-nums, no cards).
|
|
86
|
+
|
|
87
|
+
## 3. Typography
|
|
88
|
+
|
|
89
|
+
**Font selection procedure (brand register, never skip):**
|
|
90
|
+
1. Write three physical-object brand-voice words ("warm, mechanical, opinionated" —
|
|
91
|
+
never "modern" or "elegant").
|
|
92
|
+
2. List the three fonts you'd reach for by reflex. Reject any on the ban list below.
|
|
93
|
+
3. Pick for the brand as a physical object (museum caption, 1970s terminal manual,
|
|
94
|
+
concert poster, mid-century receipt). Reject the first thing that "looks designy".
|
|
95
|
+
4. If the final pick matches the original reflex, start over.
|
|
96
|
+
|
|
97
|
+
**Reflex-reject fonts (training-data defaults, banned as defaults):** Fraunces,
|
|
98
|
+
Newsreader, Lora, Crimson (all), Playfair Display, Cormorant (all), Syne, IBM Plex
|
|
99
|
+
(all), Space Mono, Space Grotesk, Inter, DM Sans/Serif, Outfit, Plus Jakarta Sans,
|
|
100
|
+
Instrument Sans/Serif. Inter/system stacks ARE legitimate in the product register
|
|
101
|
+
and for trust briefs. When an existing app already uses one, identity-preservation
|
|
102
|
+
wins — keep it.
|
|
103
|
+
|
|
104
|
+
**Serif discipline:** "creative/premium brief = serif" is the most-tested AI tell.
|
|
105
|
+
Default is sans display. Serif only when the brief is genuinely editorial/luxury/
|
|
106
|
+
publication AND you can articulate why this serif fits this brand. Emphasis inside a
|
|
107
|
+
headline = italic/bold of the SAME family, never a serif word dropped into a sans
|
|
108
|
+
headline. Italic display words with descenders (y g j p q) need `leading-[1.1]`+ and
|
|
109
|
+
bottom padding reserve.
|
|
110
|
+
|
|
111
|
+
**Scale — pick by register:**
|
|
112
|
+
- Brand: fluid `clamp()` headings, ratio ≥1.25 between steps, clamp max ≤ 6rem and
|
|
113
|
+
≤ 2.5× its min. Display tracking floor −0.04em (tighter = letters touch).
|
|
114
|
+
- Product: fixed rem scale, ratio 1.125–1.2, one family in 3-4 weights is usually
|
|
115
|
+
right. No fluid type in app UI — no major design system uses it.
|
|
116
|
+
- Both: body ≥ 16px and fixed; 45–75ch measure (`max-width: 65ch`); headings
|
|
117
|
+
`text-wrap: balance`, prose `text-wrap: pretty`; ≤ 2-3 families total; never pair
|
|
118
|
+
two similar sans — contrast on a real axis (serif+sans, geometric+humanist) or use
|
|
119
|
+
one family.
|
|
120
|
+
|
|
121
|
+
**Details that read as craft:** line-height 1.1–1.2 headings, 1.5–1.7 body; ALL-CAPS
|
|
122
|
+
labels get `letter-spacing: 0.05–0.12em`; `tabular-nums` on data columns; vertical
|
|
123
|
+
rhythm = spacing in multiples of the body line-box (16px × 1.5 → 24px grid);
|
|
124
|
+
light-on-dark text compensates on three axes: +0.05–0.1 line-height, +0.01–0.02em
|
|
125
|
+
tracking, one weight step down (400→350 effect). `font-display: swap`, preload only
|
|
126
|
+
the critical weight, variable font when using 3+ weights.
|
|
127
|
+
|
|
128
|
+
## 4. Color
|
|
129
|
+
|
|
130
|
+
**Use OKLCH.** `oklch(L C H)` is perceptually uniform. Build ramps by holding
|
|
131
|
+
chroma+hue and varying lightness; reduce chroma near white/black. The hue is a brand
|
|
132
|
+
decision — never blue-250 or warm-60 by reflex.
|
|
133
|
+
|
|
134
|
+
**Pick a color strategy before picking colors:**
|
|
135
|
+
- **Restrained** — tinted neutrals + one accent ≤10% visual weight. Product floor.
|
|
136
|
+
- **Committed** — one saturated color carries 30-60% of the surface. Brand default
|
|
137
|
+
for identity-driven pages.
|
|
138
|
+
- **Full palette** — 3-4 named roles used deliberately. Campaigns, data viz.
|
|
139
|
+
- **Drenched** — the surface IS the color. Brand heroes.
|
|
140
|
+
|
|
141
|
+
Name a real reference before committing ("Stripe purple-on-white restraint", "Klim
|
|
142
|
+
#ff4500 drench", "Vercel pure-black monochrome"). Unnamed ambition becomes beige.
|
|
143
|
+
On brand surfaces, palette IS voice — don't hedge a Committed palette with neutral
|
|
144
|
+
edges. On product surfaces, accent = primary action + selection + state, never
|
|
145
|
+
decoration, with a full semantic state vocabulary (hover/focus/active/disabled/
|
|
146
|
+
selected/loading/error/warning/success/info) and a second neutral layer for
|
|
147
|
+
sidebars/panels.
|
|
148
|
+
|
|
149
|
+
**Mechanics:**
|
|
150
|
+
- Tinted neutrals: chroma 0.005–0.015 toward THIS brand's hue. Pure gray is dead;
|
|
151
|
+
reflex-warm or reflex-cool tinting is the monoculture move.
|
|
152
|
+
- 60-30-10 by visual weight: 60% neutral surface, 30% text/borders, 10% accent.
|
|
153
|
+
Accents work because they are rare.
|
|
154
|
+
- One accent, one neutral family, locked page-wide and project-wide. No blue CTA
|
|
155
|
+
appearing in section 7 of a warm-gray page.
|
|
156
|
+
- Contrast: body 4.5:1 (AAA 7:1 target for hero copy), large text 3:1, UI components
|
|
157
|
+
3:1, placeholders 4.5:1. Gray text on colored backgrounds looks washed out — use a
|
|
158
|
+
darker shade of the background's own hue or alpha of the text color. Audit every
|
|
159
|
+
CTA and form before responding.
|
|
160
|
+
- No pure #000/#fff. Dark mode is not inverted light mode: depth from a 3-step
|
|
161
|
+
surface-lightness scale (≈15/20/25% L, brand hue, chroma constant), desaturate
|
|
162
|
+
accents slightly, reduce body weight. Redefine only semantic tokens for dark.
|
|
163
|
+
- Heavy alpha usage = incomplete palette. Define explicit overlay colors.
|
|
164
|
+
|
|
165
|
+
**Banned palettes as default reaches:** AI-purple/violet gradients + glow; the
|
|
166
|
+
premium-artisan cream/sand/beige bg (#f5f1ea family, OKLCH L .84-.97 C<.06 hue
|
|
167
|
+
40-100) + brass/clay/oxblood accents + espresso text — token names like --cream,
|
|
168
|
+
--sand, --bone are tells in themselves. Alternatives to rotate: cold luxury
|
|
169
|
+
(silver/chrome/smoke), forest + bone + amber, true black + tan, cobalt + cream,
|
|
170
|
+
terracotta + slate, olive + brick + paper, monochrome + one saturated pop. "Warmth"
|
|
171
|
+
is carried by accent, type, and imagery — not by a beige body background.
|
|
172
|
+
Override: a palette is fine when the existing brand or explicit brief names it.
|
|
173
|
+
When redesigning an extracted app, its `theme` colors are the brand — preserve.
|
|
174
|
+
|
|
175
|
+
## 5. Layout
|
|
176
|
+
|
|
177
|
+
**Hard rules (failing any = broken work):**
|
|
178
|
+
- Hero fits the initial viewport: headline ≤ 2 lines, subtext ≤ 20 words, CTA visible
|
|
179
|
+
without scroll, top padding ≤ pt-24. 4-line headline is a font-size error. Max 4
|
|
180
|
+
text elements (one eyebrow OR brand strip, headline, subtext, CTAs 1+1). Trust
|
|
181
|
+
strips, pricing teasers, feature bullets, avatar rows: all move below the hero.
|
|
182
|
+
- Hero needs a real visual. Text + gradient blob is a placeholder, not a hero.
|
|
183
|
+
- variance > 4 forbids centered-hero-over-gradient: split 50/50, left-content/
|
|
184
|
+
right-asset, or asymmetric whitespace. Centered is fine for manifesto/launch copy.
|
|
185
|
+
- Nav: one line at desktop, height 64–72px (cap 80px).
|
|
186
|
+
- A layout family appears at most ONCE per page; 8 sections need ≥ 4 families. Max 2
|
|
187
|
+
consecutive image+text zigzags. No 3-identical-cards row, ever — asymmetric grid,
|
|
188
|
+
2-col, bento, or horizontal scroll instead.
|
|
189
|
+
- Bento: exactly as many cells as content (no filler tiles); 2-3 cells carry real
|
|
190
|
+
visual variation (image/tint/pattern), never all white-on-white text.
|
|
191
|
+
- Cards only when elevation = hierarchy; otherwise border-t/divide-y/whitespace.
|
|
192
|
+
Nested cards are always wrong. Tint shadows to the background hue.
|
|
193
|
+
- Lists > 5 items: group into chunks, 2-col card grid, tabs, or marquee — never one
|
|
194
|
+
hairline-divided stack, never border-t AND border-b per row.
|
|
195
|
+
- Split-header pattern (big left headline + small floating right paragraph) banned
|
|
196
|
+
as default; stack vertically at 65ch.
|
|
197
|
+
- Grid over flex-math (`grid-cols-3 gap-6`, never `w-[calc(33%-1rem)]`);
|
|
198
|
+
`repeat(auto-fit, minmax(280px, 1fr))` for breakpoint-free card grids;
|
|
199
|
+
`min-h-[100dvh]` never `h-screen`; explicit mobile collapse per section; contain
|
|
200
|
+
at `max-w-7xl mx-auto`; semantic z-index scale, no z-[999].
|
|
201
|
+
- ONE radius system: all-sharp, all-soft (12-16px), or documented mixed rule
|
|
202
|
+
("buttons pill, cards 16, inputs 8"). Cards never above 16px radius.
|
|
203
|
+
- Spacing has rhythm: vary generous separations against tight groupings on a
|
|
204
|
+
consistent base unit; brand surfaces use fluid `clamp()` spacing that breathes.
|
|
205
|
+
- Structure encodes truth, never decoration: numbering, eyebrows, dividers, and
|
|
206
|
+
labels appear only when they say something true about the content (a real
|
|
207
|
+
sequence, a real category). If removing the device loses nothing, remove it.
|
|
208
|
+
- Product register: responsive behavior is structural (collapse sidebar, responsive
|
|
209
|
+
table), not fluid type.
|
|
210
|
+
|
|
211
|
+
## 6. Motion
|
|
212
|
+
|
|
213
|
+
Every animation answers "what does this communicate?" — hierarchy, storytelling,
|
|
214
|
+
feedback, or state change. "It looked cool" = delete it.
|
|
215
|
+
|
|
216
|
+
**The 100/300/500 rule:** 100-150ms instant feedback (press, toggle) · 200-300ms
|
|
217
|
+
state changes (menu, tooltip, hover) · 300-500ms layout changes (accordion, modal)
|
|
218
|
+
· 500-800ms entrances (hero reveal, brand only). Exits run ~75% of enter duration.
|
|
219
|
+
Feedback over 500ms feels laggy. Micro-interactions target the 80ms "feels instant"
|
|
220
|
+
threshold.
|
|
221
|
+
|
|
222
|
+
**Easing:** ease-out exponential only — `cubic-bezier(0.25,1,0.5,1)` quart,
|
|
223
|
+
`cubic-bezier(0.22,1,0.36,1)` quint, `cubic-bezier(0.16,1,0.3,1)` expo. Bounce and
|
|
224
|
+
elastic are dated; banned.
|
|
225
|
+
|
|
226
|
+
**Register:** brand = one well-orchestrated hero entrance beats scattered
|
|
227
|
+
micro-interactions; the uniform fade-and-rise on every scrolled section is the
|
|
228
|
+
saturated AI tell. Some brands skip entrance motion entirely — restraint as voice.
|
|
229
|
+
Product = 150-250ms, state-conveying only, zero page-load choreography.
|
|
230
|
+
|
|
231
|
+
**Mechanics:** animate transform/opacity by default; blur/backdrop-filter/clip-path/
|
|
232
|
+
masks/shadow allowed when they materially improve the effect, bounded to small areas,
|
|
233
|
+
verified smooth. Never casually animate width/height/top/left/margins (use FLIP or
|
|
234
|
+
grid-template-rows). Sibling stagger `calc(var(--i) * 50ms)` capped at ~500ms total.
|
|
235
|
+
IntersectionObserver (unobserve after firing), CSS scroll-driven animations, or
|
|
236
|
+
Motion/GSAP scroll tools — `window.addEventListener("scroll")` is a hard ban. Reveals
|
|
237
|
+
enhance an already-visible default; never gate content visibility on a JS-triggered
|
|
238
|
+
class (hidden tabs and headless renderers ship blank sections). Max one marquee per
|
|
239
|
+
page. `prefers-reduced-motion: reduce` alternative for everything. Optimistic UI for
|
|
240
|
+
low-stakes actions; never for payments or destructive ops.
|
|
241
|
+
|
|
242
|
+
## 7. Imagery
|
|
243
|
+
|
|
244
|
+
When the brief implies imagery (restaurant, hotel, product, travel, fashion,
|
|
245
|
+
portfolio), zero images is a bug, not restraint. Even a minimalist page needs 2-3
|
|
246
|
+
real images. Priority: (1) image-gen tool if available in your environment, at the
|
|
247
|
+
section's aspect ratio; (2) real photography —
|
|
248
|
+
`https://picsum.photos/seed/<descriptive-seed>/<w>/<h>` always resolves; Unsplash
|
|
249
|
+
only with verified photo IDs (guessed IDs 404 into broken placeholders); (3)
|
|
250
|
+
clearly-labeled placeholder slots + tell the user what's needed. Search for the
|
|
251
|
+
brand's physical object ("hand-cut pasta on a scratched wooden table"), not the
|
|
252
|
+
category ("Italian food"). One decisive photo beats five mediocre ones. Alt text
|
|
253
|
+
carries voice.
|
|
254
|
+
|
|
255
|
+
Banned: div-built fake screenshots/terminals/dashboards (the #1 AI tell), hand-drawn
|
|
256
|
+
"sketchy" SVG illustrations, `feTurbulence` paper-grain, repeating-gradient stripe
|
|
257
|
+
backgrounds, decorative grid-line overlays, hand-rolled icon paths. Icons from ONE
|
|
258
|
+
library (Phosphor/Radix/Tabler/HugeIcons; Lucide only on request), one strokeWidth
|
|
259
|
+
globally. Logo walls: real SVG marks (`https://cdn.simpleicons.org/<slug>`) or
|
|
260
|
+
generated monograms — logos only, no category captions, below the hero.
|
|
261
|
+
|
|
262
|
+
## 8. Content and copy
|
|
263
|
+
|
|
264
|
+
≤ 8-word section headlines, ≤ 25-word subtext, one copy register per page, quotes
|
|
265
|
+
≤ 3 lines with name + role attribution. No filler verbs (elevate, seamless, unleash,
|
|
266
|
+
revolutionize). No fake-precise numbers unless real or labeled mock; use believable
|
|
267
|
+
messy data ("47.2%", not "99.99%"). No "Jane Doe"/"Acme"/generic avatars — realistic
|
|
268
|
+
locale-appropriate names, credible invented brands. Re-read every visible string
|
|
269
|
+
before responding; rewrite anything grammatically broken, cutely meta, or
|
|
270
|
+
performative-craftsman ("From the field", "We respect the French ones"). Plain
|
|
271
|
+
beats clever. Data-dump tables on marketing pages → top 3-5 + "view all".
|
|
272
|
+
|
|
273
|
+
**UX writing:** write from the user's side of the screen — name things by what
|
|
274
|
+
people control and recognize, never by how the system is built. Active voice ("Save
|
|
275
|
+
changes", not "Submit"). Action names stay consistent through the flow (button
|
|
276
|
+
"Publish" → toast "Published"). Errors and empty states are direction, not mood:
|
|
277
|
+
say what happened and what to do next; never apologize vaguely. Sentence case,
|
|
278
|
+
plain verbs, no filler.
|
|
279
|
+
|
|
280
|
+
## 9. States and interaction (product floor)
|
|
281
|
+
|
|
282
|
+
Every interactive component ships default/hover/focus/active/disabled/loading/error.
|
|
283
|
+
Skeletons shaped like the final layout, not centered spinners. Empty states teach
|
|
284
|
+
the interface. Errors inline for forms, toasts only for transient events. Labels
|
|
285
|
+
above inputs; placeholder-as-label never; helper text present. `:active` gives
|
|
286
|
+
tactile press (`scale-[0.98]`). Same button shape, form vocabulary, and icon style
|
|
287
|
+
on every screen — if "save" looks different in two places, one is wrong. Modals are
|
|
288
|
+
usually laziness; exhaust inline/progressive first. Dropdowns escape
|
|
289
|
+
overflow-hidden ancestors via popover API/position-fixed/portal. Touch targets
|
|
290
|
+
≥ 44px. Never disable zoom.
|
|
291
|
+
|
|
292
|
+
## 10. Banned AI tells (match-and-refuse)
|
|
293
|
+
|
|
294
|
+
- **Em-dash (—) and en-dash separators (–): zero anywhere visible.** Periods,
|
|
295
|
+
commas, colons, plain hyphens.
|
|
296
|
+
- Eyebrow kickers (small caps tracked labels above headings) on every section — max
|
|
297
|
+
1 per 3 sections, and only as a deliberate system. Numbered section markers
|
|
298
|
+
(`01 · About`) unless the content is a real sequence.
|
|
299
|
+
- Side-stripe borders (border-left > 1px as accent) — full hairline border, 4-8%
|
|
300
|
+
background tint, or leading glyph instead.
|
|
301
|
+
- Gradient text (background-clip). Glassmorphism as default. Hero-metric template
|
|
302
|
+
(big number + label + gradient accent). Identical icon+heading+text card grids.
|
|
303
|
+
- 1px border + soft ≥16px drop shadow on the same element ("ghost card") — pick one.
|
|
304
|
+
- Hero version labels (BETA, V0.6), scroll cues ("↓ scroll to explore"),
|
|
305
|
+
locale/weather strips, decoration strips (`DESIGN · BUILD · SHIP`), vertical
|
|
306
|
+
rotated text, custom cursors, decorative status dots, pills overlaid on photos,
|
|
307
|
+
fake photo credits, version footers on marketing pages, "Quietly trusted by".
|
|
308
|
+
- Duplicate CTA intent: one label per intent per page ("Get in touch" + "Let's
|
|
309
|
+
talk" = fail). CTA labels never wrap at desktop; 1-3 words.
|
|
310
|
+
- Middle-dot separators rationed to 1 per line. Never hover-scale on `<img>`
|
|
311
|
+
elements (animate the card's border/background/shadow instead).
|
|
312
|
+
- Headline text that overflows its container at any breakpoint — test the actual
|
|
313
|
+
copy; the viewport is part of the design.
|
|
314
|
+
|
|
315
|
+
## 11. Redesign and preservation (extracted apps)
|
|
316
|
+
|
|
317
|
+
Dreative pages usually come FROM a real app. Detect the mode: preserve (evolve the
|
|
318
|
+
existing brand) vs overhaul (new language, same content/IA). When preserving: keep
|
|
319
|
+
route slugs, nav labels, form field names, logo, legal copy; extract brand tokens
|
|
320
|
+
before applying §4 (a purple brand stays purple); apply modernisation levers in
|
|
321
|
+
order — typography → spacing/rhythm → color recalibration → motion layer → hero
|
|
322
|
+
recomposition → full replacement only when unsalvageable. Honor existing
|
|
323
|
+
accessibility wins and analytics hooks. Preserve prior element-level edits when
|
|
324
|
+
`previousFile` is set.
|
|
325
|
+
|
|
326
|
+
### The transformation-depth ladder (offer it, then execute it)
|
|
327
|
+
|
|
328
|
+
A redesign request has a depth, and styling is only the shallowest rung. When the
|
|
329
|
+
user asks for meaningful change ("redesign", "make it modern", "make it look like
|
|
330
|
+
<reference site>", "change it entirely") and the depth is ambiguous, present this
|
|
331
|
+
ladder as explicit options (one short question, plain labels) and wait for the
|
|
332
|
+
answer — do NOT silently default to the shallowest rung. Bundle the specialist
|
|
333
|
+
skill picker (SKILL.md) into the same question so the user answers depth and
|
|
334
|
+
treatments in one pass:
|
|
335
|
+
|
|
336
|
+
1. **Restyle** — tokens only: color, type, spacing, radius, shadows, motion
|
|
337
|
+
polish. Markup and structure untouched. Right for "refresh the look".
|
|
338
|
+
2. **Re-layout** — recompose sections: reorder, change layout families, new hero
|
|
339
|
+
composition, new grid. Content and component boundaries survive; markup within
|
|
340
|
+
sections is rewritten as needed.
|
|
341
|
+
3. **Restructure** — rewrite the HTML/component architecture: new semantic
|
|
342
|
+
structure, new component boundaries, new navigation model, sections merged or
|
|
343
|
+
split, routing changes. Content and IA survive; the code that renders them is
|
|
344
|
+
rebuilt. Required for genre shifts (e.g. conventional page → immersive world,
|
|
345
|
+
marketing page → app shell).
|
|
346
|
+
4. **Reimagine** — full rebuild: new structure AND new IA/copy/interaction model.
|
|
347
|
+
Only the brand and the underlying purpose survive.
|
|
348
|
+
|
|
349
|
+
Once the user picks a rung, execute AT that rung — a confirmed "restructure"
|
|
350
|
+
means literally rebuilding markup, component trees, and routing, not a heavier
|
|
351
|
+
coat of CSS on the old skeleton. If mid-work you discover the chosen rung cannot
|
|
352
|
+
honestly deliver the requested outcome (the reference look demands structure the
|
|
353
|
+
current markup can't express), say so and ask to move up one rung rather than
|
|
354
|
+
shipping an imitation. Rungs 3–4 on an extracted app still honor §11 preservation
|
|
355
|
+
rules for whatever the user said to keep (routes, legal copy, form semantics).
|
|
356
|
+
|
|
357
|
+
## 12. Pre-flight checklist (run before EVERY respond)
|
|
358
|
+
|
|
359
|
+
Mentally verify; fix failures, then respond. If a box cannot be honestly ticked,
|
|
360
|
+
the output is not done.
|
|
361
|
+
|
|
362
|
+
0. Commit pass done: named palette, named fonts, one signature element, subject-
|
|
363
|
+
grounded. The quality floor (responsive to mobile, visible keyboard focus,
|
|
364
|
+
reduced motion) is built silently — never announced in copy or comments.
|
|
365
|
+
1. Register named (brand/product); design read stated; brief and plan obeyed.
|
|
366
|
+
2. All three slop tests pass (first-order, second-order, competitor sentence).
|
|
367
|
+
3. Zero em/en-dashes visible. Zero banned tells from §10.
|
|
368
|
+
4. One accent + one tinted-neutral family + one theme + one radius system + one
|
|
369
|
+
icon family, locked page-wide; matches sibling pages of this project.
|
|
370
|
+
5. Fonts: not on the reflex-reject list (or justified by existing brand); scale
|
|
371
|
+
ratio committed; body ≥16px at 45-75ch; caps tracked; data tabular.
|
|
372
|
+
6. Every CTA/form/placeholder passes WCAG AA; no CTA wraps; no duplicate CTA intent.
|
|
373
|
+
7. Hero: ≤2-line headline, ≤20-word subtext, ≤4 elements, real visual, CTA above
|
|
374
|
+
fold; centered only if variance ≤ 4 or manifesto brief.
|
|
375
|
+
8. Eyebrows ≤ ceil(sections/3); no two sections share a layout family; ≤2
|
|
376
|
+
consecutive zigzags; no 3-identical-cards; bento cells = content count.
|
|
377
|
+
9. Real images or labeled slots; no div fake-screenshots; no sketchy SVG; logos are
|
|
378
|
+
real marks.
|
|
379
|
+
10. Motion: each animation justified in one sentence; durations per 100/300/500;
|
|
380
|
+
ease-out curves; exits faster; reduced-motion safe; content visible without JS;
|
|
381
|
+
≤1 marquee; no scroll-listener.
|
|
382
|
+
11. States complete (loading/empty/error/disabled); labels above inputs; tactile
|
|
383
|
+
:active.
|
|
384
|
+
12. Mobile collapse explicit; 100dvh; no text overflow at any breakpoint; semantic
|
|
385
|
+
z-index.
|
|
386
|
+
13. Copy self-audit done: no broken/AI-cute strings, realistic data, one register.
|
|
387
|
+
14. Every block id from the layout appears as `data-dreative-id` (design-page only).
|
|
388
|
+
15. Dark mode (when in scope): semantic-token swap, surface-lightness depth,
|
|
389
|
+
desaturated accents, tested both modes.
|
|
390
|
+
|
|
391
|
+
## 13. Mobile & touch adaptation (how ambitious effects degrade)
|
|
392
|
+
|
|
393
|
+
Ambitious designs die on phones first. Every effect gets an explicit mobile
|
|
394
|
+
strategy DECIDED AT DESIGN TIME, not patched after. The rule of thumb: touch
|
|
395
|
+
devices get a *different good design*, never a broken half-version of the
|
|
396
|
+
desktop one.
|
|
397
|
+
|
|
398
|
+
**Pointer effects** (cursor followers, magnetic pull, spotlight, tilt, hover
|
|
399
|
+
reveals): gate ALL of them behind `@media (hover: hover) and (pointer: fine)`.
|
|
400
|
+
On touch, whatever hover revealed must be visible by default or reachable by
|
|
401
|
+
tap — never lost. Custom cursors simply don't exist on touch; don't ship their
|
|
402
|
+
DOM/listeners there.
|
|
403
|
+
|
|
404
|
+
**Pinned/scrubbed sections**: pinning is fragile on mobile (URL-bar resize
|
|
405
|
+
fires viewport changes mid-pin; iOS momentum scroll skips scrub frames).
|
|
406
|
+
Strategies in preference order: (1) keep the pin but shorten it (≤ 1.5
|
|
407
|
+
viewports) and drive it with `position: sticky`, never JS pinning; (2) unpin —
|
|
408
|
+
the same content as stacked sections with simple in-view reveals;
|
|
409
|
+
(3) `ScrollTrigger.matchMedia()` / a `matchMedia` branch that swaps the whole
|
|
410
|
+
choreography. Never let a desktop pin length ride on a phone.
|
|
411
|
+
|
|
412
|
+
**Parallax & depth layers**: halve the differential on small screens (8-15% →
|
|
413
|
+
4-7%) or drop to zero; small viewports make parallax read as jitter. Layered
|
|
414
|
+
depth scenes collapse to 2 layers max.
|
|
415
|
+
|
|
416
|
+
**Drag-to-explore / spatial navigation**: on touch, drag conflicts with native
|
|
417
|
+
scroll. Either give the pannable surface a dedicated full-screen mode entered
|
|
418
|
+
by tap (with a visible close), or replace it with a swipeable carousel /
|
|
419
|
+
plain scrolling index. The conventional index route (immersive.md's escape
|
|
420
|
+
hatch) becomes the PRIMARY route on mobile, not the fallback.
|
|
421
|
+
|
|
422
|
+
**WebGL/canvas**: assume the phone GPU is 5-10× weaker and thermally throttled.
|
|
423
|
+
Tier at boot (`devicePixelRatio` capped at 2, sim resolution halved,
|
|
424
|
+
post-processing off) or swap the sim for a pre-rendered video loop / poster.
|
|
425
|
+
`deviceMemory`/first-dropped-frames checks pick the tier; a visible "reduce
|
|
426
|
+
effects" toggle when the brief allows.
|
|
427
|
+
|
|
428
|
+
**Layout & ergonomics floor** (extends checklist §12.12): tap targets ≥ 44px
|
|
429
|
+
with ≥ 8px gaps; primary actions in thumb reach (bottom half) on app-register
|
|
430
|
+
mobile; `100dvh` not `100vh`; no horizontal body scroll at 320px; type scale
|
|
431
|
+
clamps DOWN gracefully (hero ≥ 2rem, body stays ≥ 16px — iOS zooms inputs
|
|
432
|
+
under 16px); sticky navs shrink rather than stack; test the three widths 320 /
|
|
433
|
+
768 / 1280 mentally before responding.
|
|
434
|
+
|
|
435
|
+
**Motion budget on mobile**: entrance choreography total ≤ 600ms (vs 900ms
|
|
436
|
+
desktop), at most 1 scroll-driven sequence per page, marquees pause when
|
|
437
|
+
off-screen. Battery is a design constraint: continuous rAF loops must idle
|
|
438
|
+
when nothing animates.
|
|
439
|
+
|
|
440
|
+
## 14. Typography sourcing (kill the Inter-everywhere default)
|
|
441
|
+
|
|
442
|
+
The reflex-reject list (§3) says what NOT to reach for; this is where to reach
|
|
443
|
+
instead. All fonts below are free (Google Fonts or Fontshare/ITF). The
|
|
444
|
+
commercial fonts real award sites use — verified: unseen.co sets **Saol
|
|
445
|
+
Display Light/Italic + Neue Montreal**; unseen's Blossom lab sets **SangBleu
|
|
446
|
+
Serif + PP Neue Montreal**; capsul-in-pro sets **Messina Sans** — are the
|
|
447
|
+
targets; the pairings below are their honest free stand-ins, not lookalikes of
|
|
448
|
+
each other.
|
|
449
|
+
|
|
450
|
+
Per aesthetic register (display / body):
|
|
451
|
+
|
|
452
|
+
- **Cinematic & experimental** (unseen-like): light editorial serif with a
|
|
453
|
+
true italic for display — `Boska`, `Sentient`, or `Gelasio Light Italic` —
|
|
454
|
+
over a neutral grotesk body — `Switzer`, `Hanken Grotesk`. Mixing italic
|
|
455
|
+
serif words INTO a grotesk headline is the genre move (unseen does exactly
|
|
456
|
+
this). Mono microtype for HUD labels: `Fragment Mono` or `Martian Mono`.
|
|
457
|
+
- **Minimal / premium product**: one grotesk family carrying everything —
|
|
458
|
+
`General Sans`, `Switzer`, or `Schibsted Grotesk` in 3-4 weights. The
|
|
459
|
+
Neue Montreal / Messina Sans stand-in tier. Tight display tracking
|
|
460
|
+
(−0.02 to −0.04em), no second family.
|
|
461
|
+
- **Editorial / luxury**: `Zodiak` or `Besley` display over `Hanken Grotesk`
|
|
462
|
+
or `Switzer` body; small-caps eyebrows tracked +0.08em. (Reach here only
|
|
463
|
+
when §3's serif discipline is satisfied.)
|
|
464
|
+
- **Bold / brutalist / campaign**: `Clash Display` or `Cabinet Grotesk` (black
|
|
465
|
+
weights) display over `Switzer`/`General Sans` body; `Bricolage Grotesque`
|
|
466
|
+
when some warmth is wanted.
|
|
467
|
+
- **Playful / consumer** (lovvelavva-like DTC): `Cabinet Grotesk` or `Gambetta`
|
|
468
|
+
display, rounded moments via weight and spacing — NOT a rounded font —
|
|
469
|
+
over `Hanken Grotesk` body.
|
|
470
|
+
- **Corporate trust / clean business**: `Switzer` or system stack; Inter is
|
|
471
|
+
legitimate here (§3). Differentiate through scale contrast and spacing,
|
|
472
|
+
not font novelty.
|
|
473
|
+
|
|
474
|
+
Rules: still run §3's selection procedure — this list feeds step 3, it does
|
|
475
|
+
not replace the brand-voice reasoning. Self-host via Fontshare/google-webfonts
|
|
476
|
+
downloads (`font-display: swap`, preload the display weight only). Never ship
|
|
477
|
+
more than 2 families / ~5 weight files. If the brief names a commercial font
|
|
478
|
+
the project already licenses, use the real thing.
|