Dev.to WebDev 🛠 Dev 👁 0 📖 6 min read

I taught my local model taste. Here's the prompt that banned the purple gradient.

Ask any model for a landing page and you can guess it before it renders. An indigo-to-violet gradient. A pill badge that says "New". A centered headline in Inter. Two buttons. Three cards, each with an icon sitting in a

Ask any model for a landing page and you can guess it before it renders.

An indigo-to-violet gradient. A pill badge that says "New". A centered headline in Inter. Two buttons. Three cards, each with an icon sitting in a pastel circle. "Supercharge your workflow."

It isn't bad, exactly. It's nobody's. Put a different logo on it and nothing else would need to change.

Onyx is the model behind Flash, my open source agent. It's an open-weights base running in Ollama, on your own machine, shaped by one long system prompt (a Modelfile). Onyx 3 is the version where I tried to teach it the thing that's hardest to write down:

taste.

Why models default to the purple gradient

A model learns what a "good website" looks like from millions of websites. Most of those were built from the same handful of templates and the same CSS framework defaults. So when you ask for "a modern landing page", the most likely page is the template. indigo-500 is the most likely accent. Inter is the most likely font.

The model isn't failing at design. It's succeeding at averaging.

So you can't fix it by saying "make it look good". "Good" is exactly what it thinks the average is. You have to change how it decides.

Taste is a decision with a reason

The core of the new TASTE section is one definition:

Taste is a decision with a reason you can say about this subject, made on purpose and held everywhere. Default is the absence of one, and a stranger can see it from across the room.

Everything else hangs off that. Onyx 3 now writes itself a four-line brief before it touches a page, a deck or a chart:

  1. What this is for, and who opens it.
  2. Two adjectives for the feel, and neither may be "modern" or "clean", because those describe every template on earth.
  3. The type and the palette, each with where it came from.
  4. One signature detail this would be remembered by.

Rule two does a surprising amount of work. Ban "modern and clean" and the model has to reach for "warm and floury", "dense and calm", "archival and quiet". Those words point somewhere. "Modern" points at the template.

Then it has to derive the look from the subject:

A bakery has flour, crust, and handwriting; a trading tool has density, tabular figures, and a red that means loss; a field guide has plates, captions, and a serif built for reading. The answer is in the thing, never in what last year's landing pages wore.

And it has to pass the swap test:

Put a competitor's logo on it. If nothing else would need to change, it has no point of view yet, and it is not done.

Typography: Inter is a fine UI face and a terrible default

I didn't ban Inter. I banned reaching for it without a reason. The TYPOGRAPHY section maps fonts to jobs:

  • a screen serif (Newsreader, Source Serif 4, Literata) for anything read at length,
  • a sturdy grotesk (Geist, Public Sans, IBM Plex Sans) for product chrome,
  • a humanist sans where warmth matters,
  • a monospace for code, data and a technical voice.

Then the details that separate "set" from "typed":

  • A real scale. Near 1.2 for interfaces, 1.333 or more for editorial, fluid with clamp(). Every size is a step.
  • Leading tightens as size grows. Body around 1.55, display around 1.05.
  • Tracking goes negative on big type and positive on small caps. Lowercase body text is never tracked.
  • Measure of 45 to 75 characters, text-wrap: balance on headings, pretty on paragraphs.
  • Tabular figures wherever numbers line up or count. A price that jitters while it animates is a typography bug.
  • No faux bold. Load the real weight or use a variable font.
  • Font loading that doesn't shove the layout: woff2, subset, preload one face, and a fallback tuned with size-adjust.

Two faces at most, plus mono if the content has code. The prompt's phrasing: "Three faces is a ransom note."

Layout: fewer boxes

The single most common tell in generated UI is boxes. A card inside a card inside a section with a border. So the LAYOUT section has an order of operations:

Separate with space first, a shift in background second, a hairline third, a bordered card last and only for things that really are separate objects you could pick up.

Plus a few rules that sound obvious and almost never happen by default:

  • Space is a scale (4, 8, 12, 16, 24, 32, 48, 64, 96). A 13px gap is a value nobody chose.
  • Proximity carries grouping. Space inside a group is about half the space between groups.
  • One focal point per screen, checked with a squint test on the screenshot.
  • Asymmetry reads as designed, symmetry as default.
  • Structure comes from the content. List what the reader must learn or do, in order, and each item becomes a section shaped by what it holds. "The hero, three feature cards, testimonial, call to action sequence is what you do when you skipped that list."

Color: OKLCH, roles, and one accent

HSL lies. Its "50% lightness" yellow is far brighter than its "50% lightness" blue, which is why hand-picked palettes look lumpy. Onyx 3 builds color in OKLCH, where equal lightness steps look equal:

  • Ramps step lightness evenly, hold the hue, and taper chroma at the ends.
  • Neutrals are tinted toward the brand hue, so greys belong to the product.
  • Tokens are named by role, not hue: --text-muted, never --grey-500. Then dark mode is a value swap.
  • One accent at 5 to 10 percent of the surface. "An accent everywhere is no accent."
  • The palette comes from the subject: a photo of the product, the material, a label, an era. If you can't tell the palette's story, it's not a palette yet.
  • Dark mode is designed, not inverted. Elevation gets lighter, the accent loses a little chroma so it doesn't vibrate.
  • A gradient needs a reason (light, material, a data value) and interpolates in oklch so the middle doesn't go muddy.

The ban list

Finally, a section called THE GENERIC LOOK: the marks of a page nobody designed. Each is allowed only if the brief asks for it by name.

  • The indigo or purple-to-pink hero gradient, and the exact framework defaults it's made of.
  • Gradient-filled headline text.
  • Inter on everything, headings included.
  • Glass cards on blurred blobs, neon glows on near-black.
  • Emoji as icons, a sparkle icon meaning "clever", icons in pastel circles above three equal cards.
  • rounded-2xl and a big shadow on every element.
  • "Unlock the power of", "Seamless", "Revolutionize", a fake logo wall.

And the important last line:

When you catch one of these in your own draft, replace it with the choice the brief points to, not with a different cliche.

Without that, a model that's told "no purple gradient" ships a teal gradient. Same page, new paint.

Taste is a constraint, not a vibe

The thing I keep coming back to: none of this is mystical. Every rule above is something a designer would say out loud to a junior on their first week. "Why this font?" "What's the one thing to remove?" "Which color isn't in the system?" Models are great at following rules that come with reasons. They're bad at inventing the reasons.

So Onyx 3 now judges its own screenshot like a hard art director, with four questions:

  1. Where does the eye land first, and is that the right place?
  2. What is the one thing to remove?
  3. Which spacing is off the scale?
  4. Which color is not in the system?

"A first draft that passes all four is rare, and the second is where it gets good."

Try it

Onyx builds from its Modelfile with Ollama:

git clone https://github.com/Natuworkguy/flash
cd flash
python3 models/build.py models/flash-onyx-<version>.Modelfile

Then ask it for a landing page for something specific (a neighborhood bakery, a seed library, a bike repair shop) and see what it picks. If it ever hands you an indigo gradient, it owes you a reason.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.