Match ring tracks and stats to HTML prototype exactly
- Ring tracks: #c2c2c2 → #ebebeb (hairline, nearly invisible like the prototype) - Middle ring: #9e9e9e → #c8c8c8 (lighter, matches HTML) - Outer arc: lineWidth 1.5 → 1, glow softened to match prototype subtlety - Stats: remove card background, inline plain layout with #ebebeb dividers - Stats value: .semibold → .light (font-weight:300), letter-spacing tightened - Stats label: size 9 → 8pt SF Mono, tracking 1.0 (matches HTML 0.12em) Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -309,45 +309,50 @@ struct BackupView: View {
|
|||||||
label: "NAS",
|
label: "NAS",
|
||||||
color: AppTheme.interactive
|
color: AppTheme.interactive
|
||||||
)
|
)
|
||||||
thinDivider
|
statDivider
|
||||||
compactStat(
|
compactStat(
|
||||||
"\(statusService.snapshot.phoneTotal)",
|
"\(statusService.snapshot.phoneTotal)",
|
||||||
label: "IPHONE",
|
label: "iPhone",
|
||||||
color: AppTheme.inkSecondary
|
color: AppTheme.inkSecondary
|
||||||
)
|
)
|
||||||
thinDivider
|
statDivider
|
||||||
compactStat(
|
compactStat(
|
||||||
"\(notBackedUpDisplayCount)",
|
"\(notBackedUpDisplayCount)",
|
||||||
label: "PENDING",
|
label: "Pending",
|
||||||
color: Color(red: 1.0, green: 0.62, blue: 0.0)
|
color: Color(red: 1.0, green: 0.62, blue: 0.0)
|
||||||
)
|
)
|
||||||
thinDivider
|
statDivider
|
||||||
compactStat(
|
compactStat(
|
||||||
"\(alreadySafeDisplayCount)",
|
"\(alreadySafeDisplayCount)",
|
||||||
label: "SAFE",
|
label: "Safe",
|
||||||
color: AppTheme.positive
|
color: AppTheme.positive
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.frame(height: 48)
|
.padding(.vertical, 4)
|
||||||
.background(AppTheme.surfaceSunken.opacity(0.85))
|
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func compactStat(_ value: String, label: String, color: Color) -> some View {
|
private func compactStat(_ value: String, label: String, color: Color) -> some View {
|
||||||
VStack(spacing: 2) {
|
VStack(spacing: 3) {
|
||||||
Text(value)
|
Text(value)
|
||||||
.font(.system(size: 15, weight: .semibold))
|
.font(.system(size: 15, weight: .light))
|
||||||
.foregroundStyle(color)
|
.foregroundStyle(color)
|
||||||
.monospacedDigit()
|
.monospacedDigit()
|
||||||
|
.kerning(-0.5)
|
||||||
Text(label)
|
Text(label)
|
||||||
.font(.system(size: 9, weight: .regular))
|
.font(.system(size: 8, weight: .regular, design: .monospaced))
|
||||||
.foregroundStyle(AppTheme.inkQuaternary)
|
.foregroundStyle(AppTheme.inkQuaternary)
|
||||||
.tracking(0.2)
|
.tracking(1.0)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.padding(.vertical, 6)
|
.padding(.vertical, 6)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var statDivider: some View {
|
||||||
|
Rectangle()
|
||||||
|
.fill(Color(red: 0.922, green: 0.922, blue: 0.922))
|
||||||
|
.frame(width: 1, height: 22)
|
||||||
|
}
|
||||||
|
|
||||||
private var thinDivider: some View {
|
private var thinDivider: some View {
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.fill(AppTheme.separator.opacity(0.5))
|
.fill(AppTheme.separator.opacity(0.5))
|
||||||
@@ -997,7 +1002,7 @@ private struct KisaniRingView: View {
|
|||||||
let innerProgress: CGFloat
|
let innerProgress: CGFloat
|
||||||
let innerColor: Color
|
let innerColor: Color
|
||||||
|
|
||||||
private let track = Color(red: 0.76, green: 0.76, blue: 0.76)
|
private let track = Color(red: 0.922, green: 0.922, blue: 0.922) // #ebebeb
|
||||||
private let nasArc = Color(red: 0.42, green: 0.52, blue: 0.68)
|
private let nasArc = Color(red: 0.42, green: 0.52, blue: 0.68)
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -1006,14 +1011,14 @@ private struct KisaniRingView: View {
|
|||||||
Circle().stroke(track, lineWidth: 1).padding(10)
|
Circle().stroke(track, lineWidth: 1).padding(10)
|
||||||
// Outer NAS progress (blue-slate + glow)
|
// Outer NAS progress (blue-slate + glow)
|
||||||
Circle().trim(from: 0, to: outerProgress)
|
Circle().trim(from: 0, to: outerProgress)
|
||||||
.stroke(nasArc, style: StrokeStyle(lineWidth: 1.5, lineCap: .round))
|
.stroke(nasArc, style: StrokeStyle(lineWidth: 1, lineCap: .round))
|
||||||
.shadow(color: nasArc.opacity(0.65), radius: 7, x: 0, y: 0)
|
.shadow(color: nasArc.opacity(0.55), radius: 5, x: 0, y: 0)
|
||||||
.rotationEffect(.degrees(-90))
|
.rotationEffect(.degrees(-90))
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.animation(.spring(response: 0.7, dampingFraction: 0.8), value: outerProgress)
|
.animation(.spring(response: 0.7, dampingFraction: 0.8), value: outerProgress)
|
||||||
|
|
||||||
// Middle static ring
|
// Middle static ring — #c8c8c8
|
||||||
Circle().stroke(Color(red: 0.62, green: 0.62, blue: 0.62), lineWidth: 1).padding(24)
|
Circle().stroke(Color(red: 0.784, green: 0.784, blue: 0.784), lineWidth: 1).padding(24)
|
||||||
|
|
||||||
// Inner track
|
// Inner track
|
||||||
Circle().stroke(track, lineWidth: 1.5).padding(38)
|
Circle().stroke(track, lineWidth: 1.5).padding(38)
|
||||||
|
|||||||
Reference in New Issue
Block a user