Guide 01
The color wheel generator
Everything downstream — surfaces, borders, states, gradients — depends on the three decisions made here. This is how Curiosityjivar turns one hue into a primary, a secondary and an accent that can survive a real interface.
Start with one hue, not five colours
Most palettes fail because they are assembled, not derived. Five colours are chosen because each one looks good in isolation, then they are dropped into an interface where they must sit beside each other at 1px, 14px and 400px scales simultaneously. The relationships were never defined, so every new component becomes a negotiation.
A generator inverts that. You pick a single base hue — the angle on the wheel that carries your brand — and every other colour is a defined offset from it. Change the base and the whole system rotates coherently. In Curiosityjivar the base hue is an integer from 0 to 359, stored as a single token, and the secondary and accent are expressed as deltas rather than absolute values.
Harmony rules, and what they are actually for
Classic harmony schemes are angular relationships on the hue wheel. They are not aesthetic guarantees; they are heuristics that keep two hues far enough apart to be distinguishable and close enough to feel deliberate.
| Scheme | Secondary offset | Accent offset | Best for |
|---|---|---|---|
| Analogous | +30° | −30° | Calm, single-brand products; dashboards and content sites |
| Complementary | +180° | +150° | High-contrast marketing pages with one loud call to action |
| Triadic | +120° | +240° | Playful products with several equally weighted categories |
| Split complementary | +150° | +210° | A safer complementary: tension without the vibration |
The trap is treating the output as finished. Two hues 180° apart in HSL can have wildly different perceived lightness — a pure yellow and a pure blue are nominally "equal" at 50% lightness and are nothing of the sort to the eye. That is why the generator runs a lightness correction pass after the hue offset, nudging each derived colour until its relative luminance lands in the band the role requires.
Roles before values
Before any hex code exists, each colour needs a job description:
- Primary — the colour of intent. Buttons that commit an action, active navigation, selected states, progress. It should be usable as a background behind white or near-white text, which puts a ceiling on its lightness.
- Secondary — the colour of structure. Section headers, secondary buttons, chart series two, informational badges. It should be visibly different from primary at a glance but never compete with it for a click.
- Accent — the colour of exception. Highlights, new-item pips, the one gradient on the landing page. Used on roughly a tenth of the visible surface, which is why it can afford to be the most saturated value in the system.
The old 60-30-10 guideline — dominant, supporting, accent — is still the fastest sanity check for a layout. If the accent is covering a third of the viewport it has stopped being an accent, and the generator's contrast maths will start failing on the surfaces beneath it.
HSL, OKLCH and the choice of colour space
HSL is convenient and universally supported: hue is an angle, saturation and lightness are percentages, and rotating a palette is a single addition. Its weakness is perceptual — equal lightness values do not look equally light across hues. OKLCH, part of the CSS Color Module Level 4 work and now widely supported in current browsers, solves that by being closer to human perception: a lightness of 0.7 looks broadly like 0.7 whether the hue is teal or orange.
Curiosityjivar generates in HSL for the wheel interaction — it is what people can reason about while dragging — then converts through a perceptual step for the lightness ramp, and finally emits HEX for maximum compatibility plus HSL and OKLCH strings for teams that want them. If your build targets only current evergreen browsers, taking the OKLCH output directly gives you smoother ramps with fewer manual corrections.
Where automated harmony stops working
Pros of generated harmony: instant coverage of every role, no accidental near-duplicates, consistent state derivation, and a palette that can be regenerated for a rebrand in seconds rather than a sprint.
Cons: it has no cultural memory. A green-red complementary pair is mathematically clean and reads as a holiday theme in many markets. It also does not know that your industry has a default — finance skews blue, agriculture skews green, developer tooling skews violet — and that deviating is either a positioning decision or a mistake, never a neutral one. And it cannot see your logo sitting in the corner of the header fighting the accent.
The practical workflow: generate, then override one value at most. If you find yourself overriding three, the base hue was wrong. Rotate the wheel instead and regenerate — it is faster and the system stays internally consistent.
Checking the result
Before you export, put the three colours through four quick tests. One: place the primary as a button background with your body text colour on it and confirm the ratio. Two: put secondary and accent side by side at 16px and check they are still distinguishable in grayscale. Three: view the trio at 20% opacity over your darkest surface — that is what borders and dividers will look like. Four: look at it on a phone outdoors if you can, because low-saturation dark palettes that sing on a calibrated monitor can disappear entirely in daylight.
Next: contrast and accessibility covers the measurement side in detail.