From d52c0aef92800671f1f91ac8a2e137e549261392 Mon Sep 17 00:00:00 2001 From: Muyue Date: Fri, 17 Oct 2025 17:36:47 +0200 Subject: [PATCH] Add animated gradient background with floating particles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement dynamic background that fills entire viewport: - Animated gradient that smoothly shifts colors every 15s - Floating radial gradients (particles) that animate independently - Multiple animation layers with different timings (20s, 25s) - Content properly layered above background (z-index handling) - Smooth, continuous animations that don't loop jarringly Changes: - App.vue: Full-screen animated background with pseudo-elements - CollaborativeInput.vue: Same animated effect - CollaborativeSession.vue: Full viewport background - All components now use 100% available space - Subtle visual interest without distracting from content Result: Modern, premium feel with movement depth 🤖 Generated with Claude Code Co-Authored-By: Claude --- frontend/src/App.vue | 116 +++++++++++++++++- .../src/components/CollaborativeInput.vue | 52 +++++++- .../src/components/CollaborativeSession.vue | 67 +++++++++- 3 files changed, 226 insertions(+), 9 deletions(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 360025d..e46da8f 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -54,20 +54,132 @@ function startNewCollaboration() { body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; - background-color: #f5f7fa; color: #2c3e50; } #app { min-height: 100vh; } + +@keyframes gradient-shift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +@keyframes float1 { + 0%, 100% { + transform: translate(0, 0) rotate(0deg); + opacity: 0.03; + } + 25% { + transform: translate(100px, -100px) rotate(90deg); + opacity: 0.05; + } + 50% { + transform: translate(-50px, 150px) rotate(180deg); + opacity: 0.03; + } + 75% { + transform: translate(-100px, -50px) rotate(270deg); + opacity: 0.04; + } +} + +@keyframes float2 { + 0%, 100% { + transform: translate(0, 0) rotate(0deg); + opacity: 0.04; + } + 25% { + transform: translate(-120px, 80px) rotate(-90deg); + opacity: 0.06; + } + 50% { + transform: translate(80px, -120px) rotate(-180deg); + opacity: 0.04; + } + 75% { + transform: translate(120px, 100px) rotate(-270deg); + opacity: 0.05; + } +} + +@keyframes float3 { + 0%, 100% { + transform: translate(0, 0) rotate(0deg); + opacity: 0.03; + } + 25% { + transform: translate(-80px, -80px) rotate(45deg); + opacity: 0.05; + } + 50% { + transform: translate(100px, 100px) rotate(135deg); + opacity: 0.03; + } + 75% { + transform: translate(-100px, 80px) rotate(225deg); + opacity: 0.04; + } +}