New look: slate-indigo panels, pink accent, Poppins, and a gradient card for your song
Inspired by a dashboard design the user shared. - App: new palette and fonts, borderless rounded panels with soft shadows, a pink-to-blue gradient card for your own song (text and controls switch to white on it), flat cards for friends, a 'Hi Chris, welcome back' header, an outline bell, and a pink pill on the active tab. - Website: the same look, plus a wide-screen layout with a sidebar, the page in a rounded panel, and a right column with your profile, recent activity and recent plays. Phones keep the top bar and bottom tabs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011Y2iUsKEWDuRGjK5FPmcUP
This commit is contained in:
@@ -1,36 +1,15 @@
|
||||
import { Image } from 'expo-image';
|
||||
import { useEffect } from 'react';
|
||||
import { StyleSheet, useWindowDimensions, View } from 'react-native';
|
||||
import Animated, { Easing, useAnimatedStyle, useSharedValue, withRepeat, withTiming } from 'react-native-reanimated';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { colors } from '@/lib/theme';
|
||||
|
||||
const AnimatedImage = Animated.createAnimatedComponent(Image);
|
||||
|
||||
/** Two soft colour blobs drifting slowly behind the content, so screens never feel static. */
|
||||
/** The page behind everything: flat slate, a touch lighter at the top. */
|
||||
export function AmbientBackground() {
|
||||
const { width, height } = useWindowDimensions();
|
||||
const t = useSharedValue(0);
|
||||
|
||||
useEffect(() => {
|
||||
t.set(withRepeat(withTiming(1, { duration: 18000, easing: Easing.inOut(Easing.sin) }), -1, true));
|
||||
}, [t]);
|
||||
|
||||
const size = Math.max(width, height) * 0.9;
|
||||
const purple = useAnimatedStyle(() => ({
|
||||
transform: [{ translateX: -size * 0.35 + t.value * width * 0.35 }, { translateY: -size * 0.3 + t.value * height * 0.12 }],
|
||||
}));
|
||||
const blue = useAnimatedStyle(() => ({
|
||||
transform: [{ translateX: width - size * 0.6 - t.value * width * 0.3 }, { translateY: height - size * 0.55 - t.value * height * 0.1 }],
|
||||
}));
|
||||
|
||||
return (
|
||||
<View style={[StyleSheet.absoluteFill, { backgroundColor: colors.bg }]} pointerEvents="none">
|
||||
<AnimatedImage source={require('@/assets/images/ambient-purple.png')} style={[styles.blob, { width: size, height: size }, purple]} />
|
||||
<AnimatedImage source={require('@/assets/images/ambient-blue.png')} style={[styles.blob, { width: size, height: size }, blue]} />
|
||||
</View>
|
||||
<LinearGradient
|
||||
colors={['#32304e', colors.bg, colors.bg]}
|
||||
locations={[0, 0.45, 1]}
|
||||
style={[StyleSheet.absoluteFill, { backgroundColor: colors.bg }]}
|
||||
pointerEvents="none"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
blob: { position: 'absolute', top: 0, left: 0, opacity: 0.45 },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user