fix: UI polish across auth, play hub, settings, wheel screens

This commit is contained in:
null 2026-06-17 20:59:21 -05:00
parent d6f5eb6b0f
commit 827cfd2e2d
6 changed files with 184 additions and 123 deletions

View File

@ -5,19 +5,25 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.BackgroundColor
import app.closer.ui.theme.OnBackgroundColor
import app.closer.ui.theme.OnPrimaryColor
import app.closer.ui.theme.OnSurfaceVariantColor
import app.closer.ui.theme.PrimaryColor
internal val AuthBackgroundBrush: Brush internal val AuthBackgroundBrush: Brush
get() = Brush.linearGradient( get() = Brush.linearGradient(
colors = listOf(Color(0xFFFFFBFE), Color(0xFFF8F1FF), Color(0xFFFFEEF7)), colors = listOf(BackgroundColor, CloserPalette.PurpleSoft, CloserPalette.PinkMist),
start = Offset.Zero, start = Offset.Zero,
end = Offset.Infinite end = Offset.Infinite
) )
internal val AuthInk = Color(0xFF261D2E) internal val AuthInk = OnBackgroundColor
internal val AuthMuted = Color(0xFF5A5060) internal val AuthMuted = OnSurfaceVariantColor
internal val AuthPrimary = Color(0xFFB98AF4) internal val AuthPrimary = PrimaryColor
internal val AuthPrimaryDeep = Color(0xFF56306F) internal val AuthPrimaryDeep = CloserPalette.PurpleDeep
internal val AuthOnPrimary = Color(0xFF24122F) internal val AuthOnPrimary = OnPrimaryColor
@Composable @Composable
internal fun authTextFieldColors() = OutlinedTextFieldDefaults.colors( internal fun authTextFieldColors() = OutlinedTextFieldDefaults.colors(

View File

@ -32,8 +32,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -41,6 +39,10 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import app.closer.core.navigation.AppRoute import app.closer.core.navigation.AppRoute
import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.closerBackgroundBrush
import app.closer.ui.theme.closerBrandGlyphBrush
import app.closer.ui.theme.closerPlayCardBrush
@Composable @Composable
fun PlayHubScreen( fun PlayHubScreen(
@ -56,13 +58,7 @@ private fun PlayHubContent(
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(closerBackgroundBrush())
Brush.linearGradient(
listOf(Color(0xFFFFFBFE), Color(0xFFF8F1FF), Color(0xFFFFEEF7)),
start = Offset.Zero,
end = Offset.Infinite
)
)
) { ) {
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
@ -80,14 +76,14 @@ private fun PlayHubContent(
Text( Text(
text = "Play", text = "Play",
style = MaterialTheme.typography.displaySmall.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.displaySmall.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF261D2E), color = MaterialTheme.colorScheme.onBackground,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
Text( Text(
text = "Pick something light, useful, or a little surprising to do together.", text = "Pick something light, useful, or a little surprising to do together.",
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -109,7 +105,7 @@ private fun PlayHubContent(
title = "Date Match", title = "Date Match",
subtitle = "Swipe ideas", subtitle = "Swipe ideas",
icon = Icons.Filled.Favorite, icon = Icons.Filled.Favorite,
tint = Color(0xFF9B1B5A), tint = CloserPalette.Romantic,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onNavigate(AppRoute.DATE_MATCH) } onClick = { onNavigate(AppRoute.DATE_MATCH) }
) )
@ -117,7 +113,7 @@ private fun PlayHubContent(
title = "Plan Date", title = "Plan Date",
subtitle = "Set the shape", subtitle = "Set the shape",
icon = Icons.Filled.Star, icon = Icons.Filled.Star,
tint = Color(0xFF6A4A00), tint = CloserPalette.Gold,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onNavigate(AppRoute.DATE_BUILDER) } onClick = { onNavigate(AppRoute.DATE_BUILDER) }
) )
@ -133,7 +129,7 @@ private fun PlayHubContent(
title = "Bucket List", title = "Bucket List",
subtitle = "Save ideas", subtitle = "Save ideas",
icon = Icons.Filled.Done, icon = Icons.Filled.Done,
tint = Color(0xFF2F5B4F), tint = CloserPalette.Evergreen,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onNavigate(AppRoute.BUCKET_LIST) } onClick = { onNavigate(AppRoute.BUCKET_LIST) }
) )
@ -141,7 +137,7 @@ private fun PlayHubContent(
title = "Wheel History", title = "Wheel History",
subtitle = "Past sessions", subtitle = "Past sessions",
icon = Icons.Filled.Home, icon = Icons.Filled.Home,
tint = Color(0xFF56306F), tint = CloserPalette.PurpleDeep,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onNavigate(AppRoute.WHEEL_HISTORY) } onClick = { onNavigate(AppRoute.WHEEL_HISTORY) }
) )
@ -159,18 +155,12 @@ private fun FeaturedPlayCard(
onClick = onClick, onClick = onClick,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(30.dp), shape = RoundedCornerShape(30.dp),
colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.9f)), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.9f)),
elevation = CardDefaults.cardElevation(defaultElevation = 12.dp) elevation = CardDefaults.cardElevation(defaultElevation = 12.dp)
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
.background( .background(closerPlayCardBrush())
Brush.linearGradient(
listOf(Color.White, Color(0xFFF3E8FF), Color(0xFFFFF7FB)),
start = Offset.Zero,
end = Offset.Infinite
)
)
.padding(20.dp), .padding(20.dp),
verticalArrangement = Arrangement.spacedBy(18.dp) verticalArrangement = Arrangement.spacedBy(18.dp)
) { ) {
@ -181,25 +171,25 @@ private fun FeaturedPlayCard(
) { ) {
Surface( Surface(
shape = RoundedCornerShape(999.dp), shape = RoundedCornerShape(999.dp),
color = Color.White.copy(alpha = 0.72f) color = MaterialTheme.colorScheme.surface.copy(alpha = 0.72f)
) { ) {
Text( Text(
text = "Wheel", text = "Wheel",
modifier = Modifier.padding(horizontal = 12.dp, vertical = 7.dp), modifier = Modifier.padding(horizontal = 12.dp, vertical = 7.dp),
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = Color(0xFF56306F), color = CloserPalette.PurpleDeep,
fontWeight = FontWeight.SemiBold fontWeight = FontWeight.SemiBold
) )
} }
Surface( Surface(
shape = RoundedCornerShape(999.dp), shape = RoundedCornerShape(999.dp),
color = Color(0xFFFFE8F4) color = MaterialTheme.colorScheme.secondaryContainer
) { ) {
Text( Text(
text = "10 prompts", text = "10 prompts",
modifier = Modifier.padding(horizontal = 12.dp, vertical = 7.dp), modifier = Modifier.padding(horizontal = 12.dp, vertical = 7.dp),
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = Color(0xFF6D2B55), color = CloserPalette.PinkAccentDeep,
fontWeight = FontWeight.SemiBold fontWeight = FontWeight.SemiBold
) )
} }
@ -220,14 +210,14 @@ private fun FeaturedPlayCard(
Text( Text(
text = "Spin the Wheel", text = "Spin the Wheel",
style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF261D2E), color = MaterialTheme.colorScheme.onSurface,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
Text( Text(
text = "Choose a mood, spin once, and move through a short session together.", text = "Choose a mood, spin once, and move through a short session together.",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 3, maxLines = 3,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -241,8 +231,8 @@ private fun FeaturedPlayCard(
.heightIn(min = 54.dp), .heightIn(min = 54.dp),
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF56306F), containerColor = CloserPalette.PurpleDeep,
contentColor = Color.White contentColor = MaterialTheme.colorScheme.surface
) )
) { ) {
Text("Choose category") Text("Choose category")
@ -264,7 +254,7 @@ private fun CompactPlayCard(
onClick = onClick, onClick = onClick,
modifier = modifier.heightIn(min = 154.dp), modifier = modifier.heightIn(min = 154.dp),
shape = RoundedCornerShape(24.dp), shape = RoundedCornerShape(24.dp),
colors = CardDefaults.cardColors(containerColor = Color.White), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp) elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
) { ) {
Column( Column(
@ -291,7 +281,7 @@ private fun CompactPlayCard(
Text( Text(
text = title, text = title,
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF261D2E), color = MaterialTheme.colorScheme.onSurface,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -303,7 +293,7 @@ private fun CompactPlayCard(
Text( Text(
text = subtitle, text = subtitle,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -327,22 +317,16 @@ private fun WheelGlyph(
Surface( Surface(
modifier = modifier, modifier = modifier,
shape = RoundedCornerShape(26.dp), shape = RoundedCornerShape(26.dp),
color = Color(0xFF56306F) color = CloserPalette.PurpleDeep
) { ) {
Box( Box(
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
modifier = Modifier.background( modifier = Modifier.background(closerBrandGlyphBrush())
Brush.linearGradient(
listOf(Color(0xFFB98AF4), Color(0xFFE7A2D1), Color(0xFF56306F)),
start = Offset.Zero,
end = Offset.Infinite
)
)
) { ) {
Icon( Icon(
imageVector = Icons.Filled.PlayArrow, imageVector = Icons.Filled.PlayArrow,
contentDescription = null, contentDescription = null,
tint = Color.White, tint = MaterialTheme.colorScheme.surface,
modifier = Modifier.size(34.dp) modifier = Modifier.size(34.dp)
) )
} }

View File

@ -5,22 +5,28 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import app.closer.ui.theme.BackgroundColor
import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.OnBackgroundColor
import app.closer.ui.theme.OnPrimaryColor
import app.closer.ui.theme.OnSurfaceVariantColor
import app.closer.ui.theme.PrimaryColor
internal val SettingsBackgroundBrush: Brush internal val SettingsBackgroundBrush: Brush
get() = Brush.linearGradient( get() = Brush.linearGradient(
colors = listOf(Color(0xFFFFFBFE), Color(0xFFF8F1FF), Color(0xFFFFEEF7)), colors = listOf(BackgroundColor, CloserPalette.PurpleSoft, CloserPalette.PinkMist),
start = Offset.Zero, start = Offset.Zero,
end = Offset.Infinite end = Offset.Infinite
) )
internal val SettingsInk = Color(0xFF261D2E) internal val SettingsInk = OnBackgroundColor
internal val SettingsMuted = Color(0xFF5A5060) internal val SettingsMuted = OnSurfaceVariantColor
internal val SettingsPrimary = Color(0xFFB98AF4) internal val SettingsPrimary = PrimaryColor
internal val SettingsPrimaryDeep = Color(0xFF56306F) internal val SettingsPrimaryDeep = CloserPalette.PurpleDeep
internal val SettingsOnPrimary = Color(0xFF24122F) internal val SettingsOnPrimary = OnPrimaryColor
internal val SettingsCard = Color.White internal val SettingsCard = Color.White
internal val SettingsSoft = Color(0xFFF4E8FF) internal val SettingsSoft = CloserPalette.PurpleSoft
internal val SettingsDanger = Color(0xFF8D2D35) internal val SettingsDanger = CloserPalette.Danger
@Composable @Composable
internal fun settingsSwitchColors() = SwitchDefaults.colors( internal fun settingsSwitchColors() = SwitchDefaults.colors(

View File

@ -0,0 +1,73 @@
package app.closer.ui.theme
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
object CloserPalette {
val PurpleDeep = Color(0xFF56306F)
val PurpleRich = Color(0xFF8F67C5)
val PurpleSoft = Color(0xFFF4E8FF)
val PurpleMist = Color(0xFFF0EDF9)
val PurpleGlow = Color(0xFFF0DFFF)
val PinkSoft = Color(0xFFFFE8F4)
val PinkMist = Color(0xFFFFEEF7)
val PinkBright = Color(0xFFE7A2D1)
val PinkWheel = Color(0xFFFFC2DD)
val PinkShell = Color(0xFFF7C8E4)
val PinkAccentDeep = Color(0xFF6D2B55)
val Romantic = Color(0xFF9B1B5A)
val Gold = Color(0xFF6A4A00)
val Evergreen = Color(0xFF2F5B4F)
val Danger = Color(0xFF8D2D35)
}
@Composable
fun closerBackgroundBrush(): Brush =
Brush.linearGradient(
colors = listOf(
MaterialTheme.colorScheme.background,
CloserPalette.PurpleSoft,
CloserPalette.PinkMist
),
start = Offset.Zero,
end = Offset.Infinite
)
@Composable
fun closerPlayCardBrush(): Brush =
Brush.linearGradient(
colors = listOf(
MaterialTheme.colorScheme.surface,
MaterialTheme.colorScheme.primaryContainer,
CloserPalette.PinkSoft
),
start = Offset.Zero,
end = Offset.Infinite
)
@Composable
fun closerBrandGlyphBrush(): Brush =
Brush.linearGradient(
colors = listOf(
MaterialTheme.colorScheme.primary,
MaterialTheme.colorScheme.secondary,
CloserPalette.PurpleDeep
),
start = Offset.Zero,
end = Offset.Infinite
)
@Composable
fun closerWheelSegmentColors(): List<Color> = listOf(
MaterialTheme.colorScheme.primary,
CloserPalette.PinkWheel,
MaterialTheme.colorScheme.secondary,
CloserPalette.PurpleGlow,
CloserPalette.PurpleRich,
MaterialTheme.colorScheme.secondaryContainer,
CloserPalette.PurpleDeep,
CloserPalette.PinkShell
)

View File

@ -34,9 +34,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -45,6 +42,8 @@ import androidx.hilt.navigation.compose.hiltViewModel
import app.closer.core.navigation.AppRoute import app.closer.core.navigation.AppRoute
import app.closer.domain.model.QuestionCategory import app.closer.domain.model.QuestionCategory
import app.closer.ui.questions.displayCategoryName import app.closer.ui.questions.displayCategoryName
import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.closerBackgroundBrush
@Composable @Composable
fun CategoryPickerScreen( fun CategoryPickerScreen(
@ -74,13 +73,7 @@ private fun CategoryPickerContent(
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(closerBackgroundBrush())
Brush.linearGradient(
listOf(Color(0xFFFFFBFE), Color(0xFFF8F1FF), Color(0xFFFFEEF7)),
start = Offset.Zero,
end = Offset.Infinite
)
)
) { ) {
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
@ -104,25 +97,38 @@ private fun CategoryPickerContent(
horizontalArrangement = Arrangement.spacedBy(14.dp), horizontalArrangement = Arrangement.spacedBy(14.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
CircularProgressIndicator(color = Color(0xFF56306F)) CircularProgressIndicator(color = CloserPalette.PurpleDeep)
Text("Loading categories…", style = MaterialTheme.typography.bodyMedium, color = Color(0xFF5A5060)) Text(
"Loading categories…",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
} }
} }
state.error != null -> item { state.error != null -> item {
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(22.dp), shape = RoundedCornerShape(22.dp),
colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.84f)) colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.84f))
) { ) {
Column(Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) { Column(Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
Text("Categories unavailable", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold, color = Color(0xFF261D2E)) Text(
Text(state.error, style = MaterialTheme.typography.bodyMedium, color = Color(0xFF5A5060)) "Categories unavailable",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.onSurface
)
Text(
state.error,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Button( Button(
onClick = onRetry, onClick = onRetry,
shape = RoundedCornerShape(16.dp), shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF56306F)) colors = ButtonDefaults.buttonColors(containerColor = CloserPalette.PurpleDeep)
) { ) {
Text("Retry", color = Color.White) Text("Retry", color = MaterialTheme.colorScheme.surface)
} }
} }
} }
@ -158,14 +164,14 @@ private fun WheelPickerHeader(
Text( Text(
text = "Spin the Wheel", text = "Spin the Wheel",
style = MaterialTheme.typography.headlineLarge.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.headlineLarge.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF261D2E), color = MaterialTheme.colorScheme.onBackground,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
Text( Text(
text = "Choose a mood and let chance pick the next conversation.", text = "Choose a mood and let chance pick the next conversation.",
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -175,8 +181,8 @@ private fun WheelPickerHeader(
modifier = Modifier.heightIn(min = 48.dp), modifier = Modifier.heightIn(min = 48.dp),
shape = RoundedCornerShape(999.dp), shape = RoundedCornerShape(999.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = Color.White.copy(alpha = 0.82f), containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.82f),
contentColor = Color(0xFF56306F) contentColor = CloserPalette.PurpleDeep
) )
) { ) {
Text("History") Text("History")
@ -185,7 +191,7 @@ private fun WheelPickerHeader(
Surface( Surface(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(22.dp), shape = RoundedCornerShape(22.dp),
color = Color(0xFFFFF8FC) color = MaterialTheme.colorScheme.surface
) { ) {
Row( Row(
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
@ -194,14 +200,14 @@ private fun WheelPickerHeader(
) { ) {
Surface( Surface(
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = Color(0xFFF0DFFF), color = CloserPalette.PurpleGlow,
modifier = Modifier.size(46.dp) modifier = Modifier.size(46.dp)
) { ) {
Box(contentAlignment = Alignment.Center) { Box(contentAlignment = Alignment.Center) {
Icon( Icon(
imageVector = Icons.Filled.PlayArrow, imageVector = Icons.Filled.PlayArrow,
contentDescription = null, contentDescription = null,
tint = Color(0xFF56306F), tint = CloserPalette.PurpleDeep,
modifier = Modifier.size(24.dp) modifier = Modifier.size(24.dp)
) )
} }
@ -213,14 +219,14 @@ private fun WheelPickerHeader(
Text( Text(
text = "Ten prompts per spin", text = "Ten prompts per spin",
style = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF261D2E), color = MaterialTheme.colorScheme.onSurface,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
Text( Text(
text = "You can skip, continue, or end whenever the moment feels complete.", text = "You can skip, continue, or end whenever the moment feels complete.",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -235,7 +241,7 @@ private fun CategoryCard(
item: CategoryPickerItem, item: CategoryPickerItem,
onClick: () -> Unit onClick: () -> Unit
) { ) {
val containerColor = if (item.isLocked) Color(0xFFFFF8FC) else Color.White val containerColor = if (item.isLocked) MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.4f) else MaterialTheme.colorScheme.surface
Card( Card(
onClick = onClick, onClick = onClick,
@ -253,14 +259,14 @@ private fun CategoryCard(
) { ) {
Surface( Surface(
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = if (item.isLocked) Color(0xFFF0EDF9) else Color(0xFFFFE8F4), color = if (item.isLocked) CloserPalette.PurpleMist else MaterialTheme.colorScheme.secondaryContainer,
modifier = Modifier.size(48.dp) modifier = Modifier.size(48.dp)
) { ) {
Box(contentAlignment = Alignment.Center) { Box(contentAlignment = Alignment.Center) {
Icon( Icon(
imageVector = if (item.isLocked) Icons.Default.Lock else Icons.Filled.Star, imageVector = if (item.isLocked) Icons.Default.Lock else Icons.Filled.Star,
contentDescription = null, contentDescription = null,
tint = if (item.isLocked) Color(0xFF9B8AA6) else Color(0xFF6D2B55), tint = if (item.isLocked) MaterialTheme.colorScheme.outline else CloserPalette.PinkAccentDeep,
modifier = Modifier.size(22.dp) modifier = Modifier.size(22.dp)
) )
} }
@ -275,7 +281,7 @@ private fun CategoryCard(
text = item.category.displayName.ifBlank { item.category.id.displayCategoryName() }, text = item.category.displayName.ifBlank { item.category.id.displayCategoryName() },
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = if (item.isLocked) Color(0xFF9B8AA6) else Color(0xFF261D2E), color = if (item.isLocked) MaterialTheme.colorScheme.outline else MaterialTheme.colorScheme.onSurface,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -287,7 +293,7 @@ private fun CategoryCard(
Icon( Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowForward, imageVector = Icons.AutoMirrored.Filled.ArrowForward,
contentDescription = if (item.isLocked) "Unlock" else "Spin", contentDescription = if (item.isLocked) "Unlock" else "Spin",
tint = if (item.isLocked) Color(0xFF9B8AA6) else Color(0xFF56306F), tint = if (item.isLocked) MaterialTheme.colorScheme.outline else CloserPalette.PurpleDeep,
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
} }
@ -298,14 +304,14 @@ private fun CategoryCard(
private fun CategoryPill(label: String) { private fun CategoryPill(label: String) {
Surface( Surface(
shape = RoundedCornerShape(999.dp), shape = RoundedCornerShape(999.dp),
color = Color(0xFFF0EDF9), color = CloserPalette.PurpleMist,
modifier = Modifier.heightIn(min = 32.dp) modifier = Modifier.heightIn(min = 32.dp)
) { ) {
Text( Text(
text = label, text = label,
modifier = Modifier.padding(horizontal = 10.dp, vertical = 5.dp), modifier = Modifier.padding(horizontal = 10.dp, vertical = 5.dp),
style = MaterialTheme.typography.labelSmall, style = MaterialTheme.typography.labelSmall,
color = Color(0xFF56306F), color = CloserPalette.PurpleDeep,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )

View File

@ -34,8 +34,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
@ -45,6 +43,9 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.closerBackgroundBrush
import app.closer.ui.theme.closerWheelSegmentColors
@Composable @Composable
fun SpinWheelScreen( fun SpinWheelScreen(
@ -88,13 +89,7 @@ private fun SpinWheelContent(
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(closerBackgroundBrush()),
Brush.linearGradient(
listOf(Color(0xFFFFFBFE), Color(0xFFF8F1FF), Color(0xFFFFEEF7)),
start = Offset.Zero,
end = Offset.Infinite
)
),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Column( Column(
@ -113,7 +108,7 @@ private fun SpinWheelContent(
Text( Text(
text = "Let the prompt find you", text = "Let the prompt find you",
style = MaterialTheme.typography.headlineMedium.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.headlineMedium.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF261D2E), color = MaterialTheme.colorScheme.onBackground,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
@ -121,13 +116,13 @@ private fun SpinWheelContent(
if (state.categoryName.isNotBlank()) { if (state.categoryName.isNotBlank()) {
Surface( Surface(
shape = RoundedCornerShape(999.dp), shape = RoundedCornerShape(999.dp),
color = Color(0xFFF0EDF9) color = CloserPalette.PurpleMist
) { ) {
Text( Text(
text = state.categoryName, text = state.categoryName,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
style = MaterialTheme.typography.labelLarge, style = MaterialTheme.typography.labelLarge,
color = Color(0xFF56306F), color = CloserPalette.PurpleDeep,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@ -154,7 +149,7 @@ private fun SpinWheelContent(
state.error != null -> Text( state.error != null -> Text(
text = state.error, text = state.error,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = Color(0xFF8D2D35), color = MaterialTheme.colorScheme.error,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -162,7 +157,7 @@ private fun SpinWheelContent(
Text( Text(
text = "${SpinWheelViewModel.SESSION_SIZE} questions selected", text = "${SpinWheelViewModel.SESSION_SIZE} questions selected",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -172,9 +167,9 @@ private fun SpinWheelContent(
.fillMaxWidth() .fillMaxWidth()
.heightIn(min = 56.dp), .heightIn(min = 56.dp),
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF56306F)) colors = ButtonDefaults.buttonColors(containerColor = CloserPalette.PurpleDeep)
) { ) {
Text("Start session", color = Color.White) Text("Start session", color = MaterialTheme.colorScheme.surface)
} }
OutlinedButton( OutlinedButton(
onClick = onSpin, onClick = onSpin,
@ -186,12 +181,12 @@ private fun SpinWheelContent(
Text("Spin again") Text("Spin again")
} }
} }
state.isLoading -> CircularProgressIndicator(color = Color(0xFF56306F)) state.isLoading -> CircularProgressIndicator(color = CloserPalette.PurpleDeep)
else -> { else -> {
Text( Text(
text = "Tap to select ${SpinWheelViewModel.SESSION_SIZE} questions at random", text = "Tap to select ${SpinWheelViewModel.SESSION_SIZE} questions at random",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = Color(0xFF5A5060), color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
@ -201,9 +196,9 @@ private fun SpinWheelContent(
.fillMaxWidth() .fillMaxWidth()
.heightIn(min = 56.dp), .heightIn(min = 56.dp),
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF56306F)) colors = ButtonDefaults.buttonColors(containerColor = CloserPalette.PurpleDeep)
) { ) {
Text("Spin wheel", color = Color.White) Text("Spin wheel", color = MaterialTheme.colorScheme.surface)
} }
} }
} }
@ -218,16 +213,7 @@ private fun WheelSpinner(
spunAndReady: Boolean, spunAndReady: Boolean,
rotation: Float rotation: Float
) { ) {
val segmentColors = listOf( val segmentColors = closerWheelSegmentColors()
Color(0xFFB98AF4),
Color(0xFFFFC2DD),
Color(0xFFE7A2D1),
Color(0xFFF0DFFF),
Color(0xFF8F67C5),
Color(0xFFFFE8F4),
Color(0xFF56306F),
Color(0xFFF7C8E4)
)
Box( Box(
modifier = Modifier.size(270.dp), modifier = Modifier.size(270.dp),
@ -268,20 +254,20 @@ private fun WheelSpinner(
lineTo(size.width, 0f) lineTo(size.width, 0f)
close() close()
} }
drawPath(path = path, color = Color(0xFF261D2E)) drawPath(path = path, color = CloserPalette.PurpleDeep)
} }
Surface( Surface(
modifier = Modifier.size(94.dp), modifier = Modifier.size(94.dp),
shape = CircleShape, shape = CircleShape,
color = Color.White, color = MaterialTheme.colorScheme.surface,
shadowElevation = 10.dp shadowElevation = 10.dp
) { ) {
Box(contentAlignment = Alignment.Center) { Box(contentAlignment = Alignment.Center) {
Text( Text(
text = if (spunAndReady) "Ready" else "Spin", text = if (spunAndReady) "Ready" else "Spin",
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold), style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.SemiBold),
color = Color(0xFF56306F), color = CloserPalette.PurpleDeep,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis