You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,8 @@ All notable changes to this project are documented here. The format is based on
6
6
7
7
### Added
8
8
9
+
* Palette gamut checks. `Color.Palette.in_gamut?/2` and `Color.Palette.gamut_report/2` answer "is every stop in this palette inside the chosen RGB working space?", with `gamut_report/2` returning a per-stop breakdown listing exactly which stops failed.
10
+
9
11
* Public APIs for designer-tool integrations. `Color.Palette.Tonal.to_css/2` and `Color.Palette.ContrastScale.to_css/2` emit CSS custom-property blocks (selector and name prefix configurable). `Color.Palette.Tonal.to_tailwind/2` and `Color.Palette.ContrastScale.to_tailwind/2` emit `theme.extend.colors` fragments ready for `tailwind.config.js`. `Color.Gamut.SVG.render/1` renders a complete chromaticity-diagram SVG — projection, gamut overlays, Planckian locus, seed / palette overlays, sizing, and colour overrides all under a single keyword-list API.
10
12
11
13
*`Color.Gamut.Diagram` — pure-data module for chromaticity diagrams.
## Gamut audits — CI checks for palette accessibility
237
+
238
+
When a palette is generated, our algorithms gamut-map every stop into the working space passed via `:gamut` (default `:SRGB`). But palettes often travel — generated against sRGB on a designer's MacBook, hand-edited by a colourist in Display P3, re-imported through a DTCG file, then deployed to users on devices that span every display gamut. A CI check that "this palette is still legal sRGB after every transformation" is exactly the kind of guard you want in a design-system pipeline.
239
+
240
+
`Color.Palette.in_gamut?/2` answers a single yes/no across every stop:
241
+
242
+
```elixir
243
+
palette =Color.Palette.tonal("#3b82f6")
244
+
245
+
ifColor.Palette.in_gamut?(palette, :SRGB) do
246
+
:ok
247
+
else
248
+
raise"Brand palette has escaped sRGB"
249
+
end
250
+
```
251
+
252
+
Need to know **which** stops failed? Use `gamut_report/2`:
for %{label: l, color: c} <- report.out_of_gamut do
264
+
IO.puts("Stop #{l} (#{Color.to_hex(c)}) is outside sRGB")
265
+
end
266
+
```
267
+
268
+
Both functions dispatch on palette type — they work uniformly across `Tonal`, `Theme`, `Contrast`, and `ContrastScale`. For `Theme`, `gamut_report/2` returns the breakdown per sub-palette under `:sub_palettes` plus a flat `:out_of_gamut` list with `:sub_palette` keys for actionable failures.
269
+
270
+
A complete Mix task you can wire into CI:
271
+
272
+
```elixir
273
+
defmoduleMix.Tasks.Brand.Auditdo
274
+
useMix.Task
275
+
276
+
@shortdoc"Fails the build if the brand palette has escaped a target gamut"
0 commit comments