Digitopia Labs

Colour palette generator

Generate a colour palette and see what is wrong with it. The lint names every offence in words instead of handing back a score with no argument.

Generate a palette

5 colours, generated in your browser. Nothing is sent anywhere.

  1. Swatch 01: #6366f1
  2. Swatch 02: #8b5cf6
  3. Swatch 03: #f8fafc
  4. Swatch 04: #94a3b8
  5. Swatch 05: #0f172a

A harmony around a random hue, with the lightnesses spread so no two swatches land on the same tone. The lint below runs again on whatever comes back.

of 100Anti-slop score 30 out of 100. Reads as templated. Four offences. The heaviest: Tailwind indigo, verbatim.

  • CriticalSwatch 01
    Tailwind indigo, verbatim

    #6366f1 sits ΔE 0.0000 from Tailwind Indigo 500 (#6366f1) — close enough to BE it. That is one of the most overused "AI-generated SaaS" colours: a Tailwind/shadcn default that shows up, barely touched, across an enormous share of AI product UI. Swap for Deep Teal (#0d9488) instead.

  • CriticalSwatch 02
    Tailwind violet, verbatim

    #8b5cf6 sits ΔE 0.0000 from Tailwind Violet 500 (#8b5cf6) — close enough to BE it. That is one of the most overused "AI-generated SaaS" colours: a Tailwind/shadcn default that shows up, barely touched, across an enormous share of AI product UI. Swap for Amber (#b45309) instead.

  • HighSwatch 03
    Untouched default neutrals

    3 of this palette's colours are Tailwind/shadcn slate steps, verbatim (within ΔE 0.012) — the palette is leaning on the default ramp for its neutrals, which is the single most common tell of a templated UI. Give the neutrals a temperature of their own, across the WHOLE ramp: #fcebdb is a starting point at #f8fafc's lightness, but swapping that one step is enough to clear this, leaving 2 borrowed steps just under the 3 this rule counts from.

  • HighSwatch 02
    The purple-indigo gradient

    #6366f1 and #8b5cf6 are both saturated purple-indigo (h 277° and 293°) at effectively the same lightness (Δ 0.020) — the purple-to-indigo gradient pair that has become AI product UI's house style. Keep one and give the other a real job: #83892c is its complement at the same lightness.

5 of 9 checks passed

no Tailwind purple · no stock AI magenta · no neon glow on black · something leads · not AI beige

What makes a palette read as machine-generated

Not randomness — the opposite. A palette reads as generated when it lands on the same small set of decisions everything else landed on, and the tells are specific enough to list. The most conspicuous is a Tailwind or shadcn default used verbatim: #6366f1 (indigo 500), #4f46e5 (indigo 600), #8b5cf6 (violet 500) and #9333ea (purple 600) have been the house accent of an enormous share of 2024–2026 product UI, and a palette that reaches for one unmodified has made no decision at all. The magenta half of the same reflex, #ec4899, usually arrives with it as a gradient.

After that come the arrangements rather than the colours. Two bright, saturated purples at almost the same lightness are not a ramp, they are the purple-to-indigo gradient every AI product launch shipped for two years. Neutrals lifted straight off zinc, slate, neutral, gray or stone are three or four decisions nobody made — greys are most of the pixels in an interface, and taking them off the shelf is the fastest way to look like the shelf. An electric accent on a near-black surface is the dark-mode-with-a-glow aesthetic. Three or more warm creams between L 82 and white are “AI beige”, the reflex that arrived as a reaction to the indigo one. And a palette where nothing leads — every colour low in chroma, spread evenly through lightness, no accent sharp enough to point at anything — reads as timid rather than considered, which is the failure mode of generating by rule instead of by intent.

None of these are bad colours. #4f46e5 is a perfectly good indigo and a warm cream is a perfectly good surface. What makes them a tell is that they are the default: the thing you get when the decision was not made, in a year when everyone is getting the same default from the same tools.

What the lint actually checks

Nine rules run on every palette, and the tool above names the ones that found nothing as well as the ones that did — a clean score should be a list of things that were looked for, not an absence you have to take on trust. They fall into two families.

  • Four proximity rules measure each colour against the named Tailwind defaults — indigo, violet, purple and the gradient’s pink — in OKLab ΔE, which is a perceptual distance rather than a hex comparison, so a colour nudged one token off the default is still caught.
  • Five palette-shape rules judge the set rather than any one member: neutrals matching three or more steps of a default ramp, a saturated purple pair less than 0.06 apart in lightness, a bright accent on a surface below L 25, three or more creams in the 40–110° hue band above L 82, and a palette whose most saturated colour is below c 0.09 with an even lightness ladder.

Every threshold above was set against real palettes rather than chosen for roundness, and each finding carries its own measurement — the ΔE, the hue, the chroma — so the claim is checkable rather than assertive. The score is 100 minus what the findings cost: 20 for a proximity offence, 15 for a palette-shape one, 5 for an advisory, floored at zero.

Why some findings are advisories and not offences

The indigo-violet corner of the wheel is genuinely crowded, and real brands live in it. Measured in ΔE against the nearest banned default: Discord’s #5865f2 at 0.0151, Stripe’s #635bff at 0.0317, Twitch’s #9146ff and Figma’s #a259ff at 0.0411, and Linear’s #5e6ad2 at 0.0493. Those are considered brand colours, not slop.

So the rule is graded rather than binary. Inside ΔE 0.012 a colour is not near the default, it is the default, and that is charged as an offence. Between 0.012 and 0.06 the finding is an advisory: the neighbourhood is oversubscribed and worth knowing about, which is useful, and it is not a telling-off. That boundary is not a compromise — it is the largest value that keeps every measured brand primary out of the offence band. Telling Stripe their brand colour is one of the most overused AI colours is the false positive that gets a lint switched off, and a lint nobody leaves on is worth nothing.

Why generating is the easy half

The generator above is not doing anything clever, and it should not pretend to be. It picks a hue, asks for a harmony around it — analogous, triadic, complementary or split-complementary — and then does the one thing that matters more than the harmony: spreads the five lightnesses across a band by stratifying it rather than sampling it, so five swatches cannot come back at the same tone. Sampling independently produces palettes with four colours at one lightness often enough to look like a bug. Monochrome is deliberately excluded from the automatic schemes, because a generate that silently returns four lightnesses of one hue reads as broken rather than as a choice; that belongs on the tints and shades page, where a one-hue ramp is the point.

That is the whole trick, and every other generator does some version of it. The reason this page exists is the second half: a palette you did not choose is worth exactly as much as the judgement that comes with it, and “here are five colours” is not a judgement. Press Generate a few times and read what the lint says each time — the useful output is not the palette, it is knowing which of the palettes was worth keeping and why.

Why there are no fix buttons on this page

Because a fix has to be proved, and proving one is not a thing a landing page should do quietly on your behalf. Every suggested colour comes from the lint’s own substitution — a named alternative for a banned default, a temperature-flipped neutral, a sharpened version of the palette’s own hue — and in Palette mode it is applied to a copy of your palette and the whole palette is linted again before the button is offered. It appears only if three things hold: the score strictly rose, that finding’s own rule costs strictly less than it did, and no other rule costs more. If a fix cannot clear that bar, there is no button at all.

This matters more than it sounds. “Warm this grey” is good advice on most palettes and, on one where the accent is already warm, it trips the hue-spread rule and makes things worse — and no amount of reasoning in advance settles which palette you have. Measuring it settles it, per palette, every time. A lint that tells you to change something and is wrong about it is worse than no lint, so the suggestions live where the proof lives.

What a good score does not mean

100 means nothing here matched a known template. It does not mean the palette is good, that the colours work together at the sizes you will use them, or that any pair of them can carry text — that last one is a separate question with a separate answer, and the contrast checker is where it gets one. The lint is a check for the specific ways a 2026 palette gives itself away, held to measurements you can re-run. Taste is still yours.

When you want to fix it, not just be told

This page generates and judges. Palette mode does the rest: lock the swatches you have decided on and generate around them, name and role each colour, paste a set of hexes in from an existing brand, and — the part this page deliberately leaves out — apply a fix. Every fix there is proved before it is offered, by applying it to a copy of your palette and linting again: the button only appears if the score rose, that finding got cheaper, and no other rule got worse. From there the same palette carries straight into the contrast matrix and the exporters, because the palette travels with you in the address bar.

Take this palette into the modeIt opens on the 5 colours above — the link carries your palette in the address, not a default.

Opens Palette mode. Free, no sign-up, and it runs in your browser like this page does.