spb/zyquo-atlas Public License
The AI-native macOS web browser — every surface, intelligent.
Swift 75.2%
JavaScript 22%
Shell 2%
Makefile 0.9%
1//2// AtlasTheme.swift3// Zyquo Atlas4//5// Author: Simon-Pierre Boucher6// Mail: contact@spboucher.ai7//8// The user-overridable theme value type (Phase 4.2). A theme is a named color9// palette + background + appearance, Codable so it imports/exports as a small10// JSON file. The base tokens in ZyquoTheme seed the flagship "Atlas Light"11// theme (Phase 4.1); the ThemeEngine swaps the active AtlasTheme live. Layout12// and typography preferences live in LayoutSettings (separate from color13// themes) so changing colors never disturbs the user's layout.14//1516import SwiftUI1718extension Color {19 /// 0xRRGGBB → Color (sRGB).20 init(hex: UInt32) {21 self.init(.sRGB,22 red: Double((hex >> 16) & 0xFF) / 255,23 green: Double((hex >> 8) & 0xFF) / 255,24 blue: Double(hex & 0xFF) / 255,25 opacity: 1)26 }27}2829enum ThemeAppearance: String, Codable, Hashable {30 case light, dark31}3233/// The 13 semantic color slots (the flagship "Atlas Light" values are the34/// Phase 4.1 base spec).35struct AtlasPalette: Codable, Hashable {36 var background: UInt3237 var surface: UInt3238 var surfaceSecondary: UInt3239 var accent: UInt3240 var accentIndigo: UInt3241 var accentSubtle: UInt3242 var textPrimary: UInt3243 var textSecondary: UInt3244 var textTertiary: UInt3245 var border: UInt3246 var success: UInt3247 var warning: UInt3248 var danger: UInt3249}5051/// Background behind the chrome / new-tab page.52struct BackgroundStyle: Codable, Hashable {53 enum Kind: String, Codable { case solid, gradient, image }54 var kind: Kind = .solid55 var colorA: UInt32 = 0xFAFBFC56 var colorB: UInt32 = 0xE6F5F357 /// Absolute path to a wallpaper image (image kind only).58 var imagePath: String?59}6061struct AtlasTheme: Codable, Hashable, Identifiable {62 var id: String63 var name: String64 var appearance: ThemeAppearance65 var palette: AtlasPalette66 var background: BackgroundStyle6768 // MARK: - Resolved SwiftUI colors (views read these)6970 var backgroundColor: Color { Color(hex: palette.background) }71 var surface: Color { Color(hex: palette.surface) }72 var surfaceSecondary: Color { Color(hex: palette.surfaceSecondary) }73 var accent: Color { Color(hex: palette.accent) }74 var accentIndigo: Color { Color(hex: palette.accentIndigo) }75 var accentSubtle: Color { Color(hex: palette.accentSubtle) }76 var textPrimary: Color { Color(hex: palette.textPrimary) }77 var textSecondary: Color { Color(hex: palette.textSecondary) }78 var textTertiary: Color { Color(hex: palette.textTertiary) }79 var border: Color { Color(hex: palette.border) }80 var success: Color { Color(hex: palette.success) }81 var warning: Color { Color(hex: palette.warning) }82 var danger: Color { Color(hex: palette.danger) }8384 var colorScheme: ColorScheme { appearance == .dark ? .dark : .light }8586 /// The chrome/new-tab background as a SwiftUI view.87 @ViewBuilder88 var backgroundView: some View {89 switch background.kind {90 case .solid:91 backgroundColor92 case .gradient:93 LinearGradient(colors: [Color(hex: background.colorA), Color(hex: background.colorB)],94 startPoint: .top, endPoint: .bottom)95 case .image:96 if let path = background.imagePath, let img = NSImage(contentsOfFile: path) {97 Image(nsImage: img).resizable().aspectRatio(contentMode: .fill)98 } else {99 backgroundColor100 }101 }102 }103}104105// MARK: - Layout & typography (separate from color themes)106107enum TabPosition: String, Codable, Hashable, CaseIterable {108 case top, left109}110111enum Density: String, Codable, Hashable, CaseIterable {112 case compact, comfortable113}114115/// User layout/typography preferences, persisted per profile and applied live.116struct LayoutSettings: Codable, Hashable {117 var tabPosition: TabPosition = .top118 var density: Density = .comfortable119 var uiScale: Double = 1.0 // 0.85 … 1.30120 var defaultPageZoom: Double = 1.0121 var showBookmarksBar: Bool = false122 var translucency: Bool = false123124 // Density-derived metrics.125 var toolbarHeight: CGFloat { density == .compact ? 38 : 44 }126 var tabBarHeight: CGFloat { density == .compact ? 30 : 36 }127 var verticalTabWidth: CGFloat { 220 }128 var rowSpacing: CGFloat { density == .compact ? ZyquoSpacing.xxs : ZyquoSpacing.xs }129130 /// UI font at a base size, scaled by the user's uiScale.131 func font(_ base: Double, weight: Font.Weight = .regular) -> Font {132 .system(size: base * uiScale, weight: weight)133 }134}135