feat: watch design from figma

This commit is contained in:
leon
2026-09-07 16:02:36 +02:00
parent b9930b7378
commit dcecd07d56
48 changed files with 2927 additions and 243 deletions
+17 -12
View File
@@ -115,24 +115,29 @@ struct WatchCoherenceView: View {
struct BreathOrb: View {
let regulation: WatchRegulationProtocol
let startedAt: Date
var showsLabel = true
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View {
TimelineView(.animation(minimumInterval: 1 / 20)) { context in
let elapsed = context.date.timeIntervalSince(startedAt)
TimelineView(.animation(minimumInterval: reduceMotion ? 1 : 1 / 20)) { context in
let elapsed = WatchDesignMode.frozen ? 0 : context.date.timeIntervalSince(startedAt)
let position = RegulationPhaseEngine.position(in: regulation, elapsedSeconds: elapsed)
let isExpanding = position?.phase.kind == .inhale
let fraction = position?.progress ?? 0
let scale = isExpanding ? 0.6 + fraction * 0.4 : 1 - fraction * 0.4
VStack(spacing: 6) {
let scale = position?.phase.kind == .inhale ? 0.65 + fraction * 0.35 : position?.phase.kind == .exhale ? 1 - fraction * 0.35 : 1
VStack(spacing: 20) {
Text(position?.phase.kind == .exhale ? "Expirez" : position?.phase.kind == .inhale ? "Inspirez" : position?.phase.label ?? "Inspirez")
.opacity(showsLabel ? 1 : 0)
.font(WatchTheme.font(20, weight: .semibold)).multilineTextAlignment(.center)
.minimumScaleFactor(0.75).lineLimit(1).fixedSize(horizontal: false, vertical: true)
ZStack {
Circle().fill(WatchTheme.accent.opacity(0.12)).frame(width: 108, height: 108)
Circle()
.fill(RadialGradient(colors: [WatchTheme.mint, WatchTheme.accent.opacity(0.25)], center: .center, startRadius: 2, endRadius: 52))
.frame(width: 88, height: 88)
.scaleEffect(scale)
Circle().fill(WatchTheme.accent.opacity(0.2)).blur(radius: 6)
Circle().fill(WatchTheme.accent.opacity(0.8))
.overlay(Circle().stroke(WatchTheme.accent.opacity(0.3)))
Circle().fill(.white.opacity(0.8)).frame(width: 8, height: 8)
}
Text(position?.phase.label ?? "Respirez").font(.headline)
}
.frame(width: 68, height: 68).scaleEffect(reduceMotion || WatchDesignMode.frozen ? 1 : scale)
.frame(height: 68).accessibilityHidden(true)
}.frame(maxWidth: .infinity).background { WatchGlow() }
}
}
}