@3xhaust/oh-my-design 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ko.md +282 -0
- package/README.md +282 -0
- package/adapters/build.ts +184 -0
- package/adapters/claude.ts +111 -0
- package/adapters/codex.ts +68 -0
- package/adapters/tokens.ts +21 -0
- package/adapters/tool-map.json +7 -0
- package/bin/omd-install.ts +76 -0
- package/bin/omd.ts +1774 -0
- package/core/asset-sourcing/index.ts +187 -0
- package/core/coach/index.ts +98 -0
- package/core/composition/app-shell-workbench.md +168 -0
- package/core/composition/asymmetric-diagonal-grid.md +178 -0
- package/core/composition/bento-grid.md +223 -0
- package/core/composition/editorial-index-labels.md +173 -0
- package/core/composition/form-wizard-stepper.md +132 -0
- package/core/composition/master-detail-flow.md +129 -0
- package/core/composition/section-inversion.md +182 -0
- package/core/composition/sidebar-margin-annotation.md +184 -0
- package/core/composition/split-screen-hero.md +224 -0
- package/core/composition/sticky-sidebar-scroll.md +219 -0
- package/core/composition/typographic-hero.md +100 -0
- package/core/composition-contract/index.ts +233 -0
- package/core/composition-contract/visual-richness.ts +101 -0
- package/core/config/index.ts +27 -0
- package/core/copy/index.ts +296 -0
- package/core/craft/finish-pass.md +356 -0
- package/core/craft/index.ts +33 -0
- package/core/design/index.ts +581 -0
- package/core/design/interaction-states.ts +189 -0
- package/core/eval-harness/index.ts +225 -0
- package/core/evidence/final.ts +444 -0
- package/core/evidence/task.ts +459 -0
- package/core/figma/client.ts +312 -0
- package/core/figma/diff.ts +261 -0
- package/core/figma/responsive.ts +310 -0
- package/core/figma/system.ts +466 -0
- package/core/figma/types.ts +185 -0
- package/core/frame/check-ux.ts +180 -0
- package/core/frame/index.ts +39 -0
- package/core/frame/write.ts +168 -0
- package/core/graphics/css-illustration-primitives.md +189 -0
- package/core/graphics/duotone-image-presets.md +173 -0
- package/core/graphics/gradient-mesh.md +178 -0
- package/core/graphics/noise-grain-texture.md +150 -0
- package/core/graphics/placeholder-policy.md +185 -0
- package/core/graphics/svg-geometric-patterns.md +145 -0
- package/core/history/index.ts +39 -0
- package/core/install/detect.ts +32 -0
- package/core/install/install.ts +321 -0
- package/core/install/patch-claude.ts +109 -0
- package/core/install/patch-codex.ts +82 -0
- package/core/interaction/index.ts +101 -0
- package/core/interaction/recipes/signature-lighting.md +203 -0
- package/core/ir/dom.ts +352 -0
- package/core/ir/normalize.ts +177 -0
- package/core/motion/easing.md +151 -0
- package/core/motion/energy.ts +188 -0
- package/core/motion/recipes/image-hover-distortion.md +198 -0
- package/core/motion/recipes/magnetic-hover.md +229 -0
- package/core/motion/recipes/marquee.md +202 -0
- package/core/motion/recipes/number-counter.md +242 -0
- package/core/motion/recipes/page-loader.md +240 -0
- package/core/motion/recipes/parallax.md +233 -0
- package/core/motion/recipes/scroll-reveal.md +210 -0
- package/core/motion/recipes/section-color-inversion.md +217 -0
- package/core/motion/recipes/split-text-entrance.md +222 -0
- package/core/motion/recipes/stagger-orchestrator.md +227 -0
- package/core/motion/recipes/sticky-scene-transition.md +246 -0
- package/core/motion/recipes/view-transitions.md +239 -0
- package/core/probe/index.ts +186 -0
- package/core/probe/schema.json +46 -0
- package/core/protocol/composition-contract.md +192 -0
- package/core/protocol/copy-deck.md +96 -0
- package/core/protocol/human-design-loop.md +447 -0
- package/core/protocol/slop-review.md +71 -0
- package/core/ref/batch.ts +94 -0
- package/core/ref/blueprint.ts +199 -0
- package/core/ref/distance.ts +225 -0
- package/core/ref/invariants.ts +162 -0
- package/core/ref/signal.ts +37 -0
- package/core/ref/store.ts +122 -0
- package/core/render/index.ts +607 -0
- package/core/rules/attribution.ts +159 -0
- package/core/rules/builtin/contrast.yaml +8 -0
- package/core/rules/builtin/focus.yaml +8 -0
- package/core/rules/builtin/hit-area.yaml +8 -0
- package/core/rules/builtin/ko.yaml +6 -0
- package/core/rules/builtin/motion.yaml +80 -0
- package/core/rules/builtin/slop.yaml +365 -0
- package/core/rules/builtin/spacing.yaml +9 -0
- package/core/rules/builtin/system.yaml +42 -0
- package/core/rules/builtin/token.yaml +8 -0
- package/core/rules/builtin/ux.yaml +125 -0
- package/core/rules/engine.ts +88 -0
- package/core/rules/leakage.ts +72 -0
- package/core/rules/motion-spec.ts +204 -0
- package/core/site/index.ts +100 -0
- package/core/slop/index.ts +427 -0
- package/core/slop/text-slop.ts +220 -0
- package/core/source-seal/index.ts +174 -0
- package/core/stack/index.ts +53 -0
- package/core/target/index.ts +183 -0
- package/core/theory/color.md +285 -0
- package/core/theory/components.md +272 -0
- package/core/theory/craft.md +270 -0
- package/core/theory/expressive.md +213 -0
- package/core/theory/imagegen.md +105 -0
- package/core/theory/layout.md +159 -0
- package/core/theory/motion.md +283 -0
- package/core/theory/typography.md +134 -0
- package/core/theory/ux.md +580 -0
- package/core/theory/voice.md +595 -0
- package/core/types.ts +684 -0
- package/package.json +40 -0
- package/src/agents/composer.agent.yaml +174 -0
- package/src/agents/eye.agent.yaml +208 -0
- package/src/agents/framer.agent.yaml +52 -0
- package/src/agents/glance.agent.yaml +19 -0
- package/src/agents/hand.agent.yaml +200 -0
- package/src/agents/scout.agent.yaml +71 -0
- package/src/agents/sketch.agent.yaml +64 -0
- package/src/agents/typesetter.agent.yaml +52 -0
- package/src/agents/writer.agent.yaml +63 -0
- package/src/skills/omd-coach/SKILL.md +40 -0
- package/src/skills/omd-critique/SKILL.md +77 -0
- package/src/skills/omd-figma/SKILL.md +256 -0
- package/src/skills/omd-humanize/SKILL.md +160 -0
- package/src/skills/omd-scout/SKILL.md +77 -0
- package/src/skills/omd-ultradesign/SKILL.md +521 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Craft — decision material
|
|
2
|
+
|
|
3
|
+
These are the decisions that separate work that looks designed from work that looks
|
|
4
|
+
generated. None of them appear in textbooks as principles; they are accumulated from
|
|
5
|
+
practitioners watching what fails and adjusting. Every entry is a condition → choice →
|
|
6
|
+
reason triple, verified against real practice.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Shadows: layered and coloured, never single-heavy
|
|
11
|
+
|
|
12
|
+
A single dense shadow — `box-shadow: 0 4px 20px rgba(0,0,0,0.4)` — reads as generated.
|
|
13
|
+
It is the shadow that appears when someone types "add a box shadow" and accepts the
|
|
14
|
+
default. It looks heavy, uniform, and unnatural because nothing in the physical world casts
|
|
15
|
+
light that way.
|
|
16
|
+
|
|
17
|
+
Natural shadow results from at least two light interactions: the ambient light that fills
|
|
18
|
+
a space with soft diffuse shadow, and the direct light that casts a sharp shadow close
|
|
19
|
+
beneath the object. Adam Wathan and Steve Schoger (*Refactoring UI*, 2018) document this
|
|
20
|
+
as the two-shadow system: a small, tight shadow directly beneath the element (sharp, low
|
|
21
|
+
opacity, small blur radius) and a larger, softer shadow extending further (large blur,
|
|
22
|
+
very low opacity). The two together read as physically plausible in a way a single shadow
|
|
23
|
+
cannot.
|
|
24
|
+
|
|
25
|
+
The values: a card at moderate elevation might use
|
|
26
|
+
`box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 4px 16px rgba(0,0,0,0.08)`. The first shadow
|
|
27
|
+
places the card; the second lifts it. Combined opacity stays low — the visual weight
|
|
28
|
+
is distributed across both.
|
|
29
|
+
|
|
30
|
+
**Coloured shadows** extend the system further. A shadow cast beneath a blue button does
|
|
31
|
+
not need to be grey — it can be a dark desaturated blue. This is how physical coloured
|
|
32
|
+
objects cast coloured shadows (ambient lighting takes on the hue of the emitting surface).
|
|
33
|
+
A coloured shadow reads as considered rather than default, and it ties the shadow to the
|
|
34
|
+
element's own colour system, making the depth feel coherent.
|
|
35
|
+
|
|
36
|
+
Condition → choice → reason: when adding elevation, compose two shadows at low opacity
|
|
37
|
+
rather than one at high opacity. When the element has a distinct brand colour, tint the
|
|
38
|
+
shadow toward that hue at 20–30% saturation.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Borders vs background contrast: the separation decision
|
|
43
|
+
|
|
44
|
+
Borders are not the only way to separate things. They are the heaviest way, and they add
|
|
45
|
+
the most noise.
|
|
46
|
+
|
|
47
|
+
Three alternatives work better in most situations:
|
|
48
|
+
|
|
49
|
+
**Background contrast**: adjacent elements with slightly different background colours read
|
|
50
|
+
as separate without a line between them. A sidebar at `#F7F7F7` and a content area at
|
|
51
|
+
`#FFFFFF` need no border — the contrast between them creates the separation. This is the
|
|
52
|
+
technique behind most modern sidebars, navigation panels, and card layouts where the
|
|
53
|
+
"border" is actually a 5% luminance difference. Wathan and Schoger (*Refactoring UI*)
|
|
54
|
+
name this explicitly: "Giving adjacent elements slightly different background colors is
|
|
55
|
+
usually all you need to create distinction between them."
|
|
56
|
+
|
|
57
|
+
**Space as separator**: if two elements have enough gap between them, the negative space
|
|
58
|
+
reads as the boundary. A group of form fields at 24px internal gap and 48px between
|
|
59
|
+
sections needs no horizontal rule — the spacing hierarchy is the divider.
|
|
60
|
+
|
|
61
|
+
**Subtle box-shadow as outline**: `box-shadow: 0 0 0 1px rgba(0,0,0,0.06)` creates a
|
|
62
|
+
visible border-weight outline without the hard, opaque line of `border: 1px solid`. At low
|
|
63
|
+
opacity, this reads as surface definition rather than containment — appropriate for cards
|
|
64
|
+
on white backgrounds where a hard border would create visual noise.
|
|
65
|
+
|
|
66
|
+
The rule: use a border when none of these three alternatives produce sufficient separation.
|
|
67
|
+
In practice, this means borders are reserved for form inputs (where the border communicates
|
|
68
|
+
interactivity, not just separation), data tables (where the row-column structure requires
|
|
69
|
+
explicit lines for alignment), and code blocks.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Text hierarchy: opacity over grey
|
|
74
|
+
|
|
75
|
+
When designing on a coloured background — a dark surface, a brand-coloured header, a card
|
|
76
|
+
with a coloured fill — secondary text is often set in a lighter grey to signal its lower
|
|
77
|
+
importance. This fails on coloured backgrounds: a fixed grey hex sits at the wrong
|
|
78
|
+
luminance relative to the background, either too light (insufficient contrast) or too dark
|
|
79
|
+
(indistinguishable from primary text).
|
|
80
|
+
|
|
81
|
+
The correct technique is opacity on white (or the background-adjacent colour), not a
|
|
82
|
+
separate grey value. Primary text: white at 87–90% opacity. Secondary text: white at
|
|
83
|
+
55–65% opacity. Tertiary / disabled: white at 35–40% opacity. These values come from
|
|
84
|
+
Material Design's dark theme specification and have been independently confirmed as
|
|
85
|
+
the correct perceptual steps.
|
|
86
|
+
|
|
87
|
+
The reason opacity outperforms fixed hex on coloured surfaces: opacity lets the background
|
|
88
|
+
colour bleed through. The secondary text picks up the surface hue, which makes it feel
|
|
89
|
+
native to the surface rather than pasted on. A fixed grey on a dark blue card looks like
|
|
90
|
+
a grey text on a blue background; an 60% opacity white on a dark blue card looks like
|
|
91
|
+
dim text that belongs on that card.
|
|
92
|
+
|
|
93
|
+
On light backgrounds, the same logic applies in reverse: use black (or the text colour)
|
|
94
|
+
at different opacity levels for hierarchy, rather than separate grey tokens. The cascade
|
|
95
|
+
reads as a single family at different weights of presence, not as multiple colours
|
|
96
|
+
competing.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Optical alignment: why mathematical centre is wrong
|
|
101
|
+
|
|
102
|
+
Centering by coordinate is not the same as centering by perception. The eye processes
|
|
103
|
+
visual weight, not coordinates; a perfectly centred element that carries more visual weight
|
|
104
|
+
at the top will appear to sit too low.
|
|
105
|
+
|
|
106
|
+
**The most common violation**: icons inside circular or square containers. A triangle
|
|
107
|
+
icon centred by coordinate at the geometric centre of its container appears to float too
|
|
108
|
+
high, because the triangle carries visual mass at its base and open space at its peak.
|
|
109
|
+
Correct optical alignment moves the icon 1–2px downward from coordinate centre.
|
|
110
|
+
|
|
111
|
+
**The second-most common violation**: icons beside text. An icon at 16px placed alongside
|
|
112
|
+
16px text is not optically aligned — the icon's visual centre and the text's cap height
|
|
113
|
+
are at different heights. The correct alignment is not to align the icon's bounding box
|
|
114
|
+
midpoint to the text's bounding box midpoint; it is to align the icon's optical centre
|
|
115
|
+
to the text's cap height. This often requires the icon to be 1–2px lower than a strict
|
|
116
|
+
middle-align would place it. Rauno Freiberg's web interface guidelines (interfaces.rauno.me)
|
|
117
|
+
note that when text and icons sit side by side, adjustment of weight, size, or position is
|
|
118
|
+
required so they don't clash visually.
|
|
119
|
+
|
|
120
|
+
**The third violation**: padding on buttons. A button with 16px padding top and bottom
|
|
121
|
+
appears to sit low if the label is a capital-heavy word, because the ascenders occupy
|
|
122
|
+
optical space that descenders do not. Adding 1px of extra top padding corrects it
|
|
123
|
+
optically while maintaining the stated 16px value in both directions.
|
|
124
|
+
|
|
125
|
+
Condition → choice → reason: when an element "looks off" despite correct coordinate
|
|
126
|
+
values, the issue is optical weight distribution. Adjust by eye in 1px increments until
|
|
127
|
+
the perception matches the intent, then document the deviation.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Optical balance vs mathematical symmetry
|
|
132
|
+
|
|
133
|
+
A symmetrical layout is not always a balanced one. Mathematical symmetry places elements
|
|
134
|
+
at equal distances from a central axis; optical balance places them at positions where
|
|
135
|
+
they carry equal visual weight.
|
|
136
|
+
|
|
137
|
+
The most common asymmetry that reads as balance: a heavy text block on one side paired
|
|
138
|
+
with a large open area on the other, because white space carries visual weight. Müller-
|
|
139
|
+
Brockmann's grid work (and its later formalisation in Josef Albers' compositional studies)
|
|
140
|
+
establishes that a large empty area "pushes back" against a dense content block — the
|
|
141
|
+
result is tension and balance, not imbalance.
|
|
142
|
+
|
|
143
|
+
The practical consequence: a design that looks "too light on the right" may not need more
|
|
144
|
+
content on the right. It may need the existing content moved slightly left, or a single
|
|
145
|
+
visual anchor (a horizontal rule, a colour block, a differently weighted element) on the
|
|
146
|
+
right that resolves the imbalance without filling the space.
|
|
147
|
+
|
|
148
|
+
Symmetry is a statement. Perfect bilateral symmetry says "this is formal and restrained."
|
|
149
|
+
Near-symmetry with deliberate asymmetric elements says "this is considered." Accidental
|
|
150
|
+
asymmetry — elements placed symmetrically by coordinate that read as unbalanced because
|
|
151
|
+
of optical weight — says "nobody checked."
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Hover states: compound changes over brightness alone
|
|
156
|
+
|
|
157
|
+
Changing brightness on hover — lighter on hover of a dark element, darker on hover of a
|
|
158
|
+
light one — is the default hover behavior and produces the least interesting result.
|
|
159
|
+
It communicates "interactive" but nothing else. Compound hover changes communicate more.
|
|
160
|
+
|
|
161
|
+
A hover state can change multiple properties simultaneously to produce a richer signal:
|
|
162
|
+
|
|
163
|
+
- **Background + shadow**: the background lightens slightly and a subtle shadow appears,
|
|
164
|
+
suggesting the element is rising off the surface to meet the cursor. This communicates
|
|
165
|
+
elevation change rather than just colour change.
|
|
166
|
+
|
|
167
|
+
- **Colour + underline reveal**: for text links, a colour shift combined with an underline
|
|
168
|
+
appearing on hover communicates "this is a link" more reliably than either signal alone.
|
|
169
|
+
The underline is the semantic signal; the colour shift is the visual confirmation.
|
|
170
|
+
|
|
171
|
+
- **Scale + shadow**: a slight scale increase (`transform: scale(1.02)`) on a card combined
|
|
172
|
+
with a shadow increase communicates physical lift — the card rises. Scale alone without
|
|
173
|
+
shadow reads as zoom; shadow alone without scale reads as flat highlighting.
|
|
174
|
+
|
|
175
|
+
Rauno Freiberg's guidelines specify that font weight should remain consistent on hover
|
|
176
|
+
or selected states to prevent layout shifts — a `font-weight` change on hover causes
|
|
177
|
+
surrounding text to reflow, which is distracting even at the character level. Use `bold`
|
|
178
|
+
for initial state or accept that the hover state cannot add weight.
|
|
179
|
+
|
|
180
|
+
The constraint from `prefers-reduced-motion`: all hover transitions must be instant (or
|
|
181
|
+
very short) when `prefers-reduced-motion: reduce` is active. A compound hover transition
|
|
182
|
+
that takes 200ms looks fine; the same 200ms transition replaying on every link in a dense
|
|
183
|
+
page layout is distracting. Scale transformations in particular should be removed or
|
|
184
|
+
reduced to zero duration under `prefers-reduced-motion`.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 60fps-safe properties
|
|
189
|
+
|
|
190
|
+
Not all CSS properties are created equal for animation. The browser rendering pipeline
|
|
191
|
+
processes properties in three stages: layout (positioning, sizing), paint (colour,
|
|
192
|
+
background, shadow), and composite (transform, opacity). Only composite-stage properties
|
|
193
|
+
can be offloaded to the GPU and animated without touching the layout or paint pipeline.
|
|
194
|
+
|
|
195
|
+
**Safe for animation** (composite only — 60fps on all reasonable hardware):
|
|
196
|
+
- `transform: translate()`, `rotate()`, `scale()`
|
|
197
|
+
- `opacity`
|
|
198
|
+
|
|
199
|
+
**Unsafe for animation** (trigger layout or paint — cause jank on mid-range devices):
|
|
200
|
+
- `width`, `height`, `top`, `left`, `bottom`, `right`
|
|
201
|
+
- `padding`, `margin`
|
|
202
|
+
- `border-width`
|
|
203
|
+
- `background-color` (triggers paint, not layout — less severe but not free)
|
|
204
|
+
- `box-shadow` (triggers paint on every frame)
|
|
205
|
+
|
|
206
|
+
The practical constraint for design: if the visual effect requires animating a property
|
|
207
|
+
not on the safe list, re-examine whether the effect can be achieved through transform and
|
|
208
|
+
opacity instead. A "growing border" on hover can be achieved with a `box-shadow` inset of
|
|
209
|
+
0 opacity transitioning to opacity 1 — or better, with a `transform: scaleX()` on a
|
|
210
|
+
pseudo-element. A "sliding in from the side" panel should use `transform: translateX()`,
|
|
211
|
+
not `left: -100%` to `left: 0`. The design constraints are the engineering constraints.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## The "design is boring" checklist
|
|
216
|
+
|
|
217
|
+
When a design feels flat or unresolved and you do not know what to change, this checklist
|
|
218
|
+
provides the diagnostic. Each item identifies a specific deficiency and its correction.
|
|
219
|
+
|
|
220
|
+
**1. Contrast scale is too narrow.** All text is at similar sizes. The solution is to make
|
|
221
|
+
the most important element dramatically larger — not 20% larger, but 2–3× larger. Dramatic
|
|
222
|
+
scale contrast reads as intentional hierarchy; mild scale difference reads as inconsistency.
|
|
223
|
+
|
|
224
|
+
**2. Everything is centred.** Centring is emphasis. When everything is centred, emphasis
|
|
225
|
+
is absent. Left-align body content, reserve centring for single-line headlines and
|
|
226
|
+
isolated call-out elements.
|
|
227
|
+
|
|
228
|
+
**3. The colour palette has no accent.** All colours are muted or neutral — there is
|
|
229
|
+
nothing with visual energy. Add one high-saturation or high-contrast element in the accent
|
|
230
|
+
role, even briefly, and the composition becomes legible.
|
|
231
|
+
|
|
232
|
+
**4. Alignment axes are too consistent.** When every element aligns on the same left edge
|
|
233
|
+
and the same grid column, the design reads as orderly but static. One intentional
|
|
234
|
+
misalignment — a large decorative element that bleeds past the grid, a pull quote indented
|
|
235
|
+
from the main measure — creates movement. But only one: two misalignments become chaos.
|
|
236
|
+
|
|
237
|
+
**5. Weight ladder is too flat.** Text throughout the design uses the same weight. The
|
|
238
|
+
hierarchy exists only through size. Add weight contrast: the primary content at
|
|
239
|
+
`font-weight: 600`, secondary at 400, tertiary at 400 and reduced opacity. The weight
|
|
240
|
+
ladder is the cheapest hierarchy tool available.
|
|
241
|
+
|
|
242
|
+
**6. There is no breathing room.** Padding and margins are too conservative. The
|
|
243
|
+
conventional instinct is to pack content because packed content "shows more value." Empty
|
|
244
|
+
space reads as confidence; packed space reads as uncertainty. Double the padding on the
|
|
245
|
+
most important element and observe whether it reads as more important, not less.
|
|
246
|
+
|
|
247
|
+
**7. No element is unexpected.** Everything is where the user expects it to be, at the
|
|
248
|
+
scale they expect it. Introduce one element that is larger, different, or placed
|
|
249
|
+
differently than its role would suggest. This is the Von Restorff mechanism: the
|
|
250
|
+
unexpected element is what gets remembered.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Sources
|
|
255
|
+
|
|
256
|
+
- Wathan & Schoger, *Refactoring UI* (2018 / refactoringui.com) — two-shadow system,
|
|
257
|
+
borders vs background contrast, colour hierarchy on coloured backgrounds, two-weight
|
|
258
|
+
system for text hierarchy
|
|
259
|
+
- Rauno Freiberg, Web Interface Guidelines (interfaces.rauno.me) — optical alignment of
|
|
260
|
+
icons and text, hover weight consistency, animation duration ceiling, tabular figures
|
|
261
|
+
- Material Design 3 (2023) — white-opacity text hierarchy on dark surfaces (87%/60%/38%),
|
|
262
|
+
GPU-composited animation properties
|
|
263
|
+
- Müller-Brockmann, *Grid Systems in Graphic Design* (1981) — optical balance and the
|
|
264
|
+
visual weight of negative space
|
|
265
|
+
- Albers, *Interaction of Color* (1963) — visual weight, optical perception of spatial
|
|
266
|
+
relationships, the inadequacy of coordinate-based alignment
|
|
267
|
+
- von Restorff, "Über die Wirkung von Bereichsbildungen im Spurenfeld" (1933) — the
|
|
268
|
+
isolation effect and why one unexpected element produces memory while many produce none
|
|
269
|
+
- Google Chrome Developers, "Stick to Compositor-Only Properties and Manage Layer Count"
|
|
270
|
+
(developers.google.com) — composite-only animation properties, paint and layout costs
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Expressive — decision material
|
|
2
|
+
|
|
3
|
+
An award-winning site is not one that does more. It is one where every choice points at the same thing. Awwwards puts the scoring on record: Design 40%, Usability 30%, Creativity 20%, Content 10% (awwwards.com/about-evaluation). The arithmetic is the argument. Creativity — the axis where spectacular effects live — accounts for one-fifth of the score. Usability accounts for thirty percent. A site that trades navigability for spectacle is betting against the judges' own rubric. The sites that win do so on Design and Usability combined, which means art direction that holds up under use, not technique that demands admiration.
|
|
4
|
+
|
|
5
|
+
This file is decision material for the register axis. It is not a catalogue of cool things to do. It is a condition→choice→reason map for when expressive technique earns its place and when it does not.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## The register decision
|
|
10
|
+
|
|
11
|
+
Every brief implies a register. The register is not the visual style — it is the intensity of the directed experience. Three positions on the axis:
|
|
12
|
+
|
|
13
|
+
**quiet**: The interface recedes. The user's work or content is the event. Dashboards, documentation, tools, reading-first products. Motion is near-zero. Typography is functional. Restraint is not timidity; it is the correct reading of what the user came to do.
|
|
14
|
+
|
|
15
|
+
**confident**: A position is visible but the interface does not perform. Brand sites, editorial products, most portfolio work. One thing is done well — a considered type scale, a deliberate palette — and nothing else competes. This is where most good work lives.
|
|
16
|
+
|
|
17
|
+
**showpiece**: The interface is the event. Brand campaign microsites, agency portfolios, product launches with a single CTA, experiential landing pages. The user came partly to experience being here. Awwwards SOTD, FWA, GDWEB — these are showpiece contexts. The register commits to one signature moment and builds everything toward it.
|
|
18
|
+
|
|
19
|
+
The error is applying showpiece technique to quiet or confident contexts. A dashboard with split-text entrances is not ambitious; it is misread. The thirty-percent Usability weight does not become a thirty-percent weight only when the judges disagree with your taste — it applies regardless of intent. Usability 30% is the reason showpiece technique must still serve navigation and clarity, not just aesthetic ambition.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## The anatomy of award-level sites
|
|
24
|
+
|
|
25
|
+
### A concept-bearing line can replace an image
|
|
26
|
+
|
|
27
|
+
On some showpiece sites, a short actual headline becomes the visual event. The face and
|
|
28
|
+
weight must carry the concept; size alone is not a concept. The pre-structure typography
|
|
29
|
+
proof tests target-language glyphs, loading, fallback, wrapping, and the availability of
|
|
30
|
+
secondary hierarchy and CTA at desktop and mobile.
|
|
31
|
+
|
|
32
|
+
Size derives from the real copy and container. `clamp()`, container queries, media queries,
|
|
33
|
+
and discrete steps are all valid when specimens justify them. A moderate heading can pass;
|
|
34
|
+
huge Hangul can also pass when its syllable rhythm is concept-bearing and proof-clean. A
|
|
35
|
+
long heavy line that becomes a clipped mobile wall fails even if one desktop render works.
|
|
36
|
+
|
|
37
|
+
### Scroll is the narrative axis
|
|
38
|
+
|
|
39
|
+
On a showpiece site, sections are not containers — they are scenes. The order of scroll is the order of a story: exposition, complication, turn, resolution. If the sections could be reordered without loss, there is no scroll narrative, only content in a column.
|
|
40
|
+
|
|
41
|
+
The structural implication: the first scene commits to the register, the middle scenes develop it, and the footer scene closes it. A footer that reverts to default template styling breaks the narrative as certainly as a film that ends with stock footage.
|
|
42
|
+
|
|
43
|
+
CSS scroll-driven animations (the `animation-timeline: scroll()` and `view()` properties, now available in Chromium and WebKit as of 2024) enable scroll-linked motion without JavaScript. The correct fallback for unsupported browsers is the static layout — which must be designed to stand without the motion. An experience that is illegible when still is not a scroll narrative; it is content that depends on JavaScript to exist.
|
|
44
|
+
|
|
45
|
+
### The first three seconds declare the register
|
|
46
|
+
|
|
47
|
+
A loader or entrance animation on a showpiece site is not a technical necessity — it is the opening sentence. It tells the user: this is what kind of experience you are in. A loader that runs longer than the asset load time is a loader that is costing more than it earns. The outer bound is three seconds; under one second is the performance target. Beyond that, a fast site is made to feel slow, and the Usability score suffers before the user has seen a single thing.
|
|
48
|
+
|
|
49
|
+
What the entrance must do in those seconds: commit the palette, declare the type register, establish the motion vocabulary. A loader that is only a spinner followed by a page reveal has wasted the three seconds it consumed.
|
|
50
|
+
|
|
51
|
+
### The concept must survive to the footer
|
|
52
|
+
|
|
53
|
+
A showpiece site that loses its nerve in the footer — reverting to small-print-grey, default columns, four generic links — reveals that the expressive register was applied to the hero and nowhere else. Applied design covers the whole surface. The footer is a scene. It may be quieter than the hero, but it is not absent.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Slop-free is not the same as distinctive
|
|
58
|
+
|
|
59
|
+
Passing every slop gate proves the absence of a known defect. It does not prove the presence of a design. A layout can be measurably clean — correct contrast, no triple-radius, no gradient-mesh cliché, one primary action — and still read as AI-made, because the composition itself is the most predictable arrangement of its parts. Distinction is a positive property the gates cannot supply; it has to be committed on purpose.
|
|
60
|
+
|
|
61
|
+
The AI-made feel is not one slop pattern. It is the sum of safe defaults: symmetric balance, boxed regions, evenly-weighted columns, and the single most common arrangement for the content type. A skeptical viewer reads it in one second — "a model produced the reasonable layout" — and that read is the failure, independent of any individual clean metric.
|
|
62
|
+
|
|
63
|
+
### Template tells (clean, but generic)
|
|
64
|
+
|
|
65
|
+
Each is a layout that survives the slop scan and still announces a template. Treat a match as a distinction failure to break, not a pass.
|
|
66
|
+
|
|
67
|
+
- **Symmetric hero split**: oversized headline on the left, a bordered panel or card on the right, balanced masses. Two competing primary masses is the usual side effect — the eye cannot find the one thing that matters first.
|
|
68
|
+
- **Triple feature-cards with arrows**: three equal-weight boxes (SIGNAL → SYSTEM → PROOF, or any A → B → C) joined by arrows. The single most templated way to show a process; recognizable as generated at a glance.
|
|
69
|
+
- **Trend-decoration as identity**: an offset drop-shadow, a glassmorphism blur, or a gradient border used as *the* idea rather than in service of one. A dated trend applied evenly is not art direction.
|
|
70
|
+
- **Boxed everything**: every region gets a border, a radius, and equal padding, so nothing dominates and the grid never breaks. Uniform containment reads as a system, not a composition.
|
|
71
|
+
- **Unused real material**: the brief supplies photographs, slides, a portrait, or data, and the layout still leads with text-in-boxes. Authentic material left out of the composition is the clearest tell that the layout was reasoned in the abstract.
|
|
72
|
+
|
|
73
|
+
### The one-risk requirement
|
|
74
|
+
|
|
75
|
+
A distinctive composition commits at least one genuine risk a template would not take, grounded in the concept and never in decoration: a deliberate asymmetry that directs the eye to one mass; a scale or weight contrast large enough to read as a decision, not a default; a grid break at the one moment that matters; or the real supplied material (image, portrait, slide, dataset) made structural rather than illustrative. One committed risk beats five safe refinements. If a candidate reads as "the reasonable layout," it has not earned the register — name the template it resembles and depart from it once, on purpose.
|
|
76
|
+
|
|
77
|
+
### The AI-SaaS landing tells (the specific template to break)
|
|
78
|
+
|
|
79
|
+
The most common generic result is the AI-SaaS landing page. Every item below is a tell to avoid, not a default to reach for — a design that matches the checklist reads as machine-made in one second regardless of polish.
|
|
80
|
+
|
|
81
|
+
- **Layout**: a centered hero (big one-line headline, short subhead, prompt box), a logo wall, then every section as a 3-column card grid with a small eyebrow label ("Features", "Use cases", "Testimonials"); sections divided only by gradient blobs; everything floating centered with left/right balance but no tension; more whitespace than the content earns; the same card component repeated down the page.
|
|
82
|
+
- **Fabricated proof**: a pretty UI mockup instead of a real product screenshot, with invented dashboard data and cliché figures (98%, 10x, 24/7). This is also a fabrication violation — never ship invented numbers or a fake product screen (see `graphics/placeholder-policy.md`).
|
|
83
|
+
- **Type**: a safe SaaS sans (Inter/Geist/Satoshi feel), an over-formal size hierarchy, grey body, a slightly faded subhead, one word (usually "AI") set in a purple gradient, keywords in pills, every sentence the same length — pretty type with no brand voice.
|
|
84
|
+
- **Copy**: the phrases in `theory/voice.md` and the `omd text-slop` scanner — "Supercharge your workflow", "Work smarter not harder", "Unlock your creativity", "AI-powered", "10x", "No code required", "The future of", "Next-generation", "let AI do the heavy lifting", "effortless".
|
|
85
|
+
- **UX (product surfaces)**: the tool suggests before the user acts; empty states full of "Try asking…" chips; a bigger Regenerate than Edit; "shorter / longer / change tone" buttons; thumbs up/down and "Was this helpful?"; "Option 1, 2, 3" instead of one committed answer; "Analyzing… / Generating…" theatre. These make the product feel like a demo of AI, not a tool that solves a problem.
|
|
86
|
+
|
|
87
|
+
The underlying failure — why designers call it "AI slop" — is mood before function, no brand specificity, seen-it-before, unaudited details, visual density high but information density low, no tension or rhythm or contrast, no human life, too average, too safe. The fix is never more effects; it is one concrete, brand-specific, evidence-grounded decision a template would not make.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Technique catalogue
|
|
92
|
+
|
|
93
|
+
Each entry names the condition under which the technique earns its place and the condition under which it does not.
|
|
94
|
+
|
|
95
|
+
### Split-text entrance (character- or word-level stagger)
|
|
96
|
+
|
|
97
|
+
**Condition for use**: The hero type is the primary visual event and the words are part of the concept — something is being said, not just displayed. The split reveals meaning progressively: each word or line lands with intent.
|
|
98
|
+
|
|
99
|
+
**Condition against**: Body copy, UI labels, secondary headings, any text the user will need to skim. Split-text on body copy turns reading into waiting. It is the most common technique deployed too broadly. GSAP SplitText and SplitType both require JavaScript; the fallback state (no JS, or reduced-motion) must show the complete text, not an empty space.
|
|
100
|
+
|
|
101
|
+
**Implementation constraint**: Stagger between siblings at 40–80ms. Beyond 80ms the entrance becomes a waterfall the user watches rather than reads.
|
|
102
|
+
|
|
103
|
+
### CSS scroll-driven animations / IntersectionObserver reveals
|
|
104
|
+
|
|
105
|
+
**Condition for use**: The content is a scroll narrative — sections have a sequential logic, and the reveal of each section reinforces the sequence. The animation is `transform` and `opacity` only; nothing that touches layout.
|
|
106
|
+
|
|
107
|
+
**Condition against**: Product UI that the user came to operate. Navigation elements. Any element the user needs to see immediately on scroll — a reveal that delays reading is a usability failure regardless of how well-timed it is.
|
|
108
|
+
|
|
109
|
+
**Implementation**: CSS scroll-driven animations (`animation-timeline: scroll()` / `view()`) are the first choice — they run off the main thread and require no JavaScript. IntersectionObserver is the fallback for broader browser support. The static layout must be complete and functional without the motion layer.
|
|
110
|
+
|
|
111
|
+
### Viewport-filling marquee
|
|
112
|
+
|
|
113
|
+
**Condition for use**: The marquee carries a message that is part of the concept — a repeated claim, a rhythmic brand phrase, a counter. The motion is continuous and low-velocity; it does not compete with adjacent interactive elements.
|
|
114
|
+
|
|
115
|
+
**Condition against**: Navigation areas, any context where the user is reading or interacting with nearby content. A marquee adjacent to a form field splits attention between peripheral motion and the focal task — vestibular disruption for users with motion sensitivity, even when `prefers-reduced-motion` is honoured. In reduced-motion contexts, the marquee must stop.
|
|
116
|
+
|
|
117
|
+
### Custom cursor (desktop, pointer media query)
|
|
118
|
+
|
|
119
|
+
**Condition for use**: The cursor reinforces the concept in a way no other element can — it follows the user's intent, so it is always in the interaction zone. Effective on portfolio and agency sites where the cursor is part of the brand vocabulary (Awwwards, awwwards.com/customize-your-mouse-cursor).
|
|
120
|
+
|
|
121
|
+
**Condition against**: Touch devices (the cursor does not exist). Any context where the interactive affordance of links and buttons needs to be clear without hover cues — custom cursors routinely break the expected `cursor: pointer` signal. Must be scoped with `@media (pointer: fine)` so it never activates on touch. On mobile it is invisible; its absence must not degrade the layout.
|
|
122
|
+
|
|
123
|
+
### Image hover distortion / filter
|
|
124
|
+
|
|
125
|
+
**Condition for use**: A gallery or portfolio grid where the hover state deepens engagement with a piece before the user clicks. The distortion (WebGL ripple, CSS filter shift, GSAP hover tween) must complete in under 150ms for hover onset and under 200ms to settle. Anything slower reads as broken.
|
|
126
|
+
|
|
127
|
+
**Condition against**: Product images where accuracy matters (e-commerce, documentation). Navigation thumbnails where the user is trying to read text.
|
|
128
|
+
|
|
129
|
+
### Grain / noise texture
|
|
130
|
+
|
|
131
|
+
**Condition for use**: Flat backgrounds or smooth gradients that read as too digital — noise adds the tactile quality that solid fills lack. The CSS-Tricks SVG filter technique (an `feTurbulence` filter composited at low opacity over a background) adds texture without weight. Particularly effective over mesh gradients, where it reduces banding.
|
|
132
|
+
|
|
133
|
+
**Condition against**: Over photography or video (redundant). On text (degrades legibility at small sizes). At high opacity on any element (reads as low-resolution encoding, not design).
|
|
134
|
+
|
|
135
|
+
### Asymmetric / diagonal grid
|
|
136
|
+
|
|
137
|
+
**Condition for use**: The concept requires tension — an editorial feeling where elements do not settle into comfortable columns. One diagonal or off-grid element is a decision; a page full of diagonal elements is entropy.
|
|
138
|
+
|
|
139
|
+
**Condition against**: Data-heavy layouts where scanability is the primary requirement. Tables, forms, anything the user reads in order.
|
|
140
|
+
|
|
141
|
+
### Section colour inversion (dark ↔ light transition)
|
|
142
|
+
|
|
143
|
+
**Condition for use**: The scroll narrative has a turn — a moment where the register shifts to mark a conceptual pivot. The inversion makes the change visible and felt, not just read. One inversion per page is usually correct; more than one is a rhythm, not a pivot.
|
|
144
|
+
|
|
145
|
+
**Condition against**: Arbitrary decoration. The inversion must correspond to a narrative event, not to a desire for visual variety. When the colour switches back without a corresponding conceptual return, the technique has been used as decoration and should be removed.
|
|
146
|
+
|
|
147
|
+
### Sticky stage / scene sequencing
|
|
148
|
+
|
|
149
|
+
**Condition for use**: A multi-scene showpiece where each scene requires the user's full attention before advancing — a product demo, a feature walk-through with animated states, a narrative with distinct chapters. The stage (`position: sticky`) pins the viewport while scroll advances the timeline inside the scene.
|
|
150
|
+
|
|
151
|
+
**Condition against**: Sites where the user is goal-oriented and is scrolling to find something specific. Sticky stages are navigation debt — the user cannot scroll past to scan; they must watch the scene play. If they have seen it before, it is friction. If there is any chance of return visits, the stage needs an explicit skip or fast-forward affordance.
|
|
152
|
+
|
|
153
|
+
### Editorial number / index labels (01, 02, 03)
|
|
154
|
+
|
|
155
|
+
**Condition for use**: The content has a genuine sequence — steps, chapters, items in an ordered argument. The large number (set at display scale, often 10–15% opacity as a background element) reinforces the ordered reading without becoming the dominant visual.
|
|
156
|
+
|
|
157
|
+
**Condition against**: Fake sequences — content that is enumerated to look like it has order but does not. Numerical labels that carry no sequential meaning are decoration, and decoration at display scale is noise.
|
|
158
|
+
|
|
159
|
+
### Blend-mode typography
|
|
160
|
+
|
|
161
|
+
**Condition for use**: Text that must maintain legibility and contrast across a moving or textured background — `mix-blend-mode: difference` inverts the pixel values at each point of contact, guaranteeing contrast regardless of what is behind the type. Effective on full-bleed images or video backgrounds where fixed colour choices will fail in some regions.
|
|
162
|
+
|
|
163
|
+
**Condition against**: Static backgrounds where the contrast can be calculated and set directly — `difference` on a static background produces a predictable result that could be a fixed colour choice, but with more browser overhead. Not appropriate for body copy (the visual complexity of difference blending at small sizes degrades legibility).
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## The restraint clause
|
|
168
|
+
|
|
169
|
+
The techniques above are a catalogue, not a checklist. A showpiece site uses two or three of them, chosen because the concept requires them, and executes each one with precision. A site that uses eight of them is an effects catalogue, not a design. It is what the Awwwards guide calls "randomness without microinteractions" — stimulation without meaning.
|
|
170
|
+
|
|
171
|
+
The selection discipline: before adding any technique, ask whether the concept — the governing metaphor — would do this. A concept framed as "a deep-sea research vessel" would animate precisely, with technical legibility, and would never distort images playfully. The same concept would not use a pastel grain texture. If the technique does not follow from the concept, it is decoration.
|
|
172
|
+
|
|
173
|
+
**Performance is not a category below craft** — it is part of Usability, which is 30% of the score. Animating only `transform` and `opacity`, honouring `prefers-reduced-motion`, and staying within 60fps on mid-range hardware are not concessions to accessibility; they are the conditions under which the expressive register earns its score. An animation that causes layout jank has failed the Usability criterion. A motion that does not honour `prefers-reduced-motion: reduce` has failed both Usability and Accessibility.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Korean showpiece typography
|
|
178
|
+
|
|
179
|
+
GDWEB (gdweb.co.kr), operating since 2005, is the leading Korean web design award. Winning categories skew toward agency brand sites and campaign microsites — seasonal brand launches, product campaign pages, experiential brand activations — rather than application UI. The showpiece register is the expected register on GDWEB, not the exceptional one. This means the baseline for expressive work in the Korean market is higher; mid-level expressive execution that would earn attention internationally passes unnoticed against the GDWEB field.
|
|
180
|
+
|
|
181
|
+
Hangul syllable blocks create a different visible rhythm from Latin letters, but they do not
|
|
182
|
+
imply a fixed size or tracking limit. Inspect the chosen face's counters, stroke density,
|
|
183
|
+
punctuation, mixed Latin/numerals, and wrapping with actual Korean copy. Word-based and
|
|
184
|
+
character-based Hangul breaking are both documented practices; choose one from the task and
|
|
185
|
+
verify it in the intended container. Huge Hangul is justified when the words are short and
|
|
186
|
+
concept-bearing and the face/weight remains clean at both proof viewports. It fails when a
|
|
187
|
+
heavy long sentence wraps into an undifferentiated wall, clips, falls back, or removes the
|
|
188
|
+
secondary message and CTA.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Graphics recipes
|
|
193
|
+
|
|
194
|
+
The background and image treatment techniques referenced in this file — grain texture,
|
|
195
|
+
gradient mesh, geometric patterns, CSS illustration primitives, duotone image presets —
|
|
196
|
+
are implemented as working CSS recipes in `core/graphics/`. The placeholder policy
|
|
197
|
+
(grey box is a defect; typographic block, pattern fill, or generated gradient instead)
|
|
198
|
+
is documented in `core/graphics/placeholder-policy.md`.
|
|
199
|
+
|
|
200
|
+
## Sources
|
|
201
|
+
|
|
202
|
+
- Awwwards, Evaluation System (awwwards.com/about-evaluation) — Design 40% / Usability 30% / Creativity 20% / Content 10%, confirmed from the official criteria page
|
|
203
|
+
- Awwwards Academy, "Art Direction Secrets to Create Unique Web Experiences" (awwwards.com/academy) — concept as the primary variable in SOTD awards; effects as amplifiers of concept, not substitutes
|
|
204
|
+
- Streza, "A Guide on Building Awwwards Worthy Websites" (medium.com, via awwwards.com search results) — one signature moment per page; microinteractions and randomness as distinguishing factors
|
|
205
|
+
- MDN Web Docs, CSS scroll-driven animations (developer.mozilla.org/en-US/docs/Web/CSS/Guides/Scroll-driven_animations) — `animation-timeline: scroll()` / `view()` specification and browser support
|
|
206
|
+
- WebKit, "A Guide to Scroll-Driven Animations with Just CSS" (webkit.org/blog/17101) — Safari support for scroll-driven animation spec
|
|
207
|
+
- Codrops, "Custom Cursor Effects" (tympanus.net/codrops/2019/01/31/custom-cursor-effects/) — pointer media query scoping; hover zone behaviour
|
|
208
|
+
- Lea Verou / CSS-Tricks, "Grainy Gradients" (css-tricks.com/grainy-gradients/) — SVG feTurbulence filter technique for noise texture; banding reduction on smooth backgrounds
|
|
209
|
+
- W3C, Requirements for Hangul Text Layout and Typography (w3.org/TR/klreq/) — syllable block structure; spacing constraints and the fixed-width character cell at display scale
|
|
210
|
+
- Awwwards, "Customize your mouse cursor" (awwwards.com/customize-your-mouse-cursor) — cursor as brand vocabulary on award-winning sites; pointer-fine scoping requirement
|
|
211
|
+
- GDWEB Design Awards, About (gdweb.co.kr/sub/about.asp) — Korean award context, judge composition, selection categories dominated by agency and campaign microsites
|
|
212
|
+
- Motion theory cross-reference: see `core/theory/motion.md` — duration windows, reduced-motion requirement, transform/opacity constraint, and the attention budget argument all apply in the showpiece register without exception
|
|
213
|
+
- Motion cookbook: working implementations of every technique catalogued above (split-text, scroll-reveal, sticky scene, section inversion, marquee, magnetic hover, and more) are in `core/motion/recipes/`; easing token vocabulary is in `core/motion/easing.md`
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Imagegen — image-first art direction (decision material)
|
|
2
|
+
|
|
3
|
+
Adapted for OMD from the image-direction discipline in lazycodex's `frontend` skill
|
|
4
|
+
(`imagegen-frontend-web`, `image-to-code`; Apache-2.0, github.com/code-yeongyu/lazycodex). This is
|
|
5
|
+
an OMD-native synthesis bound to OMD's evidence, clean-room, and anti-fabrication rules — not a copy.
|
|
6
|
+
|
|
7
|
+
**A generated image is a design reference, never a shipped asset.** It plays the exact role a Figma
|
|
8
|
+
export or a hand mockup plays: a visual contract the build implements against. It obeys the clean-room
|
|
9
|
+
boundary (`protocol/human-design-loop.md`) — you transfer layout grammar, token relationships, and
|
|
10
|
+
composition decisions, not pixels. A generated mockup never ships as a page `<img>`. Shipped imagery
|
|
11
|
+
still obeys `asset-sourcing`: a factual carrier (team photo, product screenshot, real person, logo)
|
|
12
|
+
is NEVER AI-generated; only an abstract or atmospheric zone may ship generated imagery, and only with
|
|
13
|
+
committed provenance recorded via `omd decision`.
|
|
14
|
+
|
|
15
|
+
## The safety backstop makes reference-seeding safe
|
|
16
|
+
|
|
17
|
+
Seed the concept drafts from the real reference board — the scout's measured principles and the
|
|
18
|
+
component references it captured with `omd ref add … --selector … --blueprint --shot`, which pair
|
|
19
|
+
each component's screenshot with its skin-abstracted structural grammar on one record, plus the
|
|
20
|
+
committed palette/type/material. This is the composer's art-direction step, not a build step: feed
|
|
21
|
+
the paired screenshots and blueprints to the image tool as multi-source references, but the builder
|
|
22
|
+
never sees these reference screenshots — it implements from the generated draft. Combining
|
|
23
|
+
multiple references into a NEW synthesis is the whole point, and it is safe here
|
|
24
|
+
for one specific reason: `omd ref distance` still measures the SHIPPED build against every saved
|
|
25
|
+
reference and nothing at or above 0.6 kinship ships. The kinship gate is the anti-laundering backstop,
|
|
26
|
+
so imagegen may be seeded richly without risking a copy — the final build is gated regardless of how
|
|
27
|
+
the mockup was seeded. Never seed a draft from a single reference alone and never target a specific
|
|
28
|
+
reference's pixels; synthesize 2–3 references' grammar plus the project's own concept.
|
|
29
|
+
|
|
30
|
+
## When image-first applies
|
|
31
|
+
|
|
32
|
+
Image-first is for confident/showpiece register work where the visual composition is a first-class
|
|
33
|
+
deliverable — landing pages, marketing sites, portfolios, brand/editorial pages, redesigns where the
|
|
34
|
+
look is the point. For a quiet register (dashboard, docs, tool) it is usually unnecessary; the content
|
|
35
|
+
is the event and a mockup adds nothing. Skip it and record why.
|
|
36
|
+
|
|
37
|
+
When the host provides an image-generation capability and image-first applies, the order is
|
|
38
|
+
**mandatory**:
|
|
39
|
+
|
|
40
|
+
1. **Generate** 2–3 art-directed concept-draft mockups concurrently (they are independent — do not
|
|
41
|
+
serialize them), each seeded with the committed concept's palette, type register, and material
|
|
42
|
+
PLUS the scout's paired component references (screenshot + skin-abstracted blueprint from
|
|
43
|
+
`omd ref add … --shot`) and measured principles as multi-source input. One horizontal image per
|
|
44
|
+
section for a multi-section page — never one tall board
|
|
45
|
+
with unreadable text. Do not crop an old image for a detail view; regenerate that section fresh,
|
|
46
|
+
keeping the same palette/type/radius/treatment. Store drafts under `.omd/.cache/imagegen/` and
|
|
47
|
+
record their paths + the pick with `omd decision`.
|
|
48
|
+
2. **Analyze** the chosen draft cleanly, not vibe-only: extract tokens, layout geometry, spacing
|
|
49
|
+
rhythm, type-scale relationships, component anatomy, interaction affordances, and each section's job.
|
|
50
|
+
3. **Feed** the chosen draft into `.omd/composition.md` as the reference-fidelity direction, then build
|
|
51
|
+
against it and run `omd ref distance` as usual. If the host has no image capability, fall back to
|
|
52
|
+
the evidence-based composition path — the reference board, `theory/expressive.md`, and the CSS/SVG
|
|
53
|
+
graphics recipes — and record the fallback.
|
|
54
|
+
|
|
55
|
+
Reasoning the layout in the abstract is exactly what produces the symmetric, boxed, template output
|
|
56
|
+
`expressive.md` § "Slop-free is not the same as distinctive" warns about. A generated draft forces a
|
|
57
|
+
concrete art direction to react to instead of a reasonable-sounding description.
|
|
58
|
+
|
|
59
|
+
## Break the AI defaults (aggressively)
|
|
60
|
+
|
|
61
|
+
Standard image generation and abstract layout-reasoning both collapse into the same tells. Name the
|
|
62
|
+
one a draft is drifting toward and reject it:
|
|
63
|
+
|
|
64
|
+
- centered dark hero with a purple/blue glow; floating meaningless blobs
|
|
65
|
+
- **left-text / right-image hero** — the single most overused AI pattern; allowed only when it is
|
|
66
|
+
genuinely the strongest fit, never the default first instinct
|
|
67
|
+
- generic dashboard/card spam; cards inside cards inside cards; giant rounded containers everywhere
|
|
68
|
+
- weak typography hierarchy; boring default web-type energy
|
|
69
|
+
- "luxury" that is only beige serif text; "creative" that is actually messy and unreadable
|
|
70
|
+
- text-heavy layouts with too little imagery; over-packed sections with no breathing room
|
|
71
|
+
- tiny pills, tags, and fake interface jargon used as decoration
|
|
72
|
+
|
|
73
|
+
## The variation engine
|
|
74
|
+
|
|
75
|
+
Commit to ONE strong option per axis and execute it consistently — do not mash everything together,
|
|
76
|
+
and do not repeat one anchor down the whole page. Bias toward stronger visual concepts, but the brief
|
|
77
|
+
always overrides: "clean/minimal/swiss" lowers density and variance; "editorial/creative/bold/개쩔게"
|
|
78
|
+
raises them.
|
|
79
|
+
|
|
80
|
+
- **Theme**: pristine light · deep dark · bold studio solid · quiet premium neutral
|
|
81
|
+
- **Hero scale (per page, decisive — do not split the difference)**: giant statement · mid editorial ·
|
|
82
|
+
mini minimalist (mini is confident restraint, not weakness)
|
|
83
|
+
- **Hero architecture**: cinematic centered · asymmetric split · editorial offset · image-first with
|
|
84
|
+
restrained text · inline typographic behemoth
|
|
85
|
+
- **Section system**: modular bento rhythm · alternating editorial blocks · poster-stacked storytelling ·
|
|
86
|
+
gallery-led cadence · swiss grid · asymmetric marketing flow
|
|
87
|
+
- **Composition anchor (per section)**: centered statement · top-left lead / bottom-right support ·
|
|
88
|
+
bottom-left over image · off-grid editorial offset · stacked-center minimalist · image-as-canvas with
|
|
89
|
+
text in a safe area. Across a page at least 3 different anchors must appear; never repeat one anchor
|
|
90
|
+
more than twice in a row; vary the hero so the page does not open on the AI default.
|
|
91
|
+
- **Background mode (per section)**: solid + inline asset · textured/paper/grid · full-bleed image with
|
|
92
|
+
tonal overlay · editorial side-image · duotone-treated image · cinematic tonal gradient (low-chroma,
|
|
93
|
+
palette-matched) · color-blocked diptych · micro-noise over solid. Be confident with backgrounds —
|
|
94
|
+
for a non-minimalist brief, at least one full-bleed/duotone/atmospheric background should appear;
|
|
95
|
+
never all-inline-asset unless the brief asks for restraint.
|
|
96
|
+
- **Narrative spine (per page)**: artifact/specimen · journey/waypoints · precision instrument · living
|
|
97
|
+
system · stage/spotlight · archive/dossier. Thread it through visuals and short copy.
|
|
98
|
+
|
|
99
|
+
Register still governs restraint: one signature moment, not a catalogue. The engine varies the
|
|
100
|
+
composition; it never stacks five techniques into chaos.
|
|
101
|
+
|
|
102
|
+
## The bar
|
|
103
|
+
|
|
104
|
+
Not clean-and-correct — work a senior designer at Linear, Stripe, or Supabase would ship. Correct-but-flat
|
|
105
|
+
is a failure, not a finish.
|