From 32b1f8529016e8c8bfd550477afbf8ffda55c335 Mon Sep 17 00:00:00 2001 From: Wesley Keetch Date: Tue, 8 Sep 2026 17:51:57 -0400 Subject: [PATCH] fix: address the accessibility audit's first real findings This is the audit's first run against the app, and it found genuine defects rather than noise. The empty-reminders "Create a Task" button and the weather-unavailable "Try Again" button both used plain .buttonStyle(.glass). Plain glass renders translucent over whatever content sits behind it, so its contrast is unpredictable rather than guaranteed, which is exactly what the audit caught on both. Both are primary calls to action, so switched to .glassProminent, which is what Apple recommends for exactly this case and computes a readable foreground against its tint automatically. SettingsIconLabel's icon used a fixed 29pt frame that never grew with Dynamic Type, so at large text sizes the icon shrank relative to the surrounding row text. Replaced the fixed size with @ScaledMetric so it scales with the same setting the text does. This component backs most rows in Settings, so the fix applies broadly from one change. The remaining findings (several Settings section headers and the location permission button) trace back to the app's custom accent color, whose luminance is too close to its background for WCAG text contrast. That is a brand color decision, not a bug, and is deferred to a follow-up with real design options rather than changed here silently. --- SunHat/Views/Components/SettingsIconLabel.swift | 11 +++++++++-- SunHat/Views/Reminders/AllRemindersView.swift | 2 +- SunHat/Views/Weather/WeatherView.swift | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/SunHat/Views/Components/SettingsIconLabel.swift b/SunHat/Views/Components/SettingsIconLabel.swift index 0d66962..43ac2fa 100644 --- a/SunHat/Views/Components/SettingsIconLabel.swift +++ b/SunHat/Views/Components/SettingsIconLabel.swift @@ -14,14 +14,21 @@ struct SettingsIconLabel: View { let systemImage: String let color: Color + // A fixed-point icon frame stops scaling once the row's text grows with + // Dynamic Type, which the accessibility audit flags as "Dynamic Type + // font sizes are partially unsupported". @ScaledMetric ties the icon + // frame to the same text-size setting so it grows with the row. + @ScaledMetric(relativeTo: .body) private var iconDimension: CGFloat = 29 + @ScaledMetric(relativeTo: .body) private var symbolSize: CGFloat = 14 + var body: some View { Label { Text(title) } icon: { Image(systemName: systemImage) - .font(.system(size: 14, weight: .semibold)) + .font(.system(size: symbolSize, weight: .semibold)) .foregroundStyle(.white) - .frame(width: 29, height: 29) + .frame(width: iconDimension, height: iconDimension) .background(color.gradient, in: RoundedRectangle(cornerRadius: 6.5, style: .continuous)) } } diff --git a/SunHat/Views/Reminders/AllRemindersView.swift b/SunHat/Views/Reminders/AllRemindersView.swift index f80804b..16066fb 100644 --- a/SunHat/Views/Reminders/AllRemindersView.swift +++ b/SunHat/Views/Reminders/AllRemindersView.swift @@ -275,7 +275,7 @@ struct AllRemindersView: View { .padding(.horizontal, 20) .padding(.vertical, 10) } - .buttonStyle(.glass) + .buttonStyle(.glassProminent) .padding(.bottom, 20) } .sunHatSurface(tint: .accentColor, cornerRadius: 24, prominence: 0.70) diff --git a/SunHat/Views/Weather/WeatherView.swift b/SunHat/Views/Weather/WeatherView.swift index 8b2143a..bfcd472 100644 --- a/SunHat/Views/Weather/WeatherView.swift +++ b/SunHat/Views/Weather/WeatherView.swift @@ -126,7 +126,7 @@ struct WeatherView: View { } label: { Text("Try Again", comment: "Retry button in the weather tab's unavailable state") } - .buttonStyle(.glass) + .buttonStyle(.glassProminent) } .padding(.top, 60) }