From 57e472ff34c3ca1f2f16db462e6a867c207bc9d1 Mon Sep 17 00:00:00 2001 From: Till JS Date: Sun, 17 May 2026 21:12:26 +0200 Subject: [PATCH] refactor(theme): CardsTheme forwarded auf ManaTheme.forest (v1.6.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `mana-swift-core` v1.6.0 liefert alle acht Web-Theme-Variants nativ. CardsTheme bleibt als duenner Alias bestehen — alle ~290 Call-Sites muessen nicht in einem Sprint umziehen, neue Call-Sites koennen direkt `ManaTheme.forest.` oder `@Environment(\.manaTheme)` nutzen. Spart ~100 LOC lokales HSL-Apparat. forest-Werte sind jetzt single-source in `mana/packages/themes/src/variants/forest.css`. 43/43 Tests gruen. Co-Authored-By: Claude Opus 4.7 (1M context) --- Sources/Core/Theme/CardsTheme.swift | 131 +++++----------------------- 1 file changed, 24 insertions(+), 107 deletions(-) diff --git a/Sources/Core/Theme/CardsTheme.swift b/Sources/Core/Theme/CardsTheme.swift index 79a4229..46e3855 100644 --- a/Sources/Core/Theme/CardsTheme.swift +++ b/Sources/Core/Theme/CardsTheme.swift @@ -1,112 +1,29 @@ +import ManaTokens import SwiftUI -#if canImport(UIKit) - import UIKit - - private typealias PlatformColorType = UIColor -#elseif canImport(AppKit) - import AppKit - - private typealias PlatformColorType = NSColor -#endif - -/// Forest-Theme aus `mana/packages/themes/src/variants/forest.css`. -/// Lokal in cards-native nachgebaut, weil ManaTokens v1.0.0 nur den -/// Default-Theme (mana-Variant) liefert. +/// Cards-Theme — forwarded auf ``ManaTheme/forest`` aus +/// `mana-swift-core` v1.6.0. /// -/// Migration auf einen Theme-Switch in ManaTokens ist Phase ε aus -/// `mana/docs/MANA_SWIFT.md` — bis dahin lebt forest hier. +/// Bis v1.5.x lebte hier ein 120-LOC-HSL-Apparat als lokaler Nachbau +/// der `forest.css`-Variant. Mit v1.6.0 liefert ManaTokens alle acht +/// Web-Theme-Variants nativ — `forest` ist eine davon. +/// +/// `CardsTheme` bleibt als dünner Alias bestehen, damit die ~290 +/// Call-Sites in dieser App nicht in einem einzigen Sprint umziehen +/// müssen. Neue Call-Sites bevorzugen direkt `ManaTheme.forest.` +/// (oder `@Environment(\.manaTheme)` falls die App irgendwann +/// Theme-Switching bekommt). enum CardsTheme { - /// Page-Hintergrund - static let background = dynamic(light: HSL(0, 0, 100), dark: HSL(142, 30, 8)) - - /// Standard-Text - static let foreground = dynamic(light: HSL(142, 30, 12), dark: HSL(142, 15, 95)) - - /// Card, Panel, Modal - static let surface = dynamic(light: HSL(142, 25, 98), dark: HSL(142, 25, 12)) - - /// Hover-State auf Surface - static let surfaceHover = dynamic(light: HSL(142, 20, 95), dark: HSL(142, 20, 16)) - - /// Disabled-Felder, Skeleton - static let muted = dynamic(light: HSL(142, 15, 93), dark: HSL(142, 18, 18)) - - /// Sekundär-Text, Placeholder - static let mutedForeground = dynamic(light: HSL(142, 10, 42), dark: HSL(142, 12, 65)) - - /// Rahmen, Trennlinien - static let border = dynamic(light: HSL(142, 15, 88), dark: HSL(142, 18, 22)) - - /// Cards-Brand-Grün — Tiefgrün im Light, leuchtender im Dark - static let primary = dynamic(light: HSL(142, 76, 28), dark: HSL(142, 71, 45)) - - /// Text auf Primary - static let primaryForeground = dynamic(light: HSL(0, 0, 100), dark: HSL(142, 30, 8)) - - static let error = dynamic(light: HSL(0, 84, 60), dark: HSL(0, 63, 55)) - static let success = dynamic(light: HSL(142, 71, 45), dark: HSL(142, 71, 45)) - static let warning = dynamic(light: HSL(38, 92, 50), dark: HSL(48, 96, 53)) - - // MARK: - HSL Helper - - /// Hue/Saturation/Lightness als Wert-Typ. HSL ist konkreter als ein - /// 3-Tupel und macht die Call-Sites lesbar. - struct HSL { - let hue: Double - let saturation: Double - let lightness: Double - - init(_ hue: Double, _ saturation: Double, _ lightness: Double) { - self.hue = hue - self.saturation = saturation - self.lightness = lightness - } - } - - private static func dynamic(light: HSL, dark: HSL) -> Color { - let lightColor = fromHSL(light.hue, light.saturation, light.lightness) - let darkColor = fromHSL(dark.hue, dark.saturation, dark.lightness) - - #if canImport(UIKit) - return Color(uiColor: UIColor { trait in - trait.userInterfaceStyle == .dark ? darkColor : lightColor - }) - #elseif canImport(AppKit) - return Color(nsColor: NSColor(name: nil) { appearance in - let isDark = appearance.bestMatch(from: [.darkAqua, .vibrantDark]) != nil - return isDark ? darkColor : lightColor - }) - #else - return Color(red: 0, green: 0, blue: 0) - #endif - } - - private static func fromHSL(_ hue: Double, _ saturation: Double, _ lightness: Double) -> PlatformColorType { - let h = hue / 360 - let s = saturation / 100 - let l = lightness / 100 - - if s == 0 { - return PlatformColorType(red: l, green: l, blue: l, alpha: 1) - } - - let q = l < 0.5 ? l * (1 + s) : l + s - l * s - let p = 2 * l - q - let r = hueToRGB(p, q, h + 1.0 / 3.0) - let g = hueToRGB(p, q, h) - let b = hueToRGB(p, q, h - 1.0 / 3.0) - - return PlatformColorType(red: r, green: g, blue: b, alpha: 1) - } - - private static func hueToRGB(_ p: Double, _ q: Double, _ rawT: Double) -> Double { - var t = rawT - if t < 0 { t += 1 } - if t > 1 { t -= 1 } - if t < 1.0 / 6.0 { return p + (q - p) * 6 * t } - if t < 1.0 / 2.0 { return q } - if t < 2.0 / 3.0 { return p + (q - p) * (2.0 / 3.0 - t) * 6 } - return p - } + static let background = ManaTheme.forest.background + static let foreground = ManaTheme.forest.foreground + static let surface = ManaTheme.forest.surface + static let surfaceHover = ManaTheme.forest.surfaceHover + static let muted = ManaTheme.forest.muted + static let mutedForeground = ManaTheme.forest.mutedForeground + static let border = ManaTheme.forest.border + static let primary = ManaTheme.forest.primary + static let primaryForeground = ManaTheme.forest.primaryForeground + static let error = ManaTheme.forest.error + static let success = ManaTheme.forest.success + static let warning = ManaTheme.forest.warning }