Direction first, tokens second, code last. Restraint is the default posture; ONE intentional moment per surface earns the lift.
Posture
Direction precedes tokens; tokens precede code. The picked direction is the contract — palette, type, spacing, motion all derive from it, not the other way around. Restraint is the default; reach for decoration only when a named surface goal demands it. Posture rests on references/soul.md (design philosophy) — load when the user asks "why this look" or when the model is tempted to add decoration to compensate for a thin idea.
Balance, not maximalism. ODIN's "don't hold back" (borrowed from the <design> block above) means conviction, not volume. The two failure modes catalogued in the anti-slop charter below are reciprocals — AI-generic timidity (Side A) and decorative overkill (Side B) both come from the same fear of commitment. Balance simplicity and verbosity per surface; restraint as the default, the one intentional moment as the lift, neither timid nor loud.
ODIN <design> block — LOAD-BEARING
Quoted verbatim from output-styles/odin.md lines 254–262.
<design>
Modern, elegant UI/UX. Don't hold back.
**Tokens:** MUST use design system tokens, not hardcoded values.
**Density:** 2-3x denser. Spacing: 4/8/12/16/24/32/48/64px. Medium-high density default. Ask preference when ambiguous.
**Paradigms:** Post-minimalism [default] | Neo-brutalism | Glassmorphism | Material 3 | Fluent. Avoid naive minimalism.
**Forbidden:** Purple-blue/purple-pink | `transition: all` | `font-family: system-ui` | Pure purple/red/blue/green | Self-generated palettes | Gradients (unless explicitly requested, NEVER on buttons/titles)
**Gate:** Design excellence >= 95%
</design>
Register × paradigm matrix — pointer
Every design surface is brand (marketing, landing, campaign, long-form content, portfolio — design IS the product) or product (app UI, admin, dashboard, tool — design SERVES the product). Identify before designing.
Detection rule. First match wins:
- Cue in the task itself — "landing page" / "campaign hero" → brand; "dashboard" / "settings panel" → product.
- Surface in focus — the page, file, or route being worked on; the route segment usually disambiguates (
/marketing/* vs. /app/*).
- Register field in PRD or project context (
AGENTS.md, CLAUDE.md, brand brief).
Brand register opens neo-brutalism / glassmorphism / M3 Expressive with Committed / Full palette / Drenched color strategies; product register defaults to Restrained + post-minimalism / Fluent 2. Full matrix in references/paradigms.md §0.
Anti-slop charter — LOAD-BEARING
Two-sided ban-list. Each row: ban — WHY in one line. Depth in references/anti-slop.md.
Side A — slop tells (the AI-generic look):
- Purple-blue or purple-pink gradient — RLHF over-aligns to this; betrays self-generated palette.
- Inter alone as the type system — default of every Vercel template; no commitment, no contrast.
- Centered hero plus 3-column feature grid — the shadcn landing-page silhouette; reads as preset.
- Glassmorphism on every surface — translucence loses meaning when nothing is opaque.
rounded-lg uniform on every element — radius without hierarchy is decoration, not signal.
shadow-md uniform across the surface — elevation that conveys nothing.
transition: all — animates layout, color, and transform together; jank guaranteed.
font-family: system-ui — abdicates the type decision; reads as "did not pick".
- Default Tailwind palette (slate-500 / blue-500) — the costume of "I used the framework defaults".
- Colored card borders to assert structure — borders are not the right tool for hierarchy.
- Emoji icons in production UI — accessibility hostile; locale-fragile; reads as draft.
Side B — overkill compensation (slop's louder cousin):
- Sprites on every empty pixel — decoration substituting for missing information density.
- Gradient on every section background — every section "important" means none are.
- Animation on every element entrance — motion budget is a budget; spend it once.
- Multi-paradigm mash (neo-brutalism shadow on a glass card on a Material 3 button) — paradigm conflict reads as confusion, not eclecticism.
- Decorative noise compensating for a thin idea — when the surface earns its weight, restraint amplifies it.
Color strategy axis (commitment level). Pick the strategy before picking colors. Each tier is deliberate, not a fallback.
- Restrained — tinted neutrals plus one accent at ≤10% surface coverage. Product default.
- Committed — one saturated color carries 30–60% of the surface. Brand default for identity-driven pages.
- Full palette — 3-4 named roles, each used deliberately. Brand campaigns; product data viz.
- Drenched — the surface IS the color. Brand heroes, campaign pages.
The "one accent ≤10%" cap applies only to Restrained. Committed / Full palette / Drenched exceed it on purpose; treat the cap as direction-conditional, not universal.
Direction-first workflow
Six steps. Do not skip the divergence step.
Frame the surface. Capture: surface (landing / dashboard / settings / docs / one-screen tool), primary user, density target, motion budget in ms. Then write one sentence of physical scene (who, where, ambient light, mood) that FORCES the dark/light decision. Category names alone do not force the answer — "observability dashboard" fails; "SRE glancing at incident severity on a 27-inch monitor at 2am in a dim room" succeeds. Pin why this design must feel a certain way before deciding how. Surface answers before generating directions; designing on assumed callers wastes the parallel budget.
Diverge: 3-4 directions in parallel via Verbalized Sampling. Dispatch one Explore agent per direction with a constraint that forces contrast (post-minimalism vs neo-brutalism vs Material 3 vs Fluent, or named taste anchors that pull in opposite directions). Reject converged outputs; re-dispatch with sharpened constraints if two directions read alike. See references/diversity.md for the six diversity-engineering techniques (verbalized sampling, actor-critic per candidate, persona injection, temperature, most-unlikely reframing, anti-pattern catalog).
Per direction, return a fixed shape. Each direction states: name (one or two words), 1-2 taste anchors (Linear / Stripe / Things 3 / Rosé Pine / Are.na — name the references), OKLCH palette stub (4-6 swatches, never the default Tailwind ramp), type pair (display + text, named families), spacing scale subset committed (e.g., 4/8/16/24/48), motion budget in ms with one easing curve.
Pick via per-axis single-select. Each axis (direction, density, motion budget, type pair) is its own single-select question; the recommended option carries (Recommended) and is placed first. Ticking (Recommended) is accepting the default. Never use multiSelect for axis-with-default override semantics — that shape collapses N independent decisions into one ambiguous checklist; reserve multiSelect for additive picks only (feature toggles, optional sub-tasks).
Derive DTCG-shaped tokens from the picked direction. Color, type, space, radius, shadow, motion — each a token, each referenced not hardcoded. Tokens precede component code; component code references tokens.
Route to the surface reference. Pick the row in §6 that matches the runtime; load that reference for surface-specific patterns and pitfalls.
Surface routing
| Runtime |
Reference |
| Vanilla CSS / static HTML |
references/web.md |
| React / Tailwind / shadcn |
references/react.md |
| Bubble Tea / Ratatui / Textual |
references/tui.md |
| clap / cobra / cmdliner / typer |
references/cli.md |
| Tauri / Slint / egui / Iced |
references/desktop.md |
| Qt / QML |
references/qt.md |
| Cross-platform tokens |
references/design-systems.md |
| Motion across runtimes (timing / easing / reduced motion) |
references/motion.md |
Cross-runtime references
These references are runtime-agnostic — load them when the task fits the trigger, alongside whatever surface reference is already loaded.
| Reference |
Load when… |
references/interaction-design.md |
Designing or auditing interactive elements (states, focus rings, dropdowns, modals, popovers, keyboard navigation) — applies across web / React / desktop / Qt. |
references/cognitive-load.md |
Auditing a surface for mental-effort overhead (working-memory rule, the eight common violations, the cognitive-load checklist). |
references/personas.md |
Running a persona-based design audit (Alex / Jordan / Sam / Riley / Casey, plus project-specific personas derived from PRD / brand brief). |
references/ux-writing.md |
Drafting UI labels, error messages, empty states, confirmation dialogs, and any user-facing copy — copy is design. |
references/diversity.md |
Generating diverse direction candidates in step 2 (Diverge) of the workflow — six techniques to defeat centroid convergence. |
references/cjk.md |
Designing for Chinese / Japanese / Korean content — locale tagging, Pan-CJK fonts, vertical writing / ruby, locale-specific glyphs. Routes into korean.md / japanese.md / chinese.md for per-locale production trends and DS landscape. |
Cross-surface invariants
- Color as input, never as default. Custom OKLCH palette derived from the picked direction; never the default Tailwind, Material, or Bootstrap ramp.
- Spacing scale is 4/8/12/16/24/32/48/64. Pick a subset that matches density target; commit and stick. A new value mid-build is a smell.
- At most two type families. Display plus text. A third family is a smell unless the direction explicitly demands it (e.g., a mono accent for code).
- Motion is budgeted in milliseconds. One easing curve per surface.
transition: all is forbidden — name the properties (transition: opacity 120ms ease, transform 120ms ease) so layout and paint do not animate together.
- Semantic structure precedes class names.
<nav> / <main> / <article> first; utility classes second. Class soup over weak structure is slop.
- Contrast: WCAG 2.1 AA is the legal floor. APCA is a design-input tool only — it was REMOVED from WCAG 3 in July 2023 and never reinstated. Do not claim "WCAG 3 compliant via APCA"; that compliance does not exist. Verify AA with axe-core or the browser DevTools accessibility panel.
Verification gate
- ODIN design gate ≥95% per the
<design> block above (tokens / density / paradigm / forbidden list).
- Anti-slop checklist (§4 Side A AND Side B) returns zero violations.
- Direction artifact recorded in commit body or PR description: name plus taste anchors plus one-line rationale.
- Tokens referenced not hardcoded —
git grep for raw hex, raw px values in component code; should be empty.
- Cross-surface invariants honored — spacing subset committed, ≤2 type families, motion named-properties only.
- Contrast verified via axe-core CLI or DevTools accessibility panel; WCAG 2.1 AA pass on every text surface.
- Audit tools — data-dense surfaces pass the
references/cognitive-load.md checklist (≤1 failure); shipped surfaces have been read against ≥2 of the references/personas.md archetypes.
Anti-patterns
- "Be creative" / temperature-up — generates more slop, not better direction. VS structure or nothing.
- Single-shot palette generation — RLHF over-aligns to purple; the model's first guess is the slop.
- Skipping the direction commit and jumping to component code — components without a direction are coupling without contract.
- Mixing two paradigms on one surface — neo-brutalism shadow on a glass card reads as confusion.
- Ranking directions by implementation effort — short-term cost is the wrong axis; taste fit and depth are the right ones.
1---2name: design-173description: Set visual and interaction direction for any UI surface (web, React, TUI, CLI, desktop, Qt, design-system tokens) before any UI code. Direction-first: generates 3-4 distinct directions via verbalized sampling, picks one via per-axis single-select, then derives palette, typography, spacing, motion budget. Loads when the user asks for UI work, palette/theme/tokens, mentions a design system, or when output looks AI-generic, vibe-coded, sloppy, or default Tailwind/shadcn/Bootstrap. Enforces two-sided anti-slop charter: forbids purple gradients, `transition: all`, system-ui, default Tailwind palette AND overkill compensation (sprites, gradients everywhere, animation on every element).4---5
6Direction first, tokens second, code last. Restraint is the default posture; ONE intentional moment per surface earns the lift.
7
8## Posture
9
10Direction precedes tokens; tokens precede code. The picked direction is the contract — palette, type, spacing, motion all derive from it, not the other way around. Restraint is the default; reach for decoration only when a named surface goal demands it. Posture rests on `references/soul.md` (design philosophy) — load when the user asks "why this look" or when the model is tempted to add decoration to compensate for a thin idea.
11
12**Balance, not maximalism.** ODIN's "don't hold back" (borrowed from the `<design>` block above) means conviction, not volume. The two failure modes catalogued in the anti-slop charter below are reciprocals — AI-generic timidity (Side A) and decorative overkill (Side B) both come from the same fear of commitment. Balance simplicity and verbosity per surface; restraint as the default, the one intentional moment as the lift, neither timid nor loud.
13
14## ODIN `<design>` block — LOAD-BEARING
15
16Quoted verbatim from `output-styles/odin.md` lines 254–262.
17
18```
19<design>
20Modern, elegant UI/UX. Don't hold back.
21
22**Tokens:** MUST use design system tokens, not hardcoded values.
23**Density:** 2-3x denser. Spacing: 4/8/12/16/24/32/48/64px. Medium-high density default. Ask preference when ambiguous.
24**Paradigms:** Post-minimalism [default] | Neo-brutalism | Glassmorphism | Material 3 | Fluent. Avoid naive minimalism.
25**Forbidden:** Purple-blue/purple-pink | `transition: all` | `font-family: system-ui` | Pure purple/red/blue/green | Self-generated palettes | Gradients (unless explicitly requested, NEVER on buttons/titles)
26**Gate:** Design excellence >= 95%
27</design>
28```
29
30## Register × paradigm matrix — pointer
31
32Every design surface is **brand** (marketing, landing, campaign, long-form content, portfolio — design IS the product) or **product** (app UI, admin, dashboard, tool — design SERVES the product). Identify before designing.
33
34**Detection rule.** First match wins:
351. Cue in the task itself — "landing page" / "campaign hero" → brand; "dashboard" / "settings panel" → product.
362. Surface in focus — the page, file, or route being worked on; the route segment usually disambiguates (`/marketing/*` vs. `/app/*`).
373. Register field in PRD or project context (`AGENTS.md`, `CLAUDE.md`, brand brief).
38
39Brand register opens neo-brutalism / glassmorphism / M3 Expressive with Committed / Full palette / Drenched color strategies; product register defaults to Restrained + post-minimalism / Fluent 2. Full matrix in `references/paradigms.md §0`.
40
41## Anti-slop charter — LOAD-BEARING
42
43Two-sided ban-list. Each row: ban — WHY in one line. Depth in `references/anti-slop.md`.
44
45**Side A — slop tells (the AI-generic look):**
46
47- Purple-blue or purple-pink gradient — RLHF over-aligns to this; betrays self-generated palette.
48- Inter alone as the type system — default of every Vercel template; no commitment, no contrast.
49- Centered hero plus 3-column feature grid — the shadcn landing-page silhouette; reads as preset.
50- Glassmorphism on every surface — translucence loses meaning when nothing is opaque.
51- `rounded-lg` uniform on every element — radius without hierarchy is decoration, not signal.
52- `shadow-md` uniform across the surface — elevation that conveys nothing.
53- `transition: all` — animates layout, color, and transform together; jank guaranteed.
54- `font-family: system-ui` — abdicates the type decision; reads as "did not pick".
55- Default Tailwind palette (slate-500 / blue-500) — the costume of "I used the framework defaults".
56- Colored card borders to assert structure — borders are not the right tool for hierarchy.
57- Emoji icons in production UI — accessibility hostile; locale-fragile; reads as draft.
58
59**Side B — overkill compensation (slop's louder cousin):**
60
61- Sprites on every empty pixel — decoration substituting for missing information density.
62- Gradient on every section background — every section "important" means none are.
63- Animation on every element entrance — motion budget is a budget; spend it once.
64- Multi-paradigm mash (neo-brutalism shadow on a glass card on a Material 3 button) — paradigm conflict reads as confusion, not eclecticism.
65- Decorative noise compensating for a thin idea — when the surface earns its weight, restraint amplifies it.
66
67**Color strategy axis (commitment level).** Pick the strategy before picking colors. Each tier is deliberate, not a fallback.
68
69- **Restrained** — tinted neutrals plus one accent at ≤10% surface coverage. Product default.
70- **Committed** — one saturated color carries 30–60% of the surface. Brand default for identity-driven pages.
71- **Full palette** — 3-4 named roles, each used deliberately. Brand campaigns; product data viz.
72- **Drenched** — the surface IS the color. Brand heroes, campaign pages.
73
74The "one accent ≤10%" cap applies only to **Restrained**. Committed / Full palette / Drenched exceed it on purpose; treat the cap as direction-conditional, not universal.
75
76## Direction-first workflow
77
78Six steps. Do not skip the divergence step.
79
801. **Frame the surface.** Capture: surface (landing / dashboard / settings / docs / one-screen tool), primary user, density target, motion budget in ms. **Then write one sentence of physical scene** (who, where, ambient light, mood) that FORCES the dark/light decision. Category names alone do not force the answer — "observability dashboard" fails; "SRE glancing at incident severity on a 27-inch monitor at 2am in a dim room" succeeds. Pin *why* this design must feel a certain way before deciding *how*. Surface answers before generating directions; designing on assumed callers wastes the parallel budget.
81
822. **Diverge: 3-4 directions in parallel via Verbalized Sampling.** Dispatch one Explore agent per direction with a constraint that *forces* contrast (post-minimalism vs neo-brutalism vs Material 3 vs Fluent, or named taste anchors that pull in opposite directions). Reject converged outputs; re-dispatch with sharpened constraints if two directions read alike. See `references/diversity.md` for the six diversity-engineering techniques (verbalized sampling, actor-critic per candidate, persona injection, temperature, most-unlikely reframing, anti-pattern catalog).
83
843. **Per direction, return a fixed shape.** Each direction states: name (one or two words), 1-2 taste anchors (Linear / Stripe / Things 3 / Rosé Pine / Are.na — name the references), OKLCH palette stub (4-6 swatches, never the default Tailwind ramp), type pair (display + text, named families), spacing scale subset committed (e.g., 4/8/16/24/48), motion budget in ms with one easing curve.
85
864. **Pick via per-axis single-select.** Each axis (direction, density, motion budget, type pair) is its own single-select question; the recommended option carries `(Recommended)` and is placed first. Ticking `(Recommended)` *is* accepting the default. Never use `multiSelect` for axis-with-default override semantics — that shape collapses N independent decisions into one ambiguous checklist; reserve `multiSelect` for additive picks only (feature toggles, optional sub-tasks).
87
885. **Derive DTCG-shaped tokens from the picked direction.** Color, type, space, radius, shadow, motion — each a token, each referenced not hardcoded. Tokens precede component code; component code references tokens.
89
906. **Route to the surface reference.** Pick the row in §6 that matches the runtime; load that reference for surface-specific patterns and pitfalls.
91
92## Surface routing
93
94| Runtime | Reference |
95|---|---|
96| Vanilla CSS / static HTML | `references/web.md` |
97| React / Tailwind / shadcn | `references/react.md` |
98| Bubble Tea / Ratatui / Textual | `references/tui.md` |
99| clap / cobra / cmdliner / typer | `references/cli.md` |
100| Tauri / Slint / egui / Iced | `references/desktop.md` |
101| Qt / QML | `references/qt.md` |
102| Cross-platform tokens | `references/design-systems.md` |
103| Motion across runtimes (timing / easing / reduced motion) | `references/motion.md` |
104
105## Cross-runtime references
106
107These references are runtime-agnostic — load them when the task fits the trigger, alongside whatever surface reference is already loaded.
108
109| Reference | Load when… |
110|-----------|------------|
111| `references/interaction-design.md` | Designing or auditing interactive elements (states, focus rings, dropdowns, modals, popovers, keyboard navigation) — applies across web / React / desktop / Qt. |
112| `references/cognitive-load.md` | Auditing a surface for mental-effort overhead (working-memory rule, the eight common violations, the cognitive-load checklist). |
113| `references/personas.md` | Running a persona-based design audit (Alex / Jordan / Sam / Riley / Casey, plus project-specific personas derived from PRD / brand brief). |
114| `references/ux-writing.md` | Drafting UI labels, error messages, empty states, confirmation dialogs, and any user-facing copy — copy is design. |
115| `references/diversity.md` | Generating diverse direction candidates in step 2 (Diverge) of the workflow — six techniques to defeat centroid convergence. |
116| `references/cjk.md` | Designing for Chinese / Japanese / Korean content — locale tagging, Pan-CJK fonts, vertical writing / ruby, locale-specific glyphs. Routes into `korean.md` / `japanese.md` / `chinese.md` for per-locale production trends and DS landscape. |
117
118## Cross-surface invariants
119
120- **Color as input, never as default.** Custom OKLCH palette derived from the picked direction; never the default Tailwind, Material, or Bootstrap ramp.
121- **Spacing scale is 4/8/12/16/24/32/48/64.** Pick a subset that matches density target; commit and stick. A new value mid-build is a smell.
122- **At most two type families.** Display plus text. A third family is a smell unless the direction explicitly demands it (e.g., a mono accent for code).
123- **Motion is budgeted in milliseconds.** One easing curve per surface. `transition: all` is forbidden — name the properties (`transition: opacity 120ms ease, transform 120ms ease`) so layout and paint do not animate together.
124- **Semantic structure precedes class names.** `<nav>` / `<main>` / `<article>` first; utility classes second. Class soup over weak structure is slop.
125- **Contrast: WCAG 2.1 AA is the legal floor.** APCA is a *design-input* tool only — it was REMOVED from WCAG 3 in July 2023 and never reinstated. Do not claim "WCAG 3 compliant via APCA"; that compliance does not exist. Verify AA with axe-core or the browser DevTools accessibility panel.
126
127## Verification gate
128
1291. ODIN design gate ≥95% per the `<design>` block above (tokens / density / paradigm / forbidden list).
1302. Anti-slop checklist (§4 Side A AND Side B) returns zero violations.
1313. Direction artifact recorded in commit body or PR description: name plus taste anchors plus one-line rationale.
1324. Tokens referenced not hardcoded — `git grep` for raw hex, raw px values in component code; should be empty.
1335. Cross-surface invariants honored — spacing subset committed, ≤2 type families, motion named-properties only.
1346. Contrast verified via axe-core CLI or DevTools accessibility panel; WCAG 2.1 AA pass on every text surface.
1357. Audit tools — data-dense surfaces pass the `references/cognitive-load.md` checklist (≤1 failure); shipped surfaces have been read against ≥2 of the `references/personas.md` archetypes.
136
137## Anti-patterns
138
139- "Be creative" / temperature-up — generates more slop, not better direction. VS structure or nothing.
140- Single-shot palette generation — RLHF over-aligns to purple; the model's first guess is the slop.
141- Skipping the direction commit and jumping to component code — components without a direction are coupling without contract.
142- Mixing two paradigms on one surface — neo-brutalism shadow on a glass card reads as confusion.
143- Ranking directions by implementation effort — short-term cost is the wrong axis; taste fit and depth are the right ones.