From 651cba733d2b7bd0d5ebce2aff344d4ce53bf226 Mon Sep 17 00:00:00 2001 From: MrPiglr Date: Mon, 12 Jan 2026 03:28:16 +0000 Subject: [PATCH] feat: Add sleek mobile-first design and Astro landing site - Update design tokens with dark gaming theme (OLED-friendly) - Pure black backgrounds (#000000) - Cyan primary (#00d9ff) and neon green accent (#00ff88) - Glassmorphism effects and mobile-specific tokens - Build complete React Native mobile app screens - HomeScreen: Chat list with dark cards and status indicators - MessagesScreen: Chat view with gradient bubbles and typing indicators - FriendsScreen: Friend list with online/offline sections and game presence - GamesScreen: GameForge projects with team channels - ProfileScreen: User profile with .aethex domain display - AppNavigator: Bottom tab navigation with glow effects - Create Astro marketing landing site - Hero section with animated gradients and phone mockup - Features showcase (6 cards) - Pricing tiers (Free/Premium/Enterprise) - Download section for all platforms - Fully responsive dark theme Design inspiration: BitChat, Root, Discord Dark, Telegram Mobile-first approach with 48px touch targets and safe areas --- astro-site/README.md | 67 ++++ astro-site/astro.config.mjs | 7 + astro-site/package.json | 17 + astro-site/src/components/Features.astro | 136 +++++++ astro-site/src/components/Hero.astro | 250 +++++++++++++ astro-site/src/components/Pricing.astro | 225 ++++++++++++ astro-site/src/layouts/Layout.astro | 35 ++ astro-site/src/pages/index.astro | 275 ++++++++++++++ astro-site/tailwind.config.mjs | 22 ++ .../mobile/src/navigation/AppNavigator.tsx | 120 ++++++ packages/mobile/src/screens/FriendsScreen.tsx | 222 +++++++++++ packages/mobile/src/screens/GamesScreen.tsx | 221 +++++++++++ packages/mobile/src/screens/HomeScreen.tsx | 267 ++++++++++++++ .../mobile/src/screens/MessagesScreen.tsx | 347 ++++++++++++++++++ packages/mobile/src/screens/ProfileScreen.tsx | 226 ++++++++++++ packages/mobile/src/theme/index.ts | 150 ++++++++ packages/ui/styles/tokens.ts | 243 ++++++++---- 17 files changed, 2762 insertions(+), 68 deletions(-) create mode 100644 astro-site/README.md create mode 100644 astro-site/astro.config.mjs create mode 100644 astro-site/package.json create mode 100644 astro-site/src/components/Features.astro create mode 100644 astro-site/src/components/Hero.astro create mode 100644 astro-site/src/components/Pricing.astro create mode 100644 astro-site/src/layouts/Layout.astro create mode 100644 astro-site/src/pages/index.astro create mode 100644 astro-site/tailwind.config.mjs create mode 100644 packages/mobile/src/navigation/AppNavigator.tsx create mode 100644 packages/mobile/src/screens/FriendsScreen.tsx create mode 100644 packages/mobile/src/screens/GamesScreen.tsx create mode 100644 packages/mobile/src/screens/HomeScreen.tsx create mode 100644 packages/mobile/src/screens/MessagesScreen.tsx create mode 100644 packages/mobile/src/screens/ProfileScreen.tsx create mode 100644 packages/mobile/src/theme/index.ts diff --git a/astro-site/README.md b/astro-site/README.md new file mode 100644 index 0000000..59fb4c3 --- /dev/null +++ b/astro-site/README.md @@ -0,0 +1,67 @@ +# AeThex Connect - Astro Landing Site + +Modern, sleek landing page for AeThex Connect built with Astro and Tailwind CSS. + +## Quick Start + +```bash +# Install dependencies +npm install + +# Start development server +npm run dev + +# Build for production +npm run build + +# Preview production build +npm run preview +``` + +## Structure + +``` +astro-site/ +├── src/ +│ ├── pages/ +│ │ └── index.astro # Homepage +│ ├── components/ +│ │ ├── Hero.astro # Hero section with phone mockup +│ │ ├── Features.astro # Feature cards +│ │ └── Pricing.astro # Pricing tiers +│ └── layouts/ +│ └── Layout.astro # Base layout +├── public/ # Static assets +├── astro.config.mjs +├── tailwind.config.mjs +└── package.json +``` + +## Features + +- ⚡ Lightning-fast static site generation +- 🎨 Sleek dark gaming theme +- 📱 Mobile-first responsive design +- ✨ Animated gradients and smooth transitions +- 🎯 SEO optimized +- 🚀 Ready to deploy (Vercel, Netlify, Cloudflare Pages) + +## Deploy + +### Vercel +```bash +npm i -g vercel +vercel +``` + +### Netlify +```bash +npm i -g netlify-cli +netlify deploy +``` + +### Cloudflare Pages +Connect your GitHub repo to Cloudflare Pages dashboard. + +Build command: `npm run build` +Output directory: `dist` diff --git a/astro-site/astro.config.mjs b/astro-site/astro.config.mjs new file mode 100644 index 0000000..6738d35 --- /dev/null +++ b/astro-site/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import tailwind from '@astrojs/tailwind'; + +export default defineConfig({ + integrations: [tailwind()], + site: 'https://aethex-connect.com', +}); diff --git a/astro-site/package.json b/astro-site/package.json new file mode 100644 index 0000000..0ab79c8 --- /dev/null +++ b/astro-site/package.json @@ -0,0 +1,17 @@ +{ + "name": "aethex-connect-site", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview" + }, + "dependencies": { + "astro": "^4.0.0" + }, + "devDependencies": { + "@astrojs/tailwind": "^5.0.0", + "tailwindcss": "^3.4.0" + } +} diff --git a/astro-site/src/components/Features.astro b/astro-site/src/components/Features.astro new file mode 100644 index 0000000..a2442ab --- /dev/null +++ b/astro-site/src/components/Features.astro @@ -0,0 +1,136 @@ +--- +// Features showcase +const features = [ + { + icon: '🔐', + title: 'Own Your Identity', + description: 'Your .aethex domain is an NFT. It\'s yours forever. No company can take it away.', + }, + { + icon: '💬', + title: 'Cross-Game Chat', + description: 'Voice and text that follows you across every game. Start in Valorant, join in Fortnite.', + }, + { + icon: '🎮', + title: 'GameForge Integration', + description: 'Building a game? Auto-created team channels with role-based access for your dev team.', + }, + { + icon: '📞', + title: 'Crystal Clear Calls', + description: 'Low-latency voice optimized for competitive gaming. HD video with screen sharing.', + }, + { + icon: '👥', + title: 'Persistent Friends', + description: 'See which games your friends are playing. Join their lobbies with one click.', + }, + { + icon: '💎', + title: 'Premium Tiers', + description: 'Free tier to get started. Premium for serious gamers. Enterprise for game studios.', + }, +]; +--- + +
+
+
+

Built for Gamers

+

Everything you need to stay connected with your squad across all games.

+
+ +
+ {features.map(feature => ( +
+
{feature.icon}
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ + diff --git a/astro-site/src/components/Hero.astro b/astro-site/src/components/Hero.astro new file mode 100644 index 0000000..ad4ffbc --- /dev/null +++ b/astro-site/src/components/Hero.astro @@ -0,0 +1,250 @@ +--- +// Hero component with animated gradient +--- + +
+
+
+

+ Chat Across All Games +

+

+ Your gaming identity and friends follow you everywhere. + Own your .aethex domain, connect with your squad across every game. +

+ +

+ Available on iOS, Android, Windows, macOS & Linux +

+
+ +
+
+
+
+
+ 🎮 +
+
Squad Goals
+
Let's run Valorant
+
+ 3 +
+
+ 👤 +
+
john.aethex
+
yo wanna play?
+
+
+
+
+
+
+
+
+ + diff --git a/astro-site/src/components/Pricing.astro b/astro-site/src/components/Pricing.astro new file mode 100644 index 0000000..6fff72d --- /dev/null +++ b/astro-site/src/components/Pricing.astro @@ -0,0 +1,225 @@ +--- +// Pricing section +const tiers = [ + { + name: 'Free', + price: '$0', + period: 'forever', + features: [ + '5 friends maximum', + 'Basic text messaging', + 'Subdomain identity', + '100 MB storage', + 'Community support', + ], + cta: 'Get Started', + highlight: false, + }, + { + name: 'Premium', + price: '$100', + period: 'per year', + features: [ + 'Blockchain .aethex domain (NFT)', + 'Unlimited friends', + 'HD voice & video (1080p)', + '10 GB storage', + 'Priority support', + 'Custom profile branding', + ], + cta: 'Go Premium', + highlight: true, + }, + { + name: 'Enterprise', + price: 'Custom', + period: 'contact us', + features: [ + 'Everything in Premium', + 'White-label platform', + 'Custom domain', + 'Unlimited storage', + '99.9% SLA guarantee', + 'Dedicated account manager', + ], + cta: 'Contact Sales', + highlight: false, + }, +]; +--- + +
+
+
+

Choose Your Tier

+

Start free, upgrade when you're ready.

+
+ +
+ {tiers.map(tier => ( +
+ {tier.highlight && } +
{tier.name}
+
+ {tier.price} + /{tier.period} +
+
    + {tier.features.map(feature => ( +
  • ✓ {feature}
  • + ))} +
+ + {tier.cta} + +
+ ))} +
+
+
+ + diff --git a/astro-site/src/layouts/Layout.astro b/astro-site/src/layouts/Layout.astro new file mode 100644 index 0000000..ab10917 --- /dev/null +++ b/astro-site/src/layouts/Layout.astro @@ -0,0 +1,35 @@ +--- +const { title = 'AeThex Connect - Gaming Communication Platform' } = Astro.props; +--- + + + + + + + {title} + + + + + + + + + diff --git a/astro-site/src/pages/index.astro b/astro-site/src/pages/index.astro new file mode 100644 index 0000000..992bc97 --- /dev/null +++ b/astro-site/src/pages/index.astro @@ -0,0 +1,275 @@ +--- +import Layout from '../layouts/Layout.astro'; +import Hero from '../components/Hero.astro'; +import Features from '../components/Features.astro'; +import Pricing from '../components/Pricing.astro'; +--- + + +
+ + + + + +
+ +
+ + + +
+
+ + diff --git a/astro-site/tailwind.config.mjs b/astro-site/tailwind.config.mjs new file mode 100644 index 0000000..f4f6b02 --- /dev/null +++ b/astro-site/tailwind.config.mjs @@ -0,0 +1,22 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], + theme: { + extend: { + colors: { + primary: '#00d9ff', + accent: '#00ff88', + secondary: '#a855f7', + dark: { + bg: '#000000', + card: '#0f0f0f', + elevated: '#1a1a1a', + }, + }, + fontFamily: { + sans: ['-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'sans-serif'], + }, + }, + }, + plugins: [], +}; diff --git a/packages/mobile/src/navigation/AppNavigator.tsx b/packages/mobile/src/navigation/AppNavigator.tsx new file mode 100644 index 0000000..bdfaf60 --- /dev/null +++ b/packages/mobile/src/navigation/AppNavigator.tsx @@ -0,0 +1,120 @@ +/** + * App Navigator + * Bottom tab navigation with sleek design + */ + +import React from 'react'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import { NavigationContainer } from '@react-navigation/native'; +import { StyleSheet, View, Text } from 'react-native'; +import { theme } from '../theme'; + +// Screens +import HomeScreen from '../screens/HomeScreen'; +import MessagesScreen from '../screens/MessagesScreen'; +import GamesScreen from '../screens/GamesScreen'; +import FriendsScreen from '../screens/FriendsScreen'; +import ProfileScreen from '../screens/ProfileScreen'; + +const Tab = createBottomTabNavigator(); + +const TabIcon = ({ focused, emoji }: { focused: boolean; emoji: string }) => ( + + {emoji} + +); + +export default function AppNavigator() { + return ( + + + , + }} + /> + , + tabBarBadge: 3, // Unread count + }} + /> + , + }} + /> + , + }} + /> + , + }} + /> + + + ); +} + +const styles = StyleSheet.create({ + tabBar: { + backgroundColor: theme.colors.background, + borderTopWidth: 1, + borderTopColor: theme.colors.gray900, + height: theme.layout.tabBarHeight, + paddingBottom: 8, + paddingTop: 8, + }, + tabLabel: { + fontSize: theme.typography.fontSize.xs, + fontWeight: theme.typography.fontWeight.medium, + }, + tabIcon: { + width: 40, + height: 40, + borderRadius: theme.borderRadius.md, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'transparent', + }, + tabIconActive: { + backgroundColor: theme.colors.backgroundTertiary, + ...theme.shadows.glow, + }, + tabEmoji: { + fontSize: 24, + }, +}); diff --git a/packages/mobile/src/screens/FriendsScreen.tsx b/packages/mobile/src/screens/FriendsScreen.tsx new file mode 100644 index 0000000..bb6a723 --- /dev/null +++ b/packages/mobile/src/screens/FriendsScreen.tsx @@ -0,0 +1,222 @@ +/** + * Friends Screen + * Cross-game friends list with status + */ + +import React, { useState } from 'react'; +import { + View, + Text, + StyleSheet, + FlatList, + TouchableOpacity, + SafeAreaView, + SectionList, +} from 'react-native'; +import { theme } from '../theme'; + +interface Friend { + id: string; + username: string; + status: 'online' | 'offline' | 'idle' | 'dnd'; + game?: string; + avatar: string; +} + +export default function FriendsScreen({ navigation }: any) { + const [friends] = useState([ + { id: '1', username: 'john.aethex', status: 'online', game: 'Valorant', avatar: 'J' }, + { id: '2', username: 'sarah.aethex', status: 'online', game: 'Fortnite', avatar: 'S' }, + { id: '3', username: 'mike.aethex', status: 'idle', avatar: 'M' }, + { id: '4', username: 'alex.aethex', status: 'offline', avatar: 'A' }, + ]); + + const onlineFriends = friends.filter(f => f.status === 'online'); + const offlineFriends = friends.filter(f => f.status !== 'online'); + + const sections = [ + { title: `ONLINE (${onlineFriends.length})`, data: onlineFriends }, + { title: `OFFLINE (${offlineFriends.length})`, data: offlineFriends }, + ]; + + const getStatusColor = (status: Friend['status']) => { + switch (status) { + case 'online': return theme.colors.online; + case 'idle': return theme.colors.idle; + case 'dnd': return theme.colors.dnd; + default: return theme.colors.offline; + } + }; + + const renderFriend = ({ item }: { item: Friend }) => ( + + + + {item.avatar} + + + + + {item.username} + {item.game && ( + + 🎮 + Playing {item.game} + + )} + {!item.game && item.status === 'offline' && ( + Last seen 2h ago + )} + + + + 💬 + + {item.status === 'online' && ( + + 📞 + + )} + + + ); + + return ( + + + Friends + + + + + + ( + + {section.title} + + )} + keyExtractor={(item) => item.id} + contentContainerStyle={styles.listContent} + stickySectionHeadersEnabled={false} + /> + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: theme.colors.background, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.md, + }, + headerTitle: { + fontSize: theme.typography.fontSize.xxl, + fontWeight: theme.typography.fontWeight.bold, + color: theme.colors.text, + }, + addButton: { + width: theme.layout.touchTarget, + height: theme.layout.touchTarget, + justifyContent: 'center', + alignItems: 'center', + }, + addIcon: { + fontSize: 24, + }, + listContent: { + paddingHorizontal: theme.spacing.md, + }, + sectionHeader: { + paddingVertical: theme.spacing.md, + }, + sectionTitle: { + fontSize: theme.typography.fontSize.sm, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.textTertiary, + letterSpacing: 0.5, + }, + friendCard: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.lg, + padding: theme.spacing.md, + marginBottom: theme.spacing.md, + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.05)', + }, + avatarContainer: { + position: 'relative', + marginRight: theme.spacing.md, + }, + avatar: { + width: 48, + height: 48, + borderRadius: theme.borderRadius.full, + backgroundColor: theme.colors.primary, + justifyContent: 'center', + alignItems: 'center', + }, + avatarText: { + fontSize: 20, + fontWeight: theme.typography.fontWeight.bold, + color: '#000', + }, + statusDot: { + position: 'absolute', + bottom: 0, + right: 0, + width: 14, + height: 14, + borderRadius: 7, + borderWidth: 2, + borderColor: theme.colors.card, + }, + friendInfo: { + flex: 1, + }, + username: { + fontSize: theme.typography.fontSize.base, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.text, + marginBottom: 4, + }, + gameRow: { + flexDirection: 'row', + alignItems: 'center', + }, + gameIcon: { + fontSize: 14, + marginRight: 4, + }, + gameText: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + }, + lastSeen: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textTertiary, + }, + actions: { + flexDirection: 'row', + }, + actionButton: { + width: 40, + height: 40, + justifyContent: 'center', + alignItems: 'center', + marginLeft: theme.spacing.sm, + }, + actionIcon: { + fontSize: 20, + }, +}); diff --git a/packages/mobile/src/screens/GamesScreen.tsx b/packages/mobile/src/screens/GamesScreen.tsx new file mode 100644 index 0000000..11b4b0f --- /dev/null +++ b/packages/mobile/src/screens/GamesScreen.tsx @@ -0,0 +1,221 @@ +/** + * Games Screen (GameForge) + * Game development projects and team channels + */ + +import React, { useState } from 'react'; +import { + View, + Text, + StyleSheet, + ScrollView, + TouchableOpacity, + SafeAreaView, +} from 'react-native'; +import { theme } from '../theme'; + +export default function GamesScreen() { + return ( + + + GameForge Projects + + + + + + + {/* Project Card */} + + + 🎮 + + Project Phoenix + 5 members • 3 online + + + + + {['#general', '#dev', '#art', '#test'].map(channel => ( + + {channel} + + ))} + + + + 🔴 + Build failed 2m ago + + + + {/* Another Project */} + + + 🎮 + + Indie Shooter + 2 members • 1 online + + + + + {['#general', '#dev'].map(channel => ( + + {channel} + + ))} + + + + {/* Team Status */} + + TEAM STATUS + + {[ + { name: 'sarah.aethex', role: 'Developer', online: true }, + { name: 'mike.aethex', role: 'Artist', online: true }, + { name: 'alex.aethex', role: 'Designer', online: false }, + ].map(member => ( + + + {member.name} + ({member.role}) + + ))} + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: theme.colors.background, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.md, + }, + headerTitle: { + fontSize: theme.typography.fontSize.xxl, + fontWeight: theme.typography.fontWeight.bold, + color: theme.colors.text, + }, + addButton: { + width: theme.layout.touchTarget, + height: theme.layout.touchTarget, + justifyContent: 'center', + alignItems: 'center', + }, + addIcon: { + fontSize: 24, + }, + content: { + padding: theme.spacing.md, + }, + projectCard: { + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.lg, + padding: theme.spacing.lg, + marginBottom: theme.spacing.md, + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.05)', + }, + projectHeader: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: theme.spacing.md, + }, + projectIcon: { + fontSize: 32, + marginRight: theme.spacing.md, + }, + projectInfo: { + flex: 1, + }, + projectName: { + fontSize: theme.typography.fontSize.lg, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.text, + marginBottom: 4, + }, + projectMeta: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + }, + channels: { + flexDirection: 'row', + flexWrap: 'wrap', + marginBottom: theme.spacing.md, + }, + channelButton: { + backgroundColor: theme.colors.backgroundSecondary, + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.sm, + borderRadius: theme.borderRadius.base, + marginRight: theme.spacing.sm, + marginBottom: theme.spacing.sm, + }, + channelText: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + }, + notification: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: 'rgba(239, 68, 68, 0.1)', + padding: theme.spacing.sm, + borderRadius: theme.borderRadius.base, + }, + notificationDot: { + fontSize: 12, + marginRight: theme.spacing.sm, + }, + notificationText: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.error, + }, + section: { + marginTop: theme.spacing.lg, + }, + sectionTitle: { + fontSize: theme.typography.fontSize.sm, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.textTertiary, + marginBottom: theme.spacing.md, + letterSpacing: 0.5, + }, + teamList: { + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.lg, + padding: theme.spacing.md, + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.05)', + }, + teamMember: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: theme.spacing.sm, + }, + memberDot: { + width: 8, + height: 8, + borderRadius: 4, + marginRight: theme.spacing.sm, + }, + memberName: { + fontSize: theme.typography.fontSize.base, + color: theme.colors.text, + marginRight: theme.spacing.sm, + }, + memberRole: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + }, +}); diff --git a/packages/mobile/src/screens/HomeScreen.tsx b/packages/mobile/src/screens/HomeScreen.tsx new file mode 100644 index 0000000..3a05d73 --- /dev/null +++ b/packages/mobile/src/screens/HomeScreen.tsx @@ -0,0 +1,267 @@ +/** + * Home Screen (Chat List) + * Main conversation list with sleek dark design + */ + +import React, { useState, useEffect } from 'react'; +import { + View, + Text, + StyleSheet, + FlatList, + TouchableOpacity, + TextInput, + SafeAreaView, + StatusBar, +} from 'react-native'; +import { theme } from '../theme'; + +interface Conversation { + id: string; + name: string; + lastMessage: string; + timestamp: string; + unread: number; + isOnline: boolean; + isGroup: boolean; + avatar: string; +} + +export default function HomeScreen({ navigation }: any) { + const [conversations, setConversations] = useState([ + { + id: '1', + name: 'john.aethex', + lastMessage: 'yo wanna play valorant', + timestamp: '2:30 PM', + unread: 0, + isOnline: true, + isGroup: false, + avatar: '👤', + }, + { + id: '2', + name: 'Squad Goals', + lastMessage: "Sarah: let's go", + timestamp: '1:15 PM', + unread: 3, + isOnline: true, + isGroup: true, + avatar: '🎮', + }, + { + id: '3', + name: 'mike.aethex', + lastMessage: 'gg bro', + timestamp: 'Yesterday', + unread: 0, + isOnline: false, + isGroup: false, + avatar: '👤', + }, + { + id: '4', + name: 'Project Phoenix', + lastMessage: 'Dev team meeting 3pm', + timestamp: 'Yesterday', + unread: 0, + isOnline: true, + isGroup: true, + avatar: '🎮', + }, + ]); + + const renderConversation = ({ item }: { item: Conversation }) => ( + navigation.navigate('Chat', { conversation: item })} + activeOpacity={0.7} + > + + {/* Avatar with status */} + + + {item.avatar} + + {item.isOnline && } + + + {/* Message preview */} + + + + {item.name} + + {item.timestamp} + + + + {item.lastMessage} + + {item.unread > 0 && ( + + {item.unread} + + )} + + + + + ); + + return ( + + + + {/* Header */} + + + + + AeThex Connect + + 🔍 + + + + {/* Conversation List */} + item.id} + contentContainerStyle={styles.listContent} + showsVerticalScrollIndicator={false} + /> + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: theme.colors.background, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.md, + backgroundColor: theme.colors.background, + }, + headerTitle: { + fontSize: theme.typography.fontSize.xl, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.text, + flex: 1, + marginLeft: theme.spacing.md, + }, + menuButton: { + width: theme.layout.touchTarget, + height: theme.layout.touchTarget, + justifyContent: 'center', + alignItems: 'center', + }, + menuIcon: { + fontSize: 24, + color: theme.colors.text, + }, + searchButton: { + width: theme.layout.touchTarget, + height: theme.layout.touchTarget, + justifyContent: 'center', + alignItems: 'center', + }, + searchIcon: { + fontSize: 20, + }, + listContent: { + paddingHorizontal: theme.spacing.md, + paddingBottom: theme.spacing.xl, + }, + conversationCard: { + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.lg, + marginBottom: theme.spacing.md, + padding: theme.spacing.md, + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.05)', + }, + conversationContent: { + flexDirection: 'row', + alignItems: 'center', + }, + avatarContainer: { + position: 'relative', + marginRight: theme.spacing.md, + }, + avatar: { + width: 56, + height: 56, + borderRadius: theme.borderRadius.full, + backgroundColor: theme.colors.backgroundSecondary, + justifyContent: 'center', + alignItems: 'center', + borderWidth: 2, + borderColor: theme.colors.gray800, + }, + avatarEmoji: { + fontSize: 28, + }, + statusDot: { + position: 'absolute', + bottom: 2, + right: 2, + width: 14, + height: 14, + borderRadius: 7, + backgroundColor: theme.colors.online, + borderWidth: 2, + borderColor: theme.colors.card, + }, + messagePreview: { + flex: 1, + }, + headerRow: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: 4, + }, + conversationName: { + fontSize: theme.typography.fontSize.base, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.text, + flex: 1, + }, + timestamp: { + fontSize: theme.typography.fontSize.xs, + color: theme.colors.textTertiary, + marginLeft: theme.spacing.sm, + }, + lastMessageRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + lastMessage: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + flex: 1, + }, + unreadBadge: { + backgroundColor: theme.colors.primary, + borderRadius: theme.borderRadius.full, + paddingHorizontal: 8, + paddingVertical: 2, + marginLeft: theme.spacing.sm, + minWidth: 24, + alignItems: 'center', + ...theme.shadows.glow, + }, + unreadText: { + fontSize: theme.typography.fontSize.xs, + fontWeight: theme.typography.fontWeight.bold, + color: '#000', + }, +}); diff --git a/packages/mobile/src/screens/MessagesScreen.tsx b/packages/mobile/src/screens/MessagesScreen.tsx new file mode 100644 index 0000000..b18f89a --- /dev/null +++ b/packages/mobile/src/screens/MessagesScreen.tsx @@ -0,0 +1,347 @@ +/** + * Messages Screen (Chat View) + * Individual chat conversation with message bubbles + */ + +import React, { useState } from 'react'; +import { + View, + Text, + StyleSheet, + FlatList, + TextInput, + TouchableOpacity, + SafeAreaView, + KeyboardAvoidingView, + Platform, +} from 'react-native'; +import { theme } from '../theme'; + +interface Message { + id: string; + text: string; + timestamp: string; + isOwn: boolean; + status?: 'sent' | 'delivered' | 'read'; +} + +export default function MessagesScreen({ route, navigation }: any) { + const { conversation } = route?.params || { conversation: { name: 'john.aethex' } }; + + const [messages, setMessages] = useState([ + { + id: '1', + text: "hey what's up? 🎮", + timestamp: '2:28 PM', + isOwn: true, + status: 'read', + }, + { + id: '2', + text: 'yo wanna run some valorant?', + timestamp: '2:30 PM', + isOwn: false, + }, + { + id: '3', + text: 'bet, im in 🔥', + timestamp: '2:31 PM', + isOwn: true, + status: 'delivered', + }, + ]); + + const [inputText, setInputText] = useState(''); + const [isTyping] = useState(true); + + const renderMessage = ({ item }: { item: Message }) => ( + + + + {item.text} + + + + {item.timestamp} + {item.isOwn && ( + + {item.status === 'read' && '✓✓'} + {item.status === 'delivered' && '✓'} + {item.status === 'sent' && '•'} + + )} + + + ); + + const handleSend = () => { + if (inputText.trim()) { + const newMessage: Message = { + id: Date.now().toString(), + text: inputText.trim(), + timestamp: new Date().toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }), + isOwn: true, + status: 'sent', + }; + setMessages([...messages, newMessage]); + setInputText(''); + } + }; + + return ( + + + {/* Header */} + + navigation.goBack()} style={styles.backButton}> + + + + {conversation.name} + + + Online • Playing Valorant + + + + 📞 + + + 📹 + + + + {/* Messages List */} + item.id} + contentContainerStyle={styles.messagesList} + showsVerticalScrollIndicator={false} + inverted={false} + /> + + {/* Typing Indicator */} + {isTyping && ( + + {conversation.name} is typing... + + + + + + + )} + + {/* Input Bar */} + + + + + + + + 🎤 + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: theme.colors.background, + }, + keyboardView: { + flex: 1, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.sm, + backgroundColor: theme.colors.backgroundSecondary, + borderBottomWidth: 1, + borderBottomColor: theme.colors.gray900, + }, + backButton: { + width: 40, + height: 40, + justifyContent: 'center', + alignItems: 'center', + marginRight: theme.spacing.sm, + }, + backIcon: { + fontSize: 24, + color: theme.colors.primary, + }, + headerInfo: { + flex: 1, + }, + headerTitle: { + fontSize: theme.typography.fontSize.base, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.text, + }, + statusRow: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 2, + }, + onlineDot: { + width: 8, + height: 8, + borderRadius: 4, + backgroundColor: theme.colors.online, + marginRight: 6, + }, + statusText: { + fontSize: theme.typography.fontSize.xs, + color: theme.colors.textSecondary, + }, + iconButton: { + width: 40, + height: 40, + justifyContent: 'center', + alignItems: 'center', + marginLeft: theme.spacing.sm, + }, + callIcon: { + fontSize: 20, + }, + videoIcon: { + fontSize: 20, + }, + messagesList: { + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.lg, + }, + messageContainer: { + marginBottom: theme.spacing.md, + alignItems: 'flex-start', + maxWidth: '80%', + }, + messageContainerOwn: { + alignSelf: 'flex-end', + alignItems: 'flex-end', + }, + messageBubble: { + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.xl, + padding: theme.spacing.md, + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.05)', + }, + messageBubbleOwn: { + backgroundColor: 'transparent', + borderWidth: 0, + backgroundImage: `linear-gradient(135deg, ${theme.colors.primary}, ${theme.colors.secondary})`, + }, + messageText: { + fontSize: theme.typography.fontSize.base, + color: theme.colors.text, + lineHeight: 22, + }, + messageTextOwn: { + color: '#ffffff', + }, + messageFooter: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 4, + paddingHorizontal: theme.spacing.sm, + }, + messageFooterOwn: { + flexDirection: 'row-reverse', + }, + messageTimestamp: { + fontSize: theme.typography.fontSize.xs, + color: theme.colors.textTertiary, + }, + messageStatus: { + fontSize: theme.typography.fontSize.xs, + color: theme.colors.primary, + marginLeft: 4, + }, + typingContainer: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: theme.spacing.lg, + paddingVertical: theme.spacing.sm, + }, + typingText: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + marginRight: theme.spacing.sm, + }, + typingDots: { + flexDirection: 'row', + }, + dot: { + width: 6, + height: 6, + borderRadius: 3, + backgroundColor: theme.colors.textSecondary, + marginHorizontal: 2, + }, + dot1: {}, + dot2: {}, + dot3: {}, + inputContainer: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.md, + backgroundColor: theme.colors.backgroundSecondary, + borderTopWidth: 1, + borderTopColor: theme.colors.gray900, + }, + attachButton: { + width: 40, + height: 40, + borderRadius: theme.borderRadius.full, + backgroundColor: theme.colors.card, + justifyContent: 'center', + alignItems: 'center', + marginRight: theme.spacing.sm, + }, + attachIcon: { + fontSize: 24, + color: theme.colors.primary, + }, + input: { + flex: 1, + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.lg, + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.sm, + fontSize: theme.typography.fontSize.base, + color: theme.colors.text, + maxHeight: 100, + }, + sendButton: { + width: 40, + height: 40, + borderRadius: theme.borderRadius.full, + backgroundColor: theme.colors.card, + justifyContent: 'center', + alignItems: 'center', + marginLeft: theme.spacing.sm, + }, + sendIcon: { + fontSize: 20, + }, +}); diff --git a/packages/mobile/src/screens/ProfileScreen.tsx b/packages/mobile/src/screens/ProfileScreen.tsx new file mode 100644 index 0000000..5cfb9a5 --- /dev/null +++ b/packages/mobile/src/screens/ProfileScreen.tsx @@ -0,0 +1,226 @@ +/** + * Profile Screen + * User profile with .aethex domain and settings + */ + +import React from 'react'; +import { + View, + Text, + StyleSheet, + ScrollView, + TouchableOpacity, + SafeAreaView, +} from 'react-native'; +import { theme } from '../theme'; + +export default function ProfileScreen() { + return ( + + + Settings + + + + {/* Profile Section */} + + + A + + alice.aethex ✓ + Premium Member + + + {/* Domain Card */} + + 🌐 + + alice.aethex + NFT Token: 0x742f... + Owned since: Jan 2026 + + + View on Polygon → + + + + {/* Settings Sections */} + + ACCOUNT + + + + Premium + + + + + 🔔 + Notifications + + + + + 🔒 + Privacy + + + + + 🎮 + Connected Games + + + + + {/* About Section */} + + ABOUT + + + + Help & Support + + + + + 📄 + Terms & Privacy + + + + + {/* Version */} + Version 1.0.0 + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: theme.colors.background, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: theme.spacing.md, + paddingVertical: theme.spacing.md, + }, + headerTitle: { + fontSize: theme.typography.fontSize.xxl, + fontWeight: theme.typography.fontWeight.bold, + color: theme.colors.text, + }, + content: { + padding: theme.spacing.md, + }, + profileSection: { + alignItems: 'center', + paddingVertical: theme.spacing.xl, + }, + avatarLarge: { + width: 100, + height: 100, + borderRadius: 50, + backgroundColor: theme.colors.primary, + justifyContent: 'center', + alignItems: 'center', + marginBottom: theme.spacing.md, + ...theme.shadows.glow, + }, + avatarText: { + fontSize: 48, + fontWeight: theme.typography.fontWeight.bold, + color: '#000', + }, + username: { + fontSize: theme.typography.fontSize.xxl, + fontWeight: theme.typography.fontWeight.bold, + color: theme.colors.text, + marginBottom: 4, + }, + membershipBadge: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.secondary, + }, + domainCard: { + backgroundColor: theme.colors.card, + borderRadius: theme.borderRadius.lg, + padding: theme.spacing.lg, + marginBottom: theme.spacing.xl, + borderWidth: 1, + borderColor: theme.colors.primary + '30', + }, + domainIcon: { + fontSize: 32, + marginBottom: theme.spacing.md, + }, + domainInfo: { + marginBottom: theme.spacing.md, + }, + domainName: { + fontSize: theme.typography.fontSize.lg, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.text, + marginBottom: theme.spacing.sm, + }, + domainDetail: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textSecondary, + marginBottom: 4, + }, + domainButton: { + backgroundColor: theme.colors.backgroundSecondary, + padding: theme.spacing.md, + borderRadius: theme.borderRadius.base, + alignItems: 'center', + }, + domainButtonText: { + fontSize: theme.typography.fontSize.sm, + color: theme.colors.primary, + fontWeight: theme.typography.fontWeight.medium, + }, + section: { + marginBottom: theme.spacing.xl, + }, + sectionTitle: { + fontSize: theme.typography.fontSize.sm, + fontWeight: theme.typography.fontWeight.semibold, + color: theme.colors.textTertiary, + marginBottom: theme.spacing.md, + letterSpacing: 0.5, + }, + settingItem: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: theme.colors.card, + padding: theme.spacing.lg, + borderRadius: theme.borderRadius.lg, + marginBottom: theme.spacing.sm, + borderWidth: 1, + borderColor: 'rgba(255, 255, 255, 0.05)', + }, + settingIcon: { + fontSize: 20, + marginRight: theme.spacing.md, + width: 24, + }, + settingLabel: { + flex: 1, + fontSize: theme.typography.fontSize.base, + color: theme.colors.text, + }, + settingArrow: { + fontSize: 20, + color: theme.colors.textTertiary, + }, + version: { + textAlign: 'center', + fontSize: theme.typography.fontSize.sm, + color: theme.colors.textMuted, + marginTop: theme.spacing.xl, + marginBottom: theme.spacing.xxl, + }, +}); diff --git a/packages/mobile/src/theme/index.ts b/packages/mobile/src/theme/index.ts new file mode 100644 index 0000000..e4954f3 --- /dev/null +++ b/packages/mobile/src/theme/index.ts @@ -0,0 +1,150 @@ +/** + * Mobile Theme + * Imports design tokens and adapts for React Native + */ + +// Import design tokens from UI package +import { colors, spacing, typography, borderRadius, shadows } from '@aethex/ui'; + +export const theme = { + colors: { + // Background + background: colors.background.primary, + backgroundSecondary: colors.background.secondary, + backgroundTertiary: colors.background.tertiary, + + // Card + card: colors.background.tertiary, + cardElevated: colors.background.elevated, + + // Text + text: colors.text.primary, + textSecondary: colors.text.secondary, + textTertiary: colors.text.tertiary, + textMuted: colors.text.muted, + + // Brand + primary: colors.primary[500], + primaryLight: colors.primary[400], + primaryDark: colors.primary[600], + + accent: colors.accent[500], + accentLight: colors.accent[400], + accentDark: colors.accent[600], + + secondary: colors.secondary[500], + + // Semantic + success: colors.success, + warning: colors.warning, + error: colors.error, + info: colors.info, + + // Status + online: colors.status.online, + idle: colors.status.idle, + dnd: colors.status.dnd, + offline: colors.status.offline, + + // Effects + glass: colors.effects.glass, + glassBorder: colors.effects.glassBorder, + overlay: colors.effects.overlay, + + // Gray scale + gray50: colors.gray[50], + gray100: colors.gray[100], + gray200: colors.gray[200], + gray300: colors.gray[300], + gray400: colors.gray[400], + gray500: colors.gray[500], + gray600: colors.gray[600], + gray700: colors.gray[700], + gray800: colors.gray[800], + gray900: colors.gray[900], + gray950: colors.gray[950], + }, + + spacing: { + xs: 4, + sm: 8, + md: 16, + lg: 24, + xl: 32, + xxl: 48, + xxxl: 64, + }, + + typography: { + fontFamily: typography.fontFamily.sans, + + fontSize: { + xs: 12, + sm: 14, + base: 16, + lg: 18, + xl: 20, + xxl: 24, + xxxl: 28, + huge: 32, + }, + + fontWeight: { + light: '300' as const, + normal: '400' as const, + medium: '500' as const, + semibold: '600' as const, + bold: '700' as const, + }, + }, + + borderRadius: { + sm: 6, + base: 8, + md: 12, + lg: 16, + xl: 18, + xxl: 24, + full: 9999, + }, + + shadows: { + sm: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.3, + shadowRadius: 2, + elevation: 2, + }, + md: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.4, + shadowRadius: 8, + elevation: 4, + }, + lg: { + shadowColor: '#000', + shadowOffset: { width: 0, height: 8 }, + shadowOpacity: 0.5, + shadowRadius: 16, + elevation: 8, + }, + glow: { + shadowColor: colors.primary[500], + shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.4, + shadowRadius: 20, + elevation: 10, + }, + }, + + layout: { + headerHeight: 56, + tabBarHeight: 56, + touchTarget: 48, + messageBubbleMaxWidth: '80%', + }, +}; + +export type Theme = typeof theme; diff --git a/packages/ui/styles/tokens.ts b/packages/ui/styles/tokens.ts index 82d0d2e..c6881a3 100644 --- a/packages/ui/styles/tokens.ts +++ b/packages/ui/styles/tokens.ts @@ -1,71 +1,109 @@ /** * Design System Tokens * Shared design tokens across all platforms + * + * SLEEK DARK GAMING THEME + * Inspired by: BitChat, Root, Discord Dark, Telegram */ export const colors = { - // Brand colors + // Brand colors (Cyan primary - modern gaming) primary: { + 50: '#ecfeff', + 100: '#cffafe', + 200: '#a5f3fc', + 300: '#67e8f9', + 400: '#22d3ee', + 500: '#00d9ff', // Primary cyan + 600: '#00b8d9', + 700: '#0097b3', + 800: '#007a8f', + 900: '#006073', + }, + + // Accent colors (Neon green gaming) + accent: { + 50: '#f0fdf4', + 100: '#dcfce7', + 200: '#bbf7d0', + 300: '#86efac', + 400: '#4ade80', + 500: '#00ff88', // Neon green + 600: '#00e070', + 700: '#00c05d', + 800: '#009f4a', + 900: '#00803b', + }, + + // Secondary accent (Purple for premium) + secondary: { 50: '#faf5ff', 100: '#f3e8ff', 200: '#e9d5ff', 300: '#d8b4fe', 400: '#c084fc', - 500: '#a855f7', + 500: '#a855f7', // Premium purple 600: '#9333ea', 700: '#7e22ce', 800: '#6b21a8', 900: '#581c87', }, - // Accent colors - accent: { - 50: '#fdf4ff', - 100: '#fae8ff', - 200: '#f5d0fe', - 300: '#f0abfc', - 400: '#e879f9', - 500: '#d946ef', - 600: '#c026d3', - 700: '#a21caf', - 800: '#86198f', - 900: '#701a75', - }, - - // Neutral colors (dark theme) + // Neutral colors (OLED-friendly blacks) gray: { 50: '#fafafa', - 100: '#f4f4f5', - 200: '#e4e4e7', - 300: '#d4d4d8', - 400: '#a1a1aa', - 500: '#71717a', - 600: '#52525b', - 700: '#3f3f46', - 800: '#27272a', - 900: '#18181b', - 950: '#09090b', + 100: '#f5f5f5', + 200: '#e5e5e5', + 300: '#d4d4d4', + 400: '#a3a3a3', + 500: '#737373', + 600: '#525252', + 700: '#404040', + 800: '#262626', + 900: '#171717', + 950: '#0a0a0a', // Pure black for OLED }, // Semantic colors - success: '#22c55e', - warning: '#f59e0b', - error: '#ef4444', - info: '#3b82f6', + success: '#10b981', // Green + warning: '#f59e0b', // Orange + error: '#ef4444', // Red + info: '#00d9ff', // Cyan (matches primary) - // Background + // Background (OLED-optimized) background: { - primary: '#0a0a0f', - secondary: '#18181b', - tertiary: '#27272a', + primary: '#000000', // Pure black for OLED battery saving + secondary: '#0f0f0f', // Slightly elevated + tertiary: '#1a1a1a', // Cards + elevated: '#262626', // Modals/overlays }, - // Text + // Text (High contrast for readability) text: { - primary: '#e4e4e7', - secondary: '#a1a1aa', - tertiary: '#71717a', - muted: '#52525b', + primary: '#ffffff', // White + secondary: '#b0b0b0', // Light gray + tertiary: '#707070', // Medium gray + muted: '#505050', // Dark gray + disabled: '#3a3a3a', // Very dark gray + }, + + // Special effects + effects: { + glass: 'rgba(20, 20, 20, 0.7)', // Glassmorphism background + glassBorder: 'rgba(255, 255, 255, 0.1)', // Glass border + glow: 'rgba(0, 217, 255, 0.3)', // Cyan glow + glowGreen: 'rgba(0, 255, 136, 0.3)', // Green glow + glowPurple: 'rgba(168, 85, 247, 0.3)', // Purple glow + overlay: 'rgba(0, 0, 0, 0.8)', // Dark overlay + overlayLight: 'rgba(0, 0, 0, 0.5)', // Lighter overlay + }, + + // Status indicators + status: { + online: '#3ba55c', // Discord green + idle: '#faa61a', // Yellow + dnd: '#ed4245', // Red + offline: '#747f8d', // Gray }, }; @@ -79,7 +117,8 @@ export const spacing = { 6: '1.5rem', // 24px 8: '2rem', // 32px 10: '2.5rem', // 40px - 12: '3rem', // 48px + 12: '3rem', // 48px - Touch target minimum + 14: '3.5rem', // 56px - Bottom nav height 16: '4rem', // 64px 20: '5rem', // 80px 24: '6rem', // 96px @@ -87,23 +126,25 @@ export const spacing = { export const typography = { fontFamily: { + // Use native system fonts for best mobile performance sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif', - mono: '"Fira Code", Consolas, Monaco, "Courier New", monospace', + mono: 'ui-monospace, "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace', }, fontSize: { - xs: '0.75rem', // 12px - sm: '0.875rem', // 14px - base: '1rem', // 16px - lg: '1.125rem', // 18px - xl: '1.25rem', // 20px - '2xl': '1.5rem', // 24px - '3xl': '1.875rem', // 30px - '4xl': '2.25rem', // 36px - '5xl': '3rem', // 48px + xs: '0.75rem', // 12px - Captions, timestamps + sm: '0.875rem', // 14px - Labels, secondary text + base: '1rem', // 16px - Body text (mobile readable) + lg: '1.125rem', // 18px - Emphasized text + xl: '1.25rem', // 20px - Subheadings + '2xl': '1.5rem', // 24px - Section headers + '3xl': '1.75rem', // 28px - Screen titles + '4xl': '2rem', // 32px - Hero text + '5xl': '2.5rem', // 40px - Large hero }, fontWeight: { + light: 300, normal: 400, medium: 500, semibold: 600, @@ -114,7 +155,7 @@ export const typography = { none: 1, tight: 1.25, snug: 1.375, - normal: 1.5, + normal: 1.5, // Default for readability relaxed: 1.625, loose: 2, }, @@ -122,33 +163,44 @@ export const typography = { export const borderRadius = { none: '0', - sm: '0.25rem', // 4px + sm: '0.375rem', // 6px base: '0.5rem', // 8px md: '0.75rem', // 12px - lg: '1rem', // 16px - xl: '1.5rem', // 24px - full: '9999px', + lg: '1rem', // 16px - Message bubbles + xl: '1.125rem', // 18px - Message bubbles rounded + '2xl': '1.5rem', // 24px - Cards + full: '9999px', // Pills }; export const shadows = { - sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', - base: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', - md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', - lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', - xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', - glow: '0 0 20px rgba(139, 92, 246, 0.4)', + // Subtle shadows for dark theme + sm: '0 1px 2px 0 rgba(0, 0, 0, 0.3)', + base: '0 2px 4px 0 rgba(0, 0, 0, 0.4)', + md: '0 4px 8px -2px rgba(0, 0, 0, 0.5)', + lg: '0 8px 16px -4px rgba(0, 0, 0, 0.6)', + xl: '0 16px 32px -8px rgba(0, 0, 0, 0.7)', + '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.8)', + + // Glow effects for gaming aesthetic + glowCyan: '0 0 20px rgba(0, 217, 255, 0.4)', + glowCyanStrong: '0 0 30px rgba(0, 217, 255, 0.6)', + glowGreen: '0 0 20px rgba(0, 255, 136, 0.4)', + glowPurple: '0 0 20px rgba(168, 85, 247, 0.4)', + glowSubtle: '0 0 10px rgba(255, 255, 255, 0.1)', }; export const breakpoints = { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - '2xl': '1536px', + // Mobile-first breakpoints + xs: '375px', // Small phones + sm: '640px', // Large phones + md: '768px', // Tablets + lg: '1024px', // Small laptops + xl: '1280px', // Desktop + '2xl': '1536px', // Large desktop }; export const zIndex = { + base: 0, dropdown: 1000, sticky: 1100, fixed: 1200, @@ -156,6 +208,7 @@ export const zIndex = { modal: 1400, popover: 1500, tooltip: 1600, + toast: 1700, }; export const transitions = { @@ -163,4 +216,58 @@ export const transitions = { base: '200ms cubic-bezier(0.4, 0, 0.2, 1)', slow: '300ms cubic-bezier(0.4, 0, 0.2, 1)', slower: '500ms cubic-bezier(0.4, 0, 0.2, 1)', + + // Easing functions + easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)', + easeOut: 'cubic-bezier(0, 0, 0.2, 1)', + easeIn: 'cubic-bezier(0.4, 0, 1, 1)', + spring: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)', +}; + +// Mobile-specific tokens +export const mobile = { + touchTarget: { + minimum: '44px', // iOS HIG minimum + comfortable: '48px', // Material Design + large: '56px', // Bottom nav, FABs + }, + + safeArea: { + top: 'env(safe-area-inset-top)', + bottom: 'env(safe-area-inset-bottom)', + left: 'env(safe-area-inset-left)', + right: 'env(safe-area-inset-right)', + }, + + statusBar: { + height: '44px', // iOS status bar + heightAndroid: '24px', + }, + + navbar: { + height: '56px', // Standard mobile nav + heightLarge: '64px', // Large title nav + }, + + tabBar: { + height: '56px', // Bottom tab bar + heightSafe: 'calc(56px + env(safe-area-inset-bottom))', + }, +}; + +// Glassmorphism effect tokens +export const glass = { + blur: '20px', + blurStrong: '30px', + blurSubtle: '10px', + + background: { + light: 'rgba(255, 255, 255, 0.05)', + medium: 'rgba(255, 255, 255, 0.1)', + dark: 'rgba(0, 0, 0, 0.3)', + darker: 'rgba(0, 0, 0, 0.5)', + }, + + border: 'rgba(255, 255, 255, 0.1)', + borderBright: 'rgba(255, 255, 255, 0.2)', };