summaryrefslogtreecommitdiff
path: root/DomainDig/DashboardView.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-20 20:25:01 -0500
committerChristian Cleberg <[email protected]>2026-07-20 21:03:10 -0500
commit9e58a36915bb1fe8cf88423c9519c0c12dbbf2e2 (patch)
treea9397c168adcdb63deda80440511063ef57732f4 /DomainDig/DashboardView.swift
parent2c608ed9cb11f3e835f577994b5627b9b7910f4f (diff)
downloaddomain-dig-9e58a36915bb1fe8cf88423c9519c0c12dbbf2e2.tar.gz
domain-dig-9e58a36915bb1fe8cf88423c9519c0c12dbbf2e2.tar.bz2
domain-dig-9e58a36915bb1fe8cf88423c9519c0c12dbbf2e2.zip
fix(a11y): rebalance the light palette so hues survive
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.
Diffstat (limited to 'DomainDig/DashboardView.swift')
-rw-r--r--DomainDig/DashboardView.swift24
1 files changed, 12 insertions, 12 deletions
diff --git a/DomainDig/DashboardView.swift b/DomainDig/DashboardView.swift
index 8d41ccb..16c4478 100644
--- a/DomainDig/DashboardView.swift
+++ b/DomainDig/DashboardView.swift
@@ -237,20 +237,20 @@ struct DashboardView: View {
let criticalCount = states.filter { $0.health == .critical }.count
let warningCount = states.filter { $0.health == .warning }.count
let title: String
- let color: Color
+ let tone: AppStatusTone
let systemImage: String
if criticalCount > 0 {
title = "\(criticalCount) critical"
- color = Color(.statusCritical)
+ tone = .critical
systemImage = "exclamationmark.octagon.fill"
} else if warningCount > 0 {
title = "\(warningCount) warning"
- color = Color(.statusWarning)
+ tone = .warning
systemImage = "exclamationmark.triangle.fill"
} else {
title = "Healthy"
- color = Color(.statusPositive)
+ tone = .positive
systemImage = "checkmark.circle.fill"
}
@@ -258,8 +258,8 @@ struct DashboardView: View {
model: .init(
title: title,
systemImage: systemImage,
- foregroundColor: color,
- backgroundColor: color.opacity(0.16)
+ foregroundColor: tone.foreground,
+ backgroundColor: tone.surface
)
)
}
@@ -331,11 +331,11 @@ private struct PortfolioAttentionRow: View {
private var badgeModel: AppStatusBadgeModel {
switch item.health {
case .healthy:
- return .init(title: "Healthy", systemImage: "checkmark.circle.fill", foregroundColor: Color(.statusPositive), backgroundColor: Color(.statusPositive).opacity(0.16))
+ return .init(title: "Healthy", systemImage: "checkmark.circle.fill", foregroundColor: Color(.statusPositive), backgroundColor: Color(.statusPositiveSurface))
case .warning:
- return .init(title: "Warning", systemImage: "exclamationmark.triangle.fill", foregroundColor: Color(.statusWarning), backgroundColor: Color(.statusWarning).opacity(0.16))
+ return .init(title: "Warning", systemImage: "exclamationmark.triangle.fill", foregroundColor: Color(.statusWarning), backgroundColor: Color(.statusWarningSurface))
case .critical:
- return .init(title: "Critical", systemImage: "exclamationmark.octagon.fill", foregroundColor: Color(.statusCritical), backgroundColor: Color(.statusCritical).opacity(0.16))
+ return .init(title: "Critical", systemImage: "exclamationmark.octagon.fill", foregroundColor: Color(.statusCritical), backgroundColor: Color(.statusCriticalSurface))
}
}
}
@@ -370,11 +370,11 @@ private struct PortfolioExpiryRow: View {
private var badgeModel: AppStatusBadgeModel {
switch state.certificateExpiryState {
case .none:
- return .init(title: "Healthy", systemImage: "lock.fill", foregroundColor: Color(.statusPositive), backgroundColor: Color(.statusPositive).opacity(0.16))
+ return .init(title: "Healthy", systemImage: "lock.fill", foregroundColor: Color(.statusPositive), backgroundColor: Color(.statusPositiveSurface))
case .warning:
- return .init(title: "Warning", systemImage: "exclamationmark.triangle.fill", foregroundColor: Color(.statusWarning), backgroundColor: Color(.statusWarning).opacity(0.16))
+ return .init(title: "Warning", systemImage: "exclamationmark.triangle.fill", foregroundColor: Color(.statusWarning), backgroundColor: Color(.statusWarningSurface))
case .critical:
- return .init(title: "Critical", systemImage: "xmark.octagon.fill", foregroundColor: Color(.statusCritical), backgroundColor: Color(.statusCritical).opacity(0.16))
+ return .init(title: "Critical", systemImage: "xmark.octagon.fill", foregroundColor: Color(.statusCritical), backgroundColor: Color(.statusCriticalSurface))
}
}
}