Match page 1 storage layout to design — larger card, black button

Stats card: 26pt semibold values, 18pt corners, full-width gray card
with hairline dividers. Legend centered. HOLD TO CLEAN button is
full-width black (58pt tall, 18pt radius) replacing PrimaryButtonStyle.
storageStat padding/font updated to match screenshot proportions.

Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
Robin Kutesa
2026-05-21 13:51:38 +03:00
parent 0fd025de3e
commit 93682cb72c

View File

@@ -857,40 +857,51 @@ struct BackupView: View {
@ViewBuilder @ViewBuilder
private var page1BelowContent: some View { private var page1BelowContent: some View {
// 3-col stats // Storage stats card
HStack(spacing: 0) { HStack(spacing: 0) {
storageStat(String(format: "%.0f GB", deviceUsedGB), label: "USED", storageStat(String(format: "%.0f GB", deviceUsedGB), label: "USED",
color: Color(red: 1.0, green: 0.58, blue: 0.0)) color: Color(red: 1.0, green: 0.58, blue: 0.0))
thinDivider Rectangle()
.fill(AppTheme.separator.opacity(0.35))
.frame(width: 0.5)
.padding(.vertical, 14)
storageStat(String(format: "%.0f GB", deviceFreeGB), label: "FREE", storageStat(String(format: "%.0f GB", deviceFreeGB), label: "FREE",
color: AppTheme.inkSecondary) color: AppTheme.inkSecondary)
thinDivider Rectangle()
.fill(AppTheme.separator.opacity(0.35))
.frame(width: 0.5)
.padding(.vertical, 14)
storageStat(String(format: "%.1f GB", junkGB), label: "JUNK", storageStat(String(format: "%.1f GB", junkGB), label: "JUNK",
color: AppTheme.positive) color: AppTheme.positive)
} }
.frame(height: 48) .frame(maxWidth: .infinity)
.background(AppTheme.surfaceSunken.opacity(0.85)) .background(AppTheme.surfaceSunken)
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous)) .clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
.padding(.horizontal, AppTheme.hPad) .padding(.horizontal, AppTheme.hPad)
.padding(.bottom, 12) .padding(.bottom, 18)
// Legend // Legend
HStack(spacing: 16) { HStack(spacing: 20) {
storageLegend(color: Color(red: 1.0, green: 0.58, blue: 0.0), label: "used") storageLegend(color: Color(red: 1.0, green: 0.58, blue: 0.0), label: "used")
storageLegend(color: AppTheme.positive, label: "safe to delete") storageLegend(color: AppTheme.positive, label: "safe to delete")
storageLegend(color: AppTheme.destructive, label: "junk") storageLegend(color: AppTheme.destructive, label: "junk")
} }
.frame(maxWidth: .infinity)
.padding(.horizontal, AppTheme.hPad) .padding(.horizontal, AppTheme.hPad)
.padding(.bottom, 20) .padding(.bottom, 36)
Spacer(minLength: 16).frame(maxHeight: 40)
// HOLD TO CLEAN button
Button(action: { showCleanConfirm = true }) { Button(action: { showCleanConfirm = true }) {
Text("HOLD TO CLEAN") Text("HOLD TO CLEAN")
.font(.system(size: 10, weight: .medium, design: .monospaced)) .font(.system(size: 13, weight: .medium, design: .monospaced))
.tracking(2) .tracking(2)
.foregroundStyle(.white)
.frame(maxWidth: .infinity)
.frame(height: 58)
.background(Color(red: 0.08, green: 0.08, blue: 0.08))
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
} }
.buttonStyle(PrimaryButtonStyle()) .buttonStyle(.plain)
.padding(.horizontal, AppTheme.hPad) .padding(.horizontal, AppTheme.hPad)
.simultaneousGesture( .simultaneousGesture(
LongPressGesture(minimumDuration: 0.8).onEnded { _ in showCleanConfirm = true } LongPressGesture(minimumDuration: 0.8).onEnded { _ in showCleanConfirm = true }
@@ -900,7 +911,8 @@ struct BackupView: View {
.font(.system(size: 9, weight: .regular, design: .monospaced)) .font(.system(size: 9, weight: .regular, design: .monospaced))
.foregroundStyle(AppTheme.inkTertiary) .foregroundStyle(AppTheme.inkTertiary)
.tracking(1.5) .tracking(1.5)
.padding(.top, 6) .frame(maxWidth: .infinity)
.padding(.top, 10)
.padding(.bottom, 8) .padding(.bottom, 8)
} }
@@ -967,18 +979,19 @@ struct BackupView: View {
// MARK: Storage helpers // MARK: Storage helpers
private func storageStat(_ value: String, label: String, color: Color) -> some View { private func storageStat(_ value: String, label: String, color: Color) -> some View {
VStack(spacing: 2) { VStack(spacing: 5) {
Text(value) Text(value)
.font(.system(size: 15, weight: .semibold)) .font(.system(size: 26, weight: .semibold))
.foregroundStyle(color) .foregroundStyle(color)
.monospacedDigit() .monospacedDigit()
.kerning(-0.5)
Text(label) Text(label)
.font(.system(size: 9, weight: .regular, design: .monospaced)) .font(.system(size: 9, weight: .regular, design: .monospaced))
.foregroundStyle(AppTheme.inkQuaternary) .foregroundStyle(AppTheme.inkQuaternary)
.tracking(0.5) .tracking(1.5)
} }
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.padding(.vertical, 6) .padding(.vertical, 18)
} }
private func storageLegend(color: Color, label: String) -> some View { private func storageLegend(color: Color, label: String) -> some View {