diff --git a/FuelBoard/TrendsView.swift b/FuelBoard/TrendsView.swift index 474d223..9ed58d4 100644 --- a/FuelBoard/TrendsView.swift +++ b/FuelBoard/TrendsView.swift @@ -147,32 +147,38 @@ struct TrendsView: View { @ViewBuilder private var chartArea: some View { - if isLoading { - Spacer() - ProgressView("Fetching price history…") - Spacer() - } else if loadFailed { - Spacer() - VStack(spacing: 10) { - Image(systemName: "wifi.exclamationmark") - .font(.system(size: 32)) - .foregroundStyle(.secondary) - Text("Couldn't load price history") - .font(.headline) - Button("Retry") { Task { await load() } } - .buttonStyle(.bordered) - } - Spacer() - } else if !hasAnyData { - emptyState - } else if !hasEnoughData { - emptyState // single point — nothing to draw yet - } else { - VStack(spacing: 12) { - chart - legend + // Every state anchors to the TOP of the chart slot — the same spot the + // chart occupies when data exists. The empty/loading/error states must + // not float or centre in the sheet, or the layout jumps between states. + Group { + if isLoading { + VStack(spacing: 12) { + ProgressView("Fetching price history…") + } + .padding(.top, 24) + } else if loadFailed { + VStack(spacing: 10) { + Image(systemName: "wifi.exclamationmark") + .font(.system(size: 32)) + .foregroundStyle(.secondary) + Text("Couldn't load price history") + .font(.headline) + Button("Retry") { Task { await load() } } + .buttonStyle(.bordered) + } + .padding(.top, 24) + } else if !hasAnyData { + emptyState + } else if !hasEnoughData { + emptyState // single point — nothing to draw yet + } else { + VStack(spacing: 12) { + chart + legend + } } } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) } private var emptyState: some View {