@retray-dev/ui-kit 4.0.0 → 5.2.0

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 (50) hide show
  1. package/COMPONENTS.md +1806 -663
  2. package/README.md +14 -10
  3. package/dist/index.d.mts +274 -85
  4. package/dist/index.d.ts +274 -85
  5. package/dist/index.js +1048 -321
  6. package/dist/index.mjs +1046 -324
  7. package/package.json +3 -2
  8. package/src/components/Accordion/Accordion.tsx +1 -1
  9. package/src/components/AlertBanner/AlertBanner.tsx +50 -45
  10. package/src/components/Avatar/Avatar.tsx +61 -17
  11. package/src/components/Badge/Badge.tsx +17 -15
  12. package/src/components/Button/Button.tsx +31 -42
  13. package/src/components/Card/Card.tsx +4 -4
  14. package/src/components/CategoryStrip/CategoryStrip.tsx +185 -0
  15. package/src/components/CategoryStrip/index.ts +2 -0
  16. package/src/components/Checkbox/Checkbox.tsx +44 -16
  17. package/src/components/Chip/Chip.tsx +1 -1
  18. package/src/components/ConfirmDialog/ConfirmDialog.tsx +9 -9
  19. package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +1 -0
  20. package/src/components/CurrencyInput/CurrencyInput.tsx +6 -4
  21. package/src/components/EmptyState/EmptyState.tsx +9 -9
  22. package/src/components/IconButton/IconButton.tsx +74 -34
  23. package/src/components/Input/Input.tsx +15 -13
  24. package/src/components/LabelValue/LabelValue.tsx +1 -1
  25. package/src/components/ListItem/ListItem.tsx +5 -5
  26. package/src/components/MediaCard/MediaCard.tsx +249 -0
  27. package/src/components/MediaCard/index.ts +2 -0
  28. package/src/components/Pressable/Pressable.tsx +100 -0
  29. package/src/components/Pressable/index.ts +1 -0
  30. package/src/components/Progress/Progress.tsx +14 -7
  31. package/src/components/RadioGroup/RadioGroup.tsx +1 -1
  32. package/src/components/Select/Select.tsx +5 -5
  33. package/src/components/Sheet/Sheet.tsx +35 -15
  34. package/src/components/Skeleton/Skeleton.tsx +34 -7
  35. package/src/components/Slider/Slider.tsx +2 -2
  36. package/src/components/Spinner/Spinner.tsx +1 -1
  37. package/src/components/Switch/Switch.tsx +31 -4
  38. package/src/components/Tabs/Tabs.tsx +63 -45
  39. package/src/components/Text/Text.tsx +59 -10
  40. package/src/components/Textarea/Textarea.tsx +4 -3
  41. package/src/components/Toast/Toast.tsx +77 -36
  42. package/src/components/Toggle/Toggle.tsx +3 -3
  43. package/src/index.ts +8 -2
  44. package/src/theme/ThemeProvider.tsx +11 -10
  45. package/src/theme/colorUtils.ts +80 -0
  46. package/src/theme/colors.ts +76 -35
  47. package/src/theme/index.ts +2 -2
  48. package/src/theme/types.ts +27 -13
  49. package/src/tokens.ts +150 -13
  50. package/src/utils/hover.ts +25 -0
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import React25, { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
2
- import { Platform, StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, Easing, Modal, Pressable } from 'react-native';
2
+ import { Platform, StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, Easing, Modal, ScrollView, Pressable } from 'react-native';
3
3
  import { verticalScale, scale, moderateScale, moderateVerticalScale } from 'react-native-size-matters';
4
4
  import AntDesign from '@expo/vector-icons/AntDesign';
5
5
  import Entypo from '@expo/vector-icons/Entypo';
@@ -7,11 +7,11 @@ import Feather from '@expo/vector-icons/Feather';
7
7
  import FontAwesome5 from '@expo/vector-icons/FontAwesome5';
8
8
  import MaterialIcons from '@expo/vector-icons/MaterialIcons';
9
9
  import Ionicons from '@expo/vector-icons/Ionicons';
10
- import { AntDesign as AntDesign$1, Entypo as Entypo$1, Feather as Feather$1, FontAwesome5 as FontAwesome5$1, MaterialIcons as MaterialIcons$1 } from '@expo/vector-icons';
10
+ import { AntDesign as AntDesign$1, Feather as Feather$1, Entypo as Entypo$1, FontAwesome5 as FontAwesome5$1, MaterialIcons as MaterialIcons$1 } from '@expo/vector-icons';
11
11
  import { LinearGradient } from 'expo-linear-gradient';
12
12
  import Animated11, { useSharedValue, useDerivedValue, withTiming, Easing as Easing$1, useAnimatedStyle, withSpring } from 'react-native-reanimated';
13
13
  import RNSlider from '@react-native-community/slider';
14
- import { BottomSheetModal, BottomSheetView, BottomSheetBackdrop } from '@gorhom/bottom-sheet';
14
+ import { BottomSheetModal, BottomSheetView, BottomSheetScrollView, BottomSheetBackdrop } from '@gorhom/bottom-sheet';
15
15
  export { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
16
16
  import { Picker } from '@react-native-picker/picker';
17
17
  import { scheduleOnRN } from 'react-native-worklets';
@@ -20,61 +20,125 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
20
20
 
21
21
  // src/theme/ThemeProvider.tsx
22
22
 
23
+ // src/theme/colorUtils.ts
24
+ function hexToRgb(hex) {
25
+ const clean = hex.replace("#", "");
26
+ const full = clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean;
27
+ if (full.length !== 6) return null;
28
+ return {
29
+ r: parseInt(full.slice(0, 2), 16),
30
+ g: parseInt(full.slice(2, 4), 16),
31
+ b: parseInt(full.slice(4, 6), 16)
32
+ };
33
+ }
34
+ function componentToHex(c) {
35
+ return Math.round(Math.max(0, Math.min(255, c))).toString(16).padStart(2, "0");
36
+ }
37
+ function rgbToHex(r, g, b) {
38
+ return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
39
+ }
40
+ function withAlphaOnWhite(hex, alpha) {
41
+ const rgb = hexToRgb(hex);
42
+ if (!rgb) return hex;
43
+ const r = rgb.r * alpha + 255 * (1 - alpha);
44
+ const g = rgb.g * alpha + 255 * (1 - alpha);
45
+ const b = rgb.b * alpha + 255 * (1 - alpha);
46
+ return rgbToHex(r, g, b);
47
+ }
48
+ function withAlphaOnDark(hex, alpha, bgHex = "#0f0f0f") {
49
+ const rgb = hexToRgb(hex);
50
+ const bg = hexToRgb(bgHex);
51
+ if (!rgb || !bg) return hex;
52
+ const r = rgb.r * alpha + bg.r * (1 - alpha);
53
+ const g = rgb.g * alpha + bg.g * (1 - alpha);
54
+ const b = rgb.b * alpha + bg.b * (1 - alpha);
55
+ return rgbToHex(r, g, b);
56
+ }
57
+ function mixWithBackground(fgHex, bgHex, opacity) {
58
+ const fg = hexToRgb(fgHex);
59
+ const bg = hexToRgb(bgHex);
60
+ if (!fg || !bg) return fgHex;
61
+ const r = fg.r * opacity + bg.r * (1 - opacity);
62
+ const g = fg.g * opacity + bg.g * (1 - opacity);
63
+ const b = fg.b * opacity + bg.b * (1 - opacity);
64
+ return rgbToHex(r, g, b);
65
+ }
66
+ function lighten(hex, amount) {
67
+ return withAlphaOnWhite(hex, 1 - amount);
68
+ }
69
+ function darken(hex, amount) {
70
+ const rgb = hexToRgb(hex);
71
+ if (!rgb) return hex;
72
+ return rgbToHex(rgb.r * (1 - amount), rgb.g * (1 - amount), rgb.b * (1 - amount));
73
+ }
74
+
23
75
  // src/theme/colors.ts
24
76
  var defaultLight = {
25
77
  background: "#ffffff",
26
- foreground: "#171717",
78
+ foreground: "#222222",
79
+ // Airbnb ink — deep near-black, never pure black
27
80
  card: "#ffffff",
28
- cardForeground: "#171717",
29
81
  primary: "#1a1a1a",
82
+ // Near-black primary — clean, premium default
30
83
  primaryForeground: "#ffffff",
31
- secondary: "#f1f1f1",
32
- secondaryForeground: "#171717",
33
- muted: "#f1f1f1",
34
- mutedForeground: "#a2a2a2",
35
- accent: "#e4e4e4",
36
- accentForeground: "#171717",
37
- destructive: "#ef4444",
84
+ border: "#dddddd",
85
+ // Airbnb hairline — light, airy
86
+ destructive: "#e53935",
38
87
  destructiveForeground: "#ffffff",
39
- border: "#e5e5e5",
40
- input: "#e5e5e5",
41
- ring: "#1a1a1a",
42
88
  success: "#1a7a45",
43
89
  successForeground: "#ffffff",
44
- destructiveTint: "#fff5f5",
45
- destructiveBorder: "#fecaca",
46
- successTint: "#f0fdf4",
47
- successBorder: "#bbf7d0"
90
+ warning: "#e67e00",
91
+ warningForeground: "#ffffff"
48
92
  };
49
93
  var defaultDark = {
50
94
  background: "#0f0f0f",
51
95
  foreground: "#fafafa",
52
96
  card: "#1c1c1c",
53
- cardForeground: "#fafafa",
54
97
  primary: "#fafafa",
55
98
  primaryForeground: "#0f0f0f",
56
- secondary: "#272727",
57
- secondaryForeground: "#fafafa",
58
- muted: "#272727",
59
- mutedForeground: "#9a9a9a",
60
- accent: "#2e2e2e",
61
- accentForeground: "#fafafa",
62
- destructive: "#dc2626",
63
- destructiveForeground: "#ffffff",
64
99
  border: "#303030",
65
- input: "#2a2a2a",
66
- ring: "#fafafa",
67
- success: "#166534",
100
+ destructive: "#ef5350",
101
+ destructiveForeground: "#ffffff",
102
+ success: "#2e7d52",
68
103
  successForeground: "#ffffff",
69
- destructiveTint: "#3b0a0a",
70
- destructiveBorder: "#7f1d1d",
71
- successTint: "#052e16",
72
- successBorder: "#166534"
104
+ warning: "#f57c00",
105
+ warningForeground: "#ffffff"
73
106
  };
107
+ function deriveColors(t, scheme) {
108
+ const dark = scheme === "dark";
109
+ const bg = t.background;
110
+ const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.55);
111
+ const foregroundMuted = mixWithBackground(t.foreground, bg, 0.38);
112
+ const surface = dark ? lighten(bg, -0.06) : darken(bg, 0.04);
113
+ const surfaceStrong = dark ? lighten(bg, -0.12) : darken(bg, 0.08);
114
+ const destructiveTint = dark ? withAlphaOnDark(t.destructive, 0.15, bg) : withAlphaOnWhite(t.destructive, 0.08);
115
+ const destructiveBorder = dark ? withAlphaOnDark(t.destructive, 0.45, bg) : withAlphaOnWhite(t.destructive, 0.3);
116
+ const successTint = dark ? withAlphaOnDark(t.success, 0.15, bg) : withAlphaOnWhite(t.success, 0.08);
117
+ const successBorder = dark ? withAlphaOnDark(t.success, 0.45, bg) : withAlphaOnWhite(t.success, 0.3);
118
+ const warningTint = dark ? withAlphaOnDark(t.warning, 0.15, bg) : withAlphaOnWhite(t.warning, 0.08);
119
+ const warningBorder = dark ? withAlphaOnDark(t.warning, 0.45, bg) : withAlphaOnWhite(t.warning, 0.3);
120
+ return {
121
+ ...t,
122
+ foregroundSubtle,
123
+ foregroundMuted,
124
+ surface,
125
+ surfaceStrong,
126
+ destructiveTint,
127
+ destructiveBorder,
128
+ successTint,
129
+ successBorder,
130
+ warningTint,
131
+ warningBorder,
132
+ ring: t.primary,
133
+ // focus ring always = primary
134
+ input: t.border
135
+ // input border always = border
136
+ };
137
+ }
74
138
 
75
139
  // src/theme/ThemeProvider.tsx
76
140
  var ThemeContext = createContext({
77
- colors: defaultLight,
141
+ colors: deriveColors(defaultLight, "light"),
78
142
  colorScheme: "light"
79
143
  });
80
144
  function ThemeProvider({ children, theme, colorScheme = "system" }) {
@@ -83,7 +147,8 @@ function ThemeProvider({ children, theme, colorScheme = "system" }) {
83
147
  const colors = useMemo(() => {
84
148
  const base = resolvedScheme === "dark" ? defaultDark : defaultLight;
85
149
  const override = resolvedScheme === "dark" ? theme?.dark : theme?.light;
86
- return override ? { ...base, ...override } : base;
150
+ const merged = override ? { ...base, ...override } : base;
151
+ return deriveColors(merged, resolvedScheme);
87
152
  }, [resolvedScheme, theme]);
88
153
  return /* @__PURE__ */ React25.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
89
154
  }
@@ -163,17 +228,194 @@ function renderIcon(name, size, color) {
163
228
  return React25.createElement(Icon, { name, size, color });
164
229
  }
165
230
 
231
+ // src/tokens.ts
232
+ var SPACING = {
233
+ xxs: 2,
234
+ xs: 4,
235
+ sm: 8,
236
+ md: 12,
237
+ base: 16,
238
+ lg: 24,
239
+ xl: 32,
240
+ xxl: 48,
241
+ section: 64
242
+ };
243
+ var ICON_SIZES = {
244
+ sm: 14,
245
+ md: 18,
246
+ lg: 22,
247
+ xl: 28,
248
+ "2xl": 32
249
+ };
250
+ var RADIUS = {
251
+ none: 0,
252
+ xs: 4,
253
+ sm: 8,
254
+ md: 14,
255
+ lg: 20,
256
+ xl: 32,
257
+ full: 9999
258
+ };
259
+ var SHADOWS = {
260
+ sm: {
261
+ shadowColor: "#000",
262
+ shadowOffset: { width: 0, height: 1 },
263
+ shadowOpacity: 0.06,
264
+ shadowRadius: 4,
265
+ elevation: 2
266
+ },
267
+ md: {
268
+ shadowColor: "#000",
269
+ shadowOffset: { width: 0, height: 2 },
270
+ shadowOpacity: 0.1,
271
+ shadowRadius: 8,
272
+ elevation: 5
273
+ },
274
+ lg: {
275
+ shadowColor: "#000",
276
+ shadowOffset: { width: 0, height: 6 },
277
+ shadowOpacity: 0.16,
278
+ shadowRadius: 16,
279
+ elevation: 10
280
+ },
281
+ xl: {
282
+ shadowColor: "#000",
283
+ shadowOffset: { width: 0, height: 12 },
284
+ shadowOpacity: 0.24,
285
+ shadowRadius: 24,
286
+ elevation: 18
287
+ }
288
+ };
289
+ var BREAKPOINTS = {
290
+ wide: 700
291
+ };
292
+ var TYPOGRAPHY = {
293
+ "display-hero": {
294
+ fontFamily: "Poppins-Bold",
295
+ fontSize: 64,
296
+ fontWeight: "700",
297
+ lineHeight: 70,
298
+ letterSpacing: -1
299
+ },
300
+ "display-xl": {
301
+ fontFamily: "Poppins-Bold",
302
+ fontSize: 28,
303
+ fontWeight: "700",
304
+ lineHeight: 40,
305
+ letterSpacing: 0
306
+ },
307
+ "display-lg": {
308
+ fontFamily: "Poppins-Medium",
309
+ fontSize: 22,
310
+ fontWeight: "500",
311
+ lineHeight: 26,
312
+ letterSpacing: -0.44
313
+ },
314
+ "display-md": {
315
+ fontFamily: "Poppins-Bold",
316
+ fontSize: 21,
317
+ fontWeight: "700",
318
+ lineHeight: 30,
319
+ letterSpacing: 0
320
+ },
321
+ "display-sm": {
322
+ fontFamily: "Poppins-SemiBold",
323
+ fontSize: 20,
324
+ fontWeight: "600",
325
+ lineHeight: 24,
326
+ letterSpacing: -0.18
327
+ },
328
+ "title-md": {
329
+ fontFamily: "Poppins-SemiBold",
330
+ fontSize: 16,
331
+ fontWeight: "600",
332
+ lineHeight: 20,
333
+ letterSpacing: 0
334
+ },
335
+ "title-sm": {
336
+ fontFamily: "Poppins-Medium",
337
+ fontSize: 16,
338
+ fontWeight: "500",
339
+ lineHeight: 20,
340
+ letterSpacing: 0
341
+ },
342
+ "body-md": {
343
+ fontFamily: "Poppins-Regular",
344
+ fontSize: 16,
345
+ fontWeight: "400",
346
+ lineHeight: 24,
347
+ letterSpacing: 0
348
+ },
349
+ "body-sm": {
350
+ fontFamily: "Poppins-Regular",
351
+ fontSize: 14,
352
+ fontWeight: "400",
353
+ lineHeight: 20,
354
+ letterSpacing: 0
355
+ },
356
+ caption: {
357
+ fontFamily: "Poppins-Medium",
358
+ fontSize: 14,
359
+ fontWeight: "500",
360
+ lineHeight: 18,
361
+ letterSpacing: 0
362
+ },
363
+ "caption-sm": {
364
+ fontFamily: "Poppins-Regular",
365
+ fontSize: 13,
366
+ fontWeight: "400",
367
+ lineHeight: 16,
368
+ letterSpacing: 0
369
+ },
370
+ "badge-text": {
371
+ fontFamily: "Poppins-SemiBold",
372
+ fontSize: 11,
373
+ fontWeight: "600",
374
+ lineHeight: 13,
375
+ letterSpacing: 0
376
+ },
377
+ "micro-label": {
378
+ fontFamily: "Poppins-Bold",
379
+ fontSize: 12,
380
+ fontWeight: "700",
381
+ lineHeight: 16,
382
+ letterSpacing: 0
383
+ },
384
+ "uppercase-tag": {
385
+ fontFamily: "Poppins-Bold",
386
+ fontSize: 8,
387
+ fontWeight: "700",
388
+ lineHeight: 10,
389
+ letterSpacing: 0.32,
390
+ textTransform: "uppercase"
391
+ },
392
+ "button-lg": {
393
+ fontFamily: "Poppins-Medium",
394
+ fontSize: 16,
395
+ fontWeight: "500",
396
+ lineHeight: 20,
397
+ letterSpacing: 0
398
+ },
399
+ "button-sm": {
400
+ fontFamily: "Poppins-Medium",
401
+ fontSize: 14,
402
+ fontWeight: "500",
403
+ lineHeight: 18,
404
+ letterSpacing: 0
405
+ }
406
+ };
407
+
166
408
  // src/components/Button/Button.tsx
167
409
  var nativeDriver = Platform.OS !== "web";
168
410
  var containerSizeStyles = {
169
- sm: { paddingHorizontal: s(12), paddingVertical: vs(10), minHeight: 44 },
170
- md: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 44 },
171
- lg: { paddingHorizontal: s(20), paddingVertical: vs(12), minHeight: 48 }
411
+ sm: { paddingHorizontal: s(16), paddingVertical: vs(10), minHeight: 40 },
412
+ md: { paddingHorizontal: s(24), paddingVertical: vs(14), minHeight: 48 },
413
+ lg: { paddingHorizontal: s(28), paddingVertical: vs(16), minHeight: 56 }
172
414
  };
173
415
  var labelSizeStyles = {
174
- sm: { fontSize: ms(13) },
175
- md: { fontSize: ms(15) },
176
- lg: { fontSize: ms(16) }
416
+ sm: { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize) },
417
+ md: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize) },
418
+ lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1) }
177
419
  };
178
420
  var iconSizeMap = { sm: 16, md: 18, lg: 20 };
179
421
  function Button({
@@ -196,12 +438,7 @@ function Button({
196
438
  const scale2 = useRef(new Animated.Value(1)).current;
197
439
  const handlePressIn = () => {
198
440
  if (isDisabled) return;
199
- Animated.spring(scale2, {
200
- toValue: 0.95,
201
- useNativeDriver: nativeDriver,
202
- speed: 40,
203
- bounciness: 0
204
- }).start();
441
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start();
205
442
  };
206
443
  const handlePressOut = () => {
207
444
  Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start();
@@ -212,20 +449,18 @@ function Button({
212
449
  };
213
450
  const containerVariantStyle = {
214
451
  primary: { backgroundColor: colors.primary },
215
- secondary: { backgroundColor: colors.secondary },
216
- outline: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.border },
217
- ghost: { backgroundColor: "transparent" },
452
+ secondary: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.primary },
453
+ text: { backgroundColor: "transparent" },
218
454
  destructive: { backgroundColor: colors.destructive }
219
455
  }[variant];
220
456
  const labelVariantStyle = {
221
457
  primary: { color: colors.primaryForeground },
222
- secondary: { color: colors.secondaryForeground },
223
- outline: { color: colors.foreground },
224
- ghost: { color: colors.foreground },
458
+ secondary: { color: colors.primary },
459
+ text: { color: colors.foreground },
225
460
  destructive: { color: colors.destructiveForeground }
226
461
  }[variant];
227
462
  const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], iconColor ?? labelVariantStyle.color) : typeof icon === "function" ? icon({ label, size, variant }) : icon;
228
- const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" || variant === "secondary" ? colors.primaryForeground : colors.foreground;
463
+ const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
229
464
  return /* @__PURE__ */ React25.createElement(Animated.View, { style: [fullWidth && styles.fullWidth, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25.createElement(
230
465
  TouchableOpacity,
231
466
  {
@@ -245,12 +480,20 @@ function Button({
245
480
  onPressOut: handlePressOut,
246
481
  ...props
247
482
  },
248
- loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon), /* @__PURE__ */ React25.createElement(Text, { style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0], allowFontScaling: true }, label), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon))
483
+ loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon), /* @__PURE__ */ React25.createElement(
484
+ Text,
485
+ {
486
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
487
+ allowFontScaling: true
488
+ },
489
+ label
490
+ ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon))
249
491
  ));
250
492
  }
251
493
  var styles = StyleSheet.create({
252
494
  base: {
253
- borderRadius: 8,
495
+ borderRadius: RADIUS.xl,
496
+ // 32px — pill-shaped primary CTA (Airbnb spec)
254
497
  alignItems: "center",
255
498
  justifyContent: "center",
256
499
  flexDirection: "row"
@@ -259,18 +502,18 @@ var styles = StyleSheet.create({
259
502
  width: "100%"
260
503
  },
261
504
  disabled: {
262
- opacity: 0.5
505
+ opacity: 0.45
263
506
  },
264
507
  label: {
265
- fontFamily: "Poppins-SemiBold"
508
+ fontFamily: "Poppins-Medium"
266
509
  },
267
510
  labelWithIcon: {
268
- marginHorizontal: s(8)
511
+ marginHorizontal: s(6)
269
512
  }
270
513
  });
271
514
  var nativeDriver2 = Platform.OS !== "web";
272
515
  var sizeMap = {
273
- sm: { container: s(40), icon: 18 },
516
+ sm: { container: s(32), icon: 16 },
274
517
  md: { container: s(44), icon: 20 },
275
518
  lg: { container: s(52), icon: 24 }
276
519
  };
@@ -281,6 +524,7 @@ function IconButton({
281
524
  variant = "primary",
282
525
  size = "md",
283
526
  loading = false,
527
+ badge,
284
528
  disabled,
285
529
  style,
286
530
  onPress,
@@ -291,20 +535,10 @@ function IconButton({
291
535
  const scale2 = useRef(new Animated.Value(1)).current;
292
536
  const handlePressIn = () => {
293
537
  if (isDisabled) return;
294
- Animated.spring(scale2, {
295
- toValue: 0.95,
296
- useNativeDriver: nativeDriver2,
297
- speed: 40,
298
- bounciness: 0
299
- }).start();
538
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver2, speed: 40, bounciness: 0 }).start();
300
539
  };
301
540
  const handlePressOut = () => {
302
- Animated.spring(scale2, {
303
- toValue: 1,
304
- useNativeDriver: nativeDriver2,
305
- speed: 40,
306
- bounciness: 4
307
- }).start();
541
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver2, speed: 40, bounciness: 4 }).start();
308
542
  };
309
543
  const handlePress = (e) => {
310
544
  impactLight();
@@ -312,22 +546,25 @@ function IconButton({
312
546
  };
313
547
  const containerVariantStyle = {
314
548
  primary: { backgroundColor: colors.primary },
315
- secondary: { backgroundColor: colors.secondary },
549
+ secondary: { backgroundColor: colors.surface },
316
550
  outline: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.border },
317
- ghost: { backgroundColor: "transparent" },
551
+ text: { backgroundColor: "transparent" },
318
552
  destructive: { backgroundColor: colors.destructive }
319
553
  }[variant];
320
554
  const defaultIconColor = {
321
555
  primary: colors.primaryForeground,
322
- secondary: colors.secondaryForeground,
556
+ secondary: colors.foreground,
323
557
  outline: colors.foreground,
324
- ghost: colors.foreground,
558
+ text: colors.foreground,
325
559
  destructive: colors.destructiveForeground
326
560
  }[variant];
327
- const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" || variant === "secondary" ? colors.primaryForeground : colors.foreground;
561
+ const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
328
562
  const { container: containerSize, icon: iconSize } = sizeMap[size];
329
563
  const resolvedIcon = iconName ? renderIcon(iconName, iconSize, iconColor ?? defaultIconColor) : icon;
330
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
564
+ const showBadge = badge !== void 0 && badge !== false && badge !== 0;
565
+ const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
566
+ const showCount = typeof badge === "number" && badge > 0;
567
+ return /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles2.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25.createElement(
331
568
  TouchableOpacity,
332
569
  {
333
570
  style: [
@@ -346,33 +583,93 @@ function IconButton({
346
583
  ...props
347
584
  },
348
585
  loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
349
- ));
586
+ ), showBadge && /* @__PURE__ */ React25.createElement(View, { style: [
587
+ styles2.badge,
588
+ { backgroundColor: colors.primary },
589
+ showCount ? styles2.badgeCount : styles2.badgeDot
590
+ ] }, showCount && /* @__PURE__ */ React25.createElement(Text, { style: [styles2.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
350
591
  }
351
592
  var styles2 = StyleSheet.create({
593
+ wrapper: {
594
+ alignSelf: "flex-start"
595
+ },
352
596
  base: {
353
- borderRadius: 999,
597
+ borderRadius: 9999,
354
598
  alignItems: "center",
355
599
  justifyContent: "center"
356
600
  },
357
601
  disabled: {
358
- opacity: 0.5
602
+ opacity: 0.45
603
+ },
604
+ badge: {
605
+ position: "absolute",
606
+ top: -2,
607
+ right: -2,
608
+ alignItems: "center",
609
+ justifyContent: "center"
610
+ },
611
+ badgeDot: {
612
+ width: 8,
613
+ height: 8,
614
+ borderRadius: 9999
615
+ },
616
+ badgeCount: {
617
+ minWidth: 16,
618
+ height: 16,
619
+ borderRadius: 9999,
620
+ paddingHorizontal: 3
621
+ },
622
+ badgeText: {
623
+ fontFamily: "Poppins-Bold",
624
+ fontSize: ms(9),
625
+ lineHeight: 14
359
626
  }
360
627
  });
361
628
  var variantStyles = {
362
- h1: { fontFamily: "Poppins-Bold", fontSize: ms(40), lineHeight: mvs(52) },
363
- h2: { fontFamily: "Poppins-Bold", fontSize: ms(28), lineHeight: mvs(36) },
364
- h3: { fontFamily: "Poppins-SemiBold", fontSize: ms(22), lineHeight: mvs(30) },
365
- body: { fontFamily: "Poppins-Regular", fontSize: ms(17), lineHeight: mvs(26) },
366
- caption: { fontFamily: "Poppins-Regular", fontSize: ms(13), lineHeight: mvs(20) },
367
- label: { fontFamily: "Poppins-Medium", fontSize: ms(15), lineHeight: mvs(22) }
629
+ "display-hero": { ...TYPOGRAPHY["display-hero"], fontSize: ms(TYPOGRAPHY["display-hero"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-hero"].lineHeight) },
630
+ "display-xl": { ...TYPOGRAPHY["display-xl"], fontSize: ms(TYPOGRAPHY["display-xl"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-xl"].lineHeight) },
631
+ "display-lg": { ...TYPOGRAPHY["display-lg"], fontSize: ms(TYPOGRAPHY["display-lg"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-lg"].lineHeight) },
632
+ "display-md": { ...TYPOGRAPHY["display-md"], fontSize: ms(TYPOGRAPHY["display-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-md"].lineHeight) },
633
+ "display-sm": { ...TYPOGRAPHY["display-sm"], fontSize: ms(TYPOGRAPHY["display-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["display-sm"].lineHeight) },
634
+ "title-md": { ...TYPOGRAPHY["title-md"], fontSize: ms(TYPOGRAPHY["title-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["title-md"].lineHeight) },
635
+ "title-sm": { ...TYPOGRAPHY["title-sm"], fontSize: ms(TYPOGRAPHY["title-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["title-sm"].lineHeight) },
636
+ "body-md": { ...TYPOGRAPHY["body-md"], fontSize: ms(TYPOGRAPHY["body-md"].fontSize), lineHeight: mvs(TYPOGRAPHY["body-md"].lineHeight) },
637
+ "body-sm": { ...TYPOGRAPHY["body-sm"], fontSize: ms(TYPOGRAPHY["body-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["body-sm"].lineHeight) },
638
+ caption: { ...TYPOGRAPHY["caption"], fontSize: ms(TYPOGRAPHY["caption"].fontSize), lineHeight: mvs(TYPOGRAPHY["caption"].lineHeight) },
639
+ "caption-sm": { ...TYPOGRAPHY["caption-sm"], fontSize: ms(TYPOGRAPHY["caption-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["caption-sm"].lineHeight) },
640
+ "badge-text": { ...TYPOGRAPHY["badge-text"], fontSize: ms(TYPOGRAPHY["badge-text"].fontSize), lineHeight: mvs(TYPOGRAPHY["badge-text"].lineHeight) },
641
+ "micro-label": { ...TYPOGRAPHY["micro-label"], fontSize: ms(TYPOGRAPHY["micro-label"].fontSize), lineHeight: mvs(TYPOGRAPHY["micro-label"].lineHeight) },
642
+ "uppercase-tag": { ...TYPOGRAPHY["uppercase-tag"], fontSize: ms(TYPOGRAPHY["uppercase-tag"].fontSize), lineHeight: mvs(TYPOGRAPHY["uppercase-tag"].lineHeight) },
643
+ "button-lg": { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize), lineHeight: mvs(TYPOGRAPHY["button-lg"].lineHeight) },
644
+ "button-sm": { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize), lineHeight: mvs(TYPOGRAPHY["button-sm"].lineHeight) }
368
645
  };
369
- function Text2({ variant = "body", color, style, children, ...props }) {
646
+ var defaultColorVariant = {
647
+ "display-hero": "foreground",
648
+ "display-xl": "foreground",
649
+ "display-lg": "foreground",
650
+ "display-md": "foreground",
651
+ "display-sm": "foreground",
652
+ "title-md": "foreground",
653
+ "title-sm": "foreground",
654
+ "body-md": "foregroundSubtle",
655
+ // running text — slightly softer
656
+ "body-sm": "foregroundSubtle",
657
+ caption: "foregroundMuted",
658
+ "caption-sm": "foregroundMuted",
659
+ "badge-text": "foreground",
660
+ "micro-label": "foreground",
661
+ "uppercase-tag": "foregroundMuted",
662
+ "button-lg": "foreground",
663
+ "button-sm": "foreground"
664
+ };
665
+ function Text3({ variant = "body-md", color, style, children, ...props }) {
370
666
  const { colors } = useTheme();
371
- const defaultColor = variant === "caption" ? colors.mutedForeground : colors.foreground;
667
+ const colorKey = defaultColorVariant[variant] ?? "foreground";
668
+ const resolvedColor = color ?? colors[colorKey];
372
669
  return /* @__PURE__ */ React25.createElement(
373
670
  Text,
374
671
  {
375
- style: [variantStyles[variant], { color: color ?? defaultColor }, style],
672
+ style: [variantStyles[variant], { color: resolvedColor }, style],
376
673
  allowFontScaling: true,
377
674
  ...props
378
675
  },
@@ -386,21 +683,21 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
386
683
  const [showPassword, setShowPassword] = useState(false);
387
684
  const isPassword = type === "password";
388
685
  const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
389
- const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.mutedForeground) : prefix;
390
- const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.mutedForeground })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.mutedForeground) : suffix;
686
+ const effectivePrefix = prefixIcon ? renderIcon(prefixIcon, 20, prefixIconColor ?? colors.foregroundMuted) : prefix;
687
+ const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles3.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
391
688
  return /* @__PURE__ */ React25.createElement(View, { style: [styles3.container, containerStyle] }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25.createElement(
392
689
  View,
393
690
  {
394
691
  style: [
395
692
  styles3.inputWrapper,
396
693
  {
397
- borderColor: error ? colors.destructive : focused ? colors.ring ?? colors.primary : colors.border,
694
+ borderColor: error ? colors.destructive : focused ? colors.primary : colors.border,
398
695
  backgroundColor: colors.background
399
696
  },
400
697
  inputWrapperStyle
401
698
  ]
402
699
  },
403
- effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.prefixText, { color: colors.mutedForeground }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25.createElement(View, { style: styles3.prefixContainer }, effectivePrefix) : null,
700
+ effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React25.createElement(View, { style: styles3.prefixContainer }, effectivePrefix) : null,
404
701
  /* @__PURE__ */ React25.createElement(
405
702
  TextInput,
406
703
  {
@@ -420,14 +717,14 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
420
717
  setFocused(false);
421
718
  onBlur?.(e);
422
719
  },
423
- placeholderTextColor: colors.mutedForeground,
720
+ placeholderTextColor: colors.foregroundMuted,
424
721
  allowFontScaling: true,
425
722
  secureTextEntry: effectiveSecure,
426
723
  ...props
427
724
  }
428
725
  ),
429
- effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.suffixText, { color: colors.mutedForeground }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React25.createElement(View, { style: styles3.suffixContainer }, effectiveSuffix) : null
430
- ), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
726
+ effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React25.createElement(View, { style: styles3.suffixContainer }, effectiveSuffix) : null
727
+ ), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles3.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
431
728
  }
432
729
  var styles3 = StyleSheet.create({
433
730
  container: {
@@ -435,21 +732,24 @@ var styles3 = StyleSheet.create({
435
732
  },
436
733
  label: {
437
734
  fontFamily: "Poppins-Medium",
438
- fontSize: ms(13)
735
+ fontSize: ms(14)
736
+ // caption size for input labels
439
737
  },
440
738
  inputWrapper: {
441
739
  flexDirection: "row",
442
740
  alignItems: "center",
443
- borderWidth: 1,
444
- borderRadius: ms(8),
741
+ borderWidth: 2,
742
+ borderRadius: 8,
445
743
  paddingHorizontal: s(14),
446
- paddingVertical: vs(11)
744
+ paddingVertical: vs(11),
745
+ minHeight: 48
447
746
  },
448
747
  input: {
449
748
  fontFamily: "Poppins-Regular",
450
749
  flex: 1,
451
- fontSize: ms(15),
452
- paddingVertical: 0
750
+ fontSize: ms(16),
751
+ paddingVertical: vs(2),
752
+ includeFontPadding: false
453
753
  },
454
754
  prefixContainer: {
455
755
  marginRight: s(8)
@@ -495,23 +795,25 @@ function Badge({ label, children, variant = "default", size = "md", icon, iconNa
495
795
  const { colors } = useTheme();
496
796
  const containerStyle = {
497
797
  default: { backgroundColor: colors.primary },
498
- secondary: { backgroundColor: colors.secondary },
798
+ secondary: { backgroundColor: colors.surface },
499
799
  destructive: { backgroundColor: colors.destructive },
500
800
  outline: { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border },
501
801
  success: { backgroundColor: colors.success },
502
- warning: { backgroundColor: "#f59e0b" },
802
+ warning: { backgroundColor: colors.warning },
503
803
  successOutline: { backgroundColor: colors.successTint, borderWidth: 1, borderColor: colors.successBorder },
504
- destructiveOutline: { backgroundColor: colors.destructiveTint, borderWidth: 1, borderColor: colors.destructiveBorder }
804
+ destructiveOutline: { backgroundColor: colors.destructiveTint, borderWidth: 1, borderColor: colors.destructiveBorder },
805
+ warningOutline: { backgroundColor: colors.warningTint, borderWidth: 1, borderColor: colors.warningBorder }
505
806
  }[variant];
506
807
  const textColor = {
507
808
  default: colors.primaryForeground,
508
- secondary: colors.secondaryForeground,
809
+ secondary: colors.foreground,
509
810
  destructive: colors.destructiveForeground,
510
811
  outline: colors.foreground,
511
812
  success: colors.successForeground,
512
- warning: "#ffffff",
813
+ warning: colors.warningForeground,
513
814
  successOutline: colors.success,
514
- destructiveOutline: colors.destructive
815
+ destructiveOutline: colors.destructive,
816
+ warningOutline: colors.warning
515
817
  }[variant];
516
818
  const effectiveIcon = iconName ? renderIcon(iconName, sizeIconSize[size], iconColor ?? textColor) : icon;
517
819
  const content = children ?? label;
@@ -572,7 +874,7 @@ function Card({ children, variant = "elevated", onPress, style }) {
572
874
  elevation: 0
573
875
  },
574
876
  filled: {
575
- backgroundColor: colors.accent,
877
+ backgroundColor: colors.surfaceStrong,
576
878
  borderColor: colors.border,
577
879
  shadowOpacity: 0,
578
880
  elevation: 0
@@ -599,11 +901,11 @@ function CardHeader({ children, style }) {
599
901
  }
600
902
  function CardTitle({ children, style }) {
601
903
  const { colors } = useTheme();
602
- return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.title, { color: colors.cardForeground }, style], allowFontScaling: true }, children);
904
+ return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
603
905
  }
604
906
  function CardDescription({ children, style }) {
605
907
  const { colors } = useTheme();
606
- return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.description, { color: colors.mutedForeground }, style], allowFontScaling: true }, children);
908
+ return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
607
909
  }
608
910
  function CardContent({ children, style }) {
609
911
  return /* @__PURE__ */ React25.createElement(View, { style: [styles5.content, style] }, children);
@@ -613,7 +915,8 @@ function CardFooter({ children, style }) {
613
915
  }
614
916
  var styles5 = StyleSheet.create({
615
917
  card: {
616
- borderRadius: ms(12),
918
+ borderRadius: 14,
919
+ // RADIUS.md — Airbnb property card spec
617
920
  borderWidth: 1
618
921
  },
619
922
  header: {
@@ -682,7 +985,7 @@ function Spinner({ size = "md", color, label, ...props }) {
682
985
  return /* @__PURE__ */ React25.createElement(View, { style: styles7.wrapper }, /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React25.createElement(
683
986
  Text,
684
987
  {
685
- style: [styles7.label, { color: colors.mutedForeground, fontSize: labelFontSize[size] }],
988
+ style: [styles7.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
686
989
  allowFontScaling: true
687
990
  },
688
991
  label
@@ -700,18 +1003,21 @@ var styles7 = StyleSheet.create({
700
1003
  lineHeight: mvs(18)
701
1004
  }
702
1005
  });
703
- function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
1006
+ function Skeleton({
1007
+ width = "100%",
1008
+ height = 16,
1009
+ borderRadius = 6,
1010
+ preset = "base",
1011
+ diameter = 40,
1012
+ style
1013
+ }) {
704
1014
  const { colors, colorScheme } = useTheme();
705
1015
  const shimmerAnim = useRef(new Animated.Value(0)).current;
706
1016
  const [containerWidth, setContainerWidth] = useState(300);
707
1017
  const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
708
1018
  useEffect(() => {
709
1019
  const animation = Animated.loop(
710
- Animated.timing(shimmerAnim, {
711
- toValue: 1,
712
- duration: 1200,
713
- useNativeDriver: true
714
- })
1020
+ Animated.timing(shimmerAnim, { toValue: 1, duration: 1200, useNativeDriver: true })
715
1021
  );
716
1022
  animation.start();
717
1023
  return () => animation.stop();
@@ -720,12 +1026,15 @@ function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
720
1026
  inputRange: [0, 1],
721
1027
  outputRange: [-containerWidth, containerWidth]
722
1028
  });
1029
+ const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
1030
+ const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
1031
+ const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
723
1032
  return /* @__PURE__ */ React25.createElement(
724
1033
  View,
725
1034
  {
726
1035
  style: [
727
1036
  styles8.base,
728
- { width, height, borderRadius, backgroundColor: colors.muted },
1037
+ { width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
729
1038
  style
730
1039
  ],
731
1040
  onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
@@ -758,19 +1067,32 @@ var fontSizeMap = {
758
1067
  lg: ms(22),
759
1068
  xl: ms(28)
760
1069
  };
761
- function Avatar({ src, fallback, size = "md", style }) {
1070
+ var statusSizeMap = {
1071
+ sm: 8,
1072
+ md: 10,
1073
+ lg: 13,
1074
+ xl: 16
1075
+ };
1076
+ function Avatar({ src, fallback, size = "md", status, style }) {
762
1077
  const { colors } = useTheme();
763
1078
  const [imageError, setImageError] = useState(false);
764
1079
  const dimension = sizeMap3[size];
765
1080
  const showFallback = !src || imageError;
1081
+ const statusSize = statusSizeMap[size];
1082
+ const statusColor = {
1083
+ online: "#22c55e",
1084
+ offline: "transparent",
1085
+ busy: colors.destructive,
1086
+ away: colors.warning
1087
+ };
766
1088
  const containerStyle = {
767
1089
  width: dimension,
768
1090
  height: dimension,
769
1091
  borderRadius: dimension / 2,
770
- backgroundColor: colors.muted,
1092
+ backgroundColor: colors.surface,
771
1093
  overflow: "hidden"
772
1094
  };
773
- return /* @__PURE__ */ React25.createElement(View, { style: [styles9.base, containerStyle, style] }, !showFallback ? /* @__PURE__ */ React25.createElement(
1095
+ return /* @__PURE__ */ React25.createElement(View, { style: [styles9.wrapper, style] }, /* @__PURE__ */ React25.createElement(View, { style: [styles9.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React25.createElement(
774
1096
  Image,
775
1097
  {
776
1098
  source: { uri: src },
@@ -780,64 +1102,86 @@ function Avatar({ src, fallback, size = "md", style }) {
780
1102
  ) : /* @__PURE__ */ React25.createElement(
781
1103
  Text,
782
1104
  {
783
- style: [styles9.fallback, { color: colors.mutedForeground, fontSize: fontSizeMap[size] }],
1105
+ style: [styles9.fallback, { color: colors.foregroundMuted, fontSize: fontSizeMap[size] }],
784
1106
  allowFontScaling: true
785
1107
  },
786
1108
  fallback?.slice(0, 2).toUpperCase() ?? "?"
1109
+ )), status && /* @__PURE__ */ React25.createElement(
1110
+ View,
1111
+ {
1112
+ style: [
1113
+ styles9.statusDot,
1114
+ {
1115
+ width: statusSize,
1116
+ height: statusSize,
1117
+ borderRadius: statusSize / 2,
1118
+ backgroundColor: statusColor[status],
1119
+ borderWidth: status === "offline" ? 2 : 1.5,
1120
+ borderColor: status === "offline" ? colors.border : colors.background
1121
+ }
1122
+ ]
1123
+ }
787
1124
  ));
788
1125
  }
789
1126
  var styles9 = StyleSheet.create({
1127
+ wrapper: {
1128
+ alignSelf: "flex-start",
1129
+ position: "relative"
1130
+ },
790
1131
  base: {
791
1132
  alignItems: "center",
792
1133
  justifyContent: "center"
793
1134
  },
794
1135
  fallback: {
795
1136
  fontFamily: "Poppins-Medium"
1137
+ },
1138
+ statusDot: {
1139
+ position: "absolute",
1140
+ bottom: 0,
1141
+ right: 0
796
1142
  }
797
1143
  });
798
1144
  function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, style }) {
799
1145
  const { colors } = useTheme();
800
- const bgColor = variant === "destructive" ? colors.destructiveBorder : variant === "success" ? colors.successBorder : colors.card;
801
- const textColor = variant === "destructive" ? "#991b1b" : variant === "success" ? "#166534" : colors.foreground;
802
- const borderColor = textColor;
803
- const defaultIcon = variant === "success" ? /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: 18, color: textColor }) : variant === "destructive" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "error-outline", size: 20, color: textColor }) : /* @__PURE__ */ React25.createElement(Entypo$1, { name: "info-with-circle", size: 18, color: textColor });
804
- const effectiveIcon = iconName ? renderIcon(iconName, 18, iconColor ?? textColor) : icon ?? defaultIcon;
805
- return /* @__PURE__ */ React25.createElement(View, { style: [styles10.container, { backgroundColor: bgColor, borderColor }, style] }, /* @__PURE__ */ React25.createElement(View, { style: styles10.header }, /* @__PURE__ */ React25.createElement(View, { style: styles10.icon }, effectiveIcon), title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles10.title, { color: textColor }], allowFontScaling: true }, title) : null), description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles10.description, { color: textColor, opacity: 0.85 }], allowFontScaling: true }, description) : null);
1146
+ const bgColor = variant === "destructive" ? colors.destructiveTint : variant === "success" ? colors.successTint : variant === "warning" ? colors.warningTint : colors.card;
1147
+ const borderColor = variant === "destructive" ? colors.destructiveBorder : variant === "success" ? colors.successBorder : variant === "warning" ? colors.warningBorder : colors.border;
1148
+ const accentColor = variant === "destructive" ? colors.destructive : variant === "success" ? colors.success : variant === "warning" ? colors.warning : colors.primary;
1149
+ const titleColor = variant === "default" ? colors.foreground : accentColor;
1150
+ const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
1151
+ const defaultIcon = variant === "success" ? /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "error-outline", size: 17, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25.createElement(Entypo$1, { name: "info-with-circle", size: 16, color: accentColor });
1152
+ const effectiveIcon = iconName ? renderIcon(iconName, 16, iconColor ?? accentColor) : icon ?? defaultIcon;
1153
+ return /* @__PURE__ */ React25.createElement(View, { style: [styles10.container, { backgroundColor: bgColor, borderColor }, style] }, /* @__PURE__ */ React25.createElement(View, { style: styles10.iconSlot }, effectiveIcon), /* @__PURE__ */ React25.createElement(View, { style: styles10.content }, /* @__PURE__ */ React25.createElement(Text, { style: [styles10.title, { color: titleColor }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles10.description, { color: descColor }], allowFontScaling: true }, description) : null));
806
1154
  }
807
1155
  var styles10 = StyleSheet.create({
808
1156
  container: {
809
- borderWidth: 1,
810
- borderRadius: ms(12),
811
- paddingHorizontal: s(14),
812
- paddingVertical: vs(12),
813
- gap: vs(8),
814
- shadowColor: "#000",
815
- shadowOffset: { width: 0, height: 3 },
816
- shadowOpacity: 0.1,
817
- shadowRadius: 8,
818
- elevation: 5
819
- },
820
- header: {
821
1157
  flexDirection: "row",
822
- alignItems: "center",
1158
+ alignItems: "flex-start",
1159
+ borderWidth: 0.5,
1160
+ borderRadius: 10,
1161
+ paddingHorizontal: s(12),
1162
+ paddingVertical: vs(10),
823
1163
  gap: s(10)
824
1164
  },
825
- icon: {
826
- marginTop: 0
1165
+ iconSlot: {
1166
+ marginTop: vs(1)
1167
+ },
1168
+ content: {
1169
+ flex: 1,
1170
+ gap: vs(2)
827
1171
  },
828
1172
  title: {
829
- fontFamily: "Poppins-Bold",
830
- fontSize: ms(15),
831
- lineHeight: mvs(20),
832
- flex: 1
1173
+ fontFamily: "Poppins-Medium",
1174
+ fontSize: ms(13),
1175
+ lineHeight: ms(18)
833
1176
  },
834
1177
  description: {
835
1178
  fontFamily: "Poppins-Regular",
836
- fontSize: ms(14),
837
- lineHeight: mvs(20)
1179
+ fontSize: ms(12),
1180
+ lineHeight: ms(17),
1181
+ opacity: 0.85
838
1182
  }
839
1183
  });
840
- function Progress({ value = 0, max = 100, style }) {
1184
+ function Progress({ value = 0, max = 100, variant = "default", style }) {
841
1185
  const { colors } = useTheme();
842
1186
  const percent = Math.min(Math.max(value / max * 100, 0), 100);
843
1187
  const [trackWidth, setTrackWidth] = useState(0);
@@ -851,16 +1195,17 @@ function Progress({ value = 0, max = 100, style }) {
851
1195
  bounciness: 0
852
1196
  }).start();
853
1197
  }, [percent, trackWidth]);
1198
+ const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
854
1199
  return /* @__PURE__ */ React25.createElement(
855
1200
  View,
856
1201
  {
857
- style: [styles11.track, { backgroundColor: colors.muted }, style],
1202
+ style: [styles11.track, { backgroundColor: colors.surface }, style],
858
1203
  onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
859
1204
  },
860
1205
  /* @__PURE__ */ React25.createElement(
861
1206
  Animated.View,
862
1207
  {
863
- style: [styles11.indicator, { width: animatedWidth, backgroundColor: colors.primary }]
1208
+ style: [styles11.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
864
1209
  }
865
1210
  )
866
1211
  );
@@ -868,19 +1213,19 @@ function Progress({ value = 0, max = 100, style }) {
868
1213
  var styles11 = StyleSheet.create({
869
1214
  track: {
870
1215
  height: vs(8),
871
- borderRadius: 999,
1216
+ borderRadius: 9999,
872
1217
  overflow: "hidden",
873
1218
  width: "100%"
874
1219
  },
875
1220
  indicator: {
876
1221
  height: "100%",
877
- borderRadius: 999
1222
+ borderRadius: 9999
878
1223
  }
879
1224
  });
880
1225
  function EmptyState({ icon, iconName, iconColor, title, description, action, size = "default", style }) {
881
1226
  const { colors } = useTheme();
882
1227
  const isCompact = size === "compact";
883
- const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.mutedForeground) : icon;
1228
+ const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.foregroundMuted) : icon;
884
1229
  return /* @__PURE__ */ React25.createElement(
885
1230
  View,
886
1231
  {
@@ -897,7 +1242,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, siz
897
1242
  style: [
898
1243
  styles12.iconWrapper,
899
1244
  isCompact && styles12.iconWrapperCompact,
900
- { backgroundColor: colors.muted }
1245
+ { backgroundColor: colors.surface }
901
1246
  ]
902
1247
  },
903
1248
  effectiveIcon
@@ -909,7 +1254,7 @@ function EmptyState({ icon, iconName, iconColor, title, description, action, siz
909
1254
  allowFontScaling: true
910
1255
  },
911
1256
  title
912
- ), description && !isCompact ? /* @__PURE__ */ React25.createElement(Text, { style: [styles12.description, { color: colors.mutedForeground }], allowFontScaling: true }, description) : null),
1257
+ ), description && !isCompact ? /* @__PURE__ */ React25.createElement(Text, { style: [styles12.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
913
1258
  action && !isCompact ? /* @__PURE__ */ React25.createElement(View, { style: styles12.action }, action) : null
914
1259
  );
915
1260
  }
@@ -928,16 +1273,16 @@ var styles12 = StyleSheet.create({
928
1273
  gap: vs(10)
929
1274
  },
930
1275
  iconWrapper: {
931
- width: s(48),
932
- height: s(48),
933
- borderRadius: ms(12),
1276
+ width: s(80),
1277
+ height: s(80),
1278
+ borderRadius: ms(20),
934
1279
  alignItems: "center",
935
1280
  justifyContent: "center"
936
1281
  },
937
1282
  iconWrapperCompact: {
938
- width: s(36),
939
- height: s(36),
940
- borderRadius: ms(8)
1283
+ width: s(56),
1284
+ height: s(56),
1285
+ borderRadius: ms(14)
941
1286
  },
942
1287
  textWrapper: {
943
1288
  alignItems: "center",
@@ -1001,11 +1346,11 @@ function Textarea({
1001
1346
  setFocused(false);
1002
1347
  onBlur?.(e);
1003
1348
  },
1004
- placeholderTextColor: colors.mutedForeground,
1349
+ placeholderTextColor: colors.foregroundMuted,
1005
1350
  allowFontScaling: true,
1006
1351
  ...props
1007
1352
  }
1008
- ), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
1353
+ ), error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1009
1354
  }
1010
1355
  var styles13 = StyleSheet.create({
1011
1356
  container: {
@@ -1017,11 +1362,12 @@ var styles13 = StyleSheet.create({
1017
1362
  },
1018
1363
  input: {
1019
1364
  fontFamily: "Poppins-Regular",
1020
- borderWidth: 1,
1365
+ borderWidth: 2,
1021
1366
  borderRadius: ms(8),
1022
1367
  paddingHorizontal: s(14),
1023
1368
  paddingVertical: vs(11),
1024
- fontSize: ms(15)
1369
+ fontSize: ms(15),
1370
+ includeFontPadding: false
1025
1371
  },
1026
1372
  helperText: {
1027
1373
  fontFamily: "Poppins-Regular",
@@ -1038,6 +1384,30 @@ function Checkbox({
1038
1384
  }) {
1039
1385
  const { colors } = useTheme();
1040
1386
  const scale2 = useRef(new Animated.Value(1)).current;
1387
+ const bgOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
1388
+ const checkOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
1389
+ useEffect(() => {
1390
+ Animated.parallel([
1391
+ Animated.timing(bgOpacity, {
1392
+ toValue: checked ? 1 : 0,
1393
+ duration: 150,
1394
+ useNativeDriver: false
1395
+ }),
1396
+ Animated.timing(checkOpacity, {
1397
+ toValue: checked ? 1 : 0,
1398
+ duration: 120,
1399
+ useNativeDriver: false
1400
+ })
1401
+ ]).start();
1402
+ }, [checked, bgOpacity, checkOpacity]);
1403
+ const borderColor = bgOpacity.interpolate({
1404
+ inputRange: [0, 1],
1405
+ outputRange: [colors.border, colors.primary]
1406
+ });
1407
+ const backgroundColor = bgOpacity.interpolate({
1408
+ inputRange: [0, 1],
1409
+ outputRange: ["transparent", colors.primary]
1410
+ });
1041
1411
  const handlePressIn = () => {
1042
1412
  if (disabled) return;
1043
1413
  Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver4, speed: 40, bounciness: 0 }).start();
@@ -1059,25 +1429,24 @@ function Checkbox({
1059
1429
  activeOpacity: 1,
1060
1430
  touchSoundDisabled: true
1061
1431
  },
1062
- /* @__PURE__ */ React25.createElement(
1432
+ /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
1063
1433
  Animated.View,
1064
1434
  {
1065
1435
  style: [
1066
1436
  styles14.box,
1067
1437
  {
1068
- borderColor: checked ? colors.primary : colors.border,
1069
- backgroundColor: checked ? colors.primary : "transparent",
1070
- opacity: disabled ? 0.45 : 1,
1071
- transform: [{ scale: scale2 }]
1438
+ borderColor,
1439
+ backgroundColor,
1440
+ opacity: disabled ? 0.45 : 1
1072
1441
  }
1073
1442
  ]
1074
1443
  },
1075
- checked ? /* @__PURE__ */ React25.createElement(View, { style: [styles14.checkmark, { borderColor: colors.primaryForeground }] }) : null
1076
- ),
1444
+ /* @__PURE__ */ React25.createElement(Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React25.createElement(View, { style: [styles14.checkmark, { borderColor: colors.primaryForeground }] }))
1445
+ )),
1077
1446
  label ? /* @__PURE__ */ React25.createElement(
1078
1447
  Text,
1079
1448
  {
1080
- style: [styles14.label, { color: disabled ? colors.mutedForeground : colors.foreground }],
1449
+ style: [styles14.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
1081
1450
  allowFontScaling: true
1082
1451
  },
1083
1452
  label
@@ -1117,10 +1486,13 @@ var TRACK_HEIGHT = s(30);
1117
1486
  var THUMB_SIZE = s(24);
1118
1487
  var THUMB_OFFSET = s(3);
1119
1488
  var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
1489
+ var ICON_SIZE = s(13);
1120
1490
  function Switch({ checked = false, onCheckedChange, disabled, style }) {
1121
1491
  const { colors } = useTheme();
1122
1492
  const translateX = useRef(new Animated.Value(checked ? THUMB_TRAVEL : 0)).current;
1123
1493
  const trackOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
1494
+ const checkOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
1495
+ const crossOpacity = useRef(new Animated.Value(checked ? 0 : 1)).current;
1124
1496
  useEffect(() => {
1125
1497
  Animated.parallel([
1126
1498
  Animated.spring(translateX, {
@@ -1132,12 +1504,22 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
1132
1504
  toValue: checked ? 1 : 0,
1133
1505
  duration: 150,
1134
1506
  useNativeDriver: false
1507
+ }),
1508
+ Animated.timing(checkOpacity, {
1509
+ toValue: checked ? 1 : 0,
1510
+ duration: 120,
1511
+ useNativeDriver: true
1512
+ }),
1513
+ Animated.timing(crossOpacity, {
1514
+ toValue: checked ? 0 : 1,
1515
+ duration: 120,
1516
+ useNativeDriver: true
1135
1517
  })
1136
1518
  ]).start();
1137
- }, [checked, translateX, trackOpacity]);
1519
+ }, [checked, translateX, trackOpacity, checkOpacity, crossOpacity]);
1138
1520
  const trackColor = trackOpacity.interpolate({
1139
1521
  inputRange: [0, 1],
1140
- outputRange: [colors.muted, colors.primary]
1522
+ outputRange: [colors.surface, colors.primary]
1141
1523
  });
1142
1524
  return /* @__PURE__ */ React25.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React25.createElement(
1143
1525
  TouchableOpacity,
@@ -1158,7 +1540,9 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
1158
1540
  styles15.thumb,
1159
1541
  { backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
1160
1542
  ]
1161
- }
1543
+ },
1544
+ /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles15.iconWrapper, { opacity: checkOpacity }] }, /* @__PURE__ */ React25.createElement(Feather$1, { name: "check", size: ICON_SIZE, color: colors.primary })),
1545
+ /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles15.iconWrapper, { opacity: crossOpacity }] }, /* @__PURE__ */ React25.createElement(Feather$1, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
1162
1546
  ))
1163
1547
  ));
1164
1548
  }
@@ -1182,7 +1566,12 @@ var styles15 = StyleSheet.create({
1182
1566
  shadowOffset: { width: 0, height: 1 },
1183
1567
  shadowOpacity: 0.15,
1184
1568
  shadowRadius: 2,
1185
- elevation: 2
1569
+ elevation: 2,
1570
+ alignItems: "center",
1571
+ justifyContent: "center"
1572
+ },
1573
+ iconWrapper: {
1574
+ position: "absolute"
1186
1575
  }
1187
1576
  });
1188
1577
  var nativeDriver6 = Platform.OS !== "web";
@@ -1232,7 +1621,7 @@ function Toggle({
1232
1621
  });
1233
1622
  const backgroundColor = pressAnim.interpolate({
1234
1623
  inputRange: [0, 1],
1235
- outputRange: ["transparent", colors.accent]
1624
+ outputRange: ["transparent", colors.surfaceStrong]
1236
1625
  });
1237
1626
  const textColor = pressAnim.interpolate({
1238
1627
  inputRange: [0, 1],
@@ -1251,10 +1640,10 @@ function Toggle({
1251
1640
  if (active) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, active);
1252
1641
  return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: iconSize, color: colors.primary });
1253
1642
  }
1254
- if (iconName) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.mutedForeground));
1643
+ if (iconName) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
1255
1644
  const custom = renderProp(icon);
1256
1645
  if (custom) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, custom);
1257
- return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.mutedForeground });
1646
+ return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.foregroundMuted });
1258
1647
  };
1259
1648
  return /* @__PURE__ */ React25.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles16.disabled, style] }, /* @__PURE__ */ React25.createElement(
1260
1649
  TouchableOpacity,
@@ -1351,7 +1740,7 @@ function RadioItem({
1351
1740
  {
1352
1741
  style: [
1353
1742
  styles17.label,
1354
- { color: option.disabled ? colors.mutedForeground : colors.foreground }
1743
+ { color: option.disabled ? colors.foregroundMuted : colors.foreground }
1355
1744
  ],
1356
1745
  allowFontScaling: true
1357
1746
  },
@@ -1413,7 +1802,8 @@ function TabTrigger({
1413
1802
  tab,
1414
1803
  isActive,
1415
1804
  onPress,
1416
- onLayout
1805
+ onLayout,
1806
+ variant
1417
1807
  }) {
1418
1808
  const { colors } = useTheme();
1419
1809
  const scale2 = useRef(new Animated.Value(1)).current;
@@ -1423,10 +1813,15 @@ function TabTrigger({
1423
1813
  const handlePressOut = () => {
1424
1814
  Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, speed: 40, bounciness: 4 }).start();
1425
1815
  };
1816
+ const isUnderline = variant === "underline";
1426
1817
  return /* @__PURE__ */ React25.createElement(
1427
1818
  TouchableOpacity,
1428
1819
  {
1429
- style: styles18.trigger,
1820
+ style: [
1821
+ styles18.trigger,
1822
+ isUnderline && styles18.triggerUnderline,
1823
+ isUnderline && isActive && { borderBottomColor: colors.primary }
1824
+ ],
1430
1825
  onPress,
1431
1826
  onPressIn: handlePressIn,
1432
1827
  onPressOut: handlePressOut,
@@ -1439,8 +1834,8 @@ function TabTrigger({
1439
1834
  {
1440
1835
  style: [
1441
1836
  styles18.triggerLabel,
1442
- { color: isActive ? colors.foreground : colors.mutedForeground },
1443
- isActive && styles18.activeTriggerLabel
1837
+ { color: isActive ? colors.foreground : colors.foregroundMuted },
1838
+ isActive && (isUnderline ? styles18.activeTriggerLabelUnderline : styles18.activeTriggerLabel)
1444
1839
  ],
1445
1840
  allowFontScaling: true
1446
1841
  },
@@ -1448,7 +1843,7 @@ function TabTrigger({
1448
1843
  )))
1449
1844
  );
1450
1845
  }
1451
- function Tabs({ tabs, value, onValueChange, children, style }) {
1846
+ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style }) {
1452
1847
  const [internal, setInternal] = useState(tabs[0]?.value ?? "");
1453
1848
  const { colors } = useTheme();
1454
1849
  const active = value ?? internal;
@@ -1461,18 +1856,8 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
1461
1856
  if (!layout) return;
1462
1857
  if (animate) {
1463
1858
  Animated.parallel([
1464
- Animated.spring(pillX, {
1465
- toValue: layout.x,
1466
- useNativeDriver: false,
1467
- speed: 20,
1468
- bounciness: 0
1469
- }),
1470
- Animated.spring(pillWidth, {
1471
- toValue: layout.width,
1472
- useNativeDriver: false,
1473
- speed: 20,
1474
- bounciness: 0
1475
- })
1859
+ Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, speed: 20, bounciness: 0 }),
1860
+ Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, speed: 20, bounciness: 0 })
1476
1861
  ]).start();
1477
1862
  } else {
1478
1863
  pillX.setValue(layout.x);
@@ -1480,16 +1865,16 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
1480
1865
  }
1481
1866
  };
1482
1867
  useEffect(() => {
1483
- if (initialised.current) {
1484
- animatePill(active, true);
1485
- }
1868
+ if (initialised.current) animatePill(active, true);
1486
1869
  }, [active]);
1487
1870
  const handlePress = (v) => {
1488
1871
  selectionAsync();
1489
1872
  if (!value) setInternal(v);
1490
1873
  onValueChange?.(v);
1491
1874
  };
1492
- return /* @__PURE__ */ React25.createElement(View, { style }, /* @__PURE__ */ React25.createElement(View, { style: [styles18.list, { backgroundColor: colors.muted }] }, /* @__PURE__ */ React25.createElement(
1875
+ return /* @__PURE__ */ React25.createElement(View, { style }, /* @__PURE__ */ React25.createElement(View, { style: [
1876
+ variant === "pill" ? [styles18.list, { backgroundColor: colors.surface }] : styles18.listUnderline
1877
+ ] }, variant === "pill" && /* @__PURE__ */ React25.createElement(
1493
1878
  Animated.View,
1494
1879
  {
1495
1880
  style: [
@@ -1504,7 +1889,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
1504
1889
  borderRadius: 8,
1505
1890
  shadowColor: "#000",
1506
1891
  shadowOffset: { width: 0, height: 1 },
1507
- shadowOpacity: 0.1,
1892
+ shadowOpacity: 0.08,
1508
1893
  shadowRadius: 2,
1509
1894
  elevation: 2
1510
1895
  }
@@ -1517,6 +1902,7 @@ function Tabs({ tabs, value, onValueChange, children, style }) {
1517
1902
  tab,
1518
1903
  isActive: tab.value === active,
1519
1904
  onPress: () => handlePress(tab.value),
1905
+ variant,
1520
1906
  onLayout: (e) => {
1521
1907
  const { x, width } = e.nativeEvent.layout;
1522
1908
  tabLayouts.current[tab.value] = { x, width };
@@ -1535,20 +1921,32 @@ function TabsContent({ value, activeValue, children, style }) {
1535
1921
  var styles18 = StyleSheet.create({
1536
1922
  list: {
1537
1923
  flexDirection: "row",
1538
- borderRadius: ms(12),
1924
+ borderRadius: 12,
1539
1925
  padding: s(4),
1540
1926
  gap: s(4)
1541
1927
  },
1928
+ listUnderline: {
1929
+ flexDirection: "row",
1930
+ borderBottomWidth: 1
1931
+ },
1542
1932
  pill: {},
1543
1933
  trigger: {
1544
1934
  flex: 1,
1545
1935
  paddingVertical: vs(7),
1546
1936
  paddingHorizontal: s(10),
1547
- borderRadius: ms(6),
1937
+ borderRadius: 8,
1548
1938
  alignItems: "center",
1549
1939
  justifyContent: "center",
1550
1940
  zIndex: 1
1551
1941
  },
1942
+ triggerUnderline: {
1943
+ flex: 0,
1944
+ paddingVertical: vs(12),
1945
+ paddingHorizontal: s(16),
1946
+ borderRadius: 0,
1947
+ borderBottomWidth: 2,
1948
+ borderBottomColor: "transparent"
1949
+ },
1552
1950
  triggerInner: {
1553
1951
  flexDirection: "row",
1554
1952
  alignItems: "center",
@@ -1561,6 +1959,10 @@ var styles18 = StyleSheet.create({
1561
1959
  },
1562
1960
  activeTriggerLabel: {
1563
1961
  fontFamily: "Poppins-Medium"
1962
+ },
1963
+ activeTriggerLabelUnderline: {
1964
+ fontFamily: "Poppins-SemiBold",
1965
+ fontSize: ms(14)
1564
1966
  }
1565
1967
  });
1566
1968
  function AccordionItemComponent({
@@ -1603,7 +2005,7 @@ function AccordionItemComponent({
1603
2005
  }
1604
2006
  },
1605
2007
  /* @__PURE__ */ React25.createElement(Text, { style: [styles19.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger),
1606
- /* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.mutedForeground }))
2008
+ /* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
1607
2009
  ), /* @__PURE__ */ React25.createElement(Animated11.View, { style: bodyStyle }, /* @__PURE__ */ React25.createElement(
1608
2010
  View,
1609
2011
  {
@@ -1695,7 +2097,7 @@ function Slider({
1695
2097
  }
1696
2098
  onValueChange?.(v);
1697
2099
  };
1698
- return /* @__PURE__ */ React25.createElement(View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25.createElement(View, { style: styles20.header }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.valueText, { color: colors.mutedForeground }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React25.createElement(View, { style: disabled ? styles20.disabled : void 0 }, /* @__PURE__ */ React25.createElement(
2100
+ return /* @__PURE__ */ React25.createElement(View, { style: [styles20.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React25.createElement(View, { style: styles20.header }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React25.createElement(Text, { style: [styles20.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React25.createElement(View, { style: disabled ? styles20.disabled : void 0 }, /* @__PURE__ */ React25.createElement(
1699
2101
  RNSlider,
1700
2102
  {
1701
2103
  value,
@@ -1706,7 +2108,7 @@ function Slider({
1706
2108
  onValueChange: handleValueChange,
1707
2109
  onSlidingComplete,
1708
2110
  minimumTrackTintColor: colors.primary,
1709
- maximumTrackTintColor: colors.muted,
2111
+ maximumTrackTintColor: colors.surface,
1710
2112
  thumbTintColor: colors.primary,
1711
2113
  style: styles20.slider,
1712
2114
  accessibilityLabel
@@ -1744,7 +2146,9 @@ function Sheet({
1744
2146
  title,
1745
2147
  description,
1746
2148
  children,
1747
- style
2149
+ style,
2150
+ scrollable,
2151
+ maxHeight
1748
2152
  }) {
1749
2153
  const { colors } = useTheme();
1750
2154
  const ref = useRef(null);
@@ -1765,6 +2169,8 @@ function Sheet({
1765
2169
  pressBehavior: "close"
1766
2170
  }
1767
2171
  );
2172
+ const headerNode = title || description ? /* @__PURE__ */ React25.createElement(View, { style: styles21.header }, title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.title, { color: colors.foreground }], allowFontScaling: true }, title) : null, description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null) : null;
2173
+ const useScroll = scrollable || !!maxHeight;
1768
2174
  return /* @__PURE__ */ React25.createElement(
1769
2175
  BottomSheetModal,
1770
2176
  {
@@ -1776,7 +2182,7 @@ function Sheet({
1776
2182
  handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
1777
2183
  enablePanDownToClose: true
1778
2184
  },
1779
- /* @__PURE__ */ React25.createElement(BottomSheetView, { style: [styles21.content, style] }, title || description ? /* @__PURE__ */ React25.createElement(View, { style: styles21.header }, title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.title, { color: colors.cardForeground }], allowFontScaling: true }, title) : null, description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles21.description, { color: colors.mutedForeground }], allowFontScaling: true }, description) : null) : null, children)
2185
+ /* @__PURE__ */ React25.createElement(BottomSheetView, { style: maxHeight ? { maxHeight } : void 0 }, useScroll ? /* @__PURE__ */ React25.createElement(BottomSheetScrollView, { contentContainerStyle: [styles21.content, style] }, headerNode, children) : /* @__PURE__ */ React25.createElement(BottomSheetView, { style: [styles21.content, style] }, headerNode, children))
1780
2186
  );
1781
2187
  }
1782
2188
  var styles21 = StyleSheet.create({
@@ -1875,14 +2281,14 @@ function Select({
1875
2281
  {
1876
2282
  style: [
1877
2283
  styles22.triggerText,
1878
- { color: selected ? colors.foreground : colors.mutedForeground }
2284
+ { color: selected ? colors.foreground : colors.foregroundMuted }
1879
2285
  ],
1880
2286
  numberOfLines: 1,
1881
2287
  allowFontScaling: true
1882
2288
  },
1883
2289
  selected?.label ?? placeholder
1884
2290
  ),
1885
- /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-down", size: 20, color: colors.mutedForeground })
2291
+ /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-down", size: 20, color: colors.foregroundMuted })
1886
2292
  )) : null, isIOS ? /* @__PURE__ */ React25.createElement(
1887
2293
  Modal,
1888
2294
  {
@@ -1899,7 +2305,7 @@ function Select({
1899
2305
  onValueChange: (val) => setPendingValue(val),
1900
2306
  itemStyle: { color: colors.foreground }
1901
2307
  },
1902
- !value ? /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", color: colors.mutedForeground, enabled: false }) : null,
2308
+ !value ? /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
1903
2309
  options.map((o) => /* @__PURE__ */ React25.createElement(
1904
2310
  Picker.Item,
1905
2311
  {
@@ -1907,7 +2313,7 @@ function Select({
1907
2313
  label: o.label,
1908
2314
  value: o.value,
1909
2315
  enabled: !o.disabled,
1910
- color: o.disabled ? colors.mutedForeground : colors.foreground
2316
+ color: o.disabled ? colors.foregroundMuted : colors.foreground
1911
2317
  }
1912
2318
  ))
1913
2319
  ))
@@ -1951,7 +2357,7 @@ function Select({
1951
2357
  styles22.webPicker,
1952
2358
  {
1953
2359
  borderColor: error ? colors.destructive : colors.border,
1954
- color: selected ? colors.foreground : colors.mutedForeground,
2360
+ color: selected ? colors.foreground : colors.foregroundMuted,
1955
2361
  backgroundColor: colors.background,
1956
2362
  opacity: disabled ? 0.45 : 1
1957
2363
  }
@@ -2086,22 +2492,42 @@ function ToastNotification({ item, onDismiss }) {
2086
2492
  }));
2087
2493
  const variant = item.variant ?? "default";
2088
2494
  const bgColor = {
2089
- default: colors.foreground,
2495
+ default: colors.card,
2496
+ destructive: colors.destructiveTint,
2497
+ success: colors.successTint,
2498
+ warning: colors.warningTint
2499
+ }[variant];
2500
+ const borderColor = {
2501
+ default: colors.border,
2090
2502
  destructive: colors.destructiveBorder,
2091
- success: colors.successBorder
2503
+ success: colors.successBorder,
2504
+ warning: colors.warningBorder
2092
2505
  }[variant];
2093
- const textColor = {
2094
- default: colors.background,
2095
- destructive: "#991b1b",
2096
- success: "#166534"
2506
+ const accentColor = {
2507
+ default: colors.primary,
2508
+ destructive: colors.destructive,
2509
+ success: colors.success,
2510
+ warning: colors.warning
2097
2511
  }[variant];
2098
- const borderColor = textColor;
2099
- const defaultIcon = variant === "success" ? /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: 18, color: textColor }) : variant === "destructive" ? /* @__PURE__ */ React25.createElement(AntDesign$1, { name: "exclamation-circle", size: 18, color: textColor }) : /* @__PURE__ */ React25.createElement(Entypo$1, { name: "info-with-circle", size: 18, color: textColor });
2100
- const leftIcon = item.iconName ? renderIcon(item.iconName, 22, item.iconColor ?? textColor) : item.icon ?? defaultIcon;
2101
- return /* @__PURE__ */ React25.createElement(GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles23.toast, { backgroundColor: bgColor, borderColor }, animatedStyle] }, /* @__PURE__ */ React25.createElement(View, { style: styles23.leftIconContainer }, leftIcon), /* @__PURE__ */ React25.createElement(View, { style: styles23.toastContent }, item.title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles23.toastTitle, { color: textColor }], allowFontScaling: true }, item.title) : null, item.description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles23.toastDescription, { color: textColor, opacity: 0.85 }], allowFontScaling: true }, item.description) : null), /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: onDismiss, style: styles23.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: "close-circle", size: 18, color: textColor }))));
2102
- }
2103
- function ToastProvider({ children }) {
2104
- const [toasts, setToasts] = useState([]);
2512
+ const titleColor = variant === "default" ? colors.foreground : accentColor;
2513
+ const descColor = variant === "default" ? colors.foregroundMuted : accentColor;
2514
+ const defaultIcon = variant === "success" ? /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: 16, color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React25.createElement(AntDesign$1, { name: "exclamation-circle", size: 16, color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React25.createElement(MaterialIcons$1, { name: "warning-amber", size: 17, color: accentColor }) : /* @__PURE__ */ React25.createElement(Entypo$1, { name: "info-with-circle", size: 16, color: accentColor });
2515
+ const leftIcon = item.iconName ? renderIcon(item.iconName, 16, item.iconColor ?? accentColor) : item.icon ?? defaultIcon;
2516
+ return /* @__PURE__ */ React25.createElement(GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles23.toast, { backgroundColor: bgColor, borderColor }, animatedStyle] }, /* @__PURE__ */ React25.createElement(View, { style: styles23.leftIconContainer }, leftIcon), /* @__PURE__ */ React25.createElement(View, { style: styles23.toastContent }, item.title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles23.toastTitle, { color: titleColor }], allowFontScaling: true }, item.title) : null, item.description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles23.toastDescription, { color: descColor }], allowFontScaling: true }, item.description) : null), item.action && /* @__PURE__ */ React25.createElement(
2517
+ TouchableOpacity,
2518
+ {
2519
+ onPress: () => {
2520
+ item.action.onPress();
2521
+ onDismiss();
2522
+ },
2523
+ style: styles23.actionButton,
2524
+ touchSoundDisabled: true
2525
+ },
2526
+ /* @__PURE__ */ React25.createElement(Text, { style: [styles23.actionLabel, { color: accentColor }], allowFontScaling: true }, item.action.label)
2527
+ ), /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: onDismiss, style: styles23.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React25.createElement(AntDesign$1, { name: "close-circle", size: 16, color: descColor }))));
2528
+ }
2529
+ function ToastProvider({ children }) {
2530
+ const [toasts, setToasts] = useState([]);
2105
2531
  const insets = useSafeAreaInsets();
2106
2532
  const toast = useCallback((item) => {
2107
2533
  const id = Math.random().toString(36).slice(2);
@@ -2109,6 +2535,8 @@ function ToastProvider({ children }) {
2109
2535
  notificationSuccess();
2110
2536
  } else if (item.variant === "destructive") {
2111
2537
  notificationError();
2538
+ } else if (item.variant === "warning") {
2539
+ notificationError();
2112
2540
  } else {
2113
2541
  impactLight();
2114
2542
  }
@@ -2135,38 +2563,52 @@ var styles23 = StyleSheet.create({
2135
2563
  },
2136
2564
  toast: {
2137
2565
  flexDirection: "row",
2138
- alignItems: "center",
2139
- borderRadius: ms(12),
2140
- borderWidth: 1,
2141
- paddingHorizontal: s(14),
2142
- paddingVertical: vs(12),
2566
+ alignItems: "flex-start",
2567
+ borderRadius: ms(10),
2568
+ borderWidth: 0.5,
2569
+ paddingHorizontal: s(12),
2570
+ paddingVertical: vs(10),
2143
2571
  shadowColor: "#000",
2144
- shadowOffset: { width: 0, height: 3 },
2145
- shadowOpacity: 0.1,
2146
- shadowRadius: 8,
2147
- elevation: 5
2572
+ shadowOffset: { width: 0, height: 2 },
2573
+ shadowOpacity: 0.06,
2574
+ shadowRadius: 4,
2575
+ elevation: 3
2148
2576
  },
2149
2577
  toastContent: {
2150
2578
  flex: 1,
2151
- gap: vs(4)
2579
+ gap: vs(2)
2152
2580
  },
2153
2581
  leftIconContainer: {
2154
- width: s(28),
2582
+ marginTop: vs(1),
2155
2583
  alignItems: "center",
2156
2584
  justifyContent: "center",
2157
2585
  marginRight: s(10)
2158
2586
  },
2159
2587
  toastTitle: {
2160
- fontFamily: "Poppins-SemiBold",
2161
- fontSize: ms(15)
2588
+ fontFamily: "Poppins-Medium",
2589
+ fontSize: ms(13),
2590
+ lineHeight: ms(18)
2162
2591
  },
2163
2592
  toastDescription: {
2164
2593
  fontFamily: "Poppins-Regular",
2165
- fontSize: ms(14)
2594
+ fontSize: ms(12),
2595
+ lineHeight: ms(17),
2596
+ opacity: 0.85
2166
2597
  },
2167
- dismissButton: {
2168
- padding: s(8),
2598
+ actionButton: {
2599
+ paddingHorizontal: s(8),
2600
+ paddingVertical: vs(4),
2169
2601
  marginLeft: s(4)
2602
+ },
2603
+ actionLabel: {
2604
+ fontFamily: "Poppins-Medium",
2605
+ fontSize: ms(12),
2606
+ textDecorationLine: "underline"
2607
+ },
2608
+ dismissButton: {
2609
+ padding: s(6),
2610
+ marginLeft: s(2),
2611
+ marginTop: vs(0)
2170
2612
  }
2171
2613
  });
2172
2614
  function formatCurrency(raw, separator) {
@@ -2200,7 +2642,7 @@ function CurrencyInput({
2200
2642
  onChangeValue?.(isNaN(raw) ? 0 : raw);
2201
2643
  };
2202
2644
  const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
2203
- const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.mutedForeground);
2645
+ const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
2204
2646
  const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
2205
2647
  return /* @__PURE__ */ React25.createElement(
2206
2648
  Input,
@@ -2215,7 +2657,7 @@ function CurrencyInput({
2215
2657
  editable,
2216
2658
  prefix: dollarIcon,
2217
2659
  containerStyle,
2218
- inputWrapperStyle: size === "large" ? { paddingVertical: 10 } : void 0,
2660
+ inputWrapperStyle: size === "large" ? { paddingVertical: vs(16), minHeight: 72 } : void 0,
2219
2661
  style: [inputStyle, style]
2220
2662
  }
2221
2663
  );
@@ -2241,7 +2683,8 @@ var styles24 = StyleSheet.create({
2241
2683
  container: {},
2242
2684
  amount: {
2243
2685
  fontFamily: "Poppins-Bold",
2244
- fontSize: ms(56)
2686
+ fontSize: ms(56),
2687
+ letterSpacing: -2
2245
2688
  }
2246
2689
  });
2247
2690
  var nativeDriver10 = Platform.OS !== "web";
@@ -2291,7 +2734,7 @@ function ListItem({
2291
2734
  onPress?.();
2292
2735
  };
2293
2736
  const effectiveLeft = leftIcon ? renderIcon(leftIcon, 24, leftIconColor ?? colors.foreground) : leftRender ?? icon;
2294
- const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.mutedForeground) : rightRender ?? trailing;
2737
+ const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
2295
2738
  const cardStyle = variant === "card" ? {
2296
2739
  backgroundColor: colors.card,
2297
2740
  borderRadius: 12,
@@ -2326,7 +2769,7 @@ function ListItem({
2326
2769
  ), subtitle ? /* @__PURE__ */ React25.createElement(
2327
2770
  Text,
2328
2771
  {
2329
- style: [styles25.subtitle, { color: colors.mutedForeground }, subtitleStyle],
2772
+ style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
2330
2773
  numberOfLines: 2,
2331
2774
  allowFontScaling: true
2332
2775
  },
@@ -2334,7 +2777,7 @@ function ListItem({
2334
2777
  ) : null, caption ? /* @__PURE__ */ React25.createElement(
2335
2778
  Text,
2336
2779
  {
2337
- style: [styles25.caption, { color: colors.mutedForeground }, captionStyle],
2780
+ style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
2338
2781
  numberOfLines: 1,
2339
2782
  allowFontScaling: true
2340
2783
  },
@@ -2343,11 +2786,11 @@ function ListItem({
2343
2786
  effectiveRight !== void 0 ? /* @__PURE__ */ React25.createElement(View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25.createElement(
2344
2787
  Text,
2345
2788
  {
2346
- style: [styles25.rightText, { color: colors.mutedForeground }],
2789
+ style: [styles25.rightText, { color: colors.foregroundMuted }],
2347
2790
  allowFontScaling: true
2348
2791
  },
2349
2792
  effectiveRight
2350
- ) : effectiveRight) : showChevron ? /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-right", size: 20, color: colors.mutedForeground }) : null
2793
+ ) : effectiveRight) : showChevron ? /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
2351
2794
  ), showSeparator ? /* @__PURE__ */ React25.createElement(
2352
2795
  View,
2353
2796
  {
@@ -2449,7 +2892,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2449
2892
  };
2450
2893
  const backgroundColor = pressAnim.interpolate({
2451
2894
  inputRange: [0, 1],
2452
- outputRange: [colors.secondary, colors.primary]
2895
+ outputRange: [colors.surface, colors.primary]
2453
2896
  });
2454
2897
  const textColor = pressAnim.interpolate({
2455
2898
  inputRange: [0, 1],
@@ -2571,16 +3014,7 @@ function ConfirmDialog({
2571
3014
  handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
2572
3015
  enablePanDownToClose: true
2573
3016
  },
2574
- /* @__PURE__ */ React25.createElement(BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25.createElement(Text, { style: [styles27.title, { color: colors.cardForeground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles27.description, { color: colors.mutedForeground }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React25.createElement(View, { style: styles27.actions }, /* @__PURE__ */ React25.createElement(
2575
- Button,
2576
- {
2577
- label: cancelLabel,
2578
- variant: "outline",
2579
- fullWidth: true,
2580
- onPress: onCancel,
2581
- icon: /* @__PURE__ */ React25.createElement(Feather$1, { name: "x", size: 15, color: colors.foreground })
2582
- }
2583
- ), /* @__PURE__ */ React25.createElement(
3017
+ /* @__PURE__ */ React25.createElement(BottomSheetView, { style: styles27.content }, /* @__PURE__ */ React25.createElement(Text, { style: [styles27.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React25.createElement(Text, { style: [styles27.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React25.createElement(View, { style: styles27.actions }, /* @__PURE__ */ React25.createElement(
2584
3018
  Button,
2585
3019
  {
2586
3020
  label: confirmLabel,
@@ -2596,6 +3030,15 @@ function ConfirmDialog({
2596
3030
  }
2597
3031
  )
2598
3032
  }
3033
+ ), /* @__PURE__ */ React25.createElement(
3034
+ Button,
3035
+ {
3036
+ label: cancelLabel,
3037
+ variant: "secondary",
3038
+ fullWidth: true,
3039
+ onPress: onCancel,
3040
+ icon: /* @__PURE__ */ React25.createElement(Feather$1, { name: "x", size: 15, color: colors.foreground })
3041
+ }
2599
3042
  )))
2600
3043
  );
2601
3044
  }
@@ -2631,7 +3074,7 @@ var styles27 = StyleSheet.create({
2631
3074
  });
2632
3075
  function LabelValue({ label, value, style }) {
2633
3076
  const { colors } = useTheme();
2634
- return /* @__PURE__ */ React25.createElement(View, { style: [styles28.container, style] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles28.label, { color: colors.mutedForeground }], allowFontScaling: true }, label), typeof value === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles28.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
3077
+ return /* @__PURE__ */ React25.createElement(View, { style: [styles28.container, style] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles28.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label), typeof value === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles28.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
2635
3078
  }
2636
3079
  var styles28 = StyleSheet.create({
2637
3080
  container: {
@@ -2724,63 +3167,342 @@ var styles29 = StyleSheet.create({
2724
3167
  minWidth: s(160)
2725
3168
  }
2726
3169
  });
3170
+ function useHover() {
3171
+ const [hovered, setHovered] = useState(false);
3172
+ const onMouseEnter = useCallback(() => setHovered(true), []);
3173
+ const onMouseLeave = useCallback(() => setHovered(false), []);
3174
+ if (Platform.OS !== "web") {
3175
+ return { hovered: false, hoverHandlers: {} };
3176
+ }
3177
+ return { hovered, hoverHandlers: { onMouseEnter, onMouseLeave } };
3178
+ }
2727
3179
 
2728
- // src/tokens.ts
2729
- var SPACING = {
2730
- xs: 4,
2731
- sm: 8,
2732
- md: 12,
2733
- lg: 16,
2734
- xl: 24,
2735
- "2xl": 32,
2736
- "3xl": 48
3180
+ // src/components/MediaCard/MediaCard.tsx
3181
+ var nativeDriver12 = Platform.OS !== "web";
3182
+ var aspectRatioMap = {
3183
+ "1:1": 1,
3184
+ "4:3": 3 / 4,
3185
+ "16:9": 9 / 16,
3186
+ "4:5": 5 / 4,
3187
+ "3:2": 2 / 3
2737
3188
  };
2738
- var ICON_SIZES = {
2739
- sm: 14,
2740
- md: 18,
2741
- lg: 22,
2742
- xl: 28,
2743
- "2xl": 32
2744
- };
2745
- var RADIUS = {
2746
- sm: 4,
2747
- md: 8,
2748
- lg: 12,
2749
- xl: 16,
2750
- full: 9999
2751
- };
2752
- var SHADOWS = {
2753
- sm: {
2754
- shadowColor: "#000",
2755
- shadowOffset: { width: 0, height: 1 },
2756
- shadowOpacity: 0.08,
2757
- shadowRadius: 4,
2758
- elevation: 2
3189
+ function MediaCard({
3190
+ imageSource,
3191
+ aspectRatio = "4:3",
3192
+ badge,
3193
+ actionIcon,
3194
+ actionIconName,
3195
+ actionActive = false,
3196
+ onActionPress,
3197
+ title,
3198
+ subtitle,
3199
+ caption,
3200
+ onPress,
3201
+ style,
3202
+ imageStyle,
3203
+ footer
3204
+ }) {
3205
+ const { colors } = useTheme();
3206
+ const scale2 = useRef(new Animated.Value(1)).current;
3207
+ const { hovered, hoverHandlers } = useHover();
3208
+ const handlePressIn = () => {
3209
+ if (!onPress) return;
3210
+ Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver12, speed: 40, bounciness: 0 }).start();
3211
+ };
3212
+ const handlePressOut = () => {
3213
+ if (!onPress) return;
3214
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver12, speed: 40, bounciness: 4 }).start();
3215
+ };
3216
+ const handlePress = () => {
3217
+ if (!onPress) return;
3218
+ impactLight();
3219
+ onPress();
3220
+ };
3221
+ const ratio = aspectRatioMap[aspectRatio];
3222
+ const resolvedActionIcon = actionIconName ? renderIcon(actionIconName, 18, actionActive ? colors.primary : colors.background) : actionIcon ?? renderIcon("heart", 18, actionActive ? colors.primary : colors.background);
3223
+ const cardContent = /* @__PURE__ */ React25.createElement(
3224
+ View,
3225
+ {
3226
+ style: [
3227
+ styles30.card,
3228
+ hovered && styles30.cardHovered,
3229
+ style
3230
+ ],
3231
+ ...Platform.OS === "web" ? hoverHandlers : {}
3232
+ },
3233
+ /* @__PURE__ */ React25.createElement(View, { style: [styles30.imageContainer, imageStyle] }, /* @__PURE__ */ React25.createElement(View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React25.createElement(View, { style: StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React25.createElement(
3234
+ Image,
3235
+ {
3236
+ source: imageSource,
3237
+ style: styles30.image,
3238
+ resizeMode: "cover"
3239
+ }
3240
+ ) : /* @__PURE__ */ React25.createElement(View, { style: [styles30.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React25.createElement(View, { style: styles30.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React25.createElement(
3241
+ TouchableOpacity,
3242
+ {
3243
+ style: [styles30.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
3244
+ onPress: () => {
3245
+ impactLight();
3246
+ onActionPress?.();
3247
+ },
3248
+ activeOpacity: 0.8,
3249
+ touchSoundDisabled: true
3250
+ },
3251
+ resolvedActionIcon
3252
+ )),
3253
+ (title || subtitle || caption || footer) && /* @__PURE__ */ React25.createElement(View, { style: styles30.meta }, title ? /* @__PURE__ */ React25.createElement(Text, { style: [styles30.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React25.createElement(Text, { style: [styles30.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React25.createElement(Text, { style: [styles30.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
3254
+ );
3255
+ if (onPress) {
3256
+ return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
3257
+ TouchableOpacity,
3258
+ {
3259
+ onPress: handlePress,
3260
+ onPressIn: handlePressIn,
3261
+ onPressOut: handlePressOut,
3262
+ activeOpacity: 1,
3263
+ touchSoundDisabled: true
3264
+ },
3265
+ cardContent
3266
+ ));
3267
+ }
3268
+ return cardContent;
3269
+ }
3270
+ var styles30 = StyleSheet.create({
3271
+ card: {
3272
+ borderRadius: RADIUS.md,
3273
+ // 14px — Airbnb property card spec
3274
+ overflow: "hidden",
3275
+ backgroundColor: "transparent"
2759
3276
  },
2760
- md: {
2761
- shadowColor: "#000",
2762
- shadowOffset: { width: 0, height: 3 },
2763
- shadowOpacity: 0.12,
2764
- shadowRadius: 8,
2765
- elevation: 5
3277
+ cardHovered: {
3278
+ // Web hover: lift shadow
3279
+ ...SHADOWS.md
2766
3280
  },
2767
- lg: {
2768
- shadowColor: "#000",
2769
- shadowOffset: { width: 0, height: 6 },
2770
- shadowOpacity: 0.2,
2771
- shadowRadius: 16,
2772
- elevation: 10
3281
+ imageContainer: {
3282
+ borderRadius: RADIUS.md,
3283
+ overflow: "hidden"
2773
3284
  },
2774
- xl: {
2775
- shadowColor: "#000",
2776
- shadowOffset: { width: 0, height: 12 },
2777
- shadowOpacity: 0.28,
2778
- shadowRadius: 24,
2779
- elevation: 18
3285
+ image: {
3286
+ width: "100%",
3287
+ height: "100%"
3288
+ },
3289
+ imagePlaceholder: {
3290
+ width: "100%",
3291
+ height: "100%"
3292
+ },
3293
+ badgeContainer: {
3294
+ position: "absolute",
3295
+ top: s(8),
3296
+ left: s(8)
3297
+ },
3298
+ actionButton: {
3299
+ position: "absolute",
3300
+ top: s(8),
3301
+ right: s(8),
3302
+ width: s(32),
3303
+ height: s(32),
3304
+ borderRadius: 9999,
3305
+ alignItems: "center",
3306
+ justifyContent: "center"
3307
+ },
3308
+ meta: {
3309
+ paddingTop: vs(8),
3310
+ gap: vs(2)
3311
+ },
3312
+ title: {
3313
+ fontFamily: "Poppins-SemiBold",
3314
+ fontSize: ms(14),
3315
+ lineHeight: mvs(20)
3316
+ },
3317
+ subtitle: {
3318
+ fontFamily: "Poppins-Regular",
3319
+ fontSize: ms(13),
3320
+ lineHeight: mvs(18)
3321
+ },
3322
+ caption: {
3323
+ fontFamily: "Poppins-Regular",
3324
+ fontSize: ms(12),
3325
+ lineHeight: mvs(16)
2780
3326
  }
2781
- };
2782
- var BREAKPOINTS = {
2783
- wide: 700
2784
- };
3327
+ });
3328
+ var nativeDriver13 = Platform.OS !== "web";
3329
+ function CategoryChip({
3330
+ item,
3331
+ selected,
3332
+ onPress
3333
+ }) {
3334
+ const { colors } = useTheme();
3335
+ const scale2 = useRef(new Animated.Value(1)).current;
3336
+ const handlePressIn = () => {
3337
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
3338
+ };
3339
+ const handlePressOut = () => {
3340
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
3341
+ };
3342
+ const bgColor = selected ? colors.primary : colors.surface;
3343
+ const textColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
3344
+ const borderColor = selected ? colors.primary : colors.border;
3345
+ const resolvedIcon = typeof item.icon === "string" ? renderIcon(item.icon, 16, textColor) : item.icon ?? null;
3346
+ return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
3347
+ TouchableOpacity,
3348
+ {
3349
+ style: [
3350
+ styles31.chip,
3351
+ {
3352
+ backgroundColor: bgColor,
3353
+ borderColor
3354
+ }
3355
+ ],
3356
+ onPress,
3357
+ onPressIn: handlePressIn,
3358
+ onPressOut: handlePressOut,
3359
+ activeOpacity: 1,
3360
+ touchSoundDisabled: true
3361
+ },
3362
+ resolvedIcon && /* @__PURE__ */ React25.createElement(View, { style: styles31.chipIcon }, resolvedIcon),
3363
+ /* @__PURE__ */ React25.createElement(Text, { style: [styles31.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
3364
+ item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React25.createElement(View, { style: [styles31.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles31.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
3365
+ ));
3366
+ }
3367
+ function CategoryStrip({
3368
+ categories,
3369
+ value,
3370
+ onValueChange,
3371
+ multiSelect = false,
3372
+ style,
3373
+ itemStyle
3374
+ }) {
3375
+ const selected = Array.isArray(value) ? value : value ? [value] : [];
3376
+ const handlePress = (v) => {
3377
+ selectionAsync();
3378
+ if (multiSelect) {
3379
+ const current = Array.isArray(value) ? value : value ? [value] : [];
3380
+ const next = current.includes(v) ? current.filter((x) => x !== v) : [...current, v];
3381
+ onValueChange?.(next);
3382
+ } else {
3383
+ onValueChange?.(v === value ? "" : v);
3384
+ }
3385
+ };
3386
+ return /* @__PURE__ */ React25.createElement(
3387
+ ScrollView,
3388
+ {
3389
+ horizontal: true,
3390
+ showsHorizontalScrollIndicator: false,
3391
+ contentContainerStyle: [styles31.container, style],
3392
+ style: styles31.scroll
3393
+ },
3394
+ categories.map((cat) => /* @__PURE__ */ React25.createElement(View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25.createElement(
3395
+ CategoryChip,
3396
+ {
3397
+ item: cat,
3398
+ selected: selected.includes(cat.value),
3399
+ onPress: () => handlePress(cat.value)
3400
+ }
3401
+ )))
3402
+ );
3403
+ }
3404
+ var styles31 = StyleSheet.create({
3405
+ scroll: {
3406
+ flexGrow: 0
3407
+ },
3408
+ container: {
3409
+ flexDirection: "row",
3410
+ gap: s(8),
3411
+ paddingHorizontal: s(4),
3412
+ paddingVertical: vs(4)
3413
+ },
3414
+ chip: {
3415
+ flexDirection: "row",
3416
+ alignItems: "center",
3417
+ borderRadius: RADIUS.full,
3418
+ borderWidth: 1,
3419
+ paddingHorizontal: s(14),
3420
+ paddingVertical: vs(8),
3421
+ gap: s(6)
3422
+ },
3423
+ chipIcon: {
3424
+ alignItems: "center",
3425
+ justifyContent: "center"
3426
+ },
3427
+ chipLabel: {
3428
+ fontFamily: "Poppins-Medium",
3429
+ fontSize: ms(13)
3430
+ },
3431
+ chipBadge: {
3432
+ minWidth: 16,
3433
+ height: 16,
3434
+ borderRadius: 9999,
3435
+ paddingHorizontal: 3,
3436
+ alignItems: "center",
3437
+ justifyContent: "center"
3438
+ },
3439
+ chipBadgeText: {
3440
+ fontFamily: "Poppins-Bold",
3441
+ fontSize: ms(9),
3442
+ lineHeight: 14
3443
+ }
3444
+ });
3445
+ var nativeDriver14 = Platform.OS !== "web";
3446
+ function Pressable2({
3447
+ children,
3448
+ onPress,
3449
+ pressScale = 0.98,
3450
+ bounciness = 4,
3451
+ haptics = true,
3452
+ style,
3453
+ disabled,
3454
+ hoverScale = 1.02,
3455
+ ...touchableProps
3456
+ }) {
3457
+ const scale2 = useRef(new Animated.Value(1)).current;
3458
+ const { hovered, hoverHandlers } = useHover();
3459
+ const handlePressIn = () => {
3460
+ if (disabled) return;
3461
+ Animated.spring(scale2, {
3462
+ toValue: pressScale,
3463
+ useNativeDriver: nativeDriver14,
3464
+ speed: 40,
3465
+ bounciness: 0
3466
+ }).start();
3467
+ };
3468
+ const handlePressOut = () => {
3469
+ if (disabled) return;
3470
+ Animated.spring(scale2, {
3471
+ toValue: 1,
3472
+ useNativeDriver: nativeDriver14,
3473
+ speed: 40,
3474
+ bounciness
3475
+ }).start();
3476
+ };
3477
+ const handlePress = () => {
3478
+ if (disabled || !onPress) return;
3479
+ if (haptics) impactLight();
3480
+ onPress();
3481
+ };
3482
+ const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
3483
+ return /* @__PURE__ */ React25.createElement(
3484
+ Animated.View,
3485
+ {
3486
+ style: [
3487
+ { transform: [{ scale: Animated.multiply(scale2, hoverScaleValue) }] },
3488
+ style
3489
+ ],
3490
+ ...Platform.OS === "web" ? hoverHandlers : {}
3491
+ },
3492
+ /* @__PURE__ */ React25.createElement(
3493
+ TouchableOpacity,
3494
+ {
3495
+ onPress: handlePress,
3496
+ onPressIn: handlePressIn,
3497
+ onPressOut: handlePressOut,
3498
+ activeOpacity: 1,
3499
+ disabled,
3500
+ touchSoundDisabled: true,
3501
+ ...touchableProps
3502
+ },
3503
+ children
3504
+ )
3505
+ );
3506
+ }
2785
3507
 
2786
- export { Accordion, AlertBanner, Avatar, BREAKPOINTS, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, ChipGroup, ConfirmDialog, CurrencyDisplay, CurrencyInput, CurrencyInput as CurrencyInputLarge, EmptyState, ICON_SIZES, Icon, IconButton, Input, LabelValue, ListItem, MonthPicker, Progress, RADIUS, RadioGroup, SHADOWS, SPACING, Select, Separator, Sheet, Skeleton, Slider, Spinner, Switch, Tabs, TabsContent, Text2 as Text, Textarea, ThemeProvider, ToastProvider, Toggle, defaultDark, defaultLight, renderIcon, useTheme, useToast };
3508
+ export { Accordion, AlertBanner, Avatar, BREAKPOINTS, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryStrip, Checkbox, Chip, ChipGroup, ConfirmDialog, CurrencyDisplay, CurrencyInput, CurrencyInput as CurrencyInputLarge, EmptyState, ICON_SIZES, Icon, IconButton, Input, LabelValue, ListItem, MediaCard, MonthPicker, Pressable2 as Pressable, Progress, RADIUS, RadioGroup, SHADOWS, SPACING, Select, Separator, Sheet, Skeleton, Slider, Spinner, Switch, TYPOGRAPHY, Tabs, TabsContent, Text3 as Text, Textarea, ThemeProvider, ToastProvider, Toggle, defaultDark, defaultLight, deriveColors, renderIcon, useTheme, useToast };