127 lines
4.9 KiB
Swift
127 lines
4.9 KiB
Swift
import SwiftUI
|
|
|
|
enum ClaudeTheme {
|
|
|
|
enum Palette {
|
|
static let canvas = Color(red: 0.000, green: 0.000, blue: 0.000)
|
|
static let surface = Color(red: 0.063, green: 0.055, blue: 0.043)
|
|
static let surfaceRaised = Color(red: 0.102, green: 0.090, blue: 0.071)
|
|
static let surfaceHover = Color(red: 0.141, green: 0.122, blue: 0.090)
|
|
static let border = Color(red: 0.165, green: 0.137, blue: 0.071).opacity(0.55)
|
|
static let divider = Color(red: 0.831, green: 0.667, blue: 0.290).opacity(0.10)
|
|
static let goldHairline = Color(red: 0.831, green: 0.667, blue: 0.290).opacity(0.35)
|
|
|
|
static let textPrimary = Color(red: 0.961, green: 0.910, blue: 0.784)
|
|
static let textSecondary = Color(red: 0.722, green: 0.639, blue: 0.439)
|
|
static let textTertiary = Color(red: 0.420, green: 0.369, blue: 0.239)
|
|
|
|
static let gold = Color(red: 0.831, green: 0.635, blue: 0.290)
|
|
static let goldBright = Color(red: 0.929, green: 0.776, blue: 0.392)
|
|
static let goldDeep = Color(red: 0.620, green: 0.451, blue: 0.157)
|
|
static let goldDim = Color(red: 0.353, green: 0.263, blue: 0.098)
|
|
|
|
static let accent = gold
|
|
static let accentSoft = Color(red: 0.184, green: 0.137, blue: 0.063)
|
|
static let accentDim = Color(red: 0.110, green: 0.082, blue: 0.039)
|
|
|
|
static let success = Color(red: 0.612, green: 0.792, blue: 0.439)
|
|
static let danger = Color(red: 0.890, green: 0.353, blue: 0.353)
|
|
|
|
static let bubbleOutText = Color(red: 0.082, green: 0.063, blue: 0.027)
|
|
static let bubbleInText = Color(red: 0.961, green: 0.910, blue: 0.784)
|
|
|
|
static let goldGradient = LinearGradient(
|
|
colors: [
|
|
Color(red: 0.929, green: 0.776, blue: 0.392),
|
|
Color(red: 0.831, green: 0.635, blue: 0.290),
|
|
Color(red: 0.620, green: 0.451, blue: 0.157),
|
|
],
|
|
startPoint: .topLeading,
|
|
endPoint: .bottomTrailing
|
|
)
|
|
|
|
static let bubbleOutGradient = LinearGradient(
|
|
colors: [
|
|
Color(red: 0.929, green: 0.776, blue: 0.392),
|
|
Color(red: 0.776, green: 0.580, blue: 0.243),
|
|
],
|
|
startPoint: .topLeading,
|
|
endPoint: .bottomTrailing
|
|
)
|
|
}
|
|
|
|
enum Spacing {
|
|
static let xs: CGFloat = 4
|
|
static let sm: CGFloat = 8
|
|
static let md: CGFloat = 12
|
|
static let lg: CGFloat = 16
|
|
static let xl: CGFloat = 24
|
|
static let xxl: CGFloat = 32
|
|
}
|
|
|
|
enum Radius {
|
|
static let sm: CGFloat = 8
|
|
static let md: CGFloat = 12
|
|
static let lg: CGFloat = 16
|
|
static let bubble: CGFloat = 18
|
|
static let pill: CGFloat = 999
|
|
}
|
|
|
|
enum Typography {
|
|
static let display = Font.system(size: 28, weight: .semibold, design: .serif)
|
|
static let title = Font.system(size: 22, weight: .semibold, design: .serif)
|
|
static let headline = Font.system(size: 17, weight: .semibold)
|
|
static let body = Font.system(size: 16, weight: .regular)
|
|
static let callout = Font.system(size: 15, weight: .regular)
|
|
static let caption = Font.system(size: 13, weight: .regular)
|
|
static let micro = Font.system(size: 11, weight: .medium)
|
|
static let serif = Font.system(size: 16, weight: .regular, design: .serif)
|
|
static let serifLg = Font.system(size: 22, weight: .semibold, design: .serif)
|
|
static let mono = Font.system(size: 13, weight: .regular, design: .monospaced)
|
|
}
|
|
}
|
|
|
|
struct ClaudeBackground: ViewModifier {
|
|
func body(content: Content) -> some View {
|
|
content
|
|
.background(ClaudeTheme.Palette.canvas.ignoresSafeArea())
|
|
.preferredColorScheme(.dark)
|
|
}
|
|
}
|
|
|
|
extension View {
|
|
func claudeBackground() -> some View { modifier(ClaudeBackground()) }
|
|
}
|
|
|
|
struct AvatarView: View {
|
|
let name: String
|
|
var size: CGFloat = 48
|
|
|
|
var body: some View {
|
|
let initial = String(name.prefix(1)).uppercased()
|
|
ZStack {
|
|
Circle()
|
|
.fill(ClaudeTheme.Palette.canvas)
|
|
Circle()
|
|
.strokeBorder(ClaudeTheme.Palette.goldGradient, lineWidth: max(1, size * 0.04))
|
|
Circle()
|
|
.strokeBorder(ClaudeTheme.Palette.gold.opacity(0.15), lineWidth: max(0.5, size * 0.02))
|
|
.padding(max(2, size * 0.10))
|
|
|
|
Text(initial)
|
|
.font(.system(size: size * 0.46, weight: .semibold, design: .serif))
|
|
.foregroundStyle(ClaudeTheme.Palette.goldGradient)
|
|
}
|
|
.frame(width: size, height: size)
|
|
}
|
|
}
|
|
|
|
struct MontanaSymbol: View {
|
|
var size: CGFloat = 28
|
|
var body: some View {
|
|
Image(systemName: "j.circle.fill")
|
|
.font(.system(size: size, weight: .bold))
|
|
.foregroundStyle(ClaudeTheme.Palette.goldGradient)
|
|
}
|
|
}
|