diff --git a/apps/rebreak-native/app/(app)/chat.tsx b/apps/rebreak-native/app/(app)/chat.tsx
index 2d713c0..8c2209e 100644
--- a/apps/rebreak-native/app/(app)/chat.tsx
+++ b/apps/rebreak-native/app/(app)/chat.tsx
@@ -17,7 +17,7 @@ import { apiFetch } from '../../lib/api';
import { AppHeader } from '../../components/AppHeader';
import { RoomCard, type Room } from '../../components/chat/RoomCard';
import { CreateRoomSheet } from '../../components/chat/CreateRoomSheet';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
type DmConversation = {
partnerId: string;
@@ -39,6 +39,8 @@ function formatTime(ts: string, justNowLabel: string): string {
function DmItem({ conv, onPress }: { conv: DmConversation; onPress: () => void }) {
const { t } = useTranslation();
+ const colors = useColors();
+ const styles = makeStyles(colors);
const hasUnread = conv.unreadCount > 0;
return (
@@ -95,6 +97,8 @@ function DmItem({ conv, onPress }: { conv: DmConversation; onPress: () => void }
export default function ChatScreen() {
const { t } = useTranslation();
const router = useRouter();
+ const colors = useColors();
+ const styles = makeStyles(colors);
const [tab, setTab] = useState<'groups' | 'direct'>('groups');
const [createOpen, setCreateOpen] = useState(false);
@@ -199,13 +203,13 @@ export default function ChatScreen() {
}
ListEmptyComponent={
loadingRooms ? (
-
+
) : (
@@ -225,13 +229,13 @@ export default function ChatScreen() {
}
ListEmptyComponent={
loadingDms ? (
-
+
) : (
@@ -257,154 +261,155 @@ export default function ChatScreen() {
);
}
-const styles = StyleSheet.create({
- container: { flex: 1, backgroundColor: '#fafafa' },
- headerSection: {
- paddingHorizontal: 16,
- paddingTop: 14,
- paddingBottom: 10,
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#e5e5e5',
- },
- titleRow: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- },
- title: {
- fontSize: 22,
- fontFamily: 'Nunito_800ExtraBold',
- color: '#171717',
- },
- createBtn: {
- width: 34,
- height: 34,
- borderRadius: 17,
- backgroundColor: '#007AFF',
- alignItems: 'center',
- justifyContent: 'center',
- },
- tabs: {
- flexDirection: 'row',
- marginTop: 12,
- backgroundColor: '#f5f5f5',
- borderRadius: 10,
- padding: 3,
- },
- tab: {
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- paddingVertical: 7,
- borderRadius: 8,
- },
- tabActive: {
- backgroundColor: '#fff',
- shadowColor: '#000',
- shadowOpacity: 0.05,
- shadowRadius: 2,
- shadowOffset: { width: 0, height: 1 },
- },
- tabText: {
- fontSize: 12,
- fontFamily: 'Nunito_600SemiBold',
- color: '#737373',
- marginLeft: 5,
- },
- tabTextActive: {
- color: '#007AFF',
- fontFamily: 'Nunito_700Bold',
- },
- tabBadge: {
- minWidth: 16,
- height: 16,
- borderRadius: 8,
- backgroundColor: '#007AFF',
- paddingHorizontal: 4,
- alignItems: 'center',
- justifyContent: 'center',
- marginLeft: 5,
- },
- tabBadgeText: {
- fontSize: 9,
- fontFamily: 'Nunito_700Bold',
- color: '#fff',
- },
- emptyBox: {
- alignItems: 'center',
- justifyContent: 'center',
- paddingVertical: 60,
- paddingHorizontal: 32,
- },
- emptyText: {
- fontSize: 13,
- fontFamily: 'Nunito_600SemiBold',
- color: '#a3a3a3',
- marginTop: 12,
- },
- // DM row styles
- dmRow: {
- width: '100%',
- flexDirection: 'row',
- alignItems: 'center',
- paddingHorizontal: 14,
- paddingVertical: 11,
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#f5f5f5',
- },
- dmAvatar: {
- width: 42,
- height: 42,
- borderRadius: 21,
- backgroundColor: '#e5e5e5',
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- marginRight: 10,
- },
- dmAvatarImg: { width: 42, height: 42 },
- dmAvatarInitials: {
- fontSize: 13,
- fontFamily: 'Nunito_700Bold',
- color: '#525252',
- },
- dmInfo: { flex: 1, minWidth: 0 },
- dmHeaderRow: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- },
- dmName: {
- fontSize: 14,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- flexShrink: 1,
- marginRight: 6,
- },
- dmTime: { fontSize: 11, fontFamily: 'Nunito_600SemiBold' },
- dmBottomRow: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- marginTop: 2,
- },
- dmLast: { fontSize: 12, flex: 1 },
- unreadBadge: {
- minWidth: 20,
- height: 20,
- paddingHorizontal: 6,
- borderRadius: 10,
- backgroundColor: '#007AFF',
- alignItems: 'center',
- justifyContent: 'center',
- marginLeft: 8,
- },
- unreadBadgeText: {
- fontSize: 10,
- fontFamily: 'Nunito_700Bold',
- color: '#fff',
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ container: { flex: 1, backgroundColor: colors.bg },
+ headerSection: {
+ paddingHorizontal: 16,
+ paddingTop: 14,
+ paddingBottom: 10,
+ backgroundColor: colors.bg,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ titleRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ },
+ title: {
+ fontSize: 22,
+ fontFamily: 'Nunito_800ExtraBold',
+ color: colors.text,
+ },
+ createBtn: {
+ width: 34,
+ height: 34,
+ borderRadius: 17,
+ backgroundColor: '#007AFF',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ tabs: {
+ flexDirection: 'row',
+ marginTop: 12,
+ backgroundColor: colors.surfaceElevated,
+ borderRadius: 10,
+ padding: 3,
+ },
+ tab: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 7,
+ borderRadius: 8,
+ },
+ tabActive: {
+ backgroundColor: colors.surface,
+ shadowColor: '#000',
+ shadowOpacity: 0.05,
+ shadowRadius: 2,
+ shadowOffset: { width: 0, height: 1 },
+ },
+ tabText: {
+ fontSize: 12,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.textMuted,
+ marginLeft: 5,
+ },
+ tabTextActive: {
+ color: '#007AFF',
+ fontFamily: 'Nunito_700Bold',
+ },
+ tabBadge: {
+ minWidth: 16,
+ height: 16,
+ borderRadius: 8,
+ backgroundColor: '#007AFF',
+ paddingHorizontal: 4,
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginLeft: 5,
+ },
+ tabBadgeText: {
+ fontSize: 9,
+ fontFamily: 'Nunito_700Bold',
+ color: '#fff',
+ },
+ emptyBox: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 60,
+ paddingHorizontal: 32,
+ },
+ emptyText: {
+ fontSize: 13,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.textMuted,
+ marginTop: 12,
+ },
+ dmRow: {
+ width: '100%',
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 14,
+ paddingVertical: 11,
+ backgroundColor: colors.bg,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ dmAvatar: {
+ width: 42,
+ height: 42,
+ borderRadius: 21,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ overflow: 'hidden',
+ marginRight: 10,
+ },
+ dmAvatarImg: { width: 42, height: 42 },
+ dmAvatarInitials: {
+ fontSize: 13,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ },
+ dmInfo: { flex: 1, minWidth: 0 },
+ dmHeaderRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ },
+ dmName: {
+ fontSize: 14,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ flexShrink: 1,
+ marginRight: 6,
+ },
+ dmTime: { fontSize: 11, fontFamily: 'Nunito_600SemiBold' },
+ dmBottomRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ marginTop: 2,
+ },
+ dmLast: { fontSize: 12, flex: 1 },
+ unreadBadge: {
+ minWidth: 20,
+ height: 20,
+ paddingHorizontal: 6,
+ borderRadius: 10,
+ backgroundColor: '#007AFF',
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginLeft: 8,
+ },
+ unreadBadgeText: {
+ fontSize: 10,
+ fontFamily: 'Nunito_700Bold',
+ color: '#fff',
+ },
+ });
+}
diff --git a/apps/rebreak-native/app/(app)/coach.tsx b/apps/rebreak-native/app/(app)/coach.tsx
index d2b9bdb..88ca1a3 100644
--- a/apps/rebreak-native/app/(app)/coach.tsx
+++ b/apps/rebreak-native/app/(app)/coach.tsx
@@ -1,6 +1,7 @@
import { useCallback } from 'react';
import { View } from 'react-native';
import { useRouter, useFocusEffect } from 'expo-router';
+import { useColors } from '../../lib/theme';
/**
* Placeholder-Screen für den Coach-Tab.
@@ -11,6 +12,7 @@ import { useRouter, useFocusEffect } from 'expo-router';
*/
export default function CoachTabRedirect() {
const router = useRouter();
+ const colors = useColors();
useFocusEffect(
useCallback(() => {
@@ -20,5 +22,5 @@ export default function CoachTabRedirect() {
}, [router]),
);
- return ;
+ return ;
}
diff --git a/apps/rebreak-native/app/(app)/mail.tsx b/apps/rebreak-native/app/(app)/mail.tsx
index 6b5ba24..89cf794 100644
--- a/apps/rebreak-native/app/(app)/mail.tsx
+++ b/apps/rebreak-native/app/(app)/mail.tsx
@@ -20,10 +20,12 @@ import { SuccessAlert } from '../../components/SuccessAlert';
import { useMailStatus } from '../../hooks/useMailStatus';
import { useMailDisconnect } from '../../hooks/useMailDisconnect';
import { useUserPlan } from '../../hooks/useUserPlan';
+import { useColors } from '../../lib/theme';
export default function MailScreen() {
const { t } = useTranslation();
const tabBarHeight = useBottomTabBarHeight();
+ const colors = useColors();
const { plan } = useUserPlan();
@@ -72,7 +74,7 @@ export default function MailScreen() {
if (loading) {
return (
-
+
@@ -82,7 +84,7 @@ export default function MailScreen() {
}
return (
-
+
@@ -147,7 +149,7 @@ export default function MailScreen() {
disabled={limitReached}
android_ripple={{ color: '#0066cc' }}
style={{
- backgroundColor: limitReached ? '#e5e5e5' : '#007AFF',
+ backgroundColor: limitReached ? colors.surfaceElevated : '#007AFF',
borderRadius: 12,
opacity: limitReached ? 0.7 : 1,
shadowColor: '#007AFF',
@@ -169,14 +171,14 @@ export default function MailScreen() {
{t('mail.add_account')}
diff --git a/apps/rebreak-native/app/(app)/notifications.tsx b/apps/rebreak-native/app/(app)/notifications.tsx
index 4c2aa8c..8ceae8a 100644
--- a/apps/rebreak-native/app/(app)/notifications.tsx
+++ b/apps/rebreak-native/app/(app)/notifications.tsx
@@ -7,11 +7,12 @@ import { HeroShieldCheck } from '../../components/HeroShieldCheck';
import { useTranslation } from 'react-i18next';
import { EmptyState } from '../../components/EmptyState';
import { useNotificationStore, type AppNotification } from '../../stores/notifications';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
export default function NotificationsScreen() {
const router = useRouter();
const { t } = useTranslation();
+ const colors = useColors();
const items = useNotificationStore((s) => s.items);
const loaded = useNotificationStore((s) => s.loaded);
const load = useNotificationStore((s) => s.load);
@@ -28,17 +29,16 @@ export default function NotificationsScreen() {
}, []);
return (
-
-
+
+
router.back()}
- className="w-9 h-9 rounded-full bg-neutral-100 border border-neutral-200 items-center justify-center"
+ style={{ width: 36, height: 36, borderRadius: 18, backgroundColor: colors.surfaceElevated, borderWidth: 1, borderColor: colors.border, alignItems: 'center', justifyContent: 'center' }}
>
-
+
{t('notifications.title')}
@@ -59,7 +59,7 @@ export default function NotificationsScreen() {
}
renderItem={({ item }) => (
@@ -88,6 +88,7 @@ function NotificationRow({
onPress: () => void;
onDelete: () => void;
}) {
+ const colors = useColors();
const isUnread = !notif.readAt;
return (
{/* Pure-Icon — KEIN bg-Circle (User-Wunsch: kein extra Rand). */}
@@ -117,7 +118,7 @@ function NotificationRow({
{notif.actorName}
@@ -127,7 +128,7 @@ function NotificationRow({
style={{
fontSize: 12,
fontFamily: 'Nunito_400Regular',
- color: '#525252',
+ color: colors.textMuted,
marginTop: 2,
}}
numberOfLines={2}
diff --git a/apps/rebreak-native/app/auth/callback.tsx b/apps/rebreak-native/app/auth/callback.tsx
index 5f2caf0..911f11d 100644
--- a/apps/rebreak-native/app/auth/callback.tsx
+++ b/apps/rebreak-native/app/auth/callback.tsx
@@ -15,10 +15,11 @@ import { useEffect } from 'react';
import { View, ActivityIndicator } from 'react-native';
import { useRouter, useLocalSearchParams } from 'expo-router';
import { supabase } from '../../lib/supabase';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
export default function AuthCallback() {
const router = useRouter();
+ const colors = useColors();
const params = useLocalSearchParams<{ access_token?: string; refresh_token?: string }>();
useEffect(() => {
@@ -50,7 +51,7 @@ export default function AuthCallback() {
}, []);
return (
-
+
);
diff --git a/apps/rebreak-native/app/debug.tsx b/apps/rebreak-native/app/debug.tsx
index 0fa313b..bd86267 100644
--- a/apps/rebreak-native/app/debug.tsx
+++ b/apps/rebreak-native/app/debug.tsx
@@ -3,10 +3,11 @@ import { View, Text, ScrollView, Pressable } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useRouter } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
export default function DebugScreen() {
const router = useRouter();
+ const colors = useColors();
useEffect(() => {
if (!__DEV__) {
@@ -15,11 +16,11 @@ export default function DebugScreen() {
}, [router]);
if (!__DEV__) {
- return ;
+ return ;
}
return (
-
+
-
+
Debug
@@ -119,10 +120,11 @@ function DebugStub({
subtitle: string;
icon: React.ComponentProps['name'];
}) {
+ const colors = useColors();
return (
-
+
- {title}
+ {title}
(null);
const [myUserId, setMyUserId] = useState(undefined);
@@ -234,7 +236,7 @@ export default function DmScreen() {
{/* Header */}
router.back()} hitSlop={8}>
-
+
@@ -260,7 +262,7 @@ export default function DmScreen() {
>
{isLoading && messages.length === 0 ? (
-
+
) : messages.length === 0 ? (
@@ -302,64 +304,66 @@ export default function DmScreen() {
);
}
-const styles = StyleSheet.create({
- container: { flex: 1, backgroundColor: '#fafafa' },
- header: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- paddingHorizontal: 12,
- paddingVertical: 10,
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#e5e5e5',
- },
- backBtn: {
- width: 36,
- height: 36,
- borderRadius: 12,
- backgroundColor: '#f5f5f5',
- alignItems: 'center',
- justifyContent: 'center',
- },
- headerCenter: {
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- marginHorizontal: 8,
- },
- headerAvatar: {
- width: 32,
- height: 32,
- borderRadius: 16,
- backgroundColor: '#e5e5e5',
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- marginRight: 8,
- },
- headerAvatarImg: { width: 32, height: 32 },
- headerAvatarInitials: {
- fontSize: 11,
- fontFamily: 'Nunito_700Bold',
- color: '#737373',
- },
- headerName: {
- fontSize: 15,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- flexShrink: 1,
- },
- loadingBox: {
- flex: 1,
- alignItems: 'center',
- justifyContent: 'center',
- },
- emptyText: {
- fontSize: 13,
- fontFamily: 'Nunito_600SemiBold',
- color: '#a3a3a3',
- marginTop: 12,
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ container: { flex: 1, backgroundColor: colors.bg },
+ header: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ paddingHorizontal: 12,
+ paddingVertical: 10,
+ backgroundColor: colors.bg,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ backBtn: {
+ width: 36,
+ height: 36,
+ borderRadius: 12,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ headerCenter: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginHorizontal: 8,
+ },
+ headerAvatar: {
+ width: 32,
+ height: 32,
+ borderRadius: 16,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ overflow: 'hidden',
+ marginRight: 8,
+ },
+ headerAvatarImg: { width: 32, height: 32 },
+ headerAvatarInitials: {
+ fontSize: 11,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ },
+ headerName: {
+ fontSize: 15,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ flexShrink: 1,
+ },
+ loadingBox: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ emptyText: {
+ fontSize: 13,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.textMuted,
+ marginTop: 12,
+ },
+ });
+}
diff --git a/apps/rebreak-native/app/games.tsx b/apps/rebreak-native/app/games.tsx
index ba985af..8759025 100644
--- a/apps/rebreak-native/app/games.tsx
+++ b/apps/rebreak-native/app/games.tsx
@@ -13,7 +13,7 @@ import {
TetrisGame,
} from '../components/urge/UrgeGames';
import { GameCard } from '../components/games/GameCard';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
import { apiFetch } from '../lib/api';
type GameStat = { avgStars: number; count: number };
@@ -31,6 +31,7 @@ type LastScore = { game: GameType; score: number } | null;
export default function GamesScreen() {
const router = useRouter();
const { t } = useTranslation();
+ const colors = useColors();
const [active, setActive] = useState(null);
const [lastScore, setLastScore] = useState(null);
const [gameStats, setGameStats] = useState(EMPTY_STATS);
@@ -70,7 +71,7 @@ export default function GamesScreen() {
if (active) {
return (
-
+
-
+
{t(GAME_META.find((g) => g.id === active)!.titleKey)}
@@ -127,7 +128,7 @@ export default function GamesScreen() {
}
return (
-
+
-
+
{t('games.title')}
@@ -169,7 +170,7 @@ export default function GamesScreen() {
();
const [imageFailed, setImageFailed] = useState(false);
const [isFollowing, setIsFollowing] = useState(DUMMY_FOREIGN.isFollowing);
@@ -99,13 +101,13 @@ export default function ForeignProfileScreen() {
const planStyle = planColors[profile.plan];
return (
-
+
{showImage ? (
@@ -215,9 +217,9 @@ export default function ForeignProfileScreen() {
(me?.avatar ?? null);
const [photoUri, setPhotoUri] = useState(null);
diff --git a/apps/rebreak-native/app/room.tsx b/apps/rebreak-native/app/room.tsx
index eac1f7a..a092e31 100644
--- a/apps/rebreak-native/app/room.tsx
+++ b/apps/rebreak-native/app/room.tsx
@@ -27,7 +27,7 @@ import { supabase } from '../lib/supabase';
import { ChatBubble, type ChatMsg } from '../components/chat/ChatBubble';
import { ChatInput, type SendPayload } from '../components/chat/ChatInput';
import { useRoomRealtime } from '../hooks/useChatRealtime';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
const GROUP_GAP_MS = 5 * 60 * 1000;
@@ -64,6 +64,8 @@ export default function RoomScreen() {
const { t } = useTranslation();
const router = useRouter();
const insets = useSafeAreaInsets();
+ const colors = useColors();
+ const styles = makeStyles(colors);
const queryClient = useQueryClient();
const flatRef = useRef(null);
const [myUserId, setMyUserId] = useState();
@@ -298,7 +300,7 @@ export default function RoomScreen() {
{/* Header */}
router.back()} hitSlop={8}>
-
+
@@ -320,7 +322,7 @@ export default function RoomScreen() {
setSettingsOpen(true)} hitSlop={8}>
-
+
@@ -430,6 +432,8 @@ function RoomSettingsModal({
roomId: string;
}) {
const { t } = useTranslation();
+ const colors = useColors();
+ const modal = makeModalStyles(colors);
const [pendingRequests, setPendingRequests] = useState([]);
const [loadingReqs, setLoadingReqs] = useState(false);
@@ -637,221 +641,225 @@ function RoomSettingsModal({
);
}
-const styles = StyleSheet.create({
- container: { flex: 1, backgroundColor: '#fafafa' },
- header: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingHorizontal: 12,
- paddingVertical: 10,
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#e5e5e5',
- },
- iconBtn: {
- width: 36,
- height: 36,
- borderRadius: 12,
- backgroundColor: '#f5f5f5',
- alignItems: 'center',
- justifyContent: 'center',
- },
- headerCenter: {
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center',
- marginHorizontal: 8,
- },
- headerAvatar: {
- width: 36,
- height: 36,
- borderRadius: 18,
- backgroundColor: '#e5e5e5',
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- marginRight: 8,
- },
- headerAvatarImg: { width: 36, height: 36 },
- headerAvatarInitials: {
- fontSize: 12,
- fontFamily: 'Nunito_700Bold',
- color: '#737373',
- },
- headerName: {
- fontSize: 15,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- },
- headerSub: {
- fontSize: 11,
- fontFamily: 'Nunito_500Medium',
- color: '#737373',
- marginTop: 1,
- },
- loadingBox: { flex: 1, alignItems: 'center', justifyContent: 'center' },
- joinBox: {
- flex: 1,
- alignItems: 'center',
- justifyContent: 'center',
- paddingHorizontal: 32,
- },
- joinTitle: {
- fontSize: 20,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- marginTop: 14,
- },
- joinDesc: {
- fontSize: 13,
- fontFamily: 'Nunito_500Medium',
- color: '#737373',
- marginTop: 6,
- textAlign: 'center',
- },
- joinHint: {
- fontSize: 12,
- fontFamily: 'Nunito_500Medium',
- color: '#a3a3a3',
- marginTop: 18,
- textAlign: 'center',
- },
- joinBtn: {
- marginTop: 16,
- backgroundColor: '#007AFF',
- paddingHorizontal: 32,
- paddingVertical: 12,
- borderRadius: 12,
- minWidth: 140,
- alignItems: 'center',
- },
- joinBtnText: {
- color: '#fff',
- fontSize: 14,
- fontFamily: 'Nunito_700Bold',
- },
- pendingBadge: {
- flexDirection: 'row',
- alignItems: 'center',
- backgroundColor: '#fef3c7',
- paddingHorizontal: 14,
- paddingVertical: 8,
- borderRadius: 20,
- marginTop: 16,
- },
- pendingText: {
- color: '#92400e',
- fontSize: 12,
- fontFamily: 'Nunito_700Bold',
- marginLeft: 6,
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ container: { flex: 1, backgroundColor: colors.bg },
+ header: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 12,
+ paddingVertical: 10,
+ backgroundColor: colors.bg,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ iconBtn: {
+ width: 36,
+ height: 36,
+ borderRadius: 12,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ headerCenter: {
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginHorizontal: 8,
+ },
+ headerAvatar: {
+ width: 36,
+ height: 36,
+ borderRadius: 18,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ overflow: 'hidden',
+ marginRight: 8,
+ },
+ headerAvatarImg: { width: 36, height: 36 },
+ headerAvatarInitials: {
+ fontSize: 12,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ },
+ headerName: {
+ fontSize: 15,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ },
+ headerSub: {
+ fontSize: 11,
+ fontFamily: 'Nunito_500Medium',
+ color: colors.textMuted,
+ marginTop: 1,
+ },
+ loadingBox: { flex: 1, alignItems: 'center', justifyContent: 'center' },
+ joinBox: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingHorizontal: 32,
+ },
+ joinTitle: {
+ fontSize: 20,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ marginTop: 14,
+ },
+ joinDesc: {
+ fontSize: 13,
+ fontFamily: 'Nunito_500Medium',
+ color: colors.textMuted,
+ marginTop: 6,
+ textAlign: 'center',
+ },
+ joinHint: {
+ fontSize: 12,
+ fontFamily: 'Nunito_500Medium',
+ color: colors.textMuted,
+ marginTop: 18,
+ textAlign: 'center',
+ },
+ joinBtn: {
+ marginTop: 16,
+ backgroundColor: '#007AFF',
+ paddingHorizontal: 32,
+ paddingVertical: 12,
+ borderRadius: 12,
+ minWidth: 140,
+ alignItems: 'center',
+ },
+ joinBtnText: {
+ color: '#fff',
+ fontSize: 14,
+ fontFamily: 'Nunito_700Bold',
+ },
+ pendingBadge: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ backgroundColor: '#fef3c7',
+ paddingHorizontal: 14,
+ paddingVertical: 8,
+ borderRadius: 20,
+ marginTop: 16,
+ },
+ pendingText: {
+ color: '#92400e',
+ fontSize: 12,
+ fontFamily: 'Nunito_700Bold',
+ marginLeft: 6,
+ },
+ });
+}
-const modal = StyleSheet.create({
- container: { flex: 1, backgroundColor: '#fafafa' },
- header: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- paddingHorizontal: 16,
- paddingVertical: 12,
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#e5e5e5',
- },
- title: { fontSize: 16, fontFamily: 'Nunito_700Bold', color: '#171717' },
- section: {
- backgroundColor: '#fff',
- borderRadius: 12,
- padding: 14,
- marginBottom: 12,
- },
- sectionTitle: {
- fontSize: 12,
- fontFamily: 'Nunito_700Bold',
- color: '#737373',
- textTransform: 'uppercase',
- marginBottom: 10,
- letterSpacing: 0.5,
- },
- avatarWrap: { alignSelf: 'center', marginBottom: 10 },
- avatar: { width: 80, height: 80, borderRadius: 40 },
- avatarPlaceholder: {
- backgroundColor: '#e5e5e5',
- alignItems: 'center',
- justifyContent: 'center',
- },
- avatarEdit: {
- position: 'absolute',
- right: -2,
- bottom: -2,
- width: 28,
- height: 28,
- borderRadius: 14,
- backgroundColor: '#007AFF',
- borderWidth: 3,
- borderColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
- roomName: {
- fontSize: 17,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- textAlign: 'center',
- },
- roomDesc: {
- fontSize: 12,
- fontFamily: 'Nunito_500Medium',
- color: '#737373',
- textAlign: 'center',
- marginTop: 4,
- },
- memberRow: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingVertical: 8,
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#f5f5f5',
- },
- memberAvatar: {
- width: 32,
- height: 32,
- borderRadius: 16,
- backgroundColor: '#e5e5e5',
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- marginRight: 10,
- },
- memberAvatarImg: { width: 32, height: 32 },
- memberInitials: {
- fontSize: 11,
- fontFamily: 'Nunito_700Bold',
- color: '#737373',
- },
- memberName: { fontSize: 13, fontFamily: 'Nunito_600SemiBold', color: '#171717' },
- memberRole: { fontSize: 11, color: '#a3a3a3', marginTop: 1, textTransform: 'capitalize' },
- actionBtn: {
- paddingHorizontal: 10,
- paddingVertical: 5,
- borderRadius: 6,
- },
- actionText: { fontSize: 11, fontFamily: 'Nunito_700Bold' },
- emptyText: { fontSize: 12, color: '#a3a3a3' },
- leaveBtn: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- backgroundColor: '#fee2e2',
- paddingVertical: 12,
- borderRadius: 10,
- marginTop: 8,
- },
- leaveText: {
- color: '#991b1b',
- fontSize: 13,
- fontFamily: 'Nunito_700Bold',
- marginLeft: 6,
- },
-});
+function makeModalStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ container: { flex: 1, backgroundColor: colors.bg },
+ header: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ paddingHorizontal: 16,
+ paddingVertical: 12,
+ backgroundColor: colors.bg,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ title: { fontSize: 16, fontFamily: 'Nunito_700Bold', color: colors.text },
+ section: {
+ backgroundColor: colors.surface,
+ borderRadius: 12,
+ padding: 14,
+ marginBottom: 12,
+ },
+ sectionTitle: {
+ fontSize: 12,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ textTransform: 'uppercase',
+ marginBottom: 10,
+ letterSpacing: 0.5,
+ },
+ avatarWrap: { alignSelf: 'center', marginBottom: 10 },
+ avatar: { width: 80, height: 80, borderRadius: 40 },
+ avatarPlaceholder: {
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ avatarEdit: {
+ position: 'absolute',
+ right: -2,
+ bottom: -2,
+ width: 28,
+ height: 28,
+ borderRadius: 14,
+ backgroundColor: '#007AFF',
+ borderWidth: 3,
+ borderColor: colors.bg,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ roomName: {
+ fontSize: 17,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ textAlign: 'center',
+ },
+ roomDesc: {
+ fontSize: 12,
+ fontFamily: 'Nunito_500Medium',
+ color: colors.textMuted,
+ textAlign: 'center',
+ marginTop: 4,
+ },
+ memberRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingVertical: 8,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ memberAvatar: {
+ width: 32,
+ height: 32,
+ borderRadius: 16,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ overflow: 'hidden',
+ marginRight: 10,
+ },
+ memberAvatarImg: { width: 32, height: 32 },
+ memberInitials: {
+ fontSize: 11,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ },
+ memberName: { fontSize: 13, fontFamily: 'Nunito_600SemiBold', color: colors.text },
+ memberRole: { fontSize: 11, color: colors.textMuted, marginTop: 1, textTransform: 'capitalize' },
+ actionBtn: {
+ paddingHorizontal: 10,
+ paddingVertical: 5,
+ borderRadius: 6,
+ },
+ actionText: { fontSize: 11, fontFamily: 'Nunito_700Bold' },
+ emptyText: { fontSize: 12, color: colors.textMuted },
+ leaveBtn: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ backgroundColor: '#fee2e2',
+ paddingVertical: 12,
+ borderRadius: 10,
+ marginTop: 8,
+ },
+ leaveText: {
+ color: '#991b1b',
+ fontSize: 13,
+ fontFamily: 'Nunito_700Bold',
+ marginLeft: 6,
+ },
+ });
+}
diff --git a/apps/rebreak-native/app/urge.tsx b/apps/rebreak-native/app/urge.tsx
index 4e474f5..2cd21db 100644
--- a/apps/rebreak-native/app/urge.tsx
+++ b/apps/rebreak-native/app/urge.tsx
@@ -15,7 +15,7 @@ import { useTranslation } from 'react-i18next';
import { RiveAvatar } from '../components/RiveAvatar';
import { apiFetch } from '../lib/api';
import { supabase } from '../lib/supabase';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
import {
type GameType, GAME_META, MemoryGame, TicTacToeGame, SnakeGame, TetrisGame,
} from '../components/urge/UrgeGames';
@@ -41,6 +41,8 @@ export default function SOSScreen() {
const { t, i18n } = useTranslation();
const router = useRouter();
const insets = useSafeAreaInsets();
+ const colors = useColors();
+ const st = makeStyles(colors);
const flatRef = useRef(null);
const [messages, setMessages] = useState([]);
@@ -1089,7 +1091,7 @@ export default function SOSScreen() {
{/* Header */}
-
+
@@ -1286,39 +1288,41 @@ export default function SOSScreen() {
);
}
-const st = StyleSheet.create({
- container: { flex: 1, backgroundColor: '#ffffff' },
- topBar: { position: 'absolute', left: 0, right: 0, zIndex: 10, flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between', paddingHorizontal: 12 },
- topBarBackdrop: { position: 'absolute', top: 0, left: 0, right: 0, zIndex: 9, backgroundColor: '#ffffff' },
- actionBtn: { width: 40, height: 40, borderRadius: 20, backgroundColor: 'rgba(255,255,255,0.92)', alignItems: 'center', justifyContent: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 6, elevation: 4 },
- avatarCenter: { flex: 1, alignItems: 'center', gap: 4 },
- avatarMeta: { alignItems: 'center', gap: 2 },
- avatarName: { fontSize: 14, fontFamily: 'Nunito_700Bold', color: '#0a0a0a' },
- speakingRow: { flexDirection: 'row', alignItems: 'center', gap: 6 },
- stopBtn: { width: 18, height: 18, borderRadius: 9, backgroundColor: '#f5f5f5', alignItems: 'center', justifyContent: 'center' },
- listContent: { paddingHorizontal: 12, paddingBottom: 4 },
- scrollDownBtn: { position: 'absolute', bottom: 8, right: 16, width: 36, height: 36, borderRadius: 18, backgroundColor: '#374151', alignItems: 'center', justifyContent: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.15, shadowRadius: 4, elevation: 4 },
- chip: {
- borderRadius: 14,
- borderWidth: 1.5,
- borderColor: '#9ca3af', // sichtbarer Ring (medium-grau gegen weiß)
- backgroundColor: '#ffffff',
- paddingHorizontal: 16,
- paddingVertical: 11,
- shadowColor: '#000',
- shadowOffset: { width: 0, height: 2 },
- shadowOpacity: 0.12,
- shadowRadius: 6,
- elevation: 3,
- },
- chipPressed: {
- backgroundColor: '#f3f4f6',
- borderColor: '#6b7280', // dunkler beim Press → spürbares Feedback
- transform: [{ scale: 0.97 }],
- shadowOpacity: 0.05,
- },
- chipText: { fontFamily: 'Nunito_600SemiBold', fontSize: 14, color: '#334155' },
- inputBar: { flexDirection: 'row', alignItems: 'flex-end', paddingHorizontal: 12, paddingTop: 8, borderTopWidth: 1, borderTopColor: '#f3f4f6', backgroundColor: '#fff', gap: 8 },
- textInput: { flex: 1, minHeight: 40, maxHeight: 120, backgroundColor: '#f3f4f6', borderRadius: 20, paddingHorizontal: 14, paddingVertical: 10, fontSize: 15, fontFamily: 'Nunito_400Regular', color: '#111827' },
- sendBtn: { width: 38, height: 38, borderRadius: 19, backgroundColor: '#007AFF', alignItems: 'center', justifyContent: 'center' },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ container: { flex: 1, backgroundColor: colors.bg },
+ topBar: { position: 'absolute', left: 0, right: 0, zIndex: 10, flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between', paddingHorizontal: 12 },
+ topBarBackdrop: { position: 'absolute', top: 0, left: 0, right: 0, zIndex: 9, backgroundColor: colors.bg },
+ actionBtn: { width: 40, height: 40, borderRadius: 20, backgroundColor: colors.surface, alignItems: 'center', justifyContent: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 6, elevation: 4 },
+ avatarCenter: { flex: 1, alignItems: 'center', gap: 4 },
+ avatarMeta: { alignItems: 'center', gap: 2 },
+ avatarName: { fontSize: 14, fontFamily: 'Nunito_700Bold', color: colors.text },
+ speakingRow: { flexDirection: 'row', alignItems: 'center', gap: 6 },
+ stopBtn: { width: 18, height: 18, borderRadius: 9, backgroundColor: colors.surfaceElevated, alignItems: 'center', justifyContent: 'center' },
+ listContent: { paddingHorizontal: 12, paddingBottom: 4 },
+ scrollDownBtn: { position: 'absolute', bottom: 8, right: 16, width: 36, height: 36, borderRadius: 18, backgroundColor: '#374151', alignItems: 'center', justifyContent: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.15, shadowRadius: 4, elevation: 4 },
+ chip: {
+ borderRadius: 14,
+ borderWidth: 1.5,
+ borderColor: colors.border,
+ backgroundColor: colors.bg,
+ paddingHorizontal: 16,
+ paddingVertical: 11,
+ shadowColor: '#000',
+ shadowOffset: { width: 0, height: 2 },
+ shadowOpacity: 0.12,
+ shadowRadius: 6,
+ elevation: 3,
+ },
+ chipPressed: {
+ backgroundColor: colors.surfaceElevated,
+ borderColor: colors.textMuted,
+ transform: [{ scale: 0.97 }],
+ shadowOpacity: 0.05,
+ },
+ chipText: { fontFamily: 'Nunito_600SemiBold', fontSize: 14, color: colors.textMuted },
+ inputBar: { flexDirection: 'row', alignItems: 'flex-end', paddingHorizontal: 12, paddingTop: 8, borderTopWidth: 1, borderTopColor: colors.border, backgroundColor: colors.bg, gap: 8 },
+ textInput: { flex: 1, minHeight: 40, maxHeight: 120, backgroundColor: colors.surfaceElevated, borderRadius: 20, paddingHorizontal: 14, paddingVertical: 10, fontSize: 15, fontFamily: 'Nunito_400Regular', color: colors.text },
+ sendBtn: { width: 38, height: 38, borderRadius: 19, backgroundColor: '#007AFF', alignItems: 'center', justifyContent: 'center' },
+ });
+}
diff --git a/apps/rebreak-native/components/ComposeCard.tsx b/apps/rebreak-native/components/ComposeCard.tsx
index 17d440c..afa1035 100644
--- a/apps/rebreak-native/components/ComposeCard.tsx
+++ b/apps/rebreak-native/components/ComposeCard.tsx
@@ -17,7 +17,7 @@ import * as ImagePicker from 'expo-image-picker';
import { apiFetch } from '../lib/api';
import { resolveAvatar } from '../lib/resolveAvatar';
import { useAuthStore } from '../stores/auth';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
type Props = {
onPosted?: () => void;
@@ -25,6 +25,7 @@ type Props = {
export function ComposeCard({ onPosted }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const { user } = useAuthStore();
const queryClient = useQueryClient();
const inputRef = useRef(null);
@@ -101,7 +102,7 @@ export function ComposeCard({ onPosted }: Props) {
const showActions = focused || content.length > 0;
return (
-
+
setFocused(true)}
placeholder={t('community.compose_placeholder')}
- placeholderTextColor="#a3a3a3"
+ placeholderTextColor={colors.textMuted}
multiline
- className="text-sm text-neutral-900 leading-5 min-h-[40px]"
- style={{ textAlignVertical: 'top', fontFamily: 'Nunito_400Regular' }}
+ className="text-sm leading-5 min-h-[40px]"
+ style={{ textAlignVertical: 'top', fontFamily: 'Nunito_400Regular', color: colors.text }}
/>
{imageUri && (
diff --git a/apps/rebreak-native/components/DeviceLimitReachedSheet.tsx b/apps/rebreak-native/components/DeviceLimitReachedSheet.tsx
index 2ad7d89..1d57e12 100644
--- a/apps/rebreak-native/components/DeviceLimitReachedSheet.tsx
+++ b/apps/rebreak-native/components/DeviceLimitReachedSheet.tsx
@@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react';
import { TrueSheet, type SheetDetent } from '@lodev09/react-native-true-sheet';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
import { apiFetch } from '../lib/api';
import { useDeviceLimitStore, type DeviceLimitDevice } from '../stores/deviceLimit';
@@ -40,6 +40,7 @@ function DeviceLimitRow({
onRemove: (id: string) => void;
}) {
const { t } = useTranslation();
+ const colors = useColors();
return (
(null);
const { visible, devices, max, plan, hide, removeDevice } = useDeviceLimitStore();
const [removingId, setRemovingId] = useState(null);
@@ -195,7 +197,7 @@ export function DeviceLimitReachedSheet() {
s.items);
const loaded = useNotificationStore((s) => s.loaded);
@@ -71,7 +73,7 @@ export function NotificationsDropdown({ visible, onClose, topOffset }: Props) {
position: 'absolute',
top: topOffset + 6,
right: 12,
- backgroundColor: '#ffffff',
+ backgroundColor: colors.bg,
borderRadius: 18,
shadowColor: '#000',
shadowOffset: { width: 0, height: 8 },
@@ -93,11 +95,11 @@ export function NotificationsDropdown({ visible, onClose, topOffset }: Props) {
paddingHorizontal: 16,
paddingVertical: 12,
borderBottomWidth: 1,
- borderBottomColor: '#f0f0f0',
+ borderBottomColor: colors.border,
}}
>
{t('notifications.title')}
@@ -114,13 +116,13 @@ export function NotificationsDropdown({ visible, onClose, topOffset }: Props) {
{items.length === 0 ? (
-
+
{t('notifications.empty_title')}
@@ -130,7 +132,7 @@ export function NotificationsDropdown({ visible, onClose, topOffset }: Props) {
marginTop: 2,
fontSize: 11,
fontFamily: 'Nunito_400Regular',
- color: '#a3a3a3',
+ color: colors.textMuted,
textAlign: 'center',
paddingHorizontal: 20,
}}
@@ -221,6 +223,7 @@ function NotificationRow({
onPress: () => void;
t: (k: string, opts?: any) => string;
}) {
+ const colors = useColors();
const isUnread = !notif.readAt;
const { icon, color, bg } = notifIcon(notif.type);
const isSocial =
@@ -249,8 +252,8 @@ function NotificationRow({
paddingHorizontal: 14,
paddingVertical: 11,
borderBottomWidth: 1,
- borderBottomColor: '#f5f5f5',
- backgroundColor: isUnread ? '#fff7ed' : '#ffffff',
+ borderBottomColor: colors.border,
+ backgroundColor: isUnread ? colors.surface : colors.bg,
}}
>
{/* Avatar-Logik:
@@ -297,7 +300,7 @@ function NotificationRow({
style={{
fontSize: 12,
fontFamily: 'Nunito_600SemiBold',
- color: '#0a0a0a',
+ color: colors.text,
lineHeight: 16,
}}
numberOfLines={2}
@@ -308,7 +311,7 @@ function NotificationRow({
style={{
fontSize: 10,
fontFamily: 'Nunito_400Regular',
- color: '#a3a3a3',
+ color: colors.textMuted,
marginTop: 2,
}}
>
diff --git a/apps/rebreak-native/components/OptionsBottomSheet.tsx b/apps/rebreak-native/components/OptionsBottomSheet.tsx
index 5dc3750..7586724 100644
--- a/apps/rebreak-native/components/OptionsBottomSheet.tsx
+++ b/apps/rebreak-native/components/OptionsBottomSheet.tsx
@@ -22,7 +22,7 @@ import {
Easing,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
type Option = {
value: T;
@@ -51,6 +51,7 @@ export function OptionsBottomSheet({
onClose,
}: Props) {
const insets = useSafeAreaInsets();
+ const colors = useColors();
const translateY = useRef(new Animated.Value(400)).current;
const backdropOpacity = useRef(new Animated.Value(0)).current;
diff --git a/apps/rebreak-native/components/PostCard.tsx b/apps/rebreak-native/components/PostCard.tsx
index 5f7cb84..e69e1a5 100644
--- a/apps/rebreak-native/components/PostCard.tsx
+++ b/apps/rebreak-native/components/PostCard.tsx
@@ -9,6 +9,7 @@ import { formatRelativeTime } from '../lib/formatTime';
import { useCommunityStore, type CommunityPost } from '../stores/community';
import { RiveAvatar } from './RiveAvatar';
import { HeroShieldCheck } from './HeroShieldCheck';
+import { useColors } from '../lib/theme';
type Props = {
post: CommunityPost;
@@ -17,6 +18,7 @@ type Props = {
function PostCardImpl({ post, onCommentPress }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const queryClient = useQueryClient();
// Granular selectors — subscribing to the whole store would re-render every
// PostCard whenever any user likes any post (optimisticLikes mutates).
@@ -162,7 +164,7 @@ function PostCardImpl({ post, onCommentPress }: Props) {
}, [isLiking, localLike, localCount, post.id, post.userLike, post.likesCount, applyOptimisticLike, clearOptimisticLike, revertOptimisticLike, queryClient, triggerHeartPop]);
return (
-
+
{/* Repost header */}
{post.repostOf && (
@@ -194,35 +196,35 @@ function PostCardImpl({ post, onCommentPress }: Props) {
)}
-
+
{authorLabel}
{authorDescription !== undefined && (
- {authorDescription}
+ {authorDescription}
)}
-
+
{formatRelativeTime(post.createdAt)}
{/* Content — hidden for domain_vote (replaced by poll below) */}
{!!displayContent && post.category !== 'domain_vote' && (
-
+
{displayContent}
)}
{/* domain_approved: favicon + domain name + shield badge */}
{post.category === 'domain_approved' && !!approvedDomain && (
-
+
-
-
+
+
{approvedDomain}
-
+
{t('community.domain_added_to_blocklist')}
diff --git a/apps/rebreak-native/components/PostCardSkeleton.tsx b/apps/rebreak-native/components/PostCardSkeleton.tsx
index f5edf20..3473e7b 100644
--- a/apps/rebreak-native/components/PostCardSkeleton.tsx
+++ b/apps/rebreak-native/components/PostCardSkeleton.tsx
@@ -1,18 +1,20 @@
import { View } from 'react-native';
+import { useColors } from '../lib/theme';
export function PostCardSkeleton() {
+ const colors = useColors();
return (
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
);
}
diff --git a/apps/rebreak-native/components/PostCommentsSheet.tsx b/apps/rebreak-native/components/PostCommentsSheet.tsx
index 4a32b6b..88bb00d 100644
--- a/apps/rebreak-native/components/PostCommentsSheet.tsx
+++ b/apps/rebreak-native/components/PostCommentsSheet.tsx
@@ -19,7 +19,7 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { apiFetch } from '../lib/api';
import { formatRelativeTime } from '../lib/formatTime';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
import type { CommunityComment } from '../stores/community';
const EMOJIS = ['❤️', '🙌', '🔥', '👏', '😢', '😍', '😮', '😂'];
@@ -33,6 +33,7 @@ type Props = {
export function PostCommentsSheet({ postId, visible, onClose }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const insets = useSafeAreaInsets();
const queryClient = useQueryClient();
const inputRef = useRef(null);
@@ -230,7 +231,7 @@ export function PostCommentsSheet({ postId, visible, onClose }: Props) {
@@ -268,10 +269,10 @@ export function PostCommentsSheet({ postId, visible, onClose }: Props) {
paddingTop: 6,
paddingBottom: 12,
borderBottomWidth: 1,
- borderBottomColor: '#e5e5e5',
+ borderBottomColor: colors.border,
}}
>
-
+
{t('community.comments_title')}
@@ -323,7 +324,7 @@ export function PostCommentsSheet({ postId, visible, onClose }: Props) {
paddingHorizontal: 16,
paddingVertical: 8,
borderTopWidth: 1,
- borderTopColor: '#f5f5f5',
+ borderTopColor: colors.border,
}}
>
{EMOJIS.map((e) => (
@@ -342,10 +343,10 @@ export function PostCommentsSheet({ postId, visible, onClose }: Props) {
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 8,
- backgroundColor: '#fafafa',
+ backgroundColor: colors.surface,
}}
>
-
+
{t('community.reply_to')}{' '}
@{replyTarget.nickname}
@@ -366,7 +367,7 @@ export function PostCommentsSheet({ postId, visible, onClose }: Props) {
// sonst Safe-Area
paddingBottom: keyboardHeight > 0 ? 8 : Math.max(12, insets.bottom),
borderTopWidth: 1,
- borderTopColor: '#e5e5e5',
+ borderTopColor: colors.border,
}}
>
{
heartScale.setValue(1);
@@ -447,26 +449,26 @@ function CommentRow({ comment, isReply = false, onReply, onLike }: CommentRowPro
width: isReply ? 24 : 32,
height: isReply ? 24 : 32,
borderRadius: isReply ? 12 : 16,
- backgroundColor: '#e5e5e5',
+ backgroundColor: colors.surfaceElevated,
alignItems: 'center',
justifyContent: 'center',
marginTop: 2,
}}
>
-
+
{(comment.authorNickname ?? 'AN').slice(0, 2).toUpperCase()}
-
+
{comment.authorNickname ?? t('community.anonymous_label')}
-
+
{formatRelativeTime(comment.createdAt)}
{!isReply && onReply && (
-
+
{t('community.reply')}
diff --git a/apps/rebreak-native/components/StreakBadge.tsx b/apps/rebreak-native/components/StreakBadge.tsx
index cc03ee4..cd4f840 100644
--- a/apps/rebreak-native/components/StreakBadge.tsx
+++ b/apps/rebreak-native/components/StreakBadge.tsx
@@ -1,7 +1,7 @@
import { View, Text } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
type Props = {
days: number;
@@ -16,14 +16,18 @@ const sizeMap = {
export function StreakBadge({ days, size = 'md' }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const s = sizeMap[size];
return (
-
+
- {days}
+ {days}
-
+
{days === 1 ? t('streak.label_one') : t('streak.label_other')} {t('streak.label_suffix')}
diff --git a/apps/rebreak-native/components/WheelPickerModal.tsx b/apps/rebreak-native/components/WheelPickerModal.tsx
index 2ec6668..8b2ee81 100644
--- a/apps/rebreak-native/components/WheelPickerModal.tsx
+++ b/apps/rebreak-native/components/WheelPickerModal.tsx
@@ -14,7 +14,7 @@
import { useEffect, useState } from 'react';
import { Modal, View, Text, Pressable } from 'react-native';
import { Picker } from '@react-native-picker/picker';
-import { colors } from '../lib/theme';
+import { useColors } from '../lib/theme';
type Option = { value: T; label: string };
@@ -35,6 +35,7 @@ export function WheelPickerModal({
onSelect,
onClose,
}: Props) {
+ const colors = useColors();
// Tracks the wheel's current selection (separate from confirmed value).
// Initialized from `value` prop on each open.
const [tempValue, setTempValue] = useState(value);
@@ -72,7 +73,7 @@ export function WheelPickerModal({
{}}>
({
paddingHorizontal: 16,
paddingVertical: 12,
borderBottomWidth: 1,
- borderBottomColor: '#e5e5e5',
+ borderBottomColor: colors.border,
}}
>
diff --git a/apps/rebreak-native/components/blocker/AddDomainSheet.tsx b/apps/rebreak-native/components/blocker/AddDomainSheet.tsx
index 0b42d96..eacf8ef 100644
--- a/apps/rebreak-native/components/blocker/AddDomainSheet.tsx
+++ b/apps/rebreak-native/components/blocker/AddDomainSheet.tsx
@@ -21,6 +21,7 @@ import {
normalizeDomain,
type Tier,
} from '../../hooks/useCustomDomains';
+import { useColors } from '../../lib/theme';
const SCREEN_HEIGHT = Dimensions.get('window').height;
const SHEET_HEIGHT = SCREEN_HEIGHT * 0.65; // wie bei PostCommentsSheet — 65% der Screen-Höhe
@@ -34,6 +35,7 @@ type Props = {
export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const insets = useSafeAreaInsets();
const [input, setInput] = useState('');
const [confirmPermanent, setConfirmPermanent] = useState(false);
@@ -122,7 +124,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
right: 0,
bottom: 0,
height: SHEET_HEIGHT,
- backgroundColor: '#fff',
+ backgroundColor: colors.bg,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
transform: [{ translateY }],
@@ -134,7 +136,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
>
{/* Drag-handle */}
-
+
{/* Header */}
@@ -147,15 +149,15 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
paddingTop: 6,
paddingBottom: 12,
borderBottomWidth: 1,
- borderBottomColor: '#f0f0f0',
+ borderBottomColor: colors.border,
}}
>
-
+
{t('common.cancel')}
-
+
{t('blocker.add_sheet_title')}
@@ -168,7 +170,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
style={{
fontSize: 12,
fontFamily: 'Nunito_600SemiBold',
- color: '#525252',
+ color: colors.textMuted,
marginBottom: 6,
}}
>
@@ -181,7 +183,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
setError(null);
}}
placeholder={t('blocker.add_sheet_placeholder')}
- placeholderTextColor="#a3a3a3"
+ placeholderTextColor={colors.textMuted}
autoCapitalize="none"
autoCorrect={false}
autoFocus
@@ -189,13 +191,13 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
returnKeyType="done"
onSubmitEditing={handleAdd}
style={{
- backgroundColor: '#f5f5f5',
+ backgroundColor: colors.surfaceElevated,
borderRadius: 12,
paddingHorizontal: 14,
paddingVertical: 12,
fontSize: 15,
fontFamily: 'Nunito_400Regular',
- color: '#0a0a0a',
+ color: colors.text,
}}
/>
{input && !valid && (
@@ -220,7 +222,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
alignItems: 'center',
gap: 10,
padding: 12,
- backgroundColor: '#f5f5f5',
+ backgroundColor: colors.surfaceElevated,
borderRadius: 12,
}}
>
@@ -235,7 +237,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
flex: 1,
fontSize: 14,
fontFamily: 'Nunito_600SemiBold',
- color: '#0a0a0a',
+ color: colors.text,
}}
numberOfLines={1}
>
@@ -289,8 +291,8 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
height: 22,
borderRadius: 6,
borderWidth: 1.5,
- borderColor: confirmPermanent ? '#16a34a' : '#d4d4d4',
- backgroundColor: confirmPermanent ? '#16a34a' : '#fff',
+ borderColor: confirmPermanent ? colors.success : colors.border,
+ backgroundColor: confirmPermanent ? colors.success : colors.bg,
alignItems: 'center',
justifyContent: 'center',
marginTop: 1,
@@ -303,7 +305,7 @@ export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) {
flex: 1,
fontSize: 13,
fontFamily: 'Nunito_400Regular',
- color: '#0a0a0a',
+ color: colors.text,
lineHeight: 18,
}}
>
diff --git a/apps/rebreak-native/components/blocker/CooldownBanner.tsx b/apps/rebreak-native/components/blocker/CooldownBanner.tsx
index 15391d4..4c294d1 100644
--- a/apps/rebreak-native/components/blocker/CooldownBanner.tsx
+++ b/apps/rebreak-native/components/blocker/CooldownBanner.tsx
@@ -2,6 +2,7 @@ import { View, Text, Pressable, ActivityIndicator } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
+import { useColors } from '../../lib/theme';
type Props = {
remainingFormatted: string; // "23:59:42"
@@ -10,6 +11,7 @@ type Props = {
export function CooldownBanner({ remainingFormatted, onCancel }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const [cancelling, setCancelling] = useState(false);
async function handleCancel() {
diff --git a/apps/rebreak-native/components/blocker/DeactivationExplainerSheet.tsx b/apps/rebreak-native/components/blocker/DeactivationExplainerSheet.tsx
index 97f77c0..df8c4ab 100644
--- a/apps/rebreak-native/components/blocker/DeactivationExplainerSheet.tsx
+++ b/apps/rebreak-native/components/blocker/DeactivationExplainerSheet.tsx
@@ -2,6 +2,7 @@ import { Modal, View, Text, Pressable, ScrollView, ActionSheetIOS, Platform, Ale
import { Ionicons } from '@expo/vector-icons';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
+import { useColors } from '../../lib/theme';
type Props = {
visible: boolean;
@@ -26,6 +27,7 @@ export function DeactivationExplainerSheet({
onStartCooldown,
}: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const [submitting, setSubmitting] = useState(false);
function showFinalConfirm() {
@@ -74,7 +76,7 @@ export function DeactivationExplainerSheet({
presentationStyle="pageSheet"
onRequestClose={onClose}
>
-
+
{/* Header */}
-
+
{t('common.back')}
-
+
{t('blocker.deactivation_heading')}
-
+
{t('blocker.deactivation_title')}
@@ -195,6 +197,7 @@ function BulletRow({
title: string;
text: string;
}) {
+ const colors = useColors();
return (
-
+
-
+
{title}
= {
export function DomainGrid({ domains, tier, onAdd, onSubmit, onUpgradePro }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
// Slot-relevante Domains (alles außer approved). Sortiert nach Status-Priority,
// innerhalb gleicher Priority dann newest-first by addedAt.
const visible = useMemo(() => {
@@ -85,7 +87,7 @@ export function DomainGrid({ domains, tier, onAdd, onSubmit, onUpgradePro }: Pro
{/* Header: Section-Title + Slot-Counter + Add-Button (inline, neben SlotPill) */}
-
+
{t('blocker.domain_section_title')}
@@ -122,7 +124,7 @@ export function DomainGrid({ domains, tier, onAdd, onSubmit, onUpgradePro }: Pro
const pct = (tier.usedSlots / tier.domainLimit) * 100;
const barColor = pct >= 90 ? '#dc2626' : pct >= 60 ? '#f59e0b' : '#16a34a';
return (
-
+
-
+
Promise<{ ok: boolean }>;
}) {
const { t } = useTranslation();
+ const colors = useColors();
const [submitting, setSubmitting] = useState(false);
const [imgError, setImgError] = useState(false);
const [successVisible, setSuccessVisible] = useState(false);
@@ -346,9 +350,9 @@ function DomainTile({
return (
{t('blocker.protection_card_title')}
@@ -76,7 +77,7 @@ export function ProtectionCard({ state, loading, onActivate, onPressSettings }:
style={{
fontSize: 12,
fontFamily: 'Nunito_400Regular',
- color: '#525252',
+ color: colors.textMuted,
marginTop: 2,
}}
>
@@ -100,7 +101,7 @@ export function ProtectionCard({ state, loading, onActivate, onPressSettings }:
width: 36,
height: 36,
borderRadius: 18,
- backgroundColor: '#ffffff',
+ backgroundColor: colors.surface,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#000',
@@ -108,7 +109,7 @@ export function ProtectionCard({ state, loading, onActivate, onPressSettings }:
shadowOpacity: 0.05,
shadowRadius: 2,
}}>
-
+
) : (
@@ -146,18 +147,19 @@ export function ProtectionCard({ state, loading, onActivate, onPressSettings }:
function Stat({
label,
value,
- valueColor = '#0a0a0a',
+ valueColor,
}: {
label: string;
value: string;
valueColor?: string;
}) {
+ const colors = useColors();
return (
-
+
{value}
-
+
{label}
diff --git a/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx b/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx
index add2fa2..2995249 100644
--- a/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx
+++ b/apps/rebreak-native/components/blocker/ProtectionDetailsSheet.tsx
@@ -16,6 +16,7 @@ import { useTranslation } from 'react-i18next';
import Svg, { Path, Circle } from 'react-native-svg';
import type { ProtectionState } from '../../lib/protection';
import { apiFetch } from '../../lib/api';
+import { useColors } from '../../lib/theme';
type Props = {
visible: boolean;
@@ -55,6 +56,7 @@ export function ProtectionDetailsSheet({
onRequestDeactivation,
}: Props) {
const { t, i18n } = useTranslation();
+ const colors = useColors();
const localeTag = i18n.language === 'de' ? 'de-DE' : 'en-US';
const sheetHeight = useRef(new Animated.Value(DEFAULT_HEIGHT)).current;
@@ -162,7 +164,7 @@ export function ProtectionDetailsSheet({
-
+
{/* Header */}
@@ -192,15 +194,15 @@ export function ProtectionDetailsSheet({
paddingTop: 4,
paddingBottom: 12,
borderBottomWidth: 1,
- borderBottomColor: '#f0f0f0',
+ borderBottomColor: colors.border,
}}
>
-
+
{t('blocker.details_title')}
-
+
{t('blocker.details_done')}
@@ -249,16 +251,16 @@ export function ProtectionDetailsSheet({
padding: 18,
borderRadius: 16,
borderWidth: 1,
- borderColor: '#e5e5e5',
- backgroundColor: '#fff',
+ borderColor: colors.border,
+ backgroundColor: colors.bg,
gap: 8,
}}
>
-
+
{t('blocker.kpi_submissions_title')}
-
+
{t('blocker.kpi_submissions_subtitle')}
@@ -323,14 +325,14 @@ export function ProtectionDetailsSheet({
flex: 1,
fontSize: 11,
fontFamily: 'Nunito_700Bold',
- color: '#737373',
+ color: colors.textMuted,
letterSpacing: 0.5,
textTransform: 'uppercase',
}}
>
{t('blocker.faq_heading')}
-
+
{[1, 2, 3, 4].map((n) => (
-
-
+
+
{label}
@@ -502,10 +505,10 @@ function KpiCard({
value={value}
locale={locale}
decimals={decimals}
- style={{ fontSize: 18, fontFamily: 'Nunito_900Black', color: '#0a0a0a', letterSpacing: -0.3 }}
+ style={{ fontSize: 18, fontFamily: 'Nunito_900Black', color: colors.text, letterSpacing: -0.3 }}
/>
{suffix ? (
- {suffix}
+ {suffix}
) : null}
@@ -522,13 +525,14 @@ function LegendItem({
label: string;
value: number;
}) {
+ const colors = useColors();
return (
- {value}
+ {value}
- {label}
+ {label}
);
}
@@ -543,6 +547,7 @@ function HalfDonut({
centerValue: number;
centerLabel: string;
}) {
+ const colors = useColors();
const total = Math.max(1, segments.reduce((s, x) => s + x.value, 0));
const W = 220;
@@ -582,7 +587,7 @@ function HalfDonut({
{/* Background track */}
-
+
{centerValue}
-
+
{centerLabel}
@@ -643,6 +648,7 @@ function polar(cx: number, cy: number, r: number, angleDeg: number) {
// ─── FAQ Item (chevron AT END of header row, on right) ─────────────────────
function FaqItem({ question, answer }: { question: string; answer: string }) {
+ const colors = useColors();
const [open, setOpen] = useState(false);
const rotateAnim = useRef(new Animated.Value(0)).current;
@@ -664,10 +670,10 @@ function FaqItem({ question, answer }: { question: string; answer: string }) {
style={{
alignSelf: 'stretch',
borderWidth: 1,
- borderColor: '#e5e5e5',
+ borderColor: colors.border,
borderRadius: 12,
overflow: 'hidden',
- backgroundColor: '#fff',
+ backgroundColor: colors.bg,
}}
>
-
+
{question}
@@ -687,19 +693,19 @@ function FaqItem({ question, answer }: { question: string; answer: string }) {
width: 28,
height: 28,
borderRadius: 14,
- backgroundColor: '#f5f5f5',
+ backgroundColor: colors.surfaceElevated,
alignItems: 'center',
justifyContent: 'center',
transform: [{ rotate }],
}}
>
-
+
{open && (
-
+
{answer}
diff --git a/apps/rebreak-native/components/blocker/ProtectionLockedCard.tsx b/apps/rebreak-native/components/blocker/ProtectionLockedCard.tsx
index 4d4ad5e..fe369a7 100644
--- a/apps/rebreak-native/components/blocker/ProtectionLockedCard.tsx
+++ b/apps/rebreak-native/components/blocker/ProtectionLockedCard.tsx
@@ -2,6 +2,7 @@ import { View, Text, Pressable } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import type { ProtectionState } from '../../lib/protection';
+import { useColors } from '../../lib/theme';
type Props = {
state: ProtectionState;
@@ -16,6 +17,7 @@ type Props = {
*/
export function ProtectionLockedCard({ state, onPressSettings }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const isCooldown = state.phase === 'cooldownActive';
const cardBg = isCooldown ? '#fef3c7' : '#dcfce7';
const cardBorder = isCooldown ? '#fcd34d' : '#86efac';
@@ -57,14 +59,14 @@ export function ProtectionLockedCard({ state, onPressSettings }: Props) {
-
+
{t('blocker.protection_card_locked_title')}
@@ -84,7 +86,7 @@ export function ProtectionLockedCard({ state, onPressSettings }: Props) {
width: 36,
height: 36,
borderRadius: 18,
- backgroundColor: '#ffffff',
+ backgroundColor: colors.surface,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#000',
@@ -92,7 +94,7 @@ export function ProtectionLockedCard({ state, onPressSettings }: Props) {
shadowOpacity: 0.05,
shadowRadius: 2,
}}>
-
+
@@ -118,11 +120,12 @@ export function ProtectionLockedCard({ state, onPressSettings }: Props) {
);
}
-function Stat({ label, value, valueColor = '#0a0a0a' }: { label: string; value: string; valueColor?: string }) {
+function Stat({ label, value, valueColor }: { label: string; value: string; valueColor?: string }) {
+ const colors = useColors();
return (
- {value}
- {label}
+ {value}
+ {label}
);
}
diff --git a/apps/rebreak-native/components/chat/ChatBubble.tsx b/apps/rebreak-native/components/chat/ChatBubble.tsx
index 0fa07a9..67a9ea5 100644
--- a/apps/rebreak-native/components/chat/ChatBubble.tsx
+++ b/apps/rebreak-native/components/chat/ChatBubble.tsx
@@ -13,6 +13,7 @@ import * as Clipboard from 'expo-clipboard';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { resolveAvatar } from '../../lib/resolveAvatar';
+import { useColors } from '../../lib/theme';
export type ChatMsg = {
id: string;
@@ -63,6 +64,8 @@ export function ChatBubble({
onOpenImage,
}: Props) {
const { t } = useTranslation();
+ const colors = useColors();
+ const styles = makeStyles(colors);
const [actionsOpen, setActionsOpen] = useState(false);
const longPressTimer = useRef | null>(null);
@@ -323,120 +326,122 @@ export function ChatBubble({
);
}
-const styles = StyleSheet.create({
- row: {
- flexDirection: 'row',
- paddingHorizontal: 8,
- },
- avatarSlot: {
- width: 30,
- marginRight: 4,
- justifyContent: 'flex-end',
- },
- avatar: {
- width: 26,
- height: 26,
- borderRadius: 13,
- backgroundColor: '#e5e5e5',
- },
- bubbleCol: {
- maxWidth: '78%',
- },
- nickname: {
- fontSize: 10,
- fontFamily: 'Nunito_700Bold',
- color: '#007AFF',
- marginBottom: 2,
- marginLeft: 10,
- },
- bubble: {
- borderRadius: 18,
- paddingHorizontal: 12,
- paddingVertical: 6,
- shadowColor: '#000',
- shadowOpacity: 0.05,
- shadowRadius: 1,
- shadowOffset: { width: 0, height: 1 },
- },
- bubbleOwn: {
- backgroundColor: '#007AFF',
- },
- bubbleOther: {
- backgroundColor: '#ffffff',
- borderWidth: StyleSheet.hairlineWidth,
- borderColor: '#e5e5e5',
- },
- replyPreview: {
- borderLeftWidth: 3,
- borderRadius: 8,
- paddingHorizontal: 8,
- paddingVertical: 4,
- marginBottom: 4,
- },
- imageWrap: {
- borderRadius: 12,
- overflow: 'hidden',
- position: 'relative',
- },
- image: {
- width: 220,
- height: 220,
- backgroundColor: '#f5f5f5',
- },
- imageTimeOverlay: {
- position: 'absolute',
- bottom: 6,
- right: 6,
- backgroundColor: 'rgba(0,0,0,0.5)',
- borderRadius: 10,
- paddingHorizontal: 6,
- paddingVertical: 2,
- flexDirection: 'row',
- alignItems: 'center',
- },
- content: {
- fontSize: 14,
- lineHeight: 20,
- fontFamily: 'Nunito_400Regular',
- },
- footer: {
- position: 'absolute',
- bottom: 4,
- right: 8,
- flexDirection: 'row',
- alignItems: 'center',
- },
- sheetBackdrop: {
- flex: 1,
- backgroundColor: 'rgba(0,0,0,0.5)',
- justifyContent: 'flex-end',
- },
- sheet: {
- backgroundColor: '#fff',
- borderTopLeftRadius: 20,
- borderTopRightRadius: 20,
- padding: 8,
- paddingBottom: Platform.OS === 'ios' ? 32 : 16,
- },
- sheetGrabber: {
- width: 36,
- height: 4,
- borderRadius: 2,
- backgroundColor: '#d4d4d4',
- alignSelf: 'center',
- marginBottom: 10,
- },
- sheetItem: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingHorizontal: 16,
- paddingVertical: 14,
- borderRadius: 12,
- },
- sheetText: {
- fontSize: 15,
- fontFamily: 'Nunito_600SemiBold',
- color: '#171717',
- marginLeft: 12,
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ row: {
+ flexDirection: 'row',
+ paddingHorizontal: 8,
+ },
+ avatarSlot: {
+ width: 30,
+ marginRight: 4,
+ justifyContent: 'flex-end',
+ },
+ avatar: {
+ width: 26,
+ height: 26,
+ borderRadius: 13,
+ backgroundColor: colors.surfaceElevated,
+ },
+ bubbleCol: {
+ maxWidth: '78%',
+ },
+ nickname: {
+ fontSize: 10,
+ fontFamily: 'Nunito_700Bold',
+ color: '#007AFF',
+ marginBottom: 2,
+ marginLeft: 10,
+ },
+ bubble: {
+ borderRadius: 18,
+ paddingHorizontal: 12,
+ paddingVertical: 6,
+ shadowColor: '#000',
+ shadowOpacity: 0.05,
+ shadowRadius: 1,
+ shadowOffset: { width: 0, height: 1 },
+ },
+ bubbleOwn: {
+ backgroundColor: '#007AFF',
+ },
+ bubbleOther: {
+ backgroundColor: colors.surface,
+ borderWidth: StyleSheet.hairlineWidth,
+ borderColor: colors.border,
+ },
+ replyPreview: {
+ borderLeftWidth: 3,
+ borderRadius: 8,
+ paddingHorizontal: 8,
+ paddingVertical: 4,
+ marginBottom: 4,
+ },
+ imageWrap: {
+ borderRadius: 12,
+ overflow: 'hidden',
+ position: 'relative',
+ },
+ image: {
+ width: 220,
+ height: 220,
+ backgroundColor: colors.surfaceElevated,
+ },
+ imageTimeOverlay: {
+ position: 'absolute',
+ bottom: 6,
+ right: 6,
+ backgroundColor: 'rgba(0,0,0,0.5)',
+ borderRadius: 10,
+ paddingHorizontal: 6,
+ paddingVertical: 2,
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ content: {
+ fontSize: 14,
+ lineHeight: 20,
+ fontFamily: 'Nunito_400Regular',
+ },
+ footer: {
+ position: 'absolute',
+ bottom: 4,
+ right: 8,
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ sheetBackdrop: {
+ flex: 1,
+ backgroundColor: 'rgba(0,0,0,0.5)',
+ justifyContent: 'flex-end',
+ },
+ sheet: {
+ backgroundColor: colors.bg,
+ borderTopLeftRadius: 20,
+ borderTopRightRadius: 20,
+ padding: 8,
+ paddingBottom: Platform.OS === 'ios' ? 32 : 16,
+ },
+ sheetGrabber: {
+ width: 36,
+ height: 4,
+ borderRadius: 2,
+ backgroundColor: colors.border,
+ alignSelf: 'center',
+ marginBottom: 10,
+ },
+ sheetItem: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 16,
+ paddingVertical: 14,
+ borderRadius: 12,
+ },
+ sheetText: {
+ fontSize: 15,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.text,
+ marginLeft: 12,
+ },
+ });
+}
diff --git a/apps/rebreak-native/components/chat/ChatInput.tsx b/apps/rebreak-native/components/chat/ChatInput.tsx
index e0dc47b..9c3ef5e 100644
--- a/apps/rebreak-native/components/chat/ChatInput.tsx
+++ b/apps/rebreak-native/components/chat/ChatInput.tsx
@@ -16,6 +16,7 @@ import * as FileSystem from 'expo-file-system/legacy';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { supabase } from '../../lib/supabase';
+import { useColors } from '../../lib/theme';
type ReplyTo = { id: string; nickname: string; content: string };
@@ -45,6 +46,7 @@ export function ChatInput({
onCancelReply,
}: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const [text, setText] = useState('');
const [attachment, setAttachment] = useState<{
uri: string;
@@ -137,6 +139,8 @@ export function ChatInput({
setAttachment(null);
}
+ const styles = makeStyles(colors);
+
return (
{/* Reply preview */}
@@ -231,103 +235,105 @@ function decodeBase64(base64: string): Uint8Array {
return bytes;
}
-const styles = StyleSheet.create({
- container: {
- backgroundColor: '#ffffff',
- borderTopWidth: StyleSheet.hairlineWidth,
- borderTopColor: '#e5e5e5',
- },
- replyBar: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingHorizontal: 12,
- paddingVertical: 8,
- backgroundColor: '#eff6ff',
- borderLeftWidth: 3,
- borderLeftColor: '#007AFF',
- marginHorizontal: 8,
- marginTop: 6,
- borderRadius: 8,
- },
- replyName: {
- fontSize: 11,
- fontFamily: 'Nunito_700Bold',
- color: '#007AFF',
- },
- replyContent: {
- fontSize: 11,
- fontFamily: 'Nunito_400Regular',
- color: '#525252',
- marginTop: 1,
- },
- attachBar: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingHorizontal: 12,
- paddingVertical: 6,
- backgroundColor: '#fafafa',
- marginHorizontal: 8,
- marginTop: 6,
- borderRadius: 8,
- },
- attachImg: {
- width: 36,
- height: 36,
- borderRadius: 6,
- marginRight: 8,
- },
- attachFileIcon: {
- width: 36,
- height: 36,
- borderRadius: 6,
- backgroundColor: '#e5e5e5',
- alignItems: 'center',
- justifyContent: 'center',
- marginRight: 8,
- },
- attachName: {
- flex: 1,
- fontSize: 12,
- fontFamily: 'Nunito_600SemiBold',
- color: '#171717',
- },
- row: {
- flexDirection: 'row',
- alignItems: 'flex-end',
- paddingHorizontal: 8,
- paddingTop: 8,
- paddingBottom: 8,
- },
- iconBtn: {
- width: 36,
- height: 36,
- borderRadius: 18,
- alignItems: 'center',
- justifyContent: 'center',
- marginRight: 4,
- },
- inputWrap: {
- flex: 1,
- backgroundColor: '#f5f5f5',
- borderRadius: 22,
- paddingHorizontal: 14,
- minHeight: 36,
- maxHeight: 120,
- justifyContent: 'center',
- },
- input: {
- fontSize: 14,
- lineHeight: 19,
- fontFamily: 'Nunito_400Regular',
- color: '#171717',
- paddingVertical: Platform.OS === 'ios' ? 8 : 4,
- },
- sendBtn: {
- width: 36,
- height: 36,
- borderRadius: 18,
- alignItems: 'center',
- justifyContent: 'center',
- marginLeft: 6,
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ container: {
+ backgroundColor: colors.bg,
+ borderTopWidth: StyleSheet.hairlineWidth,
+ borderTopColor: colors.border,
+ },
+ replyBar: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 12,
+ paddingVertical: 8,
+ backgroundColor: colors.surface,
+ borderLeftWidth: 3,
+ borderLeftColor: '#007AFF',
+ marginHorizontal: 8,
+ marginTop: 6,
+ borderRadius: 8,
+ },
+ replyName: {
+ fontSize: 11,
+ fontFamily: 'Nunito_700Bold',
+ color: '#007AFF',
+ },
+ replyContent: {
+ fontSize: 11,
+ fontFamily: 'Nunito_400Regular',
+ color: colors.textMuted,
+ marginTop: 1,
+ },
+ attachBar: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 12,
+ paddingVertical: 6,
+ backgroundColor: colors.surface,
+ marginHorizontal: 8,
+ marginTop: 6,
+ borderRadius: 8,
+ },
+ attachImg: {
+ width: 36,
+ height: 36,
+ borderRadius: 6,
+ marginRight: 8,
+ },
+ attachFileIcon: {
+ width: 36,
+ height: 36,
+ borderRadius: 6,
+ backgroundColor: colors.surfaceElevated,
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginRight: 8,
+ },
+ attachName: {
+ flex: 1,
+ fontSize: 12,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.text,
+ },
+ row: {
+ flexDirection: 'row',
+ alignItems: 'flex-end',
+ paddingHorizontal: 8,
+ paddingTop: 8,
+ paddingBottom: 8,
+ },
+ iconBtn: {
+ width: 36,
+ height: 36,
+ borderRadius: 18,
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginRight: 4,
+ },
+ inputWrap: {
+ flex: 1,
+ backgroundColor: colors.surfaceElevated,
+ borderRadius: 22,
+ paddingHorizontal: 14,
+ minHeight: 36,
+ maxHeight: 120,
+ justifyContent: 'center',
+ },
+ input: {
+ fontSize: 14,
+ lineHeight: 19,
+ fontFamily: 'Nunito_400Regular',
+ color: colors.text,
+ paddingVertical: Platform.OS === 'ios' ? 8 : 4,
+ },
+ sendBtn: {
+ width: 36,
+ height: 36,
+ borderRadius: 18,
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginLeft: 6,
+ },
+ });
+}
diff --git a/apps/rebreak-native/components/chat/CreateRoomSheet.tsx b/apps/rebreak-native/components/chat/CreateRoomSheet.tsx
index 5b9be05..956e058 100644
--- a/apps/rebreak-native/components/chat/CreateRoomSheet.tsx
+++ b/apps/rebreak-native/components/chat/CreateRoomSheet.tsx
@@ -12,6 +12,7 @@ import {
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { apiFetch } from '../../lib/api';
+import { useColors } from '../../lib/theme';
type Props = {
visible: boolean;
@@ -21,6 +22,8 @@ type Props = {
export function CreateRoomSheet({ visible, onClose, onCreated }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
+ const styles = makeStyles(colors);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [isPublic, setIsPublic] = useState(true);
@@ -145,138 +148,140 @@ export function CreateRoomSheet({ visible, onClose, onCreated }: Props) {
);
}
-const styles = StyleSheet.create({
- backdrop: {
- flex: 1,
- backgroundColor: 'rgba(0,0,0,0.5)',
- justifyContent: 'flex-end',
- },
- sheet: {
- backgroundColor: '#fff',
- borderTopLeftRadius: 22,
- borderTopRightRadius: 22,
- padding: 18,
- paddingBottom: Platform.OS === 'ios' ? 32 : 18,
- },
- grabber: {
- width: 36,
- height: 4,
- borderRadius: 2,
- backgroundColor: '#d4d4d4',
- alignSelf: 'center',
- marginBottom: 12,
- },
- title: {
- fontSize: 17,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- marginBottom: 14,
- },
- input: {
- backgroundColor: '#f5f5f5',
- borderRadius: 12,
- paddingHorizontal: 14,
- paddingVertical: 12,
- fontSize: 14,
- fontFamily: 'Nunito_400Regular',
- color: '#171717',
- marginBottom: 10,
- },
- toggleRow: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- paddingVertical: 6,
- marginTop: 4,
- },
- toggleLabel: {
- fontSize: 14,
- fontFamily: 'Nunito_600SemiBold',
- color: '#171717',
- },
- toggle: {
- width: 46,
- height: 28,
- borderRadius: 14,
- backgroundColor: '#e5e5e5',
- padding: 2,
- justifyContent: 'center',
- },
- toggleOn: {
- backgroundColor: '#007AFF',
- },
- toggleKnob: {
- width: 24,
- height: 24,
- borderRadius: 12,
- backgroundColor: '#fff',
- shadowColor: '#000',
- shadowOpacity: 0.15,
- shadowRadius: 2,
- shadowOffset: { width: 0, height: 1 },
- elevation: 2,
- },
- toggleKnobOn: {
- transform: [{ translateX: 18 }],
- },
- subLabel: {
- fontSize: 12,
- fontFamily: 'Nunito_600SemiBold',
- color: '#737373',
- marginBottom: 6,
- },
- modeRow: {
- flexDirection: 'row',
- },
- modeBtn: {
- flex: 1,
- paddingVertical: 8,
- borderRadius: 10,
- borderWidth: 1,
- borderColor: '#e5e5e5',
- alignItems: 'center',
- marginRight: 6,
- },
- modeBtnActive: {
- backgroundColor: '#eff6ff',
- borderColor: '#007AFF',
- },
- modeBtnText: {
- fontSize: 12,
- fontFamily: 'Nunito_600SemiBold',
- color: '#737373',
- },
- modeBtnTextActive: {
- color: '#007AFF',
- },
- actions: {
- flexDirection: 'row',
- marginTop: 20,
- },
- cancelBtn: {
- flex: 1,
- backgroundColor: '#f5f5f5',
- paddingVertical: 12,
- borderRadius: 12,
- alignItems: 'center',
- marginRight: 6,
- },
- cancelText: {
- fontSize: 14,
- fontFamily: 'Nunito_600SemiBold',
- color: '#171717',
- },
- createBtn: {
- flex: 1,
- backgroundColor: '#007AFF',
- paddingVertical: 12,
- borderRadius: 12,
- alignItems: 'center',
- marginLeft: 6,
- },
- createText: {
- fontSize: 14,
- fontFamily: 'Nunito_700Bold',
- color: '#fff',
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ backdrop: {
+ flex: 1,
+ backgroundColor: 'rgba(0,0,0,0.5)',
+ justifyContent: 'flex-end',
+ },
+ sheet: {
+ backgroundColor: colors.bg,
+ borderTopLeftRadius: 22,
+ borderTopRightRadius: 22,
+ padding: 18,
+ paddingBottom: Platform.OS === 'ios' ? 32 : 18,
+ },
+ grabber: {
+ width: 36,
+ height: 4,
+ borderRadius: 2,
+ backgroundColor: colors.border,
+ alignSelf: 'center',
+ marginBottom: 12,
+ },
+ title: {
+ fontSize: 17,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ marginBottom: 14,
+ },
+ input: {
+ backgroundColor: colors.surfaceElevated,
+ borderRadius: 12,
+ paddingHorizontal: 14,
+ paddingVertical: 12,
+ fontSize: 14,
+ fontFamily: 'Nunito_400Regular',
+ color: colors.text,
+ marginBottom: 10,
+ },
+ toggleRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ paddingVertical: 6,
+ marginTop: 4,
+ },
+ toggleLabel: {
+ fontSize: 14,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.text,
+ },
+ toggle: {
+ width: 46,
+ height: 28,
+ borderRadius: 14,
+ backgroundColor: colors.surfaceElevated,
+ padding: 2,
+ justifyContent: 'center',
+ },
+ toggleOn: {
+ backgroundColor: '#007AFF',
+ },
+ toggleKnob: {
+ width: 24,
+ height: 24,
+ borderRadius: 12,
+ backgroundColor: colors.bg,
+ shadowColor: '#000',
+ shadowOpacity: 0.15,
+ shadowRadius: 2,
+ shadowOffset: { width: 0, height: 1 },
+ elevation: 2,
+ },
+ toggleKnobOn: {
+ transform: [{ translateX: 18 }],
+ },
+ subLabel: {
+ fontSize: 12,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.textMuted,
+ marginBottom: 6,
+ },
+ modeRow: {
+ flexDirection: 'row',
+ },
+ modeBtn: {
+ flex: 1,
+ paddingVertical: 8,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.border,
+ alignItems: 'center',
+ marginRight: 6,
+ },
+ modeBtnActive: {
+ backgroundColor: colors.surface,
+ borderColor: '#007AFF',
+ },
+ modeBtnText: {
+ fontSize: 12,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.textMuted,
+ },
+ modeBtnTextActive: {
+ color: '#007AFF',
+ },
+ actions: {
+ flexDirection: 'row',
+ marginTop: 20,
+ },
+ cancelBtn: {
+ flex: 1,
+ backgroundColor: colors.surfaceElevated,
+ paddingVertical: 12,
+ borderRadius: 12,
+ alignItems: 'center',
+ marginRight: 6,
+ },
+ cancelText: {
+ fontSize: 14,
+ fontFamily: 'Nunito_600SemiBold',
+ color: colors.text,
+ },
+ createBtn: {
+ flex: 1,
+ backgroundColor: '#007AFF',
+ paddingVertical: 12,
+ borderRadius: 12,
+ alignItems: 'center',
+ marginLeft: 6,
+ },
+ createText: {
+ fontSize: 14,
+ fontFamily: 'Nunito_700Bold',
+ color: '#fff',
+ },
+ });
+}
diff --git a/apps/rebreak-native/components/chat/RoomCard.tsx b/apps/rebreak-native/components/chat/RoomCard.tsx
index 1afbac5..5ef7e86 100644
--- a/apps/rebreak-native/components/chat/RoomCard.tsx
+++ b/apps/rebreak-native/components/chat/RoomCard.tsx
@@ -1,6 +1,7 @@
import { View, Text, Pressable, Image, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
+import { useColors } from '../../lib/theme';
export type Room = {
id: string;
@@ -29,6 +30,8 @@ function formatTime(ts: string, justNow: string) {
export function RoomCard({ room, onPress }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
+ const styles = makeStyles(colors);
const initials = room.name
.split(' ')
.slice(0, 2)
@@ -42,7 +45,7 @@ export function RoomCard({ room, onPress }: Props) {
{room.avatarUrl ? (
@@ -102,116 +105,118 @@ export function RoomCard({ room, onPress }: Props) {
);
}
-const styles = StyleSheet.create({
- row: {
- width: '100%',
- flexDirection: 'row',
- alignItems: 'center',
- paddingHorizontal: 14,
- paddingVertical: 11,
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#f5f5f5',
- },
- avatar: {
- width: 42,
- height: 42,
- borderRadius: 21,
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- marginRight: 10,
- },
- avatarImg: {
- width: 42,
- height: 42,
- },
- avatarInitials: {
- fontSize: 13,
- fontFamily: 'Nunito_700Bold',
- color: '#525252',
- },
- info: {
- flex: 1,
- minWidth: 0,
- },
- headerRow: {
- flexDirection: 'row',
- alignItems: 'center',
- },
- footerRow: {
- flexDirection: 'row',
- alignItems: 'center',
- marginTop: 3,
- },
- footerTextWrap: {
- flex: 1,
- minWidth: 0,
- },
- metaPill: {
- flexDirection: 'row',
- alignItems: 'center',
- marginLeft: 8,
- paddingHorizontal: 6,
- paddingVertical: 2,
- borderRadius: 8,
- backgroundColor: '#f5f5f5',
- },
- name: {
- fontSize: 14,
- fontFamily: 'Nunito_700Bold',
- color: '#171717',
- flexShrink: 1,
- },
- defaultBadge: {
- marginLeft: 6,
- paddingHorizontal: 6,
- paddingVertical: 1,
- backgroundColor: '#eff6ff',
- borderRadius: 8,
- },
- defaultBadgeText: {
- fontSize: 9,
- fontFamily: 'Nunito_700Bold',
- color: '#007AFF',
- },
- lastMessage: {
- fontSize: 12,
- fontFamily: 'Nunito_400Regular',
- color: '#737373',
- },
- description: {
- fontSize: 12,
- fontFamily: 'Nunito_400Regular',
- color: '#a3a3a3',
- },
- right: {
- alignItems: 'flex-end',
- marginLeft: 8,
- },
- memberCount: {
- fontSize: 11,
- fontFamily: 'Nunito_700Bold',
- color: '#737373',
- marginLeft: 3,
- },
- time: {
- fontSize: 10,
- fontFamily: 'Nunito_500Medium',
- color: '#a3a3a3',
- marginLeft: 'auto',
- paddingLeft: 6,
- },
- joinBadge: {
- marginLeft: 6,
- paddingHorizontal: 8,
- paddingVertical: 3,
- backgroundColor: '#eff6ff',
- borderRadius: 10,
- },
- joinBadgeText: {
- fontSize: 10,
- fontFamily: 'Nunito_700Bold',
- color: '#007AFF',
- },
-});
+function makeStyles(colors: ReturnType) {
+ return StyleSheet.create({
+ row: {
+ width: '100%',
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 14,
+ paddingVertical: 11,
+ backgroundColor: colors.bg,
+ borderBottomWidth: StyleSheet.hairlineWidth,
+ borderBottomColor: colors.border,
+ },
+ avatar: {
+ width: 42,
+ height: 42,
+ borderRadius: 21,
+ alignItems: 'center',
+ justifyContent: 'center',
+ overflow: 'hidden',
+ marginRight: 10,
+ },
+ avatarImg: {
+ width: 42,
+ height: 42,
+ },
+ avatarInitials: {
+ fontSize: 13,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ },
+ info: {
+ flex: 1,
+ minWidth: 0,
+ },
+ headerRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ footerRow: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginTop: 3,
+ },
+ footerTextWrap: {
+ flex: 1,
+ minWidth: 0,
+ },
+ metaPill: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginLeft: 8,
+ paddingHorizontal: 6,
+ paddingVertical: 2,
+ borderRadius: 8,
+ backgroundColor: colors.surfaceElevated,
+ },
+ name: {
+ fontSize: 14,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.text,
+ flexShrink: 1,
+ },
+ defaultBadge: {
+ marginLeft: 6,
+ paddingHorizontal: 6,
+ paddingVertical: 1,
+ backgroundColor: colors.surface,
+ borderRadius: 8,
+ },
+ defaultBadgeText: {
+ fontSize: 9,
+ fontFamily: 'Nunito_700Bold',
+ color: '#007AFF',
+ },
+ lastMessage: {
+ fontSize: 12,
+ fontFamily: 'Nunito_400Regular',
+ color: colors.textMuted,
+ },
+ description: {
+ fontSize: 12,
+ fontFamily: 'Nunito_400Regular',
+ color: colors.textMuted,
+ },
+ right: {
+ alignItems: 'flex-end',
+ marginLeft: 8,
+ },
+ memberCount: {
+ fontSize: 11,
+ fontFamily: 'Nunito_700Bold',
+ color: colors.textMuted,
+ marginLeft: 3,
+ },
+ time: {
+ fontSize: 10,
+ fontFamily: 'Nunito_500Medium',
+ color: colors.textMuted,
+ marginLeft: 'auto',
+ paddingLeft: 6,
+ },
+ joinBadge: {
+ marginLeft: 6,
+ paddingHorizontal: 8,
+ paddingVertical: 3,
+ backgroundColor: colors.surface,
+ borderRadius: 10,
+ },
+ joinBadgeText: {
+ fontSize: 10,
+ fontFamily: 'Nunito_700Bold',
+ color: '#007AFF',
+ },
+ });
+}
diff --git a/apps/rebreak-native/components/mail/ConnectMailSheet.tsx b/apps/rebreak-native/components/mail/ConnectMailSheet.tsx
index 8c8a4d7..be7405b 100644
--- a/apps/rebreak-native/components/mail/ConnectMailSheet.tsx
+++ b/apps/rebreak-native/components/mail/ConnectMailSheet.tsx
@@ -18,6 +18,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { useMailConnect, detectProvider, type MailProvider } from '../../hooks/useMailConnect';
+import { useColors } from '../../lib/theme';
const SCREEN_HEIGHT = Dimensions.get('window').height;
const SHEET_HEIGHT = SCREEN_HEIGHT * 0.65;
@@ -97,6 +98,7 @@ const PROVIDERS: ProviderConfig[] = [
*/
export function ConnectMailSheet({ visible, onClose, onSuccess }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
const insets = useSafeAreaInsets();
const { connect, connecting, error: connectError } = useMailConnect();
@@ -203,7 +205,7 @@ export function ConnectMailSheet({ visible, onClose, onSuccess }: Props) {
right: 0,
bottom: 0,
height: SHEET_HEIGHT,
- backgroundColor: '#fff',
+ backgroundColor: colors.bg,
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
transform: [{ translateY }],
@@ -215,7 +217,7 @@ export function ConnectMailSheet({ visible, onClose, onSuccess }: Props) {
>
{/* Drag-Handle */}
-
+
{/* Header */}
@@ -228,24 +230,24 @@ export function ConnectMailSheet({ visible, onClose, onSuccess }: Props) {
paddingTop: 6,
paddingBottom: 12,
borderBottomWidth: 1,
- borderBottomColor: '#f0f0f0',
+ borderBottomColor: colors.border,
}}
>
{view === 'form' ? (
-
+
{t('common.back')}
) : (
-
+
{t('common.cancel')}
)}
-
+
{view === 'form' && currentProvider
? t(currentProvider.labelKey)
: t('mail.connect_sheet_title')}
@@ -293,6 +295,7 @@ function ProviderGrid({
onSelect: (p: ProviderConfig) => void;
t: (key: string) => string;
}) {
+ const colors = useColors();
return (
@@ -345,13 +348,13 @@ function ProviderGrid({
{t(p.labelKey)}
-
+
))}
@@ -394,6 +397,7 @@ function FormView({
insets,
t,
}: FormViewProps) {
+ const colors = useColors();
const canConnect = email.trim().length > 0 && password.trim().length > 0 && !connecting;
return (
@@ -461,7 +465,7 @@ function FormView({
style={{
fontSize: 12,
fontFamily: 'Nunito_600SemiBold',
- color: '#525252',
+ color: colors.textMuted,
marginBottom: 6,
}}
>
@@ -471,19 +475,19 @@ function FormView({
value={email}
onChangeText={onEmailChange}
placeholder={t('mail.form_email_placeholder')}
- placeholderTextColor="#a3a3a3"
+ placeholderTextColor={colors.textMuted}
autoCapitalize="none"
autoCorrect={false}
keyboardType="email-address"
returnKeyType="next"
style={{
- backgroundColor: '#f5f5f5',
+ backgroundColor: colors.surfaceElevated,
borderRadius: 12,
paddingHorizontal: 14,
paddingVertical: 12,
fontSize: 15,
fontFamily: 'Nunito_400Regular',
- color: '#0a0a0a',
+ color: colors.text,
}}
/>
@@ -494,7 +498,7 @@ function FormView({
style={{
fontSize: 12,
fontFamily: 'Nunito_600SemiBold',
- color: '#525252',
+ color: colors.textMuted,
marginBottom: 6,
}}
>
@@ -505,21 +509,21 @@ function FormView({
value={password}
onChangeText={onPasswordChange}
placeholder={t('mail.form_password_placeholder')}
- placeholderTextColor="#a3a3a3"
+ placeholderTextColor={colors.textMuted}
secureTextEntry={!passwordVisible}
autoCapitalize="none"
autoCorrect={false}
returnKeyType="done"
onSubmitEditing={onConnect}
style={{
- backgroundColor: '#f5f5f5',
+ backgroundColor: colors.surfaceElevated,
borderRadius: 12,
paddingHorizontal: 14,
paddingVertical: 12,
paddingRight: 46,
fontSize: 15,
fontFamily: 'Nunito_400Regular',
- color: '#0a0a0a',
+ color: colors.text,
}}
/>
{/* Drag-Handle */}
-
+
{/* Header */}
@@ -129,15 +131,15 @@ export function EditMailAccountSheet({ visible, email, onClose, onSuccess }: Pro
paddingTop: 6,
paddingBottom: 12,
borderBottomWidth: 1,
- borderBottomColor: '#f0f0f0',
+ borderBottomColor: colors.border,
}}
>
-
+
{t('common.cancel')}
-
+
{t('mail.edit_account_title')}
@@ -148,7 +150,7 @@ export function EditMailAccountSheet({ visible, email, onClose, onSuccess }: Pro
style={{
fontSize: 13,
fontFamily: 'Nunito_400Regular',
- color: '#737373',
+ color: colors.textMuted,
lineHeight: 18,
}}
>
@@ -159,13 +161,13 @@ export function EditMailAccountSheet({ visible, email, onClose, onSuccess }: Pro
style={{
flexDirection: 'row',
alignItems: 'center',
- backgroundColor: '#f5f5f5',
+ backgroundColor: colors.surfaceElevated,
borderRadius: 12,
paddingHorizontal: 14,
gap: 10,
}}
>
-
+
{
@@ -173,7 +175,7 @@ export function EditMailAccountSheet({ visible, email, onClose, onSuccess }: Pro
setFormError(null);
}}
placeholder={t('mail.app_password_placeholder')}
- placeholderTextColor="#a3a3a3"
+ placeholderTextColor={colors.textMuted}
secureTextEntry={!passwordVisible}
autoCapitalize="none"
autoCorrect={false}
@@ -182,7 +184,7 @@ export function EditMailAccountSheet({ visible, email, onClose, onSuccess }: Pro
paddingVertical: 14,
fontSize: 15,
fontFamily: 'Nunito_400Regular',
- color: '#0a0a0a',
+ color: colors.text,
}}
/>
setPasswordVisible((p) => !p)} hitSlop={8}>
diff --git a/apps/rebreak-native/components/mail/MailEmptyState.tsx b/apps/rebreak-native/components/mail/MailEmptyState.tsx
index 36fb6f7..c6765e0 100644
--- a/apps/rebreak-native/components/mail/MailEmptyState.tsx
+++ b/apps/rebreak-native/components/mail/MailEmptyState.tsx
@@ -1,6 +1,7 @@
import { Pressable, Text, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
+import { useColors } from '../../lib/theme';
type Props = {
onConnectPress: () => void;
@@ -12,14 +13,15 @@ type Props = {
*/
export function MailEmptyState({ onConnectPress }: Props) {
const { t } = useTranslation();
+ const colors = useColors();
return (
(
-
+
{t(`mail.${key}`)}
diff --git a/apps/rebreak-native/components/profile/DigaMissionBanner.tsx b/apps/rebreak-native/components/profile/DigaMissionBanner.tsx
index b31f9cd..1aa68bd 100644
--- a/apps/rebreak-native/components/profile/DigaMissionBanner.tsx
+++ b/apps/rebreak-native/components/profile/DigaMissionBanner.tsx
@@ -1,6 +1,6 @@
import { View, Text, Pressable } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
type Props = {
onDismiss?: () => void;
@@ -8,6 +8,7 @@ type Props = {
};
export function DigaMissionBanner({ onDismiss, onContribute }: Props) {
+ const colors = useColors();
return (
void; onSpeak?: (text: string) => Promise | void };
export function BreathingCard({ onDone, onSpeak }: Props) {
+ const colors = useColors();
const [breathState, setBreathState] = useState('idle');
const [countdown, setCountdown] = useState(3);
const [round, setRound] = useState(1);
@@ -86,7 +87,7 @@ export function BreathingCard({ onDone, onSpeak }: Props) {
4-7-8 Atemübung
3 Runden · beruhigt dein Nervensystem
- { setCountdown(3); setBreathState('countdown'); }}>
+ { setCountdown(3); setBreathState('countdown'); }}>
Starten
@@ -114,6 +115,7 @@ export function BreathingCard({ onDone, onSpeak }: Props) {
// ── BreathingDrawer (bottom sheet, covers input, slides up) ───────────────────
export function BreathingDrawer({ onDone, onSpeak }: Props) {
+ const colors = useColors();
const slideAnim = useRef(new Animated.Value(500)).current;
useEffect(() => {
Animated.spring(slideAnim, { toValue: 0, useNativeDriver: true, damping: 22, mass: 1, stiffness: 200 }).start();
@@ -121,7 +123,7 @@ export function BreathingDrawer({ onDone, onSpeak }: Props) {
return (
<>
-
+
@@ -131,14 +133,14 @@ export function BreathingDrawer({ onDone, onSpeak }: Props) {
const st = StyleSheet.create({
breathBackdrop: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.28)', zIndex: 20 },
- breathDrawerContainer: { position: 'absolute', bottom: 0, left: 0, right: 0, zIndex: 21, backgroundColor: '#ffffff', borderTopLeftRadius: 28, borderTopRightRadius: 28, paddingBottom: 36, shadowColor: '#000', shadowOffset: { width: 0, height: -4 }, shadowOpacity: 0.18, shadowRadius: 20, elevation: 24 },
+ breathDrawerContainer: { position: 'absolute', bottom: 0, left: 0, right: 0, zIndex: 21, borderTopLeftRadius: 28, borderTopRightRadius: 28, paddingBottom: 36, shadowColor: '#000', shadowOffset: { width: 0, height: -4 }, shadowOpacity: 0.18, shadowRadius: 20, elevation: 24 },
breathDrawerHandle: { width: 40, height: 4, borderRadius: 2, backgroundColor: '#d1d5db', alignSelf: 'center', marginTop: 14, marginBottom: 4 },
breathCardInner: { paddingHorizontal: 24, paddingTop: 20, paddingBottom: 8, alignItems: 'center', gap: 16 },
breathCircleLg: { width: 190, height: 190, borderRadius: 95, alignItems: 'center', justifyContent: 'center', borderWidth: 5 },
breathCountLg: { fontFamily: 'Nunito_800ExtraBold', fontSize: 60, color: '#111827', lineHeight: 68 },
breathTitle: { fontFamily: 'Nunito_700Bold', fontSize: 15, color: '#111827' },
breathSub: { fontFamily: 'Nunito_400Regular', fontSize: 13, color: '#6b7280', textAlign: 'center' },
- breathStartBtn: { borderRadius: 12, backgroundColor: colors.brandOrange, paddingHorizontal: 28, paddingVertical: 10, marginTop: 4 },
+ breathStartBtn: { borderRadius: 12, paddingHorizontal: 28, paddingVertical: 10, marginTop: 4 },
breathStartTxt: { color: '#fff', fontFamily: 'Nunito_700Bold', fontSize: 14 },
breathRound: { fontFamily: 'Nunito_600SemiBold', fontSize: 12, color: '#9ca3af' },
breathPhaseLabel: { fontFamily: 'Nunito_700Bold', fontSize: 13 },
diff --git a/apps/rebreak-native/components/urge/InlineRatingDrawer.tsx b/apps/rebreak-native/components/urge/InlineRatingDrawer.tsx
index da2d657..a063a58 100644
--- a/apps/rebreak-native/components/urge/InlineRatingDrawer.tsx
+++ b/apps/rebreak-native/components/urge/InlineRatingDrawer.tsx
@@ -11,7 +11,7 @@ import {
ScrollView,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
import type { SosFeedback } from './SosFeedbackModal';
/**
@@ -25,6 +25,7 @@ export function InlineRatingDrawer({
onSubmit: (feedback: SosFeedback) => Promise | void;
onClose: () => void;
}) {
+ const colors = useColors();
const slide = useRef(new Animated.Value(600)).current;
const [better, setBetter] = useState(null);
const [rating, setRating] = useState(0);
@@ -58,7 +59,7 @@ export function InlineRatingDrawer({
return (
<>
-
+
- Bewerte diese Session
+ Bewerte diese Session
-
+
Dein Feedback hilft uns, Lyra besser zu machen.
- Fühlst du dich besser?
+ Fühlst du dich besser?
- Bewertung
+ Bewertung
{[1, 2, 3, 4, 5].map((n) => (
setRating(n)} hitSlop={6}>
@@ -116,9 +117,9 @@ export function InlineRatingDrawer({
))}
- Bemerkung (optional)
+ Bemerkung (optional)
Abbrechen
@@ -199,7 +200,7 @@ const s = StyleSheet.create({
cancelTxt: { fontFamily: 'Nunito_700Bold', fontSize: 14, color: '#475569' },
submitBtn: {
flex: 2, paddingVertical: 12, borderRadius: 12,
- alignItems: 'center', backgroundColor: colors.brandOrange,
+ alignItems: 'center',
},
submitTxt: { fontFamily: 'Nunito_800ExtraBold', fontSize: 14, color: '#fff' },
});
diff --git a/apps/rebreak-native/components/urge/ShareSuccessDrawer.tsx b/apps/rebreak-native/components/urge/ShareSuccessDrawer.tsx
index 2e00899..d470403 100644
--- a/apps/rebreak-native/components/urge/ShareSuccessDrawer.tsx
+++ b/apps/rebreak-native/components/urge/ShareSuccessDrawer.tsx
@@ -12,7 +12,7 @@ import {
ScrollView,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
export interface ShareSuccessPayload {
text: string;
@@ -35,6 +35,7 @@ export function ShareSuccessDrawer({
onClose: () => void;
onRegenerate?: () => void;
}) {
+ const colors = useColors();
const slide = useRef(new Animated.Value(600)).current;
const [text, setText] = useState(initialText);
const [submitting, setSubmitting] = useState(false);
@@ -67,7 +68,7 @@ export function ShareSuccessDrawer({
return (
<>
-
+
- Erfolg teilen
+ Erfolg teilen
-
+
Inspiriere andere — dein Beitrag wird anonym in der Community gepostet.
@@ -93,7 +94,7 @@ export function ShareSuccessDrawer({
) : (
Abbrechen
@@ -203,7 +204,6 @@ const s = StyleSheet.create({
shareBtn: {
flex: 1, minWidth: 110,
flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 6,
- backgroundColor: colors.brandOrange,
borderRadius: 12, paddingVertical: 12,
},
shareBtnDisabled: { opacity: 0.5 },
diff --git a/apps/rebreak-native/components/urge/SosFeedbackModal.tsx b/apps/rebreak-native/components/urge/SosFeedbackModal.tsx
index 85f57fe..d6032c7 100644
--- a/apps/rebreak-native/components/urge/SosFeedbackModal.tsx
+++ b/apps/rebreak-native/components/urge/SosFeedbackModal.tsx
@@ -1,7 +1,7 @@
import { useState } from 'react';
import { View, Text, Pressable, TextInput, Modal, StyleSheet, Platform, KeyboardAvoidingView, ScrollView } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
export interface SosFeedback {
better: boolean | null;
@@ -18,6 +18,7 @@ export function SosFeedbackModal({
onSubmit: (feedback: SosFeedback) => void;
onSkip: () => void;
}) {
+ const colors = useColors();
const [better, setBetter] = useState(null);
const [rating, setRating] = useState(0);
const [text, setText] = useState('');
@@ -43,12 +44,12 @@ export function SosFeedbackModal({
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
>
-
- Wie war diese Session?
- Dein Feedback hilft Lyra besser zu werden.
+
+ Wie war diese Session?
+ Dein Feedback hilft Lyra besser zu werden.
{/* Better Yes/No */}
- Fühlst du dich besser?
+ Fühlst du dich besser?
{/* Stars */}
- Bewertung
+ Bewertung
{[1, 2, 3, 4, 5].map((n) => (
setRating(n)} hitSlop={6}>
@@ -81,9 +82,9 @@ export function SosFeedbackModal({
{/* Comment */}
- Bemerkung (optional)
+ Bemerkung (optional)
Überspringen
-
+
Senden
@@ -136,6 +137,6 @@ const s = StyleSheet.create({
actions: { flexDirection: 'row', gap: 10, marginTop: 18 },
skipBtn: { flex: 1, paddingVertical: 12, borderRadius: 12, alignItems: 'center', backgroundColor: '#f1f5f9' },
skipTxt: { fontFamily: 'Nunito_700Bold', fontSize: 14, color: '#475569' },
- submitBtn: { flex: 2, paddingVertical: 12, borderRadius: 12, alignItems: 'center', backgroundColor: colors.brandOrange },
+ submitBtn: { flex: 2, paddingVertical: 12, borderRadius: 12, alignItems: 'center' },
submitTxt: { fontFamily: 'Nunito_800ExtraBold', fontSize: 14, color: '#fff' },
});
diff --git a/apps/rebreak-native/components/urge/UrgeStats.tsx b/apps/rebreak-native/components/urge/UrgeStats.tsx
index 783a51b..0443815 100644
--- a/apps/rebreak-native/components/urge/UrgeStats.tsx
+++ b/apps/rebreak-native/components/urge/UrgeStats.tsx
@@ -3,7 +3,7 @@ import { View, Text, ActivityIndicator } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { apiFetch } from '../../lib/api';
-import { colors } from '../../lib/theme';
+import { useColors } from '../../lib/theme';
type Emotion = 'stress' | 'sadness' | 'anger' | 'empty' | 'boredom' | 'other';
@@ -30,6 +30,7 @@ function emotionLabel(key: string, t: (k: string) => string): string {
}
function StatCard({ label, value, color }: { label: string; value: string; color: string }) {
+ const colors = useColors();
return (
{label}
@@ -61,6 +62,7 @@ function StatCard({ label, value, color }: { label: string; value: string; color
export function UrgeStats() {
const { t } = useTranslation();
+ const colors = useColors();
const [logs, setLogs] = useState([]);
const [loading, setLoading] = useState(true);
@@ -175,18 +177,18 @@ export function UrgeStats() {
style={{
borderRadius: 18,
borderWidth: 1,
- borderColor: '#e5e7eb',
- backgroundColor: '#fff',
+ borderColor: colors.border,
+ backgroundColor: colors.bg,
padding: 14,
}}
>
{t('urge.this_week')}
-
+
-
+
{t('urge.chart_weekday_title')}
@@ -254,7 +256,7 @@ export function UrgeStats() {
}}
/>
{day.label}
@@ -268,12 +270,12 @@ export function UrgeStats() {
style={{
borderRadius: 18,
borderWidth: 1,
- borderColor: '#e5e7eb',
- backgroundColor: '#fff',
+ borderColor: colors.border,
+ backgroundColor: colors.bg,
padding: 14,
}}
>
-
+
{t('urge.chart_time_title')}
@@ -284,7 +286,7 @@ export function UrgeStats() {
style={{
width: 74,
fontSize: 12,
- color: '#6b7280',
+ color: colors.textMuted,
fontFamily: 'Nunito_600SemiBold',
}}
>
@@ -295,7 +297,7 @@ export function UrgeStats() {
flex: 1,
height: 7,
borderRadius: 4,
- backgroundColor: '#e5e7eb',
+ backgroundColor: colors.surfaceElevated,
}}
>
@@ -328,12 +330,12 @@ export function UrgeStats() {
style={{
borderRadius: 18,
borderWidth: 1,
- borderColor: '#e5e7eb',
- backgroundColor: '#fff',
+ borderColor: colors.border,
+ backgroundColor: colors.bg,
padding: 14,
}}
>
-
+
{t('urge.chart_top_emotions')}
@@ -341,9 +343,9 @@ export function UrgeStats() {
{emotionLabel(emo, t)} x{c}