chroma-harmonization
Use when constructing or auditing a multi-hue palette where all hues should appear equally saturated at each contrast stop.
Skill by thrillmade
Chalk Labs
Need help deploying chroma-harmonization?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/thrillmade-chroma-harmonization
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/chroma-harmonization
What's inside
- Skill name
chroma-harmonization- Description
- Use when constructing or auditing a multi-hue palette where all hues should appear equally saturated at each contrast stop. Names the per-stop chroma cap rule (take the minimum achievable chroma across hues at the stop), the gamut bottleneck pattern (blue at mid-L is the classic limiter in sRGB; Display P3 — UDTS's default compose gamut — reshapes it), and the relationship to UDTS's default `harmony` palette variant. Generalizes Evil Martians' Harmony algorithm.
- License
- MIT
- Instructions
- 83 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Chroma harmonization
Multi-hue palettes look unbalanced when one hue is more saturated than the rest at the same brightness stop — a neon outlier in a calm set, a washed-out blue next to a vibrant red. Chroma harmonization is the fix: at each stop, cap every hue at the **lowest-achievable chroma** across the set so the palette reads as a coherent family.
## When to use
- Constructing a multi-hue palette (3+ hues at the same set of contrast stops).
- Auditing an existing palette where one hue looks "off" against the others.
- Generating UDTS's default `harmony` palette variant.
- Code review: flag per-hue chroma values picked independently — propose the cross-hue cap.
## When NOT to use
- Single-hue palettes (no other hues to harmonize against — chroma is unconstrained by the procedure).
- Brand-spot or accent palettes where one hue *should* dominate. Use the `max` palette variant instead — see [oklch-color-space](../oklch-color-space/SKILL.md).
- Palettes constrained to legacy sRGB-only output, where the narrower gamut shifts the bottleneck calculus back toward the classic blue-at-~220° limiter (the procedure still applies — Display P3 is the default target space; substitute the sRGB boundary deliberately for legacy-only catalogs).
## The algorithm
For each contrast stop in the palette (each L value):
1. For each hue in the set, find the maximum in-gamut chroma at that (L, H) in the target color space (**Display P3 by default** — UDTS composes end-to-end in P3 via apcach's `colorSpace: 'p3'`; sRGB only when a catalog is deliberately constrained to legacy-only output).
2. Take the **minimum** of those per-hue maxima. This is the stop's chroma ceiling.
3. **Recompose, don't just clamp:** at the shared ceiling, re-solve L per hue (apcach's constant-chroma branch) so each hue still hits the stop's target Lc against its background. Clamping chroma while leaving L untouched lets achieved Lc drift off target by up to ~5 across hues — the invariant is chroma constant AND Lc constant; hue and lightness are what's allowed to drift.
4. Emit every hue at the stop using the recomposed (L, c_ceiling, h).
```
for each stop L_target:
c_max_per_hue = { h: max_chroma_in_gamut(L_target, h) for h in hues }
c_ceiling = min(c_max_per_hue.values())
for each h in hues:
l_solved = apcach_constant_chroma_solve(target_lc, h, c_ceiling, bg)
emit oklch(l_solved, c_ceiling, h)
```
**Known counterexample, not a template:** UDTS's own `harmonizeChroma` does *not* recompose — it clamps chroma and leaves the original L untouched (`{ l: original.l, c: min(original.c, ceiling), h: original.h }`). That's exactly the Lc drift this rule warns about. If you're reading the shipped code as a reference, its chroma-clamp-without-recompose is the bug to fix, not the pattern to copy.
The bottleneck pattern: at moderate lightness (L ≈ 0.5), **blue (~220°)** is the classic limiter in sRGB — its gamut is narrowest there. In Display P3 (the default compose gamut) the boundary is wider and reshaped, so blue is not guaranteed to be the tightest hue — treat the bottleneck as empirical per palette rather than assuming ~220° holds. At the extremes (L near 0 or 1) the gamut shrinks for all hues in either space, so the ceiling collapses naturally.
**Recompose can't fix the bottleneck hue's own residual.** Recomposing corrects the *other* hues' Lc drift once they're capped to the bottleneck hue's ceiling — it can't correct the bottleneck hue itself, whose compose/measure residual (see [apca-contrast](../apca-contrast/SKILL.md)'s meter-vs-composer gamut mismatch) is a property of that one hue's own gamut edge. Only a matched meter — scoring on the same gamut the composer targeted — closes that residual; recompose alone can't.
## Why the *minimum*, not the average
Average would push half the hues out of gamut at the bottleneck. Maximum would push the bottleneck hue out of gamut. Minimum is the only value where every hue can hit the target chroma in-gamut — which is the constraint that has to hold for emission.
## Headroom rule
Stay ≥ 10% below the computed ceiling. This headroom is for the **emission edge**, not the harmonization math itself: rounding when materializing the sRGB hex fallback (the compatibility export for legacy consumers — see [oklch-color-space](../oklch-color-space/SKILL.md)) and display-driver quirks can push a borderline-in-gamut P3 value out of gamut once flattened to 8-bit sRGB. A headroom margin prevents those fallback-materialization failures; it does not change the P3-native chroma math above.
## Relationship to UDTS palette variants
- **`harmony`** (UDTS default): this algorithm exactly. Every hue capped to the cross-hue minimum.
- **`max`**: each hue uncapped at its own gamut ceiling. Useful for brand or accent palettes where consistency yields to vibrancy.
- **`muted`**: harmony or max with an additional user-supplied flat chroma cap (e.g. C ≤ 0.06) — produces tonal greys like sand, stone, slate.
- **`flat`**: a single chroma across all stops for one hue (no cross-hue constraint).
- **`grey`**: zero chroma, always generated.
A UDTS catalog can ship multiple variants per hue and bind theme roles to specific (hue, variant) pairs — see the UDTS theme docs.
## Verification
After harmonizing a stop:
1. **Gamut check:** every emitted `oklch(L, c_ceiling, h)` is `displayable()` in the target color space.
2. **Visual check:** at the same stop, all hues should report identical (or near-identical) saturation in a side-by-side swatch. Use [oklch.com](https://oklch.com) or a culori-based tool.
3. **Headroom check:** the actual ceiling sits ≥ 10% below the computed **Display P3**-gamut maximum at every (L, H) in the set (verify the sRGB-fallback headroom separately, at emission).
If any hue clips at the ceiling or visually "pops," recompute with a tighter chroma cap.
## Cross-references
- **Routed here by:** [designing-a-design-system](../designing-a-design-system/SKILL.md) — the L1 dispatcher for building or extending a system.
- **REQUIRED BACKGROUND:** [oklch-color-space](../oklch-color-space/SKILL.md) — the OKLCH primitive, the gamut-mapping rule.
- **For the contrast targets at each stop:** [apca-contrast](../apca-contrast/SKILL.md) — the Lc targets that fix each L value.
- **For starting-hue palette construction before harmonization:** [palette-relationships](../palette-relationships/SKILL.md).
## Sources
- [Evil Martians' Harmony](https://evilmartians.com/opensource/harmony) — the original algorithm + interactive demo.
- [Evil Martians' Harmonizer](https://github.com/evilmartians/harmonizer) — Figma plugin implementation.
- UDTS's `harmony` palette variant — the canonical productized form of this algorithm.From thrillmade/agent-skills, MIT.
More from thrillmade/agent-skills
- 0.557score
design-token-naming
thrillmade
SUPERSEDED by `token-naming-conventions` (L0) + `udts-naming-convention` (L2, incubating) — see the design-catalog section of the README; kept unchanged…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
api-contract-enforcement
thrillmade
Flag PRs that change the shape, semantics, or error behavior of a public API without versioning, deprecation, or migration notes.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
brand-voice-review
thrillmade
Review user-facing strings for brand-voice consistency.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
component-sizing
thrillmade
SUPERSEDED by `component-sizing-principles` (L0) + `udts-component-sizing-ladders` (L2, incubating) — see the design-catalog section of the README; kept…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
component-sizing-principles
thrillmade
Use when picking a control height (button / input / chip / badge), proposing a component-height or icon-size ladder for a density mode, or auditing one-off…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
consuming-a-design-system
thrillmade
Entry-point dispatcher for CONSUMING a design system in a product — installing its tokens, wiring CSS variables, theming, upgrading across token releases, or…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
design-system-consistency
thrillmade
Use when judging whether a RENDERED surface obeys its own design system — screenshots or a live page plus the computed styles behind them — as the drift lens…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
designing-a-design-system
thrillmade
Entry-point dispatcher for BUILDING or EXTENDING a design system — creating a token architecture, color system, type scale, spacing system, or…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
skill-frontmatter-quality
thrillmade
Review SKILL.md frontmatter for trigger surface, specificity, voice, and completeness.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
apca-contrast
thrillmade
Use when picking text-on-surface contrast, auditing an accessibility budget, or generating a color against a specific contrast target.
SkillBFreshness: B★ 2Claude Code +9 - 0.554score
conventions-template
thrillmade
Template for a "review like me" skill - captures one maintainer's review conventions (formatting, what to flag, what to ignore).
SkillBFreshness: B★ 2Claude Code +9 - 0.553score
curating-a-skill-catalog
thrillmade
Use when judging whether a skill earns its place — running or reviewing a skill census cycle, triaging…
SkillBFreshness: B★ 2Claude Code +9
Signals
- Stars
- 2
- Forks
- 0
- Open issues
- 40
- Last commit (this folder)
- Aug 23, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/thrillmade/agent-skills
- Website
- logmind.dev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from thrillmade
- 0.557score
api-contract-enforcement
thrillmade
Flag PRs that change the shape, semantics, or error behavior of a public API without versioning, deprecation, or migration notes.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
brand-voice-review
thrillmade
Review user-facing strings for brand-voice consistency.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
design-token-naming
thrillmade
SUPERSEDED by `token-naming-conventions` (L0) + `udts-naming-convention` (L2, incubating) — see the design-catalog section of the README; kept unchanged…
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
skill-frontmatter-quality
thrillmade
Review SKILL.md frontmatter for trigger surface, specificity, voice, and completeness.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
apca-contrast
thrillmade
Use when picking text-on-surface contrast, auditing an accessibility budget, or generating a color against a specific contrast target.
SkillBFreshness: B★ 2Claude Code +9 - 0.557score
component-sizing
thrillmade
SUPERSEDED by `component-sizing-principles` (L0) + `udts-component-sizing-ladders` (L2, incubating) — see the design-catalog section of the README; kept…
SkillBFreshness: B★ 2Claude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get chroma-harmonization running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
chroma-harmonization skill. Agent Mart. https://agentmart.dev/skills/thrillmade-chroma-harmonization (last updated 2026-10-24)