Atelier
The generation engines as tools an agent can loop against.
8
Tools exposed
40
Candidates sampled per constrained generation
1
Source of truth, shared with the apps
4
Field bugs found by real use, then fixed
Why this exists at all.
Every design-token integration on the market extracts what a designer already made. None of them generate inside constraints, and none of them can be argued with. There is no way to ask whether a palette actually answers a brief, only whether it is structurally valid.
Meanwhile the studio's own colour and type engines were locked inside two web applications, reachable by a human with a browser and by nothing else.
The decisions, and what they rule out.
Bundle the real engines, not a reimplementation
The palette and pairing engines are built from the applications' own sources at build time. One source of truth: changing an engine in the app and rebuilding picks it up here. A second implementation would drift within a week and then quietly disagree with the thing it was copied from.
Brief words map to axes, never to hexes
Mood words resolve to positions on warmth, lightness and chroma axes, and generation is rejection-sampled against those targets. Words never map to specific colours. That would be a lookup table wearing a generator's clothes.
Report the fit separately from the structure
Structural validity, are these colours distinct, is the lightness spread usable, says nothing about whether the palette answers the brief. The two are returned as separate fields, because collapsing them lets a structurally sound palette that ignores the brief report as a success.
The things thinking about it did not catch.
Every item below is a real defect, found by measurement, with a commit behind it. They are here because the failures are more informative than the features.
The warmth metric was inverted
Warm briefs were selecting cool palettes. The tool was confidently wrong in a way no structural check could catch, because the palettes it returned were perfectly valid. They were simply answering the opposite question. Found by a session using the tool on real client work, not by its own tests.
Chroma was normalised against an unreachable ceiling
The scale topped out at a saturation the generator could not actually produce, so a maximum-chroma request could never be satisfied and the fit score was permanently pessimistic.
Unmatched brief words were silently ignored
A brief containing words outside the vocabulary dealt an unconstrained palette and reported success. It now errors, and names the words it did not understand. Silently discarding half an instruction and returning a confident result is the worst available behaviour.
Knowing the limits is part of the tool
Asked for a neon accent for this site, the generator returned muted palettes and reported 'electric', 'loud' and 'confident' as out of vocabulary. That was the correct answer: it deals balanced palettes, and a neutral system with one saturated structural colour is a different problem. The accent was derived by measurement instead. A tool that reports its own boundary is more useful than one that always produces something.
- Node
- Model Context Protocol
- Umber engine
- Kern engine
- The font moods filter by broad category only. The catalogue carries usage tags rather than typographic classifications, so a finer promise would be one the data cannot keep.
Runs inside the studio's own pipeline.