fix: wire theme switching — replace all hardcoded Amber colors with LocalKaizenAccent
All 7 files that imported Amber/AmberDeep/OnAmber/BlobX now read from LocalKaizenAccent.current instead. Theme switching in settings actually changes the UI now: message bubbles, send button, orb, blobs, sidebar highlights, model sheet, stream blocks, login screen, and settings toggles all respond to the selected theme.
This commit is contained in:
parent
918659422b
commit
d468ec893f
7 changed files with 56 additions and 48 deletions
|
|
@ -49,9 +49,7 @@ import dev.kaizen.app.chat.MeshBackground
|
||||||
import dev.kaizen.app.net.DEFAULT_BASE_URL
|
import dev.kaizen.app.net.DEFAULT_BASE_URL
|
||||||
import dev.kaizen.app.net.LoginResult
|
import dev.kaizen.app.net.LoginResult
|
||||||
import dev.kaizen.app.net.SessionViewModel
|
import dev.kaizen.app.net.SessionViewModel
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
import dev.kaizen.app.ui.theme.AmberDeep
|
|
||||||
import dev.kaizen.app.ui.theme.OnAmber
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import dev.kaizen.app.R
|
import dev.kaizen.app.R
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -65,6 +63,7 @@ import kotlinx.coroutines.launch
|
||||||
@Composable
|
@Composable
|
||||||
fun LoginScreen(session: SessionViewModel, modifier: Modifier = Modifier) {
|
fun LoginScreen(session: SessionViewModel, modifier: Modifier = Modifier) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val ctx = androidx.compose.ui.platform.LocalContext.current
|
val ctx = androidx.compose.ui.platform.LocalContext.current
|
||||||
|
|
||||||
|
|
@ -165,6 +164,7 @@ private fun GlassField(
|
||||||
) {
|
) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
|
|
||||||
val glassBg = if (isDark) {
|
val glassBg = if (isDark) {
|
||||||
Brush.verticalGradient(listOf(Color(0xFF1E293B).copy(alpha = 0.72f), Color(0xFF0F172A).copy(alpha = 0.85f)))
|
Brush.verticalGradient(listOf(Color(0xFF1E293B).copy(alpha = 0.72f), Color(0xFF0F172A).copy(alpha = 0.85f)))
|
||||||
|
|
@ -196,7 +196,7 @@ private fun GlassField(
|
||||||
value = value,
|
value = value,
|
||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
textStyle = TextStyle(color = cs.onBackground, fontSize = 16.sp),
|
textStyle = TextStyle(color = cs.onBackground, fontSize = 16.sp),
|
||||||
cursorBrush = SolidColor(Amber),
|
cursorBrush = SolidColor(accent.primary),
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
visualTransformation = if (password) PasswordVisualTransformation() else androidx.compose.ui.text.input.VisualTransformation.None,
|
visualTransformation = if (password) PasswordVisualTransformation() else androidx.compose.ui.text.input.VisualTransformation.None,
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = keyboardType, imeAction = imeAction),
|
keyboardOptions = KeyboardOptions(keyboardType = keyboardType, imeAction = imeAction),
|
||||||
|
|
@ -209,8 +209,9 @@ private fun GlassField(
|
||||||
@Composable
|
@Composable
|
||||||
private fun SignInButton(enabled: Boolean, loading: Boolean, onClick: () -> Unit) {
|
private fun SignInButton(enabled: Boolean, loading: Boolean, onClick: () -> Unit) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val fill = if (enabled || loading) {
|
val fill = if (enabled || loading) {
|
||||||
Modifier.background(Brush.linearGradient(listOf(Amber, AmberDeep)))
|
Modifier.background(Brush.linearGradient(listOf(accent.primary, accent.primaryDeep)))
|
||||||
} else {
|
} else {
|
||||||
Modifier.background(cs.surface)
|
Modifier.background(cs.surface)
|
||||||
}
|
}
|
||||||
|
|
@ -227,11 +228,11 @@ private fun SignInButton(enabled: Boolean, loading: Boolean, onClick: () -> Unit
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
CircularProgressIndicator(color = OnAmber, strokeWidth = 2.4.dp, modifier = Modifier.size(22.dp))
|
CircularProgressIndicator(color = accent.onPrimary, strokeWidth = 2.4.dp, modifier = Modifier.size(22.dp))
|
||||||
} else {
|
} else {
|
||||||
Text(
|
Text(
|
||||||
stringResource(R.string.login_submit),
|
stringResource(R.string.login_submit),
|
||||||
color = if (enabled) OnAmber else cs.onSurfaceVariant,
|
color = if (enabled) accent.onPrimary else cs.onSurfaceVariant,
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.SemiBold,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,7 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import dev.kaizen.app.ui.motion.Durations
|
import dev.kaizen.app.ui.motion.Durations
|
||||||
import dev.kaizen.app.ui.sensor.rememberTiltState
|
import dev.kaizen.app.ui.sensor.rememberTiltState
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
import dev.kaizen.app.ui.theme.AmberDeep
|
|
||||||
import dev.kaizen.app.ui.theme.BlobAmber
|
|
||||||
import dev.kaizen.app.ui.theme.BlobCoral
|
|
||||||
import dev.kaizen.app.ui.theme.BlobTeal
|
|
||||||
import dev.kaizen.app.ui.theme.DITHER_ALPHA
|
import dev.kaizen.app.ui.theme.DITHER_ALPHA
|
||||||
import dev.kaizen.app.ui.theme.rememberDitherBrush
|
import dev.kaizen.app.ui.theme.rememberDitherBrush
|
||||||
|
|
||||||
|
|
@ -47,6 +43,7 @@ import dev.kaizen.app.ui.theme.rememberDitherBrush
|
||||||
@Composable
|
@Composable
|
||||||
fun MeshBackground(content: @Composable BoxScope.() -> Unit) {
|
fun MeshBackground(content: @Composable BoxScope.() -> Unit) {
|
||||||
val dark = isSystemInDarkTheme()
|
val dark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val base = MaterialTheme.colorScheme.background
|
val base = MaterialTheme.colorScheme.background
|
||||||
// Blobs are subtler in light mode.
|
// Blobs are subtler in light mode.
|
||||||
val factor = if (dark) 1f else 0.55f
|
val factor = if (dark) 1f else 0.55f
|
||||||
|
|
@ -68,9 +65,9 @@ fun MeshBackground(content: @Composable BoxScope.() -> Unit) {
|
||||||
drawRect(brush = ditherBrush, alpha = DITHER_ALPHA)
|
drawRect(brush = ditherBrush, alpha = DITHER_ALPHA)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Blob(BlobAmber, 360.dp, (-60f + drift * 30f).dp, (-40f + drift * 24f).dp, 0.30f * factor)
|
Blob(accent.blob1, 360.dp, (-60f + drift * 30f).dp, (-40f + drift * 24f).dp, 0.30f * factor)
|
||||||
Blob(BlobCoral, 380.dp, (170f - drift * 44f).dp, (150f + drift * 40f).dp, 0.24f * factor)
|
Blob(accent.blob2, 380.dp, (170f - drift * 44f).dp, (150f + drift * 40f).dp, 0.24f * factor)
|
||||||
Blob(BlobTeal, 300.dp, (30f + drift * 50f).dp, (560f - drift * 36f).dp, 0.22f * factor)
|
Blob(accent.blob4, 300.dp, (30f + drift * 50f).dp, (560f - drift * 36f).dp, 0.22f * factor)
|
||||||
// Vignette: darken the edges so the center comes forward (dark mode only).
|
// Vignette: darken the edges so the center comes forward (dark mode only).
|
||||||
if (dark) {
|
if (dark) {
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -113,6 +110,7 @@ fun KaizenOrb(
|
||||||
amplitude: Float? = null
|
amplitude: Float? = null
|
||||||
) {
|
) {
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val transition = rememberInfiniteTransition(label = "orb")
|
val transition = rememberInfiniteTransition(label = "orb")
|
||||||
|
|
||||||
// Slow breathing loop (7s for idle, 2.4s fast breath for streaming/recording thinking)
|
// Slow breathing loop (7s for idle, 2.4s fast breath for streaming/recording thinking)
|
||||||
|
|
@ -151,7 +149,7 @@ fun KaizenOrb(
|
||||||
colors = if (recording) {
|
colors = if (recording) {
|
||||||
listOf(Color(0xFFE0A23E).copy(alpha = 0.45f), Color.Transparent)
|
listOf(Color(0xFFE0A23E).copy(alpha = 0.45f), Color.Transparent)
|
||||||
} else {
|
} else {
|
||||||
listOf(Amber.copy(alpha = if (streaming) 0.55f else 0.32f), Color.Transparent)
|
listOf(accent.primary.copy(alpha = if (streaming) 0.55f else 0.32f), Color.Transparent)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
CircleShape,
|
CircleShape,
|
||||||
|
|
@ -179,7 +177,7 @@ fun KaizenOrb(
|
||||||
colorStops = arrayOf(
|
colorStops = arrayOf(
|
||||||
0.0f to Color(0xFFFFF1D6), // Ultra bright glowing cream-white core
|
0.0f to Color(0xFFFFF1D6), // Ultra bright glowing cream-white core
|
||||||
0.35f to Color(0xFFFFCC80), // Rich luminous warm amber
|
0.35f to Color(0xFFFFCC80), // Rich luminous warm amber
|
||||||
0.75f to AmberDeep, // Saturated golden amber
|
0.75f to accent.primaryDeep, // Saturated accent
|
||||||
1.0f to Color(0xFF8D4F00) // Deep bronze-amber shadow edge (creates high contrast!)
|
1.0f to Color(0xFF8D4F00) // Deep bronze-amber shadow edge (creates high contrast!)
|
||||||
),
|
),
|
||||||
center = baseGradientCenter,
|
center = baseGradientCenter,
|
||||||
|
|
@ -210,10 +208,10 @@ fun KaizenOrb(
|
||||||
val sweepBrush1 = Brush.sweepGradient(
|
val sweepBrush1 = Brush.sweepGradient(
|
||||||
colorStops = arrayOf(
|
colorStops = arrayOf(
|
||||||
0.0f to Color.Transparent,
|
0.0f to Color.Transparent,
|
||||||
0.16f to Amber.copy(alpha = 0.65f),
|
0.16f to accent.primary.copy(alpha = 0.65f),
|
||||||
0.33f to Color.White.copy(alpha = 0.55f),
|
0.33f to Color.White.copy(alpha = 0.55f),
|
||||||
0.50f to Color.Transparent,
|
0.50f to Color.Transparent,
|
||||||
0.66f to AmberDeep.copy(alpha = 0.50f),
|
0.66f to accent.primaryDeep.copy(alpha = 0.50f),
|
||||||
1.0f to Color.Transparent
|
1.0f to Color.Transparent
|
||||||
),
|
),
|
||||||
center = coreCenter
|
center = coreCenter
|
||||||
|
|
@ -230,7 +228,7 @@ fun KaizenOrb(
|
||||||
0.0f to Color.Transparent,
|
0.0f to Color.Transparent,
|
||||||
0.25f to Color.White.copy(alpha = 0.40f),
|
0.25f to Color.White.copy(alpha = 0.40f),
|
||||||
0.50f to Color.Transparent,
|
0.50f to Color.Transparent,
|
||||||
0.75f to Amber.copy(alpha = 0.50f),
|
0.75f to accent.primary.copy(alpha = 0.50f),
|
||||||
1.0f to Color.Transparent
|
1.0f to Color.Transparent
|
||||||
),
|
),
|
||||||
center = coreCenter
|
center = coreCenter
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ import dev.kaizen.app.ui.effect.GlassTiers
|
||||||
import dev.kaizen.app.ui.effect.KaizenShadows
|
import dev.kaizen.app.ui.effect.KaizenShadows
|
||||||
import dev.kaizen.app.ui.motion.Durations
|
import dev.kaizen.app.ui.motion.Durations
|
||||||
import dev.kaizen.app.ui.shape.KaizenShapes
|
import dev.kaizen.app.ui.shape.KaizenShapes
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
import dev.kaizen.app.ui.theme.AmberDeep
|
|
||||||
import dev.kaizen.app.ui.theme.OnAmber
|
|
||||||
import dev.kaizen.app.R
|
import dev.kaizen.app.R
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
@ -189,13 +187,14 @@ fun ModePillsRow(selected: Set<Int>, onToggle: (Int) -> Unit, modifier: Modifier
|
||||||
fun MessageRow(message: Message) {
|
fun MessageRow(message: Message) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val hasAttachments = message.attachments.isNotEmpty()
|
val hasAttachments = message.attachments.isNotEmpty()
|
||||||
|
|
||||||
if (message.role == Role.User) {
|
if (message.role == Role.User) {
|
||||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
||||||
val shape = KaizenShapes.lg
|
val shape = KaizenShapes.lg
|
||||||
val borderBrush = remember { Brush.verticalGradient(listOf(Amber.copy(alpha = 0.45f), AmberDeep.copy(alpha = 0.15f))) }
|
val borderBrush = remember(accent) { Brush.verticalGradient(listOf(accent.primary.copy(alpha = 0.45f), accent.primaryDeep.copy(alpha = 0.15f))) }
|
||||||
val bgBrush = remember { Brush.verticalGradient(listOf(Amber.copy(alpha = 0.18f), AmberDeep.copy(alpha = 0.08f))) }
|
val bgBrush = remember(accent) { Brush.verticalGradient(listOf(accent.primary.copy(alpha = 0.18f), accent.primaryDeep.copy(alpha = 0.08f))) }
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
|
|
@ -312,10 +311,11 @@ fun ChatInput(
|
||||||
}
|
}
|
||||||
Box(Modifier.weight(1f).heightIn(min = 36.dp).padding(horizontal = 4.dp), contentAlignment = Alignment.CenterStart) {
|
Box(Modifier.weight(1f).heightIn(min = 36.dp).padding(horizontal = 4.dp), contentAlignment = Alignment.CenterStart) {
|
||||||
if (value.isEmpty()) Text(stringResource(R.string.chat_input_placeholder), color = cs.onSurfaceVariant, fontSize = 16.sp)
|
if (value.isEmpty()) Text(stringResource(R.string.chat_input_placeholder), color = cs.onSurfaceVariant, fontSize = 16.sp)
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
BasicTextField(
|
BasicTextField(
|
||||||
value = value, onValueChange = onValueChange,
|
value = value, onValueChange = onValueChange,
|
||||||
textStyle = TextStyle(color = cs.onBackground, fontSize = 16.sp, lineHeight = 22.sp),
|
textStyle = TextStyle(color = cs.onBackground, fontSize = 16.sp, lineHeight = 22.sp),
|
||||||
cursorBrush = SolidColor(Amber), maxLines = 6, modifier = Modifier.fillMaxWidth(),
|
cursorBrush = SolidColor(accent.primary), maxLines = 6, modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GhostIconButton(Icons.Rounded.Call, "Anruf")
|
GhostIconButton(Icons.Rounded.Call, "Anruf")
|
||||||
|
|
@ -383,7 +383,8 @@ private fun SendButton(enabled: Boolean, onClick: () -> Unit) {
|
||||||
val interaction = remember { MutableInteractionSource() }
|
val interaction = remember { MutableInteractionSource() }
|
||||||
val pressed by interaction.collectIsPressedAsState()
|
val pressed by interaction.collectIsPressedAsState()
|
||||||
val pressScale by animateFloatAsState(if (pressed) 0.86f else 1f, label = "send")
|
val pressScale by animateFloatAsState(if (pressed) 0.86f else 1f, label = "send")
|
||||||
val fill = if (enabled) Modifier.background(Brush.linearGradient(listOf(Amber, AmberDeep)))
|
val accent = LocalKaizenAccent.current
|
||||||
|
val fill = if (enabled) Modifier.background(Brush.linearGradient(listOf(accent.primary, accent.primaryDeep)))
|
||||||
else Modifier.background(cs.surface)
|
else Modifier.background(cs.surface)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -392,7 +393,7 @@ private fun SendButton(enabled: Boolean, onClick: () -> Unit) {
|
||||||
.clickable(interactionSource = interaction, indication = null, enabled = enabled, onClick = onClick),
|
.clickable(interactionSource = interaction, indication = null, enabled = enabled, onClick = onClick),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
SendArrow(color = if (enabled) OnAmber else cs.onSurfaceVariant)
|
SendArrow(color = if (enabled) accent.onPrimary else cs.onSurfaceVariant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import dev.kaizen.app.net.KaizenModel
|
import dev.kaizen.app.net.KaizenModel
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
import dev.kaizen.app.haptics.rememberHaptics
|
import dev.kaizen.app.haptics.rememberHaptics
|
||||||
|
|
||||||
/** Human label + composite-id resolver for the top pill — falls back to a de-prefixed id. */
|
/** Human label + composite-id resolver for the top pill — falls back to a de-prefixed id. */
|
||||||
|
|
@ -32,6 +32,7 @@ fun modelDisplayName(modelId: String, models: List<KaizenModel>): String =
|
||||||
@Composable
|
@Composable
|
||||||
fun ModelPill(label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
fun ModelPill(label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clip(KaizenShapes.xl)
|
.clip(KaizenShapes.xl)
|
||||||
|
|
@ -108,6 +109,7 @@ fun ModelSheet(
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||||
var query by remember { mutableStateOf("") }
|
var query by remember { mutableStateOf("") }
|
||||||
val groups = remember(models, favorites, query) { buildGroups(models, favorites, query) }
|
val groups = remember(models, favorites, query) { buildGroups(models, favorites, query) }
|
||||||
|
|
@ -152,7 +154,7 @@ fun ModelSheet(
|
||||||
value = query,
|
value = query,
|
||||||
onValueChange = { query = it },
|
onValueChange = { query = it },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
cursorBrush = SolidColor(Amber),
|
cursorBrush = SolidColor(accent.primary),
|
||||||
textStyle = androidx.compose.ui.text.TextStyle(
|
textStyle = androidx.compose.ui.text.TextStyle(
|
||||||
color = cs.onBackground,
|
color = cs.onBackground,
|
||||||
fontSize = 14.sp
|
fontSize = 14.sp
|
||||||
|
|
@ -221,6 +223,7 @@ private fun ModelRow(
|
||||||
onToggleFavorite: () -> Unit,
|
onToggleFavorite: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val haptics = rememberHaptics()
|
val haptics = rememberHaptics()
|
||||||
val providerInfo = remember(model.id, model.provider) { getProviderInfo(model.id, model.provider) }
|
val providerInfo = remember(model.id, model.provider) { getProviderInfo(model.id, model.provider) }
|
||||||
|
|
||||||
|
|
@ -231,14 +234,14 @@ private fun ModelRow(
|
||||||
.clip(KaizenShapes.md)
|
.clip(KaizenShapes.md)
|
||||||
.background(
|
.background(
|
||||||
if (selected) {
|
if (selected) {
|
||||||
Amber.copy(alpha = 0.08f)
|
accent.primary.copy(alpha = 0.08f)
|
||||||
} else {
|
} else {
|
||||||
cs.surfaceVariant.copy(alpha = 0.15f)
|
cs.surfaceVariant.copy(alpha = 0.15f)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.border(
|
.border(
|
||||||
width = 1.dp,
|
width = 1.dp,
|
||||||
color = if (selected) Amber.copy(alpha = 0.25f) else Color.Transparent,
|
color = if (selected) accent.primary.copy(alpha = 0.25f) else Color.Transparent,
|
||||||
shape = KaizenShapes.md
|
shape = KaizenShapes.md
|
||||||
)
|
)
|
||||||
.clickable { haptics.tick(); onClick() }
|
.clickable { haptics.tick(); onClick() }
|
||||||
|
|
@ -290,7 +293,7 @@ private fun ModelRow(
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = if (favorite) Icons.Rounded.Star else Icons.Rounded.StarBorder,
|
imageVector = if (favorite) Icons.Rounded.Star else Icons.Rounded.StarBorder,
|
||||||
contentDescription = "Favorit",
|
contentDescription = "Favorit",
|
||||||
tint = if (favorite) Amber else cs.onSurfaceVariant.copy(alpha = 0.35f),
|
tint = if (favorite) accent.primary else cs.onSurfaceVariant.copy(alpha = 0.35f),
|
||||||
modifier = Modifier.size(20.dp),
|
modifier = Modifier.size(20.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -300,7 +303,7 @@ private fun ModelRow(
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Rounded.Check,
|
Icons.Rounded.Check,
|
||||||
contentDescription = "Ausgewählt",
|
contentDescription = "Ausgewählt",
|
||||||
tint = Amber,
|
tint = accent.primary,
|
||||||
modifier = Modifier.size(20.dp)
|
modifier = Modifier.size(20.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ import dev.kaizen.app.ui.effect.GlassTiers
|
||||||
import dev.kaizen.app.ui.effect.KaizenShadows
|
import dev.kaizen.app.ui.effect.KaizenShadows
|
||||||
import dev.kaizen.app.ui.shape.KaizenShapes
|
import dev.kaizen.app.ui.shape.KaizenShapes
|
||||||
import dev.kaizen.app.R
|
import dev.kaizen.app.R
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
|
@ -243,14 +243,15 @@ fun KaizenSidebar(
|
||||||
private fun HistoryItemRow(item: ConversationSummary, selected: Boolean, onClick: () -> Unit) {
|
private fun HistoryItemRow(item: ConversationSummary, selected: Boolean, onClick: () -> Unit) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
|
|
||||||
val itemBg = when {
|
val itemBg = when {
|
||||||
selected -> Amber.copy(alpha = 0.14f)
|
selected -> accent.primary.copy(alpha = 0.14f)
|
||||||
isDark -> Color(0x0AFFFFFF)
|
isDark -> Color(0x0AFFFFFF)
|
||||||
else -> Color(0x05000000)
|
else -> Color(0x05000000)
|
||||||
}
|
}
|
||||||
val itemBorder = when {
|
val itemBorder = when {
|
||||||
selected -> Amber.copy(alpha = 0.35f)
|
selected -> accent.primary.copy(alpha = 0.35f)
|
||||||
isDark -> Color.White.copy(alpha = 0.04f)
|
isDark -> Color.White.copy(alpha = 0.04f)
|
||||||
else -> Color.Black.copy(alpha = 0.03f)
|
else -> Color.Black.copy(alpha = 0.03f)
|
||||||
}
|
}
|
||||||
|
|
@ -266,7 +267,7 @@ private fun HistoryItemRow(item: ConversationSummary, selected: Boolean, onClick
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
if (item.pinned) {
|
if (item.pinned) {
|
||||||
Icon(Icons.Rounded.Star, null, tint = Amber, modifier = Modifier.size(14.dp))
|
Icon(Icons.Rounded.Star, null, tint = accent.primary, modifier = Modifier.size(14.dp))
|
||||||
Spacer(Modifier.width(8.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -279,7 +280,7 @@ private fun HistoryItemRow(item: ConversationSummary, selected: Boolean, onClick
|
||||||
)
|
)
|
||||||
if (item.locked) {
|
if (item.locked) {
|
||||||
Spacer(Modifier.width(8.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
Icon(Icons.Rounded.Lock, stringResource(R.string.chat_locked_badge), tint = Amber, modifier = Modifier.size(15.dp))
|
Icon(Icons.Rounded.Lock, stringResource(R.string.chat_locked_badge), tint = accent.primary, modifier = Modifier.size(15.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,13 @@ import androidx.compose.ui.unit.sp
|
||||||
import dev.kaizen.app.net.SearchSource
|
import dev.kaizen.app.net.SearchSource
|
||||||
import dev.kaizen.app.net.ToolEvent
|
import dev.kaizen.app.net.ToolEvent
|
||||||
import dev.kaizen.app.ui.shape.KaizenShapes
|
import dev.kaizen.app.ui.shape.KaizenShapes
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ReasoningBlock(reasoning: String, streaming: Boolean = false) {
|
fun ReasoningBlock(reasoning: String, streaming: Boolean = false) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
var expanded by remember { mutableStateOf(streaming) }
|
var expanded by remember { mutableStateOf(streaming) }
|
||||||
|
|
||||||
val bg = if (isDark) Color.White.copy(alpha = 0.05f) else Color.Black.copy(alpha = 0.03f)
|
val bg = if (isDark) Color.White.copy(alpha = 0.05f) else Color.Black.copy(alpha = 0.03f)
|
||||||
|
|
@ -71,7 +72,7 @@ fun ReasoningBlock(reasoning: String, streaming: Boolean = false) {
|
||||||
.padding(horizontal = 12.dp, vertical = 8.dp),
|
.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Rounded.Psychology, null, tint = Amber, modifier = Modifier.size(16.dp))
|
Icon(Icons.Rounded.Psychology, null, tint = accent.primary, modifier = Modifier.size(16.dp))
|
||||||
Spacer(Modifier.width(8.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
Text(
|
Text(
|
||||||
"Gedankengang",
|
"Gedankengang",
|
||||||
|
|
@ -101,6 +102,7 @@ fun ReasoningBlock(reasoning: String, streaming: Boolean = false) {
|
||||||
fun ToolEventsBlock(tools: List<ToolEvent>, streaming: Boolean = false) {
|
fun ToolEventsBlock(tools: List<ToolEvent>, streaming: Boolean = false) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
val bg = if (isDark) Color.White.copy(alpha = 0.04f) else Color.Black.copy(alpha = 0.02f)
|
val bg = if (isDark) Color.White.copy(alpha = 0.04f) else Color.Black.copy(alpha = 0.02f)
|
||||||
val borderColor = if (isDark) Color.White.copy(alpha = 0.06f) else Color.Black.copy(alpha = 0.04f)
|
val borderColor = if (isDark) Color.White.copy(alpha = 0.06f) else Color.Black.copy(alpha = 0.04f)
|
||||||
|
|
||||||
|
|
@ -123,7 +125,7 @@ fun ToolEventsBlock(tools: List<ToolEvent>, streaming: Boolean = false) {
|
||||||
val tint = when (tool.type) {
|
val tint = when (tool.type) {
|
||||||
"end" -> Color(0xFF10B981)
|
"end" -> Color(0xFF10B981)
|
||||||
"error" -> Color(0xFFEF4444)
|
"error" -> Color(0xFFEF4444)
|
||||||
else -> Amber
|
else -> accent.primary
|
||||||
}
|
}
|
||||||
Icon(icon, null, tint = tint, modifier = Modifier.size(14.dp))
|
Icon(icon, null, tint = tint, modifier = Modifier.size(14.dp))
|
||||||
Spacer(Modifier.width(8.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,7 @@ import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import dev.kaizen.app.ui.theme.Amber
|
import dev.kaizen.app.ui.theme.LocalKaizenAccent
|
||||||
import dev.kaizen.app.ui.theme.AmberDeep
|
|
||||||
import dev.kaizen.app.ui.theme.Oklab
|
import dev.kaizen.app.ui.theme.Oklab
|
||||||
import dev.kaizen.app.ui.theme.themes.KaizenThemeId
|
import dev.kaizen.app.ui.theme.themes.KaizenThemeId
|
||||||
|
|
||||||
|
|
@ -159,6 +158,7 @@ fun SettingsInputCapsule(
|
||||||
) {
|
) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
|
|
||||||
val inputGlassBg = if (isDark) Color(0x12FFFFFF) else Color(0x06000000)
|
val inputGlassBg = if (isDark) Color(0x12FFFFFF) else Color(0x06000000)
|
||||||
val inputGlassBorder = if (isDark) Color.White.copy(alpha = 0.06f) else Color.Black.copy(alpha = 0.04f)
|
val inputGlassBorder = if (isDark) Color.White.copy(alpha = 0.06f) else Color.Black.copy(alpha = 0.04f)
|
||||||
|
|
@ -180,7 +180,7 @@ fun SettingsInputCapsule(
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Medium
|
fontWeight = FontWeight.Medium
|
||||||
),
|
),
|
||||||
cursorBrush = SolidColor(Amber),
|
cursorBrush = SolidColor(accent.primary),
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
|
|
@ -196,6 +196,7 @@ fun ThemeOptionPill(
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
|
|
||||||
// Exact OKLCH brand stops sourced directly from amber.css, blue.css, aurora.css, and mono.css
|
// Exact OKLCH brand stops sourced directly from amber.css, blue.css, aurora.css, and mono.css
|
||||||
val (colorStart, colorEnd) = remember(themeId, isDark) {
|
val (colorStart, colorEnd) = remember(themeId, isDark) {
|
||||||
|
|
@ -231,7 +232,7 @@ fun ThemeOptionPill(
|
||||||
.border(
|
.border(
|
||||||
width = if (selected) 2.5.dp else 1.2.dp,
|
width = if (selected) 2.5.dp else 1.2.dp,
|
||||||
brush = if (selected) {
|
brush = if (selected) {
|
||||||
Brush.verticalGradient(listOf(Amber, AmberDeep))
|
Brush.verticalGradient(listOf(accent.primary, accent.primaryDeep))
|
||||||
} else {
|
} else {
|
||||||
Brush.verticalGradient(listOf(Color.White.copy(alpha = 0.35f), Color.White.copy(alpha = 0.05f)))
|
Brush.verticalGradient(listOf(Color.White.copy(alpha = 0.35f), Color.White.copy(alpha = 0.05f)))
|
||||||
},
|
},
|
||||||
|
|
@ -269,6 +270,7 @@ fun AppearanceTogglePill(
|
||||||
) {
|
) {
|
||||||
val cs = MaterialTheme.colorScheme
|
val cs = MaterialTheme.colorScheme
|
||||||
val isDark = isSystemInDarkTheme()
|
val isDark = isSystemInDarkTheme()
|
||||||
|
val accent = LocalKaizenAccent.current
|
||||||
|
|
||||||
val glassBorder = remember(isDark) {
|
val glassBorder = remember(isDark) {
|
||||||
if (isDark) {
|
if (isDark) {
|
||||||
|
|
@ -284,7 +286,7 @@ fun AppearanceTogglePill(
|
||||||
.clip(KaizenShapes.circle)
|
.clip(KaizenShapes.circle)
|
||||||
.background(
|
.background(
|
||||||
if (selected) {
|
if (selected) {
|
||||||
Amber.copy(alpha = 0.16f)
|
accent.primary.copy(alpha = 0.16f)
|
||||||
} else {
|
} else {
|
||||||
if (isDark) Color(0x0AFFFFFF) else Color(0x82FFFFFF)
|
if (isDark) Color(0x0AFFFFFF) else Color(0x82FFFFFF)
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +294,7 @@ fun AppearanceTogglePill(
|
||||||
.border(
|
.border(
|
||||||
width = if (selected) 1.5.dp else 1.dp,
|
width = if (selected) 1.5.dp else 1.dp,
|
||||||
brush = if (selected) {
|
brush = if (selected) {
|
||||||
Brush.verticalGradient(listOf(Amber.copy(alpha = 0.50f), Amber.copy(alpha = 0.15f)))
|
Brush.verticalGradient(listOf(accent.primary.copy(alpha = 0.50f), accent.primary.copy(alpha = 0.15f)))
|
||||||
} else {
|
} else {
|
||||||
glassBorder
|
glassBorder
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue