package com.suno.android.common_ui.theme import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Typography import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp import com.suno.android.common_core_utils.environment.ThemeMode private val DarkColorScheme = darkColorScheme( primary = SunoPink, onPrimary = Color(0xFFFFFFFF), // system_on_primary_dark primaryContainer = Color(0xFF393A3E), // system_primary_container_dark onPrimaryContainer = Color(0xFFBFC0C3), // system_on_primary_container_dark inversePrimary = Color(0xFFE2E2E6), // system_primary_light secondary = Color(0xFF2A2B32), // system_secondary_dark onSecondary = Color(0xFFFFFFFF), // system_on_secondary_dark secondaryContainer = Color(0xFF41444B), // system_secondary_container_dark onSecondaryContainer = Color(0xFFC8C8CC), // system_on_secondary_container_dark tertiary = Color(0xFF3C3F48), // system_tertiary_dark onTertiary = Color(0xFFFFFFFF), // system_on_tertiary_dark tertiaryContainer = Color(0xFF555861), // system_tertiary_container_dark onTertiaryContainer = Color(0xFFD7D8DC), // system_on_tertiary_container_dark background = DarkBackgroundPrimary, // system_background_dark onBackground = Color(0xFFE3E3E3), // system_on_background_dark surface = Color(0xFF181818), // system_surface_dark onSurface = Color(0xFFE3E3E3), // system_on_surface_dark surfaceVariant = Color(0xFF303033), // system_surface_variant_dark onSurfaceVariant = Color(0xFFC4C4C7), // system_on_surface_variant_dark inverseSurface = Color(0xFFFFFFFF), // system_surface_light inverseOnSurface = Color(0xFF1C1C1F), // system_on_surface_light outline = Color(0xFF8E8E92), // system_outline_dark outlineVariant = Color(0xFF5D5D61), // system_outline_variant_dark surfaceBright = Color(0xFF262629), // system_surface_bright_dark surfaceDim = Color(0xFF0F0F0F), // system_surface_dim_dark surfaceContainer = Color(0xFF222227), // system_surface_container_dark surfaceContainerHigh = Color(0xFF323236), // system_surface_container_high_dark surfaceContainerHighest = Color(0xFF3A3A3E), // system_surface_container_highest_dark surfaceContainerLow = Color(0xFF1A1A1D), // system_surface_container_low_dark surfaceContainerLowest = Color(0xFF121213), // system_surface_container_lowest_dark surfaceTint = Color(0xFF1B1B1F), // system_primary_dark ) private val LightColorScheme = lightColorScheme( primary = SunoPink, onPrimary = Color(0xFFFFFFFF), // system_on_primary_light primaryContainer = Color(0xFFD0E4FF), // system_primary_container_light onPrimaryContainer = Color(0xFF001D39), // system_on_primary_container_light inversePrimary = Color(0xFF8AB4F8), // system_primary_dark secondary = Color(0xFF506A83), // system_secondary_light onSecondary = Color(0xFFFFFFFF), // system_on_secondary_light secondaryContainer = Color(0xFFD6E3F2), // system_secondary_container_light onSecondaryContainer = Color(0xFF0B2D4B), // system_on_secondary_container_light tertiary = Color(0xFF5D5D73), // system_tertiary_light onTertiary = Color(0xFFFFFFFF), // system_on_tertiary_light tertiaryContainer = Color(0xFFE2E1FF), // system_tertiary_container_light onTertiaryContainer = Color(0xFF1B1B2B), // system_on_tertiary_container_light background = BackgroundPrimary, // system_background_light onBackground = Color(0xFF1B1C1E), // system_on_background_light surface = Color(0xFFF5F0ED), // system_surface_light onSurface = Color(0xFF1B1C1E), // system_on_surface_light surfaceVariant = Color(0xFFF5F0ED), // system_surface_variant_light onSurfaceVariant = Color(0xFF444B50), // system_on_surface_variant_light inverseSurface = Color(0xFF303134), // system_surface_dark inverseOnSurface = Color(0xFFEDEFF1), // system_on_surface_dark outline = Color(0xFF74777A), // system_outline_light outlineVariant = Color(0xFFB1B5B8), // system_outline_variant_light surfaceBright = Color(0xFFF5F6F8), // system_surface_bright_light surfaceDim = Color(0xFFE3E4E7), // system_surface_dim_light surfaceContainer = Color(0xFFEFF1F3), // system_surface_container_light surfaceContainerHigh = Color(0xFFF4F6F8), // system_surface_container_high_light surfaceContainerHighest = Color(0xFFFFFFFF), // system_surface_container_highest_light surfaceContainerLow = Color(0xFFDDE0E3), // system_surface_container_low_light surfaceContainerLowest = Color(0xFFEFF1F3), // system_surface_container_lowest_light surfaceTint = Color(0xFF0061A1), // system_primary_light ) val materialTypography = Typography( bodyLarge = TextStyle( fontFamily = NeueMontrealFontFamily, fontWeight = FontWeight.Medium, fontSize = 24.sp, lineHeight = 32.sp, letterSpacing = 0.5.sp, ), bodyMedium = TextStyle( fontFamily = NeueMontrealFontFamily, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 32.sp, letterSpacing = 0.5.sp, ), bodySmall = TextStyle( fontFamily = NeueMontrealFontFamily, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 32.sp, letterSpacing = 0.5.sp, ), headlineLarge = TextStyle( fontFamily = EditorialFontFamily, fontSize = 40.sp, lineHeight = 48.sp, fontWeight = FontWeight.Light, letterSpacing = 0.sp, ), headlineMedium = TextStyle( fontFamily = EditorialFontFamily, fontSize = 32.sp, lineHeight = 40.sp, fontWeight = FontWeight.Light, letterSpacing = 0.sp, ), headlineSmall = TextStyle( fontFamily = EditorialFontFamily, fontSize = 24.sp, lineHeight = 32.sp, fontWeight = FontWeight.Light, letterSpacing = 0.sp, ), titleLarge = TextStyle( fontFamily = EditorialFontFamily, fontWeight = FontWeight.Normal, fontSize = 22.sp, lineHeight = 28.sp, letterSpacing = 0.sp, ), labelLarge = TextStyle(), labelMedium = TextStyle(), labelSmall = TextStyle( fontFamily = InputSansFontFamily, fontWeight = FontWeight.Medium, fontSize = 12.sp, lineHeight = 16.sp, letterSpacing = 0.5.sp, ), ) object ExtendedTheme { val mode: SunoThemeMode? @Composable get() = LocalSunoThemeMode.current val colors: SunoColors @Composable get() = LocalSunoColors.current val typography: SunoTypography @Composable get() = LocalSunoTypography.current val spacing: Spacing @Composable get() = LocalSpacing.current } private val LightSunoColors = SunoColors( backgroundPrimary = BackgroundPrimary, backgroundSecondary = BackgroundSecondary, backgroundTertiary = BackgroundTertiary, backgroundQuarternary = BackgroundQuarternary, backgroundInvert = DarkBackgroundPrimary, backgroundInactive = BackgroundInactive, textPrimary = TextPrimary, textPrimaryInverted = DarkTextPrimary, textSecondary = TextSecondary, textTertiary = TextTertiary, textBrand = TextBrand, foregroundInactive = ForegroundInactive, pillBackground = CreateModePill_Light, sunoPink = SunoPink, aukPink = AukPink, borderPrimary = BorderPrimary, neutralBadgeColor = V4NeutralGrey, badgeBackground = V4NeutralGrey, v4BadgeBorder = V4NeutralGrey, badgeTextColor = Color.Black, warning = Warning, ) private val DarkSunoColors = SunoColors( backgroundPrimary = DarkBackgroundPrimary, backgroundSecondary = DarkBackgroundSecondary, backgroundTertiary = DarkBackgroundTertiary, backgroundQuarternary = DarkBackgroundQuarternary, backgroundInvert = BackgroundPrimary, backgroundInactive = DarkBackgroundInactive, textPrimary = DarkTextPrimary, textPrimaryInverted = TextPrimary, textSecondary = DarkTextSecondary, textTertiary = DarkTextTertiary, textBrand = DarkTextBrand, foregroundInactive = DarkForegroundInactive, pillBackground = CreateModePill_Dark, sunoPink = SunoPink, aukPink = AukPink, borderPrimary = DarkBorderPrimary, badgeTextColor = V4NeutralGrey, neutralBadgeColor = V4NeutralGrey, badgeBackground = DarkModeBadgeBackground, v4BadgeBorder = V4NeutralGrey, warning = Warning, ) private val CustomTypography = SunoTypography( largeHeadline = largeHeadline, mediumHeadline = mediumHeadline, styleCardTitle = styleCardTitle, categoryHeadline = categoryHeadline, smallTrackName = smallTrackName, lyricsMode = lyricsMode, promptLarge = promptLarge, promptMedium = promptMedium, introCopy = introCopy, playlistCards = playlistCards, smallPlayerTitle = smallPlayerTitle, cardTitle = cardTitle, userTitle = userTitle, body = body, smallBody = smallBody, largeBody = largeBody, smallSubtitle = smallSubtitle, largeSubtitle = largeSubtitle, cardMeta = cardMeta, button = buttonMedium, buttonSmallCta = buttonSmallCta, socialText = socialText, mediumTitle = mediumTitle, extraLargeTitle = extraLargeTitle, ) enum class SunoThemeMode { Light, Dark, } private val LocalSunoThemeMode = compositionLocalOf { null } private val LocalSunoColors = staticCompositionLocalOf { LightSunoColors } private val LocalSunoTypography = staticCompositionLocalOf { CustomTypography } private val LocalSpacing = staticCompositionLocalOf { Spacing() } @Composable fun SunoTheme( themeMode: ThemeMode = ThemeMode.SYSTEM, // Dynamic color is available on Android 12+ content: @Composable () -> Unit, ) { val darkTheme = when (themeMode) { ThemeMode.LIGHT -> false ThemeMode.DARK -> true ThemeMode.SYSTEM -> isSystemInDarkTheme() } val colors = if (!darkTheme) LightColorScheme else DarkColorScheme val customColors = if (!darkTheme) LightSunoColors else DarkSunoColors val typography = materialTypography val customTypography = CustomTypography val customSpacing = Spacing() CompositionLocalProvider( LocalSunoThemeMode provides if (darkTheme) SunoThemeMode.Dark else SunoThemeMode.Light, LocalSunoColors provides customColors, LocalSunoTypography provides customTypography, LocalSpacing provides customSpacing, ) { MaterialTheme( colorScheme = colors, typography = typography, content = content, ) } }