v3.0 — THE BRAIN · 2026-05-28
In v2.0, the 160-brand catalogue was a pool the recommender picked from. In v3.0, it's the vocabulary a 7-axis synthesizer distills into a novel design language per brief. Same files. Same JSON. The role changed.
v2 said: "your brief sounds like a fintech dashboard. Here's the Stripe spec — use it." The output looked Stripe-like. Good for prototyping, dangerous for shipping. If you wanted "Stripe-like but for healthcare," you got Stripe-like and had to manually warm the palette.
v3 says: "your brief sounds like a fintech dashboard. Here are 8 brands whose category-seed axes are closest to yours in 7-dimensional space — Stripe, Linear, Datadog, Snowflake, ClickHouse, and 3 more. I'm going to distill their palettes, type stacks, motion vocab, and density signals into a fresh design language that fits THIS brief. No one specific brand wins. The output is unique." The same 160 brand files now play a different role.
The brief maps deterministically to 7 continuous axes:
| Axis | 0.0 end | 1.0 end |
|---|---|---|
| warmth | cold / clinical | warm / inviting |
| contrast | flat / muted | dramatic / loud |
| density | airy / sparse | dense / packed |
| geometry | sharp / angular | soft / rounded |
| formality | playful | corporate |
| motion | still | kinetic |
| type_personality | geometric | humanist |
Same brief → same axes, every call. No randomness. No clock. No LLM. Pure Python math.
Each axis then compiles to concrete tokens:
warmth → RGB warmth shift on the synthesized palettecontrast → modular type scale ratio (1.200 quiet / 1.250 balanced / 1.333 loud)density → spacing base (4/6/8/12px), line-height opennessgeometry → radius scale (2-18px), corner characterformality → tracking, motion dampening, spacing overridemotion → animation timing (140-220ms), curve picktype_personality → display family bias, weight curveThe synthesizer chooses how to consult the brand catalogue based on what the brief says:
Brief: reference_brands=[stripe] strict=True. The recommender emits 100% Stripe tokens verbatim. No synthesis. Fastest path. Used when you know exactly what you want and need pixel-fidelity to one brand.
Brief: reference_brands=[stripe] (no strict flag). Stripe gets ~70% of the vocabulary weight in the mix. The other 30% comes from 4 sibling brands whose category-seed axes match the rest of the brief. Used when you want Stripe's taste but applied to your domain.
Brief: no reference_brands at all. Synthesizer pulls 8 brands closest to the brief's axes in 7-D space, distills their vocabulary, mixes weighted by axis position. No single brand dominates. Output is novel each time. Infinity space, grounded in real brand patterns.
The maximalist v2.1 spec said: drop the manifests, generate every palette / type pair / spacing scale from scratch on every call, achieve true infinity.
We rejected this. Three reasons:
Instead, v3 achieves infinity by making the COMBINATIONS of finite vocabulary continuous. The catalogue stays. The output is still novel. Best of both.
pip install uxskill
uxskill init # auto-detects your IDE
uxskill synthesize --industry fintech-payments --tone bold
# → SynthesizedSystem(mode="pure_synthesis", axes={warmth: 0.35, ...},
# palette={canvas: "#0a1014", ...}, type_pair={...})
uxskill synthesize --brand stripe # brand_anchor (70/30)
uxskill synthesize --brand stripe --strict # strict_brand (100% Stripe)