From 20e9e23938c02c08244827340bd253893e9e43e1 Mon Sep 17 00:00:00 2001 From: 230417 <230417@epvc.pt> Date: Fri, 8 May 2026 10:40:12 +0100 Subject: [PATCH] refactor: implement bottom tab navigation and update UI component design system --- src/components/ui/Button.tsx | 26 +- src/components/ui/Card.tsx | 12 +- src/components/ui/Input.tsx | 30 +-- src/navigation/AppNavigator.tsx | 227 ++++++++++++++--- src/navigation/types.ts | 1 - src/pages/AuthLogin.tsx | 168 +++++++------ src/pages/AuthRegister.tsx | 198 ++++++++------- src/pages/Explore.tsx | 418 +++++++++++++------------------- 8 files changed, 593 insertions(+), 487 deletions(-) diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx index e72e011..862a0d9 100644 --- a/src/components/ui/Button.tsx +++ b/src/components/ui/Button.tsx @@ -36,7 +36,7 @@ export const Button = ({ children, onPress, variant = 'solid', size = 'md', disa activeOpacity={0.7} > {loading ? ( - + ) : ( {children} )} @@ -46,7 +46,7 @@ export const Button = ({ children, onPress, variant = 'solid', size = 'md', disa const styles = StyleSheet.create({ base: { - borderRadius: 8, + borderRadius: 14, alignItems: 'center', justifyContent: 'center', flexDirection: 'row', @@ -56,38 +56,38 @@ const styles = StyleSheet.create({ }, outline: { backgroundColor: 'transparent', - borderWidth: 2, - borderColor: '#6366f1', + borderWidth: 1.5, + borderColor: 'rgba(99,102,241,0.4)', }, ghost: { backgroundColor: 'transparent', }, size_sm: { - paddingHorizontal: 12, + paddingHorizontal: 14, paddingVertical: 8, }, size_md: { - paddingHorizontal: 16, - paddingVertical: 10, + paddingHorizontal: 18, + paddingVertical: 12, }, size_lg: { paddingHorizontal: 24, - paddingVertical: 14, + paddingVertical: 16, }, disabled: { - opacity: 0.5, + opacity: 0.4, }, text: { - fontWeight: '600', + fontWeight: '700', }, text_solid: { color: '#fff', }, text_outline: { - color: '#6366f1', + color: '#a5b4fc', }, text_ghost: { - color: '#6366f1', + color: '#a5b4fc', }, textSize_sm: { fontSize: 12, @@ -99,5 +99,3 @@ const styles = StyleSheet.create({ fontSize: 16, }, }); - - diff --git a/src/components/ui/Card.tsx b/src/components/ui/Card.tsx index 9939df8..87f2676 100644 --- a/src/components/ui/Card.tsx +++ b/src/components/ui/Card.tsx @@ -12,16 +12,10 @@ export const Card = ({ children, style }: Props) => { const styles = StyleSheet.create({ card: { - backgroundColor: '#fff', - borderRadius: 12, + backgroundColor: '#141420', + borderRadius: 20, padding: 16, - shadowColor: '#000', - shadowOffset: { width: 0, height: 1 }, - shadowOpacity: 0.1, - shadowRadius: 2, - elevation: 2, borderWidth: 1, - borderColor: '#e2e8f0', + borderColor: 'rgba(255,255,255,0.06)', }, }); - diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx index 7141c74..492f3aa 100644 --- a/src/components/ui/Input.tsx +++ b/src/components/ui/Input.tsx @@ -12,7 +12,7 @@ export const Input = ({ label, error, style, ...props }: Props) => { {label && {label}} {error && {error}} @@ -25,20 +25,22 @@ const styles = StyleSheet.create({ marginBottom: 16, }, label: { - fontSize: 14, - fontWeight: '600', - color: '#334155', - marginBottom: 6, + fontSize: 12, + fontWeight: '700', + color: '#94a3b8', + textTransform: 'uppercase', + letterSpacing: 0.5, + marginBottom: 8, }, input: { borderWidth: 1, - borderColor: '#cbd5e1', - borderRadius: 8, - paddingHorizontal: 12, - paddingVertical: 10, - fontSize: 14, - color: '#0f172a', - backgroundColor: '#fff', + borderColor: 'rgba(255,255,255,0.08)', + borderRadius: 14, + paddingHorizontal: 16, + paddingVertical: 14, + fontSize: 15, + color: '#f8fafc', + backgroundColor: '#1c1c2e', }, inputError: { borderColor: '#ef4444', @@ -46,8 +48,6 @@ const styles = StyleSheet.create({ error: { fontSize: 12, color: '#ef4444', - marginTop: 4, + marginTop: 6, }, }); - - diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index 9d44b78..53c6daf 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { View, Text, StyleSheet, Platform } from 'react-native'; import { useApp } from '../context/AppContext'; -import Landing from '../pages/Landing'; import AuthLogin from '../pages/AuthLogin'; import AuthRegister from '../pages/AuthRegister'; import Explore from '../pages/Explore'; @@ -12,48 +13,204 @@ import Cart from '../pages/Cart'; import Profile from '../pages/Profile'; import Dashboard from '../pages/Dashboard'; import EventsCreate from '../pages/EventsCreate'; -import { RootStackParamList } from './types'; -const Stack = createNativeStackNavigator(); +const Stack = createNativeStackNavigator(); +const Tab = createBottomTabNavigator(); +const TabIcon = ({ icon, focused }: { icon: string; focused: boolean }) => ( + + {icon} + +); + +/* ── Client Tab Stacks ── */ +function ExploreStack() { + return ( + + + + + + ); +} + +function CartStack() { + return ( + + + + ); +} + +function ClientProfileStack() { + return ( + + + + + + + ); +} + +function ClientTabs() { + const { cart } = useApp(); + return ( + + , + }} + /> + , + tabBarBadge: cart.length > 0 ? cart.length : undefined, + tabBarBadgeStyle: tabStyles.badge, + }} + /> + , + }} + /> + + ); +} + +/* ── Barbearia Tab Stacks ── */ +function DashboardStack() { + return ( + + + + + ); +} + +function BarberProfileStack() { + return ( + + + + + ); +} + +function BarbeariaTabs() { + return ( + + , + }} + /> + , + }} + /> + + ); +} + +/* ── Root Navigator ── */ export default function AppNavigator() { const { user } = useApp(); return ( - - {!user ? ( - <> - - - - - - - ) : user.role === 'barbearia' ? ( - <> - - - - - ) : ( - <> - - - - - - - - )} - + {!user ? ( + + + + + + + ) : user.role === 'barbearia' ? ( + + ) : ( + + )} ); } +const tabStyles = StyleSheet.create({ + bar: { + backgroundColor: '#0a0a0f', + borderTopColor: 'rgba(255,255,255,0.06)', + borderTopWidth: 1, + height: Platform.OS === 'ios' ? 88 : 64, + paddingBottom: Platform.OS === 'ios' ? 28 : 8, + paddingTop: 8, + }, + label: { + fontSize: 10, + fontWeight: '700', + letterSpacing: 0.5, + }, + badge: { + backgroundColor: '#6366f1', + color: '#fff', + fontSize: 10, + fontWeight: '800', + minWidth: 18, + height: 18, + lineHeight: 14, + }, +}); + +const iconStyles = StyleSheet.create({ + wrap: { + width: 32, + height: 32, + borderRadius: 10, + alignItems: 'center', + justifyContent: 'center', + }, + wrapActive: { + backgroundColor: 'rgba(99,102,241,0.15)', + }, + emoji: { + fontSize: 18, + color: '#94a3b8', + }, +}); diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 0d1ba1d..693b18f 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -1,5 +1,4 @@ export type RootStackParamList = { - Landing: undefined; Login: undefined; Register: undefined; Explore: undefined; diff --git a/src/pages/AuthLogin.tsx b/src/pages/AuthLogin.tsx index a44d3f7..d9ee06f 100644 --- a/src/pages/AuthLogin.tsx +++ b/src/pages/AuthLogin.tsx @@ -6,7 +6,6 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useApp } from '../context/AppContext'; import { Button } from '../components/ui/Button'; import { Input } from '../components/ui/Input'; -import { Card } from '../components/ui/Card'; import { RootStackParamList } from '../navigation/types'; export default function AuthLogin() { @@ -23,7 +22,6 @@ export default function AuthLogin() { setError('Preenche email e palavra-passe'); return; } - try { setLoading(true); const nextUser = await login(email.trim(), password); @@ -31,8 +29,6 @@ export default function AuthLogin() { setError('Credenciais inválidas ou email não confirmado'); return; } - - navigation.replace(nextUser.role === 'barbearia' ? 'Dashboard' : 'Explore'); } catch (e: any) { const message = e?.message || 'Credenciais inválidas ou email não confirmado'; setError(message); @@ -45,50 +41,54 @@ export default function AuthLogin() { return ( - - navigation.navigate('Landing')}> - SA - - - Bem-vindo - Aceda à sua conta Smart Agenda - - {!!error && {error}} - - { - setEmail(text); - setError(''); - }} - keyboardType="email-address" - autoCapitalize="none" - placeholder="exemplo@email.com" - /> - - { - setPassword(text); - setError(''); - }} - secureTextEntry - placeholder="••••••••" - /> - - - - - Ainda não tem conta? - navigation.navigate('Register')}> - Criar conta grátis - + + + SA - + + + Bem-vindo + Aceda à sua conta Smart Agenda + + {!!error && ( + + {error} + + )} + + { setEmail(text); setError(''); }} + keyboardType="email-address" + autoCapitalize="none" + placeholder="exemplo@email.com" + /> + + { setPassword(text); setError(''); }} + secureTextEntry + placeholder="••••••••" + /> + + + + navigation.navigate('Explore')}> + Explorar sem conta + + + + + + Ainda não tem conta? + navigation.navigate('Register')}> + Criar conta grátis + + ); @@ -97,68 +97,84 @@ export default function AuthLogin() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#f8fafc', + backgroundColor: '#0a0a0f', }, content: { - padding: 16, + padding: 24, justifyContent: 'center', minHeight: '100%', }, - card: { - padding: 24, + logoRow: { + alignItems: 'center', + marginBottom: 32, }, - iconBox: { - width: 64, - height: 64, - borderRadius: 18, - backgroundColor: '#0f172a', + logoBox: { + width: 72, + height: 72, + borderRadius: 22, + backgroundColor: '#141420', + borderWidth: 1, + borderColor: 'rgba(99,102,241,0.3)', alignItems: 'center', justifyContent: 'center', - alignSelf: 'center', - marginBottom: 18, }, - iconText: { + logoText: { color: '#818cf8', - fontSize: 18, + fontSize: 22, fontWeight: '900', }, title: { - fontSize: 30, + fontSize: 34, fontWeight: '900', - color: '#0f172a', + color: '#f8fafc', textAlign: 'center', marginBottom: 6, }, subtitle: { - fontSize: 14, + fontSize: 15, color: '#64748b', - marginBottom: 24, + marginBottom: 32, textAlign: 'center', fontWeight: '500', }, - error: { - backgroundColor: '#fff1f2', - borderColor: '#fecdd3', + errorBox: { + backgroundColor: 'rgba(239,68,68,0.1)', + borderColor: 'rgba(239,68,68,0.3)', borderWidth: 1, borderRadius: 14, - color: '#be123c', - padding: 12, + padding: 14, marginBottom: 16, + }, + errorText: { + color: '#fca5a5', fontWeight: '600', + fontSize: 13, }, submitButton: { width: '100%', - marginTop: 8, - backgroundColor: '#0f172a', + marginTop: 4, + backgroundColor: '#6366f1', + paddingVertical: 16, + }, + guestButton: { + alignSelf: 'center', + marginTop: 16, + paddingVertical: 10, + }, + guestText: { + color: '#64748b', + fontWeight: '700', + fontSize: 14, + }, + divider: { + height: 1, + backgroundColor: 'rgba(255,255,255,0.06)', + marginVertical: 24, }, footer: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', - marginTop: 24, - paddingTop: 24, - borderTopWidth: 1, - borderTopColor: '#e2e8f0', }, footerText: { fontSize: 14, @@ -166,7 +182,7 @@ const styles = StyleSheet.create({ }, footerLink: { fontSize: 14, - color: '#4f46e5', + color: '#818cf8', fontWeight: '800', }, }); diff --git a/src/pages/AuthRegister.tsx b/src/pages/AuthRegister.tsx index 714910f..e30ab74 100644 --- a/src/pages/AuthRegister.tsx +++ b/src/pages/AuthRegister.tsx @@ -6,7 +6,6 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useApp } from '../context/AppContext'; import { Button } from '../components/ui/Button'; import { Input } from '../components/ui/Input'; -import { Card } from '../components/ui/Card'; import { RootStackParamList } from '../navigation/types'; export default function AuthRegister() { @@ -42,8 +41,6 @@ export default function AuthRegister() { navigation.replace('Login'); return; } - - navigation.replace(nextUser.role === 'barbearia' ? 'Dashboard' : 'Explore'); } catch (e: any) { const message = e?.message || 'Erro ao criar conta'; setError(message); @@ -56,67 +53,69 @@ export default function AuthRegister() { return ( - - - SA + + + SA - Criar Conta - Junte-se à Smart Agenda + - {!!error && {error}} + Criar Conta + Junte-se à Smart Agenda - Eu sou... - - {(['cliente', 'barbearia'] as const).map((item) => ( - { - setRole(item); - setError(''); - }} - > - - {item === 'cliente' ? 'Cliente' : 'Barbearia'} - - - ))} + {!!error && ( + + {error} + )} - + Eu sou... + + {(['cliente', 'barbearia'] as const).map((item) => ( + { setRole(item); setError(''); }} + > + {item === 'cliente' ? '✂️' : '💈'} + + {item === 'cliente' ? 'Cliente' : 'Barbearia'} + + + ))} + + + + { setEmail(text); setError(''); }} + keyboardType="email-address" + autoCapitalize="none" + placeholder="exemplo@email.com" + /> + + + {role === 'barbearia' && ( { - setEmail(text); - setError(''); - }} - keyboardType="email-address" - autoCapitalize="none" - placeholder="exemplo@email.com" + label="Nome da barbearia" + value={shopName} + onChangeText={setShopName} + placeholder="Ex: Barbearia Estilo" /> - + )} - {role === 'barbearia' && ( - - )} + - + - - Já tem uma conta? - navigation.navigate('Login')}> - Fazer Login - - - + + Já tem uma conta? + navigation.navigate('Login')}> + Fazer Login + + ); @@ -125,102 +124,113 @@ export default function AuthRegister() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#f8fafc', + backgroundColor: '#0a0a0f', }, content: { - padding: 16, + padding: 24, justifyContent: 'center', minHeight: '100%', }, - card: { - padding: 24, + logoRow: { + alignItems: 'center', + marginBottom: 28, }, - iconBox: { - width: 64, - height: 64, - borderRadius: 18, - backgroundColor: '#0f172a', + logoBox: { + width: 72, + height: 72, + borderRadius: 22, + backgroundColor: '#141420', + borderWidth: 1, + borderColor: 'rgba(99,102,241,0.3)', alignItems: 'center', justifyContent: 'center', - alignSelf: 'center', - marginBottom: 18, }, - iconText: { + logoText: { color: '#818cf8', - fontSize: 18, + fontSize: 22, fontWeight: '900', }, title: { - fontSize: 30, + fontSize: 34, fontWeight: '900', - color: '#0f172a', + color: '#f8fafc', textAlign: 'center', marginBottom: 6, }, subtitle: { - fontSize: 14, + fontSize: 15, color: '#64748b', - marginBottom: 24, + marginBottom: 28, textAlign: 'center', fontWeight: '500', }, - error: { - backgroundColor: '#fff1f2', - borderColor: '#fecdd3', + errorBox: { + backgroundColor: 'rgba(239,68,68,0.1)', + borderColor: 'rgba(239,68,68,0.3)', borderWidth: 1, borderRadius: 14, - color: '#be123c', - padding: 12, + padding: 14, marginBottom: 16, + }, + errorText: { + color: '#fca5a5', fontWeight: '600', + fontSize: 13, }, label: { fontSize: 12, - color: '#0f172a', - fontWeight: '900', + color: '#94a3b8', + fontWeight: '700', textTransform: 'uppercase', + letterSpacing: 0.5, marginBottom: 10, }, roleContainer: { flexDirection: 'row', gap: 12, - marginBottom: 18, + marginBottom: 20, }, roleButton: { flex: 1, - padding: 16, + padding: 18, borderRadius: 16, - borderWidth: 2, - borderColor: '#f1f5f9', - backgroundColor: '#f8fafc', + borderWidth: 1.5, + borderColor: 'rgba(255,255,255,0.06)', + backgroundColor: '#141420', alignItems: 'center', + gap: 8, }, roleButtonActive: { - borderColor: '#0f172a', - backgroundColor: '#0f172a', + borderColor: '#6366f1', + backgroundColor: 'rgba(99,102,241,0.1)', + }, + roleEmoji: { + fontSize: 24, }, roleText: { fontSize: 13, - fontWeight: '900', + fontWeight: '800', color: '#64748b', textTransform: 'uppercase', }, roleTextActive: { - color: '#818cf8', + color: '#a5b4fc', }, submitButton: { width: '100%', - marginTop: 8, - backgroundColor: '#0f172a', + marginTop: 4, + backgroundColor: '#6366f1', + paddingVertical: 16, + }, + divider: { + height: 1, + backgroundColor: 'rgba(255,255,255,0.06)', + marginVertical: 24, }, footer: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', - marginTop: 24, - paddingTop: 24, - borderTopWidth: 1, - borderTopColor: '#e2e8f0', }, footerText: { fontSize: 14, @@ -228,7 +238,7 @@ const styles = StyleSheet.create({ }, footerLink: { fontSize: 14, - color: '#4f46e5', + color: '#818cf8', fontWeight: '800', }, }); diff --git a/src/pages/Explore.tsx b/src/pages/Explore.tsx index ffdbe02..8216c0e 100644 --- a/src/pages/Explore.tsx +++ b/src/pages/Explore.tsx @@ -10,7 +10,7 @@ import { RootStackParamList } from '../navigation/types'; export default function Explore() { const navigation = useNavigation>(); - const { shops, shopsReady, cart, user, logout } = useApp(); + const { shops, shopsReady, user } = useApp(); const [query, setQuery] = useState(''); const [filter, setFilter] = useState<'todas' | 'top' | 'servicos'>('todas'); @@ -28,111 +28,102 @@ export default function Explore() { }); }, [shops, query, filter]); - const goToProfile = () => { - if (!user) navigation.navigate('Login'); - else navigation.navigate(user.role === 'barbearia' ? 'Dashboard' : 'Profile'); - }; - return ( - - navigation.navigate(user ? 'Explore' : 'Landing')} style={styles.brand}> - - SA - - Smart Agenda - - - {user?.role !== 'barbearia' && ( - (user ? navigation.navigate('Cart') : navigation.navigate('Login'))}> - Carrinho - {cart.length > 0 && {cart.length}} - - )} - - {user ? user.name.charAt(0).toUpperCase() : 'Entrar'} - - - - + {/* Header */} - - As nossas barbearias + + + {user ? `Olá, ${user.name.split(' ')[0]}` : 'Descobre'} + + Barbearias + + + SA - Ver Barbearias - Descubra barbearias exclusivas e reserve o seu próximo corte em segundos. - {user && ( - - Sair da conta - - )} - + {/* Search */} + + - - {[ - ['todas', 'Melhor avaliação'], - ['top', 'Top avaliadas'], - ['servicos', 'Mais serviços'], - ].map(([id, label]) => ( - setFilter(id as typeof filter)} - style={[styles.filterChip, filter === id && styles.filterChipActive]} - > - {label} - - ))} - - + + {/* Filters */} + + {[ + ['todas', 'Melhor avaliação'], + ['top', 'Top avaliadas'], + ['servicos', 'Mais serviços'], + ].map(([id, label]) => ( + setFilter(id as typeof filter)} + style={[styles.chip, filter === id && styles.chipActive]} + > + {label} + + ))} + + + {/* Results */} {!shopsReady ? ( - + + A carregar espaços... - + ) : filtered.length === 0 ? ( - + + 🔍 Nenhuma barbearia encontrada - Tente ajustar a pesquisa ou os filtros ativos. - - + ) : ( {filtered.length} espaços disponíveis {filtered.map((shop) => ( - + navigation.navigate('ShopDetails', { shopId: shop.id })} + > {shop.imageUrl ? ( ) : ( - SA + {shop.name.charAt(0)} )} + {shop.name} - {(shop.rating || 0).toFixed(1)} + + ★ {(shop.rating || 0).toFixed(1)} + {shop.address || 'Endereço indisponível'} - {(shop.services || []).length} serviços - {(shop.barbers || []).length} barbeiros + + {(shop.services || []).length} serviços + + + {(shop.barbers || []).length} barbeiros + - - + ))} )} @@ -144,243 +135,184 @@ export default function Explore() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#f8fafc', + backgroundColor: '#0a0a0f', }, content: { - padding: 16, - gap: 18, - }, - topBar: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - gap: 12, - }, - brand: { - flexDirection: 'row', - alignItems: 'center', - gap: 10, - flex: 1, - }, - brandIcon: { - width: 34, - height: 34, - borderRadius: 10, - backgroundColor: '#4f46e5', - alignItems: 'center', - justifyContent: 'center', - }, - brandIconText: { - color: '#fff', - fontSize: 12, - fontWeight: '900', - }, - brandText: { - color: '#0f172a', - fontSize: 18, - fontWeight: '900', - textTransform: 'uppercase', - }, - topActions: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, - }, - cartButton: { - minHeight: 36, - borderRadius: 12, - backgroundColor: '#f1f5f9', - paddingHorizontal: 10, - alignItems: 'center', - justifyContent: 'center', - }, - cartText: { - color: '#334155', - fontSize: 11, - fontWeight: '900', - }, - cartBadge: { - position: 'absolute', - right: -5, - top: -5, - minWidth: 18, - textAlign: 'center', - borderRadius: 999, - backgroundColor: '#0f172a', - color: '#818cf8', - fontSize: 10, - fontWeight: '900', - paddingHorizontal: 4, - }, - profileButton: { - minWidth: 38, - height: 38, - borderRadius: 999, - backgroundColor: '#0f172a', - alignItems: 'center', - justifyContent: 'center', - paddingHorizontal: 10, - }, - profileText: { - color: '#818cf8', - fontSize: 12, - fontWeight: '900', + padding: 20, + gap: 20, + paddingBottom: 32, }, header: { - gap: 8, + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', }, - kicker: { - alignSelf: 'flex-start', - backgroundColor: '#e0e7ff', - borderRadius: 999, - paddingHorizontal: 10, - paddingVertical: 5, - }, - kickerText: { - color: '#4338ca', - fontSize: 10, - fontWeight: '900', - textTransform: 'uppercase', - }, - title: { - fontSize: 36, - lineHeight: 38, - fontWeight: '900', - color: '#0f172a', - textTransform: 'uppercase', - }, - titleAccent: { - color: '#4f46e5', - }, - subtitle: { + greeting: { color: '#64748b', fontSize: 15, - lineHeight: 22, - fontWeight: '500', - }, - logoutButton: { - alignSelf: 'flex-start', - paddingVertical: 6, - }, - logoutText: { - color: '#e11d48', - fontWeight: '800', - }, - searchCard: { - padding: 12, - gap: 12, - }, - searchInput: { - minHeight: 48, - borderRadius: 16, - backgroundColor: '#f8fafc', - color: '#0f172a', - paddingHorizontal: 14, - fontSize: 15, fontWeight: '600', + marginBottom: 2, + }, + headline: { + color: '#f8fafc', + fontSize: 32, + fontWeight: '900', + }, + brandPill: { + width: 44, + height: 44, + borderRadius: 14, + backgroundColor: '#141420', + borderWidth: 1, + borderColor: 'rgba(99,102,241,0.25)', + alignItems: 'center', + justifyContent: 'center', + }, + brandText: { + color: '#818cf8', + fontSize: 14, + fontWeight: '900', + }, + searchBox: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: '#141420', + borderRadius: 16, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.06)', + paddingHorizontal: 16, + gap: 10, + }, + searchIcon: { + color: '#475569', + fontSize: 20, + }, + searchInput: { + flex: 1, + height: 52, + color: '#f8fafc', + fontSize: 15, + fontWeight: '500', }, filters: { - flexDirection: 'row', - flexWrap: 'wrap', gap: 8, }, - filterChip: { - borderRadius: 999, - backgroundColor: '#f1f5f9', - paddingHorizontal: 12, - paddingVertical: 8, + chip: { + borderRadius: 12, + backgroundColor: '#141420', + paddingHorizontal: 16, + paddingVertical: 10, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.04)', }, - filterChipActive: { - backgroundColor: '#0f172a', + chipActive: { + backgroundColor: '#6366f1', + borderColor: '#6366f1', }, - filterText: { - color: '#475569', - fontSize: 11, - fontWeight: '900', + chipText: { + color: '#94a3b8', + fontSize: 13, + fontWeight: '700', }, - filterTextActive: { - color: '#818cf8', + chipTextActive: { + color: '#fff', }, list: { - gap: 12, + gap: 16, }, count: { - color: '#64748b', + color: '#475569', fontSize: 12, - fontWeight: '900', + fontWeight: '700', textTransform: 'uppercase', + letterSpacing: 0.5, }, shopCard: { - padding: 0, + borderRadius: 22, overflow: 'hidden', + backgroundColor: '#141420', + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.04)', }, shopImage: { width: '100%', - height: 150, + height: 160, }, shopImageFallback: { width: '100%', - height: 150, - backgroundColor: '#0f172a', + height: 160, + backgroundColor: '#1c1c2e', alignItems: 'center', justifyContent: 'center', }, - shopImageFallbackText: { - color: '#818cf8', - fontSize: 24, + shopFallbackText: { + color: '#6366f1', + fontSize: 42, fontWeight: '900', + opacity: 0.5, }, + shopOverlay: {}, shopBody: { - padding: 16, + padding: 18, gap: 10, }, shopRow: { flexDirection: 'row', alignItems: 'center', + justifyContent: 'space-between', gap: 10, }, shopName: { flex: 1, - fontSize: 20, - fontWeight: '900', - color: '#0f172a', + fontSize: 18, + fontWeight: '800', + color: '#f8fafc', }, - rating: { - color: '#fff', - backgroundColor: '#0f172a', - borderRadius: 999, - paddingHorizontal: 9, - paddingVertical: 4, + ratingPill: { + backgroundColor: 'rgba(99,102,241,0.15)', + borderRadius: 10, + paddingHorizontal: 10, + paddingVertical: 5, + }, + ratingText: { + color: '#a5b4fc', fontSize: 12, - fontWeight: '900', + fontWeight: '800', }, address: { color: '#64748b', fontWeight: '500', + fontSize: 14, }, metaRow: { flexDirection: 'row', - gap: 10, + gap: 8, + }, + metaPill: { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 8, + paddingHorizontal: 10, + paddingVertical: 5, }, metaText: { - color: '#94a3b8', + color: '#475569', fontSize: 11, - fontWeight: '900', + fontWeight: '700', textTransform: 'uppercase', }, - reserveButton: { - backgroundColor: '#0f172a', - marginTop: 4, - }, - emptyCard: { - padding: 28, + emptyState: { alignItems: 'center', - gap: 10, + padding: 40, + gap: 12, + }, + emptyIcon: { + fontSize: 48, + marginBottom: 8, }, emptyTitle: { - color: '#0f172a', + color: '#f8fafc', fontSize: 18, - fontWeight: '900', + fontWeight: '800', textAlign: 'center', }, emptyText: {