diff --git a/apps/android/app/src/main/java/com/steipete/clawdis/node/node/CanvasController.kt b/apps/android/app/src/main/java/com/steipete/clawdis/node/node/CanvasController.kt index 9a2c8960e..b6a2740aa 100644 --- a/apps/android/app/src/main/java/com/steipete/clawdis/node/node/CanvasController.kt +++ b/apps/android/app/src/main/java/com/steipete/clawdis/node/node/CanvasController.kt @@ -147,9 +147,50 @@ private val canvasHtml = } html,body { height:100%; margin:0; } body { - background: transparent; + background: radial-gradient(1200px 900px at 15% 20%, rgba(42, 113, 255, 0.18), rgba(0,0,0,0) 55%), + radial-gradient(900px 700px at 85% 30%, rgba(255, 0, 138, 0.14), rgba(0,0,0,0) 60%), + radial-gradient(1000px 900px at 60% 90%, rgba(0, 209, 255, 0.10), rgba(0,0,0,0) 60%), + #000; overflow: hidden; } + body::before { + content:""; + position: fixed; + inset: -20%; + background: + repeating-linear-gradient(0deg, rgba(255,255,255,0.02) 0, rgba(255,255,255,0.02) 1px, + transparent 1px, transparent 48px), + repeating-linear-gradient(90deg, rgba(255,255,255,0.02) 0, rgba(255,255,255,0.02) 1px, + transparent 1px, transparent 48px); + transform: rotate(-7deg); + opacity: 0.45; + pointer-events: none; + animation: clawdis-grid-drift 140s ease-in-out infinite alternate; + } + body::after { + content:""; + position: fixed; + inset: -35%; + background: + radial-gradient(900px 700px at 30% 30%, rgba(42,113,255,0.16), rgba(0,0,0,0) 60%), + radial-gradient(800px 650px at 70% 35%, rgba(255,0,138,0.12), rgba(0,0,0,0) 62%), + radial-gradient(900px 800px at 55% 75%, rgba(0,209,255,0.10), rgba(0,0,0,0) 62%); + filter: blur(28px); + opacity: 0.52; + mix-blend-mode: screen; + pointer-events: none; + animation: clawdis-glow-drift 110s ease-in-out infinite alternate; + } + @keyframes clawdis-grid-drift { + 0% { transform: translate3d(-12px, 8px, 0) rotate(-7deg); opacity: 0.40; } + 50% { transform: translate3d( 10px,-7px, 0) rotate(-6.6deg); opacity: 0.56; } + 100% { transform: translate3d(-8px, 6px, 0) rotate(-7.2deg); opacity: 0.42; } + } + @keyframes clawdis-glow-drift { + 0% { transform: translate3d(-18px, 12px, 0) scale(1.02); opacity: 0.40; } + 50% { transform: translate3d( 14px,-10px, 0) scale(1.05); opacity: 0.52; } + 100% { transform: translate3d(-10px, 8px, 0) scale(1.03); opacity: 0.43; } + } canvas { display:block; width:100vw; @@ -167,7 +208,7 @@ private val canvasHtml = text-align: center; padding: 16px 18px; border-radius: 14px; - background: rgba(18, 18, 22, 0.70); + background: rgba(18, 18, 22, 0.42); border: 1px solid rgba(255,255,255,0.08); box-shadow: 0 18px 60px rgba(0,0,0,0.55); backdrop-filter: blur(14px); diff --git a/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/ClawdisIdleBackground.kt b/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/ClawdisIdleBackground.kt deleted file mode 100644 index acadd7339..000000000 --- a/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/ClawdisIdleBackground.kt +++ /dev/null @@ -1,126 +0,0 @@ -package com.steipete.clawdis.node.ui - -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.background -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.rotate -import androidx.compose.ui.unit.dp - -@Composable -fun ClawdisIdleBackground(modifier: Modifier = Modifier) { - val t = rememberInfiniteTransition(label = "clawdis-bg") - val gridX = - t.animateFloat( - initialValue = -18f, - targetValue = 14f, - animationSpec = infiniteRepeatable(animation = tween(durationMillis = 22_000), repeatMode = RepeatMode.Reverse), - label = "gridX", - ).value - val gridY = - t.animateFloat( - initialValue = 12f, - targetValue = -10f, - animationSpec = infiniteRepeatable(animation = tween(durationMillis = 22_000), repeatMode = RepeatMode.Reverse), - label = "gridY", - ).value - - val glowX = - t.animateFloat( - initialValue = -26f, - targetValue = 20f, - animationSpec = infiniteRepeatable(animation = tween(durationMillis = 18_000), repeatMode = RepeatMode.Reverse), - label = "glowX", - ).value - val glowY = - t.animateFloat( - initialValue = 18f, - targetValue = -14f, - animationSpec = infiniteRepeatable(animation = tween(durationMillis = 18_000), repeatMode = RepeatMode.Reverse), - label = "glowY", - ).value - - Box(modifier = modifier.fillMaxSize().background(Color.Black)) { - Canvas(modifier = Modifier.fillMaxSize()) { - val w = size.width - val h = size.height - - fun radial(cx: Float, cy: Float, r: Float, color: Color): Brush = - Brush.radialGradient( - colors = listOf(color, Color.Transparent), - center = Offset(cx, cy), - radius = r, - ) - - drawRect( - brush = radial(w * 0.15f, h * 0.20f, r = maxOf(w, h) * 0.85f, color = Color(0xFF2A71FF).copy(alpha = 0.18f)), - ) - drawRect( - brush = radial(w * 0.85f, h * 0.30f, r = maxOf(w, h) * 0.75f, color = Color(0xFFFF008A).copy(alpha = 0.14f)), - ) - drawRect( - brush = radial(w * 0.60f, h * 0.90f, r = maxOf(w, h) * 0.85f, color = Color(0xFF00D1FF).copy(alpha = 0.10f)), - ) - - rotate(degrees = -7f) { - val spacing = 48.dp.toPx() - val line = Color.White.copy(alpha = 0.02f) - val offset = Offset(gridX.dp.toPx(), gridY.dp.toPx()) - - var x = (-w * 0.6f) + (offset.x % spacing) - while (x < w * 1.6f) { - drawLine(color = line, start = Offset(x, -h * 0.6f), end = Offset(x, h * 1.6f)) - x += spacing - } - - var y = (-h * 0.6f) + (offset.y % spacing) - while (y < h * 1.6f) { - drawLine(color = line, start = Offset(-w * 0.6f, y), end = Offset(w * 1.6f, y)) - y += spacing - } - } - } - - // Glow drift layer (closer to iOS WebView scaffold: blur + screen blend). - Canvas(modifier = Modifier.fillMaxSize().blur(28.dp)) { - val w = size.width - val h = size.height - val glowOffset = Offset(glowX.dp.toPx(), glowY.dp.toPx()) - - fun radial(cx: Float, cy: Float, r: Float, color: Color): Brush = - Brush.radialGradient( - colors = listOf(color, Color.Transparent), - center = Offset(cx, cy), - radius = r, - ) - - drawRect( - brush = radial(w * 0.30f + glowOffset.x, h * 0.30f + glowOffset.y, r = maxOf(w, h) * 0.75f, color = Color(0xFF2A71FF).copy(alpha = 0.16f)), - blendMode = BlendMode.Screen, - alpha = 0.55f, - ) - drawRect( - brush = radial(w * 0.70f + glowOffset.x, h * 0.35f + glowOffset.y, r = maxOf(w, h) * 0.70f, color = Color(0xFFFF008A).copy(alpha = 0.12f)), - blendMode = BlendMode.Screen, - alpha = 0.55f, - ) - drawRect( - brush = radial(w * 0.55f + glowOffset.x, h * 0.75f + glowOffset.y, r = maxOf(w, h) * 0.85f, color = Color(0xFF00D1FF).copy(alpha = 0.10f)), - blendMode = BlendMode.Screen, - alpha = 0.55f, - ) - } - } -} diff --git a/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/RootScreen.kt b/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/RootScreen.kt index d06e4717d..e20241711 100644 --- a/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/RootScreen.kt +++ b/apps/android/app/src/main/java/com/steipete/clawdis/node/ui/RootScreen.kt @@ -70,7 +70,6 @@ fun RootScreen(viewModel: MainViewModel) { PackageManager.PERMISSION_GRANTED Box(modifier = Modifier.fillMaxSize()) { - ClawdisIdleBackground(modifier = Modifier.fillMaxSize()) CanvasView(viewModel = viewModel, modifier = Modifier.fillMaxSize()) } diff --git a/apps/ios/Sources/Screen/ScreenController.swift b/apps/ios/Sources/Screen/ScreenController.swift index 5cd6bb1d6..5302dc717 100644 --- a/apps/ios/Sources/Screen/ScreenController.swift +++ b/apps/ios/Sources/Screen/ScreenController.swift @@ -130,9 +130,9 @@ final class ScreenController { repeating-linear-gradient(90deg, rgba(255,255,255,0.02) 0, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 48px); transform: rotate(-7deg); - opacity: 0.55; + opacity: 0.45; pointer-events: none; - animation: clawdis-grid-drift 22s linear infinite; + animation: clawdis-grid-drift 140s ease-in-out infinite alternate; } body::after { content:""; @@ -143,20 +143,20 @@ final class ScreenController { radial-gradient(800px 650px at 70% 35%, rgba(255,0,138,0.12), rgba(0,0,0,0) 62%), radial-gradient(900px 800px at 55% 75%, rgba(0,209,255,0.10), rgba(0,0,0,0) 62%); filter: blur(28px); - opacity: 0.55; + opacity: 0.52; mix-blend-mode: screen; pointer-events: none; - animation: clawdis-glow-drift 18s ease-in-out infinite alternate; + animation: clawdis-glow-drift 110s ease-in-out infinite alternate; } @keyframes clawdis-grid-drift { - 0% { transform: translate3d(-18px, 12px, 0) rotate(-7deg); opacity: 0.50; } - 50% { transform: translate3d( 14px,-10px, 0) rotate(-6.2deg); opacity: 0.62; } - 100% { transform: translate3d(-10px, 8px, 0) rotate(-7.4deg); opacity: 0.52; } + 0% { transform: translate3d(-12px, 8px, 0) rotate(-7deg); opacity: 0.40; } + 50% { transform: translate3d( 10px,-7px, 0) rotate(-6.6deg); opacity: 0.56; } + 100% { transform: translate3d(-8px, 6px, 0) rotate(-7.2deg); opacity: 0.42; } } @keyframes clawdis-glow-drift { - 0% { transform: translate3d(-26px, 18px, 0) scale(1.02); opacity: 0.42; } - 50% { transform: translate3d( 20px,-14px, 0) scale(1.05); opacity: 0.55; } - 100% { transform: translate3d(-12px, 10px, 0) scale(1.03); opacity: 0.46; } + 0% { transform: translate3d(-18px, 12px, 0) scale(1.02); opacity: 0.40; } + 50% { transform: translate3d( 14px,-10px, 0) scale(1.05); opacity: 0.52; } + 100% { transform: translate3d(-10px, 8px, 0) scale(1.03); opacity: 0.43; } } canvas { display:block;