authorgravatar for lucenz@proton.meSimone <lucenz@proton.me> 2026-08-15 01:32:33+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-14 19:32:33-04:00
log74f7b434865c2d758c7b1cd5f52f4c96b76d03fb
treea4bd0a3b19ef68c1dc98cb4a65600169280c4466
parente25021af767b10c560862fcec714cf67fb22cfae
signature Signed by PGP key B5690EEEBB952194

fix(web): bound OKLCH gamut mapping (#6485)

Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>

2 files changed, 17 insertions(+), 1 deletions(-)

apps/web/src/themePalette.test.ts+12
...@@ -246,6 +246,18 @@ describe("theme files", () => {...@@ -246,6 +246,18 @@ describe("theme files", () => {
246 }246 }
247 });247 });
248248
249 it("gamut maps extreme finite OKLCH chroma from theme files", () => {
250 const theme = parseThemeFile({
251 version: THEME_FILE_VERSION,
252 name: "Extreme chroma",
253 appearance: "light",
254 colors: { accent: "oklch(0.5 1e303 0)" },
255 });
256
257 expect(theme.colors.accent).toBe("oklch(0.5 1e+303 0)");
258 expect(themeColorToHex(theme.colors.accent)).toBe("#b5005e");
259 });
260
249 it("rejects unknown roles and invalid color values", () => {261 it("rejects unknown roles and invalid color values", () => {
250 expect(() =>262 expect(() =>
251 parseThemeFile({263 parseThemeFile({
apps/web/src/themePalette.ts+5-1
...@@ -902,7 +902,11 @@ function mapThemeOklchToSrgbGamut(color: ThemeOklch): ThemeOklch {...@@ -902,7 +902,11 @@ function mapThemeOklchToSrgbGamut(color: ThemeOklch): ThemeOklch {
902902
903 let low = 0;903 let low = 0;
904 let high = color.C;904 let high = color.C;
905 const steps = Math.max(1, Math.ceil(Math.log2(Math.max(color.C, 0.000001) / 0.000001)));905 const chromaResolution = 0.000001;
906 const steps = Math.max(
907 1,
908 Math.ceil(Math.log2(Math.max(color.C, chromaResolution)) - Math.log2(chromaResolution)),
909 );
906 for (let step = 0; step < steps; step += 1) {910 for (let step = 0; step < steps; step += 1) {
907 const mid = (low + high) / 2;911 const mid = (low + high) / 2;
908 if (isInGamut(mid)) low = mid;912 if (isInGamut(mid)) low = mid;