// moviefriends Design-Tokens für SwiftUI (iPhone/iPad, ab iOS 16).
// Generiert aus packages/design-tokens/tokens.json mit `pnpm tokens:build` – nicht von Hand ändern.
//
// Schriften: Big Shoulders und Instrument Sans (SIL Open Font License) als TTF ins
// App-Bundle legen und in Info.plist unter UIAppFonts eintragen.

import SwiftUI

public extension Color {
    /// Farbe aus 0xRRGGBB (sRGB) mit optionaler Deckkraft.
    init(mfHex hex: UInt32, opacity: Double = 1) {
        self.init(
            .sRGB,
            red: Double((hex >> 16) & 0xFF) / 255,
            green: Double((hex >> 8) & 0xFF) / 255,
            blue: Double(hex & 0xFF) / 255,
            opacity: opacity
        )
    }
}

/// Farben (color.*)
public enum MFColor {
    /// Nachtschwarz – Seitenhintergrund (Kinosaal)
    public static let bg = Color(mfHex: 0x0F0D0B)
    /// Sitzreihe – Karten, Panels
    public static let surface = Color(mfHex: 0x1A1714)
    /// Bühnenboden – erhöhte Flächen, Chips, Bildplatzhalter
    public static let surface2 = Color(mfHex: 0x241F1A)
    /// Eingelassene Flächen, z. B. Chat-Verlauf (A3)
    public static let surfaceSunken = Color(mfHex: 0x15120F)
    /// Holz – Standard-Rahmen von Karten, Buttons, Eingabefeldern
    public static let line = Color(mfHex: 0x3A322A)
    /// Trennlinien, z. B. unter der Kopfzeile
    public static let lineSubtle = Color(mfHex: 0x2A2520)
    /// Gestrichelte Platzhalter („Rolle hinzufügen“), Ränder von Farbfeldern
    public static let lineStrong = Color(mfHex: 0x4A4035)
    /// Gestrichelte Rahmen deaktivierter Aktionen
    public static let lineDisabled = Color(mfHex: 0x6B5F50)
    /// Elfenbein – Haupttext, Leinwand, „movie“ in der Wortmarke
    public static let fg = Color(mfHex: 0xF3ECE2)
    /// Heller Sekundärtext (Bildunterschriften, Fließtext in Karten)
    public static let fgSoft = Color(mfHex: 0xD9CFC1)
    /// Gedämpfter Text (Website, Navigation)
    public static let fg2 = Color(mfHex: 0xC9BEAE)
    /// Sekundärtext, Meta-Infos, inaktive Navigation (Screens)
    public static let fgMuted = Color(mfHex: 0xB8AC9A)
    /// Notizen, Kleingedrucktes
    public static let fg3 = Color(mfHex: 0xA89C8A)
    /// Kinogold – Akzent, Hauptbutton, aktive Zustände, Links, Fokusring, „friends“ in der Wortmarke
    public static let gold = Color(mfHex: 0xF0B24A)
    /// Link-Hover
    public static let goldHover = Color(mfHex: 0xFFD088)
    /// Hauptbutton Hover
    public static let goldButtonHover = Color(mfHex: 0xF6C46A)
    /// Text auf Gold
    public static let goldInk = Color(mfHex: 0x1C1405)
    /// Gold getönte Fläche – eigene Sprechblasen, Avatar mit Goldrand
    public static let goldTint = Color(mfHex: 0x3B2A12)
    /// Grünes Licht – fertig, bestanden, Ampel „Grün“
    public static let ok = Color(mfHex: 0x74D19B)
    /// Text in grünen Chips
    public static let okSoft = Color(mfHex: 0xB9E8CB)
    /// Grüne Fläche (Kommentar-Marker, Status)
    public static let okSurface = Color(mfHex: 0x1F3A2C)
    /// Grüne Karte „Gesamt: Grün“ (A4)
    public static let okSurface2 = Color(mfHex: 0x16251C)
    /// Hinweis/Warnung – Ampel „Gelb“, z. B. unscharfes Foto
    public static let warn = Color(mfHex: 0xF2994A)
    /// Text auf Warn-Fläche
    public static let warnSoft = Color(mfHex: 0xF2B98A)
    /// Warn-Fläche (Foto-Hinweis)
    public static let warnSurface = Color(mfHex: 0x2E1C12)
    /// Fehler – Ampel „Rot“
    public static let danger = Color(mfHex: 0xEF6F6C)
    /// Rote Avatar-/Statusfläche
    public static let dangerSurface = Color(mfHex: 0x3A2424)
    /// Perforation im Produktions-Fortschrittsband (A2–A6)
    public static let filmstrip = Color(mfHex: 0x2E2822)
    /// Papier
    public static let paperBg = Color(mfHex: 0xEFE6D6)
    /// Papier, Rand/Bildfläche
    public static let paperBg2 = Color(mfHex: 0xE2D5BE)
    /// Eselsohr
    public static let paperFold = Color(mfHex: 0xD8CBB4)
    /// Schrift auf Papier
    public static let paperInk = Color(mfHex: 0x2A2118)
    /// Sekundärtext auf Papier
    public static let paperInkMuted = Color(mfHex: 0x6E5D47)
    /// Gold-Überschrift auf Papier
    public static let paperInkGold = Color(mfHex: 0x8A5A12)
    /// Spur 1
    public static let track1 = Color(mfHex: 0x4E6A8C)
    /// Spur 2
    public static let track2 = Color(mfHex: 0x6A4E8C)
    /// Spur 3
    public static let track3 = Color(mfHex: 0x4E8C6A)
    /// Stern / „friends“ auf dunklem Grund
    public static let brandStar = Color(mfHex: 0xF0B24A)
    /// Filmstreifen-Schweif / „movie“ auf dunklem Grund
    public static let brandTail = Color(mfHex: 0xF3ECE2)
    /// Stern auf hellem Grund
    public static let brandStarOnLight = Color(mfHex: 0xD8962A)
    /// „friends“ auf hellem Grund
    public static let brandFriendsOnLight = Color(mfHex: 0xA86A10)
    /// Schweif und „movie“ auf hellem Grund
    public static let brandInkOnLight = Color(mfHex: 0x2A2118)
    /// Heller Grund (Elfenbein), zugleich Perforation der hellen Variante
    public static let brandLightBg = Color(mfHex: 0xF3ECE2)
    /// Sekundärtext auf hellem Grund
    public static let brandMutedOnLight = Color(mfHex: 0x5C4E3D)
    /// Bild-Overlay für Labels auf Fotos
    public static let overlayCaption = Color(mfHex: 0x0F0D0B, opacity: 0.78)
    /// Sticky-Kopfzeile (mit backdrop-filter: blur(8px))
    public static let overlayHeader = Color(mfHex: 0x0F0D0B, opacity: 0.92)
}

/// Schriften (font.family.*)
public enum MFFont {
    /// Überschriften, Wortmarke, große Zahlen – Überschriften in Versalien, die Wortmarke immer klein
    public static let displayFamily = "Big Shoulders"
    /// Fließtext, UI
    public static let bodyFamily = "Instrument Sans"

    /// Big Shoulders in der gewünschten Größe (Standard: 800 = .heavy).
    public static func display(_ size: CGFloat, weight: Font.Weight = .heavy) -> Font {
        .custom(displayFamily, size: size).weight(weight)
    }

    /// Instrument Sans in der gewünschten Größe.
    public static func body(_ size: CGFloat, weight: Font.Weight = .regular) -> Font {
        .custom(bodyFamily, size: size).weight(weight)
    }
}

/// Schriftgrößen in Punkt (font.size.*)
public enum MFFontSize {
    /// Winzige Labels (Zeitstrahl)
    public static let s2xs: CGFloat = 11
    /// Versal-Labels (Eyebrow), Badges
    public static let xs: CGFloat = 12
    /// Kleingedrucktes, Chips
    public static let sm: CGFloat = 13
    /// Häufigste UI-Größe (Meta, Chips, Tabs)
    public static let ui: CGFloat = 14
    /// Navigation
    public static let md: CGFloat = 15
    /// Grundschrift App
    public static let base: CGFloat = 16
    /// Grundschrift Website
    public static let bodyWeb: CGFloat = 17
    /// Hervorgehobener Text
    public static let lg: CGFloat = 18
    /// Lead-Absatz Website
    public static let leadWeb: CGFloat = 19
    /// Big Shoulders 700: Karten-/Phasentitel
    public static let xl: CGFloat = 20
    /// Big Shoulders 800: Panel-Titel
    public static let s2xl: CGFloat = 28
    /// Big Shoulders 700: Abschnittstitel (H2)
    public static let s3xl: CGFloat = 34
    /// Big Shoulders 800: Seitentitel mobil
    public static let s4xl: CGFloat = 40
    /// Big Shoulders 800: große Headline
    public static let s5xl: CGFloat = 56
    /// Big Shoulders 800: Seiten-Headline (H1, A1)
    public static let s6xl: CGFloat = 72
    /// Wortmarke in der Kopfzeile
    public static let logoHeader: CGFloat = 30
    /// Wortmarke auf dem Logo-Board (A7)
    public static let logoBoard: CGFloat = 150
}

/// Schriftschnitte (font.weight.*)
public enum MFFontWeight {
    /// Instrument Sans – Fließtext
    public static let regular: Font.Weight = .regular
    /// Instrument Sans – Navigation
    public static let medium: Font.Weight = .medium
    /// Instrument Sans – Labels; Big Shoulders klein
    public static let semibold: Font.Weight = .semibold
    /// Instrument Sans – Buttons; Big Shoulders – Abschnittstitel
    public static let bold: Font.Weight = .bold
    /// Big Shoulders – Headlines, Wortmarke
    public static let extrabold: Font.Weight = .heavy
}

/// Zeilenhöhe als Vielfaches der Schriftgröße (font.line-height.*)
public enum MFLineHeight {
    /// Headlines (0,9–1,0)
    public static let display: CGFloat = 0.95
    /// Kurze Titel, Zahlen
    public static let tight: CGFloat = 1.1
    /// Fließtext App
    public static let body: CGFloat = 1.5
    /// Fließtext Website
    public static let bodyWeb: CGFloat = 1.6
}

/// Laufweite in em – für .tracking() mit der Schriftgröße multiplizieren (font.letter-spacing.*)
public enum MFLetterSpacing {
    /// Versal-Labels 12 px, z. B. „STUDIO-LOBBY“, „02 · LÄUFT“; auch der Zusatz neben der Wortmarke („HQ“)
    public static let eyebrow: CGFloat = 0.14
    /// Weite Versal-Labels 13–14 px
    public static let eyebrowWide: CGFloat = 0.2
    /// Big Shoulders H2
    public static let heading: CGFloat = 0.03
    /// Big Shoulders H1, Wortmarke
    public static let display: CGFloat = 0.01
}

/// Zusammengesetzter Textstil (typography.*).
public struct MFTextStyle: Sendable {
    public let family: String
    public let size: CGFloat
    public let weight: Font.Weight
    public let lineHeight: CGFloat
    public let letterSpacingEm: CGFloat

    public var font: Font { .custom(family, size: size).weight(weight) }
    /// Laufweite in Punkt für .tracking()
    public var tracking: CGFloat { letterSpacingEm * size }
    /// Zusätzlicher Zeilenabstand für .lineSpacing()
    public var lineSpacing: CGFloat { max(0, (lineHeight - 1) * size) }
}

/// Textstile (typography.*)
public enum MFTypography {
    /// Wortmarke „moviefriends“ – immer klein, „movie“ Elfenbein, „friends“ Kinogold
    public static let wordmark = MFTextStyle(family: "Big Shoulders", size: 30, weight: .heavy, lineHeight: 1, letterSpacingEm: 0.01)
    /// Zusatz neben der Wortmarke („HQ“, „Brand“): Versalien, Elfenbein, halbe Wortmarken-Größe
    public static let wordmarkSuffix = MFTextStyle(family: "Instrument Sans", size: 15, weight: .semibold, lineHeight: 1, letterSpacingEm: 0.14)
    /// Seiten-Headline (H1), Versalien
    public static let display = MFTextStyle(family: "Big Shoulders", size: 72, weight: .heavy, lineHeight: 0.95, letterSpacingEm: 0.01)
    /// Abschnittstitel (H2), Versalien
    public static let heading = MFTextStyle(family: "Big Shoulders", size: 34, weight: .bold, lineHeight: 1.1, letterSpacingEm: 0.03)
    /// Karten- und Phasentitel (H3), Versalien
    public static let title = MFTextStyle(family: "Big Shoulders", size: 20, weight: .bold, lineHeight: 1.1, letterSpacingEm: 0.03)
    /// Versal-Label über Überschriften („02 · LÄUFT“)
    public static let eyebrow = MFTextStyle(family: "Instrument Sans", size: 12, weight: .bold, lineHeight: 1.1, letterSpacingEm: 0.14)
    /// Fließtext App
    public static let body = MFTextStyle(family: "Instrument Sans", size: 16, weight: .regular, lineHeight: 1.5, letterSpacingEm: 0)
    /// Fließtext Website
    public static let bodyWeb = MFTextStyle(family: "Instrument Sans", size: 17, weight: .regular, lineHeight: 1.6, letterSpacingEm: 0)
    /// UI-Text: Meta, Chips, Tabs
    public static let ui = MFTextStyle(family: "Instrument Sans", size: 14, weight: .medium, lineHeight: 1.5, letterSpacingEm: 0)
    /// Beschriftung von Buttons
    public static let button = MFTextStyle(family: "Instrument Sans", size: 16, weight: .bold, lineHeight: 1, letterSpacingEm: 0)
}

/// Abstände in Punkt (space.*)
public enum MFSpace {
    public static let s1: CGFloat = 4
    public static let s2: CGFloat = 8
    public static let s3: CGFloat = 12
    /// Seitenrand mobil
    public static let s4: CGFloat = 16
    public static let s5: CGFloat = 20
    /// Innenabstand Karten
    public static let s6: CGFloat = 24
    /// Seitenrand Screens
    public static let s8: CGFloat = 32
    public static let s10: CGFloat = 40
    /// Abstand zwischen Abschnitten
    public static let s14: CGFloat = 56
    public static let s1_5: CGFloat = 6
    public static let s2_5: CGFloat = 10
    public static let s3_5: CGFloat = 14
}

/// Eckenradien in Punkt (radius.*)
public enum MFRadius {
    /// Fortschrittsbalken, Zeitstrahl-Clips
    public static let xs: CGFloat = 3
    /// Thumbnails, kleine Flächen, Sprechblasen-Spitze
    public static let sm: CGFloat = 4
    /// Buttons, Eingabefelder, Bilder
    public static let md: CGFloat = 6
    /// Listen-Karten, Chat-Eingabe, Farbfelder
    public static let lg: CGFloat = 8
    /// Karten und Panels
    public static let xl: CGFloat = 10
    /// Sprechblasen; die Ecke zum Absender hat radius.sm (Leo: oben links, eigene: oben rechts)
    public static let bubble: CGFloat = 14
    /// Chips, Avatare, Badges, runde Buttons
    public static let pill: CGFloat = 999
}

/// Größen in Punkt (size.*)
public enum MFSize {
    /// Kleiner Button/Chip
    public static let controlSm: CGFloat = 36
    /// Standard-Button/Chip-Höhe
    public static let control: CGFloat = 40
    /// Mindest-Klickfläche, Avatar
    public static let touch: CGFloat = 44
    /// Großer Button, Eingabefeld
    public static let controlLg: CGFloat = 48
    /// Website-CTA
    public static let buttonWeb: CGFloat = 50
    /// Breite des Fokusrings (Kinogold)
    public static let focusRing: CGFloat = 2
    /// Abstand des Fokusrings (Website: 3 px)
    public static let focusOffset: CGFloat = 2
    /// Max. Inhaltsbreite App
    public static let contentMax: CGFloat = 1360
    /// Max. Inhaltsbreite Website
    public static let contentMaxWeb: CGFloat = 1200
    /// Entwurfsbreite Desktop
    public static let screenWidth: CGFloat = 1440
    /// Kleinste unterstützte Breite
    public static let screenWidthMobile: CGFloat = 390
}

/// Schatten (shadow.*) – radius = blur / 2 wie in SwiftUI üblich.
public struct MFShadowStyle: Sendable {
    public let color: Color
    public let radius: CGFloat
    public let x: CGFloat
    public let y: CGFloat
}

public enum MFShadow {
    /// Schwebendes Element – Drehbuch als Buch (A5), Dialoge
    public static let lift = MFShadowStyle(color: Color(mfHex: 0x000000, opacity: 0.55), radius: 30, x: 0, y: 24)
    /// Leuchtpunkt im Lauflicht (Website)
    public static let goldGlow = MFShadowStyle(color: Color(mfHex: 0xF0B24A), radius: 6, x: 0, y: 0)
}

/// Dauer in Sekunden (motion.duration.*)
public enum MFDuration {
    /// Hover, Fokus, Farbwechsel
    public static let fast: TimeInterval = 0.12
    /// Aufklappen, Ein-/Ausblenden
    public static let base: TimeInterval = 0.2
    /// Seitenwechsel, große Flächen, Vorhang
    public static let slow: TimeInterval = 0.4
    /// Ein Durchlauf des Lauflichts (Website)
    public static let marquee: TimeInterval = 38
}

/// Kurven (motion.easing.*) als SwiftUI-Animation mit Standarddauer motion.duration.base.
public enum MFAnimation {
    /// Standard für fast alles
    public static func standard(duration: TimeInterval = MFDuration.base) -> Animation {
        .timingCurve(0.2, 0, 0, 1, duration: duration)
    }
    /// Elemente erscheinen
    public static func enter(duration: TimeInterval = MFDuration.base) -> Animation {
        .timingCurve(0, 0, 0.2, 1, duration: duration)
    }
    /// Elemente verschwinden
    public static func exit(duration: TimeInterval = MFDuration.base) -> Animation {
        .timingCurve(0.4, 0, 1, 1, duration: duration)
    }
    /// Lauflicht, Fortschritt
    public static func linear(duration: TimeInterval = MFDuration.base) -> Animation {
        .timingCurve(0, 0, 1, 1, duration: duration)
    }
}

/// Logo-Regeln (logo.*) – Maße in Punkt, *Ratio als Faktor
public enum MFLogo {
    /// Bildmarke mit Perforation ab dieser Breite
    public static let markMinPerforation: CGFloat = 40
    /// Bildmarke ohne Perforation ab dieser Breite; darunter nur der Stern (Favicon)
    public static let markMin: CGFloat = 24
    /// Stern allein (Favicon) ab dieser Breite
    public static let starMin: CGFloat = 16
    /// Kleinste Schriftgröße der Wortmarke (digital)
    public static let wordmarkMin: CGFloat = 16
    /// Kleinste Breite des horizontalen Logos (digital)
    public static let horizontalMin: CGFloat = 120
    /// Breite der Bildmarke = 1,66 × Schriftgröße der Wortmarke
    public static let markRatio: CGFloat = 1.66
    /// Abstand Bildmarke ↔ Wortmarke und Wortmarke ↔ Zusatz = ⅓ der Schriftgröße
    public static let gapRatio: CGFloat = 0.33
    /// Zusatz neben der Wortmarke („HQ“) = ½ der Wortmarken-Schriftgröße
    public static let suffixRatio: CGFloat = 0.5
    /// Kleinste Schriftgröße des Zusatzes
    public static let suffixMin: CGFloat = 12
    /// Schutzzone auf allen Seiten = ½ Höhe der Bildmarke
    public static let clearspaceRatio: CGFloat = 0.5
    /// Eckenradius des App-Icons = 22,4 % der Kantenlänge (iOS rundet selbst ab)
    public static let appIconRadiusRatio: CGFloat = 0.224
}

/// Social-Media-Format mit Sicherheitsbereich (social.*).
public struct MFSocialFormat: Sendable {
    public let size: CGSize
    public let safeArea: EdgeInsets
}

public enum MFSocial {
    /// Beitrag quadratisch 1:1 (Instagram, Facebook, LinkedIn)
    public static let square = MFSocialFormat(size: CGSize(width: 1080, height: 1080), safeArea: EdgeInsets(top: 80, leading: 80, bottom: 80, trailing: 80))
    /// Story/Reel/Short 9:16 (Instagram, TikTok, YouTube Shorts) – oben Profilzeile, unten Antwortfeld und Bedienelemente
    public static let story = MFSocialFormat(size: CGSize(width: 1080, height: 1920), safeArea: EdgeInsets(top: 250, leading: 64, bottom: 340, trailing: 64))
    /// Link-Vorschau 1,91:1 (Open Graph, X, LinkedIn, Messenger) – manche Dienste schneiden quadratisch aus der Mitte
    public static let link = MFSocialFormat(size: CGSize(width: 1200, height: 630), safeArea: EdgeInsets(top: 40, leading: 60, bottom: 40, trailing: 60))
}
