Tighten the inbox, detail, and watch layouts so approval actions feel denser and more direct across compact surfaces.
This commit is contained in:
@@ -1,93 +1,20 @@
|
||||
import SwiftUI
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#elseif canImport(UIKit)
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
private extension Color {
|
||||
static func adaptive(
|
||||
light: (red: Double, green: Double, blue: Double, opacity: Double),
|
||||
dark: (red: Double, green: Double, blue: Double, opacity: Double)
|
||||
) -> Color {
|
||||
#if os(macOS)
|
||||
Color(
|
||||
nsColor: NSColor(name: nil) { appearance in
|
||||
let matchedAppearance = appearance.bestMatch(from: [.darkAqua, .vibrantDark, .aqua, .vibrantLight])
|
||||
let components = matchedAppearance == .darkAqua || matchedAppearance == .vibrantDark ? dark : light
|
||||
return NSColor(
|
||||
red: components.red,
|
||||
green: components.green,
|
||||
blue: components.blue,
|
||||
alpha: components.opacity
|
||||
)
|
||||
}
|
||||
)
|
||||
#elseif canImport(UIKit) && !os(watchOS)
|
||||
Color(
|
||||
uiColor: UIColor { traits in
|
||||
let components = traits.userInterfaceStyle == .dark ? dark : light
|
||||
return UIColor(
|
||||
red: components.red,
|
||||
green: components.green,
|
||||
blue: components.blue,
|
||||
alpha: components.opacity
|
||||
)
|
||||
}
|
||||
)
|
||||
#elseif os(watchOS)
|
||||
Color(
|
||||
red: dark.red,
|
||||
green: dark.green,
|
||||
blue: dark.blue,
|
||||
opacity: dark.opacity
|
||||
)
|
||||
#else
|
||||
Color(
|
||||
red: light.red,
|
||||
green: light.green,
|
||||
blue: light.blue,
|
||||
opacity: light.opacity
|
||||
)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// Legacy theme shim kept only so AppComponents.swift still compiles while
|
||||
/// the codebase has finished migrating to `IdP` / `Color.idp*` tokens.
|
||||
/// Do not reference these from new code — use `IdP.tint`, `Color.idpGroupedBackground`,
|
||||
/// etc. from `Sources/Core/Design/` instead.
|
||||
enum AppTheme {
|
||||
static let accent = Color(red: 0.12, green: 0.40, blue: 0.31)
|
||||
static let warmAccent = Color(red: 0.84, green: 0.71, blue: 0.48)
|
||||
static let border = Color.adaptive(
|
||||
light: (0.00, 0.00, 0.00, 0.08),
|
||||
dark: (1.00, 1.00, 1.00, 0.12)
|
||||
)
|
||||
static let shadow = Color.adaptive(
|
||||
light: (0.00, 0.00, 0.00, 0.05),
|
||||
dark: (0.00, 0.00, 0.00, 0.32)
|
||||
)
|
||||
static let cardFill = Color.adaptive(
|
||||
light: (1.00, 1.00, 1.00, 0.96),
|
||||
dark: (0.11, 0.12, 0.14, 0.96)
|
||||
)
|
||||
static let mutedFill = Color.adaptive(
|
||||
light: (0.972, 0.976, 0.970, 1.00),
|
||||
dark: (0.16, 0.17, 0.19, 1.00)
|
||||
)
|
||||
static let backgroundTop = Color.adaptive(
|
||||
light: (0.975, 0.978, 0.972, 1.00),
|
||||
dark: (0.08, 0.09, 0.10, 1.00)
|
||||
)
|
||||
static let backgroundBottom = Color.adaptive(
|
||||
light: (1.00, 1.00, 1.00, 1.00),
|
||||
dark: (0.05, 0.06, 0.07, 1.00)
|
||||
)
|
||||
static let backgroundGlow = Color.adaptive(
|
||||
light: (0.00, 0.00, 0.00, 0.02),
|
||||
dark: (1.00, 1.00, 1.00, 0.06)
|
||||
)
|
||||
static let chromeFill = Color.adaptive(
|
||||
light: (1.00, 1.00, 1.00, 0.98),
|
||||
dark: (0.10, 0.11, 0.13, 0.98)
|
||||
)
|
||||
static let accent: Color = IdP.tint
|
||||
static let warmAccent: Color = .orange
|
||||
static let border: Color = Color.idpSeparator
|
||||
static let shadow: Color = Color.black.opacity(0.08)
|
||||
static let cardFill: Color = Color.idpSecondaryGroupedBackground
|
||||
static let mutedFill: Color = Color.idpSecondaryGroupedBackground
|
||||
static let backgroundTop: Color = Color.idpGroupedBackground
|
||||
static let backgroundBottom: Color = Color.idpGroupedBackground
|
||||
static let backgroundGlow: Color = .clear
|
||||
static let chromeFill: Color = Color.idpSecondaryGroupedBackground
|
||||
}
|
||||
|
||||
enum AppLayout {
|
||||
@@ -97,8 +24,8 @@ enum AppLayout {
|
||||
static let regularVerticalPadding: CGFloat = 28
|
||||
static let compactContentWidth: CGFloat = 720
|
||||
static let regularContentWidth: CGFloat = 920
|
||||
static let cardRadius: CGFloat = 24
|
||||
static let largeCardRadius: CGFloat = 30
|
||||
static let cardRadius: CGFloat = IdP.cardRadius
|
||||
static let largeCardRadius: CGFloat = 28
|
||||
static let compactSectionPadding: CGFloat = 18
|
||||
static let regularSectionPadding: CGFloat = 24
|
||||
static let compactSectionSpacing: CGFloat = 18
|
||||
@@ -135,30 +62,14 @@ extension View {
|
||||
)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: radius, style: .continuous)
|
||||
.stroke(AppTheme.border, lineWidth: 1)
|
||||
.stroke(AppTheme.border, lineWidth: 0.5)
|
||||
)
|
||||
.shadow(color: AppTheme.shadow, radius: 12, y: 3)
|
||||
}
|
||||
}
|
||||
|
||||
struct AppBackground: View {
|
||||
var body: some View {
|
||||
LinearGradient(
|
||||
colors: [
|
||||
AppTheme.backgroundTop,
|
||||
AppTheme.backgroundBottom
|
||||
],
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
)
|
||||
.overlay(alignment: .top) {
|
||||
Rectangle()
|
||||
.fill(AppTheme.backgroundGlow)
|
||||
.frame(height: 160)
|
||||
.blur(radius: 60)
|
||||
.offset(y: -90)
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
Color.idpGroupedBackground.ignoresSafeArea()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,8 +137,8 @@ struct AppBadge: View {
|
||||
.font(.caption.weight(.semibold))
|
||||
.foregroundStyle(tone)
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 8)
|
||||
.background(tone.opacity(0.10), in: Capsule())
|
||||
.padding(.vertical, 6)
|
||||
.background(tone.opacity(0.14), in: Capsule())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user