@xetwa/design-system 1.0.35 → 1.0.37

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 (27) hide show
  1. package/package.json +1 -1
  2. package/src/components/Buttons/IconButton/IconButton.tsx +2 -2
  3. package/src/components/Buttons/JourneyButton/JourneyButton.tsx +8 -2
  4. package/src/components/Buttons/MainButton/MainButton.tsx +0 -19
  5. package/src/components/Buttons/WordChip/WordChip.tsx +11 -5
  6. package/src/components/Cards/BoardingPassCard/BoardingPassCard.tsx +11 -25
  7. package/src/components/Cards/ModuleCard/ModuleCard.stories.tsx +29 -2
  8. package/src/components/Cards/ModuleCard/ModuleCard.tsx +207 -54
  9. package/src/components/Cards/Passport/PassportCover.tsx +3 -3
  10. package/src/components/Charts/WeeklyProgressChart/WeeklyProgressChart.tsx +8 -9
  11. package/src/components/DataDisplay/Avatar/Avatar.tsx +8 -9
  12. package/src/components/DataDisplay/Badge/Badge.tsx +13 -20
  13. package/src/components/DataDisplay/InstructionBubble/InstructionBubble.tsx +2 -2
  14. package/src/components/DataDisplay/LevelBadge/LevelBadge.tsx +2 -15
  15. package/src/components/DataDisplay/NumberBadge/NumberBadge.tsx +1 -2
  16. package/src/components/DataDisplay/StatBadge/StatBadge.tsx +1 -1
  17. package/src/components/DataDisplay/Tag/Tag.tsx +11 -23
  18. package/src/components/Feedback/FeedbackBottomSheet/FeedbackBottomSheet.tsx +4 -13
  19. package/src/components/Headers/CountryHeader/CountryHeader.tsx +3 -3
  20. package/src/components/Headers/ProfileHeader/ProfileHeader.tsx +8 -5
  21. package/src/components/Inputs/FillInTheBlank/FillInTheBlank.tsx +5 -5
  22. package/src/components/Inputs/TextInput/TextInput.tsx +4 -4
  23. package/src/components/Navigation/BottomTabBar/BottomTabBarItem.tsx +1 -1
  24. package/src/components/Navigation/ProgressMap/ProgressMap.tsx +9 -9
  25. package/src/components/Navigation/WorldProgressMap/WorldProgressMap.tsx +9 -9
  26. package/src/components/Typography/Typography.tsx +16 -10
  27. package/src/styles/theme.ts +39 -24
@@ -34,19 +34,19 @@ export const WeeklyProgressChart = ({
34
34
  // Compute dimensions based on size variant
35
35
  let defaultMaxHeight = 80;
36
36
  let barWidth = 24;
37
- let titleFontSize = 14;
38
- let labelFontSize = 12;
37
+ let titleVariant: any = 'btnMd';
38
+ let labelVariant: any = 'bodySm';
39
39
 
40
40
  if (size === 'sm') {
41
41
  defaultMaxHeight = 50;
42
42
  barWidth = 16;
43
- titleFontSize = 12;
44
- labelFontSize = 10;
43
+ titleVariant = 'btnSm';
44
+ labelVariant = 'caption';
45
45
  } else if (size === 'lg') {
46
46
  defaultMaxHeight = 110;
47
47
  barWidth = 32;
48
- titleFontSize = 16;
49
- labelFontSize = 14;
48
+ titleVariant = 'btnLg';
49
+ labelVariant = 'bodyMd';
50
50
  }
51
51
 
52
52
  const finalMaxHeight = maxHeight ?? defaultMaxHeight;
@@ -77,7 +77,7 @@ export const WeeklyProgressChart = ({
77
77
  <View style={[styles.container, style]}>
78
78
  {/* Header / Title */}
79
79
  <View style={styles.header}>
80
- <Typography style={[styles.title, { fontSize: scaleText(titleFontSize) }]}>
80
+ <Typography variant={titleVariant} style={[styles.title]}>
81
81
  {title.toUpperCase()}
82
82
  {subtitle ? ` · ${subtitle.toUpperCase()}` : ''}
83
83
  </Typography>
@@ -122,12 +122,11 @@ export const WeeklyProgressChart = ({
122
122
  />
123
123
  </View>
124
124
  <Typography
125
+ variant={labelVariant}
125
126
  style={[
126
127
  styles.dayLabel,
127
128
  {
128
129
  color: labelColor,
129
- fontSize: scaleText(labelFontSize),
130
-
131
130
  marginTop: scale(12),
132
131
  }
133
132
  ]}
@@ -44,12 +44,12 @@ const SQUARE_RADIUS_MAP: Record<AvatarSize, number> = {
44
44
  xl: 22,
45
45
  };
46
46
 
47
- const FONT_SIZE_MAP: Record<AvatarSize, number> = {
48
- xs: 12,
49
- sm: 14,
50
- md: 18,
51
- lg: 22,
52
- xl: 28,
47
+ const VARIANT_MAP: Record<AvatarSize, any> = {
48
+ xs: 'bodySm',
49
+ sm: 'btnMd',
50
+ md: 'h2',
51
+ lg: 'h1',
52
+ xl: 'display1',
53
53
  };
54
54
 
55
55
  export const Avatar = ({
@@ -67,8 +67,7 @@ export const Avatar = ({
67
67
  ? pxSize / 2
68
68
  : scale(SQUARE_RADIUS_MAP[size]);
69
69
 
70
- const fontSize = scaleText(FONT_SIZE_MAP[size]);
71
- const lineHeight = fontSize * 1.2;
70
+ const typographyVariant = VARIANT_MAP[size];
72
71
 
73
72
  const containerStyles = [
74
73
  styles.container,
@@ -96,7 +95,7 @@ export const Avatar = ({
96
95
  return (
97
96
  <View style={containerStyles}>
98
97
  {initials ? (
99
- <Typography style={[styles.text, { fontSize, lineHeight }]}>
98
+ <Typography variant={typographyVariant} style={[styles.text]}>
100
99
  {initials}
101
100
  </Typography>
102
101
  ) : null}
@@ -70,6 +70,18 @@ export const Badge = ({
70
70
 
71
71
  const vStyles = getVariantStyles();
72
72
 
73
+ const getTypographyVariant = () => {
74
+ switch (size) {
75
+ case 'xs': return 'caption';
76
+ case 'sm': return 'caption';
77
+ case 'md': return 'bodySm';
78
+ case 'lg': return 'bodyMd';
79
+ case 'xl': return 'h3';
80
+ case 'xxl': return 'h2';
81
+ default: return 'caption';
82
+ }
83
+ };
84
+
73
85
  return (
74
86
  <View style={[
75
87
  styles.container,
@@ -78,9 +90,8 @@ export const Badge = ({
78
90
  style
79
91
  ]}>
80
92
  {typeof content === 'string' || typeof content === 'number' ? (
81
- <Typography style={[
93
+ <Typography variant={getTypographyVariant()} style={[
82
94
  styles.text,
83
- size === 'xs' ? styles.textXs : size === 'sm' ? styles.textSm : size === 'md' ? styles.textMd : size === 'lg' ? styles.textLg : size === 'xl' ? styles.textXl : styles.textXxl,
84
95
  { color: vStyles.color }
85
96
  ]}>
86
97
  {content}
@@ -125,22 +136,4 @@ const styles = StyleSheet.create({
125
136
  text: {
126
137
 
127
138
  },
128
- textXs: {
129
- fontSize: 9,
130
- },
131
- textSm: {
132
- fontSize: 10,
133
- },
134
- textMd: {
135
- fontSize: 12,
136
- },
137
- textLg: {
138
- fontSize: 14,
139
- },
140
- textXl: {
141
- fontSize: 16,
142
- },
143
- textXxl: {
144
- fontSize: 18,
145
- },
146
139
  });
@@ -45,11 +45,11 @@ export const InstructionBubble = ({
45
45
  borderWidth: scale(2),
46
46
  }
47
47
  ]}>
48
- <Typography style={[styles.title, { fontSize: scaleText(22), lineHeight: scaleText(28) }]}>
48
+ <Typography variant="h1" style={[styles.title]}>
49
49
  {title}
50
50
  </Typography>
51
51
  {subtitle && (
52
- <Typography style={[styles.subtitle, { fontSize: scaleText(14), marginTop: scale(4) }]}>
52
+ <Typography variant="bodyMd" style={[styles.subtitle, { marginTop: scale(4) }]}>
53
53
  {subtitle}
54
54
  </Typography>
55
55
  )}
@@ -75,13 +75,13 @@ export const LevelBadge = ({
75
75
  />
76
76
 
77
77
  {/* Level Code */}
78
- <Typography style={[styles.levelText, isLarge ? styles.levelTextLg : styles.levelTextSm]}>
78
+ <Typography variant={isLarge ? 'display1' : 'btnMd'} style={[styles.levelText]}>
79
79
  {levelCode}
80
80
  </Typography>
81
81
 
82
82
  {/* Optional Descriptive Label for Large Badge */}
83
83
  {isLarge && (
84
- <Typography style={[styles.labelText, { color: config.color }]}>
84
+ <Typography variant="btnMd" style={[styles.labelText, { color: config.color }]}>
85
85
  {config.label}
86
86
  </Typography>
87
87
  )}
@@ -98,21 +98,8 @@ const styles = StyleSheet.create({
98
98
  alignSelf: 'flex-start',
99
99
  },
100
100
  levelText: {
101
-
102
101
  color: '#51332d',
103
- lineHeight: 28, // Matches large font alignment
104
- },
105
- levelTextLg: {
106
- fontSize: 28,
107
- lineHeight: 30,
108
- },
109
- levelTextSm: {
110
- fontSize: 14,
111
- lineHeight: 16,
112
102
  },
113
103
  labelText: {
114
-
115
- fontSize: 14,
116
- lineHeight: 16,
117
104
  },
118
105
  });
@@ -29,8 +29,7 @@ export const NumberBadge = ({ value, selected = false, correct = false }: Number
29
29
  alignItems: 'center',
30
30
  justifyContent: 'center',
31
31
  }}>
32
- <Typography style={{
33
- fontSize: 14,
32
+ <Typography variant="btnMd" style={{
34
33
  color: textColor,
35
34
  }}>
36
35
  {value}
@@ -103,7 +103,7 @@ export const StatBadge = ({
103
103
  <View style={styles.iconContainer}>
104
104
  {renderIcon()}
105
105
  </View>
106
- <Typography style={[styles.text, { fontSize: scaleText(16) }]}>
106
+ <Typography variant="h3" style={[styles.text]}>
107
107
  {value}
108
108
  </Typography>
109
109
  </View>
@@ -72,6 +72,16 @@ export const Tag = ({
72
72
 
73
73
  const vStyles = getVariantStyles();
74
74
 
75
+ const getTypographyVariant = () => {
76
+ switch (size) {
77
+ case 'xs': return 'caption';
78
+ case 'sm': return 'caption';
79
+ case 'md': return 'caption';
80
+ case 'lg': return 'label';
81
+ default: return 'caption';
82
+ }
83
+ };
84
+
75
85
  return (
76
86
  <View style={[
77
87
  styles.container,
@@ -80,9 +90,8 @@ export const Tag = ({
80
90
  style
81
91
  ]}>
82
92
  {icon && <View style={styles.iconContainer}>{icon}</View>}
83
- <Typography style={[
93
+ <Typography variant={getTypographyVariant()} style={[
84
94
  styles.text,
85
- size === 'xs' ? styles.textXs : size === 'sm' ? styles.textSm : size === 'md' ? styles.textMd : styles.textLg,
86
95
  { color: vStyles.color }
87
96
  ]}>
88
97
  {label}
@@ -119,29 +128,8 @@ const styles = StyleSheet.create({
119
128
  borderRadius: 12,
120
129
  },
121
130
  text: {
122
-
123
131
  textTransform: 'uppercase',
124
132
  },
125
- textXs: {
126
- fontSize: 9,
127
- lineHeight: 11,
128
- letterSpacing: 0.54,
129
- },
130
- textSm: {
131
- fontSize: 10,
132
- lineHeight: 12,
133
- letterSpacing: 0.6, // 10 * 0.06em
134
- },
135
- textMd: {
136
- fontSize: 11,
137
- lineHeight: 13,
138
- letterSpacing: 0.66, // 11 * 0.06em
139
- },
140
- textLg: {
141
- fontSize: 12,
142
- lineHeight: 14,
143
- letterSpacing: 0.72,
144
- },
145
133
  iconContainer: {
146
134
  marginRight: 4,
147
135
  }
@@ -80,15 +80,15 @@ export const FeedbackBottomSheet: React.FC<FeedbackBottomSheetProps> = ({
80
80
  <Yaya variant={finalMascotVariant} avatarOnly size={64} />
81
81
  </View>
82
82
  <View style={styles.textContainer}>
83
- <Typography style={[styles.title, { color: borderColor }]}>{title}</Typography>
84
- <Typography style={[styles.subtitle, { color: borderColor }]}>{subtitle}</Typography>
83
+ <Typography variant="h1" style={[styles.title, { color: borderColor }]}>{title}</Typography>
84
+ <Typography variant="bodyLg" style={[styles.subtitle, { color: borderColor }]}>{subtitle}</Typography>
85
85
  </View>
86
86
  </View>
87
87
 
88
88
  {!isCorrect && correctAnswer && (
89
89
  <View style={styles.correctAnswerBox}>
90
- <Typography style={styles.correctAnswerLabel}>RESPOSTA CERTA</Typography>
91
- <Typography style={styles.correctAnswerText}>{correctAnswer}</Typography>
90
+ <Typography variant="label" style={styles.correctAnswerLabel}>RESPOSTA CERTA</Typography>
91
+ <Typography variant="h1" style={styles.correctAnswerText}>{correctAnswer}</Typography>
92
92
  </View>
93
93
  )}
94
94
 
@@ -132,9 +132,6 @@ const styles = StyleSheet.create({
132
132
  marginBottom: 2,
133
133
  },
134
134
  subtitle: {
135
-
136
- fontSize: 15,
137
-
138
135
  marginTop: 2,
139
136
  },
140
137
  button: {
@@ -153,16 +150,10 @@ const styles = StyleSheet.create({
153
150
  borderColor: 'rgba(207, 91, 72, 0.15)', // light red tint border
154
151
  },
155
152
  correctAnswerLabel: {
156
-
157
- fontSize: 11,
158
-
159
153
  color: '#cf5b48',
160
- letterSpacing: 0.8,
161
- textTransform: 'uppercase',
162
154
  marginBottom: 4,
163
155
  },
164
156
  correctAnswerText: {
165
- ...theme.typography.h1,
166
157
  color: theme.colors.brown[700],
167
158
  },
168
159
  buttonShadowCorrect: {
@@ -66,7 +66,7 @@ export const CountryHeader = ({
66
66
  {/* Top Bar: Back Button e Header Text */}
67
67
  <View style={[styles.topRow, { marginBottom: scale(16) }]}>
68
68
  <BackButton onPress={onBackPress} variant="glass" />
69
- <Typography style={[styles.headerText, { fontSize: scaleText(13), lineHeight: scaleText(16), marginLeft: scale(12) }]}>
69
+ <Typography variant="label" style={[styles.headerText, { marginLeft: scale(12) }]}>
70
70
  {headerText}
71
71
  </Typography>
72
72
  </View>
@@ -77,10 +77,10 @@ export const CountryHeader = ({
77
77
  <Flag countryCode={countryCode} size={scale(56)} />
78
78
  </View>
79
79
  <View style={[styles.textContainer, { marginLeft: scale(12) }]}>
80
- <Typography style={[styles.title, { fontSize: scaleText(26), lineHeight: scaleText(30) }]}>
80
+ <Typography variant="display1" style={[styles.title]}>
81
81
  {title}
82
82
  </Typography>
83
- <Typography style={[styles.subtitle, { fontSize: scaleText(13), lineHeight: scaleText(16), marginTop: scale(2) }]}>
83
+ <Typography variant="bodyMd" style={[styles.subtitle, { marginTop: scale(2) }]}>
84
84
  {subtitle}
85
85
  </Typography>
86
86
  </View>
@@ -87,14 +87,16 @@ export const ProfileHeader = ({
87
87
 
88
88
  <View style={styles.userTexts}>
89
89
  <Typography
90
- style={[styles.userName, { fontSize: scaleText(26), lineHeight: scaleText(30) }]}
90
+ variant="display1"
91
+ style={[styles.userName]}
91
92
  numberOfLines={1}
92
93
  adjustsFontSizeToFit
93
94
  >
94
95
  {userName}
95
96
  </Typography>
96
97
  <Typography
97
- style={[styles.userSubtitle, { fontSize: scaleText(14.5), lineHeight: scaleText(18), marginTop: scale(4) }]}
98
+ variant="bodyLg"
99
+ style={[styles.userSubtitle, { marginTop: scale(4) }]}
98
100
  >
99
101
  {userSubtitle}
100
102
  </Typography>
@@ -134,19 +136,20 @@ export const ProfileHeader = ({
134
136
  ) : null}
135
137
  <View style={styles.progressCardTexts}>
136
138
  <Typography
137
- style={[styles.progressTitle, { fontSize: scaleText(16.5), lineHeight: scaleText(20) }]}
139
+ variant="h3"
140
+ style={[styles.progressTitle]}
138
141
  numberOfLines={1}
139
142
  adjustsFontSizeToFit
140
143
  >
141
144
  {countryName} · {level}
142
145
  </Typography>
143
- <Typography style={[styles.progressSubtitle, { fontSize: scaleText(13.5), lineHeight: scaleText(17), marginTop: scale(2) }]}>
146
+ <Typography variant="bodyMd" style={[styles.progressSubtitle, { marginTop: scale(2) }]}>
144
147
  {moduleSubtitle}
145
148
  </Typography>
146
149
  </View>
147
150
  </View>
148
151
 
149
- <Typography style={[styles.progressPercent, { fontSize: scaleText(22), lineHeight: scaleText(26) }]}>
152
+ <Typography variant="h1" style={[styles.progressPercent]}>
150
153
  {progressPercentage}%
151
154
  </Typography>
152
155
  </View>
@@ -118,7 +118,7 @@ export const FillInTheBlank = ({
118
118
  backgroundColor,
119
119
  color: textColor,
120
120
  borderRadius: scale(10),
121
- fontSize: scaleText(16),
121
+ fontSize: theme.typography.bodyLg.fontSize,
122
122
  paddingHorizontal: scale(12),
123
123
  borderWidth: 2,
124
124
  }
@@ -141,11 +141,10 @@ export const FillInTheBlank = ({
141
141
  paddingHorizontal: scale(12),
142
142
  }
143
143
  ]}>
144
- <Typography style={[
144
+ <Typography variant="btnLg" style={[
145
145
  styles.blankText,
146
146
  {
147
147
  color: isFilled ? textColor : theme.colors.brown[400],
148
- fontSize: scaleText(16),
149
148
  }
150
149
  ]}>
151
150
  {value || (part as any).placeholder || ''}
@@ -216,7 +215,8 @@ export const FillInTheBlank = ({
216
215
  return (
217
216
  <Typography
218
217
  key={`text-${index}-${wIdx}`}
219
- style={[styles.staticText, { fontSize: scaleText(17.5), marginRight: scale(6), marginVertical: scale(4) }]}
218
+ variant="h2"
219
+ style={[styles.staticText, { marginRight: scale(6), marginVertical: scale(4) }]}
220
220
  >
221
221
  {word}
222
222
  </Typography>
@@ -231,7 +231,7 @@ export const FillInTheBlank = ({
231
231
  <View style={[styles.container, style]}>
232
232
  {/* Opcional: Texto de instrução no topo */}
233
233
  {!!instruction && (
234
- <Typography style={[styles.instructionText, { fontSize: scaleText(16), marginBottom: scale(16) }]}>
234
+ <Typography variant="h3" style={[styles.instructionText, { marginBottom: scale(16) }]}>
235
235
  {instruction}
236
236
  </Typography>
237
237
  )}
@@ -104,9 +104,9 @@ export const TextInput = forwardRef<RNTextInput, TextInputProps>(
104
104
  return (
105
105
  <View style={[styles.root, style]}>
106
106
  {label && (
107
- <Typography style={[
107
+ <Typography variant="bodySm" style={[
108
108
  styles.label,
109
- { fontSize: scaleText(12), marginBottom: scale(6) },
109
+ { marginBottom: scale(6) },
110
110
  disabled && { color: theme.colors.brown[400] }
111
111
  ]}>
112
112
  {label}
@@ -131,7 +131,7 @@ export const TextInput = forwardRef<RNTextInput, TextInputProps>(
131
131
  style={[
132
132
  styles.input,
133
133
  {
134
- fontSize: scaleText(15),
134
+ fontSize: theme.typography.bodyLg.fontSize,
135
135
  },
136
136
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
137
  Platform.OS === 'web' && ({ outlineStyle: 'none' } as any),
@@ -144,7 +144,7 @@ export const TextInput = forwardRef<RNTextInput, TextInputProps>(
144
144
  </View>
145
145
 
146
146
  {messageText && (
147
- <Typography style={[styles.message, { color: messageColor, fontSize: scaleText(12), marginTop: scale(5) }]}>
147
+ <Typography variant="bodySm" style={[styles.message, { color: messageColor, marginTop: scale(5) }]}>
148
148
  {messageText}
149
149
  </Typography>
150
150
  )}
@@ -34,11 +34,11 @@ export const BottomTabBarItem = ({
34
34
  <IconComponent stroke={color} size={scale(24)} strokeWidth={2} />
35
35
  </View>
36
36
  <Typography
37
+ variant="caption"
37
38
  style={[
38
39
  styles.label,
39
40
  {
40
41
  color,
41
- fontSize: scaleText(10),
42
42
  marginTop: scale(4),
43
43
  }
44
44
  ]}
@@ -297,12 +297,11 @@ export const ProgressMap = ({
297
297
  {/* Header Container */}
298
298
  <View style={styles.header}>
299
299
  <View style={styles.headerLeft}>
300
- <BackButton onPress={onBackPress} variant="default" />
301
300
  <View style={styles.headerText}>
302
- <Typography style={[styles.headerTitle, { fontSize: scaleText(headerTitleSize) }]}>
301
+ <Typography variant="h3" style={[styles.headerTitle, { fontSize: scaleText(headerTitleSize) }]}>
303
302
  {title.toUpperCase()}
304
303
  </Typography>
305
- <Typography style={[styles.headerSubtitle, { fontSize: scaleText(headerSubtitleSize) }]}>
304
+ <Typography variant="bodyLg" style={[styles.headerSubtitle, { fontSize: scaleText(headerSubtitleSize) }]}>
306
305
  {subtitle ?? `${stations.length} paragens · A1 → C1`}
307
306
  </Typography>
308
307
  </View>
@@ -313,7 +312,7 @@ export const ProgressMap = ({
313
312
  style={[styles.flightBtn, { borderRadius: scale(14), paddingHorizontal: scale(16), height: scale(40) }]}
314
313
  >
315
314
  <FlightIcon color="#ffffff" size={scale(16)} />
316
- <Typography style={[styles.flightBtnText, { fontSize: scaleText(12) }]}>VOO</Typography>
315
+ <Typography variant="btnSm" style={[styles.flightBtnText, { fontSize: scaleText(12) }]}>VOO</Typography>
317
316
  </TouchableOpacity>
318
317
  </View>
319
318
 
@@ -514,7 +513,7 @@ export const ProgressMap = ({
514
513
  },
515
514
  ]}
516
515
  >
517
- <Typography style={[styles.indexBadgeText, { fontSize: scaleText(9) }]}>
516
+ <Typography variant="label" style={[styles.indexBadgeText, { fontSize: scaleText(9) }]}>
518
517
  {idx + 1}
519
518
  </Typography>
520
519
  </View>
@@ -532,6 +531,7 @@ export const ProgressMap = ({
532
531
  ]}
533
532
  >
534
533
  <Typography
534
+ variant="bodySm"
535
535
  numberOfLines={1}
536
536
  style={[
537
537
  isCurrent ? styles.activeLabelText : styles.labelText,
@@ -539,7 +539,7 @@ export const ProgressMap = ({
539
539
  ]}
540
540
  >
541
541
  {p.label}{' '}
542
- <Typography style={{ opacity: isCurrent ? 0.9 : 0.6, fontSize: scaleText(10) }}>
542
+ <Typography variant="caption" style={{ opacity: isCurrent ? 0.9 : 0.6, fontSize: scaleText(10) }}>
543
543
  {p.levelCode}
544
544
  </Typography>
545
545
  {isCurrent && ' · AQUI'}
@@ -563,15 +563,15 @@ export const ProgressMap = ({
563
563
  >
564
564
  <View style={styles.legendRow}>
565
565
  <View style={[styles.legendDot, { backgroundColor: theme.colors.success }]} />
566
- <Typography style={[styles.legendText, { fontSize: scaleText(11) }]}>visitado · rever</Typography>
566
+ <Typography variant="caption" style={[styles.legendText, { fontSize: scaleText(11) }]}>visitado · rever</Typography>
567
567
  </View>
568
568
  <View style={styles.legendRow}>
569
569
  <View style={[styles.legendDot, { backgroundColor: theme.colors.primary }]} />
570
- <Typography style={[styles.legendText, { fontSize: scaleText(11) }]}>estás aqui</Typography>
570
+ <Typography variant="caption" style={[styles.legendText, { fontSize: scaleText(11) }]}>estás aqui</Typography>
571
571
  </View>
572
572
  <View style={styles.legendRow}>
573
573
  <View style={[styles.legendDot, { backgroundColor: theme.colors.brown[300] }]} />
574
- <Typography style={[styles.legendText, { fontSize: scaleText(11) }]}>bloqueado</Typography>
574
+ <Typography variant="caption" style={[styles.legendText, { fontSize: scaleText(11) }]}>bloqueado</Typography>
575
575
  </View>
576
576
  </View>
577
577
 
@@ -255,10 +255,10 @@ export const WorldProgressMap = ({
255
255
  <View style={styles.headerLeft}>
256
256
  <BackButton onPress={onBackPress} variant="default" />
257
257
  <View style={styles.headerText}>
258
- <Typography style={[styles.headerTitle, { fontSize: scaleText(headerTitleSize) }]}>
258
+ <Typography variant="btnMd" style={[styles.headerTitle]}>
259
259
  {title.toUpperCase()}
260
260
  </Typography>
261
- <Typography style={[styles.headerSubtitle, { fontSize: scaleText(headerSubtitleSize) }]}>
261
+ <Typography variant="h2" style={[styles.headerSubtitle]}>
262
262
  {subtitle ?? `${stations.length} destinos`}
263
263
  </Typography>
264
264
  </View>
@@ -269,7 +269,7 @@ export const WorldProgressMap = ({
269
269
  style={[styles.flightBtn, { borderRadius: scale(14), paddingHorizontal: scale(16), height: scale(40) }]}
270
270
  >
271
271
  <FlightIcon color="#ffffff" size={scale(16)} />
272
- <Typography style={[styles.flightBtnText, { fontSize: scaleText(12) }]}>VOO</Typography>
272
+ <Typography variant="btnSm" style={[styles.flightBtnText]}>VOO</Typography>
273
273
  </TouchableOpacity>
274
274
  </View>
275
275
 
@@ -481,7 +481,7 @@ export const WorldProgressMap = ({
481
481
  },
482
482
  ]}
483
483
  >
484
- <Typography style={[styles.indexBadgeText, { fontSize: scaleText(9) }]}>
484
+ <Typography variant="caption" style={[styles.indexBadgeText]}>
485
485
  {idx + 1}
486
486
  </Typography>
487
487
  </View>
@@ -499,14 +499,14 @@ export const WorldProgressMap = ({
499
499
  ]}
500
500
  >
501
501
  <Typography
502
+ variant="bodySm"
502
503
  numberOfLines={1}
503
504
  style={[
504
505
  isCurrent ? styles.activeLabelText : styles.labelText,
505
- { fontSize: scaleText(11.5) },
506
506
  ]}
507
507
  >
508
508
  {p.label}{' '}
509
- <Typography style={{ opacity: isCurrent ? 0.9 : 0.6, fontSize: scaleText(10) }}>
509
+ <Typography variant="caption" style={{ opacity: isCurrent ? 0.9 : 0.6 }}>
510
510
  {p.levelCode}
511
511
  </Typography>
512
512
  {isCurrent && ' · AQUI'}
@@ -532,15 +532,15 @@ export const WorldProgressMap = ({
532
532
  >
533
533
  <View style={styles.legendRow}>
534
534
  <View style={[styles.legendDot, { backgroundColor: theme.colors.success }]} />
535
- <Typography style={[styles.legendText, { fontSize: scaleText(11) }]}>visitado · rever</Typography>
535
+ <Typography variant="caption" style={[styles.legendText]}>visitado · rever</Typography>
536
536
  </View>
537
537
  <View style={styles.legendRow}>
538
538
  <View style={[styles.legendDot, { backgroundColor: theme.colors.primary }]} />
539
- <Typography style={[styles.legendText, { fontSize: scaleText(11) }]}>estás aqui</Typography>
539
+ <Typography variant="caption" style={[styles.legendText]}>estás aqui</Typography>
540
540
  </View>
541
541
  <View style={styles.legendRow}>
542
542
  <View style={[styles.legendDot, { backgroundColor: theme.colors.brown[300] }]} />
543
- <Typography style={[styles.legendText, { fontSize: scaleText(11) }]}>bloqueado</Typography>
543
+ <Typography variant="caption" style={[styles.legendText]}>bloqueado</Typography>
544
544
  </View>
545
545
  </View>
546
546
 
@@ -16,33 +16,39 @@ export interface TypographyProps extends RNTextProps {
16
16
  align?: 'auto' | 'left' | 'right' | 'center' | 'justify';
17
17
  /** Cor do texto (em formato hexadecimal ou rgba). */
18
18
  color?: string;
19
- /** Peso da fonte opcional para sobrepor a variante. */
20
- weight?: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
19
+ // A propriedade 'weight' foi removida para forçar o uso da variante correta e evitar furos na tipografia.
21
20
  }
22
21
 
23
22
  export const Typography = React.forwardRef<React.ElementRef<typeof RNText>, TypographyProps>(
24
- ({ variant = 'bodyMd', color, align, weight, style, children, ...props }, ref) => {
23
+ ({ variant = 'bodyMd', color, align, style, children, ...props }, ref) => {
25
24
  const { colors } = useTheme();
26
- const { scaleText } = useResponsive();
25
+ const { isDesktop } = useResponsive();
27
26
 
28
27
  // Resolve variant styles from the static theme tokens
29
- const typographyStyle = theme.typography[variant];
28
+ const typographyStyle = theme.typography[variant] as any;
30
29
 
31
30
  // Default text color based on the current active theme
32
31
  const defaultColor = colors.textPrimary;
33
32
 
34
- const responsiveStyle: TextStyle = {
33
+ // Use exact values from spec (no scaling!)
34
+ const exactFontSize = isDesktop && typographyStyle.desktopFontSize ? typographyStyle.desktopFontSize : typographyStyle.fontSize;
35
+ const exactLineHeight = isDesktop && typographyStyle.desktopFontSize && typographyStyle.lineHeight
36
+ ? (typographyStyle.desktopFontSize * (typographyStyle.lineHeight / typographyStyle.fontSize))
37
+ : typographyStyle.lineHeight;
38
+
39
+ const strictStyle: TextStyle = {
35
40
  ...typographyStyle,
36
- fontSize: typographyStyle.fontSize ? scaleText(typographyStyle.fontSize) : undefined,
37
- lineHeight: typographyStyle.lineHeight ? scaleText(typographyStyle.lineHeight) : undefined,
41
+ fontSize: exactFontSize,
42
+ lineHeight: exactLineHeight,
43
+ // Não propagamos campos web-only para o RN
44
+ desktopFontSize: undefined,
38
45
  };
39
46
 
40
47
  const combinedStyles = [
41
48
  { color: defaultColor },
42
- responsiveStyle,
49
+ strictStyle,
43
50
  color ? { color } : null,
44
51
  align ? { textAlign: align } : null,
45
- weight ? { fontWeight: weight } : null,
46
52
  style,
47
53
  ];
48
54