// // AppTheme.swift // Reflect (iOS) // // Created by Claude Code on 12/26/24. // import SwiftUI /// Cohesive themes that bundle colors, icons, entry styles, and voting layouts /// into unified aesthetic experiences. Each theme is designed around a specific /// emotional resonance and target user persona. enum AppTheme: Int, CaseIterable, Identifiable { case zenGarden = 0 case synthwave = 1 case celestial = 2 case editorial = 3 case mixtape = 4 case bloom = 5 case heartfelt = 6 case minimal = 7 case luxe = 8 case forecast = 9 case playful = 10 case journal = 11 var id: Int { rawValue } // MARK: - Display Properties var name: String { switch self { case .zenGarden: return "Zen Garden" case .synthwave: return "Synthwave" case .celestial: return "Celestial" case .editorial: return "Editorial" case .mixtape: return "Mixtape" case .bloom: return "Bloom" case .heartfelt: return "Heartfelt" case .minimal: return "Minimal" case .luxe: return "Luxe" case .forecast: return "Forecast" case .playful: return "Playful" case .journal: return "Journal" } } var tagline: String { switch self { case .zenGarden: return "Meditative calm" case .synthwave: return "Retro-futuristic energy" case .celestial: return "Cosmic wisdom" case .editorial: return "Literary elegance" case .mixtape: return "Analog nostalgia" case .bloom: return "Growth & healing" case .heartfelt: return "Emotional depth" case .minimal: return "Pure simplicity" case .luxe: return "Premium refinement" case .forecast: return "Mood as weather" case .playful: return "Fun & vibrant" case .journal: return "Personal diary" } } var description: String { switch self { case .zenGarden: return "Japanese minimalism meets mindful awareness. Soft pastels, organic growth icons, clean entries, and contemplative vertical voting." case .synthwave: return "80s arcade aesthetic with neon glow. Electric colors, cosmic icons, grid backgrounds, and equalizer-bar voting." case .celestial: return "Journey from void to starlight. Moon phases, orbital layouts, and planetary arrangements for cosmic mood tracking." case .editorial: return "Magazine-quality typography and layout. Clean icons, pull-quote entries, and sophisticated presentation." case .mixtape: return "Cassette culture and analog warmth. Tape reels, track numbers, and the tactile feel of pressing play." case .bloom: return "From wilted flower to full bloom. Atmospheric glowing entries, organic icons, and the gentle metaphor of growth." case .heartfelt: return "Unashamed emotional expression. Heart icons from broken to sparkling, bold colors, intuitive selection." case .minimal: return "Only the essentials. Clean typography, flat design, and zero distractions." case .luxe: return "Liquid glass and premium materials. Cutting-edge iOS design language for the discerning user." case .forecast: return "Your mood is the weather. Storm to sunshine icons, colorful bubble entries, and natural intuition." case .playful: return "Life's too short to be serious. Vibrant neons, familiar emoji, and game-like interaction." case .journal: return "Like writing in a physical diary. Stacked paper notes, handwritten feel, and intimate reflection." } } var emoji: String { switch self { case .zenGarden: return "🧘" case .synthwave: return "🌆" case .celestial: return "✨" case .editorial: return "📰" case .mixtape: return "📼" case .bloom: return "🌸" case .heartfelt: return "💖" case .minimal: return "◽" case .luxe: return "💎" case .forecast: return "🌦️" case .playful: return "🎮" case .journal: return "📒" } } // MARK: - Theme Components var colorTint: MoodTints { switch self { case .zenGarden: return .Pastel case .synthwave: return .Neon case .celestial: return .Default case .editorial: return .Pastel case .mixtape: return .Default case .bloom: return .Pastel case .heartfelt: return .Pastel case .minimal: return .Pastel case .luxe: return .Default case .forecast: return .Default case .playful: return .Neon case .journal: return .Default } } var iconPack: MoodImages { switch self { case .zenGarden: return .Garden case .synthwave: return .Cosmic case .celestial: return .Cosmic case .editorial: return .FontAwesome case .mixtape: return .Emoji case .bloom: return .Garden case .heartfelt: return .Hearts case .minimal: return .FontAwesome case .luxe: return .Cosmic case .forecast: return .Weather case .playful: return .Emoji case .journal: return .FontAwesome } } var entryStyle: DayViewStyle { switch self { case .zenGarden: return .minimal case .synthwave: return .neon case .celestial: return .orbit case .editorial: return .chronicle case .mixtape: return .tape case .bloom: return .aura case .heartfelt: return .bubble case .minimal: return .minimal case .luxe: return .glass case .forecast: return .bubble case .playful: return .pattern case .journal: return .stack } } var votingLayout: VotingLayoutStyle { switch self { case .zenGarden: return .stacked case .synthwave: return .neon case .celestial: return .orbit case .editorial: return .horizontal case .mixtape: return .cards case .bloom: return .aura case .heartfelt: return .horizontal case .minimal: return .horizontal case .luxe: return .aura case .forecast: return .horizontal case .playful: return .cards case .journal: return .stacked } } var paywallStyle: PaywallStyle { switch self { case .zenGarden: return .zen case .synthwave: return .neon case .celestial: return .celestial case .editorial: return .editorial case .mixtape: return .mixtape case .bloom: return .garden case .heartfelt: return .heartfelt case .minimal: return .minimal case .luxe: return .luxe case .forecast: return .forecast case .playful: return .playful case .journal: return .journal } } var lockScreenStyle: LockScreenStyle { switch self { case .zenGarden: return .zen case .synthwave: return .neon case .celestial: return .celestial case .editorial: return .editorial case .mixtape: return .mixtape case .bloom: return .bloom case .heartfelt: return .heartfelt case .minimal: return .minimal case .luxe: return .luxe case .forecast: return .forecast case .playful: return .playful case .journal: return .journal } } // MARK: - Preview Colors (for theme picker UI) var previewColors: [Color] { switch self { case .zenGarden: return [Color(hex: "#C1E1C1"), Color(hex: "#A7C7E7"), Color(hex: "#fdfd96")] case .synthwave: return [Color(red: 0, green: 1, blue: 0.82), Color(red: 1, green: 0, blue: 0.8), Color(hex: "#050510")] case .celestial: return [Color(hex: "#0b84ff"), Color(hex: "#31d158"), Color(hex: "#1a1a2e")] case .editorial: return [Color(hex: "#A7C7E7"), Color(hex: "#2c2c2c"), Color(hex: "#f5f5f5")] case .mixtape: return [Color(hex: "#8B4513"), Color(hex: "#D2691E"), Color(hex: "#2c2c2c")] case .bloom: return [Color(hex: "#C1E1C1"), Color(hex: "#ffb347"), Color(hex: "#FF6961")] case .heartfelt: return [Color(hex: "#FF6961"), Color(hex: "#ffb347"), Color(hex: "#C1E1C1")] case .minimal: return [Color(hex: "#A7C7E7"), Color(hex: "#e0e0e0"), Color(hex: "#f8f8f8")] case .luxe: return [Color(hex: "#0b84ff"), Color(hex: "#31d158"), Color.white.opacity(0.8)] case .forecast: return [Color(hex: "#0b84ff"), Color(hex: "#ffd709"), Color(hex: "#ff453a")] case .playful: return [Color(hex: "#39FF14"), Color(hex: "#FFF01F"), Color(hex: "#FF5F1F")] case .journal: return [Color(hex: "#D2B48C"), Color(hex: "#8B4513"), Color(hex: "#FFFEF0")] } } // MARK: - Apply Theme /// Applies all theme settings to UserDefaults func apply() { // Set color tint GroupUserDefaults.groupDefaults.set(colorTint.rawValue, forKey: UserDefaultsStore.Keys.moodTint.rawValue) // Set icon pack GroupUserDefaults.groupDefaults.set(iconPack.rawValue, forKey: UserDefaultsStore.Keys.moodImages.rawValue) // Set entry style GroupUserDefaults.groupDefaults.set(entryStyle.rawValue, forKey: UserDefaultsStore.Keys.dayViewStyle.rawValue) // Set voting layout GroupUserDefaults.groupDefaults.set(votingLayout.rawValue, forKey: UserDefaultsStore.Keys.votingLayoutStyle.rawValue) // Set paywall style GroupUserDefaults.groupDefaults.set(paywallStyle.rawValue, forKey: UserDefaultsStore.Keys.paywallStyle.rawValue) // Set lock screen style GroupUserDefaults.groupDefaults.set(lockScreenStyle.rawValue, forKey: UserDefaultsStore.Keys.lockScreenStyle.rawValue) // Log the theme change Task { @MainActor in AnalyticsManager.shared.track(.themeApplied(themeName: name)) } } } // MARK: - Theme Categories for Browsing extension AppTheme { enum Category: String, CaseIterable { case calm = "Calm & Mindful" case energetic = "Energetic & Bold" case sophisticated = "Sophisticated" case expressive = "Expressive" var themes: [AppTheme] { switch self { case .calm: return [.zenGarden, .minimal, .bloom] case .energetic: return [.synthwave, .playful, .mixtape] case .sophisticated: return [.celestial, .editorial, .luxe] case .expressive: return [.heartfelt, .forecast, .journal] } } } }