From 9e58a36915bb1fe8cf88423c9519c0c12dbbf2e2 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Mon, 20 Jul 2026 20:25:01 -0500 Subject: fix(a11y): rebalance the light palette so hues survive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported as "colors seem muted and hard to see on light mode", and correct. The light palette optimised contrast and produced mud: #7A5600 reads olive rather than amber, #146C2E bottle-dark rather than green. Contrast passed while the UI got harder to read, because hue identity is what distinguishes warning from critical at a glance. Two causes, both fixed. Every foreground was required to clear 4.5:1 against its own 16% badge tint — the harshest surface it ever sits on — which pushed each colour about 20% darker than the common case needed. Most of what is actually on screen is plain text on a card, with far more headroom. The fill is now decoupled from the foreground: AppStatusTone carries a foreground and a surface authored independently, with matching …Surface colorsets, so a foreground no longer has to survive a wash of itself. Every status foreground is now fully saturated. And warning was yellow. Yellow cannot stay yellow at a lightness low enough to pass 4.5:1 on white — it becomes olive. That is colorimetric, not a tuning problem. Warning is now orange: #AD5100 light, #FF9F0A dark. New light values: positive #008035, warning #AD5100, critical #CC0700. Worst-case ratios 4.54–6.76 across page, card, and surface in both schemes. Audit findings are unchanged — light 21, dark 18 — so the vividness costs nothing. Also picks up a literal .blue missed in phase 1: DomainDiffItem's low-severity change colour, which the phase 1 sweep did not cover because its pattern listed only cyan/yellow/green/red/orange/pink. --- .../StatusCritical.colorset/Contents.json | 12 ++-- .../StatusCriticalSurface.colorset/Contents.json | 78 ++++++++++++++++++++++ .../StatusInfoSurface.colorset/Contents.json | 78 ++++++++++++++++++++++ .../StatusNeutralSurface.colorset/Contents.json | 78 ++++++++++++++++++++++ .../StatusPositive.colorset/Contents.json | 12 ++-- .../StatusPositiveSurface.colorset/Contents.json | 78 ++++++++++++++++++++++ .../StatusWarning.colorset/Contents.json | 14 ++-- .../StatusWarningSurface.colorset/Contents.json | 78 ++++++++++++++++++++++ 8 files changed, 409 insertions(+), 19 deletions(-) create mode 100644 Shared/Colors.xcassets/StatusCriticalSurface.colorset/Contents.json create mode 100644 Shared/Colors.xcassets/StatusInfoSurface.colorset/Contents.json create mode 100644 Shared/Colors.xcassets/StatusNeutralSurface.colorset/Contents.json create mode 100644 Shared/Colors.xcassets/StatusPositiveSurface.colorset/Contents.json create mode 100644 Shared/Colors.xcassets/StatusWarningSurface.colorset/Contents.json (limited to 'Shared/Colors.xcassets') diff --git a/Shared/Colors.xcassets/StatusCritical.colorset/Contents.json b/Shared/Colors.xcassets/StatusCritical.colorset/Contents.json index 8f97cd9..2963513 100644 --- a/Shared/Colors.xcassets/StatusCritical.colorset/Contents.json +++ b/Shared/Colors.xcassets/StatusCritical.colorset/Contents.json @@ -5,9 +5,9 @@ "color": { "color-space": "srgb", "components": { - "red": "0xB3", - "green": "0x26", - "blue": "0x1E", + "red": "0xCC", + "green": "0x07", + "blue": "0x00", "alpha": "1.000" } } @@ -41,9 +41,9 @@ "color": { "color-space": "srgb", "components": { - "red": "0x8C", - "green": "0x1D", - "blue": "0x16", + "red": "0xA3", + "green": "0x05", + "blue": "0x00", "alpha": "1.000" } } diff --git a/Shared/Colors.xcassets/StatusCriticalSurface.colorset/Contents.json b/Shared/Colors.xcassets/StatusCriticalSurface.colorset/Contents.json new file mode 100644 index 0000000..31b3941 --- /dev/null +++ b/Shared/Colors.xcassets/StatusCriticalSurface.colorset/Contents.json @@ -0,0 +1,78 @@ +{ + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "srgb", + "components": { + "red": "0xFB", + "green": "0xE0", + "blue": "0xDF", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x2E", + "green": "0x13", + "blue": "0x10", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0xF7", + "green": "0xCF", + "blue": "0xCD", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + }, + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x3D", + "green": "0x19", + "blue": "0x15", + "alpha": "1.000" + } + } + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/Shared/Colors.xcassets/StatusInfoSurface.colorset/Contents.json b/Shared/Colors.xcassets/StatusInfoSurface.colorset/Contents.json new file mode 100644 index 0000000..e0a2c53 --- /dev/null +++ b/Shared/Colors.xcassets/StatusInfoSurface.colorset/Contents.json @@ -0,0 +1,78 @@ +{ + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "srgb", + "components": { + "red": "0xDF", + "green": "0xE3", + "blue": "0xFB", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x10", + "green": "0x1C", + "blue": "0x33", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0xCB", + "green": "0xD2", + "blue": "0xF7", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + }, + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x15", + "green": "0x27", + "blue": "0x44", + "alpha": "1.000" + } + } + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/Shared/Colors.xcassets/StatusNeutralSurface.colorset/Contents.json b/Shared/Colors.xcassets/StatusNeutralSurface.colorset/Contents.json new file mode 100644 index 0000000..8b8c6bd --- /dev/null +++ b/Shared/Colors.xcassets/StatusNeutralSurface.colorset/Contents.json @@ -0,0 +1,78 @@ +{ + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "srgb", + "components": { + "red": "0xEB", + "green": "0xED", + "blue": "0xEF", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x1A", + "green": "0x1A", + "blue": "0x1C", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0xDF", + "green": "0xE1", + "blue": "0xE4", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + }, + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x23", + "green": "0x23", + "blue": "0x26", + "alpha": "1.000" + } + } + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/Shared/Colors.xcassets/StatusPositive.colorset/Contents.json b/Shared/Colors.xcassets/StatusPositive.colorset/Contents.json index 22ce5e5..30280d9 100644 --- a/Shared/Colors.xcassets/StatusPositive.colorset/Contents.json +++ b/Shared/Colors.xcassets/StatusPositive.colorset/Contents.json @@ -5,9 +5,9 @@ "color": { "color-space": "srgb", "components": { - "red": "0x14", - "green": "0x6C", - "blue": "0x2E", + "red": "0x00", + "green": "0x80", + "blue": "0x35", "alpha": "1.000" } } @@ -41,9 +41,9 @@ "color": { "color-space": "srgb", "components": { - "red": "0x0B", - "green": "0x50", - "blue": "0x23", + "red": "0x00", + "green": "0x66", + "blue": "0x1F", "alpha": "1.000" } } diff --git a/Shared/Colors.xcassets/StatusPositiveSurface.colorset/Contents.json b/Shared/Colors.xcassets/StatusPositiveSurface.colorset/Contents.json new file mode 100644 index 0000000..dc80f8f --- /dev/null +++ b/Shared/Colors.xcassets/StatusPositiveSurface.colorset/Contents.json @@ -0,0 +1,78 @@ +{ + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "srgb", + "components": { + "red": "0xE3", + "green": "0xF7", + "blue": "0xEC", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x0E", + "green": "0x2A", + "blue": "0x18", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0xD3", + "green": "0xF0", + "blue": "0xE0", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + }, + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x12", + "green": "0x3A", + "blue": "0x20", + "alpha": "1.000" + } + } + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/Shared/Colors.xcassets/StatusWarning.colorset/Contents.json b/Shared/Colors.xcassets/StatusWarning.colorset/Contents.json index cc79e86..003f80c 100644 --- a/Shared/Colors.xcassets/StatusWarning.colorset/Contents.json +++ b/Shared/Colors.xcassets/StatusWarning.colorset/Contents.json @@ -5,8 +5,8 @@ "color": { "color-space": "srgb", "components": { - "red": "0x7A", - "green": "0x56", + "red": "0xAD", + "green": "0x51", "blue": "0x00", "alpha": "1.000" } @@ -24,7 +24,7 @@ "color-space": "srgb", "components": { "red": "0xFF", - "green": "0xD6", + "green": "0x9F", "blue": "0x0A", "alpha": "1.000" } @@ -41,8 +41,8 @@ "color": { "color-space": "srgb", "components": { - "red": "0x5C", - "green": "0x41", + "red": "0x8A", + "green": "0x3F", "blue": "0x00", "alpha": "1.000" } @@ -64,8 +64,8 @@ "color-space": "srgb", "components": { "red": "0xFF", - "green": "0xE5", - "blue": "0x66", + "green": "0xBF", + "blue": "0x5C", "alpha": "1.000" } } diff --git a/Shared/Colors.xcassets/StatusWarningSurface.colorset/Contents.json b/Shared/Colors.xcassets/StatusWarningSurface.colorset/Contents.json new file mode 100644 index 0000000..8030a19 --- /dev/null +++ b/Shared/Colors.xcassets/StatusWarningSurface.colorset/Contents.json @@ -0,0 +1,78 @@ +{ + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "srgb", + "components": { + "red": "0xFB", + "green": "0xEC", + "blue": "0xDF", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x2E", + "green": "0x1F", + "blue": "0x08", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0xF7", + "green": "0xE0", + "blue": "0xC9", + "alpha": "1.000" + } + } + }, + { + "idiom": "universal", + "appearances": [ + { + "appearance": "luminosity", + "value": "dark" + }, + { + "appearance": "contrast", + "value": "high" + } + ], + "color": { + "color-space": "srgb", + "components": { + "red": "0x3D", + "green": "0x2A", + "blue": "0x0B", + "alpha": "1.000" + } + } + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} -- cgit v1.2.3