fix(ui): improve financial text contrast
TD-010: use readable semantic text colors on financial surfaces while preserving signs and state meanings.
This commit is contained in:
@@ -63,11 +63,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.positive {
|
.positive {
|
||||||
color: var(--mantine-color-green-6);
|
color: var(--wl-color-positive);
|
||||||
}
|
}
|
||||||
|
|
||||||
.negative {
|
.negative {
|
||||||
color: var(--mantine-color-red-6);
|
color: var(--wl-color-negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
.expandedCard {
|
.expandedCard {
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import tokens from "./tokens.json";
|
||||||
|
|
||||||
|
function luminance(color: string) {
|
||||||
|
const channels = [1, 3, 5]
|
||||||
|
.map((index) => Number.parseInt(color.slice(index, index + 2), 16) / 255)
|
||||||
|
.map((value) =>
|
||||||
|
value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4,
|
||||||
|
);
|
||||||
|
return channels[0] * 0.2126 + channels[1] * 0.7152 + channels[2] * 0.0722;
|
||||||
|
}
|
||||||
|
describe("financial text contrast", () => {
|
||||||
|
it.each(["positive", "negative"] as const)(
|
||||||
|
"keeps %s readable on journal, position and tinted card surfaces",
|
||||||
|
(tone) => {
|
||||||
|
const role = tokens.color.roles[tone];
|
||||||
|
const palettes = tokens.color.palettes;
|
||||||
|
const foreground =
|
||||||
|
palettes[role.color as keyof typeof palettes][role.shade];
|
||||||
|
const surfaces = [
|
||||||
|
palettes.gray[0],
|
||||||
|
...Object.entries(palettes)
|
||||||
|
.filter(([name]) => name !== "dark")
|
||||||
|
.map(
|
||||||
|
([, palette]) =>
|
||||||
|
`#${[1, 3, 5]
|
||||||
|
.map((index) =>
|
||||||
|
Math.round(
|
||||||
|
Number.parseInt(palette[0].slice(index, index + 2), 16) *
|
||||||
|
0.45 +
|
||||||
|
255 * 0.55,
|
||||||
|
)
|
||||||
|
.toString(16)
|
||||||
|
.padStart(2, "0"),
|
||||||
|
)
|
||||||
|
.join("")}`,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (const background of surfaces)
|
||||||
|
expect(
|
||||||
|
(luminance(background) + 0.05) / (luminance(foreground) + 0.05),
|
||||||
|
).toBeGreaterThanOrEqual(4.5);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"#40c057",
|
"#40c057",
|
||||||
"#37b24d",
|
"#37b24d",
|
||||||
"#2f9e44",
|
"#2f9e44",
|
||||||
"#2b8a3e"
|
"#237032"
|
||||||
],
|
],
|
||||||
"red": [
|
"red": [
|
||||||
"#fff5f5",
|
"#fff5f5",
|
||||||
@@ -151,12 +151,12 @@
|
|||||||
},
|
},
|
||||||
"positive": {
|
"positive": {
|
||||||
"color": "green",
|
"color": "green",
|
||||||
"shade": 6,
|
"shade": 9,
|
||||||
"description": "Положительный результат; дополните знаком и текстом"
|
"description": "Положительный результат; дополните знаком и текстом"
|
||||||
},
|
},
|
||||||
"negative": {
|
"negative": {
|
||||||
"color": "red",
|
"color": "red",
|
||||||
"shade": 6,
|
"shade": 9,
|
||||||
"description": "Ошибка / отрицательный результат; дополните текстом"
|
"description": "Ошибка / отрицательный результат; дополните текстом"
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
|
|||||||
@@ -19,15 +19,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.positive {
|
.positive {
|
||||||
color: var(--mantine-color-green-6);
|
color: var(--wl-color-positive);
|
||||||
}
|
}
|
||||||
|
|
||||||
.negative {
|
.negative {
|
||||||
color: var(--mantine-color-red-6);
|
color: var(--wl-color-negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
.neutral {
|
.neutral {
|
||||||
color: var(--mantine-color-dimmed);
|
color: var(--mantine-color-gray-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 36em) {
|
@media (max-width: 36em) {
|
||||||
|
|||||||
Reference in New Issue
Block a user