Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion app/client/cypress/support/Pages/Anvil/AnvilSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export class AnvilSnapshot {

this.agHelper
.GetElement(this.locators.canvas)
.matchImageSnapshot(`anvil${widgetName}CanvasDark`);
.matchImageSnapshot(`anvil${widgetName}CanvasDark`, {
comparisonMethod: "ssim",
});

this.setTheme("light");
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -918,17 +918,22 @@ export class DarkModeTheme implements ColorModeTheme {
private get bdAccent() {
const color = this.seedColor.clone();

// For light content on dark background APCA contrast is negative. −15 is “The absolute minimum for any non-text that needs to be discernible and differentiable, but does not apply to semantic non-text such as icons”. In practice, thin borders are perceptually too subtle when using this as a threshold. −25 is used as the required minimum instead. Failure to reach this contrast level is most likely due to high lightness. Lightness and chroma are set to ones that reach the threshold universally regardless of hue.
if (this.bg.contrastAPCA(this.seedColor) >= -25) {
if (this.seedIsAchromatic) {
color.oklch.l = 0.87;
color.oklch.c = 0;
}
if (this.seedIsCold) {
color.oklch.l = 0.42;
color.oklch.c = 0.07;
}

if (!this.seedIsAchromatic) {
color.oklch.l = 0.84;
color.oklch.c = 0.13;
}
if (!this.seedIsCold) {
color.oklch.l = 0.38;
color.oklch.c = 0.05;
}

if (this.seedIsAchromatic) {
color.oklch.c = 0;
}
// For light content on dark background APCA contrast is negative. −15 is “The absolute minimum for any non-text that needs to be discernible and differentiable, but does not apply to semantic non-text such as icons”.
if (this.bg.contrastAPCA(this.seedColor) >= -15) {
color.oklch.l += 0.05;
}

return color;
Expand All @@ -938,6 +943,8 @@ export class DarkModeTheme implements ColorModeTheme {
// Keyboard focus outline
const color = this.bdAccent.clone();

color.oklch.l = 0.8;

// Achromatic seeds still produce colorful focus; this is good for accessibility even though it affects visual style
if (this.seedChroma < 0.12) {
color.oklch.c = 0.12;
Expand All @@ -951,18 +958,15 @@ export class DarkModeTheme implements ColorModeTheme {
// Used in checkbox, radio button
const color = this.bdAccent.clone();

color.oklch.l = 0.4;
color.oklch.c = 0.012;

if (this.seedIsAchromatic) {
color.oklch.c = 0;
}

if (this.bg.contrastAPCA(color) > -25) {
color.oklch.l += 0.15;
}

if (this.bg.contrastAPCA(color) <= -25) {
color.oklch.l += 0.09;
if (this.bg.contrastAPCA(color) >= -15) {
color.oklch.l += 0.05;
}

return color;
Expand All @@ -989,8 +993,12 @@ export class DarkModeTheme implements ColorModeTheme {
private get bdPositive() {
const color = this.bgPositive.clone();

color.oklch.l += 0.05;
color.oklch.c += 0.05;
color.oklch.l = 0.41;
color.oklch.c = 0.05;

if (this.bg.contrastAPCA(color) >= -15) {
color.oklch.l += 0.05;
}

return color;
}
Expand All @@ -1009,13 +1017,16 @@ export class DarkModeTheme implements ColorModeTheme {
// Negative (red) border. Produced out of bgNegative. Additional compensations are applied if seed is within red range.
const color = this.bgNegative.clone();

color.oklch.l = 0.46;
color.oklch.c = 0.1;

if (
this.bdAccent.oklch.l > 0.5 &&
this.bdAccent.oklch.c > 0.15 &&
this.bdAccent.oklch.h < 27 &&
this.bdAccent.oklch.h >= 5
) {
color.oklch.l += 0.18;
color.oklch.l += 0.03;
}

if (
Expand All @@ -1024,10 +1035,13 @@ export class DarkModeTheme implements ColorModeTheme {
this.bdAccent.oklch.h >= 27 &&
this.bdAccent.oklch.h < 50
) {
color.oklch.l += 0.05;
color.oklch.h -= 5;
}

if (this.bg.contrastAPCA(color) >= -15) {
color.oklch.l += 0.05;
}

return color;
}

Expand All @@ -1047,13 +1061,16 @@ export class DarkModeTheme implements ColorModeTheme {
private get bdWarning() {
const color = this.bgWarning.clone();

color.oklch.l = 0.48;
color.oklch.c = 0.12;

if (
this.bdAccent.oklch.l > 0.5 &&
this.bdAccent.oklch.c > 0.15 &&
this.bdAccent.oklch.h < 85 &&
this.bdAccent.oklch.h >= 60
) {
color.oklch.l += 0.18;
color.oklch.l += 0.03;
}

if (
Expand All @@ -1062,10 +1079,13 @@ export class DarkModeTheme implements ColorModeTheme {
this.bdAccent.oklch.h >= 85 &&
this.bdAccent.oklch.h < 110
) {
color.oklch.l += 0.05;
color.oklch.h -= 5;
}

if (this.bg.contrastAPCA(color) >= -15) {
color.oklch.l += 0.05;
}

return color;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -933,18 +933,18 @@ export class LightModeTheme implements ColorModeTheme {
}

private get bdAccent() {
// Accent border color
// Accent border color. Lighter and less saturated than accent to put focus on the text label and create nice-looking harmony.
const color = this.seedColor.clone();

// For dark content on light background APCA contrast is positive. 15 is “The absolute minimum for any non-text that needs to be discernible and differentiable, but does not apply to semantic non-text such as icons”. In practice, thin borders are perceptually too subtle when using this as a threshould. 25 is used as the required minimum instead. Failure to reach this contrast level is most likely due to high lightness. Lightness and chroma are set to ones that reach the threshold universally regardless of hue.
if (this.bg.contrastAPCA(this.seedColor) <= 25) {
if (this.seedIsAchromatic) {
color.oklch.l = 0.25;
color.oklch.l = 0.55;
color.oklch.c = 0;
}

if (!this.seedIsAchromatic) {
color.oklch.l = 0.45;
color.oklch.l = 0.55;
color.oklch.c = 0.15;
}
}
Expand All @@ -954,7 +954,9 @@ export class LightModeTheme implements ColorModeTheme {

private get bdFocus() {
// Keyboard focus outline
const color = this.bdAccent.clone();
const color = this.bgAccent.clone();

color.oklch.l = 0.55;

// Achromatic seeds still produce colorful focus; this is good for accessibility even though it affects visual style
if (this.seedChroma < 0.15) {
Expand All @@ -969,14 +971,14 @@ export class LightModeTheme implements ColorModeTheme {
// Used in checkbox, radio button
const color = this.bdAccent.clone();

color.oklch.c = 0.001;
color.oklch.c = 0.01;

if (this.seedIsAchromatic) {
color.oklch.c = 0;
}

if (this.bg.contrastAPCA(color) < 25) {
color.oklch.l -= 0.2;
if (this.bg.contrastAPCA(color) <= 15) {
color.oklch.l -= 0.05;
}

return color;
Expand Down Expand Up @@ -1008,13 +1010,14 @@ export class LightModeTheme implements ColorModeTheme {
// Positive (green) border. Additional compensations are applied if seed is withing green range.
const color = this.bgPositive.clone();

color.oklch.l = 0.8;

if (
this.bdAccent.oklch.l > 0.5 &&
this.bdAccent.oklch.c > 0.11 &&
this.bdAccent.oklch.h < 145 &&
this.bdAccent.oklch.h >= 116
) {
color.oklch.l += 0.1;
color.oklch.h += 5;
}

Expand All @@ -1024,7 +1027,6 @@ export class LightModeTheme implements ColorModeTheme {
this.bdAccent.oklch.h >= 145 &&
this.bdAccent.oklch.h < 166
) {
color.oklch.l += 0.05;
color.oklch.h -= 5;
}

Expand All @@ -1044,13 +1046,14 @@ export class LightModeTheme implements ColorModeTheme {
// Negative (red) border. Produced out of bgNegative. Additional compensations are applied if seed is within red range.
const color = this.bgNegative.clone();

color.oklch.l = 0.78;

if (
this.bdAccent.oklch.l > 0.5 &&
this.bdAccent.oklch.c > 0.15 &&
this.bdAccent.oklch.h < 27 &&
this.bdAccent.oklch.h >= 5
) {
color.oklch.l += 0.1;
color.oklch.h += 5;
}

Expand All @@ -1060,7 +1063,6 @@ export class LightModeTheme implements ColorModeTheme {
this.bdAccent.oklch.h >= 27 &&
this.bdAccent.oklch.h < 50
) {
color.oklch.l += 0.05;
color.oklch.h -= 5;
}

Expand All @@ -1080,13 +1082,14 @@ export class LightModeTheme implements ColorModeTheme {
// Warning (yellow) border. Produced out of bgNegative. Additional compensations are applied if seed is within yellow range.
const color = this.bgWarning.clone();

color.oklch.l = 0.82;

if (
this.bdAccent.oklch.l > 0.5 &&
this.bdAccent.oklch.c > 0.09 &&
this.bdAccent.oklch.h < 85 &&
this.bdAccent.oklch.h >= 60
) {
color.oklch.l += 0.1;
color.oklch.h += 10;
}

Expand All @@ -1096,7 +1099,6 @@ export class LightModeTheme implements ColorModeTheme {
this.bdAccent.oklch.h >= 85 &&
this.bdAccent.oklch.h < 110
) {
color.oklch.l += 0.05;
color.oklch.h -= 10;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -727,46 +727,46 @@ describe("bd color", () => {
describe("bdAccent color", () => {
it("should return correct color when chroma < 0.04", () => {
const { bdAccent } = new DarkModeTheme("oklch(0.45 0.03 60)").getColors();
expect(bdAccent).toEqual("rgb(83.144% 83.144% 83.144%)");
expect(bdAccent).toEqual("rgb(25.976% 25.976% 25.976%)");
});

it("should return correct color when chroma > 0.04", () => {
const { bdAccent } = new DarkModeTheme("oklch(0.45 0.1 60)").getColors();
expect(bdAccent).toEqual("rgb(100% 71.253% 43.937%)");
expect(bdAccent).toEqual("rgb(33.765% 23.5% 15.034%)");
});
});

describe("bdFocus color", () => {
it("should return correct color when lightness < 0.4", () => {
const { bdFocus } = new DarkModeTheme("oklch(0.3 0.4 60)").getColors();
expect(bdFocus).toEqual("rgb(100% 71.253% 43.937%)");
expect(bdFocus).toEqual("rgb(84.145% 71.694% 61.962%)");
});

it("should return correct color when lightness > 0.65", () => {
const { bdFocus } = new DarkModeTheme("oklch(0.85 0.03 60)").getColors();
expect(bdFocus).toEqual("rgb(100% 73.208% 48.082%)");
expect(bdFocus).toEqual("rgb(96.595% 66.918% 41.877%)");
});

it("should return correct color when chroma < 0.12", () => {
const { bdFocus } = new DarkModeTheme("oklch(0.85 0.1 60)").getColors();
expect(bdFocus).toEqual("rgb(100% 73.208% 48.082%)");
expect(bdFocus).toEqual("rgb(96.595% 66.918% 41.877%)");
});

it("should return correct color when hue is between 0 and 55", () => {
const { bdFocus } = new DarkModeTheme("oklch(0.85 0.1 30)").getColors();
expect(bdFocus).toEqual("rgb(100% 70.589% 64.779%)");
expect(bdFocus).toEqual("rgb(100% 62.553% 56.236%)");
});

it("should return correct color when hue > 340", () => {
const { bdFocus } = new DarkModeTheme("oklch(0.85 0.1 350)").getColors();
expect(bdFocus).toEqual("rgb(100% 67.801% 85.002%)");
expect(bdFocus).toEqual("rgb(97.244% 61.583% 78.647%)");
});
});

describe("bdNeutral color", () => {
it("should return correct color when chroma < 0.04", () => {
const { bdNeutral } = new DarkModeTheme("oklch(0.45 0.03 60)").getColors();
expect(bdNeutral).toEqual("rgb(94.752% 94.752% 94.752%)");
expect(bdNeutral).toEqual("rgb(33.384% 33.384% 33.384%)");
});
});

Expand All @@ -775,14 +775,14 @@ describe("bdNeutralHover", () => {
const { bdNeutralHover } = new DarkModeTheme(
"oklch(0.45 0.03 60)",
).getColors();
expect(bdNeutralHover).toEqual("rgb(63.258% 63.258% 63.258%)");
expect(bdNeutralHover).toEqual("rgb(50.211% 50.211% 50.211%)");
});
});

describe("bdPositive", () => {
it("should return correct color", () => {
const { bdPositive } = new DarkModeTheme("oklch(0.45 0.03 60)").getColors();
expect(bdPositive).toEqual("rgb(0% 71.137% 15.743%)");
expect(bdPositive).toEqual("rgb(27.641% 37.516% 27.759%)");
});
});

Expand All @@ -791,14 +791,14 @@ describe("bdPositiveHover", () => {
const { bdPositiveHover } = new DarkModeTheme(
"oklch(0.45 0.03 60)",
).getColors();
expect(bdPositiveHover).toEqual("rgb(25.51% 86.719% 33.38%)");
expect(bdPositiveHover).toEqual("rgb(40.836% 51.186% 40.879%)");
});
});

describe("bdNegative", () => {
it("should return correct color", () => {
const { bdNegative } = new DarkModeTheme("oklch(0.45 0.03 60)").getColors();
expect(bdNegative).toEqual("rgb(83.108% 4.6651% 10.252%)");
expect(bdNegative).toEqual("rgb(52.977% 24.763% 22.178%)");
});
});

Expand All @@ -807,14 +807,14 @@ describe("bdNegativeHover", () => {
const { bdNegativeHover } = new DarkModeTheme(
"oklch(0.45 0.03 60)",
).getColors();
expect(bdNegativeHover).toEqual("rgb(97.525% 25.712% 23.78%)");
expect(bdNegativeHover).toEqual("rgb(65.578% 36.03% 32.933%)");
});
});

describe("bdWarning", () => {
it("should return correct color", () => {
const { bdWarning } = new DarkModeTheme("oklch(0.45 0.03 60)").getColors();
expect(bdWarning).toEqual("rgb(85.145% 64.66% 8.0286%)");
expect(bdWarning).toEqual("rgb(47.158% 34.346% 0%)");
});
});

Expand All @@ -823,7 +823,7 @@ describe("bdWarningHover", () => {
const { bdWarningHover } = new DarkModeTheme(
"oklch(0.45 0.03 60)",
).getColors();
expect(bdWarningHover).toEqual("rgb(100% 77.286% 0%)");
expect(bdWarningHover).toEqual("rgb(61.76% 46.241% 0%)");
});
});

Expand Down
Loading