diff --git a/app/src/main/java/com/olavbg/javazone/ui/components/AnimatedDiagonalBackground.kt b/app/src/main/java/com/olavbg/javazone/ui/components/AnimatedDiagonalBackground.kt new file mode 100644 index 0000000..f1e38e0 --- /dev/null +++ b/app/src/main/java/com/olavbg/javazone/ui/components/AnimatedDiagonalBackground.kt @@ -0,0 +1,71 @@ +package com.olavbg.javazone.ui.components + +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.clipPath + +/** + * Subtle JavaZone background: two calm tones separated by a slowly moving diagonal. + * Kept deliberately low contrast so foreground content remains the visual priority. + */ +@Composable +fun AnimatedDiagonalBackground( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + val transition = rememberInfiniteTransition(label = "diagonal-background") + val sway by transition.animateFloat( + initialValue = -0.08f, + targetValue = 0.08f, + animationSpec = infiniteRepeatable( + animation = tween(durationMillis = 9000), + repeatMode = RepeatMode.Reverse, + ), + label = "diagonal-sway", + ) + + val firstTone = MaterialTheme.colorScheme.surfaceContainerLowest + val secondTone = MaterialTheme.colorScheme.surfaceContainerLow + + Box(modifier = modifier) { + Canvas(modifier = Modifier.fillMaxSize()) { + val diagonalX = size.width * (0.52f + sway) + + val firstPath = Path().apply { + moveTo(0f, 0f) + lineTo(diagonalX, 0f) + lineTo(0f, size.height) + close() + } + clipPath(firstPath) { + drawRect(color = firstTone) + } + + val secondPath = Path().apply { + moveTo(diagonalX, 0f) + lineTo(size.width, 0f) + lineTo(size.width, size.height) + lineTo(0f, size.height) + close() + } + clipPath(secondPath) { + drawRect(color = secondTone) + } + } + + Box(modifier = Modifier.fillMaxSize()) { + content() + } + } +} diff --git a/app/src/main/java/com/olavbg/javazone/ui/theme/Color.kt b/app/src/main/java/com/olavbg/javazone/ui/theme/Color.kt index c573398..a114103 100644 --- a/app/src/main/java/com/olavbg/javazone/ui/theme/Color.kt +++ b/app/src/main/java/com/olavbg/javazone/ui/theme/Color.kt @@ -2,27 +2,33 @@ package com.olavbg.javazone.ui.theme import androidx.compose.ui.graphics.Color -val FreshGreen = Color(0xFF00E676) -val DeepBlue = Color(0xFF1E3A8A) -val DarkBackground = Color(0xFF0F172A) // Rich slate navy background -val DarkSurface = Color(0xFF1E293B) // Elevated slate card surface -val DarkSurfaceVariant = Color(0xFF334155) // Border/Header variant -val DarkOnSurface = Color(0xFFF8FAFC) +// JavaZone palette: muted pastels over calm, dark neutrals. +val FreshGreen = Color(0xFF9DB8A5) +val DeepBlue = Color(0xFF667B9B) +val DarkBackground = Color(0xFF17191E) +val DarkSurface = Color(0xE6202329) // Slight translucency lets the diagonal identity show through. +val DarkSurfaceVariant = Color(0xD930343C) +val DarkOnSurface = Color(0xFFF1F0ED) -val JavaBlue = Color(0xFF2563EB) -val JavaOrange = Color(0xFFF97316) +val JavaBlue = Color(0xFF8FA9C7) +val JavaOrange = Color(0xFFD2A39A) -val WorkshopPurple = Color(0xFFA855F7) -val LightningAmber = Color(0xFFF59E0B) -val PresentationBlue = Color(0xFF60A5FA) // Lighter blue for better contrast +val WorkshopPurple = Color(0xFFB2A1C7) +val LightningAmber = Color(0xFFD1B17D) +val PresentationBlue = Color(0xFF8FA9C7) val RoomAccentColors = listOf( - Color(0xFF38BDF8), - Color(0xFF34D399), - Color(0xFFFB923C), - Color(0xFFE879F9), - Color(0xFFF87171), - Color(0xFF4ADE80), - Color(0xFFFBBF24), - Color(0xFF60A5FA) + Color(0xFF8FA9C7), + Color(0xFF9DB8A5), + Color(0xFFD2A39A), + Color(0xFFB2A1C7), + Color(0xFFC59A9A), + Color(0xFFA7B99A), + Color(0xFFD0B783), + Color(0xFF9AA9BD) ) + +val LightBackground = Color(0xFFF2F0EC) +val LightSurface = Color(0xEAFAF9F6) +val LightSurfaceVariant = Color(0xDDE3E1DD) +val LightOnSurface = Color(0xFF202228) diff --git a/app/src/main/java/com/olavbg/javazone/ui/theme/Shape.kt b/app/src/main/java/com/olavbg/javazone/ui/theme/Shape.kt index 5911913..e71e977 100644 --- a/app/src/main/java/com/olavbg/javazone/ui/theme/Shape.kt +++ b/app/src/main/java/com/olavbg/javazone/ui/theme/Shape.kt @@ -4,9 +4,10 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Shapes import androidx.compose.ui.unit.dp +// More restrained geometry: cleaner and straighter than the previous expressive radii. val Shapes = Shapes( - small = RoundedCornerShape(8.dp), - medium = RoundedCornerShape(16.dp), - large = RoundedCornerShape(24.dp), - extraLarge = RoundedCornerShape(32.dp) + small = RoundedCornerShape(6.dp), + medium = RoundedCornerShape(10.dp), + large = RoundedCornerShape(14.dp), + extraLarge = RoundedCornerShape(18.dp) ) diff --git a/app/src/main/java/com/olavbg/javazone/ui/theme/Theme.kt b/app/src/main/java/com/olavbg/javazone/ui/theme/Theme.kt index 4123ae0..c100170 100644 --- a/app/src/main/java/com/olavbg/javazone/ui/theme/Theme.kt +++ b/app/src/main/java/com/olavbg/javazone/ui/theme/Theme.kt @@ -10,39 +10,48 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import com.olavbg.javazone.ui.components.AnimatedDiagonalBackground private val DarkColorScheme = darkColorScheme( primary = FreshGreen, secondary = JavaBlue, tertiary = JavaOrange, - background = DarkBackground, + background = Color.Transparent, surface = DarkSurface, - onPrimary = Color.Black, - onSecondary = Color.White, - onTertiary = Color.Black, + surfaceContainerLowest = Color(0xFF15171B), + surfaceContainerLow = Color(0xFF1B1E23), + surfaceContainer = DarkSurface, + surfaceContainerHigh = Color(0xFF282C33), + onPrimary = Color(0xFF17201A), + onSecondary = Color(0xFF17202A), + onTertiary = Color(0xFF271A18), onBackground = DarkOnSurface, onSurface = DarkOnSurface, surfaceVariant = DarkSurfaceVariant, - onSurfaceVariant = Color(0xFF94A3B8), - secondaryContainer = Color(0xFF1E3A8A), - onSecondaryContainer = Color(0xFFDBEAFE), + onSurfaceVariant = Color(0xFFB7B9BD), + secondaryContainer = Color(0xFF344253), + onSecondaryContainer = Color(0xFFDCE5EF), ) private val LightColorScheme = lightColorScheme( - primary = DeepBlue, - secondary = FreshGreen, - tertiary = JavaOrange, - background = Color(0xFFF1F5F9), - surface = Color.White, + primary = Color(0xFF536B5B), + secondary = Color(0xFF58718F), + tertiary = Color(0xFF986B62), + background = Color.Transparent, + surface = LightSurface, + surfaceContainerLowest = Color(0xFFECEAE5), + surfaceContainerLow = Color(0xFFF0EEE9), + surfaceContainer = LightSurface, + surfaceContainerHigh = Color(0xFFE7E5E0), onPrimary = Color.White, - onSecondary = Color.Black, - onTertiary = Color.Black, - onBackground = Color(0xFF0F172A), - onSurface = Color(0xFF0F172A), - surfaceVariant = Color(0xFFE2E8F0), - onSurfaceVariant = Color(0xFF64748B), - secondaryContainer = Color(0xFFDBEAFE), - onSecondaryContainer = Color(0xFF1E3A8A), + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = LightOnSurface, + onSurface = LightOnSurface, + surfaceVariant = LightSurfaceVariant, + onSurfaceVariant = Color(0xFF5E6064), + secondaryContainer = Color(0xFFDCE5EF), + onSecondaryContainer = Color(0xFF30465D), ) @Composable @@ -56,7 +65,6 @@ fun JavaZoneTheme( val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } - darkTheme -> DarkColorScheme else -> LightColorScheme } @@ -65,6 +73,9 @@ fun JavaZoneTheme( colorScheme = colorScheme, typography = Typography, shapes = Shapes, - content = content - ) -} \ No newline at end of file + ) { + AnimatedDiagonalBackground { + content() + } + } +}