diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 429f582..7642878 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,7 +16,7 @@ android { minSdk = 26 targetSdk = 35 versionCode = 1 - versionName = "0.0.6" + versionName = "0.0.7" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/planify/mobile/ui/MainScreen.kt b/app/src/main/java/com/planify/mobile/ui/MainScreen.kt index 5cda640..12a0f54 100644 --- a/app/src/main/java/com/planify/mobile/ui/MainScreen.kt +++ b/app/src/main/java/com/planify/mobile/ui/MainScreen.kt @@ -81,14 +81,14 @@ fun MainScreen(viewModel: DrawerViewModel = hiltViewModel()) { ) val title = drawerTitles[currentRoute] ?: projects.find { "project/${it.id}" == currentRoute }?.name - ?: "Planify" + ?: "BonsaiTask" ModalNavigationDrawer( drawerState = drawerState, drawerContent = { ModalDrawerSheet { Text( - text = "Planify", + text = "BonsaiTask", fontWeight = FontWeight.Bold, modifier = Modifier.padding(horizontal = 16.dp, vertical = 20.dp), ) diff --git a/app/src/main/java/com/planify/mobile/ui/theme/Theme.kt b/app/src/main/java/com/planify/mobile/ui/theme/Theme.kt index ac4803d..072cf51 100644 --- a/app/src/main/java/com/planify/mobile/ui/theme/Theme.kt +++ b/app/src/main/java/com/planify/mobile/ui/theme/Theme.kt @@ -1,21 +1,104 @@ package com.planify.mobile.ui.theme -import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.graphics.Color import androidx.hilt.navigation.compose.hiltViewModel import com.planify.mobile.data.preferences.ThemeMode -private val LightColorScheme = lightColorScheme() -private val DarkColorScheme = darkColorScheme() +// Bonsai design tokens — extracted from the webapp CSS palette +private val Blue600 = Color(0xFF2563EB) +private val Blue700 = Color(0xFF1D4ED8) +private val Blue800 = Color(0xFF1E3A8A) +private val Blue100 = Color(0xFFDBEAFE) +private val Blue50 = Color(0xFFEFF6FF) +private val Blue300 = Color(0xFF93C5FD) +private val Blue400 = Color(0xFF60A5FA) + +private val Gray50 = Color(0xFFF9FAFB) +private val Gray100 = Color(0xFFF3F4F6) +private val Gray200 = Color(0xFFE5E7EB) +private val Gray300 = Color(0xFFD1D5DB) +private val Gray400 = Color(0xFF9CA3AF) +private val Gray500 = Color(0xFF6B7280) +private val Gray600 = Color(0xFF4B5563) +private val Gray700 = Color(0xFF374151) +private val Gray800 = Color(0xFF1F2937) +private val Gray900 = Color(0xFF111827) + +private val Green800 = Color(0xFF276749) +private val Green600 = Color(0xFF2F855A) +private val Green200 = Color(0xFFD1FAE5) +private val Green900 = Color(0xFF14532D) + +private val Red600 = Color(0xFFDC2626) +private val Red100 = Color(0xFFFEE2E2) +private val Red900 = Color(0xFF7F1D1D) + +private val BonsaiLightColorScheme = lightColorScheme( + primary = Blue600, + onPrimary = Color.White, + primaryContainer = Blue100, + onPrimaryContainer = Blue800, + secondary = Blue700, + onSecondary = Color.White, + secondaryContainer = Blue50, + onSecondaryContainer = Blue700, + tertiary = Green800, + onTertiary = Color.White, + tertiaryContainer = Green200, + onTertiaryContainer = Green900, + error = Red600, + onError = Color.White, + errorContainer = Red100, + onErrorContainer = Red900, + background = Gray50, + onBackground = Gray900, + surface = Color.White, + onSurface = Gray900, + surfaceVariant = Gray100, + onSurfaceVariant = Gray700, + outline = Gray200, + outlineVariant = Gray300, + inverseSurface = Gray800, + inverseOnSurface = Gray50, + inversePrimary = Blue300, +) + +private val BonsaiDarkColorScheme = darkColorScheme( + primary = Blue300, + onPrimary = Blue800, + primaryContainer = Blue700, + onPrimaryContainer = Blue100, + secondary = Blue400, + onSecondary = Blue800, + secondaryContainer = Blue800, + onSecondaryContainer = Blue100, + tertiary = Green200, + onTertiary = Green900, + tertiaryContainer = Green600, + onTertiaryContainer = Green200, + error = Color(0xFFF87171), + onError = Red900, + errorContainer = Color(0xFF991B1B), + onErrorContainer = Color(0xFFFECACA), + background = Gray900, + onBackground = Gray50, + surface = Gray800, + onSurface = Gray50, + surfaceVariant = Gray700, + onSurfaceVariant = Gray300, + outline = Gray600, + outlineVariant = Gray700, + inverseSurface = Gray50, + inverseOnSurface = Gray900, + inversePrimary = Blue600, +) @Composable fun PlanifyTheme( @@ -30,17 +113,8 @@ fun PlanifyTheme( ThemeMode.SYSTEM -> systemDark } - val colorScheme = when { - Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (isDark) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - isDark -> DarkColorScheme - else -> LightColorScheme - } - MaterialTheme( - colorScheme = colorScheme, + colorScheme = if (isDark) BonsaiDarkColorScheme else BonsaiLightColorScheme, typography = Typography, content = content, ) diff --git a/app/src/main/java/com/planify/mobile/ui/theme/Type.kt b/app/src/main/java/com/planify/mobile/ui/theme/Type.kt index e1e0b28..b765c41 100644 --- a/app/src/main/java/com/planify/mobile/ui/theme/Type.kt +++ b/app/src/main/java/com/planify/mobile/ui/theme/Type.kt @@ -6,10 +6,88 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp val Typography = Typography( + displayLarge = TextStyle( + fontWeight = FontWeight.Bold, + fontSize = 57.sp, + lineHeight = 64.sp, + letterSpacing = (-0.25).sp, + ), + displayMedium = TextStyle( + fontWeight = FontWeight.Bold, + fontSize = 45.sp, + lineHeight = 52.sp, + ), + displaySmall = TextStyle( + fontWeight = FontWeight.SemiBold, + fontSize = 36.sp, + lineHeight = 44.sp, + ), + headlineLarge = TextStyle( + fontWeight = FontWeight.SemiBold, + fontSize = 32.sp, + lineHeight = 40.sp, + ), + headlineMedium = TextStyle( + fontWeight = FontWeight.SemiBold, + fontSize = 28.sp, + lineHeight = 36.sp, + ), + headlineSmall = TextStyle( + fontWeight = FontWeight.SemiBold, + fontSize = 24.sp, + lineHeight = 32.sp, + ), + titleLarge = TextStyle( + fontWeight = FontWeight.SemiBold, + fontSize = 20.sp, + lineHeight = 28.sp, + ), + titleMedium = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.15.sp, + ), + titleSmall = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.1.sp, + ), bodyLarge = TextStyle( fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) + letterSpacing = 0.5.sp, + ), + bodyMedium = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.25.sp, + ), + bodySmall = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.4.sp, + ), + labelLarge = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.1.sp, + ), + labelMedium = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp, + ), + labelSmall = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp, + ), )