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
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,20 @@ export class DarkModeTheme implements ColorModeTheme {

bd: this.bd.to("sRGB").toString(),
bdAccent: this.bdAccent.to("sRGB").toString(),
bdAccentSubtle: this.bdAccentSubtle.to("sRGB").toString(),
bdFocus: this.bdFocus.to("sRGB").toString(),
bdNeutral: this.bdNeutral.to("sRGB").toString(),
bdNeutralHover: this.bdNeutralHover.to("sRGB").toString(),
bdNeutralSubtle: this.bdNeutralSubtle.to("sRGB").toString(),
bdPositive: this.bdPositive.to("sRGB").toString(),
bdPositiveHover: this.bdPositiveHover.to("sRGB").toString(),
bdPositiveSubtle: this.bdPositiveSubtle.to("sRGB").toString(),
bdNegative: this.bdNegative.to("sRGB").toString(),
bdNegativeHover: this.bdNegativeHover.to("sRGB").toString(),
bdNegativeSubtle: this.bdNegativeSubtle.to("sRGB").toString(),
bdWarning: this.bdWarning.to("sRGB").toString(),
bdWarningHover: this.bdWarningHover.to("sRGB").toString(),
bdWarningSubtle: this.bdWarningSubtle.to("sRGB").toString(),

bdOnAccent: this.bdOnAccent.to("sRGB").toString(),
bdOnNeutral: this.bdOnNeutral.to("sRGB").toString(),
Expand Down Expand Up @@ -980,6 +985,16 @@ export class DarkModeTheme implements ColorModeTheme {
return color;
}

private get bdAccentSubtle() {
// Slightly subtler version of accent border, used in outlined buttons
const color = this.bdAccent.clone();

color.oklch.l -= 0.02;
color.oklch.c -= 0.01;

return color;
}

private get bdFocus() {
// Keyboard focus outline
const color = this.bdAccent.clone();
Expand Down Expand Up @@ -1031,6 +1046,15 @@ export class DarkModeTheme implements ColorModeTheme {
return color;
}

private get bdNeutralSubtle() {
// Slightly subtler version of neutral border, used in outlined buttons
const color = this.bdNeutral.clone();

color.oklch.l -= 0.07;

return color;
}

private get bdPositive() {
const color = this.bgPositive.clone();

Expand All @@ -1054,6 +1078,16 @@ export class DarkModeTheme implements ColorModeTheme {
return color;
}

private get bdPositiveSubtle() {
// Slightly subtler version of positive border, used in outlined buttons
const color = this.bdPositive.clone();

color.oklch.l -= 0.05;
color.oklch.c -= 0.01;

return color;
}

private get bdNegative() {
// Negative (red) border. Produced out of bgNegative. Additional compensations are applied if seed is within red range.
const color = this.bgNegative.clone();
Expand Down Expand Up @@ -1099,6 +1133,16 @@ export class DarkModeTheme implements ColorModeTheme {
return color;
}

private get bdNegativeSubtle() {
// Slightly subtler version of negative border, used in outlined buttons
const color = this.bdNegative.clone();

color.oklch.l -= 0.03;
color.oklch.c -= 0.01;

return color;
}

private get bdWarning() {
const color = this.bgWarning.clone();

Expand Down Expand Up @@ -1149,6 +1193,16 @@ export class DarkModeTheme implements ColorModeTheme {
return color;
}

private get bdWarningSubtle() {
// Slightly subtler version of warning border, used in outlined buttons
const color = this.bdWarning.clone();

color.oklch.l -= 0.03;
color.oklch.c -= 0.02;

return color;
}

private get bdOnAccent() {
// Separator on bgAccent, low contrast to not pull attention from actual separated content elements
const color = this.bgAccent.clone();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,20 @@ export class LightModeTheme implements ColorModeTheme {

bd: this.bd.to("sRGB").toString(),
bdAccent: this.bdAccent.to("sRGB").toString(),
bdAccentSubtle: this.bdAccentSubtle.to("sRGB").toString(),
bdFocus: this.bdFocus.to("sRGB").toString(),
bdNeutral: this.bdNeutral.to("sRGB").toString(),
bdNeutralHover: this.bdNeutralHover.to("sRGB").toString(),
bdNeutralSubtle: this.bdNeutralSubtle.to("sRGB").toString(),
bdPositive: this.bdPositive.to("sRGB").toString(),
bdPositiveHover: this.bdPositiveHover.to("sRGB").toString(),
bdPositiveSubtle: this.bdPositiveSubtle.to("sRGB").toString(),
bdNegative: this.bdNegative.to("sRGB").toString(),
bdNegativeHover: this.bdNegativeHover.to("sRGB").toString(),
bdNegativeSubtle: this.bdNegativeSubtle.to("sRGB").toString(),
bdWarning: this.bdWarning.to("sRGB").toString(),
bdWarningHover: this.bdWarningHover.to("sRGB").toString(),
bdWarningSubtle: this.bdWarningSubtle.to("sRGB").toString(),

bdOnAccent: this.bdOnAccent.to("sRGB").toString(),
bdOnNeutral: this.bdOnNeutral.to("sRGB").toString(),
Expand Down Expand Up @@ -349,7 +354,7 @@ export class LightModeTheme implements ColorModeTheme {
// Simplified and adjusted version of bgAccentHover algorithm (bgNeutral has very low or no chroma)

if (this.bgNeutral.oklch.l < 0.06) {
color.oklch.l += 0.3;
color.oklch.l += 0.5;
}

if (this.bgNeutral.oklch.l > 0.06 && this.bgNeutral.oklch.l < 0.14) {
Expand Down Expand Up @@ -744,7 +749,7 @@ export class LightModeTheme implements ColorModeTheme {

// For dark content on light background APCA contrast is positive. 60 is “The minimum level recommended for content text that is not body, column, or block text. In other words, text you want people to read.” 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) <= 60) {
color.oklch.l = 0.45;
color.oklch.l = 0.35;

if (this.seedIsAchromatic) {
color.oklch.c = 0;
Expand Down Expand Up @@ -962,24 +967,34 @@ export class LightModeTheme implements ColorModeTheme {

private get bdAccent() {
// 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();
const color = this.fgAccent.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) {
if (this.bg.contrastAPCA(color) <= 25) {
// If seed is achromatic make sure we don't produce parasitic coloring. Our standard achromatic cut-off is set too high for the very light seeds, so using chroma value checks instead.
if (color.oklch.c <= 0.04) {
color.oklch.l = 0.55;
color.oklch.c = 0;
}

if (!this.seedIsAchromatic) {
if (color.oklch.c > 0.04) {
color.oklch.l = 0.55;
color.oklch.c = 0.15;
color.oklch.c = 0.08;
}
}

return color;
}

private get bdAccentSubtle() {
// Slightly subtler version of accent border, used in outlined buttons
const color = this.bdAccent.clone();

color.oklch.l += 0.35;

return color;
}

private get bdFocus() {
// Keyboard focus outline
const color = this.bgAccent.clone();
Expand Down Expand Up @@ -1034,6 +1049,15 @@ export class LightModeTheme implements ColorModeTheme {
return color;
}

private get bdNeutralSubtle() {
// Slightly subtler version of neutral border, used in outlined buttons
const color = this.bdNeutral.clone();

color.oklch.l += 0.35;

return color;
}

private get bdPositive() {
// Positive (green) border. Additional compensations are applied if seed is withing green range.
const color = this.bgPositive.clone();
Expand Down Expand Up @@ -1070,6 +1094,16 @@ export class LightModeTheme implements ColorModeTheme {
return color;
}

private get bdPositiveSubtle() {
// Slightly subtler version of negative border, used in outlined buttons
const color = this.bdPositive.clone();

color.oklch.l += 0.07;
color.oklch.c -= 0.09;

return color;
}

private get bdNegative() {
// Negative (red) border. Produced out of bgNegative. Additional compensations are applied if seed is within red range.
const color = this.bgNegative.clone();
Expand Down Expand Up @@ -1106,6 +1140,16 @@ export class LightModeTheme implements ColorModeTheme {
return color;
}

private get bdNegativeSubtle() {
// Slightly subtler version of negative border, used in outlined buttons
const color = this.bdNegative.clone();

color.oklch.l += 0.1;
color.oklch.h -= 0.05;

return color;
}

private get bdWarning() {
// Warning (yellow) border. Produced out of bgNegative. Additional compensations are applied if seed is within yellow range.
const color = this.bgWarning.clone();
Expand Down Expand Up @@ -1142,6 +1186,15 @@ export class LightModeTheme implements ColorModeTheme {
return color;
}

private get bdWarningSubtle() {
// Slightly subtler version of warning border, used in outlined buttons
const color = this.bdWarning.clone();

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

return color;
}
private get bdOnAccent() {
// Separator on bgAccent, low contrast to not pull attention from actual separated content elements
const color = this.bgAccent.clone();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,20 @@ export interface ColorModeTheme {
fgOnWarning: string;
// bd
bdAccent: string;
bdAccentSubtle: string;
bdFocus: string;
bdNeutral: string;
bdNeutralHover: string;
bdNeutralSubtle: string;
bdPositive: string;
bdPositiveHover: string;
bdPositiveSubtle: string;
bdNegative: string;
bdNegativeHover: string;
bdNegativeSubtle: string;
bdWarning: string;
bdWarningHover: string;
bdWarningSubtle: string;
// bd on bg*
bdOnAccent: string;
bdOnNeutral: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ describe("bgNeutralHover color", () => {
"oklch(0.05 0.03 170)",
).getColors();

expect(bgNeutralHover).toEqual("rgb(22.901% 22.901% 22.901%)");
expect(bgNeutralHover).toEqual("rgb(44.47% 44.47% 44.47%)");
});

it("should return correct color when lightness is between 0.06 and 0.14", () => {
Expand All @@ -298,23 +298,23 @@ describe("bgNeutralHover color", () => {
"oklch(0.35 0.03 170)",
).getColors();

expect(bgNeutralHover).toEqual("rgb(17.924% 17.924% 17.924%)");
expect(bgNeutralHover).toEqual("rgb(38.857% 38.857% 38.857%)");
});

it("should return correct color when lightness is between 0.7 and 0.955", () => {
const { bgNeutralHover } = new LightModeTheme(
"oklch(0.75 0.03 170)",
).getColors();

expect(bgNeutralHover).toEqual("rgb(4.3484% 4.3484% 4.3484%)");
expect(bgNeutralHover).toEqual("rgb(22.901% 22.901% 22.901%)");
});

it("should return correct color when lightness > or equal to 0.955", () => {
const { bgNeutralHover } = new LightModeTheme(
"oklch(0.96 0.03 170)",
).getColors();

expect(bgNeutralHover).toEqual("rgb(4.3484% 4.3484% 4.3484%)");
expect(bgNeutralHover).toEqual("rgb(22.901% 22.901% 22.901%)");
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
background-color: transparent;
color: var(--color-fg-$(color));
/** We use !important here to override the disabled outline styles in the main app. */
outline: var(--border-width-1) solid var(--color-bd-$(color)) !important;
outline: var(--border-width-1) solid var(--color-bd-$(color)-subtle) !important;
outline-offset: calc(-1 * var(--border-width-1)) !important;

&[data-hovered]:not([data-loading]) {
Expand Down
Loading