@retray-dev/ui-kit 5.2.0 → 6.0.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 (42) hide show
  1. package/COMPONENTS.md +500 -140
  2. package/EXAMPLES.md +666 -0
  3. package/README.md +3 -3
  4. package/dist/index.d.mts +253 -49
  5. package/dist/index.d.ts +253 -49
  6. package/dist/index.js +955 -610
  7. package/dist/index.mjs +886 -552
  8. package/package.json +9 -3
  9. package/src/components/Accordion/Accordion.tsx +31 -4
  10. package/src/components/AlertBanner/AlertBanner.tsx +16 -33
  11. package/src/components/Avatar/Avatar.tsx +21 -7
  12. package/src/components/Button/Button.tsx +34 -13
  13. package/src/components/ButtonGroup/ButtonGroup.tsx +60 -0
  14. package/src/components/ButtonGroup/index.ts +1 -0
  15. package/src/components/Card/Card.tsx +12 -9
  16. package/src/components/Chip/Chip.tsx +8 -1
  17. package/src/components/ConfirmDialog/ConfirmDialog.tsx +4 -4
  18. package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +38 -5
  19. package/src/components/DetailRow/DetailRow.tsx +140 -0
  20. package/src/components/DetailRow/index.ts +1 -0
  21. package/src/components/EmptyState/EmptyState.tsx +21 -6
  22. package/src/components/Input/Input.tsx +21 -10
  23. package/src/components/LabelValue/LabelValue.tsx +25 -4
  24. package/src/components/ListItem/ListItem.tsx +14 -8
  25. package/src/components/MediaCard/MediaCard.tsx +1 -0
  26. package/src/components/MenuItem/MenuItem.tsx +206 -0
  27. package/src/components/MenuItem/index.ts +2 -0
  28. package/src/components/MonthPicker/MonthPicker.tsx +18 -6
  29. package/src/components/Select/Select.tsx +1 -1
  30. package/src/components/Separator/Separator.tsx +2 -0
  31. package/src/components/Sheet/Sheet.tsx +165 -36
  32. package/src/components/Sheet/index.ts +1 -1
  33. package/src/components/Tabs/Tabs.tsx +4 -4
  34. package/src/components/Textarea/Textarea.tsx +66 -29
  35. package/src/components/Toast/Toast.tsx +41 -267
  36. package/src/components/Toast/index.ts +1 -2
  37. package/src/components/Toggle/Toggle.tsx +2 -2
  38. package/src/index.ts +6 -0
  39. package/src/theme/colors.ts +3 -0
  40. package/src/theme/types.ts +11 -0
  41. package/src/tokens.ts +4 -4
  42. package/src/utils/typography.ts +24 -0
package/dist/index.mjs CHANGED
@@ -1,22 +1,22 @@
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, ScrollView, Pressable } from 'react-native';
3
- import { verticalScale, scale, moderateScale, moderateVerticalScale } from 'react-native-size-matters';
1
+ import React26, { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
2
+ import { Platform, StyleSheet, Dimensions, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Easing as Easing$1, Image, Modal, ScrollView, Pressable } from 'react-native';
3
+ import { verticalScale, scale, moderateVerticalScale, moderateScale } from 'react-native-size-matters';
4
4
  import AntDesign from '@expo/vector-icons/AntDesign';
5
5
  import Entypo from '@expo/vector-icons/Entypo';
6
6
  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, Feather as Feather$1, Entypo as Entypo$1, FontAwesome5 as FontAwesome5$1, MaterialIcons as MaterialIcons$1 } from '@expo/vector-icons';
10
+ import { AntDesign as AntDesign$1, FontAwesome5 as FontAwesome5$1, MaterialIcons as MaterialIcons$1, Entypo as Entypo$1, Feather as Feather$1 } from '@expo/vector-icons';
11
11
  import { LinearGradient } from 'expo-linear-gradient';
12
- import Animated11, { useSharedValue, useDerivedValue, withTiming, Easing as Easing$1, useAnimatedStyle, withSpring } from 'react-native-reanimated';
12
+ import Animated12, { Easing, useSharedValue, useDerivedValue, withTiming, useAnimatedStyle } from 'react-native-reanimated';
13
13
  import RNSlider from '@react-native-community/slider';
14
- import { BottomSheetModal, BottomSheetView, BottomSheetScrollView, BottomSheetBackdrop } from '@gorhom/bottom-sheet';
15
- export { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
16
- import { Picker } from '@react-native-picker/picker';
17
- import { scheduleOnRN } from 'react-native-worklets';
18
- import { Gesture, GestureDetector } from 'react-native-gesture-handler';
14
+ import { BottomSheetBackdrop, BottomSheetFooter, BottomSheetModal, BottomSheetScrollView, BottomSheetView } from '@gorhom/bottom-sheet';
15
+ export { BottomSheetModalProvider, BottomSheetTextInput as SheetTextInput } from '@gorhom/bottom-sheet';
19
16
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
17
+ import { Picker } from '@react-native-picker/picker';
18
+ import { toast, Toaster } from 'sonner-native';
19
+ export { toast } from 'sonner-native';
20
20
 
21
21
  // src/theme/ThemeProvider.tsx
22
22
 
@@ -129,6 +129,9 @@ function deriveColors(t, scheme) {
129
129
  successBorder,
130
130
  warningTint,
131
131
  warningBorder,
132
+ overlay: t.overlay ?? "rgba(0,0,0,0.45)",
133
+ accentResolved: t.accent ?? t.primary,
134
+ accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
132
135
  ring: t.primary,
133
136
  // focus ring always = primary
134
137
  input: t.border
@@ -150,7 +153,7 @@ function ThemeProvider({ children, theme, colorScheme = "system" }) {
150
153
  const merged = override ? { ...base, ...override } : base;
151
154
  return deriveColors(merged, resolvedScheme);
152
155
  }, [resolvedScheme, theme]);
153
- return /* @__PURE__ */ React25.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
156
+ return /* @__PURE__ */ React26.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
154
157
  }
155
158
  function useTheme() {
156
159
  const context = useContext(ThemeContext);
@@ -175,13 +178,13 @@ function impactLight() {
175
178
  if (Platform.OS === "web") return;
176
179
  getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Light));
177
180
  }
178
- function notificationSuccess() {
181
+ function impactMedium() {
179
182
  if (Platform.OS === "web") return;
180
- getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Success));
183
+ getHaptics().then((h) => h?.impactAsync(h.ImpactFeedbackStyle.Medium));
181
184
  }
182
- function notificationError() {
185
+ function notificationSuccess() {
183
186
  if (Platform.OS === "web") return;
184
- getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Error));
187
+ getHaptics().then((h) => h?.notificationAsync(h.NotificationFeedbackType.Success));
185
188
  }
186
189
  var isWeb = Platform.OS === "web";
187
190
  var s = isWeb ? (n) => n : scale;
@@ -222,10 +225,10 @@ function Icon({ name, size, color, family }) {
222
225
  }
223
226
  if (!resolved) return null;
224
227
  const Component = resolved.component;
225
- return React25.createElement(Component, { name, size, color });
228
+ return React26.createElement(Component, { name, size, color });
226
229
  }
227
230
  function renderIcon(name, size, color) {
228
- return React25.createElement(Icon, { name, size, color });
231
+ return React26.createElement(Icon, { name, size, color });
229
232
  }
230
233
 
231
234
  // src/tokens.ts
@@ -383,17 +386,17 @@ var TYPOGRAPHY = {
383
386
  },
384
387
  "uppercase-tag": {
385
388
  fontFamily: "Poppins-Bold",
386
- fontSize: 8,
389
+ fontSize: 10,
387
390
  fontWeight: "700",
388
- lineHeight: 10,
389
- letterSpacing: 0.32,
391
+ lineHeight: 13,
392
+ letterSpacing: 0.8,
390
393
  textTransform: "uppercase"
391
394
  },
392
395
  "button-lg": {
393
396
  fontFamily: "Poppins-Medium",
394
397
  fontSize: 16,
395
398
  fontWeight: "500",
396
- lineHeight: 20,
399
+ lineHeight: 22,
397
400
  letterSpacing: 0
398
401
  },
399
402
  "button-sm": {
@@ -415,7 +418,7 @@ var containerSizeStyles = {
415
418
  var labelSizeStyles = {
416
419
  sm: { ...TYPOGRAPHY["button-sm"], fontSize: ms(TYPOGRAPHY["button-sm"].fontSize) },
417
420
  md: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize) },
418
- lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1) }
421
+ lg: { ...TYPOGRAPHY["button-lg"], fontSize: ms(TYPOGRAPHY["button-lg"].fontSize + 1), lineHeight: mvs(24) }
419
422
  };
420
423
  var iconSizeMap = { sm: 16, md: 18, lg: 20 };
421
424
  function Button({
@@ -438,13 +441,13 @@ function Button({
438
441
  const scale2 = useRef(new Animated.Value(1)).current;
439
442
  const handlePressIn = () => {
440
443
  if (isDisabled) return;
441
- Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, speed: 40, bounciness: 0 }).start();
444
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver, stiffness: 600, damping: 35, mass: 0.8 }).start();
442
445
  };
443
446
  const handlePressOut = () => {
444
- Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, speed: 40, bounciness: 4 }).start();
447
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver, stiffness: 280, damping: 22, mass: 0.8 }).start();
445
448
  };
446
449
  const handlePress = (e) => {
447
- impactLight();
450
+ impactMedium();
448
451
  onPress?.(e);
449
452
  };
450
453
  const containerVariantStyle = {
@@ -459,9 +462,13 @@ function Button({
459
462
  text: { color: colors.foreground },
460
463
  destructive: { color: colors.destructiveForeground }
461
464
  }[variant];
462
- const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], iconColor ?? labelVariantStyle.color) : typeof icon === "function" ? icon({ label, size, variant }) : icon;
465
+ const textColor = iconColor ?? labelVariantStyle.color;
466
+ const effectiveIcon = iconName ? renderIcon(iconName, iconSizeMap[size], textColor) : typeof icon === "function" ? icon({ label, size, variant, color: textColor }) : icon;
463
467
  const spinnerColor = variant === "destructive" ? colors.destructiveForeground : variant === "primary" ? colors.primaryForeground : colors.foreground;
464
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: [fullWidth && styles.fullWidth, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25.createElement(
468
+ const styleArray = Array.isArray(style) ? style : style ? [style] : [];
469
+ const flatStyle = StyleSheet.flatten(styleArray);
470
+ const { flex, ...restStyle } = flatStyle || {};
471
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: [fullWidth && styles.fullWidth, flex !== void 0 && { flex }, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React26.createElement(
465
472
  TouchableOpacity,
466
473
  {
467
474
  style: [
@@ -470,7 +477,7 @@ function Button({
470
477
  containerSizeStyles[size],
471
478
  fullWidth && styles.fullWidth,
472
479
  isDisabled && styles.disabled,
473
- style
480
+ restStyle
474
481
  ],
475
482
  disabled: isDisabled,
476
483
  activeOpacity: 1,
@@ -480,20 +487,29 @@ function Button({
480
487
  onPressOut: handlePressOut,
481
488
  ...props
482
489
  },
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(
490
+ loading ? /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(ActivityIndicator, { size: "small", color: spinnerColor, style: { marginRight: s(6) } }), /* @__PURE__ */ React26.createElement(
491
+ Text,
492
+ {
493
+ style: [styles.label, labelVariantStyle, labelSizeStyles[size], styles.labelLoading],
494
+ allowFontScaling: true,
495
+ numberOfLines: 1
496
+ },
497
+ label
498
+ )) : /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon && iconPosition === "left" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon), /* @__PURE__ */ React26.createElement(
484
499
  Text,
485
500
  {
486
501
  style: [styles.label, labelVariantStyle, labelSizeStyles[size], effectiveIcon ? styles.labelWithIcon : void 0],
487
- allowFontScaling: true
502
+ allowFontScaling: true,
503
+ numberOfLines: 1
488
504
  },
489
505
  label
490
- ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React25.createElement(React25.Fragment, null, effectiveIcon))
506
+ ), effectiveIcon && iconPosition === "right" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, effectiveIcon))
491
507
  ));
492
508
  }
493
509
  var styles = StyleSheet.create({
494
510
  base: {
495
- borderRadius: RADIUS.xl,
496
- // 32pxpill-shaped primary CTA (Airbnb spec)
511
+ borderRadius: RADIUS.md,
512
+ // 14pxAirbnb-aligned rounded rect (not pill)
497
513
  alignItems: "center",
498
514
  justifyContent: "center",
499
515
  flexDirection: "row"
@@ -505,10 +521,47 @@ var styles = StyleSheet.create({
505
521
  opacity: 0.45
506
522
  },
507
523
  label: {
508
- fontFamily: "Poppins-Medium"
524
+ fontFamily: "Poppins-Medium",
525
+ flexShrink: 1
509
526
  },
510
527
  labelWithIcon: {
511
528
  marginHorizontal: s(6)
529
+ },
530
+ labelLoading: {
531
+ opacity: 0.6
532
+ }
533
+ });
534
+ function ButtonGroup({ children, gap = 12, vertical = false, style }) {
535
+ return /* @__PURE__ */ React26.createElement(
536
+ View,
537
+ {
538
+ style: [
539
+ styles2.container,
540
+ vertical ? styles2.vertical : styles2.horizontal,
541
+ { gap: s(gap) },
542
+ style
543
+ ]
544
+ },
545
+ React26.Children.map(
546
+ children,
547
+ (child) => React26.isValidElement(child) ? React26.cloneElement(child, {
548
+ style: [
549
+ child.props.style,
550
+ { flex: 1 }
551
+ ]
552
+ }) : child
553
+ )
554
+ );
555
+ }
556
+ var styles2 = StyleSheet.create({
557
+ container: {
558
+ width: "100%"
559
+ },
560
+ horizontal: {
561
+ flexDirection: "row"
562
+ },
563
+ vertical: {
564
+ flexDirection: "column"
512
565
  }
513
566
  });
514
567
  var nativeDriver2 = Platform.OS !== "web";
@@ -564,14 +617,14 @@ function IconButton({
564
617
  const showBadge = badge !== void 0 && badge !== false && badge !== 0;
565
618
  const badgeCount = typeof badge === "number" ? Math.min(badge, 99) : null;
566
619
  const showCount = typeof badge === "number" && badge > 0;
567
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles2.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React25.createElement(
620
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: [styles3.wrapper, { transform: [{ scale: scale2 }] }] }, /* @__PURE__ */ React26.createElement(
568
621
  TouchableOpacity,
569
622
  {
570
623
  style: [
571
- styles2.base,
624
+ styles3.base,
572
625
  containerVariantStyle,
573
626
  { width: containerSize, height: containerSize },
574
- isDisabled && styles2.disabled,
627
+ isDisabled && styles3.disabled,
575
628
  style
576
629
  ],
577
630
  disabled: isDisabled,
@@ -582,14 +635,14 @@ function IconButton({
582
635
  onPressOut: handlePressOut,
583
636
  ...props
584
637
  },
585
- loading ? /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
586
- ), showBadge && /* @__PURE__ */ React25.createElement(View, { style: [
587
- styles2.badge,
638
+ loading ? /* @__PURE__ */ React26.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : resolvedIcon
639
+ ), showBadge && /* @__PURE__ */ React26.createElement(View, { style: [
640
+ styles3.badge,
588
641
  { backgroundColor: colors.primary },
589
- showCount ? styles2.badgeCount : styles2.badgeDot
590
- ] }, showCount && /* @__PURE__ */ React25.createElement(Text, { style: [styles2.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
642
+ showCount ? styles3.badgeCount : styles3.badgeDot
643
+ ] }, showCount && /* @__PURE__ */ React26.createElement(Text, { style: [styles3.badgeText, { color: colors.primaryForeground }] }, badgeCount)));
591
644
  }
592
- var styles2 = StyleSheet.create({
645
+ var styles3 = StyleSheet.create({
593
646
  wrapper: {
594
647
  alignSelf: "flex-start"
595
648
  },
@@ -666,7 +719,7 @@ function Text3({ variant = "body-md", color, style, children, ...props }) {
666
719
  const { colors } = useTheme();
667
720
  const colorKey = defaultColorVariant[variant] ?? "foreground";
668
721
  const resolvedColor = color ?? colors[colorKey];
669
- return /* @__PURE__ */ React25.createElement(
722
+ return /* @__PURE__ */ React26.createElement(
670
723
  Text,
671
724
  {
672
725
  style: [variantStyles[variant], { color: resolvedColor }, style],
@@ -677,32 +730,37 @@ function Text3({ variant = "body-md", color, style, children, ...props }) {
677
730
  );
678
731
  }
679
732
  var webInputResetStyle = Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
680
- function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, ...props }) {
733
+ function Input({ label, error, hint, disabled, prefix, suffix, prefixStyle, suffixStyle, prefixIcon, suffixIcon, prefixIconColor, suffixIconColor, type = "text", containerStyle, inputWrapperStyle, style, onFocus, onBlur, secureTextEntry, editable, ...props }) {
681
734
  const { colors } = useTheme();
682
735
  const [focused, setFocused] = useState(false);
683
736
  const [showPassword, setShowPassword] = useState(false);
737
+ const focusAnim = useRef(new Animated.Value(0)).current;
738
+ const isDisabled = disabled || editable === false;
684
739
  const isPassword = type === "password";
685
740
  const effectiveSecure = isPassword ? !showPassword : secureTextEntry;
686
741
  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;
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(
689
- View,
742
+ const effectiveSuffix = isPassword && !suffix && !suffixIcon ? /* @__PURE__ */ React26.createElement(TouchableOpacity, { onPress: () => setShowPassword(!showPassword), style: styles4.passwordToggle, activeOpacity: 0.6 }, /* @__PURE__ */ React26.createElement(AntDesign$1, { name: showPassword ? "eye" : "eye-invisible", size: 20, color: colors.foregroundMuted })) : suffixIcon ? renderIcon(suffixIcon, 20, suffixIconColor ?? colors.foregroundMuted) : suffix;
743
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles4.container, isDisabled && styles4.containerDisabled, containerStyle] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26.createElement(
744
+ Animated.View,
690
745
  {
691
746
  style: [
692
- styles3.inputWrapper,
747
+ styles4.inputWrapper,
693
748
  {
694
- borderColor: error ? colors.destructive : focused ? colors.primary : colors.border,
695
- backgroundColor: colors.background
749
+ borderColor: error ? colors.destructive : focusAnim.interpolate({
750
+ inputRange: [0, 1],
751
+ outputRange: [colors.border, colors.primary]
752
+ }),
753
+ backgroundColor: isDisabled ? colors.surface : colors.background
696
754
  },
697
755
  inputWrapperStyle
698
756
  ]
699
757
  },
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,
701
- /* @__PURE__ */ React25.createElement(
758
+ effectivePrefix ? typeof effectivePrefix === "string" ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.prefixText, { color: colors.foregroundMuted }, prefixStyle], allowFontScaling: true }, effectivePrefix) : /* @__PURE__ */ React26.createElement(View, { style: styles4.prefixContainer }, effectivePrefix) : null,
759
+ /* @__PURE__ */ React26.createElement(
702
760
  TextInput,
703
761
  {
704
762
  style: [
705
- styles3.input,
763
+ styles4.input,
706
764
  {
707
765
  color: colors.foreground
708
766
  },
@@ -711,25 +769,31 @@ function Input({ label, error, hint, prefix, suffix, prefixStyle, suffixStyle, p
711
769
  ],
712
770
  onFocus: (e) => {
713
771
  setFocused(true);
772
+ Animated.timing(focusAnim, { toValue: 1, duration: 120, easing: Easing$1.out(Easing$1.ease), useNativeDriver: false }).start();
714
773
  onFocus?.(e);
715
774
  },
716
775
  onBlur: (e) => {
717
776
  setFocused(false);
777
+ Animated.timing(focusAnim, { toValue: 0, duration: 80, easing: Easing$1.out(Easing$1.ease), useNativeDriver: false }).start();
718
778
  onBlur?.(e);
719
779
  },
720
780
  placeholderTextColor: colors.foregroundMuted,
721
781
  allowFontScaling: true,
722
782
  secureTextEntry: effectiveSecure,
783
+ editable: isDisabled ? false : editable,
723
784
  ...props
724
785
  }
725
786
  ),
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);
787
+ effectiveSuffix ? typeof effectiveSuffix === "string" ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.suffixText, { color: colors.foregroundMuted }, suffixStyle], allowFontScaling: true }, effectiveSuffix) : /* @__PURE__ */ React26.createElement(View, { style: styles4.suffixContainer }, effectiveSuffix) : null
788
+ ), error ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React26.createElement(Text, { style: [styles4.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
728
789
  }
729
- var styles3 = StyleSheet.create({
790
+ var styles4 = StyleSheet.create({
730
791
  container: {
731
792
  gap: vs(8)
732
793
  },
794
+ containerDisabled: {
795
+ opacity: 0.6
796
+ },
733
797
  label: {
734
798
  fontFamily: "Poppins-Medium",
735
799
  fontSize: ms(14)
@@ -817,9 +881,9 @@ function Badge({ label, children, variant = "default", size = "md", icon, iconNa
817
881
  }[variant];
818
882
  const effectiveIcon = iconName ? renderIcon(iconName, sizeIconSize[size], iconColor ?? textColor) : icon;
819
883
  const content = children ?? label;
820
- return /* @__PURE__ */ React25.createElement(View, { style: [styles4.container, containerStyle, sizePadding[size], { gap: sizeIconGap[size] }, style] }, effectiveIcon, typeof content === "string" ? /* @__PURE__ */ React25.createElement(Text, { style: [styles4.label, { color: textColor }, sizeFontSize[size]], allowFontScaling: true }, content) : content);
884
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles5.container, containerStyle, sizePadding[size], { gap: sizeIconGap[size] }, style] }, effectiveIcon, typeof content === "string" ? /* @__PURE__ */ React26.createElement(Text, { style: [styles5.label, { color: textColor }, sizeFontSize[size]], allowFontScaling: true }, content) : content);
821
885
  }
822
- var styles4 = StyleSheet.create({
886
+ var styles5 = StyleSheet.create({
823
887
  container: {
824
888
  borderRadius: 9999,
825
889
  alignSelf: "flex-start",
@@ -839,8 +903,9 @@ function Card({ children, variant = "elevated", onPress, style }) {
839
903
  Animated.spring(scale2, {
840
904
  toValue: 0.98,
841
905
  useNativeDriver: nativeDriver3,
842
- speed: 40,
843
- bounciness: 0
906
+ stiffness: 400,
907
+ damping: 30,
908
+ mass: 1
844
909
  }).start();
845
910
  };
846
911
  const handlePressOut = () => {
@@ -848,8 +913,9 @@ function Card({ children, variant = "elevated", onPress, style }) {
848
913
  Animated.spring(scale2, {
849
914
  toValue: 1,
850
915
  useNativeDriver: nativeDriver3,
851
- speed: 40,
852
- bounciness: 4
916
+ stiffness: 250,
917
+ damping: 24,
918
+ mass: 1
853
919
  }).start();
854
920
  };
855
921
  const handlePress = () => {
@@ -862,10 +928,10 @@ function Card({ children, variant = "elevated", onPress, style }) {
862
928
  backgroundColor: colors.card,
863
929
  borderColor: colors.border,
864
930
  shadowColor: "#000",
865
- shadowOffset: { width: 0, height: 4 },
866
- shadowOpacity: 0.06,
867
- shadowRadius: 12,
868
- elevation: 3
931
+ shadowOffset: { width: 0, height: 6 },
932
+ shadowOpacity: 0.1,
933
+ shadowRadius: 16,
934
+ elevation: 4
869
935
  },
870
936
  outlined: {
871
937
  backgroundColor: colors.card,
@@ -880,9 +946,9 @@ function Card({ children, variant = "elevated", onPress, style }) {
880
946
  elevation: 0
881
947
  }
882
948
  }[variant];
883
- const cardContent = /* @__PURE__ */ React25.createElement(View, { style: [styles5.card, variantStyle, style] }, children);
949
+ const cardContent = /* @__PURE__ */ React26.createElement(View, { style: [styles6.card, variantStyle, style] }, children);
884
950
  if (onPress) {
885
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
951
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26.createElement(
886
952
  TouchableOpacity,
887
953
  {
888
954
  onPress: handlePress,
@@ -897,26 +963,26 @@ function Card({ children, variant = "elevated", onPress, style }) {
897
963
  return cardContent;
898
964
  }
899
965
  function CardHeader({ children, style }) {
900
- return /* @__PURE__ */ React25.createElement(View, { style: [styles5.header, style] }, children);
966
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles6.header, style] }, children);
901
967
  }
902
968
  function CardTitle({ children, style }) {
903
969
  const { colors } = useTheme();
904
- return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
970
+ return /* @__PURE__ */ React26.createElement(Text, { style: [styles6.title, { color: colors.foreground }, style], allowFontScaling: true }, children);
905
971
  }
906
972
  function CardDescription({ children, style }) {
907
973
  const { colors } = useTheme();
908
- return /* @__PURE__ */ React25.createElement(Text, { style: [styles5.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
974
+ return /* @__PURE__ */ React26.createElement(Text, { style: [styles6.description, { color: colors.foregroundMuted }, style], allowFontScaling: true }, children);
909
975
  }
910
976
  function CardContent({ children, style }) {
911
- return /* @__PURE__ */ React25.createElement(View, { style: [styles5.content, style] }, children);
977
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles6.content, style] }, children);
912
978
  }
913
979
  function CardFooter({ children, style }) {
914
- return /* @__PURE__ */ React25.createElement(View, { style: [styles5.footer, style] }, children);
980
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles6.footer, style] }, children);
915
981
  }
916
- var styles5 = StyleSheet.create({
982
+ var styles6 = StyleSheet.create({
917
983
  card: {
918
- borderRadius: 14,
919
- // RADIUS.md — Airbnb property card spec
984
+ borderRadius: RADIUS.md,
985
+ // 14px — Airbnb property card spec
920
986
  borderWidth: 1
921
987
  },
922
988
  header: {
@@ -948,25 +1014,27 @@ var styles5 = StyleSheet.create({
948
1014
  });
949
1015
  function Separator({ orientation = "horizontal", style }) {
950
1016
  const { colors } = useTheme();
951
- return /* @__PURE__ */ React25.createElement(
1017
+ return /* @__PURE__ */ React26.createElement(
952
1018
  View,
953
1019
  {
954
1020
  style: [
955
- orientation === "horizontal" ? styles6.horizontal : styles6.vertical,
1021
+ orientation === "horizontal" ? styles7.horizontal : styles7.vertical,
956
1022
  { backgroundColor: colors.border },
957
1023
  style
958
1024
  ]
959
1025
  }
960
1026
  );
961
1027
  }
962
- var styles6 = StyleSheet.create({
1028
+ var styles7 = StyleSheet.create({
963
1029
  horizontal: {
964
1030
  height: 1,
965
- width: "100%"
1031
+ width: "100%",
1032
+ opacity: 0.7
966
1033
  },
967
1034
  vertical: {
968
1035
  width: 1,
969
- height: "100%"
1036
+ height: "100%",
1037
+ opacity: 0.7
970
1038
  }
971
1039
  });
972
1040
  var sizeMap2 = {
@@ -982,18 +1050,18 @@ var labelFontSize = {
982
1050
  function Spinner({ size = "md", color, label, ...props }) {
983
1051
  const { colors } = useTheme();
984
1052
  if (label) {
985
- return /* @__PURE__ */ React25.createElement(View, { style: styles7.wrapper }, /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React25.createElement(
1053
+ return /* @__PURE__ */ React26.createElement(View, { style: styles8.wrapper }, /* @__PURE__ */ React26.createElement(ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props }), /* @__PURE__ */ React26.createElement(
986
1054
  Text,
987
1055
  {
988
- style: [styles7.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
1056
+ style: [styles8.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
989
1057
  allowFontScaling: true
990
1058
  },
991
1059
  label
992
1060
  ));
993
1061
  }
994
- return /* @__PURE__ */ React25.createElement(ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props });
1062
+ return /* @__PURE__ */ React26.createElement(ActivityIndicator, { size: sizeMap2[size], color: color ?? colors.primary, ...props });
995
1063
  }
996
- var styles7 = StyleSheet.create({
1064
+ var styles8 = StyleSheet.create({
997
1065
  wrapper: {
998
1066
  alignItems: "center",
999
1067
  gap: vs(6)
@@ -1029,17 +1097,17 @@ function Skeleton({
1029
1097
  const resolvedWidth = preset === "circle" ? s(diameter) : preset === "text" ? "60%" : width;
1030
1098
  const resolvedHeight = preset === "circle" ? s(diameter) : preset === "text" ? 14 : height;
1031
1099
  const resolvedRadius = preset === "circle" ? 9999 : preset === "text" ? 4 : borderRadius;
1032
- return /* @__PURE__ */ React25.createElement(
1100
+ return /* @__PURE__ */ React26.createElement(
1033
1101
  View,
1034
1102
  {
1035
1103
  style: [
1036
- styles8.base,
1104
+ styles9.base,
1037
1105
  { width: resolvedWidth, height: resolvedHeight, borderRadius: resolvedRadius, backgroundColor: colors.surface },
1038
1106
  style
1039
1107
  ],
1040
1108
  onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
1041
1109
  },
1042
- /* @__PURE__ */ React25.createElement(Animated.View, { style: [StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React25.createElement(
1110
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: [StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React26.createElement(
1043
1111
  LinearGradient,
1044
1112
  {
1045
1113
  colors: ["transparent", shimmerHighlight, "transparent"],
@@ -1050,7 +1118,7 @@ function Skeleton({
1050
1118
  ))
1051
1119
  );
1052
1120
  }
1053
- var styles8 = StyleSheet.create({
1121
+ var styles9 = StyleSheet.create({
1054
1122
  base: {
1055
1123
  overflow: "hidden"
1056
1124
  }
@@ -1073,12 +1141,22 @@ var statusSizeMap = {
1073
1141
  lg: 13,
1074
1142
  xl: 16
1075
1143
  };
1076
- function Avatar({ src, fallback, size = "md", status, style }) {
1144
+ function getInitials(fallback, fallbackText) {
1145
+ if (fallback) return fallback.slice(0, 2).toUpperCase();
1146
+ if (fallbackText) {
1147
+ const words = fallbackText.trim().split(/\s+/);
1148
+ if (words.length === 1) return words[0].slice(0, 2).toUpperCase();
1149
+ return (words[0][0] + words[words.length - 1][0]).toUpperCase();
1150
+ }
1151
+ return "?";
1152
+ }
1153
+ function Avatar({ src, fallback, fallbackText, size = "md", status, style }) {
1077
1154
  const { colors } = useTheme();
1078
1155
  const [imageError, setImageError] = useState(false);
1079
- const dimension = sizeMap3[size];
1156
+ const dimension = typeof size === "number" ? size : sizeMap3[size];
1157
+ const fontSize = typeof size === "number" ? size * 0.38 : fontSizeMap[size];
1080
1158
  const showFallback = !src || imageError;
1081
- const statusSize = statusSizeMap[size];
1159
+ const statusSize = typeof size === "number" ? size * 0.25 : statusSizeMap[size];
1082
1160
  const statusColor = {
1083
1161
  online: "#22c55e",
1084
1162
  offline: "transparent",
@@ -1092,25 +1170,25 @@ function Avatar({ src, fallback, size = "md", status, style }) {
1092
1170
  backgroundColor: colors.surface,
1093
1171
  overflow: "hidden"
1094
1172
  };
1095
- return /* @__PURE__ */ React25.createElement(View, { style: [styles9.wrapper, style] }, /* @__PURE__ */ React25.createElement(View, { style: [styles9.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React25.createElement(
1173
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles10.wrapper, style] }, /* @__PURE__ */ React26.createElement(View, { style: [styles10.base, containerStyle] }, !showFallback ? /* @__PURE__ */ React26.createElement(
1096
1174
  Image,
1097
1175
  {
1098
1176
  source: { uri: src },
1099
1177
  style: { width: dimension, height: dimension },
1100
1178
  onError: () => setImageError(true)
1101
1179
  }
1102
- ) : /* @__PURE__ */ React25.createElement(
1180
+ ) : /* @__PURE__ */ React26.createElement(
1103
1181
  Text,
1104
1182
  {
1105
- style: [styles9.fallback, { color: colors.foregroundMuted, fontSize: fontSizeMap[size] }],
1183
+ style: [styles10.fallback, { color: colors.foregroundMuted, fontSize }],
1106
1184
  allowFontScaling: true
1107
1185
  },
1108
- fallback?.slice(0, 2).toUpperCase() ?? "?"
1109
- )), status && /* @__PURE__ */ React25.createElement(
1186
+ getInitials(fallback, fallbackText)
1187
+ )), status && /* @__PURE__ */ React26.createElement(
1110
1188
  View,
1111
1189
  {
1112
1190
  style: [
1113
- styles9.statusDot,
1191
+ styles10.statusDot,
1114
1192
  {
1115
1193
  width: statusSize,
1116
1194
  height: statusSize,
@@ -1123,7 +1201,7 @@ function Avatar({ src, fallback, size = "md", status, style }) {
1123
1201
  }
1124
1202
  ));
1125
1203
  }
1126
- var styles9 = StyleSheet.create({
1204
+ var styles10 = StyleSheet.create({
1127
1205
  wrapper: {
1128
1206
  alignSelf: "flex-start",
1129
1207
  position: "relative"
@@ -1143,24 +1221,19 @@ var styles9 = StyleSheet.create({
1143
1221
  });
1144
1222
  function AlertBanner({ title, description, variant = "default", icon, iconName, iconColor, style }) {
1145
1223
  const { colors } = useTheme();
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
1224
  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));
1225
+ const defaultIcon = variant === "success" ? /* @__PURE__ */ React26.createElement(FontAwesome5$1, { name: "check-circle", size: ms(16), color: accentColor }) : variant === "destructive" ? /* @__PURE__ */ React26.createElement(MaterialIcons$1, { name: "error-outline", size: ms(17), color: accentColor }) : variant === "warning" ? /* @__PURE__ */ React26.createElement(MaterialIcons$1, { name: "warning-amber", size: ms(17), color: accentColor }) : /* @__PURE__ */ React26.createElement(Entypo$1, { name: "info-with-circle", size: ms(16), color: accentColor });
1226
+ const effectiveIcon = iconName ? renderIcon(iconName, ms(16), iconColor ?? accentColor) : icon ?? defaultIcon;
1227
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles11.container, { backgroundColor: colors.card }, style] }, /* @__PURE__ */ React26.createElement(View, { style: styles11.iconSlot }, effectiveIcon), /* @__PURE__ */ React26.createElement(View, { style: styles11.content }, /* @__PURE__ */ React26.createElement(Text, { style: [styles11.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React26.createElement(Text, { style: [styles11.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null));
1154
1228
  }
1155
- var styles10 = StyleSheet.create({
1229
+ var styles11 = StyleSheet.create({
1156
1230
  container: {
1157
1231
  flexDirection: "row",
1158
1232
  alignItems: "flex-start",
1159
- borderWidth: 0.5,
1160
- borderRadius: 10,
1161
- paddingHorizontal: s(12),
1162
- paddingVertical: vs(10),
1163
- gap: s(10)
1233
+ borderRadius: RADIUS.lg,
1234
+ gap: s(8),
1235
+ paddingVertical: vs(8),
1236
+ paddingHorizontal: s(10)
1164
1237
  },
1165
1238
  iconSlot: {
1166
1239
  marginTop: vs(1)
@@ -1172,13 +1245,12 @@ var styles10 = StyleSheet.create({
1172
1245
  title: {
1173
1246
  fontFamily: "Poppins-Medium",
1174
1247
  fontSize: ms(13),
1175
- lineHeight: ms(18)
1248
+ lineHeight: ms(19)
1176
1249
  },
1177
1250
  description: {
1178
1251
  fontFamily: "Poppins-Regular",
1179
1252
  fontSize: ms(12),
1180
- lineHeight: ms(17),
1181
- opacity: 0.85
1253
+ lineHeight: ms(17)
1182
1254
  }
1183
1255
  });
1184
1256
  function Progress({ value = 0, max = 100, variant = "default", style }) {
@@ -1196,21 +1268,21 @@ function Progress({ value = 0, max = 100, variant = "default", style }) {
1196
1268
  }).start();
1197
1269
  }, [percent, trackWidth]);
1198
1270
  const indicatorColor = variant === "success" ? colors.success : variant === "warning" ? colors.warning : variant === "destructive" ? colors.destructive : colors.primary;
1199
- return /* @__PURE__ */ React25.createElement(
1271
+ return /* @__PURE__ */ React26.createElement(
1200
1272
  View,
1201
1273
  {
1202
- style: [styles11.track, { backgroundColor: colors.surface }, style],
1274
+ style: [styles12.track, { backgroundColor: colors.surface }, style],
1203
1275
  onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
1204
1276
  },
1205
- /* @__PURE__ */ React25.createElement(
1277
+ /* @__PURE__ */ React26.createElement(
1206
1278
  Animated.View,
1207
1279
  {
1208
- style: [styles11.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
1280
+ style: [styles12.indicator, { width: animatedWidth, backgroundColor: indicatorColor }]
1209
1281
  }
1210
1282
  )
1211
1283
  );
1212
1284
  }
1213
- var styles11 = StyleSheet.create({
1285
+ var styles12 = StyleSheet.create({
1214
1286
  track: {
1215
1287
  height: vs(8),
1216
1288
  borderRadius: 9999,
@@ -1222,72 +1294,71 @@ var styles11 = StyleSheet.create({
1222
1294
  borderRadius: 9999
1223
1295
  }
1224
1296
  });
1225
- function EmptyState({ icon, iconName, iconColor, title, description, action, size = "default", style }) {
1297
+ function EmptyState({ icon, iconName, iconColor, title, description, action, actionLabel, onAction, size = "default", style }) {
1226
1298
  const { colors } = useTheme();
1227
1299
  const isCompact = size === "compact";
1228
1300
  const effectiveIcon = iconName ? renderIcon(iconName, isCompact ? 32 : 48, iconColor ?? colors.foregroundMuted) : icon;
1229
- return /* @__PURE__ */ React25.createElement(
1301
+ return /* @__PURE__ */ React26.createElement(
1230
1302
  View,
1231
1303
  {
1232
1304
  style: [
1233
- styles12.container,
1234
- isCompact && styles12.containerCompact,
1305
+ styles13.container,
1306
+ isCompact && styles13.containerCompact,
1235
1307
  { borderColor: colors.border },
1236
1308
  style
1237
1309
  ]
1238
1310
  },
1239
- effectiveIcon ? /* @__PURE__ */ React25.createElement(
1311
+ effectiveIcon ? /* @__PURE__ */ React26.createElement(
1240
1312
  View,
1241
1313
  {
1242
1314
  style: [
1243
- styles12.iconWrapper,
1244
- isCompact && styles12.iconWrapperCompact,
1315
+ styles13.iconWrapper,
1316
+ isCompact && styles13.iconWrapperCompact,
1245
1317
  { backgroundColor: colors.surface }
1246
1318
  ]
1247
1319
  },
1248
1320
  effectiveIcon
1249
1321
  ) : null,
1250
- /* @__PURE__ */ React25.createElement(View, { style: styles12.textWrapper }, /* @__PURE__ */ React25.createElement(
1322
+ /* @__PURE__ */ React26.createElement(View, { style: styles13.textWrapper }, /* @__PURE__ */ React26.createElement(
1251
1323
  Text,
1252
1324
  {
1253
- style: [styles12.title, isCompact && styles12.titleCompact, { color: colors.foreground }],
1325
+ style: [styles13.title, isCompact && styles13.titleCompact, { color: colors.foreground }],
1254
1326
  allowFontScaling: true
1255
1327
  },
1256
1328
  title
1257
- ), description && !isCompact ? /* @__PURE__ */ React25.createElement(Text, { style: [styles12.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
1258
- action && !isCompact ? /* @__PURE__ */ React25.createElement(View, { style: styles12.action }, action) : null
1329
+ ), description && !isCompact ? /* @__PURE__ */ React26.createElement(Text, { style: [styles13.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null),
1330
+ !isCompact && (action ? /* @__PURE__ */ React26.createElement(View, { style: styles13.action }, action) : actionLabel && onAction ? /* @__PURE__ */ React26.createElement(View, { style: styles13.action }, /* @__PURE__ */ React26.createElement(Button, { label: actionLabel, variant: "primary", onPress: onAction })) : null)
1259
1331
  );
1260
1332
  }
1261
- var styles12 = StyleSheet.create({
1333
+ var styles13 = StyleSheet.create({
1262
1334
  container: {
1263
1335
  alignItems: "center",
1264
1336
  justifyContent: "center",
1265
1337
  borderWidth: 1,
1266
1338
  borderStyle: "dashed",
1267
- borderRadius: ms(12),
1268
- padding: s(32),
1269
- gap: vs(16)
1270
- },
1271
- containerCompact: {
1272
- padding: s(20),
1273
- gap: vs(10)
1339
+ borderRadius: ms(12)
1274
1340
  },
1341
+ containerCompact: {},
1275
1342
  iconWrapper: {
1276
1343
  width: s(80),
1277
1344
  height: s(80),
1278
1345
  borderRadius: ms(20),
1279
1346
  alignItems: "center",
1280
- justifyContent: "center"
1347
+ justifyContent: "center",
1348
+ marginTop: s(32)
1281
1349
  },
1282
1350
  iconWrapperCompact: {
1283
1351
  width: s(56),
1284
1352
  height: s(56),
1285
- borderRadius: ms(14)
1353
+ borderRadius: ms(14),
1354
+ marginTop: s(20)
1286
1355
  },
1287
1356
  textWrapper: {
1288
1357
  alignItems: "center",
1289
1358
  gap: vs(8),
1290
- maxWidth: s(320)
1359
+ maxWidth: s(320),
1360
+ paddingHorizontal: s(32),
1361
+ marginTop: vs(16)
1291
1362
  },
1292
1363
  title: {
1293
1364
  fontFamily: "Poppins-Medium",
@@ -1295,7 +1366,8 @@ var styles12 = StyleSheet.create({
1295
1366
  textAlign: "center"
1296
1367
  },
1297
1368
  titleCompact: {
1298
- fontSize: ms(15)
1369
+ fontSize: ms(15),
1370
+ marginTop: vs(10)
1299
1371
  },
1300
1372
  description: {
1301
1373
  fontFamily: "Poppins-Regular",
@@ -1304,7 +1376,9 @@ var styles12 = StyleSheet.create({
1304
1376
  textAlign: "center"
1305
1377
  },
1306
1378
  action: {
1307
- marginTop: vs(8)
1379
+ marginTop: vs(8),
1380
+ marginBottom: s(32),
1381
+ paddingHorizontal: s(32)
1308
1382
  }
1309
1383
  });
1310
1384
  var webInputResetStyle2 = Platform.OS === "web" ? { outlineStyle: "none", outlineWidth: 0, outlineColor: "transparent", boxShadow: "none" } : {};
@@ -1313,6 +1387,9 @@ function Textarea({
1313
1387
  error,
1314
1388
  hint,
1315
1389
  rows = 4,
1390
+ prefixIcon,
1391
+ prefixIconNode,
1392
+ prefixIconColor,
1316
1393
  containerStyle,
1317
1394
  style,
1318
1395
  onFocus,
@@ -1321,57 +1398,83 @@ function Textarea({
1321
1398
  }) {
1322
1399
  const { colors } = useTheme();
1323
1400
  const [focused, setFocused] = useState(false);
1324
- return /* @__PURE__ */ React25.createElement(View, { style: [styles13.container, containerStyle] }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles13.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25.createElement(
1325
- TextInput,
1401
+ const resolvedPrefixIcon = prefixIcon ? renderIcon(prefixIcon, ms(16), prefixIconColor ?? colors.foregroundMuted) : prefixIconNode;
1402
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles14.container, containerStyle] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles14.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React26.createElement(
1403
+ View,
1326
1404
  {
1327
- multiline: true,
1328
- numberOfLines: rows,
1329
- textAlignVertical: "top",
1330
1405
  style: [
1331
- styles13.input,
1406
+ styles14.inputWrapper,
1332
1407
  {
1333
1408
  borderColor: error ? colors.destructive : focused ? colors.ring ?? colors.primary : colors.border,
1334
- color: colors.foreground,
1335
- backgroundColor: colors.background,
1336
- minHeight: rows * vs(30)
1409
+ backgroundColor: colors.background
1410
+ }
1411
+ ]
1412
+ },
1413
+ resolvedPrefixIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles14.prefixIcon }, resolvedPrefixIcon) : null,
1414
+ /* @__PURE__ */ React26.createElement(
1415
+ TextInput,
1416
+ {
1417
+ multiline: true,
1418
+ numberOfLines: rows,
1419
+ textAlignVertical: "top",
1420
+ style: [
1421
+ styles14.input,
1422
+ {
1423
+ color: colors.foreground,
1424
+ minHeight: rows * vs(30)
1425
+ },
1426
+ webInputResetStyle2,
1427
+ style
1428
+ ],
1429
+ onFocus: (e) => {
1430
+ setFocused(true);
1431
+ onFocus?.(e);
1337
1432
  },
1338
- webInputResetStyle2,
1339
- style
1340
- ],
1341
- onFocus: (e) => {
1342
- setFocused(true);
1343
- onFocus?.(e);
1344
- },
1345
- onBlur: (e) => {
1346
- setFocused(false);
1347
- onBlur?.(e);
1348
- },
1349
- placeholderTextColor: colors.foregroundMuted,
1350
- allowFontScaling: true,
1351
- ...props
1352
- }
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);
1433
+ onBlur: (e) => {
1434
+ setFocused(false);
1435
+ onBlur?.(e);
1436
+ },
1437
+ placeholderTextColor: colors.foregroundMuted,
1438
+ allowFontScaling: true,
1439
+ ...props
1440
+ }
1441
+ )
1442
+ ), error ? /* @__PURE__ */ React26.createElement(Text, { style: [styles14.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React26.createElement(Text, { style: [styles14.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null);
1354
1443
  }
1355
- var styles13 = StyleSheet.create({
1444
+ var styles14 = StyleSheet.create({
1356
1445
  container: {
1357
- gap: vs(8)
1446
+ gap: vs(4)
1358
1447
  },
1359
1448
  label: {
1360
1449
  fontFamily: "Poppins-Medium",
1361
- fontSize: ms(13)
1450
+ fontSize: ms(13),
1451
+ lineHeight: vs(18),
1452
+ marginBottom: vs(2)
1362
1453
  },
1363
- input: {
1364
- fontFamily: "Poppins-Regular",
1365
- borderWidth: 2,
1366
- borderRadius: ms(8),
1454
+ inputWrapper: {
1455
+ borderWidth: 1,
1456
+ borderRadius: 8,
1367
1457
  paddingHorizontal: s(14),
1368
1458
  paddingVertical: vs(11),
1369
- fontSize: ms(15),
1370
- includeFontPadding: false
1459
+ gap: s(8)
1460
+ },
1461
+ prefixIcon: {
1462
+ alignItems: "flex-start",
1463
+ justifyContent: "flex-start",
1464
+ paddingTop: vs(2)
1465
+ },
1466
+ input: {
1467
+ fontFamily: "Poppins-Regular",
1468
+ fontSize: ms(14),
1469
+ lineHeight: vs(22),
1470
+ padding: 0,
1471
+ margin: 0
1371
1472
  },
1372
1473
  helperText: {
1373
1474
  fontFamily: "Poppins-Regular",
1374
- fontSize: ms(13)
1475
+ fontSize: ms(12),
1476
+ lineHeight: vs(16),
1477
+ marginTop: vs(4)
1375
1478
  }
1376
1479
  });
1377
1480
  var nativeDriver4 = Platform.OS !== "web";
@@ -1415,10 +1518,10 @@ function Checkbox({
1415
1518
  const handlePressOut = () => {
1416
1519
  Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver4, speed: 40, bounciness: 0 }).start();
1417
1520
  };
1418
- return /* @__PURE__ */ React25.createElement(
1521
+ return /* @__PURE__ */ React26.createElement(
1419
1522
  TouchableOpacity,
1420
1523
  {
1421
- style: [styles14.row, style],
1524
+ style: [styles15.row, style],
1422
1525
  onPress: () => {
1423
1526
  selectionAsync();
1424
1527
  onCheckedChange?.(!checked);
@@ -1429,11 +1532,11 @@ function Checkbox({
1429
1532
  activeOpacity: 1,
1430
1533
  touchSoundDisabled: true
1431
1534
  },
1432
- /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
1535
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26.createElement(
1433
1536
  Animated.View,
1434
1537
  {
1435
1538
  style: [
1436
- styles14.box,
1539
+ styles15.box,
1437
1540
  {
1438
1541
  borderColor,
1439
1542
  backgroundColor,
@@ -1441,19 +1544,19 @@ function Checkbox({
1441
1544
  }
1442
1545
  ]
1443
1546
  },
1444
- /* @__PURE__ */ React25.createElement(Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React25.createElement(View, { style: [styles14.checkmark, { borderColor: colors.primaryForeground }] }))
1547
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: { opacity: checkOpacity } }, /* @__PURE__ */ React26.createElement(View, { style: [styles15.checkmark, { borderColor: colors.primaryForeground }] }))
1445
1548
  )),
1446
- label ? /* @__PURE__ */ React25.createElement(
1549
+ label ? /* @__PURE__ */ React26.createElement(
1447
1550
  Text,
1448
1551
  {
1449
- style: [styles14.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
1552
+ style: [styles15.label, { color: disabled ? colors.foregroundMuted : colors.foreground }],
1450
1553
  allowFontScaling: true
1451
1554
  },
1452
1555
  label
1453
1556
  ) : null
1454
1557
  );
1455
1558
  }
1456
- var styles14 = StyleSheet.create({
1559
+ var styles15 = StyleSheet.create({
1457
1560
  row: {
1458
1561
  flexDirection: "row",
1459
1562
  alignItems: "center",
@@ -1521,7 +1624,7 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
1521
1624
  inputRange: [0, 1],
1522
1625
  outputRange: [colors.surface, colors.primary]
1523
1626
  });
1524
- return /* @__PURE__ */ React25.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React25.createElement(
1627
+ return /* @__PURE__ */ React26.createElement(View, { style: [{ opacity: disabled ? 0.45 : 1 }, style] }, /* @__PURE__ */ React26.createElement(
1525
1628
  TouchableOpacity,
1526
1629
  {
1527
1630
  onPress: () => {
@@ -1531,22 +1634,22 @@ function Switch({ checked = false, onCheckedChange, disabled, style }) {
1531
1634
  disabled,
1532
1635
  activeOpacity: 0.8,
1533
1636
  touchSoundDisabled: true,
1534
- style: styles15.wrapper
1637
+ style: styles16.wrapper
1535
1638
  },
1536
- /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles15.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React25.createElement(
1639
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: [styles16.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React26.createElement(
1537
1640
  Animated.View,
1538
1641
  {
1539
1642
  style: [
1540
- styles15.thumb,
1643
+ styles16.thumb,
1541
1644
  { backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
1542
1645
  ]
1543
1646
  },
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 }))
1647
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: [styles16.iconWrapper, { opacity: checkOpacity }] }, /* @__PURE__ */ React26.createElement(Feather$1, { name: "check", size: ICON_SIZE, color: colors.primary })),
1648
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: [styles16.iconWrapper, { opacity: crossOpacity }] }, /* @__PURE__ */ React26.createElement(Feather$1, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
1546
1649
  ))
1547
1650
  ));
1548
1651
  }
1549
- var styles15 = StyleSheet.create({
1652
+ var styles16 = StyleSheet.create({
1550
1653
  wrapper: {},
1551
1654
  track: {
1552
1655
  width: TRACK_WIDTH,
@@ -1604,16 +1707,16 @@ function Toggle({
1604
1707
  Animated.timing(pressAnim, {
1605
1708
  toValue: pressed ? 1 : 0,
1606
1709
  duration: 150,
1607
- easing: Easing.out(Easing.ease),
1710
+ easing: Easing$1.out(Easing$1.ease),
1608
1711
  useNativeDriver: false
1609
1712
  }).start();
1610
1713
  }, [pressed, pressAnim]);
1611
1714
  const handlePressIn = () => {
1612
1715
  if (disabled) return;
1613
- Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver6, speed: 40, bounciness: 0 }).start();
1716
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver6, stiffness: 600, damping: 35, mass: 0.8 }).start();
1614
1717
  };
1615
1718
  const handlePressOut = () => {
1616
- Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver6, speed: 40, bounciness: 4 }).start();
1719
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver6, stiffness: 280, damping: 22, mass: 0.8 }).start();
1617
1720
  };
1618
1721
  const borderColor = pressAnim.interpolate({
1619
1722
  inputRange: [0, 1],
@@ -1635,17 +1738,17 @@ function Toggle({
1635
1738
  return prop;
1636
1739
  };
1637
1740
  if (pressed) {
1638
- if (activeIconName) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, renderIcon(activeIconName, iconSize, activeIconColor ?? colors.primary));
1741
+ if (activeIconName) return /* @__PURE__ */ React26.createElement(React26.Fragment, null, renderIcon(activeIconName, iconSize, activeIconColor ?? colors.primary));
1639
1742
  const active = renderProp(activeIcon);
1640
- if (active) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, active);
1641
- return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "check-circle", size: iconSize, color: colors.primary });
1743
+ if (active) return /* @__PURE__ */ React26.createElement(React26.Fragment, null, active);
1744
+ return /* @__PURE__ */ React26.createElement(FontAwesome5$1, { name: "check-circle", size: iconSize, color: colors.primary });
1642
1745
  }
1643
- if (iconName) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
1746
+ if (iconName) return /* @__PURE__ */ React26.createElement(React26.Fragment, null, renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted));
1644
1747
  const custom = renderProp(icon);
1645
- if (custom) return /* @__PURE__ */ React25.createElement(React25.Fragment, null, custom);
1646
- return /* @__PURE__ */ React25.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.foregroundMuted });
1748
+ if (custom) return /* @__PURE__ */ React26.createElement(React26.Fragment, null, custom);
1749
+ return /* @__PURE__ */ React26.createElement(FontAwesome5$1, { name: "circle", size: iconSize, color: colors.foregroundMuted });
1647
1750
  };
1648
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles16.disabled, style] }, /* @__PURE__ */ React25.createElement(
1751
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles17.disabled, style] }, /* @__PURE__ */ React26.createElement(
1649
1752
  TouchableOpacity,
1650
1753
  {
1651
1754
  onPress: () => {
@@ -1659,20 +1762,20 @@ function Toggle({
1659
1762
  touchSoundDisabled: true,
1660
1763
  ...props
1661
1764
  },
1662
- /* @__PURE__ */ React25.createElement(
1765
+ /* @__PURE__ */ React26.createElement(
1663
1766
  Animated.View,
1664
1767
  {
1665
1768
  style: [
1666
- styles16.base,
1769
+ styles17.base,
1667
1770
  sizeStyles[size],
1668
1771
  { borderColor, backgroundColor, borderWidth: 2 }
1669
1772
  ]
1670
1773
  },
1671
- /* @__PURE__ */ React25.createElement(View, { style: styles16.inner }, /* @__PURE__ */ React25.createElement(LeftIcon, null), label ? /* @__PURE__ */ React25.createElement(Animated.Text, { style: [styles16.label, { color: textColor }], allowFontScaling: true }, label) : null)
1774
+ /* @__PURE__ */ React26.createElement(View, { style: styles17.inner }, /* @__PURE__ */ React26.createElement(LeftIcon, null), label ? /* @__PURE__ */ React26.createElement(Animated.Text, { style: [styles17.label, { color: textColor }], allowFontScaling: true }, label) : null)
1672
1775
  )
1673
1776
  ));
1674
1777
  }
1675
- var styles16 = StyleSheet.create({
1778
+ var styles17 = StyleSheet.create({
1676
1779
  base: {
1677
1780
  borderRadius: ms(8)
1678
1781
  },
@@ -1705,10 +1808,10 @@ function RadioItem({
1705
1808
  const handlePressOut = () => {
1706
1809
  Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver7, speed: 40, bounciness: 4 }).start();
1707
1810
  };
1708
- return /* @__PURE__ */ React25.createElement(
1811
+ return /* @__PURE__ */ React26.createElement(
1709
1812
  TouchableOpacity,
1710
1813
  {
1711
- style: styles17.row,
1814
+ style: styles18.row,
1712
1815
  onPress: () => {
1713
1816
  if (!option.disabled) {
1714
1817
  selectionAsync();
@@ -1721,11 +1824,11 @@ function RadioItem({
1721
1824
  touchSoundDisabled: true,
1722
1825
  disabled: option.disabled
1723
1826
  },
1724
- /* @__PURE__ */ React25.createElement(
1827
+ /* @__PURE__ */ React26.createElement(
1725
1828
  Animated.View,
1726
1829
  {
1727
1830
  style: [
1728
- styles17.radio,
1831
+ styles18.radio,
1729
1832
  {
1730
1833
  borderColor: selected ? colors.primary : colors.border,
1731
1834
  opacity: option.disabled ? 0.45 : 1,
@@ -1733,13 +1836,13 @@ function RadioItem({
1733
1836
  }
1734
1837
  ]
1735
1838
  },
1736
- selected ? /* @__PURE__ */ React25.createElement(View, { style: [styles17.dot, { backgroundColor: colors.primary }] }) : null
1839
+ selected ? /* @__PURE__ */ React26.createElement(View, { style: [styles18.dot, { backgroundColor: colors.primary }] }) : null
1737
1840
  ),
1738
- /* @__PURE__ */ React25.createElement(
1841
+ /* @__PURE__ */ React26.createElement(
1739
1842
  Text,
1740
1843
  {
1741
1844
  style: [
1742
- styles17.label,
1845
+ styles18.label,
1743
1846
  { color: option.disabled ? colors.foregroundMuted : colors.foreground }
1744
1847
  ],
1745
1848
  allowFontScaling: true
@@ -1755,7 +1858,7 @@ function RadioGroup({
1755
1858
  orientation = "vertical",
1756
1859
  style
1757
1860
  }) {
1758
- return /* @__PURE__ */ React25.createElement(View, { style: [styles17.container, orientation === "horizontal" && styles17.horizontal, style] }, options.map((option) => /* @__PURE__ */ React25.createElement(
1861
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles18.container, orientation === "horizontal" && styles18.horizontal, style] }, options.map((option) => /* @__PURE__ */ React26.createElement(
1759
1862
  RadioItem,
1760
1863
  {
1761
1864
  key: option.value,
@@ -1765,7 +1868,7 @@ function RadioGroup({
1765
1868
  }
1766
1869
  )));
1767
1870
  }
1768
- var styles17 = StyleSheet.create({
1871
+ var styles18 = StyleSheet.create({
1769
1872
  container: {
1770
1873
  gap: vs(12)
1771
1874
  },
@@ -1808,18 +1911,18 @@ function TabTrigger({
1808
1911
  const { colors } = useTheme();
1809
1912
  const scale2 = useRef(new Animated.Value(1)).current;
1810
1913
  const handlePressIn = () => {
1811
- Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver8, speed: 40, bounciness: 0 }).start();
1914
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver8, stiffness: 600, damping: 35, mass: 0.8 }).start();
1812
1915
  };
1813
1916
  const handlePressOut = () => {
1814
- Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, speed: 40, bounciness: 4 }).start();
1917
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver8, stiffness: 280, damping: 22, mass: 0.8 }).start();
1815
1918
  };
1816
1919
  const isUnderline = variant === "underline";
1817
- return /* @__PURE__ */ React25.createElement(
1920
+ return /* @__PURE__ */ React26.createElement(
1818
1921
  TouchableOpacity,
1819
1922
  {
1820
1923
  style: [
1821
- styles18.trigger,
1822
- isUnderline && styles18.triggerUnderline,
1924
+ styles19.trigger,
1925
+ isUnderline && styles19.triggerUnderline,
1823
1926
  isUnderline && isActive && { borderBottomColor: colors.primary }
1824
1927
  ],
1825
1928
  onPress,
@@ -1829,13 +1932,13 @@ function TabTrigger({
1829
1932
  activeOpacity: 1,
1830
1933
  touchSoundDisabled: true
1831
1934
  },
1832
- /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(View, { style: styles18.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React25.createElement(
1935
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26.createElement(View, { style: styles19.triggerInner }, tab.icon ? typeof tab.icon === "function" ? tab.icon(isActive) : tab.icon : null, /* @__PURE__ */ React26.createElement(
1833
1936
  Text,
1834
1937
  {
1835
1938
  style: [
1836
- styles18.triggerLabel,
1939
+ styles19.triggerLabel,
1837
1940
  { color: isActive ? colors.foreground : colors.foregroundMuted },
1838
- isActive && (isUnderline ? styles18.activeTriggerLabelUnderline : styles18.activeTriggerLabel)
1941
+ isActive && (isUnderline ? styles19.activeTriggerLabelUnderline : styles19.activeTriggerLabel)
1839
1942
  ],
1840
1943
  allowFontScaling: true
1841
1944
  },
@@ -1856,8 +1959,8 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1856
1959
  if (!layout) return;
1857
1960
  if (animate) {
1858
1961
  Animated.parallel([
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 })
1962
+ Animated.spring(pillX, { toValue: layout.x, useNativeDriver: false, stiffness: 380, damping: 38, mass: 1 }),
1963
+ Animated.spring(pillWidth, { toValue: layout.width, useNativeDriver: false, stiffness: 380, damping: 38, mass: 1 })
1861
1964
  ]).start();
1862
1965
  } else {
1863
1966
  pillX.setValue(layout.x);
@@ -1872,13 +1975,13 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1872
1975
  if (!value) setInternal(v);
1873
1976
  onValueChange?.(v);
1874
1977
  };
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(
1978
+ return /* @__PURE__ */ React26.createElement(View, { style }, /* @__PURE__ */ React26.createElement(View, { style: [
1979
+ variant === "pill" ? [styles19.list, { backgroundColor: colors.surface }] : styles19.listUnderline
1980
+ ] }, variant === "pill" && /* @__PURE__ */ React26.createElement(
1878
1981
  Animated.View,
1879
1982
  {
1880
1983
  style: [
1881
- styles18.pill,
1984
+ styles19.pill,
1882
1985
  {
1883
1986
  backgroundColor: colors.background,
1884
1987
  position: "absolute",
@@ -1895,7 +1998,7 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1895
1998
  }
1896
1999
  ]
1897
2000
  }
1898
- ), tabs.map((tab) => /* @__PURE__ */ React25.createElement(
2001
+ ), tabs.map((tab) => /* @__PURE__ */ React26.createElement(
1899
2002
  TabTrigger,
1900
2003
  {
1901
2004
  key: tab.value,
@@ -1916,9 +2019,9 @@ function Tabs({ tabs, variant = "pill", value, onValueChange, children, style })
1916
2019
  }
1917
2020
  function TabsContent({ value, activeValue, children, style }) {
1918
2021
  if (value !== activeValue) return null;
1919
- return /* @__PURE__ */ React25.createElement(View, { style }, children);
2022
+ return /* @__PURE__ */ React26.createElement(View, { style }, children);
1920
2023
  }
1921
- var styles18 = StyleSheet.create({
2024
+ var styles19 = StyleSheet.create({
1922
2025
  list: {
1923
2026
  flexDirection: "row",
1924
2027
  borderRadius: 12,
@@ -1965,27 +2068,30 @@ var styles18 = StyleSheet.create({
1965
2068
  fontSize: ms(14)
1966
2069
  }
1967
2070
  });
2071
+ var easingExpand = Easing.bezier(0.23, 1, 0.32, 1);
2072
+ var easingCollapse = Easing.in(Easing.ease);
1968
2073
  function AccordionItemComponent({
1969
2074
  item,
1970
2075
  isOpen,
1971
2076
  onToggle
1972
2077
  }) {
1973
2078
  const { colors } = useTheme();
2079
+ const resolvedIcon = item.iconName ? renderIcon(item.iconName, ms(16), item.iconColor ?? colors.foregroundMuted) : item.icon;
1974
2080
  const isExpanded = useSharedValue(isOpen);
1975
2081
  const height = useSharedValue(0);
1976
- React25.useEffect(() => {
2082
+ React26.useEffect(() => {
1977
2083
  isExpanded.value = isOpen;
1978
2084
  }, [isOpen]);
1979
2085
  const derivedHeight = useDerivedValue(
1980
2086
  () => withTiming(height.value * Number(isExpanded.value), {
1981
2087
  duration: 220,
1982
- easing: isExpanded.value ? Easing$1.out(Easing$1.ease) : Easing$1.in(Easing$1.ease)
2088
+ easing: isExpanded.value ? easingExpand : easingCollapse
1983
2089
  })
1984
2090
  );
1985
2091
  const derivedRotation = useDerivedValue(
1986
2092
  () => withTiming(isExpanded.value ? 1 : 0, {
1987
2093
  duration: 220,
1988
- easing: isExpanded.value ? Easing$1.out(Easing$1.ease) : Easing$1.in(Easing$1.ease)
2094
+ easing: isExpanded.value ? easingExpand : easingCollapse
1989
2095
  })
1990
2096
  );
1991
2097
  const bodyStyle = useAnimatedStyle(() => ({
@@ -1995,21 +2101,21 @@ function AccordionItemComponent({
1995
2101
  const rotationStyle = useAnimatedStyle(() => ({
1996
2102
  transform: [{ rotate: `${derivedRotation.value * 180}deg` }]
1997
2103
  }));
1998
- return /* @__PURE__ */ React25.createElement(View, { style: [styles19.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React25.createElement(
2104
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles20.item, { backgroundColor: colors.card, borderColor: colors.border }] }, /* @__PURE__ */ React26.createElement(
1999
2105
  Pressable,
2000
2106
  {
2001
- style: ({ pressed }) => [styles19.trigger, { opacity: pressed ? 0.6 : 1 }],
2107
+ style: ({ pressed }) => [styles20.trigger, { opacity: pressed ? 0.6 : 1 }],
2002
2108
  onPress: () => {
2003
2109
  selectionAsync();
2004
2110
  onToggle();
2005
2111
  }
2006
2112
  },
2007
- /* @__PURE__ */ React25.createElement(Text, { style: [styles19.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger),
2008
- /* @__PURE__ */ React25.createElement(Animated11.View, { style: [styles19.chevron, rotationStyle] }, /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2009
- ), /* @__PURE__ */ React25.createElement(Animated11.View, { style: bodyStyle }, /* @__PURE__ */ React25.createElement(
2113
+ /* @__PURE__ */ React26.createElement(View, { style: styles20.triggerContent }, resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles20.icon }, resolvedIcon) : null, /* @__PURE__ */ React26.createElement(Text, { style: [styles20.triggerText, { color: colors.foreground }], allowFontScaling: true }, item.trigger)),
2114
+ /* @__PURE__ */ React26.createElement(Animated12.View, { style: [styles20.chevron, rotationStyle] }, /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-down", size: 18, color: colors.foregroundMuted }))
2115
+ ), /* @__PURE__ */ React26.createElement(Animated12.View, { style: bodyStyle }, /* @__PURE__ */ React26.createElement(
2010
2116
  View,
2011
2117
  {
2012
- style: styles19.content,
2118
+ style: styles20.content,
2013
2119
  onLayout: (e) => {
2014
2120
  height.value = e.nativeEvent.layout.height;
2015
2121
  }
@@ -2031,7 +2137,7 @@ function Accordion({ items, type = "single", defaultValue, style }) {
2031
2137
  );
2032
2138
  }
2033
2139
  };
2034
- return /* @__PURE__ */ React25.createElement(View, { style: [styles19.list, style] }, items.map((item) => /* @__PURE__ */ React25.createElement(
2140
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles20.list, style] }, items.map((item) => /* @__PURE__ */ React26.createElement(
2035
2141
  AccordionItemComponent,
2036
2142
  {
2037
2143
  key: item.value,
@@ -2041,7 +2147,7 @@ function Accordion({ items, type = "single", defaultValue, style }) {
2041
2147
  }
2042
2148
  )));
2043
2149
  }
2044
- var styles19 = StyleSheet.create({
2150
+ var styles20 = StyleSheet.create({
2045
2151
  list: {
2046
2152
  gap: s(6)
2047
2153
  },
@@ -2057,10 +2163,19 @@ var styles19 = StyleSheet.create({
2057
2163
  paddingHorizontal: s(14),
2058
2164
  paddingVertical: vs(12)
2059
2165
  },
2166
+ triggerContent: {
2167
+ flexDirection: "row",
2168
+ alignItems: "center",
2169
+ gap: s(8),
2170
+ flex: 1
2171
+ },
2172
+ icon: {
2173
+ alignItems: "center",
2174
+ justifyContent: "center"
2175
+ },
2060
2176
  triggerText: {
2061
2177
  fontFamily: "Poppins-Medium",
2062
- fontSize: ms(14),
2063
- flex: 1
2178
+ fontSize: ms(14)
2064
2179
  },
2065
2180
  chevron: {
2066
2181
  marginLeft: s(8)
@@ -2097,7 +2212,7 @@ function Slider({
2097
2212
  }
2098
2213
  onValueChange?.(v);
2099
2214
  };
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(
2215
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles21.wrapper, style], accessibilityLabel }, label || showValue ? /* @__PURE__ */ React26.createElement(View, { style: styles21.header }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles21.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, showValue ? /* @__PURE__ */ React26.createElement(Text, { style: [styles21.valueText, { color: colors.foregroundMuted }], allowFontScaling: true }, formatValue2(value)) : null) : null, /* @__PURE__ */ React26.createElement(View, { style: disabled ? styles21.disabled : void 0 }, /* @__PURE__ */ React26.createElement(
2101
2216
  RNSlider,
2102
2217
  {
2103
2218
  value,
@@ -2110,12 +2225,12 @@ function Slider({
2110
2225
  minimumTrackTintColor: colors.primary,
2111
2226
  maximumTrackTintColor: colors.surface,
2112
2227
  thumbTintColor: colors.primary,
2113
- style: styles20.slider,
2228
+ style: styles21.slider,
2114
2229
  accessibilityLabel
2115
2230
  }
2116
2231
  )));
2117
2232
  }
2118
- var styles20 = StyleSheet.create({
2233
+ var styles21 = StyleSheet.create({
2119
2234
  wrapper: {
2120
2235
  gap: vs(8)
2121
2236
  },
@@ -2140,27 +2255,41 @@ var styles20 = StyleSheet.create({
2140
2255
  opacity: 0.45
2141
2256
  }
2142
2257
  });
2258
+ var SCREEN_HEIGHT = Dimensions.get("window").height;
2259
+ var DEFAULT_MAX_HEIGHT = SCREEN_HEIGHT * 0.85;
2260
+ var isAndroid = Platform.OS === "android";
2143
2261
  function Sheet({
2144
2262
  open,
2145
2263
  onClose,
2146
2264
  title,
2265
+ subtitle,
2147
2266
  description,
2267
+ showCloseButton = false,
2148
2268
  children,
2149
2269
  style,
2270
+ contentStyle,
2150
2271
  scrollable,
2151
- maxHeight
2272
+ maxHeight,
2273
+ keyboardBehavior,
2274
+ keyboardBlurBehavior = "restore",
2275
+ enableBlurKeyboardOnGesture = true,
2276
+ android_keyboardInputMode = "adjustPan",
2277
+ footer,
2278
+ snapPoints
2152
2279
  }) {
2153
2280
  const { colors } = useTheme();
2281
+ const insets = useSafeAreaInsets();
2154
2282
  const ref = useRef(null);
2283
+ const effectiveKeyboardBehavior = keyboardBehavior ?? "interactive";
2155
2284
  useEffect(() => {
2156
2285
  if (open) {
2157
- impactLight();
2286
+ impactMedium();
2158
2287
  ref.current?.present();
2159
2288
  } else {
2160
2289
  ref.current?.dismiss();
2161
2290
  }
2162
2291
  }, [open]);
2163
- const renderBackdrop = (props) => /* @__PURE__ */ React25.createElement(
2292
+ const renderBackdrop = useCallback((props) => /* @__PURE__ */ React26.createElement(
2164
2293
  BottomSheetBackdrop,
2165
2294
  {
2166
2295
  ...props,
@@ -2168,24 +2297,63 @@ function Sheet({
2168
2297
  appearsOnIndex: 0,
2169
2298
  pressBehavior: "close"
2170
2299
  }
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;
2300
+ ), []);
2301
+ const renderFooter = useCallback((props) => {
2302
+ if (!footer) return null;
2303
+ return /* @__PURE__ */ React26.createElement(BottomSheetFooter, { ...props }, footer);
2304
+ }, [footer]);
2305
+ const effectiveSubtitle = subtitle ?? description;
2306
+ const showHeader = !!(title || effectiveSubtitle || showCloseButton);
2307
+ const headerNode = showHeader ? /* @__PURE__ */ React26.createElement(View, { style: styles22.header }, /* @__PURE__ */ React26.createElement(View, { style: styles22.headerRow }, title ? /* @__PURE__ */ React26.createElement(Text, { style: [styles22.title, { color: colors.foreground }], allowFontScaling: true }, title) : /* @__PURE__ */ React26.createElement(View, { style: { flex: 1 } }), showCloseButton ? /* @__PURE__ */ React26.createElement(
2308
+ TouchableOpacity,
2309
+ {
2310
+ onPress: onClose,
2311
+ style: styles22.closeButton,
2312
+ activeOpacity: 0.6,
2313
+ touchSoundDisabled: true
2314
+ },
2315
+ /* @__PURE__ */ React26.createElement(AntDesign$1, { name: "close", size: ms(18), color: colors.foregroundMuted })
2316
+ ) : null), effectiveSubtitle ? /* @__PURE__ */ React26.createElement(Text, { style: [styles22.subtitle, { color: colors.foregroundMuted }], allowFontScaling: true }, effectiveSubtitle) : null) : null;
2173
2317
  const useScroll = scrollable || !!maxHeight;
2174
- return /* @__PURE__ */ React25.createElement(
2318
+ const effectiveMaxHeight = maxHeight ?? DEFAULT_MAX_HEIGHT;
2319
+ const useDynamicSizing = !snapPoints;
2320
+ return /* @__PURE__ */ React26.createElement(
2175
2321
  BottomSheetModal,
2176
2322
  {
2177
2323
  ref,
2178
- enableDynamicSizing: true,
2324
+ enableDynamicSizing: useDynamicSizing,
2325
+ snapPoints,
2326
+ maxDynamicContentSize: useDynamicSizing ? effectiveMaxHeight : void 0,
2179
2327
  onDismiss: onClose,
2180
2328
  backdropComponent: renderBackdrop,
2181
- backgroundStyle: [styles21.background, { backgroundColor: colors.card }],
2182
- handleIndicatorStyle: [styles21.handle, { backgroundColor: colors.border }],
2183
- enablePanDownToClose: true
2329
+ footerComponent: footer ? renderFooter : void 0,
2330
+ backgroundStyle: [styles22.background, { backgroundColor: colors.card }],
2331
+ handleIndicatorStyle: [styles22.handle, { backgroundColor: colors.border }],
2332
+ enablePanDownToClose: true,
2333
+ topInset: insets.top,
2334
+ keyboardBehavior: effectiveKeyboardBehavior,
2335
+ keyboardBlurBehavior,
2336
+ android_keyboardInputMode,
2337
+ enableBlurKeyboardOnGesture
2184
2338
  },
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))
2339
+ useScroll ? /* @__PURE__ */ React26.createElement(
2340
+ BottomSheetScrollView,
2341
+ {
2342
+ contentContainerStyle: [
2343
+ styles22.scrollContent,
2344
+ style
2345
+ ],
2346
+ style: contentStyle,
2347
+ showsVerticalScrollIndicator: true,
2348
+ indicatorStyle: "black",
2349
+ persistentScrollbar: isAndroid
2350
+ },
2351
+ headerNode,
2352
+ children
2353
+ ) : /* @__PURE__ */ React26.createElement(BottomSheetView, { style: [styles22.content, contentStyle, style] }, headerNode, children)
2186
2354
  );
2187
2355
  }
2188
- var styles21 = StyleSheet.create({
2356
+ var styles22 = StyleSheet.create({
2189
2357
  background: {
2190
2358
  borderTopLeftRadius: ms(16),
2191
2359
  borderTopRightRadius: ms(16)
@@ -2195,26 +2363,43 @@ var styles21 = StyleSheet.create({
2195
2363
  height: vs(4),
2196
2364
  borderRadius: ms(2)
2197
2365
  },
2198
- content: {
2199
- paddingHorizontal: s(24),
2200
- paddingBottom: vs(32)
2201
- },
2202
2366
  header: {
2203
- gap: vs(8),
2204
- marginBottom: vs(16)
2367
+ paddingHorizontal: s(16),
2368
+ paddingTop: vs(4),
2369
+ paddingBottom: vs(12),
2370
+ gap: vs(4)
2371
+ },
2372
+ headerRow: {
2373
+ flexDirection: "row",
2374
+ alignItems: "center",
2375
+ justifyContent: "space-between"
2205
2376
  },
2206
2377
  title: {
2207
2378
  fontFamily: "Poppins-SemiBold",
2208
- fontSize: ms(18)
2379
+ fontSize: ms(18),
2380
+ flex: 1
2209
2381
  },
2210
- description: {
2382
+ subtitle: {
2211
2383
  fontFamily: "Poppins-Regular",
2212
2384
  fontSize: ms(14),
2213
2385
  lineHeight: mvs(20)
2386
+ },
2387
+ closeButton: {
2388
+ padding: s(4),
2389
+ marginLeft: s(8)
2390
+ },
2391
+ content: {
2392
+ paddingHorizontal: s(16),
2393
+ paddingBottom: vs(32)
2394
+ },
2395
+ scrollContent: {
2396
+ paddingHorizontal: s(16),
2397
+ paddingBottom: vs(32),
2398
+ paddingRight: s(16)
2214
2399
  }
2215
2400
  });
2216
2401
  var isIOS = Platform.OS === "ios";
2217
- var isAndroid = Platform.OS === "android";
2402
+ var isAndroid2 = Platform.OS === "android";
2218
2403
  var isWeb2 = Platform.OS === "web";
2219
2404
  var nativeDriver9 = Platform.OS !== "web";
2220
2405
  function Select({
@@ -2246,7 +2431,7 @@ function Select({
2246
2431
  if (isIOS) {
2247
2432
  setPendingValue(value);
2248
2433
  setPickerVisible(true);
2249
- } else if (isAndroid) {
2434
+ } else if (isAndroid2) {
2250
2435
  pickerRef.current?.focus();
2251
2436
  }
2252
2437
  };
@@ -2260,11 +2445,11 @@ function Select({
2260
2445
  }
2261
2446
  setPickerVisible(false);
2262
2447
  };
2263
- return /* @__PURE__ */ React25.createElement(View, { style: [styles22.container, style] }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles22.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React25.createElement(
2448
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles23.container, style] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles23.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, !isWeb2 ? /* @__PURE__ */ React26.createElement(Animated.View, { style: { transform: [{ scale: scale2 }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React26.createElement(
2264
2449
  TouchableOpacity,
2265
2450
  {
2266
2451
  style: [
2267
- styles22.trigger,
2452
+ styles23.trigger,
2268
2453
  {
2269
2454
  borderColor: error ? colors.destructive : colors.border,
2270
2455
  backgroundColor: colors.background
@@ -2276,11 +2461,11 @@ function Select({
2276
2461
  activeOpacity: 1,
2277
2462
  touchSoundDisabled: true
2278
2463
  },
2279
- /* @__PURE__ */ React25.createElement(
2464
+ /* @__PURE__ */ React26.createElement(
2280
2465
  Text,
2281
2466
  {
2282
2467
  style: [
2283
- styles22.triggerText,
2468
+ styles23.triggerText,
2284
2469
  { color: selected ? colors.foreground : colors.foregroundMuted }
2285
2470
  ],
2286
2471
  numberOfLines: 1,
@@ -2288,8 +2473,8 @@ function Select({
2288
2473
  },
2289
2474
  selected?.label ?? placeholder
2290
2475
  ),
2291
- /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-down", size: 20, color: colors.foregroundMuted })
2292
- )) : null, isIOS ? /* @__PURE__ */ React25.createElement(
2476
+ /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-down", size: 20, color: colors.foregroundMuted })
2477
+ )) : null, isIOS ? /* @__PURE__ */ React26.createElement(
2293
2478
  Modal,
2294
2479
  {
2295
2480
  visible: pickerVisible,
@@ -2297,16 +2482,16 @@ function Select({
2297
2482
  animationType: "slide",
2298
2483
  onRequestClose: handleDismiss
2299
2484
  },
2300
- /* @__PURE__ */ React25.createElement(TouchableOpacity, { style: styles22.iosBackdrop, activeOpacity: 1, onPress: handleDismiss }),
2301
- /* @__PURE__ */ React25.createElement(View, { style: [styles22.iosSheet, { backgroundColor: colors.card }] }, /* @__PURE__ */ React25.createElement(View, { style: [styles22.iosToolbar, { borderBottomColor: colors.border }] }, label ? /* @__PURE__ */ React25.createElement(Text, { style: [styles22.iosToolbarTitle, { color: colors.foreground }], allowFontScaling: true }, label) : /* @__PURE__ */ React25.createElement(View, null), /* @__PURE__ */ React25.createElement(TouchableOpacity, { onPress: handleConfirm, style: styles22.iosDoneBtn, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 } }, /* @__PURE__ */ React25.createElement(Text, { style: [styles22.iosDoneBtnText, { color: colors.primary }], allowFontScaling: true }, "Done"))), /* @__PURE__ */ React25.createElement(
2485
+ /* @__PURE__ */ React26.createElement(TouchableOpacity, { style: styles23.iosBackdrop, activeOpacity: 1, onPress: handleDismiss }),
2486
+ /* @__PURE__ */ React26.createElement(View, { style: [styles23.iosSheet, { backgroundColor: colors.card }] }, /* @__PURE__ */ React26.createElement(View, { style: [styles23.iosToolbar, { borderBottomColor: colors.border }] }, label ? /* @__PURE__ */ React26.createElement(Text, { style: [styles23.iosToolbarTitle, { color: colors.foreground }], allowFontScaling: true }, label) : /* @__PURE__ */ React26.createElement(View, null), /* @__PURE__ */ React26.createElement(TouchableOpacity, { onPress: handleConfirm, style: styles23.iosDoneBtn, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 } }, /* @__PURE__ */ React26.createElement(Text, { style: [styles23.iosDoneBtnText, { color: colors.primary }], allowFontScaling: true }, "Done"))), /* @__PURE__ */ React26.createElement(
2302
2487
  Picker,
2303
2488
  {
2304
2489
  selectedValue: pendingValue ?? "",
2305
2490
  onValueChange: (val) => setPendingValue(val),
2306
2491
  itemStyle: { color: colors.foreground }
2307
2492
  },
2308
- !value ? /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
2309
- options.map((o) => /* @__PURE__ */ React25.createElement(
2493
+ !value ? /* @__PURE__ */ React26.createElement(Picker.Item, { label: placeholder, value: "", color: colors.foregroundMuted, enabled: false }) : null,
2494
+ options.map((o) => /* @__PURE__ */ React26.createElement(
2310
2495
  Picker.Item,
2311
2496
  {
2312
2497
  key: o.value,
@@ -2317,7 +2502,7 @@ function Select({
2317
2502
  }
2318
2503
  ))
2319
2504
  ))
2320
- ) : null, isAndroid ? /* @__PURE__ */ React25.createElement(
2505
+ ) : null, isAndroid2 ? /* @__PURE__ */ React26.createElement(
2321
2506
  Picker,
2322
2507
  {
2323
2508
  ref: pickerRef,
@@ -2331,10 +2516,10 @@ function Select({
2331
2516
  mode: "dialog",
2332
2517
  enabled: !disabled,
2333
2518
  prompt: label,
2334
- style: styles22.androidHiddenPicker
2519
+ style: styles23.androidHiddenPicker
2335
2520
  },
2336
- !value ? /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", enabled: false }) : null,
2337
- options.map((o) => /* @__PURE__ */ React25.createElement(
2521
+ !value ? /* @__PURE__ */ React26.createElement(Picker.Item, { label: placeholder, value: "", enabled: false }) : null,
2522
+ options.map((o) => /* @__PURE__ */ React26.createElement(
2338
2523
  Picker.Item,
2339
2524
  {
2340
2525
  key: o.value,
@@ -2343,7 +2528,7 @@ function Select({
2343
2528
  enabled: !o.disabled
2344
2529
  }
2345
2530
  ))
2346
- ) : null, isWeb2 ? /* @__PURE__ */ React25.createElement(
2531
+ ) : null, isWeb2 ? /* @__PURE__ */ React26.createElement(
2347
2532
  Picker,
2348
2533
  {
2349
2534
  selectedValue: value ?? "",
@@ -2354,7 +2539,7 @@ function Select({
2354
2539
  },
2355
2540
  enabled: !disabled,
2356
2541
  style: [
2357
- styles22.webPicker,
2542
+ styles23.webPicker,
2358
2543
  {
2359
2544
  borderColor: error ? colors.destructive : colors.border,
2360
2545
  color: selected ? colors.foreground : colors.foregroundMuted,
@@ -2363,8 +2548,8 @@ function Select({
2363
2548
  }
2364
2549
  ]
2365
2550
  },
2366
- /* @__PURE__ */ React25.createElement(Picker.Item, { label: placeholder, value: "", enabled: false }),
2367
- options.map((o) => /* @__PURE__ */ React25.createElement(
2551
+ /* @__PURE__ */ React26.createElement(Picker.Item, { label: placeholder, value: "", enabled: false }),
2552
+ options.map((o) => /* @__PURE__ */ React26.createElement(
2368
2553
  Picker.Item,
2369
2554
  {
2370
2555
  key: o.value,
@@ -2373,9 +2558,9 @@ function Select({
2373
2558
  enabled: !o.disabled
2374
2559
  }
2375
2560
  ))
2376
- ) : null, error ? /* @__PURE__ */ React25.createElement(Text, { style: [styles22.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null);
2561
+ ) : null, error ? /* @__PURE__ */ React26.createElement(Text, { style: [styles23.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null);
2377
2562
  }
2378
- var styles22 = StyleSheet.create({
2563
+ var styles23 = StyleSheet.create({
2379
2564
  container: {
2380
2565
  gap: vs(8)
2381
2566
  },
@@ -2445,172 +2630,46 @@ var styles22 = StyleSheet.create({
2445
2630
  fontSize: ms(15)
2446
2631
  }
2447
2632
  });
2448
- var ToastContext = createContext({
2449
- toast: () => {
2450
- },
2451
- dismiss: () => {
2452
- }
2453
- });
2454
2633
  function useToast() {
2455
- return useContext(ToastContext);
2456
- }
2457
- var SWIPE_THRESHOLD = 80;
2458
- var VELOCITY_THRESHOLD = 800;
2459
- function ToastNotification({ item, onDismiss }) {
2460
- const { colors } = useTheme();
2461
- const translateY = useSharedValue(-80);
2462
- const translateX = useSharedValue(0);
2463
- const opacity = useSharedValue(0);
2464
- useEffect(() => {
2465
- translateY.value = withTiming(0, { duration: 120, easing: Easing$1.out(Easing$1.exp) });
2466
- opacity.value = withTiming(1, { duration: 100 });
2467
- const timer = setTimeout(() => {
2468
- translateY.value = withTiming(-80, { duration: 200 });
2469
- opacity.value = withTiming(0, { duration: 200 }, (done) => {
2470
- if (done) scheduleOnRN(onDismiss);
2471
- });
2472
- }, item.duration ?? 3e3);
2473
- return () => clearTimeout(timer);
2474
- }, []);
2475
- const panGesture = Gesture.Pan().onUpdate((e) => {
2476
- translateX.value = e.translationX;
2477
- }).onEnd((e) => {
2478
- const shouldDismiss = Math.abs(translateX.value) > SWIPE_THRESHOLD || Math.abs(e.velocityX) > VELOCITY_THRESHOLD;
2479
- if (shouldDismiss) {
2480
- const direction = translateX.value > 0 ? 1 : -1;
2481
- translateX.value = withTiming(direction * 500, { duration: 200 }, (done) => {
2482
- if (done) scheduleOnRN(onDismiss);
2483
- });
2484
- opacity.value = withTiming(0, { duration: 150 });
2485
- } else {
2486
- translateX.value = withSpring(0, { damping: 20, stiffness: 300 });
2487
- }
2488
- });
2489
- const animatedStyle = useAnimatedStyle(() => ({
2490
- opacity: opacity.value,
2491
- transform: [{ translateY: translateY.value }, { translateX: translateX.value }]
2492
- }));
2493
- const variant = item.variant ?? "default";
2494
- const bgColor = {
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,
2502
- destructive: colors.destructiveBorder,
2503
- success: colors.successBorder,
2504
- warning: colors.warningBorder
2505
- }[variant];
2506
- const accentColor = {
2507
- default: colors.primary,
2508
- destructive: colors.destructive,
2509
- success: colors.success,
2510
- warning: colors.warning
2511
- }[variant];
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 }))));
2634
+ return {
2635
+ toast: toast,
2636
+ dismiss: toast.dismiss
2637
+ };
2528
2638
  }
2529
2639
  function ToastProvider({ children }) {
2530
- const [toasts, setToasts] = useState([]);
2640
+ const { colorScheme } = useTheme();
2531
2641
  const insets = useSafeAreaInsets();
2532
- const toast = useCallback((item) => {
2533
- const id = Math.random().toString(36).slice(2);
2534
- if (item.variant === "success") {
2535
- notificationSuccess();
2536
- } else if (item.variant === "destructive") {
2537
- notificationError();
2538
- } else if (item.variant === "warning") {
2539
- notificationError();
2540
- } else {
2541
- impactLight();
2642
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, children, /* @__PURE__ */ React26.createElement(
2643
+ Toaster,
2644
+ {
2645
+ theme: colorScheme,
2646
+ position: "top-center",
2647
+ richColors: false,
2648
+ gap: vs(8),
2649
+ offset: insets.top + vs(8),
2650
+ visibleToasts: 3,
2651
+ closeButton: false,
2652
+ swipeToDismissDirection: "up",
2653
+ duration: 4e3,
2654
+ toastOptions: {
2655
+ style: {
2656
+ borderRadius: ms(12),
2657
+ paddingHorizontal: s(12),
2658
+ paddingVertical: vs(10)
2659
+ },
2660
+ titleStyle: {
2661
+ fontFamily: "Poppins-Medium",
2662
+ fontSize: ms(13)
2663
+ },
2664
+ descriptionStyle: {
2665
+ fontFamily: "Poppins-Regular",
2666
+ fontSize: ms(12),
2667
+ opacity: 0.85
2668
+ }
2669
+ }
2542
2670
  }
2543
- setToasts((prev) => [{ ...item, id }, ...prev].slice(0, 3));
2544
- }, []);
2545
- const dismiss = useCallback((id) => {
2546
- setToasts((prev) => prev.filter((t) => t.id !== id));
2547
- }, []);
2548
- return /* @__PURE__ */ React25.createElement(ToastContext.Provider, { value: { toast, dismiss } }, children, /* @__PURE__ */ React25.createElement(View, { style: [styles23.container, Platform.OS === "web" && styles23.containerWeb, { top: insets.top + 8 }], pointerEvents: "box-none" }, toasts.map((item) => /* @__PURE__ */ React25.createElement(ToastNotification, { key: item.id, item, onDismiss: () => dismiss(item.id) }))));
2671
+ ));
2549
2672
  }
2550
- var styles23 = StyleSheet.create({
2551
- container: {
2552
- position: "absolute",
2553
- left: s(16),
2554
- right: s(16),
2555
- gap: vs(8),
2556
- zIndex: 9999
2557
- },
2558
- containerWeb: {
2559
- left: void 0,
2560
- right: void 0,
2561
- alignSelf: "center",
2562
- width: s(400)
2563
- },
2564
- toast: {
2565
- flexDirection: "row",
2566
- alignItems: "flex-start",
2567
- borderRadius: ms(10),
2568
- borderWidth: 0.5,
2569
- paddingHorizontal: s(12),
2570
- paddingVertical: vs(10),
2571
- shadowColor: "#000",
2572
- shadowOffset: { width: 0, height: 2 },
2573
- shadowOpacity: 0.06,
2574
- shadowRadius: 4,
2575
- elevation: 3
2576
- },
2577
- toastContent: {
2578
- flex: 1,
2579
- gap: vs(2)
2580
- },
2581
- leftIconContainer: {
2582
- marginTop: vs(1),
2583
- alignItems: "center",
2584
- justifyContent: "center",
2585
- marginRight: s(10)
2586
- },
2587
- toastTitle: {
2588
- fontFamily: "Poppins-Medium",
2589
- fontSize: ms(13),
2590
- lineHeight: ms(18)
2591
- },
2592
- toastDescription: {
2593
- fontFamily: "Poppins-Regular",
2594
- fontSize: ms(12),
2595
- lineHeight: ms(17),
2596
- opacity: 0.85
2597
- },
2598
- actionButton: {
2599
- paddingHorizontal: s(8),
2600
- paddingVertical: vs(4),
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)
2612
- }
2613
- });
2614
2673
  function formatCurrency(raw, separator) {
2615
2674
  const digits = raw.replace(/\D/g, "");
2616
2675
  if (!digits) return "";
@@ -2644,7 +2703,7 @@ function CurrencyInput({
2644
2703
  const inputStyle = size === "large" ? { fontFamily: "Poppins-Regular", fontSize: ms(36) } : { fontFamily: "Poppins-Regular" };
2645
2704
  const dollarIcon = renderIcon("dollar-sign", size === "large" ? 24 : 16, colors.foregroundMuted);
2646
2705
  const displayValue = value && prefix && value.startsWith(prefix) ? value.slice(prefix.length) : value;
2647
- return /* @__PURE__ */ React25.createElement(
2706
+ return /* @__PURE__ */ React26.createElement(
2648
2707
  Input,
2649
2708
  {
2650
2709
  value: displayValue,
@@ -2662,6 +2721,18 @@ function CurrencyInput({
2662
2721
  }
2663
2722
  );
2664
2723
  }
2724
+ var variantFontSize = {
2725
+ hero: ms(48),
2726
+ large: ms(32),
2727
+ medium: ms(18),
2728
+ small: ms(14)
2729
+ };
2730
+ var variantLetterSpacing = {
2731
+ hero: -2,
2732
+ large: -1,
2733
+ medium: -0.5,
2734
+ small: 0
2735
+ };
2665
2736
  function formatValue(value, prefix, showDecimals) {
2666
2737
  const num = typeof value === "string" ? parseFloat(value.replace(/[^0-9.-]/g, "")) : value;
2667
2738
  if (isNaN(num)) return `${prefix}0`;
@@ -2674,17 +2745,32 @@ function formatValue(value, prefix, showDecimals) {
2674
2745
  }
2675
2746
  return `${sign}${prefix}${intPart}`;
2676
2747
  }
2677
- function CurrencyDisplay({ value, prefix = "$", showDecimals = false, textColor, style }) {
2748
+ function CurrencyDisplay({ value, prefix = "$", showDecimals = false, textColor, variant, autoScale, maxFontSize, style }) {
2678
2749
  const { colors } = useTheme();
2679
2750
  const formatted = formatValue(value, prefix, showDecimals);
2680
- return /* @__PURE__ */ React25.createElement(View, { style: [styles24.container, style] }, /* @__PURE__ */ React25.createElement(Text, { style: [styles24.amount, { color: textColor ?? colors.foreground }], allowFontScaling: true }, formatted));
2751
+ const baseFontSize = variant ? variantFontSize[variant] : ms(56);
2752
+ const fontSize = maxFontSize ?? baseFontSize;
2753
+ const letterSpacing = variant ? variantLetterSpacing[variant] : -2;
2754
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles24.container, style] }, /* @__PURE__ */ React26.createElement(
2755
+ Text,
2756
+ {
2757
+ style: [styles24.amount, { color: textColor ?? colors.foreground, fontSize, letterSpacing }],
2758
+ allowFontScaling: true,
2759
+ numberOfLines: autoScale ? 1 : void 0,
2760
+ adjustsFontSizeToFit: autoScale,
2761
+ minimumFontScale: autoScale ? 0.5 : void 0
2762
+ },
2763
+ formatted
2764
+ ));
2681
2765
  }
2682
2766
  var styles24 = StyleSheet.create({
2683
- container: {},
2767
+ container: {
2768
+ alignSelf: "flex-start"
2769
+ },
2684
2770
  amount: {
2685
2771
  fontFamily: "Poppins-Bold",
2686
- fontSize: ms(56),
2687
- letterSpacing: -2
2772
+ includeFontPadding: false,
2773
+ textAlignVertical: "top"
2688
2774
  }
2689
2775
  });
2690
2776
  var nativeDriver10 = Platform.OS !== "web";
@@ -2717,16 +2803,18 @@ function ListItem({
2717
2803
  Animated.spring(scale2, {
2718
2804
  toValue: 0.97,
2719
2805
  useNativeDriver: nativeDriver10,
2720
- speed: 40,
2721
- bounciness: 0
2806
+ stiffness: 350,
2807
+ damping: 28,
2808
+ mass: 0.9
2722
2809
  }).start();
2723
2810
  };
2724
2811
  const handlePressOut = () => {
2725
2812
  Animated.spring(scale2, {
2726
2813
  toValue: 1,
2727
2814
  useNativeDriver: nativeDriver10,
2728
- speed: 40,
2729
- bounciness: 4
2815
+ stiffness: 220,
2816
+ damping: 20,
2817
+ mass: 0.9
2730
2818
  }).start();
2731
2819
  };
2732
2820
  const handlePress = () => {
@@ -2737,7 +2825,7 @@ function ListItem({
2737
2825
  const effectiveRight = rightIcon ? renderIcon(rightIcon, 24, rightIconColor ?? colors.foregroundMuted) : rightRender ?? trailing;
2738
2826
  const cardStyle = variant === "card" ? {
2739
2827
  backgroundColor: colors.card,
2740
- borderRadius: 12,
2828
+ borderRadius: RADIUS.md,
2741
2829
  borderWidth: 1,
2742
2830
  borderColor: colors.border,
2743
2831
  shadowColor: "#000",
@@ -2746,7 +2834,7 @@ function ListItem({
2746
2834
  shadowRadius: 6,
2747
2835
  elevation: 2
2748
2836
  } : {};
2749
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles25.disabled] }, /* @__PURE__ */ React25.createElement(
2837
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles25.disabled] }, /* @__PURE__ */ React26.createElement(
2750
2838
  TouchableOpacity,
2751
2839
  {
2752
2840
  style: [styles25.container, cardStyle, style],
@@ -2757,8 +2845,8 @@ function ListItem({
2757
2845
  activeOpacity: 1,
2758
2846
  touchSoundDisabled: true
2759
2847
  },
2760
- effectiveLeft ? /* @__PURE__ */ React25.createElement(View, { style: styles25.leftContainer }, effectiveLeft) : null,
2761
- /* @__PURE__ */ React25.createElement(View, { style: styles25.content }, /* @__PURE__ */ React25.createElement(
2848
+ effectiveLeft ? /* @__PURE__ */ React26.createElement(View, { style: styles25.leftContainer }, effectiveLeft) : null,
2849
+ /* @__PURE__ */ React26.createElement(View, { style: styles25.content }, /* @__PURE__ */ React26.createElement(
2762
2850
  Text,
2763
2851
  {
2764
2852
  style: [styles25.title, { color: colors.foreground }, titleStyle],
@@ -2766,7 +2854,7 @@ function ListItem({
2766
2854
  allowFontScaling: true
2767
2855
  },
2768
2856
  title
2769
- ), subtitle ? /* @__PURE__ */ React25.createElement(
2857
+ ), subtitle ? /* @__PURE__ */ React26.createElement(
2770
2858
  Text,
2771
2859
  {
2772
2860
  style: [styles25.subtitle, { color: colors.foregroundMuted }, subtitleStyle],
@@ -2774,7 +2862,7 @@ function ListItem({
2774
2862
  allowFontScaling: true
2775
2863
  },
2776
2864
  subtitle
2777
- ) : null, caption ? /* @__PURE__ */ React25.createElement(
2865
+ ) : null, caption ? /* @__PURE__ */ React26.createElement(
2778
2866
  Text,
2779
2867
  {
2780
2868
  style: [styles25.caption, { color: colors.foregroundMuted }, captionStyle],
@@ -2783,20 +2871,23 @@ function ListItem({
2783
2871
  },
2784
2872
  caption
2785
2873
  ) : null),
2786
- effectiveRight !== void 0 ? /* @__PURE__ */ React25.createElement(View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React25.createElement(
2874
+ effectiveRight !== void 0 ? /* @__PURE__ */ React26.createElement(View, { style: styles25.rightContainer }, typeof effectiveRight === "string" ? /* @__PURE__ */ React26.createElement(
2787
2875
  Text,
2788
2876
  {
2789
2877
  style: [styles25.rightText, { color: colors.foregroundMuted }],
2790
2878
  allowFontScaling: true
2791
2879
  },
2792
2880
  effectiveRight
2793
- ) : effectiveRight) : showChevron ? /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
2794
- ), showSeparator ? /* @__PURE__ */ React25.createElement(
2881
+ ) : effectiveRight) : showChevron ? /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-with-circle-right", size: 20, color: colors.foregroundMuted }) : null
2882
+ ), showSeparator ? /* @__PURE__ */ React26.createElement(
2795
2883
  View,
2796
2884
  {
2797
2885
  style: [
2798
2886
  styles25.separator,
2799
- { backgroundColor: colors.border, marginLeft: effectiveLeft ? s(16) + s(44) + s(12) : s(16) }
2887
+ {
2888
+ backgroundColor: colors.border,
2889
+ marginLeft: effectiveLeft ? s(44) + s(12) : 0
2890
+ }
2800
2891
  ]
2801
2892
  }
2802
2893
  ) : null);
@@ -2805,7 +2896,7 @@ var styles25 = StyleSheet.create({
2805
2896
  container: {
2806
2897
  flexDirection: "row",
2807
2898
  alignItems: "center",
2808
- paddingHorizontal: s(16),
2899
+ paddingHorizontal: 0,
2809
2900
  paddingVertical: vs(10),
2810
2901
  gap: s(12)
2811
2902
  },
@@ -2851,13 +2942,143 @@ var styles25 = StyleSheet.create({
2851
2942
  },
2852
2943
  separator: {
2853
2944
  height: StyleSheet.hairlineWidth,
2854
- marginRight: s(16)
2945
+ marginRight: 0
2855
2946
  },
2856
2947
  disabled: {
2857
2948
  opacity: 0.45
2858
2949
  }
2859
2950
  });
2860
2951
  var nativeDriver11 = Platform.OS !== "web";
2952
+ function MenuItem({
2953
+ label,
2954
+ iconName,
2955
+ icon,
2956
+ iconColor,
2957
+ rightRender,
2958
+ showChevron = true,
2959
+ onPress,
2960
+ disabled = false,
2961
+ variant = "plain",
2962
+ showSeparator = false,
2963
+ style,
2964
+ labelStyle
2965
+ }) {
2966
+ const { colors } = useTheme();
2967
+ const scale2 = useRef(new Animated.Value(1)).current;
2968
+ const handlePressIn = () => {
2969
+ if (disabled) return;
2970
+ Animated.spring(scale2, {
2971
+ toValue: 0.97,
2972
+ useNativeDriver: nativeDriver11,
2973
+ stiffness: 350,
2974
+ damping: 28,
2975
+ mass: 0.9
2976
+ }).start();
2977
+ };
2978
+ const handlePressOut = () => {
2979
+ Animated.spring(scale2, {
2980
+ toValue: 1,
2981
+ useNativeDriver: nativeDriver11,
2982
+ stiffness: 220,
2983
+ damping: 20,
2984
+ mass: 0.9
2985
+ }).start();
2986
+ };
2987
+ const handlePress = () => {
2988
+ selectionAsync();
2989
+ onPress();
2990
+ };
2991
+ const resolvedIcon = iconName ? renderIcon(iconName, 22, iconColor ?? colors.foreground) : icon;
2992
+ const cardStyle = variant === "card" ? {
2993
+ backgroundColor: colors.card,
2994
+ borderRadius: RADIUS.md,
2995
+ borderWidth: 1,
2996
+ borderColor: colors.border,
2997
+ shadowColor: "#000",
2998
+ shadowOffset: { width: 0, height: 2 },
2999
+ shadowOpacity: 0.06,
3000
+ shadowRadius: 6,
3001
+ elevation: 2
3002
+ } : {};
3003
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: [{ transform: [{ scale: scale2 }] }, disabled && styles26.disabled] }, /* @__PURE__ */ React26.createElement(
3004
+ TouchableOpacity,
3005
+ {
3006
+ style: [styles26.container, cardStyle, style],
3007
+ onPress: handlePress,
3008
+ onPressIn: handlePressIn,
3009
+ onPressOut: handlePressOut,
3010
+ disabled,
3011
+ activeOpacity: 1,
3012
+ touchSoundDisabled: true
3013
+ },
3014
+ resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles26.iconContainer }, resolvedIcon) : null,
3015
+ /* @__PURE__ */ React26.createElement(
3016
+ Text,
3017
+ {
3018
+ style: [styles26.label, { color: colors.foreground }, labelStyle],
3019
+ numberOfLines: 1,
3020
+ allowFontScaling: true
3021
+ },
3022
+ label
3023
+ ),
3024
+ rightRender !== void 0 ? /* @__PURE__ */ React26.createElement(
3025
+ View,
3026
+ {
3027
+ style: styles26.rightContainer,
3028
+ onStartShouldSetResponder: () => true,
3029
+ onResponderRelease: () => {
3030
+ }
3031
+ },
3032
+ rightRender
3033
+ ) : showChevron ? /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-right", size: 18, color: colors.foregroundMuted }) : null
3034
+ ), showSeparator ? /* @__PURE__ */ React26.createElement(
3035
+ View,
3036
+ {
3037
+ style: [
3038
+ styles26.separator,
3039
+ {
3040
+ backgroundColor: colors.border,
3041
+ marginLeft: resolvedIcon ? s(22) + s(12) : 0,
3042
+ opacity: 0.6
3043
+ }
3044
+ ]
3045
+ }
3046
+ ) : null);
3047
+ }
3048
+ var styles26 = StyleSheet.create({
3049
+ container: {
3050
+ flexDirection: "row",
3051
+ alignItems: "center",
3052
+ paddingHorizontal: 0,
3053
+ paddingVertical: vs(16),
3054
+ minHeight: vs(54),
3055
+ gap: s(12)
3056
+ },
3057
+ iconContainer: {
3058
+ width: s(22),
3059
+ alignItems: "center",
3060
+ justifyContent: "center",
3061
+ flexShrink: 0
3062
+ },
3063
+ label: {
3064
+ fontFamily: "Poppins-Medium",
3065
+ fontSize: ms(15),
3066
+ flex: 1
3067
+ },
3068
+ rightContainer: {
3069
+ alignItems: "flex-end",
3070
+ justifyContent: "center",
3071
+ flexShrink: 0
3072
+ },
3073
+ separator: {
3074
+ height: StyleSheet.hairlineWidth,
3075
+ marginRight: 0
3076
+ },
3077
+ disabled: {
3078
+ opacity: 0.45
3079
+ }
3080
+ });
3081
+ var nativeDriver12 = Platform.OS !== "web";
2861
3082
  function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2862
3083
  const { colors } = useTheme();
2863
3084
  const scale2 = useRef(new Animated.Value(1)).current;
@@ -2866,14 +3087,14 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2866
3087
  Animated.timing(pressAnim, {
2867
3088
  toValue: selected ? 1 : 0,
2868
3089
  duration: 150,
2869
- easing: Easing.out(Easing.ease),
3090
+ easing: Easing$1.out(Easing$1.ease),
2870
3091
  useNativeDriver: false
2871
3092
  }).start();
2872
3093
  }, [selected, pressAnim]);
2873
3094
  const handlePressIn = () => {
2874
3095
  Animated.spring(scale2, {
2875
3096
  toValue: 0.95,
2876
- useNativeDriver: nativeDriver11,
3097
+ useNativeDriver: nativeDriver12,
2877
3098
  speed: 40,
2878
3099
  bounciness: 0
2879
3100
  }).start();
@@ -2881,7 +3102,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2881
3102
  const handlePressOut = () => {
2882
3103
  Animated.spring(scale2, {
2883
3104
  toValue: 1,
2884
- useNativeDriver: nativeDriver11,
3105
+ useNativeDriver: nativeDriver12,
2885
3106
  speed: 40,
2886
3107
  bounciness: 4
2887
3108
  }).start();
@@ -2903,7 +3124,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2903
3124
  outputRange: [colors.border, colors.primary]
2904
3125
  });
2905
3126
  const resolvedIcon = iconName ? renderIcon(iconName, ms(13), selected ? colors.primaryForeground : colors.foreground) : icon;
2906
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles26.wrapper, { transform: [{ scale: scale2 }] }, style] }, /* @__PURE__ */ React25.createElement(
3127
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: [styles27.wrapper, { transform: [{ scale: scale2 }] }, style] }, /* @__PURE__ */ React26.createElement(
2907
3128
  TouchableOpacity,
2908
3129
  {
2909
3130
  onPress: handlePress,
@@ -2912,7 +3133,7 @@ function Chip({ label, selected = false, onPress, icon, iconName, style }) {
2912
3133
  activeOpacity: 1,
2913
3134
  touchSoundDisabled: true
2914
3135
  },
2915
- /* @__PURE__ */ React25.createElement(Animated.View, { style: [styles26.chip, { backgroundColor, borderColor }] }, resolvedIcon ? /* @__PURE__ */ React25.createElement(View, { style: styles26.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React25.createElement(Animated.Text, { style: [styles26.label, { color: textColor }], allowFontScaling: true }, label))
3136
+ /* @__PURE__ */ React26.createElement(Animated.View, { style: [styles27.chip, { backgroundColor, borderColor }] }, resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles27.chipIcon }, resolvedIcon) : null, /* @__PURE__ */ React26.createElement(Animated.Text, { style: [styles27.label, { color: textColor }], allowFontScaling: true }, label))
2916
3137
  ));
2917
3138
  }
2918
3139
  function ChipGroup({ options, value, onValueChange, multiSelect = false, style }) {
@@ -2937,17 +3158,19 @@ function ChipGroup({ options, value, onValueChange, multiSelect = false, style }
2937
3158
  }
2938
3159
  return optionValue === value;
2939
3160
  };
2940
- return /* @__PURE__ */ React25.createElement(View, { style: [styles26.group, style] }, options.map((opt) => /* @__PURE__ */ React25.createElement(
3161
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles27.group, style] }, options.map((opt) => /* @__PURE__ */ React26.createElement(
2941
3162
  Chip,
2942
3163
  {
2943
3164
  key: opt.value,
2944
3165
  label: opt.label,
2945
3166
  selected: isSelected(opt.value),
2946
- onPress: () => handlePress(opt.value)
3167
+ onPress: opt.disabled ? void 0 : () => handlePress(opt.value),
3168
+ iconName: opt.iconName,
3169
+ style: opt.disabled ? { opacity: 0.4 } : void 0
2947
3170
  }
2948
3171
  )));
2949
3172
  }
2950
- var styles26 = StyleSheet.create({
3173
+ var styles27 = StyleSheet.create({
2951
3174
  wrapper: {},
2952
3175
  chip: {
2953
3176
  borderRadius: 999,
@@ -2988,13 +3211,13 @@ function ConfirmDialog({
2988
3211
  const ref = useRef(null);
2989
3212
  useEffect(() => {
2990
3213
  if (visible) {
2991
- impactLight();
3214
+ impactMedium();
2992
3215
  ref.current?.present();
2993
3216
  } else {
2994
3217
  ref.current?.dismiss();
2995
3218
  }
2996
3219
  }, [visible]);
2997
- const renderBackdrop = (props) => /* @__PURE__ */ React25.createElement(
3220
+ const renderBackdrop = (props) => /* @__PURE__ */ React26.createElement(
2998
3221
  BottomSheetBackdrop,
2999
3222
  {
3000
3223
  ...props,
@@ -3003,25 +3226,28 @@ function ConfirmDialog({
3003
3226
  pressBehavior: "close"
3004
3227
  }
3005
3228
  );
3006
- return /* @__PURE__ */ React25.createElement(
3229
+ return /* @__PURE__ */ React26.createElement(
3007
3230
  BottomSheetModal,
3008
3231
  {
3009
3232
  ref,
3010
3233
  enableDynamicSizing: true,
3011
3234
  onDismiss: onCancel,
3012
3235
  backdropComponent: renderBackdrop,
3013
- backgroundStyle: [styles27.background, { backgroundColor: colors.card }],
3014
- handleIndicatorStyle: [styles27.handle, { backgroundColor: colors.border }],
3236
+ backgroundStyle: [styles28.background, { backgroundColor: colors.card }],
3237
+ handleIndicatorStyle: [styles28.handle, { backgroundColor: colors.border }],
3015
3238
  enablePanDownToClose: true
3016
3239
  },
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(
3240
+ /* @__PURE__ */ React26.createElement(BottomSheetView, { style: styles28.content }, /* @__PURE__ */ React26.createElement(Text, { style: [styles28.title, { color: colors.foreground }], allowFontScaling: true }, title), description ? /* @__PURE__ */ React26.createElement(Text, { style: [styles28.description, { color: colors.foregroundMuted }], allowFontScaling: true }, description) : null, /* @__PURE__ */ React26.createElement(View, { style: styles28.actions }, /* @__PURE__ */ React26.createElement(
3018
3241
  Button,
3019
3242
  {
3020
3243
  label: confirmLabel,
3021
3244
  variant: confirmVariant,
3022
3245
  fullWidth: true,
3023
- onPress: onConfirm,
3024
- icon: /* @__PURE__ */ React25.createElement(
3246
+ onPress: () => {
3247
+ notificationSuccess();
3248
+ onConfirm();
3249
+ },
3250
+ icon: /* @__PURE__ */ React26.createElement(
3025
3251
  Feather$1,
3026
3252
  {
3027
3253
  name: confirmVariant === "destructive" ? "trash-2" : "check",
@@ -3030,19 +3256,22 @@ function ConfirmDialog({
3030
3256
  }
3031
3257
  )
3032
3258
  }
3033
- ), /* @__PURE__ */ React25.createElement(
3259
+ ), /* @__PURE__ */ React26.createElement(
3034
3260
  Button,
3035
3261
  {
3036
3262
  label: cancelLabel,
3037
3263
  variant: "secondary",
3038
3264
  fullWidth: true,
3039
- onPress: onCancel,
3040
- icon: /* @__PURE__ */ React25.createElement(Feather$1, { name: "x", size: 15, color: colors.foreground })
3265
+ onPress: () => {
3266
+ selectionAsync();
3267
+ onCancel();
3268
+ },
3269
+ icon: /* @__PURE__ */ React26.createElement(Feather$1, { name: "x", size: 15, color: colors.foreground })
3041
3270
  }
3042
3271
  )))
3043
3272
  );
3044
3273
  }
3045
- var styles27 = StyleSheet.create({
3274
+ var styles28 = StyleSheet.create({
3046
3275
  background: {
3047
3276
  borderTopLeftRadius: ms(16),
3048
3277
  borderTopRightRadius: ms(16)
@@ -3072,17 +3301,27 @@ var styles27 = StyleSheet.create({
3072
3301
  marginTop: vs(8)
3073
3302
  }
3074
3303
  });
3075
- function LabelValue({ label, value, style }) {
3304
+ function LabelValue({ label, value, iconName, iconColor, style }) {
3076
3305
  const { colors } = useTheme();
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);
3306
+ const resolvedIcon = iconName ? renderIcon(iconName, ms(14), iconColor ?? colors.foregroundMuted) : null;
3307
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles29.container, style] }, /* @__PURE__ */ React26.createElement(View, { style: styles29.labelSide }, resolvedIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles29.icon }, resolvedIcon) : null, /* @__PURE__ */ React26.createElement(Text, { style: [styles29.label, { color: colors.foregroundMuted }], allowFontScaling: true }, label)), typeof value === "string" ? /* @__PURE__ */ React26.createElement(Text, { style: [styles29.value, { color: colors.foreground }], allowFontScaling: true }, value) : value);
3078
3308
  }
3079
- var styles28 = StyleSheet.create({
3309
+ var styles29 = StyleSheet.create({
3080
3310
  container: {
3081
3311
  flexDirection: "row",
3082
3312
  justifyContent: "space-between",
3083
3313
  alignItems: "center",
3084
3314
  gap: s(12)
3085
3315
  },
3316
+ labelSide: {
3317
+ flexDirection: "row",
3318
+ alignItems: "center",
3319
+ gap: s(4)
3320
+ },
3321
+ icon: {
3322
+ alignItems: "center",
3323
+ justifyContent: "center"
3324
+ },
3086
3325
  label: {
3087
3326
  fontFamily: "Poppins-Regular",
3088
3327
  fontSize: ms(13),
@@ -3095,22 +3334,19 @@ var styles28 = StyleSheet.create({
3095
3334
  textAlign: "right"
3096
3335
  }
3097
3336
  });
3098
- var MONTH_NAMES = [
3099
- "January",
3100
- "February",
3101
- "March",
3102
- "April",
3103
- "May",
3104
- "June",
3105
- "July",
3106
- "August",
3107
- "September",
3108
- "October",
3109
- "November",
3110
- "December"
3111
- ];
3112
- function MonthPicker({ value, onChange, style }) {
3337
+ var MONTH_NAMES = {
3338
+ en: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
3339
+ es: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"],
3340
+ pt: ["janeiro", "fevereiro", "mar\xE7o", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"],
3341
+ fr: ["janvier", "f\xE9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\xFBt", "septembre", "octobre", "novembre", "d\xE9cembre"]
3342
+ };
3343
+ function MonthPicker({ value, onChange, locale = "en", formatLabel, style }) {
3113
3344
  const { colors } = useTheme();
3345
+ const getLabel = () => {
3346
+ if (formatLabel) return formatLabel(value);
3347
+ const names = MONTH_NAMES[locale] ?? MONTH_NAMES.en;
3348
+ return `${names[value.month - 1]} ${value.year}`;
3349
+ };
3114
3350
  const handlePrev = () => {
3115
3351
  selectionAsync();
3116
3352
  if (value.month === 1) {
@@ -3127,27 +3363,27 @@ function MonthPicker({ value, onChange, style }) {
3127
3363
  onChange({ month: value.month + 1, year: value.year });
3128
3364
  }
3129
3365
  };
3130
- return /* @__PURE__ */ React25.createElement(View, { style: [styles29.container, style] }, /* @__PURE__ */ React25.createElement(
3366
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles30.container, style] }, /* @__PURE__ */ React26.createElement(
3131
3367
  TouchableOpacity,
3132
3368
  {
3133
- style: styles29.arrow,
3369
+ style: styles30.arrow,
3134
3370
  onPress: handlePrev,
3135
3371
  activeOpacity: 0.6,
3136
3372
  touchSoundDisabled: true
3137
3373
  },
3138
- /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-left", size: 22, color: colors.foreground })
3139
- ), /* @__PURE__ */ React25.createElement(Text, { style: [styles29.label, { color: colors.foreground }], allowFontScaling: true }, MONTH_NAMES[value.month - 1], " ", value.year), /* @__PURE__ */ React25.createElement(
3374
+ /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-left", size: 22, color: colors.foreground })
3375
+ ), /* @__PURE__ */ React26.createElement(Text, { style: [styles30.label, { color: colors.foreground }], allowFontScaling: true }, getLabel()), /* @__PURE__ */ React26.createElement(
3140
3376
  TouchableOpacity,
3141
3377
  {
3142
- style: styles29.arrow,
3378
+ style: styles30.arrow,
3143
3379
  onPress: handleNext,
3144
3380
  activeOpacity: 0.6,
3145
3381
  touchSoundDisabled: true
3146
3382
  },
3147
- /* @__PURE__ */ React25.createElement(Entypo$1, { name: "chevron-right", size: 22, color: colors.foreground })
3383
+ /* @__PURE__ */ React26.createElement(Entypo$1, { name: "chevron-right", size: 22, color: colors.foreground })
3148
3384
  ));
3149
3385
  }
3150
- var styles29 = StyleSheet.create({
3386
+ var styles30 = StyleSheet.create({
3151
3387
  container: {
3152
3388
  flexDirection: "row",
3153
3389
  alignItems: "center",
@@ -3178,7 +3414,7 @@ function useHover() {
3178
3414
  }
3179
3415
 
3180
3416
  // src/components/MediaCard/MediaCard.tsx
3181
- var nativeDriver12 = Platform.OS !== "web";
3417
+ var nativeDriver13 = Platform.OS !== "web";
3182
3418
  var aspectRatioMap = {
3183
3419
  "1:1": 1,
3184
3420
  "4:3": 3 / 4,
@@ -3207,11 +3443,11 @@ function MediaCard({
3207
3443
  const { hovered, hoverHandlers } = useHover();
3208
3444
  const handlePressIn = () => {
3209
3445
  if (!onPress) return;
3210
- Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver12, speed: 40, bounciness: 0 }).start();
3446
+ Animated.spring(scale2, { toValue: 0.98, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
3211
3447
  };
3212
3448
  const handlePressOut = () => {
3213
3449
  if (!onPress) return;
3214
- Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver12, speed: 40, bounciness: 4 }).start();
3450
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
3215
3451
  };
3216
3452
  const handlePress = () => {
3217
3453
  if (!onPress) return;
@@ -3220,27 +3456,27 @@ function MediaCard({
3220
3456
  };
3221
3457
  const ratio = aspectRatioMap[aspectRatio];
3222
3458
  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(
3459
+ const cardContent = /* @__PURE__ */ React26.createElement(
3224
3460
  View,
3225
3461
  {
3226
3462
  style: [
3227
- styles30.card,
3228
- hovered && styles30.cardHovered,
3463
+ styles31.card,
3464
+ hovered && styles31.cardHovered,
3229
3465
  style
3230
3466
  ],
3231
3467
  ...Platform.OS === "web" ? hoverHandlers : {}
3232
3468
  },
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(
3469
+ /* @__PURE__ */ React26.createElement(View, { style: [styles31.imageContainer, imageStyle] }, /* @__PURE__ */ React26.createElement(View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React26.createElement(View, { style: StyleSheet.absoluteFill }, imageSource ? /* @__PURE__ */ React26.createElement(
3234
3470
  Image,
3235
3471
  {
3236
3472
  source: imageSource,
3237
- style: styles30.image,
3473
+ style: styles31.image,
3238
3474
  resizeMode: "cover"
3239
3475
  }
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(
3476
+ ) : /* @__PURE__ */ React26.createElement(View, { style: [styles31.imagePlaceholder, { backgroundColor: colors.surface }] }))), badge && /* @__PURE__ */ React26.createElement(View, { style: styles31.badgeContainer }, badge), (onActionPress || actionIcon || actionIconName) && /* @__PURE__ */ React26.createElement(
3241
3477
  TouchableOpacity,
3242
3478
  {
3243
- style: [styles30.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
3479
+ style: [styles31.actionButton, { backgroundColor: "rgba(0,0,0,0.24)" }],
3244
3480
  onPress: () => {
3245
3481
  impactLight();
3246
3482
  onActionPress?.();
@@ -3250,10 +3486,10 @@ function MediaCard({
3250
3486
  },
3251
3487
  resolvedActionIcon
3252
3488
  )),
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)
3489
+ (title || subtitle || caption || footer) && /* @__PURE__ */ React26.createElement(View, { style: styles31.meta }, title ? /* @__PURE__ */ React26.createElement(Text, { style: [styles31.title, { color: colors.foreground }], numberOfLines: 2, allowFontScaling: true }, title) : null, subtitle ? /* @__PURE__ */ React26.createElement(Text, { style: [styles31.subtitle, { color: colors.foregroundSubtle }], numberOfLines: 1, allowFontScaling: true }, subtitle) : null, caption ? /* @__PURE__ */ React26.createElement(Text, { style: [styles31.caption, { color: colors.foregroundMuted }], numberOfLines: 1, allowFontScaling: true }, caption) : null, footer)
3254
3490
  );
3255
3491
  if (onPress) {
3256
- return /* @__PURE__ */ React25.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React25.createElement(
3492
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26.createElement(
3257
3493
  TouchableOpacity,
3258
3494
  {
3259
3495
  onPress: handlePress,
@@ -3267,7 +3503,7 @@ function MediaCard({
3267
3503
  }
3268
3504
  return cardContent;
3269
3505
  }
3270
- var styles30 = StyleSheet.create({
3506
+ var styles31 = StyleSheet.create({
3271
3507
  card: {
3272
3508
  borderRadius: RADIUS.md,
3273
3509
  // 14px — Airbnb property card spec
@@ -3307,6 +3543,7 @@ var styles30 = StyleSheet.create({
3307
3543
  },
3308
3544
  meta: {
3309
3545
  paddingTop: vs(8),
3546
+ paddingBottom: vs(4),
3310
3547
  gap: vs(2)
3311
3548
  },
3312
3549
  title: {
@@ -3325,7 +3562,7 @@ var styles30 = StyleSheet.create({
3325
3562
  lineHeight: mvs(16)
3326
3563
  }
3327
3564
  });
3328
- var nativeDriver13 = Platform.OS !== "web";
3565
+ var nativeDriver14 = Platform.OS !== "web";
3329
3566
  function CategoryChip({
3330
3567
  item,
3331
3568
  selected,
@@ -3334,20 +3571,20 @@ function CategoryChip({
3334
3571
  const { colors } = useTheme();
3335
3572
  const scale2 = useRef(new Animated.Value(1)).current;
3336
3573
  const handlePressIn = () => {
3337
- Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver13, speed: 40, bounciness: 0 }).start();
3574
+ Animated.spring(scale2, { toValue: 0.95, useNativeDriver: nativeDriver14, speed: 40, bounciness: 0 }).start();
3338
3575
  };
3339
3576
  const handlePressOut = () => {
3340
- Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver13, speed: 40, bounciness: 4 }).start();
3577
+ Animated.spring(scale2, { toValue: 1, useNativeDriver: nativeDriver14, speed: 40, bounciness: 4 }).start();
3341
3578
  };
3342
3579
  const bgColor = selected ? colors.primary : colors.surface;
3343
3580
  const textColor = selected ? colors.primaryForeground : colors.foregroundSubtle;
3344
3581
  const borderColor = selected ? colors.primary : colors.border;
3345
3582
  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(
3583
+ return /* @__PURE__ */ React26.createElement(Animated.View, { style: { transform: [{ scale: scale2 }] } }, /* @__PURE__ */ React26.createElement(
3347
3584
  TouchableOpacity,
3348
3585
  {
3349
3586
  style: [
3350
- styles31.chip,
3587
+ styles32.chip,
3351
3588
  {
3352
3589
  backgroundColor: bgColor,
3353
3590
  borderColor
@@ -3359,9 +3596,9 @@ function CategoryChip({
3359
3596
  activeOpacity: 1,
3360
3597
  touchSoundDisabled: true
3361
3598
  },
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)))
3599
+ resolvedIcon && /* @__PURE__ */ React26.createElement(View, { style: styles32.chipIcon }, resolvedIcon),
3600
+ /* @__PURE__ */ React26.createElement(Text, { style: [styles32.chipLabel, { color: textColor }], allowFontScaling: true }, item.label),
3601
+ item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ React26.createElement(View, { style: [styles32.chipBadge, { backgroundColor: colors.primary }] }, /* @__PURE__ */ React26.createElement(Text, { style: [styles32.chipBadgeText, { color: colors.primaryForeground }] }, Math.min(item.badge, 99)))
3365
3602
  ));
3366
3603
  }
3367
3604
  function CategoryStrip({
@@ -3383,15 +3620,15 @@ function CategoryStrip({
3383
3620
  onValueChange?.(v === value ? "" : v);
3384
3621
  }
3385
3622
  };
3386
- return /* @__PURE__ */ React25.createElement(
3623
+ return /* @__PURE__ */ React26.createElement(
3387
3624
  ScrollView,
3388
3625
  {
3389
3626
  horizontal: true,
3390
3627
  showsHorizontalScrollIndicator: false,
3391
- contentContainerStyle: [styles31.container, style],
3392
- style: styles31.scroll
3628
+ contentContainerStyle: [styles32.container, style],
3629
+ style: styles32.scroll
3393
3630
  },
3394
- categories.map((cat) => /* @__PURE__ */ React25.createElement(View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React25.createElement(
3631
+ categories.map((cat) => /* @__PURE__ */ React26.createElement(View, { key: cat.value, style: itemStyle }, /* @__PURE__ */ React26.createElement(
3395
3632
  CategoryChip,
3396
3633
  {
3397
3634
  item: cat,
@@ -3401,7 +3638,7 @@ function CategoryStrip({
3401
3638
  )))
3402
3639
  );
3403
3640
  }
3404
- var styles31 = StyleSheet.create({
3641
+ var styles32 = StyleSheet.create({
3405
3642
  scroll: {
3406
3643
  flexGrow: 0
3407
3644
  },
@@ -3442,7 +3679,7 @@ var styles31 = StyleSheet.create({
3442
3679
  lineHeight: 14
3443
3680
  }
3444
3681
  });
3445
- var nativeDriver14 = Platform.OS !== "web";
3682
+ var nativeDriver15 = Platform.OS !== "web";
3446
3683
  function Pressable2({
3447
3684
  children,
3448
3685
  onPress,
@@ -3460,7 +3697,7 @@ function Pressable2({
3460
3697
  if (disabled) return;
3461
3698
  Animated.spring(scale2, {
3462
3699
  toValue: pressScale,
3463
- useNativeDriver: nativeDriver14,
3700
+ useNativeDriver: nativeDriver15,
3464
3701
  speed: 40,
3465
3702
  bounciness: 0
3466
3703
  }).start();
@@ -3469,7 +3706,7 @@ function Pressable2({
3469
3706
  if (disabled) return;
3470
3707
  Animated.spring(scale2, {
3471
3708
  toValue: 1,
3472
- useNativeDriver: nativeDriver14,
3709
+ useNativeDriver: nativeDriver15,
3473
3710
  speed: 40,
3474
3711
  bounciness
3475
3712
  }).start();
@@ -3480,7 +3717,7 @@ function Pressable2({
3480
3717
  onPress();
3481
3718
  };
3482
3719
  const hoverScaleValue = hovered && hoverScale !== 1 ? hoverScale : 1;
3483
- return /* @__PURE__ */ React25.createElement(
3720
+ return /* @__PURE__ */ React26.createElement(
3484
3721
  Animated.View,
3485
3722
  {
3486
3723
  style: [
@@ -3489,7 +3726,7 @@ function Pressable2({
3489
3726
  ],
3490
3727
  ...Platform.OS === "web" ? hoverHandlers : {}
3491
3728
  },
3492
- /* @__PURE__ */ React25.createElement(
3729
+ /* @__PURE__ */ React26.createElement(
3493
3730
  TouchableOpacity,
3494
3731
  {
3495
3732
  onPress: handlePress,
@@ -3504,5 +3741,102 @@ function Pressable2({
3504
3741
  )
3505
3742
  );
3506
3743
  }
3744
+ var weightMap = {
3745
+ normal: "Poppins-Regular",
3746
+ medium: "Poppins-Medium",
3747
+ semibold: "Poppins-SemiBold",
3748
+ bold: "Poppins-Bold"
3749
+ };
3750
+ function DetailRow({
3751
+ label,
3752
+ value,
3753
+ separator = "dotted",
3754
+ labelWeight = "normal",
3755
+ valueColor,
3756
+ leftIcon,
3757
+ leftIconName,
3758
+ leftIconColor,
3759
+ rightIconName,
3760
+ rightIconColor,
3761
+ style,
3762
+ labelStyle,
3763
+ valueStyle
3764
+ }) {
3765
+ const { colors } = useTheme();
3766
+ const resolvedLeftIcon = leftIconName ? renderIcon(leftIconName, ms(14), leftIconColor ?? colors.foregroundMuted) : leftIcon;
3767
+ const resolvedRightIcon = rightIconName ? renderIcon(rightIconName, ms(14), rightIconColor ?? colors.foregroundMuted) : null;
3768
+ const separatorStyle = separator === "none" ? null : {
3769
+ flex: 1,
3770
+ height: 1,
3771
+ borderBottomWidth: 1,
3772
+ borderStyle: separator,
3773
+ borderColor: "rgba(128,128,128,0.3)",
3774
+ marginHorizontal: s(4)
3775
+ };
3776
+ return /* @__PURE__ */ React26.createElement(View, { style: [styles33.row, style] }, /* @__PURE__ */ React26.createElement(View, { style: styles33.labelSide }, resolvedLeftIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles33.icon }, resolvedLeftIcon) : null, typeof label === "string" ? /* @__PURE__ */ React26.createElement(
3777
+ Text,
3778
+ {
3779
+ style: [styles33.labelText, { color: colors.foregroundMuted, fontFamily: weightMap[labelWeight] }, labelStyle],
3780
+ allowFontScaling: true
3781
+ },
3782
+ label
3783
+ ) : label), separatorStyle ? /* @__PURE__ */ React26.createElement(View, { style: separatorStyle }) : /* @__PURE__ */ React26.createElement(View, { style: styles33.spacer }), /* @__PURE__ */ React26.createElement(View, { style: styles33.valueSide }, /* @__PURE__ */ React26.createElement(
3784
+ Text,
3785
+ {
3786
+ style: [styles33.valueText, { color: valueColor ?? colors.foreground }, valueStyle],
3787
+ allowFontScaling: true
3788
+ },
3789
+ value
3790
+ ), resolvedRightIcon ? /* @__PURE__ */ React26.createElement(View, { style: styles33.icon }, resolvedRightIcon) : null));
3791
+ }
3792
+ var styles33 = StyleSheet.create({
3793
+ row: {
3794
+ flexDirection: "row",
3795
+ alignItems: "center",
3796
+ gap: s(4)
3797
+ },
3798
+ labelSide: {
3799
+ flexDirection: "row",
3800
+ alignItems: "center",
3801
+ gap: s(4),
3802
+ flexShrink: 0
3803
+ },
3804
+ icon: {
3805
+ alignItems: "center",
3806
+ justifyContent: "center"
3807
+ },
3808
+ spacer: {
3809
+ flex: 1
3810
+ },
3811
+ labelText: {
3812
+ fontSize: ms(13),
3813
+ lineHeight: mvs(18)
3814
+ },
3815
+ valueSide: {
3816
+ flexDirection: "row",
3817
+ alignItems: "center",
3818
+ gap: s(4),
3819
+ flexShrink: 0
3820
+ },
3821
+ valueText: {
3822
+ fontFamily: "Poppins-SemiBold",
3823
+ fontSize: ms(13),
3824
+ lineHeight: mvs(18)
3825
+ }
3826
+ });
3827
+
3828
+ // src/utils/typography.ts
3829
+ function getResponsiveFontSize(text, maxSize, steps = [
3830
+ { maxLen: 10, subtract: 0 },
3831
+ { maxLen: 12, subtract: 4 },
3832
+ { maxLen: 14, subtract: 6 }
3833
+ ]) {
3834
+ const len = text.length;
3835
+ const sorted = [...steps].sort((a, b) => a.maxLen - b.maxLen);
3836
+ for (const step of sorted) {
3837
+ if (len <= step.maxLen) return maxSize - step.subtract;
3838
+ }
3839
+ return maxSize - 8;
3840
+ }
3507
3841
 
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 };
3842
+ export { Accordion, AlertBanner, Avatar, BREAKPOINTS, Badge, Button, ButtonGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryStrip, Checkbox, Chip, ChipGroup, ConfirmDialog, CurrencyDisplay, CurrencyInput, CurrencyInput as CurrencyInputLarge, DetailRow, EmptyState, ICON_SIZES, Icon, IconButton, Input, LabelValue, ListItem, MediaCard, MenuItem, 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, getResponsiveFontSize, renderIcon, useTheme, useToast };