Update mobile app UI with premium design system

- Add design guidelines to CLAUDE.md
- Redesign navigation with boutique styling
- Add video support to chat with compression
- Update matches/dares/quiz screens with gold/rose accents
- Improve packs browsing with category tabs
- Add SwipeCardPremium component
- Update theme with premium color palette
- Add video cleanup edge function and migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jamie BruntonandClaude Opus 4.5 committed 2026-01-01 20:26:33 +00:00
1 parent feb7657562
commit cac7a2a31d
31 files changed
+6638 -1827

No files matched your search

+35 -51
View File
@@ -33,11 +33,6 @@ export default function DaresScreen() {
entering={FadeInDown.duration(600).springify()}
style={styles.content}
>
{/* Icon */}
<View style={styles.iconContainer}>
<Ionicons name="flame" size={36} color={ACCENT_COLOR} />
</View>
{/* Title section */}
<Text style={styles.label}>ADVENTURE</Text>
<Text style={styles.title}>Dares</Text>
@@ -81,40 +76,39 @@ export default function DaresScreen() {
{/* Bottom teaser */}
<Text style={styles.teaser}>Are you ready to play?</Text>
{/* Interest button */}
{isAuthenticated && !isLoading && (
<Animated.View
entering={FadeIn.delay(500).duration(400)}
style={styles.interestButtonContainer}
>
<AnimatedPressable
onPress={toggleInterest}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
disabled={isToggling}
style={[
styles.interestButton,
isInterested && styles.interestButtonActive,
animatedButtonStyle,
]}
>
{isToggling ? (
<ActivityIndicator size="small" color={ACCENT_COLOR} />
) : (
<>
<Ionicons
name={isInterested ? "checkmark-circle" : "notifications-outline"}
size={16}
color={ACCENT_COLOR}
/>
<Text style={styles.interestButtonText}>
{isInterested ? "You're on the list!" : "I'm interested"}
</Text>
</>
)}
</AnimatedPressable>
</Animated.View>
)}
{/* Interest button - always reserve space to prevent layout shift */}
<View style={styles.interestButtonContainer}>
{isAuthenticated && !isLoading && (
<Animated.View entering={FadeIn.delay(500).duration(400)}>
<AnimatedPressable
onPress={toggleInterest}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
disabled={isToggling}
style={[
styles.interestButton,
isInterested && styles.interestButtonActive,
animatedButtonStyle,
]}
>
{isToggling ? (
<ActivityIndicator size="small" color={ACCENT_COLOR} />
) : (
<>
<Ionicons
name={isInterested ? "checkmark-circle" : "notifications-outline"}
size={16}
color={ACCENT_COLOR}
/>
<Text style={styles.interestButtonText}>
{isInterested ? "You're on the list!" : "I'm interested"}
</Text>
</>
)}
</AnimatedPressable>
</Animated.View>
)}
</View>
</Animated.View>
</View>
</GradientBackground>
@@ -127,7 +121,7 @@ const styles = StyleSheet.create({
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: spacing.lg,
paddingTop: Platform.OS === 'ios' ? 60 : 40,
paddingTop: 60,
paddingBottom: Platform.OS === 'ios' ? 120 : 100,
},
content: {
@@ -135,17 +129,6 @@ const styles = StyleSheet.create({
alignItems: 'center',
paddingHorizontal: spacing.md,
},
iconContainer: {
width: 72,
height: 72,
borderRadius: 36,
backgroundColor: 'rgba(212, 175, 55, 0.1)',
borderWidth: 1,
borderColor: 'rgba(212, 175, 55, 0.2)',
justifyContent: 'center',
alignItems: 'center',
marginBottom: spacing.xl,
},
label: {
...typography.caption1,
fontWeight: '600',
@@ -223,6 +206,7 @@ const styles = StyleSheet.create({
},
interestButtonContainer: {
marginTop: spacing.xl,
minHeight: 44,
},
interestButton: {
flexDirection: 'row',