@modhamanish/rn-mm-template 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/MMTemplate/App.tsx +15 -2
  2. package/MMTemplate/package.json +3 -0
  3. package/MMTemplate/src/components/AppText.tsx +125 -0
  4. package/MMTemplate/src/components/CustomToast.tsx +8 -6
  5. package/MMTemplate/src/components/FeatureItem.tsx +11 -8
  6. package/MMTemplate/src/components/InfoCard.tsx +10 -6
  7. package/MMTemplate/src/components/LanguageSwitcher.tsx +8 -7
  8. package/MMTemplate/src/components/TextInput.tsx +214 -23
  9. package/MMTemplate/src/components/ThemeSwitcher.tsx +12 -7
  10. package/MMTemplate/src/context/ThemeContext.tsx +15 -1
  11. package/MMTemplate/src/locales/en.json +19 -2
  12. package/MMTemplate/src/locales/hi.json +19 -2
  13. package/MMTemplate/src/navigation/AppStack.tsx +2 -0
  14. package/MMTemplate/src/navigation/MainTab.tsx +15 -4
  15. package/MMTemplate/src/navigation/routes.ts +2 -0
  16. package/MMTemplate/src/screens/AddNoteScreen.tsx +155 -0
  17. package/MMTemplate/src/screens/HomeScreen.tsx +60 -33
  18. package/MMTemplate/src/screens/LoginScreen.tsx +67 -25
  19. package/MMTemplate/src/screens/NoteScreen.tsx +241 -0
  20. package/MMTemplate/src/screens/ProfileScreen.tsx +26 -25
  21. package/MMTemplate/src/screens/SettingsScreen.tsx +17 -16
  22. package/MMTemplate/src/screens/WelcomeScreen.tsx +23 -23
  23. package/MMTemplate/src/services/axiosInstance.ts +41 -0
  24. package/MMTemplate/src/services/note.query.ts +40 -0
  25. package/MMTemplate/src/services/queryKeys.ts +4 -0
  26. package/MMTemplate/src/types/components.types.ts +47 -1
  27. package/MMTemplate/src/types/navigation.types.ts +2 -0
  28. package/MMTemplate/src/types/services.types.ts +6 -0
  29. package/MMTemplate/src/utils/storageHelper.ts +2 -0
  30. package/MMTemplate/src/utils/validationSchemas.ts +6 -0
  31. package/README.md +1 -1
  32. package/package.json +1 -1
@@ -1,11 +1,6 @@
1
1
  import React, { FC } from 'react';
2
- import {
3
- View,
4
- Text,
5
- TouchableOpacity,
6
- StyleSheet,
7
- ScrollView,
8
- } from 'react-native';
2
+ import { View, TouchableOpacity, StyleSheet, ScrollView } from 'react-native';
3
+ import AppText from '../components/AppText';
9
4
  import { useFormik } from 'formik';
10
5
  import { useTranslation } from 'react-i18next';
11
6
  import { useTheme } from '../context/ThemeContext';
@@ -65,13 +60,40 @@ const LoginScreen: FC = () => {
65
60
  >
66
61
  <AnimationView animType="FadeIn" duration={800}>
67
62
  <View style={styles.header}>
68
- <Text style={styles.title}>{t('auth.welcomeBack')}</Text>
69
- <Text style={styles.subtitle}>{t('auth.signInToContinue')}</Text>
63
+ <AppText variant="h1" style={styles.title}>
64
+ {t('auth.welcomeBack')}
65
+ </AppText>
66
+ <AppText size="body" style={styles.subtitle}>
67
+ {t('auth.signInToContinue')}
68
+ </AppText>
70
69
  </View>
71
70
  </AnimationView>
72
71
 
73
72
  <AnimationView delay={200} animType="FadeIn" duration={800}>
74
73
  <View style={styles.formContainer}>
74
+ {/* Hint Banner */}
75
+ <View style={styles.hintBanner}>
76
+ <AppText variant="bold" style={styles.hintTitle}>
77
+ {t('auth.mockCredentialsHint')}
78
+ </AppText>
79
+ <View style={styles.hintContent}>
80
+ <AppText variant="semiBold" size={13} style={styles.hintLabel}>
81
+ {t('auth.email')}:{' '}
82
+ </AppText>
83
+ <AppText size={13} style={styles.hintValue}>
84
+ {userMockData.email}
85
+ </AppText>
86
+ </View>
87
+ <View style={styles.hintContent}>
88
+ <AppText variant="semiBold" size={13} style={styles.hintLabel}>
89
+ {t('auth.password')}:{' '}
90
+ </AppText>
91
+ <AppText size={13} style={styles.hintValue}>
92
+ {userMockData.password}
93
+ </AppText>
94
+ </View>
95
+ </View>
96
+
75
97
  {/* Email Input */}
76
98
  <TextInput
77
99
  label={t('auth.email')}
@@ -102,9 +124,9 @@ const LoginScreen: FC = () => {
102
124
 
103
125
  {/* Forgot Password */}
104
126
  <TouchableOpacity style={styles.forgotPassword}>
105
- <Text style={styles.forgotPasswordText}>
127
+ <AppText variant="semiBold" style={styles.forgotPasswordText}>
106
128
  {t('auth.forgotPassword')}
107
- </Text>
129
+ </AppText>
108
130
  </TouchableOpacity>
109
131
 
110
132
  {/* Login Button */}
@@ -112,16 +134,24 @@ const LoginScreen: FC = () => {
112
134
  style={styles.loginButton}
113
135
  onPress={() => formik.handleSubmit()}
114
136
  >
115
- <Text style={styles.loginButtonText}>{t('auth.login')}</Text>
137
+ <AppText
138
+ variant="bold"
139
+ size="body"
140
+ style={styles.loginButtonText}
141
+ >
142
+ {t('auth.login')}
143
+ </AppText>
116
144
  </TouchableOpacity>
117
145
 
118
146
  {/* Sign Up Link */}
119
147
  <View style={styles.signupContainer}>
120
- <Text style={styles.signupText}>
148
+ <AppText style={styles.signupText}>
121
149
  {t('auth.dontHaveAccount')}{' '}
122
- </Text>
150
+ </AppText>
123
151
  <TouchableOpacity>
124
- <Text style={styles.signupLink}>{t('auth.signUp')}</Text>
152
+ <AppText variant="semiBold" style={styles.signupLink}>
153
+ {t('auth.signUp')}
154
+ </AppText>
125
155
  </TouchableOpacity>
126
156
  </View>
127
157
  </View>
@@ -149,26 +179,43 @@ const getStyles = ({ colors }: ThemeType) =>
149
179
  alignItems: 'center',
150
180
  },
151
181
  title: {
152
- fontSize: 32,
153
- fontWeight: '700',
154
182
  color: colors.textColor,
155
183
  marginBottom: 8,
156
184
  },
157
185
  subtitle: {
158
- fontSize: 16,
159
186
  color: colors.textColor + 'CC',
160
187
  },
161
188
  formContainer: {
162
189
  width: '100%',
163
190
  },
191
+ hintBanner: {
192
+ backgroundColor: colors.primary + '10',
193
+ padding: 16,
194
+ borderRadius: 12,
195
+ borderWidth: 1,
196
+ borderColor: colors.primary + '30',
197
+ marginBottom: 24,
198
+ },
199
+ hintTitle: {
200
+ color: colors.primary,
201
+ marginBottom: 8,
202
+ },
203
+ hintContent: {
204
+ flexDirection: 'row',
205
+ marginBottom: 4,
206
+ },
207
+ hintLabel: {
208
+ color: colors.textColor,
209
+ },
210
+ hintValue: {
211
+ color: colors.textColor + 'CC',
212
+ },
164
213
  forgotPassword: {
165
214
  alignSelf: 'flex-end',
166
215
  marginBottom: 24,
167
216
  },
168
217
  forgotPasswordText: {
169
218
  color: colors.primary,
170
- fontSize: 14,
171
- fontWeight: '600',
172
219
  },
173
220
  loginButton: {
174
221
  backgroundColor: colors.primary,
@@ -179,8 +226,6 @@ const getStyles = ({ colors }: ThemeType) =>
179
226
  },
180
227
  loginButtonText: {
181
228
  color: colors.white,
182
- fontSize: 16,
183
- fontWeight: '700',
184
229
  },
185
230
  signupContainer: {
186
231
  flexDirection: 'row',
@@ -189,11 +234,8 @@ const getStyles = ({ colors }: ThemeType) =>
189
234
  },
190
235
  signupText: {
191
236
  color: colors.textColor + 'CC',
192
- fontSize: 14,
193
237
  },
194
238
  signupLink: {
195
239
  color: colors.primary,
196
- fontSize: 14,
197
- fontWeight: '600',
198
240
  },
199
241
  });
@@ -0,0 +1,241 @@
1
+ import {
2
+ StyleSheet,
3
+ FlatList,
4
+ View,
5
+ TouchableOpacity,
6
+ ActivityIndicator,
7
+ RefreshControl,
8
+ } from 'react-native';
9
+ import AppText from '../components/AppText';
10
+ import React, { FC, useMemo } from 'react';
11
+ import FullScreenContainer from '../components/FullScreenContainer';
12
+ import { useTheme } from '../context/ThemeContext';
13
+ import { useTranslation } from 'react-i18next';
14
+ import { ThemeType } from '../theme/Colors';
15
+ import { useGetNotesQuery } from '../services/note.query';
16
+ import { Note } from '../types/services.types';
17
+ import AnimationView from '../components/AnimationView';
18
+
19
+ import { navigate } from '../utils/navigationUtils';
20
+ import Routes from '../navigation/routes';
21
+
22
+ const NoteScreen: FC = () => {
23
+ const { t } = useTranslation();
24
+ const theme = useTheme();
25
+ const styles = getStyles(theme);
26
+
27
+ const { data: notes, isLoading, refetch, isRefetching } = useGetNotesQuery();
28
+
29
+ const renderNoteItem = ({ item, index }: { item: Note; index: number }) => (
30
+ <AnimationView delay={index * 100} animType="FadeIn" duration={500}>
31
+ <TouchableOpacity style={styles.noteCard} activeOpacity={0.7}>
32
+ <View style={styles.noteHeader}>
33
+ <AppText
34
+ variant="bold"
35
+ size={18}
36
+ style={styles.noteTitle}
37
+ numberOfLines={1}
38
+ >
39
+ {item.title}
40
+ </AppText>
41
+ <View style={styles.noteTag}>
42
+ <AppText
43
+ variant="semiBold"
44
+ size="xsmall"
45
+ style={styles.noteTagText}
46
+ >
47
+ #{index + 1}
48
+ </AppText>
49
+ </View>
50
+ </View>
51
+ <AppText style={styles.noteContent} numberOfLines={3}>
52
+ {item.description}
53
+ </AppText>
54
+ </TouchableOpacity>
55
+ </AnimationView>
56
+ );
57
+
58
+ const listHeader = useMemo(
59
+ () => (
60
+ <View style={styles.headerContainer}>
61
+ <AppText variant="h1" style={styles.headerTitle}>
62
+ {t('common.notes')}
63
+ </AppText>
64
+ <AppText style={styles.headerSubtitle}>
65
+ {notes?.length || 0} {t('common.notes').toLowerCase()}
66
+ </AppText>
67
+ </View>
68
+ ),
69
+ [notes?.length, styles, t],
70
+ );
71
+
72
+ const emptyComponent = () => (
73
+ <View style={styles.emptyContainer}>
74
+ <AppText size={60} style={styles.emptyIcon}>
75
+ 📝
76
+ </AppText>
77
+ <AppText size={18} style={styles.emptyText}>
78
+ {t('common.noNotesFound')}
79
+ </AppText>
80
+ <TouchableOpacity
81
+ style={styles.addNoteButtonSmall}
82
+ activeOpacity={0.8}
83
+ onPress={() => navigate(Routes.AddNoteScreen)}
84
+ >
85
+ <AppText
86
+ variant="bold"
87
+ size="body"
88
+ style={styles.addNoteButtonTextSmall}
89
+ >
90
+ {t('common.addNote')}
91
+ </AppText>
92
+ </TouchableOpacity>
93
+ </View>
94
+ );
95
+
96
+ return (
97
+ <FullScreenContainer style={styles.container}>
98
+ {isLoading && !isRefetching ? (
99
+ <View style={styles.loadingContainer}>
100
+ <ActivityIndicator size="large" color={theme.colors.primary} />
101
+ </View>
102
+ ) : (
103
+ <FlatList
104
+ data={notes}
105
+ keyExtractor={(_, index) => index.toString()}
106
+ renderItem={renderNoteItem}
107
+ ListHeaderComponent={listHeader}
108
+ ListEmptyComponent={emptyComponent}
109
+ contentContainerStyle={styles.listContent}
110
+ refreshControl={
111
+ <RefreshControl
112
+ refreshing={isRefetching}
113
+ onRefresh={refetch}
114
+ tintColor={theme.colors.primary}
115
+ colors={[theme.colors.primary]}
116
+ />
117
+ }
118
+ />
119
+ )}
120
+ <TouchableOpacity
121
+ style={styles.fab}
122
+ activeOpacity={0.8}
123
+ onPress={() => navigate(Routes.AddNoteScreen)}
124
+ >
125
+ <AppText size="xxlarge" style={styles.fabIcon}>
126
+ +
127
+ </AppText>
128
+ </TouchableOpacity>
129
+ </FullScreenContainer>
130
+ );
131
+ };
132
+
133
+ export default NoteScreen;
134
+
135
+ const getStyles = ({ colors }: ThemeType) =>
136
+ StyleSheet.create({
137
+ container: {
138
+ flex: 1,
139
+ backgroundColor: colors.backgroundColor,
140
+ },
141
+ loadingContainer: {
142
+ flex: 1,
143
+ justifyContent: 'center',
144
+ alignItems: 'center',
145
+ },
146
+ listContent: {
147
+ padding: 20,
148
+ paddingBottom: 100,
149
+ },
150
+ headerContainer: {
151
+ marginBottom: 24,
152
+ marginTop: 20,
153
+ },
154
+ headerTitle: {
155
+ color: colors.textColor,
156
+ letterSpacing: -0.5,
157
+ },
158
+ headerSubtitle: {
159
+ color: colors.textColor + '80',
160
+ marginTop: 4,
161
+ },
162
+ noteCard: {
163
+ backgroundColor: colors.backgroundColor,
164
+ borderRadius: 16,
165
+ padding: 16,
166
+ marginBottom: 16,
167
+ borderWidth: 1,
168
+ borderColor: colors.textColor + '15',
169
+ shadowColor: colors.black,
170
+ shadowOffset: { width: 0, height: 2 },
171
+ shadowOpacity: 0.05,
172
+ shadowRadius: 10,
173
+ elevation: 2,
174
+ },
175
+ noteHeader: {
176
+ flexDirection: 'row',
177
+ justifyContent: 'space-between',
178
+ alignItems: 'center',
179
+ marginBottom: 8,
180
+ },
181
+ noteTitle: {
182
+ color: colors.textColor,
183
+ flex: 1,
184
+ marginRight: 8,
185
+ },
186
+ noteTag: {
187
+ backgroundColor: colors.primary + '15',
188
+ paddingHorizontal: 8,
189
+ paddingVertical: 4,
190
+ borderRadius: 8,
191
+ },
192
+ noteTagText: {
193
+ color: colors.primary,
194
+ textTransform: 'uppercase',
195
+ },
196
+ noteContent: {
197
+ color: colors.textColor + 'B3',
198
+ lineHeight: 20,
199
+ },
200
+ emptyContainer: {
201
+ flex: 1,
202
+ alignItems: 'center',
203
+ justifyContent: 'center',
204
+ marginTop: 100,
205
+ },
206
+ emptyIcon: {
207
+ marginBottom: 16,
208
+ },
209
+ emptyText: {
210
+ color: colors.textColor + '80',
211
+ marginBottom: 24,
212
+ },
213
+ addNoteButtonSmall: {
214
+ backgroundColor: colors.primary,
215
+ paddingHorizontal: 24,
216
+ paddingVertical: 12,
217
+ borderRadius: 12,
218
+ },
219
+ addNoteButtonTextSmall: {
220
+ color: colors.white,
221
+ },
222
+ fab: {
223
+ position: 'absolute',
224
+ right: 20,
225
+ bottom: 20,
226
+ width: 60,
227
+ height: 60,
228
+ borderRadius: 30,
229
+ backgroundColor: colors.primary,
230
+ justifyContent: 'center',
231
+ alignItems: 'center',
232
+ elevation: 5,
233
+ shadowColor: colors.black,
234
+ shadowOffset: { width: 0, height: 4 },
235
+ shadowOpacity: 0.3,
236
+ shadowRadius: 6,
237
+ },
238
+ fabIcon: {
239
+ color: colors.white,
240
+ },
241
+ });
@@ -1,5 +1,6 @@
1
1
  import React, { FC } from 'react';
2
- import { View, Text, TouchableOpacity, StyleSheet, Alert } from 'react-native';
2
+ import { View, TouchableOpacity, StyleSheet, Alert } from 'react-native';
3
+ import AppText from '../components/AppText';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import { useTheme } from '../context/ThemeContext';
5
6
  import { ThemeType } from '../theme/Colors';
@@ -41,26 +42,32 @@ const ProfileScreen: FC = () => {
41
42
  <AnimationView animType="FadeIn" duration={800}>
42
43
  <View style={styles.header}>
43
44
  <View style={styles.avatarContainer}>
44
- <Text style={styles.avatarText}>
45
+ <AppText variant="bold" size={40} style={styles.avatarText}>
45
46
  {user?.name?.charAt(0).toUpperCase() || 'U'}
46
- </Text>
47
+ </AppText>
47
48
  </View>
48
- <Text style={styles.name}>{user?.name || 'User'}</Text>
49
- <Text style={styles.email}>
49
+ <AppText variant="bold" style={styles.name}>
50
+ {user?.name || 'User'}
51
+ </AppText>
52
+ <AppText style={styles.email}>
50
53
  {user?.email || 'user@example.com'}
51
- </Text>
54
+ </AppText>
52
55
  </View>
53
56
  </AnimationView>
54
57
 
55
58
  <AnimationView delay={300} animType="FadeIn" duration={800}>
56
59
  <InfoCard title={t('profile.accountInformation')} icon="👤">
57
60
  <View style={styles.infoRow}>
58
- <Text style={styles.infoLabel}>{t('profile.name')}:</Text>
59
- <Text style={styles.infoValue}>{user?.name || 'N/A'}</Text>
61
+ <AppText variant="semiBold" style={styles.infoLabel}>
62
+ {t('profile.name')}:
63
+ </AppText>
64
+ <AppText style={styles.infoValue}>{user?.name || 'N/A'}</AppText>
60
65
  </View>
61
66
  <View style={styles.infoRow}>
62
- <Text style={styles.infoLabel}>{t('profile.email')}:</Text>
63
- <Text style={styles.infoValue}>{user?.email || 'N/A'}</Text>
67
+ <AppText variant="semiBold" style={styles.infoLabel}>
68
+ {t('profile.email')}:
69
+ </AppText>
70
+ <AppText style={styles.infoValue}>{user?.email || 'N/A'}</AppText>
64
71
  </View>
65
72
  </InfoCard>
66
73
  </AnimationView>
@@ -70,15 +77,21 @@ const ProfileScreen: FC = () => {
70
77
  style={styles.settingsButton}
71
78
  onPress={() => navigate(Routes.SettingsScreen)}
72
79
  >
73
- <Text style={styles.settingsButtonText}>
80
+ <AppText
81
+ variant="bold"
82
+ size="body"
83
+ style={styles.settingsButtonText}
84
+ >
74
85
  ⚙️ {t('settings.settings')}
75
- </Text>
86
+ </AppText>
76
87
  </TouchableOpacity>
77
88
  </AnimationView>
78
89
 
79
90
  <AnimationView delay={600} animType="FadeIn" duration={800}>
80
91
  <TouchableOpacity style={styles.logoutButton} onPress={confirmLogout}>
81
- <Text style={styles.logoutButtonText}>{t('common.logout')}</Text>
92
+ <AppText variant="bold" size="body" style={styles.logoutButtonText}>
93
+ {t('common.logout')}
94
+ </AppText>
82
95
  </TouchableOpacity>
83
96
  </AnimationView>
84
97
  </View>
@@ -113,18 +126,13 @@ const getStyles = ({ colors }: ThemeType) =>
113
126
  marginBottom: 16,
114
127
  },
115
128
  avatarText: {
116
- fontSize: 40,
117
- fontWeight: '700',
118
129
  color: colors.white,
119
130
  },
120
131
  name: {
121
- fontSize: 24,
122
- fontWeight: '700',
123
132
  color: colors.textColor,
124
133
  marginBottom: 4,
125
134
  },
126
135
  email: {
127
- fontSize: 14,
128
136
  color: colors.textColor + 'CC',
129
137
  },
130
138
  infoRow: {
@@ -134,12 +142,9 @@ const getStyles = ({ colors }: ThemeType) =>
134
142
  paddingVertical: 8,
135
143
  },
136
144
  infoLabel: {
137
- fontSize: 14,
138
- fontWeight: '600',
139
145
  color: colors.textColor,
140
146
  },
141
147
  infoValue: {
142
- fontSize: 14,
143
148
  color: colors.textColor + 'CC',
144
149
  },
145
150
  logoutButton: {
@@ -151,8 +156,6 @@ const getStyles = ({ colors }: ThemeType) =>
151
156
  },
152
157
  logoutButtonText: {
153
158
  color: colors.white,
154
- fontSize: 16,
155
- fontWeight: '700',
156
159
  },
157
160
  settingsButton: {
158
161
  backgroundColor: colors.backgroundColor,
@@ -165,7 +168,5 @@ const getStyles = ({ colors }: ThemeType) =>
165
168
  },
166
169
  settingsButtonText: {
167
170
  color: colors.primary,
168
- fontSize: 16,
169
- fontWeight: '700',
170
171
  },
171
172
  });
@@ -1,5 +1,6 @@
1
1
  import React, { FC } from 'react';
2
- import { View, Text, StyleSheet, ScrollView } from 'react-native';
2
+ import { View, StyleSheet, ScrollView } from 'react-native';
3
+ import AppText from '../components/AppText';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import { useTheme } from '../context/ThemeContext';
5
6
  import { ThemeType } from '../theme/Colors';
@@ -21,20 +22,24 @@ const SettingsScreen: FC = () => {
21
22
  >
22
23
  <AnimationView animType="FadeIn" duration={800}>
23
24
  <View style={styles.header}>
24
- <Text style={styles.title}>{t('settings.settings')}</Text>
25
- <Text style={styles.subtitle}>
25
+ <AppText variant="h1" style={styles.title}>
26
+ {t('settings.settings')}
27
+ </AppText>
28
+ <AppText size="body" style={styles.subtitle}>
26
29
  {t('settings.customizeYourExperience')}
27
- </Text>
30
+ </AppText>
28
31
  </View>
29
32
  </AnimationView>
30
33
 
31
34
  {/* Language Section */}
32
35
  <AnimationView delay={200} animType="FadeIn" duration={800}>
33
36
  <View style={styles.section}>
34
- <Text style={styles.sectionTitle}>{t('settings.language')}</Text>
35
- <Text style={styles.sectionDescription}>
37
+ <AppText variant="semiBold" size={18} style={styles.sectionTitle}>
38
+ {t('settings.language')}
39
+ </AppText>
40
+ <AppText style={styles.sectionDescription}>
36
41
  {t('settings.chooseYourPreferredLanguage')}
37
- </Text>
42
+ </AppText>
38
43
  <LanguageSwitcher />
39
44
  </View>
40
45
  </AnimationView>
@@ -42,10 +47,12 @@ const SettingsScreen: FC = () => {
42
47
  {/* Theme Section */}
43
48
  <AnimationView delay={400} animType="FadeIn" duration={800}>
44
49
  <View style={styles.section}>
45
- <Text style={styles.sectionTitle}>{t('settings.theme')}</Text>
46
- <Text style={styles.sectionDescription}>
50
+ <AppText variant="semiBold" size={18} style={styles.sectionTitle}>
51
+ {t('settings.theme')}
52
+ </AppText>
53
+ <AppText style={styles.sectionDescription}>
47
54
  {t('settings.switchBetweenLightAndDark')}
48
- </Text>
55
+ </AppText>
49
56
  <ThemeSwitcher />
50
57
  </View>
51
58
  </AnimationView>
@@ -70,26 +77,20 @@ const getStyles = ({ colors }: ThemeType) =>
70
77
  marginBottom: 32,
71
78
  },
72
79
  title: {
73
- fontSize: 32,
74
- fontWeight: '700',
75
80
  color: colors.textColor,
76
81
  marginBottom: 8,
77
82
  },
78
83
  subtitle: {
79
- fontSize: 16,
80
84
  color: colors.textColor + 'CC',
81
85
  },
82
86
  section: {
83
87
  marginBottom: 32,
84
88
  },
85
89
  sectionTitle: {
86
- fontSize: 18,
87
- fontWeight: '600',
88
90
  color: colors.textColor,
89
91
  marginBottom: 8,
90
92
  },
91
93
  sectionDescription: {
92
- fontSize: 14,
93
94
  color: colors.textColor + 'CC',
94
95
  marginBottom: 16,
95
96
  },